gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.cf9433f56
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/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +48 -10
- package/dist/resources/extensions/gsd/auto/phases.js +66 -45
- package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +32 -16
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +124 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- 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.js +77 -5
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +36 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
- 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/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 +39 -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/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 +82 -16
- 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/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 +7 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +19 -19
- 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/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/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- package/dist/resources/extensions/gsd/worktree-resolver.js +33 -17
- 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 +10 -10
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/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 +10 -10
- 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/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-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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
- 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/runner.d.ts +3 -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 +17 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +99 -0
- 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 +7 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/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/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/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/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.ts +8 -0
- 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/runner.test.ts +110 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +19 -1
- package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- 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/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 +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +67 -18
- package/src/resources/extensions/gsd/auto/phases.ts +77 -48
- package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +42 -15
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
- package/src/resources/extensions/gsd/auto-prompts.ts +133 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
- package/src/resources/extensions/gsd/auto-start.ts +7 -6
- 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.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -2
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
- 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/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 +41 -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/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 +98 -16
- 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/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 +7 -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 +19 -19
- 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/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/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 +155 -5
- 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/clean-root-preflight.test.ts +88 -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/context-budget.test.ts +10 -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 +112 -6
- 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/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/journal-integration.test.ts +234 -0
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -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/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 +38 -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/quick-external-gsd.test.ts +40 -0
- 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/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/status-db-open.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- 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-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-resolver.test.ts +63 -1
- 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/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/src/resources/extensions/gsd/worktree-resolver.ts +36 -15
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_ssgManifest.js +0 -0
|
@@ -50,6 +50,15 @@ export interface FileEditEvidence {
|
|
|
50
50
|
|
|
51
51
|
export type EvidenceEntry = BashEvidence | FileWriteEvidence | FileEditEvidence;
|
|
52
52
|
|
|
53
|
+
const EXECUTION_TOOL_NAMES = new Set([
|
|
54
|
+
"bash",
|
|
55
|
+
"Bash",
|
|
56
|
+
"gsd_exec",
|
|
57
|
+
"gsd_exec_search",
|
|
58
|
+
"mcp__gsd-workflow__gsd_exec",
|
|
59
|
+
"mcp__gsd-workflow__gsd_exec_search",
|
|
60
|
+
]);
|
|
61
|
+
|
|
53
62
|
// ─── Module State ───────────────────────────────────────────────────────────
|
|
54
63
|
|
|
55
64
|
let unitEvidence: EvidenceEntry[] = [];
|
|
@@ -188,11 +197,11 @@ export function clearEvidenceFromDisk(
|
|
|
188
197
|
* Exit codes and output are filled in by recordToolResult after execution.
|
|
189
198
|
*/
|
|
190
199
|
export function recordToolCall(toolCallId: string, toolName: string, input: Record<string, unknown>): void {
|
|
191
|
-
if (toolName
|
|
200
|
+
if (EXECUTION_TOOL_NAMES.has(toolName)) {
|
|
192
201
|
unitEvidence.push({
|
|
193
202
|
kind: "bash",
|
|
194
203
|
toolCallId,
|
|
195
|
-
command: String(input.command ?? ""),
|
|
204
|
+
command: String(input.command ?? input.cmd ?? input.query ?? ""),
|
|
196
205
|
exitCode: -1,
|
|
197
206
|
outputSnippet: "",
|
|
198
207
|
timestamp: Date.now(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
3
|
|
|
4
|
-
import { _buildAbortedPauseContext } from "../bootstrap/agent-end-recovery.js";
|
|
4
|
+
import { _buildAbortedPauseContext, isUserInitiatedAbortMessage } from "../bootstrap/agent-end-recovery.js";
|
|
5
5
|
import { _buildCancelledUnitStopReason } from "../auto/phases.js";
|
|
6
6
|
|
|
7
7
|
test("aborted agent_end maps errorMessage into structured aborted pause context", () => {
|
|
@@ -30,3 +30,9 @@ test("cancelled non-session failures are labeled as unit aborts (not session-cre
|
|
|
30
30
|
assert.equal(cancelled.stopReason, "Unit aborted: tool invocation cancelled");
|
|
31
31
|
assert.equal(cancelled.loopReason, "unit-aborted");
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
test("provider user-abort errors are recognized as cancellations, not provider outages", () => {
|
|
35
|
+
assert.equal(isUserInitiatedAbortMessage("Claude Code process aborted by user"), true);
|
|
36
|
+
assert.equal(isUserInitiatedAbortMessage("Request aborted by user"), true);
|
|
37
|
+
assert.equal(isUserInitiatedAbortMessage("HTTP 503 Service Unavailable"), false);
|
|
38
|
+
});
|
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
_refreshLastCommitForTests,
|
|
24
24
|
_getLastCommitForTests,
|
|
25
25
|
_getLastCommitFetchedAtForTests,
|
|
26
|
+
formatRuntimeHealthSignal,
|
|
27
|
+
shouldRenderRoadmapProgress,
|
|
26
28
|
} from "../auto-dashboard.ts";
|
|
27
29
|
import {
|
|
28
30
|
openDatabase,
|
|
@@ -193,6 +195,37 @@ test("formatWidgetTokens formats millions with M", () => {
|
|
|
193
195
|
assert.equal(formatWidgetTokens(25_000_000), "25M");
|
|
194
196
|
});
|
|
195
197
|
|
|
198
|
+
test("formatRuntimeHealthSignal surfaces idle recovery instead of generic progress", () => {
|
|
199
|
+
const signal = formatRuntimeHealthSignal({
|
|
200
|
+
version: 1,
|
|
201
|
+
unitType: "research-milestone",
|
|
202
|
+
unitId: "M001",
|
|
203
|
+
startedAt: 1_000,
|
|
204
|
+
updatedAt: 600_000,
|
|
205
|
+
phase: "recovered",
|
|
206
|
+
wrapupWarningSent: false,
|
|
207
|
+
continueHereFired: false,
|
|
208
|
+
timeoutAt: null,
|
|
209
|
+
lastProgressAt: 1_000,
|
|
210
|
+
progressCount: 1,
|
|
211
|
+
lastProgressKind: "idle-recovery-retry",
|
|
212
|
+
recoveryAttempts: 1,
|
|
213
|
+
lastRecoveryReason: "idle",
|
|
214
|
+
}, 600_000);
|
|
215
|
+
|
|
216
|
+
assert.deepEqual(signal, {
|
|
217
|
+
level: "yellow",
|
|
218
|
+
summary: "Recovering",
|
|
219
|
+
detail: "retry 1 after idle stall",
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test("shouldRenderRoadmapProgress hides pre-roadmap zero-slice progress", () => {
|
|
224
|
+
assert.equal(shouldRenderRoadmapProgress(null), false);
|
|
225
|
+
assert.equal(shouldRenderRoadmapProgress({ done: 0, total: 0, activeSliceTasks: null } as any), false);
|
|
226
|
+
assert.equal(shouldRenderRoadmapProgress({ done: 0, total: 1, activeSliceTasks: null } as any), true);
|
|
227
|
+
});
|
|
228
|
+
|
|
196
229
|
// ─── estimateTimeRemaining ──────────────────────────────────────────────
|
|
197
230
|
|
|
198
231
|
test("estimateTimeRemaining returns null when no ledger data", () => {
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
_resetPendingResolve,
|
|
11
11
|
_hasPendingResolveForTest,
|
|
12
12
|
_setActiveSession,
|
|
13
|
+
_setSessionSwitchInFlight,
|
|
14
|
+
_consumePendingSwitchCancellation,
|
|
13
15
|
isSessionSwitchInFlight,
|
|
14
16
|
} from "../auto/resolve.js";
|
|
15
17
|
import { runUnit } from "../auto/run-unit.js";
|
|
@@ -206,6 +208,28 @@ test("runUnit returns cancelled when session creation fails", async () => {
|
|
|
206
208
|
assert.equal(pi.calls.length, 0);
|
|
207
209
|
});
|
|
208
210
|
|
|
211
|
+
test("runUnit clears queued switch cancellation when session creation fails", async () => {
|
|
212
|
+
_resetPendingResolve();
|
|
213
|
+
|
|
214
|
+
const ctx = makeMockCtx();
|
|
215
|
+
const pi = makeMockPi();
|
|
216
|
+
const s = makeMockSession({
|
|
217
|
+
newSessionThrows: "connection refused",
|
|
218
|
+
onNewSessionStart: () => {
|
|
219
|
+
resolveAgentEndCancelled({
|
|
220
|
+
message: "Claude Code process aborted by user",
|
|
221
|
+
category: "aborted",
|
|
222
|
+
isTransient: false,
|
|
223
|
+
});
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
const result = await runUnit(ctx, pi, s, "task", "T01", "prompt");
|
|
228
|
+
|
|
229
|
+
assert.equal(result.status, "cancelled");
|
|
230
|
+
assert.equal(_consumePendingSwitchCancellation(), null);
|
|
231
|
+
});
|
|
232
|
+
|
|
209
233
|
test("runUnit returns cancelled when session creation times out", async () => {
|
|
210
234
|
_resetPendingResolve();
|
|
211
235
|
|
|
@@ -221,6 +245,34 @@ test("runUnit returns cancelled when session creation times out", async () => {
|
|
|
221
245
|
assert.equal(pi.calls.length, 0);
|
|
222
246
|
});
|
|
223
247
|
|
|
248
|
+
test("runUnit consumes a cancellation queued during session switch before dispatch", async () => {
|
|
249
|
+
_resetPendingResolve();
|
|
250
|
+
|
|
251
|
+
const ctx = makeMockCtx();
|
|
252
|
+
const pi = makeMockPi();
|
|
253
|
+
let cancellationQueued = false;
|
|
254
|
+
const s = makeMockSession({
|
|
255
|
+
newSessionDelayMs: 10,
|
|
256
|
+
onNewSessionStart: () => {
|
|
257
|
+
setTimeout(() => {
|
|
258
|
+
cancellationQueued = !resolveAgentEndCancelled({
|
|
259
|
+
message: "Claude Code process aborted by user",
|
|
260
|
+
category: "aborted",
|
|
261
|
+
isTransient: false,
|
|
262
|
+
});
|
|
263
|
+
}, 0);
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
const result = await runUnit(ctx, pi, s, "plan-slice", "M009/S01", "prompt");
|
|
268
|
+
|
|
269
|
+
assert.equal(cancellationQueued, true);
|
|
270
|
+
assert.equal(result.status, "cancelled");
|
|
271
|
+
assert.equal(result.errorContext?.category, "aborted");
|
|
272
|
+
assert.equal(result.errorContext?.message, "Claude Code process aborted by user");
|
|
273
|
+
assert.equal(pi.calls.length, 0, "queued switch cancellation must prevent prompt dispatch");
|
|
274
|
+
});
|
|
275
|
+
|
|
224
276
|
test("runUnit keeps the session-switch guard across a late newSession settlement", async () => {
|
|
225
277
|
_resetPendingResolve();
|
|
226
278
|
mock.timers.enable();
|
|
@@ -879,7 +931,11 @@ test("autoLoop passes structured session-lock failure details to the handler", a
|
|
|
879
931
|
);
|
|
880
932
|
});
|
|
881
933
|
|
|
882
|
-
|
|
934
|
+
// Regression for #5308: the iteration prelude must dequeue sidecar items
|
|
935
|
+
// (popping the queue and emitting the `sidecar-dequeue` journal event) BEFORE
|
|
936
|
+
// validateSessionLock + break-on-invalid. Inverting that order silently drops
|
|
937
|
+
// queued sidecar work on lock-loss. Covers first-iteration and mid-session.
|
|
938
|
+
test("autoLoop dequeues sidecar item before session-lock break (first iteration, #5308)", async () => {
|
|
883
939
|
_resetPendingResolve();
|
|
884
940
|
|
|
885
941
|
const ctx = makeMockCtx();
|
|
@@ -911,12 +967,87 @@ test("autoLoop keeps queued sidecar work when the session lock is lost", async (
|
|
|
911
967
|
|
|
912
968
|
await autoLoop(ctx, pi, s, deps);
|
|
913
969
|
|
|
914
|
-
assert.equal(
|
|
915
|
-
|
|
916
|
-
|
|
970
|
+
assert.equal(
|
|
971
|
+
s.sidecarQueue.length,
|
|
972
|
+
0,
|
|
973
|
+
"sidecar item must be popped on lock-loss iteration (pre-#5308 ordering)",
|
|
974
|
+
);
|
|
975
|
+
assert.ok(
|
|
976
|
+
journalEvents.includes("sidecar-dequeue"),
|
|
977
|
+
"sidecar-dequeue journal event must be emitted before session-lock break",
|
|
978
|
+
);
|
|
979
|
+
assert.ok(
|
|
980
|
+
deps.callLog.includes("handleLostSessionLock"),
|
|
981
|
+
"session lock handler must still fire after sidecar dequeue",
|
|
982
|
+
);
|
|
917
983
|
assert.ok(!deps.callLog.includes("deriveState"), "lock loss should stop before deriving state");
|
|
918
984
|
});
|
|
919
985
|
|
|
986
|
+
test("autoLoop dequeues sidecar item before session-lock break (mid-session, #5308)", async () => {
|
|
987
|
+
_resetPendingResolve();
|
|
988
|
+
|
|
989
|
+
const ctx = makeMockCtx();
|
|
990
|
+
ctx.ui.setStatus = () => {};
|
|
991
|
+
const pi = makeMockPi();
|
|
992
|
+
const s = makeLoopSession();
|
|
993
|
+
|
|
994
|
+
const journalEvents: string[] = [];
|
|
995
|
+
let lockCheckCount = 0;
|
|
996
|
+
const deps = makeMockDeps({
|
|
997
|
+
// First iteration: lock valid; second iteration: lock invalidates.
|
|
998
|
+
validateSessionLock: () => {
|
|
999
|
+
lockCheckCount += 1;
|
|
1000
|
+
if (lockCheckCount === 1) {
|
|
1001
|
+
return { valid: true } as SessionLockStatus;
|
|
1002
|
+
}
|
|
1003
|
+
return {
|
|
1004
|
+
valid: false,
|
|
1005
|
+
failureReason: "compromised",
|
|
1006
|
+
expectedPid: process.pid,
|
|
1007
|
+
} as SessionLockStatus;
|
|
1008
|
+
},
|
|
1009
|
+
handleLostSessionLock: () => {
|
|
1010
|
+
deps.callLog.push("handleLostSessionLock");
|
|
1011
|
+
},
|
|
1012
|
+
emitJournalEvent: (entry) => {
|
|
1013
|
+
journalEvents.push(entry.eventType);
|
|
1014
|
+
},
|
|
1015
|
+
// Enqueue a sidecar item at the end of iteration 1, so iteration 2 begins
|
|
1016
|
+
// with a non-empty queue and an invalid lock.
|
|
1017
|
+
postUnitPostVerification: async () => {
|
|
1018
|
+
deps.callLog.push("postUnitPostVerification");
|
|
1019
|
+
s.sidecarQueue.push({
|
|
1020
|
+
kind: "hook" as const,
|
|
1021
|
+
unitType: "hook/review",
|
|
1022
|
+
unitId: "M001/S01/T01/review",
|
|
1023
|
+
prompt: "review the code",
|
|
1024
|
+
});
|
|
1025
|
+
return "continue" as const;
|
|
1026
|
+
},
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
const loopPromise = autoLoop(ctx, pi, s, deps);
|
|
1030
|
+
// Allow the loop to reach runUnit's await on iteration 1.
|
|
1031
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
1032
|
+
resolveAgentEnd(makeEvent());
|
|
1033
|
+
await loopPromise;
|
|
1034
|
+
|
|
1035
|
+
assert.ok(lockCheckCount >= 2, "lock validator must run on iteration 2");
|
|
1036
|
+
assert.equal(
|
|
1037
|
+
s.sidecarQueue.length,
|
|
1038
|
+
0,
|
|
1039
|
+
"queued sidecar item must be popped on the lock-loss iteration",
|
|
1040
|
+
);
|
|
1041
|
+
assert.ok(
|
|
1042
|
+
journalEvents.includes("sidecar-dequeue"),
|
|
1043
|
+
"sidecar-dequeue journal event must be emitted before session-lock break",
|
|
1044
|
+
);
|
|
1045
|
+
assert.ok(
|
|
1046
|
+
deps.callLog.includes("handleLostSessionLock"),
|
|
1047
|
+
"lock-loss handler must still fire on iteration 2",
|
|
1048
|
+
);
|
|
1049
|
+
});
|
|
1050
|
+
|
|
920
1051
|
test("autoLoop exits on terminal blocked state", async (t) => {
|
|
921
1052
|
_resetPendingResolve();
|
|
922
1053
|
|
|
@@ -2010,6 +2141,25 @@ test("resolveAgentEndCancelled without args produces no errorContext field", asy
|
|
|
2010
2141
|
assert.equal(resolved.errorContext, undefined, "errorContext must not be present when no args passed");
|
|
2011
2142
|
});
|
|
2012
2143
|
|
|
2144
|
+
test("resolveAgentEndCancelled queues cancellation that arrives during session switch", () => {
|
|
2145
|
+
_resetPendingResolve();
|
|
2146
|
+
|
|
2147
|
+
_setSessionSwitchInFlight(true);
|
|
2148
|
+
const resolved = resolveAgentEndCancelled({
|
|
2149
|
+
message: "Claude Code process aborted by user",
|
|
2150
|
+
category: "aborted",
|
|
2151
|
+
isTransient: false,
|
|
2152
|
+
});
|
|
2153
|
+
|
|
2154
|
+
assert.equal(resolved, false);
|
|
2155
|
+
const pending = _consumePendingSwitchCancellation();
|
|
2156
|
+
assert.ok(pending?.errorContext, "queued cancellation should preserve errorContext");
|
|
2157
|
+
assert.equal(pending.errorContext.category, "aborted");
|
|
2158
|
+
assert.equal(pending.errorContext.message, "Claude Code process aborted by user");
|
|
2159
|
+
assert.equal(_consumePendingSwitchCancellation(), null);
|
|
2160
|
+
_resetPendingResolve();
|
|
2161
|
+
});
|
|
2162
|
+
|
|
2013
2163
|
// ─── #1571: artifact verification retry ──────────────────────────────────────
|
|
2014
2164
|
|
|
2015
2165
|
test("autoLoop re-iterates when postUnitPreVerification returns retry (#1571)", async () => {
|
|
@@ -2477,7 +2627,7 @@ test("autoLoop warns but proceeds for greenfield project (no project files) (#18
|
|
|
2477
2627
|
"should not stop with health check failure for greenfield project",
|
|
2478
2628
|
);
|
|
2479
2629
|
const greenfieldWarning = notifications.find(
|
|
2480
|
-
(n) => n.includes("no
|
|
2630
|
+
(n) => n.includes("no project content yet") && n.includes("greenfield"),
|
|
2481
2631
|
);
|
|
2482
2632
|
assert.ok(
|
|
2483
2633
|
greenfieldWarning,
|
|
@@ -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 {
|