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
|
@@ -91,140 +91,142 @@ async function loadGuidanceExport(): Promise<{ collectOneSecretWithGuidance: Fun
|
|
|
91
91
|
|
|
92
92
|
// ─── collectSecretsFromManifest: categorization ───────────────────────────────
|
|
93
93
|
|
|
94
|
-
test("collectSecretsFromManifest: categorizes entries — pending keys need collection, existing keys are skipped", async (
|
|
94
|
+
test("collectSecretsFromManifest: categorizes entries — pending keys need collection, existing keys are skipped", async () => {
|
|
95
95
|
const { collectSecretsFromManifest } = await loadOrchestrator();
|
|
96
96
|
|
|
97
97
|
const tmp = makeTempDir("manifest-collect");
|
|
98
98
|
const savedA = process.env.EXISTING_KEY_A;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
custom: async (_factory: any) => {
|
|
120
|
-
callIndex++;
|
|
121
|
-
if (callIndex <= 1) return null; // summary screen dismiss
|
|
122
|
-
return "mock-secret-value"; // collect pending key
|
|
99
|
+
try {
|
|
100
|
+
process.env.EXISTING_KEY_A = "already-set";
|
|
101
|
+
|
|
102
|
+
const manifest = makeManifest([
|
|
103
|
+
{ key: "EXISTING_KEY_A", status: "pending" },
|
|
104
|
+
{ key: "PENDING_KEY_B", status: "pending", guidance: ["Step 1: Go to dashboard", "Step 2: Click create key"] },
|
|
105
|
+
{ key: "SKIPPED_KEY_C", status: "skipped" },
|
|
106
|
+
]);
|
|
107
|
+
await writeManifestFile(tmp, manifest);
|
|
108
|
+
|
|
109
|
+
let callIndex = 0;
|
|
110
|
+
const mockCtx = {
|
|
111
|
+
cwd: tmp,
|
|
112
|
+
hasUI: true,
|
|
113
|
+
ui: {
|
|
114
|
+
custom: async (_factory: any) => {
|
|
115
|
+
callIndex++;
|
|
116
|
+
if (callIndex <= 1) return null; // summary screen dismiss
|
|
117
|
+
return "mock-secret-value"; // collect pending key
|
|
118
|
+
},
|
|
123
119
|
},
|
|
124
|
-
}
|
|
125
|
-
};
|
|
120
|
+
};
|
|
126
121
|
|
|
127
|
-
|
|
122
|
+
const result = await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
|
|
128
123
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
124
|
+
// EXISTING_KEY_A should be in existingSkipped (it's in process.env)
|
|
125
|
+
assert.ok(result.existingSkipped?.includes("EXISTING_KEY_A"),
|
|
126
|
+
"EXISTING_KEY_A should be in existingSkipped");
|
|
132
127
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
// PENDING_KEY_B should have been collected (applied)
|
|
129
|
+
assert.ok(result.applied.includes("PENDING_KEY_B"),
|
|
130
|
+
"PENDING_KEY_B should be in applied");
|
|
136
131
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
// SKIPPED_KEY_C should remain skipped
|
|
133
|
+
assert.ok(result.skipped.includes("SKIPPED_KEY_C"),
|
|
134
|
+
"SKIPPED_KEY_C should be in skipped");
|
|
135
|
+
} finally {
|
|
136
|
+
delete process.env.EXISTING_KEY_A;
|
|
137
|
+
if (savedA !== undefined) process.env.EXISTING_KEY_A = savedA;
|
|
138
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
-
test("collectSecretsFromManifest: existing keys are excluded from the collection list — not prompted", async (
|
|
142
|
+
test("collectSecretsFromManifest: existing keys are excluded from the collection list — not prompted", async () => {
|
|
143
143
|
const { collectSecretsFromManifest } = await loadOrchestrator();
|
|
144
144
|
|
|
145
145
|
const tmp = makeTempDir("manifest-collect-skip");
|
|
146
146
|
const savedA = process.env.ALREADY_SET_KEY;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return null; // dismiss summary
|
|
172
|
-
}
|
|
173
|
-
collectedKeyNames.push("prompted");
|
|
174
|
-
return "mock-value";
|
|
147
|
+
try {
|
|
148
|
+
process.env.ALREADY_SET_KEY = "present";
|
|
149
|
+
|
|
150
|
+
const manifest = makeManifest([
|
|
151
|
+
{ key: "ALREADY_SET_KEY", status: "pending" },
|
|
152
|
+
{ key: "NEEDS_COLLECTION", status: "pending" },
|
|
153
|
+
]);
|
|
154
|
+
await writeManifestFile(tmp, manifest);
|
|
155
|
+
|
|
156
|
+
const collectedKeyNames: string[] = [];
|
|
157
|
+
let summaryShown = false;
|
|
158
|
+
const mockCtx = {
|
|
159
|
+
cwd: tmp,
|
|
160
|
+
hasUI: true,
|
|
161
|
+
ui: {
|
|
162
|
+
custom: async (factory: any) => {
|
|
163
|
+
// Intercept the factory to check what key is being collected
|
|
164
|
+
if (!summaryShown) {
|
|
165
|
+
summaryShown = true;
|
|
166
|
+
return null; // dismiss summary
|
|
167
|
+
}
|
|
168
|
+
collectedKeyNames.push("prompted");
|
|
169
|
+
return "mock-value";
|
|
170
|
+
},
|
|
175
171
|
},
|
|
176
|
-
}
|
|
177
|
-
};
|
|
172
|
+
};
|
|
178
173
|
|
|
179
|
-
|
|
174
|
+
const result = await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
|
|
180
175
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
176
|
+
// ALREADY_SET_KEY should not have been prompted — only NEEDS_COLLECTION should
|
|
177
|
+
assert.ok(!result.applied.includes("ALREADY_SET_KEY"),
|
|
178
|
+
"ALREADY_SET_KEY should not be in applied (it was auto-skipped)");
|
|
179
|
+
assert.ok(result.existingSkipped?.includes("ALREADY_SET_KEY"),
|
|
180
|
+
"ALREADY_SET_KEY should be in existingSkipped");
|
|
181
|
+
} finally {
|
|
182
|
+
delete process.env.ALREADY_SET_KEY;
|
|
183
|
+
if (savedA !== undefined) process.env.ALREADY_SET_KEY = savedA;
|
|
184
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
185
|
+
}
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
-
test("collectSecretsFromManifest: manifest statuses are updated after collection", async (
|
|
188
|
+
test("collectSecretsFromManifest: manifest statuses are updated after collection", async () => {
|
|
189
189
|
const { collectSecretsFromManifest } = await loadOrchestrator();
|
|
190
190
|
|
|
191
191
|
const tmp = makeTempDir("manifest-update");
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
192
|
+
try {
|
|
193
|
+
const manifest = makeManifest([
|
|
194
|
+
{ key: "KEY_TO_COLLECT", status: "pending" },
|
|
195
|
+
{ key: "KEY_TO_SKIP", status: "pending" },
|
|
196
|
+
]);
|
|
197
|
+
const manifestPath = await writeManifestFile(tmp, manifest);
|
|
198
|
+
|
|
199
|
+
let callIndex = 0;
|
|
200
|
+
const mockCtx = {
|
|
201
|
+
cwd: tmp,
|
|
202
|
+
hasUI: true,
|
|
203
|
+
ui: {
|
|
204
|
+
custom: async (_factory: any) => {
|
|
205
|
+
callIndex++;
|
|
206
|
+
if (callIndex <= 1) return null; // summary screen dismiss
|
|
207
|
+
if (callIndex === 2) return "secret-value"; // KEY_TO_COLLECT
|
|
208
|
+
return null; // KEY_TO_SKIP — user skips
|
|
209
|
+
},
|
|
210
210
|
},
|
|
211
|
-
}
|
|
212
|
-
};
|
|
211
|
+
};
|
|
213
212
|
|
|
214
|
-
|
|
213
|
+
await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
|
|
215
214
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
// Read back the manifest file and verify statuses were updated
|
|
216
|
+
const { parseSecretsManifest } = await loadFilesExports();
|
|
217
|
+
const updatedContent = readFileSync(manifestPath, "utf8");
|
|
218
|
+
const updatedManifest = parseSecretsManifest(updatedContent);
|
|
220
219
|
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
const keyToCollect = updatedManifest.entries.find(e => e.key === "KEY_TO_COLLECT");
|
|
221
|
+
const keyToSkip = updatedManifest.entries.find(e => e.key === "KEY_TO_SKIP");
|
|
223
222
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
assert.equal(keyToCollect?.status, "collected",
|
|
224
|
+
"KEY_TO_COLLECT should have status 'collected' after providing a value");
|
|
225
|
+
assert.equal(keyToSkip?.status, "skipped",
|
|
226
|
+
"KEY_TO_SKIP should have status 'skipped' after user skipped it");
|
|
227
|
+
} finally {
|
|
228
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
229
|
+
}
|
|
228
230
|
});
|
|
229
231
|
|
|
230
232
|
// ─── showSecretsSummary: render output ────────────────────────────────────────
|
|
@@ -421,47 +423,47 @@ test("collectOneSecret: no guidance provided — render output has no guidance s
|
|
|
421
423
|
|
|
422
424
|
// ─── collectSecretsFromManifest: returns structured result ────────────────────
|
|
423
425
|
|
|
424
|
-
test("collectSecretsFromManifest: returns result with applied, skipped, and existingSkipped arrays", async (
|
|
426
|
+
test("collectSecretsFromManifest: returns result with applied, skipped, and existingSkipped arrays", async () => {
|
|
425
427
|
const { collectSecretsFromManifest } = await loadOrchestrator();
|
|
426
428
|
|
|
427
429
|
const tmp = makeTempDir("manifest-result");
|
|
428
430
|
const savedKey = process.env.RESULT_TEST_EXISTING;
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
custom: async (_factory: any) => {
|
|
449
|
-
callIndex++;
|
|
450
|
-
if (callIndex <= 1) return null; // summary dismiss
|
|
451
|
-
return "secret-value"; // collect the pending key
|
|
431
|
+
try {
|
|
432
|
+
process.env.RESULT_TEST_EXISTING = "already-here";
|
|
433
|
+
|
|
434
|
+
const manifest = makeManifest([
|
|
435
|
+
{ key: "RESULT_TEST_EXISTING", status: "pending" },
|
|
436
|
+
{ key: "RESULT_TEST_NEW", status: "pending" },
|
|
437
|
+
]);
|
|
438
|
+
await writeManifestFile(tmp, manifest);
|
|
439
|
+
|
|
440
|
+
let callIndex = 0;
|
|
441
|
+
const mockCtx = {
|
|
442
|
+
cwd: tmp,
|
|
443
|
+
hasUI: true,
|
|
444
|
+
ui: {
|
|
445
|
+
custom: async (_factory: any) => {
|
|
446
|
+
callIndex++;
|
|
447
|
+
if (callIndex <= 1) return null; // summary dismiss
|
|
448
|
+
return "secret-value"; // collect the pending key
|
|
449
|
+
},
|
|
452
450
|
},
|
|
453
|
-
}
|
|
454
|
-
};
|
|
451
|
+
};
|
|
455
452
|
|
|
456
|
-
|
|
453
|
+
const result = await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
|
|
457
454
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
455
|
+
// Verify result shape
|
|
456
|
+
assert.ok(Array.isArray(result.applied), "result should have applied array");
|
|
457
|
+
assert.ok(Array.isArray(result.skipped), "result should have skipped array");
|
|
458
|
+
assert.ok(Array.isArray(result.existingSkipped), "result should have existingSkipped array");
|
|
462
459
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
460
|
+
assert.ok(result.existingSkipped.includes("RESULT_TEST_EXISTING"),
|
|
461
|
+
"existing key should be in existingSkipped");
|
|
462
|
+
assert.ok(result.applied.includes("RESULT_TEST_NEW"),
|
|
463
|
+
"collected key should be in applied");
|
|
464
|
+
} finally {
|
|
465
|
+
delete process.env.RESULT_TEST_EXISTING;
|
|
466
|
+
if (savedKey !== undefined) process.env.RESULT_TEST_EXISTING = savedKey;
|
|
467
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
468
|
+
}
|
|
467
469
|
});
|
|
@@ -7,40 +7,40 @@ import fs from "node:fs";
|
|
|
7
7
|
import { handleInspect } from "../commands-inspect.ts";
|
|
8
8
|
import { closeDatabase, openDatabase } from "../gsd-db.ts";
|
|
9
9
|
|
|
10
|
-
test("/gsd inspect opens existing database when it was not yet opened in session", async (
|
|
10
|
+
test("/gsd inspect opens existing database when it was not yet opened in session", async () => {
|
|
11
11
|
closeDatabase();
|
|
12
12
|
|
|
13
13
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gsd-inspect-db-"));
|
|
14
14
|
const prevCwd = process.cwd();
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
16
|
+
try {
|
|
17
|
+
const gsdDir = path.join(tmp, ".gsd");
|
|
18
|
+
fs.mkdirSync(gsdDir, { recursive: true });
|
|
19
|
+
const dbPath = path.join(gsdDir, "gsd.db");
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const dbPath = path.join(gsdDir, "gsd.db");
|
|
25
|
-
|
|
26
|
-
assert.equal(openDatabase(dbPath), true);
|
|
27
|
-
closeDatabase();
|
|
21
|
+
assert.equal(openDatabase(dbPath), true);
|
|
22
|
+
closeDatabase();
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
process.chdir(tmp);
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
const notifications: Array<{ message: string; level: string }> = [];
|
|
27
|
+
const ctx = {
|
|
28
|
+
ui: {
|
|
29
|
+
notify(message: string, level: string) {
|
|
30
|
+
notifications.push({ message, level });
|
|
31
|
+
},
|
|
36
32
|
},
|
|
37
|
-
}
|
|
38
|
-
} as any;
|
|
33
|
+
} as any;
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
await handleInspect(ctx);
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
assert.equal(notifications.length, 1);
|
|
38
|
+
assert.equal(notifications[0].level, "info");
|
|
39
|
+
assert.match(notifications[0].message, /=== GSD Database Inspect ===/);
|
|
40
|
+
assert.doesNotMatch(notifications[0].message, /No GSD database available/);
|
|
41
|
+
} finally {
|
|
42
|
+
process.chdir(prevCwd);
|
|
43
|
+
closeDatabase();
|
|
44
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
45
|
+
}
|
|
46
46
|
});
|
|
@@ -42,22 +42,22 @@ function writeDebugLog(dir: string, name: string, entries: Record<string, unknow
|
|
|
42
42
|
|
|
43
43
|
// ─── Tests ──────────────────────────────────────────────────────────────────
|
|
44
44
|
|
|
45
|
-
test("logs shows empty state message when no logs exist", async (
|
|
45
|
+
test("logs shows empty state message when no logs exist", async () => {
|
|
46
46
|
const dir = createTestDir();
|
|
47
47
|
const ctx = createMockCtx();
|
|
48
48
|
const origCwd = process.cwd();
|
|
49
49
|
process.chdir(dir);
|
|
50
|
-
|
|
50
|
+
try {
|
|
51
|
+
await handleLogs("", ctx as any);
|
|
52
|
+
assert.equal(ctx.notifications.length, 1);
|
|
53
|
+
assert.ok(ctx.notifications[0].msg.includes("No logs found"));
|
|
54
|
+
} finally {
|
|
51
55
|
process.chdir(origCwd);
|
|
52
56
|
rmSync(dir, { recursive: true, force: true });
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
await handleLogs("", ctx as any);
|
|
56
|
-
assert.equal(ctx.notifications.length, 1);
|
|
57
|
-
assert.ok(ctx.notifications[0].msg.includes("No logs found"));
|
|
57
|
+
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
test("logs lists activity logs", async (
|
|
60
|
+
test("logs lists activity logs", async () => {
|
|
61
61
|
const dir = createTestDir();
|
|
62
62
|
const ctx = createMockCtx();
|
|
63
63
|
const origCwd = process.cwd();
|
|
@@ -71,21 +71,21 @@ test("logs lists activity logs", async (t) => {
|
|
|
71
71
|
{ role: "assistant", content: "Completing slice S01" },
|
|
72
72
|
]);
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
try {
|
|
75
|
+
await handleLogs("", ctx as any);
|
|
76
|
+
assert.equal(ctx.notifications.length, 1);
|
|
77
|
+
const msg = ctx.notifications[0].msg;
|
|
78
|
+
assert.ok(msg.includes("Activity Logs"), "should show activity logs header");
|
|
79
|
+
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
80
|
+
assert.ok(msg.includes("complete-slice"), "should show second log");
|
|
81
|
+
assert.ok(msg.includes("/gsd logs <#>"), "should show usage hint");
|
|
82
|
+
} finally {
|
|
75
83
|
process.chdir(origCwd);
|
|
76
84
|
rmSync(dir, { recursive: true, force: true });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
await handleLogs("", ctx as any);
|
|
80
|
-
assert.equal(ctx.notifications.length, 1);
|
|
81
|
-
const msg = ctx.notifications[0].msg;
|
|
82
|
-
assert.ok(msg.includes("Activity Logs"), "should show activity logs header");
|
|
83
|
-
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
84
|
-
assert.ok(msg.includes("complete-slice"), "should show second log");
|
|
85
|
-
assert.ok(msg.includes("/gsd logs <#>"), "should show usage hint");
|
|
85
|
+
}
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
test("logs <N> shows activity log details", async (
|
|
88
|
+
test("logs <N> shows activity log details", async () => {
|
|
89
89
|
const dir = createTestDir();
|
|
90
90
|
const ctx = createMockCtx();
|
|
91
91
|
const origCwd = process.cwd();
|
|
@@ -99,40 +99,40 @@ test("logs <N> shows activity log details", async (t) => {
|
|
|
99
99
|
{ role: "assistant", content: "I ran the tests and wrote a file" },
|
|
100
100
|
]);
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
try {
|
|
103
|
+
await handleLogs("1", ctx as any);
|
|
104
|
+
assert.equal(ctx.notifications.length, 1);
|
|
105
|
+
const msg = ctx.notifications[0].msg;
|
|
106
|
+
assert.ok(msg.includes("Activity Log #1"), "should show log number");
|
|
107
|
+
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
108
|
+
assert.ok(msg.includes("Tool calls: 2"), "should count tool calls");
|
|
109
|
+
assert.ok(msg.includes("Errors: 1"), "should count errors");
|
|
110
|
+
assert.ok(msg.includes("/tmp/test.ts"), "should show files written");
|
|
111
|
+
assert.ok(msg.includes("npm test"), "should show commands run");
|
|
112
|
+
} finally {
|
|
103
113
|
process.chdir(origCwd);
|
|
104
114
|
rmSync(dir, { recursive: true, force: true });
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
await handleLogs("1", ctx as any);
|
|
108
|
-
assert.equal(ctx.notifications.length, 1);
|
|
109
|
-
const msg = ctx.notifications[0].msg;
|
|
110
|
-
assert.ok(msg.includes("Activity Log #1"), "should show log number");
|
|
111
|
-
assert.ok(msg.includes("execute-task"), "should show unit type");
|
|
112
|
-
assert.ok(msg.includes("Tool calls: 2"), "should count tool calls");
|
|
113
|
-
assert.ok(msg.includes("Errors: 1"), "should count errors");
|
|
114
|
-
assert.ok(msg.includes("/tmp/test.ts"), "should show files written");
|
|
115
|
-
assert.ok(msg.includes("npm test"), "should show commands run");
|
|
115
|
+
}
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
test("logs <N> shows not found for invalid seq", async (
|
|
118
|
+
test("logs <N> shows not found for invalid seq", async () => {
|
|
119
119
|
const dir = createTestDir();
|
|
120
120
|
const ctx = createMockCtx();
|
|
121
121
|
const origCwd = process.cwd();
|
|
122
122
|
process.chdir(dir);
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
try {
|
|
125
|
+
await handleLogs("999", ctx as any);
|
|
126
|
+
assert.equal(ctx.notifications.length, 1);
|
|
127
|
+
assert.ok(ctx.notifications[0].msg.includes("not found"));
|
|
128
|
+
assert.equal(ctx.notifications[0].level, "warning");
|
|
129
|
+
} finally {
|
|
125
130
|
process.chdir(origCwd);
|
|
126
131
|
rmSync(dir, { recursive: true, force: true });
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
await handleLogs("999", ctx as any);
|
|
130
|
-
assert.equal(ctx.notifications.length, 1);
|
|
131
|
-
assert.ok(ctx.notifications[0].msg.includes("not found"));
|
|
132
|
-
assert.equal(ctx.notifications[0].level, "warning");
|
|
132
|
+
}
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
test("logs debug lists debug logs", async (
|
|
135
|
+
test("logs debug lists debug logs", async () => {
|
|
136
136
|
const dir = createTestDir();
|
|
137
137
|
const ctx = createMockCtx();
|
|
138
138
|
const origCwd = process.cwd();
|
|
@@ -143,19 +143,19 @@ test("logs debug lists debug logs", async (t) => {
|
|
|
143
143
|
{ ts: "2026-03-18T10:35:00Z", event: "debug-summary", dispatches: 5 },
|
|
144
144
|
]);
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
try {
|
|
147
|
+
await handleLogs("debug", ctx as any);
|
|
148
|
+
assert.equal(ctx.notifications.length, 1);
|
|
149
|
+
const msg = ctx.notifications[0].msg;
|
|
150
|
+
assert.ok(msg.includes("Debug Logs"), "should show debug logs header");
|
|
151
|
+
assert.ok(msg.includes("debug-2026-03-18T10-30-00.log"), "should show filename");
|
|
152
|
+
} finally {
|
|
147
153
|
process.chdir(origCwd);
|
|
148
154
|
rmSync(dir, { recursive: true, force: true });
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
await handleLogs("debug", ctx as any);
|
|
152
|
-
assert.equal(ctx.notifications.length, 1);
|
|
153
|
-
const msg = ctx.notifications[0].msg;
|
|
154
|
-
assert.ok(msg.includes("Debug Logs"), "should show debug logs header");
|
|
155
|
-
assert.ok(msg.includes("debug-2026-03-18T10-30-00.log"), "should show filename");
|
|
155
|
+
}
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
test("logs debug <N> shows debug log summary", async (
|
|
158
|
+
test("logs debug <N> shows debug log summary", async () => {
|
|
159
159
|
const dir = createTestDir();
|
|
160
160
|
const ctx = createMockCtx();
|
|
161
161
|
const origCwd = process.cwd();
|
|
@@ -167,21 +167,21 @@ test("logs debug <N> shows debug log summary", async (t) => {
|
|
|
167
167
|
{ ts: "2026-03-18T10:35:00Z", event: "debug-summary", dispatches: 5 },
|
|
168
168
|
]);
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
try {
|
|
171
|
+
await handleLogs("debug 1", ctx as any);
|
|
172
|
+
assert.equal(ctx.notifications.length, 1);
|
|
173
|
+
const msg = ctx.notifications[0].msg;
|
|
174
|
+
assert.ok(msg.includes("Debug Log:"), "should show debug log header");
|
|
175
|
+
assert.ok(msg.includes("Events: 3"), "should count events");
|
|
176
|
+
assert.ok(msg.includes("Dispatches: 5"), "should show dispatch count");
|
|
177
|
+
assert.ok(msg.includes("dispatch-error"), "should show errors");
|
|
178
|
+
} finally {
|
|
171
179
|
process.chdir(origCwd);
|
|
172
180
|
rmSync(dir, { recursive: true, force: true });
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
await handleLogs("debug 1", ctx as any);
|
|
176
|
-
assert.equal(ctx.notifications.length, 1);
|
|
177
|
-
const msg = ctx.notifications[0].msg;
|
|
178
|
-
assert.ok(msg.includes("Debug Log:"), "should show debug log header");
|
|
179
|
-
assert.ok(msg.includes("Events: 3"), "should count events");
|
|
180
|
-
assert.ok(msg.includes("Dispatches: 5"), "should show dispatch count");
|
|
181
|
-
assert.ok(msg.includes("dispatch-error"), "should show errors");
|
|
181
|
+
}
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
test("logs tail shows recent activity summaries", async (
|
|
184
|
+
test("logs tail shows recent activity summaries", async () => {
|
|
185
185
|
const dir = createTestDir();
|
|
186
186
|
const ctx = createMockCtx();
|
|
187
187
|
const origCwd = process.cwd();
|
|
@@ -195,20 +195,20 @@ test("logs tail shows recent activity summaries", async (t) => {
|
|
|
195
195
|
{ role: "toolResult", toolCallId: "1", toolName: "bash", isError: true },
|
|
196
196
|
]);
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
try {
|
|
199
|
+
await handleLogs("tail 2", ctx as any);
|
|
200
|
+
assert.equal(ctx.notifications.length, 1);
|
|
201
|
+
const msg = ctx.notifications[0].msg;
|
|
202
|
+
assert.ok(msg.includes("Last 2 activity log(s)"), "should show count");
|
|
203
|
+
assert.ok(msg.includes("#1"), "should show first log");
|
|
204
|
+
assert.ok(msg.includes("#2"), "should show second log");
|
|
205
|
+
} finally {
|
|
199
206
|
process.chdir(origCwd);
|
|
200
207
|
rmSync(dir, { recursive: true, force: true });
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
await handleLogs("tail 2", ctx as any);
|
|
204
|
-
assert.equal(ctx.notifications.length, 1);
|
|
205
|
-
const msg = ctx.notifications[0].msg;
|
|
206
|
-
assert.ok(msg.includes("Last 2 activity log(s)"), "should show count");
|
|
207
|
-
assert.ok(msg.includes("#1"), "should show first log");
|
|
208
|
-
assert.ok(msg.includes("#2"), "should show second log");
|
|
208
|
+
}
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
-
test("logs clear removes old logs", async (
|
|
211
|
+
test("logs clear removes old logs", async () => {
|
|
212
212
|
const dir = createTestDir();
|
|
213
213
|
const ctx = createMockCtx();
|
|
214
214
|
const origCwd = process.cwd();
|
|
@@ -225,17 +225,17 @@ test("logs clear removes old logs", async (t) => {
|
|
|
225
225
|
writeActivityLog(dir, i, "execute-task", `M001/S01/T0${i}`, [{ type: "toolCall" }]);
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
|
|
228
|
+
try {
|
|
229
|
+
await handleLogs("clear", ctx as any);
|
|
230
|
+
assert.equal(ctx.notifications.length, 1);
|
|
231
|
+
// Old log should be removed, recent ones kept
|
|
232
|
+
assert.ok(!existsSync(oldFile), "old log should be removed");
|
|
233
|
+
assert.ok(
|
|
234
|
+
existsSync(join(dir, ".gsd", "activity", "007-execute-task-M001-S01-T07.jsonl")),
|
|
235
|
+
"most recent log should be kept",
|
|
236
|
+
);
|
|
237
|
+
} finally {
|
|
229
238
|
process.chdir(origCwd);
|
|
230
239
|
rmSync(dir, { recursive: true, force: true });
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
await handleLogs("clear", ctx as any);
|
|
234
|
-
assert.equal(ctx.notifications.length, 1);
|
|
235
|
-
// Old log should be removed, recent ones kept
|
|
236
|
-
assert.ok(!existsSync(oldFile), "old log should be removed");
|
|
237
|
-
assert.ok(
|
|
238
|
-
existsSync(join(dir, ".gsd", "activity", "007-execute-task-M001-S01-T07.jsonl")),
|
|
239
|
-
"most recent log should be kept",
|
|
240
|
-
);
|
|
240
|
+
}
|
|
241
241
|
});
|