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
|
@@ -13,7 +13,7 @@ import { loadFile, saveFile } from "./files.js";
|
|
|
13
13
|
import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
|
|
14
14
|
import { parseRoadmapSlices } from "./roadmap-slices.js";
|
|
15
15
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
16
|
-
import { buildSkillActivationBlock } from "./auto-prompts.js";
|
|
16
|
+
import { buildDiscussMilestonePrompt, buildSkillActivationBlock } from "./auto-prompts.js";
|
|
17
17
|
import { deriveState } from "./state.js";
|
|
18
18
|
import { invalidateAllCaches } from "./cache.js";
|
|
19
19
|
import { startAutoDetached } from "./auto.js";
|
|
@@ -38,7 +38,7 @@ import { isInheritedRepo } from "./repo-identity.js";
|
|
|
38
38
|
import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
|
|
39
39
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
40
40
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
41
|
-
import { ensurePlanV2Graph } from "./uok/plan-v2.js";
|
|
41
|
+
import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
|
|
42
42
|
import { detectProjectState } from "./detection.js";
|
|
43
43
|
import { showProjectInit, offerMigration } from "./init-wizard.js";
|
|
44
44
|
import { validateDirectory } from "./validate-directory.js";
|
|
@@ -93,24 +93,29 @@ function needsPlanV2Gate(state: GSDState): boolean {
|
|
|
93
93
|
|| state.phase === "completing-milestone";
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
type PlanV2GateDecision = "pass" | "recover-missing-context" | "block";
|
|
97
|
+
|
|
96
98
|
function runPlanV2Gate(
|
|
97
99
|
ctx: ExtensionContext,
|
|
98
100
|
basePath: string,
|
|
99
101
|
state: GSDState,
|
|
100
|
-
):
|
|
102
|
+
): PlanV2GateDecision {
|
|
101
103
|
const prefs = loadEffectiveGSDPreferences()?.preferences;
|
|
102
104
|
const uokFlags = resolveUokFlags(prefs);
|
|
103
|
-
if (!uokFlags.planV2 || !needsPlanV2Gate(state)) return
|
|
105
|
+
if (!uokFlags.planV2 || !needsPlanV2Gate(state)) return "pass";
|
|
104
106
|
const compiled = ensurePlanV2Graph(basePath, state);
|
|
105
107
|
if (!compiled.ok) {
|
|
108
|
+
if (isMissingFinalizedContextResult(compiled)) {
|
|
109
|
+
return "recover-missing-context";
|
|
110
|
+
}
|
|
106
111
|
const reason = compiled.reason ?? "plan-v2 compilation failed";
|
|
107
112
|
ctx.ui.notify(
|
|
108
|
-
`Plan gate failed-closed: ${reason}. Complete plan/discuss artifacts before execution
|
|
113
|
+
`Plan gate failed-closed: ${reason}. Complete plan/discuss artifacts before execution.\n\nIf this keeps happening, try: /gsd doctor heal`,
|
|
109
114
|
"error",
|
|
110
115
|
);
|
|
111
|
-
return
|
|
116
|
+
return "block";
|
|
112
117
|
}
|
|
113
|
-
return
|
|
118
|
+
return "pass";
|
|
114
119
|
}
|
|
115
120
|
|
|
116
121
|
// ─── Commit Instruction Helpers ──────────────────────────────────────────────
|
|
@@ -130,8 +135,20 @@ interface PendingAutoStartEntry {
|
|
|
130
135
|
milestoneId: string; // the milestone being discussed
|
|
131
136
|
step?: boolean; // preserve step mode through discuss → auto transition
|
|
132
137
|
createdAt: number; // timestamp for staleness detection (#3274)
|
|
138
|
+
// #4573: counter for how many times the LLM emitted the ready phrase
|
|
139
|
+
// without writing the required artifacts. Cleared on entry delete/recreate.
|
|
140
|
+
readyRejectCount?: number;
|
|
133
141
|
}
|
|
134
142
|
|
|
143
|
+
// #4573: cap for how many times we nudge the LLM after a premature ready
|
|
144
|
+
// phrase before giving up and asking the user to re-run /gsd.
|
|
145
|
+
const MAX_READY_REJECTS = 2;
|
|
146
|
+
|
|
147
|
+
// #4573: matches the canonical ready phrase the discuss prompt asks the LLM
|
|
148
|
+
// to emit. Accepts any M-prefixed milestone ID (three digits + optional
|
|
149
|
+
// suffix) with optional trailing punctuation.
|
|
150
|
+
const READY_PHRASE_RE = /\bMilestone\s+M\d{3}[A-Z0-9-]*\s+ready\.?/i;
|
|
151
|
+
|
|
135
152
|
const pendingAutoStartMap = new Map<string, PendingAutoStartEntry>();
|
|
136
153
|
|
|
137
154
|
/**
|
|
@@ -279,6 +296,215 @@ export function checkAutoStartAfterDiscuss(): boolean {
|
|
|
279
296
|
return true;
|
|
280
297
|
}
|
|
281
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Extract the concatenated text content from an assistant message, whether it
|
|
301
|
+
* stores content as a string or as an array of text blocks.
|
|
302
|
+
*/
|
|
303
|
+
function extractAssistantText(msg: any): string {
|
|
304
|
+
if (!msg) return "";
|
|
305
|
+
const content = msg.content;
|
|
306
|
+
if (typeof content === "string") return content;
|
|
307
|
+
if (!Array.isArray(content)) return "";
|
|
308
|
+
const parts: string[] = [];
|
|
309
|
+
for (const block of content) {
|
|
310
|
+
if (!block || typeof block !== "object") continue;
|
|
311
|
+
if (block.type === "text" && typeof block.text === "string") parts.push(block.text);
|
|
312
|
+
}
|
|
313
|
+
return parts.join("\n");
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Return true if the assistant message contains any tool-use block.
|
|
318
|
+
*/
|
|
319
|
+
function hasToolUse(msg: any): boolean {
|
|
320
|
+
if (!msg) return false;
|
|
321
|
+
const content = msg.content;
|
|
322
|
+
if (!Array.isArray(content)) return false;
|
|
323
|
+
return content.some((b: any) => b && typeof b === "object" && (b.type === "tool_use" || b.type === "tool-use"));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* #4573 — Detect and recover from the "ready phrase without files" failure mode.
|
|
328
|
+
*
|
|
329
|
+
* When the LLM emits "Milestone {{id}} ready." but has not written CONTEXT.md
|
|
330
|
+
* or ROADMAP.md, `checkAutoStartAfterDiscuss()` silently returns false and the
|
|
331
|
+
* next /gsd invocation loops into the "All milestones complete" warning.
|
|
332
|
+
*
|
|
333
|
+
* This function, called from `handleAgentEnd` after `checkAutoStartAfterDiscuss`
|
|
334
|
+
* returns false, pattern-matches the ready phrase on the last assistant message.
|
|
335
|
+
* If it fired AND neither CONTEXT.md nor ROADMAP.md exists, it:
|
|
336
|
+
* 1. Notifies the user that the signal was rejected.
|
|
337
|
+
* 2. Injects a system message via `pi.sendMessage(..., {triggerTurn:true})`
|
|
338
|
+
* telling the LLM the signal was premature and to emit the writes now.
|
|
339
|
+
* 3. Caps at `MAX_READY_REJECTS` per-entry; beyond that, gives up and asks
|
|
340
|
+
* the user to re-run /gsd.
|
|
341
|
+
*
|
|
342
|
+
* Returns true when a nudge (or give-up) was emitted, signaling the caller to
|
|
343
|
+
* skip `resolveAgentEnd`.
|
|
344
|
+
*/
|
|
345
|
+
export function maybeHandleReadyPhraseWithoutFiles(event: { messages: any[] }): boolean {
|
|
346
|
+
const entry = _getPendingAutoStart();
|
|
347
|
+
if (!entry) return false;
|
|
348
|
+
const { ctx, pi, basePath, milestoneId } = entry;
|
|
349
|
+
|
|
350
|
+
// Gate: last assistant message must contain the ready phrase
|
|
351
|
+
const lastMsg = event.messages[event.messages.length - 1];
|
|
352
|
+
const text = extractAssistantText(lastMsg);
|
|
353
|
+
if (!READY_PHRASE_RE.test(text)) return false;
|
|
354
|
+
|
|
355
|
+
// Gate: artifacts must still be missing — if they exist, the happy path
|
|
356
|
+
// already fired and we have nothing to do.
|
|
357
|
+
const contextFile = resolveMilestoneFile(basePath, milestoneId, "CONTEXT");
|
|
358
|
+
const roadmapFile = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
359
|
+
if (contextFile || roadmapFile) return false;
|
|
360
|
+
|
|
361
|
+
entry.readyRejectCount = (entry.readyRejectCount ?? 0) + 1;
|
|
362
|
+
|
|
363
|
+
if (entry.readyRejectCount > MAX_READY_REJECTS) {
|
|
364
|
+
// Give up: clear state and tell the user to re-run /gsd. Avoids an
|
|
365
|
+
// infinite nudge loop when the LLM never produces the writes.
|
|
366
|
+
pendingAutoStartMap.delete(basePath);
|
|
367
|
+
ctx.ui.notify(
|
|
368
|
+
`Milestone ${milestoneId}: LLM signaled "ready" ${entry.readyRejectCount} times without writing files. ` +
|
|
369
|
+
`Stopping auto-nudge. Run /gsd to try again.`,
|
|
370
|
+
"error",
|
|
371
|
+
);
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
ctx.ui.notify(
|
|
376
|
+
`Milestone ${milestoneId}: "ready" signal rejected — CONTEXT.md and ROADMAP.md are missing. Asking the LLM to complete the writes.`,
|
|
377
|
+
"warning",
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
const nudge =
|
|
381
|
+
`You emitted "Milestone ${milestoneId} ready." but neither ` +
|
|
382
|
+
`.gsd/milestones/${milestoneId}/${milestoneId}-CONTEXT.md nor ` +
|
|
383
|
+
`.gsd/milestones/${milestoneId}/${milestoneId}-ROADMAP.md exists on disk. ` +
|
|
384
|
+
`The ready phrase is a POST-WRITE signal and has been rejected. ` +
|
|
385
|
+
`In this turn: (1) write PROJECT.md, REQUIREMENTS.md, and the milestone ` +
|
|
386
|
+
`CONTEXT.md, (2) call gsd_plan_milestone, then (3) emit the ready phrase. ` +
|
|
387
|
+
`Do not describe these steps — execute them as tool calls. ` +
|
|
388
|
+
`This is retry ${entry.readyRejectCount}/${MAX_READY_REJECTS}; further ` +
|
|
389
|
+
`premature signals will clear the session.`;
|
|
390
|
+
|
|
391
|
+
try {
|
|
392
|
+
pi.sendMessage(
|
|
393
|
+
{ customType: "gsd-ready-no-files", content: nudge, display: false },
|
|
394
|
+
{ triggerTurn: true },
|
|
395
|
+
);
|
|
396
|
+
} catch (e) {
|
|
397
|
+
logWarning("guided", `ready-phrase nudge sendMessage failed: ${(e as Error).message}`);
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* #4573 — Detect and recover from the "announces tool, never calls it" stall.
|
|
405
|
+
*
|
|
406
|
+
* The LLM emits text like "I'll now write the CONTEXT.md file" but the turn
|
|
407
|
+
* ends with zero tool-use blocks. The harness has no post-turn tool-call
|
|
408
|
+
* validation, so the unit promise resolves and the user sees a stalled state.
|
|
409
|
+
*
|
|
410
|
+
* This function, called from `handleAgentEnd`, inspects the last assistant
|
|
411
|
+
* message. If ALL of the following are true, it injects a recovery message:
|
|
412
|
+
* - Text-only (no tool-use blocks)
|
|
413
|
+
* - Contains a commit-intent phrase ("I'll write", "I'll call", etc.)
|
|
414
|
+
* - Auto-mode is active OR a discussion autostart is pending
|
|
415
|
+
* - `emptyTurnRetryCount` is under the cap
|
|
416
|
+
*
|
|
417
|
+
* Per-handler state is held on the `PendingAutoStartEntry` when present, and
|
|
418
|
+
* on a module-level map otherwise. The counter resets on any successful
|
|
419
|
+
* tool-use turn via `resetEmptyTurnCounter`.
|
|
420
|
+
*/
|
|
421
|
+
const emptyTurnCounterByBase = new Map<string, number>();
|
|
422
|
+
const MAX_EMPTY_TURN_RETRIES = 2;
|
|
423
|
+
|
|
424
|
+
// Phrases that indicate the LLM is about to do something but has not yet.
|
|
425
|
+
// Kept tight to avoid flagging legitimate narration like "I'll wait for your answer."
|
|
426
|
+
const COMMIT_INTENT_RE =
|
|
427
|
+
/\b(?:I['’]ll|I will|Next,? I['’]ll|Now I['’]ll|Let me|I['’]m going to|I am going to)\s+(?:now\s+)?(?:write|create|call|invoke|update|add|make|run|execute|generate|produce|emit|compose|implement|save|apply|commit)\b/i;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Reset the empty-turn counter for a basePath after a successful tool-use turn.
|
|
431
|
+
* Called from handleAgentEnd when the last message contains tool_use blocks.
|
|
432
|
+
*/
|
|
433
|
+
export function resetEmptyTurnCounter(basePath?: string): void {
|
|
434
|
+
if (basePath) emptyTurnCounterByBase.delete(basePath);
|
|
435
|
+
else emptyTurnCounterByBase.clear();
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export function maybeHandleEmptyIntentTurn(
|
|
439
|
+
event: { messages: any[] },
|
|
440
|
+
isAuto: boolean,
|
|
441
|
+
): boolean {
|
|
442
|
+
// Gate: only fire when there is system-driven work in flight. Interactive
|
|
443
|
+
// /gsd discuss (user-driven) produces legitimate text-only turns.
|
|
444
|
+
if (!isAuto && pendingAutoStartMap.size === 0) return false;
|
|
445
|
+
|
|
446
|
+
const lastMsg = event.messages[event.messages.length - 1];
|
|
447
|
+
if (!lastMsg) return false;
|
|
448
|
+
if (hasToolUse(lastMsg)) return false;
|
|
449
|
+
|
|
450
|
+
const text = extractAssistantText(lastMsg).trim();
|
|
451
|
+
if (!text) return false;
|
|
452
|
+
|
|
453
|
+
// Skip if the LLM is emitting the ready phrase — that is the ready-no-files
|
|
454
|
+
// path, handled by maybeHandleReadyPhraseWithoutFiles.
|
|
455
|
+
if (READY_PHRASE_RE.test(text)) return false;
|
|
456
|
+
|
|
457
|
+
// Skip if the LLM is clearly handing back to the user. Keep the heuristic
|
|
458
|
+
// tight: a trailing question mark on the last non-empty line is the common
|
|
459
|
+
// signal for "I asked the user a question and stopped."
|
|
460
|
+
const lines = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
461
|
+
const lastLine = lines[lines.length - 1] ?? "";
|
|
462
|
+
if (lastLine.endsWith("?")) return false;
|
|
463
|
+
|
|
464
|
+
// Must contain a commit-intent phrase — this is the stall we care about.
|
|
465
|
+
if (!COMMIT_INTENT_RE.test(text)) return false;
|
|
466
|
+
|
|
467
|
+
// Resolve the target basePath + pi for injection. Prefer the pending
|
|
468
|
+
// autostart entry (discuss flow); otherwise we cannot inject.
|
|
469
|
+
const entry = _getPendingAutoStart();
|
|
470
|
+
if (!entry) return false;
|
|
471
|
+
const { ctx, pi, basePath } = entry;
|
|
472
|
+
|
|
473
|
+
const count = (emptyTurnCounterByBase.get(basePath) ?? 0) + 1;
|
|
474
|
+
emptyTurnCounterByBase.set(basePath, count);
|
|
475
|
+
|
|
476
|
+
if (count > MAX_EMPTY_TURN_RETRIES) {
|
|
477
|
+
ctx.ui.notify(
|
|
478
|
+
`Empty-turn recovery: LLM announced intent ${count} times without calling any tool. ` +
|
|
479
|
+
`Stopping auto-nudge.`,
|
|
480
|
+
"error",
|
|
481
|
+
);
|
|
482
|
+
return false; // let the normal flow resolve/pause the unit
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
ctx.ui.notify(
|
|
486
|
+
`Empty-turn detected: LLM announced intent but called no tool. Prompting it to execute.`,
|
|
487
|
+
"info",
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
const nudge =
|
|
491
|
+
`Your last turn announced an action (e.g. "I'll write…" or "Let me call…") ` +
|
|
492
|
+
`but contained no tool call. The system records zero tool-use blocks for ` +
|
|
493
|
+
`that turn. Execute the announced action NOW as a tool call in this turn. ` +
|
|
494
|
+
`Do not describe it again. Retry ${count}/${MAX_EMPTY_TURN_RETRIES}.`;
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
pi.sendMessage(
|
|
498
|
+
{ customType: "gsd-empty-turn-recovery", content: nudge, display: false },
|
|
499
|
+
{ triggerTurn: true },
|
|
500
|
+
);
|
|
501
|
+
} catch (e) {
|
|
502
|
+
logWarning("guided", `empty-turn nudge sendMessage failed: ${(e as Error).message}`);
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
|
|
282
508
|
/**
|
|
283
509
|
* Extract milestone IDs from PROJECT.md milestone sequence table.
|
|
284
510
|
* Looks for rows like "| M001 | Name | Status |" and extracts the ID column.
|
|
@@ -604,8 +830,13 @@ export async function showHeadlessMilestoneCreation(
|
|
|
604
830
|
// Set pending auto start (auto-mode triggers on "Milestone X ready." via checkAutoStartAfterDiscuss)
|
|
605
831
|
pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, createdAt: Date.now() });
|
|
606
832
|
|
|
607
|
-
// Dispatch
|
|
608
|
-
|
|
833
|
+
// Dispatch as discuss-milestone. The LLM writes PROJECT.md, REQUIREMENTS.md,
|
|
834
|
+
// and CONTEXT.md, then calls gsd_plan_milestone — this is semantically the
|
|
835
|
+
// discuss path, just non-interactive. Using "plan-milestone" here caused
|
|
836
|
+
// model/tool routing to skip discuss-flow tool scoping and
|
|
837
|
+
// `checkAutoStartAfterDiscuss` guardrails that rely on the
|
|
838
|
+
// "discuss-"-prefixed unitType.
|
|
839
|
+
await dispatchWorkflow(pi, prompt, "gsd-run", ctx, "discuss-milestone");
|
|
609
840
|
}
|
|
610
841
|
|
|
611
842
|
|
|
@@ -1352,7 +1583,8 @@ export async function showSmartEntry(
|
|
|
1352
1583
|
logWarning("guided", `STATE.md rebuild failed: ${(err as Error).message}`);
|
|
1353
1584
|
}
|
|
1354
1585
|
|
|
1355
|
-
|
|
1586
|
+
const planV2GateDecision = runPlanV2Gate(ctx, basePath, state);
|
|
1587
|
+
if (planV2GateDecision === "block") return;
|
|
1356
1588
|
|
|
1357
1589
|
if (!state.activeMilestone?.id) {
|
|
1358
1590
|
// Guard: if a discuss session is already in flight, don't re-inject the prompt.
|
|
@@ -1440,6 +1672,23 @@ export async function showSmartEntry(
|
|
|
1440
1672
|
const milestoneId = state.activeMilestone.id;
|
|
1441
1673
|
const milestoneTitle = state.activeMilestone.title;
|
|
1442
1674
|
|
|
1675
|
+
if (planV2GateDecision === "recover-missing-context") {
|
|
1676
|
+
pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId, step: stepMode, createdAt: Date.now() });
|
|
1677
|
+
await dispatchWorkflow(
|
|
1678
|
+
pi,
|
|
1679
|
+
await buildDiscussMilestonePrompt(
|
|
1680
|
+
milestoneId,
|
|
1681
|
+
milestoneTitle,
|
|
1682
|
+
basePath,
|
|
1683
|
+
getStructuredQuestionsAvailability(pi, ctx),
|
|
1684
|
+
),
|
|
1685
|
+
"gsd-discuss",
|
|
1686
|
+
ctx,
|
|
1687
|
+
"discuss-milestone",
|
|
1688
|
+
);
|
|
1689
|
+
return;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1443
1692
|
// ── All milestones complete → New milestone ──────────────────────────
|
|
1444
1693
|
if (state.phase === "complete") {
|
|
1445
1694
|
const choice = await showNextAction(ctx, {
|
|
@@ -108,6 +108,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
|
|
|
108
108
|
let data = initialData;
|
|
109
109
|
let cachedLines: string[] | undefined;
|
|
110
110
|
let refreshInFlight = false;
|
|
111
|
+
let isDisposed = false;
|
|
111
112
|
|
|
112
113
|
const refresh = async () => {
|
|
113
114
|
if (refreshInFlight) return;
|
|
@@ -115,7 +116,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
|
|
|
115
116
|
try {
|
|
116
117
|
data = loadHealthWidgetData(basePath);
|
|
117
118
|
cachedLines = undefined;
|
|
118
|
-
_tui.requestRender();
|
|
119
|
+
if (!isDisposed) _tui.requestRender();
|
|
119
120
|
} catch { /* non-fatal */ } finally {
|
|
120
121
|
refreshInFlight = false;
|
|
121
122
|
}
|
|
@@ -140,6 +141,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
|
|
|
140
141
|
},
|
|
141
142
|
invalidate(): void { cachedLines = undefined; cachedWidth = undefined; },
|
|
142
143
|
dispose(): void {
|
|
144
|
+
isDisposed = true;
|
|
143
145
|
clearInterval(refreshTimer);
|
|
144
146
|
},
|
|
145
147
|
};
|
|
@@ -12,8 +12,18 @@
|
|
|
12
12
|
* - Silent failure: journal writes never throw — absence of events is the failure signal
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
appendFileSync,
|
|
17
|
+
closeSync,
|
|
18
|
+
existsSync,
|
|
19
|
+
mkdirSync,
|
|
20
|
+
openSync,
|
|
21
|
+
readdirSync,
|
|
22
|
+
readFileSync,
|
|
23
|
+
} from "node:fs";
|
|
16
24
|
import { join } from "node:path";
|
|
25
|
+
import { isStaleWrite } from "./auto/turn-epoch.js";
|
|
26
|
+
import { withFileLockSync } from "./file-lock.js";
|
|
17
27
|
import { gsdRoot } from "./paths.js";
|
|
18
28
|
import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
|
|
19
29
|
import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
|
|
@@ -39,7 +49,8 @@ export type JournalEventType =
|
|
|
39
49
|
| "worktree-create-failed"
|
|
40
50
|
| "worktree-skip"
|
|
41
51
|
| "worktree-merge-start"
|
|
42
|
-
| "worktree-merge-failed"
|
|
52
|
+
| "worktree-merge-failed"
|
|
53
|
+
| "artifact-verification-retry";
|
|
43
54
|
|
|
44
55
|
/** A single structured event in the journal. */
|
|
45
56
|
export interface JournalEntry {
|
|
@@ -83,12 +94,27 @@ export interface JournalQueryFilters {
|
|
|
83
94
|
* Never throws — all errors are silently caught.
|
|
84
95
|
*/
|
|
85
96
|
export function emitJournalEvent(basePath: string, entry: JournalEntry): void {
|
|
97
|
+
// Drop writes from a turn superseded by timeout recovery / cancellation.
|
|
98
|
+
// See auto/turn-epoch.ts for the full rationale.
|
|
99
|
+
if (isStaleWrite("journal")) return;
|
|
86
100
|
try {
|
|
87
101
|
const journalDir = join(gsdRoot(basePath), "journal");
|
|
88
102
|
mkdirSync(journalDir, { recursive: true });
|
|
89
103
|
const dateStr = entry.ts.slice(0, 10);
|
|
90
104
|
const filePath = join(journalDir, `${dateStr}.jsonl`);
|
|
91
|
-
|
|
105
|
+
// Ensure file exists so proper-lockfile can acquire a lock against it.
|
|
106
|
+
if (!existsSync(filePath)) closeSync(openSync(filePath, "a"));
|
|
107
|
+
// onLocked: "skip" — journal writes are best-effort. POSIX O_APPEND
|
|
108
|
+
// atomicity still protects small entries; the lock mainly serializes
|
|
109
|
+
// larger writes and gives cross-process exclusivity on platforms where
|
|
110
|
+
// O_APPEND semantics are weaker (Windows).
|
|
111
|
+
withFileLockSync(
|
|
112
|
+
filePath,
|
|
113
|
+
() => {
|
|
114
|
+
appendFileSync(filePath, JSON.stringify(entry) + "\n");
|
|
115
|
+
},
|
|
116
|
+
{ onLocked: "skip" },
|
|
117
|
+
);
|
|
92
118
|
} catch {
|
|
93
119
|
// Silent failure — journal must never break auto-mode
|
|
94
120
|
}
|
|
@@ -51,6 +51,8 @@ export const PROVIDER_REGISTRY: ProviderInfo[] = [
|
|
|
51
51
|
{ id: "xai", label: "xAI (Grok)", category: "llm", envVar: "XAI_API_KEY", dashboardUrl: "console.x.ai" },
|
|
52
52
|
{ id: "openrouter", label: "OpenRouter", category: "llm", envVar: "OPENROUTER_API_KEY", dashboardUrl: "openrouter.ai/keys" },
|
|
53
53
|
{ id: "mistral", label: "Mistral", category: "llm", envVar: "MISTRAL_API_KEY", dashboardUrl: "console.mistral.ai" },
|
|
54
|
+
{ id: "minimax", label: "MiniMax", category: "llm", envVar: "MINIMAX_API_KEY", dashboardUrl: "platform.minimax.io" },
|
|
55
|
+
{ id: "minimax-cn", label: "MiniMax CN", category: "llm", envVar: "MINIMAX_CN_API_KEY", dashboardUrl: "platform.minimax.io" },
|
|
54
56
|
{ id: "ollama-cloud", label: "Ollama Cloud", category: "llm", envVar: "OLLAMA_API_KEY" },
|
|
55
57
|
{ id: "custom-openai", label: "Custom (OpenAI-compat)", category: "llm", envVar: "CUSTOM_OPENAI_API_KEY" },
|
|
56
58
|
{ id: "cerebras", label: "Cerebras", category: "llm", envVar: "CEREBRAS_API_KEY" },
|
|
@@ -486,6 +488,26 @@ const TEST_ENDPOINTS: Record<string, { url: string; method?: string; headers?: (
|
|
|
486
488
|
url: "https://api.mistral.ai/v1/models",
|
|
487
489
|
headers: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
488
490
|
},
|
|
491
|
+
minimax: {
|
|
492
|
+
url: "https://api.minimax.io/anthropic/v1/messages",
|
|
493
|
+
method: "POST",
|
|
494
|
+
headers: (key) => ({
|
|
495
|
+
"x-api-key": key,
|
|
496
|
+
"anthropic-version": "2023-06-01",
|
|
497
|
+
"content-type": "application/json",
|
|
498
|
+
}),
|
|
499
|
+
body: JSON.stringify({ model: "MiniMax-M2.7", max_tokens: 1, messages: [{ role: "user", content: "hi" }] }),
|
|
500
|
+
},
|
|
501
|
+
"minimax-cn": {
|
|
502
|
+
url: "https://api.minimaxi.com/anthropic/v1/messages",
|
|
503
|
+
method: "POST",
|
|
504
|
+
headers: (key) => ({
|
|
505
|
+
"x-api-key": key,
|
|
506
|
+
"anthropic-version": "2023-06-01",
|
|
507
|
+
"content-type": "application/json",
|
|
508
|
+
}),
|
|
509
|
+
body: JSON.stringify({ model: "MiniMax-M2.7", max_tokens: 1, messages: [{ role: "user", content: "hi" }] }),
|
|
510
|
+
},
|
|
489
511
|
openrouter: {
|
|
490
512
|
url: "https://openrouter.ai/api/v1/models",
|
|
491
513
|
headers: (key) => ({ Authorization: `Bearer ${key}` }),
|
|
@@ -23,6 +23,21 @@ import { loadQueueOrder, saveQueueOrder } from "./queue-order.js";
|
|
|
23
23
|
import { deleteMilestone, getMilestone, isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
|
|
24
24
|
import { removeWorktree } from "./worktree-manager.js";
|
|
25
25
|
import { logWarning } from "./workflow-logger.js";
|
|
26
|
+
import { isAutoActive } from "./auto.js";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Writer-side assert for mutations that race with auto-mode's squash merge (#4704).
|
|
30
|
+
* Auto-mode is confirmed not to call parkMilestone/discardMilestone/unparkMilestone
|
|
31
|
+
* internally — these throws only surface invariant violations from new or forgotten
|
|
32
|
+
* call sites, which is the correct failure mode to catch loudly.
|
|
33
|
+
*/
|
|
34
|
+
function assertNotAutoActive(action: string): void {
|
|
35
|
+
if (isAutoActive()) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`${action} cannot run while auto-mode is active. Stop auto-mode first with /gsd stop.`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
26
41
|
|
|
27
42
|
// ─── Park ──────────────────────────────────────────────────────────────────
|
|
28
43
|
|
|
@@ -32,6 +47,7 @@ import { logWarning } from "./workflow-logger.js";
|
|
|
32
47
|
* Returns true if successfully parked, false if milestone not found or already parked.
|
|
33
48
|
*/
|
|
34
49
|
export function parkMilestone(basePath: string, milestoneId: string, reason: string): boolean {
|
|
50
|
+
assertNotAutoActive("park milestone");
|
|
35
51
|
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
36
52
|
if (!mDir || !existsSync(mDir)) return false;
|
|
37
53
|
|
|
@@ -74,6 +90,7 @@ export function parkMilestone(basePath: string, milestoneId: string, reason: str
|
|
|
74
90
|
* Returns true if successfully unparked, false if milestone not found or not parked.
|
|
75
91
|
*/
|
|
76
92
|
export function unparkMilestone(basePath: string, milestoneId: string): boolean {
|
|
93
|
+
assertNotAutoActive("unpark milestone");
|
|
77
94
|
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
78
95
|
if (!mDir || !existsSync(mDir)) return false;
|
|
79
96
|
|
|
@@ -108,6 +125,7 @@ export function unparkMilestone(basePath: string, milestoneId: string): boolean
|
|
|
108
125
|
* Returns true if successfully discarded, false if milestone not found.
|
|
109
126
|
*/
|
|
110
127
|
export function discardMilestone(basePath: string, milestoneId: string): boolean {
|
|
128
|
+
assertNotAutoActive("discard milestone");
|
|
111
129
|
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
112
130
|
if (!mDir || !existsSync(mDir)) return false;
|
|
113
131
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared milestone SUMMARY classifier.
|
|
3
|
+
*
|
|
4
|
+
* SUMMARY presence alone is not enough to prove milestone completion: recovery
|
|
5
|
+
* and blocker paths also write SUMMARY files. Keep this leaf module free of
|
|
6
|
+
* state/auto imports so state derivation, dispatch guards, and recovery can
|
|
7
|
+
* share one definition without cycles.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { splitFrontmatter, parseFrontmatterMap } from "../shared/frontmatter.js";
|
|
11
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
12
|
+
|
|
13
|
+
export type MilestoneSummaryOutcome = "success" | "failure" | "unknown";
|
|
14
|
+
|
|
15
|
+
export function classifyMilestoneSummaryContent(content: string): MilestoneSummaryOutcome {
|
|
16
|
+
const [fmLines] = splitFrontmatter(content);
|
|
17
|
+
const fm = fmLines ? parseFrontmatterMap(fmLines) : null;
|
|
18
|
+
const rawStatus = typeof fm?.status === "string" ? fm.status.trim().toLowerCase() : "";
|
|
19
|
+
if (rawStatus) {
|
|
20
|
+
if (isClosedStatus(rawStatus)) return "success";
|
|
21
|
+
if (["active", "pending", "blocked", "failed", "failure", "incomplete"].includes(rawStatus)) {
|
|
22
|
+
return "failure";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const failureSignal =
|
|
27
|
+
/(?:^|\n)\s*#\s*BLOCKER\b/i.test(content)
|
|
28
|
+
|| /auto-mode recovery failed/i.test(content)
|
|
29
|
+
|| /verification\s+failed/i.test(content)
|
|
30
|
+
|| /(?:^|\n)\s*(?:status|verdict|outcome|result)\s*[:=-]\s*not complete\b/i.test(content);
|
|
31
|
+
if (failureSignal) return "failure";
|
|
32
|
+
return "unknown";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Legacy-compatible terminal check for state derivation.
|
|
37
|
+
* Unknown summaries remain terminal to preserve old handwritten SUMMARY files;
|
|
38
|
+
* explicit failure summaries do not.
|
|
39
|
+
*/
|
|
40
|
+
export function isTerminalMilestoneSummaryContent(content: string): boolean {
|
|
41
|
+
return classifyMilestoneSummaryContent(content) !== "failure";
|
|
42
|
+
}
|
|
@@ -561,6 +561,23 @@ function bareModelId(modelId: string): string {
|
|
|
561
561
|
return modelId.includes("/") ? modelId.split("/").pop()! : modelId;
|
|
562
562
|
}
|
|
563
563
|
|
|
564
|
+
// ─── Provider-specific Tool Limits ─────────────────────────────────────────
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Groq enforces a hard limit of 128 tools per request.
|
|
568
|
+
* Requests exceeding this limit receive a 400 error:
|
|
569
|
+
* "maximum number of items is 128"
|
|
570
|
+
* @see https://console.groq.com/docs/tool-use
|
|
571
|
+
*/
|
|
572
|
+
export const GROQ_MAX_TOOLS = 128;
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Provider IDs that map to the Groq API backend.
|
|
576
|
+
* Used to detect Groq at the GSD routing layer where only the provider string
|
|
577
|
+
* is available (the pi-ai openai-completions adapter is shared across providers).
|
|
578
|
+
*/
|
|
579
|
+
const GROQ_PROVIDER_IDS = new Set(["groq"]);
|
|
580
|
+
|
|
564
581
|
// ─── Tool Compatibility Filter (ADR-005 Phase 3) ───────────────────────────
|
|
565
582
|
|
|
566
583
|
/**
|
|
@@ -588,10 +605,17 @@ export function isToolCompatibleWithProvider(
|
|
|
588
605
|
/**
|
|
589
606
|
* Filter a list of tool names to only those compatible with a provider.
|
|
590
607
|
* Used by the routing pipeline to adjust tool sets when switching providers.
|
|
608
|
+
*
|
|
609
|
+
* @param toolNames - The full list of active tool names to filter.
|
|
610
|
+
* @param providerApi - The pi-ai API string (e.g. "openai-completions").
|
|
611
|
+
* @param provider - Optional provider ID (e.g. "groq"). Used to apply
|
|
612
|
+
* provider-specific limits that can't be expressed as API-level capabilities
|
|
613
|
+
* (e.g. Groq's 128-tool hard limit on the shared openai-completions adapter).
|
|
591
614
|
*/
|
|
592
615
|
export function filterToolsForProvider(
|
|
593
616
|
toolNames: string[],
|
|
594
617
|
providerApi: string,
|
|
618
|
+
provider?: string,
|
|
595
619
|
): { compatible: string[]; filtered: string[] } {
|
|
596
620
|
const providerCaps = getProviderCapabilities(providerApi);
|
|
597
621
|
|
|
@@ -611,6 +635,17 @@ export function filterToolsForProvider(
|
|
|
611
635
|
}
|
|
612
636
|
}
|
|
613
637
|
|
|
638
|
+
// Groq enforces a hard limit of 128 tools per request (#4376).
|
|
639
|
+
// Trim the compatible list to GROQ_MAX_TOOLS and move the excess to filtered.
|
|
640
|
+
if (provider && GROQ_PROVIDER_IDS.has(provider) && compatible.length > GROQ_MAX_TOOLS) {
|
|
641
|
+
const trimmed = compatible.splice(GROQ_MAX_TOOLS);
|
|
642
|
+
filtered.push(...trimmed);
|
|
643
|
+
console.warn(
|
|
644
|
+
`[gsd] Groq tool limit: ${compatible.length + trimmed.length} tools active but Groq allows at most ${GROQ_MAX_TOOLS}. ` +
|
|
645
|
+
`Trimming to the first ${GROQ_MAX_TOOLS} tools. Removed: ${trimmed.join(", ")}`,
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
614
649
|
return { compatible, filtered };
|
|
615
650
|
}
|
|
616
651
|
|
|
@@ -620,11 +655,17 @@ export function filterToolsForProvider(
|
|
|
620
655
|
*
|
|
621
656
|
* This is a hard filter only — it removes tools that would fail at the
|
|
622
657
|
* provider level. It does NOT remove tools based on soft heuristics.
|
|
658
|
+
*
|
|
659
|
+
* @param activeToolNames - The full list of currently active tool names.
|
|
660
|
+
* @param selectedModelApi - The pi-ai API string for the selected model.
|
|
661
|
+
* @param provider - Optional provider ID (e.g. "groq") for provider-specific
|
|
662
|
+
* limits beyond what the API-level capability profile expresses.
|
|
623
663
|
*/
|
|
624
664
|
export function adjustToolSet(
|
|
625
665
|
activeToolNames: string[],
|
|
626
666
|
selectedModelApi: string,
|
|
667
|
+
provider?: string,
|
|
627
668
|
): { toolNames: string[]; removedTools: string[] } {
|
|
628
|
-
const { compatible, filtered } = filterToolsForProvider(activeToolNames, selectedModelApi);
|
|
669
|
+
const { compatible, filtered } = filterToolsForProvider(activeToolNames, selectedModelApi, provider);
|
|
629
670
|
return { toolNames: compatible, removedTools: filtered };
|
|
630
671
|
}
|