Commit graph

1074 commits

Author SHA1 Message Date
Tom Boucher
4a43679bc0 fix: add debug logging to silent early-return paths in dispatchNextUnit (#823) (#836) 2026-03-17 07:59:13 -06:00
Tom Boucher
a7453719f5 fix: add fallback parser for prose-style roadmaps without ## Slices section (#807) (#835)
When the LLM writes freeform prose roadmaps with `## Slice S01: Title`
headers instead of the machine-readable `## Slices` checklist,
parseRoadmapSlices() returned zero slices, causing deriveState() to
permanently block with 'No slice eligible'.

Add a fallback parser that detects prose-style `## Slice SXX:` headers
(and variants like `## S01:`, `## S01 —`) and extracts slice IDs,
titles, and dependencies from the prose. Also parses `Depends on:`
text patterns. All fallback slices default to risk:medium and done:false.
2026-03-17 07:49:50 -06:00
Tom Boucher
2f459b5d03 fix: remove untracked .gsd/ state files before milestone merge checkout (#827) (#834)
When merging a milestone back to main, `git checkout main` fails if
untracked .gsd/ state files (STATE.md, completed-units.json, auto.lock)
in the working tree conflict with tracked files on the branch.

Remove these known GSD-managed state files before checkout. They are
runtime artifacts regenerated by doctor/rebuildState and are not
meaningful in the main working tree — the worktree had the real state.
2026-03-17 07:49:26 -06:00
Tom Boucher
d94728aa7e fix: prevent crash when cancelling OAuth provider login dialog (#821) (#831)
OAuthSelectorComponent calls its onSelect callback synchronously (no
await), but the callback was async — calling showLoginDialog which
throws 'Login cancelled' on Escape. The unhandled rejection bubbled
up to the uncaughtException handler and crashed GSD.

Wrap the async work in a named function with .catch() so cancellation
errors are swallowed gracefully. showLoginDialog already handles its
own error display internally.
2026-03-17 07:49:09 -06:00
Tom Boucher
776a8800d8 fix: include STATE.md, KNOWLEDGE.md, OVERRIDES.md in worktree artifact copy (#809) (#830)
Worktree initialization only copied DECISIONS.md, REQUIREMENTS.md,
PROJECT.md, and QUEUE.md. The missing STATE.md caused the pre-dispatch
health check in doctor-proactive.ts to block dispatch with
'STATE.md missing'.

Add STATE.md, KNOWLEDGE.md, and OVERRIDES.md to the copy list so
worktrees start with complete planning state.
2026-03-17 07:48:53 -06:00
Tom Boucher
c6d1bdd1cc fix: compare gsdVersion instead of syncedAt for resource staleness check (#804) (#829)
Every new pi session writes a fresh syncedAt timestamp to
managed-resources.json, causing a running auto-mode session to falsely
detect a GSD update and stop. The actual version (gsdVersion) only
changes on real upgrades.

Switch the staleness check from syncedAt (timestamp) to gsdVersion
(semver string) so that launching a second session no longer triggers
a false positive.
2026-03-17 07:48:38 -06:00
Tom Boucher
ef706726c8 fix: use unique temp paths in saveFile() to prevent parallel write collisions (#810) (#828)
When multiple tool calls (e.g. concurrent gsd_save_decision) target the
same markdown file, the deterministic .tmp suffix caused ENOENT on
rename() because one caller consumed the temp file before another could
rename it.

Replace the static `.tmp` suffix with a per-call random suffix so each
concurrent writer gets its own temp file. Also clean up orphaned temp
files on rename failure.
2026-03-17 07:48:18 -06:00
Tom Boucher
b44896e187 fix: generate validation and summary files for completed milestones during migration (#819) (#838)
The .planning → .gsd migration creates roadmaps and summaries but not
VALIDATION files. deriveState() requires a terminal validation file
(verdict: pass) to consider a milestone complete. Without it, every
migrated milestone enters validating-milestone phase, blocking progress
to the actual current milestone.

For milestones where all slices are done, write a pass-through
VALIDATION.md (verdict: pass, migrated: true) and SUMMARY.md so
deriveState() skips them correctly.

Updated integration test to verify VALIDATION/SUMMARY files are written
and deriveState returns 'complete' phase with activeMilestone pointing
to the last completed entry (expected behavior).
2026-03-17 07:47:57 -06:00
Tom Boucher
1aebc06c46 docs: update documentation for v2.24 release features (#825)
- README: add parallel orchestration link, update loop diagram with validate-milestone phase
- architecture: add lazy provider loading, memory-extractor/store modules, update module table to v2.24
- auto-mode: add rate limit recovery section, parallel worker status in dashboard
- commands: add headless new-milestone command with --context/--context-text/--auto flags
- getting-started: add update check notification note
- troubleshooting: update rate limit recovery guidance
- visualizer: add task counts, discussion status to progress tab
2026-03-17 07:47:28 -06:00
Adam Dry
68edb39f9e fix: add gsd_generate_milestone_id tool for multi-milestone unique ID generation (#818)
When unique_milestone_ids is enabled, the LLM cannot generate random
suffixes itself. Previously only the first milestone got a correct ID
(pre-generated in TS), while subsequent milestones in multi-milestone
projects got bare M002/M003 without suffixes.

Added a gsd_generate_milestone_id tool that the LLM calls to get each
milestone ID. The tool scans disk for existing milestones and respects
the unique_milestone_ids preference, making it impossible to produce
wrong-format IDs.

Updated discuss, discuss-headless, and queue prompts to instruct the
LLM to use the tool instead of inventing milestone IDs.
2026-03-17 07:47:11 -06:00
deseltrus
7c449b8b73 feat: worker NDJSON monitoring + budget enforcement for parallel orchestration (#814)
* feat: worker NDJSON monitoring, budget enforcement, PID-based stop fallback

Closes three gaps in parallel orchestration:

1. **Worker stdout monitoring** — Workers now run with `--mode json` so
   they emit NDJSON events. The coordinator parses stdout line-by-line,
   extracting cost/token data from `message_end` events. This keeps
   per-worker cost tracking in sync with actual API spend and updates
   session status files for live dashboard visibility.

2. **Budget enforcement before spawn** — `startParallel()` now checks
   `isBudgetExceeded()` before each worker spawn. When the aggregate
   cost across all workers reaches the configured ceiling, no new
   workers are started.

3. **PID-based stop fallback** — `stopParallel()` now falls back to
   `process.kill(pid, "SIGTERM")` when the ChildProcess handle is null
   (e.g., after coordinator restart when handles aren't available).
   Previously, orphaned workers could not be stopped.

Includes 11 new tests covering NDJSON format validation, cost
aggregation, budget ceiling comparison, and PID-based kill patterns.
All 54 existing parallel-orchestration tests still pass.

Relates to #672

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: currentUnit type must match SessionStatus interface (object | null, not string)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 07:46:52 -06:00
Lex Christopherson
4883ed1e99 2.25.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:47:17 -06:00
Lex Christopherson
8c9b40cb5e docs: update changelog for v2.25.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:46:58 -06:00
TÂCHES
440e6e878f feat: render native web search in TUI + PREFER_BRAVE_SEARCH toggle (#806)
* feat: render native web search tool calls in TUI

The Anthropic streaming parser silently dropped server_tool_use and
web_search_tool_result content blocks, making native web search
invisible. Add ServerToolUseContent and WebSearchResultContent types,
handle both block types in the streaming parser and conversation replay,
and render them as ToolExecutionComponent in the interactive TUI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add PREFER_BRAVE_SEARCH env var to bypass native web search

Set PREFER_BRAVE_SEARCH=1 to keep Brave/custom search tools active
on Anthropic models instead of injecting native server-side web search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: skip non-toolCall blocks in Mistral provider conversation replay

The ServerToolUseContent and WebSearchResultContent types added for
native web search don't have id/name/arguments properties, causing
TypeScript errors when the Mistral provider tried to push them as
tool calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:35:20 -06:00
TÂCHES
3adacf3ff5 feat: meaningful commit messages from task summaries (#803)
* feat: meaningful commit messages from task summaries (#785, #784)

Post-task commits now derive messages from the task summary one-liner,
inferred type, and key files. Planning prompts respect commit_docs: false.
Commit type inference expanded with perf type and oneLiner parameter.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: replace invalidateStateCache with invalidateAllCaches in crash recovery

PR #799 reintroduced invalidateStateCache() calls in the phantom skip
loop crash recovery paths. These should use invalidateAllCaches() which
is the renamed function.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve CI failures from main merge conflicts

- Replace invalidateStateCache() → invalidateAllCaches() in crash
  recovery paths (reintroduced by PR #799 merge)
- Expand smart-entry-draft test chunk window from 3000 to 4000 chars
  to accommodate commitInstruction additions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:30:33 -06:00
TÂCHES
28bb77b999 Merge pull request #805 from jeremymcs/test/expand-e2e-smoke-tests
test: expand E2E smoke tests with 14 new CLI verification tests
2026-03-16 23:18:25 -06:00
Jeremy McSpadden
aaf3fe394c fix: replace orphaned invalidateStateCache() calls and remove dead test
- Replace 2 remaining invalidateStateCache() calls with invalidateAllCaches()
  in auto.ts phantom skip loop recovery paths (lines 2473, 2551)
- Remove commit-message.test.ts which referenced the removed
  deriveCommitMessage export from auto.ts
2026-03-17 00:09:02 -05:00
Jeremy McSpadden
2d037249c4 test: expand E2E smoke tests with 14 new CLI verification tests
Add comprehensive black-box smoke tests covering command routing,
graceful error handling, headless mode validation, and help completeness.

New tests:
- Command routing: headless --help, sessions --help
- Flag aliases: -v (--version), -h (--help)
- Error handling: no-TTY clean exit, unknown flags resilience
- Headless mode: missing .gsd/ dir, missing --context, invalid/negative --timeout
- Help completeness: all subcommands listed, all key flags listed
- Edge cases: --version ignores trailing args, headless positional help

All tests run without API keys and use temp directory isolation.
2026-03-17 00:02:26 -05:00
TÂCHES
0e5cbee8d8 Merge pull request #799 from gsd-build/fix/790-crash-recovery-phantom-loop
fix: prevent phantom skip loop from stale crash recovery context (#790)
2026-03-16 22:35:10 -06:00
TÂCHES
e695cccc91 Merge pull request #801 from gsd-build/fix/clear-artifacts-in-invalidateAllCaches
fix: include DB artifact cache in invalidateAllCaches (#793)
2026-03-16 22:34:56 -06:00
TÂCHES
01646dce48 Merge pull request #798 from gsd-build/fix/792-skip-loop-uninterruptible
fix: make skip-loop interruptible and count toward lifetime cap (#792)
2026-03-16 22:32:45 -06:00
Lex Christopherson
72c86e0792 fix: include DB artifact cache in invalidateAllCaches (#793)
Cherry-picked from #797 — adds clearArtifacts() to gsd-db.ts and wires
it into invalidateAllCaches() so the DB artifact table is cleared
alongside state/path/parse caches.

Co-Authored-By: 0xLeathery (PR #797)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:32:10 -06:00
TÂCHES
5271e51a84 Merge pull request #796 from jeremymcs/fix/793-db-cache-invalidation
fix: invalidateAllCaches() in skip-loop eviction and rebuildState (#793)
2026-03-16 22:31:23 -06:00
Lex Christopherson
0184498a44 fix: prevent phantom skip loop from stale crash recovery context (#790)
When a crash lock references a unit from a fully-completed milestone,
crash recovery injects stale context that fights the skip-loop breaker,
creating an infinite evict/repair cycle with selfHealRuntimeRecords.

Fix 1: Validate recovered unit's milestone before synthesizing recovery
context. If the milestone has a SUMMARY file (complete), discard the
stale recovery context and clear the lock without injection.

Fix 2: Skip-loop breaker cross-checks whether the evicted unit belongs
to a completed milestone. If so, the eviction is counterproductive —
clear the skip counter and re-dispatch from fresh state instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:30:15 -06:00
TÂCHES
3e52f4d66b feat: incremental memory system for auto-mode (#795)
* chore: add .audits/ to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add auto-learned project memory system

Extracts durable knowledge from completed unit activity logs via
background LLM calls (Haiku-preferred) and injects ranked memories
into the system prompt. Includes DB schema v3 migration, memory store
CRUD with confidence/hit-count ranking, secret redaction, decay, and
cap enforcement.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add timestamp to UserMessage in memory extractor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update schema version assertion in md-importer test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:29:35 -06:00
Lex Christopherson
22f623889f fix: make skip-loop interruptible and count toward lifetime cap (#792)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 22:27:39 -06:00
Jeremy McSpadden
3991479570 fix: invalidateAllCaches() in skip-loop eviction and rebuildState (#793)
Root cause:
  The skip-loop breaker in dispatchNextUnit() called invalidateStateCache()
  which only clears the in-memory _stateCache. Path caches (nativeTreeCache,
  dirEntryCache) and parse caches (_parseCache) remained warm. On the next
  deriveState() call, the nativeBatchParseGsdFiles/cachedLoadFile path used
  the stale cache to build fileContentCache, returning the same stale unit
  — looping forever even though disk had the correct [x] state.

  rebuildState() in doctor.ts had the same bug: it called deriveState()
  without invalidating caches first, writing stale state to STATE.md.

Fix:
  1. auto.ts: replace all invalidateStateCache() calls in dispatch hot paths
     with invalidateAllCaches() so path, parse, and state caches are all
     cleared before the next deriveState() call.

  2. doctor.ts: call invalidateAllCaches() at the top of rebuildState() so
     STATE.md is always written from fresh disk reads.

  3. Remove now-unused invalidateStateCache import from auto.ts.

Test:
  Added #793 test to auto-recovery.test.ts: creates a fixture with T01
  active, simulates task completion on disk (plan [x] + summary written),
  calls invalidateAllCaches(), then asserts deriveState() returns T02 as
  active (not T01 again). 30 passed, 0 failed.
2026-03-16 23:21:13 -05:00
Jeremy McSpadden
3ea832c166 fix: reconcile plan checkboxes on worktree re-attach after crash (#778) (#794)
Root cause:
  When auto-mode stops via crash (not graceful stop), the milestone branch
  HEAD lags behind the filesystem state at the project root. This is because
  syncStateToProjectRoot() runs after every task completion and writes [x]
  checkboxes to the project root, but the auto-commit that would record
  those changes to the milestone branch may not have fired before the crash.

  On restart, createAutoWorktree() re-attaches the worktree to the milestone
  branch HEAD (which still has [ ] for the crashed task). When dispatchNextUnit()
  then runs verifyExpectedArtifact(), it reads the plan from the worktree and
  finds [ ], treats the completion record as stale, evicts the key, and
  re-dispatches — entering an infinite skip/dispatch loop.

Fix:
  Add reconcilePlanCheckboxes(projectRoot, wtPath, milestoneId) which is called
  when re-attaching to an existing branch. It walks every markdown file in the
  milestone directory at the project root and forward-applies any [x] checkbox
  states that are ahead of the worktree version (never downgrades [x] → [ ]).
  It also forward-merges completed-units.json.

  The project root is the correct source of truth here because
  syncStateToProjectRoot() is called after every task completion and keeps
  it up-to-date. If the branch HEAD is behind due to a crash, the root
  filesystem copy is the last known good state.

  This is safe: we only ever advance checkbox state ([ ] → [x]), never
  regress it. The milestone branch content is preserved for all other files.

Test:
  Added test case to auto-worktree.test.ts covering the exact scenario:
  - T01 [x] committed to milestone branch, T02 [x] written to project root
    (by syncStateToProjectRoot) but commit never fired
  - Worktree re-created from milestone branch HEAD (T02 still [ ])
  - After reconciliation, worktree plan has T02 [x], T03 stays [ ]
2026-03-16 22:14:34 -06:00
Jeremy McSpadden
2b3846fab9 feat: enrich visualizer with stats and discussion status (#791) 2026-03-16 22:14:06 -06:00
Tom Boucher
59134fa426 docs: update documentation for v2.23 release features (#788)
New v2.23 features documented:

- getting-started.md: Add VS Code extension install section (chat participant,
  sidebar dashboard, command palette, RPC requirement)
- README.md: Add VS Code extension to documentation index, update troubleshooting
  link to include forensics
- docs/README.md: Add VS Code extension to user documentation table
- architecture.md: Add headless mode, MCP server mode, and VS Code extension to
  system structure diagram; expand Browser Tools description to cover 10 new tools
  (PDF export, device emulation, visual regression, structured extraction, route
  mocking, etc.); add missing extensions (Async Jobs, Remote Questions, TTSR,
  Universal Config)
- auto-mode.md: Add validate-milestone phase to the pipeline diagram and phase
  descriptions — reconciliation gate before milestone completion
- configuration.md: Add models.json resolution section — custom model definitions
  with ~/.gsd/agent/models.json and ~/.pi/agent/models.json fallback

Co-authored-by: TÂCHES <afromanguy@me.com>
2026-03-16 21:56:00 -06:00
Tom Boucher
2f2d0507c1 docs: update documentation for v2.22 features (#787)
New v2.22 features documented:

- commands.md: Add /gsd forensics (post-mortem investigation) and /gsd cleanup
- commands.md: Add MCP Server Mode section for --mode mcp
- configuration.md: Add /gsd prefs import-claude commands for Claude marketplace import
- skills.md: Add review, test, and lint skills to bundled skills table
- auto-mode.md: Add Post-Mortem Investigation section referencing /gsd forensics
- troubleshooting.md: Add forensics to Getting Help section, fix corrupted duplicate line
- README.md: Update troubleshooting link description to include forensics
2026-03-16 21:47:20 -06:00
Tom Boucher
7712abe7d1 refactor: remove unnecessary 'as any' casts, dead exports, and duplicate code (#786)
Issues addressed:

1. guided-flow.ts: Remove 12 unnecessary 'ctx as any' casts
   - ctx is already ExtensionCommandContext, matching showNextAction/showConfirm signatures
   - The casts masked type-checking with no benefit

2. triage-ui.ts: Remove 1 unnecessary 'ctx as any' cast (same issue as #1)

3. migrate/command.ts: Remove 2 unnecessary 'ctx as any' casts (same issue as #1)

4. models-resolver.ts: Remove dead exports hasBothModelsFiles() and getModelsPaths()
   - Never imported outside the module or in any test file
   - resolveModelsJsonPath() (the only consumer) remains

5. resource-loader.ts: Remove dead export readManagedResourceSyncedAt()
   - Exported but never imported anywhere in the entire codebase

6. bg-shell/overlay.ts: Extract processStatusHeader() helper
   - DRYs the duplicated status icon + name + uptime + tab indicator
     construction shared between renderOutput() and renderEvents()

7. get-secrets-from-user.ts: Merge duplicate vercel/convex deployment blocks
   - Both had identical exec → check result code → push applied/errors pattern
   - Merged into single conditional with destination-specific command string

Documented but not changed (boundary constraints):
- src/mcp-server.ts ↔ src/resources/extensions/gsd/mcp-server.ts
  (compiled/jiti boundary prevents sharing)
- src/remote-questions-config.ts ↔ remote-questions/remote-command.ts
  (same compiled/jiti boundary per #592)
- cli.ts internal duplication of session setup (structural, different resource loader configs)
2026-03-16 21:47:04 -06:00
Lex Christopherson
ad4e68551d 2.24.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:38:35 -06:00
Lex Christopherson
fe61c3cacd docs: update changelog for v2.24.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:38:19 -06:00
TÂCHES
193b2b32a5 fix: strip clack UI from postinstall, keep silent Playwright download (#783)
npm ≥7 suppresses lifecycle script output by default, so the clack
banner/spinner was invisible during `npm install -g`. The user-facing
onboarding experience already lives at first `gsd` launch (onboarding.ts),
making the postinstall UI redundant dead code.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:35:04 -06:00
TÂCHES
69d37d3196 feat: add headless new-milestone command for programmatic milestone creation (#781)
Enables fully headless project creation from specification documents via
`gsd headless new-milestone --context spec.md`. Supports file input,
stdin piping, inline text, and optional auto-mode chaining with --auto.

Key changes:
- headless.ts: new CLI flags (--context, --context-text, --auto, --verbose),
  context loading (file/stdin/inline), .gsd/ bootstrapping, auto-mode chaining
- commands.ts: /gsd new-milestone command routing via headless context temp file
- guided-flow.ts: showHeadlessMilestoneCreation(), bootstrapGsdProject(),
  buildHeadlessDiscussPrompt() for non-interactive milestone creation
- prompts/discuss-headless.md: headless variant of discuss.md that skips Q&A
  rounds and works entirely from the provided specification
- help-text.ts: documentation for new-milestone subcommand and flags

Closes #765

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:28:56 -06:00
Tom Boucher
8dcb2f9195 fix: sync completed-units.json across worktree boundary (#769) (#780)
Follow-up to #774. When GSD runs in worktree isolation mode,
completed-units.json can fragment across project root and worktree
locations. If a session crashes or the worktree is removed after
milestone merge, keys written to the worktree are lost — causing
already-completed units to be re-dispatched.

Two fixes:
1. syncStateToProjectRoot() now performs a set-union merge of
   completed-units.json from worktree into project root.
2. After worktree entry at startup, loadPersistedKeys() runs against
   both project root and worktree so the in-memory completedKeySet
   contains the union of both locations.

Co-authored-by: Lex Christopherson <lex@glittercowboy.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:28:08 -06:00
Jeremy McSpadden
d64ed32850 feat: interactive update prompt on startup (#770) (#775)
* feat: interactive update prompt on startup (#770)

When a newer version of gsd-pi is available, show an interactive
prompt at startup with two options:
  [1] Update now  (runs npm install -g gsd-pi@latest)
  [2] Skip

- Adds checkAndPromptForUpdates() to update-check.ts
  - Reuses existing 24h cache so the registry is hit at most once/day
  - Shows a boxed banner with current → latest versions
  - Runs npm install -g gsd-pi@latest if the user picks [1]
  - Exits after a successful update so the user relaunches with the new build
  - Cleans up stdin state (listeners + raw mode) so the TUI starts cleanly
- Updates cli.ts to call checkAndPromptForUpdates() instead of the
  fire-and-forget checkForUpdates() in interactive mode
- Skipped in print/RPC/MCP/headless modes (isPrintMode guard)

* fix: update-check prompt cleanup and robustness (#770)

- Remove duplicate NPM_PACKAGE constant (was shadowing NPM_PACKAGE_NAME)
- Fix hardcoded box width: measure visible text width dynamically so the
  border aligns correctly for any version string length
- Add 30s timeout to rl.question so the prompt auto-skips in non-TTY
  or piped-stdin edge cases that slip past the isPrintMode guard

* fix: address review feedback on update prompt (#770)

Three issues from @glittercowboy's review:

1. Box rendering bug: mid line was built as '║' + content + '║' then
   sliced with .slice(1,-1) which cuts into ANSI escape sequences.
   Fix: build midContent without delimiters and wrap with chalk.yellow('║')
   directly, keeping a separate plain-text midVisible for width measurement.

2. Missing TTY guard: !isPrintMode alone isn't sufficient — a piped
   stdin without --print would sit waiting 30s silently.
   Fix: gate checkAndPromptForUpdates() on process.stdin.isTTY; fall back
   to the passive checkForUpdates() banner for non-TTY interactive mode.

3. Dead import: checkForUpdates was imported but unused after the
   previous refactor. Now used again as the non-TTY fallback — no
   dead code.
2026-03-16 21:09:33 -06:00
TÂCHES
ed341a95b1 fix: downgrade missing_tasks_dir to warning for completed slices (#772)
* fix: downgrade missing_tasks_dir to warning for completed slices (#726)

When a worktree is removed and artifacts are rebuilt, tasks/ directories
aren't recreated. For completed slices this is cosmetic scaffolding, not
a structural error. Downgrade severity from "error" to "warning" so
completed milestones can render in /gsd visualize.

Also skip the missing_slice_plan warning entirely for completed slices,
since a plan file serves no purpose after completion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use slice.done instead of non-existent frontmatter.status

The SummaryFrontmatter type doesn't have a `status` property.
Use `slice.done` from the roadmap parser instead, which is the
canonical completion signal already available in scope.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:09:17 -06:00
TÂCHES
912b48adad fix: auto-resume auto-mode after rate limit cooldown (#756) (#776)
When auto-mode pauses due to a rate limit, schedule automatic resumption
after the rate limit window elapses. Shows a countdown notification so
the user knows what's happening. Non-rate-limit errors still pause
indefinitely for manual intervention.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:03:46 -06:00
Tom Boucher
3c1a4e9109 fix: worktree artifact verification uses correct base path (#769) (#774)
Three fixes for the worktree isolation stuck-state bug:

1. selfHealRuntimeRecords on initial start used the function parameter
   `base` (main project root) instead of `basePath` (worktree path after
   entry). This meant stale runtime records in the worktree were never
   found or healed, leaving dispatched records that block auto-mode.

2. syncStateToProjectRoot now copies runtime/units/ records alongside
   milestone data. This provides defense-in-depth: even if selfHeal runs
   before worktree re-entry, stale records from a prior sync are visible.

3. initMetrics and initRoutingHistory also corrected from `base` to
   `basePath` — same class of bug (stale function parameter after
   worktree entry).

Adds test verifying selfHealRuntimeRecords resolves artifacts and clears
records correctly when pointed at a worktree base path.
2026-03-16 21:03:22 -06:00
TÂCHES
52848d7fd2 fix: raise maxDelayMs default from 60s to 300s (#756) (#773)
Anthropic rate limit reset windows are typically 60-120s. The previous 60s
default, combined with the +1s buffer in extractRetryAfterMs(), meant that
virtually all rate limit retries were immediately abandoned.

300s (5 min) covers the vast majority of rate limit windows and lets the
built-in retry logic work as intended.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:03:13 -06:00
Lex Christopherson
2ff45b7439 fix: remove bogus AGENTS.md symlink from dev-symlink script
Nothing reads ~/.gsd/agent/AGENTS.md, and the script was incorrectly
pointing it at agents/researcher.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:46:54 -06:00
Gary Trakhman
0c28a1d078 feat: Add symlink-based development workflow for src/resources/ (#744)
- Add scripts/dev-symlink.sh for managing symlinks between src/resources/
  and ~/.gsd/agent/
- Supports three modes: create (default), --remove, --status
- Preserves config files: auth.json, models.json, settings.json,
  managed-resources.json
- Creates symlinks for: extensions/, skills/, agents/, GSD-WORKFLOW.md
- Backs up existing directories before creating symlinks
- Adds npm scripts: dev:symlink, dev:symlink:remove, dev:symlink:status,
  dev:clean, dev:full
2026-03-16 20:45:52 -06:00
Lex Christopherson
7d17be3880 Merge pull request #764 from x3kim/add-command-descriptions
feat: add descriptions to /gsd autocomplete commands
2026-03-16 20:45:22 -06:00
Lex Christopherson
d75d089f93 Merge pull request #768 from faldor20/fix/file-permissions
Fix read-only file permissions after cpSync from Nix store
2026-03-16 20:45:15 -06:00
TÂCHES
0aa8934fb3 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-16 20:44:53 -06:00
copilot-swe-agent[bot]
9ed5c12efe Fix read-only file permissions after cpSync from Nix store
Co-authored-by: faldor20 <26968035+faldor20@users.noreply.github.com>
2026-03-16 20:44:43 -06:00
x3kim
2b281af37a feat: add descriptions to /gsd autocomplete commands 2026-03-16 20:42:34 -06:00
TÂCHES
4e562831e6 Merge pull request #762 from 0xLeathery/fix/stop-auto-reason
fix: add stop reason to every auto-mode stop
2026-03-16 20:39:50 -06:00