gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b
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 +4 -2
- package/dist/cli.js +0 -19
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +119 -18
- package/dist/resources/extensions/gsd/auto/phases.js +212 -135
- package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
- package/dist/resources/extensions/gsd/auto-start.js +199 -9
- package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
- package/dist/resources/extensions/gsd/auto.js +95 -27
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
- package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/context-budget.js +37 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +36 -4
- package/dist/resources/extensions/gsd/graph.js +9 -3
- package/dist/resources/extensions/gsd/gsd-db.js +146 -13
- package/dist/resources/extensions/gsd/guided-flow.js +129 -44
- package/dist/resources/extensions/gsd/memory-store.js +69 -12
- package/dist/resources/extensions/gsd/migrate/command.js +40 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/quick.js +34 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
- package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
- package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
- 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 +11 -11
- 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/onboarding/route.js +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 +11 -11
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
- package/dist/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +12 -8
- package/packages/contracts/package.json +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -17
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
- package/packages/mcp-server/src/workflow-tools.ts +30 -16
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +9 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +8 -0
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +14 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
- package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/fake-model.js +27 -0
- package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/index.js +8 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
- package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/fake.js +319 -0
- package/packages/pi-ai/dist/providers/fake.js.map +1 -0
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/src/models/fake-model.ts +30 -0
- package/packages/pi-ai/src/models/index.ts +9 -0
- package/packages/pi-ai/src/providers/fake.ts +376 -0
- package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
- 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-tool-refresh.test.js +18 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -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 +44 -7
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -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 +9 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -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 +20 -7
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
- 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/hooks-runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -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 +109 -17
- 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 +69 -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/chat-controller.test.js +93 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -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-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
- 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 +26 -0
- 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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
- package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
- package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
- package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
- package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/index.d.ts +1 -0
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -0
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/style.d.ts +41 -0
- package/packages/pi-tui/dist/style.d.ts.map +1 -0
- package/packages/pi-tui/dist/style.js +158 -0
- package/packages/pi-tui/dist/style.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts +0 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +21 -16
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
- package/packages/pi-tui/src/index.ts +9 -0
- package/packages/pi-tui/src/style.ts +225 -0
- package/packages/pi-tui/src/tui.ts +23 -16
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +18 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +36 -27
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
- package/src/resources/extensions/github-sync/templates.ts +38 -8
- package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
- package/src/resources/extensions/gsd/auto/loop.ts +151 -26
- package/src/resources/extensions/gsd/auto/phases.ts +289 -196
- package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
- package/src/resources/extensions/gsd/auto/session.ts +8 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
- package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
- package/src/resources/extensions/gsd/auto-start.ts +237 -15
- package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
- package/src/resources/extensions/gsd/auto.ts +110 -22
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
- package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/context-budget.ts +44 -2
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +46 -8
- package/src/resources/extensions/gsd/graph.ts +12 -5
- package/src/resources/extensions/gsd/gsd-db.ts +168 -13
- package/src/resources/extensions/gsd/guided-flow.ts +150 -51
- package/src/resources/extensions/gsd/memory-store.ts +77 -12
- package/src/resources/extensions/gsd/migrate/command.ts +47 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/quick.ts +37 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
- package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
- package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Verifies low-risk auto-prompt duplication cuts render through prompt builders.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import type { TestContext } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
|
|
11
|
+
import { invalidateAllCaches } from "../cache.ts";
|
|
12
|
+
import {
|
|
13
|
+
closeDatabase,
|
|
14
|
+
insertMilestone,
|
|
15
|
+
insertSlice,
|
|
16
|
+
insertTask,
|
|
17
|
+
openDatabase,
|
|
18
|
+
upsertMilestonePlanning,
|
|
19
|
+
} from "../gsd-db.ts";
|
|
20
|
+
|
|
21
|
+
type AutoPromptBuilders = typeof import("../auto-prompts.ts");
|
|
22
|
+
|
|
23
|
+
function makeBase(prefix: string): string {
|
|
24
|
+
const base = mkdtempSync(join(tmpdir(), prefix));
|
|
25
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
26
|
+
return base;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function cleanup(base: string): void {
|
|
30
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
31
|
+
invalidateAllCaches();
|
|
32
|
+
rmSync(base, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function loadAutoPromptBuilders(t: TestContext): Promise<AutoPromptBuilders> {
|
|
36
|
+
const previousGsdHome = process.env.GSD_HOME;
|
|
37
|
+
const isolatedHome = mkdtempSync(join(tmpdir(), "gsd-prompt-loader-home-"));
|
|
38
|
+
process.env.GSD_HOME = isolatedHome;
|
|
39
|
+
t.after(() => {
|
|
40
|
+
if (previousGsdHome === undefined) delete process.env.GSD_HOME;
|
|
41
|
+
else process.env.GSD_HOME = previousGsdHome;
|
|
42
|
+
rmSync(isolatedHome, { recursive: true, force: true });
|
|
43
|
+
});
|
|
44
|
+
return import(`../auto-prompts.ts?promptDupCuts=${Date.now()}-${Math.random()}`) as Promise<AutoPromptBuilders>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function seedDb(base: string, taskStatus = "complete"): void {
|
|
48
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
49
|
+
insertMilestone({ id: "M001", title: "Prompt Cuts", status: "active", depends_on: [] });
|
|
50
|
+
upsertMilestonePlanning("M001", {
|
|
51
|
+
title: "Prompt Cuts",
|
|
52
|
+
status: "active",
|
|
53
|
+
vision: "Reduce duplicate prompt reads.",
|
|
54
|
+
successCriteria: ["Prompt builders render compact context."],
|
|
55
|
+
keyRisks: [],
|
|
56
|
+
proofStrategy: [],
|
|
57
|
+
verificationContract: "",
|
|
58
|
+
verificationIntegration: "",
|
|
59
|
+
verificationOperational: "",
|
|
60
|
+
verificationUat: "",
|
|
61
|
+
definitionOfDone: [],
|
|
62
|
+
requirementCoverage: "",
|
|
63
|
+
boundaryMapMarkdown: "",
|
|
64
|
+
});
|
|
65
|
+
insertSlice({
|
|
66
|
+
id: "S01",
|
|
67
|
+
milestoneId: "M001",
|
|
68
|
+
title: "Prompt Slice",
|
|
69
|
+
status: "active",
|
|
70
|
+
risk: "low",
|
|
71
|
+
depends: [],
|
|
72
|
+
demo: "",
|
|
73
|
+
sequence: 1,
|
|
74
|
+
});
|
|
75
|
+
insertTask({
|
|
76
|
+
id: "T01",
|
|
77
|
+
sliceId: "S01",
|
|
78
|
+
milestoneId: "M001",
|
|
79
|
+
title: "Task one",
|
|
80
|
+
status: taskStatus,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function writeRoadmapAndPlan(base: string): void {
|
|
85
|
+
writeFileSync(
|
|
86
|
+
join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
|
|
87
|
+
[
|
|
88
|
+
"# M001 Roadmap",
|
|
89
|
+
"## Slices",
|
|
90
|
+
"- [ ] **S01: Prompt Slice** `risk:low` `depends:[]`",
|
|
91
|
+
].join("\n"),
|
|
92
|
+
);
|
|
93
|
+
writeFileSync(
|
|
94
|
+
join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
|
|
95
|
+
[
|
|
96
|
+
"# S01 Plan",
|
|
97
|
+
"",
|
|
98
|
+
"**Goal:** Reduce duplicate prompt reads.",
|
|
99
|
+
"",
|
|
100
|
+
"## Tasks",
|
|
101
|
+
"- [x] **T01: Task one** `est:15m`",
|
|
102
|
+
].join("\n"),
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function writeTaskSummary(base: string, options?: { blocker?: boolean; repeatedNarrative?: string }): void {
|
|
107
|
+
const narrative = options?.repeatedNarrative ?? "This full implementation narrative should stay out of closer prompts.";
|
|
108
|
+
writeFileSync(
|
|
109
|
+
join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md"),
|
|
110
|
+
[
|
|
111
|
+
"---",
|
|
112
|
+
"id: T01",
|
|
113
|
+
"parent: S01",
|
|
114
|
+
"milestone: M001",
|
|
115
|
+
"provides:",
|
|
116
|
+
" - prompt context reduction",
|
|
117
|
+
"key_files:",
|
|
118
|
+
" - src/resources/extensions/gsd/auto-prompts.ts",
|
|
119
|
+
"key_decisions:",
|
|
120
|
+
" - use compact excerpts before full reads",
|
|
121
|
+
"patterns_established:",
|
|
122
|
+
" - excerpt-first complete-slice context",
|
|
123
|
+
"observability_surfaces: []",
|
|
124
|
+
"duration: 15m",
|
|
125
|
+
"verification_result: passed",
|
|
126
|
+
"completed_at: 2026-05-06T12:00:00Z",
|
|
127
|
+
`blocker_discovered: ${options?.blocker ? "true" : "false"}`,
|
|
128
|
+
"---",
|
|
129
|
+
"",
|
|
130
|
+
"# T01: Task one",
|
|
131
|
+
"**One-line result.**",
|
|
132
|
+
"",
|
|
133
|
+
"## What Happened",
|
|
134
|
+
narrative,
|
|
135
|
+
"",
|
|
136
|
+
"## Verification",
|
|
137
|
+
"node:test passed.",
|
|
138
|
+
"",
|
|
139
|
+
"## Diagnostics",
|
|
140
|
+
"Prompt size stayed bounded.",
|
|
141
|
+
].join("\n"),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
test("execute-task rendering makes memory_query and template disk reads fallback-only", async (t) => {
|
|
146
|
+
const base = makeBase("gsd-execute-dup-cuts-");
|
|
147
|
+
t.after(() => cleanup(base));
|
|
148
|
+
invalidateAllCaches();
|
|
149
|
+
|
|
150
|
+
seedDb(base, "pending");
|
|
151
|
+
writeRoadmapAndPlan(base);
|
|
152
|
+
writeFileSync(
|
|
153
|
+
join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-PLAN.md"),
|
|
154
|
+
"# T01 Plan\n\nDo the prompt edit.\n",
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const { buildExecuteTaskPrompt } = await loadAutoPromptBuilders(t);
|
|
158
|
+
const prompt = await buildExecuteTaskPrompt("M001", "S01", "Prompt Slice", "T01", "Task one", base);
|
|
159
|
+
|
|
160
|
+
assert.match(prompt, /Call `memory_query`.*only when no injected memory block exists or the inlined memory\/context is insufficient/s);
|
|
161
|
+
assert.doesNotMatch(prompt, /Call `memory_query` with 2-4 keywords from the task title and touched files unless this is purely mechanical/);
|
|
162
|
+
assert.match(prompt, /Use the inlined Task Summary template below/);
|
|
163
|
+
assert.match(prompt, /Read `.*task-summary\.md` only if the inlined template is absent or visibly truncated/);
|
|
164
|
+
assert.doesNotMatch(prompt, /Read the template at `.*task-summary\.md`/);
|
|
165
|
+
assert.match(prompt, /### Output Template: Task Summary/);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("complete-slice renders task summary excerpts without full summary bodies", async (t) => {
|
|
169
|
+
const base = makeBase("gsd-complete-slice-excerpts-");
|
|
170
|
+
t.after(() => cleanup(base));
|
|
171
|
+
invalidateAllCaches();
|
|
172
|
+
|
|
173
|
+
seedDb(base);
|
|
174
|
+
writeRoadmapAndPlan(base);
|
|
175
|
+
const repeatedNarrative = "FULL_TASK_BODY_SHOULD_NOT_RENDER ".repeat(40);
|
|
176
|
+
writeTaskSummary(base, { repeatedNarrative });
|
|
177
|
+
|
|
178
|
+
const { buildCompleteSlicePrompt } = await loadAutoPromptBuilders(t);
|
|
179
|
+
const prompt = await buildCompleteSlicePrompt("M001", "Prompt Cuts", "S01", "Prompt Slice", base);
|
|
180
|
+
|
|
181
|
+
assert.match(prompt, /### Task Summary: T01 \(excerpt\)/);
|
|
182
|
+
assert.match(prompt, /On-demand.*read `\.gsd\/milestones\/M001\/slices\/S01\/tasks\/T01-SUMMARY\.md` only when this excerpt is absent\/truncated/s);
|
|
183
|
+
assert.doesNotMatch(prompt, /FULL_TASK_BODY_SHOULD_NOT_RENDER/);
|
|
184
|
+
assert.match(prompt, /Review the inlined task-summary excerpts/);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("complete-slice caps malformed task summaries instead of inlining full bodies", async (t) => {
|
|
188
|
+
const base = makeBase("gsd-complete-slice-malformed-excerpts-");
|
|
189
|
+
t.after(() => cleanup(base));
|
|
190
|
+
invalidateAllCaches();
|
|
191
|
+
|
|
192
|
+
seedDb(base);
|
|
193
|
+
writeRoadmapAndPlan(base);
|
|
194
|
+
writeFileSync(
|
|
195
|
+
join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-SUMMARY.md"),
|
|
196
|
+
[
|
|
197
|
+
"# Legacy summary without frontmatter id",
|
|
198
|
+
"LEGACY_FULL_BODY_SHOULD_BE_CAPPED ".repeat(200),
|
|
199
|
+
].join("\n"),
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const { buildCompleteSlicePrompt } = await loadAutoPromptBuilders(t);
|
|
203
|
+
const prompt = await buildCompleteSlicePrompt("M001", "Prompt Cuts", "S01", "Prompt Slice", base);
|
|
204
|
+
|
|
205
|
+
assert.match(prompt, /Truncated malformed summary/);
|
|
206
|
+
assert.ok(prompt.length < 20_000);
|
|
207
|
+
assert.ok((prompt.match(/LEGACY_FULL_BODY_SHOULD_BE_CAPPED/g) ?? []).length < 60);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test("replan-slice renders blocker summary excerpt and tells the agent to read full only on demand", async (t) => {
|
|
211
|
+
const base = makeBase("gsd-replan-excerpts-");
|
|
212
|
+
t.after(() => cleanup(base));
|
|
213
|
+
invalidateAllCaches();
|
|
214
|
+
|
|
215
|
+
seedDb(base);
|
|
216
|
+
writeRoadmapAndPlan(base);
|
|
217
|
+
writeTaskSummary(base, {
|
|
218
|
+
blocker: true,
|
|
219
|
+
repeatedNarrative: "FULL_BLOCKER_BODY_SHOULD_NOT_RENDER ".repeat(40),
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
const { buildReplanSlicePrompt } = await loadAutoPromptBuilders(t);
|
|
223
|
+
const prompt = await buildReplanSlicePrompt("M001", "Prompt Cuts", "S01", "Prompt Slice", base);
|
|
224
|
+
|
|
225
|
+
assert.match(prompt, /### Blocker Task Summary: T01 \(excerpt\)/);
|
|
226
|
+
assert.match(prompt, /Use the inlined blocker summary excerpt first/);
|
|
227
|
+
assert.match(prompt, /Read the full blocker task summary only if the excerpt is absent, marked truncated, or lacks the specific blocker evidence needed to replan/);
|
|
228
|
+
assert.doesNotMatch(prompt, /FULL_BLOCKER_BODY_SHOULD_NOT_RENDER/);
|
|
229
|
+
assert.doesNotMatch(prompt, /Read the blocker task summary carefully/);
|
|
230
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync, readdirSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { dirname } from "node:path";
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const promptsDir = join(__dirname, "..", "prompts");
|
|
11
|
+
|
|
12
|
+
test("prompt templates do not reference legacy milestone-root .gsd paths", () => {
|
|
13
|
+
const offenders: string[] = [];
|
|
14
|
+
for (const file of readdirSync(promptsDir)) {
|
|
15
|
+
if (!file.endsWith(".md")) continue;
|
|
16
|
+
const content = readFileSync(join(promptsDir, file), "utf-8");
|
|
17
|
+
const legacyPatterns = [
|
|
18
|
+
/\.gsd\/\{\{(?:milestoneId|mid)\}\}\//g,
|
|
19
|
+
/\.gsd\/<milestone-id>\//g,
|
|
20
|
+
/\.gsd\/<ID>\//g,
|
|
21
|
+
];
|
|
22
|
+
for (const pattern of legacyPatterns) {
|
|
23
|
+
if (pattern.test(content)) {
|
|
24
|
+
offenders.push(`${file}: ${pattern.source}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
assert.deepEqual(
|
|
30
|
+
offenders,
|
|
31
|
+
[],
|
|
32
|
+
"Milestone artifacts must use .gsd/milestones/<MID>/..., not legacy .gsd/<MID>/...",
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("quick task prompt delegates commit policy to quick.ts", () => {
|
|
37
|
+
const content = readFileSync(join(promptsDir, "quick-task.md"), "utf-8");
|
|
38
|
+
assert.match(content, /\{\{commitInstruction\}\}/);
|
|
39
|
+
assert.doesNotMatch(content, /Stage only relevant files/);
|
|
40
|
+
});
|
|
@@ -65,6 +65,25 @@ describe('prompt step ordering (#3696)', () => {
|
|
|
65
65
|
assert.ok(learningsIdx < completeMilestoneIdx, 'learnings extraction must happen before gsd_complete_milestone');
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
test('complete-milestone duplicate guard checks milestone status before durable writes', () => {
|
|
69
|
+
const guardMatch = completeMilestoneMd.match(/^\d+\.\s.*gsd_milestone_status/m);
|
|
70
|
+
const reqUpdateMatch = completeMilestoneMd.match(/^\d+\.\s.*gsd_requirement_update/m);
|
|
71
|
+
assert.ok(guardMatch, 'complete-milestone must start with a gsd_milestone_status duplicate guard');
|
|
72
|
+
assert.ok(reqUpdateMatch, 'gsd_requirement_update should appear in a numbered step');
|
|
73
|
+
|
|
74
|
+
const guardIdx = completeMilestoneMd.indexOf(guardMatch![0]);
|
|
75
|
+
const reqUpdateIdx = completeMilestoneMd.indexOf(reqUpdateMatch![0]);
|
|
76
|
+
assert.ok(
|
|
77
|
+
guardIdx < reqUpdateIdx,
|
|
78
|
+
'duplicate guard must run before requirement/project/learnings writes',
|
|
79
|
+
);
|
|
80
|
+
assert.match(
|
|
81
|
+
completeMilestoneMd,
|
|
82
|
+
/status(?:`|\*\*)?\s+(?:is\s+)?(?:`complete`|"complete")/i,
|
|
83
|
+
'duplicate guard must tell the agent to stop when status is complete',
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
68
87
|
test('complete-slice.md uses gsd_requirement_update', () => {
|
|
69
88
|
assert.match(completeSliceMd, /gsd_requirement_update/,
|
|
70
89
|
'complete-slice.md should reference gsd_requirement_update');
|
|
@@ -28,8 +28,8 @@ describe('query-tools ensureDbOpen usage (#3672)', () => {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
test('calls ensureDbOpen() before DB queries', () => {
|
|
31
|
-
assert.match(source, /await ensureDbOpen\(
|
|
32
|
-
'query-tools should call await ensureDbOpen()');
|
|
31
|
+
assert.match(source, /await ensureDbOpen\([^)]*\)/,
|
|
32
|
+
'query-tools should call await ensureDbOpen(...)');
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
test('no longer imports isDbAvailable in the execute path', () => {
|
|
@@ -41,7 +41,7 @@ describe('query-tools ensureDbOpen usage (#3672)', () => {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
test('uses dbAvailable result from ensureDbOpen', () => {
|
|
44
|
-
assert.match(source, /dbAvailable\s*=\s*await ensureDbOpen\(
|
|
44
|
+
assert.match(source, /dbAvailable\s*=\s*await ensureDbOpen\([^)]*\)/,
|
|
45
45
|
'should store ensureDbOpen result in dbAvailable');
|
|
46
46
|
});
|
|
47
47
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, mkdirSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { buildQuickCommitInstruction } from "../quick.ts";
|
|
8
|
+
|
|
9
|
+
function git(cwd: string, args: string[]): void {
|
|
10
|
+
const result = spawnSync("git", args, { cwd, encoding: "utf-8" });
|
|
11
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
test("quick task commit instruction does not ask agents to stage external .gsd quick files", { skip: process.platform === "win32" }, () => {
|
|
15
|
+
const tempRoot = realpathSync(mkdtempSync(join(tmpdir(), "gsd-quick-ext-")));
|
|
16
|
+
const repo = join(tempRoot, "repo");
|
|
17
|
+
const externalGsd = join(tempRoot, "state");
|
|
18
|
+
mkdirSync(repo);
|
|
19
|
+
mkdirSync(externalGsd);
|
|
20
|
+
|
|
21
|
+
const previousCwd = process.cwd();
|
|
22
|
+
try {
|
|
23
|
+
git(repo, ["init"]);
|
|
24
|
+
git(repo, ["config", "user.email", "test@example.com"]);
|
|
25
|
+
git(repo, ["config", "user.name", "Test User"]);
|
|
26
|
+
writeFileSync(join(repo, "README.md"), "# Test\n", "utf-8");
|
|
27
|
+
git(repo, ["add", "README.md"]);
|
|
28
|
+
git(repo, ["commit", "-m", "init"]);
|
|
29
|
+
symlinkSync(externalGsd, join(repo, ".gsd"), "dir");
|
|
30
|
+
|
|
31
|
+
const instruction = buildQuickCommitInstruction(repo, join(repo, ".gsd"));
|
|
32
|
+
|
|
33
|
+
assert.match(instruction, /do not stage or commit `\.gsd\/quick\/\.\.\.`/);
|
|
34
|
+
assert.match(instruction, /nothing in the project repo to commit/);
|
|
35
|
+
assert.match(instruction, /Write the quick summary file directly/);
|
|
36
|
+
} finally {
|
|
37
|
+
process.chdir(previousCwd);
|
|
38
|
+
rmSync(tempRoot, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -24,7 +24,7 @@ describe('restore tools after discuss flow scoping (#3628)', () => {
|
|
|
24
24
|
it('savedTools is declared before the discuss scoping block', () => {
|
|
25
25
|
// savedTools must be declared before the discuss-* check
|
|
26
26
|
const savedToolsDecl = src.indexOf('let savedTools')
|
|
27
|
-
const discussCheck = src.indexOf('if (unitType?.startsWith("discuss-")
|
|
27
|
+
const discussCheck = src.indexOf('if (unitType?.startsWith("discuss-")')
|
|
28
28
|
assert.ok(savedToolsDecl !== -1, 'savedTools variable must be declared')
|
|
29
29
|
assert.ok(discussCheck !== -1, 'discuss-* type check must exist')
|
|
30
30
|
assert.ok(
|
|
@@ -33,40 +33,61 @@ describe('restore tools after discuss flow scoping (#3628)', () => {
|
|
|
33
33
|
)
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
-
it('savedTools captures current tools
|
|
37
|
-
const discussCheck = src.indexOf('if (unitType?.startsWith("discuss-")
|
|
36
|
+
it('savedTools captures current tools before scoping can mutate active state', () => {
|
|
37
|
+
const discussCheck = src.indexOf('if (unitType?.startsWith("discuss-")')
|
|
38
38
|
assert.ok(discussCheck !== -1)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
const
|
|
40
|
+
const currentToolsDecl = src.indexOf('const currentTools = pi.getActiveTools()')
|
|
41
|
+
const savedToolsAssign = src.indexOf('savedTools = {', currentToolsDecl)
|
|
42
|
+
const firstMutation = src.indexOf('pi.setActiveTools(scopedTools)')
|
|
42
43
|
assert.ok(
|
|
43
|
-
|
|
44
|
-
'
|
|
44
|
+
currentToolsDecl !== -1 && savedToolsAssign !== -1 && firstMutation !== -1,
|
|
45
|
+
'guided-flow.ts must capture current tools, save them, and then scope active tools',
|
|
46
|
+
)
|
|
47
|
+
assert.ok(
|
|
48
|
+
currentToolsDecl < savedToolsAssign && savedToolsAssign < firstMutation,
|
|
49
|
+
'savedTools must capture currentTools before any discuss scoping mutation',
|
|
50
|
+
)
|
|
51
|
+
assert.ok(
|
|
52
|
+
src.slice(savedToolsAssign, firstMutation).includes('tools: currentTools'),
|
|
53
|
+
'savedTools must include currentTools before the first scoping mutation',
|
|
45
54
|
)
|
|
46
55
|
})
|
|
47
56
|
|
|
57
|
+
it('scoping and workflow read happen inside the restore try block', () => {
|
|
58
|
+
const savedToolsDecl = src.indexOf('let savedTools')
|
|
59
|
+
const tryIdx = src.indexOf('try {', savedToolsDecl)
|
|
60
|
+
const firstMutation = src.indexOf('pi.setActiveTools(scopedTools)')
|
|
61
|
+
const workflowRead = src.indexOf('readFileSync(workflowPath')
|
|
62
|
+
const finallyIdx = src.indexOf('} finally {', tryIdx)
|
|
63
|
+
|
|
64
|
+
assert.ok(savedToolsDecl !== -1, 'savedTools variable must be declared')
|
|
65
|
+
assert.ok(tryIdx !== -1, 'restore try block must exist')
|
|
66
|
+
assert.ok(firstMutation !== -1, 'discuss scoping mutation must exist')
|
|
67
|
+
assert.ok(workflowRead !== -1, 'workflow file read must exist')
|
|
68
|
+
assert.ok(finallyIdx !== -1, 'restore finally block must exist')
|
|
69
|
+
assert.ok(tryIdx < firstMutation && firstMutation < finallyIdx, 'scoping mutation must be inside try/finally')
|
|
70
|
+
assert.ok(tryIdx < workflowRead && workflowRead < finallyIdx, 'workflow file read must be inside try/finally')
|
|
71
|
+
})
|
|
72
|
+
|
|
48
73
|
it('savedTools is restored after sendMessage', () => {
|
|
49
74
|
// #4573: guided-flow.ts now contains multiple `triggerTurn: true` calls
|
|
50
75
|
// (ready-phrase and empty-turn recovery paths). The discuss-flow scoping
|
|
51
|
-
// sendMessage is the one that follows `
|
|
76
|
+
// sendMessage is the one that follows `tools: currentTools`, so
|
|
52
77
|
// anchor the search there rather than at the first `triggerTurn: true`.
|
|
53
|
-
const savedToolsAssign = src.indexOf('
|
|
54
|
-
assert.ok(savedToolsAssign !== -1, 'savedTools
|
|
78
|
+
const savedToolsAssign = src.indexOf('tools: currentTools')
|
|
79
|
+
assert.ok(savedToolsAssign !== -1, 'savedTools must capture currentTools')
|
|
55
80
|
|
|
56
81
|
const sendMsg = src.indexOf('triggerTurn: true', savedToolsAssign)
|
|
57
82
|
assert.ok(sendMsg !== -1, 'discuss-flow sendMessage with triggerTurn must exist after savedTools capture')
|
|
58
83
|
|
|
59
|
-
// After sendMessage, savedTools should be restored via
|
|
84
|
+
// After sendMessage, savedTools should be restored via the shared helper.
|
|
60
85
|
// Use fromIdx to anchor at the discuss-flow sendMessage, not the first
|
|
61
86
|
// triggerTurn: true occurrence in the file.
|
|
62
87
|
const afterSend = extractSourceRegion(src, 'triggerTurn: true', { fromIdx: savedToolsAssign })
|
|
63
88
|
assert.ok(
|
|
64
|
-
afterSend.includes('
|
|
65
|
-
'savedTools
|
|
66
|
-
)
|
|
67
|
-
assert.ok(
|
|
68
|
-
afterSend.includes('setActiveTools(savedTools)'),
|
|
69
|
-
'setActiveTools(savedTools) must be called to restore the full tool set',
|
|
89
|
+
afterSend.includes('restoreGsdWorkflowTools(pi, savedTools)'),
|
|
90
|
+
'restoreGsdWorkflowTools(pi, savedTools) must restore the full scoped state',
|
|
70
91
|
)
|
|
71
92
|
})
|
|
72
93
|
})
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
7
|
+
|
|
8
|
+
import { buildCompleteMilestonePrompt, buildPlanMilestonePrompt } from "../auto-prompts.ts";
|
|
9
|
+
|
|
10
|
+
function git(cwd: string, args: string[]): string {
|
|
11
|
+
return execFileSync("git", args, {
|
|
12
|
+
cwd,
|
|
13
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
14
|
+
encoding: "utf-8",
|
|
15
|
+
env: { ...process.env, GIT_AUTHOR_NAME: "Test User", GIT_AUTHOR_EMAIL: "test@example.com", GIT_COMMITTER_NAME: "Test User", GIT_COMMITTER_EMAIL: "test@example.com" },
|
|
16
|
+
}).trim();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function makeRepo(files: Record<string, string>): string {
|
|
20
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-right-size-"));
|
|
21
|
+
git(base, ["init", "-b", "main"]);
|
|
22
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
23
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"), "# Context\n\nTest milestone.");
|
|
24
|
+
for (const [path, content] of Object.entries(files)) {
|
|
25
|
+
const abs = join(base, path);
|
|
26
|
+
mkdirSync(join(abs, ".."), { recursive: true });
|
|
27
|
+
writeFileSync(abs, content);
|
|
28
|
+
}
|
|
29
|
+
git(base, ["add", "."]);
|
|
30
|
+
git(base, ["commit", "-m", "init"]);
|
|
31
|
+
return base;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function writeCompleteMilestoneFiles(base: string, validation: string): void {
|
|
35
|
+
const dir = join(base, ".gsd", "milestones", "M001");
|
|
36
|
+
mkdirSync(join(dir, "slices", "S01"), { recursive: true });
|
|
37
|
+
writeFileSync(join(dir, "M001-ROADMAP.md"), "# M001\n\n## Slices\n- [x] **S01: One** `risk:low` `depends:[]`\n > Done\n");
|
|
38
|
+
writeFileSync(join(dir, "M001-VALIDATION.md"), validation);
|
|
39
|
+
writeFileSync(join(dir, "slices", "S01", "S01-SUMMARY.md"), "# S01 Summary\n\n**Verification:** passed\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function validationMetadata(): string {
|
|
43
|
+
return [
|
|
44
|
+
"validation_metadata:",
|
|
45
|
+
" covered_artifacts:",
|
|
46
|
+
" - `.gsd/milestones/M001/M001-VALIDATION.md`",
|
|
47
|
+
" - `.gsd/milestones/M001/M001-ROADMAP.md`",
|
|
48
|
+
" - `.gsd/milestones/M001/slices/S01/S01-SUMMARY.md`",
|
|
49
|
+
].join("\n");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
test("plan-milestone prompt includes tiny untyped project classification and one-slice guidance", async () => {
|
|
53
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
54
|
+
try {
|
|
55
|
+
const prompt = await buildPlanMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
56
|
+
assert.match(prompt, /\*\*Kind:\*\* untyped-existing/);
|
|
57
|
+
assert.match(prompt, /\*\*Content files:\*\* 1/);
|
|
58
|
+
assert.match(prompt, /`index\.html`/);
|
|
59
|
+
assert.match(prompt, /Prefer exactly one slice/);
|
|
60
|
+
} finally {
|
|
61
|
+
rmSync(base, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("plan-milestone prompt includes small untyped project 1-2 slice guidance", async () => {
|
|
66
|
+
const base = makeRepo({
|
|
67
|
+
"index.html": "html",
|
|
68
|
+
"README.md": "readme",
|
|
69
|
+
"styles.css": "body {}",
|
|
70
|
+
});
|
|
71
|
+
try {
|
|
72
|
+
const prompt = await buildPlanMilestonePrompt("M001", "Polish static files", base, "minimal");
|
|
73
|
+
assert.match(prompt, /\*\*Kind:\*\* untyped-existing/);
|
|
74
|
+
assert.match(prompt, /\*\*Content files:\*\* 3/);
|
|
75
|
+
assert.match(prompt, /Prefer 1-2 slices/);
|
|
76
|
+
} finally {
|
|
77
|
+
rmSync(base, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("plan-milestone prompt keeps normal guidance for typed projects", async () => {
|
|
82
|
+
const base = makeRepo({
|
|
83
|
+
"package.json": "{\"scripts\":{\"test\":\"node --test\"}}\n",
|
|
84
|
+
"src/index.js": "console.log('ok');\n",
|
|
85
|
+
});
|
|
86
|
+
try {
|
|
87
|
+
const prompt = await buildPlanMilestonePrompt("M001", "Update app", base, "minimal");
|
|
88
|
+
assert.match(prompt, /\*\*Kind:\*\* typed-existing/);
|
|
89
|
+
assert.match(prompt, /Use normal ecosystem-aware planning guidance/);
|
|
90
|
+
assert.doesNotMatch(prompt, /Prefer exactly one slice/);
|
|
91
|
+
} finally {
|
|
92
|
+
rmSync(base, { recursive: true, force: true });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("workflow docs no longer contain blanket 4-10 slice guidance", () => {
|
|
97
|
+
const docs = readFileSync(join(process.cwd(), "src", "resources", "GSD-WORKFLOW.md"), "utf-8");
|
|
98
|
+
assert.doesNotMatch(docs, /4-10 slices/);
|
|
99
|
+
assert.match(docs, /1-10 slices/);
|
|
100
|
+
assert.match(docs, /single-file/);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("prompt templates carry right-sized planning and closeout mode guidance", () => {
|
|
104
|
+
const planTemplate = readFileSync(join(process.cwd(), "src", "resources", "extensions", "gsd", "prompts", "plan-milestone.md"), "utf-8");
|
|
105
|
+
const completeTemplate = readFileSync(join(process.cwd(), "src", "resources", "extensions", "gsd", "prompts", "complete-milestone.md"), "utf-8");
|
|
106
|
+
|
|
107
|
+
assert.match(planTemplate, /Use 1-10 slices, sized to the work/);
|
|
108
|
+
assert.match(planTemplate, /tiny\/single-file\/static work should usually be one slice/);
|
|
109
|
+
assert.match(planTemplate, /untyped-existing/);
|
|
110
|
+
assert.match(completeTemplate, /Closeout Review Mode/);
|
|
111
|
+
assert.match(completeTemplate, /passing validation artifact is present/);
|
|
112
|
+
assert.doesNotMatch(completeTemplate, /^### Delegate Review Work/m);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("complete-milestone prompt trusts passing validation artifact", async () => {
|
|
116
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
117
|
+
try {
|
|
118
|
+
writeCompleteMilestoneFiles(base, `---\nverdict: pass\nremediation_round: 0\n---\n\n# Validation\n${validationMetadata()}\n\nAll checks passed.`);
|
|
119
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
120
|
+
assert.match(prompt, /Passing Validation Artifact/);
|
|
121
|
+
assert.match(prompt, /Treat it as authoritative/);
|
|
122
|
+
assert.match(prompt, /Do not delegate fresh reviewer\/security\/tester audits/);
|
|
123
|
+
assert.match(prompt, /All checks passed/);
|
|
124
|
+
} finally {
|
|
125
|
+
rmSync(base, { recursive: true, force: true });
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("complete-milestone prompt trusts centralized markdown body pass verdict", async () => {
|
|
130
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
131
|
+
try {
|
|
132
|
+
writeCompleteMilestoneFiles(base, `# Validation\n\n**Verdict:** PASS\n\n${validationMetadata()}\n\nAll checks passed.`);
|
|
133
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
134
|
+
assert.match(prompt, /Passing Validation Artifact/);
|
|
135
|
+
assert.match(prompt, /Treat it as authoritative/);
|
|
136
|
+
assert.match(prompt, /Do not delegate fresh reviewer\/security\/tester audits/);
|
|
137
|
+
} finally {
|
|
138
|
+
rmSync(base, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("complete-milestone prompt does not trust stale pass validation without metadata", async () => {
|
|
143
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
144
|
+
try {
|
|
145
|
+
writeCompleteMilestoneFiles(base, "---\nverdict: pass\nremediation_round: 0\n---\n\n# Validation\nAll checks passed.");
|
|
146
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
147
|
+
assert.match(prompt, /Validation Requires Attention/);
|
|
148
|
+
assert.match(prompt, /missing freshness metadata/);
|
|
149
|
+
assert.doesNotMatch(prompt, /Passing Validation Artifact/);
|
|
150
|
+
} finally {
|
|
151
|
+
rmSync(base, { recursive: true, force: true });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("complete-milestone prompt does not trust pass validation missing current summary coverage", async () => {
|
|
156
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
157
|
+
try {
|
|
158
|
+
writeCompleteMilestoneFiles(base, [
|
|
159
|
+
"---",
|
|
160
|
+
"verdict: pass",
|
|
161
|
+
"remediation_round: 0",
|
|
162
|
+
"---",
|
|
163
|
+
"",
|
|
164
|
+
"# Validation",
|
|
165
|
+
"validation_metadata:",
|
|
166
|
+
" covered_artifacts:",
|
|
167
|
+
" - `.gsd/milestones/M001/M001-VALIDATION.md`",
|
|
168
|
+
" - `.gsd/milestones/M001/M001-ROADMAP.md`",
|
|
169
|
+
"",
|
|
170
|
+
"All checks passed.",
|
|
171
|
+
].join("\n"));
|
|
172
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
173
|
+
assert.match(prompt, /Validation Requires Attention/);
|
|
174
|
+
assert.match(prompt, /does not cover current milestone artifacts/);
|
|
175
|
+
assert.doesNotMatch(prompt, /Passing Validation Artifact/);
|
|
176
|
+
} finally {
|
|
177
|
+
rmSync(base, { recursive: true, force: true });
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("complete-milestone prompt keeps deeper review path without passing validation", async () => {
|
|
182
|
+
const base = makeRepo({ "index.html": "<!doctype html>\n<title>Test</title>\n" });
|
|
183
|
+
try {
|
|
184
|
+
writeCompleteMilestoneFiles(base, "---\nverdict: needs-attention\nremediation_round: 0\n---\n\n# Validation\nFix gaps.");
|
|
185
|
+
const prompt = await buildCompleteMilestonePrompt("M001", "Polish static page", base, "minimal");
|
|
186
|
+
assert.match(prompt, /Validation Requires Attention/);
|
|
187
|
+
assert.match(prompt, /verdict `needs-attention`/);
|
|
188
|
+
assert.match(prompt, /Use `subagent` for review work needing fresh context/i);
|
|
189
|
+
} finally {
|
|
190
|
+
rmSync(base, { recursive: true, force: true });
|
|
191
|
+
}
|
|
192
|
+
});
|