gsd-pi 2.44.0-dev.848dd4c → 2.44.0
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 +12 -30
- package/dist/resources/extensions/gsd/auto-start.js +0 -10
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -5
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- 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 +2 -2
- 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/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/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 +5 -5
- 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 +14 -14
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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 +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.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 +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +8 -6
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +26 -24
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +48 -29
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +44 -34
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +34 -30
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +12 -10
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +47 -43
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +43 -31
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +45 -40
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/src/resources/extensions/gsd/auto-start.ts +0 -14
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -8
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +16 -14
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +57 -43
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +523 -465
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +75 -73
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +56 -34
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +656 -533
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +143 -165
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +52 -29
- package/src/resources/extensions/gsd/tests/captures.test.ts +176 -148
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +33 -32
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +143 -141
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +59 -38
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +263 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +302 -250
- package/src/resources/extensions/gsd/tests/context-store.test.ts +367 -354
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +72 -68
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +106 -92
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +35 -27
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +237 -220
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +420 -390
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +92 -76
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +83 -68
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -152
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +101 -78
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +227 -192
- package/src/resources/extensions/gsd/tests/detection.test.ts +278 -232
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +34 -30
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +180 -164
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +49 -43
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +38 -34
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +75 -54
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +32 -21
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +97 -72
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +44 -38
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +145 -104
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +106 -84
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +60 -54
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +93 -72
- package/src/resources/extensions/gsd/tests/doctor.test.ts +134 -104
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +131 -123
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +24 -20
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +57 -48
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +42 -30
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +206 -198
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/git-service.test.ts +388 -285
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +39 -31
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +69 -63
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +264 -255
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +119 -108
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +103 -81
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +262 -229
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +102 -81
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +18 -16
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +46 -41
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +53 -42
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +194 -150
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +125 -101
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +54 -45
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +93 -80
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +66 -57
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +93 -83
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +170 -161
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +141 -125
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +131 -107
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +96 -87
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +164 -125
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +94 -81
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +36 -35
- package/src/resources/extensions/gsd/tests/overrides.test.ts +106 -99
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +47 -40
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +28 -25
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +83 -66
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +77 -54
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +115 -68
- package/src/resources/extensions/gsd/tests/parsers.test.ts +611 -546
- package/src/resources/extensions/gsd/tests/paths.test.ts +87 -72
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +117 -77
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +119 -93
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +82 -70
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +55 -42
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +73 -45
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +38 -28
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +80 -73
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +74 -71
- package/src/resources/extensions/gsd/tests/requirements.test.ts +75 -70
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +66 -44
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +181 -114
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +65 -63
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +128 -66
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +25 -18
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +28 -22
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +56 -54
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +25 -23
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +11 -9
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +82 -66
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +47 -46
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +22 -20
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +86 -84
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +43 -41
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +96 -94
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +52 -50
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +13 -10
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +18 -14
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +39 -38
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +21 -17
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +30 -25
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +22 -15
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +66 -59
- package/src/resources/extensions/gsd/tests/worktree.test.ts +50 -44
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -63
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
1
|
+
import { createTestContext } from './test-helpers.ts';
|
|
3
2
|
import * as fs from 'node:fs';
|
|
4
3
|
import * as path from 'node:path';
|
|
5
4
|
import * as os from 'node:os';
|
|
@@ -19,6 +18,8 @@ import {
|
|
|
19
18
|
_resetProvider,
|
|
20
19
|
} from '../gsd-db.ts';
|
|
21
20
|
|
|
21
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
22
|
+
|
|
22
23
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
24
|
// Helper: create a temp file path for file-backed DB tests
|
|
24
25
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -46,306 +47,314 @@ function cleanup(dbPath: string): void {
|
|
|
46
47
|
// gsd-db tests
|
|
47
48
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
console.log('\n=== gsd-db: provider detection ===');
|
|
51
|
+
{
|
|
52
|
+
const provider = getDbProvider();
|
|
53
|
+
assertTrue(provider !== null, 'provider should be non-null');
|
|
54
|
+
assertTrue(
|
|
55
|
+
provider === 'node:sqlite' || provider === 'better-sqlite3',
|
|
56
|
+
`provider should be a known name, got: ${provider}`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
console.log('\n=== gsd-db: fresh DB schema init (memory) ===');
|
|
61
|
+
{
|
|
62
|
+
const ok = openDatabase(':memory:');
|
|
63
|
+
assertTrue(ok, 'openDatabase should return true');
|
|
64
|
+
assertTrue(isDbAvailable(), 'isDbAvailable should be true after open');
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
// Check schema_version table
|
|
67
|
+
const adapter = _getAdapter()!;
|
|
68
|
+
const version = adapter.prepare('SELECT MAX(version) as version FROM schema_version').get();
|
|
69
|
+
assertEq(version?.['version'], 10, 'schema version should be 10');
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
// Check tables exist by querying them
|
|
72
|
+
const dRows = adapter.prepare('SELECT count(*) as cnt FROM decisions').get();
|
|
73
|
+
assertEq(dRows?.['cnt'], 0, 'decisions table should exist and be empty');
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
const rRows = adapter.prepare('SELECT count(*) as cnt FROM requirements').get();
|
|
76
|
+
assertEq(rRows?.['cnt'], 0, 'requirements table should exist and be empty');
|
|
77
|
+
|
|
78
|
+
closeDatabase();
|
|
79
|
+
assertTrue(!isDbAvailable(), 'isDbAvailable should be false after close');
|
|
80
|
+
}
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
console.log('\n=== gsd-db: double-init idempotency ===');
|
|
83
|
+
{
|
|
84
|
+
const dbPath = tempDbPath();
|
|
85
|
+
openDatabase(dbPath);
|
|
86
|
+
|
|
87
|
+
// Insert a decision so we can verify it survives re-init
|
|
88
|
+
insertDecision({
|
|
89
|
+
id: 'D001',
|
|
90
|
+
when_context: 'test',
|
|
91
|
+
scope: 'global',
|
|
92
|
+
decision: 'test decision',
|
|
93
|
+
choice: 'option A',
|
|
94
|
+
rationale: 'because',
|
|
95
|
+
revisable: 'yes',
|
|
96
|
+
made_by: 'agent',
|
|
97
|
+
superseded_by: null,
|
|
78
98
|
});
|
|
79
99
|
|
|
80
|
-
|
|
81
|
-
const dbPath = tempDbPath();
|
|
82
|
-
openDatabase(dbPath);
|
|
83
|
-
|
|
84
|
-
// Insert a decision so we can verify it survives re-init
|
|
85
|
-
insertDecision({
|
|
86
|
-
id: 'D001',
|
|
87
|
-
when_context: 'test',
|
|
88
|
-
scope: 'global',
|
|
89
|
-
decision: 'test decision',
|
|
90
|
-
choice: 'option A',
|
|
91
|
-
rationale: 'because',
|
|
92
|
-
revisable: 'yes',
|
|
93
|
-
made_by: 'agent',
|
|
94
|
-
superseded_by: null,
|
|
95
|
-
});
|
|
100
|
+
closeDatabase();
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
// Re-open same DB — schema init should be idempotent
|
|
103
|
+
openDatabase(dbPath);
|
|
104
|
+
const d = getDecisionById('D001');
|
|
105
|
+
assertTrue(d !== null, 'decision should survive re-init');
|
|
106
|
+
assertEq(d?.id, 'D001', 'decision ID preserved after re-init');
|
|
98
107
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
assert.deepStrictEqual(d?.id, 'D001', 'decision ID preserved after re-init');
|
|
108
|
+
// Schema version should still be 1 (not duplicated)
|
|
109
|
+
const adapter = _getAdapter()!;
|
|
110
|
+
const versions = adapter.prepare('SELECT count(*) as cnt FROM schema_version').get();
|
|
111
|
+
assertEq(versions?.['cnt'], 1, 'schema_version should have exactly 1 row after double-init');
|
|
104
112
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const versions = adapter.prepare('SELECT count(*) as cnt FROM schema_version').get();
|
|
108
|
-
assert.deepStrictEqual(versions?.['cnt'], 1, 'schema_version should have exactly 1 row after double-init');
|
|
113
|
+
cleanup(dbPath);
|
|
114
|
+
}
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
console.log('\n=== gsd-db: insert + get decision ===');
|
|
117
|
+
{
|
|
118
|
+
openDatabase(':memory:');
|
|
119
|
+
insertDecision({
|
|
120
|
+
id: 'D042',
|
|
121
|
+
when_context: 'during sprint 3',
|
|
122
|
+
scope: 'M001/S02',
|
|
123
|
+
decision: 'use SQLite for storage',
|
|
124
|
+
choice: 'node:sqlite',
|
|
125
|
+
rationale: 'built-in, zero deps',
|
|
126
|
+
revisable: 'yes, if perf insufficient',
|
|
127
|
+
made_by: 'agent',
|
|
128
|
+
superseded_by: null,
|
|
111
129
|
});
|
|
112
130
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
choice: 'node:sqlite',
|
|
121
|
-
rationale: 'built-in, zero deps',
|
|
122
|
-
revisable: 'yes, if perf insufficient',
|
|
123
|
-
made_by: 'agent',
|
|
124
|
-
superseded_by: null,
|
|
125
|
-
});
|
|
131
|
+
const d = getDecisionById('D042');
|
|
132
|
+
assertTrue(d !== null, 'should find inserted decision');
|
|
133
|
+
assertEq(d?.id, 'D042', 'decision id');
|
|
134
|
+
assertEq(d?.scope, 'M001/S02', 'decision scope');
|
|
135
|
+
assertEq(d?.choice, 'node:sqlite', 'decision choice');
|
|
136
|
+
assertTrue(typeof d?.seq === 'number' && d.seq > 0, 'seq should be auto-assigned positive number');
|
|
137
|
+
assertEq(d?.superseded_by, null, 'superseded_by should be null');
|
|
126
138
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
assert.deepStrictEqual(d?.scope, 'M001/S02', 'decision scope');
|
|
131
|
-
assert.deepStrictEqual(d?.choice, 'node:sqlite', 'decision choice');
|
|
132
|
-
assert.ok(typeof d?.seq === 'number' && d.seq > 0, 'seq should be auto-assigned positive number');
|
|
133
|
-
assert.deepStrictEqual(d?.superseded_by, null, 'superseded_by should be null');
|
|
139
|
+
// Non-existent
|
|
140
|
+
const missing = getDecisionById('D999');
|
|
141
|
+
assertEq(missing, null, 'non-existent decision returns null');
|
|
134
142
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
assert.deepStrictEqual(missing, null, 'non-existent decision returns null');
|
|
143
|
+
closeDatabase();
|
|
144
|
+
}
|
|
138
145
|
|
|
139
|
-
|
|
146
|
+
console.log('\n=== gsd-db: insert + get requirement ===');
|
|
147
|
+
{
|
|
148
|
+
openDatabase(':memory:');
|
|
149
|
+
insertRequirement({
|
|
150
|
+
id: 'R007',
|
|
151
|
+
class: 'functional',
|
|
152
|
+
status: 'active',
|
|
153
|
+
description: 'System must persist decisions',
|
|
154
|
+
why: 'decisions inform future agents',
|
|
155
|
+
source: 'M001-CONTEXT',
|
|
156
|
+
primary_owner: 'S01',
|
|
157
|
+
supporting_slices: 'S02, S03',
|
|
158
|
+
validation: 'insert and query roundtrip',
|
|
159
|
+
notes: 'high priority',
|
|
160
|
+
full_content: 'Full text of requirement...',
|
|
161
|
+
superseded_by: null,
|
|
140
162
|
});
|
|
141
163
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
why: 'decisions inform future agents',
|
|
150
|
-
source: 'M001-CONTEXT',
|
|
151
|
-
primary_owner: 'S01',
|
|
152
|
-
supporting_slices: 'S02, S03',
|
|
153
|
-
validation: 'insert and query roundtrip',
|
|
154
|
-
notes: 'high priority',
|
|
155
|
-
full_content: 'Full text of requirement...',
|
|
156
|
-
superseded_by: null,
|
|
157
|
-
});
|
|
164
|
+
const r = getRequirementById('R007');
|
|
165
|
+
assertTrue(r !== null, 'should find inserted requirement');
|
|
166
|
+
assertEq(r?.id, 'R007', 'requirement id');
|
|
167
|
+
assertEq(r?.class, 'functional', 'requirement class');
|
|
168
|
+
assertEq(r?.status, 'active', 'requirement status');
|
|
169
|
+
assertEq(r?.primary_owner, 'S01', 'requirement primary_owner');
|
|
170
|
+
assertEq(r?.superseded_by, null, 'superseded_by should be null');
|
|
158
171
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
assert.deepStrictEqual(r?.class, 'functional', 'requirement class');
|
|
163
|
-
assert.deepStrictEqual(r?.status, 'active', 'requirement status');
|
|
164
|
-
assert.deepStrictEqual(r?.primary_owner, 'S01', 'requirement primary_owner');
|
|
165
|
-
assert.deepStrictEqual(r?.superseded_by, null, 'superseded_by should be null');
|
|
172
|
+
// Non-existent
|
|
173
|
+
const missing = getRequirementById('R999');
|
|
174
|
+
assertEq(missing, null, 'non-existent requirement returns null');
|
|
166
175
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
assert.deepStrictEqual(missing, null, 'non-existent requirement returns null');
|
|
176
|
+
closeDatabase();
|
|
177
|
+
}
|
|
170
178
|
|
|
171
|
-
|
|
179
|
+
console.log('\n=== gsd-db: active_decisions view excludes superseded ===');
|
|
180
|
+
{
|
|
181
|
+
openDatabase(':memory:');
|
|
182
|
+
|
|
183
|
+
insertDecision({
|
|
184
|
+
id: 'D001',
|
|
185
|
+
when_context: 'early',
|
|
186
|
+
scope: 'global',
|
|
187
|
+
decision: 'use JSON files',
|
|
188
|
+
choice: 'JSON',
|
|
189
|
+
rationale: 'simple',
|
|
190
|
+
revisable: 'yes',
|
|
191
|
+
made_by: 'agent',
|
|
192
|
+
superseded_by: 'D002', // superseded!
|
|
172
193
|
});
|
|
173
194
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
made_by: 'agent',
|
|
186
|
-
superseded_by: 'D002', // superseded!
|
|
187
|
-
});
|
|
195
|
+
insertDecision({
|
|
196
|
+
id: 'D002',
|
|
197
|
+
when_context: 'later',
|
|
198
|
+
scope: 'global',
|
|
199
|
+
decision: 'use SQLite',
|
|
200
|
+
choice: 'SQLite',
|
|
201
|
+
rationale: 'better querying',
|
|
202
|
+
revisable: 'yes',
|
|
203
|
+
made_by: 'agent',
|
|
204
|
+
superseded_by: null, // active
|
|
205
|
+
});
|
|
188
206
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
207
|
+
insertDecision({
|
|
208
|
+
id: 'D003',
|
|
209
|
+
when_context: 'same time',
|
|
210
|
+
scope: 'local',
|
|
211
|
+
decision: 'use WAL mode',
|
|
212
|
+
choice: 'WAL',
|
|
213
|
+
rationale: 'concurrent reads',
|
|
214
|
+
revisable: 'no',
|
|
215
|
+
made_by: 'agent',
|
|
216
|
+
superseded_by: null, // active
|
|
217
|
+
});
|
|
200
218
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
decision: 'use WAL mode',
|
|
206
|
-
choice: 'WAL',
|
|
207
|
-
rationale: 'concurrent reads',
|
|
208
|
-
revisable: 'no',
|
|
209
|
-
made_by: 'agent',
|
|
210
|
-
superseded_by: null, // active
|
|
211
|
-
});
|
|
219
|
+
const active = getActiveDecisions();
|
|
220
|
+
assertEq(active.length, 2, 'active_decisions should return 2 (not the superseded one)');
|
|
221
|
+
const ids = active.map(d => d.id).sort();
|
|
222
|
+
assertEq(ids, ['D002', 'D003'], 'active decisions should be D002 and D003');
|
|
212
223
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
224
|
+
// Verify D001 is still in the raw table
|
|
225
|
+
const d1 = getDecisionById('D001');
|
|
226
|
+
assertTrue(d1 !== null, 'superseded decision still exists in raw table');
|
|
227
|
+
assertEq(d1?.superseded_by, 'D002', 'superseded_by is set');
|
|
217
228
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
assert.ok(d1 !== null, 'superseded decision still exists in raw table');
|
|
221
|
-
assert.deepStrictEqual(d1?.superseded_by, 'D002', 'superseded_by is set');
|
|
229
|
+
closeDatabase();
|
|
230
|
+
}
|
|
222
231
|
|
|
223
|
-
|
|
232
|
+
console.log('\n=== gsd-db: active_requirements view excludes superseded ===');
|
|
233
|
+
{
|
|
234
|
+
openDatabase(':memory:');
|
|
235
|
+
|
|
236
|
+
insertRequirement({
|
|
237
|
+
id: 'R001',
|
|
238
|
+
class: 'functional',
|
|
239
|
+
status: 'active',
|
|
240
|
+
description: 'old requirement',
|
|
241
|
+
why: 'was needed',
|
|
242
|
+
source: 'M001',
|
|
243
|
+
primary_owner: 'S01',
|
|
244
|
+
supporting_slices: '',
|
|
245
|
+
validation: 'test',
|
|
246
|
+
notes: '',
|
|
247
|
+
full_content: '',
|
|
248
|
+
superseded_by: 'R002', // superseded!
|
|
224
249
|
});
|
|
225
250
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
full_content: '',
|
|
241
|
-
superseded_by: 'R002', // superseded!
|
|
242
|
-
});
|
|
251
|
+
insertRequirement({
|
|
252
|
+
id: 'R002',
|
|
253
|
+
class: 'functional',
|
|
254
|
+
status: 'active',
|
|
255
|
+
description: 'new requirement',
|
|
256
|
+
why: 'replaces R001',
|
|
257
|
+
source: 'M001',
|
|
258
|
+
primary_owner: 'S01',
|
|
259
|
+
supporting_slices: '',
|
|
260
|
+
validation: 'test',
|
|
261
|
+
notes: '',
|
|
262
|
+
full_content: '',
|
|
263
|
+
superseded_by: null, // active
|
|
264
|
+
});
|
|
243
265
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
status: 'active',
|
|
248
|
-
description: 'new requirement',
|
|
249
|
-
why: 'replaces R001',
|
|
250
|
-
source: 'M001',
|
|
251
|
-
primary_owner: 'S01',
|
|
252
|
-
supporting_slices: '',
|
|
253
|
-
validation: 'test',
|
|
254
|
-
notes: '',
|
|
255
|
-
full_content: '',
|
|
256
|
-
superseded_by: null, // active
|
|
257
|
-
});
|
|
266
|
+
const active = getActiveRequirements();
|
|
267
|
+
assertEq(active.length, 1, 'active_requirements should return 1');
|
|
268
|
+
assertEq(active[0]?.id, 'R002', 'only R002 should be active');
|
|
258
269
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
270
|
+
// R001 still in raw table
|
|
271
|
+
const r1 = getRequirementById('R001');
|
|
272
|
+
assertTrue(r1 !== null, 'superseded requirement still in raw table');
|
|
262
273
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
assert.ok(r1 !== null, 'superseded requirement still in raw table');
|
|
274
|
+
closeDatabase();
|
|
275
|
+
}
|
|
266
276
|
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
console.log('\n=== gsd-db: WAL mode on file-backed DB ===');
|
|
278
|
+
{
|
|
279
|
+
const dbPath = tempDbPath();
|
|
280
|
+
openDatabase(dbPath);
|
|
269
281
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
282
|
+
const adapter = _getAdapter()!;
|
|
283
|
+
const mode = adapter.prepare('PRAGMA journal_mode').get();
|
|
284
|
+
assertEq(mode?.['journal_mode'], 'wal', 'journal_mode should be wal for file-backed DB');
|
|
273
285
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
assert.deepStrictEqual(mode?.['journal_mode'], 'wal', 'journal_mode should be wal for file-backed DB');
|
|
286
|
+
cleanup(dbPath);
|
|
287
|
+
}
|
|
277
288
|
|
|
278
|
-
|
|
289
|
+
console.log('\n=== gsd-db: transaction rollback on error ===');
|
|
290
|
+
{
|
|
291
|
+
openDatabase(':memory:');
|
|
292
|
+
|
|
293
|
+
// Insert a decision normally
|
|
294
|
+
insertDecision({
|
|
295
|
+
id: 'D010',
|
|
296
|
+
when_context: 'test',
|
|
297
|
+
scope: 'test',
|
|
298
|
+
decision: 'test',
|
|
299
|
+
choice: 'test',
|
|
300
|
+
rationale: 'test',
|
|
301
|
+
revisable: 'test',
|
|
302
|
+
made_by: 'agent',
|
|
303
|
+
superseded_by: null,
|
|
279
304
|
});
|
|
280
305
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
// Try a transaction that fails — the insert inside should be rolled back
|
|
298
|
-
let threw = false;
|
|
299
|
-
try {
|
|
300
|
-
transaction(() => {
|
|
301
|
-
insertDecision({
|
|
302
|
-
id: 'D011',
|
|
303
|
-
when_context: 'should be rolled back',
|
|
304
|
-
scope: 'test',
|
|
305
|
-
decision: 'test',
|
|
306
|
-
choice: 'test',
|
|
307
|
-
rationale: 'test',
|
|
308
|
-
revisable: 'test',
|
|
309
|
-
made_by: 'agent',
|
|
310
|
-
superseded_by: null,
|
|
311
|
-
});
|
|
312
|
-
throw new Error('intentional failure');
|
|
306
|
+
// Try a transaction that fails — the insert inside should be rolled back
|
|
307
|
+
let threw = false;
|
|
308
|
+
try {
|
|
309
|
+
transaction(() => {
|
|
310
|
+
insertDecision({
|
|
311
|
+
id: 'D011',
|
|
312
|
+
when_context: 'should be rolled back',
|
|
313
|
+
scope: 'test',
|
|
314
|
+
decision: 'test',
|
|
315
|
+
choice: 'test',
|
|
316
|
+
rationale: 'test',
|
|
317
|
+
revisable: 'test',
|
|
318
|
+
made_by: 'agent',
|
|
319
|
+
superseded_by: null,
|
|
313
320
|
});
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
321
|
+
throw new Error('intentional failure');
|
|
322
|
+
});
|
|
323
|
+
} catch (err) {
|
|
324
|
+
if ((err as Error).message === 'intentional failure') {
|
|
325
|
+
threw = true;
|
|
318
326
|
}
|
|
327
|
+
}
|
|
319
328
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
// D010 should still be there
|
|
325
|
-
const d10 = getDecisionById('D010');
|
|
326
|
-
assert.ok(d10 !== null, 'D010 should survive the failed transaction');
|
|
329
|
+
assertTrue(threw, 'transaction should re-throw the error');
|
|
330
|
+
const d11 = getDecisionById('D011');
|
|
331
|
+
assertEq(d11, null, 'D011 should be rolled back (not found)');
|
|
327
332
|
|
|
328
|
-
|
|
329
|
-
|
|
333
|
+
// D010 should still be there
|
|
334
|
+
const d10 = getDecisionById('D010');
|
|
335
|
+
assertTrue(d10 !== null, 'D010 should survive the failed transaction');
|
|
330
336
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
closeDatabase();
|
|
334
|
-
assert.ok(!isDbAvailable(), 'DB should not be available');
|
|
337
|
+
closeDatabase();
|
|
338
|
+
}
|
|
335
339
|
|
|
336
|
-
|
|
337
|
-
|
|
340
|
+
console.log('\n=== gsd-db: query wrappers return null/empty when DB unavailable ===');
|
|
341
|
+
{
|
|
342
|
+
// Ensure DB is closed
|
|
343
|
+
closeDatabase();
|
|
344
|
+
assertTrue(!isDbAvailable(), 'DB should not be available');
|
|
338
345
|
|
|
339
|
-
|
|
340
|
-
|
|
346
|
+
const d = getDecisionById('D001');
|
|
347
|
+
assertEq(d, null, 'getDecisionById returns null when DB closed');
|
|
341
348
|
|
|
342
|
-
|
|
343
|
-
|
|
349
|
+
const r = getRequirementById('R001');
|
|
350
|
+
assertEq(r, null, 'getRequirementById returns null when DB closed');
|
|
344
351
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
});
|
|
352
|
+
const ad = getActiveDecisions();
|
|
353
|
+
assertEq(ad, [], 'getActiveDecisions returns [] when DB closed');
|
|
348
354
|
|
|
349
|
-
|
|
355
|
+
const ar = getActiveRequirements();
|
|
356
|
+
assertEq(ar, [], 'getActiveRequirements returns [] when DB closed');
|
|
357
|
+
}
|
|
350
358
|
|
|
351
|
-
|
|
359
|
+
// ─── Final Report ──────────────────────────────────────────────────────────
|
|
360
|
+
report();
|