gsd-pi 2.71.0 → 2.72.0-dev.de4c4b3
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 +57 -17
- package/dist/cli.js +29 -3
- package/dist/headless-events.d.ts +2 -0
- package/dist/headless-events.js +7 -0
- package/dist/headless.js +16 -3
- package/dist/mcp-server.js +40 -17
- package/dist/provider-migrations.d.ts +10 -0
- package/dist/provider-migrations.js +12 -0
- package/dist/resource-loader.js +139 -13
- package/dist/resources/GSD-WORKFLOW.md +1 -1
- package/dist/resources/agents/debugger.md +58 -0
- package/dist/resources/agents/doc-writer.md +43 -0
- package/dist/resources/agents/git-ops.md +56 -0
- package/dist/resources/agents/javascript-pro.md +46 -271
- package/dist/resources/agents/planner.md +55 -0
- package/dist/resources/agents/refactorer.md +47 -0
- package/dist/resources/agents/reviewer.md +48 -0
- package/dist/resources/agents/security.md +59 -0
- package/dist/resources/agents/tester.md +50 -0
- package/dist/resources/agents/typescript-pro.md +41 -235
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +113 -10
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +5 -1
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
- package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
- package/dist/resources/extensions/gsd/auto-start.js +34 -7
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +56 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
- package/dist/resources/extensions/gsd/commands/context.js +15 -6
- package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
- package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
- package/dist/resources/extensions/gsd/error-classifier.js +5 -2
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/gate-registry.js +208 -0
- package/dist/resources/extensions/gsd/gsd-db.js +41 -0
- package/dist/resources/extensions/gsd/guided-flow.js +5 -10
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +11 -12
- package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
- package/dist/resources/extensions/gsd/notification-store.js +56 -5
- package/dist/resources/extensions/gsd/notification-widget.js +5 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
- package/dist/resources/extensions/gsd/prompt-validation.js +126 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/dist/resources/extensions/gsd/session-model-override.js +25 -0
- package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
- package/dist/resources/extensions/gsd/state.js +9 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +52 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +51 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +4 -1
- package/dist/resources/extensions/ollama/index.js +13 -5
- package/dist/resources/extensions/shared/gsd-phase-state.js +35 -0
- package/dist/resources/extensions/subagent/agents.js +8 -0
- package/dist/resources/extensions/subagent/index.js +17 -0
- package/dist/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/startup-model-validation.d.ts +0 -1
- package/dist/startup-model-validation.js +6 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/server.d.ts +12 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +90 -42
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -12
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/server.ts +110 -38
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +32 -12
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +7 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
- package/packages/pi-ai/src/providers/anthropic.ts +8 -4
- package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -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 +2 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +55 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +57 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +24 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -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 +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +43 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +7 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.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 +4 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
- package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
- package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +83 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +60 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/agents/debugger.md +58 -0
- package/src/resources/agents/doc-writer.md +43 -0
- package/src/resources/agents/git-ops.md +56 -0
- package/src/resources/agents/javascript-pro.md +46 -271
- package/src/resources/agents/planner.md +55 -0
- package/src/resources/agents/refactorer.md +47 -0
- package/src/resources/agents/reviewer.md +48 -0
- package/src/resources/agents/security.md +59 -0
- package/src/resources/agents/tester.md +50 -0
- package/src/resources/agents/typescript-pro.md +41 -235
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +122 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +189 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +45 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
- package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
- package/src/resources/extensions/gsd/auto-start.ts +41 -7
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +72 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -5
- package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
- package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
- package/src/resources/extensions/gsd/error-classifier.ts +5 -2
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/gate-registry.ts +251 -0
- package/src/resources/extensions/gsd/gsd-db.ts +51 -0
- package/src/resources/extensions/gsd/guided-flow.ts +5 -10
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/metrics.ts +12 -1
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +11 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
- package/src/resources/extensions/gsd/notification-store.ts +54 -5
- package/src/resources/extensions/gsd/notification-widget.ts +5 -14
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
- package/src/resources/extensions/gsd/prompt-validation.ts +157 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +3 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/src/resources/extensions/gsd/session-model-override.ts +36 -0
- package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
- package/src/resources/extensions/gsd/state.ts +13 -2
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/complete-slice-gate-closure.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/gate-registry.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prompt-system-gate-coverage.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +63 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +4 -1
- package/src/resources/extensions/gsd/types.ts +26 -0
- package/src/resources/extensions/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/extensions/shared/gsd-phase-state.ts +42 -0
- package/src/resources/extensions/shared/tests/gsd-phase-state.test.ts +48 -0
- package/src/resources/extensions/subagent/agents.ts +10 -0
- package/src/resources/extensions/subagent/index.ts +18 -0
- package/src/resources/extensions/subagent/tests/agents-conflicts.test.ts +33 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_ssgManifest.js +0 -0
|
@@ -22,6 +22,8 @@ A researcher explored the codebase and a planner decomposed the work — you are
|
|
|
22
22
|
|
|
23
23
|
{{slicePlanExcerpt}}
|
|
24
24
|
|
|
25
|
+
{{gatesToClose}}
|
|
26
|
+
|
|
25
27
|
## Backing Source Artifacts
|
|
26
28
|
- Slice plan: `{{planPath}}`
|
|
27
29
|
- Task plan source: `{{taskPlanPath}}`
|
|
@@ -32,29 +34,30 @@ Then:
|
|
|
32
34
|
0. Narrate step transitions, key implementation decisions, and verification outcomes as you work. Keep it terse — one line between tool-call clusters, not between every call — but write complete sentences in user-facing prose, not shorthand notes or scratchpad fragments.
|
|
33
35
|
1. {{skillActivation}} Follow any activated skills before writing code. If no skills match this task, skip this step.
|
|
34
36
|
2. Execute the steps in the inlined task plan, adapting minor local mismatches when the surrounding code differs from the planner's snapshot
|
|
35
|
-
3.
|
|
36
|
-
4.
|
|
37
|
-
5.
|
|
37
|
+
3. Before any `Write` that creates an artifact or output file, check whether that path already exists. If it does, read it first and decide whether the work is already done, should be extended, or truly needs replacement. "Create" in the plan does **not** mean the file is missing — a prior session may already have started it.
|
|
38
|
+
4. Build the real thing. If the task plan says "create login endpoint", build an endpoint that actually authenticates against a real store, not one that returns a hardcoded success response. If the task plan says "create dashboard page", build a page that renders real data from the API, not a component with hardcoded props. Stubs and mocks are for tests, not for the shipped feature.
|
|
39
|
+
5. Write or update tests as part of execution — tests are verification, not an afterthought. If the slice plan defines test files in its Verification section and this is the first task, create them (they should initially fail).
|
|
40
|
+
6. When implementing non-trivial runtime behavior (async flows, API boundaries, background processes, error paths), add or preserve agent-usable observability. Skip this for simple changes where it doesn't apply.
|
|
38
41
|
|
|
39
42
|
**Background process rule:** Never use bare `command &` to run background processes. The shell's `&` operator leaves stdout/stderr attached to the parent, which causes the Bash tool to hang indefinitely waiting for those streams to close. Always redirect output before backgrounding:
|
|
40
43
|
- Correct: `command > /dev/null 2>&1 &` or `nohup command > /dev/null 2>&1 &`
|
|
41
44
|
- Example: `python -m http.server 8080 > /dev/null 2>&1 &` (NOT `python -m http.server 8080 &`)
|
|
42
45
|
- Preferred: use the `bg_shell` tool if available — it manages process lifecycle correctly without stream-inheritance issues
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
7. If the task plan includes a **Failure Modes** section (Q5), implement the error/timeout/malformed handling specified. Verify each dependency's failure path is handled. Skip if the section is absent.
|
|
47
|
+
8. If the task plan includes a **Load Profile** section (Q6), implement protections for the identified 10x breakpoint (connection pooling, rate limiting, pagination, etc.). Skip if absent.
|
|
48
|
+
9. If the task plan includes a **Negative Tests** section (Q7), write the specified negative test cases alongside the happy-path tests — malformed inputs, error paths, and boundary conditions. Skip if absent.
|
|
49
|
+
10. Verify must-haves are met by running concrete checks (tests, commands, observable behaviors)
|
|
50
|
+
11. Run the slice-level verification checks defined in the slice plan's Verification section. Track which pass. On the final task of the slice, all must pass before marking done. On intermediate tasks, partial passes are expected — note which ones pass in the summary.
|
|
51
|
+
12. After the verification gate runs (you'll see gate results in stderr/notify output), populate the `## Verification Evidence` table in your task summary with the check results. Use the `formatEvidenceTable` format: one row per check with command, exit code, verdict (✅ pass / ❌ fail), and duration. If no verification commands were discovered, note that in the section.
|
|
52
|
+
13. If the task touches UI, browser flows, DOM behavior, or user-visible web state:
|
|
50
53
|
- exercise the real flow in the browser
|
|
51
54
|
- prefer `browser_batch` when the next few actions are obvious and sequential
|
|
52
55
|
- prefer `browser_assert` for explicit pass/fail verification of the intended outcome
|
|
53
56
|
- use `browser_diff` when an action's effect is ambiguous
|
|
54
57
|
- use console/network/dialog diagnostics when validating async, stateful, or failure-prone UI
|
|
55
58
|
- record verification in terms of explicit checks passed/failed, not only prose interpretation
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
14. If the task plan includes an Observability Impact section, verify those signals directly. Skip this step if the task plan omits the section.
|
|
60
|
+
15. **If execution is running long or verification fails:**
|
|
58
61
|
|
|
59
62
|
**Context budget:** You have approximately **{{verificationBudget}}** reserved for verification context. If you've used most of your context and haven't finished all steps, stop implementing and prioritize writing the task summary with clear notes on what's done and what remains. A partial summary that enables clean resumption is more valuable than one more half-finished step with no documentation. Never sacrifice summary quality for one more implementation step.
|
|
60
63
|
|
|
@@ -65,13 +68,13 @@ Then:
|
|
|
65
68
|
- Distinguish "I know" from "I assume." Observable facts (the error says X) are strong evidence. Assumptions (this library should work this way) need verification.
|
|
66
69
|
- Know when to stop. If you've tried 3+ fixes without progress, your mental model is probably wrong. Stop. List what you know for certain. List what you've ruled out. Form fresh hypotheses from there.
|
|
67
70
|
- Don't fix symptoms. Understand *why* something fails before changing code. A test that passes after a change you don't understand is luck, not a fix.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
16. **Blocker discovery:** If execution reveals that the remaining slice plan is fundamentally invalid — not just a bug or minor deviation, but a plan-invalidating finding like a wrong API, missing capability, or architectural mismatch — set `blocker_discovered: true` in the task summary frontmatter and describe the blocker clearly in the summary narrative. Do NOT set `blocker_discovered: true` for ordinary debugging, minor deviations, or issues that can be fixed within the current task or the remaining plan. This flag triggers an automatic replan of the slice.
|
|
72
|
+
17. If you made an architectural, pattern, library, or observability decision during this task that downstream work should know about, append it to `.gsd/DECISIONS.md` (read the template at `~/.gsd/agent/extensions/gsd/templates/decisions.md` if the file doesn't exist yet). Not every task produces decisions — only append when a meaningful choice was made.
|
|
73
|
+
18. If you discover a non-obvious rule, recurring gotcha, or useful pattern during execution, append it to `.gsd/KNOWLEDGE.md`. Only add entries that would save future agents from repeating your investigation. Don't add obvious things.
|
|
74
|
+
19. Read the template at `~/.gsd/agent/extensions/gsd/templates/task-summary.md`
|
|
75
|
+
20. Use that template to prepare the completion content you will pass to `gsd_complete_task` using the camelCase fields `milestoneId`, `sliceId`, `taskId`, `oneLiner`, `narrative`, `verification`, and `verificationEvidence`. Do **not** manually write `{{taskSummaryPath}}` — the DB-backed tool is the canonical write path and renders the summary file for you.
|
|
76
|
+
21. Call `gsd_complete_task` with milestoneId, sliceId, taskId, and the completion fields derived from the template. This is your final required step — do NOT manually edit PLAN.md checkboxes. The tool marks the task complete, updates the DB, renders `{{taskSummaryPath}}`, and updates PLAN.md automatically.
|
|
77
|
+
22. Do not run git commands — the system reads your task summary after completion and creates a meaningful commit from it (type inferred from title, message from your one-liner, key files from frontmatter). Write a clear, specific one-liner in the summary — it becomes the commit message.
|
|
75
78
|
|
|
76
79
|
All work stays in your working directory: `{{workingDirectory}}`.
|
|
77
80
|
|
|
@@ -32,6 +32,8 @@ Ask **1–3 questions per round**. Keep each question focused on one of:
|
|
|
32
32
|
- **The biggest technical unknowns / risks** — what could fail, what hasn't been proven
|
|
33
33
|
- **What external systems/services this touches** — APIs, databases, third-party services
|
|
34
34
|
|
|
35
|
+
**Never fabricate or simulate user input.** Never generate fake transcript markers like `[User]`, `[Human]`, or `User:`. Ask one question round, then wait for the user's actual response before continuing.
|
|
36
|
+
|
|
35
37
|
**If `{{structuredQuestionsAvailable}}` is `true`:** use `ask_user_questions` for each round. 1–3 questions per call, each as a separate question object. Keep option labels short (3–5 words). Always include a freeform "Other / let me explain" option. When the user picks that option or writes a long freeform answer, switch to plain text follow-up for that thread before resuming structured questions. **IMPORTANT: Call `ask_user_questions` exactly once per turn. Never make multiple calls with the same or overlapping questions — wait for the user's response before asking the next round.**
|
|
36
38
|
|
|
37
39
|
**If `{{structuredQuestionsAvailable}}` is `false`:** ask questions in plain text. Keep each round to 1–3 focused questions. Wait for answers before asking the next round.
|
|
@@ -22,6 +22,8 @@ Do **not** go deep — just enough that your questions reflect what's actually t
|
|
|
22
22
|
|
|
23
23
|
### Question rounds
|
|
24
24
|
|
|
25
|
+
**Never fabricate or simulate user input.** Never generate fake transcript markers like `[User]`, `[Human]`, or `User:`. Ask one question round, then wait for the user's actual response before continuing.
|
|
26
|
+
|
|
25
27
|
**If `{{structuredQuestionsAvailable}}` is `true`:** Ask **1–3 questions per round** using `ask_user_questions`. **Call `ask_user_questions` exactly once per turn — never make multiple calls with the same or overlapping questions. Wait for the user's response before asking the next round.**
|
|
26
28
|
**If `{{structuredQuestionsAvailable}}` is `false`:** Ask **1–3 questions per round** in plain text. Number them and wait for the user's response before asking the next round.
|
|
27
29
|
Keep each question focused on one of:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Resume interrupted work. Find the continue file (`{{sliceId}}-CONTINUE.md` or `continue.md`) in slice {{sliceId}} of milestone {{milestoneId}}, read it, and use it as the recovery contract for where to pick up. Do **not** delete the continue file immediately. Keep it until the task is successfully completed or you have written a newer summary/continue artifact that clearly supersedes it. If the resumed attempt fails again, update or replace the continue file so no recovery context is lost. {{skillActivation}}
|
|
1
|
+
Resume interrupted work. Find the continue file (`{{sliceId}}-CONTINUE.md` or `continue.md`) in slice {{sliceId}} of milestone {{milestoneId}}, read it, and use it as the recovery contract for where to pick up. Before you create any expected artifact or output file, check whether it already exists and read it first — a prior session may already have started or completed that work. Do **not** delete the continue file immediately. Keep it until the task is successfully completed or you have written a newer summary/continue artifact that clearly supersedes it. If the resumed attempt fails again, update or replace the continue file so no recovery context is lost. {{skillActivation}}
|
|
@@ -18,6 +18,7 @@ Say exactly: "What do you want to add?" — nothing else. Wait for the user's an
|
|
|
18
18
|
## Discussion Phase
|
|
19
19
|
|
|
20
20
|
After they describe it, your job is to understand the new work deeply enough to create context files that a future planning session can use.
|
|
21
|
+
Never fabricate or simulate user input during this discussion. Never generate fake transcript markers like `[User]`, `[Human]`, or `User:`. Ask one question round, then wait for the user's actual response before continuing.
|
|
21
22
|
|
|
22
23
|
**If the user provides a file path or pastes a large document** (spec, design doc, product plan, chat export), read it fully before asking questions. Use it as the starting point — don't ask them to re-explain what's already in the document. Your questions should fill gaps and resolve ambiguities the document doesn't cover.
|
|
23
24
|
|
|
@@ -36,11 +37,11 @@ Don't go deep — just enough that your next question reflects what's actually t
|
|
|
36
37
|
- How the new work relates to existing milestones — overlap, dependencies, prerequisites
|
|
37
38
|
- If `.gsd/REQUIREMENTS.md` exists: which unmet Active or Deferred requirements this queued work advances
|
|
38
39
|
|
|
39
|
-
**Then use ask_user_questions** to dig into gray areas — scope boundaries, proof expectations, integration choices, tech preferences when they materially matter, and what's in vs out. 1-3 questions per round.
|
|
40
|
+
**Then use ask_user_questions** to dig into gray areas — scope boundaries, proof expectations, integration choices, tech preferences when they materially matter, and what's in vs out. Ask 1-3 questions per round, then wait for the user's response before asking the next round.
|
|
40
41
|
|
|
41
42
|
If a `GSD Skill Preferences` block is present in system context, use it to decide which skills to load and follow during discuss/planning work, but do not let it override the required discuss flow or artifact requirements.
|
|
42
43
|
|
|
43
|
-
**Self-regulate:** Do **not** ask a meta "ready to queue?" question after every round. Keep going until you have enough depth to write the context well, then use a single wrap-up prompt if needed.
|
|
44
|
+
**Self-regulate:** Do **not** ask a meta "ready to queue?" question after every round. Keep going until you have enough depth to write the context well, then use a single wrap-up prompt if needed. Do not infer permission to continue from silence or from partial prior answers — each new round requires an actual user response.
|
|
44
45
|
|
|
45
46
|
## Existing Milestone Awareness
|
|
46
47
|
|
|
@@ -35,6 +35,7 @@ GSD ships with bundled skills. Load the relevant skill file with the `read` tool
|
|
|
35
35
|
- Read before edit.
|
|
36
36
|
- Reproduce before fix when possible.
|
|
37
37
|
- Work is not done until the relevant verification has passed.
|
|
38
|
+
- **Never fabricate, simulate, or role-play user responses.** Never generate markers like `[User]`, `[Human]`, `User:`, or similar to represent user input inside your own output. Ask one question round (1-3 questions), then stop and wait for the user's actual response before continuing. If `ask_user_questions` is available, treat its returned response as the only valid structured user input for that round.
|
|
38
39
|
- Never print, echo, log, or restate secrets or credentials. Report only key names and applied/skipped status.
|
|
39
40
|
- Never ask the user to edit `.env` files or set secrets manually. Use `secure_env_collect`.
|
|
40
41
|
- In enduring files, write current state only unless the file is explicitly historical.
|
|
@@ -18,6 +18,8 @@ All relevant context has been preloaded below — the roadmap, all slice summari
|
|
|
18
18
|
|
|
19
19
|
{{inlinedContext}}
|
|
20
20
|
|
|
21
|
+
{{gatesToEvaluate}}
|
|
22
|
+
|
|
21
23
|
## Execution Protocol
|
|
22
24
|
|
|
23
25
|
### Step 1 — Dispatch Parallel Reviewers
|
|
@@ -31,7 +33,7 @@ Prompt: "Review milestone {{milestoneId}} requirements coverage. Working directo
|
|
|
31
33
|
Prompt: "Review milestone {{milestoneId}} cross-slice integration. Working directory: {{workingDirectory}}. Read `{{roadmapPath}}` and find the boundary map (produces/consumes contracts). For each boundary, check that the producing slice's SUMMARY confirms it produced the artifact, and the consuming slice's SUMMARY confirms it consumed it. Output a markdown table: Boundary | Producer Summary | Consumer Summary | Status. End with a one-line verdict: PASS if all boundaries honored, NEEDS-ATTENTION if any gaps."
|
|
32
34
|
|
|
33
35
|
**Reviewer C — Assessment & Acceptance Criteria**
|
|
34
|
-
Prompt: "Review milestone {{milestoneId}} assessment evidence and acceptance criteria. Working directory: {{workingDirectory}}. Read `.gsd/{{milestoneId}}/CONTEXT.md` for acceptance criteria. Check for ASSESSMENT files in each slice directory. Verify each acceptance criterion maps to either a passing assessment result or clear SUMMARY evidence. Output a checklist
|
|
36
|
+
Prompt: "Review milestone {{milestoneId}} assessment evidence and acceptance criteria. Working directory: {{workingDirectory}}. Read `.gsd/{{milestoneId}}/CONTEXT.md` for acceptance criteria. Check for ASSESSMENT files in each slice directory. Verify each acceptance criterion maps to either a passing assessment result or clear SUMMARY evidence. Then review the inlined milestone verification classes from planning. For each non-empty planned class, output a markdown table: Class | Planned Check | Evidence | Verdict. Use the exact class names `Contract`, `Integration`, `Operational`, and `UAT` whenever those classes are present. If no verification classes were planned, say that explicitly. Output two sections: `Acceptance Criteria` with a checklist `[ ] Criterion | Evidence`, and `Verification Classes` with the table. End with a one-line verdict: PASS if all criteria and verification classes are covered, NEEDS-ATTENTION if gaps exist."
|
|
35
37
|
|
|
36
38
|
### Step 2 — Synthesize Findings
|
|
37
39
|
|
|
@@ -70,6 +72,7 @@ reviewers: 3
|
|
|
70
72
|
```
|
|
71
73
|
|
|
72
74
|
Call `gsd_validate_milestone` with the camelCase fields `milestoneId`, `verdict`, `remediationRound`, `successCriteriaChecklist`, `sliceDeliveryAudit`, `crossSliceIntegration`, `requirementCoverage`, `verdictRationale`, and `remediationPlan` when needed. If you include verification-class analysis, pass it in `verificationClasses`.
|
|
75
|
+
Extract the `Verification Classes` subsection from Reviewer C and pass it verbatim in `verificationClasses` so the persisted validation output uses the canonical class names `Contract`, `Integration`, `Operational`, and `UAT`.
|
|
73
76
|
|
|
74
77
|
**DB access safety:** Do NOT query `.gsd/gsd.db` directly via `sqlite3` or `node -e require('better-sqlite3')` — the engine owns the WAL connection. Use `gsd_milestone_status` to read milestone and slice state. All data you need is already inlined in the context above or accessible via the `gsd_*` tools. Direct DB access corrupts the WAL and bypasses tool-level validation.
|
|
75
78
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface SessionModelOverride {
|
|
2
|
+
provider: string;
|
|
3
|
+
id: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const sessionOverrides = new Map<string, SessionModelOverride>();
|
|
7
|
+
|
|
8
|
+
function normalizeSessionId(sessionId: string): string {
|
|
9
|
+
return typeof sessionId === "string" ? sessionId.trim() : "";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setSessionModelOverride(
|
|
13
|
+
sessionId: string,
|
|
14
|
+
override: SessionModelOverride,
|
|
15
|
+
): void {
|
|
16
|
+
const key = normalizeSessionId(sessionId);
|
|
17
|
+
if (!key) return;
|
|
18
|
+
sessionOverrides.set(key, {
|
|
19
|
+
provider: override.provider,
|
|
20
|
+
id: override.id,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getSessionModelOverride(
|
|
25
|
+
sessionId: string,
|
|
26
|
+
): SessionModelOverride | undefined {
|
|
27
|
+
const key = normalizeSessionId(sessionId);
|
|
28
|
+
if (!key) return undefined;
|
|
29
|
+
return sessionOverrides.get(key);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function clearSessionModelOverride(sessionId: string): void {
|
|
33
|
+
const key = normalizeSessionId(sessionId);
|
|
34
|
+
if (!key) return;
|
|
35
|
+
sessionOverrides.delete(key);
|
|
36
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Canonical GSD shortcut definitions used by registration, help text, and overlays.
|
|
2
|
+
|
|
3
|
+
import { formatShortcut } from "./files.js";
|
|
4
|
+
|
|
5
|
+
export type GSDShortcutId = "dashboard" | "notifications" | "parallel";
|
|
6
|
+
|
|
7
|
+
type GSDShortcutDef = {
|
|
8
|
+
key: "g" | "n" | "p";
|
|
9
|
+
action: string;
|
|
10
|
+
command: string;
|
|
11
|
+
/** Whether the Ctrl+Shift fallback is registered (false when it conflicts with an app keybinding). */
|
|
12
|
+
hasFallback: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const GSD_SHORTCUTS: Record<GSDShortcutId, GSDShortcutDef> = {
|
|
16
|
+
dashboard: {
|
|
17
|
+
key: "g",
|
|
18
|
+
action: "Open GSD dashboard",
|
|
19
|
+
command: "/gsd status",
|
|
20
|
+
hasFallback: true,
|
|
21
|
+
},
|
|
22
|
+
notifications: {
|
|
23
|
+
key: "n",
|
|
24
|
+
action: "Open notification history",
|
|
25
|
+
command: "/gsd notifications",
|
|
26
|
+
hasFallback: true,
|
|
27
|
+
},
|
|
28
|
+
parallel: {
|
|
29
|
+
key: "p",
|
|
30
|
+
action: "Open parallel worker monitor",
|
|
31
|
+
command: "/gsd parallel watch",
|
|
32
|
+
hasFallback: false, // Ctrl+Shift+P conflicts with cycleModelBackward
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function combo(prefix: "Ctrl+Alt+" | "Ctrl+Shift+", key: string): string {
|
|
37
|
+
return `${prefix}${key.toUpperCase()}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function primaryShortcutCombo(id: GSDShortcutId): string {
|
|
41
|
+
return combo("Ctrl+Alt+", GSD_SHORTCUTS[id].key);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function fallbackShortcutCombo(id: GSDShortcutId): string {
|
|
45
|
+
return combo("Ctrl+Shift+", GSD_SHORTCUTS[id].key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function shortcutPair(id: GSDShortcutId, formatter: (combo: string) => string = (combo) => combo): string {
|
|
49
|
+
const primary = formatter(primaryShortcutCombo(id));
|
|
50
|
+
if (!GSD_SHORTCUTS[id].hasFallback) return primary;
|
|
51
|
+
return `${primary} / ${formatter(fallbackShortcutCombo(id))}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function formattedShortcutPair(id: GSDShortcutId): string {
|
|
55
|
+
return shortcutPair(id, formatShortcut);
|
|
56
|
+
}
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
insertSlice,
|
|
59
59
|
insertTask,
|
|
60
60
|
updateTaskStatus,
|
|
61
|
-
|
|
61
|
+
getPendingGateCountForTurn,
|
|
62
62
|
type MilestoneRow,
|
|
63
63
|
type SliceRow,
|
|
64
64
|
type TaskRow,
|
|
@@ -864,7 +864,18 @@ export async function deriveStateFromDb(basePath: string): Promise<GSDState> {
|
|
|
864
864
|
}
|
|
865
865
|
}
|
|
866
866
|
|
|
867
|
-
|
|
867
|
+
// ── Quality gate evaluation check ──────────────────────────────────
|
|
868
|
+
// Pause before execution only when gates owned by the `gate-evaluate`
|
|
869
|
+
// turn (Q3/Q4) are still pending. Q8 is also `scope:"slice"` but is
|
|
870
|
+
// owned by `complete-slice`, so it must NOT block the evaluating-gates
|
|
871
|
+
// phase — otherwise auto-loop stalls forever waiting for a gate that
|
|
872
|
+
// this turn never evaluates. See gate-registry.ts for the ownership map.
|
|
873
|
+
// Slices with zero gate rows (pre-feature or simple) skip straight through.
|
|
874
|
+
const pendingGateCount = getPendingGateCountForTurn(
|
|
875
|
+
activeMilestone.id,
|
|
876
|
+
activeSlice.id,
|
|
877
|
+
"gate-evaluate",
|
|
878
|
+
);
|
|
868
879
|
if (pendingGateCount > 0) {
|
|
869
880
|
return {
|
|
870
881
|
activeMilestone, activeSlice, activeTask: null,
|
|
@@ -7,9 +7,8 @@ const sourcePath = join(import.meta.dirname, "..", "auto-start.ts");
|
|
|
7
7
|
const source = readFileSync(sourcePath, "utf-8");
|
|
8
8
|
|
|
9
9
|
test("bootstrapAutoSession snapshots ctx.model before guided-flow entry (#2829)", () => {
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
const snapshotIdx = source.indexOf("const startModelSnapshot = preferredModel");
|
|
10
|
+
// The snapshot ordering guarantee still holds: build snapshot before guided-flow.
|
|
11
|
+
const snapshotIdx = source.indexOf("const startModelSnapshot = manualSessionOverride");
|
|
13
12
|
assert.ok(snapshotIdx > -1, "auto-start.ts should snapshot model at bootstrap start");
|
|
14
13
|
|
|
15
14
|
const firstDiscussIdx = source.indexOf('await showSmartEntry(ctx, pi, base, { step: requestedStepMode });');
|
|
@@ -29,8 +28,11 @@ test("bootstrapAutoSession restores autoModeStartModel from the early snapshot (
|
|
|
29
28
|
assert.ok(snapshotRefIdx > -1, "autoModeStartModel should be restored from startModelSnapshot");
|
|
30
29
|
});
|
|
31
30
|
|
|
32
|
-
test("bootstrapAutoSession
|
|
33
|
-
|
|
31
|
+
test("bootstrapAutoSession checks manual session override before preferences", () => {
|
|
32
|
+
const manualIdx = source.indexOf("const manualSessionOverride = getSessionModelOverride(");
|
|
33
|
+
assert.ok(manualIdx > -1, "auto-start.ts should read session model override first");
|
|
34
|
+
|
|
35
|
+
// resolveDefaultSessionModel() should still be called for fallback behavior
|
|
34
36
|
const preferredIdx = source.indexOf("const preferredModel = resolveDefaultSessionModel(");
|
|
35
37
|
assert.ok(preferredIdx > -1, "auto-start.ts should call resolveDefaultSessionModel()");
|
|
36
38
|
|
|
@@ -38,11 +40,25 @@ test("bootstrapAutoSession prefers GSD PREFERENCES.md over settings.json for sta
|
|
|
38
40
|
const withProviderIdx = source.indexOf("resolveDefaultSessionModel(ctx.model?.provider)");
|
|
39
41
|
assert.ok(withProviderIdx > -1, "auto-start.ts should pass ctx.model?.provider for bare ID resolution");
|
|
40
42
|
|
|
41
|
-
const snapshotIdx = source.indexOf("const startModelSnapshot =
|
|
42
|
-
assert.ok(snapshotIdx > -1, "startModelSnapshot should
|
|
43
|
+
const snapshotIdx = source.indexOf("const startModelSnapshot = manualSessionOverride");
|
|
44
|
+
assert.ok(snapshotIdx > -1, "startModelSnapshot should prefer manual session override");
|
|
43
45
|
|
|
44
46
|
assert.ok(
|
|
45
|
-
preferredIdx < snapshotIdx,
|
|
46
|
-
"
|
|
47
|
+
manualIdx < snapshotIdx && preferredIdx < snapshotIdx,
|
|
48
|
+
"manual override and preference fallback must be resolved before building startModelSnapshot",
|
|
47
49
|
);
|
|
48
50
|
});
|
|
51
|
+
|
|
52
|
+
test("bootstrapAutoSession validates preferred model against live registry auth (#unconfigured-models)", () => {
|
|
53
|
+
// The raw PREFERENCES.md value must be validated against getAvailable()
|
|
54
|
+
// before being captured as the snapshot, so an unconfigured provider
|
|
55
|
+
// (no API key / OAuth) can't become autoModeStartModel.
|
|
56
|
+
const validationIdx = source.indexOf("ctx.modelRegistry.getAvailable()");
|
|
57
|
+
assert.ok(validationIdx > -1, "auto-start.ts should validate preferred model against getAvailable()");
|
|
58
|
+
|
|
59
|
+
const resolveModelIdIdx = source.indexOf("resolveModelId");
|
|
60
|
+
assert.ok(resolveModelIdIdx > -1, "auto-start.ts should resolve preferred model against the registry");
|
|
61
|
+
|
|
62
|
+
const warningIdx = source.indexOf("is not configured; falling back to session default");
|
|
63
|
+
assert.ok(warningIdx > -1, "auto-start.ts should warn when preferred model is unconfigured");
|
|
64
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { createTestContext } from "./test-helpers.ts";
|
|
5
|
+
|
|
6
|
+
const { assertTrue, report } = createTestContext();
|
|
7
|
+
|
|
8
|
+
const srcPath = join(import.meta.dirname, "..", "auto-start.ts");
|
|
9
|
+
const src = readFileSync(srcPath, "utf-8");
|
|
10
|
+
|
|
11
|
+
console.log("\n=== #3822: worktree bootstrap uses project DB path ===");
|
|
12
|
+
|
|
13
|
+
const dbLifecycleIdx = src.indexOf("// ── DB lifecycle ──");
|
|
14
|
+
assertTrue(dbLifecycleIdx > 0, "auto-start.ts has a DB lifecycle section");
|
|
15
|
+
|
|
16
|
+
const dbLifecycleRegion = dbLifecycleIdx > 0 ? src.slice(dbLifecycleIdx, dbLifecycleIdx + 600) : "";
|
|
17
|
+
|
|
18
|
+
assertTrue(
|
|
19
|
+
dbLifecycleRegion.includes("const gsdDbPath = resolveProjectRootDbPath(s.basePath);"),
|
|
20
|
+
"DB lifecycle resolves the project-root DB path after worktree entry (#3822)",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
assertTrue(
|
|
24
|
+
!dbLifecycleRegion.includes('join(s.basePath, ".gsd", "gsd.db")'),
|
|
25
|
+
"DB lifecycle no longer derives gsd.db directly from the worktree path (#3822)",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
report();
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const systemContextSrc = readFileSync(
|
|
7
|
+
join(import.meta.dirname, "..", "bootstrap", "system-context.ts"),
|
|
8
|
+
"utf-8",
|
|
9
|
+
);
|
|
10
|
+
const registerHooksSrc = readFileSync(
|
|
11
|
+
join(import.meta.dirname, "..", "bootstrap", "register-hooks.ts"),
|
|
12
|
+
"utf-8",
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
describe("bootstrap deriveState DB guards (#3844)", () => {
|
|
16
|
+
test("system-context opens DB before deriveState in resume flows", () => {
|
|
17
|
+
const helperIdx = systemContextSrc.indexOf("const ensureStateDbOpen = async () => {");
|
|
18
|
+
const firstDeriveIdx = systemContextSrc.indexOf("const state = await deriveState(basePath);");
|
|
19
|
+
assert.ok(helperIdx > -1, "system-context should define a DB-open helper for deriveState callers");
|
|
20
|
+
assert.ok(firstDeriveIdx > -1, "system-context should still derive state for resume flows");
|
|
21
|
+
assert.ok(helperIdx < firstDeriveIdx, "system-context should prepare DB opening before deriveState resume calls");
|
|
22
|
+
assert.match(
|
|
23
|
+
systemContextSrc,
|
|
24
|
+
/await ensureStateDbOpen\(\);\s*\n\s*const state = await deriveState\(basePath\);/g,
|
|
25
|
+
"system-context resume flows should open DB before deriveState",
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("register-hooks opens DB before deriveState in session_before_compact", () => {
|
|
30
|
+
const compactIdx = registerHooksSrc.indexOf('pi.on("session_before_compact"');
|
|
31
|
+
assert.ok(compactIdx > -1, "register-hooks should define session_before_compact");
|
|
32
|
+
const compactSection = registerHooksSrc.slice(compactIdx, compactIdx + 1600);
|
|
33
|
+
const ensureIdx = compactSection.indexOf("ensureDbOpen()");
|
|
34
|
+
const deriveIdx = compactSection.indexOf("deriveState(basePath)");
|
|
35
|
+
assert.ok(ensureIdx > -1, "session_before_compact should call ensureDbOpen()");
|
|
36
|
+
assert.ok(deriveIdx > -1, "session_before_compact should derive state");
|
|
37
|
+
assert.ok(ensureIdx < deriveIdx, "session_before_compact should open DB before deriveState");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* complete-slice gate closure integration test.
|
|
3
|
+
*
|
|
4
|
+
* Pins the fix for the Q8-stall bug: complete-slice must close every gate
|
|
5
|
+
* owned by the complete-slice turn based on the content of the matching
|
|
6
|
+
* CompleteSliceParams field. Without this, Q8 stays pending forever and
|
|
7
|
+
* blocks state derivation on subsequent loops.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import * as fs from "node:fs";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
import * as os from "node:os";
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
openDatabase,
|
|
18
|
+
closeDatabase,
|
|
19
|
+
insertMilestone,
|
|
20
|
+
insertSlice,
|
|
21
|
+
insertTask,
|
|
22
|
+
insertGateRow,
|
|
23
|
+
getGateResults,
|
|
24
|
+
} from "../gsd-db.ts";
|
|
25
|
+
import { handleCompleteSlice } from "../tools/complete-slice.ts";
|
|
26
|
+
import type { CompleteSliceParams } from "../types.ts";
|
|
27
|
+
|
|
28
|
+
function makeValidSliceParams(overrides: Partial<CompleteSliceParams> = {}): CompleteSliceParams {
|
|
29
|
+
return {
|
|
30
|
+
sliceId: "S01",
|
|
31
|
+
milestoneId: "M001",
|
|
32
|
+
sliceTitle: "Test Slice",
|
|
33
|
+
oneLiner: "Implemented test slice",
|
|
34
|
+
narrative: "Built and tested.",
|
|
35
|
+
verification: "All tests pass.",
|
|
36
|
+
deviations: "None.",
|
|
37
|
+
knownLimitations: "None.",
|
|
38
|
+
followUps: "None.",
|
|
39
|
+
keyFiles: ["src/foo.ts"],
|
|
40
|
+
keyDecisions: [],
|
|
41
|
+
patternsEstablished: [],
|
|
42
|
+
observabilitySurfaces: [],
|
|
43
|
+
provides: [],
|
|
44
|
+
requirementsSurfaced: [],
|
|
45
|
+
drillDownPaths: [],
|
|
46
|
+
affects: [],
|
|
47
|
+
requirementsAdvanced: [],
|
|
48
|
+
requirementsValidated: [],
|
|
49
|
+
requirementsInvalidated: [],
|
|
50
|
+
filesModified: [],
|
|
51
|
+
requires: [],
|
|
52
|
+
uatContent: "## Smoke Test\n\nVerify happy path.",
|
|
53
|
+
...overrides,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
describe("complete-slice closes complete-slice-owned gates", () => {
|
|
58
|
+
let dbPath: string;
|
|
59
|
+
let basePath: string;
|
|
60
|
+
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
dbPath = path.join(
|
|
63
|
+
fs.mkdtempSync(path.join(os.tmpdir(), "gsd-slice-gate-")),
|
|
64
|
+
"test.db",
|
|
65
|
+
);
|
|
66
|
+
openDatabase(dbPath);
|
|
67
|
+
|
|
68
|
+
basePath = fs.mkdtempSync(path.join(os.tmpdir(), "gsd-slice-gate-handler-"));
|
|
69
|
+
const sliceDir = path.join(
|
|
70
|
+
basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks",
|
|
71
|
+
);
|
|
72
|
+
fs.mkdirSync(sliceDir, { recursive: true });
|
|
73
|
+
fs.writeFileSync(
|
|
74
|
+
path.join(basePath, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
75
|
+
[
|
|
76
|
+
"# M001: Test Milestone",
|
|
77
|
+
"",
|
|
78
|
+
"## Slices",
|
|
79
|
+
"",
|
|
80
|
+
'- [ ] **S01: Test Slice** `risk:medium` `depends:[]`',
|
|
81
|
+
" - After this: basic functionality works",
|
|
82
|
+
].join("\n"),
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
insertMilestone({ id: "M001" });
|
|
86
|
+
insertSlice({ id: "S01", milestoneId: "M001" });
|
|
87
|
+
insertTask({
|
|
88
|
+
id: "T01", sliceId: "S01", milestoneId: "M001",
|
|
89
|
+
status: "complete", title: "Task 1",
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Seed Q8 as pending — this is what plan-slice does today.
|
|
93
|
+
insertGateRow({
|
|
94
|
+
milestoneId: "M001", sliceId: "S01",
|
|
95
|
+
gateId: "Q8", scope: "slice",
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
afterEach(() => {
|
|
100
|
+
closeDatabase();
|
|
101
|
+
fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
|
|
102
|
+
fs.rmSync(basePath, { recursive: true, force: true });
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("Q8 closes as 'pass' when operationalReadiness is populated", async () => {
|
|
106
|
+
const params = makeValidSliceParams({
|
|
107
|
+
operationalReadiness: [
|
|
108
|
+
"- Health signal: /health endpoint returns 200",
|
|
109
|
+
"- Failure signal: error rate alert in observability dashboard",
|
|
110
|
+
"- Recovery: systemd auto-restart",
|
|
111
|
+
].join("\n"),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const result = await handleCompleteSlice(params, basePath);
|
|
115
|
+
assert.ok(!("error" in result), `handler failed: ${(result as any).error}`);
|
|
116
|
+
|
|
117
|
+
const gates = getGateResults("M001", "S01", "slice");
|
|
118
|
+
const q8 = gates.find((g) => g.gate_id === "Q8");
|
|
119
|
+
assert.ok(q8, "Q8 row must exist after complete-slice");
|
|
120
|
+
assert.equal(q8.status, "complete");
|
|
121
|
+
assert.equal(q8.verdict, "pass");
|
|
122
|
+
assert.ok(
|
|
123
|
+
q8.findings.includes("Health signal"),
|
|
124
|
+
"Q8 findings must capture the operationalReadiness content",
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("Q8 closes as 'omitted' when operationalReadiness is empty", async () => {
|
|
129
|
+
const params = makeValidSliceParams({ operationalReadiness: "" });
|
|
130
|
+
|
|
131
|
+
const result = await handleCompleteSlice(params, basePath);
|
|
132
|
+
assert.ok(!("error" in result), `handler failed: ${(result as any).error}`);
|
|
133
|
+
|
|
134
|
+
const gates = getGateResults("M001", "S01", "slice");
|
|
135
|
+
const q8 = gates.find((g) => g.gate_id === "Q8");
|
|
136
|
+
assert.ok(q8, "Q8 row must exist after complete-slice");
|
|
137
|
+
assert.equal(q8.status, "complete");
|
|
138
|
+
assert.equal(q8.verdict, "omitted");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test("Q8 also closes when operationalReadiness is omitted entirely", async () => {
|
|
142
|
+
// A model that doesn't pass operationalReadiness at all must still
|
|
143
|
+
// move Q8 out of 'pending' — leaving it pending produces the stall.
|
|
144
|
+
const params = makeValidSliceParams();
|
|
145
|
+
const result = await handleCompleteSlice(params, basePath);
|
|
146
|
+
assert.ok(!("error" in result), `handler failed: ${(result as any).error}`);
|
|
147
|
+
|
|
148
|
+
const gates = getGateResults("M001", "S01", "slice");
|
|
149
|
+
const q8 = gates.find((g) => g.gate_id === "Q8");
|
|
150
|
+
assert.ok(q8);
|
|
151
|
+
assert.notEqual(q8.status, "pending", "Q8 must never remain pending after complete-slice");
|
|
152
|
+
assert.equal(q8.verdict, "omitted");
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("summary markdown contains Operational Readiness section", async () => {
|
|
156
|
+
const params = makeValidSliceParams({
|
|
157
|
+
operationalReadiness: "- Health signal: /health\n- Failure signal: alert",
|
|
158
|
+
});
|
|
159
|
+
const result = await handleCompleteSlice(params, basePath);
|
|
160
|
+
assert.ok(!("error" in result));
|
|
161
|
+
if (!("error" in result)) {
|
|
162
|
+
const summary = fs.readFileSync(result.summaryPath, "utf-8");
|
|
163
|
+
assert.match(summary, /^## Operational Readiness/m);
|
|
164
|
+
assert.match(summary, /Health signal: \/health/);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const promptPath = join(process.cwd(), "src/resources/extensions/gsd/prompts/complete-slice.md");
|
|
7
|
+
const prompt = readFileSync(promptPath, "utf-8");
|
|
8
|
+
|
|
9
|
+
test("complete-slice prompt explains the flat task summary layout", () => {
|
|
10
|
+
assert.match(prompt, /flat file layout/i);
|
|
11
|
+
assert.match(prompt, /T01-SUMMARY\.md/);
|
|
12
|
+
assert.match(prompt, /not inside per-task subdirectories like `tasks\/T01\/SUMMARY\.md`/i);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("complete-slice prompt forbids the wrong task summary glob", () => {
|
|
16
|
+
assert.match(prompt, /find .*tasks -name "\*-SUMMARY\.md"/i);
|
|
17
|
+
assert.match(prompt, /Never use `tasks\/\*\/SUMMARY\.md`/);
|
|
18
|
+
});
|