The idle watchdog checked lastProgressAt to detect stalled agents, but
nothing updated that timestamp during normal execution. Any task taking
>10min triggered false idle recovery, steering messages, and eventually
got skipped — even while actively writing code.
Add detectWorkingTreeActivity() check before recovery: if git reports
uncommitted changes, the agent is working. Bump lastProgressAt and
skip recovery. Genuinely idle agents (clean working tree) still get
recovered as before.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Merge improvements:
- Auto-detect current worktree: /worktree merge (bare) and /worktree merge main
work from inside a worktree without specifying the worktree name
- Full repo diffs: preview and LLM prompt show all changed files, not just .gsd/
- Accurate preview: direct diff (main vs branch) shows actual merge impact
- Per-file line stats: +N/-N shown for each file in merge preview
- CWD fix: chdir to main tree before dispatching merge to prevent broken CWD
after worktree cleanup
- Prompt includes explicit paths so the LLM knows where to read/write
Create/switch:
- /worktree create <name> works as alias for create-or-switch behavior
- Guard against creating a worktree when the branch is already in use
Remove:
- /worktree remove <name> validates the name exists before attempting removal
- /worktree remove <name> confirms before deleting
- /worktree remove all removes every worktree after confirmation prompt
Reload resilience:
- Detects if CWD is inside a worktree on extension init and restores
originalCwd tracking, surviving /reload without losing worktree state
Command descriptions:
- /worktree shows '(also /wt)' in description
- /wt shows 'Alias for /worktree'
The Anthropic API rejects images exceeding 2000px in multi-image requests.
With deviceScaleFactor=2, viewport screenshots were 2560x1600px, triggering
400 errors that halted execution. Add scale:"css" to all API-facing screenshot
calls and a constrainScreenshot() fallback that downscales oversized images
(e.g. fullPage on tall pages) via the browser's canvas — zero new dependencies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update buildResourceLoader to include ~/.pi/agent/extensions/ in
additionalExtensionPaths, allowing GSD to discover and use extensions
installed in pi's default location.
This resolves extension loading issues when users have extensions
installed in ~/.pi/agent/extensions/ instead of ~/.gsd/agent/extensions/.
- resource-loader.ts: add piExtensionsDir to additionalExtensionPaths
- app-smoke.test.ts: add test verifying the source includes .pi path
Child processes (Git Bash/MSYS2) strip the ENABLE_VIRTUAL_TERMINAL_INPUT
flag from the shared stdin console handle, corrupting terminal input.
Re-enable the flag after every child process exits in bash.js, bg-shell,
and cache FFI handles in pi-tui for cheap repeated calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cli.ts unconditionally entered InteractiveMode, ignoring --mode, -p,
--no-session and other flags the subagent extension passes to child
processes. The child would wait for TTY input that never arrives
(stdin is "ignore"), causing the parent to hang forever on "working".
Parse CLI args to detect print/subagent mode and route to runPrintMode()
with proper session, model, extension, and system prompt handling.
Closes#45
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sessions are stored in a single flat ~/.gsd/sessions/ directory, so
/resume shows sessions from all projects regardless of which folder
you're in.
Use per-cwd subdirectories under ~/.gsd/sessions/ with the same
path encoding the upstream SDK uses (--path-segments--), so /resume
only lists sessions from the current working directory.
- bg_shell killProcess: add Windows-specific taskkill /F /T /PID path
with proper error handling (spawnSync with timeout, not stdio: "ignore")
- bg_shell startProcess: use getShellConfig() instead of hardcoded "bash",
disable detached mode on Windows (process groups don't apply)
- GSD bash tool: wrap execute to inject 120s default timeout when the LLM
omits the timeout parameter, preventing indefinite hangs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- wizard.ts: also check for \b (0x08) which Windows terminals send for backspace
- browser-tools: read BROWSER_PATH env var and pass as executablePath to Playwright
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Non-execute-task and execute-task idle recovery now:
- Checks if the artifact already exists before steering (early advance)
- Escalates steering on final attempt ("last chance before skip")
- Writes blocker placeholder artifacts and advances the pipeline when
retries are exhausted, instead of pausing auto-mode silently
Closes#17
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Milestones completed before the roadmap convention (e.g. M001-M003)
have SUMMARY files but no ROADMAP. Previously these were treated as
incomplete, causing the first one to become the active milestone with
a fallback title like 'M001: M001'.
Now getActiveMilestoneId(), the completeMilestoneIds pre-computation,
and the deriveState() registry loop all check for a SUMMARY file when
no roadmap exists and mark the milestone as complete, extracting the
title from the summary H1.
Uses getAll() instead of getAvailable() so stale models like grok-2
are caught even when the user has no auth for the correct provider yet.
Resets thinking to off when the configured model was invalid.
- Remove gsd-pi from its own dependencies (circular dep caused ENOTEMPTY install failures)
- Auto-select anthropic/claude-sonnet-4-6 as default model for new installs
- Reset to valid model if configured model no longer exists in registry
- Default thinking level to off
When Tab opens the notes field, committed/checked options now stay
visually prominent (text color + muted description) while unselected
options dim. Previously Tab greyed everything out equally.
- optionUnselected: respect isCommitted when isFocusDimmed
- checkboxUnselected: respect isChecked for description color when isFocusDimmed
All prompt files under src/resources/extensions/gsd/prompts/ hardcoded
~/.pi/agent/extensions/gsd/templates/ but GSD overrides the agent
directory to ~/.gsd/agent/ in loader.ts. This caused all template reads
to fail silently — the agent never loaded formatting guidance.
Replaced all 26 occurrences across 16 files.
- All outward-facing GitHub tool actions now require user confirmation
via a themed yes/no dialog before executing (create, update, close,
reopen issues; create/update PRs; add comments; submit reviews;
request reviewers; create labels/milestones)
- New shared confirm-ui.ts component using the shared UI design system
- Read-only actions (list, view, search, diff, files, checks) ungated
- License changed from BUSL-1.1 to MIT
When no milestone exists, both /gsd and /gsd auto reach showSmartEntry
and call dispatchWorkflow — overwriting pendingAutoStart and restarting
the conversation mid-interview every time the user re-ran the command.
Add a pendingAutoStart check at the top of the !activeMilestone branch.
If a discuss session is already in progress, notify the user instead of
re-dispatching.
Fixes#6
When users logged in via /login but never explicitly ran /model, the agent
would throw 'No model configured' on every action. Now GSD auto-selects
a default model from available authenticated providers on startup.
Preference order: claude-sonnet-4-20250514 > any Anthropic model > first available.
Also documented /model command in README Getting Started section.
Closes#4
- Consolidate execution guidance: merge AGENTS.md hard rules, heuristics,
playbooks, and communication style into system.md as single source of truth
- Remove now-redundant AGENTS.md file
- Add ensurePreferences() to auto-create .gsd/PREFERENCES.md template during
GSD bootstrap with complete YAML frontmatter, field descriptions, and examples
- Update guided-flow to call ensurePreferences() on first .gsd/ init
- Build verified
These extensions were removed from the repo but the loader still
referenced them and the README still listed them. Removed from:
- src/loader.ts extension entry points (11 → 9)
- README bundled extensions table
- app-smoke test assertions
Brave now uses separate API keys per plan:
- BRAVE_API_KEY (Search plan) → web search, LLM context, news, etc.
- BRAVE_ANSWERS_KEY (Answers plan) → chat/completions
Updated:
- wizard: prompts for and stores both keys
- loadStoredEnvKeys: hydrates BRAVE_ANSWERS_KEY from auth.json
- smoke tests: covers BRAVE_ANSWERS_KEY hydration
- verify-s03.sh: includes BRAVE_ANSWERS_KEY in env and structural checks