@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
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
getMilestoneSlices,
|
|
23
23
|
getSliceTasks,
|
|
24
24
|
updateSliceStatus,
|
|
25
|
+
insertGateRow,
|
|
26
|
+
saveGateResult,
|
|
25
27
|
_getAdapter,
|
|
26
28
|
} from '../gsd-db.ts';
|
|
27
29
|
import {
|
|
@@ -44,6 +46,7 @@ import {
|
|
|
44
46
|
parseSummary,
|
|
45
47
|
parseTaskPlanFile,
|
|
46
48
|
clearParseCache,
|
|
49
|
+
extractSection,
|
|
47
50
|
} from '../files.ts';
|
|
48
51
|
import { clearPathCache, _clearGsdRootCache } from '../paths.ts';
|
|
49
52
|
import { invalidateStateCache } from '../state.ts';
|
|
@@ -645,6 +648,125 @@ test('── markdown-renderer: slice plan summarizes task descriptions without
|
|
|
645
648
|
}
|
|
646
649
|
});
|
|
647
650
|
|
|
651
|
+
test('── markdown-renderer: renderPlanFromDb marks flagged slice gates ──', async () => {
|
|
652
|
+
const tmpDir = makeTmpDir();
|
|
653
|
+
const dbPath = path.join(tmpDir, '.gsd', 'gsd.db');
|
|
654
|
+
openDatabase(dbPath);
|
|
655
|
+
clearAllCaches();
|
|
656
|
+
|
|
657
|
+
try {
|
|
658
|
+
insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
|
|
659
|
+
scaffoldDirs(tmpDir, 'M001', ['S01']);
|
|
660
|
+
insertSlice({
|
|
661
|
+
id: 'S01',
|
|
662
|
+
milestoneId: 'M001',
|
|
663
|
+
title: 'Risky slice',
|
|
664
|
+
status: 'pending',
|
|
665
|
+
demo: 'Reviewers can see flagged gates.',
|
|
666
|
+
planning: {
|
|
667
|
+
goal: 'Persist gate concern state.',
|
|
668
|
+
successCriteria: '- Flagged gates stay visible',
|
|
669
|
+
},
|
|
670
|
+
});
|
|
671
|
+
insertTask({
|
|
672
|
+
id: 'T01',
|
|
673
|
+
sliceId: 'S01',
|
|
674
|
+
milestoneId: 'M001',
|
|
675
|
+
title: 'Render gate state',
|
|
676
|
+
status: 'pending',
|
|
677
|
+
});
|
|
678
|
+
insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q3', scope: 'slice' });
|
|
679
|
+
insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q4', scope: 'slice' });
|
|
680
|
+
|
|
681
|
+
const findings = '- Shared gate findings.';
|
|
682
|
+
saveGateResult({
|
|
683
|
+
milestoneId: 'M001',
|
|
684
|
+
sliceId: 'S01',
|
|
685
|
+
gateId: 'Q3',
|
|
686
|
+
verdict: 'flag',
|
|
687
|
+
rationale: 'Concern recorded.',
|
|
688
|
+
findings,
|
|
689
|
+
});
|
|
690
|
+
saveGateResult({
|
|
691
|
+
milestoneId: 'M001',
|
|
692
|
+
sliceId: 'S01',
|
|
693
|
+
gateId: 'Q4',
|
|
694
|
+
verdict: 'pass',
|
|
695
|
+
rationale: 'No concern.',
|
|
696
|
+
findings,
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
const rendered = await renderPlanFromDb(tmpDir, 'M001', 'S01');
|
|
700
|
+
const threatSurface = extractSection(rendered.content, 'Threat Surface');
|
|
701
|
+
const requirementImpact = extractSection(rendered.content, 'Requirement Impact');
|
|
702
|
+
|
|
703
|
+
assert.ok(threatSurface?.includes('> **Warning:** Verdict: flag - concerns recorded below'));
|
|
704
|
+
assert.ok(threatSurface?.includes(findings));
|
|
705
|
+
assert.ok(!requirementImpact?.includes('Verdict: flag'), 'passing gate should not render a flag warning');
|
|
706
|
+
assert.ok(requirementImpact?.includes(findings), 'passing gate still renders findings');
|
|
707
|
+
} finally {
|
|
708
|
+
closeDatabase();
|
|
709
|
+
cleanupDir(tmpDir);
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
test('── markdown-renderer: renderTaskPlanFromDb marks flagged task gates ──', async () => {
|
|
714
|
+
const tmpDir = makeTmpDir();
|
|
715
|
+
const dbPath = path.join(tmpDir, '.gsd', 'gsd.db');
|
|
716
|
+
openDatabase(dbPath);
|
|
717
|
+
clearAllCaches();
|
|
718
|
+
|
|
719
|
+
try {
|
|
720
|
+
insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
|
|
721
|
+
scaffoldDirs(tmpDir, 'M001', ['S01']);
|
|
722
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Slice', status: 'pending' });
|
|
723
|
+
insertTask({
|
|
724
|
+
id: 'T01',
|
|
725
|
+
sliceId: 'S01',
|
|
726
|
+
milestoneId: 'M001',
|
|
727
|
+
title: 'Task gate render',
|
|
728
|
+
status: 'pending',
|
|
729
|
+
planning: {
|
|
730
|
+
description: 'Render task quality gates.',
|
|
731
|
+
},
|
|
732
|
+
});
|
|
733
|
+
insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q5', scope: 'task', taskId: 'T01' });
|
|
734
|
+
insertGateRow({ milestoneId: 'M001', sliceId: 'S01', gateId: 'Q6', scope: 'task', taskId: 'T01' });
|
|
735
|
+
|
|
736
|
+
const findings = '- Same task findings.';
|
|
737
|
+
saveGateResult({
|
|
738
|
+
milestoneId: 'M001',
|
|
739
|
+
sliceId: 'S01',
|
|
740
|
+
taskId: 'T01',
|
|
741
|
+
gateId: 'Q5',
|
|
742
|
+
verdict: 'flag',
|
|
743
|
+
rationale: 'Concern recorded.',
|
|
744
|
+
findings,
|
|
745
|
+
});
|
|
746
|
+
saveGateResult({
|
|
747
|
+
milestoneId: 'M001',
|
|
748
|
+
sliceId: 'S01',
|
|
749
|
+
taskId: 'T01',
|
|
750
|
+
gateId: 'Q6',
|
|
751
|
+
verdict: 'pass',
|
|
752
|
+
rationale: 'No concern.',
|
|
753
|
+
findings,
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
const rendered = await renderTaskPlanFromDb(tmpDir, 'M001', 'S01', 'T01');
|
|
757
|
+
const failureModes = extractSection(rendered.content, 'Failure Modes');
|
|
758
|
+
const loadProfile = extractSection(rendered.content, 'Load Profile');
|
|
759
|
+
|
|
760
|
+
assert.ok(failureModes?.includes('> **Warning:** Verdict: flag - concerns recorded below'));
|
|
761
|
+
assert.ok(failureModes?.includes(findings));
|
|
762
|
+
assert.ok(!loadProfile?.includes('Verdict: flag'), 'passing task gate should not render a flag warning');
|
|
763
|
+
assert.ok(loadProfile?.includes(findings), 'passing task gate still renders findings');
|
|
764
|
+
} finally {
|
|
765
|
+
closeDatabase();
|
|
766
|
+
cleanupDir(tmpDir);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
|
|
648
770
|
test('── markdown-renderer: renderTaskPlanFromDb throws for missing task ──', async () => {
|
|
649
771
|
const tmpDir = makeTmpDir();
|
|
650
772
|
const dbPath = path.join(tmpDir, '.gsd', 'gsd.db');
|
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
SCHEMA_VERSION,
|
|
6
6
|
_getAdapter,
|
|
7
7
|
} from '../gsd-db.ts';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as os from 'node:os';
|
|
8
11
|
import {
|
|
9
12
|
_resetLogs,
|
|
10
13
|
peekLogs,
|
|
@@ -22,6 +25,7 @@ import {
|
|
|
22
25
|
markUnitProcessed,
|
|
23
26
|
decayStaleMemories,
|
|
24
27
|
enforceMemoryCap,
|
|
28
|
+
queryMemoriesRanked,
|
|
25
29
|
applyMemoryActions,
|
|
26
30
|
formatMemoriesForPrompt,
|
|
27
31
|
} from '../memory-store.ts';
|
|
@@ -29,6 +33,16 @@ import type { MemoryAction } from '../memory-store.ts';
|
|
|
29
33
|
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
30
34
|
import assert from 'node:assert/strict';
|
|
31
35
|
|
|
36
|
+
function tempDbPath(): string {
|
|
37
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-memory-store-test-'));
|
|
38
|
+
return path.join(dir, 'test.db');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function cleanupDbPath(dbPath: string): void {
|
|
42
|
+
closeDatabase();
|
|
43
|
+
fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
47
|
// memory-store: fallback when DB not open
|
|
34
48
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -366,6 +380,40 @@ test('memory-store: schema includes memories table', () => {
|
|
|
366
380
|
closeDatabase();
|
|
367
381
|
});
|
|
368
382
|
|
|
383
|
+
test('memory-store: reopening rebuilds FTS index for pre-FTS memories', () => {
|
|
384
|
+
const dbPath = tempDbPath();
|
|
385
|
+
try {
|
|
386
|
+
openDatabase(dbPath);
|
|
387
|
+
const id = createMemory({ category: 'gotcha', content: 'pre FTS auth memory must become searchable' });
|
|
388
|
+
assert.equal(id, 'MEM001');
|
|
389
|
+
|
|
390
|
+
const adapter = _getAdapter()!;
|
|
391
|
+
const fts = adapter.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='memories_fts'").get();
|
|
392
|
+
if (!fts) return;
|
|
393
|
+
|
|
394
|
+
adapter.exec('DROP TRIGGER IF EXISTS memories_ai');
|
|
395
|
+
adapter.exec('DROP TRIGGER IF EXISTS memories_ad');
|
|
396
|
+
adapter.exec('DROP TRIGGER IF EXISTS memories_au');
|
|
397
|
+
adapter.exec('DROP TABLE IF EXISTS memories_fts');
|
|
398
|
+
adapter.prepare(
|
|
399
|
+
"DELETE FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = 'memories_fts_rebuilt_at'",
|
|
400
|
+
).run();
|
|
401
|
+
closeDatabase();
|
|
402
|
+
|
|
403
|
+
openDatabase(dbPath);
|
|
404
|
+
const reopened = _getAdapter()!;
|
|
405
|
+
const marker = reopened.prepare(
|
|
406
|
+
"SELECT value_json FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = 'memories_fts_rebuilt_at'",
|
|
407
|
+
).get();
|
|
408
|
+
assert.ok(marker, 'FTS rebuild marker should be set after reopening');
|
|
409
|
+
|
|
410
|
+
const hits = queryMemoriesRanked({ query: 'auth', k: 5 }).map((hit) => hit.memory.id);
|
|
411
|
+
assert.deepEqual(hits, ['MEM001']);
|
|
412
|
+
} finally {
|
|
413
|
+
cleanupDbPath(dbPath);
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
369
417
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
370
418
|
// regression #4967 — createMemory must not silently swallow SQL errors
|
|
371
419
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -9,7 +9,15 @@ import { tmpdir } from "node:os";
|
|
|
9
9
|
import { execFileSync } from "node:child_process";
|
|
10
10
|
|
|
11
11
|
import { mergeMilestoneToMain } from "../auto-worktree.ts";
|
|
12
|
-
import {
|
|
12
|
+
import { checkCloseoutConsistencyGate } from "../closeout-consistency-gate.ts";
|
|
13
|
+
import {
|
|
14
|
+
closeDatabase,
|
|
15
|
+
insertAssessment,
|
|
16
|
+
insertMilestone,
|
|
17
|
+
insertSlice,
|
|
18
|
+
insertTask,
|
|
19
|
+
openDatabase,
|
|
20
|
+
} from "../gsd-db.ts";
|
|
13
21
|
|
|
14
22
|
function git(args: string[], cwd: string): string {
|
|
15
23
|
return execFileSync("git", args, {
|
|
@@ -61,3 +69,25 @@ test("mergeMilestoneToMain blocks when project DB closeout is still open", () =>
|
|
|
61
69
|
if (existsSync(repo)) rmSync(repo, { recursive: true, force: true });
|
|
62
70
|
}
|
|
63
71
|
});
|
|
72
|
+
|
|
73
|
+
test("closeout consistency treats deferred slices as inactive", () => {
|
|
74
|
+
try {
|
|
75
|
+
assert.equal(openDatabase(":memory:"), true);
|
|
76
|
+
insertMilestone({ id: "M001", title: "Milestone One", status: "complete" });
|
|
77
|
+
insertSlice({ milestoneId: "M001", id: "S01", title: "Done", status: "complete" });
|
|
78
|
+
insertTask({ milestoneId: "M001", sliceId: "S01", id: "T01", title: "Done", status: "complete" });
|
|
79
|
+
insertSlice({ milestoneId: "M001", id: "S02", title: "Deferred", status: "deferred" });
|
|
80
|
+
insertTask({ milestoneId: "M001", sliceId: "S02", id: "T02", title: "Deferred", status: "pending" });
|
|
81
|
+
insertAssessment({
|
|
82
|
+
path: "milestones/M001/M001-VALIDATION.md",
|
|
83
|
+
milestoneId: "M001",
|
|
84
|
+
status: "pass",
|
|
85
|
+
scope: "milestone-validation",
|
|
86
|
+
fullContent: "verdict: pass",
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
assert.deepEqual(checkCloseoutConsistencyGate("M001"), { ok: true });
|
|
90
|
+
} finally {
|
|
91
|
+
closeDatabase();
|
|
92
|
+
}
|
|
93
|
+
});
|
|
@@ -112,6 +112,12 @@ describe("pruneMetricsLedger: invalidates scoped ledger cache", () => {
|
|
|
112
112
|
// 3. Prune to keepCount=2 — should evict 3 old units from disk AND clear scopedLedgers.
|
|
113
113
|
const removed = pruneMetricsLedger(tmpDir, 2);
|
|
114
114
|
assert.equal(removed, 3, "pruneMetricsLedger should report 3 removed units");
|
|
115
|
+
const prunedRaw = readFileSync(metricsPath(tmpDir), "utf-8");
|
|
116
|
+
assert.equal(
|
|
117
|
+
prunedRaw,
|
|
118
|
+
JSON.stringify(JSON.parse(prunedRaw)) + "\n",
|
|
119
|
+
"pruneMetricsLedger should persist compact metrics.json",
|
|
120
|
+
);
|
|
115
121
|
|
|
116
122
|
// 4. Snapshot a new unit via scope. This exercises the lazy-reload path
|
|
117
123
|
// (scopedLedgers was cleared by prune) and writes the result to disk.
|
|
@@ -259,6 +259,7 @@ test("initMetrics creates ledger, snapshotUnitMetrics persists across resets", (
|
|
|
259
259
|
// Verify file content
|
|
260
260
|
const raw = readFileSync(join(tmpBase, ".gsd", "metrics.json"), "utf-8");
|
|
261
261
|
const parsed: MetricsLedger = JSON.parse(raw);
|
|
262
|
+
assert.equal(raw, JSON.stringify(parsed) + "\n", "metrics.json should be serialized compactly");
|
|
262
263
|
assert.equal(parsed.version, 1);
|
|
263
264
|
assert.equal(parsed.units.length, 1);
|
|
264
265
|
|
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
existsSync,
|
|
8
8
|
mkdirSync,
|
|
9
9
|
realpathSync,
|
|
10
|
+
readFileSync,
|
|
10
11
|
} from "node:fs";
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import { syncBuiltinESMExports } from "node:module";
|
|
11
14
|
import { join } from "node:path";
|
|
12
15
|
import { tmpdir } from "node:os";
|
|
13
16
|
import { execSync } from "node:child_process";
|
|
@@ -116,6 +119,60 @@ describe("migrate-external worktree guard (#2970)", () => {
|
|
|
116
119
|
});
|
|
117
120
|
});
|
|
118
121
|
|
|
122
|
+
describe("migrateToExternalState copy failure rollback (#1047)", () => {
|
|
123
|
+
test("restores .gsd when a source entry fails to copy", () => {
|
|
124
|
+
const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-migrate-copy-fail-")));
|
|
125
|
+
const stateDir = realpathSync(mkdtempSync(join(tmpdir(), "gsd-state-copy-fail-")));
|
|
126
|
+
const previousStateDir = process.env.GSD_STATE_DIR;
|
|
127
|
+
const previousProjectId = process.env.GSD_PROJECT_ID;
|
|
128
|
+
const originalCpSync = fs.cpSync;
|
|
129
|
+
process.env.GSD_STATE_DIR = stateDir;
|
|
130
|
+
process.env.GSD_PROJECT_ID = "copy-fail";
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
run("git init -b main", base);
|
|
134
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
135
|
+
writeFileSync(join(base, ".gsd", "PREFERENCES.md"), "# prefs\n", "utf-8");
|
|
136
|
+
writeFileSync(join(base, ".gsd", "gsd.db"), "state", "utf-8");
|
|
137
|
+
const failingSource = join(base, ".gsd.migrating", "gsd.db");
|
|
138
|
+
fs.cpSync = ((...args: Parameters<typeof fs.cpSync>) => {
|
|
139
|
+
const src = args[0];
|
|
140
|
+
if (String(src) === failingSource) {
|
|
141
|
+
const error = new Error("simulated copy failure") as NodeJS.ErrnoException;
|
|
142
|
+
error.code = "EACCES";
|
|
143
|
+
throw error;
|
|
144
|
+
}
|
|
145
|
+
return originalCpSync(...args);
|
|
146
|
+
}) as typeof fs.cpSync;
|
|
147
|
+
syncBuiltinESMExports();
|
|
148
|
+
|
|
149
|
+
const result = migrateToExternalState(base);
|
|
150
|
+
|
|
151
|
+
assert.equal(result.migrated, false, "copy failure must fail the migration");
|
|
152
|
+
assert.match(result.error ?? "", /Migration copy failed/);
|
|
153
|
+
assert.ok(existsSync(join(base, ".gsd", "gsd.db")), "source .gsd must be restored");
|
|
154
|
+
assert.equal(readFileSync(join(base, ".gsd", "PREFERENCES.md"), "utf-8"), "# prefs\n");
|
|
155
|
+
assert.ok(!existsSync(join(base, ".gsd.migrating")), "backup staging dir must not remain after restore");
|
|
156
|
+
assert.ok(!existsSync(join(stateDir, "projects", "copy-fail", "gsd.db")), "failed file must not be reported as migrated");
|
|
157
|
+
} finally {
|
|
158
|
+
fs.cpSync = originalCpSync;
|
|
159
|
+
syncBuiltinESMExports();
|
|
160
|
+
if (previousStateDir === undefined) {
|
|
161
|
+
delete process.env.GSD_STATE_DIR;
|
|
162
|
+
} else {
|
|
163
|
+
process.env.GSD_STATE_DIR = previousStateDir;
|
|
164
|
+
}
|
|
165
|
+
if (previousProjectId === undefined) {
|
|
166
|
+
delete process.env.GSD_PROJECT_ID;
|
|
167
|
+
} else {
|
|
168
|
+
process.env.GSD_PROJECT_ID = previousProjectId;
|
|
169
|
+
}
|
|
170
|
+
rmSync(base, { recursive: true, force: true });
|
|
171
|
+
rmSync(stateDir, { recursive: true, force: true });
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
119
176
|
// Regression tests for #5571 — recoverFailedMigration handles orphaned .gsd.migrating
|
|
120
177
|
describe("recoverFailedMigration (#5571)", () => {
|
|
121
178
|
test("returns false when .gsd.migrating does not exist", () => {
|
|
@@ -429,3 +429,73 @@ test("rebuildMarkdownProjectionsFromDb realigns markdown when DB holds extra row
|
|
|
429
429
|
cleanup(base);
|
|
430
430
|
}
|
|
431
431
|
});
|
|
432
|
+
|
|
433
|
+
test("rebuildMarkdownProjectionsFromDb realigns markdown for numeric milestone IDs", async () => {
|
|
434
|
+
const base = makeBase();
|
|
435
|
+
try {
|
|
436
|
+
await writeGSDDirectory({ projectContent: "# P\n", decisionsContent: "", requirements: [], milestones: [] }, base);
|
|
437
|
+
assert.equal(await ensureDbOpen(base), true);
|
|
438
|
+
insertMilestone({ id: "15", title: "Numeric milestone", status: "active" });
|
|
439
|
+
insertSlice({
|
|
440
|
+
id: "S01",
|
|
441
|
+
milestoneId: "15",
|
|
442
|
+
title: "Numeric slice",
|
|
443
|
+
status: "pending",
|
|
444
|
+
risk: "medium",
|
|
445
|
+
depends: [],
|
|
446
|
+
demo: "d",
|
|
447
|
+
sequence: 1,
|
|
448
|
+
});
|
|
449
|
+
insertTask({
|
|
450
|
+
id: "T01",
|
|
451
|
+
sliceId: "S01",
|
|
452
|
+
milestoneId: "15",
|
|
453
|
+
title: "Numeric task",
|
|
454
|
+
status: "pending",
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
const before = await checkMarkdownHierarchyAgainstDb(base);
|
|
458
|
+
assert.equal(before.recoveryCommand, "/gsd rebuild markdown");
|
|
459
|
+
|
|
460
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.ts");
|
|
461
|
+
const rebuild = await rebuildMarkdownProjectionsFromDb(base);
|
|
462
|
+
assert.ok(rebuild.rendered > 0, "expected markdown projections to render");
|
|
463
|
+
|
|
464
|
+
const after = await checkMarkdownHierarchyAgainstDb(base);
|
|
465
|
+
assert.equal(after.action, "none");
|
|
466
|
+
assert.equal(after.reason, "in-sync");
|
|
467
|
+
assert.deepEqual(after.markdown, { milestones: 1, slices: 1, tasks: 1 });
|
|
468
|
+
assert.deepEqual(after.beforeDb, { milestones: 1, slices: 1, tasks: 1 });
|
|
469
|
+
} finally {
|
|
470
|
+
cleanup(base);
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
test("rebuildMarkdownProjectionsFromDb realigns markdown for planned zero-slice milestones", async () => {
|
|
475
|
+
const base = makeBase();
|
|
476
|
+
try {
|
|
477
|
+
await writeGSDDirectory({ projectContent: "# P\n", decisionsContent: "", requirements: [], milestones: [] }, base);
|
|
478
|
+
assert.equal(await ensureDbOpen(base), true);
|
|
479
|
+
insertMilestone({
|
|
480
|
+
id: "M016",
|
|
481
|
+
title: "Queued milestone",
|
|
482
|
+
status: "queued",
|
|
483
|
+
planning: { vision: "Defined but not sliced yet" },
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
const before = await checkMarkdownHierarchyAgainstDb(base);
|
|
487
|
+
assert.equal(before.recoveryCommand, "/gsd rebuild markdown");
|
|
488
|
+
|
|
489
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.ts");
|
|
490
|
+
const rebuild = await rebuildMarkdownProjectionsFromDb(base);
|
|
491
|
+
assert.ok(rebuild.rendered > 0, "expected markdown projections to render");
|
|
492
|
+
|
|
493
|
+
const after = await checkMarkdownHierarchyAgainstDb(base);
|
|
494
|
+
assert.equal(after.action, "none");
|
|
495
|
+
assert.equal(after.reason, "in-sync");
|
|
496
|
+
assert.deepEqual(after.markdown, { milestones: 1, slices: 0, tasks: 0 });
|
|
497
|
+
assert.deepEqual(after.beforeDb, { milestones: 1, slices: 0, tasks: 0 });
|
|
498
|
+
} finally {
|
|
499
|
+
cleanup(base);
|
|
500
|
+
}
|
|
501
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// gsd-pi + src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts
|
|
2
|
-
// Regression
|
|
3
|
-
//
|
|
2
|
+
// Regression coverage for orphaned gsd-preflight-stash entries from completed
|
|
3
|
+
// milestones: safe startup recovery for untracked work, manual warnings for
|
|
4
|
+
// tracked or dirty-tree cases that would silently mutate user state.
|
|
4
5
|
|
|
5
6
|
import { describe, test, beforeEach, afterEach } from "node:test";
|
|
6
7
|
import assert from "node:assert/strict";
|
|
@@ -37,6 +38,13 @@ function pushPreflightStash(repo: string, milestoneId: string, fileName: string,
|
|
|
37
38
|
return marker;
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
function pushTrackedPreflightStash(repo: string, milestoneId: string, fileName: string, content: string): string {
|
|
42
|
+
writeFileSync(join(repo, fileName), content);
|
|
43
|
+
const marker = `gsd-preflight-stash:${milestoneId}:42:1700000000000:tracked`;
|
|
44
|
+
git(repo, "stash", "push", "-m", `gsd-preflight-stash [${marker}]`);
|
|
45
|
+
return marker;
|
|
46
|
+
}
|
|
47
|
+
|
|
40
48
|
describe("auditOrphanedPreflightStashes", () => {
|
|
41
49
|
let repo: string;
|
|
42
50
|
|
|
@@ -83,6 +91,23 @@ describe("auditOrphanedPreflightStashes", () => {
|
|
|
83
91
|
assert.match(list, /gsd-preflight-stash:M002:/);
|
|
84
92
|
});
|
|
85
93
|
|
|
94
|
+
test("does not auto-apply a tracked orphan preflight stash onto a clean working tree", () => {
|
|
95
|
+
pushTrackedPreflightStash(repo, "M006", "seed.txt", "seed\ntracked pre-merge work\n");
|
|
96
|
+
assert.equal(readFileSync(join(repo, "seed.txt"), "utf-8"), "seed\n");
|
|
97
|
+
|
|
98
|
+
const result = auditOrphanedPreflightStashes(repo, () => true);
|
|
99
|
+
|
|
100
|
+
assert.equal(result.applied.length, 0);
|
|
101
|
+
assert.equal(result.warnings.length, 1);
|
|
102
|
+
assert.match(result.warnings[0], /not auto-applied/);
|
|
103
|
+
assert.match(result.warnings[0], /stash modifies tracked files/);
|
|
104
|
+
assert.match(result.warnings[0], /git stash apply stash@\{\d+\}/);
|
|
105
|
+
assert.equal(readFileSync(join(repo, "seed.txt"), "utf-8"), "seed\n");
|
|
106
|
+
|
|
107
|
+
const list = git(repo, "stash", "list");
|
|
108
|
+
assert.match(list, /gsd-preflight-stash:M006:/);
|
|
109
|
+
});
|
|
110
|
+
|
|
86
111
|
test("ignores stashes whose milestone is not complete", () => {
|
|
87
112
|
pushPreflightStash(repo, "M003", "wip.txt", "still-working\n");
|
|
88
113
|
|
|
@@ -115,23 +140,25 @@ describe("auditOrphanedPreflightStashes", () => {
|
|
|
115
140
|
assert.match(result.warnings[0], /db unavailable/);
|
|
116
141
|
});
|
|
117
142
|
|
|
118
|
-
test("collects a warning
|
|
119
|
-
// Push a stash containing a change to seed.txt; then dirty seed.txt
|
|
120
|
-
//
|
|
143
|
+
test("collects a warning instead of applying when the working tree is not clean", () => {
|
|
144
|
+
// Push a stash containing a change to seed.txt; then dirty seed.txt before
|
|
145
|
+
// the audit runs. Startup recovery must leave the tree untouched and ask
|
|
146
|
+
// the user to apply the retained backup stash manually.
|
|
121
147
|
writeFileSync(join(repo, "seed.txt"), "stashed\n");
|
|
122
148
|
const marker = `gsd-preflight-stash:M005:42:1700:zz`;
|
|
123
149
|
git(repo, "stash", "push", "-m", `gsd-preflight-stash [${marker}]`);
|
|
124
150
|
|
|
125
|
-
// Dirty the working tree so apply will conflict.
|
|
126
151
|
writeFileSync(join(repo, "seed.txt"), "conflicting modification\n");
|
|
127
152
|
|
|
128
153
|
const result = auditOrphanedPreflightStashes(repo, () => true);
|
|
129
154
|
|
|
130
155
|
assert.equal(result.applied.length, 0);
|
|
131
156
|
assert.equal(result.warnings.length, 1);
|
|
132
|
-
assert.match(result.warnings[0], /
|
|
157
|
+
assert.match(result.warnings[0], /not auto-applied/);
|
|
158
|
+
assert.match(result.warnings[0], /working tree not clean/);
|
|
133
159
|
assert.match(result.warnings[0], /M005/);
|
|
134
160
|
assert.match(result.warnings[0], /git stash apply/);
|
|
161
|
+
assert.equal(readFileSync(join(repo, "seed.txt"), "utf-8"), "conflicting modification\n");
|
|
135
162
|
|
|
136
163
|
const list = git(repo, "stash", "list");
|
|
137
164
|
assert.match(list, /gsd-preflight-stash:M005:/);
|
|
@@ -169,6 +196,63 @@ describe("auditOrphanedPreflightStashes", () => {
|
|
|
169
196
|
"second run must NOT warn — files are already restored from first run",
|
|
170
197
|
);
|
|
171
198
|
});
|
|
199
|
+
|
|
200
|
+
test("warns instead of silently skipping when only some stash untracked files were restored", () => {
|
|
201
|
+
// Cursor Bugbot caught: isAlreadyRestoredUntrackedStatus treated a dirty
|
|
202
|
+
// tree as fully restored when every *current* untracked path appeared in
|
|
203
|
+
// the stash, without requiring every *stash* untracked path to be present.
|
|
204
|
+
// A partial restore (only some files recovered) was misread as the
|
|
205
|
+
// idempotent steady state, so the audit no-oped and the remaining pre-merge
|
|
206
|
+
// files stayed missing with no warning.
|
|
207
|
+
writeFileSync(join(repo, "first.txt"), "first\n");
|
|
208
|
+
writeFileSync(join(repo, "second.txt"), "second\n");
|
|
209
|
+
const marker = `gsd-preflight-stash:M007:42:1700000000000:partial`;
|
|
210
|
+
git(repo, "stash", "push", "--include-untracked", "-m", `gsd-preflight-stash [${marker}]`);
|
|
211
|
+
|
|
212
|
+
// Both files are stashed away.
|
|
213
|
+
assert.equal(existsSync(join(repo, "first.txt")), false);
|
|
214
|
+
assert.equal(existsSync(join(repo, "second.txt")), false);
|
|
215
|
+
|
|
216
|
+
// Simulate a partial restore: only first.txt came back; second.txt is still
|
|
217
|
+
// missing from the working tree.
|
|
218
|
+
writeFileSync(join(repo, "first.txt"), "first\n");
|
|
219
|
+
|
|
220
|
+
const result = auditOrphanedPreflightStashes(repo, () => true);
|
|
221
|
+
|
|
222
|
+
// Must NOT be treated as already-restored: second.txt is still missing, so
|
|
223
|
+
// the audit must surface a manual-recovery warning rather than no-op.
|
|
224
|
+
assert.equal(result.applied.length, 0);
|
|
225
|
+
assert.equal(result.warnings.length, 1, "partial restore must warn, not silently no-op");
|
|
226
|
+
assert.match(result.warnings[0], /not auto-applied/);
|
|
227
|
+
assert.match(result.warnings[0], /working tree not clean/);
|
|
228
|
+
assert.match(result.warnings[0], /M007/);
|
|
229
|
+
assert.match(result.warnings[0], /git stash apply/);
|
|
230
|
+
|
|
231
|
+
// The stash entry must remain so the user can recover second.txt manually.
|
|
232
|
+
const list = git(repo, "stash", "list");
|
|
233
|
+
assert.match(list, /gsd-preflight-stash:M007:/);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test("fully restored multi-file untracked stash stays a silent no-op", () => {
|
|
237
|
+
// Guards the other direction of the set-equality fix: when EVERY stash
|
|
238
|
+
// untracked file is present in the working tree, the genuine idempotent
|
|
239
|
+
// steady state must still be recognized and skipped without warning, even
|
|
240
|
+
// when the stash captured more than one file.
|
|
241
|
+
writeFileSync(join(repo, "alpha.txt"), "alpha\n");
|
|
242
|
+
writeFileSync(join(repo, "beta.txt"), "beta\n");
|
|
243
|
+
const marker = `gsd-preflight-stash:M008:42:1700000000000:multi`;
|
|
244
|
+
git(repo, "stash", "push", "--include-untracked", "-m", `gsd-preflight-stash [${marker}]`);
|
|
245
|
+
|
|
246
|
+
const first = auditOrphanedPreflightStashes(repo, () => true);
|
|
247
|
+
assert.equal(first.applied.length, 1, "first run applies both files");
|
|
248
|
+
assert.equal(first.warnings.length, 0);
|
|
249
|
+
assert.equal(existsSync(join(repo, "alpha.txt")), true);
|
|
250
|
+
assert.equal(existsSync(join(repo, "beta.txt")), true);
|
|
251
|
+
|
|
252
|
+
const second = auditOrphanedPreflightStashes(repo, () => true);
|
|
253
|
+
assert.equal(second.applied.length, 0, "second run skips");
|
|
254
|
+
assert.equal(second.warnings.length, 0, "fully restored multi-file stash must not warn");
|
|
255
|
+
});
|
|
172
256
|
});
|
|
173
257
|
|
|
174
258
|
test("_isAlreadyRestoredApplyError detects the git stash apply already-exists error", () => {
|
|
@@ -54,9 +54,12 @@ const ALLOWED_IMPORTERS = new Set([
|
|
|
54
54
|
// explicit degraded-mode fallback when DB has no task rows (warns on use)
|
|
55
55
|
"gsd/reactive-graph.ts",
|
|
56
56
|
// recovery path: explicit pre-migration/DB-unavailable fallback branches
|
|
57
|
-
|
|
57
|
+
// (verifyExpectedArtifact extracted here from auto-recovery.ts)
|
|
58
|
+
"gsd/artifact-verification.ts",
|
|
58
59
|
// diagnostics-only surfaces: report on projections, make no dispatch decisions
|
|
59
60
|
"gsd/doctor.ts",
|
|
61
|
+
// diagnostics-only: compares PLAN.md task checkboxes against DB status
|
|
62
|
+
"gsd/doctor-engine-checks.ts",
|
|
60
63
|
// display/telemetry-only surfaces
|
|
61
64
|
"gsd/workspace-index.ts",
|
|
62
65
|
"gsd/visualizer-data.ts",
|
|
@@ -55,8 +55,8 @@ describe("pendingAutoStart scope pinning (C1)", () => {
|
|
|
55
55
|
assert.ok(entry.scope, "entry.scope should be set");
|
|
56
56
|
assert.equal(entry.scope.milestoneId, "M001");
|
|
57
57
|
|
|
58
|
-
const expectedContext = join(base, ".gsd", "
|
|
59
|
-
const expectedRoadmap = join(base, ".gsd", "
|
|
58
|
+
const expectedContext = join(base, ".gsd", "phases", "01-m001", "01-CONTEXT.md");
|
|
59
|
+
const expectedRoadmap = join(base, ".gsd", "phases", "01-m001", "01-ROADMAP.md");
|
|
60
60
|
const expectedState = join(base, ".gsd", "STATE.md");
|
|
61
61
|
|
|
62
62
|
assert.equal(entry.scope.contextFile(), expectedContext);
|
|
@@ -34,6 +34,7 @@ const BASE_VARS = {
|
|
|
34
34
|
planTemplatePath: "C:\\Users\\Test\\.gsd\\agent\\extensions\\gsd\\templates\\plan.md",
|
|
35
35
|
taskPlanTemplatePath: "C:\\Users\\Test\\.gsd\\agent\\extensions\\gsd\\templates\\task-plan.md",
|
|
36
36
|
skillActivation: "Load the relevant skills.",
|
|
37
|
+
repoRegistry: "",
|
|
37
38
|
};
|
|
38
39
|
|
|
39
40
|
const DEFAULT_SKILL_ACTIVATION = "If a `GSD Skill Preferences` block is present in system context, use it and the `<available_skills>` catalog in your system prompt to decide which skills to load and follow for this unit, without relaxing required verification or artifact rules.";
|
|
@@ -61,6 +62,22 @@ test("plan-slice prompt: all variables substituted", () => {
|
|
|
61
62
|
assert.ok(result.includes("S01"));
|
|
62
63
|
});
|
|
63
64
|
|
|
65
|
+
test("plan-slice prompt: repoRegistry block surfaces declared repositories when non-empty", () => {
|
|
66
|
+
const block = "### Declared Repositories\n\n- `frontend` (frontend/)\n- `backend` (backend/)\n\nAssign each task's `targetRepositories`";
|
|
67
|
+
const result = loadPrompt("plan-slice", { ...BASE_VARS, repoRegistry: block, commitInstruction: "Do not commit." });
|
|
68
|
+
assert.ok(result.includes("### Declared Repositories"), "declared repositories block should appear when provided");
|
|
69
|
+
assert.ok(result.includes("`frontend`"), "declared repo ids should be visible to the planner");
|
|
70
|
+
assert.ok(result.includes("targetRepositories"), "repo-assignment guidance should appear");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("plan-slice prompt: empty repoRegistry leaves no orphan marker", () => {
|
|
74
|
+
const result = loadPrompt("plan-slice", { ...BASE_VARS, repoRegistry: "", commitInstruction: "Do not commit." });
|
|
75
|
+
assert.ok(!result.includes("{{repoRegistry}}"), "the repoRegistry placeholder must be substituted");
|
|
76
|
+
// The block heading only renders when repoRegistry is non-empty; the rule-9
|
|
77
|
+
// guidance text mentions "Declared Repositories" but is not a rendered block.
|
|
78
|
+
assert.ok(!result.includes("### Declared Repositories"), "single-repo prompts must not show a declared-repositories block");
|
|
79
|
+
});
|
|
80
|
+
|
|
64
81
|
test("plan-slice prompt: DB-backed tool names survive template substitution", () => {
|
|
65
82
|
const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
|
|
66
83
|
assert.ok(result.includes("gsd_plan_slice"), "gsd_plan_slice should appear in rendered prompt");
|
|
@@ -94,6 +111,16 @@ test("plan-slice prompt: absence checks use negated quiet searches", () => {
|
|
|
94
111
|
assert.ok(result.includes("count commands exit 1 when they find zero matches"));
|
|
95
112
|
});
|
|
96
113
|
|
|
114
|
+
test("plan-slice prompt: npm package existence rule is stated during generation", () => {
|
|
115
|
+
const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
|
|
116
|
+
assert.ok(result.includes("reference only packages that exist on the public npm registry"));
|
|
117
|
+
assert.ok(result.includes("remove or correct any package name that is not real"));
|
|
118
|
+
// The post-unit pre-execution gate parses package names from require/import
|
|
119
|
+
// patterns too, not just install commands, so the rule must cover that scope.
|
|
120
|
+
assert.ok(result.includes("require('...')"));
|
|
121
|
+
assert.ok(result.includes("import ... from '...'"));
|
|
122
|
+
});
|
|
123
|
+
|
|
97
124
|
test("plan-slice prompt: footer references gsd_plan_slice tool, not direct write", () => {
|
|
98
125
|
const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
|
|
99
126
|
assert.ok(
|