The roadmap parser regex used (\w+) to capture slice/task IDs, which
only matches [a-zA-Z0-9_]. Fractional IDs like S03.5 (created by
/gsd steer) contain a dot, causing the parser to skip the entire line.
The dispatcher then jumps from S03 to S04, finds S04 blocked by
the unparsed S03.5, and gives up with 'earlier slice is not complete'.
Update the ID capture group to ([\w.]+) in both:
- roadmap-slices.ts (primary roadmap parser)
- files.ts (plan task parser, for consistency)
This allows dots in slice/task IDs while preserving all existing
behavior for standard IDs like S01, S02, T01, etc.
Closes#681
Fix type compatibility issues introduced in the JS→TS conversion:
- Restore PageEntry.page to `any` (holds Playwright Page instance)
- Use Record<string, any> for session parameters in
buildFailureHypothesis and summarizeBrowserSession (callers pass
rich objects with extra properties)
- Use Record<string, unknown> for formatTimelineEntries options
- Add explicit type annotations to local variables and callbacks
to satisfy noImplicitAny in tsconfig.extensions.json
Capture the session file path on pause and synthesize a recovery briefing
on resume, so the next agent knows what already happened instead of
restarting the unit from scratch.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move @types/mime-types from dependencies to devDependencies in pi-tui
(type declarations are only needed at compile time)
- Align chalk version: upgrade root from ^5.5.0 to ^5.6.2 to match
pi-ai and avoid version skew
- Extract duplicated help text from loader.ts and cli.ts into shared
help-text.ts module (single source of truth)
- Convert validate-pack.sh to Node.js for Windows compatibility
- Fix dev.js using unnecessary npx for tsc (it's a devDependency,
use node_modules/.bin/tsc directly)
When auto-mode loop recovery marks tasks as [x] in the plan file and
auto is restarted, the done count can equal total. The display always
showed done+1 (assuming "currently working on next task"), causing
values like "task 5/4". Clamp to total so it never exceeds the max.
Closes#662
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Convert browser-tools/core.js (1058 lines) to native TypeScript with
full type annotations from the existing .d.ts file. Remove the
separate .d.ts declaration file (types are now inline).
- Add c8 test coverage reporting: `npm run test:coverage` generates
text + lcov reports with 50% statement threshold baseline.
- Add coverage/ to .gitignore
All 712 unit tests, 63 browser-tools tests, and 11 integration tests
pass with zero regressions.
1. Windows: `start` command opens CMD instead of browser during GitHub
Copilot login — pass empty title arg so URL is treated as target
2. Launch banner missing Tavily provider in web search status display
3. MCPorter auto-installs via npm when not found (like ripgrep auto-download)
4. Notification prefs showing [object Object] — guard against non-boolean values
Closes#663
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agent now cancels in-flight async_bash jobs after editing source files
before re-running them, preventing stale results from polluting context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix loadStoredEnvKeys divergent provider lists: add telegram_bot and
custom-openai to wizard.ts (the canonical copy used by CLI), remove
dead duplicate from onboarding.ts
- Security: add SAFE_COMMAND_PREFIXES allowlist to resolveConfigValue
to prevent arbitrary RCE via settings.json shell commands
- Security: add TOFU (Trust On First Use) model for project-local
extensions — skip untrusted .pi/extensions/ with stderr warning
- Performance: debounce sql.js MemoryStorage persistence (500ms window)
so rapid mutations coalesce into a single db.export()+writeFileSync
- Fix double lstatSync call in tool-bootstrap.ts isRegularFile
- Add 26 new tests covering all changes
findMilestoneIds() had a bare catch that returned [] on any error,
causing showSmartEntry() to think no milestones exist and restart
the new-project discuss flow in a loop. Add error logging when the
directory exists but scanning fails, and a sanity check that warns
the user instead of looping when the directory has entries that
weren't recognized.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- google-search test: mock getApiKeyForProvider to return JSON string
matching real OAuth provider behavior (token+projectId), instead of
using AuthStorage.inMemory which bypasses the OAuth getApiKey transform
- smoke test: split on /[/\\]/ for Windows path separator compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Windows, raw paths like D:\... are interpreted as protocol "d:" by
the ESM loader. Convert via pathToFileURL before dynamic import.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kept both health gate (main) and debug timer (PR) in auto.ts.
Added agentInstructionsBlock to fullSystem composition in index.ts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Combine budget fields (contextWindowTokens, truncationSections,
continueHereFired) from PR #594 with prompt char tracking fields
(promptCharCount, baselineCharCount) from main.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Telegram Bot API as a third remote questions channel alongside
Discord and Slack. Implements the ChannelAdapter interface with inline
keyboard buttons, callback query handling, text reply polling, and
supergroup message URL generation.
Closes#645
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extension-based providers like pi-claude-cli may not require credentials
in auth.json, causing shouldRunOnboarding() to always return true and
repeat the wizard every launch. Now checks if a defaultProvider is
already set in settings before triggering the wizard.
Merge main into feat/context-window-budget, combining:
- Budget fields (contextWindowTokens, truncationSections, continueHereFired)
from the PR with routing fields (tier, modelDowngraded) from main in
UnitMetrics interface
- Unified opts parameter pattern in snapshotUnitMetrics
- KNOWLEDGE.md step from main with template path references from the PR
in execute-task.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add workflow mode system (solo/team) with /gsd mode command
Introduces a `mode` preference that bundles sensible defaults for solo
developers vs team workflows, replacing the need to manually configure
5-8 individual git preferences.
* fix: resolve TS2339 — use string narrowing for ctx.ui.select return type
Two fixes for the model configuration bleeding between simultaneous
GSD instances that share the same global settings.json.
## Root Cause
1. `setDefaultModelAndProvider()` always persisted to `~/.gsd/agent/settings.json`
(global), so when either instance's interactive mode changed models (via
Ctrl+P or /model), it overwrote the other instance's saved default.
2. When auto-mode dispatched a new unit (after context wipe), if no
per-unit-type model preference was configured, the session picked up
the default from the now-contaminated global settings file.
## Fix 1: Project-scoped model persistence (settings-manager.ts)
`setDefaultModelAndProvider()`, `setDefaultModel()`, and `setDefaultProvider()`
now persist to project-level settings (`.pi/settings.json`) when a project
settings file exists, falling back to global only when no project context
is available. This prevents concurrent instances from overwriting each
other's model choice.
Added `hasProjectSettingsFile()` helper to detect project context.
## Fix 2: Auto-mode model capture (auto.ts)
Captures the session's model at auto-mode start (`autoModeStartModel`).
At each unit dispatch, if no model preference is configured for the unit
type, the captured model is re-applied with `persist: false`. This
ensures each auto-mode session maintains its own model regardless of
what other instances write to the shared settings file.
## Tests
3 new tests covering:
- Project settings file isolates model from global
- Two projects have independent model configs
- autoModeStartModel concept prevents model drift
All 448 existing tests pass.
Fixes#650
* fix: bg_shell ready_port timeout and error handling (#428)
When a server fails to bind to the configured ready_port, the process
would stay in "starting" status indefinitely after the probing interval
cleared, with no error surfaced to the agent. This fixes the hang by:
- Transitioning process to "error" status when port probing times out
- Detecting process exit during port polling and reporting stderr context
- Adding ready_timeout parameter for custom timeout values
- Including stderr output in waitForReady timeout/error responses
- Registering SIGTERM/SIGINT handlers to clean up bg processes on exit
Closes#428
* feat: add /gsd quick command and agent-instructions.md injection (#425)
Implements two features from issue #425:
1. `/gsd quick <task>` — lightweight task execution with GSD guarantees
(atomic commits, state tracking) without the full milestone ceremony.
Creates `.gsd/quick/<num>-<slug>/` directory, a git branch, and
dispatches a focused prompt for in-session execution.
2. Agent instructions file — loads `~/.gsd/agent-instructions.md` (global)
and `.gsd/agent-instructions.md` (project), injects into every GSD
agent session via the before_agent_start hook. Lets users add durable
instructions like notification preferences or environment constraints.
Closes#425
---------
Co-authored-by: TÂCHES <afromanguy@me.com>
* feat(doctor): add 7 runtime health checks with auto-fix
Add comprehensive runtime health monitoring to /gsd doctor:
- stale_crash_lock: detect dead auto.lock from crashed sessions, auto-clear
- orphaned_completed_units: find completed-unit keys referencing missing artifacts, auto-remove
- stale_hook_state: detect residual hook cycle counts with no running session, auto-clear
- activity_log_bloat: flag activity/ dir exceeding 500 files or 100MB, auto-prune (7-day retention)
- state_file_missing: detect missing STATE.md when milestones exist, auto-generate
- state_file_stale: detect STATE.md drift (wrong phase/milestone/slice), auto-rebuild
- gitignore_missing_patterns: detect missing critical GSD runtime patterns in .gitignore, auto-fix
All checks are non-fatal (gracefully degrade on read errors) and respect
the existing fix/fixLevel system. Includes 34 new test assertions across
9 test scenarios in doctor-runtime.test.ts.
* feat(doctor): add proactive healing layer for auto-mode
Three new mechanisms for automatic health monitoring:
1. Pre-dispatch health gate: runs before each unit dispatch in auto-mode.
Checks for stale crash locks (auto-clears) and corrupt merge state
(auto-heals via abortAndReset). Pauses auto-mode if critical issues
can't be resolved.
2. Health score tracking: records error/warning/fix counts after each
post-unit doctor run. Tracks trends (improving/stable/degrading)
across a sliding window of 50 snapshots. Monitors consecutive
error unit streaks.
3. Auto-heal escalation: when deterministic fixes can't resolve errors
after 5 consecutive units AND health trend is not improving,
automatically dispatches LLM-assisted heal (dispatchDoctorHeal).
Single-fire per session to prevent spam. Defers escalation when
trend is improving (fixes are working, just slowly).
Integration points in auto.ts:
- resetProactiveHealing() on start/stop
- preDispatchHealthGate() before deriveState in dispatchNextUnit
- recordHealthSnapshot() + checkHealEscalation() in post-unit hook
- formatHealthSummary() available for dashboard display
Includes 30 test assertions across 15 scenarios.
Development planning artifacts (.gsd/) are project-specific state that
lives in worktree branches during active development. Tracking them on
main causes merge conflicts with worktree-isolated auto-mode and leaves
stale snapshots that mislead.
- Remove 157 .gsd/ files from git tracking (kept on disk)
- Replace granular .gsd/ gitignore rules with single .gsd/ entry
- Files remain available locally for reference
Closes#647
* feat: add worktree post-create hook for environment setup (#597)
Add git.worktree_post_create preference — a script path that GSD
runs after creating any worktree (both auto-mode and manual /worktree).
The script receives SOURCE_DIR and WORKTREE_DIR as environment
variables, enabling users to copy .env files, symlink asset
directories, or run other setup commands that git worktrees don't
inherit from the main tree.
Implementation:
- Add worktree_post_create field to GitPreferences interface
- Add validation in validatePreferences (must be non-empty string)
- Add runWorktreePostCreateHook() in auto-worktree.ts — resolves
relative paths against project root, runs with 30s timeout,
failure is non-fatal (warning only)
- Integrate hook call in createAutoWorktree() (auto-mode path)
- Integrate hook call in worktree-command.ts (manual /worktree path)
- Update docs/configuration.md with full usage guide and example
hook script
- Update preferences-reference.md with field documentation
Example configuration:
git:
worktree_post_create: .gsd/hooks/post-worktree-create
Example hook script:
#!/bin/bash
cp "$SOURCE_DIR/.env" "$WORKTREE_DIR/.env"
ln -sf "$SOURCE_DIR/assets" "$WORKTREE_DIR/assets"
Closes#597
* fix: use Node.js scripts in hook tests for Windows compatibility
Replace bash hook scripts with cross-platform Node.js scripts in
worktree-post-create-hook.test.ts. On macOS/Linux, scripts use
#!/usr/bin/env node shebang. On Windows, generates batch files
that invoke node -e. Fixes windows-portability CI failures.
* fix: Windows CI failures in worktree post-create hook tests
- Use path.isAbsolute() instead of startsWith("/") to detect absolute
paths on Windows (fixes double-path bug like C:\...\C:\...)
- Add .bat extension to hook scripts on Windows so they are recognized
as executable by cmd.exe
- Extract isWin constant and hookPath() helper for consistent
platform-aware test setup
Fixes 3 failing tests in windows-portability CI job:
- executes hook script with correct env vars
- supports absolute hook paths
- hook can copy files from source to worktree
* fix: adopt main's help command and error message in commands.ts
The auto-merge missed main's addition of the help handler, showHelp
function, and updated description/subcommands array. Added them
manually and updated the visualizer help text to reflect 7-tab TUI.
* fix: write Windows hook scripts as .bat + companion .js file
The previous approach embedded multi-line JavaScript in a node -e "..."
argument inside the .bat file. cmd.exe splits on newlines, so each JS
line was interpreted as a separate batch command ('const' is not
recognized...).
Now writes the JS code to a companion .js file and the .bat invokes
it with `node "%~dp0<file>.js"`, which works reliably on Windows.
---------
Co-authored-by: TÂCHES <afromanguy@me.com>
* docs(M004): context, requirements, and roadmap
* chore(M004): record integration branch
* chore(M004/S01): auto-commit after research-slice
* docs(S01): add slice plan
* chore(M004/S01/T01): auto-commit after execute-task
* chore(M004/S01/T02): auto-commit after execute-task
* chore(M004/S01): auto-commit after complete-slice
* chore(M004/S01): auto-commit after reassess-roadmap
* chore(M004/S02): auto-commit after research-slice
* docs(S02): add slice plan
* chore(M004/S02/T01): auto-commit after execute-task
* chore(M004/S02/T02): auto-commit after execute-task
* chore(M004/S02): auto-commit after complete-slice
* docs(M004): reassess roadmap after S02
* chore(M004/S03): auto-commit after research-slice
* docs(S03): add slice plan
* chore(M004/S03/T01): auto-commit after execute-task
* chore(M004/S03/T02): auto-commit after execute-task
* chore(M004/S03/T03): auto-commit after execute-task
* chore(M004/S03): auto-commit after complete-slice
* chore(M004): record integration branch
* chore(M004/S04): auto-commit after research-slice
* docs(S04): add slice plan
* chore: update state to executing S04
* chore(M004/S04/T01): auto-commit after execute-task
* chore(M004/S04/T02): auto-commit after execute-task
* chore(M004/S04): auto-commit after complete-slice
* docs(M004): reassess roadmap after S04
* chore(M004/S05): auto-commit after research-slice
* docs(S05): add slice plan
* chore(M004/S05/T01): auto-commit after execute-task
* chore(M004/S05/T02): auto-commit after execute-task
* chore(M004/S05): auto-commit after complete-slice
* chore(M004/S05): auto-commit after reassess-roadmap
* chore(M004/S06): auto-commit after research-slice
* docs(S06): add slice plan
* chore: update STATE.md for S06 execution
* chore(M004/S06/T01): auto-commit after execute-task
* chore(M004/S06/T02): auto-commit after execute-task
* chore(M004/S06): auto-commit after complete-slice
* chore(M004/S06): auto-commit after reassess-roadmap
* chore(M004/S07): auto-commit after research-slice
* docs(S07): add slice plan
* chore(M004/S07/T01): auto-commit after execute-task
* chore(M004/S07): auto-commit after complete-slice
* chore(M004): auto-commit after complete-milestone
* docs(M004): milestone summary and state update
* fix: path traversal guard, ATTACH allowlist, restore deleted export-html
- db-writer.ts: validate saveArtifactToDb path stays within .gsd/ using
resolve() to prevent directory traversal via LLM tool input
- gsd-db.ts: replace single-quote-only ATTACH guard with strict character
allowlist regex for worktree DB path validation
- Restore accidentally deleted pkg/dist/core/export-html/ templates
(removed in b30baeb7 during S04/T01 auto-execution)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: remove .gsd/ from tracking — private project work docs
.gsd/ contains personal planning artifacts, not public source code.
Replace granular runtime gitignore rules with blanket .gsd/ ignore.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve 4 strict typecheck errors for tsconfig.extensions.json
- gsd-db.ts: cast origEmit.apply return to boolean
- md-importer.ts: double-cast Requirement to Record<string, unknown>
- gsd-inspect.test.ts: remove extraneous arg from report()
- md-importer.test.ts: nullish coalesce on optional chain to boolean
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update compression test to accept DB-aware helper pattern
The context-compression test checks auto-prompts.ts source for
inlineGsdRootFile calls, but M004 replaces these with DB-aware
helpers (inlineRequirementsFromDb etc). Accept either pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use single-quote blocklist instead of path allowlist for ATTACH guard
Allowlist regex broke on Windows temp paths containing tildes (RUNNER~1),
parens, and other valid OS path chars. The only actual injection vector
for ATTACH DATABASE '...' is a single quote breaking the SQL literal.
Block that one char instead of trying to enumerate all valid path chars.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* revert: restore .gsd/ tracking and original gitignore rules
The blanket .gsd/ ignore was incorrect — GSD users need planning
files tracked. Restore main's granular runtime-only gitignore and
re-add all .gsd/ planning files from main.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: use double quotes in git commit message for Windows compatibility
Single quotes in shell commands don't work on Windows PowerShell.
The commit message 'add gsd dir' was split into separate pathspecs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add workflow visualizer TUI overlay with 4-tab interactive view
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
* feat: expand workflow visualizer with 8 new features across 7 tabs
Add critical path analysis, risk heatmap, cost projections, Gantt
timeline, live agent activity, diff/changelog, search/filter, and
export capabilities to the workflow visualizer overlay.
- Critical path: O(V+E) topological sort + longest path algorithm
with slack computation for milestones and slices
- Risk heatmap: colored block grid with legend and summary counts
- Cost projections: avg cost/slice, burn rate, sparkline, budget warnings
- Gantt timeline: horizontal bars with phase coloring and time axis
(falls back to list view on narrow terminals)
- Agent activity: real-time status, progress bar, completion rate
- Changelog: parsed SUMMARY files with mtime-based caching
- Search/filter: / enters filter mode, f cycles field, supports
keyword/status/risk filtering
- Export: standalone writeExportFile() + m/j/s keys for
markdown/JSON/snapshot export from overlay
Tab bar expanded from 4 to 7 tabs. 146 new test assertions across
4 test files. All 604 tests pass with zero regressions.
* fix: update help text to reflect 7-tab visualizer