Files
callstack__agent-device/test/integration/smoke-cli.test.ts
Michał Pierzchała 2ec4e91b11 refactor(core): move the command descriptor registry into its own workspace package (#2348)
* 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>
2026-09-06 12:55:14 +02:00

56 lines
2.0 KiB
TypeScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { runCmdSync } from '@agent-device/host-kit/command';
import { cliAliasesForCommand } from '../../src/commands/cli-command-aliases.ts';
import { listCliCommandNames } from '@agent-device/command-registry/catalog';
function runCli(args: string[]): { status: number; stdout: string; stderr: string } {
const result = runCmdSync(
process.execPath,
['--experimental-strip-types', 'src/bin.ts', ...args],
{ allowFailure: true },
);
return { status: result.exitCode, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
}
test('cli --help returns usage', () => {
const result = runCli(['--help']);
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, /agent-device/i);
assert.match(result.stdout, /agent-device help commands/i);
const commands = runCli(['help', 'commands']);
assert.equal(commands.status, 0, commands.stderr);
assert.match(commands.stdout, /reinstall <app> <path>/i);
});
test('cli --version prints semver and exits 0', () => {
const result = runCli(['--version']);
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, /^\d+\.\d+\.\d+/i);
});
test('cli -V prints semver and exits 0', () => {
const result = runCli(['-V']);
assert.equal(result.status, 0, result.stderr);
assert.match(result.stdout, /^\d+\.\d+\.\d+/i);
});
test('cli without command prints usage and exits 1', () => {
const result = runCli([]);
assert.equal(result.status, 1, result.stderr);
assert.match(result.stdout, /agent-device <command>/i);
});
test('alias --help matches the canonical command help', () => {
const aliases = listCliCommandNames().flatMap((command) =>
cliAliasesForCommand(command).map((entry) => [entry.alias, command] as const),
);
assert.ok(aliases.length > 0);
for (const [alias, canonical] of aliases) {
const result = runCli([alias, '--help']);
assert.equal(result.status, 0, result.stderr);
assert.equal(result.stdout, runCli([canonical, '--help']).stdout, alias);
}
});