Commit graph

50 commits

Author SHA1 Message Date
TÂCHES
193b2b32a5 fix: strip clack UI from postinstall, keep silent Playwright download (#783)
npm ≥7 suppresses lifecycle script output by default, so the clack
banner/spinner was invisible during `npm install -g`. The user-facing
onboarding experience already lives at first `gsd` launch (onboarding.ts),
making the postinstall UI redundant dead code.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 21:35:04 -06:00
Jeremy McSpadden
6ed9cd5359 fix: resolve CI failures in VS Code extension PR
- Fix Windows MCP test failures: use pathToFileURL() instead of bare
  join() paths for dynamic imports, fixing ERR_UNSUPPORTED_ESM_URL_SCHEME
  on Windows where D:\ paths are not valid ESM import specifiers

- Remove parallel orchestration code that was WIP from another feature
  branch and not part of the VS Code extension scope (commands.ts,
  preferences.ts, types.ts changes reverted to main)

- Rebase cleanly onto main, resolving mcp-server.ts merge conflict by
  keeping main's dynamic import approach with PR's exported interface
  and JSDoc documentation
2026-03-16 16:53:34 -05:00
Jeremy McSpadden
48feced87d feat: add VS Code extension scaffold and MCP server compiled module
- Add vscode-extension/ with full MVP scaffold:
  - GsdClient: spawns gsd --mode rpc, JSON line communication
  - @gsd Chat participant: forward messages to agent, stream responses
  - Sidebar panel: connection status, model info, start/stop controls
  - Command palette: gsd.start, gsd.stop, gsd.newSession, gsd.sendMessage
  - Extension config: gsd.binaryPath setting
- Add compiled MCP server module at src/mcp-server.ts for tsc output
- Add MCP server tests verifying module import and instantiation
2026-03-16 16:46:20 -05:00
Ryan Harrington
f87b4938ca fix/gsd-bg-shell-stale-cwd: normalize bg-shell worktree cwd detection 2026-03-16 17:02:58 -04:00
Ryan Harrington
8b8ba0d207 fix/gsd-bg-shell-stale-cwd: resync bg-shell cwd after auto-worktree exit 2026-03-16 16:45:21 -04:00
TÂCHES
966e5e80fb Merge pull request #673 from jeremymcs/feat/v2.20-phase2-3-features
feat: v2.20 Phase 2-4 — skills, integrations, MCP server
2026-03-16 14:29:07 -06:00
Jeremy McSpadden
062b5c65eb fix: skip environment-dependent tests in CI
- Skip E2E --print test when no API key is configured (process hangs
  waiting for onboarding wizard input in non-TTY CI environments)
- Skip file-watcher extensions subdirectory test on Windows (chokidar
  subdirectory event delivery is unreliable in Windows CI runners)
2026-03-16 14:38:59 -05:00
Jeremy McSpadden
3690e7a8ca fix: stabilize file-watcher and E2E smoke tests for CI
- Increase file-watcher extension directory test delay to 1500ms with
  500ms settle time (Windows filesystem events are slower)
- Make E2E --print test more permissive on exit code 1: check for
  unhandled crash indicators instead of specific error messages
  (error text varies by CI environment)
2026-03-16 14:32:25 -05:00
TÂCHES
07effd64cc Merge pull request #471 from Jamie-BitFlight/feat/claude-import-skills-plugins
feat: import Claude marketplace plugins with namespaced components
2026-03-16 13:32:09 -06:00
Jeremy McSpadden
ce6e684899 fix: increase file-watcher test delay for CI stability 2026-03-16 14:00:47 -05: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
973b8992e5 feat: add GitHub API client, diff-aware context, tiktoken token counting
- Add GitHub API integration via @octokit/rest: createGitHubClient,
  getRepoInfo (parses HTTPS/SSH remotes), createPullRequest,
  getPullRequest, listPullRequestReviews, createIssueComment
- Add diff-aware context module: getRecentlyChangedFiles,
  getChangedFilesWithContext, rankFilesByRelevance — prioritizes
  recently-changed files for context window budget allocation
- Add accurate token counting via tiktoken: countTokens (async),
  countTokensSync, initTokenCounter — falls back to chars/4 heuristic
  when tiktoken is unavailable
- 27 new tests across 3 test files
2026-03-16 13:50:00 -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
ebbcbe363a security: add SSRF protection to fetch_page tool
Block requests to private/internal addresses in the fetch_page tool:
- Private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x)
- Cloud metadata endpoints (metadata.google.internal, instance-data)
- localhost
- Non-HTTP protocols (file://, ftp://)
- IPv6 private ranges (::1, fc00:, fd, fe80:)

Add isBlockedUrl() to url-utils.ts with 11 new tests covering all
blocked and allowed URL patterns.
2026-03-16 13:35:48 -05:00
Jeremy McSpadden
2c926c12e3 fix: Phase 1 quick wins — bug fixes, security hardening, and performance
- 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
2026-03-16 13:18:02 -05:00
Lex Christopherson
3d2f294f6a fix: google-search OAuth test mock and Windows path separator in smoke test
- 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>
2026-03-16 11:56:46 -06:00
Lex Christopherson
20e0fe2460 Merge remote-tracking branch 'origin/main' into test/extension-smoke-test 2026-03-16 11:48:44 -06:00
Lex Christopherson
d187a1ed2d fix: use file:// URL for dynamic imports in smoke test (Windows compat)
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>
2026-03-16 11:46:04 -06:00
Jamie McGregor Nelson
13730189f2 test(claude-import): use portable fixtures for marketplace discovery tests 2026-03-16 11:47:28 -04:00
Jamie McGregor Nelson
60413c4ea9 test: skip marketplace contract tests when local repos are absent 2026-03-16 11:47:28 -04:00
Jamie McGregor Nelson
2e3fa903b1 feat: import Claude marketplace plugins with namespaced components 2026-03-16 11:47:28 -04:00
Lex Christopherson
40dd80a41e fix(voice): replace __dirname with import.meta.dirname for ESM compat
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:35:07 -06:00
Lex Christopherson
15462a7da7 test: add extension smoke test to catch import failures in CI
Dynamically discovers all bundled extensions and verifies they can be
imported without throwing. Catches missing imports, circular deps, and
broken module resolution that tsc cannot detect since extensions are
loaded at runtime via jiti.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:27:39 -06:00
Harald Heckmann
186a1de406 feat: Use google search via Google OAuth if available 2026-03-15 11:13:36 +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
Flux Labs
16364c7dba fix: prevent web_search tool injection for non-Anthropic providers serving Claude models (#444) (#446)
GitHub Copilot users with Claude models got 400 errors because the native
Anthropic web_search_20250305 tool was injected into requests to Copilot's
API proxy, which doesn't support it. The root cause was that model_select
never fires before the first API request on new sessions, so the fallback
heuristic (model name starts with "claude-") couldn't distinguish direct
Anthropic from proxied providers.

Fix: pass the resolved Model object through to the before_provider_request
event so extensions can check model.provider directly instead of relying on
model name heuristics.
2026-03-14 22:15:00 -06:00
Flux Labs
ecf8125e39 feat: add Ollama Cloud as model and web tool provider (#430) (#434)
Add Ollama Cloud (ollama.com) as a built-in provider with both model
hosting and web search/fetch capabilities.

Model provider:
- 13 curated models via OpenAI-compatible API (Llama 3.1, Qwen 3,
  DeepSeek R1, Gemma 3, Mistral, Phi-4, GPT-OSS)
- Auth via OLLAMA_API_KEY environment variable
- Registered in onboarding, env hydration, and model resolver

Web tool provider:
- Search via POST ollama.com/api/web_search
- Page fetch via POST ollama.com/api/web_fetch (fallback after Jina)
- Added as third search provider option alongside Tavily and Brave
- /search-provider command updated with ollama option

Closes #430
2026-03-14 21:03:31 -06:00
deseltrus
aca53c5853 refactor: replace hardcoded extension list with dynamic discovery in loader
loader.ts previously maintained a hardcoded list of bundled extension paths
for GSD_BUNDLED_EXTENSION_PATHS. This required manual updates whenever
extensions were added or removed, and created a consistency gap with
buildResourceLoader() which already discovers extensions dynamically.

Replace with runtime directory scanning that mirrors the discovery rules
in resource-loader.ts:
- Top-level .ts/.js files → extension entry point
- Directories with index.ts or index.js → extension entry point
- Directories without either (shared/, remote-questions/) → skipped

Benefits:
- Adding a new extension no longer requires editing loader.ts
- GSD_BUNDLED_EXTENSION_PATHS stays in sync with what buildResourceLoader()
  loads in the main process — subagents now receive the same extensions
- Fixes: 5 extensions (google-search, mcporter, ttsr, universal-config,
  voice) were loaded in the main process but missing from
  GSD_BUNDLED_EXTENSION_PATHS, meaning subagents did not receive them
- Eliminates a common source of merge conflicts for contributors and forks
  that add custom extensions
2026-03-14 20:37:18 +01:00
Flux Labs
b6ec4f9fad Fix packaging verification and path portability (#378) 2026-03-14 12:28:14 -06:00
Juan Francisco Lebrero
f6f1f9aa27 fix(search): always use native Anthropic web search when available (#374)
Three bugs prevented native web_search from being used with Anthropic:

1. model_select never fires on session restore (SDK's modelsAreEqual
   guard suppresses it when the default model matches the restored one),
   so isAnthropicProvider stayed false and native search was never
   injected. Fix: fall back to detecting "claude-" in the payload model
   name when model_select hasn't fired.

2. Custom search tools (search-the-web, search_and_read) were only
   removed from the payload when BRAVE_API_KEY was missing. With the
   key present, the model saw both native and Brave tools and often
   picked the Brave ones, which failed with network errors. Fix: always
   remove custom search tools from Anthropic requests.

3. google_search (Gemini-based) was not included in the disable list,
   so the model could call it even without GEMINI_API_KEY set. Fix: new
   CUSTOM_SEARCH_TOOL_NAMES list covers all three custom search tools.
2026-03-14 11:46:50 -06:00
Jamie Nelson
f791731d4f feat: add GitHub Workflows skill with CI workflow and ci_monitor tool (#294)
* feat: add GitHub Workflows skill with CI workflow and ci_monitor tool

- Runs on push to main and feature branches
- Runs on pull requests to main
- Build + test pipeline using Node 22

Cross-platform CI monitoring tool for debugging GitHub Actions:
- `runs` - List recent workflow runs
- `watch` - Monitor running workflow
- `fail-fast` - Exit 1 on first failure (for scripts)
- `log-failed` - Show failed job logs
- `test-summary` - Extract test pass/fail counts
- `check-actions` - GraphQL query for action versions
- `grep` - Search logs with context
- `wait-for` - Block until deployment keyword appears

Pure Node.js - no shell interpolation, works on macOS/Windows/Linux.

Drift-immune skill that:
- Routes all CI operations through ci_monitor.cjs
- Fetches live docs from docs.github.com (no stale training data)
- Provides validation constraints (BEFORE/AFTER/EVIDENCE)

- Split tests into test:unit (141 tests, ~12s) and test:integration (5 tests)
- Fixed idle-recovery.test.ts for current implementation
- Removed AGENTS.md dead code from resource-loader.ts
- Moved npm run build out of tests (fixes ENOBUFS)

When CI fails, you need observable diagnostics:
- `gh run` output is not script-friendly
- ci_monitor.cjs provides structured output for automation
- The skill ensures AI uses the tool, not stale training data

* fix: resolve imports and path for current upstream version

- Updated imports from @mariozechner/pi-coding-agent to @gsd/pi-coding-agent
- Fixed integration test path calculation to use process.cwd()
- Kept test:unit and test:integration scripts

* fix: replace search provider preference instead of accumulating

AuthStorage.set() for api_key credentials appends to the existing list
rather than replacing. When setSearchProviderPreference was called twice
with different values, the second call appended the new value, leaving
the first value at index 0, which get() returned.

Fix: call auth.remove() before auth.set() to ensure only the latest
preference is stored.

https://claude.ai/code/session_01Qx7HRSDb117KzDZzdKk1KB

* fix: address all 10 open PR review comments

- package.json: run build before test:integration so a fresh checkout works
- pack-install.test.ts: replace execSync+shell redirects with execFileSync
  argument arrays (portable, no shell parsing, paths with spaces safe)
- ci_monitor.test.ts: remove unconditional passed++ after assert; move
  success message after the failed > 0 check so it only prints on success
- setup_gh.cjs: replace unzip/tar shell-outs with platform-specific
  execFileSync calls (unzip on macOS, PowerShell Expand-Archive on Windows);
  add compareVersions() for correct element-by-element semver comparison
- ci_monitor.cjs: add --repo/-R global option so repo is overrideable;
  fix getLogs() to use gh run view --log --job instead of binary REST endpoint

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: make all changed files fully cross-platform (Windows/macOS/Linux)

- pack-install.test.ts: use tar npm package instead of tar CLI; resolve
  gsd binary as gsd.cmd on Windows; skip shebang check on Windows
- setup_gh.cjs: use execFileSync for all binary invocations; replace
  which with where on Windows; add Windows PATH guidance; filter preferred
  install dirs by platform; unify ZIP extraction to use process.platform
  consistently; escape single quotes in PowerShell Expand-Archive args
- ci_monitor.cjs: use path.join for .github/workflows paths; replace
  all split('\n') with split(/\r?\n/) to handle Windows CRLF output

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* refactor: simplify and deduplicate changed files

- ci_monitor.cjs: memoize getRepo() so gh repo view subprocess runs at
  most once per invocation instead of once per command call in watch loops
- pack-install.test.ts: extract packTarball() helper to eliminate
  duplicate npm pack logic across two tests; remove unused contents variable

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* refactor: remove redundant existsSync before canWrite() in findInstallDir

canWrite() already returns false for non-existent directories, so the
pre-check was a TOCTOU-style redundancy with no behavioral value.

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: replace tar npm package with Node built-ins (zlib + manual tar parsing)

tar is not in the dependency tree. listTarEntries() decompresses via
createGunzip() and parses the 512-byte tar block format directly,
reading name/prefix/type/size fields per POSIX ustar spec. No external
dependency required. Also fixes the broken tarball variable reference
left over from the packTarball() refactor.

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* remove: drop setup_gh scripts in favour of ci_monitor

setup_gh.cjs and setup_gh.py were one-shot gh CLI installers.
ci_monitor.cjs covers the day-to-day CI use case and is the tool
the skill routes through. Environments that need gh installed can
use brew/winget/distro packages directly.

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: run only unit tests in CI — integration tests cause ENOBUFS

The integration tests (npm pack → npm install → spawn node) exceed
the buffer limits of the CI runner environment. They are documented
as requiring a manual build+run step. CI now runs test:unit only.

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: run all tests in CI without ENOBUFS

- ci.yml: run unit and integration as separate steps; build is already
  its own step so test:integration doesn't need to rebuild
- package.json: remove npm run build from test:integration script
- pack-install.test.ts: npm install uses stdio:'ignore' to avoid
  piping large output through Node buffers (root cause of ENOBUFS);
  add early dist/ check with clear error message instead of rebuilding

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: resolve ENOBUFS and clean up setup_gh references

- pack-install.test.ts: derive tarball filename from package.json
  instead of piping npm pack --json stdout; use stdio:ignore throughout
  to avoid exhausting OS pipe buffers on CI runners
- SKILL.md: remove setup_gh install instructions; assume gh is
  pre-installed via system package manager; point to ci_monitor.cjs
- github_project_setup.py: remove setup_gh.py reference from error message

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

* fix: address Copilot review comments on pack-install.test.ts

- listTarEntries: collect chunks in array, Buffer.concat once on end
  instead of O(n²) repeated concat in data handler
- listTarEntries: attach error handler to createReadStream so read
  errors reject the Promise instead of crashing the process
- npm pack: use stdio:['ignore','ignore','pipe'] to preserve stderr
  for diagnostics while still avoiding ENOBUFS on stdout
- npm install: same — pipe stderr so failures include error output

https://claude.ai/code/session_01AT6CgcAB62kWcDsTJg9HZM

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-13 22:31:17 -06:00
Jamie Nelson
17074c4db5 fix: update tests for current implementation (#284)
- idle-recovery.test.ts: Use 'unknown-type' instead of 'execute-task'
  for null-path test (execute-task now has artifact paths for task summaries)

- app-smoke.test.ts: Remove AGENTS.md assertions (merged into system.md
  in commit 0b6d88f). Add ENOBUFS skip handling for tarball tests
  (system buffer exhaustion is not a code issue).
2026-03-13 16:26:17 -06: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
c344b0af54 fix: use provider field instead of model name prefix for Anthropic detection (#142) (#196)
The before_provider_request hook used model.startsWith("claude") to gate
native web search injection. This matched claude-* models served by any
provider (GitHub Copilot, AWS Bedrock, etc.), incorrectly injecting
Anthropic-only web_search_20250305 tool definitions into non-Anthropic
API requests.

The fix checks the isAnthropicProvider flag (set by model_select via the
provider field) instead of sniffing the model name.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:22:52 -06:00
TÂCHES
789a6645da feat: TTSR + blob/artifact storage (ported from oh-my-pi)
* docs(M002): context, requirements, and roadmap

* feat: port TTSR and blob/artifact storage from oh-my-pi

Phase 1 — TTSR (Time Traveling Stream Rules):
- TtsrManager: regex-based stream monitoring with scope filtering,
  repeat gating, and buffer isolation (picomatch replaces Bun.Glob)
- Rule loader: scans ~/.gsd/agent/rules/*.md and .gsd/rules/*.md
  with YAML frontmatter parsing; project rules override global
- TTSR extension: wires into pi event lifecycle (session_start,
  turn_start, message_update, turn_end, agent_end) to abort on
  match and inject violation as system reminder via sendMessage
- Interrupt template for rule violation injection

Phase 2 — Blob/Artifact Storage:
- BlobStore: content-addressed storage at ~/.gsd/agent/blobs/ using
  Node crypto (sha256), sync I/O, automatic deduplication
- ArtifactManager: session-scoped sequential artifact files stored
  alongside session JSONL (lazy dir creation, resume-safe ID scan)
- Session manager integration: prepareForPersistence externalizes
  images ≥1KB to blob store before JSONL write; resolveBlobRefs
  rehydrates on session load; truncates strings >500KB
- Bash tool artifact spill: uses ArtifactManager instead of temp
  files when available, includes artifact:// references in output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden blob store, TTSR manager, and dep classification

- Validate SHA-256 hex format in BlobStore.get/has/parseBlobRef to
  prevent path traversal via crafted blob references
- Cap TTSR per-stream buffers at 512KB to prevent unbounded memory growth
- Move picomatch from devDependencies to dependencies (runtime import)
- Warn on invalid regex in TTSR rule conditions instead of silent skip
- Remove .gsd/ planning files that were force-added past .gitignore
- Add trailing newline to ttsr-interrupt.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add tests for blob store, artifact manager, TTSR manager, and rule loader

55 tests covering:
- BlobStore put/get/has, idempotency, path traversal rejection
- parseBlobRef/isBlobRef validation, externalize/resolve round-trips
- ArtifactManager sequential IDs, lazy dir creation, session resume
- TtsrManager rule matching, scope filtering, buffer isolation,
  repeat gating, buffer size cap, injection persistence
- Rule loader frontmatter parsing, directory scanning, merge logic

Also fixes BlobStore constructor to avoid TS parameter property syntax
(incompatible with Node's strip-only TypeScript mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:43:56 -06: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
Facu_Viñas
a595b9e28e fix: prevent duplicate tools on provider toggle, suppress restore notifications, fix Windows test globs
- Prevent duplicate Brave tool entries when toggling providers repeatedly
  by filtering already-active tools before re-adding (BUG-1)
- Remove single quotes from test glob patterns in package.json so Windows
  shell expands them correctly (BUG-2)
- Fix test mock fire() to call all handlers instead of short-circuiting
  on first match, matching real framework behavior (BUG-3)
- Suppress "Native Anthropic web search active" notification on session
  restore (source: "restore") to reduce UX noise (BUG-4)
- Add regression tests for all 4 bugs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:50:03 -03:00
Facu_Viñas
e22a2f7622 fix: remove Brave search tools from API payload when no BRAVE_API_KEY
The model_select event doesn't reliably fire on startup, so Brave tools
remained visible to Claude even without a key. Now before_provider_request
filters search-the-web and search_and_read from the payload directly,
ensuring Claude only sees the native web_search tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:50:03 -03:00
Facu_Viñas
2252a6dfca fix: strip thinking blocks from history to fix conversation replay error
The Pi SDK's streaming parser drops server_tool_use and
web_search_tool_result content blocks. When the conversation is replayed,
assistant messages are incomplete, causing the Anthropic API to reject
requests with "thinking blocks cannot be modified."

Fix: stripThinkingFromHistory() removes thinking/redacted_thinking blocks
from all assistant messages before sending, since they're all from stored
history. The model generates fresh thinking for each new turn.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:50:03 -03:00
Facu_Viñas
4ba7930240 test: add tests for native Anthropic web search hook logic
12 tests covering: tool injection for claude models, non-claude passthrough,
double-injection prevention, tool deactivation/reactivation on model switch,
and session_start diagnostics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:50:02 -03:00
deseltrus
9fb348b123 feat: add Tavily as alternative search provider (#102)
Add Tavily Search API as an alternative backend for search-the-web and
search_and_read tools. Tavily is selected automatically when TAVILY_API_KEY
is set (preferred over Brave when both keys present). Existing Brave
Search paths are completely unchanged.

Motivation: Brave Search API signup requires Stripe payment which may
not be available in all regions. Tavily offers a free tier and also
provides a Deep Research API for future expansion.

Changes:
- Auth: Tavily API key in wizard, auth.json storage, env hydration
- search-the-web: Tavily POST backend with response normalization
- search_and_read: Tavily advanced search with client-side token budgeting
- /search-provider: slash command for explicit provider switching
- 61 new tests covering all Tavily integration paths
- Zero changes to existing Brave code paths
2026-03-12 07:12:19 -06:00
dan bachelder
dfebda73af fix: avoid sudo prompts in postinstall (#73)
Co-authored-by: Ada <ada@clawdbot>
2026-03-11 18:19:33 -06:00
Lex Christopherson
a21022a3ef docs: update README for current state, remove github extension
- Remove github extension (3 files) and its test
- Fix GitHub badge/link URLs (glittercowboy/gsd-pi → gsd-build/GSD-2)
- Update /gsd description: wizard → step mode (default since /gsd next)
- Add missing commands: /gsd next, /worktree, /voice, /exit, /clear, keybindings
- Update bundled extensions: 9 → 13 (add Google Search, Mac Tools, MCPorter, Voice)
- Add Google Gemini API key to first launch, requirements, architecture tree
2026-03-11 17:10:51 -06:00
Gary Trakhman
0a955c0b98 fix: support pi extensions from ~/.pi/agent/extensions/ (#51)
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
2026-03-11 13:09:30 -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
Lex Christopherson
2d2858cf85 fix: remove worktree and plan-mode from loader and README (not bundled)
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
2026-03-10 22:49:30 -06:00
Lex Christopherson
a4779f8e83 feat(wizard): add BRAVE_ANSWERS_KEY support
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
2026-03-10 22:44:28 -06:00
Lex Christopherson
3bd2f8cb63 Initial commit 2026-03-10 22:28:37 -06:00