autoStartTime was never saved to paused-session.json, so cross-session
resume always started with autoStartTime=0 and the widget showed no
elapsed timer. Now saved on pause, restored on resume with Date.now()
fallback for old files.
Also fixes widget layout: elapsed/ETA stays on the header line above
the milestone/branch info line.
The enhanced_verification_* preferences were validated and typed but not
included in mergePreferences(), causing project-level overrides to be
silently ignored. This fix ensures project preferences properly merge
with user-level defaults.
Integrates pre/post-execution checks into auto-mode:
- auto-verification.ts: runEnhancedPreChecks/runEnhancedPostChecks integration
- auto-post-unit.ts: pause control flow when blocking checks fail
- Respects enhanced_verification_strict preference for blocking vs warning
Control flow: blocking failures trigger auto-mode pause for user review.
Adds 3 post-execution checks that run after task completion:
- Import resolution: verifies relative imports resolve to existing files
- Export verification: confirms exported symbols are defined
- Type consistency: validates function return types match declarations
All checks follow the permissive-by-default pattern (R012) - warnings don't block.
Adds 4 pre-execution checks that run before each task:
- File ops review: surfaces create/edit/delete intent for manual review
- Read-before-create guard: fails when plan reads a file before creating it
- Package existence: verifies npm packages exist before install attempts
- Interface contract: warns on mismatched function signatures
Includes preference types and validation for enhanced_verification settings.
The welcome screen lines stopped short on wide terminals because
termWidth was capped at 200 columns. Remove the cap so separator
lines extend to the full terminal width.
Satisfies the CI test requirement for the capture.ts source change.
Two describe blocks:
- Static: verifies the lazy-load pattern is structurally correct in
source (no top-level import, getSharp helper present, null guard present)
- Behavioral: verifies constrainScreenshot returns the raw buffer
unchanged when sharp is null (unavailable platform / bunx)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sharp requires platform-specific native binaries and is unavailable
when running via bunx or on platforms like Raspberry Pi (ARM) where
the prebuilt binary may not exist.
The previous top-level static import caused the browser-tools extension
to crash at load time before any tool was ever called.
Replace the static import with a lazy getSharp() helper that catches
import failures and caches the result. constrainScreenshot returns the
raw buffer unchanged when sharp is unavailable — screenshots remain
functional, just without resizing.
The core bunx extension-loading fix (routing bunx through virtualModules
in loader.ts) belongs upstream in pi-mono and will be submitted there
once the OSS weekend freeze lifts on 2026-04-13.
Related: #3504
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use `git reset --hard <sha>` for rollback instead of `git branch -f`
which fails on checked-out branches and worktrees
- Clear pendingProviderRegistrations after preflush to prevent duplicate
registration when bindCore() runs
- Process Ollama stream content on terminal `done:true` chunks to avoid
truncating trailing assistant text
The system prompt hardcoded ~/.gsd/agent/skills/ paths for bundled skills,
causing ENOENT loops when skills weren't installed at those locations. The
auto-mode loop treated ENOENT as transient and retried indefinitely.
- Replace hardcoded skill paths in system.md with {{bundledSkillsTable}} template
variable, resolved dynamically via resolveSkillReference() at runtime
- Replace hardcoded templates dir path with {{templatesDir}} variable
- Add buildBundledSkillsTable() to system-context.ts — only includes skills
that actually exist on disk
- Export getTemplatesDir() from prompt-loader.ts
- Add Rule 4 to detect-stuck.ts: same ENOENT path seen twice in the sliding
window triggers immediate stuck detection (missing files don't self-heal)
- Add 4 tests for Rule 4 coverage
Closes#3575
- Move new coercion tests to standalone file using node:test +
node:assert/strict (per CONTRIBUTING testing standards)
- Remove tests from legacy complete-slice.test.ts to avoid mixing
test frameworks in the same file
LLMs sometimes pass plain strings instead of the expected object shape
for array fields like filesModified and requires, causing TypeBox
validation to reject the input before the execute function runs. This
adds Type.Union schemas to accept both formats and normalizes strings
to objects with sensible defaults in the execute functions.
Closes#3565