mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
2ec4e91b11
* refactor(core): move the command descriptor registry into its own package `src/core/command-descriptor/`, `src/command-catalog.ts`, `src/core/wait-positionals.ts` and `src/core/parse-timeout.ts` move as git renames into a new private package `@agent-device/command-registry` (deps: contracts, selectors). One subpath per module points straight at the moved file; no `index.ts`, no re-export at the old path. Every consumer switches to the owning specifier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz * test(host-kit): pin the command-registry package inside the daemon code graph The daemon reaches the registry and its catalog only by workspace specifier. A walk that stopped at the package boundary would report an unchanged signature after a descriptor edit, and the client would keep reusing a daemon running the superseded policy. The manifest is asserted beside the sources because its `exports` map is what chose them. The cache doc comment quoting the old ~800-module graph is corrected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz * chore(gates): point the descriptor-registry gates at the package path R66's `COMMAND_DESCRIPTOR_MODULE`, R16's record-runtime join subject and the Fallow `AssertTrue` totality-guard key follow the registry to its package. The two descriptor hubs leave `HUB_ENTRY_FILES` because the package manifest now publishes them, so the eager-closure gate discovers them as facades and one entry gets one rule; this also flips `denyPlatformImplementations` from false (hub) to true (package entry) for both, which is intentional and stricter. `command-registry` joins the ranked spine at rank 1. No `APPROVED_OVER_CEILING` row: rename detection carries every moved entry's merge-base baseline, so all twelve fall under the no-growth rule rather than a ceiling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jqfa11D8QsCMuL17SsLvDz --------- Co-authored-by: Claude <noreply@anthropic.com>
35 lines
1.4 KiB
TypeScript
35 lines
1.4 KiB
TypeScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { COMMAND_OWNER_FILES } from '@agent-device/command-registry/owner-files';
|
|
import { getDaemonRouteOwnerFiles } from '../src/daemon/route-owner-files.ts';
|
|
import { walkFiles } from './lib/walk-files.ts';
|
|
|
|
const repoRoot = path.resolve(import.meta.dirname, '..');
|
|
const distRoot = path.join(repoRoot, 'dist', 'src');
|
|
const ownerPaths = new Set([
|
|
...Object.values(COMMAND_OWNER_FILES).flat(),
|
|
...Object.values(getDaemonRouteOwnerFiles()),
|
|
]);
|
|
const forbiddenMetadata = new Set(['ownerFiles', ...ownerPaths]);
|
|
|
|
const bundleFiles = walkFiles(distRoot).filter((file) => file.endsWith('.js'));
|
|
if (bundleFiles.length === 0) {
|
|
throw new Error('No dist/src JavaScript files found. Run `pnpm build` first.');
|
|
}
|
|
|
|
const leaks = bundleFiles.flatMap((file) => {
|
|
const content = fs.readFileSync(file, 'utf8');
|
|
return [...forbiddenMetadata]
|
|
.filter((value) => content.includes(value))
|
|
.map((value) => ({ file: path.relative(repoRoot, file), value }));
|
|
});
|
|
|
|
if (leaks.length > 0) {
|
|
const details = leaks.map(({ file, value }) => `- ${value} in ${file}`).join('\n');
|
|
throw new Error(`Owner-file navigation metadata leaked into production bundles:\n${details}`);
|
|
}
|
|
|
|
process.stdout.write(
|
|
`Verified the ownerFiles key and ${ownerPaths.size} owner-file paths are absent from ${bundleFiles.length} production bundles.\n`,
|
|
);
|