phasegate 0.254.0 → 0.283.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/README.ja.md +6 -3
- package/README.md +6 -3
- package/docs/contracts/attestation-v2.schema.json +110 -0
- package/docs/guide/cli-reference.md +12 -1
- package/docs/guide/configuration.md +56 -0
- package/docs/guide/installation.md +1 -1
- package/docs/templates/ci/aidlc-gate.yml +60 -2
- package/package.json +2 -2
- package/scripts/harness/agent-integration/application/dto/open-world-obligations-context-dto.ts +30 -0
- package/scripts/harness/agent-integration/application/ports/world-obligations-query-port.ts +30 -0
- package/scripts/harness/agent-integration/application/usecases/get-open-world-obligations-context-usecase.ts +66 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +30 -27
- package/scripts/harness/agent-integration/infrastructure/adapters/world-model-open-obligations-query-adapter.ts +58 -0
- package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +29 -16
- package/scripts/harness/agent-integration/presentation/session-start-hook.ts +37 -1
- package/scripts/harness/agent-integration/presentation/stop-hook.ts +35 -26
- package/scripts/harness/agent-integration/presentation/world-obligations-session-context.ts +60 -0
- package/scripts/harness/attestation/application/dto/attestation-document.ts +17 -4
- package/scripts/harness/attestation/application/mappers/attestation-record-mapper.ts +55 -4
- package/scripts/harness/attestation/application/ports/world-snapshot-root-provider.ts +10 -0
- package/scripts/harness/attestation/application/usecases/produce-attestation-usecase.ts +33 -7
- package/scripts/harness/attestation/composition-root.ts +5 -0
- package/scripts/harness/attestation/domain/entities/attestation-record.ts +37 -2
- package/scripts/harness/attestation/index.ts +7 -1
- package/scripts/harness/attestation/presentation/handlers/attest-handler.ts +5 -2
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +40 -9
- package/scripts/harness/config-foundation/application/mappers/world-model-config-mapper.ts +15 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +70 -87
- package/scripts/harness/config-foundation/domain/services/preset-resolution-service.ts +80 -88
- package/scripts/harness/config-foundation/domain/value-objects/project-config.ts +34 -18
- package/scripts/harness/config-foundation/domain/value-objects/world-config.ts +198 -0
- package/scripts/harness/config-foundation/index.ts +14 -15
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/repositories/file-system-config-repository.ts +27 -18
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +84 -8
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +84 -8
- package/scripts/harness/harness-api/domain/ports/config-query-port.ts +11 -1
- package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +125 -86
- package/scripts/harness/harness-api/domain/services/status-derivation-service.ts +31 -21
- package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +18 -4
- package/scripts/harness/harness-api/domain/value-objects/harness-status-summary.ts +23 -8
- package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +4 -4
- package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +79 -34
- package/scripts/harness/installation/application/usecases/run-install.ts +199 -51
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +277 -69
- package/scripts/harness/installation/domain/deployment-manifest.ts +43 -0
- package/scripts/harness/integrations/pre-commit.ts +169 -27
- package/scripts/harness/main.ts +200 -136
- package/scripts/harness/traceability-model/application/dto/changed-design-fragment-dto.ts +31 -0
- package/scripts/harness/traceability-model/application/facades/design-change-read-facade.ts +14 -0
- package/scripts/harness/traceability-model/application/ports/staged-design-change-source-port.ts +9 -0
- package/scripts/harness/traceability-model/composition-root.ts +5 -0
- package/scripts/harness/traceability-model/index.ts +9 -0
- package/scripts/harness/traceability-model/infrastructure/adapters/git-staged-design-change-adapter.ts +155 -0
- package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +31 -0
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +57 -6
- package/scripts/harness/validator-system/composition-root.ts +25 -7
- package/scripts/harness/validator-system/domain/ports/ac-coverage-policy-port.ts +10 -1
- package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts +28 -0
- package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts +11 -0
- package/scripts/harness/validator-system/domain/services/design-change-declaration-policy.ts +75 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts +78 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts +76 -0
- package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +4 -0
- package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +126 -18
- package/scripts/harness/validator-system/infrastructure/adapters/nyquist-ac-coverage-policy-adapter.ts +49 -20
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-admission-adapter.ts +56 -0
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-rederivation-adapter.ts +56 -0
- package/scripts/harness/world-model/application/dto/pinned-design-endpoint-dto.ts +19 -0
- package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +92 -27
- package/scripts/harness/world-model/application/dto/world-snapshot-root-dto.ts +8 -0
- package/scripts/harness/world-model/application/facades/pinned-design-endpoint-facade.ts +63 -0
- package/scripts/harness/world-model/application/facades/world-snapshot-root-facade.ts +19 -0
- package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +3 -1
- package/scripts/harness/world-model/composition-root.ts +62 -33
- package/scripts/harness/world-model/index.ts +11 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +48 -13
- package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +6 -4
- package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +6 -2
package/scripts/harness/main.ts
CHANGED
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
* @work-item-id WI-217
|
|
23
23
|
* @work-item-id WI-219
|
|
24
24
|
* @work-item-id WI-291
|
|
25
|
+
* @work-item-id WI-300
|
|
26
|
+
* @work-item-id WI-306
|
|
27
|
+
* @work-item-id WI-308
|
|
25
28
|
*
|
|
26
29
|
* Phasegate CLI エントリポイント。
|
|
27
30
|
* 各Unitの Composition Root からハンドラーを取得し、コマンドに応じてディスパッチする。
|
|
@@ -45,6 +48,7 @@ import { createBiomeAstEngineModule } from "./biome-ast-engine/composition-root.
|
|
|
45
48
|
import { buildCiGovernance } from "./ci-governance/composition-root.js";
|
|
46
49
|
import { toPhaseConfigSection } from "./config-foundation/application/mappers/phase-config-section-mapper.js";
|
|
47
50
|
import { toValidatorSystemConfig } from "./config-foundation/application/mappers/validator-system-config-mapper.js";
|
|
51
|
+
import { toWorldModelConfig } from "./config-foundation/application/mappers/world-model-config-mapper.js";
|
|
48
52
|
import { createConfigFoundationModule } from "./config-foundation/composition-root.js";
|
|
49
53
|
import { ConfigValidationError } from "./config-foundation/domain/errors/config-validation-error.js";
|
|
50
54
|
import type { HarnessConfigV2 } from "./config-foundation/domain/harness-config.js";
|
|
@@ -690,8 +694,8 @@ Options:
|
|
|
690
694
|
--agent <claude|codex|both> Agent context and hook targets (default: both)
|
|
691
695
|
--skills <core|all> Rendered agent context skill mode (default: all)
|
|
692
696
|
--workflow <standard|strict> Rendered agent context workflow mode (default: standard)
|
|
693
|
-
--with-husky Include Husky hook targets
|
|
694
|
-
--with-ci Include GitHub Actions target
|
|
697
|
+
--with-husky Include Husky hook targets (opt-in; omitted by default)
|
|
698
|
+
--with-ci Include GitHub Actions target (opt-in; omitted by default)
|
|
695
699
|
--personal Use local-only install: no package.json, agent docs, Husky, CI, .gitignore, GitHub CLI, secrets, or CI setting writes.
|
|
696
700
|
With --agent claude, initializes .phasegate-local config/settings/skills and ignored .claude shims.
|
|
697
701
|
--json Output machine-readable JSON
|
|
@@ -1851,7 +1855,18 @@ function emitV2SchemaWarningOnce(sourcePath: string): void {
|
|
|
1851
1855
|
);
|
|
1852
1856
|
}
|
|
1853
1857
|
|
|
1854
|
-
|
|
1858
|
+
/**
|
|
1859
|
+
* 不正 config でも fail-open(警告 + 既定設定で続行)にするコマンド。
|
|
1860
|
+
* GitHub #40: config 検証の fail-closed が dispatch より上流にあると、pre-tool-use hook
|
|
1861
|
+
* 経由で Write/Edit/Bash が全遮断され、config 自身を修復する経路が消える(自己修復
|
|
1862
|
+
* デッドロック)。hook(エージェントのツール遮断点)と doctor(自己診断)は復旧経路
|
|
1863
|
+
* として常に起動可能でなければならない。validate / ci-check 等の検査系コマンドは
|
|
1864
|
+
* fail-closed を維持する(gated スコープへの書き込みは hook 内の phase-gate 判定が
|
|
1865
|
+
* 引き続き fail-closed でブロックする)。
|
|
1866
|
+
*/
|
|
1867
|
+
const CONFIG_FAIL_OPEN_COMMANDS: ReadonlySet<string> = new Set(["hook", "doctor"]);
|
|
1868
|
+
|
|
1869
|
+
async function loadResolvedConfig(command?: string): Promise<HarnessConfigV2 | undefined> {
|
|
1855
1870
|
try {
|
|
1856
1871
|
const configModule = createConfigFoundationModule();
|
|
1857
1872
|
const result = await configModule.usecases.loadResolvedConfigUseCase.execute();
|
|
@@ -1862,6 +1877,15 @@ async function loadResolvedConfig(): Promise<HarnessConfigV2 | undefined> {
|
|
|
1862
1877
|
} catch (error) {
|
|
1863
1878
|
if (error instanceof ConfigValidationError) {
|
|
1864
1879
|
process.stderr.write(`Invalid phasegate.config.json: ${error.message}\n`);
|
|
1880
|
+
if (command !== undefined && CONFIG_FAIL_OPEN_COMMANDS.has(command)) {
|
|
1881
|
+
process.stderr.write(
|
|
1882
|
+
"Warning: continuing with default settings so diagnosis and self-repair stay possible. Fix the reported path in phasegate.config.json to restore full gating.\n",
|
|
1883
|
+
);
|
|
1884
|
+
return undefined;
|
|
1885
|
+
}
|
|
1886
|
+
process.stderr.write(
|
|
1887
|
+
"Recovery: fix the reported path/type in phasegate.config.json (or restore it from version control). `phasegate doctor` and agent hooks remain available while the config is invalid.\n",
|
|
1888
|
+
);
|
|
1865
1889
|
process.exit(2);
|
|
1866
1890
|
}
|
|
1867
1891
|
if (error instanceof ConfigNotFoundError) {
|
|
@@ -1881,24 +1905,41 @@ async function loadWorldResolvedConfig() {
|
|
|
1881
1905
|
try {
|
|
1882
1906
|
const configModule = createConfigFoundationModule();
|
|
1883
1907
|
const result = await configModule.usecases.loadResolvedConfigUseCase.execute();
|
|
1884
|
-
return
|
|
1885
|
-
designDocsRoot: result.config.paths.designDocs,
|
|
1886
|
-
inceptionRoot: result.config.paths.inceptionDocs,
|
|
1887
|
-
requirementMatrixPath: result.config.layers.L3.requirementMatrixPath,
|
|
1888
|
-
};
|
|
1908
|
+
return toWorldModelConfig(result.config);
|
|
1889
1909
|
} catch (error) {
|
|
1890
1910
|
if (error instanceof ConfigNotFoundError) return undefined;
|
|
1891
1911
|
throw error;
|
|
1892
1912
|
}
|
|
1893
1913
|
}
|
|
1894
1914
|
|
|
1915
|
+
/**
|
|
1916
|
+
* WI-308: pipe接続されたstdout / stderrのpending writeを完了してから終了状態へ移る。
|
|
1917
|
+
* `process.exit()`はNodeのstream queueを待たないため、64 KiB超のJSONを切断し得る。
|
|
1918
|
+
*/
|
|
1919
|
+
async function finishCliExit(exitCode: number): Promise<void> {
|
|
1920
|
+
const drain = (stream: NodeJS.WriteStream): Promise<void> =>
|
|
1921
|
+
new Promise((resolvePromise, reject) => {
|
|
1922
|
+
stream.write("", (error) => {
|
|
1923
|
+
if (error) {
|
|
1924
|
+
reject(error);
|
|
1925
|
+
return;
|
|
1926
|
+
}
|
|
1927
|
+
resolvePromise();
|
|
1928
|
+
});
|
|
1929
|
+
});
|
|
1930
|
+
|
|
1931
|
+
await Promise.all([drain(process.stdout), drain(process.stderr)]);
|
|
1932
|
+
process.exitCode = exitCode;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1895
1935
|
async function main(): Promise<void> {
|
|
1896
1936
|
const args = process.argv.slice(2);
|
|
1897
1937
|
const command = args[0];
|
|
1898
1938
|
|
|
1899
1939
|
if (!command || command === "--help" || command === "help") {
|
|
1900
1940
|
printUsage();
|
|
1901
|
-
|
|
1941
|
+
await finishCliExit(0);
|
|
1942
|
+
return;
|
|
1902
1943
|
}
|
|
1903
1944
|
|
|
1904
1945
|
const rootDir = getProjectRoot();
|
|
@@ -1907,19 +1948,21 @@ async function main(): Promise<void> {
|
|
|
1907
1948
|
if (command === "--version" || command === "version") {
|
|
1908
1949
|
const version = await getHarnessVersion(harnessRoot);
|
|
1909
1950
|
console.log(`phasegate v${version}`);
|
|
1910
|
-
|
|
1951
|
+
await finishCliExit(0);
|
|
1952
|
+
return;
|
|
1911
1953
|
}
|
|
1912
1954
|
|
|
1913
1955
|
// Pre-dispatch: 全 subcommand で --help / -h を最優先で解釈し usage 出力 (副作用走行を防ぐ — WI-091 finding #3)
|
|
1914
1956
|
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
1915
1957
|
printSubcommandHelp(command);
|
|
1916
|
-
|
|
1958
|
+
await finishCliExit(0);
|
|
1959
|
+
return;
|
|
1917
1960
|
}
|
|
1918
1961
|
|
|
1919
1962
|
const json = hasFlag(args, "--json");
|
|
1920
1963
|
|
|
1921
1964
|
// Cross-unit wiring: 設定を先に解決し、各Unit に注入する
|
|
1922
|
-
const resolvedConfig = command.startsWith("world:") ? undefined : await loadResolvedConfig();
|
|
1965
|
+
const resolvedConfig = command.startsWith("world:") ? undefined : await loadResolvedConfig(command);
|
|
1923
1966
|
|
|
1924
1967
|
try {
|
|
1925
1968
|
switch (command) {
|
|
@@ -2188,8 +2231,8 @@ async function main(): Promise<void> {
|
|
|
2188
2231
|
console.log(" • Q&A about phasegate concepts: invoke /phasegate-toolkit-guide");
|
|
2189
2232
|
console.log(" • Diagnose & tune phasegate.config.json: invoke /phasegate-config-doctor");
|
|
2190
2233
|
}
|
|
2191
|
-
|
|
2192
|
-
|
|
2234
|
+
await finishCliExit(hasStructuredInstallError(installResult) ? 1 : 0);
|
|
2235
|
+
return;
|
|
2193
2236
|
}
|
|
2194
2237
|
|
|
2195
2238
|
case "update-skills": {
|
|
@@ -2214,8 +2257,8 @@ async function main(): Promise<void> {
|
|
|
2214
2257
|
});
|
|
2215
2258
|
if (!json) console.log("phasegate update-skills is deprecated; running phasegate reconcile.");
|
|
2216
2259
|
console.log(result.stdout);
|
|
2217
|
-
|
|
2218
|
-
|
|
2260
|
+
await finishCliExit(result.exitCode);
|
|
2261
|
+
return;
|
|
2219
2262
|
}
|
|
2220
2263
|
|
|
2221
2264
|
case "doctor": {
|
|
@@ -2241,14 +2284,14 @@ async function main(): Promise<void> {
|
|
|
2241
2284
|
agent,
|
|
2242
2285
|
});
|
|
2243
2286
|
console.log(result.stdout);
|
|
2244
|
-
|
|
2245
|
-
|
|
2287
|
+
await finishCliExit(result.exitCode);
|
|
2288
|
+
return;
|
|
2246
2289
|
}
|
|
2247
2290
|
|
|
2248
2291
|
case "emit-agent-rules": {
|
|
2249
2292
|
console.log(emitAgentRulesBlock());
|
|
2250
|
-
|
|
2251
|
-
|
|
2293
|
+
await finishCliExit(0);
|
|
2294
|
+
return;
|
|
2252
2295
|
}
|
|
2253
2296
|
|
|
2254
2297
|
case "scaffold-wi": {
|
|
@@ -2274,8 +2317,8 @@ async function main(): Promise<void> {
|
|
|
2274
2317
|
inceptionRoot: parseFlag(args, "--root") ?? configuredPersonalRoot,
|
|
2275
2318
|
});
|
|
2276
2319
|
console.log(`Created ${descriptionPath}`);
|
|
2277
|
-
|
|
2278
|
-
|
|
2320
|
+
await finishCliExit(0);
|
|
2321
|
+
return;
|
|
2279
2322
|
}
|
|
2280
2323
|
|
|
2281
2324
|
case "install": {
|
|
@@ -2323,8 +2366,8 @@ async function main(): Promise<void> {
|
|
|
2323
2366
|
force: hasFlag(args, "--force"),
|
|
2324
2367
|
includeClaude,
|
|
2325
2368
|
includeCodex,
|
|
2326
|
-
includeHusky: !personal,
|
|
2327
|
-
includeCi: !personal,
|
|
2369
|
+
includeHusky: !personal && hasFlag(args, "--with-husky"),
|
|
2370
|
+
includeCi: !personal && hasFlag(args, "--with-ci"),
|
|
2328
2371
|
skillSet: skillSetRaw,
|
|
2329
2372
|
workflow: parseWorkflowMode(workflowRaw),
|
|
2330
2373
|
agent,
|
|
@@ -2332,8 +2375,8 @@ async function main(): Promise<void> {
|
|
|
2332
2375
|
json,
|
|
2333
2376
|
});
|
|
2334
2377
|
console.log(result.stdout);
|
|
2335
|
-
|
|
2336
|
-
|
|
2378
|
+
await finishCliExit(result.exitCode);
|
|
2379
|
+
return;
|
|
2337
2380
|
}
|
|
2338
2381
|
|
|
2339
2382
|
case "setup:agent": {
|
|
@@ -2415,8 +2458,8 @@ async function main(): Promise<void> {
|
|
|
2415
2458
|
console.log("Validation:");
|
|
2416
2459
|
for (const command of plan.validation) console.log(`- ${command}`);
|
|
2417
2460
|
}
|
|
2418
|
-
|
|
2419
|
-
|
|
2461
|
+
await finishCliExit(hasStructuredInstallError(installResult) ? 1 : 0);
|
|
2462
|
+
return;
|
|
2420
2463
|
}
|
|
2421
2464
|
|
|
2422
2465
|
case "config:plan": {
|
|
@@ -2446,7 +2489,8 @@ async function main(): Promise<void> {
|
|
|
2446
2489
|
for (const operation of applyResult.appliedOperations)
|
|
2447
2490
|
console.log(`- ${operation.op} ${operation.pointer}`);
|
|
2448
2491
|
}
|
|
2449
|
-
|
|
2492
|
+
await finishCliExit(0);
|
|
2493
|
+
return;
|
|
2450
2494
|
} catch (error) {
|
|
2451
2495
|
const message = error instanceof Error ? error.message : String(error);
|
|
2452
2496
|
if (json) {
|
|
@@ -2460,7 +2504,8 @@ async function main(): Promise<void> {
|
|
|
2460
2504
|
} else {
|
|
2461
2505
|
console.error(`Error: ${message}`);
|
|
2462
2506
|
}
|
|
2463
|
-
|
|
2507
|
+
await finishCliExit(1);
|
|
2508
|
+
return;
|
|
2464
2509
|
}
|
|
2465
2510
|
}
|
|
2466
2511
|
if (json) {
|
|
@@ -2474,8 +2519,8 @@ async function main(): Promise<void> {
|
|
|
2474
2519
|
console.log("Validation:");
|
|
2475
2520
|
for (const validation of plan.validations) console.log(`- ${validation}`);
|
|
2476
2521
|
}
|
|
2477
|
-
|
|
2478
|
-
|
|
2522
|
+
await finishCliExit(0);
|
|
2523
|
+
return;
|
|
2479
2524
|
}
|
|
2480
2525
|
|
|
2481
2526
|
case "session": {
|
|
@@ -2496,7 +2541,8 @@ async function main(): Promise<void> {
|
|
|
2496
2541
|
`Full Mode session started: ${session.workItemId} unit=${session.unit} expiresAt=${session.expiresAt}`,
|
|
2497
2542
|
);
|
|
2498
2543
|
}
|
|
2499
|
-
|
|
2544
|
+
await finishCliExit(0);
|
|
2545
|
+
return;
|
|
2500
2546
|
} catch (error) {
|
|
2501
2547
|
const message = error instanceof Error ? error.message : String(error);
|
|
2502
2548
|
if (json) {
|
|
@@ -2504,7 +2550,8 @@ async function main(): Promise<void> {
|
|
|
2504
2550
|
} else {
|
|
2505
2551
|
console.error(`Error: ${message}`);
|
|
2506
2552
|
}
|
|
2507
|
-
|
|
2553
|
+
await finishCliExit(2);
|
|
2554
|
+
return;
|
|
2508
2555
|
}
|
|
2509
2556
|
}
|
|
2510
2557
|
if (subcommand === "end") {
|
|
@@ -2517,7 +2564,8 @@ async function main(): Promise<void> {
|
|
|
2517
2564
|
} else {
|
|
2518
2565
|
console.log("No Full Mode session was active.");
|
|
2519
2566
|
}
|
|
2520
|
-
|
|
2567
|
+
await finishCliExit(0);
|
|
2568
|
+
return;
|
|
2521
2569
|
} catch (error) {
|
|
2522
2570
|
const message = error instanceof Error ? error.message : String(error);
|
|
2523
2571
|
if (json) {
|
|
@@ -2525,7 +2573,8 @@ async function main(): Promise<void> {
|
|
|
2525
2573
|
} else {
|
|
2526
2574
|
console.error(`Error: ${message}`);
|
|
2527
2575
|
}
|
|
2528
|
-
|
|
2576
|
+
await finishCliExit(2);
|
|
2577
|
+
return;
|
|
2529
2578
|
}
|
|
2530
2579
|
}
|
|
2531
2580
|
console.error("Error: session subcommand must be begin or end.");
|
|
@@ -2552,8 +2601,8 @@ async function main(): Promise<void> {
|
|
|
2552
2601
|
json,
|
|
2553
2602
|
});
|
|
2554
2603
|
console.log(result.stdout);
|
|
2555
|
-
|
|
2556
|
-
|
|
2604
|
+
await finishCliExit(result.exitCode);
|
|
2605
|
+
return;
|
|
2557
2606
|
}
|
|
2558
2607
|
|
|
2559
2608
|
case "reconcile": {
|
|
@@ -2577,8 +2626,8 @@ async function main(): Promise<void> {
|
|
|
2577
2626
|
json,
|
|
2578
2627
|
});
|
|
2579
2628
|
console.log(result.stdout);
|
|
2580
|
-
|
|
2581
|
-
|
|
2629
|
+
await finishCliExit(result.exitCode);
|
|
2630
|
+
return;
|
|
2582
2631
|
}
|
|
2583
2632
|
|
|
2584
2633
|
// ── config-foundation ──
|
|
@@ -2593,8 +2642,8 @@ async function main(): Promise<void> {
|
|
|
2593
2642
|
configPath,
|
|
2594
2643
|
});
|
|
2595
2644
|
console.log(result.output);
|
|
2596
|
-
|
|
2597
|
-
|
|
2645
|
+
await finishCliExit(result.exitCode);
|
|
2646
|
+
return;
|
|
2598
2647
|
}
|
|
2599
2648
|
|
|
2600
2649
|
case "disable-feature": {
|
|
@@ -2608,8 +2657,8 @@ async function main(): Promise<void> {
|
|
|
2608
2657
|
configPath,
|
|
2609
2658
|
});
|
|
2610
2659
|
console.log(result.output);
|
|
2611
|
-
|
|
2612
|
-
|
|
2660
|
+
await finishCliExit(result.exitCode);
|
|
2661
|
+
return;
|
|
2613
2662
|
}
|
|
2614
2663
|
|
|
2615
2664
|
case "list-features": {
|
|
@@ -2618,8 +2667,8 @@ async function main(): Promise<void> {
|
|
|
2618
2667
|
list: true,
|
|
2619
2668
|
});
|
|
2620
2669
|
console.log(result.output);
|
|
2621
|
-
|
|
2622
|
-
|
|
2670
|
+
await finishCliExit(result.exitCode);
|
|
2671
|
+
return;
|
|
2623
2672
|
}
|
|
2624
2673
|
|
|
2625
2674
|
case "migrate": {
|
|
@@ -2631,8 +2680,8 @@ async function main(): Promise<void> {
|
|
|
2631
2680
|
json,
|
|
2632
2681
|
});
|
|
2633
2682
|
console.log(result.text);
|
|
2634
|
-
|
|
2635
|
-
|
|
2683
|
+
await finishCliExit(result.exitCode);
|
|
2684
|
+
return;
|
|
2636
2685
|
}
|
|
2637
2686
|
const mod = createConfigFoundationModule();
|
|
2638
2687
|
const targetVersion = parseFlag(args, "--schema") ?? "v3";
|
|
@@ -2642,8 +2691,8 @@ async function main(): Promise<void> {
|
|
|
2642
2691
|
configPath,
|
|
2643
2692
|
});
|
|
2644
2693
|
console.log(result.output);
|
|
2645
|
-
|
|
2646
|
-
|
|
2694
|
+
await finishCliExit(result.exitCode);
|
|
2695
|
+
return;
|
|
2647
2696
|
}
|
|
2648
2697
|
|
|
2649
2698
|
// ── harness-error ──
|
|
@@ -2657,8 +2706,8 @@ async function main(): Promise<void> {
|
|
|
2657
2706
|
failOnError,
|
|
2658
2707
|
});
|
|
2659
2708
|
console.log(result.output);
|
|
2660
|
-
|
|
2661
|
-
|
|
2709
|
+
await finishCliExit(result.exitCode);
|
|
2710
|
+
return;
|
|
2662
2711
|
}
|
|
2663
2712
|
|
|
2664
2713
|
case "validate-fix": {
|
|
@@ -2672,8 +2721,8 @@ async function main(): Promise<void> {
|
|
|
2672
2721
|
format,
|
|
2673
2722
|
});
|
|
2674
2723
|
console.log(result.output);
|
|
2675
|
-
|
|
2676
|
-
|
|
2724
|
+
await finishCliExit(result.exitCode);
|
|
2725
|
+
return;
|
|
2677
2726
|
}
|
|
2678
2727
|
|
|
2679
2728
|
case "list-errors": {
|
|
@@ -2685,8 +2734,8 @@ async function main(): Promise<void> {
|
|
|
2685
2734
|
layer,
|
|
2686
2735
|
});
|
|
2687
2736
|
console.log(result.output);
|
|
2688
|
-
|
|
2689
|
-
|
|
2737
|
+
await finishCliExit(result.exitCode);
|
|
2738
|
+
return;
|
|
2690
2739
|
}
|
|
2691
2740
|
|
|
2692
2741
|
// ── traceability-model ──
|
|
@@ -2698,8 +2747,8 @@ async function main(): Promise<void> {
|
|
|
2698
2747
|
json,
|
|
2699
2748
|
});
|
|
2700
2749
|
console.log(result.text);
|
|
2701
|
-
|
|
2702
|
-
|
|
2750
|
+
await finishCliExit(result.exitCode);
|
|
2751
|
+
return;
|
|
2703
2752
|
}
|
|
2704
2753
|
|
|
2705
2754
|
case "work-items:status": {
|
|
@@ -2714,8 +2763,8 @@ async function main(): Promise<void> {
|
|
|
2714
2763
|
json,
|
|
2715
2764
|
});
|
|
2716
2765
|
console.log(result.text);
|
|
2717
|
-
|
|
2718
|
-
|
|
2766
|
+
await finishCliExit(result.exitCode);
|
|
2767
|
+
return;
|
|
2719
2768
|
}
|
|
2720
2769
|
|
|
2721
2770
|
// ── world-model ──
|
|
@@ -2791,8 +2840,8 @@ async function main(): Promise<void> {
|
|
|
2791
2840
|
json,
|
|
2792
2841
|
});
|
|
2793
2842
|
console.log(result.text);
|
|
2794
|
-
|
|
2795
|
-
|
|
2843
|
+
await finishCliExit(result.exitCode);
|
|
2844
|
+
return;
|
|
2796
2845
|
}
|
|
2797
2846
|
|
|
2798
2847
|
// ── adr-foundation ──
|
|
@@ -2807,8 +2856,8 @@ async function main(): Promise<void> {
|
|
|
2807
2856
|
json,
|
|
2808
2857
|
});
|
|
2809
2858
|
console.log(result.text);
|
|
2810
|
-
|
|
2811
|
-
|
|
2859
|
+
await finishCliExit(result.exitCode);
|
|
2860
|
+
return;
|
|
2812
2861
|
}
|
|
2813
2862
|
|
|
2814
2863
|
case "validate-adr": {
|
|
@@ -2821,8 +2870,8 @@ async function main(): Promise<void> {
|
|
|
2821
2870
|
json,
|
|
2822
2871
|
});
|
|
2823
2872
|
console.log(result.text);
|
|
2824
|
-
|
|
2825
|
-
|
|
2873
|
+
await finishCliExit(result.exitCode);
|
|
2874
|
+
return;
|
|
2826
2875
|
}
|
|
2827
2876
|
|
|
2828
2877
|
// ── biome-ast-engine ──
|
|
@@ -2832,8 +2881,8 @@ async function main(): Promise<void> {
|
|
|
2832
2881
|
const mod = createBiomeAstEngineModule(rootDir, { l1Config, architecture });
|
|
2833
2882
|
const result = await mod.harnessLintCommandHandler.execute(args.slice(1));
|
|
2834
2883
|
console.log(result.text);
|
|
2835
|
-
|
|
2836
|
-
|
|
2884
|
+
await finishCliExit(result.exitCode);
|
|
2885
|
+
return;
|
|
2837
2886
|
}
|
|
2838
2887
|
|
|
2839
2888
|
// ── validator-system ──
|
|
@@ -2860,8 +2909,8 @@ async function main(): Promise<void> {
|
|
|
2860
2909
|
if ((layer === "L2" || layer === "all") && format !== "ci") {
|
|
2861
2910
|
await printStoryReflectionValidationSummary(rootDir, unit);
|
|
2862
2911
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2912
|
+
await finishCliExit(result.exitCode);
|
|
2913
|
+
return;
|
|
2865
2914
|
}
|
|
2866
2915
|
|
|
2867
2916
|
// ── quick-mode / ci-check ──
|
|
@@ -2916,8 +2965,8 @@ async function main(): Promise<void> {
|
|
|
2916
2965
|
format,
|
|
2917
2966
|
failOnFullRequired,
|
|
2918
2967
|
});
|
|
2919
|
-
|
|
2920
|
-
|
|
2968
|
+
await finishCliExit(result.exitCode);
|
|
2969
|
+
return;
|
|
2921
2970
|
}
|
|
2922
2971
|
|
|
2923
2972
|
// ── harness-api ──
|
|
@@ -3077,7 +3126,16 @@ async function main(): Promise<void> {
|
|
|
3077
3126
|
}
|
|
3078
3127
|
const { createAttestationModule } = await import("./attestation/index.js");
|
|
3079
3128
|
const pkgVersion = await getHarnessVersion(harnessRoot);
|
|
3080
|
-
const
|
|
3129
|
+
const worldModule = createWorldModelModule({
|
|
3130
|
+
rootDir,
|
|
3131
|
+
resolvedConfig: await loadWorldResolvedConfig(),
|
|
3132
|
+
});
|
|
3133
|
+
const mod = createAttestationModule(rootDir, {
|
|
3134
|
+
pkgVersion,
|
|
3135
|
+
worldSnapshotRootProvider: {
|
|
3136
|
+
getWorldSnapshotRoot: async () => (await worldModule.worldSnapshotRootFacade.read()).worldSnapshotRoot,
|
|
3137
|
+
},
|
|
3138
|
+
});
|
|
3081
3139
|
const result = await mod.attestHandler.handle({
|
|
3082
3140
|
out: parseFlag(args, "--out") ?? ".harness/attestation.json",
|
|
3083
3141
|
requirePass: hasFlag(args, "--require-pass"),
|
|
@@ -3085,8 +3143,8 @@ async function main(): Promise<void> {
|
|
|
3085
3143
|
mode: parseFlag(args, "--mode"),
|
|
3086
3144
|
});
|
|
3087
3145
|
console.log(result.output);
|
|
3088
|
-
|
|
3089
|
-
|
|
3146
|
+
await finishCliExit(result.exitCode);
|
|
3147
|
+
return;
|
|
3090
3148
|
}
|
|
3091
3149
|
|
|
3092
3150
|
case "phasegate:verify-attestation": {
|
|
@@ -3103,8 +3161,8 @@ async function main(): Promise<void> {
|
|
|
3103
3161
|
emitJson: json,
|
|
3104
3162
|
});
|
|
3105
3163
|
console.log(result.output);
|
|
3106
|
-
|
|
3107
|
-
|
|
3164
|
+
await finishCliExit(result.exitCode);
|
|
3165
|
+
return;
|
|
3108
3166
|
}
|
|
3109
3167
|
|
|
3110
3168
|
// ── ci-governance ──
|
|
@@ -3127,7 +3185,8 @@ Options:
|
|
|
3127
3185
|
Examples:
|
|
3128
3186
|
phasegate ci:generate-template --type aidlc-gate
|
|
3129
3187
|
phasegate ci:generate-template --preset strict --type pre-commit --render`);
|
|
3130
|
-
|
|
3188
|
+
await finishCliExit(0);
|
|
3189
|
+
return;
|
|
3131
3190
|
}
|
|
3132
3191
|
const flagError = validateKnownFlags(args.slice(1), ["--preset", "--type", "--render", "--json", "--help"]);
|
|
3133
3192
|
if (flagError !== null) {
|
|
@@ -3141,8 +3200,8 @@ Examples:
|
|
|
3141
3200
|
const format = json ? "json" : "human";
|
|
3142
3201
|
const result = await mod.generateCiTemplateHandler.handle({ presetId, templateType, render, format });
|
|
3143
3202
|
console.log(result.output);
|
|
3144
|
-
|
|
3145
|
-
|
|
3203
|
+
await finishCliExit(result.exitCode);
|
|
3204
|
+
return;
|
|
3146
3205
|
}
|
|
3147
3206
|
|
|
3148
3207
|
case "ci:migrate-agents-md": {
|
|
@@ -3152,8 +3211,8 @@ Examples:
|
|
|
3152
3211
|
const format = json ? "json" : "human";
|
|
3153
3212
|
const result = await mod.migrateAgentsMdHandler.handle({ dryRun, validateOnly, format });
|
|
3154
3213
|
console.log(result.output);
|
|
3155
|
-
|
|
3156
|
-
|
|
3214
|
+
await finishCliExit(result.exitCode);
|
|
3215
|
+
return;
|
|
3157
3216
|
}
|
|
3158
3217
|
|
|
3159
3218
|
case "ci:auto-refresh-agent-context": {
|
|
@@ -3163,8 +3222,8 @@ Examples:
|
|
|
3163
3222
|
const format = json ? "json" : "human";
|
|
3164
3223
|
const result = await mod.refreshAgentContextHandler.handle({ dryRun, apply, format });
|
|
3165
3224
|
console.log(result.output);
|
|
3166
|
-
|
|
3167
|
-
|
|
3225
|
+
await finishCliExit(result.exitCode);
|
|
3226
|
+
return;
|
|
3168
3227
|
}
|
|
3169
3228
|
|
|
3170
3229
|
case "refresh-claude-md": {
|
|
@@ -3174,8 +3233,8 @@ Examples:
|
|
|
3174
3233
|
const format = json ? "json" : "human";
|
|
3175
3234
|
const result = await mod.refreshClaudeMdHandler.handle({ dryRun, apply, format });
|
|
3176
3235
|
console.log(result.output);
|
|
3177
|
-
|
|
3178
|
-
|
|
3236
|
+
await finishCliExit(result.exitCode);
|
|
3237
|
+
return;
|
|
3179
3238
|
}
|
|
3180
3239
|
|
|
3181
3240
|
case "p2:check-agent-context": {
|
|
@@ -3185,8 +3244,8 @@ Examples:
|
|
|
3185
3244
|
const format = json ? "json" : "human";
|
|
3186
3245
|
const result = await mod.checkAgentContextHandler.handle({ thresholdDays, format });
|
|
3187
3246
|
console.log(result.output);
|
|
3188
|
-
|
|
3189
|
-
|
|
3247
|
+
await finishCliExit(result.exitCode);
|
|
3248
|
+
return;
|
|
3190
3249
|
}
|
|
3191
3250
|
|
|
3192
3251
|
case "ci:check-repetition": {
|
|
@@ -3196,8 +3255,8 @@ Examples:
|
|
|
3196
3255
|
const format = json ? "json" : "human";
|
|
3197
3256
|
const result = await mod.checkRepetitionHandler.handle({ errorCode, reset, format });
|
|
3198
3257
|
console.log(result.output);
|
|
3199
|
-
|
|
3200
|
-
|
|
3258
|
+
await finishCliExit(result.exitCode);
|
|
3259
|
+
return;
|
|
3201
3260
|
}
|
|
3202
3261
|
|
|
3203
3262
|
case "baseline": {
|
|
@@ -3219,8 +3278,8 @@ Examples:
|
|
|
3219
3278
|
format,
|
|
3220
3279
|
});
|
|
3221
3280
|
console.log(result.output);
|
|
3222
|
-
|
|
3223
|
-
|
|
3281
|
+
await finishCliExit(result.exitCode);
|
|
3282
|
+
return;
|
|
3224
3283
|
}
|
|
3225
3284
|
|
|
3226
3285
|
case "scaffold-design": {
|
|
@@ -3240,8 +3299,8 @@ Examples:
|
|
|
3240
3299
|
format,
|
|
3241
3300
|
});
|
|
3242
3301
|
console.log(result.output);
|
|
3243
|
-
|
|
3244
|
-
|
|
3302
|
+
await finishCliExit(result.exitCode);
|
|
3303
|
+
return;
|
|
3245
3304
|
}
|
|
3246
3305
|
|
|
3247
3306
|
case "integrity:pin": {
|
|
@@ -3250,8 +3309,8 @@ Examples:
|
|
|
3250
3309
|
const format = json ? "json" : "human";
|
|
3251
3310
|
const result = await mod.integrityHandler.pin({ dryRun, format });
|
|
3252
3311
|
console.log(result.output);
|
|
3253
|
-
|
|
3254
|
-
|
|
3312
|
+
await finishCliExit(result.exitCode);
|
|
3313
|
+
return;
|
|
3255
3314
|
}
|
|
3256
3315
|
|
|
3257
3316
|
case "integrity:verify": {
|
|
@@ -3259,8 +3318,8 @@ Examples:
|
|
|
3259
3318
|
const format = json ? "json" : "human";
|
|
3260
3319
|
const result = await mod.integrityHandler.verify({ format });
|
|
3261
3320
|
console.log(result.output);
|
|
3262
|
-
|
|
3263
|
-
|
|
3321
|
+
await finishCliExit(result.exitCode);
|
|
3322
|
+
return;
|
|
3264
3323
|
}
|
|
3265
3324
|
|
|
3266
3325
|
// ── skill-quality ──
|
|
@@ -3275,8 +3334,8 @@ Examples:
|
|
|
3275
3334
|
const passed = hasFlag(args, "--passed");
|
|
3276
3335
|
const result = await mod.executeTddCycleHandler.handle({ unit, storyId, description, phase, passed });
|
|
3277
3336
|
console.log(result.message);
|
|
3278
|
-
|
|
3279
|
-
|
|
3337
|
+
await finishCliExit(result.exitCode);
|
|
3338
|
+
return;
|
|
3280
3339
|
}
|
|
3281
3340
|
|
|
3282
3341
|
case "skill:check-coverage": {
|
|
@@ -3285,8 +3344,8 @@ Examples:
|
|
|
3285
3344
|
const format = json ? "json" : "human";
|
|
3286
3345
|
const result = await mod.checkCoverageHandler.handle({ storyId, format });
|
|
3287
3346
|
console.log(result.message);
|
|
3288
|
-
|
|
3289
|
-
|
|
3347
|
+
await finishCliExit(result.exitCode);
|
|
3348
|
+
return;
|
|
3290
3349
|
}
|
|
3291
3350
|
|
|
3292
3351
|
case "skill:collect-lessons": {
|
|
@@ -3297,8 +3356,8 @@ Examples:
|
|
|
3297
3356
|
const writeArtifact = hasFlag(args, "--write-artifact");
|
|
3298
3357
|
const result = await mod.collectLessonsHandler.handle({ storyId, sources, writeArtifact });
|
|
3299
3358
|
console.log(result.message);
|
|
3300
|
-
|
|
3301
|
-
|
|
3359
|
+
await finishCliExit(result.exitCode);
|
|
3360
|
+
return;
|
|
3302
3361
|
}
|
|
3303
3362
|
|
|
3304
3363
|
case "skill:apply-cascade-update": {
|
|
@@ -3307,8 +3366,8 @@ Examples:
|
|
|
3307
3366
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3308
3367
|
const result = await mod.applyCascadeUpdateHandler.handle({ storyId, dryRun, format: json ? "json" : "human" });
|
|
3309
3368
|
console.log(result.message);
|
|
3310
|
-
|
|
3311
|
-
|
|
3369
|
+
await finishCliExit(result.exitCode);
|
|
3370
|
+
return;
|
|
3312
3371
|
}
|
|
3313
3372
|
|
|
3314
3373
|
case "skill:validate-structure": {
|
|
@@ -3317,8 +3376,8 @@ Examples:
|
|
|
3317
3376
|
const format = json ? "json" : "human";
|
|
3318
3377
|
const result = await mod.validateSkillStructureHandler.handle({ skillFile, format });
|
|
3319
3378
|
console.log(result.message);
|
|
3320
|
-
|
|
3321
|
-
|
|
3379
|
+
await finishCliExit(result.exitCode);
|
|
3380
|
+
return;
|
|
3322
3381
|
}
|
|
3323
3382
|
|
|
3324
3383
|
// ── regression-suite ──
|
|
@@ -3329,8 +3388,8 @@ Examples:
|
|
|
3329
3388
|
? JSON.stringify(result, null, 2)
|
|
3330
3389
|
: `K-Requirements: ${result.passedCount}/${result.totalCount} passed`;
|
|
3331
3390
|
console.log(output);
|
|
3332
|
-
|
|
3333
|
-
|
|
3391
|
+
await finishCliExit(result.failedCount > 0 ? 1 : 0);
|
|
3392
|
+
return;
|
|
3334
3393
|
}
|
|
3335
3394
|
|
|
3336
3395
|
case "regression:run-gng-gate": {
|
|
@@ -3340,8 +3399,8 @@ Examples:
|
|
|
3340
3399
|
? JSON.stringify(result, null, 2)
|
|
3341
3400
|
: `GnG Gate: ${result.passedCount}/${result.totalCount} passed`;
|
|
3342
3401
|
console.log(output);
|
|
3343
|
-
|
|
3344
|
-
|
|
3402
|
+
await finishCliExit(result.failedCount > 0 ? 1 : 0);
|
|
3403
|
+
return;
|
|
3345
3404
|
}
|
|
3346
3405
|
|
|
3347
3406
|
case "regression:run-agent-guard": {
|
|
@@ -3351,8 +3410,8 @@ Examples:
|
|
|
3351
3410
|
? JSON.stringify(result, null, 2)
|
|
3352
3411
|
: `Agent Independence: ${result.passedCount}/${result.totalCount} passed`;
|
|
3353
3412
|
console.log(output);
|
|
3354
|
-
|
|
3355
|
-
|
|
3413
|
+
await finishCliExit(result.failedCount > 0 ? 1 : 0);
|
|
3414
|
+
return;
|
|
3356
3415
|
}
|
|
3357
3416
|
|
|
3358
3417
|
case "regression:run-k14-k15": {
|
|
@@ -3362,8 +3421,8 @@ Examples:
|
|
|
3362
3421
|
? JSON.stringify(result, null, 2)
|
|
3363
3422
|
: `K14/K15: ${result.passedCount}/${result.totalCount} passed`;
|
|
3364
3423
|
console.log(output);
|
|
3365
|
-
|
|
3366
|
-
|
|
3424
|
+
await finishCliExit(result.failedCount > 0 ? 1 : 0);
|
|
3425
|
+
return;
|
|
3367
3426
|
}
|
|
3368
3427
|
|
|
3369
3428
|
case "regression:configure-ci-gate": {
|
|
@@ -3379,8 +3438,8 @@ Examples:
|
|
|
3379
3438
|
? JSON.stringify(result, null, 2)
|
|
3380
3439
|
: `CI gate configured: suites=${result.requiredSuiteIds.join(",")}, threshold=${result.coverageThreshold}%`;
|
|
3381
3440
|
console.log(output);
|
|
3382
|
-
|
|
3383
|
-
|
|
3441
|
+
await finishCliExit(0);
|
|
3442
|
+
return;
|
|
3384
3443
|
}
|
|
3385
3444
|
|
|
3386
3445
|
case "regression:analyze-migration": {
|
|
@@ -3391,8 +3450,8 @@ Examples:
|
|
|
3391
3450
|
? JSON.stringify(result, null, 2)
|
|
3392
3451
|
: `Migration analysis: total=${result.totalCount}, migrated=${result.migratedCount}, modified=${result.modifiedCount}, skipped=${result.skippedCount}`;
|
|
3393
3452
|
console.log(output);
|
|
3394
|
-
|
|
3395
|
-
|
|
3453
|
+
await finishCliExit(0);
|
|
3454
|
+
return;
|
|
3396
3455
|
}
|
|
3397
3456
|
|
|
3398
3457
|
case "regression:migrate-v0-tests": {
|
|
@@ -3403,8 +3462,8 @@ Examples:
|
|
|
3403
3462
|
? JSON.stringify(result, null, 2)
|
|
3404
3463
|
: `Migration: total=${result.totalCount}, migrated=${result.migratedCount}, modified=${result.modifiedCount}, skipped=${result.skippedCount}`;
|
|
3405
3464
|
console.log(output);
|
|
3406
|
-
|
|
3407
|
-
|
|
3465
|
+
await finishCliExit(0);
|
|
3466
|
+
return;
|
|
3408
3467
|
}
|
|
3409
3468
|
|
|
3410
3469
|
// ── phase2-extensions ──
|
|
@@ -3413,8 +3472,8 @@ Examples:
|
|
|
3413
3472
|
const p2args = args.slice(1);
|
|
3414
3473
|
const result = await mod.checkFreshnessHandler.handle(p2args);
|
|
3415
3474
|
console.log(result.stdout);
|
|
3416
|
-
|
|
3417
|
-
|
|
3475
|
+
await finishCliExit(result.exitCode);
|
|
3476
|
+
return;
|
|
3418
3477
|
}
|
|
3419
3478
|
|
|
3420
3479
|
case "p2:validate-pointers": {
|
|
@@ -3422,8 +3481,8 @@ Examples:
|
|
|
3422
3481
|
const p2args = args.slice(1);
|
|
3423
3482
|
const result = await mod.validatePointersHandler.handle(p2args);
|
|
3424
3483
|
console.log(result.stdout);
|
|
3425
|
-
|
|
3426
|
-
|
|
3484
|
+
await finishCliExit(result.exitCode);
|
|
3485
|
+
return;
|
|
3427
3486
|
}
|
|
3428
3487
|
|
|
3429
3488
|
case "p2:generate-e2e-template": {
|
|
@@ -3431,8 +3490,8 @@ Examples:
|
|
|
3431
3490
|
const p2args = args.slice(1);
|
|
3432
3491
|
const result = await mod.generateE2ETemplateHandler.handle(p2args);
|
|
3433
3492
|
console.log(result.stdout);
|
|
3434
|
-
|
|
3435
|
-
|
|
3493
|
+
await finishCliExit(result.exitCode);
|
|
3494
|
+
return;
|
|
3436
3495
|
}
|
|
3437
3496
|
|
|
3438
3497
|
case "p2:check-initial-creation": {
|
|
@@ -3440,8 +3499,8 @@ Examples:
|
|
|
3440
3499
|
const p2args = args.slice(1);
|
|
3441
3500
|
const result = await mod.checkInitialCreationExpirationHandler.handle(p2args);
|
|
3442
3501
|
console.log(result.stdout);
|
|
3443
|
-
|
|
3444
|
-
|
|
3502
|
+
await finishCliExit(result.exitCode);
|
|
3503
|
+
return;
|
|
3445
3504
|
}
|
|
3446
3505
|
|
|
3447
3506
|
// ── agent integration / hooks ──
|
|
@@ -3500,7 +3559,8 @@ Examples:
|
|
|
3500
3559
|
case "delegate-sonnet": {
|
|
3501
3560
|
if (hasFlag(args, "--help") || hasFlag(args, "-h")) {
|
|
3502
3561
|
printSubcommandHelp("delegate-sonnet");
|
|
3503
|
-
|
|
3562
|
+
await finishCliExit(0);
|
|
3563
|
+
return;
|
|
3504
3564
|
}
|
|
3505
3565
|
if (!hasFlag(args, "--dry-run") && (await isModelDelegationDisabled(rootDir))) {
|
|
3506
3566
|
console.error(
|
|
@@ -3509,7 +3569,8 @@ Examples:
|
|
|
3509
3569
|
message: "phasegate delegate-sonnet is disabled by modelRouting.delegation=none",
|
|
3510
3570
|
}),
|
|
3511
3571
|
);
|
|
3512
|
-
|
|
3572
|
+
await finishCliExit(1);
|
|
3573
|
+
return;
|
|
3513
3574
|
}
|
|
3514
3575
|
const { spawn } = await import("node:child_process");
|
|
3515
3576
|
const scriptPath = join(harnessRoot, "scripts/delegate-sonnet.sh");
|
|
@@ -3559,7 +3620,8 @@ Examples:
|
|
|
3559
3620
|
}
|
|
3560
3621
|
console.log("");
|
|
3561
3622
|
}
|
|
3562
|
-
|
|
3623
|
+
await finishCliExit(0);
|
|
3624
|
+
return;
|
|
3563
3625
|
}
|
|
3564
3626
|
|
|
3565
3627
|
if (subCommand === "info") {
|
|
@@ -3573,7 +3635,8 @@ Examples:
|
|
|
3573
3635
|
try {
|
|
3574
3636
|
const content = await fs.readFile(skillMdPath, "utf-8");
|
|
3575
3637
|
console.log(content);
|
|
3576
|
-
|
|
3638
|
+
await finishCliExit(0);
|
|
3639
|
+
return;
|
|
3577
3640
|
} catch {
|
|
3578
3641
|
console.error(`Skill not found: ${skillName}`);
|
|
3579
3642
|
console.error(`Expected: ${skillMdPath}`);
|
|
@@ -3589,12 +3652,13 @@ Examples:
|
|
|
3589
3652
|
default:
|
|
3590
3653
|
console.error(`Unknown command: ${command}`);
|
|
3591
3654
|
printUsage();
|
|
3592
|
-
|
|
3655
|
+
await finishCliExit(2);
|
|
3656
|
+
return;
|
|
3593
3657
|
}
|
|
3594
3658
|
} catch (error: unknown) {
|
|
3595
3659
|
const message = error instanceof Error ? error.message : "Unknown error occurred";
|
|
3596
3660
|
console.error(`Fatal: ${message}`);
|
|
3597
|
-
|
|
3661
|
+
await finishCliExit(2);
|
|
3598
3662
|
}
|
|
3599
3663
|
}
|
|
3600
3664
|
|