gsd-pi 2.45.0 → 2.46.0-dev.cc9d310
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/auto/phases.js +27 -42
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto/session.js +0 -11
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +5 -4
- package/dist/resources/extensions/gsd/auto.js +12 -57
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +15 -12
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
- package/dist/resources/extensions/gsd/commands/context.js +0 -4
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
- package/dist/resources/extensions/gsd/crash-recovery.js +2 -4
- package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
- package/dist/resources/extensions/gsd/db-writer.js +9 -9
- package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
- package/dist/resources/extensions/gsd/doctor.js +5 -3
- package/dist/resources/extensions/gsd/gsd-db.js +16 -3
- package/dist/resources/extensions/gsd/guided-flow.js +1 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
- package/dist/resources/extensions/gsd/preferences-types.js +2 -2
- package/dist/resources/extensions/gsd/preferences.js +8 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +7 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/session-lock.js +1 -3
- package/dist/resources/extensions/gsd/state.js +7 -0
- package/dist/resources/extensions/gsd/sync-lock.js +89 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
- package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +30 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +27 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +32 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
- package/dist/resources/extensions/gsd/workflow-events.js +102 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
- package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +4 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +37 -0
- package/dist/resources/extensions/gsd/write-intercept.js +84 -0
- package/dist/resources/extensions/voice/index.js +11 -16
- package/dist/resources/extensions/voice/linux-ready.js +67 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- 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 +17 -17
- 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-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +2 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +20 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
- package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
- package/packages/pi-coding-agent/src/core/model-registry.ts +30 -3
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
- package/src/resources/extensions/gsd/auto/phases.ts +24 -44
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto/session.ts +0 -18
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
- package/src/resources/extensions/gsd/auto-start.ts +1 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -5
- package/src/resources/extensions/gsd/auto.ts +7 -83
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -12
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/commands/context.ts +0 -5
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +1 -5
- package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
- package/src/resources/extensions/gsd/db-writer.ts +9 -17
- package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
- package/src/resources/extensions/gsd/doctor-types.ts +7 -1
- package/src/resources/extensions/gsd/doctor.ts +6 -3
- package/src/resources/extensions/gsd/gsd-db.ts +16 -3
- package/src/resources/extensions/gsd/guided-flow.ts +1 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
- package/src/resources/extensions/gsd/preferences-types.ts +2 -2
- package/src/resources/extensions/gsd/preferences.ts +7 -3
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
- package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/queue.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +7 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/session-lock.ts +0 -4
- package/src/resources/extensions/gsd/state.ts +8 -0
- package/src/resources/extensions/gsd/sync-lock.ts +94 -0
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +5 -13
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +264 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +317 -250
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +2 -8
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +42 -3
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -7
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +0 -2
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +15 -14
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
- package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +35 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +38 -1
- package/src/resources/extensions/gsd/types.ts +8 -0
- package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
- package/src/resources/extensions/gsd/workflow-events.ts +154 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
- package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +4 -9
- package/src/resources/extensions/gsd/worktree-resolver.ts +37 -0
- package/src/resources/extensions/gsd/write-intercept.ts +90 -0
- package/src/resources/extensions/voice/index.ts +11 -21
- package/src/resources/extensions/voice/linux-ready.ts +87 -0
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
- package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// GSD Extension — Write Intercept for Agent State File Blocks
|
|
2
|
+
// Detects agent attempts to write authoritative state files and returns
|
|
3
|
+
// an error directing the agent to use the engine tool API instead.
|
|
4
|
+
|
|
5
|
+
import { realpathSync } from "node:fs";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Patterns matching authoritative .gsd/ state files that agents must NOT write directly.
|
|
10
|
+
*
|
|
11
|
+
* Only STATE.md is blocked — it is purely engine-rendered from DB state.
|
|
12
|
+
* All other .gsd/ files are agent-authored content that agents create and
|
|
13
|
+
* update during discuss, plan, and execute phases:
|
|
14
|
+
* - REQUIREMENTS.md — agents create during discuss, read during planning
|
|
15
|
+
* - PROJECT.md — agents create during discuss, update at milestone close
|
|
16
|
+
* - ROADMAP.md / PLAN.md — agents create during planning, engine renders checkboxes
|
|
17
|
+
* - SUMMARY.md, KNOWLEDGE.md, CONTEXT.md — non-authoritative content
|
|
18
|
+
*/
|
|
19
|
+
const BLOCKED_PATTERNS: RegExp[] = [
|
|
20
|
+
// STATE.md is the only purely engine-rendered file.
|
|
21
|
+
// Case-insensitive to prevent bypass on macOS (case-insensitive APFS).
|
|
22
|
+
// (^|[/\\]) matches both absolute paths (/project/.gsd/…) and bare relative
|
|
23
|
+
// paths (.gsd/STATE.md) so a path without a leading separator is also blocked.
|
|
24
|
+
/(^|[/\\])\.gsd[/\\]STATE\.md$/i,
|
|
25
|
+
// Also match resolved symlink paths under ~/.gsd/projects/ (Pitfall #6)
|
|
26
|
+
/(^|[/\\])\.gsd[/\\]projects[/\\][^/\\]+[/\\]STATE\.md$/i,
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Bash command patterns that target STATE.md.
|
|
31
|
+
* Covers common shell write patterns: redirect, tee, cp, mv, sed -i, etc.
|
|
32
|
+
*/
|
|
33
|
+
const BASH_STATE_PATTERNS: RegExp[] = [
|
|
34
|
+
// Redirect/pipe writes: > STATE.md, >> STATE.md, >| STATE.md
|
|
35
|
+
/[>|]+\s*\S*STATE\.md/i,
|
|
36
|
+
// tee to STATE.md
|
|
37
|
+
/\btee\b.*STATE\.md/i,
|
|
38
|
+
// cp/mv targeting STATE.md
|
|
39
|
+
/\b(cp|mv)\b.*STATE\.md/i,
|
|
40
|
+
// sed -i editing STATE.md
|
|
41
|
+
/\bsed\b.*-i.*STATE\.md/i,
|
|
42
|
+
// dd output to STATE.md
|
|
43
|
+
/\bdd\b.*of=\S*STATE\.md/i,
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Tests whether the given file path matches a blocked authoritative .gsd/ state file.
|
|
48
|
+
* Resolves `..` segments via path.resolve() and attempts realpathSync for symlinks.
|
|
49
|
+
*/
|
|
50
|
+
export function isBlockedStateFile(filePath: string): boolean {
|
|
51
|
+
// Check raw path first
|
|
52
|
+
if (matchesBlockedPattern(filePath)) return true;
|
|
53
|
+
|
|
54
|
+
// Resolve ".." segments (works even for non-existing files)
|
|
55
|
+
const resolved = resolve(filePath);
|
|
56
|
+
if (resolved !== filePath && matchesBlockedPattern(resolved)) return true;
|
|
57
|
+
|
|
58
|
+
// Also try symlink resolution — file may not exist yet, so wrap in try/catch
|
|
59
|
+
try {
|
|
60
|
+
const realpath = realpathSync(filePath);
|
|
61
|
+
if (realpath !== filePath && realpath !== resolved && matchesBlockedPattern(realpath)) return true;
|
|
62
|
+
} catch {
|
|
63
|
+
// File doesn't exist yet — path matching above is sufficient
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Tests whether a bash command appears to target STATE.md for writing.
|
|
71
|
+
*/
|
|
72
|
+
export function isBashWriteToStateFile(command: string): boolean {
|
|
73
|
+
return BASH_STATE_PATTERNS.some((pattern) => pattern.test(command));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function matchesBlockedPattern(path: string): boolean {
|
|
77
|
+
return BLOCKED_PATTERNS.some((pattern) => pattern.test(path));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Error message returned when an agent attempts to directly write an authoritative .gsd/ state file.
|
|
82
|
+
* Directs the agent to use engine tool calls instead.
|
|
83
|
+
*/
|
|
84
|
+
export const BLOCKED_WRITE_ERROR = `Direct writes to .gsd/STATE.md are blocked. Use engine tool calls instead:
|
|
85
|
+
- To complete a task: call gsd_complete_task(milestone_id, slice_id, task_id, summary)
|
|
86
|
+
- To complete a slice: call gsd_complete_slice(milestone_id, slice_id, summary, uat_result)
|
|
87
|
+
- To save a decision: call gsd_save_decision(scope, decision, choice, rationale)
|
|
88
|
+
- To start a task: call gsd_start_task(milestone_id, slice_id, task_id)
|
|
89
|
+
- To record verification: call gsd_record_verification(milestone_id, slice_id, task_id, evidence)
|
|
90
|
+
- To report a blocker: call gsd_report_blocker(milestone_id, slice_id, task_id, description)`;
|
|
@@ -4,9 +4,9 @@ import type { AssistantMessage } from "@gsd/pi-ai";
|
|
|
4
4
|
import { isKeyRelease, Key, matchesKey, truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
5
5
|
import { spawn, execFileSync, type ChildProcess } from "node:child_process";
|
|
6
6
|
import * as fs from "node:fs";
|
|
7
|
-
import * as os from "node:os";
|
|
8
7
|
import * as path from "node:path";
|
|
9
8
|
import * as readline from "node:readline";
|
|
9
|
+
import { linuxPython, diagnoseSounddeviceError, ensureVoiceVenv, VOICE_VENV_PYTHON } from "./linux-ready.js";
|
|
10
10
|
|
|
11
11
|
const __extensionDir = import.meta.dirname!;
|
|
12
12
|
const SWIFT_SRC = path.join(__extensionDir, "speech-recognizer.swift");
|
|
@@ -15,19 +15,6 @@ const PYTHON_SCRIPT = path.join(__extensionDir, "speech-recognizer.py");
|
|
|
15
15
|
|
|
16
16
|
const IS_DARWIN = process.platform === "darwin";
|
|
17
17
|
const IS_LINUX = process.platform === "linux";
|
|
18
|
-
const VOICE_VENV_PYTHON = path.join(
|
|
19
|
-
process.env.HOME || process.env.USERPROFILE || os.homedir(),
|
|
20
|
-
".gsd",
|
|
21
|
-
"voice-venv",
|
|
22
|
-
"bin",
|
|
23
|
-
"python3",
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
/** Return the python3 binary path — prefer venv if it exists, else system. */
|
|
27
|
-
function linuxPython(): string {
|
|
28
|
-
if (fs.existsSync(VOICE_VENV_PYTHON)) return VOICE_VENV_PYTHON;
|
|
29
|
-
return "python3";
|
|
30
|
-
}
|
|
31
18
|
|
|
32
19
|
function ensureBinary(): boolean {
|
|
33
20
|
if (fs.existsSync(RECOGNIZER_BIN)) return true;
|
|
@@ -69,17 +56,20 @@ function ensureLinuxReady(ctx: ExtensionContext): boolean {
|
|
|
69
56
|
});
|
|
70
57
|
} catch (err: unknown) {
|
|
71
58
|
const stderr = (err as { stderr?: Buffer })?.stderr?.toString() ?? "";
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
ctx.ui.notify(
|
|
59
|
+
const diagnosis = diagnoseSounddeviceError(stderr);
|
|
60
|
+
|
|
61
|
+
if (diagnosis === "missing-module") {
|
|
62
|
+
// Module not installed — auto-create venv (handles PEP 668 systems
|
|
63
|
+
// where system pip is blocked). See #2403.
|
|
64
|
+
if (!ensureVoiceVenv({ notify: (msg, level) => ctx.ui.notify(msg, level) })) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
78
67
|
linuxReady = true;
|
|
79
68
|
return true;
|
|
69
|
+
} else if (diagnosis === "missing-portaudio") {
|
|
70
|
+
ctx.ui.notify("Voice: install libportaudio2 with: sudo apt install libportaudio2", "error");
|
|
80
71
|
} else {
|
|
81
72
|
ctx.ui.notify(`Voice: dependency check failed — ${stderr.split("\n")[0] || "unknown error"}`, "error");
|
|
82
|
-
return false;
|
|
83
73
|
}
|
|
84
74
|
return false;
|
|
85
75
|
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* linux-ready.ts — Linux voice readiness logic (extracted for testability).
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Detecting system vs venv python3
|
|
6
|
+
* - Diagnosing sounddevice import errors (portaudio vs missing module)
|
|
7
|
+
* - Auto-creating venv on PEP 668 systems
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execFileSync } from "node:child_process";
|
|
11
|
+
import * as fs from "node:fs";
|
|
12
|
+
import * as os from "node:os";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
|
|
15
|
+
export const VOICE_VENV_DIR = path.join(
|
|
16
|
+
process.env.HOME || process.env.USERPROFILE || os.homedir(),
|
|
17
|
+
".gsd",
|
|
18
|
+
"voice-venv",
|
|
19
|
+
);
|
|
20
|
+
export const VOICE_VENV_PYTHON = path.join(VOICE_VENV_DIR, "bin", "python3");
|
|
21
|
+
|
|
22
|
+
/** Return the python3 binary path — prefer venv if it exists, else system. */
|
|
23
|
+
export function linuxPython(): string {
|
|
24
|
+
if (fs.existsSync(VOICE_VENV_PYTHON)) return VOICE_VENV_PYTHON;
|
|
25
|
+
return "python3";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Diagnose a sounddevice import error from its stderr output.
|
|
30
|
+
*
|
|
31
|
+
* Returns:
|
|
32
|
+
* - "missing-module" — sounddevice python package not installed
|
|
33
|
+
* - "missing-portaudio" — libportaudio2 native library not found
|
|
34
|
+
* - "unknown" — unrecognized error
|
|
35
|
+
*
|
|
36
|
+
* IMPORTANT: Check "No module" / "ModuleNotFoundError" BEFORE checking for the
|
|
37
|
+
* word "sounddevice", because `ModuleNotFoundError: No module named 'sounddevice'`
|
|
38
|
+
* contains both strings. The more specific check must come first.
|
|
39
|
+
*/
|
|
40
|
+
export function diagnoseSounddeviceError(stderr: string): "missing-module" | "missing-portaudio" | "unknown" {
|
|
41
|
+
// Check for missing Python module FIRST — the error message
|
|
42
|
+
// "ModuleNotFoundError: No module named 'sounddevice'" contains the word
|
|
43
|
+
// "sounddevice", so the old order (checking "sounddevice" first) was wrong.
|
|
44
|
+
if (stderr.includes("No module") || stderr.includes("ModuleNotFoundError")) {
|
|
45
|
+
return "missing-module";
|
|
46
|
+
}
|
|
47
|
+
// Now check for native portaudio library issues.
|
|
48
|
+
if (stderr.includes("PortAudio") || stderr.includes("portaudio")) {
|
|
49
|
+
return "missing-portaudio";
|
|
50
|
+
}
|
|
51
|
+
return "unknown";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ReadinessCallbacks {
|
|
55
|
+
notify: (message: string, level: "info" | "error") => void;
|
|
56
|
+
/** Override for execFileSync — for testing. Uses execFileSync (safe, no shell). */
|
|
57
|
+
execFile?: typeof execFileSync;
|
|
58
|
+
/** Override for fs.existsSync — for testing */
|
|
59
|
+
exists?: typeof fs.existsSync;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Auto-create the voice venv if it doesn't exist.
|
|
64
|
+
* Uses execFileSync internally (no shell, safe from injection).
|
|
65
|
+
*
|
|
66
|
+
* Returns true on success, false on failure.
|
|
67
|
+
*/
|
|
68
|
+
export function ensureVoiceVenv(cb: ReadinessCallbacks): boolean {
|
|
69
|
+
const exists = cb.exists ?? fs.existsSync;
|
|
70
|
+
const execFile = cb.execFile ?? execFileSync;
|
|
71
|
+
|
|
72
|
+
if (exists(VOICE_VENV_PYTHON)) return true;
|
|
73
|
+
|
|
74
|
+
cb.notify("Voice: setting up Python environment — one-time setup", "info");
|
|
75
|
+
try {
|
|
76
|
+
execFile("python3", ["-m", "venv", VOICE_VENV_DIR], { timeout: 30000 });
|
|
77
|
+
execFile(
|
|
78
|
+
path.join(VOICE_VENV_DIR, "bin", "pip"),
|
|
79
|
+
["install", "sounddevice", "requests", "--quiet"],
|
|
80
|
+
{ timeout: 120000 },
|
|
81
|
+
);
|
|
82
|
+
return true;
|
|
83
|
+
} catch {
|
|
84
|
+
cb.notify("Voice: failed to create Python venv — run: python3 -m venv ~/.gsd/voice-venv", "error");
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* linux-ready.test.ts — Tests for Linux voice readiness logic (#2403).
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - diagnoseSounddeviceError branch ordering (ModuleNotFoundError must NOT
|
|
6
|
+
* match the portaudio branch, even though it contains "sounddevice")
|
|
7
|
+
* - ensureVoiceVenv auto-creation
|
|
8
|
+
* - linuxPython venv detection
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { createTestContext } from "../../gsd/tests/test-helpers.ts";
|
|
12
|
+
import { diagnoseSounddeviceError, ensureVoiceVenv } from "../linux-ready.ts";
|
|
13
|
+
|
|
14
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
15
|
+
|
|
16
|
+
function main(): void {
|
|
17
|
+
// ── diagnoseSounddeviceError ──────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
// The critical regression: "ModuleNotFoundError: No module named 'sounddevice'"
|
|
20
|
+
// contains the word "sounddevice", so the old code matched the portaudio branch.
|
|
21
|
+
console.log("\n=== diagnoseSounddeviceError: ModuleNotFoundError must return missing-module ===");
|
|
22
|
+
{
|
|
23
|
+
const stderr = "Traceback (most recent call last):\n File \"<string>\", line 1, in <module>\nModuleNotFoundError: No module named 'sounddevice'";
|
|
24
|
+
assertEq(diagnoseSounddeviceError(stderr), "missing-module",
|
|
25
|
+
"ModuleNotFoundError for sounddevice should be 'missing-module', not 'missing-portaudio'");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log("\n=== diagnoseSounddeviceError: 'No module named sounddevice' variant ===");
|
|
29
|
+
{
|
|
30
|
+
const stderr = "ImportError: No module named sounddevice";
|
|
31
|
+
assertEq(diagnoseSounddeviceError(stderr), "missing-module",
|
|
32
|
+
"'No module' substring should return missing-module");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log("\n=== diagnoseSounddeviceError: actual portaudio error ===");
|
|
36
|
+
{
|
|
37
|
+
const stderr = "OSError: PortAudio library not found";
|
|
38
|
+
assertEq(diagnoseSounddeviceError(stderr), "missing-portaudio",
|
|
39
|
+
"PortAudio library error should return missing-portaudio");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log("\n=== diagnoseSounddeviceError: lowercase portaudio error ===");
|
|
43
|
+
{
|
|
44
|
+
const stderr = "OSError: libportaudio.so.2: cannot open shared object file: No such file or directory";
|
|
45
|
+
assertEq(diagnoseSounddeviceError(stderr), "missing-portaudio",
|
|
46
|
+
"lowercase portaudio error should return missing-portaudio");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.log("\n=== diagnoseSounddeviceError: unrelated error ===");
|
|
50
|
+
{
|
|
51
|
+
const stderr = "SyntaxError: invalid syntax";
|
|
52
|
+
assertEq(diagnoseSounddeviceError(stderr), "unknown",
|
|
53
|
+
"unrelated error should return unknown");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log("\n=== diagnoseSounddeviceError: empty stderr ===");
|
|
57
|
+
{
|
|
58
|
+
assertEq(diagnoseSounddeviceError(""), "unknown",
|
|
59
|
+
"empty stderr should return unknown");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── ensureVoiceVenv ──────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
console.log("\n=== ensureVoiceVenv: returns true when venv already exists ===");
|
|
65
|
+
{
|
|
66
|
+
const notifications: string[] = [];
|
|
67
|
+
const result = ensureVoiceVenv({
|
|
68
|
+
notify: (msg) => notifications.push(msg),
|
|
69
|
+
exists: () => true,
|
|
70
|
+
execFile: (() => Buffer.from("")) as any,
|
|
71
|
+
});
|
|
72
|
+
assertTrue(result, "should return true when venv exists");
|
|
73
|
+
assertEq(notifications.length, 0, "should not notify when venv exists");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log("\n=== ensureVoiceVenv: creates venv when missing ===");
|
|
77
|
+
{
|
|
78
|
+
const notifications: string[] = [];
|
|
79
|
+
const commands: string[][] = [];
|
|
80
|
+
let existsCalled = false;
|
|
81
|
+
|
|
82
|
+
const result = ensureVoiceVenv({
|
|
83
|
+
notify: (msg) => notifications.push(msg),
|
|
84
|
+
exists: () => { existsCalled = true; return false; },
|
|
85
|
+
execFile: ((cmd: string, args: string[]) => {
|
|
86
|
+
commands.push([cmd, ...args]);
|
|
87
|
+
return Buffer.from("");
|
|
88
|
+
}) as any,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
assertTrue(result, "should return true after venv creation");
|
|
92
|
+
assertTrue(existsCalled, "should check if venv exists");
|
|
93
|
+
assertEq(commands.length, 2, "should run 2 commands (venv + pip)");
|
|
94
|
+
assertTrue(commands[0][0] === "python3", "first command is python3");
|
|
95
|
+
assertTrue(commands[0].includes("-m") && commands[0].includes("venv"),
|
|
96
|
+
"first command creates venv");
|
|
97
|
+
assertTrue(commands[1][0].endsWith("bin/pip"), "second command is pip");
|
|
98
|
+
assertTrue(commands[1].includes("sounddevice"), "pip installs sounddevice");
|
|
99
|
+
assertTrue(commands[1].includes("requests"), "pip installs requests");
|
|
100
|
+
assertTrue(notifications[0].includes("one-time setup"),
|
|
101
|
+
"notifies about one-time setup");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
console.log("\n=== ensureVoiceVenv: returns false and notifies on failure ===");
|
|
105
|
+
{
|
|
106
|
+
const notifications: Array<{ msg: string; level: string }> = [];
|
|
107
|
+
|
|
108
|
+
const result = ensureVoiceVenv({
|
|
109
|
+
notify: (msg, level) => notifications.push({ msg, level }),
|
|
110
|
+
exists: () => false,
|
|
111
|
+
execFile: (() => { throw new Error("externally-managed-environment"); }) as any,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
assertTrue(!result, "should return false on failure");
|
|
115
|
+
const errorNotif = notifications.find(n => n.level === "error");
|
|
116
|
+
assertTrue(errorNotif !== undefined, "should emit error notification");
|
|
117
|
+
assertTrue(errorNotif!.msg.includes("python3 -m venv"),
|
|
118
|
+
"error message should suggest manual venv creation");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
report();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
main();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8974],{5214:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorage",{enumerable:!0,get:function(){return r.workAsyncStorageInstance}});let r=n(17828)},15726:(e,t,n)=>{Promise.resolve().then(n.bind(n,66919))},17828:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"workAsyncStorageInstance",{enumerable:!0,get:function(){return r}});let r=(0,n(64054).createAsyncLocalStorage)()},21957:(e,t,n)=>{"use strict";function r({moduleIds:e}){return null}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"PreloadChunks",{enumerable:!0,get:function(){return r}}),n(95155),n(47650),n(5214),n(2451),n(53887)},37206:(e,t,n)=>{"use strict";n.d(t,{default:()=>u.a});var r=n(75707),u=n.n(r)},41112:(e,t,n)=>{"use strict";function r({reason:e,children:t}){return t}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"BailoutToCSR",{enumerable:!0,get:function(){return r}}),n(1980)},64054:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n={bindSnapshot:function(){return s},createAsyncLocalStorage:function(){return a},createSnapshot:function(){return i}};for(var r in n)Object.defineProperty(t,r,{enumerable:!0,get:n[r]});let u=Object.defineProperty(Error("Invariant: AsyncLocalStorage accessed in runtime where it is not available"),"__NEXT_ERROR_CODE",{value:"E504",enumerable:!1,configurable:!0});class l{disable(){throw u}getStore(){}run(){throw u}exit(){throw u}enterWith(){throw u}static bind(e){return e}}let o="u">typeof globalThis&&globalThis.AsyncLocalStorage;function a(){return o?new o:new l}function s(e){return o?o.bind(e):l.bind(e)}function i(){return o?o.snapshot():function(e,...t){return e(...t)}}},66919:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(95155);let u=(0,n(37206).default)(()=>Promise.all([n.e(1838),n.e(6079),n.e(4986),n.e(485),n.e(4024)]).then(n.bind(n,4024)).then(e=>e.GSDAppShell),{loadableGenerated:{webpack:()=>[4024]},ssr:!1,loading:()=>(0,r.jsx)("div",{className:"flex h-screen items-center justify-center bg-background text-sm text-muted-foreground",children:"Loading workspace…"})});function l(){return(0,r.jsx)(u,{})}},68635:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return s}});let r=n(95155),u=n(12115),l=n(41112);function o(e){return{default:e&&"default"in e?e.default:e}}n(21957);let a={loader:()=>Promise.resolve(o(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},n=(0,u.lazy)(()=>t.loader().then(o)),s=t.loading;function i(e){let o=s?(0,r.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,i=a?u.Suspense:u.Fragment,c=t.ssr?(0,r.jsxs)(r.Fragment,{children:[null,(0,r.jsx)(n,{...e})]}):(0,r.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,r.jsx)(n,{...e})});return(0,r.jsx)(i,{...a?{fallback:o}:{},children:c})}return i.displayName="LoadableComponent",i}},75707:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return u}});let r=n(73623)._(n(68635));function u(e,t){let n={};"function"==typeof e&&(n.loader=e);let u={...n,...t};return(0,r.default)({...u,modules:u.loadableGenerated?.modules})}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=15726)),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[7358],{2852:(e,s,n)=>{Promise.resolve().then(n.t.bind(n,27123,23)),Promise.resolve().then(n.t.bind(n,61304,23)),Promise.resolve().then(n.t.bind(n,78616,23)),Promise.resolve().then(n.t.bind(n,64777,23)),Promise.resolve().then(n.t.bind(n,57121,23)),Promise.resolve().then(n.t.bind(n,74581,23)),Promise.resolve().then(n.t.bind(n,90484,23)),Promise.resolve().then(n.bind(n,86869))},19393:()=>{}},e=>{var s=s=>e(e.s=s);e.O(0,[8441,3794],()=>(s(83861),s(2852))),_N_E=e.O()}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[9337],{52560:(e,s,_)=>{Promise.resolve().then(_.t.bind(_,27123,23))}},e=>{e.O(0,[8441,3794,7358],()=>e(e.s=52560)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|