@opengsd/gsd-core 1.18.0 → 1.19.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -1
- package/.opencode/plugins/gsd-core.js +2 -3
- package/agents/gsd-code-fixer.compact.md +2 -2
- package/agents/gsd-code-fixer.md +4 -3
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +422 -103
- package/gsd-core/bin/gsd-tools.cjs +106 -7
- package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
- package/gsd-core/bin/lib/args-terminator.cjs +114 -0
- package/gsd-core/bin/lib/broken-windows.cjs +59 -1
- package/gsd-core/bin/lib/capability-lock.cjs +13 -2
- package/gsd-core/bin/lib/capability-registry.cjs +156 -74
- package/gsd-core/bin/lib/capability-state.cjs +14 -8
- package/gsd-core/bin/lib/capability-validator.cjs +17 -0
- package/gsd-core/bin/lib/config-loader.cjs +10 -0
- package/gsd-core/bin/lib/config.cjs +256 -58
- package/gsd-core/bin/lib/core-utils.cjs +34 -0
- package/gsd-core/bin/lib/decision-coverage-support.cjs +74 -0
- package/gsd-core/bin/lib/gate-context-drift.cjs +8 -3
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +6 -1
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +6 -1
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +63 -22
- package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
- package/gsd-core/bin/lib/git-info-exclude.cjs +57 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +18 -3
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
- package/gsd-core/bin/lib/host-integration.cjs +13 -6
- package/gsd-core/bin/lib/init.cjs +65 -1
- package/gsd-core/bin/lib/install-engine.cjs +246 -32
- package/gsd-core/bin/lib/install-profiles.cjs +9 -4
- package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
- package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +113 -0
- package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
- package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
- package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
- package/gsd-core/bin/lib/milestone.cjs +43 -1
- package/gsd-core/bin/lib/model-catalog.cjs +8 -0
- package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
- package/gsd-core/bin/lib/phase-id.cjs +21 -4
- package/gsd-core/bin/lib/phase-lifecycle.cjs +37 -4
- package/gsd-core/bin/lib/phase.cjs +115 -26
- package/gsd-core/bin/lib/planning-snapshot.cjs +3 -1
- package/gsd-core/bin/lib/planning-workspace.cjs +18 -0
- package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
- package/gsd-core/bin/lib/read-only-git-env.cjs +58 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +35 -2
- package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
- package/gsd-core/bin/lib/roadmap-parser.cjs +12 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +39 -2
- package/gsd-core/bin/lib/roadmap.cjs +33 -25
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +381 -14
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
- package/gsd-core/bin/lib/shell-command-projection.cjs +121 -16
- package/gsd-core/bin/lib/smart-entry.cjs +13 -0
- package/gsd-core/bin/lib/state-contract.cjs +29 -9
- package/gsd-core/bin/lib/state-document.cjs +12 -4
- package/gsd-core/bin/lib/state-transition.cjs +119 -24
- package/gsd-core/bin/lib/state.cjs +50 -28
- package/gsd-core/bin/lib/surface.cjs +9 -0
- package/gsd-core/bin/lib/task-command-router.cjs +5 -25
- package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
- package/gsd-core/bin/lib/verification.cjs +96 -9
- package/gsd-core/bin/lib/verify.cjs +2 -0
- package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
- package/gsd-core/references/git-integration.md +11 -0
- package/gsd-core/references/loop-hook-dispatch.md +13 -6
- package/gsd-core/references/planning-config.md +2 -0
- package/gsd-core/references/tdd.md +2 -2
- package/gsd-core/templates/DEBUG.md +16 -0
- package/gsd-core/templates/config.json +2 -1
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/audit-fix.md +2 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
- package/gsd-core/workflows/code-review.md +61 -7
- package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
- package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
- package/gsd-core/workflows/complete-milestone.md +37 -150
- package/gsd-core/workflows/diagnose-issues.md +29 -5
- package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +33 -2
- package/gsd-core/workflows/discuss-phase-power.md +19 -2
- package/gsd-core/workflows/discuss-phase.md +6 -10
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +7 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
- package/gsd-core/workflows/execute-phase.md +9 -5
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +2 -2
- package/gsd-core/workflows/plan-phase.md +13 -13
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
- package/gsd-core/workflows/quick.md +1 -1
- package/gsd-core/workflows/review.md +16 -13
- package/gsd-core/workflows/section-manifest.json +5 -0
- package/gsd-core/workflows/settings.md +1 -0
- package/gsd-core/workflows/ship.md +3 -4
- package/gsd-core/workflows/spec-phase.md +3 -6
- package/gsd-core/workflows/verify-work.md +4 -3
- package/hooks/dist/gsd-agent-isolation-guard.js +11 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-path-export.js +95 -0
- package/hooks/dist/gsd-secret-read-guard.js +172 -39
- package/hooks/dist/gsd-statusline.js +35 -2
- package/hooks/dist/gsd-windsurf-pre-write.js +28 -1
- package/hooks/dist/gsd-workflow-guard.js +1 -1
- package/hooks/dist/gsd-worktree-path-guard.js +28 -1
- package/hooks/dist/lib/isolation-sentinel.js +44 -0
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +11 -1
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-path-export.js +95 -0
- package/hooks/gsd-secret-read-guard.js +172 -39
- package/hooks/gsd-statusline.js +35 -2
- package/hooks/gsd-windsurf-pre-write.js +28 -1
- package/hooks/gsd-workflow-guard.js +1 -1
- package/hooks/gsd-worktree-path-guard.js +28 -1
- package/hooks/hooks.json +1 -0
- package/hooks/lib/isolation-sentinel.js +44 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +13 -6
- package/pi/gsd.cjs +1047 -10
- package/pi/package-agents/gsd-advisor-researcher.md +113 -0
- package/pi/package-agents/gsd-ai-researcher.md +111 -0
- package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
- package/pi/package-agents/gsd-code-fixer.md +769 -0
- package/pi/package-agents/gsd-code-reviewer.md +402 -0
- package/pi/package-agents/gsd-codebase-mapper.md +850 -0
- package/pi/package-agents/gsd-debug-session-manager.md +416 -0
- package/pi/package-agents/gsd-debugger.md +1274 -0
- package/pi/package-agents/gsd-doc-classifier.md +269 -0
- package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
- package/pi/package-agents/gsd-doc-verifier.md +212 -0
- package/pi/package-agents/gsd-doc-writer.md +626 -0
- package/pi/package-agents/gsd-dom-verifier.md +164 -0
- package/pi/package-agents/gsd-domain-researcher.md +144 -0
- package/pi/package-agents/gsd-eval-auditor.md +185 -0
- package/pi/package-agents/gsd-eval-planner.md +149 -0
- package/pi/package-agents/gsd-executor.md +894 -0
- package/pi/package-agents/gsd-framework-selector.md +159 -0
- package/pi/package-agents/gsd-integration-checker.md +476 -0
- package/pi/package-agents/gsd-intel-updater.md +338 -0
- package/pi/package-agents/gsd-mempalace-curator.md +49 -0
- package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
- package/pi/package-agents/gsd-pattern-mapper.md +340 -0
- package/pi/package-agents/gsd-phase-researcher.md +897 -0
- package/pi/package-agents/gsd-plan-checker.md +1077 -0
- package/pi/package-agents/gsd-planner.md +1003 -0
- package/pi/package-agents/gsd-project-researcher.md +611 -0
- package/pi/package-agents/gsd-research-synthesizer.md +259 -0
- package/pi/package-agents/gsd-roadmapper.md +779 -0
- package/pi/package-agents/gsd-security-auditor.md +171 -0
- package/pi/package-agents/gsd-ui-auditor.md +581 -0
- package/pi/package-agents/gsd-ui-checker.md +417 -0
- package/pi/package-agents/gsd-ui-researcher.md +469 -0
- package/pi/package-agents/gsd-user-profiler.md +174 -0
- package/pi/package-agents/gsd-verifier.md +963 -0
- package/pi/package-agents/manifest.json +39 -0
- package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
- package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
- package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
- package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
- package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
- package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
- package/pi/package-skills/gsd-capture/SKILL.md +68 -0
- package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
- package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
- package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
- package/pi/package-skills/gsd-config/SKILL.md +60 -0
- package/pi/package-skills/gsd-debug/SKILL.md +64 -0
- package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
- package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
- package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-explore/SKILL.md +26 -0
- package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
- package/pi/package-skills/gsd-fast/SKILL.md +33 -0
- package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
- package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
- package/pi/package-skills/gsd-health/SKILL.md +36 -0
- package/pi/package-skills/gsd-help/SKILL.md +37 -0
- package/pi/package-skills/gsd-import/SKILL.md +46 -0
- package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
- package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
- package/pi/package-skills/gsd-manager/SKILL.md +46 -0
- package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
- package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
- package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
- package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
- package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
- package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
- package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
- package/pi/package-skills/gsd-next/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
- package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
- package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
- package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
- package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
- package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
- package/pi/package-skills/gsd-phase/SKILL.md +61 -0
- package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
- package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
- package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
- package/pi/package-skills/gsd-progress/SKILL.md +51 -0
- package/pi/package-skills/gsd-quick/SKILL.md +179 -0
- package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
- package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
- package/pi/package-skills/gsd-review/SKILL.md +50 -0
- package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
- package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-settings/SKILL.md +30 -0
- package/pi/package-skills/gsd-ship/SKILL.md +27 -0
- package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
- package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
- package/pi/package-skills/gsd-spike/SKILL.md +53 -0
- package/pi/package-skills/gsd-stats/SKILL.md +22 -0
- package/pi/package-skills/gsd-surface/SKILL.md +177 -0
- package/pi/package-skills/gsd-thread/SKILL.md +29 -0
- package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
- package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
- package/pi/package-skills/gsd-undo/SKILL.md +38 -0
- package/pi/package-skills/gsd-update/SKILL.md +51 -0
- package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
- package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
- package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
- package/scripts/build-hooks.js +4 -0
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +20 -7
- package/scripts/gen-health-docs.cjs +13 -1
- package/scripts/gen-pi-package-skills.cjs +217 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +11 -1
- package/scripts/lib/platform-conformance-tier.generated.cjs +26 -1
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
- package/scripts/lint-retired-runtime-name.cjs +5 -0
- package/scripts/npm-audit-baseline.cjs +41 -7
- package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
- package/scripts/select-docs-guards.cjs +1 -1
- package/scripts/self-test-report-policy.cjs +350 -0
- package/vscode/package.json +1 -1
- package/scripts/diagnose-validate-commit-in-tier.cjs +0 -270
- package/scripts/diagnose-validate-commit-phases.cjs +0 -348
- package/scripts/xtrace-phase-timing.cjs +0 -205
|
@@ -78,6 +78,17 @@ function isClosedMilestoneHeading(headingText) {
|
|
|
78
78
|
function stripShippedMilestones(content) {
|
|
79
79
|
return (0, markdown_sectionizer_cjs_1.stripTaggedBlocks)(content, 'details');
|
|
80
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* #5543: run `edit` over the ROADMAP with every shipped `<details>` block hidden
|
|
83
|
+
* and restored byte-for-byte afterwards. For writers whose active milestone
|
|
84
|
+
* could not be resolved: the first `### Phase N:` in document order must never
|
|
85
|
+
* be the one inside a shipped block. Layout-independent (the active phase may
|
|
86
|
+
* sit before or after a shipped block) and, unlike a "region after the last
|
|
87
|
+
* `</details>`" cut, not fooled by a `</details>` in a fence or inline code.
|
|
88
|
+
*/
|
|
89
|
+
function editOutsideShippedBlocks(content, edit) {
|
|
90
|
+
return (0, markdown_sectionizer_cjs_1.editOutsideTaggedBlocks)(content, 'details', edit);
|
|
91
|
+
}
|
|
81
92
|
/**
|
|
82
93
|
* #3982: strip only <details> blocks whose <summary> marks a CLOSED milestone
|
|
83
94
|
* (ARCHIVED/SHIPPED/✅/… without an active marker) — the narrow form of
|
|
@@ -2287,6 +2298,7 @@ module.exports = {
|
|
|
2287
2298
|
getMilestonePhaseFilter,
|
|
2288
2299
|
currentMilestoneRawRanges,
|
|
2289
2300
|
withPhaseSection,
|
|
2301
|
+
editOutsideShippedBlocks,
|
|
2290
2302
|
computeMilestoneSectionEnd,
|
|
2291
2303
|
locateMilestoneHeadings,
|
|
2292
2304
|
listMilestoneHeadings,
|
|
@@ -12,7 +12,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
};
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
-
const node_child_process_1 = require("node:child_process");
|
|
16
15
|
const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
|
|
17
16
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
18
17
|
const planningWorkspace = require("./planning-workspace.cjs");
|
|
@@ -1923,7 +1922,45 @@ function applyMigration(cwd, plan, options = {}) {
|
|
|
1923
1922
|
// ── Real run: verify clean working tree ───────────────────────────────────
|
|
1924
1923
|
let gitStatus;
|
|
1925
1924
|
try {
|
|
1926
|
-
|
|
1925
|
+
// #5048: this is a read-only spawn, but git still refreshes the index under
|
|
1926
|
+
// it and takes the optional `.git/index.lock` to write the refreshed copy
|
|
1927
|
+
// back — which can lose a race against a real `git add` / `git commit` in
|
|
1928
|
+
// the same repo. Routing through the shared execGit seam (CONTEXT.md, OS
|
|
1929
|
+
// Shell Projection) is what gets GIT_OPTIONAL_LOCKS=0 here; a bare execSync
|
|
1930
|
+
// bypassed the seam and therefore the opt-out, so this call site was the one
|
|
1931
|
+
// read-only `git status` the seam change did not reach. shell-free, so no
|
|
1932
|
+
// argv quoting or PATH-resolution policy is introduced.
|
|
1933
|
+
const statusTimeoutMs = 10_000;
|
|
1934
|
+
const result = (0, shell_command_projection_cjs_1.execGit)(['status', '--porcelain'], { cwd, timeout: statusTimeoutMs });
|
|
1935
|
+
// #5048: execSync carried the cause on the thrown error. execGit reports a
|
|
1936
|
+
// timeout, a spawn/buffer failure or a signal through `timedOut`/`error`/
|
|
1937
|
+
// `signal` with an exit code of `status ?? 1` and often an empty stderr.
|
|
1938
|
+
// Order matters: a maxBuffer overflow returns signal SIGTERM *and*
|
|
1939
|
+
// error.code ENOBUFS — check `error` before `signal` so the real cause is
|
|
1940
|
+
// not reported as "killed by SIGTERM". Only a genuine non-zero exit falls
|
|
1941
|
+
// through. (ENOENT is rewritten by `_spawnResult` to exit 127 + stderr.)
|
|
1942
|
+
if (result.timedOut) {
|
|
1943
|
+
throw new Error(`git status timed out after ${statusTimeoutMs} ms`);
|
|
1944
|
+
}
|
|
1945
|
+
if (result.error) {
|
|
1946
|
+
// The cause is not always a failed spawn: ENOBUFS and EPERM reach this
|
|
1947
|
+
// branch with the process already started (a maxBuffer overflow returns
|
|
1948
|
+
// signal SIGTERM *and* error.code ENOBUFS). So the message stays neutral
|
|
1949
|
+
// about starting and names the code instead of inferring a cause from it.
|
|
1950
|
+
const code = result.error.code;
|
|
1951
|
+
const why = code === 'ENOBUFS' ? 'output exceeded the buffer' : code;
|
|
1952
|
+
const detail = why && !result.error.message.includes(why)
|
|
1953
|
+
? `${result.error.message} (${why})`
|
|
1954
|
+
: result.error.message;
|
|
1955
|
+
throw new Error(detail);
|
|
1956
|
+
}
|
|
1957
|
+
if (result.signal) {
|
|
1958
|
+
throw new Error(`git status was killed by ${result.signal}`);
|
|
1959
|
+
}
|
|
1960
|
+
if (result.exitCode !== 0) {
|
|
1961
|
+
throw new Error(result.stderr || `git exited ${result.exitCode}`);
|
|
1962
|
+
}
|
|
1963
|
+
gitStatus = result.stdout;
|
|
1927
1964
|
}
|
|
1928
1965
|
catch (err) {
|
|
1929
1966
|
throw new Error(`git status failed: ${err.message}`);
|
|
@@ -1111,13 +1111,26 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
|
|
|
1111
1111
|
// Heading target: the exact grammar `planSectionPattern` /
|
|
1112
1112
|
// `insertRowsPatternA|B` anchor on (an ATX phase heading for this phase).
|
|
1113
1113
|
const headingTargetFound = new RegExp(phaseHeadingAnchor, 'i').test(gateActiveRegion);
|
|
1114
|
+
// #5545: the phase-checklist bullet grammar, defined ONCE for the writer
|
|
1115
|
+
// (an unchecked bullet to tick) and the gate probe (`anyState`).
|
|
1116
|
+
// Line-anchored, with only an optional `**` before the label and horizontal
|
|
1117
|
+
// whitespace, so a bullet that merely MENTIONS "Phase N" is not the phase's
|
|
1118
|
+
// bullet and no `\s` can run past the line end (which used to land the
|
|
1119
|
+
// `(completed …)` annotation on the NEXT line). A decorated bullet (emoji,
|
|
1120
|
+
// blockquote, link) is deliberately NOT the phase's bullet either — the
|
|
1121
|
+
// same narrowing #4965 made for `roadmap analyze`'s checklist reader.
|
|
1122
|
+
// The lookahead only PEEKS (its `\s` may see a newline but consumes none):
|
|
1123
|
+
// the label must be followed by `:`, whitespace or the end of the line, so
|
|
1124
|
+
// `Phase 2.1` / `Phase 20` are not `Phase 2`. Capture group 1 is the opening
|
|
1125
|
+
// `- [`, group 2 the rest of the line after the box.
|
|
1126
|
+
const phaseChecklistBullet = (anyState) => new RegExp(`^([ \\t]*-[ \\t]*\\[)${anyState ? '[ x]' : ' '}(\\][ \\t]*(?:\\*\\*)?[ \\t]*Phase[ \\t]+${phasePattern}${OPTIONAL_PHASE_TAG_SOURCE}(?=[:\\s]|$)[^\\n]*)`, 'im');
|
|
1114
1127
|
// Checklist target: when the phase is complete, its own checklist bullet
|
|
1115
1128
|
// (`- [ ] **Phase N: …**`) IS a writable phase row — the completion
|
|
1116
1129
|
// checkbox stamp below updates it. Same grammar as that writer, widened
|
|
1117
1130
|
// one notch to `[ x]` so an ALREADY-checked bullet still counts as a
|
|
1118
1131
|
// found target: an idempotent re-run then takes the honest
|
|
1119
1132
|
// "no changes were needed" decline instead of this refusal.
|
|
1120
|
-
const checklistTargetFound = isComplete &&
|
|
1133
|
+
const checklistTargetFound = isComplete && phaseChecklistBullet(true).test(gateActiveRegion);
|
|
1121
1134
|
// Table-row target: set by the row-scoped cell updates below.
|
|
1122
1135
|
let tableRowFound = false;
|
|
1123
1136
|
// Progress table row: update Plans Complete/Status/Completed columns BY
|
|
@@ -1399,24 +1412,25 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
|
|
|
1399
1412
|
});
|
|
1400
1413
|
// If complete: check checkbox
|
|
1401
1414
|
if (isComplete) {
|
|
1402
|
-
|
|
1403
|
-
roadmapContent = replaceInCurrentMilestone(roadmapContent, checkboxPattern, `$1x$2 (completed ${today})`);
|
|
1415
|
+
roadmapContent = replaceInCurrentMilestone(roadmapContent, phaseChecklistBullet(false), `$1x$2 (completed ${today})`);
|
|
1404
1416
|
}
|
|
1405
1417
|
// Mark completed plan checkboxes (e.g. "- [ ] 50-01-PLAN.md", "- [ ] 50-01:", or "- [ ] **50-01**")
|
|
1406
1418
|
// #4741: tick only plans the phase's own COUNT still counts. `plans` is the
|
|
1407
1419
|
// superseded-filtered set (#2349 via scanPhasePlans) while `summaries` is
|
|
1408
1420
|
// the raw *-SUMMARY.md listing — a superseded plan can carry a SUMMARY
|
|
1409
1421
|
// (e.g. `status: halted`), and ticking it read as "executed" right under a
|
|
1410
|
-
// count line that excludes it.
|
|
1411
|
-
//
|
|
1412
|
-
//
|
|
1422
|
+
// count line that excludes it. #5542: a summary belongs to a live plan only
|
|
1423
|
+
// by the SAME pairing rule the counts use (`summaryCandidates` via
|
|
1424
|
+
// `countMatchedSummaries`), never by id prefix — a leftover `47-1` summary
|
|
1425
|
+
// must not survive because a live `47-10` plan starts with `47-1`. Rows
|
|
1426
|
+
// match the id up to a boundary (`planRowPattern`), so `47-1` never ticks
|
|
1427
|
+
// `47-10-PLAN.md`.
|
|
1413
1428
|
const tickableSummaries = phaseInfo.summaries
|
|
1414
1429
|
.map((summaryFile) => ({ summaryFile, planId: summaryFile.replace('-SUMMARY.md', '').replace('SUMMARY.md', '') }))
|
|
1415
|
-
.filter(({ planId }) => planId !== ''
|
|
1430
|
+
.filter(({ summaryFile, planId }) => planId !== ''
|
|
1431
|
+
&& coreUtils.summaryPairsWithAnyPlan(phaseInfo.plans, summaryFile));
|
|
1416
1432
|
for (const { planId } of tickableSummaries) {
|
|
1417
|
-
|
|
1418
|
-
const planCheckboxPattern = new RegExp(`(-\\s*\\[) (\\]\\s*(?:\\*\\*)?${planEscaped}(?:\\*\\*)?)`, 'i');
|
|
1419
|
-
roadmapContent = roadmapContent.replace(planCheckboxPattern, '$1x$2');
|
|
1433
|
+
roadmapContent = roadmapContent.replace(coreUtils.planRowPattern(planId), '$1x$2');
|
|
1420
1434
|
}
|
|
1421
1435
|
// Compute the active (post-</details>) region offset ONCE. Both the
|
|
1422
1436
|
// missing-plan DETECTION and the row INSERTION must use the same active
|
|
@@ -1440,23 +1454,19 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
|
|
|
1440
1454
|
//
|
|
1441
1455
|
// #4786: a plan row may be written WITH the `-PLAN.md` suffix (canonical
|
|
1442
1456
|
// template form) or WITHOUT it (hand-written form: `- [x] 659-01 — desc`).
|
|
1443
|
-
// The tick loop above keys on the bare planId stem
|
|
1444
|
-
//
|
|
1445
|
-
//
|
|
1446
|
-
//
|
|
1447
|
-
//
|
|
1448
|
-
//
|
|
1449
|
-
//
|
|
1450
|
-
// `.` — a dotted sub-id (`5-01.5`) is a real distinct plan, and counting
|
|
1451
|
-
// its row as 5-01's presence would suppress a genuine insertion.
|
|
1457
|
+
// The tick loop above keys on the bare planId stem, while detection required
|
|
1458
|
+
// the full `-PLAN.md` filename — so every suffix-less row was counted
|
|
1459
|
+
// missing and the insertion fired BESIDE the recognized list — 32 checkbox
|
|
1460
|
+
// lines for 16 plans, exit 0. The stem arm below accepts the bare id only
|
|
1461
|
+
// up to the SAME boundary the tick loop uses (`planRowPattern`, #5542), so
|
|
1462
|
+
// `5-011` never satisfies `5-01` and a dotted sub-id (`5-01.5`) is a real
|
|
1463
|
+
// distinct plan whose row does not count as 5-01's presence.
|
|
1452
1464
|
const missingPlans = phaseInfo.plans.filter((planFile) => {
|
|
1453
1465
|
const planEscaped = (0, pattern_cjs_1.escapeRegex)(planFile);
|
|
1454
1466
|
if (new RegExp(`-\\s*\\[[x ]\\]\\s*(?:\\*\\*)?${planEscaped}`, 'i').test(activeRegion))
|
|
1455
1467
|
return false;
|
|
1456
1468
|
const stem = planFile.replace(/-PLAN\.md$/i, '');
|
|
1457
|
-
|
|
1458
|
-
const stemPresent = new RegExp(`-\\s*\\[[x ]\\]\\s*(?:\\*\\*)?${stemEscaped}(?=$|\\s|:|—|–|-PLAN\\.md|\\.md|\\*\\*|\\))`, 'i').test(activeRegion);
|
|
1459
|
-
return !stemPresent;
|
|
1469
|
+
return !coreUtils.planRowPattern(stem, { anyState: true }).test(activeRegion);
|
|
1460
1470
|
});
|
|
1461
1471
|
if (missingPlans.length > 0) {
|
|
1462
1472
|
// Insert missing plan checklist rows (#1163). We prefer to anchor to the
|
|
@@ -1502,9 +1512,7 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
|
|
|
1502
1512
|
// (#4741: same superseded-filtered tick list as the loop above — a
|
|
1503
1513
|
// pre-existing superseded row must stay unchecked on this path too).
|
|
1504
1514
|
for (const { planId } of tickableSummaries) {
|
|
1505
|
-
|
|
1506
|
-
const planCheckboxPattern = new RegExp(`(-\\s*\\[) (\\]\\s*(?:\\*\\*)?${planEscaped}(?:\\*\\*)?)`, 'i');
|
|
1507
|
-
roadmapContent = roadmapContent.replace(planCheckboxPattern, '$1x$2');
|
|
1515
|
+
roadmapContent = roadmapContent.replace(coreUtils.planRowPattern(planId), '$1x$2');
|
|
1508
1516
|
}
|
|
1509
1517
|
}
|
|
1510
1518
|
}
|