Commit Graph

446 Commits

Author SHA1 Message Date
benzntech
b621d556f0 feat: add Exa and Firecrawl MCP support for research agents
Integrate Exa (semantic search) and Firecrawl (deep web scraping) as
MCP-based research tools, following the existing Brave Search pattern.

- Add tool declarations to all 3 researcher agents
- Add tool strategy sections with usage guidance and priority
- Add config detection for FIRECRAWL_API_KEY and EXA_API_KEY env vars
- Add firecrawl/exa_search config keys to core defaults and init output
- Update source priority hierarchy across all researchers
2026-03-20 14:53:46 +05:30
Diego Mariño
fd2a80675a merge: resolve conflicts with upstream main
VALID_CONFIG_KEYS: merge our additions (workflow.auto_advance,
workflow.node_repair, workflow.node_repair_budget, hooks.context_warnings)
with upstream's additions (workflow.text_mode, git.quick_branch_template).

ensureConfigFile(): keep our refactored version that delegates to
buildNewProjectConfig({}) instead of upstream's duplicated logic.

buildNewProjectConfig(): add git.quick_branch_template: null and
workflow.text_mode: false to match upstream's new keys.

new-project.md: integrate upstream's Step 5.1 Sub-Repo Detection
after our commit block; drop upstream's duplicate Note (ours at
line 493 is more detailed).
2026-03-19 22:48:21 +01:00
Srinivas Koduri
32c6d880bf fix: address maintainer review — gate findProjectRoot, warn on unmatched files
1. Gate findProjectRoot to commands that access .planning/ — skip for
   pure-utility commands (generate-slug, current-timestamp, template,
   frontmatter, verify-path-exists, verify-summary) to avoid unnecessary
   filesystem traversal on every invocation.

2. Warn to stderr when commit-to-subrepo encounters files that don't
   match any configured sub-repo prefix.

3. Document that loadConfig auto-syncs sub_repos with the filesystem,
   so config.json may be rewritten when repos are added or removed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:19:00 -07:00
Srinivas Koduri
d0aae7b63c fix: address PR review — nested path resolution, sub_repos in init, depth-1 detection
- findProjectRoot: use isInsideGitRepo() to walk up and find .git in
  ancestor dirs, fixing nested paths like backend/src/modules/
- Add sub_repos to cmdInitExecutePhase output so execute-plan.md and
  gsd-executor.md can route commits correctly
- Align new-project.md sub-repo detection to maxdepth 1 matching
  detectSubRepos() behavior
- Add 3 nested path tests for .git heuristic, sub_repos, and multiRepo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:18:20 -07:00
Srinivas Koduri
21081dc821 feat: multi-repo workspace support with auto-detection and project root resolution
Add support for workspaces with multiple independent git repositories.
When configured, GSD routes commits to the correct sub-repo and ensures
.planning/ stays at the project root.

Core features:
- detectSubRepos(): scans child directories for .git to discover repos
- findProjectRoot(): walks up from CWD to find the project root that
  owns .planning/, preventing orphaned .planning/ in sub-repos
- loadConfig auto-syncs sub_repos when repos are added or removed
- Migrates legacy "multiRepo: true" to sub_repos array automatically
- All init commands include project_root in output
- cmdCommitToSubrepo: groups files by sub-repo prefix, commits independently

Zero impact on single-repo workflows — sub_repos defaults to empty array.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:18:20 -07:00
Tom Boucher
3e2c85e6fd refactor: consolidate STATE.md field helpers, fix command injection in isGitIgnored
Refactoring:
- Extract stateReplaceFieldWithFallback() to state.cjs as single source of truth
  for the try-primary-then-fallback pattern that was duplicated inline across
  phase.cjs, milestone.cjs, and state.cjs
- Replace all inline bold-only regex patterns in cmdPhaseComplete with shared
  stateReplaceField/stateExtractField helpers — now supports both **Bold:**
  and plain Field: STATE.md formats (fixes the same bug as #924)
- Replace inline bold-only regex patterns in cmdMilestoneComplete with shared helpers
- Replace inline bold-only regex for Completed Phases/Total Phases/Progress
  counters in cmdPhaseComplete with stateExtractField/stateReplaceField
- Replace inline bold-only Total Phases regex in cmdPhaseRemove with shared helpers

Security:
- Fix command injection surface in isGitIgnored (core.cjs): replace execSync with
  string concatenation with execFileSync using array arguments — prevents shell
  interpretation of special characters in file paths

Tests (7 new):
- 5 tests for stateReplaceFieldWithFallback: primary field, fallback, neither,
  preference, and plain format
- 1 regression test: phase complete with plain-format STATE.md fields
- 1 regression test: milestone complete with plain-format STATE.md fields

854 tests pass (was 847). No behavioral regressions.
2026-03-19 15:05:20 -04:00
Tom Boucher
0afffb15f5 feat(core): worktree-aware .planning/ resolution and file locking (#1215)
- Add resolveWorktreeRoot() that detects linked worktrees via
  git rev-parse --git-common-dir and resolves to the main worktree
  where .planning/ lives
- Add withPlanningLock() file-based locking mechanism to prevent
  concurrent worktrees from corrupting shared planning files
- Wire worktree root resolution into gsd-tools.cjs main entry point
- Add regression tests for resolveWorktreeRoot (non-git, normal repo)
  and withPlanningLock (normal execution, error cleanup, stale lock
  recovery)
2026-03-19 13:41:11 -04:00
Tom Boucher
d585612afa Merge pull request #1229 from tonymfer/fix/commit-stage-deletions
fix(commit): stage file deletions when passed non-existent paths
2026-03-19 13:01:06 -04:00
Tom Boucher
44e141c043 Merge pull request #1218 from j2h4u/fix/one-liner-extraction
fix(lifecycle): extract one-liner from summary body when not in frontmatter
2026-03-19 12:59:52 -04:00
Tom Boucher
aa29c46ca6 Merge pull request #947 from j2h4u/fix/state-advance-plan-compound
fix(state): parse compound Plan field in advance-plan command
2026-03-19 12:59:18 -04:00
Tony Park
6dc8caa0d5 fix(commit): stage file deletions when passed non-existent paths
When check-todos moves a file from pending/ to done/, the commit only
staged the new destination. The deletion of the source was never staged
because `git add` on a non-existent path is a no-op. Now we detect
missing files and use `git rm --cached` to stage the deletion.

Closes #1228

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 01:51:33 +09:00
j2h4u
e3bc614eb7 fix(roadmap): handle 5-column progress tables with Milestone column
The regex-based table parser captured a fixed number of columns,
so 5-column tables (Phase | Milestone | Plans | Status | Completed)
had the Milestone column eaten and Status/Date written to wrong cells.

Replaced regex with cell-based `split('|')` parsing that detects
column count (4 or 5) and updates the correct cells by index.
Affects both `cmdRoadmapUpdatePlanProgress` and `cmdPhaseComplete`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 21:30:41 +05:00
j2h4u
104a39e573 fix(lifecycle): extract one-liner from summary body when not in frontmatter
The summary template puts the one-liner as a `**bold**` line after the
`# Phase N` heading, but `cmdSummaryExtract` and `cmdMilestoneComplete`
only checked frontmatter `one-liner` field — which is often empty.

Adds `extractOneLinerFromBody()` to core.cjs as a fallback that parses
the first `**...**` line after the heading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 21:29:25 +05:00
j2h4u
85a65fd384 fix(state): parse compound Plan field in advance-plan command
`cmdStateAdvancePlan` expected separate `Current Plan` and
`Total Plans in Phase` fields, but the current STATE.md template
uses a single compound field: `Plan: X of Y in current phase`.

Now tries legacy separate fields first, then falls back to parsing
the compound format. Preserves the compound format when writing back
(replaces only the plan number). Also handles `Last activity`
(lowercase) field name from current template.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 21:28:26 +05:00
Tom Boucher
efc398c554 Merge pull request #1223 from trek-e/fix/remote-session-menu-fallback-1214
fix(workflows): text_mode config for Claude Code remote session compatibility
2026-03-19 12:13:10 -04:00
Tom Boucher
ea1797d362 Merge pull request #922 from j2h4u/fix/plan-checkboxes-progress
fix(roadmap): mark individual plan checkboxes when summaries exist
2026-03-19 12:09:03 -04:00
Tom Boucher
f9434f7ffc Merge pull request #1212 from jecanore/feat/audit-uat
feat: add verification debt tracking and /gsd:audit-uat command
2026-03-19 12:05:36 -04:00
Tom Boucher
86cbd5442b Merge pull request #1217 from j2h4u/fix/task-count-pattern
fix(milestone): read task count from **Tasks:** field in summary body
2026-03-19 12:04:37 -04:00
Tom Boucher
841da5a80d Merge pull request #1155 from gsd-build/Solvely/quick-task-branching
feat(quick): add quick-task branch support
2026-03-19 12:03:58 -04:00
Tom Boucher
37ae2bc936 Merge pull request #1154 from gsd-build/Solvely/soft-gsd-workflow-enforcement
feat(new-project): add soft GSD workflow enforcement
2026-03-19 12:03:31 -04:00
Tom Boucher
9506b895c1 Merge pull request #1151 from 0Shard/fix/semver-and-frontmatter-parsing
fix: semver 3+ segment parsing and CRLF frontmatter corruption recovery
2026-03-19 12:02:43 -04:00
Tom Boucher
0342ce33c6 Merge pull request #1149 from Solvely-Colin/Solvely/health-non-destructive-state-repair
fix(health): preserve state on phase mismatch repair
2026-03-19 12:02:11 -04:00
Tom Boucher
b0523d6cbe Merge pull request #1148 from Solvely-Colin/Solvely/reset-milestone-phase-numbers
feat(milestones): support safe phase-number resets
2026-03-19 12:01:52 -04:00
Tom Boucher
e0e74ada73 Merge pull request #1134 from trek-e/feat/ticket-based-phase-ids-1019
feat: support ticket-based phase identifiers for team workflows (#1019)
2026-03-19 12:00:57 -04:00
Tom Boucher
0487151142 fix(workflows): add text_mode config for Claude Code remote session compatibility (#1214)
- Add workflow.text_mode config option (default: false) that replaces
  AskUserQuestion TUI menus with plain-text numbered lists
- Document --text flag and config-set workflow.text_mode true as the
  fix for /rc remote sessions where the Claude App cannot forward TUI
  menu selections
- Update discuss-phase.md with text mode parsing and answer_validation
  fallback documentation
- Add text_mode to loadConfig defaults and VALID_CONFIG_KEYS
- Add regression tests for config-set and loadConfig
2026-03-19 09:19:01 -04:00
j2h4u
b34bf532ef fix(milestone): read task count from **Tasks:** field in summary body
The summary template writes task count as `**Tasks:** N` in the
Performance section, but `cmdMilestoneComplete` only counted
`## Task N` markdown headers — which don't exist in that format.

Now checks three patterns in order: `**Tasks:** N` field (primary),
`<task` XML tags, then `## Task N` headers (legacy fallback).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 14:37:21 +05:00
j2h4u
459f7f3b64 fix(roadmap): mark individual plan checkboxes when summaries exist
`cmdRoadmapUpdatePlanProgress` only marked phase-level checkboxes
(e.g. `- [ ] Phase 50: Build`) but skipped plan-level entries
(e.g. `- [ ] 50-01-PLAN.md`). Now iterates phase summaries and
marks matching plan checkboxes as complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 14:36:11 +05:00
jecanore
60a76ae06e feat: add verification debt tracking and /gsd:audit-uat command
Prevent silent loss of UAT/verification items when projects advance.
Surfaces outstanding items across all prior phases so nothing is forgotten.

New command:
- /gsd:audit-uat — cross-phase audit with categorized report and test plan

New capabilities:
- Cross-phase health check in /gsd:progress (Step 1.6)
- status: partial for incomplete UAT sessions
- result: blocked with blocked_by tag for dependency-gated tests
- human_needed items persisted as trackable HUMAN-UAT.md files
- Phase completion and transition warnings for verification debt

Files: 4 new, 14 modified (9 feature + 5 docs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 00:05:05 -05:00
Tom Boucher
1d4deb0f8b refactor: adopt planningPaths() across 4 modules — eliminate 34 inline path constructions
Consolidates repeated path.join(cwd, '.planning', ...) patterns into
calls to the shared planningPaths() helper from core.cjs.

Modules updated:
- state.cjs: 16 → planningPaths() (2 remain for non-standard paths)
- commands.cjs: 8 → planningPaths() (4 remain for todos dir)
- milestone.cjs: 5 → planningPaths() (3 remain for archive/milestones)
- roadmap.cjs: 4 → planningPaths()

Benefits:
- Single source of truth for .planning/ directory structure
- Easier to change planning dir location in the future
- Consistent path construction across the codebase
- No behavioral changes — pure refactor

797/797 tests pass.
2026-03-18 23:39:47 -04:00
Tom Boucher
a4da216523 feat: support ticket-based phase identifiers for team workflows (#1019)
Teams sharing a GSD repo collide on sequential phase numbers when multiple
people create phases concurrently. This adds support for arbitrary string
IDs (e.g. PROJ-42, AUTH-101) as phase identifiers.

New config option:
  { "phase_naming": "custom" }

Changes:
- core.cjs: normalizePhaseName() handles non-numeric IDs gracefully
- core.cjs: comparePhaseNum() falls back to string comparison for custom IDs
- core.cjs: searchPhaseInDir() matches custom ID prefixes case-insensitively
- core.cjs: getMilestonePhaseFilter() recognizes custom ID directory names
- core.cjs: getRoadmapPhaseInternal() matches Phase headers with any word chars
- core.cjs: loadConfig() adds phase_naming option (default: 'sequential')
- phase.cjs: cmdPhaseAdd() accepts --id flag for custom phase IDs
- verify.cjs: health check skips sequential numbering validation in custom mode
- gsd-tools.cjs: phase add --id PROJ-42 "description" wired up

Usage:
  # Sequential mode (default, backward compatible)
  gsd-tools phase add "User Authentication"  # → Phase 3

  # Custom mode (config: phase_naming: custom)
  gsd-tools phase add --id PROJ-42 "User Authentication"
  # Creates: .planning/phases/PROJ-42-user-authentication/
  # ROADMAP: ### Phase PROJ-42: User Authentication

All 755 existing tests pass.

Fixes #1019
2026-03-18 20:27:12 -04:00
Diego Mariño
29241b3cf9 Merge branch 'main' into feat/materialize-new-project-config 2026-03-18 23:12:42 +01:00
Tom Boucher
973c6b267d Merge pull request #1115 from trek-e/feat/discuss-phase-todo-crossref 2026-03-18 18:09:42 -04:00
Tom Boucher
7424b3448d Merge pull request #1117 from trek-e/fix/parallel-commit-no-verify-1116 2026-03-18 18:09:17 -04:00
Tom Boucher
73d6ec06cc Merge pull request #1132 from trek-e/feat/1m-context-awareness-1086 2026-03-18 18:08:19 -04:00
Tom Boucher
60f38cdb9e fix: remove duplicate stateExtractField, cross-platform code detection, STATE.md file locking
Code review fixes from codebase pattern analysis:

1. state.cjs: Remove duplicate stateExtractField() definition (lines 12 vs 184).
   The second definition shadowed the first with identical logic. Keeps the
   original that uses escapeRegex() from core.cjs.

2. init.cjs: Replace Unix-only 'find' pipe with cross-platform fs.readdirSync
   recursive walk for code file detection. The execSync('find ... | grep ...')
   command fails on Windows where these Unix utilities aren't available.
   Removes unused child_process import.

3. state.cjs: Add lockfile-based mutual exclusion to writeStateMd() to prevent
   parallel executor agents from overwriting each other's STATE.md changes.
   Uses O_EXCL atomic file creation for lock acquisition, stale lock detection
   (10s timeout), and spin-wait with jitter. Ensures data integrity during
   wave-based parallel execution where multiple agents update STATE.md
   concurrently.

All 755 existing tests pass.
2026-03-18 17:17:34 -04:00
Tom Boucher
3bfc0f6845 fix: add --no-verify support for parallel executor commits (#1116)
Parallel executor agents trigger pre-commit hooks on every commit, causing
build lock contention (e.g., cargo lock fights in Rust projects) and 40+
minute delays from cascading retries.

Changes:
- Add --no-verify flag to gsd-tools commit command (commands.cjs)
- Wire --no-verify through gsd-tools.cjs CLI parser
- Update execute-phase.md to instruct parallel agents to use --no-verify
- Add post-wave hook validation step so orchestrator runs hooks once
- Update execute-plan.md pre-commit handling: parallel agents skip hooks,
  sequential agents still handle hooks normally
- Add parallel agent note to git-integration.md reference

Fixes #1116
2026-03-18 17:17:34 -04:00
Tom Boucher
c7954d1ad7 refactor: deduplicate code, add planningPaths helper, annotate empty catches
Code quality refactoring across 9 lib modules:

1. state.cjs: Remove duplicate stateExtractField() definition (lines 12
   vs 184). Replace 3 inline regex escape patterns with escapeRegex()
   from core.cjs. Add getStatePath() local helper for the 15 repeated
   statePath declarations. Import planningPaths from core.

2. core.cjs: Add planningPaths(cwd) helper returning an object with all
   common .planning paths (state, roadmap, project, config, phases,
   requirements). Add planningDir(cwd) shorthand. Export both.

3. init.cjs: Replace Unix-only execSync('find . | grep | head') with
   cross-platform fs.readdirSync recursive walk for code file detection.
   Remove unused child_process import. Fixes Windows compatibility.

4. All lib modules: Annotate 48 empty catch blocks with
   /* intentionally empty */ to distinguish deliberate error swallowing
   from accidental missing handlers. Affected: commands.cjs (8),
   config.cjs (1), core.cjs (4), init.cjs (13), milestone.cjs (3),
   phase.cjs (6), roadmap.cjs (1), state.cjs (3), verify.cjs (9).

All 755 tests pass.
2026-03-18 12:31:20 -04:00
Tom Boucher
0377951a04 feat: context window size awareness for 1M+ models (#1086)
GSD was designed around 200k context windows. With Opus 4.6 / Sonnet 4.6
shipping 1M context at standard pricing, GSD should adapt its strategies.

Changes:
- Add context_window config option (default: 200000, configurable to 1000000)
- Expose context_window in init output so workflows can adapt behavior
- Update execute-phase.md to note context-size-dependent strategies:
  - 200k: paths-only executor context, 10-15% orchestrator budget
  - 1M+: richer context passing, inline small phases, relaxed /clear
- Context monitor already uses percentage-based thresholds (adaptive)

Users can opt in via config.json:
  { "context_window": 1000000 }

Addresses #1086
2026-03-18 12:27:55 -04:00
Tom Boucher
e84999663c feat(discuss-phase): cross-reference pending todos against phase scope
Add a cross_reference_todos step to discuss-phase that surfaces relevant
backlog items before scope-setting decisions are made.

Implementation:
- New 'todo match-phase <N>' CLI command (commands.cjs) that scores
  pending todos against a phase's ROADMAP goal using three heuristics:
  keyword overlap, area match, and file path overlap
- New cross_reference_todos step in discuss-phase.md between
  load_prior_context and scout_codebase
- CONTEXT.md template gains 'Folded Todos' subsection in <decisions>
  and 'Reviewed Todos (not folded)' subsection in <deferred>

Design:
- No AI call for matching — pure keyword/area/file heuristics for speed
- Silent skip when todo_count is 0 or no matches (no workflow slowdown)
- Auto mode folds all todos with score >= 0.4 automatically
- Scoring: keywords (up to 0.6), area match (0.3), file overlap (0.4)

Tests: 5 new tests covering empty state, keyword matching, unrelated
todo exclusion, area matching, and score sorting.

Closes #1111
2026-03-18 12:25:04 -04:00
Tom Boucher
7101ddcb9c fix: prevent PROJECT.md drift and fix phase completion counters (#956) (#1130)
Two gaps in the standard workflow cycle caused planning document drift:

1. PROJECT.md was never updated during discuss → plan → execute → verify.
   Only transition.md (optional) and complete-milestone evolved it.
   Added an 'update_project_md' step to execute-phase.md that evolves
   PROJECT.md after phase completion: moves requirements to Validated,
   updates Current State, bumps Last Updated timestamp.

2. cmdPhaseComplete() in phase.cjs advanced 'Current Phase' but never
   incremented 'Completed Phases' counter or recalculated 'percent'.
   Added counter increment and percentage recalculation based on
   completed/total phases ratio.

Addresses the workflow-level gaps identified in #956:
- PROJECT.md evolution in execute-phase (gap #2)
- completed_phases counter not incremented (gap #1 table row 3)
- percent never recalculated (gap #1 table row 4)

Fixes #956
2026-03-18 10:00:24 -06:00
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
c2c4301a98 feat: model alias-to-full-ID resolution for Task API compatibility (#991) (#1141)
Claude Code's Task tool sometimes doesn't resolve short aliases (opus,
sonnet, haiku) and passes them directly to the API, causing 404s. Tasks
then inherit the parent session's model instead of the configured one.

Added:
- MODEL_ALIAS_MAP in core.cjs mapping aliases to full model IDs
- resolve_model_ids config option (default: false for backward compat)
- resolveModelInternal() maps aliases when resolve_model_ids is true

Usage:
  { "resolve_model_ids": true }

This causes gsd-tools resolve-model to return 'claude-sonnet-4-5' instead
of 'sonnet', which the Task tool passes to the API without needing alias
resolution on Claude Code's side.

The alias map is maintained per release. Users can also use model_overrides
for full control.

All 755 tests pass.

Fixes #991
2026-03-18 09:57:42 -06:00
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
Diego Mariño
f649543b20 feat: materialize full config on new-project initialization
Add `config-new-project` CLI command that writes a complete,
fully-materialized `.planning/config.json` with sane defaults
instead of the previous partial template (6-7 user-chosen keys
only). Unset keys are no longer silently resolved at read time —
every key GSD reads is written explicitly at project creation.

Previously, missing keys were resolved silently by loadConfig()
defaults, making the effective config non-discoverable. Now every
key that GSD reads is written explicitly at project creation.

- buildNewProjectConfig() — single source of truth for all
  defaults; merges hardcoded ← ~/.gsd/defaults.json ← user choices
- ensureConfigFile() refactored to reuse buildNewProjectConfig({})
  instead of duplicating default logic (~40 lines removed)
- new-project.md Steps 2a and 5 updated to call config-new-project
  instead of writing a hardcoded partial JSON template
- Test coverage for config.cjs: 78.96% → 93.81% statements,
  100% functions; adds config-set-model-profile test suite

FIXES:
- VALID_CONFIG_KEYS extended with workflow.auto_advance,
  workflow.node_repair, workflow.node_repair_budget,
  hooks.context_warnings — these keys had hardcoded defaults
  but were not settable via config-set
2026-03-18 14:58:58 +01:00
Colin
3a0c81133b feat(quick): add quick-task branch support 2026-03-17 12:04:02 -04:00
Colin
f5167a5ca9 feat(claude-md): add workflow enforcement guidance 2026-03-17 11:41:44 -04:00
0Shard
7156f02ed5 fix: semver 3+ segment parsing and CRLF frontmatter corruption recovery
- fix(core): getMilestoneInfo() version regex `\d+\.\d+` only matched
  2-segment versions (v1.2). Changed to `\d+(?:\.\d+)+` to support
  3+ segments (v1.2.1, v2.0.1). Same fix in roadmap.cjs milestone
  extraction pattern.

- fix(state): stripFrontmatter() used `^---\n` (LF-only) which failed
  to strip CRLF frontmatter blocks. When STATE.md had dual frontmatter
  blocks from prior CRLF corruption, each writeStateMd() call preserved
  the stale block and prepended a new wrong one. Now handles CRLF and
  strips all stacked frontmatter blocks.

- fix(frontmatter): extractFrontmatter() always used the first ---
  block. When dual blocks exist from corruption, the first is stale.
  Now uses the last block (most recent sync).
2026-03-17 17:18:48 +02:00
Colin
6b6c73256d fix(health): preserve state on phase mismatch repair 2026-03-17 11:08:32 -04:00
Colin
52b2d390cc feat(milestones): support safe phase-number resets 2026-03-17 11:00:24 -04: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