@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
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
// File Purpose: Tests the one-time migration from nested to flat-phase layout.
|
|
3
3
|
import test, { afterEach } from "node:test";
|
|
4
4
|
import assert from "node:assert/strict";
|
|
5
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readdirSync, readFileSync } from "node:fs";
|
|
5
|
+
import { mkdtempSync, mkdirSync, renameSync, rmSync, writeFileSync, existsSync, readdirSync, readFileSync, utimesSync } from "node:fs";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
_setFlatPhaseMigrationFsOpsForTest,
|
|
12
|
+
migrateToFlatPhase,
|
|
13
|
+
needsFlatPhaseMigration,
|
|
14
|
+
pruneStaleFlatPhaseBackups,
|
|
15
|
+
} from "../flat-phase-migration.ts";
|
|
11
16
|
import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks } from "../gsd-db.ts";
|
|
12
17
|
|
|
13
18
|
const tmpDirs: string[] = [];
|
|
@@ -60,6 +65,42 @@ test("migrateToFlatPhase moves content from milestones/ to phases/", async () =>
|
|
|
60
65
|
assert.ok(!existsSync(join(base, ".gsd", "milestones")), "milestones/ should be removed");
|
|
61
66
|
});
|
|
62
67
|
|
|
68
|
+
test("migrateToFlatPhase ignores and removes stale phase dirs from prior aborted runs", async () => {
|
|
69
|
+
const base = makeTmp();
|
|
70
|
+
const stalePhaseDir = join(base, ".gsd", "phases", "99-stale-aborted-run");
|
|
71
|
+
mkdirSync(stalePhaseDir, { recursive: true });
|
|
72
|
+
|
|
73
|
+
await migrateToFlatPhase(base);
|
|
74
|
+
|
|
75
|
+
assert.ok(existsSync(join(base, ".gsd", "phases", "01-foundation")), "current DB phase should render");
|
|
76
|
+
assert.equal(existsSync(stalePhaseDir), false, "stale pre-existing phase dir should be removed");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("migrateToFlatPhase falls back to copy-delete when legacy rename is blocked", async (t) => {
|
|
80
|
+
const base = makeTmp();
|
|
81
|
+
const milestonesPath = join(base, ".gsd", "milestones");
|
|
82
|
+
const migratingPath = join(base, ".gsd", "milestones.migrating");
|
|
83
|
+
let blockedRenameAttempts = 0;
|
|
84
|
+
|
|
85
|
+
const restoreFsOps = _setFlatPhaseMigrationFsOpsForTest({
|
|
86
|
+
renameSync(src, dst) {
|
|
87
|
+
if (src === milestonesPath && dst === migratingPath) {
|
|
88
|
+
blockedRenameAttempts++;
|
|
89
|
+
throw Object.assign(new Error("simulated busy handle"), { code: "EPERM" });
|
|
90
|
+
}
|
|
91
|
+
return renameSync(src, dst);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
t.after(restoreFsOps);
|
|
95
|
+
|
|
96
|
+
await migrateToFlatPhase(base);
|
|
97
|
+
|
|
98
|
+
assert.equal(blockedRenameAttempts, 1, "test should exercise the rename fallback path");
|
|
99
|
+
assert.ok(existsSync(join(base, ".gsd", "phases", "01-foundation")), "flat phase should render");
|
|
100
|
+
assert.equal(existsSync(milestonesPath), false, "legacy milestones dir should be removed");
|
|
101
|
+
assert.equal(existsSync(migratingPath), false, "staging dir should be removed after success");
|
|
102
|
+
});
|
|
103
|
+
|
|
63
104
|
test("migrateToFlatPhase creates a backup", async () => {
|
|
64
105
|
const base = makeTmp();
|
|
65
106
|
await migrateToFlatPhase(base);
|
|
@@ -112,3 +153,34 @@ test("migrateToFlatPhase preserves slice sidecar artifacts and skips recovery pl
|
|
|
112
153
|
"recovery placeholder PLAN should not be promoted when no DB tasks can render a real plan",
|
|
113
154
|
);
|
|
114
155
|
});
|
|
156
|
+
|
|
157
|
+
test("pruneStaleFlatPhaseBackups removes migrate-* dirs older than retention window", async () => {
|
|
158
|
+
const base = makeTmp();
|
|
159
|
+
await migrateToFlatPhase(base);
|
|
160
|
+
|
|
161
|
+
const backupRoot = join(base, ".gsd-backups");
|
|
162
|
+
assert.ok(existsSync(backupRoot), "backup should exist immediately after migration");
|
|
163
|
+
|
|
164
|
+
const staleDir = join(backupRoot, "migrate-stale");
|
|
165
|
+
mkdirSync(staleDir, { recursive: true });
|
|
166
|
+
writeFileSync(join(staleDir, "marker.txt"), "old backup\n", "utf-8");
|
|
167
|
+
const staleDate = new Date(Date.now() - 31 * 24 * 60 * 60 * 1000);
|
|
168
|
+
utimesSync(staleDir, staleDate, staleDate);
|
|
169
|
+
|
|
170
|
+
const removed = pruneStaleFlatPhaseBackups(base);
|
|
171
|
+
assert.equal(removed, 1, "stale migrate-* dir should be pruned");
|
|
172
|
+
assert.equal(existsSync(staleDir), false, "stale backup dir should be gone");
|
|
173
|
+
assert.ok(existsSync(backupRoot), "fresh migration backup should remain");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("pruneStaleFlatPhaseBackups is a no-op while flat-phase migration is still needed", () => {
|
|
177
|
+
const base = makeTmp();
|
|
178
|
+
const backupRoot = join(base, ".gsd-backups", "migrate-stale");
|
|
179
|
+
mkdirSync(backupRoot, { recursive: true });
|
|
180
|
+
writeFileSync(join(backupRoot, "marker.txt"), "old backup\n", "utf-8");
|
|
181
|
+
const staleDate = new Date(Date.now() - 31 * 24 * 60 * 60 * 1000);
|
|
182
|
+
utimesSync(backupRoot, staleDate, staleDate);
|
|
183
|
+
|
|
184
|
+
assert.equal(pruneStaleFlatPhaseBackups(base), 0, "must not prune while migration is pending");
|
|
185
|
+
assert.ok(existsSync(backupRoot), "backup must remain until migration completes");
|
|
186
|
+
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Regression
|
|
3
|
-
*
|
|
4
|
-
* per request — routing only degrades quality with no cost benefit.
|
|
2
|
+
* Regression tests for flat-rate provider detection and the explicit opt-out
|
|
3
|
+
* that suppresses dynamic routing for subscription providers.
|
|
5
4
|
*/
|
|
6
5
|
|
|
7
6
|
import { describe, test } from "node:test";
|
|
@@ -9,7 +8,7 @@ import assert from "node:assert/strict";
|
|
|
9
8
|
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
10
9
|
import { tmpdir } from "node:os";
|
|
11
10
|
import { join } from "node:path";
|
|
12
|
-
import { buildFlatRateContext, isFlatRateProvider, resolvePreferredModelConfig } from "../auto-model-selection.ts";
|
|
11
|
+
import { buildFlatRateContext, isFlatRateProvider, resolvePreferredModelConfig, selectAndApplyModel } from "../auto-model-selection.ts";
|
|
13
12
|
|
|
14
13
|
describe("flat-rate provider routing guard (#3453)", () => {
|
|
15
14
|
|
|
@@ -35,23 +34,18 @@ describe("flat-rate provider routing guard (#3453)", () => {
|
|
|
35
34
|
assert.equal(isFlatRateProvider("openai"), false);
|
|
36
35
|
});
|
|
37
36
|
|
|
38
|
-
test("resolvePreferredModelConfig
|
|
37
|
+
test("resolvePreferredModelConfig synthesizes routing config for copilot start model when routing is enabled", () => {
|
|
39
38
|
const originalCwd = process.cwd();
|
|
40
39
|
const originalGsdHome = process.env.GSD_HOME;
|
|
41
40
|
const tempProject = mkdtempSync(join(tmpdir(), "gsd-flat-rate-project-"));
|
|
42
41
|
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-flat-rate-home-"));
|
|
43
42
|
|
|
44
|
-
// When the user's start model is on a flat-rate provider,
|
|
45
|
-
// resolvePreferredModelConfig should not synthesize a routing
|
|
46
|
-
// config from tier_models — it should return undefined so the
|
|
47
|
-
// user's selected model is preserved.
|
|
48
43
|
try {
|
|
49
44
|
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
50
45
|
writeFileSync(
|
|
51
46
|
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
52
47
|
[
|
|
53
48
|
"---",
|
|
54
|
-
"token_profile: burn-max",
|
|
55
49
|
"dynamic_routing:",
|
|
56
50
|
" enabled: true",
|
|
57
51
|
" tier_models:",
|
|
@@ -70,10 +64,83 @@ describe("flat-rate provider routing guard (#3453)", () => {
|
|
|
70
64
|
id: "claude-sonnet-4",
|
|
71
65
|
});
|
|
72
66
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
assert.deepEqual(result, {
|
|
68
|
+
primary: "claude-opus-4-6",
|
|
69
|
+
fallbacks: [],
|
|
70
|
+
source: "synthesized",
|
|
71
|
+
});
|
|
72
|
+
} finally {
|
|
73
|
+
process.chdir(originalCwd);
|
|
74
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
75
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
76
|
+
rmSync(tempProject, { recursive: true, force: true });
|
|
77
|
+
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("selectAndApplyModel runs synthesized dynamic routing for flat-rate start model", async () => {
|
|
82
|
+
const originalCwd = process.cwd();
|
|
83
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
84
|
+
const tempProject = mkdtempSync(join(tmpdir(), "gsd-flat-rate-project-"));
|
|
85
|
+
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-flat-rate-home-"));
|
|
86
|
+
const setModelCalls: string[] = [];
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
90
|
+
writeFileSync(
|
|
91
|
+
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
92
|
+
[
|
|
93
|
+
"---",
|
|
94
|
+
"dynamic_routing:",
|
|
95
|
+
" enabled: true",
|
|
96
|
+
" hooks: false",
|
|
97
|
+
" budget_pressure: false",
|
|
98
|
+
" tier_models:",
|
|
99
|
+
" light: claude-haiku-4-5",
|
|
100
|
+
" standard: claude-sonnet-4-6",
|
|
101
|
+
" heavy: claude-opus-4-6",
|
|
102
|
+
"---",
|
|
103
|
+
].join("\n"),
|
|
104
|
+
"utf-8",
|
|
105
|
+
);
|
|
106
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
107
|
+
process.chdir(tempProject);
|
|
108
|
+
|
|
109
|
+
const availableModels = [
|
|
110
|
+
{ id: "claude-haiku-4-5", provider: "claude-code", api: "anthropic-messages" },
|
|
111
|
+
{ id: "claude-sonnet-4-6", provider: "claude-code", api: "anthropic-messages" },
|
|
112
|
+
{ id: "claude-opus-4-6", provider: "claude-code", api: "anthropic-messages" },
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
const result = await selectAndApplyModel(
|
|
116
|
+
{
|
|
117
|
+
modelRegistry: { getAvailable: () => availableModels },
|
|
118
|
+
sessionManager: { getSessionId: () => "test-session" },
|
|
119
|
+
ui: { notify: () => {} },
|
|
120
|
+
model: { provider: "claude-code", id: "claude-opus-4-6", api: "anthropic-messages" },
|
|
121
|
+
} as any,
|
|
122
|
+
{
|
|
123
|
+
setModel: async (model: { provider: string; id: string }) => {
|
|
124
|
+
setModelCalls.push(`${model.provider}/${model.id}`);
|
|
125
|
+
return true;
|
|
126
|
+
},
|
|
127
|
+
emitBeforeModelSelect: async () => undefined,
|
|
128
|
+
getActiveTools: () => [],
|
|
129
|
+
emitAdjustToolSet: async () => undefined,
|
|
130
|
+
setActiveTools: () => {},
|
|
131
|
+
} as any,
|
|
132
|
+
"execute-task",
|
|
133
|
+
"M001/S01/T01",
|
|
134
|
+
tempProject,
|
|
135
|
+
undefined,
|
|
136
|
+
false,
|
|
137
|
+
{ provider: "claude-code", id: "claude-opus-4-6" },
|
|
138
|
+
undefined,
|
|
139
|
+
true,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
assert.deepEqual(setModelCalls, ["claude-code/claude-sonnet-4-6"]);
|
|
143
|
+
assert.deepEqual(result.routing, { tier: "standard", modelDowngraded: true });
|
|
77
144
|
} finally {
|
|
78
145
|
process.chdir(originalCwd);
|
|
79
146
|
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
@@ -220,9 +287,9 @@ describe("buildFlatRateContext()", () => {
|
|
|
220
287
|
});
|
|
221
288
|
});
|
|
222
289
|
|
|
223
|
-
// ─── #4386: allow_flat_rate_providers
|
|
290
|
+
// ─── #4386/#1115: allow_flat_rate_providers override ────────────────────────
|
|
224
291
|
|
|
225
|
-
describe("flat-rate routing
|
|
292
|
+
describe("flat-rate routing override (#4386/#1115)", () => {
|
|
226
293
|
function withPrefs(prefsYaml: string, fn: () => void): void {
|
|
227
294
|
const originalCwd = process.cwd();
|
|
228
295
|
const originalGsdHome = process.env.GSD_HOME;
|
|
@@ -247,7 +314,7 @@ describe("flat-rate routing opt-in (#4386)", () => {
|
|
|
247
314
|
}
|
|
248
315
|
}
|
|
249
316
|
|
|
250
|
-
test("default (
|
|
317
|
+
test("default (allow absent): flat-rate start model still synthesizes routing config", () => {
|
|
251
318
|
withPrefs(
|
|
252
319
|
[
|
|
253
320
|
"dynamic_routing:",
|
|
@@ -260,12 +327,13 @@ describe("flat-rate routing opt-in (#4386)", () => {
|
|
|
260
327
|
provider: "claude-code",
|
|
261
328
|
id: "claude-opus-4-6",
|
|
262
329
|
});
|
|
263
|
-
assert.
|
|
330
|
+
assert.ok(result, "routing config should be synthesized");
|
|
331
|
+
assert.equal(result!.primary, "claude-opus-4-6");
|
|
264
332
|
},
|
|
265
333
|
);
|
|
266
334
|
});
|
|
267
335
|
|
|
268
|
-
test("
|
|
336
|
+
test("explicit allow: synthesizes a routing config for flat-rate start model", () => {
|
|
269
337
|
withPrefs(
|
|
270
338
|
[
|
|
271
339
|
"dynamic_routing:",
|
|
@@ -14,6 +14,7 @@ import { tmpdir } from "node:os";
|
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
checkAutoStartAfterDiscuss,
|
|
17
|
+
_getPendingAutoStart,
|
|
17
18
|
setPendingAutoStart,
|
|
18
19
|
clearPendingAutoStart,
|
|
19
20
|
} from "../guided-flow.ts";
|
|
@@ -21,6 +22,7 @@ import { drainLogs } from "../workflow-logger.ts";
|
|
|
21
22
|
import {
|
|
22
23
|
openDatabase,
|
|
23
24
|
closeDatabase,
|
|
25
|
+
getMilestone,
|
|
24
26
|
insertMilestone,
|
|
25
27
|
} from "../gsd-db.ts";
|
|
26
28
|
|
|
@@ -59,6 +61,12 @@ function mkBase(): string {
|
|
|
59
61
|
return base;
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
function mkFlatBase(): string {
|
|
65
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-gate1b-flat-"));
|
|
66
|
+
mkdirSync(join(base, ".gsd", "phases", "01-m001"), { recursive: true });
|
|
67
|
+
return base;
|
|
68
|
+
}
|
|
69
|
+
|
|
62
70
|
function writeContext(base: string): void {
|
|
63
71
|
writeFileSync(
|
|
64
72
|
join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
|
|
@@ -66,6 +74,13 @@ function writeContext(base: string): void {
|
|
|
66
74
|
);
|
|
67
75
|
}
|
|
68
76
|
|
|
77
|
+
function writeFlatContext(base: string): void {
|
|
78
|
+
writeFileSync(
|
|
79
|
+
join(base, ".gsd", "phases", "01-m001", "01-CONTEXT.md"),
|
|
80
|
+
"# M001: Test Milestone\n\nContext written by discuss phase.\n",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
69
84
|
describe("Gate 1b discussion handoff in checkAutoStartAfterDiscuss", () => {
|
|
70
85
|
let base: string;
|
|
71
86
|
let cap: MockCapture;
|
|
@@ -142,4 +157,78 @@ describe("Gate 1b discussion handoff in checkAutoStartAfterDiscuss", () => {
|
|
|
142
157
|
);
|
|
143
158
|
assert.equal(gate1bLog, undefined, "Gate 1b must not log when CONTEXT.md is absent");
|
|
144
159
|
});
|
|
160
|
+
|
|
161
|
+
test("flat-phase CONTEXT.md accepts handoff without a legacy milestone context file", () => {
|
|
162
|
+
base = mkFlatBase();
|
|
163
|
+
openDatabase(":memory:");
|
|
164
|
+
insertMilestone({ id: "M001", title: "Test Milestone", status: "queued" });
|
|
165
|
+
writeFlatContext(base);
|
|
166
|
+
|
|
167
|
+
cap = mkCapture();
|
|
168
|
+
setPendingAutoStart(base, {
|
|
169
|
+
basePath: base,
|
|
170
|
+
milestoneId: "M001",
|
|
171
|
+
startAuto: false,
|
|
172
|
+
ctx: mkCtx(cap),
|
|
173
|
+
pi: mkPi(cap),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const result = checkAutoStartAfterDiscuss();
|
|
177
|
+
|
|
178
|
+
assert.equal(result, true, "flat-phase context must be found by the handoff");
|
|
179
|
+
assert.equal(cap.messages.length, 0, "startAuto=false must suppress scheduling");
|
|
180
|
+
assert.deepEqual(cap.notifies[0], {
|
|
181
|
+
msg: "Milestone M001 context captured. Continuing the planning pipeline.",
|
|
182
|
+
level: "success",
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("DB-unavailable recovery blocks handoff instead of reporting success", () => {
|
|
187
|
+
base = mkFlatBase();
|
|
188
|
+
writeFlatContext(base);
|
|
189
|
+
|
|
190
|
+
cap = mkCapture();
|
|
191
|
+
setPendingAutoStart(base, {
|
|
192
|
+
basePath: base,
|
|
193
|
+
milestoneId: "M001",
|
|
194
|
+
startAuto: false,
|
|
195
|
+
ctx: mkCtx(cap),
|
|
196
|
+
pi: mkPi(cap),
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const result = checkAutoStartAfterDiscuss();
|
|
200
|
+
|
|
201
|
+
assert.equal(result, false, "handoff must fail closed when the DB row cannot be confirmed");
|
|
202
|
+
assert.equal(cap.messages.length, 0, "must not schedule auto-start when DB is unavailable");
|
|
203
|
+
assert.equal(
|
|
204
|
+
cap.notifies.some(n => n.level === "success"),
|
|
205
|
+
false,
|
|
206
|
+
"must not report a successful handoff when DB recovery was skipped",
|
|
207
|
+
);
|
|
208
|
+
assert.ok(_getPendingAutoStart(base), "pending handoff should remain for a later recovery attempt");
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test("missing DB row with CONTEXT.md inserts a queued row and accepts handoff", () => {
|
|
212
|
+
base = mkFlatBase();
|
|
213
|
+
openDatabase(":memory:");
|
|
214
|
+
writeFlatContext(base);
|
|
215
|
+
|
|
216
|
+
cap = mkCapture();
|
|
217
|
+
setPendingAutoStart(base, {
|
|
218
|
+
basePath: base,
|
|
219
|
+
milestoneId: "M001",
|
|
220
|
+
startAuto: false,
|
|
221
|
+
ctx: mkCtx(cap),
|
|
222
|
+
pi: mkPi(cap),
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const result = checkAutoStartAfterDiscuss();
|
|
226
|
+
|
|
227
|
+
assert.equal(result, true, "successful insert should recover the missing row");
|
|
228
|
+
assert.equal(getMilestone("M001")?.status, "queued");
|
|
229
|
+
assert.deepEqual(cap.notifies[0], {
|
|
230
|
+
msg: "Milestone M001 context captured. Continuing the planning pipeline.",
|
|
231
|
+
level: "success",
|
|
232
|
+
});
|
|
233
|
+
});
|
|
145
234
|
});
|
|
@@ -40,6 +40,10 @@ describe('ensureGitignore writes .bg-shell/ baseline (#4902)', () => {
|
|
|
40
40
|
lines.has('.bg-shell/'),
|
|
41
41
|
`.gitignore should include .bg-shell/. Got:\n${ignore}`,
|
|
42
42
|
);
|
|
43
|
+
assert.ok(
|
|
44
|
+
lines.has('.gsd-backups/'),
|
|
45
|
+
`.gitignore should include .gsd-backups/. Got:\n${ignore}`,
|
|
46
|
+
);
|
|
43
47
|
} finally {
|
|
44
48
|
cleanup(dir);
|
|
45
49
|
}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
clearPendingAutoStart,
|
|
21
21
|
checkAutoStartAfterDiscuss,
|
|
22
22
|
} from "../guided-flow.ts";
|
|
23
|
+
import { closeDatabase, openDatabase } from "../gsd-db.ts";
|
|
23
24
|
|
|
24
25
|
function pendingInput(basePath: string, milestoneId: string) {
|
|
25
26
|
return {
|
|
@@ -34,6 +35,7 @@ function pendingInput(basePath: string, milestoneId: string) {
|
|
|
34
35
|
|
|
35
36
|
describe("#2985 Bug 3 — concurrent discuss sessions must be independent", () => {
|
|
36
37
|
beforeEach(() => {
|
|
38
|
+
closeDatabase();
|
|
37
39
|
clearPendingAutoStart();
|
|
38
40
|
});
|
|
39
41
|
|
|
@@ -75,6 +77,7 @@ describe("#2985 Bug 3 — concurrent discuss sessions must be independent", () =
|
|
|
75
77
|
|
|
76
78
|
describe("#2985 Bug 4 — getDiscussionMilestoneId must be keyed by basePath", () => {
|
|
77
79
|
beforeEach(() => {
|
|
80
|
+
closeDatabase();
|
|
78
81
|
clearPendingAutoStart();
|
|
79
82
|
});
|
|
80
83
|
|
|
@@ -110,6 +113,7 @@ describe("#2985 Bug 4 — getDiscussionMilestoneId must be keyed by basePath", (
|
|
|
110
113
|
test("checkAutoStartAfterDiscuss ignores missing manifest for single-milestone discuss on established project", () => {
|
|
111
114
|
const base = mkdtempSync(join(tmpdir(), "gsd-auto-start-manifest-"));
|
|
112
115
|
try {
|
|
116
|
+
openDatabase(":memory:");
|
|
113
117
|
const gsdDir = join(base, ".gsd");
|
|
114
118
|
const milestoneDir = join(gsdDir, "milestones", "M001");
|
|
115
119
|
mkdirSync(milestoneDir, { recursive: true });
|
|
@@ -132,6 +136,7 @@ test("checkAutoStartAfterDiscuss ignores missing manifest for single-milestone d
|
|
|
132
136
|
const started = checkAutoStartAfterDiscuss();
|
|
133
137
|
assert.equal(started, true, "project history alone should not require a manifest");
|
|
134
138
|
} finally {
|
|
139
|
+
closeDatabase();
|
|
135
140
|
clearPendingAutoStart();
|
|
136
141
|
rmSync(base, { recursive: true, force: true });
|
|
137
142
|
}
|
|
@@ -151,6 +156,7 @@ test("checkAutoStartAfterDiscuss(basePath) selects the matching pending entry wh
|
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
try {
|
|
159
|
+
openDatabase(":memory:");
|
|
154
160
|
clearPendingAutoStart();
|
|
155
161
|
writeReadyArtifacts(projectA, "M001");
|
|
156
162
|
writeReadyArtifacts(projectB, "M002");
|
|
@@ -172,6 +178,7 @@ test("checkAutoStartAfterDiscuss(basePath) selects the matching pending entry wh
|
|
|
172
178
|
assert.equal(getDiscussionMilestoneId(projectA), "M001", "projectA should remain pending");
|
|
173
179
|
assert.equal(getDiscussionMilestoneId(projectB), null, "projectB should be cleared after start");
|
|
174
180
|
} finally {
|
|
181
|
+
closeDatabase();
|
|
175
182
|
clearPendingAutoStart();
|
|
176
183
|
rmSync(projectA, { recursive: true, force: true });
|
|
177
184
|
rmSync(projectB, { recursive: true, force: true });
|
|
@@ -183,6 +190,7 @@ test("checkAutoStartAfterDiscuss can accept context handoff without scheduling a
|
|
|
183
190
|
let waitForIdleCalls = 0;
|
|
184
191
|
const notifications: string[] = [];
|
|
185
192
|
try {
|
|
193
|
+
openDatabase(":memory:");
|
|
186
194
|
const gsdDir = join(base, ".gsd");
|
|
187
195
|
const milestoneDir = join(gsdDir, "milestones", "M001");
|
|
188
196
|
mkdirSync(milestoneDir, { recursive: true });
|
|
@@ -215,6 +223,7 @@ test("checkAutoStartAfterDiscuss can accept context handoff without scheduling a
|
|
|
215
223
|
assert.equal(waitForIdleCalls, 0, "headless-owned auto start must not schedule guided-flow auto");
|
|
216
224
|
assert.equal(getDiscussionMilestoneId(base), null, "accepted handoff should still be cleared");
|
|
217
225
|
} finally {
|
|
226
|
+
closeDatabase();
|
|
218
227
|
clearPendingAutoStart();
|
|
219
228
|
rmSync(base, { recursive: true, force: true });
|
|
220
229
|
}
|
|
@@ -294,12 +294,13 @@ describe('git-service', async () => {
|
|
|
294
294
|
|
|
295
295
|
assert.deepStrictEqual(
|
|
296
296
|
RUNTIME_EXCLUSION_PATHS.length,
|
|
297
|
-
|
|
298
|
-
"exactly
|
|
297
|
+
18,
|
|
298
|
+
"exactly 18 runtime exclusion paths"
|
|
299
299
|
);
|
|
300
300
|
|
|
301
301
|
const expectedPaths = [
|
|
302
302
|
".gsd-worktrees/",
|
|
303
|
+
".gsd-backups/**",
|
|
303
304
|
".gsd/activity/",
|
|
304
305
|
".gsd/audit/",
|
|
305
306
|
".gsd/forensics/",
|
|
@@ -1623,11 +1624,13 @@ process.exit(result.status ?? 0);
|
|
|
1623
1624
|
// Create and track runtime files (simulates pre-.gitignore state)
|
|
1624
1625
|
mkdirSync(join(repo, ".gsd", "activity"), { recursive: true });
|
|
1625
1626
|
mkdirSync(join(repo, ".gsd", "runtime"), { recursive: true });
|
|
1627
|
+
mkdirSync(join(repo, ".gsd-backups", "migrate-old"), { recursive: true });
|
|
1626
1628
|
writeFileSync(join(repo, ".gsd", "completed-units.json"), '["u1"]');
|
|
1627
1629
|
writeFileSync(join(repo, ".gsd", "metrics.json"), '{}');
|
|
1628
1630
|
writeFileSync(join(repo, ".gsd", "STATE.md"), "# State");
|
|
1629
1631
|
writeFileSync(join(repo, ".gsd", "activity", "log.jsonl"), "{}");
|
|
1630
1632
|
writeFileSync(join(repo, ".gsd", "runtime", "data.json"), "{}");
|
|
1633
|
+
writeFileSync(join(repo, ".gsd-backups", "migrate-old", "marker.txt"), "backup");
|
|
1631
1634
|
writeFileSync(join(repo, "src.ts"), "code");
|
|
1632
1635
|
runGit(repo, ["add", "-A"]);
|
|
1633
1636
|
runGit(repo, ["commit", "-m", "init"]);
|
|
@@ -1636,6 +1639,8 @@ process.exit(result.status ?? 0);
|
|
|
1636
1639
|
const trackedBefore = run("git ls-files .gsd/", repo);
|
|
1637
1640
|
assert.ok(trackedBefore.includes("completed-units.json"), "untrack: precondition — completed-units tracked");
|
|
1638
1641
|
assert.ok(trackedBefore.includes("metrics.json"), "untrack: precondition — metrics tracked");
|
|
1642
|
+
const backupTrackedBefore = run("git ls-files .gsd-backups/", repo);
|
|
1643
|
+
assert.ok(backupTrackedBefore.includes("marker.txt"), "untrack: precondition — migration backup tracked");
|
|
1639
1644
|
|
|
1640
1645
|
// Run untrackRuntimeFiles
|
|
1641
1646
|
untrackRuntimeFiles(repo);
|
|
@@ -1643,6 +1648,8 @@ process.exit(result.status ?? 0);
|
|
|
1643
1648
|
// Runtime files should be removed from the index
|
|
1644
1649
|
const trackedAfter = run("git ls-files .gsd/", repo);
|
|
1645
1650
|
assert.deepStrictEqual(trackedAfter, "", "untrack: all runtime files removed from index");
|
|
1651
|
+
const backupTrackedAfter = run("git ls-files .gsd-backups/", repo);
|
|
1652
|
+
assert.deepStrictEqual(backupTrackedAfter, "", "untrack: migration backups removed from index");
|
|
1646
1653
|
|
|
1647
1654
|
// Non-runtime files remain tracked
|
|
1648
1655
|
const srcTracked = run("git ls-files src.ts", repo);
|
|
@@ -1653,6 +1660,8 @@ process.exit(result.status ?? 0);
|
|
|
1653
1660
|
"untrack: completed-units.json still on disk");
|
|
1654
1661
|
assert.ok(existsSync(join(repo, ".gsd", "metrics.json")),
|
|
1655
1662
|
"untrack: metrics.json still on disk");
|
|
1663
|
+
assert.ok(existsSync(join(repo, ".gsd-backups", "migrate-old", "marker.txt")),
|
|
1664
|
+
"untrack: migration backup still on disk");
|
|
1656
1665
|
|
|
1657
1666
|
// Idempotent — running again doesn't error
|
|
1658
1667
|
untrackRuntimeFiles(repo);
|
|
@@ -90,6 +90,8 @@ import { clearPathCache } from "../../paths.ts";
|
|
|
90
90
|
// Fixture Helpers
|
|
91
91
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
92
92
|
|
|
93
|
+
const UAT_VERDICT_GATE_RULE_NAME = "uat-verdict-gate (non-PASS observed; closeout enforces)";
|
|
94
|
+
|
|
93
95
|
function makeTempDir(): string {
|
|
94
96
|
return mkdtempSync(join(tmpdir(), "gsd-edge-cases-"));
|
|
95
97
|
}
|
|
@@ -280,7 +282,7 @@ function buildDispatchCtx(
|
|
|
280
282
|
|
|
281
283
|
function getUatVerdictGate(): import("../../auto-dispatch.ts").DispatchRule {
|
|
282
284
|
const rule = DISPATCH_RULES.find(
|
|
283
|
-
r => r.name ===
|
|
285
|
+
r => r.name === UAT_VERDICT_GATE_RULE_NAME,
|
|
284
286
|
);
|
|
285
287
|
assert.ok(rule, "uat-verdict-gate rule should be registered");
|
|
286
288
|
return rule;
|
|
@@ -867,7 +869,7 @@ describe("dispatch failure modes", () => {
|
|
|
867
869
|
// Verify critical ordering constraints
|
|
868
870
|
const summarizeIdx = ruleNames.indexOf("summarizing → complete-slice");
|
|
869
871
|
const runUatIdx = ruleNames.indexOf("run-uat (post-completion)");
|
|
870
|
-
const uatGateIdx = ruleNames.indexOf(
|
|
872
|
+
const uatGateIdx = ruleNames.indexOf(UAT_VERDICT_GATE_RULE_NAME);
|
|
871
873
|
const executeIdx = ruleNames.indexOf("executing → execute-task");
|
|
872
874
|
|
|
873
875
|
// summarizing should come before execute-task
|
|
@@ -19,6 +19,7 @@ import { tmpdir } from "node:os";
|
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
21
|
saveJsonFile,
|
|
22
|
+
saveJsonFileCompact,
|
|
22
23
|
loadJsonFile,
|
|
23
24
|
writeJsonFileAtomic,
|
|
24
25
|
} from "../json-persistence.ts";
|
|
@@ -56,6 +57,37 @@ test("saveJsonFile creates file with valid JSON content", () => {
|
|
|
56
57
|
}
|
|
57
58
|
});
|
|
58
59
|
|
|
60
|
+
test("saveJsonFile keeps pretty-printed output for human-readable state", () => {
|
|
61
|
+
const dir = makeTempDir();
|
|
62
|
+
const filePath = join(dir, "pretty.json");
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const data = { foo: "bar", nested: { count: 42 } };
|
|
66
|
+
saveJsonFile(filePath, data);
|
|
67
|
+
|
|
68
|
+
const content = readFileSync(filePath, "utf-8");
|
|
69
|
+
assert.equal(content, JSON.stringify(data, null, 2) + "\n");
|
|
70
|
+
} finally {
|
|
71
|
+
cleanup(dir);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("saveJsonFileCompact writes valid compact JSON content", () => {
|
|
76
|
+
const dir = makeTempDir();
|
|
77
|
+
const filePath = join(dir, "compact.json");
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
const data = { foo: "bar", nested: { count: 42 } };
|
|
81
|
+
saveJsonFileCompact(filePath, data);
|
|
82
|
+
|
|
83
|
+
const content = readFileSync(filePath, "utf-8");
|
|
84
|
+
assert.equal(content, JSON.stringify(data) + "\n");
|
|
85
|
+
assert.deepEqual(JSON.parse(content), data);
|
|
86
|
+
} finally {
|
|
87
|
+
cleanup(dir);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
59
91
|
test("saveJsonFile does not leave .tmp files on success", () => {
|
|
60
92
|
const dir = makeTempDir();
|
|
61
93
|
const filePath = join(dir, "clean.json");
|
|
@@ -72,6 +104,21 @@ test("saveJsonFile does not leave .tmp files on success", () => {
|
|
|
72
104
|
}
|
|
73
105
|
});
|
|
74
106
|
|
|
107
|
+
test("saveJsonFileCompact does not leave .tmp files on success", () => {
|
|
108
|
+
const dir = makeTempDir();
|
|
109
|
+
const filePath = join(dir, "compact-clean.json");
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
saveJsonFileCompact(filePath, { test: true });
|
|
113
|
+
|
|
114
|
+
const files = readdirSync(dir);
|
|
115
|
+
const tmpFiles = files.filter(f => f.includes(".tmp"));
|
|
116
|
+
assert.equal(tmpFiles.length, 0, `Unexpected .tmp files: ${tmpFiles.join(", ")}`);
|
|
117
|
+
} finally {
|
|
118
|
+
cleanup(dir);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
75
122
|
test("saveJsonFile creates parent directories", () => {
|
|
76
123
|
const dir = makeTempDir();
|
|
77
124
|
const filePath = join(dir, "deep", "nested", "data.json");
|
|
@@ -161,6 +161,41 @@ test("backfill is idempotent — second run on the same file is a no-op", () =>
|
|
|
161
161
|
}
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
test("backfill skips a knowledge row whose memory insert throws and continues later rows", () => {
|
|
165
|
+
const base = makeTmpBase();
|
|
166
|
+
try {
|
|
167
|
+
writeKnowledgeMd(base, FIXTURE);
|
|
168
|
+
|
|
169
|
+
const adapter = _getAdapter();
|
|
170
|
+
assert.ok(adapter);
|
|
171
|
+
adapter.exec(`
|
|
172
|
+
CREATE TRIGGER fail_p002_memory_insert
|
|
173
|
+
BEFORE INSERT ON memories
|
|
174
|
+
WHEN json_extract(NEW.structured_fields, '$.sourceKnowledgeId') = 'P002'
|
|
175
|
+
BEGIN
|
|
176
|
+
SELECT RAISE(ABORT, 'poison knowledge P002');
|
|
177
|
+
END
|
|
178
|
+
`);
|
|
179
|
+
|
|
180
|
+
const written = backfillKnowledgeToMemories(base);
|
|
181
|
+
assert.equal(written, 2, "one poisoned row should not abort the batch");
|
|
182
|
+
|
|
183
|
+
const rows = adapter
|
|
184
|
+
.prepare(
|
|
185
|
+
"SELECT structured_fields FROM memories WHERE structured_fields LIKE '%\"sourceKnowledgeId\":\"%' ORDER BY seq",
|
|
186
|
+
)
|
|
187
|
+
.all() as Array<{ structured_fields: string }>;
|
|
188
|
+
|
|
189
|
+
assert.deepEqual(
|
|
190
|
+
rows.map((row) => JSON.parse(row.structured_fields).sourceKnowledgeId),
|
|
191
|
+
["P001", "L001"],
|
|
192
|
+
"rows after the poisoned knowledge entry should still be migrated",
|
|
193
|
+
);
|
|
194
|
+
} finally {
|
|
195
|
+
cleanup(base);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
164
199
|
test("backfill returns 0 when KNOWLEDGE.md is absent", () => {
|
|
165
200
|
const base = makeTmpBase();
|
|
166
201
|
try {
|