phasegate 0.340.0 → 0.341.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 +12 -0
- package/docs/folder_management_rules.md +10 -1
- package/docs/guide/cli-reference.md +23 -3
- package/docs/guide/configuration.md +28 -2
- package/docs/guide/hooks-integration.md +7 -1
- package/docs/guide/skills-overview.md +3 -0
- package/package.json +2 -1
- package/scripts/harness/agent-integration/application/usecases/handle-post-tool-use-usecase.ts +4 -0
- package/scripts/harness/agent-integration/application/usecases/handle-pre-tool-use-usecase.ts +36 -1
- package/scripts/harness/agent-integration/application/usecases/handle-stop-usecase.ts +3 -9
- package/scripts/harness/agent-integration/domain/ports/story-reflection-query-port.ts +2 -0
- package/scripts/harness/agent-integration/domain/services/hook-to-cli-translator.ts +8 -5
- package/scripts/harness/agent-integration/domain/value-objects/hook-translation-result.ts +1 -1
- package/scripts/harness/agent-integration/domain/value-objects/story-reflection-query-result.ts +10 -2
- package/scripts/harness/agent-integration/domain/value-objects/write-target-scope.ts +12 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/child-process-cli-executor-adapter.ts +64 -13
- package/scripts/harness/agent-integration/infrastructure/adapters/file-system-story-reflection-query-adapter.ts +108 -2
- package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +8 -6
- package/scripts/harness/agent-integration/presentation/hook-skip-event-recorder.ts +3 -0
- package/scripts/harness/agent-integration/presentation/post-tool-use-feedback.ts +39 -0
- package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +20 -27
- package/scripts/harness/agent-integration/presentation/pre-tool-use-hook.ts +3 -0
- package/scripts/harness/agent-integration/presentation/stop-hook.ts +1 -3
- package/scripts/harness/biome-ast-engine/infrastructure/adapters/biome-cli-executor-adapter.ts +21 -1
- package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +5 -0
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +15 -0
- package/scripts/harness/config-foundation/infrastructure/validators/ajv-config-schema-validator.ts +6 -3
- package/scripts/harness/harness-api/domain/ports/biome-lint-port.ts +2 -1
- package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +12 -1
- package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +10 -2
- package/scripts/harness/installation/application/bundled-skill-selection.ts +28 -2
- package/scripts/harness/installation/application/checks/check-utils.ts +2 -2
- package/scripts/harness/installation/application/usecases/run-install.ts +5 -5
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +62 -21
- package/scripts/harness/installation/presentation/cli/install-handler.ts +2 -1
- package/scripts/harness/main.ts +128 -90
- package/scripts/harness/phase-dependency-model/domain/services/story-reflection-checker.ts +48 -5
- package/scripts/harness/phase-dependency-model/domain/services/work-item-reflection-scope-resolver.ts +64 -0
- package/scripts/harness/phase-dependency-model/domain/values/story-reflection-mapping.ts +8 -2
- package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.ts +6 -1
- package/scripts/harness/phase-dependency-model/infrastructure/filesystem/file-system-work-item-dependency-catalog.ts +73 -0
- package/scripts/harness/quick-mode/application/dto/change-category-classification-contract.ts +4 -0
- package/scripts/harness/quick-mode/application/ports/change-risk-advisory-port.ts +16 -0
- package/scripts/harness/quick-mode/composition-root.ts +5 -1
- package/scripts/harness/quick-mode/infrastructure/adapters/snapshot-risk-advisory-adapter.ts +118 -0
- package/scripts/harness/quick-mode/presentation/formatters/change-category-formatter.ts +7 -0
- package/scripts/harness/quick-mode/presentation/handlers/check-change-category-handler.ts +12 -1
- package/scripts/harness/setup/skill-deployer.ts +3 -45
- package/scripts/harness/skill-quality/application/dto/run-plan-checker-loop-output.ts +1 -0
- package/scripts/harness/skill-quality/application/usecases/apply-cascade-update-usecase.ts +9 -4
- package/scripts/harness/skill-quality/application/usecases/execute-tdd-cycle-usecase.ts +2 -1
- package/scripts/harness/skill-quality/application/usecases/run-plan-checker-loop-usecase.ts +8 -0
- package/scripts/harness/skill-quality/composition-root.ts +14 -7
- package/scripts/harness/skill-quality/domain/ports/plan-check-executor-port.ts +2 -0
- package/scripts/harness/skill-quality/domain/value-objects/cascade-update-target.ts +15 -1
- package/scripts/harness/skill-quality/infrastructure/adapters/l1-biome-validator-adapter.ts +9 -1
- package/scripts/harness/skill-quality/infrastructure/adapters/l2-validator-system-adapter.ts +18 -2
- package/scripts/harness/skill-quality/presentation/handlers/apply-cascade-update-handler.ts +8 -2
- package/scripts/harness/skill-quality/presentation/handlers/execute-tdd-cycle-handler.ts +4 -3
- package/scripts/harness/skill-quality/presentation/handlers/run-plan-checker-loop-handler.ts +11 -4
- package/scripts/harness/traceability-model/infrastructure/parsers/work-item-frontmatter-parser.ts +41 -0
- package/skills/README.md +7 -0
- package/skills/cascade-updater/SKILL.md +37 -109
- package/skills/cascade-updater/references//345/261/244/345/210/245/345/210/244/345/256/232/343/202/254/343/202/244/343/203/211.md +5 -3
- package/skills/release-publisher/SKILL.md +3 -1
- package/skills/skill-creator/SKILL.md +8 -9
package/scripts/harness/main.ts
CHANGED
|
@@ -45,9 +45,8 @@ import {
|
|
|
45
45
|
} from "node:fs/promises";
|
|
46
46
|
import { basename, dirname, join, resolve } from "node:path";
|
|
47
47
|
import { fileURLToPath } from "node:url";
|
|
48
|
-
import { createAdrFoundationModule } from "./adr-foundation/composition-root.js";
|
|
49
48
|
import { createBiomeAstEngineModule } from "./biome-ast-engine/composition-root.js";
|
|
50
|
-
import {
|
|
49
|
+
import type { CiGovernanceDocPaths } from "./ci-governance/composition-root.js";
|
|
51
50
|
import { toPhaseConfigSection } from "./config-foundation/application/mappers/phase-config-section-mapper.js";
|
|
52
51
|
import { toValidatorSystemConfig } from "./config-foundation/application/mappers/validator-system-config-mapper.js";
|
|
53
52
|
import { toWorldModelConfig } from "./config-foundation/application/mappers/world-model-config-mapper.js";
|
|
@@ -59,16 +58,13 @@ import {
|
|
|
59
58
|
ConfigPersistenceError,
|
|
60
59
|
} from "./config-foundation/infrastructure/repositories/file-system-config-repository.js";
|
|
61
60
|
import { createHarnessApiModule } from "./harness-api/composition-root.js";
|
|
62
|
-
import { createHarnessErrorModule } from "./harness-error/composition-root.js";
|
|
63
61
|
import {
|
|
64
62
|
type DeployManifestRecord,
|
|
65
63
|
SkillDeployerManifestBuilder,
|
|
66
64
|
} from "./installation/application/wrappers/skill-deployer-manifest-builder.js";
|
|
67
|
-
import { createInstallationModule } from "./installation/composition-root.js";
|
|
68
65
|
import { type AgentTarget, isAgentTarget } from "./installation/domain/agent-target.js";
|
|
69
66
|
import { NodeCryptoHashAdapter } from "./installation/infrastructure/adapters/node-crypto-hash-adapter.js";
|
|
70
67
|
import { CheckStoryReflectionUseCase } from "./phase-dependency-model/application/usecases/check-story-reflection-usecase.js";
|
|
71
|
-
import { createPhaseDependencyModelModule } from "./phase-dependency-model/composition-root.js";
|
|
72
68
|
import { StoryReflectionChecker } from "./phase-dependency-model/domain/services/story-reflection-checker.js";
|
|
73
69
|
import { StoryReflectionResult } from "./phase-dependency-model/domain/values/story-reflection-result.js";
|
|
74
70
|
import {
|
|
@@ -77,10 +73,9 @@ import {
|
|
|
77
73
|
} from "./phase-dependency-model/infrastructure/config/harness-config-phase-config-provider.js";
|
|
78
74
|
import { FileSystemStoryReflectionAdapter } from "./phase-dependency-model/infrastructure/filesystem/file-system-story-reflection-adapter.js";
|
|
79
75
|
import { StoryReflectionStatusPresenter } from "./phase-dependency-model/presentation/cli/story-reflection-status-presenter.js";
|
|
80
|
-
import {
|
|
81
|
-
import { createQuickModeCompositionRoot, type QuickModeCompositionRootOptions } from "./quick-mode/composition-root.js";
|
|
82
|
-
import { buildRegressionSuite } from "./regression-suite/composition-root.js";
|
|
76
|
+
import type { QuickModeCompositionRootOptions } from "./quick-mode/composition-root.js";
|
|
83
77
|
import type { SkillSet } from "./setup/skill-deployer.js";
|
|
78
|
+
import { isSkillSet } from "./installation/application/bundled-skill-selection.js";
|
|
84
79
|
import {
|
|
85
80
|
deployAgentSkillLinks,
|
|
86
81
|
deployCiWorkflows,
|
|
@@ -97,11 +92,7 @@ import {
|
|
|
97
92
|
initHarnessConfig,
|
|
98
93
|
listAvailableSkillNames,
|
|
99
94
|
} from "./setup/skill-deployer.js";
|
|
100
|
-
import {
|
|
101
|
-
import { createTraceabilityModelModule } from "./traceability-model/composition-root.js";
|
|
102
|
-
import { createValidatorSystemModule } from "./validator-system/composition-root.js";
|
|
103
|
-
import {
|
|
104
|
-
createWorldModelModule,
|
|
95
|
+
import type {
|
|
105
96
|
WorldDeriveCommandHandler,
|
|
106
97
|
WorldInspectCommandHandler,
|
|
107
98
|
WorldPinCommandHandler,
|
|
@@ -210,7 +201,7 @@ Usage: phasegate <command> [options]
|
|
|
210
201
|
Setup:
|
|
211
202
|
init Initialize project: deploy skills + design docs + phasegate.config.json
|
|
212
203
|
(--name <project-name>, --preset <full|standard|minimal|custom>,
|
|
213
|
-
--skills <core|all>, --agent <claude|codex|both|grok|antigravity|all>, --workflow <standard|strict>,
|
|
204
|
+
--skills <core|consumer|all>, --agent <claude|codex|both|grok|antigravity|all>, --workflow <standard|strict>,
|
|
214
205
|
--language <language>, --with-husky, --with-ci, --yes)
|
|
215
206
|
update-skills Alias for reconcile (kept for compatibility)
|
|
216
207
|
doctor Diagnose silent installation failures (--json, --strict, --personal, --agent <claude|codex|both|grok|antigravity|all>, --report-out <path>)
|
|
@@ -283,7 +274,7 @@ Gate semantics:
|
|
|
283
274
|
session begin Start a Full Mode session (--mode full, --unit, --work-item, --reason, --duration)
|
|
284
275
|
session end End a Full Mode session (--work-item)
|
|
285
276
|
|
|
286
|
-
skill:execute-tdd-cycle Execute TDD cycle (--unit, --story, --desc, --phase RED|GREEN|REFACTOR, --passed)
|
|
277
|
+
skill:execute-tdd-cycle Execute TDD cycle (--unit, --story, --desc, --phase RED|GREEN|REFACTOR, --passed, optional --configured-validation)
|
|
287
278
|
skill:check-coverage Check coverage (--story <storyId>, --json)
|
|
288
279
|
skill:collect-lessons Collect lessons (--story <storyId>, --sources <paths>, --write-artifact)
|
|
289
280
|
skill:apply-cascade-update Apply cascade update (--story <storyId>, --dry-run)
|
|
@@ -495,7 +486,7 @@ async function saveInstallationManifest(
|
|
|
495
486
|
): Promise<void> {
|
|
496
487
|
const filteredRecords = (await Promise.all(records)).filter((record) => record !== null);
|
|
497
488
|
if (filteredRecords.length === 0) return;
|
|
498
|
-
const mod = createInstallationModule();
|
|
489
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
499
490
|
const builder = new SkillDeployerManifestBuilder(new NodeCryptoHashAdapter());
|
|
500
491
|
await mod.manifestRepository.save(rootDir, builder.build(version, filteredRecords));
|
|
501
492
|
}
|
|
@@ -707,7 +698,7 @@ Initialize phasegate in the current project: deploy skills + design docs + phase
|
|
|
707
698
|
Options:
|
|
708
699
|
--name <project-name> Project name (default: "my-project")
|
|
709
700
|
--preset <full|standard|minimal|custom> Phase dependency preset (default: "standard")
|
|
710
|
-
--skills <core|all>
|
|
701
|
+
--skills <core|consumer|all> Skill set to deploy (default: "all"; consumer excludes maintainer skills)
|
|
711
702
|
--agent <claude|codex|both|grok|antigravity|all> Agent integration target (default: "claude")
|
|
712
703
|
--workflow <standard|strict> Workflow enforcement defaults (default: "standard")
|
|
713
704
|
--language <language> Project language declaration (default: "typescript")
|
|
@@ -735,7 +726,7 @@ Options:
|
|
|
735
726
|
--apply Write merge results and manifest
|
|
736
727
|
--force Force ai-assisted/manual targets after backing up existing files
|
|
737
728
|
--agent <claude|codex|both|grok|antigravity|all> Agent context and hook targets (default: both)
|
|
738
|
-
--skills <core|all>
|
|
729
|
+
--skills <core|consumer|all> Skill set to deploy (default: all; consumer excludes maintainer skills)
|
|
739
730
|
--workflow <standard|strict> Rendered agent context workflow mode (default: standard)
|
|
740
731
|
--with-husky Include Husky hook targets (opt-in; omitted by default)
|
|
741
732
|
--with-ci Include GitHub Actions target (opt-in; omitted by default)
|
|
@@ -902,6 +893,7 @@ Options:
|
|
|
902
893
|
--paths <csv> Comma-separated file paths to classify.
|
|
903
894
|
--format <human|json> Output format. Default: human.
|
|
904
895
|
--fail-on-full-required Exit with code 1 when Full Mode is required.
|
|
896
|
+
--risk-snapshots <json> Optional before/after snapshots for advisory review; does not change gates.
|
|
905
897
|
--help, -h Show this help.
|
|
906
898
|
|
|
907
899
|
Examples:
|
|
@@ -1567,11 +1559,7 @@ function isPlainRecord(value: unknown): value is Record<string, unknown> {
|
|
|
1567
1559
|
}
|
|
1568
1560
|
|
|
1569
1561
|
async function readProjectJson(rootDir: string, relativePath: string): Promise<unknown | null> {
|
|
1570
|
-
|
|
1571
|
-
return JSON.parse(await fsReadFile(join(rootDir, relativePath), "utf8")) as unknown;
|
|
1572
|
-
} catch {
|
|
1573
|
-
return null;
|
|
1574
|
-
}
|
|
1562
|
+
return JSON.parse(await fsReadFile(join(rootDir, relativePath), "utf8")) as unknown;
|
|
1575
1563
|
}
|
|
1576
1564
|
|
|
1577
1565
|
function withNestedValue(source: unknown, path: readonly string[], value: unknown): Record<string, unknown> {
|
|
@@ -1595,7 +1583,7 @@ function getNestedValue(source: unknown, path: readonly string[]): unknown {
|
|
|
1595
1583
|
return cursor;
|
|
1596
1584
|
}
|
|
1597
1585
|
|
|
1598
|
-
function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | null): ConfigPatchPreview {
|
|
1586
|
+
function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | null, missing = false): ConfigPatchPreview {
|
|
1599
1587
|
const configIntents: Record<
|
|
1600
1588
|
ConfigChangeIntent,
|
|
1601
1589
|
readonly { readonly pointer: string; readonly path: readonly string[]; readonly value: unknown }[]
|
|
@@ -1639,6 +1627,16 @@ function buildConfigPatchPreview(intent: ConfigChangeIntent, before: unknown | n
|
|
|
1639
1627
|
operations: [],
|
|
1640
1628
|
};
|
|
1641
1629
|
}
|
|
1630
|
+
if (!isPlainRecord(before) && !missing) {
|
|
1631
|
+
return {
|
|
1632
|
+
path: "phasegate.config.json",
|
|
1633
|
+
applicability: "blocked",
|
|
1634
|
+
blockedReason: "An existing JSON object configuration is required. Review phasegate install --dry-run before initialization, or restore a valid configuration before retrying.",
|
|
1635
|
+
before,
|
|
1636
|
+
after: before,
|
|
1637
|
+
operations: [],
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1642
1640
|
let after: unknown = before;
|
|
1643
1641
|
const operations: ConfigPatchOperation[] = [];
|
|
1644
1642
|
for (const change of changes) {
|
|
@@ -1674,6 +1672,9 @@ async function applyConfigPlan(
|
|
|
1674
1672
|
if (patch.applicability !== "applicable") {
|
|
1675
1673
|
throw new Error(`config plan is not applicable: ${patch.blockedReason ?? patch.applicability}`);
|
|
1676
1674
|
}
|
|
1675
|
+
if (!isPlainRecord(patch.before)) {
|
|
1676
|
+
throw new Error("phasegate.config.json is missing. Review phasegate install --dry-run before initialization; config:plan does not create a partial configuration.");
|
|
1677
|
+
}
|
|
1677
1678
|
if (patch.operations.length === 0) {
|
|
1678
1679
|
throw new Error("config plan has no operations to apply.");
|
|
1679
1680
|
}
|
|
@@ -1682,13 +1683,16 @@ async function applyConfigPlan(
|
|
|
1682
1683
|
}
|
|
1683
1684
|
|
|
1684
1685
|
const configPath = join(rootDir, patch.path);
|
|
1686
|
+
const beforeText = await fsReadFile(configPath, "utf8");
|
|
1687
|
+
if (JSON.stringify(JSON.parse(beforeText)) !== JSON.stringify(patch.before)) {
|
|
1688
|
+
throw new Error("phasegate.config.json changed after planning. Review config:plan --dry-run again before applying; no configuration was changed.");
|
|
1689
|
+
}
|
|
1685
1690
|
const backupPath = configPlanBackupPath(rootDir, new Date());
|
|
1686
1691
|
await fsMkdir(dirname(backupPath), { recursive: true });
|
|
1687
|
-
|
|
1688
|
-
await fsWriteFile(backupPath, beforeText, "utf8");
|
|
1692
|
+
await fsWriteFile(backupPath, beforeText, { encoding: "utf8", flag: "wx" });
|
|
1689
1693
|
|
|
1690
1694
|
const tempPath = `${configPath}.tmp-${process.pid}-${Date.now()}`;
|
|
1691
|
-
await fsWriteFile(tempPath, `${JSON.stringify(patch.after, null, 2)}\n`, "utf8");
|
|
1695
|
+
await fsWriteFile(tempPath, `${JSON.stringify(patch.after, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
|
|
1692
1696
|
await fsRename(tempPath, configPath);
|
|
1693
1697
|
|
|
1694
1698
|
return {
|
|
@@ -1829,11 +1833,31 @@ async function buildConfigChangePlan(rootDir: string, intent: ConfigChangeIntent
|
|
|
1829
1833
|
],
|
|
1830
1834
|
},
|
|
1831
1835
|
};
|
|
1832
|
-
|
|
1836
|
+
let before: unknown = null;
|
|
1837
|
+
let readFailure: string | undefined;
|
|
1838
|
+
let missing = false;
|
|
1839
|
+
try {
|
|
1840
|
+
before = await readProjectJson(rootDir, "phasegate.config.json");
|
|
1841
|
+
} catch (error) {
|
|
1842
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
1843
|
+
missing = true;
|
|
1844
|
+
} else if (error instanceof SyntaxError) {
|
|
1845
|
+
readFailure = "Cannot parse phasegate.config.json. Restore valid JSON from version control or a known-good backup through an authorized recovery path, then preview again. The original file has not been changed.";
|
|
1846
|
+
} else {
|
|
1847
|
+
readFailure = `Cannot read phasegate.config.json. Check file access permissions before retrying. The original file has not been changed. ${error instanceof Error ? error.message : String(error)}`;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
let configPatch = buildConfigPatchPreview(intent, before, missing);
|
|
1851
|
+
if (readFailure && configPatch.applicability !== "not-applicable") {
|
|
1852
|
+
configPatch = { ...configPatch, applicability: "blocked", blockedReason: readFailure, after: before, operations: [] };
|
|
1853
|
+
}
|
|
1833
1854
|
return {
|
|
1834
1855
|
intent,
|
|
1835
1856
|
...catalog[intent],
|
|
1836
|
-
|
|
1857
|
+
commands: missing && configPatch.applicability === "applicable"
|
|
1858
|
+
? ["phasegate install --dry-run", ...catalog[intent].commands]
|
|
1859
|
+
: catalog[intent].commands,
|
|
1860
|
+
configPatch,
|
|
1837
1861
|
diffExplanation:
|
|
1838
1862
|
"Review the listed targets first, apply through PhaseGate managed commands where possible, then run the validations in order.",
|
|
1839
1863
|
rollback: "Use git diff for config changes; use phasegate uninstall/reconcile dry-runs for managed setup targets.",
|
|
@@ -2143,8 +2167,8 @@ async function main(): Promise<void> {
|
|
|
2143
2167
|
}
|
|
2144
2168
|
const phasePreset = parseInitPhasePreset(rawPhasePreset);
|
|
2145
2169
|
const skillSetRaw = parseFlag(args, "--skills") ?? "all";
|
|
2146
|
-
if (skillSetRaw
|
|
2147
|
-
console.error(`Invalid --skills value: "${skillSetRaw}". Use "core" or "all".`);
|
|
2170
|
+
if (!isSkillSet(skillSetRaw)) {
|
|
2171
|
+
console.error(`Invalid --skills value: "${skillSetRaw}". Use "core", "consumer", or "all".`);
|
|
2148
2172
|
process.exit(2);
|
|
2149
2173
|
}
|
|
2150
2174
|
const skillSet: SkillSet = skillSetRaw;
|
|
@@ -2226,7 +2250,7 @@ async function main(): Promise<void> {
|
|
|
2226
2250
|
huskyPrePushResult?.created ? await createFileManifestRecord(rootDir, join(".husky", "pre-push")) : null,
|
|
2227
2251
|
...(ciWorkflowResult?.copiedFiles.map((path) => createFileManifestRecord(rootDir, path)) ?? []),
|
|
2228
2252
|
]);
|
|
2229
|
-
const installModule = createInstallationModule();
|
|
2253
|
+
const installModule = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2230
2254
|
const installResult = await installModule.runInstallUseCase.execute({
|
|
2231
2255
|
projectRoot: rootDir,
|
|
2232
2256
|
harnessRoot,
|
|
@@ -2390,7 +2414,7 @@ async function main(): Promise<void> {
|
|
|
2390
2414
|
}
|
|
2391
2415
|
const apply = hasFlag(args, "--apply");
|
|
2392
2416
|
const dryRun = hasFlag(args, "--dry-run") || !apply;
|
|
2393
|
-
const mod = createInstallationModule();
|
|
2417
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2394
2418
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
2395
2419
|
const result = await mod.reconcileHandler.execute({
|
|
2396
2420
|
projectRoot: rootDir,
|
|
@@ -2419,7 +2443,7 @@ async function main(): Promise<void> {
|
|
|
2419
2443
|
console.error(`Invalid --agent value: "${parseFlag(args, "--agent")}". Use <${AGENT_TARGET_USAGE}>.`);
|
|
2420
2444
|
process.exit(2);
|
|
2421
2445
|
}
|
|
2422
|
-
const mod = createInstallationModule();
|
|
2446
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2423
2447
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
2424
2448
|
const result = await mod.doctorHandler.execute({
|
|
2425
2449
|
projectRoot: rootDir,
|
|
@@ -2493,8 +2517,8 @@ async function main(): Promise<void> {
|
|
|
2493
2517
|
process.exit(2);
|
|
2494
2518
|
}
|
|
2495
2519
|
const skillSetRaw = parseFlag(args, "--skills") ?? "all";
|
|
2496
|
-
if (skillSetRaw
|
|
2497
|
-
console.error(`Invalid --skills value: "${skillSetRaw}". Use "core" or "all".`);
|
|
2520
|
+
if (!isSkillSet(skillSetRaw)) {
|
|
2521
|
+
console.error(`Invalid --skills value: "${skillSetRaw}". Use "core", "consumer", or "all".`);
|
|
2498
2522
|
process.exit(2);
|
|
2499
2523
|
}
|
|
2500
2524
|
const workflowRaw = parseFlag(args, "--workflow");
|
|
@@ -2505,7 +2529,7 @@ async function main(): Promise<void> {
|
|
|
2505
2529
|
const includeClaude = agent === "claude" || agent === "both" || agent === "grok" || agent === "all";
|
|
2506
2530
|
const includeCodex = agent === "codex" || agent === "both" || agent === "all";
|
|
2507
2531
|
const personal = hasFlag(args, "--personal");
|
|
2508
|
-
const mod = createInstallationModule();
|
|
2532
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2509
2533
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
2510
2534
|
const result = await mod.installHandler.execute({
|
|
2511
2535
|
projectRoot: rootDir,
|
|
@@ -2578,7 +2602,7 @@ async function main(): Promise<void> {
|
|
|
2578
2602
|
packageDependency: packageResult,
|
|
2579
2603
|
configCreated: configResult.created,
|
|
2580
2604
|
};
|
|
2581
|
-
const mod = createInstallationModule();
|
|
2605
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2582
2606
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
2583
2607
|
installResult = await mod.runInstallUseCase.execute({
|
|
2584
2608
|
projectRoot: rootDir,
|
|
@@ -2745,7 +2769,7 @@ async function main(): Promise<void> {
|
|
|
2745
2769
|
}
|
|
2746
2770
|
const apply = hasFlag(args, "--apply");
|
|
2747
2771
|
const dryRun = hasFlag(args, "--dry-run") || !apply;
|
|
2748
|
-
const mod = createInstallationModule();
|
|
2772
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2749
2773
|
const result = await mod.uninstallHandler.execute({
|
|
2750
2774
|
projectRoot: rootDir,
|
|
2751
2775
|
harnessRoot,
|
|
@@ -2768,7 +2792,7 @@ async function main(): Promise<void> {
|
|
|
2768
2792
|
}
|
|
2769
2793
|
const apply = hasFlag(args, "--apply");
|
|
2770
2794
|
const dryRun = hasFlag(args, "--dry-run") || !apply;
|
|
2771
|
-
const mod = createInstallationModule();
|
|
2795
|
+
const mod = (await import("./installation/composition-root.js")).createInstallationModule();
|
|
2772
2796
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
2773
2797
|
const result = await mod.reconcileHandler.execute({
|
|
2774
2798
|
projectRoot: rootDir,
|
|
@@ -2827,7 +2851,7 @@ async function main(): Promise<void> {
|
|
|
2827
2851
|
|
|
2828
2852
|
case "migrate": {
|
|
2829
2853
|
if (args[1] === "work-items") {
|
|
2830
|
-
const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2854
|
+
const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2831
2855
|
const result = await mod.migrateWorkItemsCommandHandler.execute({
|
|
2832
2856
|
dryRun: hasFlag(args, "--dry-run"),
|
|
2833
2857
|
apply: hasFlag(args, "--apply"),
|
|
@@ -2851,7 +2875,7 @@ async function main(): Promise<void> {
|
|
|
2851
2875
|
|
|
2852
2876
|
// ── harness-error ──
|
|
2853
2877
|
case "render-errors": {
|
|
2854
|
-
const mod = createHarnessErrorModule(rootDir);
|
|
2878
|
+
const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
|
|
2855
2879
|
const format = toRenderFormat(parseFlag(args, "--format") ?? "human");
|
|
2856
2880
|
const failOnError = hasFlag(args, "--fail-on-error");
|
|
2857
2881
|
const result = mod.renderHarnessErrorsHandler.execute({
|
|
@@ -2865,7 +2889,7 @@ async function main(): Promise<void> {
|
|
|
2865
2889
|
}
|
|
2866
2890
|
|
|
2867
2891
|
case "validate-fix": {
|
|
2868
|
-
const mod = createHarnessErrorModule(rootDir);
|
|
2892
|
+
const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
|
|
2869
2893
|
const code = parseFlag(args, "--code");
|
|
2870
2894
|
const failFast = hasFlag(args, "--fail-fast");
|
|
2871
2895
|
const format = toListFormat(parseFlag(args, "--format") ?? "human");
|
|
@@ -2880,7 +2904,7 @@ async function main(): Promise<void> {
|
|
|
2880
2904
|
}
|
|
2881
2905
|
|
|
2882
2906
|
case "list-errors": {
|
|
2883
|
-
const mod = createHarnessErrorModule(rootDir);
|
|
2907
|
+
const mod = (await import("./harness-error/composition-root.js")).createHarnessErrorModule(rootDir);
|
|
2884
2908
|
const format = toListFormat(parseFlag(args, "--format") ?? "human");
|
|
2885
2909
|
const layer = toLayerFilter(parseFlag(args, "--layer"));
|
|
2886
2910
|
const result = await mod.listErrorDefinitionsHandler.execute({
|
|
@@ -2894,7 +2918,7 @@ async function main(): Promise<void> {
|
|
|
2894
2918
|
|
|
2895
2919
|
// ── traceability-model ──
|
|
2896
2920
|
case "validate-metadata": {
|
|
2897
|
-
const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2921
|
+
const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2898
2922
|
const filePaths = parsePositionalArgs(args.slice(1));
|
|
2899
2923
|
const result = await mod.validateMetadataCommandHandler.execute({
|
|
2900
2924
|
filePaths,
|
|
@@ -2906,7 +2930,7 @@ async function main(): Promise<void> {
|
|
|
2906
2930
|
}
|
|
2907
2931
|
|
|
2908
2932
|
case "work-items:status": {
|
|
2909
|
-
const mod = createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2933
|
+
const mod = (await import("./traceability-model/composition-root.js")).createTraceabilityModelModule(rootDir, toTraceabilityModelOptions(resolvedConfig));
|
|
2910
2934
|
const result = await mod.workItemStatusCommandHandler.execute({
|
|
2911
2935
|
dryRun: hasFlag(args, "--dry-run"),
|
|
2912
2936
|
apply: hasFlag(args, "--apply"),
|
|
@@ -2925,12 +2949,12 @@ async function main(): Promise<void> {
|
|
|
2925
2949
|
case "world:inspect": {
|
|
2926
2950
|
let handler: WorldInspectCommandHandler;
|
|
2927
2951
|
try {
|
|
2928
|
-
handler = createWorldModelModule({
|
|
2952
|
+
handler = (await import("./world-model/index.js")).createWorldModelModule({
|
|
2929
2953
|
rootDir,
|
|
2930
2954
|
resolvedConfig: await loadWorldResolvedConfig(),
|
|
2931
2955
|
}).worldInspectCommandHandler;
|
|
2932
2956
|
} catch (error) {
|
|
2933
|
-
handler = WorldInspectCommandHandler.fromFailure(error);
|
|
2957
|
+
handler = (await import("./world-model/index.js")).WorldInspectCommandHandler.fromFailure(error);
|
|
2934
2958
|
}
|
|
2935
2959
|
const result = await handler.execute(args.slice(1));
|
|
2936
2960
|
if (result.stdout.length > 0) process.stdout.write(result.stdout);
|
|
@@ -2942,12 +2966,12 @@ async function main(): Promise<void> {
|
|
|
2942
2966
|
case "world:pin": {
|
|
2943
2967
|
let handler: WorldPinCommandHandler;
|
|
2944
2968
|
try {
|
|
2945
|
-
handler = createWorldModelModule({
|
|
2969
|
+
handler = (await import("./world-model/index.js")).createWorldModelModule({
|
|
2946
2970
|
rootDir,
|
|
2947
2971
|
resolvedConfig: await loadWorldResolvedConfig(),
|
|
2948
2972
|
}).worldPinCommandHandler;
|
|
2949
2973
|
} catch (error) {
|
|
2950
|
-
handler = WorldPinCommandHandler.fromFailure(error);
|
|
2974
|
+
handler = (await import("./world-model/index.js")).WorldPinCommandHandler.fromFailure(error);
|
|
2951
2975
|
}
|
|
2952
2976
|
const result = await handler.execute(args.slice(1));
|
|
2953
2977
|
if (result.stdout.length > 0) process.stdout.write(result.stdout);
|
|
@@ -2959,12 +2983,12 @@ async function main(): Promise<void> {
|
|
|
2959
2983
|
case "world:derive": {
|
|
2960
2984
|
let handler: WorldDeriveCommandHandler;
|
|
2961
2985
|
try {
|
|
2962
|
-
handler = createWorldModelModule({
|
|
2986
|
+
handler = (await import("./world-model/index.js")).createWorldModelModule({
|
|
2963
2987
|
rootDir,
|
|
2964
2988
|
resolvedConfig: await loadWorldResolvedConfig(),
|
|
2965
2989
|
}).worldDeriveCommandHandler;
|
|
2966
2990
|
} catch (error) {
|
|
2967
|
-
handler = WorldDeriveCommandHandler.fromFailure(error);
|
|
2991
|
+
handler = (await import("./world-model/index.js")).WorldDeriveCommandHandler.fromFailure(error);
|
|
2968
2992
|
}
|
|
2969
2993
|
const result = await handler.execute(args.slice(1));
|
|
2970
2994
|
if (result.stdout.length > 0) process.stdout.write(result.stdout);
|
|
@@ -2977,7 +3001,7 @@ async function main(): Promise<void> {
|
|
|
2977
3001
|
case "check-phase-gate": {
|
|
2978
3002
|
const phaseConfig = resolvedConfig ? toPhaseConfigSection(resolvedConfig) : undefined;
|
|
2979
3003
|
const reportOutputDir = resolvedConfig?.reporting.outputDir;
|
|
2980
|
-
const mod = createPhaseDependencyModelModule({
|
|
3004
|
+
const mod = (await import("./phase-dependency-model/composition-root.js")).createPhaseDependencyModelModule({
|
|
2981
3005
|
rootDir,
|
|
2982
3006
|
phaseConfig,
|
|
2983
3007
|
reportOutputDir,
|
|
@@ -3003,7 +3027,7 @@ async function main(): Promise<void> {
|
|
|
3003
3027
|
// ADR ディレクトリを rootDir として渡す(project root を渡すと readdir が ADR を
|
|
3004
3028
|
// 一切発見できず vacuous な valid を返す phantom gate になる)。
|
|
3005
3029
|
case "list-adrs": {
|
|
3006
|
-
const mod = createAdrFoundationModule(join(rootDir, "docs", "ADR"));
|
|
3030
|
+
const mod = (await import("./adr-foundation/composition-root.js")).createAdrFoundationModule(join(rootDir, "docs", "ADR"));
|
|
3007
3031
|
const statuses = toAdrStatuses(parseFlag(args, "--status"));
|
|
3008
3032
|
const result = await mod.listAdrsCommandHandler.execute({
|
|
3009
3033
|
statuses,
|
|
@@ -3015,7 +3039,7 @@ async function main(): Promise<void> {
|
|
|
3015
3039
|
}
|
|
3016
3040
|
|
|
3017
3041
|
case "validate-adr": {
|
|
3018
|
-
const mod = createAdrFoundationModule(join(rootDir, "docs", "ADR"));
|
|
3042
|
+
const mod = (await import("./adr-foundation/composition-root.js")).createAdrFoundationModule(join(rootDir, "docs", "ADR"));
|
|
3019
3043
|
const all = hasFlag(args, "--all");
|
|
3020
3044
|
const adrRef = args.find((a) => !a.startsWith("--") && a !== command);
|
|
3021
3045
|
const result = await mod.validateAdrCommandHandler.execute({
|
|
@@ -3041,7 +3065,7 @@ async function main(): Promise<void> {
|
|
|
3041
3065
|
|
|
3042
3066
|
// ── validator-system ──
|
|
3043
3067
|
case "validate": {
|
|
3044
|
-
const mod = createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
|
|
3068
|
+
const mod = (await import("./validator-system/composition-root.js")).createValidatorSystemModule(toValidatorSystemConfig(resolvedConfig));
|
|
3045
3069
|
const layer = parseValidateLayer(args);
|
|
3046
3070
|
const unit = parseFlag(args, "--unit");
|
|
3047
3071
|
const phase = parseFlag(args, "--phase");
|
|
@@ -3074,7 +3098,7 @@ async function main(): Promise<void> {
|
|
|
3074
3098
|
// WI-364: check-change-category (WI-351) と同様に解決済み configPath / rootDir を注入する。
|
|
3075
3099
|
// 無指定だと quickMode 設定を cwd 基準でしか探せず、サブディレクトリ実行で
|
|
3076
3100
|
// HarnessConfigNotFoundError → exit 2 になっていた。
|
|
3077
|
-
const mod = createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
|
|
3101
|
+
const mod = (await import("./quick-mode/composition-root.js")).createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
|
|
3078
3102
|
const failOnReject = hasFlag(args, "--fail-on-reject");
|
|
3079
3103
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3080
3104
|
const files = parseFlag(args, "--files");
|
|
@@ -3103,6 +3127,7 @@ async function main(): Promise<void> {
|
|
|
3103
3127
|
" --paths <csv> Comma-separated file paths to classify.",
|
|
3104
3128
|
" --format <human|json> Output format. Default: human.",
|
|
3105
3129
|
" --fail-on-full-required Exit with code 1 when Full Mode is required.",
|
|
3130
|
+
" --risk-snapshots <json> Optional before/after snapshots for advisory review; does not change gates.",
|
|
3106
3131
|
" --help Show this help.",
|
|
3107
3132
|
"",
|
|
3108
3133
|
"Examples:",
|
|
@@ -3113,14 +3138,19 @@ async function main(): Promise<void> {
|
|
|
3113
3138
|
);
|
|
3114
3139
|
return;
|
|
3115
3140
|
}
|
|
3116
|
-
const mod = createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
|
|
3141
|
+
const mod = (await import("./quick-mode/composition-root.js")).createQuickModeCompositionRoot(await resolveQuickModeCompositionOptions());
|
|
3117
3142
|
const paths = parseFlag(args, "--paths");
|
|
3118
3143
|
const format = parseFlag(args, "--format") as "human" | "json" | undefined;
|
|
3119
3144
|
const failOnFullRequired = hasFlag(args, "--fail-on-full-required");
|
|
3145
|
+
const riskSnapshots = parseFlag(args, "--risk-snapshots");
|
|
3146
|
+
if (hasFlag(args, "--risk-snapshots") && !riskSnapshots) {
|
|
3147
|
+
throw new Error("--risk-snapshots requires a JSON file path.");
|
|
3148
|
+
}
|
|
3120
3149
|
const result = await mod.checkChangeCategoryHandler.handle({
|
|
3121
3150
|
paths,
|
|
3122
3151
|
format,
|
|
3123
3152
|
failOnFullRequired,
|
|
3153
|
+
riskSnapshots,
|
|
3124
3154
|
});
|
|
3125
3155
|
await finishCliExit(result.exitCode);
|
|
3126
3156
|
return;
|
|
@@ -3206,9 +3236,8 @@ async function main(): Promise<void> {
|
|
|
3206
3236
|
const mod = createHarnessApiModule();
|
|
3207
3237
|
const flags: Record<string, boolean | string> = {};
|
|
3208
3238
|
if (json) flags.json = true;
|
|
3209
|
-
const
|
|
3210
|
-
|
|
3211
|
-
await mod.handlers.lint.handle({}, flags);
|
|
3239
|
+
const targets = args.flatMap((arg, index) => arg === '--target' && args[index + 1] !== undefined ? [args[index + 1]] : []);
|
|
3240
|
+
await mod.handlers.lint.handle(targets.length > 0 ? { reportTargets: JSON.stringify(targets) } : {}, flags);
|
|
3212
3241
|
break;
|
|
3213
3242
|
}
|
|
3214
3243
|
|
|
@@ -3283,7 +3312,7 @@ async function main(): Promise<void> {
|
|
|
3283
3312
|
}
|
|
3284
3313
|
const { createAttestationModule } = await import("./attestation/index.js");
|
|
3285
3314
|
const pkgVersion = await getHarnessVersion(harnessRoot);
|
|
3286
|
-
const worldModule = createWorldModelModule({
|
|
3315
|
+
const worldModule = (await import("./world-model/index.js")).createWorldModelModule({
|
|
3287
3316
|
rootDir,
|
|
3288
3317
|
resolvedConfig: await loadWorldResolvedConfig(),
|
|
3289
3318
|
});
|
|
@@ -3350,7 +3379,7 @@ Examples:
|
|
|
3350
3379
|
console.error(flagError);
|
|
3351
3380
|
process.exit(2);
|
|
3352
3381
|
}
|
|
3353
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3382
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3354
3383
|
const presetId = parseFlag(args, "--preset") ?? "standard";
|
|
3355
3384
|
const templateType = parseFlag(args, "--type") ?? "aidlc-gate";
|
|
3356
3385
|
const render = hasFlag(args, "--render");
|
|
@@ -3362,7 +3391,7 @@ Examples:
|
|
|
3362
3391
|
}
|
|
3363
3392
|
|
|
3364
3393
|
case "ci:migrate-agents-md": {
|
|
3365
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3394
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3366
3395
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3367
3396
|
const validateOnly = hasFlag(args, "--validate-only");
|
|
3368
3397
|
const format = json ? "json" : "human";
|
|
@@ -3373,7 +3402,7 @@ Examples:
|
|
|
3373
3402
|
}
|
|
3374
3403
|
|
|
3375
3404
|
case "ci:auto-refresh-agent-context": {
|
|
3376
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3405
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3377
3406
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3378
3407
|
const apply = hasFlag(args, "--apply");
|
|
3379
3408
|
const format = json ? "json" : "human";
|
|
@@ -3384,7 +3413,7 @@ Examples:
|
|
|
3384
3413
|
}
|
|
3385
3414
|
|
|
3386
3415
|
case "refresh-claude-md": {
|
|
3387
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3416
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3388
3417
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3389
3418
|
const apply = hasFlag(args, "--apply");
|
|
3390
3419
|
const format = json ? "json" : "human";
|
|
@@ -3395,7 +3424,7 @@ Examples:
|
|
|
3395
3424
|
}
|
|
3396
3425
|
|
|
3397
3426
|
case "p2:check-agent-context": {
|
|
3398
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3427
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3399
3428
|
const thresholdRaw = parseFlag(args, "--threshold-days");
|
|
3400
3429
|
const thresholdDays = thresholdRaw === undefined ? undefined : Number(thresholdRaw);
|
|
3401
3430
|
const format = json ? "json" : "human";
|
|
@@ -3406,7 +3435,7 @@ Examples:
|
|
|
3406
3435
|
}
|
|
3407
3436
|
|
|
3408
3437
|
case "ci:check-repetition": {
|
|
3409
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3438
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3410
3439
|
const errorCode = parseFlag(args, "--code") ?? "";
|
|
3411
3440
|
const reset = hasFlag(args, "--reset");
|
|
3412
3441
|
const format = json ? "json" : "human";
|
|
@@ -3417,7 +3446,7 @@ Examples:
|
|
|
3417
3446
|
}
|
|
3418
3447
|
|
|
3419
3448
|
case "baseline": {
|
|
3420
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3449
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3421
3450
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3422
3451
|
const force = hasFlag(args, "--force");
|
|
3423
3452
|
const pathsFlag = parseFlag(args, "--paths");
|
|
@@ -3440,7 +3469,7 @@ Examples:
|
|
|
3440
3469
|
}
|
|
3441
3470
|
|
|
3442
3471
|
case "scaffold-design": {
|
|
3443
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3472
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3444
3473
|
const unit = parseFlag(args, "--unit") ?? "";
|
|
3445
3474
|
const phase = parseFlag(args, "--phase") ?? "";
|
|
3446
3475
|
const dryRun = hasFlag(args, "--dry-run");
|
|
@@ -3461,7 +3490,7 @@ Examples:
|
|
|
3461
3490
|
}
|
|
3462
3491
|
|
|
3463
3492
|
case "scaffold-inception": {
|
|
3464
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3493
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3465
3494
|
const kind = parseFlag(args, "--kind") ?? "";
|
|
3466
3495
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3467
3496
|
const apply = hasFlag(args, "--apply");
|
|
@@ -3480,7 +3509,7 @@ Examples:
|
|
|
3480
3509
|
}
|
|
3481
3510
|
|
|
3482
3511
|
case "templates": {
|
|
3483
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3512
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3484
3513
|
const subCommand = args[1];
|
|
3485
3514
|
const emit = async (result: { exitCode: number; output: string; errorOutput: string }): Promise<void> => {
|
|
3486
3515
|
if (result.output.length > 0) console.log(result.output);
|
|
@@ -3503,7 +3532,7 @@ Examples:
|
|
|
3503
3532
|
}
|
|
3504
3533
|
|
|
3505
3534
|
case "integrity:pin": {
|
|
3506
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3535
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3507
3536
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3508
3537
|
const format = json ? "json" : "human";
|
|
3509
3538
|
const result = await mod.integrityHandler.pin({ dryRun, format });
|
|
@@ -3513,7 +3542,7 @@ Examples:
|
|
|
3513
3542
|
}
|
|
3514
3543
|
|
|
3515
3544
|
case "integrity:verify": {
|
|
3516
|
-
const mod = buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3545
|
+
const mod = (await import("./ci-governance/composition-root.js")).buildCiGovernance(rootDir, harnessRoot, toCiGovernanceDocPaths(resolvedConfig));
|
|
3517
3546
|
const format = json ? "json" : "human";
|
|
3518
3547
|
const result = await mod.integrityHandler.verify({ format });
|
|
3519
3548
|
console.log(result.output);
|
|
@@ -3523,7 +3552,15 @@ Examples:
|
|
|
3523
3552
|
|
|
3524
3553
|
// ── skill-quality ──
|
|
3525
3554
|
case "skill:execute-tdd-cycle": {
|
|
3526
|
-
const
|
|
3555
|
+
const configuredValidation = hasFlag(args, "--configured-validation");
|
|
3556
|
+
const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers(configuredValidation ? {
|
|
3557
|
+
rootDir,
|
|
3558
|
+
l1Config: resolvedConfig
|
|
3559
|
+
? { l1Config: toL1Config(resolvedConfig), architecture: toArchitectureInput(resolvedConfig) }
|
|
3560
|
+
: undefined,
|
|
3561
|
+
validatorSystemConfig: toValidatorSystemConfig(resolvedConfig),
|
|
3562
|
+
failOnWarning: resolvedConfig?.validate.failOnWarning,
|
|
3563
|
+
} : {});
|
|
3527
3564
|
const unit = parseFlag(args, "--unit") ?? "";
|
|
3528
3565
|
const storyId = parseFlag(args, "--story") ?? "";
|
|
3529
3566
|
const description = parseFlag(args, "--desc") ?? "";
|
|
@@ -3533,12 +3570,13 @@ Examples:
|
|
|
3533
3570
|
const passed = hasFlag(args, "--passed");
|
|
3534
3571
|
const result = await mod.executeTddCycleHandler.handle({ unit, storyId, description, phase, passed });
|
|
3535
3572
|
console.log(result.message);
|
|
3573
|
+
console.log(`Validation profile: ${configuredValidation ? "configured" : "legacy (use --configured-validation to explicitly adopt resolved project validation settings)"}`);
|
|
3536
3574
|
await finishCliExit(result.exitCode);
|
|
3537
3575
|
return;
|
|
3538
3576
|
}
|
|
3539
3577
|
|
|
3540
3578
|
case "skill:check-coverage": {
|
|
3541
|
-
const mod = createSkillQualityHandlers();
|
|
3579
|
+
const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
|
|
3542
3580
|
const storyId = parseFlag(args, "--story") ?? "";
|
|
3543
3581
|
const format = json ? "json" : "human";
|
|
3544
3582
|
const result = await mod.checkCoverageHandler.handle({ storyId, format });
|
|
@@ -3548,7 +3586,7 @@ Examples:
|
|
|
3548
3586
|
}
|
|
3549
3587
|
|
|
3550
3588
|
case "skill:collect-lessons": {
|
|
3551
|
-
const mod = createSkillQualityHandlers();
|
|
3589
|
+
const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
|
|
3552
3590
|
const storyId = parseFlag(args, "--story") ?? "";
|
|
3553
3591
|
const sourcesRaw = parseFlag(args, "--sources") ?? "";
|
|
3554
3592
|
const sources = sourcesRaw ? sourcesRaw.split(",") : [];
|
|
@@ -3560,7 +3598,7 @@ Examples:
|
|
|
3560
3598
|
}
|
|
3561
3599
|
|
|
3562
3600
|
case "skill:apply-cascade-update": {
|
|
3563
|
-
const mod = createSkillQualityHandlers();
|
|
3601
|
+
const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
|
|
3564
3602
|
const storyId = parseFlag(args, "--story") ?? "";
|
|
3565
3603
|
const dryRun = hasFlag(args, "--dry-run");
|
|
3566
3604
|
const result = await mod.applyCascadeUpdateHandler.handle({ storyId, dryRun, format: json ? "json" : "human" });
|
|
@@ -3570,7 +3608,7 @@ Examples:
|
|
|
3570
3608
|
}
|
|
3571
3609
|
|
|
3572
3610
|
case "skill:validate-structure": {
|
|
3573
|
-
const mod = createSkillQualityHandlers();
|
|
3611
|
+
const mod = (await import("./skill-quality/composition-root.js")).createSkillQualityHandlers();
|
|
3574
3612
|
const skillFile = parseFlag(args, "--file") ?? "";
|
|
3575
3613
|
const format = json ? "json" : "human";
|
|
3576
3614
|
const result = await mod.validateSkillStructureHandler.handle({ skillFile, format });
|
|
@@ -3581,7 +3619,7 @@ Examples:
|
|
|
3581
3619
|
|
|
3582
3620
|
// ── regression-suite ──
|
|
3583
3621
|
case "regression:run-k-requirements": {
|
|
3584
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3622
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3585
3623
|
const result = await mod.runKRequirementsRegressionUseCase.execute();
|
|
3586
3624
|
const output = json
|
|
3587
3625
|
? JSON.stringify(result, null, 2)
|
|
@@ -3592,7 +3630,7 @@ Examples:
|
|
|
3592
3630
|
}
|
|
3593
3631
|
|
|
3594
3632
|
case "regression:run-gng-gate": {
|
|
3595
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3633
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3596
3634
|
const result = await mod.runGngGateRegressionUseCase.execute();
|
|
3597
3635
|
const output = json
|
|
3598
3636
|
? JSON.stringify(result, null, 2)
|
|
@@ -3603,7 +3641,7 @@ Examples:
|
|
|
3603
3641
|
}
|
|
3604
3642
|
|
|
3605
3643
|
case "regression:run-agent-guard": {
|
|
3606
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3644
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3607
3645
|
const result = await mod.runAgentIndependenceGuardUseCase.execute();
|
|
3608
3646
|
const output = json
|
|
3609
3647
|
? JSON.stringify(result, null, 2)
|
|
@@ -3614,7 +3652,7 @@ Examples:
|
|
|
3614
3652
|
}
|
|
3615
3653
|
|
|
3616
3654
|
case "regression:run-k14-k15": {
|
|
3617
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3655
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3618
3656
|
const result = await mod.runK14K15RegressionUseCase.execute();
|
|
3619
3657
|
const output = json
|
|
3620
3658
|
? JSON.stringify(result, null, 2)
|
|
@@ -3625,7 +3663,7 @@ Examples:
|
|
|
3625
3663
|
}
|
|
3626
3664
|
|
|
3627
3665
|
case "regression:configure-ci-gate": {
|
|
3628
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3666
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3629
3667
|
const requiredSuiteIds = parseSuiteIds(parseFlag(args, "--suites") ?? DEFAULT_REGRESSION_SUITES);
|
|
3630
3668
|
const threshold = parseCoverageThreshold(parseFlag(args, "--threshold"));
|
|
3631
3669
|
const result = await mod.configureCiGateUseCase.execute({
|
|
@@ -3642,7 +3680,7 @@ Examples:
|
|
|
3642
3680
|
}
|
|
3643
3681
|
|
|
3644
3682
|
case "regression:analyze-migration": {
|
|
3645
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3683
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3646
3684
|
const dryRun = !hasFlag(args, "--no-dry-run");
|
|
3647
3685
|
const result = await mod.analyzeV0MigrationUseCase.execute({ dryRun });
|
|
3648
3686
|
const output = json
|
|
@@ -3654,7 +3692,7 @@ Examples:
|
|
|
3654
3692
|
}
|
|
3655
3693
|
|
|
3656
3694
|
case "regression:migrate-v0-tests": {
|
|
3657
|
-
const mod = buildRegressionSuite(rootDir);
|
|
3695
|
+
const mod = (await import("./regression-suite/composition-root.js")).buildRegressionSuite(rootDir);
|
|
3658
3696
|
const confirm = hasFlag(args, "--confirm");
|
|
3659
3697
|
const result = await mod.migrateV0TestsUseCase.execute({ confirmExecute: confirm });
|
|
3660
3698
|
const output = json
|
|
@@ -3667,7 +3705,7 @@ Examples:
|
|
|
3667
3705
|
|
|
3668
3706
|
// ── phase2-extensions ──
|
|
3669
3707
|
case "p2:check-freshness": {
|
|
3670
|
-
const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3708
|
+
const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3671
3709
|
const p2args = args.slice(1);
|
|
3672
3710
|
const result = await mod.checkFreshnessHandler.handle(p2args);
|
|
3673
3711
|
console.log(result.stdout);
|
|
@@ -3676,7 +3714,7 @@ Examples:
|
|
|
3676
3714
|
}
|
|
3677
3715
|
|
|
3678
3716
|
case "p2:validate-pointers": {
|
|
3679
|
-
const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3717
|
+
const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3680
3718
|
const p2args = args.slice(1);
|
|
3681
3719
|
const result = await mod.validatePointersHandler.handle(p2args);
|
|
3682
3720
|
console.log(result.stdout);
|
|
@@ -3685,7 +3723,7 @@ Examples:
|
|
|
3685
3723
|
}
|
|
3686
3724
|
|
|
3687
3725
|
case "p2:generate-e2e-template": {
|
|
3688
|
-
const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3726
|
+
const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3689
3727
|
const p2args = args.slice(1);
|
|
3690
3728
|
const result = await mod.generateE2ETemplateHandler.handle(p2args);
|
|
3691
3729
|
console.log(result.stdout);
|
|
@@ -3694,7 +3732,7 @@ Examples:
|
|
|
3694
3732
|
}
|
|
3695
3733
|
|
|
3696
3734
|
case "p2:check-initial-creation": {
|
|
3697
|
-
const mod = buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3735
|
+
const mod = (await import("./phase2-extensions/composition-root.js")).buildPhase2Extensions(rootDir, resolvedConfig ?? undefined);
|
|
3698
3736
|
const p2args = args.slice(1);
|
|
3699
3737
|
const result = await mod.checkInitialCreationExpirationHandler.handle(p2args);
|
|
3700
3738
|
console.log(result.stdout);
|