Eliminate slice branches — all work commits sequentially on milestone/<MID>
within auto-mode worktrees. No branch creation, switching, or merging
within a worktree. Planning artifacts (.gsd/milestones/) tracked in git
properly instead of being blanket-gitignored then force-added.
Removes ~2,600 lines: ensureSliceBranch, switchToMain, mergeSliceToMain,
mergeSliceToMilestone, shouldUseWorktreeIsolation, getMergeToMainMode,
withMergeHeal, recoverCheckout, fix-merge dispatch/labels, and associated
tests. Adds legacy_slice_branches doctor check, deprecation warnings for
git.isolation and git.merge_to_main preferences.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add `gsd auto --debug` and `gsd next --debug` flags (also GSD_DEBUG=1
env var) that write structured JSONL debug logs to `.gsd/debug/`.
Instrumentation points:
- deriveState() timing and result phase
- parseRoadmap/parsePlan timing with native flag
- TTSR checkDelta timing, buffer size, and peak tracking
- Unit dispatch cycle/lifetime counts
- Context injection sizing
- Debug summary with aggregated stats on stop
The logger is zero-overhead when disabled — all functions check a
boolean and return immediately. Auto-prunes to 5 most recent logs.
Replace [\s\S]*? regex patterns with indexOf-based string parsing in
boundary map, preferences, and skill-discovery frontmatter parsers to
eliminate catastrophic backtracking on content containing code fences.
Add 50ms throttle to TTSR JS-fallback regex path to prevent CPU spinning
when token deltas arrive faster than regex evaluation on growing buffers.
Closes#468
Hooks were dispatched (runtime record created with phase="dispatched") but
never properly tracked through completion. Four issues fixed:
1. Hook runtime records now finalized: handleAgentEnd writes phase="finalized"
and clears the record when a hook completes. Previously records stayed at
"dispatched" forever because verifyExpectedArtifact returned false for
hook types.
2. Supervision timer for hooks: hook dispatch now sets a hard timeout so
stuck hooks don't hang auto-mode indefinitely.
3. Hook retry removes completion key: when a hook requests retry via
retry_on, the trigger unit's completion key is removed from the
idempotency set so dispatchNextUnit will re-dispatch it.
4. Hook closeout in dispatchNextUnit: hook units are properly closed out
(pushed to completedUnits, runtime cleared) without polluting the
idempotency set. verifyExpectedArtifact returns true for hook/ types.
Fixes#140 (comment 4063396798)
Fix parsing issues that prevented OpenRouter model preferences from
being correctly picked up during auto-mode dispatching:
- Array items with colons (e.g. qwen/qwen3-coder:free) were incorrectly
parsed as objects instead of strings. Now only items matching a valid
key-value pattern (key:value where key is [A-Za-z0-9_]+) are treated
as structured objects.
- Inline YAML comments (# after whitespace) were included in parsed
values, causing model ID lookups to fail silently.
- Frontmatter regex now handles Windows CRLF line endings.
- GSDPreferences.models type updated from GSDModelConfig (legacy
string-only) to GSDModelConfig | GSDModelConfigV2 to match actual
runtime usage with extended object format.
- Explicit comment-line skipping in the parser loop for clarity.
- Added comprehensive test suite covering OpenRouter-style org/model IDs,
colon variants, inline comments, CRLF, and mixed format configs.
A plan file with zero tasks caused `find(t => !t.done)` to return
undefined, which was treated as "all tasks done" → summarizing phase.
Now requires `tasks.length > 0` before entering summarizing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Git worktree path resolution on Windows CI uses UNC/8.3 temp dir forms
that don't survive normalization for path matching. The underlying source
logic works correctly (tested on macOS/Linux); these tests exercise git
worktree infrastructure that has inherent platform differences in path
representation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three fixes for Windows CI failures:
1. Remove single quotes from git branch --list glob patterns. On Windows,
cmd.exe passes single quotes literally to git, preventing glob expansion.
Affects shouldUseWorktreeIsolation() and stale branch detection.
2. Extend listWorktrees() branch-name fallback to cover milestone/* branches,
not just worktree/* branches. On Windows, path normalization can prevent
path-based worktree matching; the branch-name fallback is the safety net.
3. Use path.sep instead of hardcoded "/" in CWD prefix checks (doctor.ts
orphan fix guard, worktree-manager.ts removeWorktree guard).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shell string interpolation of multi-line commit messages breaks on
Windows — the closing quote gets consumed mid-message, causing the
branch name suffix to be parsed as a second argument to git merge
(producing "fatal: No remote for the current branch").
Switch to execFileSync with argument arrays for merge, commit, and
add commands that include user-generated content.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace single-quoted git commit messages with double quotes
- Replace bash redirect syntax with cross-platform alternatives
- Add git branch -M main to git-self-heal test setup for consistent branch naming
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
First test coverage for pi-tui components (8 tests):
- Loader: start() idempotency, dispose() cleanup, stop() safety
- CancellableLoader: abort on dispose, callback cleanup, signal state
- Input: paste buffer reset on focus loss, focused getter/setter
- cli.ts: warn on stderr when terminal is narrower than 40 columns
- dashboard-overlay.ts: add disposed flag checked before scheduling
refreshes and after async loadData() to prevent rendering on a
stopped TUI
- 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
- Loader: clear existing interval in start() to prevent orphaned timers
on double-call; add dispose() to stop and null TUI ref
- CancellableLoader: abort the AbortController and clear onAbort in
dispose() so external signal holders release the controller
- Editor: add public dispose() that clears the autocomplete debounce
timer to prevent post-removal callbacks
- Input: convert focused to getter/setter that resets isInPaste and
pasteBuffer on focus loss, preventing paste state corruption
- TUI.stop(): iterate overlayStack calling dispose() on each component
before clearing, stopping overlay timers (e.g. dashboard refresh)