Commit Graph

15 Commits

Author SHA1 Message Date
Tom Boucher
7dd31e6d20 feat: signal file for decision points — WAITING.json (#1034) (#1133)
When GSD hits a blocking decision point (AskUserQuestion, next action prompt),
external watchers have no way to detect it. Users monitoring multiple auto
sessions must visually check each terminal.

Added:
- state signal-waiting: writes .planning/WAITING.json (or .gsd/WAITING.json)
  with type, question, options, timestamp, and phase info
- state signal-resume: removes WAITING.json when user answers

Signal file format:
  { status, type, question, options[], since, phase }

External tools can watch for this file via fswatch, polling, or inotify.
Complements the existing remote-questions extension (Slack/Discord).

Fixes #1034
2026-03-18 09:59:39 -06:00
Tom Boucher
2842f076ea fix: CRLF frontmatter parsing, duplicate cwd crash, STATE.md phase transitions (#1105)
- fix(frontmatter): handle CRLF line endings in extractFrontmatter,
  spliceFrontmatter, and parseMustHavesBlock — fixes wave parsing on
  Windows where all plans reported as wave 1 (#1085)

- fix(hooks): remove duplicate const cwd declaration in
  gsd-context-monitor.js that caused SyntaxError on every PostToolUse
  invocation (#1091, #1092, #1094)

- feat(state): add 'state begin-phase' command that updates STATUS,
  Last Activity, Current focus, Current Position, and plan counts
  when a new phase starts executing (#1102, #1103, #1104)

- docs(workflow): add state begin-phase call to execute-phase workflow
  validate_phase step so STATE.md is current from the start
2026-03-16 13:40:21 -06:00
Tom Boucher
460f92e727 feat: normalize generated markdown for markdownlint compliance (#1112)
Add normalizeMd() utility that fixes common markdownlint violations
in GSD-generated .planning/ files, improving IDE readability:

  MD022 — Blank lines around headings
  MD031 — Blank lines around fenced code blocks
  MD032 — Blank lines around lists
  MD012 — No multiple consecutive blank lines (collapsed to max 2)
  MD047 — Files end with a single newline

Applied at key write points:
  - state.cjs: writeStateMd() normalizes STATE.md on every write
  - frontmatter.cjs: frontmatter set/merge commands normalize output
  - template.cjs: template fill normalizes generated plan/summary files
  - milestone.cjs: MILESTONES.md archive writes normalized

Includes 14 new tests covering all rules, edge cases (CRLF, frontmatter,
ordered lists, code blocks, real-world STATE.md patterns).

Closes #1040
2026-03-16 13:39:34 -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
Tibsfox
641cdbdae7 fix(state): deduplicate extractField into shared helper with regex escaping
Two defensive hardening changes:

1. state.cjs: Replace two identical inline extractField closures
   (cmdStateSnapshot and buildStateFrontmatter) with a shared
   stateExtractField(content, fieldName) helper at module scope.
   The helper uses escapeRegex on fieldName before interpolation
   into RegExp constructors, preventing breakage if a field name
   ever contains regex metacharacters. Net removal of duplicated
   logic.

2. gsd-plan-checker.md: Bound the "relevant" definition in the
   exhaustive cross-check instruction. A requirement is "relevant"
   only if ROADMAP.md explicitly maps it to this phase or the phase
   goal directly implies it — prevents false blocker flags for
   requirements belonging to other phases.

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
e1b3277869 fix(state): derive total_phases from ROADMAP when phases lack directories
Phases listed in ROADMAP.md but not yet planned (no directory on disk)
were excluded from total_phases, causing premature milestone completion.
Now uses Math.max(diskDirs, roadmapCount) via filter.phaseCount.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 16:07:53 -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
8c017034a3 fix(state): support both bold and plain field formats in all state.cjs functions
Expand dual-format parsing to cover all 8 field extraction and
replacement locations in state.cjs. The previous fix only covered
cmdStateSnapshot and buildStateFrontmatter (read path), leaving 6
write-path functions with bold-only regex that silently failed on
plain-format STATE.md files.

Functions fixed:
- stateExtractField: shared read helper (cascades to cmdStateAdvancePlan,
  cmdStateRecordSession)
- stateReplaceField: shared write helper (cascades to all state mutations)
- cmdStateGet: individual field lookup
- cmdStatePatch: batch field updates
- cmdStateUpdate: single field updates
- cmdStateUpdateProgress: progress bar writes
- cmdStateSnapshot session section: Last Date, Stopped At, Resume File

Each function now tries **Field:** bold format first (preserving
existing behavior), then falls back to plain Field: format. This
eliminates the read/write asymmetry where state-snapshot could read
plain-format fields but state-update/state-patch could not modify them.

Closes #730

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 05:34:43 -08:00
Tibsfox
78eaabc3da fix(state): support both bold and plain field formats in state parsing
extractField in state-snapshot and buildStateFrontmatter only matches
the **Field:** bold markdown format, but STATE.md may use plain
Field: format depending on how it was generated. When all fields
return null, progress routing freezes with no matching condition.

Add dual-format parsing: try **Field:** first, fall back to plain
Field: with line-start anchor. Both instances in cmdStateSnapshot
and buildStateFrontmatter are updated consistently.

Closes #730

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 04:48:16 -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
Lex Christopherson
0ca1a59ab3 feat: add YAML frontmatter sync to STATE.md for machine readability 2026-02-25 07:20:14 -06:00
Colin Johnson
77d434709d Fix STATE.md decision corruption and dollar handling (#701) 2026-02-23 09:55:54 -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
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