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
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
3
6
|
|
|
4
7
|
import { runFinalize } from "../auto/phases.ts";
|
|
5
8
|
import { AutoSession } from "../auto/session.ts";
|
|
9
|
+
import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "../unit-runtime.ts";
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
11
|
+
async function runSuccessfulFinalize(s: AutoSession) {
|
|
12
|
+
const unit = s.currentUnit;
|
|
13
|
+
assert.ok(unit, "test setup must provide currentUnit");
|
|
14
|
+
|
|
15
|
+
writeUnitRuntimeRecord(s.basePath, unit.type, unit.id, unit.startedAt, {
|
|
16
|
+
phase: "dispatched",
|
|
17
|
+
});
|
|
15
18
|
|
|
16
19
|
const deps = {
|
|
17
20
|
clearUnitTimeout() {},
|
|
@@ -26,7 +29,7 @@ test("runFinalize clears currentUnit after successful finalize", async () => {
|
|
|
26
29
|
postUnitPostVerification: async () => "continue",
|
|
27
30
|
};
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
return runFinalize(
|
|
30
33
|
{
|
|
31
34
|
ctx: { ui: { notify() {} } },
|
|
32
35
|
pi: {},
|
|
@@ -38,8 +41,8 @@ test("runFinalize clears currentUnit after successful finalize", async () => {
|
|
|
38
41
|
nextSeq: () => 1,
|
|
39
42
|
} as any,
|
|
40
43
|
{
|
|
41
|
-
unitType:
|
|
42
|
-
unitId:
|
|
44
|
+
unitType: unit.type,
|
|
45
|
+
unitId: unit.id,
|
|
43
46
|
prompt: "",
|
|
44
47
|
finalPrompt: "",
|
|
45
48
|
pauseAfterUatDispatch: false,
|
|
@@ -55,7 +58,47 @@ test("runFinalize clears currentUnit after successful finalize", async () => {
|
|
|
55
58
|
consecutiveFinalizeTimeouts: 0,
|
|
56
59
|
},
|
|
57
60
|
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
test("runFinalize clears currentUnit after successful finalize", async () => {
|
|
64
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-finalize-current-unit-"));
|
|
65
|
+
const s = new AutoSession();
|
|
66
|
+
s.basePath = base;
|
|
67
|
+
s.currentUnit = {
|
|
68
|
+
type: "execute-task",
|
|
69
|
+
id: "M001/S01/T01",
|
|
70
|
+
startedAt: Date.now(),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const result = await runSuccessfulFinalize(s);
|
|
75
|
+
|
|
76
|
+
assert.equal(result.action, "next");
|
|
77
|
+
assert.equal(s.currentUnit, null);
|
|
78
|
+
} finally {
|
|
79
|
+
rmSync(base, { recursive: true, force: true });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("runFinalize marks unit runtime finalized after successful finalize", async () => {
|
|
84
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-finalize-runtime-"));
|
|
85
|
+
const s = new AutoSession();
|
|
86
|
+
const startedAt = Date.now();
|
|
87
|
+
s.basePath = base;
|
|
88
|
+
s.currentUnit = {
|
|
89
|
+
type: "complete-milestone",
|
|
90
|
+
id: "M001",
|
|
91
|
+
startedAt,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const result = await runSuccessfulFinalize(s);
|
|
96
|
+
const runtime = readUnitRuntimeRecord(base, "complete-milestone", "M001");
|
|
58
97
|
|
|
59
|
-
|
|
60
|
-
|
|
98
|
+
assert.equal(result.action, "next");
|
|
99
|
+
assert.equal(runtime?.phase, "finalized");
|
|
100
|
+
assert.equal(runtime?.lastProgressKind, "finalize-success");
|
|
101
|
+
} finally {
|
|
102
|
+
rmSync(base, { recursive: true, force: true });
|
|
103
|
+
}
|
|
61
104
|
});
|
|
@@ -5,13 +5,14 @@ import { join } from "node:path";
|
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
|
|
8
|
-
import { verifyExpectedArtifact, hasImplementationArtifacts, resolveExpectedArtifactPath, diagnoseExpectedArtifact, buildLoopRemediationSteps, writeBlockerPlaceholder } from "../auto-recovery.ts";
|
|
8
|
+
import { verifyExpectedArtifact, hasImplementationArtifacts, resolveExpectedArtifactPath, diagnoseExpectedArtifact, buildLoopRemediationSteps, writeBlockerPlaceholder, refreshRecoveryDbForArtifact } from "../auto-recovery.ts";
|
|
9
9
|
import { resolveMilestoneFile } from "../paths.ts";
|
|
10
|
-
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertGateRow, insertTask } from "../gsd-db.ts";
|
|
10
|
+
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertGateRow, insertTask, getMilestoneCommitAttributionShas } from "../gsd-db.ts";
|
|
11
11
|
import { clearParseCache } from "../files.ts";
|
|
12
12
|
import { parseRoadmap } from "../parsers-legacy.ts";
|
|
13
13
|
import { invalidateAllCaches } from "../cache.ts";
|
|
14
14
|
import { deriveState, invalidateStateCache } from "../state.ts";
|
|
15
|
+
import { writeIntegrationBranch } from "../git-service.ts";
|
|
15
16
|
|
|
16
17
|
const tmpDirs: string[] = [];
|
|
17
18
|
|
|
@@ -174,6 +175,19 @@ test("resolveExpectedArtifactPath returns correct path for all slice-level types
|
|
|
174
175
|
}
|
|
175
176
|
});
|
|
176
177
|
|
|
178
|
+
test("refreshRecoveryDbForArtifact treats missing execute-task DB rows as fatal mismatches", () => {
|
|
179
|
+
makeTmpProject();
|
|
180
|
+
|
|
181
|
+
const result = refreshRecoveryDbForArtifact("execute-task", "M001/S01/T01");
|
|
182
|
+
|
|
183
|
+
assert.deepEqual(result, {
|
|
184
|
+
ok: false,
|
|
185
|
+
fatal: true,
|
|
186
|
+
reason: "execute-task-artifact-db-missing",
|
|
187
|
+
message: "Stuck recovery found execute-task M001/S01/T01 artifacts, but no matching DB task row exists after refresh.",
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
177
191
|
// ─── diagnoseExpectedArtifact ─────────────────────────────────────────────
|
|
178
192
|
|
|
179
193
|
test("diagnoseExpectedArtifact returns description for known types", () => {
|
|
@@ -735,6 +749,174 @@ test("hasImplementationArtifacts rejects milestone-scoped main history with only
|
|
|
735
749
|
}
|
|
736
750
|
});
|
|
737
751
|
|
|
752
|
+
test("hasImplementationArtifacts finds integration implementation-only commits when milestone branch diff is .gsd-only", () => {
|
|
753
|
+
const base = makeGitBase();
|
|
754
|
+
try {
|
|
755
|
+
mkdirSync(join(base, "src"), { recursive: true });
|
|
756
|
+
writeFileSync(join(base, "src", "feature.ts"), "export function feature() {}\n");
|
|
757
|
+
execFileSync("git", ["add", "src/feature.ts"], { cwd: base, stdio: "ignore" });
|
|
758
|
+
execFileSync("git", ["commit", "-m", "feat: add milestone feature\n\nGSD-Task: S01/T01"], { cwd: base, stdio: "ignore" });
|
|
759
|
+
|
|
760
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
761
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
762
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
|
|
763
|
+
insertSlice({
|
|
764
|
+
id: "S01",
|
|
765
|
+
milestoneId: "M001",
|
|
766
|
+
title: "Slice One",
|
|
767
|
+
status: "complete",
|
|
768
|
+
risk: "low",
|
|
769
|
+
depends: [],
|
|
770
|
+
});
|
|
771
|
+
insertTask({
|
|
772
|
+
id: "T01",
|
|
773
|
+
sliceId: "S01",
|
|
774
|
+
milestoneId: "M001",
|
|
775
|
+
title: "Task One",
|
|
776
|
+
status: "complete",
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
execFileSync("git", ["checkout", "-b", "milestone/M001"], { cwd: base, stdio: "ignore" });
|
|
780
|
+
writeIntegrationBranch(base, "M001", "main");
|
|
781
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"), "# Milestone Summary\nDone.");
|
|
782
|
+
execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
|
|
783
|
+
execFileSync("git", ["commit", "-m", "chore: auto-commit after complete-milestone\n\nGSD-Unit: M001"], { cwd: base, stdio: "ignore" });
|
|
784
|
+
|
|
785
|
+
const result = hasImplementationArtifacts(base, "M001");
|
|
786
|
+
assert.equal(
|
|
787
|
+
result,
|
|
788
|
+
"present",
|
|
789
|
+
".gsd-only milestone closeout diffs should still honor implementation commits already on the integration branch",
|
|
790
|
+
);
|
|
791
|
+
} finally {
|
|
792
|
+
cleanup(base);
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
test("hasImplementationArtifacts backfills untagged main implementation commits from completed task file hints", () => {
|
|
797
|
+
const base = makeGitBase();
|
|
798
|
+
try {
|
|
799
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
800
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
801
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
|
|
802
|
+
insertSlice({
|
|
803
|
+
id: "S01",
|
|
804
|
+
milestoneId: "M001",
|
|
805
|
+
title: "Slice One",
|
|
806
|
+
status: "complete",
|
|
807
|
+
risk: "low",
|
|
808
|
+
depends: [],
|
|
809
|
+
});
|
|
810
|
+
insertTask({
|
|
811
|
+
id: "T01",
|
|
812
|
+
sliceId: "S01",
|
|
813
|
+
milestoneId: "M001",
|
|
814
|
+
title: "Task One",
|
|
815
|
+
status: "complete",
|
|
816
|
+
keyFiles: ["index.html", "style.css", "app.js"],
|
|
817
|
+
planning: { files: ["index.html", "style.css", "app.js"] },
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
writeFileSync(join(base, "index.html"), "<main></main>\n");
|
|
821
|
+
writeFileSync(join(base, "style.css"), "main { display: block; }\n");
|
|
822
|
+
writeFileSync(join(base, "app.js"), "document.body.dataset.ready = 'true';\n");
|
|
823
|
+
execFileSync("git", ["add", "index.html", "style.css", "app.js"], { cwd: base, stdio: "ignore" });
|
|
824
|
+
execFileSync("git", ["commit", "-m", "feat: add to-do app with CRUD and localStorage persistence"], { cwd: base, stdio: "ignore" });
|
|
825
|
+
const commitSha = execFileSync("git", ["rev-parse", "HEAD"], { cwd: base, encoding: "utf-8" }).trim();
|
|
826
|
+
|
|
827
|
+
const result = hasImplementationArtifacts(base, "M001");
|
|
828
|
+
assert.equal(
|
|
829
|
+
result,
|
|
830
|
+
"present",
|
|
831
|
+
"completed task file hints should repair prior untagged implementation commits on main",
|
|
832
|
+
);
|
|
833
|
+
assert.deepEqual(getMilestoneCommitAttributionShas("M001"), [commitSha]);
|
|
834
|
+
} finally {
|
|
835
|
+
cleanup(base);
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
|
|
839
|
+
test("hasImplementationArtifacts does not backfill untagged commits before milestone creation", () => {
|
|
840
|
+
const base = makeGitBase();
|
|
841
|
+
try {
|
|
842
|
+
writeFileSync(join(base, "app.js"), "document.body.dataset.ready = 'old';\n");
|
|
843
|
+
execFileSync("git", ["add", "app.js"], { cwd: base, stdio: "ignore" });
|
|
844
|
+
execFileSync("git", ["commit", "-m", "feat: old app work"], {
|
|
845
|
+
cwd: base,
|
|
846
|
+
stdio: "ignore",
|
|
847
|
+
env: {
|
|
848
|
+
...process.env,
|
|
849
|
+
GIT_AUTHOR_DATE: "2020-01-01T00:00:00Z",
|
|
850
|
+
GIT_COMMITTER_DATE: "2020-01-01T00:00:00Z",
|
|
851
|
+
},
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
855
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
856
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
|
|
857
|
+
insertSlice({
|
|
858
|
+
id: "S01",
|
|
859
|
+
milestoneId: "M001",
|
|
860
|
+
title: "Slice One",
|
|
861
|
+
status: "complete",
|
|
862
|
+
risk: "low",
|
|
863
|
+
depends: [],
|
|
864
|
+
});
|
|
865
|
+
insertTask({
|
|
866
|
+
id: "T01",
|
|
867
|
+
sliceId: "S01",
|
|
868
|
+
milestoneId: "M001",
|
|
869
|
+
title: "Task One",
|
|
870
|
+
status: "complete",
|
|
871
|
+
keyFiles: ["app.js"],
|
|
872
|
+
planning: { files: ["app.js"] },
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
const result = hasImplementationArtifacts(base, "M001");
|
|
876
|
+
assert.equal(result, "absent", "pre-milestone commits must not be attributed to the milestone");
|
|
877
|
+
assert.deepEqual(getMilestoneCommitAttributionShas("M001"), []);
|
|
878
|
+
} finally {
|
|
879
|
+
cleanup(base);
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
test("hasImplementationArtifacts does not backfill unrelated untagged implementation commits", () => {
|
|
884
|
+
const base = makeGitBase();
|
|
885
|
+
try {
|
|
886
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
887
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
888
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "active" });
|
|
889
|
+
insertSlice({
|
|
890
|
+
id: "S01",
|
|
891
|
+
milestoneId: "M001",
|
|
892
|
+
title: "Slice One",
|
|
893
|
+
status: "complete",
|
|
894
|
+
risk: "low",
|
|
895
|
+
depends: [],
|
|
896
|
+
});
|
|
897
|
+
insertTask({
|
|
898
|
+
id: "T01",
|
|
899
|
+
sliceId: "S01",
|
|
900
|
+
milestoneId: "M001",
|
|
901
|
+
title: "Task One",
|
|
902
|
+
status: "complete",
|
|
903
|
+
keyFiles: ["src/expected.ts"],
|
|
904
|
+
planning: { files: ["src/expected.ts"] },
|
|
905
|
+
});
|
|
906
|
+
|
|
907
|
+
mkdirSync(join(base, "src"), { recursive: true });
|
|
908
|
+
writeFileSync(join(base, "src", "unrelated.ts"), "export const unrelated = true;\n");
|
|
909
|
+
execFileSync("git", ["add", "src/unrelated.ts"], { cwd: base, stdio: "ignore" });
|
|
910
|
+
execFileSync("git", ["commit", "-m", "feat: unrelated work"], { cwd: base, stdio: "ignore" });
|
|
911
|
+
|
|
912
|
+
const result = hasImplementationArtifacts(base, "M001");
|
|
913
|
+
assert.equal(result, "absent", "backfill must require overlap with completed task file hints");
|
|
914
|
+
assert.deepEqual(getMilestoneCommitAttributionShas("M001"), []);
|
|
915
|
+
} finally {
|
|
916
|
+
cleanup(base);
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
|
|
738
920
|
test("hasImplementationArtifacts treats empty non-integration branch diff as absent (#4699)", () => {
|
|
739
921
|
const base = makeGitBase();
|
|
740
922
|
try {
|
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
|
|
4
4
|
import { describe, test } from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
|
-
import { readFileSync } from "node:fs";
|
|
6
|
+
import { mkdtempSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
|
|
10
|
+
import { autoSession } from "../auto-runtime-state.ts";
|
|
11
|
+
import { dispatchHookUnit } from "../auto.ts";
|
|
12
|
+
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
13
|
+
import { clearDiscussionFlowState, getPendingGate } from "../bootstrap/write-gate.ts";
|
|
8
14
|
|
|
9
15
|
const autoTimersPath = join(import.meta.dirname, "..", "auto-timers.ts");
|
|
10
16
|
const autoTimersSrc = readFileSync(autoTimersPath, "utf-8");
|
|
@@ -18,6 +24,37 @@ const runUnitSrc = readFileSync(runUnitPath, "utf-8");
|
|
|
18
24
|
const registerHooksPath = join(import.meta.dirname, "..", "bootstrap", "register-hooks.ts");
|
|
19
25
|
const registerHooksSrc = readFileSync(registerHooksPath, "utf-8");
|
|
20
26
|
|
|
27
|
+
function makeHookHarness() {
|
|
28
|
+
const handlers = new Map<string, Array<(event: any, ctx: any) => Promise<any>>>();
|
|
29
|
+
const pi = {
|
|
30
|
+
on(name: string, handler: (event: any, ctx: any) => Promise<any>) {
|
|
31
|
+
const current = handlers.get(name) ?? [];
|
|
32
|
+
current.push(handler);
|
|
33
|
+
handlers.set(name, current);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
const ctx = {
|
|
37
|
+
ui: {
|
|
38
|
+
notify: () => {},
|
|
39
|
+
setStatus: () => {},
|
|
40
|
+
setWidget: () => {},
|
|
41
|
+
},
|
|
42
|
+
modelRegistry: {
|
|
43
|
+
setDisabledModelProviders: () => {},
|
|
44
|
+
},
|
|
45
|
+
setCompactionThresholdOverride: () => {},
|
|
46
|
+
};
|
|
47
|
+
async function emit(name: string, event: any): Promise<any> {
|
|
48
|
+
for (const handler of handlers.get(name) ?? []) {
|
|
49
|
+
const result = await handler(event, ctx);
|
|
50
|
+
if (result?.block) return result;
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
registerHooks(pi as any, []);
|
|
55
|
+
return { emit };
|
|
56
|
+
}
|
|
57
|
+
|
|
21
58
|
describe("#3512: gsd-auto-wrapup must not interrupt in-flight tool calls", () => {
|
|
22
59
|
test("soft timeout wrapup gates triggerTurn on getInFlightToolCount() === 0", () => {
|
|
23
60
|
// The soft timeout sendMessage must NOT use a hardcoded `triggerTurn: true`.
|
|
@@ -73,10 +110,65 @@ describe("#3512: gsd-auto-wrapup must not interrupt in-flight tool calls", () =>
|
|
|
73
110
|
});
|
|
74
111
|
});
|
|
75
112
|
|
|
113
|
+
describe("hook dispatch session workspace root", () => {
|
|
114
|
+
test("dispatchHookUnit passes basePath explicitly to newSession", async (t) => {
|
|
115
|
+
const originalCwd = process.cwd();
|
|
116
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-hook-cwd-"));
|
|
117
|
+
mkdirSync(join(basePath, ".gsd"), { recursive: true });
|
|
118
|
+
autoSession.reset();
|
|
119
|
+
t.after(() => {
|
|
120
|
+
try {
|
|
121
|
+
process.chdir(originalCwd);
|
|
122
|
+
} catch {
|
|
123
|
+
// best effort cleanup after cwd-sensitive dispatch tests
|
|
124
|
+
}
|
|
125
|
+
autoSession.reset();
|
|
126
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
let newSessionOptions: unknown;
|
|
130
|
+
const ctx = {
|
|
131
|
+
ui: {
|
|
132
|
+
notify: () => {},
|
|
133
|
+
setStatus: () => {},
|
|
134
|
+
setWidget: () => {},
|
|
135
|
+
},
|
|
136
|
+
modelRegistry: {
|
|
137
|
+
getAvailable: () => [],
|
|
138
|
+
},
|
|
139
|
+
sessionManager: {
|
|
140
|
+
getSessionFile: () => join(basePath, "session.jsonl"),
|
|
141
|
+
},
|
|
142
|
+
newSession: async (options?: unknown) => {
|
|
143
|
+
newSessionOptions = options;
|
|
144
|
+
return { cancelled: false };
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
const pi = {
|
|
148
|
+
sendMessage: () => {},
|
|
149
|
+
setModel: async () => true,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const dispatched = await dispatchHookUnit(
|
|
153
|
+
ctx as any,
|
|
154
|
+
pi as any,
|
|
155
|
+
"review",
|
|
156
|
+
"execute-task",
|
|
157
|
+
"M001/S01/T01",
|
|
158
|
+
"review the completed unit",
|
|
159
|
+
undefined,
|
|
160
|
+
basePath,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
assert.equal(dispatched, true);
|
|
164
|
+
assert.deepEqual(newSessionOptions, { workspaceRoot: basePath });
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
76
168
|
describe("#4276: pending/skipped tools stay visible to auto-mode hooks", () => {
|
|
77
169
|
test("tool_call handler marks GSD tools in-flight before execution_start", () => {
|
|
78
170
|
const startMarker = 'pi.on("tool_call", async (event, ctx) => {';
|
|
79
|
-
const endMarker = 'pi.on("tool_result", async (event) => {';
|
|
171
|
+
const endMarker = 'pi.on("tool_result", async (event, ctx) => {';
|
|
80
172
|
const toolCallSection = registerHooksSrc.slice(
|
|
81
173
|
registerHooksSrc.indexOf(startMarker),
|
|
82
174
|
registerHooksSrc.indexOf(endMarker),
|
|
@@ -90,7 +182,7 @@ describe("#4276: pending/skipped tools stay visible to auto-mode hooks", () => {
|
|
|
90
182
|
});
|
|
91
183
|
|
|
92
184
|
test("tool_result handler clears pending tools and records queued-skip errors", () => {
|
|
93
|
-
const startMarker = 'pi.on("tool_result", async (event) => {';
|
|
185
|
+
const startMarker = 'pi.on("tool_result", async (event, ctx) => {';
|
|
94
186
|
const endMarker = 'pi.on("tool_execution_start", async (event) => {';
|
|
95
187
|
const toolResultSection = registerHooksSrc.slice(
|
|
96
188
|
registerHooksSrc.indexOf(startMarker),
|
|
@@ -193,7 +285,7 @@ describe("#4365: tool_execution_start hook must pass toolName to markToolStart",
|
|
|
193
285
|
});
|
|
194
286
|
|
|
195
287
|
describe("deep setup approval questions pause immediately", () => {
|
|
196
|
-
test("register-hooks
|
|
288
|
+
test("register-hooks defers the pending gate during message_update without aborting the stream", () => {
|
|
197
289
|
const startMarker = 'pi.on("message_update"';
|
|
198
290
|
const endMarker = 'pi.on("session_shutdown"';
|
|
199
291
|
const messageUpdateSection = registerHooksSrc.slice(
|
|
@@ -210,8 +302,8 @@ describe("deep setup approval questions pause immediately", () => {
|
|
|
210
302
|
"message_update must detect approval/question boundaries",
|
|
211
303
|
);
|
|
212
304
|
assert.ok(
|
|
213
|
-
messageUpdateSection.includes("approvalGateIdForUnit") && messageUpdateSection.includes("
|
|
214
|
-
"plain-text approval questions must
|
|
305
|
+
messageUpdateSection.includes("approvalGateIdForUnit") && messageUpdateSection.includes("deferApprovalGate"),
|
|
306
|
+
"plain-text approval questions must defer the durable write gate until same-turn draft persistence can finish",
|
|
215
307
|
);
|
|
216
308
|
assert.ok(
|
|
217
309
|
messageUpdateSection.includes("getDiscussionMilestoneIdFor") && messageUpdateSection.includes('"discuss-milestone"'),
|
|
@@ -222,4 +314,74 @@ describe("deep setup approval questions pause immediately", () => {
|
|
|
222
314
|
"message_update must NOT abort the stream — aborting eats the model's question text on external CLI providers; the pending gate set above blocks subsequent tool calls instead",
|
|
223
315
|
);
|
|
224
316
|
});
|
|
317
|
+
|
|
318
|
+
test("plain-text approval boundary defers durable gate until same-turn CONTEXT-DRAFT can save", async () => {
|
|
319
|
+
const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-deferred-approval-")));
|
|
320
|
+
const previousCwd = process.cwd();
|
|
321
|
+
try {
|
|
322
|
+
mkdirSync(join(base, ".gsd", "milestones", "M003"), { recursive: true });
|
|
323
|
+
process.chdir(base);
|
|
324
|
+
clearDiscussionFlowState(base);
|
|
325
|
+
autoSession.reset();
|
|
326
|
+
autoSession.basePath = base;
|
|
327
|
+
autoSession.currentUnit = {
|
|
328
|
+
type: "discuss-milestone",
|
|
329
|
+
id: "M003",
|
|
330
|
+
startedAt: Date.now(),
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const { emit } = makeHookHarness();
|
|
334
|
+
await emit("message_update", {
|
|
335
|
+
message: {
|
|
336
|
+
role: "assistant",
|
|
337
|
+
content: [{ type: "text", text: "Did I capture that correctly? If not, tell me what I missed." }],
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
assert.equal(
|
|
342
|
+
getPendingGate(base),
|
|
343
|
+
null,
|
|
344
|
+
"approval text should not install the durable pending gate until the assistant turn ends",
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
const draftResult = await emit("tool_call", {
|
|
348
|
+
toolCallId: "draft-save",
|
|
349
|
+
toolName: "gsd_summary_save",
|
|
350
|
+
input: {
|
|
351
|
+
milestone_id: "M003",
|
|
352
|
+
artifact_type: "CONTEXT-DRAFT",
|
|
353
|
+
content: "# M003 Draft\n",
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
assert.equal(
|
|
357
|
+
draftResult?.block,
|
|
358
|
+
undefined,
|
|
359
|
+
"same-turn CONTEXT-DRAFT persistence should remain allowed after the approval text streams",
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const finalContextResult = await emit("tool_call", {
|
|
363
|
+
toolCallId: "final-context",
|
|
364
|
+
toolName: "gsd_summary_save",
|
|
365
|
+
input: {
|
|
366
|
+
milestone_id: "M003",
|
|
367
|
+
artifact_type: "CONTEXT",
|
|
368
|
+
content: "# M003 Context\n",
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
assert.equal(finalContextResult?.block, true, "final CONTEXT must still wait for approval");
|
|
372
|
+
assert.match(finalContextResult.reason, /Approval question "depth_verification_M003_confirm"/);
|
|
373
|
+
|
|
374
|
+
await emit("agent_end", { messages: [] });
|
|
375
|
+
assert.equal(
|
|
376
|
+
getPendingGate(base),
|
|
377
|
+
"depth_verification_M003_confirm",
|
|
378
|
+
"agent_end should activate the durable pending gate for the next turn",
|
|
379
|
+
);
|
|
380
|
+
} finally {
|
|
381
|
+
process.chdir(previousCwd);
|
|
382
|
+
autoSession.reset();
|
|
383
|
+
clearDiscussionFlowState(base);
|
|
384
|
+
rmSync(base, { recursive: true, force: true });
|
|
385
|
+
}
|
|
386
|
+
});
|
|
225
387
|
});
|
|
@@ -131,9 +131,11 @@ test("postflightPopStash — restores stashed changes and emits info notificatio
|
|
|
131
131
|
run('git commit -m "simulate merge"', repo);
|
|
132
132
|
|
|
133
133
|
const postNotifications: Array<{ msg: string; level: string }> = [];
|
|
134
|
-
postflightPopStash(repo, "M004", (msg, level) => {
|
|
134
|
+
const postflight = postflightPopStash(repo, "M004", preflight.stashMarker, (msg, level) => {
|
|
135
135
|
postNotifications.push({ msg, level });
|
|
136
136
|
});
|
|
137
|
+
assert.equal(postflight.restored, true, "postflight must report successful restore");
|
|
138
|
+
assert.equal(postflight.needsManualRecovery, false, "successful restore must not need manual recovery");
|
|
137
139
|
|
|
138
140
|
// The stashed README.md change must be restored
|
|
139
141
|
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
@@ -171,7 +173,8 @@ test("preflight + merge + postflight round-trip preserves uncommitted changes",
|
|
|
171
173
|
run('git commit -m "feat: add feature"', repo);
|
|
172
174
|
|
|
173
175
|
// Postflight: pop stash
|
|
174
|
-
postflightPopStash(repo, "M005", () => {});
|
|
176
|
+
const postflight = postflightPopStash(repo, "M005", preflight.stashMarker, () => {});
|
|
177
|
+
assert.equal(postflight.needsManualRecovery, false, "clean restore must not stop auto-mode");
|
|
175
178
|
|
|
176
179
|
// README.md must still have our local content
|
|
177
180
|
const restored = readFileSync(join(repo, "README.md"), "utf-8");
|
|
@@ -184,3 +187,95 @@ test("preflight + merge + postflight round-trip preserves uncommitted changes",
|
|
|
184
187
|
try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
|
|
185
188
|
}
|
|
186
189
|
});
|
|
190
|
+
|
|
191
|
+
test("postflightPopStash conflict warning names the exact stash ref", () => {
|
|
192
|
+
const repo = createTempRepo();
|
|
193
|
+
try {
|
|
194
|
+
writeFileSync(join(repo, "README.md"), "# local work\n");
|
|
195
|
+
const preflight = preflightCleanRoot(repo, "M005C", () => {});
|
|
196
|
+
assert.equal(preflight.stashPushed, true, "must have stashed");
|
|
197
|
+
|
|
198
|
+
writeFileSync(join(repo, "README.md"), "# merged work\n");
|
|
199
|
+
run("git add README.md", repo);
|
|
200
|
+
run('git commit -m "simulate conflicting merge"', repo);
|
|
201
|
+
|
|
202
|
+
const notifications: Array<{ msg: string; level: string }> = [];
|
|
203
|
+
const postflight = postflightPopStash(repo, "M005C", preflight.stashMarker, (msg, level) => {
|
|
204
|
+
notifications.push({ msg, level });
|
|
205
|
+
});
|
|
206
|
+
assert.equal(postflight.restored, false, "conflicted restore must report restored=false");
|
|
207
|
+
assert.equal(postflight.needsManualRecovery, true, "conflicted restore must require manual recovery");
|
|
208
|
+
assert.match(postflight.message, /failed after merge of milestone M005C/);
|
|
209
|
+
|
|
210
|
+
const warning = notifications.find((n) => n.level === "warning")?.msg ?? "";
|
|
211
|
+
assert.match(warning, /git stash pop stash@\{\d+\}/);
|
|
212
|
+
assert.match(warning, /git stash apply stash@\{\d+\}/);
|
|
213
|
+
} finally {
|
|
214
|
+
try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("postflightPopStash restores the matching GSD stash, not stash@{0}", () => {
|
|
219
|
+
const repo = createTempRepo();
|
|
220
|
+
try {
|
|
221
|
+
writeFileSync(join(repo, "README.md"), "# target stash\n");
|
|
222
|
+
const preflight = preflightCleanRoot(repo, "M006", () => {});
|
|
223
|
+
assert.equal(preflight.stashPushed, true, "must have stashed target change");
|
|
224
|
+
|
|
225
|
+
writeFileSync(join(repo, "other.txt"), "other stash\n");
|
|
226
|
+
run('git stash push --include-untracked -m "unrelated newer stash"', repo);
|
|
227
|
+
|
|
228
|
+
const postflight = postflightPopStash(repo, "M006", preflight.stashMarker, () => {});
|
|
229
|
+
assert.equal(postflight.needsManualRecovery, false, "targeted restore must not need manual recovery");
|
|
230
|
+
|
|
231
|
+
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
232
|
+
assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
|
|
233
|
+
const stashList = run("git stash list", repo);
|
|
234
|
+
assert.ok(stashList.includes("unrelated newer stash"), "unrelated newer stash must remain");
|
|
235
|
+
assert.ok(!stashList.includes("gsd-preflight-stash [gsd-preflight-stash:M006"), "target stash should be consumed");
|
|
236
|
+
} finally {
|
|
237
|
+
try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test("postflightPopStash restores the exact preflight marker when another same-milestone stash exists", () => {
|
|
242
|
+
const repo = createTempRepo();
|
|
243
|
+
try {
|
|
244
|
+
writeFileSync(join(repo, "README.md"), "# target stash\n");
|
|
245
|
+
const preflight = preflightCleanRoot(repo, "M007", () => {});
|
|
246
|
+
assert.equal(preflight.stashPushed, true, "must have stashed target change");
|
|
247
|
+
assert.ok(preflight.stashMarker, "preflight must expose exact stash marker");
|
|
248
|
+
|
|
249
|
+
writeFileSync(join(repo, "same-milestone.txt"), "newer same milestone stash\n");
|
|
250
|
+
run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M007:other]"', repo);
|
|
251
|
+
|
|
252
|
+
const postflight = postflightPopStash(repo, "M007", preflight.stashMarker, () => {});
|
|
253
|
+
assert.equal(postflight.needsManualRecovery, false, "exact marker restore must not need manual recovery");
|
|
254
|
+
|
|
255
|
+
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
256
|
+
assert.equal(content.replace(/\r\n/g, "\n"), "# target stash\n");
|
|
257
|
+
const stashList = run("git stash list", repo);
|
|
258
|
+
assert.ok(stashList.includes("gsd-preflight-stash:M007:other"), "newer same-milestone stash must remain");
|
|
259
|
+
assert.ok(!stashList.includes(preflight.stashMarker), "exact target stash should be consumed");
|
|
260
|
+
} finally {
|
|
261
|
+
try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test("postflightPopStash falls back to milestone marker prefix when exact marker is unavailable", () => {
|
|
266
|
+
const repo = createTempRepo();
|
|
267
|
+
try {
|
|
268
|
+
writeFileSync(join(repo, "README.md"), "# fallback stash\n");
|
|
269
|
+
run('git stash push --include-untracked -m "gsd-preflight-stash [gsd-preflight-stash:M008:fallback]"', repo);
|
|
270
|
+
|
|
271
|
+
const postflight = postflightPopStash(repo, "M008", undefined, () => {});
|
|
272
|
+
assert.equal(postflight.needsManualRecovery, false, "fallback marker restore must not need manual recovery");
|
|
273
|
+
|
|
274
|
+
const content = readFileSync(join(repo, "README.md"), "utf-8");
|
|
275
|
+
assert.equal(content.replace(/\r\n/g, "\n"), "# fallback stash\n");
|
|
276
|
+
const stashList = run("git stash list", repo);
|
|
277
|
+
assert.ok(!stashList.includes("gsd-preflight-stash:M008:fallback"), "fallback stash should be consumed");
|
|
278
|
+
} finally {
|
|
279
|
+
try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
|
|
280
|
+
}
|
|
281
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD2 commands-extract-learnings tests
|
|
1
2
|
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
2
3
|
import assert from "node:assert/strict";
|
|
3
4
|
import { mkdirSync, writeFileSync, rmSync, readFileSync } from "node:fs";
|
|
@@ -484,6 +485,14 @@ describe("buildExtractionStepsBlock", () => {
|
|
|
484
485
|
assert.ok(/skip/i.test(block));
|
|
485
486
|
});
|
|
486
487
|
|
|
488
|
+
it("limits duplicate checks to one milestone-scoped memory query", () => {
|
|
489
|
+
const block = buildExtractionStepsBlock(ctx);
|
|
490
|
+
const memoryQueryMatches = block.match(/memory_query/g) ?? [];
|
|
491
|
+
assert.equal(memoryQueryMatches.length, 1);
|
|
492
|
+
assert.ok(block.includes("Do not re-read milestone artefacts or repeat memory queries category-by-category"));
|
|
493
|
+
assert.ok(!block.includes("Before each `capture_thought` call, optionally call `memory_query`"));
|
|
494
|
+
});
|
|
495
|
+
|
|
487
496
|
it("instructs capture_thought as the sole persistence path for Patterns, Lessons, and Decisions (ADR-013 step 6 cutover)", () => {
|
|
488
497
|
const block = buildExtractionStepsBlock(ctx);
|
|
489
498
|
// Each of the three persistence steps must call capture_thought.
|