@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
|
@@ -1,12 +1,130 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
3
|
+
import { getAllMilestones, getMilestoneSlices, getSliceTasks, isDbAvailable, isMemoriesFtsAvailable, _getAdapter, } from "./gsd-db.js";
|
|
4
|
+
import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
|
|
3
5
|
import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
|
|
4
|
-
import { resolveGsdPathContract, resolveMilestoneFile } from "./paths.js";
|
|
6
|
+
import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
5
7
|
import { deriveState } from "./state.js";
|
|
8
|
+
import { isClosedStatus } from "./status-guards.js";
|
|
6
9
|
import { workflowEventLogPath } from "./workflow-event-ledger.js";
|
|
7
10
|
import { readEvents } from "./workflow-events.js";
|
|
8
11
|
import { flushWorkflowProjections } from "./projection-flush.js";
|
|
9
|
-
|
|
12
|
+
import { parseRoadmapSlices } from "./roadmap-slices.js";
|
|
13
|
+
import { parsePlan } from "./parsers-legacy.js";
|
|
14
|
+
const USER_AUTHORED_ARTIFACT_TYPES = new Set(["CONTEXT", "RESEARCH"]);
|
|
15
|
+
function relativeFile(basePath, filePath) {
|
|
16
|
+
return relative(basePath, filePath).split("\\").join("/");
|
|
17
|
+
}
|
|
18
|
+
function normalizedArtifactType(artifactType) {
|
|
19
|
+
return artifactType.trim().toUpperCase();
|
|
20
|
+
}
|
|
21
|
+
function isUserAuthoredArtifactType(artifactType) {
|
|
22
|
+
return USER_AUTHORED_ARTIFACT_TYPES.has(normalizedArtifactType(artifactType));
|
|
23
|
+
}
|
|
24
|
+
function userContentRecoveryCommand(artifactType) {
|
|
25
|
+
return normalizedArtifactType(artifactType) === "CONTEXT" ? "/gsd discuss" : "/gsd auto";
|
|
26
|
+
}
|
|
27
|
+
function userContentMissingMessage(path, artifactType) {
|
|
28
|
+
const type = normalizedArtifactType(artifactType) || "UNKNOWN";
|
|
29
|
+
return `Artifact \`${path}\` is a user-authored ${type} file recorded in the database but missing from disk. Re-run \`${userContentRecoveryCommand(type)}\` in this milestone to regenerate it.`;
|
|
30
|
+
}
|
|
31
|
+
function reportCheckboxDbStatusDivergence(issues, basePath, filePath, scope, unitId, status, checkboxDone) {
|
|
32
|
+
const dbDone = isClosedStatus(status);
|
|
33
|
+
if (checkboxDone === dbDone)
|
|
34
|
+
return;
|
|
35
|
+
issues.push({
|
|
36
|
+
severity: "error",
|
|
37
|
+
code: "checkbox_db_status_divergence",
|
|
38
|
+
scope,
|
|
39
|
+
unitId,
|
|
40
|
+
message: `${scope === "slice" ? "Slice" : "Task"} ${unitId} is ${dbDone ? "closed" : "open"} in the database (status: ${status}) but the markdown checkbox is ${checkboxDone ? "checked" : "unchecked"}.`,
|
|
41
|
+
file: relativeFile(basePath, filePath),
|
|
42
|
+
fixable: false,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function checkProjectionCheckboxDbStatus(basePath, milestoneIds, issues) {
|
|
46
|
+
for (const milestoneId of milestoneIds) {
|
|
47
|
+
const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
48
|
+
const slices = getMilestoneSlices(milestoneId);
|
|
49
|
+
if (roadmapPath && existsSync(roadmapPath)) {
|
|
50
|
+
try {
|
|
51
|
+
const roadmap = readFileSync(roadmapPath, "utf-8");
|
|
52
|
+
const sliceDoneById = new Map(parseRoadmapSlices(roadmap).map((entry) => [entry.id, entry.done]));
|
|
53
|
+
for (const slice of slices) {
|
|
54
|
+
const checkboxDone = sliceDoneById.get(slice.id);
|
|
55
|
+
if (checkboxDone === undefined)
|
|
56
|
+
continue;
|
|
57
|
+
reportCheckboxDbStatusDivergence(issues, basePath, roadmapPath, "slice", `${milestoneId}/${slice.id}`, slice.status, checkboxDone);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Non-fatal — checkbox drift diagnostics must never block doctor.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const slice of slices) {
|
|
65
|
+
const planPath = resolveSliceFile(basePath, milestoneId, slice.id, "PLAN");
|
|
66
|
+
if (!planPath || !existsSync(planPath))
|
|
67
|
+
continue;
|
|
68
|
+
try {
|
|
69
|
+
const plan = readFileSync(planPath, "utf-8");
|
|
70
|
+
// parsePlan reads the authoritative task checkboxes (the flat-phase
|
|
71
|
+
// <tasks> block / ## Tasks section), so a stray task-style checkbox
|
|
72
|
+
// line elsewhere in PLAN.md (e.g. a Must-Haves or Verification bullet
|
|
73
|
+
// above <tasks>) can no longer hide real drift or fake a divergence.
|
|
74
|
+
const taskDoneById = new Map(parsePlan(plan).tasks.map((entry) => [entry.id, entry.done]));
|
|
75
|
+
for (const task of getSliceTasks(milestoneId, slice.id)) {
|
|
76
|
+
const checkboxDone = taskDoneById.get(task.id);
|
|
77
|
+
if (checkboxDone === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
reportCheckboxDbStatusDivergence(issues, basePath, planPath, "task", `${milestoneId}/${slice.id}/${task.id}`, task.status, checkboxDone);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Non-fatal — checkbox drift diagnostics must never block doctor.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function isClearedByMilestoneShellProjectionFlush(basePath, issue, reRenderedMilestoneIds) {
|
|
89
|
+
if (issue.code !== "checkbox_db_status_divergence")
|
|
90
|
+
return false;
|
|
91
|
+
if (issue.scope !== "slice")
|
|
92
|
+
return false;
|
|
93
|
+
const milestoneId = issue.unitId.split("/")[0] ?? "";
|
|
94
|
+
if (!reRenderedMilestoneIds.has(milestoneId))
|
|
95
|
+
return false;
|
|
96
|
+
const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
97
|
+
if (!roadmapPath || !issue.file)
|
|
98
|
+
return false;
|
|
99
|
+
return issue.file === relativeFile(basePath, roadmapPath);
|
|
100
|
+
}
|
|
101
|
+
function artifactExistsOnDisk(basePath, artifactPath) {
|
|
102
|
+
if (isAbsolute(artifactPath))
|
|
103
|
+
return existsSync(artifactPath);
|
|
104
|
+
return [
|
|
105
|
+
join(gsdProjectionRoot(basePath), artifactPath),
|
|
106
|
+
join(gsdRoot(basePath), artifactPath),
|
|
107
|
+
].some((candidate) => existsSync(candidate));
|
|
108
|
+
}
|
|
109
|
+
function artifactUnitId(row) {
|
|
110
|
+
if (!row.milestone_id)
|
|
111
|
+
return "project";
|
|
112
|
+
if (row.slice_id && row.task_id)
|
|
113
|
+
return `${row.milestone_id}/${row.slice_id}/${row.task_id}`;
|
|
114
|
+
if (row.slice_id)
|
|
115
|
+
return `${row.milestone_id}/${row.slice_id}`;
|
|
116
|
+
return row.milestone_id;
|
|
117
|
+
}
|
|
118
|
+
function artifactScope(row) {
|
|
119
|
+
if (row.task_id)
|
|
120
|
+
return "task";
|
|
121
|
+
if (row.slice_id)
|
|
122
|
+
return "slice";
|
|
123
|
+
if (row.milestone_id)
|
|
124
|
+
return "milestone";
|
|
125
|
+
return "project";
|
|
126
|
+
}
|
|
127
|
+
export async function checkEngineHealth(basePath, issues, fixesApplied, options) {
|
|
10
128
|
const dbPath = resolveGsdPathContract(basePath).projectDb;
|
|
11
129
|
if (!isDbAvailable() && existsSync(dbPath)) {
|
|
12
130
|
issues.push({
|
|
@@ -23,6 +141,30 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
23
141
|
try {
|
|
24
142
|
if (isDbAvailable()) {
|
|
25
143
|
const adapter = _getAdapter();
|
|
144
|
+
try {
|
|
145
|
+
if (isMemoriesFtsAvailable(adapter)) {
|
|
146
|
+
const runtimeKv = adapter
|
|
147
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='runtime_kv'")
|
|
148
|
+
.get();
|
|
149
|
+
const marker = runtimeKv
|
|
150
|
+
? adapter.prepare("SELECT 1 as present FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = :key").get({ ":key": MEMORIES_FTS_REBUILT_KEY })
|
|
151
|
+
: undefined;
|
|
152
|
+
if (!marker) {
|
|
153
|
+
issues.push({
|
|
154
|
+
severity: "warning",
|
|
155
|
+
code: "memories_fts_rebuild_missing",
|
|
156
|
+
scope: "project",
|
|
157
|
+
unitId: "project",
|
|
158
|
+
message: `Memory full-text index exists but runtime_kv has no ${MEMORIES_FTS_REBUILT_KEY} marker. The index may be stale or incomplete, so memory search can silently degrade to the LIKE fallback.`,
|
|
159
|
+
file: ".gsd/gsd.db",
|
|
160
|
+
fixable: false,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Non-fatal — memory FTS health check failed
|
|
167
|
+
}
|
|
26
168
|
// a. Orphaned tasks (task.slice_id points to non-existent slice)
|
|
27
169
|
try {
|
|
28
170
|
const orphanedTasks = adapter
|
|
@@ -172,7 +314,53 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
172
314
|
catch {
|
|
173
315
|
// Non-fatal — completed-milestone reopen check failed
|
|
174
316
|
}
|
|
175
|
-
// f.
|
|
317
|
+
// f. Artifact rows reference files that no longer exist on disk.
|
|
318
|
+
const missingUserContentArtifacts = [];
|
|
319
|
+
try {
|
|
320
|
+
const artifactRows = adapter
|
|
321
|
+
.prepare(`SELECT path, artifact_type, milestone_id, slice_id, task_id
|
|
322
|
+
FROM artifacts
|
|
323
|
+
WHERE path != ''
|
|
324
|
+
ORDER BY path`)
|
|
325
|
+
.all();
|
|
326
|
+
for (const row of artifactRows) {
|
|
327
|
+
if (artifactExistsOnDisk(basePath, row.path))
|
|
328
|
+
continue;
|
|
329
|
+
const unitId = artifactUnitId(row);
|
|
330
|
+
if (isUserAuthoredArtifactType(row.artifact_type)) {
|
|
331
|
+
const artifactType = normalizedArtifactType(row.artifact_type);
|
|
332
|
+
missingUserContentArtifacts.push({ path: row.path, artifactType });
|
|
333
|
+
issues.push({
|
|
334
|
+
severity: "warning",
|
|
335
|
+
code: "artifact_user_content_missing",
|
|
336
|
+
scope: artifactScope(row),
|
|
337
|
+
unitId,
|
|
338
|
+
message: userContentMissingMessage(row.path, artifactType),
|
|
339
|
+
file: row.path,
|
|
340
|
+
fixable: false,
|
|
341
|
+
});
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
issues.push({
|
|
345
|
+
severity: "error",
|
|
346
|
+
code: "artifact_file_missing",
|
|
347
|
+
scope: artifactScope(row),
|
|
348
|
+
unitId,
|
|
349
|
+
message: `Artifact ${row.path} is recorded in the database as ${row.artifact_type || "UNKNOWN"} but no matching file exists on disk`,
|
|
350
|
+
file: row.path,
|
|
351
|
+
fixable: false,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
// Non-fatal — artifact file existence check failed
|
|
357
|
+
}
|
|
358
|
+
if (options?.repair) {
|
|
359
|
+
for (const artifact of missingUserContentArtifacts) {
|
|
360
|
+
fixesApplied.push(`skipped user-authored ${artifact.artifactType} artifact ${artifact.path} (content cannot be regenerated from the database)`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// g. Completion artifacts disagree with open DB hierarchy rows.
|
|
176
364
|
try {
|
|
177
365
|
const rows = adapter
|
|
178
366
|
.prepare(`SELECT a.path, a.artifact_type, a.milestone_id, a.slice_id, a.task_id, a.imported_at,
|
|
@@ -189,6 +377,8 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
189
377
|
.all();
|
|
190
378
|
const seen = new Set();
|
|
191
379
|
for (const row of rows) {
|
|
380
|
+
if (!artifactExistsOnDisk(basePath, row.path))
|
|
381
|
+
continue;
|
|
192
382
|
const reopenAt = latestExplicitReopenAt(basePath, row.milestone_id);
|
|
193
383
|
if (!isAfter(row.imported_at, reopenAt))
|
|
194
384
|
continue;
|
|
@@ -223,9 +413,24 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
223
413
|
catch {
|
|
224
414
|
// Non-fatal — DB constraint checks failed entirely
|
|
225
415
|
}
|
|
416
|
+
// Checkbox-vs-DB divergence detection runs before projection drift auto-fix
|
|
417
|
+
// so stale re-renders cannot overwrite manually edited markdown first. Runs
|
|
418
|
+
// inside its own try/catch: getAllMilestones / getMilestoneSlices /
|
|
419
|
+
// getSliceTasks issue prepared queries that can throw on a corrupt or locked
|
|
420
|
+
// DB, and like every other DB-touching check here this diagnostic must never
|
|
421
|
+
// block doctor.
|
|
422
|
+
try {
|
|
423
|
+
if (isDbAvailable()) {
|
|
424
|
+
checkProjectionCheckboxDbStatus(basePath, getAllMilestones().map((milestone) => milestone.id), issues);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
// Non-fatal: checkbox-vs-DB divergence check must never block doctor
|
|
429
|
+
}
|
|
226
430
|
// ── Projection drift detection ──────────────────────────────────────────
|
|
227
431
|
// If the DB is available, check whether markdown projections are stale
|
|
228
432
|
// relative to the event log and re-render them.
|
|
433
|
+
const reRenderedMilestoneIds = [];
|
|
229
434
|
try {
|
|
230
435
|
if (isDbAvailable()) {
|
|
231
436
|
const eventLogPath = workflowEventLogPath(basePath);
|
|
@@ -241,6 +446,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
241
446
|
try {
|
|
242
447
|
await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
|
|
243
448
|
fixesApplied.push(`re-rendered missing projections for ${milestone.id}`);
|
|
449
|
+
reRenderedMilestoneIds.push(milestone.id);
|
|
244
450
|
}
|
|
245
451
|
catch {
|
|
246
452
|
// Non-fatal — projection re-render failed
|
|
@@ -252,6 +458,7 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
252
458
|
try {
|
|
253
459
|
await flushWorkflowProjections(basePath, { milestoneId: milestone.id });
|
|
254
460
|
fixesApplied.push(`re-rendered stale projections for ${milestone.id}`);
|
|
461
|
+
reRenderedMilestoneIds.push(milestone.id);
|
|
255
462
|
}
|
|
256
463
|
catch {
|
|
257
464
|
// Non-fatal — projection re-render failed
|
|
@@ -264,4 +471,19 @@ export async function checkEngineHealth(basePath, issues, fixesApplied) {
|
|
|
264
471
|
catch {
|
|
265
472
|
// Non-fatal — projection drift check must never block doctor
|
|
266
473
|
}
|
|
474
|
+
if (reRenderedMilestoneIds.length > 0) {
|
|
475
|
+
const reRendered = new Set(reRenderedMilestoneIds);
|
|
476
|
+
for (let i = issues.length - 1; i >= 0; i--) {
|
|
477
|
+
const issue = issues[i];
|
|
478
|
+
// flushWorkflowProjections re-renders milestone shell projections (not
|
|
479
|
+
// slice PLAN.md files), so only clear stale ROADMAP checkbox diagnostics.
|
|
480
|
+
if (isClearedByMilestoneShellProjectionFlush(basePath, issue, reRendered)) {
|
|
481
|
+
issues.splice(i, 1);
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (issue.code === "artifact_file_missing" && issue.file && artifactExistsOnDisk(basePath, issue.file)) {
|
|
485
|
+
issues.splice(i, 1);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
267
489
|
}
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { existsSync, readFileSync } from "node:fs";
|
|
14
14
|
import { access, readFile } from "node:fs/promises";
|
|
15
|
+
import { homedir } from "node:os";
|
|
15
16
|
import { delimiter, join } from "node:path";
|
|
16
17
|
import { AuthStorage } from "@gsd/pi-coding-agent";
|
|
17
18
|
import { getEnvApiKey } from "@gsd/pi-ai";
|
|
19
|
+
import { isCursorAgentReadyUncached } from "../cursor-cli/readiness.js";
|
|
18
20
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
19
21
|
import { getAuthPath, PROVIDER_REGISTRY, supportsBrowserOAuth } from "./key-manager.js";
|
|
20
|
-
import { homedir } from "node:os";
|
|
21
22
|
// ── Provider routing constants ────────────────────────────────────────────────
|
|
22
23
|
/**
|
|
23
24
|
* Providers that use external CLI authentication (not API keys).
|
|
@@ -27,6 +28,7 @@ const CLI_AUTH_PROVIDERS = new Set([
|
|
|
27
28
|
"claude-code",
|
|
28
29
|
"google-gemini-cli",
|
|
29
30
|
"google-antigravity",
|
|
31
|
+
"cursor-agent",
|
|
30
32
|
]);
|
|
31
33
|
/**
|
|
32
34
|
* Providers that can serve models normally associated with another provider.
|
|
@@ -34,9 +36,9 @@ const CLI_AUTH_PROVIDERS = new Set([
|
|
|
34
36
|
* e.g. GitHub Copilot subscriptions can access Claude and GPT models.
|
|
35
37
|
*/
|
|
36
38
|
const PROVIDER_ROUTES = {
|
|
37
|
-
anthropic: ["github-copilot", "claude-code"],
|
|
38
|
-
openai: ["github-copilot", "openai-codex"],
|
|
39
|
-
google: ["google-antigravity", "google-gemini-cli"],
|
|
39
|
+
anthropic: ["github-copilot", "claude-code", "cursor-agent"],
|
|
40
|
+
openai: ["github-copilot", "openai-codex", "cursor-agent"],
|
|
41
|
+
google: ["google-antigravity", "google-gemini-cli", "cursor-agent"],
|
|
40
42
|
};
|
|
41
43
|
// ── Model → Provider ID mapping ───────────────────────────────────────────────
|
|
42
44
|
/**
|
|
@@ -61,6 +63,7 @@ function modelToProviderId(model) {
|
|
|
61
63
|
anthropic: "anthropic",
|
|
62
64
|
openai: "openai",
|
|
63
65
|
"github-copilot": "github-copilot",
|
|
66
|
+
"cursor-agent": "cursor-agent",
|
|
64
67
|
};
|
|
65
68
|
if (prefixMap[prefix])
|
|
66
69
|
return prefixMap[prefix];
|
|
@@ -73,6 +76,8 @@ function modelToProviderId(model) {
|
|
|
73
76
|
return "openai";
|
|
74
77
|
if (lower.startsWith("gemini"))
|
|
75
78
|
return "google";
|
|
79
|
+
if (lower.startsWith("composer"))
|
|
80
|
+
return "cursor-agent";
|
|
76
81
|
if (lower.startsWith("llama") || lower.startsWith("mixtral"))
|
|
77
82
|
return "groq";
|
|
78
83
|
if (lower.startsWith("grok"))
|
|
@@ -129,10 +134,12 @@ const CLI_BINARY_MAP = {
|
|
|
129
134
|
"claude-code": ["claude", "claude-code"],
|
|
130
135
|
"google-gemini-cli": ["gemini"],
|
|
131
136
|
"google-antigravity": ["agy"],
|
|
137
|
+
"cursor-agent": ["cursor-agent"],
|
|
132
138
|
};
|
|
133
139
|
const CLI_AUTH_PATH_CHECK_PROVIDERS = new Set([
|
|
134
140
|
"google-gemini-cli",
|
|
135
141
|
"google-antigravity",
|
|
142
|
+
"cursor-agent",
|
|
136
143
|
]);
|
|
137
144
|
let asyncCliBinaryPathCache = null;
|
|
138
145
|
function cliExecutableNames(providerId) {
|
|
@@ -173,6 +180,17 @@ function isCliBinaryInPath(providerId) {
|
|
|
173
180
|
const pathDirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
174
181
|
return pathDirs.some(dir => executableNames.some(name => existsSync(join(dir, name))));
|
|
175
182
|
}
|
|
183
|
+
function isExternalCliProviderReady(providerId) {
|
|
184
|
+
if (providerId === "cursor-agent")
|
|
185
|
+
return isCursorAgentReadyUncached();
|
|
186
|
+
return isCliBinaryInPath(providerId);
|
|
187
|
+
}
|
|
188
|
+
function cursorAgentFailureDetail() {
|
|
189
|
+
if (!isCliBinaryInPath("cursor-agent")) {
|
|
190
|
+
return "Install Cursor Agent and ensure `cursor-agent` is on PATH";
|
|
191
|
+
}
|
|
192
|
+
return "Run `cursor-agent login` or set CURSOR_API_KEY";
|
|
193
|
+
}
|
|
176
194
|
async function isCliBinaryInPathAsync(providerId) {
|
|
177
195
|
const executableNames = cliExecutableNames(providerId);
|
|
178
196
|
if (executableNames.length === 0)
|
|
@@ -293,6 +311,11 @@ function resolveKeyFromAuthOrEnv(providerId) {
|
|
|
293
311
|
return null;
|
|
294
312
|
}
|
|
295
313
|
function resolveKey(providerId) {
|
|
314
|
+
if (providerId === "cursor-agent") {
|
|
315
|
+
return isExternalCliProviderReady(providerId)
|
|
316
|
+
? { found: true, source: "env", backedOff: false }
|
|
317
|
+
: { found: false, source: "none", backedOff: false };
|
|
318
|
+
}
|
|
296
319
|
const direct = resolveKeyFromAuthOrEnv(providerId);
|
|
297
320
|
if (direct)
|
|
298
321
|
return direct;
|
|
@@ -301,7 +324,7 @@ function resolveKey(providerId) {
|
|
|
301
324
|
}
|
|
302
325
|
// Cross-provider routes can use a local CLI when it is installed. Explicit
|
|
303
326
|
// external CLI provider selections are handled in checkLlmProviders() below.
|
|
304
|
-
if (CLI_AUTH_PROVIDERS.has(providerId) &&
|
|
327
|
+
if (CLI_AUTH_PROVIDERS.has(providerId) && isExternalCliProviderReady(providerId)) {
|
|
305
328
|
return { found: true, source: "env", backedOff: false };
|
|
306
329
|
}
|
|
307
330
|
return { found: false, source: "none", backedOff: false };
|
|
@@ -316,17 +339,22 @@ function checkLlmProviders() {
|
|
|
316
339
|
if (CLI_AUTH_PROVIDERS.has(providerId)) {
|
|
317
340
|
const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
|
|
318
341
|
const label = info?.label ?? providerId;
|
|
319
|
-
if (CLI_AUTH_PATH_CHECK_PROVIDERS.has(providerId) && !
|
|
342
|
+
if (CLI_AUTH_PATH_CHECK_PROVIDERS.has(providerId) && !isExternalCliProviderReady(providerId)) {
|
|
320
343
|
const binaries = CLI_BINARY_MAP[providerId]?.map(binary => `\`${binary}\``).join(" or ");
|
|
344
|
+
const detail = providerId === "cursor-agent"
|
|
345
|
+
? cursorAgentFailureDetail()
|
|
346
|
+
: binaries
|
|
347
|
+
? `Install ${label} and ensure ${binaries} is on PATH`
|
|
348
|
+
: `Install ${label} and ensure its CLI is on PATH`;
|
|
321
349
|
results.push({
|
|
322
350
|
name: providerId,
|
|
323
351
|
label,
|
|
324
352
|
category: "llm",
|
|
325
353
|
status: "error",
|
|
326
|
-
message:
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
354
|
+
message: providerId === "cursor-agent" && isCliBinaryInPath(providerId)
|
|
355
|
+
? `${label} — CLI not authenticated`
|
|
356
|
+
: `${label} — CLI not found`,
|
|
357
|
+
detail,
|
|
330
358
|
required: true,
|
|
331
359
|
});
|
|
332
360
|
continue;
|
|
@@ -387,6 +387,9 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
|
|
|
387
387
|
if (!existingLines.has(".gsd-worktrees/") && !existingLines.has(".gsd-worktrees")) {
|
|
388
388
|
missing.push(".gsd-worktrees/");
|
|
389
389
|
}
|
|
390
|
+
if (!existingLines.has(".gsd-backups/") && !existingLines.has(".gsd-backups")) {
|
|
391
|
+
missing.push(".gsd-backups/");
|
|
392
|
+
}
|
|
390
393
|
if (!hasBlanketIgnore) {
|
|
391
394
|
missing.push(...criticalPatterns.filter(p => !existingLines.has(p)));
|
|
392
395
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, lstatSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
1
|
+
import { existsSync, mkdirSync, lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
3
4
|
import { loadFile, parseSummary, saveFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
|
|
4
5
|
import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
|
|
5
6
|
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
@@ -12,6 +13,8 @@ import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
|
12
13
|
import { collectPreferenceDiagnostics, formatPreferenceDiagnosticDetail } from "./preferences-diagnostics.js";
|
|
13
14
|
import { isClosedStatus } from "./status-guards.js";
|
|
14
15
|
import { GLOBAL_STATE_CODES } from "./doctor-types.js";
|
|
16
|
+
import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
|
|
17
|
+
import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
|
|
15
18
|
import { checkGitHealth, checkRuntimeHealth, checkGlobalHealth, checkEngineHealth } from "./doctor-checks.js";
|
|
16
19
|
import { checkEnvironmentHealth } from "./doctor-environment.js";
|
|
17
20
|
import { runProviderChecks } from "./doctor-providers.js";
|
|
@@ -281,6 +284,92 @@ export async function readDoctorHistory(basePath, lastN = 50) {
|
|
|
281
284
|
return [];
|
|
282
285
|
}
|
|
283
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Resolve the git working-tree root for a path, or null if it is not a repo.
|
|
289
|
+
* Used by the workspace-repository probe to check that a declared child path is
|
|
290
|
+
* itself a git repository (not merely nested inside the parent's repo).
|
|
291
|
+
*/
|
|
292
|
+
function resolveGitToplevel(cwd) {
|
|
293
|
+
try {
|
|
294
|
+
const out = execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
295
|
+
cwd,
|
|
296
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
297
|
+
encoding: "utf-8",
|
|
298
|
+
env: GIT_NO_PROMPT_ENV,
|
|
299
|
+
}).trim();
|
|
300
|
+
return out ? resolve(out) : null;
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/** realpath that falls back to the resolved path if the link cannot be read. */
|
|
307
|
+
function realpathSafe(p) {
|
|
308
|
+
try {
|
|
309
|
+
return realpathSync(p);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
return resolve(p);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Parent-workspace probe (#818): validate that every declared child repository
|
|
317
|
+
* exists on disk and is a git repository at its own root. The registry only
|
|
318
|
+
* checks paths stay inside the project root; it never checks existence or
|
|
319
|
+
* git-ness, so a typo'd path (e.g. `frontned`) would otherwise build cleanly
|
|
320
|
+
* and silently produce "no problems found." No-op for single-repo projects.
|
|
321
|
+
*/
|
|
322
|
+
function checkWorkspaceRepositoryHealth(basePath, prefs, issues) {
|
|
323
|
+
if (prefs?.workspace?.mode !== "parent")
|
|
324
|
+
return;
|
|
325
|
+
let registry;
|
|
326
|
+
try {
|
|
327
|
+
registry = createRepositoryRegistryFromPreferences(basePath, prefs);
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
issues.push({
|
|
331
|
+
severity: "error",
|
|
332
|
+
code: "invalid_preferences",
|
|
333
|
+
scope: "project",
|
|
334
|
+
unitId: "workspace",
|
|
335
|
+
message: `workspace registry failed to build: ${err instanceof Error ? err.message : String(err)}`,
|
|
336
|
+
fixable: false,
|
|
337
|
+
});
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
for (const repo of registry.repositories) {
|
|
341
|
+
if (repo.id === "project")
|
|
342
|
+
continue;
|
|
343
|
+
if (!existsSync(repo.root)) {
|
|
344
|
+
issues.push({
|
|
345
|
+
severity: "error",
|
|
346
|
+
code: "workspace_repo_path_missing",
|
|
347
|
+
scope: "project",
|
|
348
|
+
unitId: `workspace.repositories.${repo.id}`,
|
|
349
|
+
message: `declared repository "${repo.id}" path does not exist on disk: ${repo.root}`,
|
|
350
|
+
fixable: false,
|
|
351
|
+
});
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
// Must be a repo at its OWN root — a plain dir nested in the parent repo
|
|
355
|
+
// would otherwise pass a bare `nativeIsRepo` check via the enclosing
|
|
356
|
+
// parent's .git. Compare on realpath so symlinked temp roots (macOS
|
|
357
|
+
// /var vs /private/var) don't cause a false mismatch.
|
|
358
|
+
const toplevel = resolveGitToplevel(repo.root);
|
|
359
|
+
const declaredReal = realpathSafe(repo.root);
|
|
360
|
+
const toplevelReal = toplevel ? realpathSafe(toplevel) : null;
|
|
361
|
+
if (toplevelReal !== declaredReal) {
|
|
362
|
+
issues.push({
|
|
363
|
+
severity: "warning",
|
|
364
|
+
code: "workspace_repo_not_a_repo",
|
|
365
|
+
scope: "project",
|
|
366
|
+
unitId: `workspace.repositories.${repo.id}`,
|
|
367
|
+
message: `declared repository "${repo.id}" path is not a git repository at its own root: ${repo.root}`,
|
|
368
|
+
fixable: false,
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
284
373
|
export async function runGSDDoctor(basePath, options) {
|
|
285
374
|
const issues = [];
|
|
286
375
|
const fixesApplied = [];
|
|
@@ -336,6 +425,7 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
336
425
|
(prefs?.preferences?.git?.isolation === "worktree" ? "worktree" :
|
|
337
426
|
prefs?.preferences?.git?.isolation === "branch" ? "branch" : "none");
|
|
338
427
|
await checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode, dryRun);
|
|
428
|
+
checkWorkspaceRepositoryHealth(basePath, prefs?.preferences, issues);
|
|
339
429
|
const gitMs = Date.now() - t0git;
|
|
340
430
|
// Runtime health checks — timed
|
|
341
431
|
const t0runtime = Date.now();
|
|
@@ -352,7 +442,7 @@ export async function runGSDDoctor(basePath, options) {
|
|
|
352
442
|
});
|
|
353
443
|
const envMs = Date.now() - t0env;
|
|
354
444
|
// Engine health checks — DB constraints and projection drift
|
|
355
|
-
await checkEngineHealth(basePath, issues, fixesApplied);
|
|
445
|
+
await checkEngineHealth(basePath, issues, fixesApplied, { repair: fix && !dryRun });
|
|
356
446
|
const milestonesPath = milestonesDir(basePath);
|
|
357
447
|
const legacyMilestonesPath2 = legacyMilestonesDir(basePath);
|
|
358
448
|
if (!existsSync(milestonesPath) && !existsSync(legacyMilestonesPath2)) {
|
|
@@ -11,7 +11,8 @@ import { spawn } from "node:child_process";
|
|
|
11
11
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { resolve } from "node:path";
|
|
14
|
-
import { killProcessTree, SIGKILL_GRACE_MS, HARD_DEADLINE_MS } from "@gsd/pi-coding-agent";
|
|
14
|
+
import { getShellConfig, killProcessTree, SIGKILL_GRACE_MS, HARD_DEADLINE_MS } from "@gsd/pi-coding-agent";
|
|
15
|
+
import { redactSecrets } from "./redact-secrets.js";
|
|
15
16
|
const ALWAYS_FORWARD_ENV = ["PATH", "HOME"];
|
|
16
17
|
// SIGKILL_GRACE_MS / HARD_DEADLINE_MS are imported from @gsd/pi-coding-agent
|
|
17
18
|
// (shell.ts) — the single source of truth for the graceful-kill timing ladder —
|
|
@@ -60,7 +61,13 @@ function clampTimeout(request, opts) {
|
|
|
60
61
|
function resolveCommand(runtime) {
|
|
61
62
|
switch (runtime) {
|
|
62
63
|
case "bash":
|
|
63
|
-
|
|
64
|
+
try {
|
|
65
|
+
const { shell, args } = getShellConfig();
|
|
66
|
+
return { cmd: shell, args };
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return { cmd: "bash", args: ["-c"] };
|
|
70
|
+
}
|
|
64
71
|
case "node":
|
|
65
72
|
return { cmd: process.execPath, args: ["-e"] };
|
|
66
73
|
case "python":
|
|
@@ -226,8 +233,11 @@ export function runExecSandbox(request, opts) {
|
|
|
226
233
|
const stderrBuf = Buffer.concat(stderrChunks);
|
|
227
234
|
const stdoutSuffix = stdoutTruncated ? "\n[truncated: stdout cap reached]\n" : "";
|
|
228
235
|
const stderrSuffix = stderrTruncated ? "\n[truncated: stderr cap reached]\n" : "";
|
|
229
|
-
|
|
230
|
-
|
|
236
|
+
// Redact secret-shaped substrings before persisting to .gsd/exec/ (skipped by
|
|
237
|
+
// the secret scanner). The returned digest is derived from the raw buffer
|
|
238
|
+
// below and is redacted downstream when the session is written to activity/.
|
|
239
|
+
writeFileSync(stdoutPath, redactSecrets(Buffer.concat([stdoutBuf, Buffer.from(stdoutSuffix, "utf-8")]).toString("utf-8")));
|
|
240
|
+
writeFileSync(stderrPath, redactSecrets(Buffer.concat([stderrBuf, Buffer.from(stderrSuffix, "utf-8")]).toString("utf-8")));
|
|
231
241
|
const digestBody = tail(stdoutBuf, opts.digest_chars);
|
|
232
242
|
const digest = digestBody.length > 0
|
|
233
243
|
? digestBody
|