Commit Graph

13 Commits

Author SHA1 Message Date
Tom Boucher
26d742c548 fix(core): replace negative-heuristic stripShippedMilestones with positive milestone lookup (#1145) (#1146)
stripShippedMilestones() uses a negative heuristic: strip all <details>
blocks, assume what remains is the current milestone. This breaks when
agents accidentally wrap the current milestone in <details> for
collapsibility — all downstream consumers then see an empty milestone.

Observed failure: cmdPhaseComplete() returns is_last_phase: true and
next_phase: null for non-final phases because the current milestone's
phases were stripped along with shipped ones.

Added extractCurrentMilestone(content, cwd) — a positive lookup that:
1. Reads the current milestone version from STATE.md frontmatter
2. Falls back to 🚧 in-progress marker in ROADMAP.md
3. Finds the section heading matching that version
4. Returns only that section's content
5. Falls back to stripShippedMilestones() if version can't be determined

Updated 12 call sites across 6 files to use extractCurrentMilestone:
- core.cjs: getRoadmapPhaseInternal(), getMilestonePhaseFilter()
- phase.cjs: cmdPhaseAdd(), cmdPhaseInsert(), cmdPhaseComplete() (2 sites)
- roadmap.cjs: cmdRoadmapGetPhase(), cmdRoadmapAnalyze()
- commands.cjs: stats/progress display
- verify.cjs: phase verification (2 sites)
- init.cjs: project initialization

Kept stripShippedMilestones() for:
- getMilestoneInfo() — determines the version itself, can't use positive lookup
- replaceInCurrentMilestone() — write operations, conservative boundary
- extractCurrentMilestone() fallback — when no version available

All 755 tests pass.

Fixes #1145
2026-03-18 09:57:31 -06:00
Shard
ca4ae7b3b8 fix: scope ROADMAP.md searches to current milestone (#1059)
Phase numbers reset per milestone (v1.0 Phase 1-26, v1.1 Phase 1-6,
v1.2 Phase 1-6). Functions that searched ROADMAP.md for phase headings
or checkboxes would match archived milestone entries inside <details>
blocks before reaching the current milestone's entries.

This caused:
- roadmap_complete: true for phases that aren't complete (checkbox
  regex matched the archived [x] Phase N from a previous milestone)
- phase-complete marking the wrong checkbox (archived instead of current)
- phase-add computing wrong maxPhase from archived headings
- progress not showing phases defined in ROADMAP but not yet on disk
2026-03-15 11:39:59 -06:00
ashanuoc
c82c0a76b9 fix(phase-complete): improve REQUIREMENTS.md traceability updates (closes #848)
- Scope phase section regex to prevent cross-phase boundary matching
- Handle 'In Progress' status in traceability table (not just 'Pending')
- Add requirements_updated field to phase complete result object
- Add 3 new tests: result field, In Progress status, cross-boundary safety

Co-authored-by: ashanuoc <ashanuoc@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 21:57:48 -06:00
Tibsfox
15226feb18 fix(core): complete toPosixPath coverage for Windows output paths
Three files emit path.join or path.relative results directly into
JSON output without normalizing backslashes on Windows. Wrap these
with toPosixPath (already used in core.cjs and init.cjs) so agents
receive consistent forward-slash paths on all platforms.

Files changed:
- phase.cjs: wrap directory path in cmdPhasesFind
- commands.cjs: wrap todo path in cmdListTodos, relPath in cmdScaffold
- template.cjs: wrap relPath in cmdTemplateFill (both exists and
  created branches)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 08:01:54 -06:00
TÂCHES
43c0bde6d0 Merge pull request #822 from Tibsfox/fix/core-lifecycle-state
fix(core): correct phase lifecycle, milestone detection, state parsing, and CLI commit messages
2026-03-02 16:20:03 -06:00
j2h4u
b863ed6de5 fix(state): scope phase counting to current milestone
Extract getMilestonePhaseFilter() from milestone.cjs closure into core.cjs
as a shared helper. Apply it in buildStateFrontmatter and cmdPhaseComplete
so multi-milestone projects count only current milestone's phases instead
of all directories on disk.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 16:07:49 -06:00
Tibsfox
4e00c50022 fix(phase): add ROADMAP.md fallback to cmdPhaseComplete next-phase scan
cmdPhaseComplete determines is_last_phase and next_phase by scanning
.planning/phases/ directories on disk. Phases defined in ROADMAP.md
but not yet planned (no directory created) are invisible to this scan,
causing premature is_last_phase:true when only the first phase has
been scaffolded.

Add a fallback that parses ROADMAP.md phase headings when the
filesystem scan finds no next phase. Uses the existing comparePhaseNum
utility for consistent ordering with letter suffixes and decimals.

Closes #709

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 04:48:04 -08:00
ROMB
3a417522c9 fix: phase-plan-index returns null/empty for files_modified, objective, task_count (#734)
cmdPhasePlanIndex had 3 mismatches with the canonical XML plan format
defined in templates/phase-prompt.md:

- files_modified: looked up fm['files-modified'] (hyphen) but plans use
  files_modified (underscore). Now checks underscore first, hyphen fallback.
- objective: read from YAML frontmatter but plans put it in <objective>
  XML tag. Now extracts first line from the tag, falls back to frontmatter.
- task_count: matched ## Task N markdown headings but plans use <task>
  XML tags. Now counts XML tags first, markdown fallback.

All three fixes preserve backward compat with legacy markdown-style plans.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 12:58:36 -06:00
Lex Christopherson
0ca1a59ab3 feat: add YAML frontmatter sync to STATE.md for machine readability 2026-02-25 07:20:14 -06:00
TÂCHES
bc77456204 fix: handle multi-level decimal phases and escape regex in phase operations (#720)
Phase number parsing only matched single-decimal (e.g. 03.2) but crashed
on multi-level decimals (e.g. 03.2.1). Requirement IDs with regex
metacharacters (parentheses, dots) were interpolated raw into RegExp
constructors, causing SyntaxError crashes.

- Add escapeRegex() utility for safe regex interpolation
- Update normalizePhaseName/comparePhaseNum for multi-level decimals
- Replace all .replace('.', '\\.') with escapeRegex() across modules
- Escape reqId before regex interpolation in cmdPhaseComplete
- Update all phase dir matching regexes from (?:\.\d+)? to (?:\.\d+)*
- Add regression test for phase complete 03.2.1

Closes #621

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:32:02 -06:00
dush999
ea3c22d345 fix: propagate phase_req_ids from ROADMAP to workflow agents (#684) (#702)
Added TBD guard test before merge.
2026-02-23 09:35:28 -06:00
Lex Christopherson
ed11f41ff2 Merge branch 'main' into fix/universal-phase-number-support
Rebased PR #639 onto refactored modular structure (lib/core.cjs, lib/phase.cjs, etc.)

Changes ported from monolithic gsd-tools.cjs to new modules:
- Add comparePhaseNum() helper to lib/core.cjs for universal phase sorting
- Update normalizePhaseName() regex to handle letter-suffix phases (12A, 12B)
- Update all phase-matching regexes across lib/*.cjs with [A-Z]? pattern
- Replace parseFloat-based sorting with comparePhaseNum throughout
- Add 15 new tests for comparePhaseNum, normalizePhaseName, and letter-suffix sorting

Sort order: 12 → 12.1 → 12.2 → 12A → 12A.1 → 12A.2 → 12B → 13

Co-Authored-By: vinicius-tersi <MDQ6VXNlcjUyNDk2NDYw>
2026-02-22 07:16:38 -06:00
Tyler Satre
c67ab759a7 refactor: split gsd-tools.cjs into 11 domain modules under bin/lib/
Break the 5324-line monolith into focused modules:
- core.cjs: shared utilities, constants, internal helpers
- frontmatter.cjs: YAML frontmatter parsing/serialization/CRUD
- state.cjs: STATE.md operations + progression engine
- phase.cjs: phase CRUD, query, and lifecycle
- roadmap.cjs: roadmap parsing and updates
- verify.cjs: verification suite + consistency/health validation
- config.cjs: config ensure/set/get
- template.cjs: template selection and fill
- milestone.cjs: milestone + requirements lifecycle
- commands.cjs: standalone utility commands
- init.cjs: compound init commands for workflow bootstrapping

gsd-tools.cjs is now a thin CLI router (~550 lines including
JSDoc) that imports from lib/ modules. All 81 tests pass.
Also updates package.json test script to point to tests/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:40:45 -05:00