Commit Graph

60 Commits

Author SHA1 Message Date
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
Ethan Hurst
ff3e2fd5eb fix: escape regex metacharacters in stateExtractField (#741)
stateReplaceField properly escaped fieldName before building the regex,
but stateExtractField did not. Field names containing regex metacharacters
could cause incorrect matches or regex errors.

Co-authored-by: Ethan Hurst <ethan.hurst@outlook.com.au>
2026-02-27 12:58:55 -06:00
Ethan Hurst
93c9def0ef fix: load nyquist_validation from config (#740)
loadConfig() didn't include nyquist_validation in its return object, so
cmdInitPlanPhase always set nyquist_validation_enabled to undefined. The
plan-phase workflow could never detect whether Nyquist validation was
enabled or disabled via config.

Co-authored-by: Ethan Hurst <ethan.hurst@outlook.com.au>
2026-02-27 12:58:42 -06: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
9c27da0261 fix(windows): cross-platform path separators, JSON quoting, and dollar signs
- Add toPosixPath() helper to normalize output paths to forward slashes
- Use string concatenation for relative base paths instead of path.join()
- Apply toPosixPath() to all user-facing file paths in init.cjs output
- Use array-based execFileSync in test helpers to bypass shell quoting
  issues with JSON args and dollar signs on Windows cmd.exe

Fixes 7 test failures on Windows: frontmatter set/merge (3), init
path assertions (2), and state dollar-amount corruption (2).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:34:36 -06:00
TÂCHES
3affa48306 Merge pull request #783 from Hnturk/claude/laughing-haslett
fix: getMilestoneInfo() returns wrong version after milestone complet…
2026-02-27 09:26:15 -06:00
TÂCHES
10576a58da Merge pull request #785 from Tibsfox/fix/milestones-reverse-chronological
fix(milestone): insert MILESTONES.md entries in reverse chronological order
2026-02-27 09:23:14 -06:00
Tibsfox
732ea09f81 fix(milestone): insert MILESTONES.md entries in reverse chronological order
cmdMilestoneComplete previously appended new milestone entries at the
end of MILESTONES.md. Over successive milestones this produced
chronological order (oldest first), which is counterintuitive — users
expect the most recent milestone at the top.

This fix detects the file header (h1-h3) and inserts the new entry
immediately after it, pushing older entries down. Files without a
recognizable header get the entry prepended. New files still get a
default '# Milestones' header.

Adds 2 tests: single insertion ordering assertion and three-sequential-
completions verification (v1.2 < v1.1 < v1.0 in file order).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 03:46:37 -08:00
Tibsfox
367149d0b2 fix(milestone): scope stats, accomplishments, and archive to current milestone phases
cmdMilestoneComplete previously iterated ALL phase directories in
.planning/phases/, including phases from prior milestones that remain on
disk. This produced inflated stats, stale accomplishments from old
summaries, and --archive-phases moving directories that belong to
earlier milestones.

This fix parses ROADMAP.md to extract phase numbers for the current
milestone, builds a normalized Set for O(1) lookup, and filters all
phase directory operations through an isDirInMilestone() helper.

The helper handles edge cases: leading zeros (01 -> 1), letter suffixes
(3A), decimal phases (3.1), large numbers (456), and excludes
non-numeric directories (notes/, misc/).

Adds 5 tests covering scoped stats, scoped archive, prefix collision
guard, non-numeric directory exclusion, and large phase numbers.

Complements upstream PRs #756 and #783 which fix getMilestoneInfo()
milestone detection — this fix addresses milestone completion scoping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 03:45:42 -08:00
Hnturk
38c19466ae fix: getMilestoneInfo() returns wrong version after milestone completion (#768)
Strip <details> blocks (shipped milestones) before matching, and extract
both version and name from the same ## heading for consistency.
2026-02-27 11:17:36 +03:00
Ethan Hurst
752e038914 fix: load model_overrides from config and use resolveModelInternal in CLI
loadConfig() never returned model_overrides, so resolveModelInternal()
could never find per-agent overrides — they were silently ignored.

Additionally, cmdResolveModel duplicated model resolution logic but
skipped the override check entirely. Now delegates to resolveModelInternal
so both code paths behave consistently.
2026-02-26 05:47:19 +10: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
Colin Johnson
77d434709d Fix STATE.md decision corruption and dollar handling (#701) 2026-02-23 09:55:54 -06:00
TÂCHES
0176a3ec5b fix: map requirements-completed frontmatter in summary-extract (#627) (#716)
Add requirements_completed field to summary-extract output, mapping
from SUMMARY frontmatter requirements-completed key. Enables
/gsd:audit-milestone cross-check to receive data from SUMMARY source.

Re-applied from #631 against refactored codebase (commands.cjs + split tests).

Co-authored-by: Colin Johnson <Solvely-Colin@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:55:22 -06:00
TÂCHES
3704829aa6 fix: clamp progress bar percent to prevent RangeError crash (#715)
When orphaned SUMMARY.md files cause totalSummaries > totalPlans, the
progress percentage exceeds 100%, making String.repeat() throw RangeError
on negative arguments. Clamp percent to Math.min(100, ...) at all three
computation sites (state, commands, roadmap).

Closes #633

Co-authored-by: vinicius-tersi <vinicius-tersi@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:51:28 -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
3a56a207a5 fix(gsd-tools): support --cwd override for state-snapshot
Add --cwd <path> / --cwd=<path> support so sandboxed subagents running
outside the project root can target a specific directory. Invalid paths
return a clear error. Tests ported to tests/state.test.cjs (the old
monolithic test file was split into domain files on main).

Closes #622

Co-Authored-By: Colin Johnson <colin@solvely.net>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:31:06 -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
Lex Christopherson
4d09f8743e Merge PR #687: feat: add Nyquist validation layer to plan-phase pipeline
- Adds validation architecture research to gsd-phase-researcher
- Adds Dimension 8 (Nyquist Compliance) to gsd-plan-checker
- Creates VALIDATION.md template
- Default nyquist_validation: false (opt-in, not opt-out)

Co-Authored-By: Bantuson <Fana@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-20 14:28:04 -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
Tyler Satre
fa2e156887 refactor: split gsd-tools.test.cjs into domain test files
Move 81 tests (18 describe blocks) from single monolithic test file
into 7 domain-specific test files under tests/ with shared helpers.
Test parity verified: 81/81 pass before and after split.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:30:54 -05:00
Bantuson
e0f9c738c9 feat: add Nyquist validation layer to plan-phase pipeline
Adds automated feedback architecture research to gsd-phase-researcher,
enforces it as Dimension 8 in gsd-plan-checker, and introduces
{phase}-VALIDATION.md as the per-phase validation contract.

Ensures every phase plan includes automated verify commands before
execution begins. Opt-out via workflow.nyquist_validation: false.

Closes #122 (partial), related #117

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:46:39 +02:00
Lex Christopherson
3dcd3f0609 refactor: complete context-proxy orchestration flow 2026-02-19 12:40:45 -06:00
Lex Christopherson
bf2f57105f fix(#657): create backup before STATE.md regeneration
/gsd:health --repair now creates a timestamped backup
(STATE.md.bak-YYYY-MM-DDTHH-MM-SS) before overwriting STATE.md,
preventing accidental data loss of accumulated context.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-19 12:21:04 -06:00
Lex Christopherson
1764abc615 fix: executor updates ROADMAP.md and REQUIREMENTS.md per-plan
gsd-executor had no instruction to update ROADMAP or REQUIREMENTS after
completing a plan — both stayed unchecked throughout milestone execution.

- Add `roadmap update-plan-progress` call to executor state_updates
- Add `requirements mark-complete` CLI command to gsd-tools
- Wire requirement marking into executor and execute-plan workflows
- Include ROADMAP.md and REQUIREMENTS.md in executor final commit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 13:19:02 -06:00
vinicius_tersi
7461b3d25d fix: universal phase number parsing with comparePhaseNum helper
Fixes phase number handling to support all formats: integers (12),
decimals (12.1), letter-suffix (12A), and hybrids (12A.1).

Changes:
- normalizePhaseName() now handles letter+decimal format
- New comparePhaseNum() helper for correct sort order
- All directory .sort() calls use comparePhaseNum instead of parseFloat
- All phase-matching regexes updated with [A-Z]? for letter support
- cmdPhaseComplete uses comparePhaseNum for next-phase detection
- Export comparePhaseNum and normalizePhaseName for unit testing
- 14 new unit tests for comparePhaseNum (8) and normalizePhaseName (6)

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

Fixes #621

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 11:38:35 -03:00
Lex Christopherson
cbf809417a fix: requirements tracking chain — strip brackets, add requirements field to plans and summaries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:21:59 -06:00
Lex Christopherson
7510a8a84a feat(quick): add --full flag for plan-checking and verification
Enables quality guarantees on quick tasks without full milestone ceremony.
--full spawns plan-checker (max 2 iterations) and post-execution verifier,
produces VERIFICATION.md, and adds Status column to STATE.md table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:56:31 -06:00
Lex Christopherson
1dcedb635e feat(auto-advance): chain phase execution across full milestone
Wire execute-phase to invoke transition.md inline when --auto flag or
workflow.auto_advance config is set, propagate --auto through transition
to next phase invocations, add config-get command to gsd-tools, and fix
broken "config get" calls to use hyphenated "config-get" subcommand.

Closes #344

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 16:37:47 -06:00
Lex Christopherson
cb7d4dbc3c feat(health): add /gsd:health command for planning directory validation
Validates .planning/ integrity and reports actionable issues:
- Missing/malformed files (PROJECT.md, ROADMAP.md, STATE.md, config.json)
- Phase directory naming, orphaned plans, roadmap/disk consistency
- Auto-repair for config.json and STATE.md with --repair flag

Closes #338

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 16:25:01 -06:00
Lex Christopherson
0f2a3fafff fix: add .gitkeep to phase directories for git tracking
Phase directories created by /gsd:add-phase and /gsd:insert-phase were
empty until planning, causing git to ignore them. This prevented syncing
across machines.

Fixes #427

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:03:06 -06:00
Lex Christopherson
41cb7455f5 feat(phases): archive completed milestone phase directories (closes #489)
Add optional phase archival to milestone completion and a standalone
/gsd:cleanup command for retroactive use. Phase dirs move to
.planning/milestones/v{X.Y}-phases/, reducing phases/ clutter after
multiple milestones.

Core changes:
- getArchivedPhaseDirs() and searchPhaseInDir() helpers in gsd-tools
- findPhaseInternal() searches archives when phase not found in current
- cmdPhasesList() accepts --include-archived flag
- cmdHistoryDigest() scans both current and archived phases
- cmdMilestoneComplete() accepts --archive-phases flag
- Workflow globs replaced with find-phase/phases-list CLI calls

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:33:50 -06:00
Lex Christopherson
8d977328e4 fix(tools): write large JSON payloads to tmpfile to prevent truncation (closes #493)
When init commands include many file contents (state, roadmap, requirements,
etc.), the JSON output can exceed Claude Code's Bash tool buffer (~50KB),
causing parse errors. The output() function now auto-detects large payloads
and writes to a tmpfile, returning @file:/path instead. All workflows that
consume init output handle both formats.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 14:33:50 -06:00
Lex Christopherson
9aeafc0f48 fix(tools): support #### heading depth in phase matching
Multi-milestone roadmaps use #### for phases nested under milestone
headers. Expanded all phase-matching regexes from #{2,3} to #{2,4}.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:15:08 -06:00
Lex Christopherson
37bb14eaf8 feat(config): add user-level default settings via ~/.gsd/defaults.json (closes #492)
New projects seed config from ~/.gsd/defaults.json when available,
skipping the 8 setup questions. /gsd:settings offers to save current
settings as global defaults after configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:14:58 -06:00
Lex Christopherson
afb93a37c6 fix(tools): normalize phase padding in insert command (closes #494)
Phase insert failed when zero-padding differed between user input and
ROADMAP.md headers (e.g. "9.05" vs "09.05"). Normalize input and use
flexible regex matching with optional leading zeros.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:14:17 -06:00
Lex Christopherson
24b933e018 fix: rename gsd-tools.js to .cjs to prevent ESM conflicts (closes #495)
Projects with "type": "module" in package.json cause Node to treat
gsd-tools.js as ESM, crashing on require(). The .cjs extension forces
CommonJS regardless of the host project's module configuration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:03:22 -06:00
Lex Christopherson
a5caf9194b feat(config): add per-agent model overrides (#510)
Allow overriding specific agent models without changing the entire profile.
Add model_overrides key to config that takes precedence over profile lookup.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 10:41:04 -06:00
Lex Christopherson
c8827fede1 fix(tools): deterministic ROADMAP progress table updates from disk (#537)
Replace NL instructions in execute-plan and execute-phase workflows with
deterministic `roadmap update-plan-progress` command that counts PLAN vs
SUMMARY files on disk. Prevents LLM from miscounting plan progress.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:58:32 -06:00
Lex Christopherson
4fb04287d0 fix(verifier): use ROADMAP Success Criteria instead of deriving truths from Goal (#538)
The verifier was deriving verification truths from the vague one-line Goal
field, allowing partial implementations to pass. Now extracts Success Criteria
as a structured array from `roadmap get-phase` and uses them directly as truths,
with Goal derivation as fallback for older ROADMAPs without Success Criteria.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 09:53:13 -06:00
Lex Christopherson
a142002dfe fix(tools): update REQUIREMENTS.md traceability when phase completes
cmdPhaseComplete now updates REQUIREMENTS.md when a phase finishes:
- Checks off requirement checkboxes (- [ ] → - [x])
- Updates traceability table status (Pending → Complete)

Parses Requirements line from ROADMAP.md phase section to find
which REQ-IDs belong to the completing phase.

Fixes #539

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 09:51:37 -06:00
Lex Christopherson
2b9951b9c8 fix(agents): return 'inherit' instead of 'opus' for model resolution (#558)
Claude Code's "opus" alias maps to a specific model version (claude-opus-4-1).
Organizations that block older opus versions while allowing newer ones see
agents silently fall back to Sonnet. By returning "inherit" instead, agents
use whatever opus version the user has configured in their session.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 09:21:40 -06:00
Lex Christopherson
b9f9ee98d0 fix(init): fall back to ROADMAP.md when phase directory missing (#521)
`init phase-op` only checked disk for phase directories, failing on
phases with Plans: TBD since no directory exists yet. Now falls back
to parsing ROADMAP.md when findPhaseInternal returns null.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 08:40:26 -06:00
Lex Christopherson
7b140c2dd2 fix(roadmap): accept ## and ### phase headers, detect malformed ROADMAPs (#598, #599)
- Parser now accepts both `## Phase X:` and `### Phase X:` headers
- `roadmap get-phase` detects when phases exist in summary list but
  missing detail sections, returns `error: 'malformed_roadmap'`
- `roadmap analyze` returns `missing_phase_details` array
- Updated gsd-roadmapper instructions with explicit format requirements
- Added 2 tests for new functionality (77 total, all passing)

Closes #598, closes #599

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 08:38:54 -06:00
Lex Christopherson
9d815d31db Revert 12 PRs merged without authorization
Reverts:
- #413 fix(install): build hooks/dist on the fly for dev installs
- #396 refactor(statusline): display git branch in status line
- #543 Add in-progress state for todos
- #532 feat: add git_tag config option
- #171 Add OpenCode installer package
- #519 feat: Add Mistral Vibe CLI Support
- #389 docs: use @latest for uninstall commands
- #288 fix(install): auto-migrate renamed statusline.js reference
- #502 fix(#501): verify-work defers diagnosis/planning
- #497 fix: move resolved debug sessions to resolved/ folder
- #512 fix: create feature branch before first commit
- #545 fix: add Write tool to gsd-verifier

These were merged without owner approval.
2026-02-14 14:25:26 -06:00
Emre Erdoğan
6f98b4f70e Add in-progress state for todos instead of marking done immediately (#543)
feat: Add in-progress state for todos
2026-02-14 14:18:06 -06:00
Solvely-Colin
430a7e4f17 feat: add git_tag config option to disable tagging on milestone completion (#532)
feat: Add git_tag config option to disable tagging on milestone completion
2026-02-14 14:18:04 -06:00
pds
c3c9d523c3 fix: create feature branch before first commit in discuss/plan workflows (#512)
Bug fix: Create feature branch before first commit in discuss/plan workflows
2026-02-14 14:17:04 -06:00
Lex Christopherson
60ccba9446 feat: add Brave Search integration for researchers
- Add `websearch` command to gsd-tools.js for Brave API
- Detect BRAVE_API_KEY env var or ~/.gsd/brave_api_key file
- Persist brave_search setting to config.json on project init
- Update researcher agents to check config before calling

Graceful degradation: if brave_search is false, agents use
built-in WebSearch without wasted Bash calls.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 10:36:26 -06:00