Commit graph

912 commits

Author SHA1 Message Date
TÂCHES
9838ef3781 Merge pull request #689 from jeremymcs/fix/visualizer-completedAt-date-coercion
fix: coerce completedAt to String in visualizer changelog sort
2026-03-16 14:18:09 -06:00
TÂCHES
e4d47de1f6 Merge pull request #690 from trek-e/fix/688-thinking-minimal-gpt5
fix: clamp 'minimal' thinking level to 'low' for gpt-5.x models (#688)
2026-03-16 14:17:51 -06:00
Tom Boucher
1a499aecb2 fix: clamp 'minimal' thinking level to 'low' for gpt-5.x models (#688)
gpt-5.x models (via Copilot/OpenAI/Azure) don't support 'minimal' as a
reasoning effort level — they only accept 'none', 'low', 'medium',
'high', and 'xhigh'. Setting /thinking minimal with gpt-5.4 causes a
400 error.

The openai-codex-responses provider already had this clamping, but the
openai-responses and azure-openai-responses providers passed the value
through unclamped.

Add clampReasoningForModel() to both providers that maps 'minimal' to
'low' for gpt-5.x models, matching the existing behavior in
openai-codex-responses.

Fixes the bug portion of #688
2026-03-16 16:02:54 -04:00
Jeremy McSpadden
a01df1f110 fix: coerce completedAt to String in visualizer changelog sort
YAML frontmatter parsers can return Date objects for ISO date strings
instead of plain strings. This caused a TypeError when calling
.localeCompare() on a Date object in the changelog sort.

Wrap completedAt with String() at both assignment and sort to handle
both native and JS parser paths safely.
2026-03-16 14:59:29 -05:00
TÂCHES
72223d0a7a Merge pull request #685 from gsd-build/fix/643-warp-unsupported-shortcuts
fix: add Warp to unsupported Ctrl+Alt shortcut list
2026-03-16 13:43:40 -06:00
Lex Christopherson
36345c12fc fix: add Warp terminal to unsupported Ctrl+Alt shortcut list
Warp terminal (both macOS and Windows) does not emit recognized escape
sequences for Ctrl+Alt key combos. This adds Warp to the unsupported
terminals list so users see the /gsd status fallback hint.

Closes #643

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 13:37:53 -06: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
TÂCHES
c03505dd69 Merge pull request #684 from trek-e/fix/677-plan-slice-executor-constraints
fix: provide executorContextConstraints to plan-slice template (#677)
2026-03-16 13:31:51 -06:00
TÂCHES
0ad5bebc33 Merge pull request #683 from trek-e/fix/681-fractional-slice-id
fix: support fractional slice IDs (e.g. S03.5) in roadmap parser (#681)
2026-03-16 13:31:10 -06:00
Tom Boucher
7b014e13fb fix: support fractional slice IDs (e.g. S03.5) in roadmap parser (#681)
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
2026-03-16 15:25:58 -04:00
Tom Boucher
523debee6c fix: provide executorContextConstraints to plan-slice template (#677)
The plan-slice.md template declares {{executorContextConstraints}} but
buildPlanSlicePrompt() never passed this variable, causing loadPrompt()
to throw: 'template declares {{executorContextConstraints}} but no value
was provided.'

Add formatExecutorConstraints() that uses the budget engine
(computeBudgets + resolveExecutorContextWindow) to generate the
executor context constraints block with task count ranges and inline
context budgets based on the configured executor model's context window.

Pass the formatted string to loadPrompt() as executorContextConstraints.

Closes #677
2026-03-16 15:23:39 -04:00
TÂCHES
5a2d194f64 Merge pull request #678 from trek-e/fix/654-worktree-state-sync
fix: sync worktree .gsd/ state to project root after each unit (#654)
2026-03-16 13:21:51 -06:00
TÂCHES
0112a0f390 Merge pull request #680 from trek-e/fix/658-warp-cursor-visibility
fix: auto-enable hardware cursor in Warp terminal (#658)
2026-03-16 13:20:37 -06:00
TÂCHES
36d5ad7a0e Merge pull request #679 from trek-e/fix/455-tui-scrollback-disruption
fix: remove CSI 3J scrollback clear from TUI full redraws (#455)
2026-03-16 13:20:13 -06:00
TÂCHES
d66679e6ad Merge pull request #675 from deseltrus/fix/worktree-edge-cases
fix: worktree edge cases (resolveGitDir, captureIntegrationBranch, doctor)
2026-03-16 13:19:52 -06:00
Tom Boucher
bdbd3579c9 fix: sync worktree state to project root after each unit (#654)
When auto-mode runs in a worktree, .gsd/ metadata (STATE.md, roadmap
checkboxes, slice plans, task summaries) only updates inside the
worktree directory. The project root on main retains stale state.

If auto-mode restarts, startAutoMode() calls deriveState(projectRoot)
which reads the stale .gsd/ from main, sees completed units as
incomplete, and re-dispatches them — causing an infinite loop on
already-finished work.

Add syncStateToProjectRoot() that copies STATE.md and the active
milestone directory from worktree → project root after each unit's
rebuildState + autoCommit. This ensures deriveState(projectRoot) on
restart reads current completion state.

The sync is fully non-fatal (try/catch wrapped). Failure falls back
to existing behavior. Uses cpSync with recursive:true for the
milestone directory tree.
2026-03-16 15:13:24 -04:00
deseltrus
35f63f050a fix: derive initial state from worktree when one exists (#654)
When auto-mode restarts after being stopped, the initial deriveState()
reads from the project root which has stale .gsd/ metadata. Completed
units appear incomplete, causing re-dispatch of finished work.

The auto-worktree (if it exists from the previous run) has the current
state. After the initial deriveState(base), check if an auto-worktree
exists for the active milestone and re-derive from there.

This is safe because:
- Only triggers when worktree isolation is enabled
- Only when not already inside a worktree
- Only when an auto-worktree actually exists for the milestone
- The worktree setup at lines 976+ still runs normally after

Fixes #654

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:13:16 +01:00
deseltrus
25eab8f368 test: fix worktree-bugfix tests for CI (git config + Windows compat)
Use separate git commands instead of && chains (fails on Windows).
Configure git user.name/email before commit (not set in CI runners).
Mirrors the pattern from worktree-e2e.test.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:13:02 +01:00
Tom Boucher
d862c43424 fix: auto-enable hardware cursor in Warp terminal (#658)
Warp terminal does not correctly re-render inverse video (\x1b[7m)
cursor indicators on arrow key movement, making the cursor appear
invisible when navigating with arrow keys.

Auto-detect Warp via TERM_PROGRAM=WarpTerminal and enable the hardware
cursor by default (same as PI_HARDWARE_CURSOR=1). The hardware cursor
is positioned correctly via CURSOR_MARKER and provides reliable visual
feedback in Warp.

Terminals that render inverse video correctly (iTerm2, Terminal.app)
are unaffected — they continue using the fake cursor by default.
2026-03-16 15:11:58 -04:00
TÂCHES
feccaf2998 Merge pull request #674 from trek-e/chore/docs-v2.20.0
docs: update documentation for v2.20.0 release
2026-03-16 13:11:50 -06:00
TÂCHES
2f1abf7aae Merge pull request #676 from adamdry/f-opt-out-of-worktrees
feat: add git.isolation "none" mode — no worktree, no milestone branch
2026-03-16 13:11:35 -06:00
Tom Boucher
0ced559044 fix: remove CSI 3J scrollback clear from TUI full redraws (#455)
During full redraws, the TUI emitted \x1b[3J (clear scrollback) before
\x1b[2J\x1b[H (clear screen + home). In terminals like Ubuntu Terminal
that honor CSI 3J, this destroyed the scrollback buffer and caused the
scrollbar/view position to jump to the top during phase transitions.

Replace with just \x1b[2J\x1b[H which clears the visible screen and
homes the cursor without touching scrollback history. This preserves
view continuity while still performing a clean redraw.
2026-03-16 15:11:11 -04:00
Adam Dry
bd8bc876ee docs: add "none" to isolation field in preferences-reference.md
PR #651 added preferences-reference.md which listed only "worktree" and
"branch" as isolation options. Updated to include "none" with description.
2026-03-16 19:02:41 +00:00
Adam Dry
6cf0df1bb2 ci: fail if .gsd/ directory is checked in 2026-03-16 19:02:32 +00:00
Adam Dry
6aaace9838 feat: add git.isolation "none" mode
Adds git.isolation: "none" so developers can use GSD's full planning/execution
methodology with all work happening directly on their current branch — no worktree,
no milestone branch, no merge step.

- Preference plumbing: "none" accepted/validated, getIsolationMode() helper
- Core bypass: all worktree/branch gates in auto.ts skip in none mode
- Peripheral: doctor skips worktree checks, system prompt omits worktree context
- Docs: git-strategy, configuration, auto-mode, troubleshooting, system prompt updated
- Tests: 11 new tests, 621/621 pass
2026-03-16 19:02:32 +00:00
deseltrus
57529d0c7f fix: worktree edge cases — resolveGitDir, captureIntegrationBranch guard, doctor path
Three fixes for git worktree usage:

1. Add resolveGitDir() that follows the gitdir: pointer in worktree
   .git files. Without this, any code looking for MERGE_HEAD,
   SQUASH_MSG, or rebase state checks the wrong path in worktrees.

2. Guard captureIntegrationBranch() with detectWorktreeName() — in a
   worktree the base branch is implicit (worktree/<name>), so writing
   it to META.json leaves stale metadata that persists after merge-back.

3. Use resolveGitDir() in doctor.ts for corrupt merge state detection.
   Previously hardcoded join(basePath, ".git") which misses worktrees.

Includes 7 regression tests covering all three fixes.

Relates to #654 (stale state from main branch instead of worktree)
Relates to #672 (parallel milestone orchestration)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:00:58 +01:00
Lex Christopherson
b6b9f44758 2.21.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:54:52 -06:00
Lex Christopherson
7763e7d6b5 docs: update changelog for v2.21.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:54:40 -06:00
Tom Boucher
18a0abbfe3 docs: update documentation for v2.20.0 release
Update README and docs/ to cover new features and changes in v2.20.0:

- commands.md: Added /gsd quick, /gsd mode, /gsd help, /gsd skill-health,
  /gsd hooks, /gsd run-hook, gsd --debug flag. Reorganized into
  Session Commands, Configuration & Diagnostics, Git, and Session Management.
- skills.md: Added Skill Lifecycle Management section covering telemetry,
  health dashboard (/gsd skill-health), staleness detection, and heal-skill
  post-unit analysis.
- remote-questions.md: Added Telegram as a third channel alongside
  Slack and Discord, with setup instructions and bot requirements.
- configuration.md: Added skill_staleness_days preference.
- README.md: Added skill_staleness_days to key settings table, new
  Agent Instructions section, and Debug Mode section.
2026-03-16 14:50:36 -04:00
Lex Christopherson
c92b937305 docs: clear old files 2026-03-16 12:50:27 -06:00
Jamie McGregor Nelson
d4cf95f204 fix: type errors in claude-import.ts and marketplace-discovery.ts 2026-03-16 14:46:31 -04:00
TÂCHES
a90aa0c8d6 Merge pull request #666 from jeremymcs/fix/v2.19.0-phase1-quick-wins
fix: v2.20 Phase 1+2 — bugs, security, performance, code quality
2026-03-16 12:44:17 -06:00
TÂCHES
0a43e6de4e Merge pull request #671 from gsd-build/fix/665-auto-resume-recovery
fix: auto-mode resume preserves context from paused session
2026-03-16 12:44:08 -06:00
Jamie McGregor Nelson
d85f7b8d82 fix: resolve TypeScript errors in test files
- claude-import-tui.test.ts: add proper mock for ExtensionCommandContext
  with all required properties using type assertions
- marketplace-discovery.test.ts: add explicit check for result.error
  before accessing it to satisfy strict null checking
2026-03-16 14:43:52 -04:00
Jeremy McSpadden
6a46c9df1a fix: resolve browser-tools TypeScript type errors in CI
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
2026-03-16 13:39:14 -05:00
TÂCHES
26b4e483bd Merge pull request #669 from gsd-build/fix/662-task-count-display
fix: clamp task counter to prevent display overflow after loop recovery
2026-03-16 12:36:02 -06: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
TÂCHES
970479d5b4 Merge pull request #668 from gsd-build/fix/663-small-issues
fix: resolve 4 small issues (#663)
2026-03-16 12:35:48 -06:00
Lex Christopherson
38c300fd80 fix: reuse crash recovery infrastructure for pause/resume context (#665)
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>
2026-03-16 12:35:03 -06:00
Jeremy McSpadden
d41338cafb refactor: extract inline build scripts from package.json to files
- Extract copy-resources, copy-themes, copy-export-html from root
  package.json inline node -e commands to proper .cjs script files
- Extract pi-coding-agent copy-assets (356-char inline command) to
  scripts/copy-assets.cjs with readable multi-line formatting
- All scripts use .cjs extension for CommonJS compatibility in ESM
  package context
2026-03-16 13:34:05 -05:00
Jeremy McSpadden
4af3e5b741 fix: move @types/mime-types to devDependencies, align chalk versions
- 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
2026-03-16 13:31:15 -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
Jamie McGregor Nelson
c6e06f344b chore: sync package-lock.json 2026-03-16 14:26:14 -04:00
Lex Christopherson
3399852f6d fix: clamp task counter to prevent "task 5/4" display after loop recovery
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>
2026-03-16 12:26:06 -06:00
TÂCHES
1a856ec109 Merge pull request #667 from gsd-build/fix/664-cancel-stale-async-jobs
fix: cancel stale async jobs after source edits (#664)
2026-03-16 12:25:53 -06:00
Jeremy McSpadden
9c8a24042f feat: convert browser-tools/core.js to TypeScript, add c8 test coverage
- 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.
2026-03-16 13:25:52 -05:00
Lex Christopherson
a58e256e42 fix: resolve 4 small issues reported in #663
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>
2026-03-16 12:23:20 -06:00
Lex Christopherson
d6cf8b4358 fix: add stale async job cancellation heuristic to system prompt (#664)
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>
2026-03-16 12:20:54 -06: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
2966be30cb 2.20.0 2026-03-16 12:16:27 -06:00