@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
|
@@ -90,6 +90,28 @@ function scanHasExtraIdentities(a: HierarchyScan, b: HierarchyScan): boolean {
|
|
|
90
90
|
);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function paddedMilestoneId(id: string): string | null {
|
|
94
|
+
return /^\d+$/.test(id) ? `M${id.padStart(3, "0")}` : null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function replaceSetPrefix(values: Set<string>, from: string, to: string): void {
|
|
98
|
+
for (const value of [...values]) {
|
|
99
|
+
if (value !== from && !value.startsWith(`${from}/`)) continue;
|
|
100
|
+
values.delete(value);
|
|
101
|
+
values.add(`${to}${value.slice(from.length)}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function alignNumericMarkdownIdsWithDb(markdownScan: HierarchyScan, dbScan: HierarchyScan): void {
|
|
106
|
+
for (const dbId of dbScan.milestones) {
|
|
107
|
+
const paddedId = paddedMilestoneId(dbId);
|
|
108
|
+
if (!paddedId || dbScan.milestones.has(paddedId) || !markdownScan.milestones.has(paddedId)) continue;
|
|
109
|
+
replaceSetPrefix(markdownScan.milestones, paddedId, dbId);
|
|
110
|
+
replaceSetPrefix(markdownScan.slices, paddedId, dbId);
|
|
111
|
+
replaceSetPrefix(markdownScan.tasks, paddedId, dbId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
93
115
|
/**
|
|
94
116
|
* True when the DB holds any milestone/slice/task identity the markdown lacks —
|
|
95
117
|
* i.e. a `/gsd recover --confirm` (markdown → DB) would DELETE authoritative DB
|
|
@@ -185,6 +207,7 @@ export async function checkMarkdownHierarchyAgainstDb(
|
|
|
185
207
|
|
|
186
208
|
const dbScan = scanDbHierarchy();
|
|
187
209
|
const beforeDb = dbScan.counts;
|
|
210
|
+
alignNumericMarkdownIdsWithDb(markdownScan, dbScan);
|
|
188
211
|
|
|
189
212
|
// Discussion-phase scratch: a milestone dir with no ROADMAP and no DB row is
|
|
190
213
|
// a pre-registration discussion artifact (CONTEXT/CONTEXT-DRAFT only — the
|
|
@@ -141,7 +141,8 @@ export function clearReservedMilestoneIds(): void {
|
|
|
141
141
|
|
|
142
142
|
// ─── Discovery ──────────────────────────────────────────────────────────────
|
|
143
143
|
|
|
144
|
-
function scanMilestoneIdsFromDir(dir: string): string[] {
|
|
144
|
+
function scanMilestoneIdsFromDir(basePath: string, dir: string): string[] {
|
|
145
|
+
const legacyNumericIds = idsWithLegacyNumericDirs(basePath);
|
|
145
146
|
return readdirSync(dir, { withFileTypes: true })
|
|
146
147
|
.filter((d) => d.isDirectory())
|
|
147
148
|
.map((d) => {
|
|
@@ -149,6 +150,12 @@ function scanMilestoneIdsFromDir(dir: string): string[] {
|
|
|
149
150
|
if (MILESTONE_ID_RE.test(d.name)) {
|
|
150
151
|
return d.name;
|
|
151
152
|
}
|
|
153
|
+
// Legacy recovery/imports may contain bare numeric milestone directories
|
|
154
|
+
// (for example `milestones/15/15-ROADMAP.md`). The DB can preserve that
|
|
155
|
+
// id, and rebuild renders it, so drift scans must see it too.
|
|
156
|
+
if (/^\d+$/.test(d.name)) {
|
|
157
|
+
return d.name;
|
|
158
|
+
}
|
|
152
159
|
// Legacy layout: M001-abcdef-slug descriptor directories
|
|
153
160
|
const legacyMatch = d.name.match(/^(M\d{3}(?:-[a-z0-9]{6})?)-/);
|
|
154
161
|
if (legacyMatch) {
|
|
@@ -162,6 +169,10 @@ function scanMilestoneIdsFromDir(dir: string): string[] {
|
|
|
162
169
|
if (MILESTONE_ID_RE.test(fromSlug)) {
|
|
163
170
|
return fromSlug;
|
|
164
171
|
}
|
|
172
|
+
const numericId = String(phaseNum);
|
|
173
|
+
if (legacyNumericIds.has(numericId)) {
|
|
174
|
+
return numericId;
|
|
175
|
+
}
|
|
165
176
|
return `M${String(phaseNum).padStart(3, "0")}`;
|
|
166
177
|
}
|
|
167
178
|
return null;
|
|
@@ -169,6 +180,24 @@ function scanMilestoneIdsFromDir(dir: string): string[] {
|
|
|
169
180
|
.filter((id): id is string => id !== null);
|
|
170
181
|
}
|
|
171
182
|
|
|
183
|
+
function idsWithLegacyNumericDirs(basePath: string): Set<string> {
|
|
184
|
+
const legacyDir = join(gsdProjectionRoot(basePath), "milestones");
|
|
185
|
+
const ids = new Set<string>();
|
|
186
|
+
try {
|
|
187
|
+
for (const entry of readdirSync(legacyDir, { withFileTypes: true })) {
|
|
188
|
+
if (entry.isDirectory() && /^\d+$/.test(entry.name)) ids.add(entry.name);
|
|
189
|
+
}
|
|
190
|
+
} catch (err) {
|
|
191
|
+
// A missing legacy directory is the common, benign case (nothing to
|
|
192
|
+
// consult). Only surface a real failure when the directory exists but
|
|
193
|
+
// could not be read.
|
|
194
|
+
if (existsSync(legacyDir)) {
|
|
195
|
+
logWarning("engine", `idsWithLegacyNumericDirs: ${legacyDir} exists but readdirSync failed — ${getErrorMessage(err)}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return ids;
|
|
199
|
+
}
|
|
200
|
+
|
|
172
201
|
/** Scan the milestones directory and return IDs sorted by queue order (or numeric fallback). */
|
|
173
202
|
export function findMilestoneIds(basePath: string): string[] {
|
|
174
203
|
const root = gsdProjectionRoot(basePath);
|
|
@@ -181,7 +210,7 @@ export function findMilestoneIds(basePath: string): string[] {
|
|
|
181
210
|
const ids = new Set<string>();
|
|
182
211
|
for (const dir of dirs) {
|
|
183
212
|
try {
|
|
184
|
-
for (const id of scanMilestoneIdsFromDir(dir)) ids.add(id);
|
|
213
|
+
for (const id of scanMilestoneIdsFromDir(basePath, dir)) ids.add(id);
|
|
185
214
|
} catch (err) {
|
|
186
215
|
if (existsSync(dir)) {
|
|
187
216
|
logWarning("engine", `findMilestoneIds: ${dir} exists but readdirSync failed — ${getErrorMessage(err)}`);
|
|
@@ -24,11 +24,10 @@ export interface DynamicRoutingConfig {
|
|
|
24
24
|
cross_provider?: boolean; // default: true
|
|
25
25
|
hooks?: boolean; // default: true
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
28
|
-
* GitHub Copilot).
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* subscription (e.g. haiku for research, opus for architecture). (#4386)
|
|
27
|
+
* Override dynamic routing for flat-rate providers (e.g. claude-code,
|
|
28
|
+
* GitHub Copilot). Omit or set true to honor `dynamic_routing.enabled`;
|
|
29
|
+
* set false to preserve one-model dispatch when the subscription makes
|
|
30
|
+
* per-request cost identical.
|
|
32
31
|
*/
|
|
33
32
|
allow_flat_rate_providers?: boolean;
|
|
34
33
|
}
|
|
@@ -33,16 +33,87 @@ function _isAlreadyRestoredApplyError(err: unknown): boolean {
|
|
|
33
33
|
|
|
34
34
|
export { _isAlreadyRestoredApplyError };
|
|
35
35
|
|
|
36
|
+
function gitOutput(basePath: string, args: string[]): string {
|
|
37
|
+
return execFileSync("git", args, {
|
|
38
|
+
cwd: basePath,
|
|
39
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
40
|
+
encoding: "utf-8",
|
|
41
|
+
env: GIT_NO_PROMPT_ENV,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function listStashUntrackedPaths(basePath: string, stashRef: string): string[] | null {
|
|
46
|
+
try {
|
|
47
|
+
return gitOutput(basePath, ["ls-tree", "-r", "-z", "--name-only", `${stashRef}^3`]).split("\0").filter(Boolean);
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function listStashTrackedPaths(basePath: string, stashRef: string): string[] | null {
|
|
54
|
+
try {
|
|
55
|
+
return gitOutput(basePath, ["diff", "--name-only", "-z", `${stashRef}^1`, stashRef]).split("\0").filter(Boolean);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface PorcelainEntry {
|
|
62
|
+
code: string;
|
|
63
|
+
path: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function readWorkingTreeStatus(basePath: string): PorcelainEntry[] | null {
|
|
67
|
+
try {
|
|
68
|
+
return gitOutput(basePath, ["status", "--porcelain", "-z", "--untracked-files=all"])
|
|
69
|
+
.split("\0")
|
|
70
|
+
.filter(Boolean)
|
|
71
|
+
.map((entry) => ({ code: entry.slice(0, 2), path: entry.slice(3) }));
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isAlreadyRestoredUntrackedStatus(basePath: string, stashRef: string, statusEntries: PorcelainEntry[]): boolean {
|
|
78
|
+
if (statusEntries.length === 0 || statusEntries.some((entry) => entry.code !== "??")) return false;
|
|
79
|
+
const stashTrackedPaths = listStashTrackedPaths(basePath, stashRef);
|
|
80
|
+
if (!stashTrackedPaths || stashTrackedPaths.length > 0) return false;
|
|
81
|
+
const stashUntrackedPaths = listStashUntrackedPaths(basePath, stashRef);
|
|
82
|
+
if (!stashUntrackedPaths || stashUntrackedPaths.length === 0) return false;
|
|
83
|
+
const stashUntrackedPathSet = new Set(stashUntrackedPaths);
|
|
84
|
+
const workingTreeUntrackedPathSet = new Set(statusEntries.map((entry) => entry.path));
|
|
85
|
+
// "Already restored" requires the working tree's untracked paths to match the
|
|
86
|
+
// stash's untracked paths exactly, in BOTH directions:
|
|
87
|
+
// 1. every current untracked path comes from the stash (no unexplained user
|
|
88
|
+
// work that an apply would clobber), AND
|
|
89
|
+
// 2. every stash untracked path is already present in the working tree.
|
|
90
|
+
// Without (2), a partial restore (where only some stash files were recovered)
|
|
91
|
+
// would be misread as fully restored: the audit would no-op without applying
|
|
92
|
+
// or warning, leaving the remaining pre-merge files missing.
|
|
93
|
+
return (
|
|
94
|
+
statusEntries.every((entry) => stashUntrackedPathSet.has(entry.path)) &&
|
|
95
|
+
stashUntrackedPaths.every((path) => workingTreeUntrackedPathSet.has(path))
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function manualApplyWarning(stashRef: string, milestoneId: string, reason: string): string {
|
|
100
|
+
return (
|
|
101
|
+
`Pre-merge stash ${stashRef} for milestone ${milestoneId} not auto-applied: ${reason}; ` +
|
|
102
|
+
`run \`git stash apply ${stashRef}\` manually to restore your pre-merge changes.`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
36
106
|
/**
|
|
37
107
|
* Audit `git stash list` for orphaned `gsd-preflight-stash:M00x:*` entries.
|
|
38
108
|
*
|
|
39
109
|
* The matching merge code in `phases.ts` previously skipped the postflight
|
|
40
110
|
* pop whenever `mergeAndExit` threw, leaking the user's pre-merge working
|
|
41
|
-
* tree into the stash list.
|
|
42
|
-
*
|
|
111
|
+
* tree into the stash list. Completed-milestone stashes are only auto-applied
|
|
112
|
+
* when the working tree is clean and the stash does not modify tracked files.
|
|
113
|
+
* Dirty trees and tracked-file stashes are left untouched with a manual
|
|
114
|
+
* recovery warning. When auto-apply is safe, `git stash apply` is invoked —
|
|
43
115
|
* NOT `pop`. The stash entry stays in the list so the user retains a backup
|
|
44
|
-
* if the apply produces unexpected merge results.
|
|
45
|
-
* startup runs.
|
|
116
|
+
* if the apply produces unexpected merge results.
|
|
46
117
|
*
|
|
47
118
|
* Failures are best-effort: a list error (no repo, git unavailable) returns
|
|
48
119
|
* an empty result. An apply error becomes a warning the user sees alongside
|
|
@@ -56,16 +127,7 @@ export function auditOrphanedPreflightStashes(
|
|
|
56
127
|
|
|
57
128
|
let listOutput: string;
|
|
58
129
|
try {
|
|
59
|
-
listOutput =
|
|
60
|
-
"git",
|
|
61
|
-
["stash", "list", "--format=%gd%x00%s"],
|
|
62
|
-
{
|
|
63
|
-
cwd: basePath,
|
|
64
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
65
|
-
encoding: "utf-8",
|
|
66
|
-
env: GIT_NO_PROMPT_ENV,
|
|
67
|
-
},
|
|
68
|
-
);
|
|
130
|
+
listOutput = gitOutput(basePath, ["stash", "list", "--format=%gd%x00%s"]);
|
|
69
131
|
} catch {
|
|
70
132
|
return result;
|
|
71
133
|
}
|
|
@@ -93,13 +155,39 @@ export function auditOrphanedPreflightStashes(
|
|
|
93
155
|
}
|
|
94
156
|
if (!complete) continue;
|
|
95
157
|
|
|
158
|
+
const statusEntries = readWorkingTreeStatus(basePath);
|
|
159
|
+
if (!statusEntries) {
|
|
160
|
+
result.warnings.push(
|
|
161
|
+
manualApplyWarning(ref, milestoneId, "could not verify working tree status"),
|
|
162
|
+
);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (statusEntries.length > 0) {
|
|
166
|
+
if (isAlreadyRestoredUntrackedStatus(basePath, ref, statusEntries)) continue;
|
|
167
|
+
result.warnings.push(manualApplyWarning(ref, milestoneId, "working tree not clean"));
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const trackedPaths = listStashTrackedPaths(basePath, ref);
|
|
172
|
+
if (trackedPaths === null) {
|
|
173
|
+
result.warnings.push(
|
|
174
|
+
manualApplyWarning(ref, milestoneId, "could not inspect tracked paths in stash"),
|
|
175
|
+
);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (trackedPaths.length > 0) {
|
|
179
|
+
// A retained tracked-file stash has no durable marker showing whether a
|
|
180
|
+
// clean tree needs first recovery or would be re-mutated by an old backup.
|
|
181
|
+
const preview = trackedPaths.slice(0, 5).join(", ");
|
|
182
|
+
const suffix = trackedPaths.length > 5 ? `, and ${trackedPaths.length - 5} more` : "";
|
|
183
|
+
result.warnings.push(
|
|
184
|
+
manualApplyWarning(ref, milestoneId, `stash modifies tracked files (${preview}${suffix})`),
|
|
185
|
+
);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
|
|
96
189
|
try {
|
|
97
|
-
|
|
98
|
-
cwd: basePath,
|
|
99
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
100
|
-
encoding: "utf-8",
|
|
101
|
-
env: GIT_NO_PROMPT_ENV,
|
|
102
|
-
});
|
|
190
|
+
gitOutput(basePath, ["stash", "apply", "--quiet", ref]);
|
|
103
191
|
result.applied.push({ milestoneId, stashRef: ref });
|
|
104
192
|
} catch (err) {
|
|
105
193
|
// Idempotent steady state: stash was already applied in a prior audit
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { PreferenceDiagnostic } from "./preferences-types.js";
|
|
2
2
|
import {
|
|
3
|
+
loadEffectiveGSDPreferences,
|
|
3
4
|
loadGlobalGSDPreferences,
|
|
4
5
|
loadProjectGSDPreferences,
|
|
5
6
|
} from "./preferences.js";
|
|
7
|
+
import { crossAxisPreferenceWarnings } from "./preferences-validation.js";
|
|
6
8
|
|
|
7
9
|
interface PreferenceNotificationContext {
|
|
8
10
|
ui: {
|
|
@@ -30,6 +32,28 @@ export function collectPreferenceDiagnostics(basePath?: string): PreferenceDiagn
|
|
|
30
32
|
seen.add(signature);
|
|
31
33
|
unique.push(diagnostic);
|
|
32
34
|
}
|
|
35
|
+
|
|
36
|
+
const effective = loadEffectiveGSDPreferences(basePath);
|
|
37
|
+
if (effective) {
|
|
38
|
+
const existingMessages = new Set(unique.map((diagnostic) => diagnostic.message));
|
|
39
|
+
for (const message of crossAxisPreferenceWarnings(effective.preferences)) {
|
|
40
|
+
if (existingMessages.has(message)) continue;
|
|
41
|
+
const diagnostic: PreferenceDiagnostic = {
|
|
42
|
+
path: effective.path,
|
|
43
|
+
scope: effective.scope,
|
|
44
|
+
severity: "warning",
|
|
45
|
+
kind: "validation",
|
|
46
|
+
message,
|
|
47
|
+
sanitized: true,
|
|
48
|
+
};
|
|
49
|
+
const signature = preferenceDiagnosticSignature(diagnostic);
|
|
50
|
+
if (seen.has(signature)) continue;
|
|
51
|
+
seen.add(signature);
|
|
52
|
+
existingMessages.add(message);
|
|
53
|
+
unique.push(diagnostic);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
33
57
|
return unique;
|
|
34
58
|
}
|
|
35
59
|
|
|
@@ -99,10 +99,13 @@ export function resolveModelWithFallbacksForUnit(
|
|
|
99
99
|
basePath?: string,
|
|
100
100
|
availableModelIds?: string[],
|
|
101
101
|
preferredModelId?: string,
|
|
102
|
+
skipProfileDefaults = false,
|
|
102
103
|
): ResolvedModelConfig | undefined {
|
|
103
|
-
const loadOpts =
|
|
104
|
-
? { availableModelIds
|
|
105
|
-
:
|
|
104
|
+
const loadOpts = {
|
|
105
|
+
...(availableModelIds !== undefined ? { availableModelIds } : {}),
|
|
106
|
+
...(preferredModelId !== undefined ? { preferredModelId } : {}),
|
|
107
|
+
...(skipProfileDefaults ? { skipProfileDefaults: true } : {}),
|
|
108
|
+
};
|
|
106
109
|
const prefs = loadEffectiveGSDPreferences(basePath, loadOpts);
|
|
107
110
|
const chain = phaseChainForUnit(unitType);
|
|
108
111
|
if (!chain) return undefined;
|
|
@@ -51,6 +51,16 @@ const VALID_POST_UNIT_HOOK_ON_BLOCK_ACTIONS = new Set([
|
|
|
51
51
|
]);
|
|
52
52
|
const VALID_GATE_EVALUATE_SLICE_GATES = new Set<string>(getGateIdsForTurn("gate-evaluate"));
|
|
53
53
|
|
|
54
|
+
/** Cross-axis warnings that only apply to the effective (merged) preference shape. */
|
|
55
|
+
export function crossAxisPreferenceWarnings(preferences: GSDPreferences): string[] {
|
|
56
|
+
if (preferences.mode === "team" && preferences.workspace?.mode === "parent") {
|
|
57
|
+
return [
|
|
58
|
+
"mode:team + workspace.mode:parent: team branch-push/PR resolves at the project root and will not push child repositories — see docs/dev/ADR-044",
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
export function validatePreferences(preferences: GSDPreferences): {
|
|
55
65
|
preferences: GSDPreferences;
|
|
56
66
|
errors: string[];
|
|
@@ -509,8 +519,11 @@ export function validatePreferences(preferences: GSDPreferences): {
|
|
|
509
519
|
|
|
510
520
|
// ─── Remote Questions ───────────────────────────────────────────────
|
|
511
521
|
if (preferences.remote_questions !== undefined) {
|
|
512
|
-
|
|
513
|
-
|
|
522
|
+
const remoteQuestions = preferences.remote_questions as unknown;
|
|
523
|
+
if (typeof remoteQuestions === "object" && remoteQuestions !== null) {
|
|
524
|
+
validated.remote_questions = remoteQuestions as GSDPreferences["remote_questions"];
|
|
525
|
+
} else if (remoteQuestions === false) {
|
|
526
|
+
// Explicit disable for a globally-configured remote questions channel.
|
|
514
527
|
} else {
|
|
515
528
|
errors.push("remote_questions must be an object");
|
|
516
529
|
}
|
|
@@ -1495,6 +1508,17 @@ export function validatePreferences(preferences: GSDPreferences): {
|
|
|
1495
1508
|
} else {
|
|
1496
1509
|
errors.push("workspace must be an object");
|
|
1497
1510
|
}
|
|
1511
|
+
|
|
1512
|
+
// parent mode is behavioral: it must coordinate at least one declared
|
|
1513
|
+
// child repository. Without one it is indistinguishable from project
|
|
1514
|
+
// mode, so reject it explicitly rather than silently degrading.
|
|
1515
|
+
if (validated.workspace?.mode === "parent") {
|
|
1516
|
+
const childRepoCount = validated.workspace.repositories ? Object.keys(validated.workspace.repositories).length : 0;
|
|
1517
|
+
if (childRepoCount === 0) {
|
|
1518
|
+
errors.push('workspace.mode "parent" requires at least one repository under workspace.repositories');
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1498
1522
|
}
|
|
1499
1523
|
|
|
1500
1524
|
// ─── Enhanced Verification ──────────────────────────────────────────────────
|
|
@@ -1568,5 +1592,7 @@ export function validatePreferences(preferences: GSDPreferences): {
|
|
|
1568
1592
|
}
|
|
1569
1593
|
}
|
|
1570
1594
|
|
|
1595
|
+
warnings.push(...crossAxisPreferenceWarnings(validated));
|
|
1596
|
+
|
|
1571
1597
|
return { preferences: validated, errors, warnings };
|
|
1572
1598
|
}
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
type SkillDiscoveryMode,
|
|
40
40
|
formatSkillRef,
|
|
41
41
|
} from "./preferences-types.js";
|
|
42
|
-
import { validatePreferences } from "./preferences-validation.js";
|
|
42
|
+
import { crossAxisPreferenceWarnings, validatePreferences } from "./preferences-validation.js";
|
|
43
43
|
import { gsdHome } from "./gsd-home.js";
|
|
44
44
|
|
|
45
45
|
// ─── Re-exports: types ──────────────────────────────────────────────────────
|
|
@@ -270,6 +270,12 @@ export function normalizePreferencesShape(
|
|
|
270
270
|
const EFFECTIVE_PREFERENCES_CACHE_MAX = 64;
|
|
271
271
|
const effectivePreferencesCache = new Map<string, LoadedGSDPreferences | null>();
|
|
272
272
|
|
|
273
|
+
type EffectivePreferencesLoadOptions = {
|
|
274
|
+
availableModelIds?: string[];
|
|
275
|
+
preferredModelId?: string;
|
|
276
|
+
skipProfileDefaults?: boolean;
|
|
277
|
+
};
|
|
278
|
+
|
|
273
279
|
export function clearGSDPreferencesCache(): void {
|
|
274
280
|
effectivePreferencesCache.clear();
|
|
275
281
|
}
|
|
@@ -301,7 +307,7 @@ function preferencesFileSignature(path: string): string {
|
|
|
301
307
|
|
|
302
308
|
function effectivePreferencesCacheKey(
|
|
303
309
|
basePath?: string,
|
|
304
|
-
opts?:
|
|
310
|
+
opts?: EffectivePreferencesLoadOptions,
|
|
305
311
|
): string {
|
|
306
312
|
return JSON.stringify({
|
|
307
313
|
basePath: basePath ?? null,
|
|
@@ -309,6 +315,7 @@ function effectivePreferencesCacheKey(
|
|
|
309
315
|
project: projectPreferencesCandidatePaths(basePath).map(preferencesFileSignature),
|
|
310
316
|
availableModelIds: opts?.availableModelIds ?? null,
|
|
311
317
|
preferredModelId: opts?.preferredModelId ?? null,
|
|
318
|
+
skipProfileDefaults: opts?.skipProfileDefaults === true,
|
|
312
319
|
});
|
|
313
320
|
}
|
|
314
321
|
|
|
@@ -338,7 +345,7 @@ export function loadProjectGSDPreferences(basePath?: string): LoadedGSDPreferenc
|
|
|
338
345
|
|
|
339
346
|
export function loadEffectiveGSDPreferences(
|
|
340
347
|
basePath?: string,
|
|
341
|
-
opts?:
|
|
348
|
+
opts?: EffectivePreferencesLoadOptions,
|
|
342
349
|
): LoadedGSDPreferences | null {
|
|
343
350
|
const cacheKey = effectivePreferencesCacheKey(basePath, opts);
|
|
344
351
|
if (effectivePreferencesCache.has(cacheKey)) {
|
|
@@ -384,7 +391,7 @@ export function loadEffectiveGSDPreferences(
|
|
|
384
391
|
} else {
|
|
385
392
|
profileForDefaults = DEFAULT_TOKEN_PROFILE;
|
|
386
393
|
}
|
|
387
|
-
if (profileForDefaults) {
|
|
394
|
+
if (profileForDefaults && !opts?.skipProfileDefaults) {
|
|
388
395
|
const profileDefaults = _resolveProfileDefaults(
|
|
389
396
|
profileForDefaults,
|
|
390
397
|
opts?.availableModelIds,
|
|
@@ -409,11 +416,38 @@ export function loadEffectiveGSDPreferences(
|
|
|
409
416
|
}
|
|
410
417
|
|
|
411
418
|
result = stripInheritedPlanningDepth(result, projectHasPlanningDepth);
|
|
419
|
+
result = appendCrossAxisPreferenceWarnings(result);
|
|
412
420
|
|
|
413
421
|
cacheEffectivePreferences(cacheKey, result);
|
|
414
422
|
return result;
|
|
415
423
|
}
|
|
416
424
|
|
|
425
|
+
function appendCrossAxisPreferenceWarnings(loaded: LoadedGSDPreferences): LoadedGSDPreferences {
|
|
426
|
+
const crossWarnings = crossAxisPreferenceWarnings(loaded.preferences);
|
|
427
|
+
const existingMessages = new Set([
|
|
428
|
+
...(loaded.warnings ?? []),
|
|
429
|
+
...(loaded.diagnostics ?? []).map((diagnostic) => diagnostic.message),
|
|
430
|
+
]);
|
|
431
|
+
const newWarnings = crossWarnings.filter((message) => !existingMessages.has(message));
|
|
432
|
+
if (newWarnings.length === 0) return loaded;
|
|
433
|
+
|
|
434
|
+
return {
|
|
435
|
+
...loaded,
|
|
436
|
+
warnings: [...(loaded.warnings ?? []), ...newWarnings],
|
|
437
|
+
diagnostics: [
|
|
438
|
+
...(loaded.diagnostics ?? []),
|
|
439
|
+
...newWarnings.map((message): PreferenceDiagnostic => ({
|
|
440
|
+
path: loaded.path,
|
|
441
|
+
scope: loaded.scope,
|
|
442
|
+
severity: "warning",
|
|
443
|
+
kind: "validation",
|
|
444
|
+
message,
|
|
445
|
+
sanitized: true,
|
|
446
|
+
})),
|
|
447
|
+
],
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
417
451
|
function withoutProfilePhaseDefaults(defaults: Partial<GSDPreferences>): Partial<GSDPreferences> {
|
|
418
452
|
if (defaults.phases === undefined) return defaults;
|
|
419
453
|
const { phases: _phases, ...rest } = defaults;
|
|
@@ -16,18 +16,20 @@ You are running the GSD **code-review** workflow — review source files changed
|
|
|
16
16
|
|
|
17
17
|
1. **Determine the file set.** Use the explicit `--files` list if provided. Otherwise derive the changed source files from the active slice's recent commits / SUMMARY, or fall back to the git diff against the base branch. Exclude `.gsd/`, lockfiles, generated/vendored code, and docs unless `--files` names them.
|
|
18
18
|
|
|
19
|
-
2. **
|
|
19
|
+
2. **Gather diff-first context.** Run `git diff` for the file set (or the relevant commit range) and use that as the primary review evidence. Use `read` only when the diff is insufficient — new/untracked files, truncated hunks, or missing surrounding context needed for a finding. Do **not** read every changed file when the diff already covers the edits. If the Tool Call Loop Guard blocks a tool, stop calling tools for the rest of this turn and continue in text.
|
|
20
|
+
|
|
21
|
+
3. **Review at the requested depth:**
|
|
20
22
|
- **quick** — bugs, security, and correctness only.
|
|
21
23
|
- **standard** (default) — quick + maintainability, error handling, edge cases.
|
|
22
24
|
- **deep** — standard + performance, concurrency, API design, test coverage gaps.
|
|
23
25
|
|
|
24
26
|
Ground every finding in the actual code with file path + line reference. Categorize each by severity (critical / warning / nit) and type (bug, security, quality, performance).
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
4. **Write the review.** Produce `.gsd/reviews/{{reviewId}}-REVIEW.md` with the findings table and per-finding detail (location, issue, suggested fix).
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
5. **Present results.** Summarize counts by severity and list the critical findings first.
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
6. **Fix mode** (only when `--fix` is set): for each finding that is safely auto-fixable (deterministic, no behavior change beyond the fix), apply it. After each fix batch, run the project's tests. Commit atomically with the finding IDs referenced in the message. Do not auto-apply findings that are ambiguous or that change public behavior — surface those for a human decision instead.
|
|
31
33
|
|
|
32
34
|
## Success criteria
|
|
33
35
|
|
|
@@ -104,8 +104,8 @@ If the preference is off, ignore this section and plan every slice fully.
|
|
|
104
104
|
|
|
105
105
|
If the roadmap has one slice, also plan S01 and its tasks inline:
|
|
106
106
|
|
|
107
|
-
1. After `gsd_plan_milestone` returns, call `gsd_plan_slice` for S01 with
|
|
108
|
-
2. Use inlined **Slice Plan** and **Task Plan** templates for tool parameters.
|
|
107
|
+
1. After `gsd_plan_milestone` returns, call `gsd_plan_slice` for S01 with slice metadata only; omit `tasks`.
|
|
108
|
+
2. Then call `gsd_plan_task` once per S01 task. Use inlined **Slice Plan** and **Task Plan** templates for tool parameters.
|
|
109
109
|
3. Keep simple slices lean. Omit Proof Level, Integration Closure, and Observability if all would be "none"; executable verification commands are enough.
|
|
110
110
|
|
|
111
111
|
Do **not** write plan files manually; use DB-backed tools so state stays consistent.
|
|
@@ -32,6 +32,8 @@ Before planning, validate roadmap assumptions against code and dependency summar
|
|
|
32
32
|
|
|
33
33
|
If slice research is inlined, trust its architectural findings, but verify every concrete file path you place in task `inputs` or `expectedOutput` against the current tree or prior/same-task outputs. Explore enough code to confirm paths, boundaries, and verification. Executors later get only task plans, slice excerpt, and prior summaries, so put required paths, steps, inputs, and outputs in task plans.
|
|
34
34
|
|
|
35
|
+
{{repoRegistry}}
|
|
36
|
+
|
|
35
37
|
{{executorContextConstraints}}
|
|
36
38
|
|
|
37
39
|
## Planning Rules
|
|
@@ -45,8 +47,8 @@ If slice research is inlined, trust its architectural findings, but verify every
|
|
|
45
47
|
6. Include Threat Surface (Q3), Requirement Impact (Q4), proof level, observability, integration closure, Failure Modes (Q5), Load Profile (Q6), and Negative Tests (Q7) only where applicable.
|
|
46
48
|
7. Right-size tasks. Simple slices can be one task; split only when context, ownership, or verification boundaries justify it.
|
|
47
49
|
8. Task `verify` commands must be safe, simple commands. Do not use shell pipes, redirects, semicolons, backticks, command substitution, output trimming, or grep regex alternation with `|`. If multiple checks are needed, create a small test file and run it with `node --test` or a package test script, or use separate simple commands joined only with `&&`. For absence checks, verify a pattern does not exist with `! grep -q 'pattern' file` or `! rg -q 'pattern' file`; do not use `grep -c` or `rg -c` to assert zero matches because count commands exit 1 when they find zero matches, and the verification gate treats that as failure.
|
|
48
|
-
9. Each task needs the exact
|
|
49
|
-
10. Persist
|
|
50
|
+
9. Each task persisted with `gsd_plan_task` needs the exact shape: `milestoneId`, `sliceId`, `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. In a parent workspace (when a Declared Repositories block is present above), also set `targetRepositories` to the repository id(s) the task touches. `description` should contain the Why / Do / Done-when narrative. Any npm package name in a task description's install/add instructions (`npm install`, `yarn add`, `pnpm add`) or in `require('...')` or `import ... from '...'` code examples is subject to pre-execution registry validation; reference only packages that exist on the public npm registry, and remove or correct any package name that is not real. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, tests, or describes — those belong in `inputs`, `verify`, `description`, or slice success criteria. If a task is a pure verification or test task that produces no new files, `expectedOutput` must be `[]`; if it writes a test-result log or assertion output file, list only that concrete file path. A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
|
|
51
|
+
10. Persist incrementally through DB-backed tools. First call `gsd_plan_slice` with `milestoneId`, `sliceId`, `goal`, and optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact` (and `targetRepositories` in a parent workspace, to set the slice-wide default); omit `tasks` for this metadata call. Then call `gsd_plan_task` once per task, using the task shape above. Each successful tool call saves progress and re-renders `{{outputPath}}` from DB. The DB-backed tools are the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
|
|
50
52
|
11. Self-audit before finishing: goal/demo closure, requirement coverage, deliverable coverage audit (cross-check every file listed in CONTEXT.md `## Scope` / `### In Scope` against task `files` or `expectedOutput`), locked decisions, concrete paths, dependency order, wiring, scope size, proof truthfulness, feature completeness, and quality gates. Quality gates: non-trivial slices/tasks include specific Q3-Q7 coverage where applicable.
|
|
51
53
|
12. If planning creates structural decisions, call `gsd_decision_save` for each; the tool persists the decision and regenerates `.gsd/DECISIONS.md`.
|
|
52
54
|
13. {{commitInstruction}}
|
|
@@ -55,6 +57,6 @@ The slice directory already exists. Do not mkdir.
|
|
|
55
57
|
|
|
56
58
|
**Autonomous execution:** no human is available. Do not call `ask_user_questions` or `secure_env_collect`; make reasonable assumptions and document them.
|
|
57
59
|
|
|
58
|
-
**You MUST call `gsd_plan_slice`
|
|
60
|
+
**You MUST call `gsd_plan_slice` and then `gsd_plan_task` once for each planned task before finishing, unless the stale-path safety rule above stops the unit before safe planning can occur.**
|
|
59
61
|
|
|
60
62
|
When done, say: "Slice {{sliceId}} planned." Say this exactly once — if you already said it in a prior message, do not repeat it.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// redact-secrets.ts
|
|
2
|
+
// Best-effort redaction of secret-shaped substrings before persisting free text
|
|
3
|
+
// (exec-sandbox output, activity-log session entries) to disk under .gsd/, which
|
|
4
|
+
// the secret scanner skips. Patterns mirror scripts/secret-scan.mjs.
|
|
5
|
+
|
|
6
|
+
const PLACEHOLDER = "«redacted»";
|
|
7
|
+
|
|
8
|
+
// Each secret shape. Global flag so replace() catches every occurrence in a line.
|
|
9
|
+
// Order is not significant — matches are replaced independently.
|
|
10
|
+
const PATTERNS: RegExp[] = [
|
|
11
|
+
/AKIA[0-9A-Z]{16}/g, // AWS access key id
|
|
12
|
+
/(api[_-]?key|apikey|api[_-]?secret)[ \t]*[:=][ \t]*['"][0-9a-zA-Z_./-]{20,}['"]/gi,
|
|
13
|
+
/(secret|token|password|passwd|pwd|credential)[ \t]*[:=][ \t]*['"][^\s'"]{8,}['"]/gi,
|
|
14
|
+
/(authorization|bearer)[ \t]*[:=][ \t]*['"][^\s'"]{8,}['"]/gi,
|
|
15
|
+
/Bearer[ \t]+[0-9a-zA-Z._-]{8,}/g, // Authorization: Bearer <token> (unquoted)
|
|
16
|
+
/-----BEGIN\s+(RSA|DSA|EC|OPENSSH|PGP)\s+PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA|DSA|EC|OPENSSH|PGP)\s+PRIVATE\s+KEY-----/g,
|
|
17
|
+
/(mysql|postgres|postgresql|mongodb|redis|amqp|mssql):\/\/[^\s'"]{8,}/gi,
|
|
18
|
+
/gh[pousr]_[0-9a-zA-Z]{36,}/g, // GitHub token
|
|
19
|
+
/glpat-[0-9a-zA-Z-]{20,}/g, // GitLab token
|
|
20
|
+
/xox[baprs]-[0-9a-zA-Z-]{10,}/g, // Slack token
|
|
21
|
+
/hooks\.slack\.com\/services\/T[0-9A-Z]{8,}\/B[0-9A-Z]{8,}\/[0-9a-zA-Z]{20,}/g,
|
|
22
|
+
/AIza[0-9A-Za-z_-]{35}/g, // Google API key
|
|
23
|
+
/[sr]k_(live|test)_[0-9a-zA-Z]{20,}/g, // Stripe key
|
|
24
|
+
/sk-(ant-)?[0-9a-zA-Z_-]{20,}/g, // OpenAI / Anthropic style key
|
|
25
|
+
/npm_[0-9a-zA-Z]{36,}/g, // npm token
|
|
26
|
+
/(secret|key|token|password)[ \t]*[:=][ \t]*['"]?[0-9a-f]{32,}['"]?/gi, // hex secret
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Replace secret-shaped substrings in `text` with a placeholder, preserving the
|
|
31
|
+
* surrounding content. Pure and safe to call per log line. The placeholder
|
|
32
|
+
* contains no quote/brace/backslash, so redacting a JSON string keeps it valid.
|
|
33
|
+
*/
|
|
34
|
+
export function redactSecrets(text: string): string {
|
|
35
|
+
let out = text;
|
|
36
|
+
for (const pattern of PATTERNS) {
|
|
37
|
+
out = out.replace(pattern, PLACEHOLDER);
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
@@ -23,6 +23,12 @@ export interface RepositoryRegistry {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function defaultRepositoryTargets(registry: RepositoryRegistry): string[] {
|
|
26
|
+
// In parent mode, default to the declared child repositories so work is
|
|
27
|
+
// attributed to the repo it touches — not silently to the root "project".
|
|
28
|
+
if (registry.mode === "parent") {
|
|
29
|
+
return registry.repositories.filter((repo) => repo.id !== "project").map((repo) => repo.id);
|
|
30
|
+
}
|
|
31
|
+
|
|
26
32
|
const project = registry.byId.get("project");
|
|
27
33
|
if (project) return [project.id];
|
|
28
34
|
const first = registry.repositories[0];
|
|
@@ -78,7 +84,7 @@ export function createRepositoryRegistry(
|
|
|
78
84
|
): RepositoryRegistry {
|
|
79
85
|
const contract = resolveGsdPathContract(basePath);
|
|
80
86
|
const projectRoot = contract.isWorktree
|
|
81
|
-
? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.
|
|
87
|
+
? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.workRoot
|
|
82
88
|
: contract.projectRoot;
|
|
83
89
|
const mode = workspacePrefs?.mode ?? "project";
|
|
84
90
|
const repoMap = new Map<string, RegisteredRepository>();
|
|
@@ -5,8 +5,18 @@ import { execFileSync } from "node:child_process";
|
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
+
import { GSD_RUNTIME_PATTERNS } from "./gitignore.js";
|
|
8
9
|
|
|
9
10
|
const MAX_SYNC_FINGERPRINT_BYTES = 1_500_000_000;
|
|
11
|
+
const ROOT_RUNTIME_PATH_PREFIXES = Array.from(
|
|
12
|
+
new Set(
|
|
13
|
+
GSD_RUNTIME_PATTERNS.map((pattern) => {
|
|
14
|
+
const path = pattern.replace(/\/+$/, "");
|
|
15
|
+
const slash = path.indexOf("/");
|
|
16
|
+
return slash === -1 ? path : path.slice(0, slash);
|
|
17
|
+
}),
|
|
18
|
+
),
|
|
19
|
+
);
|
|
10
20
|
|
|
11
21
|
export interface RootDirtyEntry {
|
|
12
22
|
path: string;
|
|
@@ -25,7 +35,9 @@ export interface RootWriteLeak {
|
|
|
25
35
|
export type RootDirtySnapshot = Map<string, RootDirtyEntry>;
|
|
26
36
|
|
|
27
37
|
function isRootRuntimePath(path: string): boolean {
|
|
28
|
-
return
|
|
38
|
+
return ROOT_RUNTIME_PATH_PREFIXES.some(
|
|
39
|
+
(prefix) => path === prefix || path.startsWith(`${prefix}/`),
|
|
40
|
+
);
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
function fileFingerprint(rootPath: string, relPath: string): string {
|