phasegate 0.152.7 → 0.152.9
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/README.md +17 -1
- package/docs/ADR/ADR-002-pre-commit-validators.md +5 -2
- package/docs/ADR/ADR-004-scheduled-validators.md +4 -2
- package/docs/ADR/ADR-013-story-reflection-gate.md +2 -2
- package/docs/guide/cli-reference.md +4 -2
- package/docs/guide/configuration.md +9 -0
- package/docs/guide/getting-started.md +64 -0
- package/docs/guide/installation.md +13 -4
- package/docs/guide/recipes.md +65 -0
- package/docs/guide/setup-artifacts.md +21 -1
- package/docs/guide/troubleshooting.md +60 -0
- package/docs/templates/agent-context/AGENTS.md.template.md +45 -0
- package/docs/templates/agent-context/CLAUDE.md.template.md +4 -0
- package/package.json +1 -1
- package/scripts/harness/ci-governance/infrastructure/adapters/agents-md-file-adapter.ts +31 -5
- package/scripts/harness/installation/application/usecases/run-install.ts +78 -4
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +57 -4
- package/scripts/harness/installation/application/usecases/run-uninstall.ts +13 -1
- package/scripts/harness/installation/presentation/cli/install-handler.ts +7 -0
- package/scripts/harness/main.ts +293 -1
- package/skills/phasegate-config-doctor/SKILL.md +4 -0
- package/skills/phasegate-toolkit-guide/SKILL.md +5 -0
package/scripts/harness/main.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @layer presentation
|
|
4
4
|
* @work-item-id WI-090 / WI-091
|
|
5
5
|
* @work-item-id WI-113 / WI-142
|
|
6
|
+
* @work-item-id WI-171 / WI-172 / WI-173
|
|
6
7
|
*
|
|
7
8
|
* Phasegate CLI エントリポイント。
|
|
8
9
|
* 各Unitの Composition Root からハンドラーを取得し、コマンドに応じてディスパッチする。
|
|
@@ -155,6 +156,8 @@ Setup:
|
|
|
155
156
|
install Install phasegate managed files (--dry-run|--apply, --force)
|
|
156
157
|
uninstall Uninstall phasegate managed files (--dry-run|--apply, --force)
|
|
157
158
|
reconcile Reconcile phasegate managed files (--dry-run|--apply, --force)
|
|
159
|
+
setup:agent Diagnose repo setup and produce/apply an agent-readable setup plan
|
|
160
|
+
config:plan Produce an agent-readable configuration change plan
|
|
158
161
|
|
|
159
162
|
Commands:
|
|
160
163
|
enable-feature <name> Enable a harness feature
|
|
@@ -193,6 +196,8 @@ Commands:
|
|
|
193
196
|
ci:auto-refresh-agent-context Refresh AGENTS.md / CLAUDE.md (--dry-run, --apply, --json)
|
|
194
197
|
refresh-claude-md Refresh CLAUDE.md standard sections (--dry-run, --apply, --json)
|
|
195
198
|
p2:check-agent-context Check AGENTS.md / CLAUDE.md freshness (--threshold-days <n>, --json)
|
|
199
|
+
setup:agent Plan agent-driven setup (--intent <minimal|recommended|strict|ci-only|agent-hooks|retrofit>, --agent <claude|codex|both>, --dry-run|--apply, --json)
|
|
200
|
+
config:plan Plan safe config changes (--intent <l4-strict|codex-hooks|ci-fail-on-warning|baseline-reset|quick-mode-strict>, --dry-run, --json)
|
|
196
201
|
ci:check-repetition Check error repetition (--code <errorCode>, --reset, --json)
|
|
197
202
|
baseline Create retrofit baseline snapshot (--dry-run, --force, --paths <glob,glob,...>, --json)
|
|
198
203
|
scaffold-design Scaffold a design doc (--unit <id>, --phase <logical|domain|uiux|unit-test|it-test>, --force, --json)
|
|
@@ -482,8 +487,38 @@ Options:
|
|
|
482
487
|
--dry-run Preview target actions without writing (default)
|
|
483
488
|
--apply Write merge results and manifest
|
|
484
489
|
--force Force ai-assisted/manual targets after backing up existing files
|
|
490
|
+
--agent <claude|codex|both> Agent context and hook targets (default: both)
|
|
491
|
+
--skills <core|all> Rendered agent context skill mode (default: all)
|
|
492
|
+
--workflow <standard|strict> Rendered agent context workflow mode (default: standard)
|
|
493
|
+
--with-husky Include Husky hook targets
|
|
494
|
+
--with-ci Include GitHub Actions target
|
|
485
495
|
--json Output machine-readable JSON
|
|
486
496
|
--help, -h Show this help`,
|
|
497
|
+
"setup:agent": `Usage: phasegate setup:agent [options]
|
|
498
|
+
|
|
499
|
+
Diagnose repository setup and produce an agent-readable setup plan.
|
|
500
|
+
|
|
501
|
+
Options:
|
|
502
|
+
--intent <minimal|recommended|strict|ci-only|agent-hooks|retrofit>
|
|
503
|
+
--agent <claude|codex|both>
|
|
504
|
+
--workflow <standard|strict>
|
|
505
|
+
--with-husky
|
|
506
|
+
--with-ci
|
|
507
|
+
--dry-run
|
|
508
|
+
--apply
|
|
509
|
+
--json
|
|
510
|
+
--help, -h Show this help`,
|
|
511
|
+
"config:plan": `Usage: phasegate config:plan --intent <intent> [options]
|
|
512
|
+
|
|
513
|
+
Produce an agent-readable configuration change plan.
|
|
514
|
+
|
|
515
|
+
Intents:
|
|
516
|
+
l4-strict, codex-hooks, ci-fail-on-warning, baseline-reset, quick-mode-strict
|
|
517
|
+
|
|
518
|
+
Options:
|
|
519
|
+
--dry-run
|
|
520
|
+
--json
|
|
521
|
+
--help, -h Show this help`,
|
|
487
522
|
reconcile: `Usage: phasegate reconcile [options]
|
|
488
523
|
|
|
489
524
|
Reconcile PhaseGate-managed files with the current bundled templates.
|
|
@@ -685,6 +720,9 @@ function parseCoverageThreshold(raw: string | undefined): number {
|
|
|
685
720
|
}
|
|
686
721
|
|
|
687
722
|
type InitPhasePreset = "full" | "standard" | "minimal" | "custom";
|
|
723
|
+
type AgentTarget = "claude" | "codex" | "both";
|
|
724
|
+
type SetupIntent = "minimal" | "recommended" | "strict" | "ci-only" | "agent-hooks" | "retrofit";
|
|
725
|
+
type ConfigChangeIntent = "l4-strict" | "codex-hooks" | "ci-fail-on-warning" | "baseline-reset" | "quick-mode-strict";
|
|
688
726
|
|
|
689
727
|
function parseInitPhasePreset(value: string | undefined): InitPhasePreset | undefined {
|
|
690
728
|
if (value === undefined) return undefined;
|
|
@@ -694,6 +732,149 @@ function parseInitPhasePreset(value: string | undefined): InitPhasePreset | unde
|
|
|
694
732
|
return undefined;
|
|
695
733
|
}
|
|
696
734
|
|
|
735
|
+
function parseAgentTarget(value: string | undefined, fallback: AgentTarget = "both"): AgentTarget {
|
|
736
|
+
if (value === "claude" || value === "codex" || value === "both") return value;
|
|
737
|
+
return fallback;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
function parseSetupIntent(value: string | undefined): SetupIntent {
|
|
741
|
+
if (
|
|
742
|
+
value === "minimal" ||
|
|
743
|
+
value === "recommended" ||
|
|
744
|
+
value === "strict" ||
|
|
745
|
+
value === "ci-only" ||
|
|
746
|
+
value === "agent-hooks" ||
|
|
747
|
+
value === "retrofit"
|
|
748
|
+
) {
|
|
749
|
+
return value;
|
|
750
|
+
}
|
|
751
|
+
return "recommended";
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
function parseConfigChangeIntent(value: string | undefined): ConfigChangeIntent {
|
|
755
|
+
if (
|
|
756
|
+
value === "l4-strict" ||
|
|
757
|
+
value === "codex-hooks" ||
|
|
758
|
+
value === "ci-fail-on-warning" ||
|
|
759
|
+
value === "baseline-reset" ||
|
|
760
|
+
value === "quick-mode-strict"
|
|
761
|
+
) {
|
|
762
|
+
return value;
|
|
763
|
+
}
|
|
764
|
+
return "l4-strict";
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
async function projectFileExists(rootDir: string, relativePath: string): Promise<boolean> {
|
|
768
|
+
try {
|
|
769
|
+
await fsReadFile(join(rootDir, relativePath));
|
|
770
|
+
return true;
|
|
771
|
+
} catch {
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
async function buildAgentSetupPlan(rootDir: string, input: {
|
|
777
|
+
readonly intent: SetupIntent;
|
|
778
|
+
readonly agent: AgentTarget;
|
|
779
|
+
readonly withHusky: boolean;
|
|
780
|
+
readonly withCi: boolean;
|
|
781
|
+
readonly workflow: WorkflowMode;
|
|
782
|
+
}) {
|
|
783
|
+
const checks = {
|
|
784
|
+
packageJson: await projectFileExists(rootDir, "package.json"),
|
|
785
|
+
phasegateConfig: await projectFileExists(rootDir, "phasegate.config.json"),
|
|
786
|
+
claudeSettings: await projectFileExists(rootDir, ".claude/settings.json"),
|
|
787
|
+
codexHooks: await projectFileExists(rootDir, ".codex/hooks.json"),
|
|
788
|
+
agentsMd: await projectFileExists(rootDir, "AGENTS.md"),
|
|
789
|
+
claudeMd: await projectFileExists(rootDir, "CLAUDE.md"),
|
|
790
|
+
huskyPreCommit: await projectFileExists(rootDir, ".husky/pre-commit"),
|
|
791
|
+
ciWorkflow: await projectFileExists(rootDir, ".github/workflows/phasegate-aidlc-gate.yml"),
|
|
792
|
+
};
|
|
793
|
+
const includeClaude = input.agent === "claude" || input.agent === "both";
|
|
794
|
+
const includeCodex = input.agent === "codex" || input.agent === "both";
|
|
795
|
+
const changes = [
|
|
796
|
+
!checks.packageJson ? "Add phasegate devDependency and phasegate scripts to package.json." : "Keep existing package.json and merge missing phasegate scripts only.",
|
|
797
|
+
!checks.phasegateConfig ? `Create phasegate.config.json for ${input.workflow} workflow.` : "Keep existing phasegate.config.json; review config:plan before changing policy.",
|
|
798
|
+
includeClaude ? "Create or refresh .claude/settings.json and CLAUDE.md managed section." : null,
|
|
799
|
+
includeCodex ? "Create or refresh .codex/hooks.json and AGENTS.md managed section." : null,
|
|
800
|
+
input.withHusky ? "Create or refresh Husky pre-commit, commit-msg, and pre-push backstops." : "Leave Husky hooks unmanaged in this setup run.",
|
|
801
|
+
input.withCi ? "Create or refresh GitHub Actions PhaseGate workflow." : "Leave CI workflow unmanaged in this setup run.",
|
|
802
|
+
].filter((item): item is string => item !== null);
|
|
803
|
+
const questions = [
|
|
804
|
+
input.intent === "recommended" ? "Do you want both Claude and Codex context files, or only the agent you actively use?" : null,
|
|
805
|
+
input.intent === "retrofit" ? "Should existing hooks/workflows be preserved as user-owned content or migrated into PhaseGate managed blocks?" : null,
|
|
806
|
+
input.intent === "ci-only" ? "Should local hooks remain disabled while CI enforces the same checks?" : null,
|
|
807
|
+
input.workflow !== "strict" ? "Do you want strict WI/product reflection enforcement now, or after the first green run?" : null,
|
|
808
|
+
].filter((item): item is string => item !== null);
|
|
809
|
+
return {
|
|
810
|
+
intent: input.intent,
|
|
811
|
+
agent: input.agent,
|
|
812
|
+
detected: checks,
|
|
813
|
+
questions,
|
|
814
|
+
changes,
|
|
815
|
+
risks: [
|
|
816
|
+
"Existing user content outside PhaseGate managed markers is preserved.",
|
|
817
|
+
"Manual review is still required when a managed target has complex user edits and --force is not used.",
|
|
818
|
+
],
|
|
819
|
+
rollback: [
|
|
820
|
+
"Run phasegate uninstall --dry-run to preview reversal.",
|
|
821
|
+
"Run phasegate uninstall --apply after reviewing the managed targets.",
|
|
822
|
+
"Backups are written under .phasegate/backups when force is used on changed managed files.",
|
|
823
|
+
],
|
|
824
|
+
validation: [
|
|
825
|
+
"phasegate doctor",
|
|
826
|
+
"phasegate phasegate:check-ready",
|
|
827
|
+
"phasegate validate --layer L2 --format human",
|
|
828
|
+
],
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
function buildConfigChangePlan(intent: ConfigChangeIntent) {
|
|
833
|
+
const catalog: Record<ConfigChangeIntent, {
|
|
834
|
+
readonly targets: readonly string[];
|
|
835
|
+
readonly commands: readonly string[];
|
|
836
|
+
readonly validations: readonly string[];
|
|
837
|
+
readonly risks: readonly string[];
|
|
838
|
+
}> = {
|
|
839
|
+
"l4-strict": {
|
|
840
|
+
targets: ["phasegate.config.json: layers.L4.enabled", "phasegate.config.json: layers.L4.failOnWarning"],
|
|
841
|
+
commands: ["phasegate validate --layer L4 --fail-on-warning --format human"],
|
|
842
|
+
validations: ["phasegate phasegate:detect-drift --json", "phasegate phasegate:check-ready"],
|
|
843
|
+
risks: ["L4 findings may be advisory today but become blocking when fail-on-warning is enabled."],
|
|
844
|
+
},
|
|
845
|
+
"codex-hooks": {
|
|
846
|
+
targets: [".codex/hooks.json", "AGENTS.md", ".codex/skills"],
|
|
847
|
+
commands: ["phasegate install --agent codex --apply", "codex features enable codex_hooks"],
|
|
848
|
+
validations: ["phasegate doctor --json", "phasegate phasegate:status --json"],
|
|
849
|
+
risks: ["Codex apply_patch writes still require the pre-commit backstop for full coverage."],
|
|
850
|
+
},
|
|
851
|
+
"ci-fail-on-warning": {
|
|
852
|
+
targets: [".github/workflows/phasegate-aidlc-gate.yml", "phasegate.config.json"],
|
|
853
|
+
commands: ["phasegate install --with-ci --apply", "phasegate validate --layer L4 --fail-on-warning"],
|
|
854
|
+
validations: ["phasegate doctor", "phasegate ci:generate-template --type aidlc-gate --render"],
|
|
855
|
+
risks: ["Existing warning-only projects may start failing CI after rollout."],
|
|
856
|
+
},
|
|
857
|
+
"baseline-reset": {
|
|
858
|
+
targets: [".phasegate/baseline.json"],
|
|
859
|
+
commands: ["phasegate baseline --dry-run", "phasegate baseline --force --json"],
|
|
860
|
+
validations: ["phasegate phasegate:status --json", "phasegate phasegate:check-ready"],
|
|
861
|
+
risks: ["A reset can hide historical drift if reviewed without the generated diff."],
|
|
862
|
+
},
|
|
863
|
+
"quick-mode-strict": {
|
|
864
|
+
targets: ["phasegate.config.json: quickMode"],
|
|
865
|
+
commands: ["phasegate check-change-category --paths <changed-files> --format json"],
|
|
866
|
+
validations: ["phasegate ci-check --quick --dry-run", "phasegate phasegate:check-ready"],
|
|
867
|
+
risks: ["More changes will require Full Mode validation before commit."],
|
|
868
|
+
},
|
|
869
|
+
};
|
|
870
|
+
return {
|
|
871
|
+
intent,
|
|
872
|
+
...catalog[intent],
|
|
873
|
+
diffExplanation: "Review the listed targets first, apply through PhaseGate managed commands where possible, then run the validations in order.",
|
|
874
|
+
rollback: "Use git diff for config changes; use phasegate uninstall/reconcile dry-runs for managed setup targets.",
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
|
|
697
878
|
type RuleSeverity = "error" | "warning" | "off";
|
|
698
879
|
|
|
699
880
|
function toRuleSeverity(value: string): RuleSeverity {
|
|
@@ -999,6 +1180,9 @@ async function main(): Promise<void> {
|
|
|
999
1180
|
includeCodex: deployCodex,
|
|
1000
1181
|
includeHusky: withHusky,
|
|
1001
1182
|
includeCi: withCi,
|
|
1183
|
+
skillSet,
|
|
1184
|
+
workflow,
|
|
1185
|
+
agent,
|
|
1002
1186
|
});
|
|
1003
1187
|
console.log(
|
|
1004
1188
|
`✓ Skills deployed to ${result.targetDir} (${result.deployedSkills.length} skills, set: ${skillSet})`,
|
|
@@ -1196,7 +1380,7 @@ async function main(): Promise<void> {
|
|
|
1196
1380
|
}
|
|
1197
1381
|
|
|
1198
1382
|
case "install": {
|
|
1199
|
-
const KNOWN_INSTALL_FLAGS = ["--dry-run", "--apply", "--force", "--json"];
|
|
1383
|
+
const KNOWN_INSTALL_FLAGS = ["--dry-run", "--apply", "--force", "--json", "--agent", "--skills", "--workflow", "--with-husky", "--with-ci"];
|
|
1200
1384
|
const flagError = validateKnownFlags(args, KNOWN_INSTALL_FLAGS);
|
|
1201
1385
|
if (flagError) {
|
|
1202
1386
|
console.error(flagError);
|
|
@@ -1204,6 +1388,19 @@ async function main(): Promise<void> {
|
|
|
1204
1388
|
}
|
|
1205
1389
|
const apply = hasFlag(args, "--apply");
|
|
1206
1390
|
const dryRun = hasFlag(args, "--dry-run") || !apply;
|
|
1391
|
+
const agent = parseAgentTarget(parseFlag(args, "--agent"), "both");
|
|
1392
|
+
const skillSetRaw = parseFlag(args, "--skills") ?? "all";
|
|
1393
|
+
if (skillSetRaw !== "core" && skillSetRaw !== "all") {
|
|
1394
|
+
console.error(`Invalid --skills value: "${skillSetRaw}". Use "core" or "all".`);
|
|
1395
|
+
process.exit(2);
|
|
1396
|
+
}
|
|
1397
|
+
const workflowRaw = parseFlag(args, "--workflow");
|
|
1398
|
+
if (workflowRaw !== undefined && workflowRaw !== "standard" && workflowRaw !== "strict") {
|
|
1399
|
+
console.error(`Invalid --workflow value: "${workflowRaw}". Use "standard" or "strict".`);
|
|
1400
|
+
process.exit(2);
|
|
1401
|
+
}
|
|
1402
|
+
const includeClaude = agent === "claude" || agent === "both";
|
|
1403
|
+
const includeCodex = agent === "codex" || agent === "both";
|
|
1207
1404
|
const mod = createInstallationModule();
|
|
1208
1405
|
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
1209
1406
|
const result = await mod.installHandler.execute({
|
|
@@ -1213,6 +1410,13 @@ async function main(): Promise<void> {
|
|
|
1213
1410
|
dryRun,
|
|
1214
1411
|
apply,
|
|
1215
1412
|
force: hasFlag(args, "--force"),
|
|
1413
|
+
includeClaude,
|
|
1414
|
+
includeCodex,
|
|
1415
|
+
includeHusky: true,
|
|
1416
|
+
includeCi: true,
|
|
1417
|
+
skillSet: skillSetRaw,
|
|
1418
|
+
workflow: parseWorkflowMode(workflowRaw),
|
|
1419
|
+
agent,
|
|
1216
1420
|
json,
|
|
1217
1421
|
});
|
|
1218
1422
|
console.log(result.stdout);
|
|
@@ -1220,6 +1424,94 @@ async function main(): Promise<void> {
|
|
|
1220
1424
|
break;
|
|
1221
1425
|
}
|
|
1222
1426
|
|
|
1427
|
+
case "setup:agent": {
|
|
1428
|
+
const KNOWN_SETUP_AGENT_FLAGS = ["--intent", "--agent", "--workflow", "--with-husky", "--with-ci", "--dry-run", "--apply", "--force", "--json"];
|
|
1429
|
+
const flagError = validateKnownFlags(args, KNOWN_SETUP_AGENT_FLAGS);
|
|
1430
|
+
if (flagError) {
|
|
1431
|
+
console.error(flagError);
|
|
1432
|
+
process.exit(2);
|
|
1433
|
+
}
|
|
1434
|
+
const intent = parseSetupIntent(parseFlag(args, "--intent"));
|
|
1435
|
+
const agent = parseAgentTarget(parseFlag(args, "--agent"), "both");
|
|
1436
|
+
const workflow = parseWorkflowMode(parseFlag(args, "--workflow") ?? (intent === "strict" ? "strict" : "standard"));
|
|
1437
|
+
const withCi = hasFlag(args, "--with-ci") || intent === "ci-only" || intent === "strict";
|
|
1438
|
+
const withHusky = hasFlag(args, "--with-husky") || intent === "agent-hooks" || intent === "strict";
|
|
1439
|
+
const plan = await buildAgentSetupPlan(rootDir, { intent, agent, withHusky, withCi, workflow });
|
|
1440
|
+
const apply = hasFlag(args, "--apply");
|
|
1441
|
+
let installResult: unknown = null;
|
|
1442
|
+
let bootstrapResult: unknown = null;
|
|
1443
|
+
if (apply) {
|
|
1444
|
+
const skillResult = await deploySkills(harnessRoot, rootDir, "all");
|
|
1445
|
+
const packageResult = await ensurePhasegatePackageDependency(rootDir, skillResult.version);
|
|
1446
|
+
const configResult = await initHarnessConfig(rootDir, "my-project", workflow === "strict" ? "full" : "standard", {
|
|
1447
|
+
ciEnabled: withCi,
|
|
1448
|
+
workflow,
|
|
1449
|
+
});
|
|
1450
|
+
bootstrapResult = {
|
|
1451
|
+
skillsDeployed: skillResult.deployedSkills.length,
|
|
1452
|
+
packageDependency: packageResult,
|
|
1453
|
+
configCreated: configResult.created,
|
|
1454
|
+
};
|
|
1455
|
+
const mod = createInstallationModule();
|
|
1456
|
+
const phasegateVersion = await getHarnessVersion(harnessRoot);
|
|
1457
|
+
installResult = await mod.runInstallUseCase.execute({
|
|
1458
|
+
projectRoot: rootDir,
|
|
1459
|
+
harnessRoot,
|
|
1460
|
+
phasegateVersion,
|
|
1461
|
+
dryRun: false,
|
|
1462
|
+
apply: true,
|
|
1463
|
+
force: hasFlag(args, "--force"),
|
|
1464
|
+
includeClaude: agent === "claude" || agent === "both",
|
|
1465
|
+
includeCodex: agent === "codex" || agent === "both",
|
|
1466
|
+
includeHusky: withHusky,
|
|
1467
|
+
includeCi: withCi,
|
|
1468
|
+
skillSet: "all",
|
|
1469
|
+
workflow,
|
|
1470
|
+
agent,
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
const output = { plan, applied: apply, bootstrapResult, installResult };
|
|
1474
|
+
if (json) {
|
|
1475
|
+
console.log(JSON.stringify(output, null, 2));
|
|
1476
|
+
} else {
|
|
1477
|
+
console.log(`phasegate setup:agent ${apply ? "apply" : "dry-run"} (${intent}, ${agent})`);
|
|
1478
|
+
for (const change of plan.changes) console.log(`- ${change}`);
|
|
1479
|
+
if (plan.questions.length > 0) {
|
|
1480
|
+
console.log("");
|
|
1481
|
+
console.log("Questions:");
|
|
1482
|
+
for (const question of plan.questions) console.log(`- ${question}`);
|
|
1483
|
+
}
|
|
1484
|
+
console.log("");
|
|
1485
|
+
console.log("Validation:");
|
|
1486
|
+
for (const command of plan.validation) console.log(`- ${command}`);
|
|
1487
|
+
}
|
|
1488
|
+
process.exit(0);
|
|
1489
|
+
break;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
case "config:plan": {
|
|
1493
|
+
const KNOWN_CONFIG_PLAN_FLAGS = ["--intent", "--dry-run", "--json"];
|
|
1494
|
+
const flagError = validateKnownFlags(args, KNOWN_CONFIG_PLAN_FLAGS);
|
|
1495
|
+
if (flagError) {
|
|
1496
|
+
console.error(flagError);
|
|
1497
|
+
process.exit(2);
|
|
1498
|
+
}
|
|
1499
|
+
const plan = buildConfigChangePlan(parseConfigChangeIntent(parseFlag(args, "--intent")));
|
|
1500
|
+
if (json) {
|
|
1501
|
+
console.log(JSON.stringify(plan, null, 2));
|
|
1502
|
+
} else {
|
|
1503
|
+
console.log(`phasegate config:plan (${plan.intent})`);
|
|
1504
|
+
console.log("Targets:");
|
|
1505
|
+
for (const target of plan.targets) console.log(`- ${target}`);
|
|
1506
|
+
console.log("Commands:");
|
|
1507
|
+
for (const command of plan.commands) console.log(`- ${command}`);
|
|
1508
|
+
console.log("Validation:");
|
|
1509
|
+
for (const validation of plan.validations) console.log(`- ${validation}`);
|
|
1510
|
+
}
|
|
1511
|
+
process.exit(0);
|
|
1512
|
+
break;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1223
1515
|
case "uninstall": {
|
|
1224
1516
|
const KNOWN_UNINSTALL_FLAGS = ["--dry-run", "--apply", "--force", "--json"];
|
|
1225
1517
|
const flagError = validateKnownFlags(args, KNOWN_UNINSTALL_FLAGS);
|
|
@@ -39,6 +39,7 @@ phasegate を導入した直後の config は単純な default で、実プロ
|
|
|
39
39
|
| Codex hooks | `.codex/hooks.json` | managed hook JSON と Codex hook 配線確認 |
|
|
40
40
|
| Husky scripts | `.husky/pre-commit`, `.husky/commit-msg`, `.husky/pre-push` | pre-commit backstop と bypass audit の確認 |
|
|
41
41
|
| CI workflows | `.github/workflows/*` | `phasegate-aidlc-gate.yml` や既存 workflow との競合確認 |
|
|
42
|
+
| agent context | `AGENTS.md`, `CLAUDE.md` | PhaseGate managed section、lesson pointer section、user-owned content の境界確認 |
|
|
42
43
|
|
|
43
44
|
**schema は必要なときだけ Read** (enum 違反疑い時など): `node_modules/phasegate/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json` (or `harness-config-v2.schema.json` if v2)。
|
|
44
45
|
|
|
@@ -131,6 +132,9 @@ product-architect で Unit を作り、いくつかの logical_design を書い
|
|
|
131
132
|
- reconcile / uninstall が refuse → user modified managed target として扱い、`--force` のリスクと backup path を説明して承認を取る
|
|
132
133
|
- Codex の `codex_hooks` feature flag は user-level setting。project-local `install` では変更されないため、必要なら `codex features enable codex_hooks` を案内
|
|
133
134
|
- Codex native `apply_patch` bypass は hook で完全捕捉できない。`.husky/pre-commit` の `phasegate pre-commit` が backstop になるため、Husky 配線を診断対象に含める
|
|
135
|
+
- 初回 setup / retrofit / CI-only / agent-hooks の判断が曖昧な場合は `npx phasegate setup:agent --dry-run --json` を先に使い、検出済み状態、質問、変更案、rollback、validation を根拠として提案する。<!-- @work-item-id WI-172 -->
|
|
136
|
+
- 「L4 を厳しめにして」「Codex hook を有効にして」「CI で warning を fail にして」などの自然言語依頼は、`npx phasegate config:plan --intent <intent> --dry-run --json` で対象ファイル、コマンド、リスク、検証を確認してから diff を提案する。<!-- @work-item-id WI-173 -->
|
|
137
|
+
- `AGENTS.md` は標準運用ルールの managed section と lesson pointer section を分ける。`ci:auto-refresh-agent-context --apply` は lesson pointers 専用 section を更新し、標準運用ルールや user-owned content を置換してはいけない。<!-- @work-item-id WI-174 -->
|
|
134
138
|
|
|
135
139
|
### Step 3: 診断レポート
|
|
136
140
|
|
|
@@ -123,12 +123,17 @@ docs/guide/ # phasegate リポジトリ自体 (dogfood)
|
|
|
123
123
|
- 「.phasegate/manifest.json や hook-skip-events は何?」
|
|
124
124
|
|
|
125
125
|
**参照先**:
|
|
126
|
+
- 最短導線: `docs/guide/getting-started.md`
|
|
127
|
+
- recipes: `docs/guide/recipes.md`
|
|
128
|
+
- troubleshooting: `docs/guide/troubleshooting.md`
|
|
126
129
|
- 新規導入: `docs/guide/installation.md`
|
|
127
130
|
- 既存プロジェクト導入: `docs/guide/retrofit-adoption.md`
|
|
128
131
|
- setup artifact / doctor finding / legacy artifact: `docs/guide/setup-artifacts.md`
|
|
129
132
|
|
|
130
133
|
`setup-artifacts.md` は managed target / generated artifact / runtime state / legacy artifact / user-level setting の分類を持つ。`doctor --report-out` は明示 path への出力で、`.phasegate/last-doctor-report.json` は固定生成物ではない点もここを参照する。<!-- @work-item-id WI-153 -->
|
|
131
134
|
|
|
135
|
+
`setup:agent` は初回 setup / retrofit / CI-only / agent hook 有効化の agent-readable planner、`config:plan` は安全な設定変更 intent planner。質問が「次に何を実行するか」「この変更はどの file/validation に対応するか」に寄っている場合は、これらの guide と CLI を案内する。<!-- @work-item-id WI-171, WI-172, WI-173 -->
|
|
136
|
+
|
|
132
137
|
### 8. skill 一覧と使い分け
|
|
133
138
|
|
|
134
139
|
ユーザー質問例:
|