Commit graph

1037 commits

Author SHA1 Message Date
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
TÂCHES
f602cc19f4 Merge pull request #763 from 0xLeathery/fix/resource-sync-always
fix: always sync bundled resources and clean stale files
2026-03-16 20:35:12 -06:00
Lex Christopherson
28c48e0a40 Merge pull request #719 from jeremymcs/feat/672-parallel-milestone-orchestration
feat: parallel milestone orchestration foundation (#672)
2026-03-16 20:32:54 -06:00
Jeremy McSpadden
e36da37f33 fix: add required customType and display fields to parallel sendMessage calls
The sendMessage() API requires customType and display fields. All parallel
command handlers were missing these, causing typecheck failures in CI.
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
0ee7016bc7 feat: add dashboard parallel workers view, 80% budget alert, and E2E tests
Add three remaining features:

1. Dashboard multi-session view: New worker registry
   (subagent/worker-registry.ts) tracks active parallel subagent sessions
   with batch grouping and status lifecycle. Dashboard overlay now renders
   a "Parallel Workers" section showing per-batch worker status with
   agent names, task previews, and elapsed time.

2. Budget approach notification at 80%: Added 80% threshold to the
   existing 75/90/100 budget alert levels. Fires an "Approaching budget
   ceiling" notification with desktop alert at the 80% mark, giving
   users earlier warning before hitting enforcement thresholds.

3. End-to-end testing across milestones: New E2E test validates parallel
   worker lifecycle across M001/M002 milestones, metrics accumulation,
   full budget alert progression (0→75→80→90→100), cost prediction with
   multi-milestone data, and combined worker+budget scenarios.
   Worker registry unit tests cover registration, batch grouping, status
   updates, and edge cases.
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
01b0d530c8 docs: parallel milestone orchestration documentation
New: docs/parallel-orchestration.md — comprehensive guide covering:
- Architecture overview with coordinator/worker diagram
- Worker isolation model (process, worktree, state, context)
- Eligibility analysis (dependencies + file overlap)
- Configuration reference (all parallel.* keys)
- Commands reference (/gsd parallel start|status|stop|pause|resume|merge)
- Signal lifecycle (coordinator → worker communication)
- Merge reconciliation with conflict handling
- Budget management across workers
- Doctor integration and health monitoring
- Safety model breakdown
- File layout (.gsd/parallel/ and .gsd/worktrees/)
- Troubleshooting guide

Updated existing docs:
- auto-mode.md: cross-reference to parallel orchestration
- configuration.md: parallel config block with all keys
- commands.md: parallel commands table
- git-strategy.md: parallel worktree branching diagram
- README.md: added to documentation index
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
9232ad6a2b feat: worker process spawning, milestone lock, signal handling (#672)
Worker spawning (parallel-orchestrator.ts):
- spawnWorker() creates child processes via spawn() with
  GSD_MILESTONE_LOCK env var for state isolation
- GSD_PARALLEL_WORKER env var prevents nested parallel sessions
- Workers run `gsd --print "/gsd auto"` in their worktree cwd
- Exit handler updates worker state on completion/crash
- Graceful error handling for spawn failures (ENOENT, etc.)
- SIGTERM sent on stopParallel for immediate process termination

Worktree creation:
- createMilestoneWorktree() creates git worktrees using
  milestone/<MID> branch naming without chdir (coordinator stays put)
- Reuses existing milestone branches to preserve prior work
- Runs post-create hooks for user scripts (.env copy, etc.)

GSD_MILESTONE_LOCK in state.ts:
- deriveState() filters to only the locked milestone
- getActiveMilestoneId() short-circuits when lock is set
- Complete worker isolation — each process sees one milestone

Signal consumption in auto.ts:
- handleAgentEnd() checks for coordinator signals between units
- Responds to "stop" and "pause" signals immediately

/gsd parallel merge command:
- Merge specific or all completed milestones back to main

976/976 full test suite passing, zero regressions.
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
3dbb1faa13 feat: milestone lock, signal handling, merge command, worker stub (#672)
GSD_MILESTONE_LOCK in state.ts:
- deriveState() filters milestoneIds to only the locked milestone
- getActiveMilestoneId() short-circuits when lock is set
- Each parallel worker sees only its assigned milestone

Signal consumption in auto.ts:
- handleAgentEnd() checks for coordinator signals before dispatching
- Responds to "stop" (calls stopAuto) and "pause" (calls pauseAuto)
- Only active when GSD_MILESTONE_LOCK env var is set

/gsd parallel merge command:
- /gsd parallel merge [mid] — merge specific or all completed milestones
- Wired into commands.ts with argument completions

Worker spawning stub:
- spawnWorker() validates state and documents the implementation plan
- Actual process forking deferred to auto-mode integration

976/976 full test suite passing, zero regressions.
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
db1032f580 feat: doctor integration, merge reconciliation, dispatch hardening credit (#672)
Doctor integration:
- Add "stale_parallel_session" issue code to /gsd doctor
- Detects orphaned parallel sessions (dead PID or expired heartbeat)
- Auto-fixable: cleans up stale .gsd/parallel/ status files

Merge reconciliation (parallel-merge.ts):
- determineMergeOrder: sequential or by-completion ordering
- mergeCompletedMilestone: wraps existing mergeMilestoneToMain with
  parallel-safe error handling and session cleanup
- mergeAllCompleted: sequential merge with stop-on-conflict
- formatMergeResults: human-readable merge status output

Dispatch hardening (PR 2 from plan):
Already landed via @deseltrus contributions:
- _skipDepth + MAX_SKIP_DEPTH guard (#465)
- _dispatching re-entrancy mutex (#465)
- inFlightTools tool-aware idle detection (#596)

Tests: 54 total (15 new), 976/976 full suite passing.

Suggested-by: deseltrus <deseltrus@users.noreply.github.com>
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
77e14a060b fix: add .gsd/parallel/ to gitignore patterns
Prevents parallel session status and signal files from being
tracked by git. These are runtime-only coordination files.
2026-03-16 20:32:10 -06:00
Jeremy McSpadden
eb302fe1d2 feat: parallel milestone orchestration foundation (#672)
Add infrastructure for parallel milestone execution behind
`parallel.enabled: false` flag (opt-in, zero impact to existing users).

New modules:
- session-status-io.ts: File-based IPC protocol with atomic writes,
  signal lifecycle (pause/resume/stop), and stale session detection
- parallel-eligibility.ts: Milestone parallelism analysis checking
  dependency satisfaction and file overlap across slice plans
- parallel-orchestrator.ts: Core orchestrator managing worker lifecycle,
  budget tracking, and coordination via session status files
- /gsd parallel [start|status|stop|pause|resume] command handlers

Modified:
- types.ts: ParallelConfig interface (enabled, max_workers, budget_ceiling,
  merge_strategy, auto_merge)
- preferences.ts: Parallel config validation, merging, and resolver
- commands.ts: /gsd parallel subcommand routing with argument completions

Tests: 39 new tests covering session I/O roundtrip, signal lifecycle,
stale detection, eligibility formatting, orchestrator lifecycle,
budget enforcement, and preference validation.
2026-03-16 20:32:10 -06:00
TÂCHES
392b75a4db Merge pull request #767 from trek-e/fix/759-auto-mode-stale-state-loop
fix: prevent stale state loop on auto-mode restart with existing worktree (#759)
2026-03-16 20:29:43 -06:00
TÂCHES
6a452f27d9 Merge pull request #750 from jeremymcs/fix/startup-lazy-loading
perf: lazy-load LLM provider SDKs to reduce startup time
2026-03-16 20:28:32 -06:00
Tom Boucher
aafd254f45 fix: prevent stale state loop on auto-mode restart with existing worktree (#759)
Two compounding bugs caused auto-mode to loop infinitely after stopping
and restarting when a worktree with committed progress existed:

Bug 1: copyPlanningArtifacts overwrites worktree state on restart

When auto-mode restarts and the milestone branch exists (worktree dir was
removed but branch preserved), createAutoWorktree re-attaches the worktree
to the existing branch — git correctly checks out the committed state with
[x] checkboxes. But then copyPlanningArtifacts unconditionally copies the
project root's .gsd/milestones/ into the worktree, overwriting the correct
[x] with stale [ ] from the root (which isn't always fully synced).

Fix: Skip copyPlanningArtifacts when branchExists is true. The branch
checkout already has the correct artifacts from committed work.

Bug 2: deriveState reads stale content from SQLite DB

deriveState had a DB-first content loading path that read artifact content
from the SQLite artifacts table. This table was populated once during
migrateFromMarkdown and never updated when files changed on disk (roadmap
checkbox updates, plan changes, etc.). Even after fixing files on disk,
deriveState returned stale DB content, keeping the state machine stuck.

Fix: Remove the DB content loading path from deriveState entirely. The
native Rust batch parser (nativeBatchParseGsdFiles) reads all .md files
in one call and is fast enough. The DB is still used for structured queries
(decisions, requirements) but no longer as a content cache for state
derivation.

Updated derive-state-db.test.ts Test 5 to write requirements to disk
instead of testing the now-removed DB-only content path.
2026-03-16 22:20:30 -04:00
Ethan Hurst
0dd0a1a4d2 fix: add missing reasonSuffix declaration in stopAuto
The reason parameter was added to stopAuto() but the reasonSuffix
variable derived from it was never declared, causing TS2304 errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:13:02 +10:00
TÂCHES
ebde7501dd Merge pull request #748 from jeremymcs/fix/739-epipe-stale-research-state
fix(auto): prevent runaway execute-task when task plan missing after failed research (#739)
2026-03-16 20:02:27 -06:00
TÂCHES
30dad00965 Merge pull request #758 from jeremymcs/fix/757-worktree-merge-checkout
fix: skip redundant checkout in worktree merge when main already current
2026-03-16 20:02:06 -06:00
Ethan Hurst
6eed4413ef fix: always sync bundled resources and clean stale files (#761)
Remove the version-match early return in initResources() that skipped
resource sync when versions matched. This allowed the runtime at
~/.gsd/agent/extensions/ to drift from the bundled resources when
individual files were manually copied or leftover from a newer version.

Also adds rmSync of bundled subdirectories before each cpSync to remove
stale files that exist only in the runtime. User-created extension
directories are preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:49:44 +10:00
Ethan
04721cb20e Merge branch 'main' into fix/stop-auto-reason 2026-03-17 11:48:42 +10:00
Ethan Hurst
894089cc32 fix: add stop reason to every auto-mode stop (#760)
stopAuto() now accepts an optional `reason` parameter that is included
in the session summary — every stop is self-documenting instead of
showing a generic "Auto-mode stopped" message.

Also replaces the catch-all `!mid` check with registry-aware logic that
distinguishes "all complete" from "blocked" and "unexpected no active
milestone" (with diagnostic output). Adds midTitle recovery fallback
when title regex strips to empty string.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:38:54 +10:00
Jeremy McSpadden
00438b2bb4 fix: skip redundant checkout in worktree merge when main already current (#757)
When mergeMilestoneToMain runs from a worktree context, main is already
checked out at the project root. The unconditional git checkout main
fails with "already used by worktree" because git refuses to checkout a
branch that is active in another worktree.

Skip the checkout when the integration branch is already current at the
project root, which is always the case in worktree-mode merges.
2026-03-16 20:24:24 -05:00
Jeremy McSpadden
a5660e05cc Merge branch 'main' into fix/739-epipe-stale-research-state
Resolve conflicts between #699 (empty scaffold rejection) and #739
(task plan file verification) in auto-dispatch.ts imports and
auto-recovery.test.ts tests.

- auto-dispatch.ts: merged imports from both branches (resolveTaskFile
  from #739, resolveMilestonePath/buildMilestoneFileName from main)
- auto-recovery.test.ts: included all tests from both #699 (empty
  scaffold, actual tasks, completed tasks) and #739 (all task plans
  exist, missing task plan, no tasks). Updated #699 tests to create
  task plan files alongside slice plans to satisfy #739's verification.
  Updated #739 "no tasks" test to expect false per #699's requirement
  that plans must have task entries.
- auto-recovery.ts: auto-merged cleanly, both checks coexist

All 26 recovery tests pass. Full build clean.
2026-03-16 20:08:01 -05:00
TÂCHES
3cf6b35b8a Merge pull request #736 from gsd-build/feat/validate-milestone-code
feat(gsd): implement validate-milestone phase and dispatch
2026-03-16 18:57:45 -06:00
Lex Christopherson
d91690bb44 2.23.0 2026-03-16 18:57:13 -06:00
Lex Christopherson
50d6a52a2a docs: update changelog for v2.23.0 2026-03-16 18:57:02 -06:00
TÂCHES
5b3d9fff17 Merge pull request #713 from frizynn/feat/gsd-headless-command
feat: redesign gsd headless for full workflow orchestration
2026-03-16 18:49:05 -06:00
TÂCHES
83cc25fc90 Merge branch 'main' into fix/739-epipe-stale-research-state 2026-03-16 18:48:09 -06:00
Lex Christopherson
09d62e01d1 feat(gsd): implement validate-milestone phase and dispatch
Add a `validating-milestone` phase that runs BEFORE `completing-milestone`
to reconcile planned work against delivered work. The validator checks
success criteria, slice deliverables, cross-slice integration, and
requirement coverage before allowing milestone completion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:46:08 -06:00
TÂCHES
e0c1cc2f9d Merge branch 'main' into feat/gsd-headless-command 2026-03-16 18:44:18 -06:00
TÂCHES
889a2ee137 Merge pull request #755 from jeremymcs/feat/vscode-marketplace
feat(vscode): marketplace-ready files for VS Code extension publishing
2026-03-16 18:43:31 -06:00
TÂCHES
1e951f9648 Merge pull request #718 from jeremymcs/fix/682-vscode-extension-rebase
feat: VS Code extension — rebased with CI + review fixes (#682)
2026-03-16 18:42:30 -06:00
TÂCHES
4d78620ff1 Merge pull request #754 from jeremymcs/fix/forensics-version-loading
fix(forensics): use GSD_VERSION env var instead of package.json path traversal
2026-03-16 18:42:09 -06:00
TÂCHES
08a34abb08 Merge pull request #753 from jeremymcs/docs/update-all-recent-changes
docs: update documentation for all post-2.22.0 changes
2026-03-16 18:41:51 -06:00
TÂCHES
0f13a8d59c Merge pull request #752 from jeremymcs/feat/688-guided-discuss-milestone
feat(discuss): structured question rounds in guided-discuss-milestone (#688)
2026-03-16 18:41:37 -06:00
TÂCHES
f4f998efc5 Merge pull request #747 from trek-e/fix/733-bash-ampersand-hang
fix: add anti-pattern rule against bash with & to prevent agent hangs (#733)
2026-03-16 18:38:40 -06:00
TÂCHES
8ca9725bb0 Merge pull request #745 from jeremymcs/fix/737-dependency-range-expansion
fix(roadmap): expand range syntax in depends (S01-S04 → S01,S02,S03,S04)
2026-03-16 18:37:53 -06:00
TÂCHES
10f4ac0817 Merge pull request #743 from gtrak/feat/models-json-resolver-v2
feat: Add models.json resolution with fallback to ~/.pi/agent/models.json
2026-03-16 18:37:04 -06:00
TÂCHES
a129e15759 Merge pull request #738 from jeremymcs/fix/733-background-command-hang
fix: prevent indefinite hang when LLM uses bare & to background processes (#733)
2026-03-16 18:36:29 -06:00