gsd-pi 2.81.0-dev.72a81bdf3 → 2.82.0-dev.20138ae42
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 +50 -31
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +10 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
- package/dist/resources/extensions/cmux/index.js +5 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
- package/dist/resources/extensions/gsd/auto/loop.js +5 -5
- package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
- package/dist/resources/extensions/gsd/auto/phases.js +30 -1
- package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
- package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +233 -127
- package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
- package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
- package/dist/resources/extensions/gsd/auto-start.js +85 -12
- package/dist/resources/extensions/gsd/auto-verification.js +28 -22
- package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
- package/dist/resources/extensions/gsd/auto.js +158 -55
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +25 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -1
- package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor.js +2 -28
- package/dist/resources/extensions/gsd/export-html.js +27 -425
- package/dist/resources/extensions/gsd/git-service.js +39 -1
- package/dist/resources/extensions/gsd/gsd-db.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow.js +93 -111
- package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +6 -1
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
- package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
- package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
- package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
- package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
- package/dist/resources/extensions/gsd/status-guards.js +4 -0
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/templates/plan.md +8 -5
- package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
- package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
- package/dist/resources/extensions/gsd/validation.js +23 -1
- package/dist/resources/extensions/gsd/verification-gate.js +68 -7
- package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
- package/dist/resources/extensions/shared/html-shell.js +388 -0
- package/dist/resources/extensions/subagent/index.js +448 -78
- package/dist/resources/extensions/subagent/launch.js +77 -0
- package/dist/resources/extensions/subagent/run-store.js +148 -0
- package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
- package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/dist/resources/extensions/visual-brief/index.js +5 -0
- package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
- package/dist/resources/extensions/visual-brief/prompts.js +140 -0
- 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 +12 -12
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
- 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 +4 -5
- 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 +2 -5
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -7
- 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 +4 -7
- 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 +4 -5
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
- 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/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
- package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-9a4db269f9ed63ad.js} +1 -1
- package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
- package/package.json +6 -5
- package/packages/contracts/dist/rpc.test.js +7 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +21 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +24 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/src/rpc.test.ts +8 -0
- package/packages/contracts/src/workflow.ts +24 -0
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +14 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +80 -0
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
- package/packages/mcp-server/src/workflow-tools.ts +168 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.json +2 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +5 -6
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
- package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
- package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
- package/packages/pi-ai/src/providers/simple-options.ts +5 -6
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
- package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/tui.ts +6 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +10 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
- package/src/resources/extensions/cmux/index.ts +6 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
- package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
- package/src/resources/extensions/gsd/auto/loop.ts +8 -5
- package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
- package/src/resources/extensions/gsd/auto/phases.ts +36 -1
- package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
- package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +266 -139
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
- package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
- package/src/resources/extensions/gsd/auto-start.ts +92 -9
- package/src/resources/extensions/gsd/auto-verification.ts +36 -34
- package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
- package/src/resources/extensions/gsd/auto.ts +167 -53
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +33 -6
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -3
- package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -1
- package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +2 -27
- package/src/resources/extensions/gsd/export-html.ts +27 -427
- package/src/resources/extensions/gsd/git-service.ts +45 -1
- package/src/resources/extensions/gsd/gsd-db.ts +3 -0
- package/src/resources/extensions/gsd/guided-flow.ts +126 -128
- package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +6 -1
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
- package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
- package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
- package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
- package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
- package/src/resources/extensions/gsd/prompts/queue.md +4 -4
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
- package/src/resources/extensions/gsd/status-guards.ts +5 -0
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/templates/plan.md +8 -5
- package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +129 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +12 -11
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
- package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
- package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
- package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +86 -7
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
- package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
- package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
- package/src/resources/extensions/gsd/types.ts +1 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
- package/src/resources/extensions/gsd/validation.ts +23 -1
- package/src/resources/extensions/gsd/verification-gate.ts +78 -6
- package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
- package/src/resources/extensions/shared/html-shell.ts +412 -0
- package/src/resources/extensions/subagent/index.ts +567 -103
- package/src/resources/extensions/subagent/launch.ts +131 -0
- package/src/resources/extensions/subagent/run-store.ts +218 -0
- package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
- package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
- package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
- package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
- package/src/resources/extensions/visual-brief/index.ts +8 -0
- package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
- package/src/resources/extensions/visual-brief/prompts.ts +183 -0
- package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
- package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
- package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
- package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
- package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_ssgManifest.js +0 -0
|
@@ -23,7 +23,7 @@ An override was issued by the user that changes a fundamental decision or approa
|
|
|
23
23
|
- For DECISIONS.md: append a new decision entry documenting the override and why. Do NOT delete prior decisions — mark them as superseded with a note.
|
|
24
24
|
- For slice plans (S##-PLAN.md): update Goal, Demo, and Verification sections if affected. Update Files Likely Touched if the override changes scope. Do NOT modify completed task entries.
|
|
25
25
|
- For REQUIREMENTS.md: update requirement descriptions if the override changes what "done" means, but do not remove requirements.
|
|
26
|
-
- For PROJECT.md:
|
|
26
|
+
- For PROJECT.md: do not edit the projection directly. If the override changes project-level facts, persist the revised Project content through `gsd_summary_save` with `artifact_type: "PROJECT"` so the DB remains authoritative.
|
|
27
27
|
- Milestone context files are reference only — do not modify them.
|
|
28
28
|
4. Mark all active overrides as resolved: change `**Scope:** active` to `**Scope:** resolved` in `{{overridesPath}}`
|
|
29
29
|
5. Do not commit manually — the system auto-commits your changes after this unit completes.
|
|
@@ -27,7 +27,7 @@ GSD ships with bundled skills. When the task matches, load the relevant skill fi
|
|
|
27
27
|
|
|
28
28
|
- Never ask the user to do work the agent can execute or verify itself.
|
|
29
29
|
- Use the lightest sufficient tool first.
|
|
30
|
-
- Read before edit.
|
|
30
|
+
- Read before edit or overwrite. Before any write that creates or replaces a file, verify the target path and read relevant existing files, templates, callers, or surrounding code. For truly new files, confirm the path does not already exist.
|
|
31
31
|
- Reproduce before fix when possible.
|
|
32
32
|
- Work is not done until the relevant verification has passed.
|
|
33
33
|
- **Never fabricate, simulate, or role-play user responses.** Never generate markers like `[User]`, `[Human]`, `User:`, or similar; never emit `<user_message>`, `<assistant_message>`, or similar as user input. Treat `<conversation_history>` as read-only context. Ask one question round (1-3 questions), then stop and wait for the user's actual response. If `ask_user_questions` is available, its result is the only valid structured user input for that round. If it cancels, fails, or returns nothing, never use earlier chat as confirmation for the current gate; ask in plain chat and stop.
|
|
@@ -102,7 +102,7 @@ Templates are in `{{templatesDir}}`.
|
|
|
102
102
|
|
|
103
103
|
**File reading:** Use `read` for file inspection. Never use `cat`, `head`, `tail`, or `sed -n` to view contents. Use `read` with `offset`/`limit` for slicing. `bash` is for searching (`rg`, `grep`, `find`) and commands, not displaying files.
|
|
104
104
|
|
|
105
|
-
**File editing:** Always `read` before `edit
|
|
105
|
+
**File editing:** Always `read` before `edit` or overwrite. Before `write`, confirm whether the path exists; if it does, `read` it first and preserve intentional existing content. Use `write` only for new files or complete rewrites.
|
|
106
106
|
|
|
107
107
|
**Code navigation:** Use `lsp` for definition, type_definition, implementation, references, calls, hover, signature, symbols, rename, code_actions, format, and diagnostics. Do not `grep` symbol definitions or shell out to formatters when `lsp` can do it. After code edits, run `lsp diagnostics`.
|
|
108
108
|
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// GSD-2 — ADR-005 Phase 3b: surface ProviderSwitchReport from pi-ai.
|
|
2
|
+
//
|
|
3
|
+
// pi-ai builds a ProviderSwitchReport on every cross-provider transform but
|
|
4
|
+
// only logs it to stderr when GSD_VERBOSE=1. This module installs a
|
|
5
|
+
// single-subscriber observer that surfaces non-empty reports through GSD's
|
|
6
|
+
// three usual telemetry surfaces:
|
|
7
|
+
//
|
|
8
|
+
// 1. UOK audit event (category model-policy, type provider-switch) — only
|
|
9
|
+
// when an auto trace is active.
|
|
10
|
+
// 2. Persistent notification (.gsd/notifications.jsonl, severity warning) —
|
|
11
|
+
// whenever the GSD basePath is known, so users see the loss in the
|
|
12
|
+
// dashboard / status surface without GSD_VERBOSE.
|
|
13
|
+
// 3. In-memory counter, exposed via getProviderSwitchStats() so any
|
|
14
|
+
// caller (dashboard, doctor, tests) can read the rollup.
|
|
15
|
+
|
|
16
|
+
import { setProviderSwitchObserver, type ProviderSwitchReport } from "@gsd/pi-ai";
|
|
17
|
+
|
|
18
|
+
import { autoSession } from "./auto-runtime-state.js";
|
|
19
|
+
import { appendNotification } from "./notification-store.js";
|
|
20
|
+
import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
|
|
21
|
+
|
|
22
|
+
/** Rollup of cross-provider context transformations, grouped by trace. */
|
|
23
|
+
export interface ProviderSwitchStats {
|
|
24
|
+
/** Total non-empty reports observed since process start (or last reset). */
|
|
25
|
+
totalSwitches: number;
|
|
26
|
+
/** Sum of every counted transformation across all reports. */
|
|
27
|
+
totals: {
|
|
28
|
+
thinkingBlocksDropped: number;
|
|
29
|
+
thinkingBlocksDowngraded: number;
|
|
30
|
+
toolCallIdsRemapped: number;
|
|
31
|
+
syntheticToolResultsInserted: number;
|
|
32
|
+
thoughtSignaturesDropped: number;
|
|
33
|
+
};
|
|
34
|
+
/** Per-trace breakdown. Key "interactive" covers reports outside auto-mode. */
|
|
35
|
+
byTrace: Record<string, TraceSwitchStats>;
|
|
36
|
+
/** The most recent non-empty report, if any. */
|
|
37
|
+
lastReport: ProviderSwitchReport | null;
|
|
38
|
+
/** ISO timestamp of the most recent non-empty report, if any. */
|
|
39
|
+
lastAt: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface TraceSwitchStats {
|
|
43
|
+
switches: number;
|
|
44
|
+
lastReport: ProviderSwitchReport;
|
|
45
|
+
lastAt: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const INTERACTIVE_TRACE_KEY = "interactive";
|
|
49
|
+
|
|
50
|
+
interface MutableTraceStats {
|
|
51
|
+
switches: number;
|
|
52
|
+
lastReport: ProviderSwitchReport;
|
|
53
|
+
lastAt: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let installed = false;
|
|
57
|
+
let totalSwitches = 0;
|
|
58
|
+
const totals = {
|
|
59
|
+
thinkingBlocksDropped: 0,
|
|
60
|
+
thinkingBlocksDowngraded: 0,
|
|
61
|
+
toolCallIdsRemapped: 0,
|
|
62
|
+
syntheticToolResultsInserted: 0,
|
|
63
|
+
thoughtSignaturesDropped: 0,
|
|
64
|
+
};
|
|
65
|
+
const byTrace = new Map<string, MutableTraceStats>();
|
|
66
|
+
let lastReport: ProviderSwitchReport | null = null;
|
|
67
|
+
let lastAt: string | null = null;
|
|
68
|
+
|
|
69
|
+
/** Format a one-line summary suitable for a notification message. */
|
|
70
|
+
function summarize(report: ProviderSwitchReport): string {
|
|
71
|
+
const parts: string[] = [];
|
|
72
|
+
if (report.thinkingBlocksDropped > 0) parts.push(`${report.thinkingBlocksDropped} thinking dropped`);
|
|
73
|
+
if (report.thinkingBlocksDowngraded > 0) parts.push(`${report.thinkingBlocksDowngraded} thinking downgraded`);
|
|
74
|
+
if (report.toolCallIdsRemapped > 0) parts.push(`${report.toolCallIdsRemapped} tool ids remapped`);
|
|
75
|
+
if (report.syntheticToolResultsInserted > 0) parts.push(`${report.syntheticToolResultsInserted} synthetic tool results`);
|
|
76
|
+
if (report.thoughtSignaturesDropped > 0) parts.push(`${report.thoughtSignaturesDropped} thought signatures dropped`);
|
|
77
|
+
return `Provider switch ${report.fromApi} → ${report.toApi}: ${parts.join(", ")}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function recordReport(report: ProviderSwitchReport): void {
|
|
81
|
+
const now = new Date().toISOString();
|
|
82
|
+
totalSwitches += 1;
|
|
83
|
+
totals.thinkingBlocksDropped += report.thinkingBlocksDropped;
|
|
84
|
+
totals.thinkingBlocksDowngraded += report.thinkingBlocksDowngraded;
|
|
85
|
+
totals.toolCallIdsRemapped += report.toolCallIdsRemapped;
|
|
86
|
+
totals.syntheticToolResultsInserted += report.syntheticToolResultsInserted;
|
|
87
|
+
totals.thoughtSignaturesDropped += report.thoughtSignaturesDropped;
|
|
88
|
+
lastReport = report;
|
|
89
|
+
lastAt = now;
|
|
90
|
+
|
|
91
|
+
const traceKey = autoSession.currentTraceId ?? INTERACTIVE_TRACE_KEY;
|
|
92
|
+
const existing = byTrace.get(traceKey);
|
|
93
|
+
if (existing) {
|
|
94
|
+
existing.switches += 1;
|
|
95
|
+
existing.lastReport = report;
|
|
96
|
+
existing.lastAt = now;
|
|
97
|
+
} else {
|
|
98
|
+
byTrace.set(traceKey, { switches: 1, lastReport: report, lastAt: now });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function emitAudit(report: ProviderSwitchReport): void {
|
|
103
|
+
const traceId = autoSession.currentTraceId;
|
|
104
|
+
const basePath = autoSession.basePath;
|
|
105
|
+
if (!traceId || !basePath) return;
|
|
106
|
+
try {
|
|
107
|
+
emitUokAuditEvent(
|
|
108
|
+
basePath,
|
|
109
|
+
buildAuditEnvelope({
|
|
110
|
+
traceId,
|
|
111
|
+
category: "model-policy",
|
|
112
|
+
type: "provider-switch",
|
|
113
|
+
payload: {
|
|
114
|
+
fromApi: report.fromApi,
|
|
115
|
+
toApi: report.toApi,
|
|
116
|
+
thinkingBlocksDropped: report.thinkingBlocksDropped,
|
|
117
|
+
thinkingBlocksDowngraded: report.thinkingBlocksDowngraded,
|
|
118
|
+
toolCallIdsRemapped: report.toolCallIdsRemapped,
|
|
119
|
+
syntheticToolResultsInserted: report.syntheticToolResultsInserted,
|
|
120
|
+
thoughtSignaturesDropped: report.thoughtSignaturesDropped,
|
|
121
|
+
},
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
} catch {
|
|
125
|
+
// Audit emission is best-effort. Counter + notification still fire.
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function emitNotification(report: ProviderSwitchReport): void {
|
|
130
|
+
try {
|
|
131
|
+
appendNotification(summarize(report), "warning", "workflow-logger");
|
|
132
|
+
} catch {
|
|
133
|
+
// Notification persistence is best-effort.
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function handleReport(report: ProviderSwitchReport): void {
|
|
138
|
+
recordReport(report);
|
|
139
|
+
emitAudit(report);
|
|
140
|
+
emitNotification(report);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Install the pi-ai observer. Idempotent — calling more than once is a no-op
|
|
145
|
+
* after the first install.
|
|
146
|
+
*/
|
|
147
|
+
export function installProviderSwitchObserver(): void {
|
|
148
|
+
if (installed) return;
|
|
149
|
+
setProviderSwitchObserver(handleReport);
|
|
150
|
+
installed = true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Uninstall the observer. Intended for tests. */
|
|
154
|
+
export function uninstallProviderSwitchObserver(): void {
|
|
155
|
+
setProviderSwitchObserver(undefined);
|
|
156
|
+
installed = false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Read-only snapshot of the in-memory rollup. */
|
|
160
|
+
export function getProviderSwitchStats(): ProviderSwitchStats {
|
|
161
|
+
const trace: Record<string, TraceSwitchStats> = {};
|
|
162
|
+
for (const [key, value] of byTrace) {
|
|
163
|
+
trace[key] = { switches: value.switches, lastReport: { ...value.lastReport }, lastAt: value.lastAt };
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
totalSwitches,
|
|
167
|
+
totals: { ...totals },
|
|
168
|
+
byTrace: trace,
|
|
169
|
+
lastReport: lastReport ? { ...lastReport } : null,
|
|
170
|
+
lastAt,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Reset the in-memory rollup. Intended for tests. */
|
|
175
|
+
export function _resetProviderSwitchStats(): void {
|
|
176
|
+
totalSwitches = 0;
|
|
177
|
+
totals.thinkingBlocksDropped = 0;
|
|
178
|
+
totals.thinkingBlocksDowngraded = 0;
|
|
179
|
+
totals.toolCallIdsRemapped = 0;
|
|
180
|
+
totals.syntheticToolResultsInserted = 0;
|
|
181
|
+
totals.thoughtSignaturesDropped = 0;
|
|
182
|
+
byTrace.clear();
|
|
183
|
+
lastReport = null;
|
|
184
|
+
lastAt = null;
|
|
185
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// GSD-2 — Smart entry routing decisions.
|
|
2
|
+
// Pure route selection for /gsd guided wizard choices.
|
|
3
|
+
|
|
4
|
+
export type SmartEntryIsolationMode = "worktree" | "branch" | "none";
|
|
5
|
+
|
|
6
|
+
export type ActiveTaskChoice =
|
|
7
|
+
| "execute"
|
|
8
|
+
| "auto"
|
|
9
|
+
| "status"
|
|
10
|
+
| "milestone_actions";
|
|
11
|
+
|
|
12
|
+
export type ActiveTaskRoute =
|
|
13
|
+
| {
|
|
14
|
+
kind: "auto-bootstrap";
|
|
15
|
+
verboseMode: false;
|
|
16
|
+
options?: {
|
|
17
|
+
step?: true;
|
|
18
|
+
milestoneLock?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
kind: "guided-dispatch";
|
|
23
|
+
unitType: "execute-task";
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
kind: "status";
|
|
27
|
+
}
|
|
28
|
+
| {
|
|
29
|
+
kind: "milestone-actions";
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function resolveGuidedExecuteLaunchMode(
|
|
33
|
+
isolationMode: SmartEntryIsolationMode,
|
|
34
|
+
): "auto-step" | "guided-dispatch" {
|
|
35
|
+
return isolationMode === "worktree" ? "auto-step" : "guided-dispatch";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function resolveActiveTaskChoiceRoute(input: {
|
|
39
|
+
choice: ActiveTaskChoice;
|
|
40
|
+
isolationMode: SmartEntryIsolationMode;
|
|
41
|
+
milestoneId: string;
|
|
42
|
+
}): ActiveTaskRoute {
|
|
43
|
+
if (input.choice === "auto") {
|
|
44
|
+
return {
|
|
45
|
+
kind: "auto-bootstrap",
|
|
46
|
+
verboseMode: false,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (input.choice === "execute") {
|
|
51
|
+
if (resolveGuidedExecuteLaunchMode(input.isolationMode) === "auto-step") {
|
|
52
|
+
return {
|
|
53
|
+
kind: "auto-bootstrap",
|
|
54
|
+
verboseMode: false,
|
|
55
|
+
options: {
|
|
56
|
+
step: true,
|
|
57
|
+
milestoneLock: input.milestoneId,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
kind: "guided-dispatch",
|
|
64
|
+
unitType: "execute-task",
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (input.choice === "status") {
|
|
69
|
+
return { kind: "status" };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (input.choice === "milestone_actions") {
|
|
73
|
+
return { kind: "milestone-actions" };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
throw new Error(`Invalid ActiveTaskChoice: ${input.choice}`);
|
|
77
|
+
}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from "../../native-git-bridge.js";
|
|
24
24
|
import type { GSDState } from "../../types.js";
|
|
25
25
|
import { logError, logWarning } from "../../workflow-logger.js";
|
|
26
|
+
import { isGsdWorktreePath } from "../../worktree-root.js";
|
|
26
27
|
import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
|
|
27
28
|
|
|
28
29
|
export type MergeReconcileResult = "clean" | "reconciled" | "blocked";
|
|
@@ -46,7 +47,13 @@ function resolveGitDir(basePath: string): string {
|
|
|
46
47
|
return isAbsolute(gitDir) ? gitDir : resolve(basePath, gitDir);
|
|
47
48
|
}
|
|
48
49
|
} catch (err) {
|
|
49
|
-
|
|
50
|
+
const message = getErrorMessage(err);
|
|
51
|
+
logWarning("recovery", `gitdir resolution failed: ${message}`);
|
|
52
|
+
if (isGsdWorktreePath(basePath)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Worktree integrity failure: ${basePath} is not a valid git worktree (git rev-parse failed: ${message.split("\n")[0]}). Repair or recreate the worktree before retrying.`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
return join(basePath, ".git");
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
// Project/App: GSD-2
|
|
2
2
|
// File Purpose: ADR-017 unregistered-milestone drift handler. Detects
|
|
3
3
|
// milestones whose on-disk directory has meaningful content (ROADMAP/
|
|
4
|
-
// CONTEXT/SUMMARY) but no DB row, then
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// CONTEXT/SUMMARY) but no DB row, then fails closed with an explicit recovery
|
|
5
|
+
// instruction. Markdown hierarchy import is reserved for operator-controlled
|
|
6
|
+
// migration/recovery commands, not automatic runtime reconciliation.
|
|
7
7
|
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
|
|
10
10
|
import { getMilestone, isDbAvailable } from "../../gsd-db.js";
|
|
11
|
-
import { migrateHierarchyToDb } from "../../md-importer.js";
|
|
12
11
|
import { findMilestoneIds } from "../../milestone-ids.js";
|
|
13
12
|
import { resolveMilestoneFile } from "../../paths.js";
|
|
14
13
|
import type { GSDState } from "../../types.js";
|
|
@@ -46,20 +45,18 @@ export function detectUnregisteredMilestoneDrift(
|
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
|
-
* Repair
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* Note: even though we receive one record at a time, the importer is a
|
|
54
|
-
* project-wide operation. Repeated invocation across multiple drift records
|
|
55
|
-
* in the same pass is wasteful but safe; a future optimization could
|
|
56
|
-
* coalesce by checking whether the importer has already run this pass.
|
|
48
|
+
* Repair intentionally fails closed. The project-root DB is authoritative at
|
|
49
|
+
* runtime; markdown-only milestones must be imported through an explicit
|
|
50
|
+
* migration/recovery command so operators opt into changing canonical state.
|
|
57
51
|
*/
|
|
58
52
|
export function repairUnregisteredMilestone(
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
record: UnregisteredMilestoneDrift,
|
|
54
|
+
_ctx: DriftContext,
|
|
61
55
|
): void {
|
|
62
|
-
|
|
56
|
+
throw new Error(
|
|
57
|
+
`Milestone ${record.milestoneId} exists only as markdown projection. ` +
|
|
58
|
+
"Runtime reconciliation will not import markdown into the authoritative DB; run explicit GSD recovery/migration if this markdown should repopulate the database.",
|
|
59
|
+
);
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
export const unregisteredMilestoneHandler: DriftHandler<UnregisteredMilestoneDrift> = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Project/App: GSD-2
|
|
2
2
|
// File Purpose: ADR-017 roadmap-divergence drift handler. Detects mismatches
|
|
3
|
-
// between ROADMAP.md (parsed slice sequence
|
|
4
|
-
// DB slice rows for that milestone, then
|
|
5
|
-
//
|
|
3
|
+
// between ROADMAP.md (parsed slice sequence, depends declarations, and
|
|
4
|
+
// checkboxes) and the DB slice rows for that milestone, then re-renders the
|
|
5
|
+
// ROADMAP projection from the authoritative DB rows.
|
|
6
6
|
|
|
7
7
|
import { existsSync, readFileSync } from "node:fs";
|
|
8
8
|
|
|
@@ -10,12 +10,12 @@ import {
|
|
|
10
10
|
getMilestone,
|
|
11
11
|
getMilestoneSlices,
|
|
12
12
|
isDbAvailable,
|
|
13
|
-
syncSliceDependencies,
|
|
14
13
|
} from "../../gsd-db.js";
|
|
15
|
-
import {
|
|
14
|
+
import { renderRoadmapFromDb } from "../../markdown-renderer.js";
|
|
16
15
|
import { findMilestoneIds } from "../../milestone-ids.js";
|
|
17
16
|
import { parseRoadmap } from "../../parsers-legacy.js";
|
|
18
17
|
import { resolveMilestoneFile } from "../../paths.js";
|
|
18
|
+
import { isClosedStatus } from "../../status-guards.js";
|
|
19
19
|
import type { GSDState } from "../../types.js";
|
|
20
20
|
import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
|
|
21
21
|
|
|
@@ -46,14 +46,20 @@ function milestoneHasDivergence(
|
|
|
46
46
|
|
|
47
47
|
const dbSlices = getMilestoneSlices(milestoneId);
|
|
48
48
|
const dbSliceMap = new Map(dbSlices.map((s) => [s.id, s]));
|
|
49
|
+
const roadmapSliceIds = new Set<string>();
|
|
49
50
|
|
|
50
51
|
for (let i = 0; i < roadmap.slices.length; i++) {
|
|
51
52
|
const roadmapSlice = roadmap.slices[i]!;
|
|
53
|
+
roadmapSliceIds.add(roadmapSlice.id);
|
|
52
54
|
const expectedSequence = i + 1;
|
|
53
55
|
const dbSlice = dbSliceMap.get(roadmapSlice.id);
|
|
54
56
|
if (!dbSlice) return true; // Roadmap has a slice the DB doesn't.
|
|
55
57
|
if (dbSlice.sequence !== expectedSequence) return true;
|
|
56
58
|
if (!arraysEqual(dbSlice.depends, roadmapSlice.depends)) return true;
|
|
59
|
+
if (isClosedStatus(dbSlice.status) !== roadmapSlice.done) return true;
|
|
60
|
+
}
|
|
61
|
+
for (const dbSlice of dbSlices) {
|
|
62
|
+
if (!roadmapSliceIds.has(dbSlice.id)) return true;
|
|
57
63
|
}
|
|
58
64
|
return false;
|
|
59
65
|
}
|
|
@@ -77,29 +83,15 @@ export function detectRoadmapDivergenceDrift(
|
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
/**
|
|
80
|
-
* Repair a milestone's roadmap divergence
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* 2. syncSliceDependencies updates the junction table per slice — the
|
|
84
|
-
* importer only writes the JSON column, not the relational view.
|
|
86
|
+
* Repair a milestone's roadmap divergence by regenerating the projection from
|
|
87
|
+
* DB rows. ROADMAP.md is a projection; runtime reconciliation must not import
|
|
88
|
+
* slice presence, sequence, dependencies, or checkbox state from markdown.
|
|
85
89
|
*/
|
|
86
|
-
export function repairRoadmapDivergence(
|
|
90
|
+
export async function repairRoadmapDivergence(
|
|
87
91
|
record: RoadmapDivergenceDrift,
|
|
88
92
|
ctx: DriftContext,
|
|
89
|
-
): void {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const roadmapPath = resolveMilestoneFile(ctx.basePath, record.milestoneId, "ROADMAP");
|
|
93
|
-
if (!roadmapPath || !existsSync(roadmapPath)) return;
|
|
94
|
-
|
|
95
|
-
try {
|
|
96
|
-
const roadmap = parseRoadmap(readFileSync(roadmapPath, "utf-8"));
|
|
97
|
-
for (const slice of roadmap.slices) {
|
|
98
|
-
syncSliceDependencies(record.milestoneId, slice.id, slice.depends);
|
|
99
|
-
}
|
|
100
|
-
} catch {
|
|
101
|
-
/* parse failure: detector will fire again next pass */
|
|
102
|
-
}
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
await renderRoadmapFromDb(ctx.basePath, record.milestoneId);
|
|
103
95
|
}
|
|
104
96
|
|
|
105
97
|
export const roadmapDivergenceHandler: DriftHandler<RoadmapDivergenceDrift> = {
|
|
@@ -25,3 +25,8 @@ export function isDeferredStatus(status: string): boolean {
|
|
|
25
25
|
export function isInactiveStatus(status: string): boolean {
|
|
26
26
|
return isClosedStatus(status) || isDeferredStatus(status);
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/** Returns true when a prior milestone should not block dispatch ordering. */
|
|
30
|
+
export function isSkippedForDispatch(status: string): boolean {
|
|
31
|
+
return isClosedStatus(status) || status === "parked" || isDeferredStatus(status);
|
|
32
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Project Knowledge
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Project-specific rules plus projected patterns and lessons learned.
|
|
4
|
+
Rules are maintained in this file. Patterns and lessons are persisted to the memories table and rendered here on the next session-start projection.
|
|
5
5
|
|
|
6
6
|
## Rules
|
|
7
7
|
|
|
@@ -99,11 +99,11 @@
|
|
|
99
99
|
- "Improve UI"
|
|
100
100
|
|
|
101
101
|
Each task should usually include:
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
106
|
-
-
|
|
102
|
+
- description: why this task exists, concrete steps, and done-when acceptance
|
|
103
|
+
- files: JSON array of likely touched paths
|
|
104
|
+
- verify: the command, test, or runtime check that proves it worked
|
|
105
|
+
- inputs: JSON array of existing paths or prior task outputs this task consumes
|
|
106
|
+
- expectedOutput: JSON array of paths this task creates or overwrites
|
|
107
107
|
|
|
108
108
|
Keep the checkbox line format exactly:
|
|
109
109
|
- [ ] **T01: Title** `est:30m`
|
|
@@ -131,10 +131,13 @@
|
|
|
131
131
|
|
|
132
132
|
Verify field rules:
|
|
133
133
|
- MUST be a mechanically executable command: `npm test`, `grep -q "pattern" file`, `test -f path`
|
|
134
|
+
- MUST NOT use shell pipes, redirects, semicolons, backticks, command substitution, or output trimming
|
|
134
135
|
- For content/document tasks: verify file existence, section count, YAML validity, or word count
|
|
135
136
|
NOT exact phrasing, specific formulas, or "zero TBD" aspirational criteria
|
|
136
137
|
- If no command can verify the output, write: "Manual review — file exists and is non-empty"
|
|
138
|
+
- BAD: `python3 -m pytest tests/ -q --tb=short 2>&1 | tail -5`
|
|
137
139
|
- BAD: "Sections 3.1 and 3.2 exist with exact formulas. Zero TBD/TODO."
|
|
140
|
+
- GOOD: `python3 -m pytest tests/ -q --tb=short`
|
|
138
141
|
- GOOD: `grep -c "^## " doc.md` returns >= 4 (4+ sections), `! grep -q "TBD\|TODO" doc.md`
|
|
139
142
|
|
|
140
143
|
Integration closure rule:
|
|
@@ -72,7 +72,8 @@ skills_used:
|
|
|
72
72
|
<!-- Every input MUST be a backtick-wrapped file path. These paths are machine-parsed to
|
|
73
73
|
derive task dependencies — vague descriptions without paths break dependency detection.
|
|
74
74
|
For the first task in a slice with no prior task outputs, list the existing source files
|
|
75
|
-
this task reads or modifies.
|
|
75
|
+
this task reads or modifies.
|
|
76
|
+
Tool field: inputs must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
|
|
76
77
|
|
|
77
78
|
- `{{filePath}}` — {{whatThisTaskNeedsFromPriorWork}}
|
|
78
79
|
|
|
@@ -82,6 +83,7 @@ skills_used:
|
|
|
82
83
|
or modifies. These paths are machine-parsed to derive task dependencies.
|
|
83
84
|
This task should produce a real increment toward making the slice goal/demo true. A full
|
|
84
85
|
slice plan should not be able to mark every task complete while the claimed slice behavior
|
|
85
|
-
still does not work at the stated proof level.
|
|
86
|
+
still does not work at the stated proof level.
|
|
87
|
+
Tool field: expectedOutput must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
|
|
86
88
|
|
|
87
89
|
- `{{filePath}}` — {{whatThisTaskCreatesOrModifies}}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
formatWidgetTokens,
|
|
14
14
|
estimateTimeRemaining,
|
|
15
15
|
extractUatSliceId,
|
|
16
|
+
buildPhaseHandoffOutcome,
|
|
16
17
|
updateProgressWidget,
|
|
17
18
|
setAutoOutcomeWidget,
|
|
18
19
|
getRoadmapSlicesSync,
|
|
@@ -255,6 +256,76 @@ test("setAutoOutcomeWidget renders a durable next-action handoff", () => {
|
|
|
255
256
|
assert.match(output, /\/gsd auto/);
|
|
256
257
|
});
|
|
257
258
|
|
|
259
|
+
test("buildPhaseHandoffOutcome summarizes the last phase result", () => {
|
|
260
|
+
const snapshot = buildPhaseHandoffOutcome({
|
|
261
|
+
unitType: "plan-slice",
|
|
262
|
+
unitId: "M005/S01",
|
|
263
|
+
agentEndMessages: [
|
|
264
|
+
{ message: { role: "assistant", content: "Planned S01 with category-aware filtering and validation steps." } },
|
|
265
|
+
],
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
assert.equal(snapshot.status, "complete");
|
|
269
|
+
assert.equal(snapshot.title, "PLAN complete");
|
|
270
|
+
assert.match(snapshot.detail ?? "", /category-aware filtering/);
|
|
271
|
+
assert.equal(snapshot.unitLabel, "planning M005/S01");
|
|
272
|
+
assert.match(snapshot.nextAction, /next phase/);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("buildPhaseHandoffOutcome ignores non-assistant trailing messages", () => {
|
|
276
|
+
const snapshot = buildPhaseHandoffOutcome({
|
|
277
|
+
unitType: "plan-slice",
|
|
278
|
+
unitId: "M005/S01",
|
|
279
|
+
agentEndMessages: [
|
|
280
|
+
{ message: { role: "assistant", content: "Assistant summary to hand off." } },
|
|
281
|
+
{ role: "tool", content: "Tool output should not be shown." },
|
|
282
|
+
{ role: "user", content: "User follow-up should not be shown." },
|
|
283
|
+
],
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
assert.match(snapshot.detail ?? "", /Assistant summary/);
|
|
287
|
+
assert.doesNotMatch(snapshot.detail ?? "", /Tool output/);
|
|
288
|
+
assert.doesNotMatch(snapshot.detail ?? "", /User follow-up/);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test("updateProgressWidget preserves the phase handoff during session switching", () => {
|
|
292
|
+
const calls: Array<[string, unknown]> = [];
|
|
293
|
+
updateProgressWidget(
|
|
294
|
+
{
|
|
295
|
+
hasUI: true,
|
|
296
|
+
ui: {
|
|
297
|
+
setWidget(key: string, factory: unknown) {
|
|
298
|
+
calls.push([key, factory]);
|
|
299
|
+
},
|
|
300
|
+
setHeader() {},
|
|
301
|
+
setStatus() {},
|
|
302
|
+
},
|
|
303
|
+
} as any,
|
|
304
|
+
"execute-task",
|
|
305
|
+
"M005/S01/T01",
|
|
306
|
+
{
|
|
307
|
+
phase: "executing",
|
|
308
|
+
activeSlice: { id: "S01", title: "Filter chip bar" },
|
|
309
|
+
activeTask: { id: "T01", title: "Add category filter" },
|
|
310
|
+
} as any,
|
|
311
|
+
{
|
|
312
|
+
getAutoStartTime: () => Date.now(),
|
|
313
|
+
isStepMode: () => false,
|
|
314
|
+
getCmdCtx: () => null,
|
|
315
|
+
getBasePath: () => "",
|
|
316
|
+
isVerbose: () => false,
|
|
317
|
+
isSessionSwitching: () => true,
|
|
318
|
+
getCurrentDispatchedModelId: () => null,
|
|
319
|
+
},
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
assert.ok(calls.some(([key]) => key === "gsd-progress"));
|
|
323
|
+
assert.ok(
|
|
324
|
+
!calls.some(([key, value]) => key === "gsd-outcome" && value === undefined),
|
|
325
|
+
"handoff widget should stay visible until the next progress frame renders",
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
258
329
|
test("shouldRenderRoadmapProgress hides pre-roadmap zero-slice progress", () => {
|
|
259
330
|
assert.equal(shouldRenderRoadmapProgress(null), false);
|
|
260
331
|
assert.equal(shouldRenderRoadmapProgress({ done: 0, total: 0, activeSliceTasks: null } as any), false);
|