@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
|
@@ -182,6 +182,70 @@ test("prefs wizard save path preserves every known preference key", async () =>
|
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
+
test("verification wizard prompts for per-unit cost cap and persists it (regression #1121)", async () => {
|
|
186
|
+
// Regression for #1121: the `/gsd prefs` Verification category never prompted for
|
|
187
|
+
// `per_unit_cost_cap_usd`, so the per-unit cost cap could only be set by hand-editing
|
|
188
|
+
// PREFERENCES.md. Drive the wizard into Verification, answer the cap prompt, and assert
|
|
189
|
+
// the prompt exists and the entered value is serialized + round-trips back as a number.
|
|
190
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-"));
|
|
191
|
+
const prefsPath = join(dir, "PREFERENCES.md");
|
|
192
|
+
|
|
193
|
+
const inputLabels: string[] = [];
|
|
194
|
+
let topMenuVisits = 0;
|
|
195
|
+
|
|
196
|
+
const ctx = {
|
|
197
|
+
ui: {
|
|
198
|
+
notify() {},
|
|
199
|
+
select: async (label: string, options: string[]) => {
|
|
200
|
+
if (label === "GSD Preferences") {
|
|
201
|
+
topMenuVisits += 1;
|
|
202
|
+
if (topMenuVisits === 1) {
|
|
203
|
+
const verification = options.find((o) => o.startsWith("Verification"));
|
|
204
|
+
assert.ok(verification, "wizard menu must offer a Verification category");
|
|
205
|
+
return verification;
|
|
206
|
+
}
|
|
207
|
+
return "── Save & Exit ──";
|
|
208
|
+
}
|
|
209
|
+
// verification_commands string-list sub-menu — leave it untouched
|
|
210
|
+
if (options.includes("Done")) return "Done";
|
|
211
|
+
// boolean/enum prompts within the category — keep the current value
|
|
212
|
+
if (options.includes("(keep current)")) return "(keep current)";
|
|
213
|
+
return options[options.length - 1];
|
|
214
|
+
},
|
|
215
|
+
input: async (label: string) => {
|
|
216
|
+
inputLabels.push(label);
|
|
217
|
+
if (label.includes("Per-unit cost cap")) return "12.5";
|
|
218
|
+
return null; // escape every other numeric/string prompt (no change)
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
waitForIdle: async () => {},
|
|
222
|
+
reload: async () => {},
|
|
223
|
+
} as any;
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
|
|
227
|
+
|
|
228
|
+
// The Verification wizard must actually ask for the per-unit cost cap.
|
|
229
|
+
assert.ok(
|
|
230
|
+
inputLabels.some((l) => l.includes("Per-unit cost cap")),
|
|
231
|
+
`Verification wizard must prompt for the per-unit cost cap; prompts seen:\n${inputLabels.join("\n")}`,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// The entered value must be serialized to PREFERENCES.md...
|
|
235
|
+
const saved = readFileSync(prefsPath, "utf-8");
|
|
236
|
+
assert.match(saved, /per_unit_cost_cap_usd:\s*12\.5(\s|$)/m);
|
|
237
|
+
|
|
238
|
+
// ...and round-trip back through the parser/validator as a number.
|
|
239
|
+
const parsed = parsePreferencesMarkdown(saved);
|
|
240
|
+
assert.notEqual(parsed, null);
|
|
241
|
+
const { errors, preferences } = validatePreferences(parsed!);
|
|
242
|
+
assert.deepEqual(errors, []);
|
|
243
|
+
assert.equal(preferences.per_unit_cost_cap_usd, 12.5);
|
|
244
|
+
} finally {
|
|
245
|
+
rmSync(dir, { recursive: true, force: true });
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
185
249
|
test("category summaries expose the wizard menu surface for configured prefs", () => {
|
|
186
250
|
const summaries = buildCategorySummaries(PREF_SAMPLE_VALUES);
|
|
187
251
|
assert.deepEqual(
|
|
@@ -203,11 +267,14 @@ test("category summaries expose the wizard menu surface for configured prefs", (
|
|
|
203
267
|
"timeouts",
|
|
204
268
|
"uok",
|
|
205
269
|
"verification",
|
|
270
|
+
"workspace",
|
|
206
271
|
],
|
|
207
272
|
);
|
|
208
273
|
assert.match(summaries.models, /phase/);
|
|
209
274
|
assert.match(summaries.integrations, /remote: C123/);
|
|
210
275
|
assert.match(summaries.verification, /1 cmd/);
|
|
276
|
+
assert.match(summaries.workspace, /mode: parent/);
|
|
277
|
+
assert.match(summaries.workspace, /1 repo/);
|
|
211
278
|
});
|
|
212
279
|
|
|
213
280
|
test("models wizard offers discovered models for enabled providers", async () => {
|
|
@@ -276,3 +343,78 @@ test("models wizard offers discovered models for enabled providers", async () =>
|
|
|
276
343
|
rmSync(dir, { recursive: true, force: true });
|
|
277
344
|
}
|
|
278
345
|
});
|
|
346
|
+
|
|
347
|
+
test("workspace wizard category configures parent mode with a declared repository", async () => {
|
|
348
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-workspace-"));
|
|
349
|
+
const prefsPath = join(dir, "PREFERENCES.md");
|
|
350
|
+
try {
|
|
351
|
+
// Drive: Workspace → parent mode → Add repository (id=frontend, path=frontend,
|
|
352
|
+
// role=ui, verification=npm test, commit policy auto) → Done → Save & Exit.
|
|
353
|
+
const selects = [
|
|
354
|
+
"Workspace (single-repo)", // pick the Workspace category
|
|
355
|
+
"parent", // promptEnum: workspace mode
|
|
356
|
+
"Add repository", // sub-menu
|
|
357
|
+
"(keep current)", // promptEnum: commit policy -> keep auto default
|
|
358
|
+
"Done", // exit repo sub-menu
|
|
359
|
+
"── Save & Exit ──", // exit wizard
|
|
360
|
+
];
|
|
361
|
+
const inputs = [
|
|
362
|
+
"frontend", // repository id
|
|
363
|
+
"frontend", // repository path
|
|
364
|
+
"ui", // role
|
|
365
|
+
"npm test", // verification commands
|
|
366
|
+
];
|
|
367
|
+
const ctx = {
|
|
368
|
+
ui: {
|
|
369
|
+
notify() {},
|
|
370
|
+
select: async () => selects.shift(),
|
|
371
|
+
input: async () => inputs.shift(),
|
|
372
|
+
},
|
|
373
|
+
waitForIdle: async () => {},
|
|
374
|
+
reload: async () => {},
|
|
375
|
+
} as any;
|
|
376
|
+
|
|
377
|
+
await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
|
|
378
|
+
|
|
379
|
+
const saved = readFileSync(prefsPath, "utf-8");
|
|
380
|
+
assert.match(saved, /mode: parent/);
|
|
381
|
+
assert.match(saved, /frontend:/);
|
|
382
|
+
assert.match(saved, /path: frontend/);
|
|
383
|
+
assert.match(saved, /role: ui/);
|
|
384
|
+
assert.match(saved, /npm test/);
|
|
385
|
+
assert.equal(selects.length, 0, "all queued selects should be consumed");
|
|
386
|
+
assert.equal(inputs.length, 0, "all queued inputs should be consumed");
|
|
387
|
+
} finally {
|
|
388
|
+
rmSync(dir, { recursive: true, force: true });
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
test("workspace wizard does not save parent mode when no repository is declared", async () => {
|
|
393
|
+
const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-workspace-empty-"));
|
|
394
|
+
const prefsPath = join(dir, "PREFERENCES.md");
|
|
395
|
+
try {
|
|
396
|
+
// parent mode with no repos added → should warn and not persist workspace.
|
|
397
|
+
const selects = [
|
|
398
|
+
"Workspace (single-repo)",
|
|
399
|
+
"parent",
|
|
400
|
+
"Done", // add nothing
|
|
401
|
+
"── Save & Exit ──",
|
|
402
|
+
];
|
|
403
|
+
const ctx = {
|
|
404
|
+
ui: {
|
|
405
|
+
notify() {},
|
|
406
|
+
select: async () => selects.shift(),
|
|
407
|
+
input: async () => "",
|
|
408
|
+
},
|
|
409
|
+
waitForIdle: async () => {},
|
|
410
|
+
reload: async () => {},
|
|
411
|
+
} as any;
|
|
412
|
+
|
|
413
|
+
await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
|
|
414
|
+
|
|
415
|
+
const saved = readFileSync(prefsPath, "utf-8");
|
|
416
|
+
assert.doesNotMatch(saved, /mode: parent/, "parent mode must not persist without a declared repo");
|
|
417
|
+
} finally {
|
|
418
|
+
rmSync(dir, { recursive: true, force: true });
|
|
419
|
+
}
|
|
420
|
+
});
|
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
getSlice,
|
|
18
18
|
} from "../gsd-db.ts";
|
|
19
19
|
import { autoHealSketchFlags } from "../state-reconciliation/drift/sketch-flag.ts";
|
|
20
|
-
import { deriveState, deriveStateFromDb } from "../state.ts";
|
|
20
|
+
import { deriveState, deriveStateFromDb, invalidateStateCache } from "../state.ts";
|
|
21
|
+
import { reconcileBeforeDispatch } from "../state-reconciliation.ts";
|
|
21
22
|
import { resolveDispatch } from "../auto-dispatch.ts";
|
|
22
23
|
import type { DispatchContext } from "../auto-dispatch.ts";
|
|
23
24
|
|
|
@@ -174,7 +175,7 @@ test("ADR-011: refining + flag flipped OFF mid-milestone → falls through to pl
|
|
|
174
175
|
}
|
|
175
176
|
});
|
|
176
177
|
|
|
177
|
-
test("ADR-011: existing PLAN
|
|
178
|
+
test("ADR-011: existing PLAN + stale sketch flag heals via reconcileBeforeDispatch, then dispatch routes past refining (progressive_planning ON)", async (t) => {
|
|
178
179
|
const originalCwd = process.cwd();
|
|
179
180
|
const base = makeFixtureBase();
|
|
180
181
|
t.after(() => cleanup(base, originalCwd));
|
|
@@ -188,11 +189,22 @@ test("ADR-011: existing PLAN heals stale sketch flag via deriveStateFromDb (prog
|
|
|
188
189
|
);
|
|
189
190
|
process.chdir(base);
|
|
190
191
|
|
|
191
|
-
//
|
|
192
|
-
//
|
|
192
|
+
// Derivation is pure (ADR-017): a stale sketch flag (PLAN on disk but
|
|
193
|
+
// is_sketch=1) yields 'refining' and must NOT mutate the DB. Healing is
|
|
194
|
+
// owned by reconcileBeforeDispatch, which runs before every dispatch.
|
|
195
|
+
invalidateStateCache();
|
|
196
|
+
const beforeReconcile = await deriveStateFromDb(base);
|
|
197
|
+
assert.equal(beforeReconcile.activeSlice?.id, "S02");
|
|
198
|
+
assert.equal(beforeReconcile.phase, "refining", "derive alone must not heal the stale sketch flag");
|
|
199
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "derive must not mutate is_sketch");
|
|
200
|
+
|
|
201
|
+
const reconcile = await reconcileBeforeDispatch(base);
|
|
202
|
+
assert.equal(reconcile.ok, true);
|
|
203
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile clears the stale sketch flag once PLAN exists");
|
|
204
|
+
|
|
205
|
+
invalidateStateCache();
|
|
193
206
|
const state = await deriveStateFromDb(base);
|
|
194
|
-
assert.equal(
|
|
195
|
-
assert.equal(state.phase, "planning", "derive: phase advances past refining once flag is healed");
|
|
207
|
+
assert.equal(state.phase, "planning", "re-derive advances past refining once the flag is healed");
|
|
196
208
|
|
|
197
209
|
const ctx: DispatchContext = {
|
|
198
210
|
basePath: base,
|
|
@@ -229,7 +241,7 @@ test("ADR-011: autoHealSketchFlags flips is_sketch=0 when PLAN file exists", asy
|
|
|
229
241
|
assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "post-heal: flag cleared");
|
|
230
242
|
});
|
|
231
243
|
|
|
232
|
-
test("ADR-011:
|
|
244
|
+
test("ADR-011: reconcileBeforeDispatch auto-heals stale sketch flag when PLAN exists", async (t) => {
|
|
233
245
|
const originalCwd = process.cwd();
|
|
234
246
|
const base = makeFixtureBase();
|
|
235
247
|
t.after(() => cleanup(base, originalCwd));
|
|
@@ -244,12 +256,23 @@ test("ADR-011: deriveStateFromDb auto-heals stale sketch flag when PLAN exists",
|
|
|
244
256
|
);
|
|
245
257
|
process.chdir(base);
|
|
246
258
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
259
|
+
// Pure derivation reports the stale flag as 'refining' without repairing it.
|
|
260
|
+
invalidateStateCache();
|
|
261
|
+
const stale = await deriveStateFromDb(base);
|
|
262
|
+
assert.equal(stale.phase, "refining", "derive alone must not heal the stale flag");
|
|
263
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "is_sketch unchanged before reconcile");
|
|
264
|
+
|
|
265
|
+
// Reconciliation owns the repair (ADR-017 stale-sketch-flag drift handler).
|
|
266
|
+
const reconcile = await reconcileBeforeDispatch(base);
|
|
267
|
+
assert.equal(reconcile.ok, true);
|
|
268
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile should clear stale is_sketch");
|
|
269
|
+
|
|
270
|
+
invalidateStateCache();
|
|
271
|
+
const healed = await deriveStateFromDb(base);
|
|
272
|
+
assert.equal(healed.phase, "planning", "state advances past refining once the stale flag is healed");
|
|
250
273
|
});
|
|
251
274
|
|
|
252
|
-
test("ADR-011: deriveState
|
|
275
|
+
test("ADR-011: deriveState stays pure across worktree/canonical-root; healing belongs to reconcile at the canonical artifact root", async (t) => {
|
|
253
276
|
const originalCwd = process.cwd();
|
|
254
277
|
const base = makeFixtureBase();
|
|
255
278
|
t.after(() => cleanup(base, originalCwd));
|
|
@@ -265,9 +288,22 @@ test("ADR-011: deriveState uses canonical artifact root for sketch-flag healing"
|
|
|
265
288
|
mkdirSync(worktreePath, { recursive: true });
|
|
266
289
|
process.chdir(worktreePath);
|
|
267
290
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
291
|
+
// Deriving from the worktree with reads routed to the canonical artifact
|
|
292
|
+
// root resolves DB state but never mutates it (ADR-017: derive is pure).
|
|
293
|
+
// The legacy projectRootForReads-driven heal is gone; healing now happens
|
|
294
|
+
// in reconcileBeforeDispatch, which auto runs against canonicalProjectRoot.
|
|
295
|
+
invalidateStateCache();
|
|
296
|
+
const beforeReconcile = await deriveState(worktreePath, { projectRootForReads: base });
|
|
297
|
+
assert.equal(beforeReconcile.phase, "refining", "derive alone must not heal, even via projectRootForReads");
|
|
298
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "derive must not mutate is_sketch");
|
|
299
|
+
|
|
300
|
+
const reconcile = await reconcileBeforeDispatch(base);
|
|
301
|
+
assert.equal(reconcile.ok, true);
|
|
302
|
+
assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile at the canonical root heals the stale flag");
|
|
303
|
+
|
|
304
|
+
invalidateStateCache();
|
|
305
|
+
const healed = await deriveState(worktreePath, { projectRootForReads: base });
|
|
306
|
+
assert.equal(healed.phase, "planning", "re-derive advances past refining once healed at the canonical root");
|
|
271
307
|
});
|
|
272
308
|
|
|
273
309
|
test("ADR-011: schema v16 is idempotent — re-opening DB preserves is_sketch and sketch_scope columns", async (t) => {
|
|
@@ -72,6 +72,25 @@ function setupDependencyFixture(
|
|
|
72
72
|
mkdirSync(targetSliceDir, { recursive: true });
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
function setupFlatPhaseSlicePlan(base: string): void {
|
|
76
|
+
const phaseDir = join(base, ".gsd", "phases", "01-flat-phase");
|
|
77
|
+
mkdirSync(phaseDir, { recursive: true });
|
|
78
|
+
writeFileSync(
|
|
79
|
+
join(phaseDir, "01-01-PLAN.md"),
|
|
80
|
+
[
|
|
81
|
+
"# S01: Flat phase slice",
|
|
82
|
+
"",
|
|
83
|
+
"## Tasks",
|
|
84
|
+
"",
|
|
85
|
+
"- [ ] **T01: Flat task** `est:15m`",
|
|
86
|
+
"",
|
|
87
|
+
"## Verification",
|
|
88
|
+
"",
|
|
89
|
+
"- Rendered prompt points at this slice plan.",
|
|
90
|
+
].join("\n"),
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
75
94
|
// ─── inlineDependencySummaries truncation ─────────────────────────────────────
|
|
76
95
|
|
|
77
96
|
describe("prompt-budget: inlineDependencySummaries truncation", () => {
|
|
@@ -412,6 +431,26 @@ describe("prompt-budget: execute-task template", () => {
|
|
|
412
431
|
}
|
|
413
432
|
});
|
|
414
433
|
|
|
434
|
+
it("flat-phase execute-task fallback points at the slice plan", async () => {
|
|
435
|
+
const base = createFixtureBase();
|
|
436
|
+
try {
|
|
437
|
+
setupFlatPhaseSlicePlan(base);
|
|
438
|
+
|
|
439
|
+
const prompt = await buildExecuteTaskPrompt("M001", "S01", "Slice", "T01", "Task", base, {
|
|
440
|
+
level: "minimal",
|
|
441
|
+
sessionContextWindow: 128_000,
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
assert.match(
|
|
445
|
+
prompt,
|
|
446
|
+
/Task plan not found at dispatch time\. Read `\.gsd\/phases\/01-flat-phase\/01-01-PLAN\.md` before executing\./,
|
|
447
|
+
);
|
|
448
|
+
assert.doesNotMatch(prompt, /\.gsd\/phases\/01-flat-phase\/tasks\/T01-PLAN\.md/);
|
|
449
|
+
} finally {
|
|
450
|
+
cleanup(base);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
|
|
415
454
|
it("verificationBudget format varies with context window size", () => {
|
|
416
455
|
const budget128K = computeBudgets(128_000);
|
|
417
456
|
const budget1M = computeBudgets(1_000_000);
|
|
@@ -566,6 +605,25 @@ describe("prompt-budget: execute-task builder truncation pattern", () => {
|
|
|
566
605
|
});
|
|
567
606
|
|
|
568
607
|
describe("prompt-budget: reactive-execute builder", () => {
|
|
608
|
+
it("flat-phase subagent fallback points at the slice plan", async () => {
|
|
609
|
+
const base = createFixtureBase();
|
|
610
|
+
try {
|
|
611
|
+
setupFlatPhaseSlicePlan(base);
|
|
612
|
+
|
|
613
|
+
const prompt = await buildReactiveExecutePrompt("M001", "Milestone", "S01", "Slice", ["T01"], base, undefined, {
|
|
614
|
+
sessionContextWindow: 128_000,
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
assert.match(
|
|
618
|
+
prompt,
|
|
619
|
+
/Task plan not found at dispatch time\. Read `\.gsd\/phases\/01-flat-phase\/01-01-PLAN\.md` before executing\./,
|
|
620
|
+
);
|
|
621
|
+
assert.doesNotMatch(prompt, /\.gsd\/phases\/01-flat-phase\/tasks\/T01-PLAN\.md/);
|
|
622
|
+
} finally {
|
|
623
|
+
cleanup(base);
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
569
627
|
it("caps dependency carry-forward per ready subagent", async () => {
|
|
570
628
|
const base = createFixtureBase();
|
|
571
629
|
try {
|
|
@@ -533,6 +533,7 @@ test("plan-milestone prompt references DB-backed planning tool and explicitly fo
|
|
|
533
533
|
assert.match(prompt, /Do \*\*not\*\* write `?\{\{outputPath\}\}`?, `?ROADMAP\.md`?, or other planning artifacts manually/i);
|
|
534
534
|
assert.match(prompt, /NEVER call `gsd_plan_milestone` with only `milestoneId` and `sliceId`/);
|
|
535
535
|
assert.match(prompt, /gsd_plan_slice/);
|
|
536
|
+
assert.match(prompt, /gsd_plan_task/);
|
|
536
537
|
});
|
|
537
538
|
|
|
538
539
|
test("discuss prompts forbid gsd_plan_milestone slice-only tool args", () => {
|
|
@@ -548,12 +549,12 @@ test("plan-slice prompt no longer frames direct PLAN writes as the source of tru
|
|
|
548
549
|
assert.match(prompt, /Do \*\*not\*\* rely on direct `PLAN\.md` writes as the source of truth/i);
|
|
549
550
|
});
|
|
550
551
|
|
|
551
|
-
test("plan-slice prompt explicitly names
|
|
552
|
+
test("plan-slice prompt explicitly names incremental DB-backed planning tools", () => {
|
|
552
553
|
const prompt = readPrompt("plan-slice");
|
|
553
554
|
assert.match(prompt, /gsd_plan_slice/);
|
|
554
555
|
assert.match(prompt, /gsd_plan_task/);
|
|
555
|
-
|
|
556
|
-
assert.match(prompt, /DB-backed
|
|
556
|
+
assert.match(prompt, /Persist incrementally through DB-backed tools/i);
|
|
557
|
+
assert.match(prompt, /DB-backed tools are the canonical write path/i);
|
|
557
558
|
});
|
|
558
559
|
|
|
559
560
|
test("plan-slice prompt does not instruct direct file writes as a primary step", () => {
|
|
@@ -562,11 +563,12 @@ test("plan-slice prompt does not instruct direct file writes as a primary step",
|
|
|
562
563
|
assert.doesNotMatch(prompt, /^\d+\.\s+Write `?\{\{outputPath\}\}`?\s*$/m);
|
|
563
564
|
});
|
|
564
565
|
|
|
565
|
-
test("plan-slice prompt
|
|
566
|
+
test("plan-slice prompt requires per-task incremental persistence", () => {
|
|
566
567
|
const prompt = readPrompt("plan-slice");
|
|
567
|
-
// gsd_plan_slice persists tasks in its transaction — no separate gsd_plan_task calls needed
|
|
568
568
|
assert.match(prompt, /gsd_plan_task/);
|
|
569
|
-
assert.match(prompt, /
|
|
569
|
+
assert.match(prompt, /omit `tasks` for this metadata call/i);
|
|
570
|
+
assert.match(prompt, /call `gsd_plan_task` once per task/i);
|
|
571
|
+
assert.doesNotMatch(prompt, /do not call `gsd_plan_task`/i);
|
|
570
572
|
});
|
|
571
573
|
|
|
572
574
|
test("plan-slice prompt references web app UAT guidance when planning browser work", () => {
|
|
@@ -227,7 +227,7 @@ test("plan-slice verify-fail logs a recovery warning when the tasks dir is missi
|
|
|
227
227
|
}
|
|
228
228
|
});
|
|
229
229
|
|
|
230
|
-
test("plan-slice verify-fail logs a recovery warning when an individual task
|
|
230
|
+
test("plan-slice verify-fail logs a recovery warning when an individual task artifact is missing", () => {
|
|
231
231
|
const base = createFixtureBase("gsd-recovery-logs-taskplan-");
|
|
232
232
|
try {
|
|
233
233
|
const dir = sliceDir(base, "M001", "S01");
|
|
@@ -236,17 +236,17 @@ test("plan-slice verify-fail logs a recovery warning when an individual task pla
|
|
|
236
236
|
"# S01: Has task\n\n## Tasks\n\n- [ ] **T01: A** `est:15m`\n",
|
|
237
237
|
"utf-8",
|
|
238
238
|
);
|
|
239
|
-
// Create the tasks dir but NOT
|
|
239
|
+
// Create the tasks dir but NOT any T01 task artifact inside it.
|
|
240
240
|
mkdirSync(join(dir, "tasks"), { recursive: true });
|
|
241
241
|
|
|
242
242
|
const { result, logs } = verifyAndCaptureLogs("plan-slice", "M001/S01", base);
|
|
243
243
|
|
|
244
|
-
assert.equal(result, false, "a missing task
|
|
244
|
+
assert.equal(result, false, "a missing task artifact must fail verification");
|
|
245
245
|
const recovery = findRecovery(logs);
|
|
246
246
|
assert.ok(recovery, "a recovery warning must be logged");
|
|
247
247
|
assert.match(
|
|
248
248
|
recovery!.message,
|
|
249
|
-
/verify-fail plan-slice M001\/S01: task
|
|
249
|
+
/verify-fail plan-slice M001\/S01: task artifact missing for T01/u,
|
|
250
250
|
);
|
|
251
251
|
} finally {
|
|
252
252
|
rmSync(base, { recursive: true, force: true });
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// redact-secrets.test.ts
|
|
2
|
+
// Verifies secret-shaped substrings are replaced while benign text and JSON
|
|
3
|
+
// structure are preserved.
|
|
4
|
+
//
|
|
5
|
+
// Fake secrets are assembled from fragments at runtime so external secret
|
|
6
|
+
// scanners (GitGuardian) and the repo secret-scan never see a literal
|
|
7
|
+
// secret-shaped string in this source file — the runtime value still matches
|
|
8
|
+
// the redaction patterns, which is what the test exercises.
|
|
9
|
+
|
|
10
|
+
import { test } from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { redactSecrets } from "../redact-secrets.js";
|
|
13
|
+
|
|
14
|
+
const PLACEHOLDER = "«redacted»";
|
|
15
|
+
|
|
16
|
+
// Fragment-built fakes (never a full secret literal in source).
|
|
17
|
+
const FAKE = {
|
|
18
|
+
github: "gh" + "p_" + "A".repeat(36), // GitHub PAT shape: ghp_ + 36 chars
|
|
19
|
+
aws: "AKIA" + "IOSFODNN7EXAMPL0", // AWS access key id shape: AKIA + 16 chars
|
|
20
|
+
anthropic: "sk-" + "ant-" + "x".repeat(28), // Anthropic key shape
|
|
21
|
+
bearer: "sk-" + "b".repeat(24), // generic sk- token
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
test("redacts a Bearer authorization token", () => {
|
|
25
|
+
const out = redactSecrets(`Authorization: Bearer ${FAKE.bearer}`);
|
|
26
|
+
assert.ok(out.includes("Authorization:"), "keeps the label context");
|
|
27
|
+
assert.ok(out.includes(PLACEHOLDER), "redacts the token");
|
|
28
|
+
assert.ok(!out.includes(FAKE.bearer), "raw token is gone");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("redacts key=value style secrets", () => {
|
|
32
|
+
const anth = redactSecrets(`ANTHROPIC_API_KEY="${FAKE.anthropic}"`);
|
|
33
|
+
assert.ok(anth.includes(PLACEHOLDER) && !anth.includes(FAKE.anthropic));
|
|
34
|
+
const gh = redactSecrets(`"token": "${FAKE.github}"`);
|
|
35
|
+
assert.ok(gh.includes(PLACEHOLDER) && !gh.includes(FAKE.github));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("redacts an AWS access key id", () => {
|
|
39
|
+
const out = redactSecrets(`aws key ${FAKE.aws} in output`);
|
|
40
|
+
assert.ok(out.includes(PLACEHOLDER) && !out.includes(FAKE.aws));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("leaves benign text mentioning 'token' untouched", () => {
|
|
44
|
+
const line = "The token is passed to the next unit for processing.";
|
|
45
|
+
assert.equal(redactSecrets(line), line);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("redacting a JSON string keeps it valid JSON", () => {
|
|
49
|
+
const original = JSON.stringify({ msg: "using key=SECRETVALUE here", auth: FAKE.github });
|
|
50
|
+
const redacted = redactSecrets(original);
|
|
51
|
+
// Must still parse.
|
|
52
|
+
const parsed = JSON.parse(redacted) as { msg: string; auth: string };
|
|
53
|
+
// The bare GitHub token is redacted; the non-keyword "key=..." stays (no false structure break).
|
|
54
|
+
assert.ok(!redacted.includes(FAKE.github));
|
|
55
|
+
assert.equal(parsed.auth, PLACEHOLDER);
|
|
56
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Verifies session bootstrap fails closed when flat-phase migration cannot complete.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
|
|
10
|
+
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
11
|
+
import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
|
|
12
|
+
|
|
13
|
+
type HookHandler = (event: unknown, ctx: any) => Promise<void> | void;
|
|
14
|
+
|
|
15
|
+
function createSessionStartHandler(): HookHandler {
|
|
16
|
+
const handlers = new Map<string, HookHandler>();
|
|
17
|
+
const pi = {
|
|
18
|
+
on(event: string, handler: HookHandler) {
|
|
19
|
+
handlers.set(event, handler);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
registerHooks(pi as any, []);
|
|
24
|
+
const sessionStart = handlers.get("session_start");
|
|
25
|
+
assert.ok(sessionStart, "session_start handler should be registered");
|
|
26
|
+
return sessionStart;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function makeContext(basePath: string) {
|
|
30
|
+
return {
|
|
31
|
+
cwd: basePath,
|
|
32
|
+
hasUI: false,
|
|
33
|
+
ui: {
|
|
34
|
+
notify: () => {},
|
|
35
|
+
setStatus: () => {},
|
|
36
|
+
setWidget: () => {},
|
|
37
|
+
setWorkingMessage: () => {},
|
|
38
|
+
onTerminalInput: () => () => {},
|
|
39
|
+
},
|
|
40
|
+
model: null,
|
|
41
|
+
modelRegistry: {
|
|
42
|
+
setDisabledModelProviders: () => {},
|
|
43
|
+
},
|
|
44
|
+
sessionManager: {
|
|
45
|
+
getSessionId: () => null,
|
|
46
|
+
},
|
|
47
|
+
setCompactionThresholdOverride: () => {},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
test("session_start rejects when required flat-phase migration fails", async (t) => {
|
|
52
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-bootstrap-flat-migration-"));
|
|
53
|
+
t.after(() => {
|
|
54
|
+
closeDatabase();
|
|
55
|
+
rmSync(base, { recursive: true, force: true });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
59
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"), "# M001: Foundation\n", "utf-8");
|
|
60
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
61
|
+
insertMilestone({ id: "M001", title: "Foundation", status: "active" });
|
|
62
|
+
closeDatabase();
|
|
63
|
+
|
|
64
|
+
writeFileSync(join(base, ".gsd-backups"), "not a directory\n", "utf-8");
|
|
65
|
+
|
|
66
|
+
const sessionStart = createSessionStartHandler();
|
|
67
|
+
|
|
68
|
+
await assert.rejects(
|
|
69
|
+
() => Promise.resolve(sessionStart({}, makeContext(base))),
|
|
70
|
+
/flat-phase migration/,
|
|
71
|
+
);
|
|
72
|
+
assert.ok(existsSync(join(base, ".gsd", "milestones", "M001")), "legacy layout should remain for recovery");
|
|
73
|
+
});
|