gsd-pi 2.76.0-dev.fe143342a → 2.77.0-dev.1d17f366c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -35
- package/dist/claude-cli-check.js +32 -3
- package/dist/cli-web-branch.d.ts +1 -0
- package/dist/cli-web-branch.js +3 -0
- package/dist/cli.js +38 -2
- package/dist/extension-discovery.d.ts +6 -0
- package/dist/extension-discovery.js +37 -0
- package/dist/extension-registry.d.ts +3 -0
- package/dist/extension-sort.d.ts +18 -0
- package/dist/extension-sort.js +114 -0
- package/dist/extension-validator.d.ts +47 -0
- package/dist/extension-validator.js +127 -0
- package/dist/loader.js +35 -7
- package/dist/onboarding.js +45 -0
- package/dist/provider-migrations.d.ts +18 -0
- package/dist/provider-migrations.js +14 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +4 -3
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +78 -59
- package/dist/resources/extensions/cmux/index.js +20 -0
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
- package/dist/resources/extensions/google-search/index.js +3 -375
- package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
- package/dist/resources/extensions/gsd/auto/loop.js +90 -2
- package/dist/resources/extensions/gsd/auto/phases.js +95 -21
- package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +48 -4
- package/dist/resources/extensions/gsd/auto/session.js +18 -1
- package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +115 -17
- package/dist/resources/extensions/gsd/auto-loop.js +1 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +90 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +46 -1
- package/dist/resources/extensions/gsd/auto-start.js +45 -39
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +109 -61
- package/dist/resources/extensions/gsd/auto.js +97 -31
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +27 -1
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +4 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
- package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
- package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
- package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
- package/dist/resources/extensions/gsd/file-lock.js +49 -9
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +2 -0
- package/dist/resources/extensions/gsd/gsd-db.js +90 -30
- package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow.js +212 -9
- package/dist/resources/extensions/gsd/health-widget.js +4 -1
- package/dist/resources/extensions/gsd/journal.js +17 -2
- package/dist/resources/extensions/gsd/key-manager.js +22 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
- package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
- package/dist/resources/extensions/gsd/model-router.js +36 -3
- package/dist/resources/extensions/gsd/notifications.js +30 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +31 -6
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/reports.js +5 -4
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +12 -4
- package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +25 -25
- package/dist/resources/extensions/gsd/token-counter.js +22 -5
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
- package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
- package/dist/resources/extensions/gsd/uok/audit.js +18 -2
- package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +30 -7
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +1 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
- package/dist/resources/extensions/mcp-client/auth.js +10 -1
- package/dist/resources/extensions/mcp-client/index.js +118 -9
- package/dist/resources/extensions/shared/cmux-events.js +12 -0
- package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
- package/dist/resources/skills/create-skill/SKILL.md +2 -2
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/dist/resources/skills/verify-before-complete/SKILL.md +2 -1
- package/dist/resources/skills/write-docs/SKILL.md +2 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
- package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
- package/dist/welcome-screen.js +6 -1
- package/dist/wizard.js +2 -0
- package/package.json +16 -14
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +3 -3
- package/packages/mcp-server/dist/env-writer.d.ts +1 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
- package/packages/mcp-server/dist/env-writer.js +74 -6
- package/packages/mcp-server/dist/env-writer.js.map +1 -1
- package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
- package/packages/mcp-server/dist/remote-questions.js +732 -0
- package/packages/mcp-server/dist/remote-questions.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +95 -10
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/session-manager.d.ts +14 -0
- package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
- package/packages/mcp-server/dist/session-manager.js +49 -1
- package/packages/mcp-server/dist/session-manager.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +9 -3
- package/packages/mcp-server/src/env-writer.test.ts +79 -1
- package/packages/mcp-server/src/env-writer.ts +76 -6
- package/packages/mcp-server/src/mcp-server.test.ts +67 -0
- package/packages/mcp-server/src/readers/readers.test.ts +5 -1
- package/packages/mcp-server/src/remote-questions.test.ts +294 -0
- package/packages/mcp-server/src/remote-questions.ts +916 -0
- package/packages/mcp-server/src/server.ts +118 -16
- package/packages/mcp-server/src/session-manager.ts +43 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +44 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.test.json +19 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +6 -1
- package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +6 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
- package/packages/pi-ai/dist/models/custom.d.ts +38 -0
- package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/custom.js +41 -0
- package/packages/pi-ai/dist/models/custom.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +16 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/package.json +6 -1
- package/packages/pi-ai/src/models/custom.ts +42 -0
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
- package/packages/pi-ai/src/providers/anthropic.ts +9 -3
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
- package/packages/pi-ai/src/providers/simple-options.ts +17 -1
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +7 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
- package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
- package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +24 -8
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +14 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
- package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +14 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +21 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
- package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +6 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
- package/packages/pi-coding-agent/src/core/agent-session.ts +11 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
- package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
- package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +24 -11
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +15 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
- package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +16 -0
- package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +30 -1
- package/packages/pi-coding-agent/src/core/session-manager.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
- package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +21 -0
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +20 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +6 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +27 -0
- package/packages/pi-tui/src/stdin-buffer.ts +26 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +6 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +512 -0
- package/scripts/lib/workspace-manifest.cjs +86 -0
- package/scripts/link-workspace-packages.cjs +5 -17
- package/scripts/postinstall.js +9 -178
- package/src/resources/extensions/claude-code-cli/readiness.ts +4 -3
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +91 -63
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +114 -12
- package/src/resources/extensions/cmux/index.ts +35 -10
- package/src/resources/extensions/github-sync/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/templates.test.ts +59 -0
- package/src/resources/extensions/google-search/extension-manifest.json +5 -4
- package/src/resources/extensions/google-search/index.ts +9 -470
- package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -1
- package/src/resources/extensions/gsd/auto/loop.ts +104 -2
- package/src/resources/extensions/gsd/auto/phases.ts +123 -21
- package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +56 -4
- package/src/resources/extensions/gsd/auto/session.ts +28 -1
- package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
- package/src/resources/extensions/gsd/auto/types.ts +1 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +117 -16
- package/src/resources/extensions/gsd/auto-loop.ts +1 -1
- package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +92 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +40 -1
- package/src/resources/extensions/gsd/auto-start.ts +48 -52
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +122 -68
- package/src/resources/extensions/gsd/auto.ts +105 -35
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
- package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
- package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
- package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
- package/src/resources/extensions/gsd/file-lock.ts +84 -11
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +2 -1
- package/src/resources/extensions/gsd/gsd-db.ts +92 -32
- package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow.ts +259 -10
- package/src/resources/extensions/gsd/health-widget.ts +3 -1
- package/src/resources/extensions/gsd/journal.ts +29 -3
- package/src/resources/extensions/gsd/key-manager.ts +22 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
- package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
- package/src/resources/extensions/gsd/model-router.ts +42 -1
- package/src/resources/extensions/gsd/notifications.ts +27 -15
- package/src/resources/extensions/gsd/pre-execution-checks.ts +33 -7
- package/src/resources/extensions/gsd/preferences-types.ts +8 -0
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/reports.ts +5 -4
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +16 -3
- package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +35 -30
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +238 -4
- package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +161 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +1 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +296 -1
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +337 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +39 -25
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
- package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +42 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +138 -5
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
- package/src/resources/extensions/gsd/token-counter.ts +22 -5
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
- package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
- package/src/resources/extensions/gsd/uok/audit.ts +20 -2
- package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +39 -8
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +23 -3
- package/src/resources/extensions/gsd/worktree-manager.ts +1 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
- package/src/resources/extensions/mcp-client/auth.ts +12 -1
- package/src/resources/extensions/mcp-client/index.ts +129 -10
- package/src/resources/extensions/shared/cmux-events.ts +59 -0
- package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
- package/src/resources/skills/create-skill/SKILL.md +2 -2
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
- package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
- package/src/resources/skills/verify-before-complete/SKILL.md +2 -1
- package/src/resources/skills/write-docs/SKILL.md +2 -1
- package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
- /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_ssgManifest.js +0 -0
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
5
|
import type { NotificationPreferences } from "./types.js";
|
|
6
6
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
7
|
-
import { CmuxClient, emitOsc777Notification, resolveCmuxConfig } from "../cmux/index.js";
|
|
8
7
|
import { sendRemoteNotification } from "../remote-questions/notify.js";
|
|
9
8
|
|
|
10
9
|
export type NotifyLevel = "info" | "success" | "warning" | "error";
|
|
@@ -39,20 +38,33 @@ export function sendDesktopNotification(
|
|
|
39
38
|
|
|
40
39
|
if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
// cmux delivery and desktop delivery are independent — if cmux import or
|
|
42
|
+
// delivery fails, we must still attempt the native desktop notification.
|
|
43
|
+
const runCmux = async () => {
|
|
44
|
+
try {
|
|
45
|
+
const { CmuxClient, emitOsc777Notification, resolveCmuxConfig } = await import("../cmux/index.js");
|
|
46
|
+
const cmux = resolveCmuxConfig(loaded);
|
|
47
|
+
if (cmux.notifications) {
|
|
48
|
+
const delivered = CmuxClient.fromPreferences(loaded).notify(title, message);
|
|
49
|
+
if (delivered) return true;
|
|
50
|
+
emitOsc777Notification(title, message);
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
// cmux unavailable — fall through to desktop notification
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
void runCmux().then((deliveredByCmux) => {
|
|
59
|
+
if (deliveredByCmux) return;
|
|
60
|
+
try {
|
|
61
|
+
const command = buildDesktopNotificationCommand(process.platform, title, message, level);
|
|
62
|
+
if (!command) return;
|
|
63
|
+
execFileSync(command.file, command.args, { timeout: 3000, stdio: "ignore" });
|
|
64
|
+
} catch {
|
|
65
|
+
// Non-fatal — desktop notifications are best-effort
|
|
66
|
+
}
|
|
67
|
+
}).catch(() => {});
|
|
56
68
|
}
|
|
57
69
|
|
|
58
70
|
export function shouldSendDesktopNotification(
|
|
@@ -328,6 +328,16 @@ function extractPathFromAnnotation(raw: string): string {
|
|
|
328
328
|
return backtickMatch[2].trim();
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
// Strip leading/trailing double or single quotes wrapping the whole value.
|
|
332
|
+
// Plan documents sometimes emit `"src/foo.ts"` or `'src/bar.ts'` as input
|
|
333
|
+
// annotations. Stripping the wrapper allows the inner path to be checked
|
|
334
|
+
// correctly instead of producing a false-positive "file not found" error
|
|
335
|
+
// for a literal string with quote characters in it (#3747).
|
|
336
|
+
const quoteMatch = trimmed.match(/^(["'])([^"']+)\1$/);
|
|
337
|
+
if (quoteMatch) {
|
|
338
|
+
return quoteMatch[2].trim();
|
|
339
|
+
}
|
|
340
|
+
|
|
331
341
|
const annotatedMatch = trimmed.match(/^(.+?)\s+[—–-]\s+.+$/);
|
|
332
342
|
if (annotatedMatch) {
|
|
333
343
|
const prefix = annotatedMatch[1].trim();
|
|
@@ -398,13 +408,19 @@ function containsGlobPattern(candidate: string): boolean {
|
|
|
398
408
|
|
|
399
409
|
/**
|
|
400
410
|
* Build a set of files that will be created by tasks up to (but not including) taskIndex.
|
|
411
|
+
* Also includes outputs of completed tasks at any position — a completed task has already
|
|
412
|
+
* run and its outputs are available regardless of sequence position or disk state (#4071).
|
|
401
413
|
* All paths are normalized for consistent comparison.
|
|
402
414
|
*/
|
|
403
415
|
function getExpectedOutputsUpTo(tasks: TaskRow[], taskIndex: number): Set<string> {
|
|
404
416
|
const outputs = new Set<string>();
|
|
405
|
-
for (let i = 0; i <
|
|
406
|
-
|
|
407
|
-
|
|
417
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
418
|
+
const task = tasks[i];
|
|
419
|
+
// Include prior tasks (i < taskIndex) OR completed tasks at any position
|
|
420
|
+
if (i < taskIndex || task.status === "completed") {
|
|
421
|
+
for (const file of task.expected_output) {
|
|
422
|
+
outputs.add(normalizeFilePath(file));
|
|
423
|
+
}
|
|
408
424
|
}
|
|
409
425
|
}
|
|
410
426
|
return outputs;
|
|
@@ -491,13 +507,19 @@ export function checkTaskOrdering(
|
|
|
491
507
|
const results: PreExecutionCheckJSON[] = [];
|
|
492
508
|
|
|
493
509
|
// Build map: normalized file → task index that creates it
|
|
494
|
-
const fileCreators = new Map<string, { taskId: string; index: number; originalPath: string }>();
|
|
510
|
+
const fileCreators = new Map<string, { taskId: string; index: number; originalPath: string; completed: boolean }>();
|
|
495
511
|
for (let i = 0; i < tasks.length; i++) {
|
|
496
512
|
const task = tasks[i];
|
|
497
513
|
for (const file of task.expected_output) {
|
|
498
514
|
const normalizedFile = normalizeFilePath(file);
|
|
499
|
-
|
|
500
|
-
|
|
515
|
+
const existing = fileCreators.get(normalizedFile);
|
|
516
|
+
if (!existing || (!existing.completed && task.status === "completed")) {
|
|
517
|
+
fileCreators.set(normalizedFile, {
|
|
518
|
+
taskId: task.id,
|
|
519
|
+
index: i,
|
|
520
|
+
originalPath: file,
|
|
521
|
+
completed: task.status === "completed",
|
|
522
|
+
});
|
|
501
523
|
}
|
|
502
524
|
}
|
|
503
525
|
}
|
|
@@ -521,7 +543,11 @@ export function checkTaskOrdering(
|
|
|
521
543
|
const creator = fileCreators.get(normalizedFile);
|
|
522
544
|
const absolutePath = resolve(basePath, normalizedFile);
|
|
523
545
|
const existsOnDisk = existsSync(absolutePath);
|
|
524
|
-
if
|
|
546
|
+
// Skip if the creating task has already completed — its output is available
|
|
547
|
+
// regardless of disk state (e.g. file was a temp artifact cleaned up after
|
|
548
|
+
// the task ran, or a replan introduced a new earlier-sequence task that
|
|
549
|
+
// reads this pre-execution output). (#4071)
|
|
550
|
+
if (creator && creator.index > i && !existsOnDisk && !creator.completed) {
|
|
525
551
|
// Task reads file that is created later — impossible ordering
|
|
526
552
|
results.push({
|
|
527
553
|
category: "file",
|
|
@@ -392,6 +392,14 @@ export interface GSDPreferences {
|
|
|
392
392
|
checkpoints?: boolean;
|
|
393
393
|
auto_rollback?: boolean;
|
|
394
394
|
timeout_scale_cap?: number;
|
|
395
|
+
/**
|
|
396
|
+
* Glob patterns for files that are always expected side-effects of any task.
|
|
397
|
+
* Files matching any pattern here are excluded from unexpected-change warnings.
|
|
398
|
+
* Supports standard glob syntax (e.g. `tracking/history/**`, `*.log`).
|
|
399
|
+
* Fixes #4385/#4436 — audit-trail snapshots, build artifacts, and other
|
|
400
|
+
* project-level secondary writes shouldn't require per-task declaration.
|
|
401
|
+
*/
|
|
402
|
+
file_change_allowlist?: string[];
|
|
395
403
|
};
|
|
396
404
|
|
|
397
405
|
|
|
@@ -162,7 +162,20 @@ Preserve the specification's exact terminology, emphasis, and specific framing.
|
|
|
162
162
|
6. For each architectural or pattern decision, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
|
|
163
163
|
7. {{commitInstruction}}
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
166
|
+
|
|
167
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
168
|
+
|
|
169
|
+
- [ ] Written `.gsd/PROJECT.md` (step 2)
|
|
170
|
+
- [ ] Written `.gsd/REQUIREMENTS.md` (step 3)
|
|
171
|
+
- [ ] Written `{{contextPath}}` (step 4)
|
|
172
|
+
- [ ] Called `gsd_plan_milestone` (step 5)
|
|
173
|
+
|
|
174
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
175
|
+
|
|
176
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
177
|
+
|
|
178
|
+
After completing steps 1–7 above, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
|
|
166
179
|
|
|
167
180
|
### Multi-Milestone
|
|
168
181
|
|
|
@@ -234,7 +247,21 @@ For single-milestone projects, do NOT write this file.
|
|
|
234
247
|
|
|
235
248
|
7. {{multiMilestoneCommitInstruction}}
|
|
236
249
|
|
|
237
|
-
|
|
250
|
+
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
251
|
+
|
|
252
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
253
|
+
|
|
254
|
+
- [ ] Written `.gsd/PROJECT.md`
|
|
255
|
+
- [ ] Written `.gsd/REQUIREMENTS.md`
|
|
256
|
+
- [ ] Written the primary milestone `CONTEXT.md`
|
|
257
|
+
- [ ] Called `gsd_plan_milestone` for the primary milestone
|
|
258
|
+
- [ ] Written `.gsd/DISCUSSION-MANIFEST.json` with `gates_completed === total`
|
|
259
|
+
|
|
260
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
261
|
+
|
|
262
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
263
|
+
|
|
264
|
+
After completing every step above, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
|
|
238
265
|
|
|
239
266
|
## Critical Rules
|
|
240
267
|
|
|
@@ -339,7 +339,20 @@ These sections are in addition to whatever other context the discussion surfaced
|
|
|
339
339
|
6. For each architectural or pattern decision made during discussion, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
|
|
340
340
|
7. {{commitInstruction}}
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
343
|
+
|
|
344
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
345
|
+
|
|
346
|
+
- [ ] Written `.gsd/PROJECT.md` (step 2)
|
|
347
|
+
- [ ] Written `.gsd/REQUIREMENTS.md` (step 3)
|
|
348
|
+
- [ ] Written `{{contextPath}}` (step 4)
|
|
349
|
+
- [ ] Called `gsd_plan_milestone` (step 5)
|
|
350
|
+
|
|
351
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
352
|
+
|
|
353
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
354
|
+
|
|
355
|
+
After completing steps 1–7 above, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
|
|
343
356
|
|
|
344
357
|
### Multi-Milestone
|
|
345
358
|
|
|
@@ -418,6 +431,20 @@ For single-milestone projects, do NOT write this file — it is only for multi-m
|
|
|
418
431
|
|
|
419
432
|
7. {{multiMilestoneCommitInstruction}}
|
|
420
433
|
|
|
421
|
-
|
|
434
|
+
### Ready-phrase pre-condition (NON-BYPASSABLE)
|
|
435
|
+
|
|
436
|
+
Before emitting the ready phrase, verify in the CURRENT turn that you have:
|
|
437
|
+
|
|
438
|
+
- [ ] Written `.gsd/PROJECT.md` (Phase 1)
|
|
439
|
+
- [ ] Written `.gsd/REQUIREMENTS.md` (Phase 1)
|
|
440
|
+
- [ ] Written primary-milestone `CONTEXT.md` (Phase 2)
|
|
441
|
+
- [ ] Called `gsd_plan_milestone` for the primary milestone (Phase 2)
|
|
442
|
+
- [ ] Written `.gsd/DISCUSSION-MANIFEST.json` with `gates_completed === total` (Phase 3)
|
|
443
|
+
|
|
444
|
+
If ANY box is unchecked, **STOP**. Do NOT emit the ready phrase. Emit the missing tool calls in this same turn. The system detects missing artifacts and will reject premature ready signals — you will be asked again and retries are capped.
|
|
445
|
+
|
|
446
|
+
Do not announce the ready phrase as something you are "about to" do. Do not narrate "now writing the files" as a substitute for actually writing them. The ready phrase is a post-write signal, not an intent signal.
|
|
447
|
+
|
|
448
|
+
After completing all phases above, say exactly: "Milestone M001 ready." — nothing else. Auto-mode will start automatically.
|
|
422
449
|
|
|
423
450
|
{{inlinedTemplates}}
|
|
@@ -7,9 +7,10 @@ Rules:
|
|
|
7
7
|
2. Read before edit.
|
|
8
8
|
3. Prefer fixing authoritative artifacts over masking warnings.
|
|
9
9
|
4. For missing summaries or UAT files, generate the real artifact from existing slice/task context when possible — do not leave placeholders if you can reconstruct the real content.
|
|
10
|
-
5.
|
|
11
|
-
6.
|
|
12
|
-
7.
|
|
10
|
+
5. For a missing milestone `CONTEXT.md` when the milestone is already past `pre-planning` (phase is `executing`, `summarizing`, `validating-milestone`, or `completing-milestone`): the artifact was skipped during bootstrap and must be reconstructed before execution can resume. Read `PROJECT.md`, `REQUIREMENTS.md`, the milestone's `ROADMAP.md`, and any slice-level context on disk, then write `.gsd/milestones/<milestone-id>/<milestone-id>-CONTEXT.md` with the real context for the scoped milestone. Do not leave a stub — the plan gate will reject it on the next cycle.
|
|
11
|
+
6. After each repair cluster, verify the relevant invariant directly from disk.
|
|
12
|
+
7. When done, rerun `/gsd doctor {{doctorCommandSuffix}}` mentally by ensuring the remaining issue set for this scope is reduced or cleared.
|
|
13
|
+
8. Do NOT query `.gsd/gsd.db` directly via `sqlite3` or `node -e require('better-sqlite3')` — use `gsd_milestone_status` to inspect DB state. Direct access bypasses the WAL connection owned by the engine and can corrupt in-flight writes.
|
|
13
14
|
|
|
14
15
|
## Doctor Summary
|
|
15
16
|
|
|
@@ -27,4 +28,4 @@ Then:
|
|
|
27
28
|
- Repair the unresolved issues in scope
|
|
28
29
|
- Keep changes minimal and targeted
|
|
29
30
|
- If unresolved issues remain outside scope, leave them untouched and mention them briefly
|
|
30
|
-
- End with: "GSD doctor heal complete."
|
|
31
|
+
- End with: "GSD doctor heal complete."
|
|
@@ -15,8 +15,11 @@ Dispatch ALL slices simultaneously using the `subagent` tool in **parallel mode*
|
|
|
15
15
|
1. Call `subagent` with `tasks: [...]` containing one entry per slice below
|
|
16
16
|
2. Wait for ALL subagents to complete
|
|
17
17
|
3. Verify each slice's RESEARCH file was written (check the `.gsd/{{mid}}/` directory)
|
|
18
|
-
4. If
|
|
19
|
-
5.
|
|
18
|
+
4. If a subagent failed to write its RESEARCH file, retry it **once** individually
|
|
19
|
+
5. If it fails a second time, write a partial RESEARCH file for that slice with a `## BLOCKER` section explaining the failure — do NOT retry again
|
|
20
|
+
6. Report which slices completed research and which (if any) needed a blocker note
|
|
21
|
+
|
|
22
|
+
**Important**: Each failed slice gets exactly one retry. After that, write the blocker and move on. Never retry the same slice more than once.
|
|
20
23
|
|
|
21
24
|
## Subagent Prompts
|
|
22
25
|
|
|
@@ -213,6 +213,7 @@ Fix the root cause, not symptoms. When applying a temporary mitigation, label it
|
|
|
213
213
|
- State uncertainty plainly: "Not sure this handles X - testing it." No performed confidence, no hedging paragraphs.
|
|
214
214
|
- All user-visible narration must be grammatical English. Do not emit compressed planner notes like "Need inspect X" or "Maybe read Y first". If it would look acceptable in a commit comment or standup note, it's acceptable here.
|
|
215
215
|
- When debugging, stay curious. Problems are puzzles. Say what's interesting about the failure before reaching for fixes.
|
|
216
|
+
- After completing a task, give a brief completion summary and present 2-4 contextual next-step options as a numbered list (the last option is always "Other"). This reduces cognitive load by letting the user pick rather than formulate what's next. Omit the numbered list when the response must follow a strict output format (JSON, patches, commit messages, structured data).
|
|
216
217
|
|
|
217
218
|
Good narration: "Three existing handlers follow a middleware pattern - using that instead of a custom wrapper."
|
|
218
219
|
Good narration: "Tests pass. Running slice-level verification."
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
* Manual: /gsd export --html
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { readFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
18
18
|
import { join, basename } from 'node:path';
|
|
19
|
+
import { atomicWriteSync } from './atomic-write.js';
|
|
19
20
|
import { gsdRoot } from './paths.js';
|
|
20
21
|
import { formatCost, formatTokenCount } from './metrics.js';
|
|
21
22
|
import { formatDateShort, formatDuration } from '../shared/format-utils.js';
|
|
@@ -83,7 +84,7 @@ export function loadReportsIndex(basePath: string): ReportsIndex | null {
|
|
|
83
84
|
function saveReportsIndex(basePath: string, index: ReportsIndex): void {
|
|
84
85
|
const dir = reportsDir(basePath);
|
|
85
86
|
mkdirSync(dir, { recursive: true });
|
|
86
|
-
|
|
87
|
+
atomicWriteSync(reportsIndexPath(basePath), JSON.stringify(index, null, 2) + '\n', 'utf-8');
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
// ─── Write a report snapshot ──────────────────────────────────────────────────
|
|
@@ -121,7 +122,7 @@ export function writeReportSnapshot(args: WriteReportSnapshotArgs): string {
|
|
|
121
122
|
const filename = `${prefix}-${timestamp}.html`;
|
|
122
123
|
const filePath = join(dir, filename);
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
atomicWriteSync(filePath, args.html, 'utf-8');
|
|
125
126
|
|
|
126
127
|
// Load or init registry
|
|
127
128
|
const existing = loadReportsIndex(args.basePath);
|
|
@@ -170,7 +171,7 @@ export function writeReportSnapshot(args: WriteReportSnapshotArgs): string {
|
|
|
170
171
|
|
|
171
172
|
export function regenerateHtmlIndex(basePath: string, index: ReportsIndex): void {
|
|
172
173
|
const html = buildIndexHtml(index);
|
|
173
|
-
|
|
174
|
+
atomicWriteSync(reportsHtmlIndexPath(basePath), html, 'utf-8');
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
function buildIndexHtml(index: ReportsIndex): string {
|
|
@@ -3,10 +3,26 @@
|
|
|
3
3
|
* Tracks every bash command, file write, and file edit during a unit execution.
|
|
4
4
|
* Evidence is compared against LLM completion claims in evidence-cross-ref.ts.
|
|
5
5
|
*
|
|
6
|
+
* Evidence is persisted to .gsd/safety/evidence-<mid>-<sid>-<tid>.json so it
|
|
7
|
+
* survives session restarts (pause/resume, crash recovery). On unit start,
|
|
8
|
+
* call resetEvidence() then loadEvidenceFromDisk(). On every new tool call,
|
|
9
|
+
* saveEvidenceToDisk() is called automatically by recordToolCall/recordToolResult.
|
|
10
|
+
*
|
|
6
11
|
* Follows the same module-level Map pattern as auto-tool-tracking.ts.
|
|
7
12
|
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
8
13
|
*/
|
|
9
14
|
|
|
15
|
+
import {
|
|
16
|
+
existsSync,
|
|
17
|
+
mkdirSync,
|
|
18
|
+
readFileSync,
|
|
19
|
+
writeFileSync,
|
|
20
|
+
renameSync,
|
|
21
|
+
unlinkSync,
|
|
22
|
+
} from "node:fs";
|
|
23
|
+
import { join, dirname } from "node:path";
|
|
24
|
+
import { randomBytes } from "node:crypto";
|
|
25
|
+
|
|
10
26
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
11
27
|
|
|
12
28
|
export interface BashEvidence {
|
|
@@ -62,6 +78,109 @@ export function getFilePaths(): string[] {
|
|
|
62
78
|
.map(e => e.path);
|
|
63
79
|
}
|
|
64
80
|
|
|
81
|
+
// ─── Persistence (Bug #4385 — evidence must survive session restarts) ────────
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Build the path for the evidence JSON file for a given unit.
|
|
85
|
+
* Lives under .gsd/safety/ which is gitignored and session-scoped.
|
|
86
|
+
*/
|
|
87
|
+
function evidencePath(basePath: string, milestoneId: string, sliceId: string, taskId: string): string {
|
|
88
|
+
return join(basePath, ".gsd", "safety", `evidence-${milestoneId}-${sliceId}-${taskId}.json`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validate that a parsed value is an array of EvidenceEntry objects.
|
|
93
|
+
* Rejects corrupt / schema-mismatch data rather than letting it poison state.
|
|
94
|
+
*/
|
|
95
|
+
function isEvidenceArray(data: unknown): data is EvidenceEntry[] {
|
|
96
|
+
if (!Array.isArray(data)) return false;
|
|
97
|
+
return data.every((e) => {
|
|
98
|
+
if (e === null || typeof e !== "object") return false;
|
|
99
|
+
const rec = e as Record<string, unknown>;
|
|
100
|
+
if (typeof rec.toolCallId !== "string") return false;
|
|
101
|
+
if (typeof rec.timestamp !== "number") return false;
|
|
102
|
+
if (rec.kind === "bash") {
|
|
103
|
+
return (
|
|
104
|
+
typeof rec.command === "string" &&
|
|
105
|
+
typeof rec.exitCode === "number" &&
|
|
106
|
+
typeof rec.outputSnippet === "string"
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (rec.kind === "write" || rec.kind === "edit") {
|
|
110
|
+
return typeof rec.path === "string";
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Persist the current in-memory evidence to disk so it survives a session
|
|
118
|
+
* restart. Called from saveEvidenceToDisk after recordToolCall/recordToolResult.
|
|
119
|
+
* Non-fatal — persistence failures must never break unit execution.
|
|
120
|
+
*/
|
|
121
|
+
export function saveEvidenceToDisk(
|
|
122
|
+
basePath: string,
|
|
123
|
+
milestoneId: string,
|
|
124
|
+
sliceId: string,
|
|
125
|
+
taskId: string,
|
|
126
|
+
): void {
|
|
127
|
+
try {
|
|
128
|
+
const path = evidencePath(basePath, milestoneId, sliceId, taskId);
|
|
129
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
130
|
+
const tmp = `${path}.tmp.${randomBytes(4).toString("hex")}`;
|
|
131
|
+
writeFileSync(tmp, JSON.stringify(unitEvidence, null, 2) + "\n", "utf-8");
|
|
132
|
+
renameSync(tmp, path);
|
|
133
|
+
} catch {
|
|
134
|
+
// Non-fatal — don't let persistence failures break unit execution
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Load persisted evidence from disk into the in-memory array.
|
|
140
|
+
* Call after resetEvidence() on session resume to restore context for a
|
|
141
|
+
* partially-executed unit. If the file does not exist (fresh unit), this
|
|
142
|
+
* is a no-op — getEvidence() will return [] which is correct.
|
|
143
|
+
*/
|
|
144
|
+
export function loadEvidenceFromDisk(
|
|
145
|
+
basePath: string,
|
|
146
|
+
milestoneId: string,
|
|
147
|
+
sliceId: string,
|
|
148
|
+
taskId: string,
|
|
149
|
+
): void {
|
|
150
|
+
try {
|
|
151
|
+
const path = evidencePath(basePath, milestoneId, sliceId, taskId);
|
|
152
|
+
if (!existsSync(path)) return;
|
|
153
|
+
const raw = readFileSync(path, "utf-8");
|
|
154
|
+
const parsed = JSON.parse(raw);
|
|
155
|
+
if (isEvidenceArray(parsed)) {
|
|
156
|
+
unitEvidence = parsed;
|
|
157
|
+
}
|
|
158
|
+
} catch {
|
|
159
|
+
// Non-fatal — corrupt / missing file is treated as empty evidence
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Delete the persisted evidence file for a unit after it has been fully
|
|
165
|
+
* processed. Prevents stale evidence from affecting future retries of
|
|
166
|
+
* the same unit ID.
|
|
167
|
+
*/
|
|
168
|
+
export function clearEvidenceFromDisk(
|
|
169
|
+
basePath: string,
|
|
170
|
+
milestoneId: string,
|
|
171
|
+
sliceId: string,
|
|
172
|
+
taskId: string,
|
|
173
|
+
): void {
|
|
174
|
+
try {
|
|
175
|
+
const path = evidencePath(basePath, milestoneId, sliceId, taskId);
|
|
176
|
+
if (existsSync(path)) {
|
|
177
|
+
unlinkSync(path);
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
// Non-fatal
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
65
184
|
// ─── Recording (called from register-hooks.ts) ─────────────────────────────
|
|
66
185
|
|
|
67
186
|
/**
|
|
@@ -4,15 +4,23 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Uses tasks.expected_output (DB column, populated from per-task ## Expected Output)
|
|
6
6
|
* and tasks.files (from slice PLAN.md - Files: subline) as the expected set.
|
|
7
|
-
* Compares against git diff
|
|
7
|
+
* Compares against `git diff-tree --root --no-commit-id -r --name-only HEAD` after auto-commit.
|
|
8
|
+
* Using diff-tree --root handles initial commits, shallow clones, and merge commits correctly
|
|
9
|
+
* (Bug #4385 — git diff HEAD~1 failed on initial commits).
|
|
8
10
|
*
|
|
9
11
|
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
10
12
|
*/
|
|
11
13
|
|
|
14
|
+
import { createRequire } from "node:module";
|
|
12
15
|
import { execFileSync } from "node:child_process";
|
|
13
16
|
import { normalizePlannedFileReference } from "../files.js";
|
|
14
17
|
import { logWarning } from "../workflow-logger.js";
|
|
15
18
|
|
|
19
|
+
const _require = createRequire(import.meta.url);
|
|
20
|
+
type PicomatchMatcher = (input: string) => boolean;
|
|
21
|
+
type PicomatchFn = (pattern: string, opts?: { dot?: boolean }) => PicomatchMatcher;
|
|
22
|
+
const picomatch = _require("picomatch") as PicomatchFn;
|
|
23
|
+
|
|
16
24
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
17
25
|
|
|
18
26
|
export interface FileViolation {
|
|
@@ -43,6 +51,7 @@ export function validateFileChanges(
|
|
|
43
51
|
basePath: string,
|
|
44
52
|
expectedOutput: string[],
|
|
45
53
|
plannedFiles: string[],
|
|
54
|
+
fileChangeAllowlist: string[] = [],
|
|
46
55
|
): FileChangeAudit | null {
|
|
47
56
|
const allExpected = new Set([...expectedOutput, ...plannedFiles]);
|
|
48
57
|
|
|
@@ -63,8 +72,12 @@ export function validateFileChanges(
|
|
|
63
72
|
),
|
|
64
73
|
);
|
|
65
74
|
|
|
66
|
-
//
|
|
67
|
-
const
|
|
75
|
+
// Build allowlist matchers once (dot: true so patterns like `**/.hidden` work).
|
|
76
|
+
const allowlistMatchers = fileChangeAllowlist.map(p => picomatch(p, { dot: true }));
|
|
77
|
+
const isAllowlisted = (f: string) => allowlistMatchers.some(m => m(f));
|
|
78
|
+
|
|
79
|
+
// Compute symmetric difference, excluding allowlisted files
|
|
80
|
+
const unexpectedFiles = projectFiles.filter(f => !normalizedExpected.has(f) && !isAllowlisted(f));
|
|
68
81
|
const missingFiles = [...normalizedExpected].filter(f => !projectFiles.includes(f));
|
|
69
82
|
|
|
70
83
|
const violations: FileViolation[] = [];
|
|
@@ -25,6 +25,8 @@ export interface SafetyHarnessConfig {
|
|
|
25
25
|
checkpoints: boolean;
|
|
26
26
|
auto_rollback: boolean;
|
|
27
27
|
timeout_scale_cap: number;
|
|
28
|
+
/** Glob patterns for files excluded from unexpected-change warnings (#4385). */
|
|
29
|
+
file_change_allowlist: string[];
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
// ─── Defaults ───────────────────────────────────────────────────────────────
|
|
@@ -39,6 +41,7 @@ const DEFAULTS: SafetyHarnessConfig = {
|
|
|
39
41
|
checkpoints: true,
|
|
40
42
|
auto_rollback: false,
|
|
41
43
|
timeout_scale_cap: 6,
|
|
44
|
+
file_change_allowlist: [],
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
// ─── Public API ─────────────────────────────────────────────────────────────
|
|
@@ -62,6 +65,9 @@ export function resolveSafetyHarnessConfig(
|
|
|
62
65
|
checkpoints: typeof raw.checkpoints === "boolean" ? raw.checkpoints : DEFAULTS.checkpoints,
|
|
63
66
|
auto_rollback: typeof raw.auto_rollback === "boolean" ? raw.auto_rollback : DEFAULTS.auto_rollback,
|
|
64
67
|
timeout_scale_cap: typeof raw.timeout_scale_cap === "number" ? raw.timeout_scale_cap : DEFAULTS.timeout_scale_cap,
|
|
68
|
+
file_change_allowlist: Array.isArray(raw.file_change_allowlist)
|
|
69
|
+
? (raw.file_change_allowlist as unknown[]).filter((p): p is string => typeof p === "string")
|
|
70
|
+
: DEFAULTS.file_change_allowlist,
|
|
65
71
|
};
|
|
66
72
|
}
|
|
67
73
|
|
|
@@ -86,6 +92,9 @@ export {
|
|
|
86
92
|
getFilePaths,
|
|
87
93
|
recordToolCall,
|
|
88
94
|
recordToolResult,
|
|
95
|
+
saveEvidenceToDisk,
|
|
96
|
+
loadEvidenceFromDisk,
|
|
97
|
+
clearEvidenceFromDisk,
|
|
89
98
|
} from "./evidence-collector.js";
|
|
90
99
|
|
|
91
100
|
export type { EvidenceEntry, BashEvidence, FileWriteEvidence, FileEditEvidence } from "./evidence-collector.js";
|