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>
81 lines
3.9 KiB
TypeScript
81 lines
3.9 KiB
TypeScript
// Layering scans read tracked repository paths only. Most rules consume production TypeScript;
|
|
// the retired zones also consume every tracked path under their former roots so non-TS fixtures
|
|
// cannot bypass the ownership boundary.
|
|
//
|
|
// A leaf module on purpose. `check.ts` owns the scan and imports `package-boundaries.ts`, so the
|
|
// boundary rules cannot import `check.ts` back for its file list; without a shared leaf the two
|
|
// would each grow their own enumerator, and the moment those disagree a rule silently changes
|
|
// scope. That is not hypothetical -- it is the #1965 review finding this module exists to fix:
|
|
// `facadeEntryFiles` was briefly implemented as a raw `readdir` walk, which quietly widened R11
|
|
// from tracked files to whatever happened to be on disk.
|
|
//
|
|
// Tracked-only is a hard rule, not an optimization. A layering gate describes COMMITTED state:
|
|
// `docs/adr/0019-request-bound-platform-runtime.md` requires review "from a clean committed tree
|
|
// with all production files present in HEAD", and `check.ts` separately fails closed when
|
|
// production TypeScript is untracked. A scratch file a contributor has not committed -- a
|
|
// throwaway `facades/experiment.ts`, a half-finished module -- must be invisible here, or a gate
|
|
// that is supposed to describe the repository starts failing on the contents of someone's working
|
|
// directory instead.
|
|
|
|
import { execFileSync } from 'node:child_process';
|
|
|
|
// `src/**/*.ts` only matches NESTED files, so root-level `src/*.ts` (src/cli.ts,
|
|
// src/backend.ts) needs its own pathspec or it silently drops out of every scan.
|
|
// Workspace package sources are production files too (#1490 W0).
|
|
const TRACKED_SOURCE_PATHSPECS = [
|
|
'src/*.ts',
|
|
'src/**/*.ts',
|
|
'packages/*/src/*.ts',
|
|
'packages/*/src/**/*.ts',
|
|
];
|
|
|
|
/**
|
|
* Every tracked `packages/<pkg>/package.json`, repo-root-relative.
|
|
*
|
|
* The manifest half of the same rule. A package directory a contributor has created but not
|
|
* committed declares no entry surfaces as far as any gate is concerned -- otherwise scratch work
|
|
* changes what R11 and the loading-shape budgets police (#1965 review, second tracked-only pass).
|
|
* `platform-package-repository.ts` already reads its manifests this way for R13; this is the same
|
|
* enumeration widened to every workspace package.
|
|
*/
|
|
export function listTrackedPackageManifests(repoRoot: string): string[] {
|
|
return listTrackedFiles(repoRoot, ['packages/*/package.json']);
|
|
}
|
|
|
|
/** Every tracked `.ts` source file under the scanned roots, repo-root-relative. */
|
|
export function listTrackedTypeScriptFiles(repoRoot: string): string[] {
|
|
return listTrackedFiles(repoRoot, TRACKED_SOURCE_PATHSPECS);
|
|
}
|
|
|
|
/** Every tracked file under the retired platform root, regardless of extension. */
|
|
export function listTrackedPlatformZoneFiles(repoRoot: string): string[] {
|
|
return listTrackedFilesUnderRoot(repoRoot, 'src/platforms');
|
|
}
|
|
|
|
/** Every tracked path at or under the retired `src/utils` root, regardless of extension. */
|
|
export function listTrackedSrcUtilsFiles(repoRoot: string): string[] {
|
|
return listTrackedFilesUnderRoot(repoRoot, 'src/utils');
|
|
}
|
|
|
|
function listTrackedFilesUnderRoot(repoRoot: string, root: string): string[] {
|
|
return listTrackedFiles(repoRoot, [root]);
|
|
}
|
|
|
|
function listTrackedFiles(repoRoot: string, pathspecs: readonly string[]): string[] {
|
|
const out = execFileSync('git', ['ls-files', '-z', '--', ...pathspecs], {
|
|
cwd: repoRoot,
|
|
encoding: 'utf8',
|
|
});
|
|
return out.split('\0').filter(Boolean);
|
|
}
|
|
|
|
/** Production sources only: test files and `__tests__/` trees are not layering subjects. */
|
|
export function isProductionSourceFile(file: string): boolean {
|
|
return file.endsWith('.ts') && !/(?:^|\/)__tests__\//.test(file) && !/\.test\.ts$/.test(file);
|
|
}
|
|
|
|
/** The canonical layering scan input: tracked, production, repo-root-relative. */
|
|
export function listTrackedProductionSources(repoRoot: string): string[] {
|
|
return listTrackedTypeScriptFiles(repoRoot).filter(isProductionSourceFile);
|
|
}
|