gsd-pi 2.73.1 → 2.74.0-dev.b741afb
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/dist/cli-web-branch.d.ts +4 -3
- package/dist/cli-web-branch.js +10 -7
- package/dist/cli.js +184 -206
- package/dist/headless-query.js +4 -1
- package/dist/help-text.js +23 -0
- package/dist/logo.d.ts +1 -1
- package/dist/logo.js +1 -1
- package/dist/onboarding.js +59 -53
- package/dist/resource-loader.js +2 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
- package/dist/resources/extensions/gsd/auto/phases.js +60 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +11 -3
- package/dist/resources/extensions/gsd/auto-model-selection.js +54 -11
- package/dist/resources/extensions/gsd/auto-post-unit.js +93 -57
- package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
- package/dist/resources/extensions/gsd/auto-start.js +23 -6
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
- package/dist/resources/extensions/gsd/auto-verification.js +88 -3
- package/dist/resources/extensions/gsd/auto.js +37 -10
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +21 -8
- package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
- package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
- package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
- package/dist/resources/extensions/gsd/commands-do.js +79 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +8 -2
- package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
- package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
- package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
- package/dist/resources/extensions/gsd/commands-ship.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +3 -5
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/graph-context.js +66 -0
- package/dist/resources/extensions/gsd/gsd-db.js +321 -0
- package/dist/resources/extensions/gsd/index.js +15 -2
- package/dist/resources/extensions/gsd/md-importer.js +3 -4
- package/dist/resources/extensions/gsd/memory-store.js +19 -51
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
- package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
- package/dist/resources/extensions/gsd/notification-widget.js +2 -2
- package/dist/resources/extensions/gsd/preferences-models.js +43 -0
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +22 -0
- package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/dist/resources/extensions/gsd/state.js +66 -15
- package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
- package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
- package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
- package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
- package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
- package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
- package/dist/tsconfig.extensions.tsbuildinfo +1 -0
- package/dist/update-check.d.ts +1 -0
- package/dist/update-check.js +13 -5
- package/dist/update-cmd.js +4 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +3 -3
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/index.d.ts +3 -0
- package/packages/mcp-server/dist/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/index.js +3 -0
- package/packages/mcp-server/dist/index.js.map +1 -1
- package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
- package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
- package/packages/mcp-server/dist/readers/graph.js +548 -0
- package/packages/mcp-server/dist/readers/graph.js.map +1 -0
- package/packages/mcp-server/dist/readers/index.d.ts +2 -0
- package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
- package/packages/mcp-server/dist/readers/index.js +1 -0
- package/packages/mcp-server/dist/readers/index.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +65 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/index.ts +15 -0
- package/packages/mcp-server/src/readers/graph.test.ts +426 -0
- package/packages/mcp-server/src/readers/graph.ts +708 -0
- package/packages/mcp-server/src/readers/index.ts +12 -0
- package/packages/mcp-server/src/server.ts +83 -0
- package/packages/mcp-server/tsconfig.json +1 -0
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
- package/packages/native/package.json +2 -2
- package/packages/native/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.json +1 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-ai/dist/index.d.ts +1 -0
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -0
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/overflow.js +12 -0
- package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
- package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +4 -0
- package/packages/pi-ai/src/utils/overflow.ts +14 -1
- package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
- package/packages/pi-ai/tsconfig.json +1 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +313 -8
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
- package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
- package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +12 -2
- 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 +61 -28
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +9 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
- 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 +94 -16
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +11 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +355 -8
- package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
- package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +74 -32
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +113 -21
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +11 -3
- package/packages/pi-coding-agent/tsconfig.json +1 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +60 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +32 -3
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
- package/packages/pi-tui/src/tui.ts +31 -3
- package/packages/pi-tui/tsconfig.json +1 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/tsconfig.json +1 -0
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
- package/src/resources/extensions/gsd/auto/loop-deps.ts +6 -0
- package/src/resources/extensions/gsd/auto/phases.ts +90 -10
- package/src/resources/extensions/gsd/auto-dispatch.ts +10 -4
- package/src/resources/extensions/gsd/auto-model-selection.ts +85 -11
- package/src/resources/extensions/gsd/auto-post-unit.ts +107 -58
- package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
- package/src/resources/extensions/gsd/auto-start.ts +30 -6
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
- package/src/resources/extensions/gsd/auto-verification.ts +98 -3
- package/src/resources/extensions/gsd/auto.ts +38 -14
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -8
- package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +20 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
- package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
- package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
- package/src/resources/extensions/gsd/commands-do.ts +109 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +8 -2
- package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
- package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
- package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
- package/src/resources/extensions/gsd/commands-ship.ts +219 -0
- package/src/resources/extensions/gsd/db-writer.ts +3 -5
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/graph-context.ts +85 -0
- package/src/resources/extensions/gsd/gsd-db.ts +467 -0
- package/src/resources/extensions/gsd/index.ts +18 -2
- package/src/resources/extensions/gsd/md-importer.ts +3 -5
- package/src/resources/extensions/gsd/memory-store.ts +31 -62
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
- package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
- package/src/resources/extensions/gsd/notification-widget.ts +2 -2
- package/src/resources/extensions/gsd/preferences-models.ts +41 -0
- package/src/resources/extensions/gsd/preferences-types.ts +12 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +23 -0
- package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
- package/src/resources/extensions/gsd/state.ts +80 -17
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
- package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +137 -1
- package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +91 -2
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +19 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
- package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
- package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
- package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
- package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
- package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{Qr27MOHx0lxRGnJvlhxxu → XnHY5eXUsTCFmNodWHetD}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qr27MOHx0lxRGnJvlhxxu → XnHY5eXUsTCFmNodWHetD}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
// GSD Extension — workflow-logger wiring regression tests
|
|
2
|
+
//
|
|
3
|
+
// Verifies the plumbing between workflow-logger and the rest of the state
|
|
4
|
+
// system (auto-loop phases, detect-stuck, notification store). Without this
|
|
5
|
+
// wiring, warnings/errors logged during a unit leak across units, never
|
|
6
|
+
// reach the user as a consolidated post-unit alert, and don't enrich
|
|
7
|
+
// stuck-detection reasons.
|
|
8
|
+
|
|
9
|
+
import test from "node:test";
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
logWarning,
|
|
16
|
+
logError,
|
|
17
|
+
peekLogs,
|
|
18
|
+
_resetLogs,
|
|
19
|
+
setStderrLoggingEnabled,
|
|
20
|
+
} from "../workflow-logger.ts";
|
|
21
|
+
import { detectStuck } from "../auto/detect-stuck.ts";
|
|
22
|
+
|
|
23
|
+
const phasesSrc = readFileSync(
|
|
24
|
+
join(import.meta.dirname, "..", "auto", "phases.ts"),
|
|
25
|
+
"utf-8",
|
|
26
|
+
);
|
|
27
|
+
const autoSrc = readFileSync(
|
|
28
|
+
join(import.meta.dirname, "..", "auto.ts"),
|
|
29
|
+
"utf-8",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// ─── Source-scan: phases.ts calls the logger lifecycle API ─────────────────
|
|
33
|
+
|
|
34
|
+
test("auto/phases.ts imports _resetLogs, drainAndSummarize, formatForNotification, hasAnyIssues", () => {
|
|
35
|
+
assert.match(
|
|
36
|
+
phasesSrc,
|
|
37
|
+
/from\s+"\.\.\/workflow-logger\.js"/,
|
|
38
|
+
"phases.ts imports from workflow-logger",
|
|
39
|
+
);
|
|
40
|
+
for (const name of [
|
|
41
|
+
"_resetLogs",
|
|
42
|
+
"drainLogs",
|
|
43
|
+
"drainAndSummarize",
|
|
44
|
+
"formatForNotification",
|
|
45
|
+
"hasAnyIssues",
|
|
46
|
+
]) {
|
|
47
|
+
assert.ok(
|
|
48
|
+
phasesSrc.includes(name),
|
|
49
|
+
`phases.ts should reference ${name}`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("runUnitPhase calls _resetLogs() before assigning s.currentUnit", () => {
|
|
55
|
+
// Find the "s.currentUnit = { type: unitType" assignment line and check
|
|
56
|
+
// the preceding ~500 chars contain a _resetLogs() call.
|
|
57
|
+
const idx = phasesSrc.indexOf("s.currentUnit = { type: unitType");
|
|
58
|
+
assert.ok(idx > 0, "runUnitPhase should assign s.currentUnit");
|
|
59
|
+
const before = phasesSrc.slice(Math.max(0, idx - 500), idx);
|
|
60
|
+
assert.match(
|
|
61
|
+
before,
|
|
62
|
+
/_resetLogs\(\)/,
|
|
63
|
+
"_resetLogs() must be called immediately before s.currentUnit assignment",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("runFinalize drains and surfaces logger buffer via ctx.ui.notify", () => {
|
|
68
|
+
// Locate the runFinalize success path and verify it calls drainAndSummarize
|
|
69
|
+
// and routes the result through ctx.ui.notify.
|
|
70
|
+
const runFinalizeIdx = phasesSrc.indexOf("export async function runFinalize");
|
|
71
|
+
assert.ok(runFinalizeIdx > 0, "runFinalize export should exist");
|
|
72
|
+
const finalizeBody = phasesSrc.slice(runFinalizeIdx);
|
|
73
|
+
assert.match(
|
|
74
|
+
finalizeBody,
|
|
75
|
+
/hasAnyIssues\(\)/,
|
|
76
|
+
"runFinalize should gate drain on hasAnyIssues",
|
|
77
|
+
);
|
|
78
|
+
assert.match(
|
|
79
|
+
finalizeBody,
|
|
80
|
+
/drainAndSummarize\(\)/,
|
|
81
|
+
"runFinalize should call drainAndSummarize on success",
|
|
82
|
+
);
|
|
83
|
+
assert.match(
|
|
84
|
+
finalizeBody,
|
|
85
|
+
/formatForNotification\(logs\)/,
|
|
86
|
+
"runFinalize should format drained logs for the notification",
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("runFinalize timeout branches drain the buffer to prevent bleed", () => {
|
|
91
|
+
// Both timeout branches null out s.currentUnit — they should also drain
|
|
92
|
+
// so accumulated logs for the timed-out unit don't leak into the next.
|
|
93
|
+
const runFinalizeIdx = phasesSrc.indexOf("export async function runFinalize");
|
|
94
|
+
const finalizeBody = phasesSrc.slice(runFinalizeIdx);
|
|
95
|
+
const drainCallCount =
|
|
96
|
+
(finalizeBody.match(/drainLogs\(\)/g) ?? []).length;
|
|
97
|
+
assert.ok(
|
|
98
|
+
drainCallCount >= 2,
|
|
99
|
+
`runFinalize timeout branches should each call drainLogs() (found ${drainCallCount}, expected >= 2)`,
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// ─── Source-scan: auto.ts calls setLogBasePath in startAuto ────────────────
|
|
104
|
+
|
|
105
|
+
test("startAuto calls setLogBasePath(base) so audit log is pinned on resume", () => {
|
|
106
|
+
const startAutoIdx = autoSrc.indexOf("export async function startAuto");
|
|
107
|
+
assert.ok(startAutoIdx > 0, "startAuto export should exist");
|
|
108
|
+
const body = autoSrc.slice(startAutoIdx);
|
|
109
|
+
assert.match(
|
|
110
|
+
body,
|
|
111
|
+
/setLogBasePath\(base\)/,
|
|
112
|
+
"startAuto must call setLogBasePath(base) to pin the audit log",
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// ─── Runtime: detect-stuck enriches reason with summarizeLogs() ────────────
|
|
117
|
+
|
|
118
|
+
test("detectStuck reason includes workflow-logger summary when logs present", () => {
|
|
119
|
+
setStderrLoggingEnabled(false);
|
|
120
|
+
try {
|
|
121
|
+
_resetLogs();
|
|
122
|
+
logWarning("projection", "STATE.md render failed");
|
|
123
|
+
logError("db", "WAL checkpoint failed");
|
|
124
|
+
|
|
125
|
+
const result = detectStuck([
|
|
126
|
+
{ key: "execute-task/slice-A/task-1", error: "ENOENT: no such file" },
|
|
127
|
+
{ key: "execute-task/slice-A/task-1", error: "ENOENT: no such file" },
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
assert.notEqual(result, null);
|
|
131
|
+
assert.equal(result!.stuck, true);
|
|
132
|
+
assert.match(
|
|
133
|
+
result!.reason,
|
|
134
|
+
/Same error repeated:/,
|
|
135
|
+
"reason should still start with the rule string",
|
|
136
|
+
);
|
|
137
|
+
assert.match(
|
|
138
|
+
result!.reason,
|
|
139
|
+
/STATE\.md render failed/,
|
|
140
|
+
"reason should include the accumulated logger warning",
|
|
141
|
+
);
|
|
142
|
+
assert.match(
|
|
143
|
+
result!.reason,
|
|
144
|
+
/WAL checkpoint failed/,
|
|
145
|
+
"reason should include the accumulated logger error",
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Critical: summarizeLogs must not drain — the auto-loop's finalize
|
|
149
|
+
// step owns the buffer lifecycle, detect-stuck is read-only.
|
|
150
|
+
assert.equal(
|
|
151
|
+
peekLogs().length,
|
|
152
|
+
2,
|
|
153
|
+
"detect-stuck must not drain the buffer",
|
|
154
|
+
);
|
|
155
|
+
} finally {
|
|
156
|
+
_resetLogs();
|
|
157
|
+
setStderrLoggingEnabled(true);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("detectStuck reason unchanged when logger buffer is empty", () => {
|
|
162
|
+
setStderrLoggingEnabled(false);
|
|
163
|
+
try {
|
|
164
|
+
_resetLogs();
|
|
165
|
+
const result = detectStuck([
|
|
166
|
+
{ key: "A", error: "boom" },
|
|
167
|
+
{ key: "A", error: "boom" },
|
|
168
|
+
]);
|
|
169
|
+
assert.notEqual(result, null);
|
|
170
|
+
// No trailing " — " suffix when there are no logs to summarize.
|
|
171
|
+
assert.doesNotMatch(
|
|
172
|
+
result!.reason,
|
|
173
|
+
/ — \d+ (error|warning)/,
|
|
174
|
+
"reason should have no logger suffix when buffer is empty",
|
|
175
|
+
);
|
|
176
|
+
} finally {
|
|
177
|
+
setStderrLoggingEnabled(true);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// ─── Runtime: readTransaction rollback failure surfaces via logError ────────
|
|
182
|
+
//
|
|
183
|
+
// snapshotState now delegates its transaction to readTransaction() in
|
|
184
|
+
// gsd-db.ts (single-writer refactor in #4198), so the split-brain
|
|
185
|
+
// ROLLBACK-failure log lives there, not in workflow-manifest.ts.
|
|
186
|
+
|
|
187
|
+
test("readTransaction logs ROLLBACK failures as split-brain signal", () => {
|
|
188
|
+
const dbSrc = readFileSync(
|
|
189
|
+
join(import.meta.dirname, "..", "gsd-db.ts"),
|
|
190
|
+
"utf-8",
|
|
191
|
+
);
|
|
192
|
+
assert.match(
|
|
193
|
+
dbSrc,
|
|
194
|
+
/logError\("db",\s*"snapshotState ROLLBACK failed"/,
|
|
195
|
+
"readTransaction ROLLBACK catch should call logError",
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// ─── Runtime: state.ts and workflow-projections.ts log silent bailouts ─────
|
|
200
|
+
|
|
201
|
+
test("state.ts logs roadmap read failures instead of silently continuing", () => {
|
|
202
|
+
const stateSrc = readFileSync(
|
|
203
|
+
join(import.meta.dirname, "..", "state.ts"),
|
|
204
|
+
"utf-8",
|
|
205
|
+
);
|
|
206
|
+
assert.match(
|
|
207
|
+
stateSrc,
|
|
208
|
+
/logWarning\("state",\s*"reconcileDiskToDb: roadmap read failed/,
|
|
209
|
+
"state.ts reconcileDiskToDb should log roadmap read failures",
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test("workflow-projections.ts logs DB probe failures instead of silent return", () => {
|
|
214
|
+
const projectionsSrc = readFileSync(
|
|
215
|
+
join(import.meta.dirname, "..", "workflow-projections.ts"),
|
|
216
|
+
"utf-8",
|
|
217
|
+
);
|
|
218
|
+
assert.match(
|
|
219
|
+
projectionsSrc,
|
|
220
|
+
/logWarning\("projection",\s*"renderStateProjection: DB handle probe failed/,
|
|
221
|
+
"renderStateProjection DB probe should log on failure",
|
|
222
|
+
);
|
|
223
|
+
});
|
|
@@ -424,6 +424,25 @@ export async function handleCompleteSlice(
|
|
|
424
424
|
logError("tool", `complete-slice event log FAILED — completion invisible to reconciliation`, { error: (eventErr as Error).message });
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
// Fire-and-forget graph rebuild — must NOT await, must NOT crash slice completion.
|
|
428
|
+
// Dynamic import of the package name (not a relative path) so it resolves
|
|
429
|
+
// correctly via package.json#exports in both development and production.
|
|
430
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
431
|
+
(async () => {
|
|
432
|
+
try {
|
|
433
|
+
const graphMod = await import("@gsd-build/mcp-server") as {
|
|
434
|
+
buildGraph: (dir: string) => Promise<{ nodes: unknown[]; edges: unknown[]; builtAt: string }>;
|
|
435
|
+
writeGraph: (gsdRoot: string, graph: unknown) => Promise<void>;
|
|
436
|
+
resolveGsdRoot: (basePath: string) => string;
|
|
437
|
+
};
|
|
438
|
+
const g = await graphMod.buildGraph(basePath);
|
|
439
|
+
await graphMod.writeGraph(graphMod.resolveGsdRoot(basePath), g);
|
|
440
|
+
} catch (graphErr) {
|
|
441
|
+
// Graph rebuild is best-effort — log at warning level but never propagate
|
|
442
|
+
logWarning("tool", `complete-slice graph rebuild failed (non-fatal): ${(graphErr as Error).message ?? String(graphErr)}`);
|
|
443
|
+
}
|
|
444
|
+
})();
|
|
445
|
+
|
|
427
446
|
return {
|
|
428
447
|
sliceId: params.sliceId,
|
|
429
448
|
milestoneId: params.milestoneId,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getMilestone,
|
|
6
6
|
getSliceStatusSummary,
|
|
7
7
|
getSliceTaskCounts,
|
|
8
|
-
|
|
8
|
+
readTransaction,
|
|
9
9
|
saveGateResult,
|
|
10
10
|
} from "../gsd-db.js";
|
|
11
11
|
import { GATE_REGISTRY } from "../gate-registry.js";
|
|
@@ -616,12 +616,9 @@ export async function executeMilestoneStatus(
|
|
|
616
616
|
};
|
|
617
617
|
}
|
|
618
618
|
|
|
619
|
-
|
|
620
|
-
adapter.exec("BEGIN");
|
|
621
|
-
try {
|
|
619
|
+
return readTransaction(() => {
|
|
622
620
|
const milestone = getMilestone(params.milestoneId);
|
|
623
621
|
if (!milestone) {
|
|
624
|
-
adapter.exec("COMMIT");
|
|
625
622
|
return {
|
|
626
623
|
content: [{ type: "text", text: `Milestone ${params.milestoneId} not found in database.` }],
|
|
627
624
|
details: { operation: "milestone_status", milestoneId: params.milestoneId, found: false },
|
|
@@ -635,8 +632,6 @@ export async function executeMilestoneStatus(
|
|
|
635
632
|
taskCounts: getSliceTaskCounts(params.milestoneId, s.id),
|
|
636
633
|
}));
|
|
637
634
|
|
|
638
|
-
adapter.exec("COMMIT");
|
|
639
|
-
|
|
640
635
|
const result = {
|
|
641
636
|
milestoneId: milestone.id,
|
|
642
637
|
title: milestone.title,
|
|
@@ -651,10 +646,7 @@ export async function executeMilestoneStatus(
|
|
|
651
646
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
652
647
|
details: { operation: "milestone_status", milestoneId: milestone.id, sliceCount: slices.length },
|
|
653
648
|
};
|
|
654
|
-
}
|
|
655
|
-
try { adapter.exec("ROLLBACK"); } catch { /* swallow */ }
|
|
656
|
-
throw txErr;
|
|
657
|
-
}
|
|
649
|
+
});
|
|
658
650
|
} catch (err) {
|
|
659
651
|
const msg = err instanceof Error ? err.message : String(err);
|
|
660
652
|
logWarning("tool", `gsd_milestone_status tool failed: ${msg}`);
|
|
@@ -111,14 +111,9 @@ export function executeReplan(
|
|
|
111
111
|
// Also write replan_triggered_at column for DB-backed detection
|
|
112
112
|
try {
|
|
113
113
|
const req = createRequire(import.meta.url);
|
|
114
|
-
const { isDbAvailable,
|
|
114
|
+
const { isDbAvailable, setSliceReplanTriggeredAt } = req("./gsd-db.js");
|
|
115
115
|
if (isDbAvailable()) {
|
|
116
|
-
|
|
117
|
-
if (adapter) {
|
|
118
|
-
adapter.prepare(
|
|
119
|
-
"UPDATE slices SET replan_triggered_at = :ts WHERE milestone_id = :mid AND id = :sid",
|
|
120
|
-
).run({ ":ts": ts, ":mid": mid, ":sid": sid });
|
|
121
|
-
}
|
|
116
|
+
setSliceReplanTriggeredAt(mid, sid, ts);
|
|
122
117
|
}
|
|
123
118
|
} catch {
|
|
124
119
|
// DB write is best-effort — disk file is the primary trigger for fallback path
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
_getAdapter,
|
|
3
|
-
|
|
3
|
+
readTransaction,
|
|
4
|
+
restoreManifest,
|
|
4
5
|
type MilestoneRow,
|
|
5
6
|
type SliceRow,
|
|
6
7
|
type TaskRow,
|
|
@@ -74,9 +75,7 @@ export function snapshotState(): StateManifest {
|
|
|
74
75
|
|
|
75
76
|
// Wrap all reads in a deferred transaction so the snapshot is consistent
|
|
76
77
|
// (all SELECTs see the same DB state even if a concurrent write lands between them).
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
try {
|
|
78
|
+
return readTransaction(() => {
|
|
80
79
|
const rawMilestones = db.prepare("SELECT * FROM milestones ORDER BY id").all() as Record<string, unknown>[];
|
|
81
80
|
const milestones: MilestoneRow[] = rawMilestones.map((r) => ({
|
|
82
81
|
id: r["id"] as string,
|
|
@@ -186,109 +185,15 @@ export function snapshotState(): StateManifest {
|
|
|
186
185
|
verification_evidence,
|
|
187
186
|
};
|
|
188
187
|
|
|
189
|
-
db.exec("COMMIT");
|
|
190
188
|
return result;
|
|
191
|
-
}
|
|
192
|
-
try { db.exec("ROLLBACK"); } catch { /* ignore rollback failure */ }
|
|
193
|
-
throw err;
|
|
194
|
-
}
|
|
189
|
+
});
|
|
195
190
|
}
|
|
196
191
|
|
|
197
192
|
// ─── restore ─────────────────────────────────────────────────────────────
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
* Only touches engine tables + decisions. Does NOT modify artifacts or memories.
|
|
203
|
-
*/
|
|
204
|
-
function restore(manifest: StateManifest): void {
|
|
205
|
-
const db = requireDb();
|
|
206
|
-
|
|
207
|
-
transaction(() => {
|
|
208
|
-
// Clear engine tables (order matters for foreign-key-like consistency)
|
|
209
|
-
db.exec("DELETE FROM verification_evidence");
|
|
210
|
-
db.exec("DELETE FROM tasks");
|
|
211
|
-
db.exec("DELETE FROM slices");
|
|
212
|
-
db.exec("DELETE FROM milestones");
|
|
213
|
-
db.exec("DELETE FROM decisions WHERE 1=1");
|
|
214
|
-
|
|
215
|
-
// Restore milestones
|
|
216
|
-
const msStmt = db.prepare(
|
|
217
|
-
`INSERT INTO milestones (id, title, status, depends_on, created_at, completed_at,
|
|
218
|
-
vision, success_criteria, key_risks, proof_strategy,
|
|
219
|
-
verification_contract, verification_integration, verification_operational, verification_uat,
|
|
220
|
-
definition_of_done, requirement_coverage, boundary_map_markdown)
|
|
221
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
222
|
-
);
|
|
223
|
-
for (const m of manifest.milestones) {
|
|
224
|
-
msStmt.run(
|
|
225
|
-
m.id, m.title, m.status,
|
|
226
|
-
JSON.stringify(m.depends_on), m.created_at, m.completed_at,
|
|
227
|
-
m.vision, JSON.stringify(m.success_criteria), JSON.stringify(m.key_risks),
|
|
228
|
-
JSON.stringify(m.proof_strategy),
|
|
229
|
-
m.verification_contract, m.verification_integration, m.verification_operational, m.verification_uat,
|
|
230
|
-
JSON.stringify(m.definition_of_done), m.requirement_coverage, m.boundary_map_markdown,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Restore slices
|
|
235
|
-
const slStmt = db.prepare(
|
|
236
|
-
`INSERT INTO slices (milestone_id, id, title, status, risk, depends, demo,
|
|
237
|
-
created_at, completed_at, full_summary_md, full_uat_md,
|
|
238
|
-
goal, success_criteria, proof_level, integration_closure, observability_impact,
|
|
239
|
-
sequence, replan_triggered_at)
|
|
240
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
241
|
-
);
|
|
242
|
-
for (const s of manifest.slices) {
|
|
243
|
-
slStmt.run(
|
|
244
|
-
s.milestone_id, s.id, s.title, s.status, s.risk,
|
|
245
|
-
JSON.stringify(s.depends), s.demo,
|
|
246
|
-
s.created_at, s.completed_at, s.full_summary_md, s.full_uat_md,
|
|
247
|
-
s.goal, s.success_criteria, s.proof_level, s.integration_closure, s.observability_impact,
|
|
248
|
-
s.sequence, s.replan_triggered_at,
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Restore tasks
|
|
253
|
-
const tkStmt = db.prepare(
|
|
254
|
-
`INSERT INTO tasks (milestone_id, slice_id, id, title, status,
|
|
255
|
-
one_liner, narrative, verification_result, duration, completed_at,
|
|
256
|
-
blocker_discovered, deviations, known_issues, key_files, key_decisions,
|
|
257
|
-
full_summary_md, description, estimate, files, verify,
|
|
258
|
-
inputs, expected_output, observability_impact, sequence)
|
|
259
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
260
|
-
);
|
|
261
|
-
for (const t of manifest.tasks) {
|
|
262
|
-
tkStmt.run(
|
|
263
|
-
t.milestone_id, t.slice_id, t.id, t.title, t.status,
|
|
264
|
-
t.one_liner, t.narrative, t.verification_result, t.duration, t.completed_at,
|
|
265
|
-
t.blocker_discovered ? 1 : 0, t.deviations, t.known_issues,
|
|
266
|
-
JSON.stringify(t.key_files), JSON.stringify(t.key_decisions),
|
|
267
|
-
t.full_summary_md, t.description, t.estimate, JSON.stringify(t.files), t.verify,
|
|
268
|
-
JSON.stringify(t.inputs), JSON.stringify(t.expected_output),
|
|
269
|
-
t.observability_impact, t.sequence,
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Restore decisions
|
|
274
|
-
const dcStmt = db.prepare(
|
|
275
|
-
`INSERT INTO decisions (seq, id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
|
|
276
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
277
|
-
);
|
|
278
|
-
for (const d of manifest.decisions) {
|
|
279
|
-
dcStmt.run(d.seq, d.id, d.when_context, d.scope, d.decision, d.choice, d.rationale, d.revisable, d.made_by, d.superseded_by);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Restore verification evidence
|
|
283
|
-
const evStmt = db.prepare(
|
|
284
|
-
`INSERT INTO verification_evidence (task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at)
|
|
285
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
286
|
-
);
|
|
287
|
-
for (const e of manifest.verification_evidence) {
|
|
288
|
-
evStmt.run(e.task_id, e.slice_id, e.milestone_id, e.command, e.exit_code, e.verdict, e.duration_ms, e.created_at);
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
}
|
|
193
|
+
//
|
|
194
|
+
// The actual restore() implementation lives in gsd-db.ts (single-writer
|
|
195
|
+
// invariant). This module only orchestrates reading the manifest file
|
|
196
|
+
// and handing it to the writer.
|
|
292
197
|
|
|
293
198
|
// ─── writeManifest ───────────────────────────────────────────────────────
|
|
294
199
|
|
|
@@ -346,6 +251,6 @@ export function bootstrapFromManifest(basePath: string): boolean {
|
|
|
346
251
|
return false;
|
|
347
252
|
}
|
|
348
253
|
|
|
349
|
-
|
|
254
|
+
restoreManifest(manifest);
|
|
350
255
|
return true;
|
|
351
256
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
-
import { _getAdapter,
|
|
8
|
+
import { _getAdapter, bulkInsertLegacyHierarchy } from "./gsd-db.js";
|
|
9
9
|
import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
|
|
10
10
|
import { logWarning } from "./workflow-logger.js";
|
|
11
11
|
|
|
@@ -219,34 +219,26 @@ export function migrateFromMarkdown(basePath: string): void {
|
|
|
219
219
|
return;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// Insert tasks (using v10 column names: sequence, blocker_discovered, full_summary_md)
|
|
244
|
-
const insertTask = db.prepare(
|
|
245
|
-
"INSERT INTO tasks (id, slice_id, milestone_id, title, description, status, estimate, files, sequence) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
|
246
|
-
);
|
|
247
|
-
for (const t of taskInserts) {
|
|
248
|
-
insertTask.run(t.id, t.sliceId, t.milestoneId, t.title, "", t.status, "", "[]", t.sequence);
|
|
249
|
-
}
|
|
222
|
+
bulkInsertLegacyHierarchy({
|
|
223
|
+
milestones: milestoneInserts,
|
|
224
|
+
slices: sliceInserts.map(s => ({
|
|
225
|
+
id: s.id,
|
|
226
|
+
milestoneId: s.milestoneId,
|
|
227
|
+
title: s.title,
|
|
228
|
+
status: s.status,
|
|
229
|
+
risk: s.risk,
|
|
230
|
+
sequence: s.sequence,
|
|
231
|
+
})),
|
|
232
|
+
tasks: taskInserts.map(t => ({
|
|
233
|
+
id: t.id,
|
|
234
|
+
sliceId: t.sliceId,
|
|
235
|
+
milestoneId: t.milestoneId,
|
|
236
|
+
title: t.title,
|
|
237
|
+
status: t.status,
|
|
238
|
+
sequence: t.sequence,
|
|
239
|
+
})),
|
|
240
|
+
clearMilestoneIds: migratedMilestoneIds,
|
|
241
|
+
createdAt: now,
|
|
250
242
|
});
|
|
251
243
|
}
|
|
252
244
|
|
|
@@ -350,7 +350,14 @@ export async function renderStateProjection(basePath: string): Promise<void> {
|
|
|
350
350
|
// Probe DB handle — adapter may be set but underlying handle closed
|
|
351
351
|
const adapter = _getAdapter();
|
|
352
352
|
if (!adapter) return;
|
|
353
|
-
try {
|
|
353
|
+
try {
|
|
354
|
+
adapter.prepare("SELECT 1").get();
|
|
355
|
+
} catch (err) {
|
|
356
|
+
logWarning("projection", "renderStateProjection: DB handle probe failed, skipping render", {
|
|
357
|
+
error: (err as Error).message,
|
|
358
|
+
});
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
354
361
|
const state = await deriveState(basePath);
|
|
355
362
|
const content = renderStateContent(state);
|
|
356
363
|
const dir = join(basePath, ".gsd");
|
|
@@ -10,12 +10,13 @@ import {
|
|
|
10
10
|
updateMilestoneStatus,
|
|
11
11
|
getSliceTasks,
|
|
12
12
|
insertMilestone,
|
|
13
|
-
_getAdapter,
|
|
14
13
|
getMilestoneSlices,
|
|
15
14
|
insertVerificationEvidence,
|
|
16
15
|
upsertDecision,
|
|
17
16
|
openDatabase,
|
|
18
17
|
setTaskBlockerDiscovered,
|
|
18
|
+
insertOrIgnoreSlice,
|
|
19
|
+
insertOrIgnoreTask,
|
|
19
20
|
} from "./gsd-db.js";
|
|
20
21
|
import { isClosedStatus } from "./status-guards.js";
|
|
21
22
|
import { invalidateStateCache } from "./state.js";
|
|
@@ -164,13 +165,12 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
164
165
|
const milestoneId = p["milestoneId"] as string;
|
|
165
166
|
const sliceId = p["sliceId"] as string;
|
|
166
167
|
if (milestoneId && sliceId) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
168
|
+
insertOrIgnoreSlice({
|
|
169
|
+
milestoneId,
|
|
170
|
+
sliceId,
|
|
171
|
+
title: (p["title"] as string) ?? sliceId,
|
|
172
|
+
createdAt: event.ts,
|
|
173
|
+
});
|
|
174
174
|
}
|
|
175
175
|
break;
|
|
176
176
|
}
|
|
@@ -182,13 +182,13 @@ function replayEvents(events: WorkflowEvent[]): void {
|
|
|
182
182
|
const sliceId = p["sliceId"] as string;
|
|
183
183
|
const taskId = p["taskId"] as string;
|
|
184
184
|
if (milestoneId && sliceId && taskId) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
185
|
+
insertOrIgnoreTask({
|
|
186
|
+
milestoneId,
|
|
187
|
+
sliceId,
|
|
188
|
+
taskId,
|
|
189
|
+
title: (p["title"] as string) ?? taskId,
|
|
190
|
+
createdAt: event.ts,
|
|
191
|
+
});
|
|
192
192
|
}
|
|
193
193
|
break;
|
|
194
194
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8974],{5214:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorage",{enumerable:!0,get:function(){return r.workAsyncStorageInstance}});let r=n(17828)},15726:(e,t,n)=>{Promise.resolve().then(n.bind(n,66919))},17828:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorageInstance",{enumerable:!0,get:function(){return r}});let r=(0,n(64054).createAsyncLocalStorage)()},21957:(e,t,n)=>{"use strict";function r({moduleIds:e}){return null}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadChunks",{enumerable:!0,get:function(){return r}}),n(95155),n(47650),n(5214),n(2451),n(53887)},37206:(e,t,n)=>{"use strict";n.d(t,{default:()=>u.a});var r=n(75707),u=n.n(r)},41112:(e,t,n)=>{"use strict";function r({reason:e,children:t}){return t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}}),n(1980)},64054:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n={bindSnapshot:function(){return s},createAsyncLocalStorage:function(){return a},createSnapshot:function(){return i}};for(var r in n)Object.defineProperty(t,r,{enumerable:!0,get:n[r]});let u=Object.defineProperty(Error("Invariant: AsyncLocalStorage accessed in runtime where it is not available"),"__NEXT_ERROR_CODE",{value:"E504",enumerable:!1,configurable:!0});class l{disable(){throw u}getStore(){}run(){throw u}exit(){throw u}enterWith(){throw u}static bind(e){return e}}let o="u">typeof globalThis&&globalThis.AsyncLocalStorage;function a(){return o?new o:new l}function s(e){return o?o.bind(e):l.bind(e)}function i(){return o?o.snapshot():function(e,...t){return e(...t)}}},66919:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(95155);let u=(0,n(37206).default)(()=>Promise.all([n.e(1838),n.e(6079),n.e(4986),n.e(2008),n.e(2826)]).then(n.bind(n,62826)).then(e=>e.GSDAppShell),{loadableGenerated:{webpack:()=>[62826]},ssr:!1,loading:()=>(0,r.jsx)("div",{className:"flex h-screen items-center justify-center bg-background text-sm text-muted-foreground",children:"Loading workspace…"})});function l(){return(0,r.jsx)(u,{})}},68635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}});let r=n(95155),u=n(12115),l=n(41112);function o(e){return{default:e&&"default"in e?e.default:e}}n(21957);let a={loader:()=>Promise.resolve(o(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},n=(0,u.lazy)(()=>t.loader().then(o)),s=t.loading;function i(e){let o=s?(0,r.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,i=a?u.Suspense:u.Fragment,c=t.ssr?(0,r.jsxs)(r.Fragment,{children:[null,(0,r.jsx)(n,{...e})]}):(0,r.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i,{...a?{fallback:o}:{},children:c})}return i.displayName="LoadableComponent",i}},75707:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let r=n(73623)._(n(68635));function u(e,t){let n={};"function"==typeof e&&(n.loader=e);let u={...n,...t};return(0,r.default)({...u,modules:u.loadableGenerated?.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=15726)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{2852:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,27123,23)),Promise.resolve().then(n.t.bind(n,61304,23)),Promise.resolve().then(n.t.bind(n,78616,23)),Promise.resolve().then(n.t.bind(n,64777,23)),Promise.resolve().then(n.t.bind(n,57121,23)),Promise.resolve().then(n.t.bind(n,74581,23)),Promise.resolve().then(n.t.bind(n,90484,23)),Promise.resolve().then(n.bind(n,86869))},19393:()=>{}},e=>{var s=s=>e(e.s=s);e.O(0,[8441,3794],()=>(s(83861),s(2852))),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{52560:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,27123,23))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=52560)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|