Commit graph

424 commits

Author SHA1 Message Date
TÂCHES
fd29c02c81 feat(lsp): activate LSP by default, add call hierarchy/format/signature, sync edits (#639)
LSP was never activated in interactive sessions because the default
active tools list hardcoded only read/bash/edit/write. This adds lsp
to that list and ships four new capabilities alongside edit sync and
stronger prompt guidance.

- Add "lsp" to default active tools in agent-session.ts
- New actions: incoming_calls, outgoing_calls, format, signature
- Wire edit/write tools to notify LSP clients on file changes
- Strengthen system prompt and GSD prompt with full LSP operation catalog

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 09:22:52 -06:00
Gary Trakhman
1ea9163dea feat: add yaml support, run-hook command, and path sanitization (#637)
* feat: allow extensions to use 'yaml' and rework frontmatter parsing

* feat: add run-hook command for manual hook execution

* fix: sanitize slashes in unitType for runtime file paths
2026-03-16 09:22:23 -06:00
Tom Boucher
db9f006f19 fix(auto): preserve milestone branch on stop to prevent work loss (#601) (#632)
* fix(auto): preserve milestone branch on stop to prevent work loss (#601)

When auto-mode stops mid-milestone, the worktree teardown was
force-deleting the milestone branch (git branch -D). On the next
/gsd auto, a fresh branch was created from the integration branch,
losing all committed work from the prior session. This caused
auto-mode to re-trigger milestone planning instead of resuming
execution.

Three changes:

1. stopAuto: pass preserveBranch: true to teardownAutoWorktree so the
   milestone branch survives. Also auto-commit dirty state before
   leaving the worktree.

2. createAutoWorktree: when the milestone branch already exists,
   re-attach the worktree to it as-is instead of force-resetting it
   to the integration branch (which would also destroy prior work).

3. startAuto: detect surviving milestone branches when state appears
   to be pre-planning. Skip the early-return to discuss/plan flow
   and let the worktree setup + dispatch handle it from the branch's
   actual state.

The branch is still deleted during mergeMilestoneToMain (milestone
completion) after the work has been squash-merged, so no cleanup
change is needed there.

* fix: add null guard for state.activeMilestone to satisfy TypeScript
2026-03-16 09:11:26 -06:00
Colin Johnson
5fec6ea81e enhance: bring Slack remote questions to parity (#628)
* enhance: bring Slack remote questions to parity

* chore(M004): record integration branch

* fix: restore remote questions adapter import
2026-03-16 09:01:41 -06:00
Jeremy McSpadden
2fd4a1da60 refactor: replace serial prefs wizard with categorized menu (#623)
* refactor: replace serial prefs wizard with categorized menu

The /gsd prefs wizard previously dumped 20+ prompts in sequence, which
was overwhelming. This refactors it into a category picker loop where
users select from 7 categories (Models, Timeouts, Git, Skills, Budget,
Notifications, Advanced), configure only what they need, and return to
the menu with updated summaries showing current values at a glance.

- Extract 7 category functions from monolithic handlePrefsWizard
- Add buildCategorySummaries() for current-value display in menu
- Category loop with Save & Exit / Escape to serialize and write
- No logic changes to individual prompts — pure structural refactor

* fix: narrow ctx.ui.select return type for TypeScript strict mode

ctx.ui.select returns string | string[], so startsWith is not available
without narrowing. Extract to string with typeof guard before dispatching.
2026-03-16 09:01:27 -06:00
Tom Boucher
369bd8aeb9 fix: auto mode re-derives state after discussion fallthrough (#609) (#629)
When /gsd auto is called with no milestone, it delegates to the
discussion flow (showSmartEntry). Previously, if the LLM didn't follow
the discussion protocol — e.g. for simple tasks where it judged the
ceremony overkill and started editing directly — auto mode never
activated. The function returned after showSmartEntry with no retry
or notification, leaving the user in a loop.

Fix: After showSmartEntry returns in both the no-milestone and
pre-planning paths, re-derive state from disk. If the LLM produced
enough artifacts (CONTEXT.md, ROADMAP.md, or advanced the phase),
auto mode proceeds instead of returning. If not, a clear warning
tells the user what happened and what to do next.

This handles the case where the LLM writes files but doesn't follow
the exact discussion → CONTEXT.md → checkAutoStartAfterDiscuss flow.
2026-03-16 09:01:14 -06:00
Juan Francisco Lebrero
370897df81 feat: add /gsd help command with categorized reference for all subcommands (#630)
Adds /gsd help (aliases: h, ?) that displays a grouped reference of
every available subcommand with usage, flags, and shortcuts.

Commands are organized by category: Workflow, Visibility, Course
Correction, Project Knowledge, Configuration, and Maintenance.

Also simplifies the "Unknown command" error to point users to /gsd help
instead of listing all commands inline.
2026-03-16 08:41:08 -06:00
Flux Labs
5ade4bf3ed feat: add workflow visualizer TUI overlay with 4-tab interactive view (#626)
Add `/gsd visualize` command that opens a full-screen TUI overlay with
four tabs: Progress (milestone/slice/task tree), Dependencies (ASCII
dep graph), Metrics (cost/token bar charts), and Timeline (chronological
execution history). Supports Tab/1-4 switching, per-tab scrolling, and
auto-refresh every 2s. Opt-in auto-trigger hint after milestone
completion via `auto_visualize` preference.

New files:
- visualizer-data.ts: async data loader aggregating state + metrics
- visualizer-views.ts: 4 pure view renderers
- visualizer-overlay.ts: overlay class with tab/scroll/cache management
- tests/visualizer-views.test.ts: 21 assertions on view renderers
- tests/visualizer-data.test.ts: 33 source contract assertions

Modified:
- commands.ts: register "visualize" subcommand + handler
- auto.ts: milestone completion hint when auto_visualize enabled
- preferences.ts: add auto_visualize preference key
2026-03-16 08:19:08 -06:00
Juan Francisco Lebrero
88bdf9bc8d fix: use absolute paths for write-target variables in auto-mode prompts (#627)
In worktree contexts, the LLM received relative output paths like
`.gsd/milestones/M002/slices/S01/S01-RESEARCH.md` combined with a
working directory containing `.gsd/worktrees/M002`. The double .gsd
in the resulting path confused the LLM, which resolved the relative
path against the project root instead of the worktree — writing
artifacts to the wrong location and triggering loop detection.

All write-target path variables (outputPath, taskSummaryPath,
sliceSummaryPath, milestoneSummaryPath, replanPath, planPath,
uatResultPath, assessmentPath, secretsOutputPath) are now passed
as absolute paths via join(base, relPath), eliminating the need
for the LLM to do path arithmetic in confusing worktree layouts.
2026-03-16 08:18:53 -06:00
Tom Boucher
e0a309f5b5 feat(M004): mid-execution flexibility — capture, triage, and redirect (#512)
Solo developers can fire-and-forget thoughts during auto-mode execution
via /gsd capture. The system triages accumulated captures at natural seams
between tasks, classifies their impact into five types (quick-task, inject,
defer, replan, note), and proposes appropriate action with user confirmation
for plan-modifying resolutions.

Pipeline: capture → triage → confirm → resolve → resume
- /gsd capture appends to .gsd/CAPTURES.md (worktree-aware)
- Triage fires automatically between tasks in handleAgentEnd
- Five resolution types: inline quick task, inject task into plan,
  defer for reassess, trigger replan with context, acknowledge as note
- Dashboard overlay shows pending capture count badge
- Capture context injected into replan-slice and reassess-roadmap prompts
- Parse failure falls back to note — pipeline never blocks

New modules: captures.ts, triage-ui.ts, triage-resolution.ts
New prompt: triage-captures.md
52 tests across 3 test files, all passing
Requirements R045-R051 validated

Closes #505

chore: pre-merge cleanup — remove dead code, single-read dashboard optimization

- Remove processTriageResults() and associated types (dead code, superseded by
  inline resolution in auto.ts dispatch loop)
- Add countPendingCaptures() for single-read regex count on dashboard hot path
  (replaces two-phase hasPendingCaptures + loadPendingCaptures)
- Update triage-dispatch tests to match new implementation
2026-03-16 07:54:12 -06:00
Flux Labs
77309207ce feat: dynamic model routing for token consumption optimization (#579)
* feat: dynamic model routing for token consumption optimization (#575)

Add complexity-based model routing that classifies units into light/standard/heavy
tiers and routes to cheaper models when appropriate. Reduces token consumption
by 20-50% for users on capped plans.

- Complexity classifier with heuristic-based tier assignment (no LLM call)
- Model router with downgrade-only semantics (user's config is ceiling)
- Budget-pressure-aware routing (more aggressive as budget fills)
- Cross-provider cost comparison via bundled cost table
- Hook classification support
- Escalation on failure (light → standard → heavy)
- Full preference validation and merge support
- Metrics tracking with tier and downgrade fields
- 40 new tests (classifier, router, cost table)

Closes #575

* feat: phases 2-4 — dashboard, adaptive learning, task introspection

Phase 2 — Observability & Dashboard:
- Tier badge [L]/[S]/[H] displayed in progress widget next to phase label
- Dynamic routing savings summary shown in footer when units have been downgraded
- Tier and modelDowngraded fields passed through snapshotUnitMetrics

Phase 3 — Adaptive Learning:
- New routing-history.ts: tracks success/failure per tier per unit-type pattern
- Rolling window of 50 entries per pattern to prevent stale data
- User feedback support (over/under/ok) with 2x weight vs automatic
- Failure rate >20% auto-bumps tier for that pattern
- Tag-specific patterns (e.g. execute-task:docs) for granular learning
- History persists to .gsd/routing-history.json
- Classifier consults adaptive history before finalizing tier

Phase 4 — Task Plan Introspection:
- Code block counting in task plans (5+ blocks → heavy)
- Complexity keyword detection: migration, architecture, security,
  performance, concurrency, compatibility
- Multiple complexity keywords (2+) → heavy, single → standard
- New codeBlockCount and complexityKeywords fields in TaskMetadata

Tests: 16 new tests (routing history + introspection), 419 total passing
2026-03-16 07:53:53 -06:00
Adam Dry
7567d2db05 test: add feature-branch lifecycle integration test (#624)
* test: add feature-branch lifecycle integration test

Proves the core invariant: milestone worktrees branch from and merge
back to the feature branch, never touching main. Covers:
- Full lifecycle with unique milestone IDs (M001-xxxxxx format)
- Untracked .gsd/ planning files copied into worktree
- Multiple successive milestones on the same feature branch
- Main branch completely untouched throughout

* fix: commitCount return type (parseInt)
2026-03-16 07:52:43 -06:00
Flux Labs
c8f8795e73 fix: handle worktree lifecycle on mid-session milestone transitions (#616) (#618) 2026-03-16 07:38:29 -06:00
Juan Francisco Lebrero
9ffb927856 fix: eager template cache warming prevents version-skew crash in long auto-mode sessions (#621) 2026-03-16 07:38:00 -06:00
Tom Boucher
d065964c4a enhance: Discord integration parity with Slack + documentation (#620) 2026-03-16 07:37:28 -06:00
Flux Labs
6998ef2ae4 docs: comprehensive update to preferences reference and configuration guide (#614)
Update both docs/configuration.md (user-facing) and
src/resources/extensions/gsd/docs/preferences-reference.md (internal)
with complete coverage of all GSD preferences:

- Add /gsd prefs subcommands table (global, project, status, wizard, setup)
- Document token_profile (budget/balanced/quality) and phases settings
- Document context_pause_threshold field
- Document remote_questions configuration (Slack/Discord)
- Document git.merge_strategy (squash/merge) and git.isolation (worktree/branch)
- Expand post_unit_hooks with missing agent field
- Expand pre_dispatch_hooks with skip_if, unit_type, model fields
  and action validation rules
- Add known unit types list for hook before/after arrays
- Add examples for pre-dispatch hooks (modify/skip/replace)
- Add examples for token profile, phases, and remote questions
- Update models to show all 6 phases (research, planning, execution,
  execution_simple, completion, subagent)
- Add full example combining all major settings
2026-03-16 07:09:50 -06:00
Tom Boucher
2924a1d666 fix: showNextAction falls back to select() when custom() returns undefined (#447) (#615)
In RPC mode, ctx.ui.custom() returns undefined without emitting any event.
This caused showNextAction() — and all 13+ call sites in guided-flow.ts —
to silently complete without taking action. No error thrown, no event
emitted, command handler returns normally.

Fix: After custom() returns, check for undefined/null and fall back to
ctx.ui.select() which IS implemented in RPC mode. Maps the action list
to select labels and resolves the chosen action id.
2026-03-16 07:09:37 -06:00
Tom Boucher
15be720fbf fix: multiple open issue bugfixes (#592, #603, #606, #608, #602) (#612)
Four bugfixes for open issues:

1. Worktree created from integration branch, not main (#606)
   - createAutoWorktree reads integration branch from META.json
   - mergeMilestoneToMain merges to integration branch, not hardcoded main
   - createWorktree accepts optional startPoint parameter

2. Resolve project root from worktree paths in all commands (#608, #602)
   - Add resolveProjectRoot() to detect .gsd/worktrees/ in cwd
   - All GSD commands use projectRoot() instead of raw process.cwd()
   - Fixes stale cwd after milestone completion (#608)
   - Fixes discuss/status basepath disagreement (#602)

3. Milestone merge skipped in branch isolation mode (#603)
   - Add branch-mode fallback when isInAutoWorktree() is false
   - Detects milestone/* branch and performs squash-merge
   - Uses same mergeMilestoneToMain flow as worktree mode

4. Remote questions onboarding missing .js module (#592)
   - Extract saveRemoteQuestionsConfig into compiled src/ helper
   - Avoids cross-boundary import from compiled JS to raw .ts
2026-03-16 06:58:23 -06:00
Flux Labs
7e25e6d427 fix: prevent stale worktree cwd after milestone completion (#608) (#610)
After milestone completion and merge, the process cwd could remain
inside .gsd/worktrees/<MID>/, causing new milestone writes to land
in the wrong directory.

Three-layer fix:
1. escapeStaleWorktree() at startAuto entry — detects if base path
   is inside .gsd/worktrees/ and chdir back to project root
2. stopAuto() unconditionally restores cwd to originalBasePath,
   not just when isInAutoWorktree returns true (module state may
   have been cleared by mergeMilestoneToMain already)
3. Milestone merge error handler restores cwd on partial failure
   where mergeMilestoneToMain chdir'd but then threw

Closes #608
2026-03-16 06:58:02 -06:00
Flux Labs
b0f880689b fix: prevent heap OOM during long-running auto-mode sessions (#611) (#613)
Multiple sources of unbounded memory growth caused V8 to OOM after
~50 minutes of auto-mode operation:

1. activity-log.ts: saveActivityLog serialized ALL session entries
   into a single string for SHA1 dedup, allocating hundreds of MB
   per unit cycle. Now uses streaming writes (writeSync per entry)
   and a lightweight fingerprint (entry count + last 3 entries hash)
   instead of full-content hashing.

2. activity-log.ts: activityLogState Map was never cleared between
   sessions, accumulating lastSnapshotKeyByUnit entries indefinitely.
   Added clearActivityLogState() export, called from stopAuto().

3. auto.ts: completedUnits array grew unbounded for dashboard
   display. Now capped at 200 entries and cleared on stopAuto().

4. paths.ts: dirEntryCache and dirListCache Maps grew without bounds
   between clearPathCache() calls. Added DIR_CACHE_MAX (200) eviction
   — when cache exceeds limit, it's cleared before adding new entries.

Closes #611
2026-03-16 06:57:39 -06:00
Tom Boucher
27cfababdb fix: worktree created from integration branch, not main (#606) (#607) 2026-03-16 06:35:28 -06:00
Flux Labs
9ed812ed54 feat: dynamic model discovery & provider management UX (#581) 2026-03-16 06:23:18 -06:00
Copilot
570f6195be Keep /gsd auto artifact writes scoped to the active milestone worktree (#590) 2026-03-16 06:22:59 -06:00
Flux Labs
a9b14dc181 feat: add .gsd/KNOWLEDGE.md — persistent project-specific context (#585) 2026-03-16 06:15:18 -06:00
deseltrus
e5244658b3 fix(auto): tool-aware idle detection prevents false interruption of long-running tasks (#596) 2026-03-16 06:07:14 -06:00
deseltrus
ce553ec022 fix: parseContextDependsOn() destroys unique milestone ID case, breaking dependency resolution (#604) 2026-03-16 06:06:09 -06:00
deseltrus
0820b1196d feat: queue reorder — reorder milestone execution via /gsd queue (#460) 2026-03-16 06:05:45 -06:00
Flux Labs
d35ae683f1 Fix #453 native hangs in GSD auto-mode paths (#502)
* fix: avoid native hangs in gsd auto paths

* fix: use .js extension in edit-diff.test.ts import for tsc compatibility

* fix: prevent OOM on large file diffs and implement context-line windowing

- Add size guard (MAX_DP_CELLS=4M) to buildLineDiff that falls back to a
  linear-time prefix/suffix matching algorithm for large files, preventing
  the O(n*m) DP table from causing OOM crashes
- Implement contextLines parameter in generateDiffString so only lines
  within N lines of a change are rendered (with "..." separators), matching
  unified diff behavior — the parameter was previously accepted but ignored
- Add tests for both context windowing and large-file fallback

---------

Co-authored-by: TÂCHES <afromanguy@me.com>
2026-03-15 22:22:58 -06:00
Tom Boucher
67341caef1 feat: token optimization — profile presets, context compression, complexity routing, budget prediction (#582)
Reduces auto-mode token consumption by 40-60% through coordinated
optimizations driven by a single token_profile preference.

Profile presets (budget/balanced/quality):
- One preference key coordinates model selection, phase skipping,
  context compression, and subagent routing
- Balanced is the default for new projects (D046)
- Explicit user preferences always override profile defaults

Phase skipping:
- Guard clauses on research-milestone, research-slice, and
  reassess-roadmap dispatch rules
- Skipped phases return null (fall-through), preserving state machine
- Budget profile skips all research + reassess; balanced skips slice
  research only

Context compression:
- inlineLevel parameter (full/standard/minimal) on 6 prompt builders
- Minimal: only output template + essential context (≥30% reduction)
- Standard: skip redundant templates
- Full: current behavior unchanged

Complexity routing:
- classifyTaskComplexity() for task plans (step/file/signal heuristics)
- classifyUnitComplexity() for unit types with budget pressure
  thresholds at 50/75/90% (from #579)
- execution_simple model config for cheap simple-task routing
- escalateTier() for failure recovery (light→standard→heavy)

Adaptive learning (from #579):
- routing-history.ts tracks success/failure per tier per pattern
- Rolling 50-entry window, 20% failure threshold auto-bumps tier
- User feedback weighted 2x vs automatic detection
- Persists to .gsd/routing-history.json

Budget prediction:
- getAverageCostPerUnitType() + predictRemainingCost() in metrics
- projectedRemainingCost + profileDowngraded in AutoDashboardData
- One-way auto-downgrade within a milestone (D048)

Addresses #575

95 tests across 5 test files, all passing.
2026-03-15 22:20:38 -06:00
Flux Labs
4c283192bd fix: allow stopping auto-mode from a different terminal (#586)
* fix: allow stopping auto-mode from a different terminal (#584)

Auto-mode lock file was written to the worktree path instead of the
project root, making it invisible to other processes. Additionally,
/gsd stop only checked in-memory state which is process-local.

- Add lockBase() helper to always write auto.lock at project root
- Add stopAutoRemote() for cross-process stop via SIGTERM
- Update /gsd stop to fall back to lock-file-based remote stop

* fix: handle Windows SIGTERM behavior in stop-auto-remote test

On Windows, SIGTERM is not interceptable by Node.js processes — the
process exits with code 1 rather than running the SIGTERM handler.
Accept either exit code on Windows while still asserting clean exit (0)
on Unix platforms.
2026-03-15 22:19:04 -06:00
Flux Labs
5866bb0b27 fix: parse cache collision causing false loop detection on complete-slice (#583)
cacheKey() used length + first/last 100 chars, which collides when a
checkbox changes [ ] → [x] mid-file (same length, same endpoints).
verifyExpectedArtifact() only cleared the path cache, not the parse
cache, so parseRoadmap() returned stale data with done=false.

- Add clearParseCache() to verifyExpectedArtifact alongside clearPathCache
- Include middle 100-char sample in cacheKey to prevent interior collisions
- Add regression test for the cache collision scenario
2026-03-15 22:10:48 -06:00
Flux Labs
5a662c4655 feat: add git.commit_docs setting to keep .gsd/ local-only (#588)
* feat: add git.commit_docs setting to keep .gsd/ local-only (#501)

Adds a new `commit_docs` boolean to git preferences. When set to `false`:
- The entire `.gsd/` directory is added to `.gitignore`
- `smartStage()` excludes all `.gsd/` files from commits
- Bootstrap init skips the "chore: init gsd" commit
- `writeIntegrationBranch()` skips committing metadata
- The self-heal that removes blanket `.gsd/` patterns is bypassed

This allows users in corporate environments or mixed teams to use GSD
without polluting the shared git repository with planning artifacts.

Closes #501

* feat: add commit_docs toggle to preferences wizard

Adds "Track .gsd/ planning docs in git" to the /gsd prefs wizard,
allowing users to toggle commit_docs interactively alongside other
git settings like main_branch.
2026-03-15 22:09:29 -06:00
Lex Christopherson
c9c110fa8d fix: auto-mode continues after guided milestone planning
The guided flow's "Create roadmap" path never set pendingAutoStart,
so checkAutoStartAfterDiscuss() always returned false after planning
completed. Auto-mode stalled at "Milestone planned" instead of
proceeding to slice research/execution.

Three fixes:
- Set pendingAutoStart when choice === "plan" in showSmartEntry
- Relax Gate 1 to accept ROADMAP.md (plan path) or CONTEXT.md (discuss path)
- Add STATE.md write instruction to guided-plan-milestone prompt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 20:28:32 -06:00
Flux Labs
c8b42ed2ae feat: native perf optimizations — deriveState, JSONL, paths, parsing (#576)
Four native Rust optimizations to eliminate hot-path bottlenecks:

1. deriveState raw content (gsd_parser.rs, state.ts):
   - Added rawContent field to ParsedGsdFile in batch parser
   - Eliminates 43-line frontmatter re-serialization loop in state.ts
   - Batch cache now stores original file content directly

2. JSONL streaming parser (gsd_parser.rs, session-forensics.ts):
   - Added parseJsonlTail() — reads from file tail with constant memory
   - Handles arbitrary file sizes (no more 10MB OOM risk)
   - synthesizeCrashRecovery and readLastActivityLog use native first

3. Native directory tree index (gsd_parser.rs, paths.ts):
   - Added scanGsdTree() — walks .gsd/ tree once, returns all entries
   - paths.ts builds lookup map from native scan
   - cachedReaddirWithTypes/cachedReaddir check native cache first
   - Eliminates 20-50 readdirSync calls per dispatch

4. Native plan/summary parsers (gsd_parser.rs, files.ts):
   - Added parsePlanFile() — parses tasks, must-haves, estimates
   - Added parseSummaryFile() — parses frontmatter, sections, files
   - files.ts calls native first, falls back to JS regex parsers
   - 3-5x faster per file, ~20 files per deriveState

All optimizations follow the established pattern: native-first with
JS fallback when native module unavailable.
2026-03-15 20:16:42 -06:00
Flux Labs
343a43f028 feat: move git operations to Rust via git2 crate (#572)
* feat: move git operations to Rust via git2 crate (#524)

Eliminates ~70 execSync/execFileSync git CLI calls across 15 TypeScript
files by implementing native libgit2 operations in Rust and routing all
consumers through the native-git-bridge.

Rust (native/crates/engine/src/git.rs):
- Added 28 new NAPI functions covering both read and write operations
- Read: git_is_repo, git_has_staged_changes, git_diff_stat,
  git_diff_name_status, git_diff_numstat, git_diff_content,
  git_log_oneline, git_worktree_list, git_branch_list,
  git_branch_list_merged, git_ls_files, git_for_each_ref,
  git_conflict_files, git_batch_info
- Write: git_init, git_add_all, git_add_paths, git_reset_paths,
  git_commit, git_checkout_branch, git_checkout_theirs,
  git_merge_squash, git_merge_abort, git_rebase_abort,
  git_reset_hard, git_branch_delete, git_branch_force_reset,
  git_rm_cached, git_rm_force, git_worktree_add,
  git_worktree_remove, git_worktree_prune, git_revert_commit,
  git_revert_abort, git_update_ref

TypeScript (native-git-bridge.ts):
- Added 35 bridge functions with native-first + execSync fallback
- New types: GitDiffStat, GitNameStatus, GitNumstat, GitLogEntry,
  GitWorktreeEntry, GitBatchInfo, GitMergeResult

Consumer migrations (15 files):
- worktree-manager.ts: removed local runGit/getMainBranch, all ops native
- auto-worktree.ts: merge, checkout, conflict resolution all native
- git-service.ts: smart staging, commits, snapshots all native
- auto.ts, guided-flow.ts: repo init/bootstrap native
- auto-supervisor.ts: working tree detection native
- git-self-heal.ts: merge/rebase abort, reset all native
- doctor.ts: health checks, branch listing, worktree cleanup native
- commands.ts: branch/snapshot cleanup native
- session-forensics.ts: diff stat queries native
- auto-recovery.ts: merge state reconciliation native
- gitignore.ts, undo.ts, worktree-command.ts: remaining ops native

Kept as execSync (by design):
- git push (credential handling too complex for libgit2)
- native-git-bridge.ts fallbacks (graceful degradation)
- runPreMergeCheck (runs arbitrary user commands)

Closes #524

* fix: restore getMainBranch export from worktree-manager

The agent migration removed getMainBranch from worktree-manager.ts but
worktree-command.ts still imports it. Re-add as a thin wrapper around
nativeDetectMainBranch.

* fix: address PR #572 review feedback — security, correctness, error handling

CRITICAL:
- Path traversal protection via validate_path_within_repo() for
  git_rm_force and git_checkout_theirs
- git_branch_delete defaults to safe delete (force=false)

HIGH:
- Replace silent .ok() with proper error propagation in git_commit,
  git_merge_abort, git_rebase_abort, git_rm_force, git_checkout_theirs
- nativeDiffStat fallback parses numeric stats from git output
- nativeBatchInfo fallback counts staged/unstaged from porcelain status

MEDIUM:
- Wire up dead force param in removeWorktree()
- Read MERGE_MSG/SQUASH_MSG when commit message empty
- nativeLsFiles uses gitFileExec without fragile quote wrapping
- Fix operator precedence in git_ls_files
2026-03-15 20:02:10 -06:00
Flux Labs
a3c52b2a1b perf: optimize hot-path lookups, cache clearing, and error resilience (#560)
* fix(undo): use invalidateAllCaches to prevent stale state after undo

After deleting summary files and modifying PLAN files, only
invalidateStateCache() was called. Path and parse caches remained
stale, causing deriveState() to return incorrect results — showing
undone tasks as still complete.

* perf: optimize hot-path lookups, cache clearing, and error resilience

- Replace O(n) Array.includes() with Set-based O(1) lookups in
  persistCompletedKey, findCommitsForUnit, and extractCommitShas
- Skip unnecessary cache invalidation for hook units in
  verifyExpectedArtifact (moved clearPathCache after hook early-return)
- Avoid redundant disk writes in removePersistedKey when key not present
- Single-pass partition for conflicted files in reconcileMergeState
  instead of two separate filter passes
- Wrap undo git operations in try/finally to guarantee cache
  invalidation even on partial failure
- Surface auto-start errors to user via ui.notify instead of
  swallowing silently (was debug-only logging)
2026-03-15 19:47:30 -06:00
Jean-Dominique Stepek
71cf0eef3b fix: git commands fail when repo path contains spaces (#561)
* fix: use execFileSync for git commands to handle paths with spaces

execSync builds a shell command string via string interpolation, so any
path containing spaces (e.g. 'Current Projects/my-repo') gets word-split
by the shell into multiple arguments. This caused 'git worktree add' to
fail with a usage error whenever the repo was in a directory with spaces.

Switch all three git runner functions to execFileSync, which takes args
as an array and bypasses the shell entirely. Paths are passed as discrete
arguments and never subject to word-splitting or other shell expansions.

Affected files:
- worktree-manager.ts: runGit()
- git-service.ts: runGit()
- native-git-bridge.ts: gitExec()

* fix: restore pre-merge check command execution
2026-03-15 19:35:50 -06:00
TÂCHES
324d508eaf ci: add extension type-checking to CI pipeline (#568)
* ci: add extension type-checking to CI pipeline and prepublishOnly

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

* fix: resolve remaining extension type errors after merge

- Use cred.type === "api_key" for proper union narrowing in loadToolApiKeys
- Fix optional level parameter in provider-error-pause 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-15 19:26:45 -06:00
TÂCHES
7578292b6b fix: resolve TypeScript errors in GSD extension files (#571)
Add "success" to notify type union across ExtensionUIContext, interactive
mode, and RPC mode implementations. Fix null safety for readFileSync and
contextUsage.percent in auto.ts. Add discriminated union narrowing for
dispatch results. Add string type guards for select() return values in
commands.ts. Align ProviderErrorPauseUI notify signature. Simplify
AuthStorage return type.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:12:23 -06:00
Flux Labs
5eb4d94e10 feat: add /gsd steer command for hard-steering plan documents (#82) (#566)
Adds `/gsd steer <change>` command that registers user overrides in
`.gsd/OVERRIDES.md`. Active overrides are injected into all prompts.
A `rewrite-docs` dispatch unit propagates overrides across plan docs.

Addresses all review concerns from PR #409:
- resolveAllOverrides wired into handleAgentEnd
- Circuit breaker (max 3 attempts, then force-resolve)
- verifyExpectedArtifact validates OVERRIDES.md state
- Milestone-only unitId when no active slice
- Test temp dirs cleaned up
2026-03-15 19:10:59 -06:00
TÂCHES
26890f3b09 fix: resolve TypeScript errors in GSD test files (#570)
- Remove extraneous argument in auto-worktree report() call
- Replace vitest imports with node:test in integration-mixed-milestones and unique-milestone-ids
- Cast deprecated merge_to_main references as any in preferences-git tests
- Type pre-dispatch hook arrays as PreDispatchHookConfig[] in preferences-hooks tests

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:10:36 -06:00
TÂCHES
96cd2732bf fix: resolve TypeScript errors in async-jobs extension (#569)
Add missing parameters (signal, onUpdate, ctx) to tool execute signatures
and details property to return objects to satisfy AgentToolResult<T> type.
Fix string-to-boolean type mismatch on display property in sendMessage calls.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:07:57 -06:00
geromet
dfd2a1b5b4 fix: load tool API keys from auth.json at session startup (#563)
Export TOOL_KEYS constant and add loadToolApiKeys() function to load
API keys from ~/.gsd/agent/auth.json into environment variables.

Called in session_start handler so tool-based extensions (Context7,
Brave Search, Jina, Tavily, Groq) work immediately without requiring
/gsd config.
2026-03-15 18:58:00 -06:00
TÂCHES
96df01063f fix: auto-mode worktree path and resource sync bugs (#557)
* fix(auto): add missing import for resolveSkillDiscoveryMode

Used at line 687 but not imported, causing "resolveSkillDiscoveryMode is
not defined" crash on auto-mode startup.

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

* fix(auto): add workingDirectory to all auto-mode prompt templates

Six prompt templates (reassess-roadmap, complete-milestone, replan-slice,
run-uat, research-milestone, plan-milestone) were missing the working
directory directive. Without it, the LLM infers the main repo path from
system context and cd's there instead of staying in the worktree. This
causes artifacts to be written to the wrong location, preventing the
dispatch loop from detecting completion and triggering infinite
re-dispatches of the same unit.

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

* fix(auto): detect mid-session resource updates and stop gracefully

Templates are read from disk on each dispatch but extension code is
loaded once at startup. If resources are re-synced mid-session (via
/gsd:update, npm update, or dev copy-resources), templates may expect
variables the in-memory code doesn't provide, causing a crash.

Add a syncedAt timestamp to managed-resources.json. Auto-mode captures
this at startup and checks before each dispatch. If resources changed,
it stops with a clear message instead of crashing.

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

* test: add workingDirectory to prompt template test fixtures

Tests that load prompt templates via loadPromptFromWorktree now pass the
workingDirectory variable, matching the updated templates that include
the {{workingDirectory}} directive.

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-15 18:26:55 -06:00
Jamie Nelson
d88db53715 docs: sync GSD workflow resource (#476)
* docs: sync GSD workflow resource

* docs: resolve workflow naming review comments

---------

Co-authored-by: TÂCHES <afromanguy@me.com>
2026-03-15 18:23:52 -06:00
Flux Labs
6f6ef16ee9 fix(undo): use invalidateAllCaches to prevent stale state after undo (#556)
After deleting summary files and modifying PLAN files, only
invalidateStateCache() was called. Path and parse caches remained
stale, causing deriveState() to return incorrect results — showing
undone tasks as still complete.
2026-03-15 18:19:09 -06:00
Flux Labs
ecef348a95 fix(auto): harden recovery — checkbox verification, atomic writes, roadmap checks (#547)
Four fixes to auto-recovery logic that caused silent failures or
inconsistent state:

1. skipExecuteTask: return false when checkbox regex doesn't match the
   plan format, so callers fall through to other recovery strategies
   instead of assuming success (lines 252-255)

2. verifyExpectedArtifact: fail verification on corrupt/unparseable
   roadmap instead of silently passing. Prevents advancing past an
   incomplete complete-slice when the roadmap file is malformed (line 152)

3. removePersistedKey: use atomic tmp+rename write (matching
   persistCompletedKey) to prevent completed-units.json corruption
   on crash mid-write (line 293)

4. selfHealRuntimeRecords: use verifyExpectedArtifact instead of bare
   existsSync for execute-task healing, so tasks with summary but
   unchecked plan checkbox aren't incorrectly marked complete (line 374)

Co-authored-by: TÂCHES <afromanguy@me.com>
2026-03-15 18:15:44 -06:00
Flux Labs
3101469b4d fix(auto): refresh progress widget from disk every 5s during unit execution (#549) (#552)
The progress bar in the auto-mode widget was snapshot-based — only
updated at dispatch time via updateSliceProgressCache(). During
long-running units (especially after the worktree architecture in
PR #506), the bar appeared frozen even as tasks completed on disk.

Add a 5-second interval inside the widget that re-reads the roadmap
and plan files from disk, so slice/task progress reflects reality
without waiting for the next unit dispatch.

Closes #549
2026-03-15 18:12:48 -06:00
Lex Christopherson
f70ddea074 test: add unit tests for auto-dashboard, auto-recovery, crash-recovery (#526)
46 new tests covering 3 previously untested modules:

- auto-dashboard.test.ts (18 tests): unitVerb, unitPhaseLabel,
  describeNextUnit phase mapping, formatAutoElapsed, formatWidgetTokens
- crash-recovery.test.ts (10 tests): writeLock/readCrashLock round-trip,
  clearLock, isLockProcessAlive (own PID, dead PID, invalid PIDs),
  formatCrashInfo
- auto-recovery.test.ts (18 tests): resolveExpectedArtifactPath for all
  unit types, diagnoseExpectedArtifact, buildLoopRemediationSteps,
  completed-unit key persistence (persist, load, remove, idempotency)

Total test count: 123 → 169

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 17:33:48 -06:00
TÂCHES
ee355b52d1 Merge pull request #482 from fluxlabs/fix/tui-resource-leaks-and-quality
fix: TUI resource leaks, code quality, and regression tests
2026-03-15 17:32:31 -06:00