Commit graph

39 commits

Author SHA1 Message Date
Jeremy McSpadden
ce1ad35706 perf: skip initResources when version matches, consolidate startup I/O (#1052)
- Add version-match early return to initResources() — skips ~800ms of
  synchronous rmSync + cpSync when managed-resources.json already matches
  the running GSD version (steady-state on every launch)
- Consolidate package.json reads in loader.ts from 3 to 1 — single read
  reused for --version, --help, banner, and GSD_VERSION env var
- Replace blocking checkAndPromptForUpdates() with passive checkForUpdates()
  to avoid blocking startup on npm registry fetch + user prompt (up to 5s)
- Cache bundled extension keys in resource-loader to avoid redundant
  filesystem scan in buildResourceLoader()
- Use GSD_VERSION env var in getBundledGsdVersion() to skip package.json
  re-read from resource-loader.ts
- Add test verifying version-skip behavior: marker file survives when
  versions match, gets cleaned on mismatch
2026-03-17 21:57:13 -06:00
Tom Boucher
3b18711524 fix: don't overwrite user's model choice when API key is temporarily unavailable (#910) (#928)
The startup model validation overwrote the user's configured model when
it was 'not available' (API key missing, OAuth token expired, rate
limited). This silently changed the model to a fallback like
google/gemini-1.5-flash or openai/gpt-5.4.

Fix: Only trigger the fallback when the configured model doesn't exist
in the registry at all (removed/unknown). A model that exists but is
temporarily unavailable (credential issue) keeps its setting — the
session-level fallback resolver handles it at prompt time.
2026-03-17 14:01:51 -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
e0c1cc2f9d Merge branch 'main' into feat/gsd-headless-command 2026-03-16 18:44:18 -06:00
Gary Trakhman
49c7c0d540 feat: Add models.json resolution with fallback to ~/.pi/agent/models.json
- Create src/models-resolver.ts with resolveModelsJsonPath() function
- Fallback chain: ~/.gsd/agent/models.json → ~/.pi/agent/models.json → create new
- Integrate into cli.ts ModelRegistry initialization
- Provides smooth migration path for users with existing pi-coding-agent config
2026-03-16 23:05:59 +00:00
frizynn
b09e2a549c feat: add gsd headless CLI subcommand for non-interactive auto-mode
Adds a first-class `gsd headless` command that runs auto-mode without a
TUI by spawning a child process in RPC mode via RpcClient. Useful for
CI/CD pipelines, scripts, and unattended execution.

CLI interface:
  gsd headless                  - Run auto-mode until complete
  gsd headless --step           - Run one unit only (sends /gsd next)
  gsd headless --timeout 300000 - Custom timeout (default 5 min)
  gsd headless --json           - Forward RPC events as JSONL to stdout
  gsd headless --verbose        - Show full agent text and tool results
  gsd headless --model <id>     - Override model

Exit codes: 0 = complete, 1 = error/timeout, 2 = blocked

Features:
- Extension UI auto-responder (handles select, confirm, input, editor,
  notify, setStatus, setWidget, setTitle, set_editor_text)
- Completion detection via terminal notification keywords + idle timeout
- Human-readable progress output to stderr
- SIGINT/SIGTERM forwarding for clean shutdown
- Child process crash detection
- Completion summary with diagnostics on failure
2026-03-16 19:45:39 -03:00
sgodoy90
72cef21876 feat: add gsd sessions subcommand for session picker
Add a new `gsd sessions` subcommand that lists all saved sessions for
the current directory and lets the user interactively pick one to resume.

Currently `gsd --continue` only resumes the most recent session, with no
way to access older conversations. This change adds:

- `gsd sessions` subcommand that calls SessionManager.list() to enumerate
  all sessions for the current working directory
- Interactive numbered list showing date, message count, session name (if
  set), and a preview of the first message
- Selection by number to resume any past session via SessionManager.open()
- Subcommand help text (`gsd sessions --help`)
- Help text entry in the main `gsd --help` output

The implementation uses only existing SessionManager APIs (list, open) -
no SDK changes required.
2026-03-16 15:27:10 -06:00
Jeremy McSpadden
8d56ab2893 feat: add MCP server mode, /lint skill, E2E smoke tests
- Add native MCP server mode (--mode mcp): exposes GSD's tools via
  Model Context Protocol over stdin/stdout for Claude Desktop, VS Code,
  and other MCP-compatible clients. Uses @modelcontextprotocol/sdk.
- Add /lint skill: auto-detects ESLint, Biome, Prettier, rustfmt,
  gofmt, Black, Ruff and runs with structured output
- Add 6 E2E smoke tests: --version, --help, config --help, update
  --help, --list-models, and --mode text --print startup
- Fix diff-context.ts stdio type for CI compatibility
- Fix token-counter.ts tiktoken import for extensions typecheck
- Update help text and CLI to include --mode mcp
2026-03-16 13:56:31 -05:00
Jeremy McSpadden
0b3163d297 feat: add /review skill, /test skill, chokidar file watcher, subcommand help
- Add /review skill: reviews staged/unstaged/commit changes for security,
  performance, bugs, and quality with structured findings by severity
- Add /test skill: auto-detects test framework, generates comprehensive
  tests for source files, or runs suites with failure analysis
- Add chokidar file watcher: watches ~/.gsd/agent/ for config changes
  (settings.json, auth.json, models.json, extensions/) with debounced
  events on an EventBus
- Add --help per subcommand: `gsd config --help` and `gsd update --help`
  show subcommand-specific usage information
- 8 new file-watcher tests (start/stop, event emission, debouncing,
  unrelated file filtering)
2026-03-16 13:47:25 -05:00
Jeremy McSpadden
a79e953caa refactor: deduplicate help text, cross-platform validate-pack, fix dev.js
- 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)
2026-03-16 13:29:31 -05:00
Rebecca Chernoff
17fbf7d925 fix: skip onboarding wizard when extension provider already configured (#589)
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.
2026-03-16 11:07:15 -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
Flux Labs
8913aea968 fix: prevent arrow keys from inserting escape sequences as text (#493)
Arrow keys produce `^[[D`/`^[[C` instead of moving the cursor when event
loop latency causes the StdinBuffer to split escape sequences.

Three layered fixes:

1. Increase StdinBuffer timeout from 10ms to 50ms (matches xterm default)
   so split escape sequences are reassembled even under load.

2. Clean up stale readline listeners after @clack/prompts onboarding —
   readline.emitKeypressEvents() leaves a permanent data listener that
   is unnecessary for the TUI.

3. Guard in editor against CSI remnants: if a split still occurs, reject
   text matching navigation escape patterns ([A-F, [H, [Z, [n~) instead
   of inserting them as characters.

Closes #493
2026-03-15 17:17:58 -05:00
Flux Labs
4a76d7b174 Merge branch 'main' into fix/tui-resource-leaks-and-quality 2026-03-15 11:39:52 -05:00
Flux Labs
4995afed90 refactor: replace hardcoded ANSI escapes with chalk, add debug logging
- cli.ts: use chalk.yellow/dim/bold instead of raw \x1b sequences for
  version mismatch message; chalk v5 auto-respects NO_COLOR
- update-check.ts: same chalk migration for the update banner
- guided-flow.ts: log auto-start errors when GSD_DEBUG is set instead
  of silently swallowing them
2026-03-15 09:56:41 -05:00
deseltrus
d154d992dd feat(config): session-internal /gsd config + fix key hydration
Three fixes for config/setup UX:

1. cli.ts: Add missing loadStoredEnvKeys() call in gsd config flow.
   Previously, gsd config showed keys as "not configured" even when
   they existed in auth.json because env vars weren't hydrated first.

2. commands.ts: New /gsd config slash command that lets users configure
   API keys (Tavily, Brave, Context7, Jina, Groq) from within a running
   session. Keys are saved to auth.json and activated immediately.
   No need to exit the session and run gsd config externally.

3. command-search-provider.ts: Show native Anthropic web search status
   when using Claude models, so users know search works even without
   Brave/Tavily keys.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 08:35:27 +01:00
Colin Johnson
fe03743b08 fix: guard against newer synced resources (#445)
Co-authored-by: TÂCHES <afromanguy@me.com>
2026-03-14 22:58:18 -06:00
Juan Francisco Lebrero
3a1b8f457d feat: opus 4.6 1M default, model selector UX, Discord onboarding (#290) 2026-03-14 08:43:56 -06:00
Juan Francisco Lebrero
0858092098 feat: add gsd update subcommand for self-update
Adds a CLI subcommand that checks npm for the latest version and
runs `npm install -g gsd-pi@latest` if an update is available.
Prints current/latest version and clear success/failure messages.
2026-03-13 18:47:33 -03:00
Facu_Viñas
5a2ed4eb05 feat: add startup update check with 24h cache
Queries npm registry at most once per 24h to check if a newer version
of gsd-pi is available. Displays a non-blocking banner in interactive
mode when an update exists. The check is fire-and-forget — network
errors or timeouts never block startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:28:43 -03:00
TÂCHES
2a3c2b5194 Merge pull request #151 from dbachelder/fix/pi-provider-reuse-and-extension-loading
fix: reuse Pi provider config and load Pi extensions correctly
2026-03-12 22:25:15 -06:00
Lex Christopherson
c80d640d35 feat: vendor Pi source into workspace monorepo
Vendor all 4 Pi packages (tui, ai, agent-core, coding-agent) from
pi-mono v0.57.1 as @gsd/* workspace packages under packages/. This
replaces the compiled npm dependency (@mariozechner/pi-coding-agent)
and patch-package workflow, giving direct source access for
modifications.

- Copy Pi source from pi-mono v0.57.1 into packages/
- Create workspace package.json + tsconfig.json for each package
- Rename ~240 imports from @mariozechner/pi-* to @gsd/pi-*
- Apply existing patches as source edits (setModel persist, VT input)
- Remove @mariozechner/pi-coding-agent dep and patch-package
- Update build pipeline to build packages in dependency order
- Add pi-upstream git remote for future selective syncing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:55:17 -06:00
dan
00cb2f36a8 fix: reuse pi provider config and extension loading 2026-03-12 20:44:09 -07:00
vp275
d7a90cf0e6 Add --continue / -c flag to resume the most recent session
Uses the existing SessionManager.continueRecent() from the Pi SDK
to load the most recent session for the current working directory.
Mirrors the --continue flag already available in the base Pi CLI.
2026-03-13 07:51:29 +05:30
Lex Christopherson
b72d852771 feat: migrate provider credentials from existing Pi install
Closes #122

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:08:34 -06:00
TÂCHES
e93a44d967 feat: add clack-based onboarding wizard and gsd config command (#118)
Replace the plain-text API-key-only wizard with a branded, clack-based
onboarding experience that guides first-launch users through LLM provider
authentication (OAuth or API key), optional tool API keys, and a summary.

- Create src/logo.ts as single source of truth for ASCII logo
- Create src/onboarding.ts with shouldRunOnboarding() and runOnboarding()
- Trim src/wizard.ts to env hydration only (loadStoredEnvKeys)
- Wire onboarding into src/cli.ts, add `gsd config` subcommand
- Remove duplicate first-launch banner from src/loader.ts

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:02:00 -06:00
Lex Christopherson
254c3c8931 fix: address 11 community-reported bugs across CLI, auto-mode, and extensions
CLI routing (#81, #107):
- Import and route --mode rpc to runRpcMode() instead of silently falling through to runPrintMode
- Add TTY guard before interactive mode — exit with helpful message when stdin is not a TTY
- Add --version and --help flags

Auto-mode infinite loop (#96):
- Move summarizing/complete-slice dispatch before reassessment check (D1) — ensures mergeSliceToMain always runs
- Add per-unit dispatch counter to detect alternating loops like A→B→A→B (D3)

Windows shell escaping (#106, #98):
- Platform-aware escapeShellArg() in mcporter extension — double quotes on Windows, single quotes on Unix

CRASH: parseSummary (#91):
- Add asStringArray() helper to safely coerce YAML bare scalars (e.g. "none") to string arrays
- Applied to all 7 frontmatter fields that expect string[]

Google Search model (#99):
- Replace hardcoded gemini-3-flash-preview with env var GEMINI_SEARCH_MODEL (default: gemini-2.5-flash)

Worktree branch collision (#84):
- Check git worktree list before checkout to detect branches already in use by another worktree

Migration UX (#90, #93):
- Improve error messages to distinguish migration from new project setup, suggest /gsd:new-project

Keyboard shortcuts (#100, #104):
- Document terminal protocol requirement in shortcut descriptions — Ctrl+Alt combos need Kitty/modifyOtherKeys

Closes #81, #84, #91, #96, #99, #106, #107
Addresses #90, #93, #95, #98, #100, #104

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 08:37:00 -06:00
Lex Christopherson
5eb02e9a1c fix: auto-commit before branch switch and migrate legacy flat sessions
ensureSliceBranch() now auto-commits dirty files before git checkout,
preventing "would be overwritten" errors when doctor/STATE.md rebuild
leaves uncommitted changes between slice dispatches. (closes #63)

On startup, migrate any .jsonl session files from the flat
~/.gsd/sessions/ directory into the per-cwd subdirectory so /resume
can find sessions created before per-directory scoping was added.
(closes #64)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:07:54 -06:00
Lex Christopherson
d4a46beef7 fix: support print/JSON mode in cli.js so subagents don't hang
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>
2026-03-11 11:21:12 -06:00
TÂCHES
0d251d9707 fix: bootstrap managed tools and gh auth
Preserve the original #39 fix while adding the missing hardening and regression coverage. Credit to @LuxVTZ for the original fix incorporated here.
2026-03-11 10:52:45 -06:00
vp275
f307923db2 fix: scope session list to current working directory
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.
2026-03-11 21:39:02 +05:30
jonathancostin
0b1f02219b fix: restore scoped models from settings on new session startup (#22) 2026-03-11 06:57:55 -06:00
Vedant
afa1fffaac fix: startup fallback overwrites user's default model with Sonnet (#29) 2026-03-11 06:57:31 -06:00
Lex Christopherson
cce10ffc89 fix: validate default model against full registry on every startup
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.
2026-03-11 01:51:48 -06:00
Lex Christopherson
b364e369d5 fix: remove circular self-dependency, default to anthropic/claude-sonnet-4-6 with thinking off
- 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
2026-03-11 01:47:36 -06:00
Lex Christopherson
3086e5d979 fix(cli): match default model by id.includes('sonnet') — API returns dated IDs not aliases 2026-03-11 01:33:34 -06:00
Lex Christopherson
fc9da03cbf fix: use claude-sonnet-4-6 as default model 2026-03-10 23:55:12 -06:00
Lex Christopherson
0181ff2dca fix: auto-select default model after login to prevent 'No model configured' error
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
2026-03-10 23:54:33 -06:00
Lex Christopherson
3bd2f8cb63 Initial commit 2026-03-10 22:28:37 -06:00