gsd-pi 2.44.0 → 2.45.0-dev.1afbdaa
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 +30 -12
- package/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/activity-log.js +7 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
- package/dist/resources/extensions/gsd/auto/phases.js +63 -77
- 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-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +33 -5
- package/dist/resources/extensions/gsd/auto-timers.js +57 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
- package/dist/resources/extensions/gsd/auto.js +42 -60
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +170 -11
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/context.js +0 -4
- package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
- 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 +40 -22
- package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
- package/dist/resources/extensions/gsd/doctor.js +13 -3
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +28 -4
- package/dist/resources/extensions/gsd/guided-flow.js +1 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- 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 +17 -5
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
- 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 +5 -3
- 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/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
- package/dist/resources/extensions/gsd/repo-identity.js +45 -7
- package/dist/resources/extensions/gsd/rethink.js +115 -0
- package/dist/resources/extensions/gsd/session-lock.js +1 -3
- package/dist/resources/extensions/gsd/state.js +48 -3
- 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 +31 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +28 -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 +34 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- 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 +34 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
- package/dist/resources/extensions/gsd/write-intercept.js +84 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- 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 +5 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- 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 +6 -6
- 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 +6 -6
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +12 -12
- 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-react-loadable-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/4024.11ca5c01938e5948.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
- 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/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +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/native/dist/stream-process/index.js +2 -2
- package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
- package/packages/native/src/stream-process/index.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -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/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.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/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.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/local-model-check.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.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 +13 -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 +40 -3
- 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/dist/core/resolve-config-value.test.js +34 -44
- 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 +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +17 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- 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/local-model-check.ts +45 -0
- 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 +51 -4
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/main.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/activity-log.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
- package/src/resources/extensions/gsd/auto/phases.ts +69 -91
- 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-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +40 -5
- package/src/resources/extensions/gsd/auto-timers.ts +64 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
- package/src/resources/extensions/gsd/auto.ts +44 -86
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +162 -11
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/context.ts +0 -5
- package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
- 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 +41 -27
- 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 +13 -4
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +32 -4
- package/src/resources/extensions/gsd/guided-flow.ts +1 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -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 +18 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
- 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 +5 -3
- 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/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +83 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- package/src/resources/extensions/gsd/repo-identity.ts +46 -7
- package/src/resources/extensions/gsd/rethink.ts +154 -0
- package/src/resources/extensions/gsd/session-lock.ts +0 -4
- package/src/resources/extensions/gsd/state.ts +49 -1
- package/src/resources/extensions/gsd/sync-lock.ts +94 -0
- 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 +19 -29
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- 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 +134 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +15 -14
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +27 -12
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +26 -40
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +82 -103
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +33 -42
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +75 -37
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +39 -53
- 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 +24 -29
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- 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/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -9
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -21
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
- 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/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -47
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- 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/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- 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 +40 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +37 -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 +41 -1
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- 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 +41 -5
- package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
- package/src/resources/extensions/gsd/write-intercept.ts +90 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -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/4024.0de81b543b28b9fe.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.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/chunks/webpack-9014b5adb127a98a.js +0 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → j-BskPs0nxxPeYY-bSrab}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → j-BskPs0nxxPeYY-bSrab}/_ssgManifest.js +0 -0
|
@@ -62,7 +62,7 @@ function toScope(local: boolean): LifecycleHookScope {
|
|
|
62
62
|
return local ? "project" : "user";
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function readManifestRuntimeDeps(dir: string): string[] {
|
|
65
|
+
export function readManifestRuntimeDeps(dir: string): string[] {
|
|
66
66
|
const manifestPath = join(dir, "extension-manifest.json");
|
|
67
67
|
if (!existsSync(manifestPath)) return [];
|
|
68
68
|
try {
|
|
@@ -73,7 +73,7 @@ function readManifestRuntimeDeps(dir: string): string[] {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function collectRuntimeDependencies(installedPath: string, entryPaths: string[]): string[] {
|
|
76
|
+
export function collectRuntimeDependencies(installedPath: string, entryPaths: string[]): string[] {
|
|
77
77
|
const deps = new Set<string>();
|
|
78
78
|
const candidateDirs = new Set<string>([installedPath, ...entryPaths.map((entryPath) => dirname(entryPath))]);
|
|
79
79
|
for (const dir of candidateDirs) {
|
|
@@ -84,7 +84,7 @@ function collectRuntimeDependencies(installedPath: string, entryPaths: string[])
|
|
|
84
84
|
return Array.from(deps);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
function verifyRuntimeDependencies(runtimeDeps: string[], source: string, appName: string): void {
|
|
87
|
+
export function verifyRuntimeDependencies(runtimeDeps: string[], source: string, appName: string): void {
|
|
88
88
|
const missing: string[] = [];
|
|
89
89
|
for (const dep of runtimeDeps) {
|
|
90
90
|
const result = spawnSync(dep, ["--version"], { encoding: "utf-8", timeout: 5000 });
|
|
@@ -99,7 +99,7 @@ function verifyRuntimeDependencies(runtimeDeps: string[], source: string, appNam
|
|
|
99
99
|
);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
function resolveLocalSourcePath(source: string, cwd: string): string | undefined {
|
|
102
|
+
export function resolveLocalSourcePath(source: string, cwd: string): string | undefined {
|
|
103
103
|
const trimmed = source.trim();
|
|
104
104
|
if (!trimmed) return undefined;
|
|
105
105
|
if (trimmed.startsWith("npm:")) return undefined;
|
|
@@ -193,13 +193,19 @@ function getLegacyExportCandidates(phase: LifecycleHookPhase): string[] {
|
|
|
193
193
|
return [phase];
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
const _legacyModuleCache = new Map<string, Record<string, unknown>>();
|
|
197
|
+
|
|
196
198
|
async function runLegacyExportHook(
|
|
197
199
|
entryPath: string,
|
|
198
200
|
phase: LifecycleHookPhase,
|
|
199
201
|
context: LifecycleHookContext,
|
|
200
202
|
): Promise<LifecycleHookHandler | null> {
|
|
201
203
|
try {
|
|
202
|
-
|
|
204
|
+
let module = _legacyModuleCache.get(entryPath);
|
|
205
|
+
if (!module) {
|
|
206
|
+
module = await importExtensionModule<Record<string, unknown>>(import.meta.url, pathToFileURL(entryPath).href);
|
|
207
|
+
_legacyModuleCache.set(entryPath, module);
|
|
208
|
+
}
|
|
203
209
|
for (const exportName of getLegacyExportCandidates(phase)) {
|
|
204
210
|
const candidate = module[exportName];
|
|
205
211
|
if (typeof candidate === "function") {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* local-model-check.ts — Utility to detect if a model baseUrl is local.
|
|
3
|
+
*
|
|
4
|
+
* Leaf module with zero transitive dependencies on TypeScript parameter properties.
|
|
5
|
+
* Used by ModelRegistry and tests.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Check if a model's baseUrl points to a local endpoint.
|
|
10
|
+
* Returns true for localhost, 127.0.0.1, 0.0.0.0, ::1, or unix socket paths.
|
|
11
|
+
* Returns false if baseUrl is empty (cloud provider) or points to a remote host.
|
|
12
|
+
*/
|
|
13
|
+
export function isLocalModel(model: { baseUrl: string }): boolean {
|
|
14
|
+
const url = model.baseUrl;
|
|
15
|
+
if (!url) return false;
|
|
16
|
+
|
|
17
|
+
// Unix socket paths
|
|
18
|
+
if (url.startsWith("unix://") || url.startsWith("unix:")) return true;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const parsed = new URL(url);
|
|
22
|
+
const hostname = parsed.hostname;
|
|
23
|
+
if (
|
|
24
|
+
hostname === "localhost" ||
|
|
25
|
+
hostname === "127.0.0.1" ||
|
|
26
|
+
hostname === "0.0.0.0" ||
|
|
27
|
+
hostname === "::1" ||
|
|
28
|
+
hostname === "[::1]"
|
|
29
|
+
) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// If URL parsing fails, check raw string for local patterns
|
|
34
|
+
if (
|
|
35
|
+
url.includes("localhost") ||
|
|
36
|
+
url.includes("127.0.0.1") ||
|
|
37
|
+
url.includes("0.0.0.0") ||
|
|
38
|
+
url.includes("[::1]")
|
|
39
|
+
) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
|
-
import type { Api, Model } from "@gsd/pi-ai";
|
|
3
|
+
import type { Api, Model, SimpleStreamOptions, Context, AssistantMessageEventStream } from "@gsd/pi-ai";
|
|
4
|
+
import { getApiProvider } from "@gsd/pi-ai";
|
|
4
5
|
import type { AuthStorage } from "./auth-storage.js";
|
|
5
6
|
import { ModelRegistry } from "./model-registry.js";
|
|
6
7
|
|
|
@@ -17,11 +18,11 @@ function createRegistry(hasAuthFn?: (provider: string) => boolean): ModelRegistr
|
|
|
17
18
|
return new ModelRegistry(authStorage, undefined);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
function createProviderModel(id: string): NonNullable<Parameters<ModelRegistry["registerProvider"]>[1]["models"]>[number] {
|
|
21
|
+
function createProviderModel(id: string, api?: string): NonNullable<Parameters<ModelRegistry["registerProvider"]>[1]["models"]>[number] {
|
|
21
22
|
return {
|
|
22
23
|
id,
|
|
23
24
|
name: id,
|
|
24
|
-
api: "openai-completions",
|
|
25
|
+
api: (api ?? "openai-completions") as Api,
|
|
25
26
|
reasoning: false,
|
|
26
27
|
input: ["text"],
|
|
27
28
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
@@ -34,34 +35,89 @@ function findModel(registry: ModelRegistry, provider: string, id: string): Model
|
|
|
34
35
|
return registry.getAvailable().find((m) => m.provider === provider && m.id === id);
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
function makeModel(provider: string, id: string, api: string): Model<Api> {
|
|
39
|
+
return {
|
|
40
|
+
id,
|
|
41
|
+
name: id,
|
|
42
|
+
api: api as Api,
|
|
43
|
+
provider,
|
|
44
|
+
baseUrl: `${provider}:`,
|
|
45
|
+
reasoning: false,
|
|
46
|
+
input: ["text"],
|
|
47
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
48
|
+
contextWindow: 128000,
|
|
49
|
+
maxTokens: 16384,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function makeContext(): Context {
|
|
54
|
+
return {
|
|
55
|
+
systemPrompt: "test",
|
|
56
|
+
messages: [{ role: "user", content: "hello", timestamp: Date.now() }],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** No-op streamSimple for tests that need one to pass validation but don't inspect it. */
|
|
61
|
+
const noopStreamSimple = (_model: Model<Api>, _context: Context, _options?: SimpleStreamOptions) => {
|
|
62
|
+
return {
|
|
63
|
+
[Symbol.asyncIterator]() { return { next: async () => ({ value: undefined, done: true as const }) }; },
|
|
64
|
+
result: () => Promise.resolve({ role: "assistant" as const, content: [], api: "test" as Api, provider: "test", model: "test", usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } }, stopReason: "stop" as const, timestamp: Date.now() }),
|
|
65
|
+
push: () => {},
|
|
66
|
+
end: () => {},
|
|
67
|
+
} as unknown as AssistantMessageEventStream;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** Create a spy streamSimple that captures the options it receives and returns a stub stream. */
|
|
71
|
+
function createStreamSpy(): {
|
|
72
|
+
streamSimple: (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
|
|
73
|
+
getCapturedOptions: () => SimpleStreamOptions | undefined;
|
|
74
|
+
} {
|
|
75
|
+
let capturedOptions: SimpleStreamOptions | undefined;
|
|
76
|
+
const streamSimple = (_model: Model<Api>, _context: Context, options?: SimpleStreamOptions) => {
|
|
77
|
+
capturedOptions = options;
|
|
78
|
+
// Return a minimal stub that satisfies AssistantMessageEventStream
|
|
79
|
+
return {
|
|
80
|
+
[Symbol.asyncIterator]() { return { next: async () => ({ value: undefined, done: true as const }) }; },
|
|
81
|
+
result: () => Promise.resolve({ role: "assistant" as const, content: [], api: "test" as Api, provider: "test", model: "test", usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } }, stopReason: "stop" as const, timestamp: Date.now() }),
|
|
82
|
+
push: () => {},
|
|
83
|
+
end: () => {},
|
|
84
|
+
} as unknown as AssistantMessageEventStream;
|
|
85
|
+
};
|
|
86
|
+
return { streamSimple, getCapturedOptions: () => capturedOptions };
|
|
87
|
+
}
|
|
88
|
+
|
|
37
89
|
// ─── Registration ─────────────────────────────────────────────────────────────
|
|
38
90
|
|
|
39
91
|
describe("ModelRegistry authMode — registration", () => {
|
|
40
|
-
it("registers externalCli provider without apiKey/oauth", () => {
|
|
92
|
+
it("registers externalCli provider with streamSimple and without apiKey/oauth", () => {
|
|
41
93
|
const registry = createRegistry();
|
|
94
|
+
const spy = createStreamSpy();
|
|
42
95
|
assert.doesNotThrow(() => {
|
|
43
96
|
registry.registerProvider("cli-provider", {
|
|
44
97
|
authMode: "externalCli",
|
|
45
98
|
baseUrl: "https://cli.local",
|
|
46
99
|
api: "openai-completions",
|
|
100
|
+
streamSimple: spy.streamSimple,
|
|
47
101
|
models: [createProviderModel("cli-model")],
|
|
48
102
|
});
|
|
49
103
|
});
|
|
50
104
|
});
|
|
51
105
|
|
|
52
|
-
it("registers none provider without apiKey/oauth", () => {
|
|
106
|
+
it("registers none provider with streamSimple and without apiKey/oauth", () => {
|
|
53
107
|
const registry = createRegistry();
|
|
108
|
+
const spy = createStreamSpy();
|
|
54
109
|
assert.doesNotThrow(() => {
|
|
55
110
|
registry.registerProvider("none-provider", {
|
|
56
111
|
authMode: "none",
|
|
57
112
|
baseUrl: "http://localhost:11434",
|
|
58
113
|
api: "openai-completions",
|
|
114
|
+
streamSimple: spy.streamSimple,
|
|
59
115
|
models: [createProviderModel("local-model")],
|
|
60
116
|
});
|
|
61
117
|
});
|
|
62
118
|
});
|
|
63
119
|
|
|
64
|
-
it("rejects apiKey provider without apiKey or oauth", () => {
|
|
120
|
+
it("rejects apiKey provider without apiKey or oauth — message mentions authMode", () => {
|
|
65
121
|
const registry = createRegistry();
|
|
66
122
|
assert.throws(() => {
|
|
67
123
|
registry.registerProvider("apikey-provider", {
|
|
@@ -70,6 +126,10 @@ describe("ModelRegistry authMode — registration", () => {
|
|
|
70
126
|
api: "openai-completions",
|
|
71
127
|
models: [createProviderModel("model")],
|
|
72
128
|
});
|
|
129
|
+
}, (err: Error) => {
|
|
130
|
+
assert.ok(err.message.includes("authMode"), "error message must mention authMode");
|
|
131
|
+
assert.ok(err.message.includes("externalCli"), "error message must suggest externalCli");
|
|
132
|
+
return true;
|
|
73
133
|
});
|
|
74
134
|
});
|
|
75
135
|
|
|
@@ -81,6 +141,79 @@ describe("ModelRegistry authMode — registration", () => {
|
|
|
81
141
|
api: "openai-completions",
|
|
82
142
|
models: [createProviderModel("model")],
|
|
83
143
|
});
|
|
144
|
+
}, (err: Error) => {
|
|
145
|
+
assert.ok(err.message.includes("authMode"), "error message must mention authMode");
|
|
146
|
+
return true;
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("rejects externalCli provider without streamSimple", () => {
|
|
151
|
+
const registry = createRegistry();
|
|
152
|
+
assert.throws(() => {
|
|
153
|
+
registry.registerProvider("cli-no-stream", {
|
|
154
|
+
authMode: "externalCli",
|
|
155
|
+
baseUrl: "https://cli.local",
|
|
156
|
+
api: "openai-completions",
|
|
157
|
+
models: [createProviderModel("model")],
|
|
158
|
+
});
|
|
159
|
+
}, (err: Error) => {
|
|
160
|
+
assert.ok(err.message.includes("streamSimple"), "error message must mention streamSimple");
|
|
161
|
+
assert.ok(err.message.includes("externalCli"), "error message must mention authMode");
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("rejects none provider without streamSimple", () => {
|
|
167
|
+
const registry = createRegistry();
|
|
168
|
+
assert.throws(() => {
|
|
169
|
+
registry.registerProvider("none-no-stream", {
|
|
170
|
+
authMode: "none",
|
|
171
|
+
baseUrl: "http://localhost:11434",
|
|
172
|
+
api: "openai-completions",
|
|
173
|
+
models: [createProviderModel("model")],
|
|
174
|
+
});
|
|
175
|
+
}, (err: Error) => {
|
|
176
|
+
assert.ok(err.message.includes("streamSimple"), "error message must mention streamSimple");
|
|
177
|
+
assert.ok(err.message.includes("none"), "error message must mention authMode");
|
|
178
|
+
return true;
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("rejects externalCli provider that also sets apiKey", () => {
|
|
183
|
+
const registry = createRegistry();
|
|
184
|
+
const spy = createStreamSpy();
|
|
185
|
+
assert.throws(() => {
|
|
186
|
+
registry.registerProvider("cli-with-key", {
|
|
187
|
+
authMode: "externalCli",
|
|
188
|
+
baseUrl: "https://cli.local",
|
|
189
|
+
api: "openai-completions",
|
|
190
|
+
apiKey: "SHOULD_NOT_EXIST",
|
|
191
|
+
streamSimple: spy.streamSimple,
|
|
192
|
+
models: [createProviderModel("model")],
|
|
193
|
+
});
|
|
194
|
+
}, (err: Error) => {
|
|
195
|
+
assert.ok(err.message.includes("apiKey"), "error message must mention apiKey");
|
|
196
|
+
assert.ok(err.message.includes("externalCli"), "error message must mention authMode");
|
|
197
|
+
return true;
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it("rejects none provider that also sets apiKey", () => {
|
|
202
|
+
const registry = createRegistry();
|
|
203
|
+
const spy = createStreamSpy();
|
|
204
|
+
assert.throws(() => {
|
|
205
|
+
registry.registerProvider("none-with-key", {
|
|
206
|
+
authMode: "none",
|
|
207
|
+
baseUrl: "http://localhost:11434",
|
|
208
|
+
api: "openai-completions",
|
|
209
|
+
apiKey: "SHOULD_NOT_EXIST",
|
|
210
|
+
streamSimple: spy.streamSimple,
|
|
211
|
+
models: [createProviderModel("model")],
|
|
212
|
+
});
|
|
213
|
+
}, (err: Error) => {
|
|
214
|
+
assert.ok(err.message.includes("apiKey"), "error message must mention apiKey");
|
|
215
|
+
assert.ok(err.message.includes("none"), "error message must mention authMode");
|
|
216
|
+
return true;
|
|
84
217
|
});
|
|
85
218
|
});
|
|
86
219
|
});
|
|
@@ -99,6 +232,7 @@ describe("ModelRegistry authMode — getProviderAuthMode", () => {
|
|
|
99
232
|
authMode: "externalCli",
|
|
100
233
|
baseUrl: "https://cli.local",
|
|
101
234
|
api: "openai-completions",
|
|
235
|
+
streamSimple: noopStreamSimple,
|
|
102
236
|
models: [createProviderModel("m")],
|
|
103
237
|
});
|
|
104
238
|
assert.equal(registry.getProviderAuthMode("cli"), "externalCli");
|
|
@@ -110,6 +244,7 @@ describe("ModelRegistry authMode — getProviderAuthMode", () => {
|
|
|
110
244
|
authMode: "none",
|
|
111
245
|
baseUrl: "http://localhost:11434",
|
|
112
246
|
api: "openai-completions",
|
|
247
|
+
streamSimple: noopStreamSimple,
|
|
113
248
|
models: [createProviderModel("m")],
|
|
114
249
|
});
|
|
115
250
|
assert.equal(registry.getProviderAuthMode("local"), "none");
|
|
@@ -125,6 +260,7 @@ describe("ModelRegistry authMode — isProviderRequestReady", () => {
|
|
|
125
260
|
authMode: "externalCli",
|
|
126
261
|
baseUrl: "https://cli.local",
|
|
127
262
|
api: "openai-completions",
|
|
263
|
+
streamSimple: noopStreamSimple,
|
|
128
264
|
models: [createProviderModel("m")],
|
|
129
265
|
});
|
|
130
266
|
assert.equal(registry.isProviderRequestReady("cli"), true);
|
|
@@ -136,6 +272,7 @@ describe("ModelRegistry authMode — isProviderRequestReady", () => {
|
|
|
136
272
|
authMode: "none",
|
|
137
273
|
baseUrl: "http://localhost:11434",
|
|
138
274
|
api: "openai-completions",
|
|
275
|
+
streamSimple: noopStreamSimple,
|
|
139
276
|
models: [createProviderModel("m")],
|
|
140
277
|
});
|
|
141
278
|
assert.equal(registry.isProviderRequestReady("local"), true);
|
|
@@ -161,6 +298,7 @@ describe("ModelRegistry authMode — isReady callback", () => {
|
|
|
161
298
|
authMode: "externalCli",
|
|
162
299
|
baseUrl: "https://cli.local",
|
|
163
300
|
api: "openai-completions",
|
|
301
|
+
streamSimple: noopStreamSimple,
|
|
164
302
|
isReady: () => false,
|
|
165
303
|
models: [createProviderModel("m")],
|
|
166
304
|
});
|
|
@@ -185,6 +323,7 @@ describe("ModelRegistry authMode — isReady callback", () => {
|
|
|
185
323
|
authMode: "externalCli",
|
|
186
324
|
baseUrl: "https://cli.local",
|
|
187
325
|
api: "openai-completions",
|
|
326
|
+
streamSimple: noopStreamSimple,
|
|
188
327
|
isReady: () => true,
|
|
189
328
|
models: [createProviderModel("m")],
|
|
190
329
|
});
|
|
@@ -197,6 +336,7 @@ describe("ModelRegistry authMode — isReady callback", () => {
|
|
|
197
336
|
authMode: "externalCli",
|
|
198
337
|
baseUrl: "https://cli.local",
|
|
199
338
|
api: "openai-completions",
|
|
339
|
+
streamSimple: noopStreamSimple,
|
|
200
340
|
models: [createProviderModel("m")],
|
|
201
341
|
});
|
|
202
342
|
// externalCli without isReady → true (default)
|
|
@@ -213,6 +353,7 @@ describe("ModelRegistry authMode — getAvailable", () => {
|
|
|
213
353
|
authMode: "externalCli",
|
|
214
354
|
baseUrl: "https://cli.local",
|
|
215
355
|
api: "openai-completions",
|
|
356
|
+
streamSimple: noopStreamSimple,
|
|
216
357
|
models: [createProviderModel("cli-model")],
|
|
217
358
|
});
|
|
218
359
|
assert.ok(findModel(registry, "cli", "cli-model"));
|
|
@@ -224,6 +365,7 @@ describe("ModelRegistry authMode — getAvailable", () => {
|
|
|
224
365
|
authMode: "none",
|
|
225
366
|
baseUrl: "http://localhost:11434",
|
|
226
367
|
api: "openai-completions",
|
|
368
|
+
streamSimple: noopStreamSimple,
|
|
227
369
|
models: [createProviderModel("local-model")],
|
|
228
370
|
});
|
|
229
371
|
assert.ok(findModel(registry, "local", "local-model"));
|
|
@@ -235,6 +377,7 @@ describe("ModelRegistry authMode — getAvailable", () => {
|
|
|
235
377
|
authMode: "externalCli",
|
|
236
378
|
baseUrl: "https://cli.local",
|
|
237
379
|
api: "openai-completions",
|
|
380
|
+
streamSimple: noopStreamSimple,
|
|
238
381
|
isReady: () => false,
|
|
239
382
|
models: [createProviderModel("m")],
|
|
240
383
|
});
|
|
@@ -243,10 +386,7 @@ describe("ModelRegistry authMode — getAvailable", () => {
|
|
|
243
386
|
|
|
244
387
|
it("excludes apiKey models without stored auth", () => {
|
|
245
388
|
const registry = createRegistry(() => false);
|
|
246
|
-
// Built-in providers have no registeredProviders entry, so authMode defaults to apiKey
|
|
247
|
-
// getAvailable filters by isProviderRequestReady → hasAuth → false
|
|
248
389
|
const available = registry.getAvailable();
|
|
249
|
-
// No models should be available since hasAuth returns false for everything
|
|
250
390
|
assert.equal(available.length, 0);
|
|
251
391
|
});
|
|
252
392
|
});
|
|
@@ -260,6 +400,7 @@ describe("ModelRegistry authMode — getApiKey", () => {
|
|
|
260
400
|
authMode: "externalCli",
|
|
261
401
|
baseUrl: "https://cli.local",
|
|
262
402
|
api: "openai-completions",
|
|
403
|
+
streamSimple: noopStreamSimple,
|
|
263
404
|
models: [createProviderModel("m")],
|
|
264
405
|
});
|
|
265
406
|
const model = registry.getAll().find((m) => m.provider === "cli")!;
|
|
@@ -272,6 +413,7 @@ describe("ModelRegistry authMode — getApiKey", () => {
|
|
|
272
413
|
authMode: "none",
|
|
273
414
|
baseUrl: "http://localhost:11434",
|
|
274
415
|
api: "openai-completions",
|
|
416
|
+
streamSimple: noopStreamSimple,
|
|
275
417
|
models: [createProviderModel("m")],
|
|
276
418
|
});
|
|
277
419
|
const model = registry.getAll().find((m) => m.provider === "local")!;
|
|
@@ -280,9 +422,153 @@ describe("ModelRegistry authMode — getApiKey", () => {
|
|
|
280
422
|
|
|
281
423
|
it("delegates to authStorage for apiKey provider", async () => {
|
|
282
424
|
const registry = createRegistry();
|
|
283
|
-
// authStorage.getApiKey returns undefined (no key configured)
|
|
284
|
-
// For apiKey providers this is an expected "no key" response, not early exit
|
|
285
425
|
const key = await registry.getApiKeyForProvider("anthropic");
|
|
286
426
|
assert.equal(key, undefined);
|
|
287
427
|
});
|
|
288
428
|
});
|
|
429
|
+
|
|
430
|
+
// ─── streamSimple apiKey stripping ────────────────────────────────────────────
|
|
431
|
+
|
|
432
|
+
describe("ModelRegistry authMode — streamSimple apiKey boundary", () => {
|
|
433
|
+
it("strips apiKey from options for externalCli provider", () => {
|
|
434
|
+
const registry = createRegistry();
|
|
435
|
+
const spy = createStreamSpy();
|
|
436
|
+
const apiType = `ext-cli-strip-${Date.now()}`;
|
|
437
|
+
|
|
438
|
+
registry.registerProvider("cli-strip", {
|
|
439
|
+
authMode: "externalCli",
|
|
440
|
+
baseUrl: "https://cli.local",
|
|
441
|
+
api: apiType as Api,
|
|
442
|
+
streamSimple: spy.streamSimple,
|
|
443
|
+
models: [createProviderModel("m", apiType)],
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const provider = getApiProvider(apiType as Api);
|
|
447
|
+
assert.ok(provider, "provider must be registered in api registry");
|
|
448
|
+
|
|
449
|
+
provider.streamSimple(
|
|
450
|
+
makeModel("cli-strip", "m", apiType),
|
|
451
|
+
makeContext(),
|
|
452
|
+
{ apiKey: "should-be-stripped", maxTokens: 1024 } as SimpleStreamOptions,
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const captured = spy.getCapturedOptions();
|
|
456
|
+
assert.ok(captured, "streamSimple must have been called");
|
|
457
|
+
assert.equal("apiKey" in captured, false, "apiKey must not exist in options for externalCli provider");
|
|
458
|
+
assert.equal(captured.maxTokens, 1024, "other options must pass through");
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
it("strips apiKey from options for none provider", () => {
|
|
462
|
+
const registry = createRegistry();
|
|
463
|
+
const spy = createStreamSpy();
|
|
464
|
+
const apiType = `none-strip-${Date.now()}`;
|
|
465
|
+
|
|
466
|
+
registry.registerProvider("none-strip", {
|
|
467
|
+
authMode: "none",
|
|
468
|
+
baseUrl: "http://localhost:11434",
|
|
469
|
+
api: apiType as Api,
|
|
470
|
+
streamSimple: spy.streamSimple,
|
|
471
|
+
models: [createProviderModel("m", apiType)],
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
const provider = getApiProvider(apiType as Api);
|
|
475
|
+
assert.ok(provider, "provider must be registered in api registry");
|
|
476
|
+
|
|
477
|
+
provider.streamSimple(
|
|
478
|
+
makeModel("none-strip", "m", apiType),
|
|
479
|
+
makeContext(),
|
|
480
|
+
{ apiKey: "should-be-stripped", maxTokens: 2048 } as SimpleStreamOptions,
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
const captured = spy.getCapturedOptions();
|
|
484
|
+
assert.ok(captured, "streamSimple must have been called");
|
|
485
|
+
assert.equal("apiKey" in captured, false, "apiKey must not exist in options for none provider");
|
|
486
|
+
assert.equal(captured.maxTokens, 2048, "other options must pass through");
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it("preserves apiKey in options for apiKey provider", () => {
|
|
490
|
+
const registry = createRegistry();
|
|
491
|
+
const spy = createStreamSpy();
|
|
492
|
+
const apiType = `apikey-preserve-${Date.now()}`;
|
|
493
|
+
|
|
494
|
+
registry.registerProvider("apikey-preserve", {
|
|
495
|
+
apiKey: "MY_KEY",
|
|
496
|
+
baseUrl: "https://api.local",
|
|
497
|
+
api: apiType as Api,
|
|
498
|
+
streamSimple: spy.streamSimple,
|
|
499
|
+
models: [createProviderModel("m", apiType)],
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
const provider = getApiProvider(apiType as Api);
|
|
503
|
+
assert.ok(provider, "provider must be registered in api registry");
|
|
504
|
+
|
|
505
|
+
provider.streamSimple(
|
|
506
|
+
makeModel("apikey-preserve", "m", apiType),
|
|
507
|
+
makeContext(),
|
|
508
|
+
{ apiKey: "sk-real-key", maxTokens: 4096 } as SimpleStreamOptions,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
const captured = spy.getCapturedOptions();
|
|
512
|
+
assert.ok(captured, "streamSimple must have been called");
|
|
513
|
+
assert.equal(captured.apiKey, "sk-real-key", "apiKey must be preserved for apiKey provider");
|
|
514
|
+
assert.equal(captured.maxTokens, 4096, "other options must pass through");
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
it("handles undefined options for externalCli provider", () => {
|
|
518
|
+
const registry = createRegistry();
|
|
519
|
+
const spy = createStreamSpy();
|
|
520
|
+
const apiType = `ext-cli-undef-${Date.now()}`;
|
|
521
|
+
|
|
522
|
+
registry.registerProvider("cli-undef", {
|
|
523
|
+
authMode: "externalCli",
|
|
524
|
+
baseUrl: "https://cli.local",
|
|
525
|
+
api: apiType as Api,
|
|
526
|
+
streamSimple: spy.streamSimple,
|
|
527
|
+
models: [createProviderModel("m", apiType)],
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
const provider = getApiProvider(apiType as Api);
|
|
531
|
+
assert.ok(provider, "provider must be registered in api registry");
|
|
532
|
+
|
|
533
|
+
provider.streamSimple(
|
|
534
|
+
makeModel("cli-undef", "m", apiType),
|
|
535
|
+
makeContext(),
|
|
536
|
+
undefined,
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
const captured = spy.getCapturedOptions();
|
|
540
|
+
assert.ok(captured !== undefined, "streamSimple must have been called");
|
|
541
|
+
assert.equal("apiKey" in captured, false, "apiKey must not exist even when options is undefined");
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it("strips apiKey but preserves signal and other fields for externalCli", () => {
|
|
545
|
+
const registry = createRegistry();
|
|
546
|
+
const spy = createStreamSpy();
|
|
547
|
+
const apiType = `ext-cli-fields-${Date.now()}`;
|
|
548
|
+
const abortController = new AbortController();
|
|
549
|
+
|
|
550
|
+
registry.registerProvider("cli-fields", {
|
|
551
|
+
authMode: "externalCli",
|
|
552
|
+
baseUrl: "https://cli.local",
|
|
553
|
+
api: apiType as Api,
|
|
554
|
+
streamSimple: spy.streamSimple,
|
|
555
|
+
models: [createProviderModel("m", apiType)],
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
const provider = getApiProvider(apiType as Api);
|
|
559
|
+
assert.ok(provider, "provider must be registered in api registry");
|
|
560
|
+
|
|
561
|
+
provider.streamSimple(
|
|
562
|
+
makeModel("cli-fields", "m", apiType),
|
|
563
|
+
makeContext(),
|
|
564
|
+
{ apiKey: "strip-me", maxTokens: 8192, signal: abortController.signal, reasoning: "high" } as SimpleStreamOptions,
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
const captured = spy.getCapturedOptions();
|
|
568
|
+
assert.ok(captured, "streamSimple must have been called");
|
|
569
|
+
assert.equal("apiKey" in captured, false, "apiKey must be stripped");
|
|
570
|
+
assert.equal(captured.maxTokens, 8192, "maxTokens must pass through");
|
|
571
|
+
assert.equal(captured.signal, abortController.signal, "signal must pass through");
|
|
572
|
+
assert.equal((captured as Record<string, unknown>).reasoning, "high", "reasoning must pass through");
|
|
573
|
+
});
|
|
574
|
+
});
|
|
@@ -28,6 +28,7 @@ import { ModelDiscoveryCache } from "./discovery-cache.js";
|
|
|
28
28
|
import type { DiscoveredModel, DiscoveryResult } from "./model-discovery.js";
|
|
29
29
|
import { getDefaultTTL, getDiscoverableProviders, getDiscoveryAdapter } from "./model-discovery.js";
|
|
30
30
|
import { clearConfigValueCache, resolveConfigValue, resolveHeaders } from "./resolve-config-value.js";
|
|
31
|
+
import { isLocalModel } from "./local-model-check.js";
|
|
31
32
|
|
|
32
33
|
const Ajv = (AjvModule as any).default || AjvModule;
|
|
33
34
|
const ajv = new Ajv();
|
|
@@ -557,7 +558,7 @@ export class ModelRegistry {
|
|
|
557
558
|
async getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {
|
|
558
559
|
const authMode = this.getProviderAuthMode(model.provider);
|
|
559
560
|
if (authMode === "externalCli" || authMode === "none") return undefined;
|
|
560
|
-
return this.authStorage.getApiKey(model.provider, sessionId);
|
|
561
|
+
return this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl });
|
|
561
562
|
}
|
|
562
563
|
|
|
563
564
|
/**
|
|
@@ -622,7 +623,18 @@ export class ModelRegistry {
|
|
|
622
623
|
if (!config.api) {
|
|
623
624
|
throw new Error(`Provider ${providerName}: "api" is required when registering streamSimple.`);
|
|
624
625
|
}
|
|
625
|
-
const
|
|
626
|
+
const rawStreamSimple = config.streamSimple;
|
|
627
|
+
const authMode = config.authMode ?? "apiKey";
|
|
628
|
+
|
|
629
|
+
// Keyless providers never see apiKey in options — enforced at registration,
|
|
630
|
+
// not by convention. Prevents undefined from reaching any handler.
|
|
631
|
+
const streamSimple = (authMode === "externalCli" || authMode === "none")
|
|
632
|
+
? ((model: Model<Api>, context: Context, options?: SimpleStreamOptions) => {
|
|
633
|
+
const { apiKey: _, ...opts } = options ?? {};
|
|
634
|
+
return rawStreamSimple(model, context, opts as SimpleStreamOptions);
|
|
635
|
+
})
|
|
636
|
+
: rawStreamSimple;
|
|
637
|
+
|
|
626
638
|
registerApiProvider(
|
|
627
639
|
{
|
|
628
640
|
api: config.api,
|
|
@@ -648,7 +660,22 @@ export class ModelRegistry {
|
|
|
648
660
|
}
|
|
649
661
|
const authMode = config.authMode ?? (config.oauth ? "oauth" : config.apiKey ? "apiKey" : "apiKey");
|
|
650
662
|
if (authMode === "apiKey" && !config.apiKey && !config.oauth) {
|
|
651
|
-
throw new Error(
|
|
663
|
+
throw new Error(
|
|
664
|
+
`Provider ${providerName}: "apiKey" or "oauth" is required when authMode is "apiKey" (the default). ` +
|
|
665
|
+
`Set authMode to "externalCli" or "none" for keyless providers.`,
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if ((authMode === "externalCli" || authMode === "none") && !config.streamSimple) {
|
|
669
|
+
throw new Error(
|
|
670
|
+
`Provider ${providerName}: "streamSimple" is required when authMode is "${authMode}". ` +
|
|
671
|
+
`Keyless providers must supply their own stream handler.`,
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
if ((authMode === "externalCli" || authMode === "none") && config.apiKey) {
|
|
675
|
+
throw new Error(
|
|
676
|
+
`Provider ${providerName}: "apiKey" cannot be set when authMode is "${authMode}". ` +
|
|
677
|
+
`Keyless providers should not provide API key credentials.`,
|
|
678
|
+
);
|
|
652
679
|
}
|
|
653
680
|
|
|
654
681
|
// Parse and add new models
|
|
@@ -807,6 +834,25 @@ export class ModelRegistry {
|
|
|
807
834
|
}
|
|
808
835
|
return converted;
|
|
809
836
|
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Check if a model's baseUrl points to a local endpoint.
|
|
840
|
+
* Delegates to standalone isLocalModel() function.
|
|
841
|
+
*/
|
|
842
|
+
static isLocalModel(model: Model<Api>): boolean {
|
|
843
|
+
return isLocalModel(model);
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Check if all models in the registry are local.
|
|
848
|
+
* Returns true only if every model passes isLocalModel().
|
|
849
|
+
* Returns false if there are no models.
|
|
850
|
+
*/
|
|
851
|
+
isAllLocalChain(): boolean {
|
|
852
|
+
const models = this.getAll();
|
|
853
|
+
if (models.length === 0) return false;
|
|
854
|
+
return models.every((m) => isLocalModel(m));
|
|
855
|
+
}
|
|
810
856
|
}
|
|
811
857
|
|
|
812
858
|
/**
|
|
@@ -814,7 +860,8 @@ export class ModelRegistry {
|
|
|
814
860
|
*/
|
|
815
861
|
export interface ProviderConfigInput {
|
|
816
862
|
authMode?: ProviderAuthMode;
|
|
817
|
-
/** Optional readiness check. Called by isProviderRequestReady() before default auth checks.
|
|
863
|
+
/** Optional readiness check. Called by isProviderRequestReady() before default auth checks.
|
|
864
|
+
* Trusted at the same level as extension code — extensions already have arbitrary code execution. */
|
|
818
865
|
isReady?: () => boolean;
|
|
819
866
|
baseUrl?: string;
|
|
820
867
|
apiKey?: string;
|