@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f
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 +11 -11
- package/dist/cli.js +17 -4
- package/dist/headless-answers.js +1 -1
- package/dist/headless-ui.d.ts +1 -1
- package/dist/headless-ui.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/onboarding.js +11 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +20 -25
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
- package/dist/resources/extensions/cursor-cli/index.js +16 -0
- package/dist/resources/extensions/cursor-cli/models.js +63 -0
- package/dist/resources/extensions/cursor-cli/package.json +11 -0
- package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
- package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
- package/dist/resources/extensions/gsd/activity-log.js +4 -1
- package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
- package/dist/resources/extensions/gsd/auto-budget.js +5 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
- package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
- package/dist/resources/extensions/gsd/auto-start.js +4 -3
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
- package/dist/resources/extensions/gsd/auto-verification.js +5 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
- package/dist/resources/extensions/gsd/auto.js +32 -10
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
- package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db/queries.js +39 -0
- package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
- package/dist/resources/extensions/gsd/db-workspace.js +55 -3
- package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
- package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/doctor.js +93 -3
- package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
- package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
- package/dist/resources/extensions/gsd/git-service.js +61 -8
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guidance.js +1 -0
- package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
- package/dist/resources/extensions/gsd/guided-flow.js +40 -2
- package/dist/resources/extensions/gsd/json-persistence.js +20 -0
- package/dist/resources/extensions/gsd/key-manager.js +1 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
- package/dist/resources/extensions/gsd/layout-policy.js +3 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/metrics.js +4 -4
- package/dist/resources/extensions/gsd/migrate-external.js +22 -5
- package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
- package/dist/resources/extensions/gsd/preferences-models.js +6 -4
- package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
- package/dist/resources/extensions/gsd/preferences.js +29 -2
- package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
- package/dist/resources/extensions/gsd/repository-registry.js +6 -1
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
- package/dist/resources/extensions/gsd/safe-fs.js +23 -2
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
- package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
- package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
- package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
- package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
- package/dist/resources/extensions/gsd/state.js +12 -611
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
- package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
- package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
- package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
- package/dist/resources/extensions/gsd/undo.js +43 -6
- package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
- package/dist/resources/extensions/gsd/unit-registry.js +11 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
- package/dist/resources/extensions/gsd/verification-gate.js +7 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
- package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
- package/dist/resources/extensions/gsd/workspace.js +26 -8
- package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- 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 +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_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 +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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/8357.js +2 -2
- 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/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/wizard.d.ts +8 -0
- package/dist/wizard.js +8 -1
- package/integrations/hermes/__init__.py +31 -0
- package/integrations/hermes/tests/test_directory_loader.py +37 -0
- package/package.json +8 -8
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
- package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
- package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-runtime.js +25 -1
- package/packages/daemon/dist/cloud-runtime.js.map +1 -1
- package/packages/daemon/dist/cloud-runtime.test.js +51 -0
- package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
- package/packages/daemon/dist/message-batcher.d.ts +7 -0
- package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
- package/packages/daemon/dist/message-batcher.js +13 -0
- package/packages/daemon/dist/message-batcher.js.map +1 -1
- package/packages/daemon/dist/message-batcher.test.js +48 -0
- package/packages/daemon/dist/message-batcher.test.js.map +1 -1
- package/packages/daemon/package.json +5 -5
- package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +3 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts +2 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +2 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
- package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
- package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +3 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +46 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +38 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -2
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +3 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/dist/rpc-client.js +1 -1
- package/packages/rpc-client/dist/rpc-client.js.map +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme-schema.d.ts +75 -75
- package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/theme/theme-schema.js +1 -1
- package/pkg/dist/theme/theme-schema.js.map +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +11 -7
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/link-workspace-packages.cjs +14 -4
- package/src/resources/GSD-WORKFLOW.md +20 -25
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
- package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
- package/src/resources/extensions/cursor-cli/index.ts +18 -0
- package/src/resources/extensions/cursor-cli/models.ts +65 -0
- package/src/resources/extensions/cursor-cli/package.json +11 -0
- package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
- package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
- package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
- package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
- package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
- package/src/resources/extensions/gsd/activity-log.ts +4 -1
- package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
- package/src/resources/extensions/gsd/auto-budget.ts +12 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
- package/src/resources/extensions/gsd/auto-start.ts +4 -3
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
- package/src/resources/extensions/gsd/auto.ts +36 -8
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db/queries.ts +40 -0
- package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
- package/src/resources/extensions/gsd/db-workspace.ts +61 -3
- package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
- package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
- package/src/resources/extensions/gsd/doctor-types.ts +8 -1
- package/src/resources/extensions/gsd/doctor.ts +95 -3
- package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
- package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
- package/src/resources/extensions/gsd/git-service.ts +70 -9
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guidance.ts +2 -0
- package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
- package/src/resources/extensions/gsd/guided-flow.ts +45 -2
- package/src/resources/extensions/gsd/json-persistence.ts +20 -0
- package/src/resources/extensions/gsd/key-manager.ts +1 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
- package/src/resources/extensions/gsd/layout-policy.ts +2 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/metrics.ts +4 -4
- package/src/resources/extensions/gsd/migrate-external.ts +17 -4
- package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
- package/src/resources/extensions/gsd/model-router.ts +4 -5
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
- package/src/resources/extensions/gsd/preferences-models.ts +6 -3
- package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
- package/src/resources/extensions/gsd/preferences.ts +38 -4
- package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
- package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
- package/src/resources/extensions/gsd/repository-registry.ts +7 -1
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
- package/src/resources/extensions/gsd/safe-fs.ts +22 -2
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
- package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
- package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
- package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
- package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
- package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
- package/src/resources/extensions/gsd/state.ts +32 -732
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
- package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
- package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
- package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
- package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
- package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
- package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
- package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
- package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
- package/src/resources/extensions/gsd/undo.ts +47 -6
- package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
- package/src/resources/extensions/gsd/unit-registry.ts +11 -3
- package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
- package/src/resources/extensions/gsd/verification-gate.ts +8 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
- package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
- package/src/resources/extensions/gsd/workspace.ts +42 -8
- package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
- package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
|
@@ -10,10 +10,15 @@
|
|
|
10
10
|
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
12
12
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
13
|
-
import { join, dirname, extname } from "node:path";
|
|
13
|
+
import { join, dirname, extname, relative, sep } from "node:path";
|
|
14
14
|
|
|
15
15
|
import { execSync } from "node:child_process";
|
|
16
16
|
import { gsdRoot } from "./paths.js";
|
|
17
|
+
import {
|
|
18
|
+
createRepositoryRegistryFromPreferences,
|
|
19
|
+
type RepositoryRegistry,
|
|
20
|
+
} from "./repository-registry.js";
|
|
21
|
+
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
17
22
|
|
|
18
23
|
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
19
24
|
|
|
@@ -28,6 +33,8 @@ export interface CodebaseMapMetadata {
|
|
|
28
33
|
fingerprint: string;
|
|
29
34
|
fileCount: number;
|
|
30
35
|
truncated: boolean;
|
|
36
|
+
/** Repo ids whose files appear in a workspace-aware map (parent mode only). */
|
|
37
|
+
repositories?: string[];
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
export interface EnsureCodebaseMapOptions {
|
|
@@ -48,12 +55,16 @@ export interface EnsureCodebaseMapResult {
|
|
|
48
55
|
interface FileEntry {
|
|
49
56
|
path: string;
|
|
50
57
|
description: string;
|
|
58
|
+
/** Declaring repo id for workspace-aware maps (parent mode); undefined otherwise. */
|
|
59
|
+
repo?: string;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
interface DirectoryGroup {
|
|
54
63
|
path: string;
|
|
55
64
|
files: FileEntry[];
|
|
56
65
|
collapsed: boolean;
|
|
66
|
+
/** Repo id this group belongs to for workspace-aware maps; undefined otherwise. */
|
|
67
|
+
repo?: string;
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
interface ResolvedCodebaseMapOptions {
|
|
@@ -66,6 +77,8 @@ interface ResolvedCodebaseMapOptions {
|
|
|
66
77
|
interface EnumeratedFiles {
|
|
67
78
|
files: string[];
|
|
68
79
|
truncated: boolean;
|
|
80
|
+
/** Per-file repo labels aligned with `files` (workspace-aware maps only). */
|
|
81
|
+
repos?: string[];
|
|
69
82
|
}
|
|
70
83
|
|
|
71
84
|
// ─── Defaults ────────────────────────────────────────────────────────────────
|
|
@@ -209,13 +222,99 @@ function lsFiles(basePath: string): string[] {
|
|
|
209
222
|
* Enumerate tracked files, applying exclusions and the maxFiles cap.
|
|
210
223
|
* Returns both the file list and whether truncation occurred.
|
|
211
224
|
*/
|
|
212
|
-
function enumerateFiles(basePath: string, excludes: string[], maxFiles: number):
|
|
225
|
+
function enumerateFiles(basePath: string, excludes: string[], maxFiles: number): EnumeratedFiles {
|
|
213
226
|
const allFiles = lsFiles(basePath);
|
|
214
227
|
const filtered = allFiles.filter((f) => !shouldExclude(f, excludes));
|
|
215
228
|
const truncated = filtered.length > maxFiles;
|
|
216
229
|
return { files: truncated ? filtered.slice(0, maxFiles) : filtered, truncated };
|
|
217
230
|
}
|
|
218
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Build a workspace-aware registry for parent mode, or null when the project is
|
|
234
|
+
* single-repo (no declared child repositories). Returns null so the caller falls
|
|
235
|
+
* back to the legacy single-root enumeration and produces byte-identical output.
|
|
236
|
+
*/
|
|
237
|
+
function loadWorkspaceRegistry(basePath: string): RepositoryRegistry | null {
|
|
238
|
+
const preferences = loadEffectiveGSDPreferences(basePath)?.preferences;
|
|
239
|
+
const workspace = preferences?.workspace;
|
|
240
|
+
const mode = workspace?.mode ?? "project";
|
|
241
|
+
// Parent mode is only meaningful with at least one declared child repo; the
|
|
242
|
+
// implicit "project" repo is always present, so require a declared non-project id.
|
|
243
|
+
const hasDeclaredChildRepo = workspace?.repositories
|
|
244
|
+
? Object.keys(workspace.repositories).some((id) => id !== "project")
|
|
245
|
+
: false;
|
|
246
|
+
if (mode !== "parent" || !hasDeclaredChildRepo) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
return createRepositoryRegistryFromPreferences(basePath, preferences);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** Stable key fragment for workspace-aware enumeration inputs (mode + declared repos). */
|
|
253
|
+
function workspaceEnumerationSignature(basePath: string): string {
|
|
254
|
+
const registry = loadWorkspaceRegistry(basePath);
|
|
255
|
+
if (!registry) return "single-root";
|
|
256
|
+
return JSON.stringify({
|
|
257
|
+
mode: registry.mode,
|
|
258
|
+
repositories: registry.repositories
|
|
259
|
+
.map((repo) => ({ id: repo.id, root: repo.root }))
|
|
260
|
+
.sort((a, b) => a.id.localeCompare(b.id)),
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Enumerate tracked files across every declared repository in a parent workspace.
|
|
266
|
+
* Child-repo paths are rewritten to be workspace-relative (e.g. `frontend/src/x`)
|
|
267
|
+
* and tagged with their declaring repo id so the map can render repo-labelled
|
|
268
|
+
* sections. The maxFiles cap is applied across the union of all repositories.
|
|
269
|
+
*/
|
|
270
|
+
function enumerateWorkspaceFiles(
|
|
271
|
+
registry: RepositoryRegistry,
|
|
272
|
+
excludes: string[],
|
|
273
|
+
maxFiles: number,
|
|
274
|
+
): EnumeratedFiles {
|
|
275
|
+
type WorkspaceEntry = { workspacePath: string; repoId: string };
|
|
276
|
+
const perRepo: WorkspaceEntry[][] = [];
|
|
277
|
+
const seen = new Set<string>();
|
|
278
|
+
let totalEligible = 0;
|
|
279
|
+
|
|
280
|
+
for (const repo of registry.repositories) {
|
|
281
|
+
const rawFiles = lsFiles(repo.root);
|
|
282
|
+
const repoPrefix = relative(registry.projectRoot, repo.root).split(sep).join("/");
|
|
283
|
+
const repoEntries: WorkspaceEntry[] = [];
|
|
284
|
+
|
|
285
|
+
for (const file of rawFiles) {
|
|
286
|
+
// Rewrite before exclusion so workspace-relative patterns (e.g. frontend/…) apply.
|
|
287
|
+
const workspacePath = repoPrefix ? `${repoPrefix}/${file}` : file;
|
|
288
|
+
if (shouldExclude(workspacePath, excludes)) continue;
|
|
289
|
+
if (seen.has(workspacePath)) continue;
|
|
290
|
+
seen.add(workspacePath);
|
|
291
|
+
totalEligible++;
|
|
292
|
+
repoEntries.push({ workspacePath, repoId: repo.id });
|
|
293
|
+
}
|
|
294
|
+
perRepo.push(repoEntries);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const files: string[] = [];
|
|
298
|
+
const repos: string[] = [];
|
|
299
|
+
const indices = new Array(perRepo.length).fill(0);
|
|
300
|
+
|
|
301
|
+
while (files.length < maxFiles) {
|
|
302
|
+
let progressed = false;
|
|
303
|
+
for (let i = 0; i < perRepo.length; i++) {
|
|
304
|
+
if (indices[i] < perRepo[i].length) {
|
|
305
|
+
const entry = perRepo[i][indices[i]++];
|
|
306
|
+
files.push(entry.workspacePath);
|
|
307
|
+
repos.push(entry.repoId);
|
|
308
|
+
progressed = true;
|
|
309
|
+
if (files.length >= maxFiles) break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (!progressed) break;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return { files, repos, truncated: totalEligible > files.length };
|
|
316
|
+
}
|
|
317
|
+
|
|
219
318
|
function resolveGeneratorOptions(options?: CodebaseMapOptions): ResolvedCodebaseMapOptions {
|
|
220
319
|
const excludes = [...DEFAULT_EXCLUDES, ...(options?.excludePatterns ?? [])];
|
|
221
320
|
const maxFiles = options?.maxFiles ?? DEFAULT_MAX_FILES;
|
|
@@ -236,10 +335,12 @@ function computeCodebaseFingerprint(
|
|
|
236
335
|
files: string[],
|
|
237
336
|
resolved: ResolvedCodebaseMapOptions,
|
|
238
337
|
truncated: boolean,
|
|
338
|
+
repos?: string[],
|
|
239
339
|
): string {
|
|
240
340
|
return createHash("sha1")
|
|
241
341
|
.update(JSON.stringify({
|
|
242
342
|
files,
|
|
343
|
+
...(repos ? { repos } : {}),
|
|
243
344
|
truncated,
|
|
244
345
|
optionSignature: resolved.optionSignature,
|
|
245
346
|
}))
|
|
@@ -252,32 +353,61 @@ function groupByDirectory(
|
|
|
252
353
|
files: string[],
|
|
253
354
|
descriptions: Map<string, string>,
|
|
254
355
|
collapseThreshold: number,
|
|
356
|
+
repos?: string[],
|
|
255
357
|
): DirectoryGroup[] {
|
|
256
358
|
const dirMap = new Map<string, FileEntry[]>();
|
|
257
359
|
|
|
258
|
-
for (
|
|
360
|
+
for (let i = 0; i < files.length; i++) {
|
|
361
|
+
const file = files[i];
|
|
259
362
|
const dir = dirname(file);
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
363
|
+
const dirPath = dir === "." ? "" : dir;
|
|
364
|
+
const repoId = repos?.[i];
|
|
365
|
+
const groupKey = repoId !== undefined ? `${repoId}\0${dirPath}` : dirPath;
|
|
366
|
+
if (!dirMap.has(groupKey)) {
|
|
367
|
+
dirMap.set(groupKey, []);
|
|
263
368
|
}
|
|
264
|
-
dirMap.get(
|
|
369
|
+
dirMap.get(groupKey)!.push({
|
|
265
370
|
path: file,
|
|
266
371
|
description: descriptions.get(file) ?? "",
|
|
372
|
+
repo: repoId,
|
|
267
373
|
});
|
|
268
374
|
}
|
|
269
375
|
|
|
270
376
|
const groups: DirectoryGroup[] = [];
|
|
271
|
-
const
|
|
377
|
+
const repoOrder = new Map<string, number>();
|
|
378
|
+
if (repos) {
|
|
379
|
+
for (let i = 0; i < repos.length; i++) {
|
|
380
|
+
if (!repoOrder.has(repos[i])) {
|
|
381
|
+
repoOrder.set(repos[i], repoOrder.size);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const sortedDirs = [...dirMap.keys()].sort((a, b) => {
|
|
386
|
+
// Single-repo (project) mode must stay byte-identical to the pre-workspace
|
|
387
|
+
// output, which ordered directories with a bare `.sort()` (UTF-16 code-unit
|
|
388
|
+
// order, so uppercase sorts before lowercase). localeCompare would diverge
|
|
389
|
+
// for mixed-case names (e.g. "Zoo" before "apple" flips), so preserve
|
|
390
|
+
// code-unit ordering here; only the repo-partitioning key is added on top.
|
|
391
|
+
if (!repos) return a < b ? -1 : a > b ? 1 : 0;
|
|
392
|
+
const repoA = dirMap.get(a)![0]?.repo ?? "";
|
|
393
|
+
const repoB = dirMap.get(b)![0]?.repo ?? "";
|
|
394
|
+
const orderA = repoOrder.get(repoA) ?? 0;
|
|
395
|
+
const orderB = repoOrder.get(repoB) ?? 0;
|
|
396
|
+
if (orderA !== orderB) return orderA - orderB;
|
|
397
|
+
return a.localeCompare(b);
|
|
398
|
+
});
|
|
272
399
|
|
|
273
|
-
for (const
|
|
274
|
-
const dirFiles = dirMap.get(
|
|
400
|
+
for (const groupKey of sortedDirs) {
|
|
401
|
+
const dirFiles = dirMap.get(groupKey)!;
|
|
275
402
|
dirFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
403
|
+
const dirPath = repos ? groupKey.slice(groupKey.indexOf("\0") + 1) : groupKey;
|
|
276
404
|
|
|
277
405
|
groups.push({
|
|
278
|
-
path:
|
|
406
|
+
path: dirPath,
|
|
279
407
|
files: dirFiles,
|
|
280
408
|
collapsed: dirFiles.length > collapseThreshold,
|
|
409
|
+
// Each group is scoped to one repo in workspace-aware mode.
|
|
410
|
+
repo: dirFiles[0]?.repo,
|
|
281
411
|
});
|
|
282
412
|
}
|
|
283
413
|
|
|
@@ -304,7 +434,19 @@ function renderCodebaseMap(
|
|
|
304
434
|
}
|
|
305
435
|
lines.push("");
|
|
306
436
|
|
|
437
|
+
let emittedRepo: string | undefined;
|
|
307
438
|
for (const group of groups) {
|
|
439
|
+
// In a workspace-aware map, partition directories under their declaring
|
|
440
|
+
// repository. `## [repo-id]` headings are used (not `###`) so they never
|
|
441
|
+
// collide with the per-directory `### <dir>/` headings or the
|
|
442
|
+
// `parseCodebaseMap` list-item regexes. Groups are sorted by declaring
|
|
443
|
+
// repo (enumeration order) then directory path so each repo is contiguous.
|
|
444
|
+
if (group.repo && group.repo !== emittedRepo) {
|
|
445
|
+
emittedRepo = group.repo;
|
|
446
|
+
lines.push(`## [${group.repo}]`);
|
|
447
|
+
lines.push("");
|
|
448
|
+
}
|
|
449
|
+
|
|
308
450
|
const heading = group.path || "(root)";
|
|
309
451
|
lines.push(`### ${heading}/`);
|
|
310
452
|
|
|
@@ -361,13 +503,15 @@ function buildCodebaseMap(
|
|
|
361
503
|
} {
|
|
362
504
|
const listed = enumerated ?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
|
|
363
505
|
const descriptions = existingDescriptions ?? new Map<string, string>();
|
|
364
|
-
const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold);
|
|
506
|
+
const groups = groupByDirectory(listed.files, descriptions, resolved.collapseThreshold, listed.repos);
|
|
365
507
|
const generatedAt = new Date().toISOString().split(".")[0] + "Z";
|
|
508
|
+
const repoIds = listed.repos ? Array.from(new Set(listed.repos)) : undefined;
|
|
366
509
|
const metadata: CodebaseMapMetadata = {
|
|
367
510
|
generatedAt,
|
|
368
|
-
fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated),
|
|
511
|
+
fingerprint: computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos),
|
|
369
512
|
fileCount: listed.files.length,
|
|
370
513
|
truncated: listed.truncated,
|
|
514
|
+
...(repoIds ? { repositories: repoIds } : {}),
|
|
371
515
|
};
|
|
372
516
|
const content = renderCodebaseMap(groups, listed.files.length, listed.truncated, metadata);
|
|
373
517
|
|
|
@@ -387,13 +531,28 @@ function buildCodebaseMap(
|
|
|
387
531
|
* Generate a fresh CODEBASE.md from scratch.
|
|
388
532
|
* Preserves existing descriptions if `existingDescriptions` is provided.
|
|
389
533
|
*/
|
|
534
|
+
/**
|
|
535
|
+
* Resolve workspace-aware enumeration for parent mode, or undefined to fall
|
|
536
|
+
* back to the legacy single-root enumeration. Centralized so all three public
|
|
537
|
+
* entry points (generate/update/ensure) share one discovery path.
|
|
538
|
+
*/
|
|
539
|
+
function resolveWorkspaceEnumeration(
|
|
540
|
+
basePath: string,
|
|
541
|
+
resolved: ResolvedCodebaseMapOptions,
|
|
542
|
+
): EnumeratedFiles | undefined {
|
|
543
|
+
const registry = loadWorkspaceRegistry(basePath);
|
|
544
|
+
if (!registry) return undefined;
|
|
545
|
+
return enumerateWorkspaceFiles(registry, resolved.excludes, resolved.maxFiles);
|
|
546
|
+
}
|
|
547
|
+
|
|
390
548
|
export function generateCodebaseMap(
|
|
391
549
|
basePath: string,
|
|
392
550
|
options?: CodebaseMapOptions,
|
|
393
551
|
existingDescriptions?: Map<string, string>,
|
|
394
552
|
): { content: string; fileCount: number; truncated: boolean; files: string[]; fingerprint: string; generatedAt: string } {
|
|
395
553
|
const resolved = resolveGeneratorOptions(options);
|
|
396
|
-
|
|
554
|
+
const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
|
|
555
|
+
return buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
|
|
397
556
|
}
|
|
398
557
|
|
|
399
558
|
/**
|
|
@@ -427,7 +586,8 @@ export function updateCodebaseMap(
|
|
|
427
586
|
|
|
428
587
|
// Generate new map preserving descriptions — reuse the returned file list
|
|
429
588
|
// to avoid a second enumeration (prevents race between content and stats).
|
|
430
|
-
const
|
|
589
|
+
const enumerated = resolveWorkspaceEnumeration(basePath, resolved);
|
|
590
|
+
const result = buildCodebaseMap(basePath, resolved, existingDescriptions, enumerated);
|
|
431
591
|
const currentSet = new Set(result.files);
|
|
432
592
|
|
|
433
593
|
// Count changes
|
|
@@ -467,7 +627,7 @@ export function ensureCodebaseMapFresh(
|
|
|
467
627
|
ensureOptions?: EnsureCodebaseMapOptions,
|
|
468
628
|
): EnsureCodebaseMapResult {
|
|
469
629
|
const resolved = resolveGeneratorOptions(options);
|
|
470
|
-
const cacheKey = `${basePath}::${resolved.optionSignature}`;
|
|
630
|
+
const cacheKey = `${basePath}::${resolved.optionSignature}::${workspaceEnumerationSignature(basePath)}`;
|
|
471
631
|
const ttlMs = ensureOptions?.ttlMs ?? DEFAULT_REFRESH_TTL_MS;
|
|
472
632
|
const force = ensureOptions?.force === true;
|
|
473
633
|
const now = Date.now();
|
|
@@ -481,8 +641,9 @@ export function ensureCodebaseMapFresh(
|
|
|
481
641
|
}
|
|
482
642
|
|
|
483
643
|
const existing = readCodebaseMap(basePath);
|
|
484
|
-
const listed =
|
|
485
|
-
|
|
644
|
+
const listed = resolveWorkspaceEnumeration(basePath, resolved)
|
|
645
|
+
?? enumerateFiles(basePath, resolved.excludes, resolved.maxFiles);
|
|
646
|
+
const fingerprint = computeCodebaseFingerprint(listed.files, resolved, listed.truncated, listed.repos);
|
|
486
647
|
|
|
487
648
|
const cacheAndReturn = (result: EnsureCodebaseMapResult): EnsureCodebaseMapResult => {
|
|
488
649
|
freshnessCache.set(cacheKey, { checkedAt: now, result });
|
|
@@ -4,7 +4,9 @@ import type { GSDState } from "../../types.js";
|
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
|
|
6
6
|
import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
|
|
7
|
+
import { isRepositoryDirty } from "../../git-service.js";
|
|
7
8
|
import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, availableModelIdsFromRegistry, modelIdsForProfileResolution, resolveProfileAnchorProvider, resolveDisabledModelProvidersFromPreferences } from "../../preferences.js";
|
|
9
|
+
import { createRepositoryRegistryFromPreferences } from "../../repository-registry.js";
|
|
8
10
|
import { ensurePreferencesFile, handlePrefs, handlePrefsMode, handlePrefsWizard, handleLanguage } from "../../commands-prefs-wizard.js";
|
|
9
11
|
import { runEnvironmentChecks } from "../../doctor-environment.js";
|
|
10
12
|
import { deriveState } from "../../state.js";
|
|
@@ -220,7 +222,7 @@ export async function handleStatus(ctx: ExtensionCommandContext): Promise<void>
|
|
|
220
222
|
);
|
|
221
223
|
|
|
222
224
|
if (result === undefined) {
|
|
223
|
-
ctx.ui.notify(formatTextStatus(state), "info");
|
|
225
|
+
ctx.ui.notify(formatTextStatus(state, basePath), "info");
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
|
|
@@ -610,7 +612,8 @@ export async function handleCoreCommand(
|
|
|
610
612
|
return false;
|
|
611
613
|
}
|
|
612
614
|
|
|
613
|
-
export function formatTextStatus(state: GSDState): string {
|
|
615
|
+
export function formatTextStatus(state: GSDState, basePath?: string): string {
|
|
616
|
+
const root = basePath ?? projectRoot();
|
|
614
617
|
const lines: string[] = ["GSD Status\n"];
|
|
615
618
|
lines.push(formatProgressLine(computeProgressScore()));
|
|
616
619
|
lines.push("");
|
|
@@ -653,7 +656,7 @@ export function formatTextStatus(state: GSDState): string {
|
|
|
653
656
|
}
|
|
654
657
|
}
|
|
655
658
|
|
|
656
|
-
const envResults = runEnvironmentChecks(
|
|
659
|
+
const envResults = runEnvironmentChecks(root);
|
|
657
660
|
const envIssues = envResults.filter((result) => result.status !== "ok");
|
|
658
661
|
if (envIssues.length > 0) {
|
|
659
662
|
lines.push("");
|
|
@@ -663,5 +666,38 @@ export function formatTextStatus(state: GSDState): string {
|
|
|
663
666
|
}
|
|
664
667
|
}
|
|
665
668
|
|
|
669
|
+
// Parent-workspace per-repository git health (#818). No-op for single-repo
|
|
670
|
+
// projects; surfaces which declared child repos have uncommitted changes.
|
|
671
|
+
const repoBlock = buildWorkspaceRepoStatusBlock(root);
|
|
672
|
+
if (repoBlock) {
|
|
673
|
+
lines.push("");
|
|
674
|
+
lines.push("Repositories:");
|
|
675
|
+
lines.push(repoBlock);
|
|
676
|
+
}
|
|
677
|
+
|
|
666
678
|
return lines.join("\n");
|
|
667
679
|
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Build a per-repository dirty/clean summary for parent-workspace status.
|
|
683
|
+
* Returns "" for single-repo (project-mode) projects so the status output is
|
|
684
|
+
* unchanged; otherwise one line per declared child repository.
|
|
685
|
+
*/
|
|
686
|
+
function buildWorkspaceRepoStatusBlock(basePath: string): string {
|
|
687
|
+
let registry;
|
|
688
|
+
try {
|
|
689
|
+
registry = createRepositoryRegistryFromPreferences(basePath, loadEffectiveGSDPreferences(basePath)?.preferences);
|
|
690
|
+
} catch {
|
|
691
|
+
return "";
|
|
692
|
+
}
|
|
693
|
+
if (registry.mode !== "parent") return "";
|
|
694
|
+
const childRepos = registry.repositories.filter((repo) => repo.id !== "project");
|
|
695
|
+
if (childRepos.length === 0) return "";
|
|
696
|
+
|
|
697
|
+
return childRepos
|
|
698
|
+
.map((repo) => {
|
|
699
|
+
const dirty = isRepositoryDirty(repo.root);
|
|
700
|
+
return ` ${dirty ? "✗" : "✓"} ${repo.id}${repo.role ? ` — ${repo.role}` : ""}${dirty ? " (uncommitted changes)" : " (clean)"}`;
|
|
701
|
+
})
|
|
702
|
+
.join("\n");
|
|
703
|
+
}
|
|
@@ -551,6 +551,17 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
|
|
|
551
551
|
if (parts.length > 0) integrationsSummary = parts.join(", ");
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
+
// Workspace (parent-workspace multi-repo)
|
|
555
|
+
const workspace = prefs.workspace as Record<string, unknown> | undefined;
|
|
556
|
+
const workspaceRepos = workspace?.repositories as Record<string, unknown> | undefined;
|
|
557
|
+
let workspaceSummary = "(single-repo)";
|
|
558
|
+
{
|
|
559
|
+
const parts: string[] = [];
|
|
560
|
+
if (workspace?.mode) parts.push(`mode: ${workspace.mode}`);
|
|
561
|
+
if (workspaceRepos && Object.keys(workspaceRepos).length > 0) parts.push(`${Object.keys(workspaceRepos).length} repo(s)`);
|
|
562
|
+
if (parts.length > 0) workspaceSummary = parts.join(", ");
|
|
563
|
+
}
|
|
564
|
+
|
|
554
565
|
return {
|
|
555
566
|
mode: modeSummary,
|
|
556
567
|
models: modelsSummary,
|
|
@@ -568,6 +579,7 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
|
|
|
568
579
|
hooks: hooksSummary,
|
|
569
580
|
uok: uokSummary,
|
|
570
581
|
integrations: integrationsSummary,
|
|
582
|
+
workspace: workspaceSummary,
|
|
571
583
|
};
|
|
572
584
|
}
|
|
573
585
|
|
|
@@ -758,7 +770,10 @@ async function configureDynamicRouting(ctx: ExtensionCommandContext, prefs: Reco
|
|
|
758
770
|
const hooks = await promptBoolean(ctx, "Route hook sessions dynamically", dr.hooks, true);
|
|
759
771
|
if (hooks !== undefined) dr.hooks = hooks;
|
|
760
772
|
|
|
761
|
-
|
|
773
|
+
// Opt-out flag (#1115): routing is allowed for flat-rate providers by
|
|
774
|
+
// default; only an explicit `false` suppresses it. The default hint reflects
|
|
775
|
+
// that allow-by-default behavior.
|
|
776
|
+
const flatRate = await promptBoolean(ctx, "Allow dynamic routing for flat-rate providers", dr.allow_flat_rate_providers, true);
|
|
762
777
|
if (flatRate !== undefined) dr.allow_flat_rate_providers = flatRate;
|
|
763
778
|
|
|
764
779
|
// tier_models.light / standard / heavy — optional model IDs
|
|
@@ -968,6 +983,114 @@ async function configureSkills(ctx: ExtensionCommandContext, prefs: Record<strin
|
|
|
968
983
|
applyNumber(prefs, "skill_staleness_days", staleness);
|
|
969
984
|
}
|
|
970
985
|
|
|
986
|
+
async function configureWorkspace(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
|
|
987
|
+
type RepoConfig = { path: string; role?: string; verification?: string[]; commit_policy?: "auto" | "skip" };
|
|
988
|
+
let workspace = (prefs.workspace ?? {}) as { mode?: "project" | "parent"; repositories?: Record<string, RepoConfig> };
|
|
989
|
+
|
|
990
|
+
// Mode
|
|
991
|
+
const mode = await promptEnum(ctx, "Workspace mode", workspace.mode, ["project", "parent"]);
|
|
992
|
+
if (mode !== undefined) workspace = { ...workspace, mode: mode as "project" | "parent" };
|
|
993
|
+
|
|
994
|
+
if (workspace.mode !== "parent") {
|
|
995
|
+
// Single-repo mode: drop any declared repositories and persist.
|
|
996
|
+
if (workspace.repositories && Object.keys(workspace.repositories).length > 0) {
|
|
997
|
+
const clear = await promptBoolean(ctx, "Clear declared repositories (switch to single-repo)?", false, false);
|
|
998
|
+
if (clear) workspace = { mode: workspace.mode };
|
|
999
|
+
}
|
|
1000
|
+
persistWorkspace(prefs, workspace);
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// Parent mode — edit child repositories via a sub-menu.
|
|
1005
|
+
let repositories = { ...(workspace.repositories ?? {}) };
|
|
1006
|
+
while (true) {
|
|
1007
|
+
const ids = Object.keys(repositories).sort();
|
|
1008
|
+
const summary = ids.length === 0 ? "(no repositories — parent mode requires at least one)" : `${ids.length} repo(s)`;
|
|
1009
|
+
const listLabels = ids.map((id) => {
|
|
1010
|
+
const r = repositories[id];
|
|
1011
|
+
const roleStr = r.role ? ` — ${r.role}` : "";
|
|
1012
|
+
const policyStr = r.commit_policy === "skip" ? " [skip]" : "";
|
|
1013
|
+
return `${id} (${r.path})${roleStr}${policyStr}`;
|
|
1014
|
+
});
|
|
1015
|
+
const choice = await ctx.ui.select(`Declared repositories — ${summary}`, [...listLabels, "Add repository", "Done"]);
|
|
1016
|
+
const pick = typeof choice === "string" ? choice : "";
|
|
1017
|
+
if (!pick || pick === "Done") break;
|
|
1018
|
+
if (pick === "Add repository") {
|
|
1019
|
+
const idInput = await ctx.ui.input("Repository id (letters, digits, . _ -; 'project' is reserved):", "");
|
|
1020
|
+
const id = typeof idInput === "string" ? idInput.trim() : "";
|
|
1021
|
+
if (!id || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id)) {
|
|
1022
|
+
ctx.ui.notify("Invalid repository id — must match ^[A-Za-z0-9][A-Za-z0-9._-]*$ and cannot be 'project'.", "warning");
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
if (id === "project" || repositories[id]) {
|
|
1026
|
+
ctx.ui.notify(`Repository id "${id}" is reserved or already declared.`, "warning");
|
|
1027
|
+
continue;
|
|
1028
|
+
}
|
|
1029
|
+
const pathInput = await ctx.ui.input("Repository path (relative to project root, e.g. frontend):", "");
|
|
1030
|
+
const path = typeof pathInput === "string" ? pathInput.trim() : "";
|
|
1031
|
+
if (!path) { ctx.ui.notify("Repository path is required.", "warning"); continue; }
|
|
1032
|
+
const repo: RepoConfig = { path };
|
|
1033
|
+
const roleInput = await ctx.ui.input("Role/label (optional):", "");
|
|
1034
|
+
if (typeof roleInput === "string" && roleInput.trim()) repo.role = roleInput.trim();
|
|
1035
|
+
const verifyInput = await ctx.ui.input("Verification commands (comma- or newline-separated, optional):", "");
|
|
1036
|
+
if (typeof verifyInput === "string" && verifyInput.trim()) {
|
|
1037
|
+
const cmds = parseStringList(verifyInput);
|
|
1038
|
+
if (cmds.length > 0) repo.verification = cmds;
|
|
1039
|
+
}
|
|
1040
|
+
const policy = await promptEnum(ctx, "Commit policy", undefined, ["auto", "skip"]);
|
|
1041
|
+
if (policy === "skip") repo.commit_policy = "skip";
|
|
1042
|
+
repositories[id] = repo;
|
|
1043
|
+
} else {
|
|
1044
|
+
// Edit/delete an existing repo (the first token is the id).
|
|
1045
|
+
const id = pick.split(" ")[0];
|
|
1046
|
+
if (!repositories[id]) continue;
|
|
1047
|
+
const editChoice = await ctx.ui.select(
|
|
1048
|
+
`Repository ${id}`,
|
|
1049
|
+
["Edit path", "Edit role", "Edit verification", "Edit commit policy", "Delete repository", "Cancel"],
|
|
1050
|
+
);
|
|
1051
|
+
const ec = typeof editChoice === "string" ? editChoice : "";
|
|
1052
|
+
if (!ec || ec === "Cancel") continue;
|
|
1053
|
+
if (ec === "Delete repository") {
|
|
1054
|
+
delete repositories[id];
|
|
1055
|
+
} else if (ec === "Edit path") {
|
|
1056
|
+
const v = await ctx.ui.input("Repository path:", repositories[id].path);
|
|
1057
|
+
if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], path: v.trim() };
|
|
1058
|
+
} else if (ec === "Edit role") {
|
|
1059
|
+
const v = await ctx.ui.input("Role/label (blank to clear):", repositories[id].role ?? "");
|
|
1060
|
+
if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], role: v.trim() };
|
|
1061
|
+
else if (typeof v === "string") { const { role, ...rest } = repositories[id]; void role; repositories[id] = rest; }
|
|
1062
|
+
} else if (ec === "Edit verification") {
|
|
1063
|
+
const v = await ctx.ui.input("Verification commands (blank to clear):", (repositories[id].verification ?? []).join(", "));
|
|
1064
|
+
if (typeof v === "string" && v.trim()) {
|
|
1065
|
+
const cmds = parseStringList(v);
|
|
1066
|
+
if (cmds.length > 0) repositories[id] = { ...repositories[id], verification: cmds };
|
|
1067
|
+
} else if (typeof v === "string") {
|
|
1068
|
+
const { verification, ...rest } = repositories[id]; void verification; repositories[id] = rest;
|
|
1069
|
+
}
|
|
1070
|
+
} else if (ec === "Edit commit policy") {
|
|
1071
|
+
const policy = await promptEnum(ctx, "Commit policy", repositories[id].commit_policy, ["auto", "skip"]);
|
|
1072
|
+
if (policy === "skip") repositories[id] = { ...repositories[id], commit_policy: "skip" };
|
|
1073
|
+
else { const { commit_policy, ...rest } = repositories[id]; void commit_policy; repositories[id] = rest; }
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
if (Object.keys(repositories).length === 0) {
|
|
1079
|
+
ctx.ui.notify("Parent mode requires at least one repository — mode not saved.", "warning");
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
persistWorkspace(prefs, { mode: "parent", repositories });
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/** Persist the workspace config onto prefs, dropping it entirely when empty. */
|
|
1086
|
+
function persistWorkspace(prefs: Record<string, unknown>, workspace: { mode?: string; repositories?: Record<string, unknown> }): void {
|
|
1087
|
+
if (!workspace.mode && (!workspace.repositories || Object.keys(workspace.repositories).length === 0)) {
|
|
1088
|
+
delete prefs.workspace;
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
prefs.workspace = workspace;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
971
1094
|
async function configureSkillRules(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
|
|
972
1095
|
type Rule = { when: string; use?: string[]; prefer?: string[]; avoid?: string[] };
|
|
973
1096
|
let rules: Rule[] = Array.isArray(prefs.skill_rules) ? [...prefs.skill_rules as Rule[]] : [];
|
|
@@ -1176,6 +1299,14 @@ async function configureVerification(ctx: ExtensionCommandContext, prefs: Record
|
|
|
1176
1299
|
const maxRetries = await promptInteger(ctx, "Verification max retries", prefs.verification_max_retries, "2");
|
|
1177
1300
|
applyNumber(prefs, "verification_max_retries", maxRetries);
|
|
1178
1301
|
|
|
1302
|
+
const perUnitCap = await promptNumber(
|
|
1303
|
+
ctx,
|
|
1304
|
+
"Per-unit cost cap (USD; retry cost ceiling, blank = clear to default)",
|
|
1305
|
+
prefs.per_unit_cost_cap_usd,
|
|
1306
|
+
"5.0",
|
|
1307
|
+
);
|
|
1308
|
+
applyNumber(prefs, "per_unit_cost_cap_usd", perUnitCap);
|
|
1309
|
+
|
|
1179
1310
|
const ev = await promptBoolean(ctx, "Enhanced verification (master toggle)", prefs.enhanced_verification, true);
|
|
1180
1311
|
if (ev !== undefined) prefs.enhanced_verification = ev;
|
|
1181
1312
|
const evPre = await promptBoolean(ctx, "Enhanced verification — pre-execution checks", prefs.enhanced_verification_pre, true);
|
|
@@ -1228,7 +1359,7 @@ async function configureContextCodebase(ctx: ExtensionCommandContext, prefs: Rec
|
|
|
1228
1359
|
const maskTurns = await promptInteger(ctx, "Observation mask turns (1–50)", cm.observation_mask_turns, "8");
|
|
1229
1360
|
if (maskTurns !== undefined && maskTurns !== "clear") cm.observation_mask_turns = maskTurns;
|
|
1230
1361
|
else if (maskTurns === "clear") delete cm.observation_mask_turns;
|
|
1231
|
-
const thresh = await promptNumber(ctx, "
|
|
1362
|
+
const thresh = await promptNumber(ctx, "Soft context warning threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
|
|
1232
1363
|
if (thresh !== undefined && thresh !== "clear") cm.compaction_threshold_percent = thresh;
|
|
1233
1364
|
else if (thresh === "clear") delete cm.compaction_threshold_percent;
|
|
1234
1365
|
const toolMax = await promptInteger(ctx, "Tool result max chars (200–10000)", cm.tool_result_max_chars, "800");
|
|
@@ -1621,6 +1752,7 @@ export async function handlePrefsWizard(
|
|
|
1621
1752
|
`Hooks ${summaries.hooks}`,
|
|
1622
1753
|
`UoK ${summaries.uok}`,
|
|
1623
1754
|
`Integrations ${summaries.integrations}`,
|
|
1755
|
+
`Workspace ${summaries.workspace}`,
|
|
1624
1756
|
`Advanced ${summaries.advanced}`,
|
|
1625
1757
|
`── Save & Exit ──`,
|
|
1626
1758
|
];
|
|
@@ -1644,6 +1776,7 @@ export async function handlePrefsWizard(
|
|
|
1644
1776
|
else if (choice.startsWith("Hooks")) await configureHooks(ctx, prefs);
|
|
1645
1777
|
else if (choice.startsWith("UoK")) await configureUoK(ctx, prefs);
|
|
1646
1778
|
else if (choice.startsWith("Integrations")) await configureIntegrations(ctx, prefs);
|
|
1779
|
+
else if (choice.startsWith("Workspace")) await configureWorkspace(ctx, prefs);
|
|
1647
1780
|
else if (choice.startsWith("Advanced")) await configureAdvanced(ctx, prefs);
|
|
1648
1781
|
}
|
|
1649
1782
|
|
|
@@ -1780,6 +1913,7 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
|
|
|
1780
1913
|
"reactive_execution", "gate_evaluation",
|
|
1781
1914
|
"auto_visualize", "auto_report",
|
|
1782
1915
|
"verification_commands", "verification_auto_fix", "verification_max_retries",
|
|
1916
|
+
"per_unit_cost_cap_usd",
|
|
1783
1917
|
"enhanced_verification", "enhanced_verification_pre",
|
|
1784
1918
|
"enhanced_verification_post", "enhanced_verification_strict",
|
|
1785
1919
|
"safety_harness",
|
|
@@ -112,7 +112,7 @@ function formatThresholdLines(): string[] {
|
|
|
112
112
|
|
|
113
113
|
const compactionThreshold = prefs?.context_management?.compaction_threshold_percent;
|
|
114
114
|
if (typeof compactionThreshold === "number") {
|
|
115
|
-
lines.push(`
|
|
115
|
+
lines.push(`Soft context warning: ${Math.round(compactionThreshold * 100)}%`);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
return lines;
|
|
@@ -315,8 +315,19 @@ async function handleRemove(args: string, ctx: ExtensionCommandContext): Promise
|
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
try {
|
|
318
|
-
removeWorktree(basePath, name, { deleteBranch: true });
|
|
319
|
-
|
|
318
|
+
const removed = removeWorktree(basePath, name, { deleteBranch: true });
|
|
319
|
+
if (removed) {
|
|
320
|
+
ctx.ui.notify(`Removed worktree ${name}.`, "info");
|
|
321
|
+
} else {
|
|
322
|
+
ctx.ui.notify(
|
|
323
|
+
[
|
|
324
|
+
`Worktree removal aborted for "${name}" to preserve uncommitted changes.`,
|
|
325
|
+
"",
|
|
326
|
+
"Manual quarantine recovery may be needed before retrying removal.",
|
|
327
|
+
].join("\n"),
|
|
328
|
+
"warning",
|
|
329
|
+
);
|
|
330
|
+
}
|
|
320
331
|
} catch (err) {
|
|
321
332
|
const msg = err instanceof Error ? err.message : String(err);
|
|
322
333
|
ctx.ui.notify(
|
|
@@ -47,7 +47,11 @@ import {
|
|
|
47
47
|
applyMigrationV28MemoryLastHitAt,
|
|
48
48
|
applyMigrationV29RepositoryTargets,
|
|
49
49
|
} from "../db-migration-steps.js";
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
isMemoriesFtsAvailableSchema,
|
|
52
|
+
rebuildMemoriesFtsSchemaOnce,
|
|
53
|
+
tryCreateMemoriesFtsSchema,
|
|
54
|
+
} from "../db-memory-fts-schema.js";
|
|
51
55
|
import { createDbOpenState, type DbOpenPhase } from "../db-open-state.js";
|
|
52
56
|
import { createRuntimeKvTableV25 } from "../db-runtime-kv-schema.js";
|
|
53
57
|
import { getCurrentSchemaVersion, recordSchemaVersion } from "../db-schema-metadata.js";
|
|
@@ -134,6 +138,9 @@ function initSchema(db: DbAdapter, fileBacked: boolean, dbPath: string | null):
|
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
migrateSchema(db, dbPath);
|
|
141
|
+
rebuildMemoriesFtsSchemaOnce(db, {
|
|
142
|
+
onRebuildFailed: (message) => logWarning("db", message),
|
|
143
|
+
});
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
export function _isLikelyWslDrvFsPathForTest(dbPath: string | null): boolean {
|