@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.5c1a3ff2
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 +10 -8
- package/dist/cli.js +5 -1
- package/dist/headless-events.d.ts +2 -1
- package/dist/headless-events.js +11 -3
- package/dist/headless-milestone-readiness.d.ts +29 -0
- package/dist/headless-milestone-readiness.js +161 -0
- package/dist/headless.js +25 -2
- package/dist/print-mode-exit.d.ts +12 -0
- package/dist/print-mode-exit.js +14 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +18 -49
- package/dist/resources/extensions/browser-tools/capture.js +2 -77
- package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
- package/dist/resources/extensions/gsd/auto-dispatch.js +74 -19
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +125 -18
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +5 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +31 -5
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
- package/dist/resources/extensions/gsd/command-feedback.js +16 -12
- package/dist/resources/extensions/gsd/compat/compat-marker.js +19 -2
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +51 -16
- package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
- package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
- package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
- package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +3 -6
- package/dist/resources/extensions/gsd/flat-phase-migration.js +156 -21
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +187 -45
- package/dist/resources/extensions/gsd/guided-flow.js +38 -13
- package/dist/resources/extensions/gsd/markdown-renderer.js +17 -13
- package/dist/resources/extensions/gsd/md-importer.js +107 -20
- package/dist/resources/extensions/gsd/migrate/command.js +19 -162
- package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
- package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
- package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
- package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
- package/dist/resources/extensions/gsd/model-router.js +11 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
- package/dist/resources/extensions/gsd/paths.js +55 -11
- package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
- package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
- package/dist/resources/extensions/gsd/preferences-types.js +5 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
- package/dist/resources/extensions/gsd/preferences.js +17 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +27 -13
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +13 -3
- package/dist/resources/extensions/gsd/stop-notice.js +15 -1
- package/dist/resources/extensions/gsd/sync-lock.js +13 -7
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
- package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
- package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/unit-registry.js +4 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +6 -0
- package/dist/resources/extensions/mac-tools/index.js +31 -9
- 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 +8 -8
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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.js +2 -2
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +5 -5
- 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 +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +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/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/package.json +0 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.js +31 -3
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +12 -10
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/dist/cloud-config.d.ts +1 -1
- package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
- package/packages/daemon/dist/cloud-config.js +5 -1
- package/packages/daemon/dist/cloud-config.js.map +1 -1
- package/packages/daemon/dist/cloud-config.test.js +51 -1
- package/packages/daemon/dist/cloud-config.test.js.map +1 -1
- package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
- package/packages/daemon/dist/local-tool-executor.js +2 -0
- package/packages/daemon/dist/local-tool-executor.js.map +1 -1
- package/packages/daemon/package.json +6 -6
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/dist/cli.d.ts +5 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cli.js +160 -0
- package/packages/gsd-cloud/dist/cli.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.js +231 -0
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
- package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
- package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +35 -0
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js +258 -0
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
- package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/cloud-token.js +37 -0
- package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
- package/packages/gsd-cloud/dist/config.d.ts +17 -0
- package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/config.js +146 -0
- package/packages/gsd-cloud/dist/config.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
- package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.js +128 -0
- package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
- package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
- package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
- package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/executor.js +11 -0
- package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
- package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
- package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/index.js +29 -0
- package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
- package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
- package/packages/gsd-cloud/dist/index.d.ts +7 -0
- package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/index.js +8 -0
- package/packages/gsd-cloud/dist/index.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
- package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
- package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
- package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
- package/packages/gsd-cloud/dist/logger.d.ts +25 -0
- package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/logger.js +72 -0
- package/packages/gsd-cloud/dist/logger.js.map +1 -0
- package/packages/gsd-cloud/dist/types.d.ts +51 -0
- package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/types.js +9 -0
- package/packages/gsd-cloud/dist/types.js.map +1 -0
- package/packages/gsd-cloud/package.json +3 -3
- package/packages/mcp-server/README.md +15 -2
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +64 -2
- 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.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +119 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +107 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +25 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.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/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +18 -49
- package/src/resources/extensions/browser-tools/capture.ts +2 -86
- package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
- package/src/resources/extensions/gsd/auto-dispatch.ts +86 -19
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +142 -16
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -10
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
- package/src/resources/extensions/gsd/command-feedback.ts +19 -12
- package/src/resources/extensions/gsd/compat/compat-marker.ts +21 -4
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +53 -17
- package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
- package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
- package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
- package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +3 -5
- package/src/resources/extensions/gsd/flat-phase-migration.ts +160 -19
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +255 -52
- package/src/resources/extensions/gsd/guided-flow.ts +48 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +25 -21
- package/src/resources/extensions/gsd/md-importer.ts +114 -16
- package/src/resources/extensions/gsd/migrate/command.ts +21 -227
- package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
- package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
- package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
- package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
- package/src/resources/extensions/gsd/model-router.ts +12 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
- package/src/resources/extensions/gsd/paths.ts +62 -11
- package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
- package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
- package/src/resources/extensions/gsd/preferences.ts +25 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +30 -13
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +16 -3
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
- package/src/resources/extensions/gsd/stop-notice.ts +18 -1
- package/src/resources/extensions/gsd/sync-lock.ts +14 -6
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
- package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +17 -0
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
- package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
- package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
- package/src/resources/extensions/gsd/types.ts +11 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/unit-registry.ts +4 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +12 -0
- package/src/resources/extensions/mac-tools/index.ts +52 -9
- package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → 6YWV7VAPg-jqjfPswrKZb}/_ssgManifest.js +0 -0
|
@@ -56,6 +56,10 @@ function buildBlock(
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function expectedSkillRead(base: string, name: string): string {
|
|
60
|
+
return `Read the skill file at \`${join(base, "skills", name, "SKILL.md")}\``;
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
test("buildSkillActivationBlock does not auto-activate skills via broad context heuristic", () => {
|
|
60
64
|
const base = makeTempBase();
|
|
61
65
|
try {
|
|
@@ -92,7 +96,7 @@ test("buildSkillActivationBlock activates skills via prefer_skills when context
|
|
|
92
96
|
prefer_skills: ["react"],
|
|
93
97
|
});
|
|
94
98
|
|
|
95
|
-
assert.
|
|
99
|
+
assert.ok(result.includes(expectedSkillRead(base, "react")));
|
|
96
100
|
assert.doesNotMatch(result, /swiftui/);
|
|
97
101
|
} finally {
|
|
98
102
|
cleanup(base);
|
|
@@ -111,7 +115,7 @@ test("buildSkillActivationBlock includes always_use_skills using read-based skil
|
|
|
111
115
|
|
|
112
116
|
assert.equal(
|
|
113
117
|
result,
|
|
114
|
-
|
|
118
|
+
`<skill_activation>Read the skill file at \`${join(base, "skills", "swift-testing", "SKILL.md")}\`.</skill_activation>`,
|
|
115
119
|
);
|
|
116
120
|
} finally {
|
|
117
121
|
cleanup(base);
|
|
@@ -140,8 +144,8 @@ test("buildSkillActivationBlock includes skill_rules matches and task-plan skill
|
|
|
140
144
|
skill_rules: [{ when: "prisma database schema", use: ["prisma"] }],
|
|
141
145
|
});
|
|
142
146
|
|
|
143
|
-
assert.
|
|
144
|
-
assert.
|
|
147
|
+
assert.ok(result.includes(expectedSkillRead(base, "accessibility")));
|
|
148
|
+
assert.ok(result.includes(expectedSkillRead(base, "prisma")));
|
|
145
149
|
} finally {
|
|
146
150
|
cleanup(base);
|
|
147
151
|
}
|
|
@@ -163,7 +167,7 @@ test("buildSkillActivationBlock matches skill_rules against exact unit type cont
|
|
|
163
167
|
],
|
|
164
168
|
});
|
|
165
169
|
|
|
166
|
-
assert.
|
|
170
|
+
assert.ok(result.includes(expectedSkillRead(base, "complete-slice-policies")));
|
|
167
171
|
assert.doesNotMatch(result, /slice-broad/);
|
|
168
172
|
} finally {
|
|
169
173
|
cleanup(base);
|
|
@@ -267,8 +271,8 @@ test("buildSkillActivationBlock allows valid skill names and rejects invalid one
|
|
|
267
271
|
});
|
|
268
272
|
|
|
269
273
|
assert.match(result, /skill_activation/);
|
|
270
|
-
assert.
|
|
271
|
-
assert.
|
|
274
|
+
assert.ok(result.includes(expectedSkillRead(base, "react")));
|
|
275
|
+
assert.ok(result.includes(expectedSkillRead(base, "good-skill-2")));
|
|
272
276
|
assert.doesNotMatch(result, /bad'name/);
|
|
273
277
|
} finally {
|
|
274
278
|
cleanup(base);
|
|
@@ -292,8 +296,8 @@ test("buildSkillActivationBlock: explicit always_use_skills bypass the unit-type
|
|
|
292
296
|
always_use_skills: ["write-docs", "swiftui"],
|
|
293
297
|
});
|
|
294
298
|
|
|
295
|
-
assert.
|
|
296
|
-
assert.
|
|
299
|
+
assert.ok(result.includes(expectedSkillRead(base, "write-docs")));
|
|
300
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
297
301
|
} finally {
|
|
298
302
|
cleanup(base);
|
|
299
303
|
}
|
|
@@ -310,7 +314,7 @@ test("buildSkillActivationBlock falls through to all skills for unknown unit typ
|
|
|
310
314
|
});
|
|
311
315
|
|
|
312
316
|
// Unknown unit type = wildcard fallback (pre-manifest behavior).
|
|
313
|
-
assert.
|
|
317
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
314
318
|
} finally {
|
|
315
319
|
cleanup(base);
|
|
316
320
|
}
|
|
@@ -327,7 +331,7 @@ test("buildSkillActivationBlock without unitType preserves pre-manifest behavior
|
|
|
327
331
|
always_use_skills: ["swiftui"],
|
|
328
332
|
});
|
|
329
333
|
|
|
330
|
-
assert.
|
|
334
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
331
335
|
} finally {
|
|
332
336
|
cleanup(base);
|
|
333
337
|
}
|
|
@@ -344,12 +348,12 @@ test("milestone prompt builders propagate always_use_skills through buildSkillAc
|
|
|
344
348
|
loadOnlyTestSkills(base);
|
|
345
349
|
|
|
346
350
|
const researchPrompt = await buildResearchMilestonePrompt("M001", "Test", base);
|
|
347
|
-
assert.
|
|
348
|
-
assert.
|
|
351
|
+
assert.ok(researchPrompt.includes(expectedSkillRead(base, "write-docs")));
|
|
352
|
+
assert.ok(researchPrompt.includes(expectedSkillRead(base, "swiftui")));
|
|
349
353
|
|
|
350
354
|
const planPrompt = await buildPlanMilestonePrompt("M001", "Test", base);
|
|
351
|
-
assert.
|
|
352
|
-
assert.
|
|
355
|
+
assert.ok(planPrompt.includes(expectedSkillRead(base, "write-docs")));
|
|
356
|
+
assert.ok(planPrompt.includes(expectedSkillRead(base, "swiftui")));
|
|
353
357
|
} finally {
|
|
354
358
|
cleanup(base);
|
|
355
359
|
}
|
|
@@ -380,7 +384,7 @@ test("complete-slice prompt propagates always_use_skills through buildSkillActiv
|
|
|
380
384
|
|
|
381
385
|
const prompt = await buildCompleteSlicePrompt("M001", "Test", "S01", "Slice", base);
|
|
382
386
|
|
|
383
|
-
assert.
|
|
387
|
+
assert.ok(prompt.includes(expectedSkillRead(base, "write-docs")));
|
|
384
388
|
} finally {
|
|
385
389
|
cleanup(base);
|
|
386
390
|
}
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
updateTaskStatus,
|
|
26
26
|
} from "../gsd-db.ts";
|
|
27
27
|
import { handleSkipSlice } from "../tools/skip-slice.ts";
|
|
28
|
+
import { skipSliceCascade } from "../db/writers/cascades.ts";
|
|
28
29
|
|
|
29
30
|
describe("handleSkipSlice cascades skip to tasks (#4375)", () => {
|
|
30
31
|
let dir: string;
|
|
@@ -122,4 +123,24 @@ describe("handleSkipSlice cascades skip to tasks (#4375)", () => {
|
|
|
122
123
|
assert.match(result.error!, /not found/i);
|
|
123
124
|
assert.equal(result.errorCode, "slice_not_found");
|
|
124
125
|
});
|
|
126
|
+
|
|
127
|
+
test("skipSliceCascade rejects a slice in the legacy 'closed' status without nulling completed_at", () => {
|
|
128
|
+
const completedAt = "2026-01-01T00:00:00.000Z";
|
|
129
|
+
updateSliceStatus("M001", "S03", "closed", completedAt);
|
|
130
|
+
|
|
131
|
+
const outcome = skipSliceCascade("M001", "S03");
|
|
132
|
+
assert.deepEqual(outcome, { ok: false, reason: "slice-already-complete" });
|
|
133
|
+
|
|
134
|
+
const slice = getSlice("M001", "S03");
|
|
135
|
+
assert.equal(slice?.status, "closed", "closed slice must not be downgraded to skipped");
|
|
136
|
+
assert.equal(slice?.completed_at, completedAt, "completed_at must be preserved");
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("skipSliceCascade still re-skips an already-skipped slice (ok, wasAlreadySkipped)", () => {
|
|
140
|
+
updateSliceStatus("M001", "S03", "skipped");
|
|
141
|
+
|
|
142
|
+
const outcome = skipSliceCascade("M001", "S03");
|
|
143
|
+
assert.equal(outcome.ok, true);
|
|
144
|
+
if (outcome.ok) assert.equal(outcome.wasAlreadySkipped, true);
|
|
145
|
+
});
|
|
125
146
|
});
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
isPauseNotice,
|
|
15
15
|
isBlockedNoticeMessage,
|
|
16
16
|
isManualResolutionNotice,
|
|
17
|
+
isInteractiveMenuUnavailableNotice,
|
|
17
18
|
PAUSED_NOTICE_PREFIXES,
|
|
18
19
|
TERMINAL_NOTICE_PREFIXES,
|
|
19
20
|
} from "../stop-notice.js";
|
|
@@ -62,6 +63,22 @@ describe("emitter↔detector round-trip", () => {
|
|
|
62
63
|
assert.ok(isBlockedNoticeMessage(message));
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
test("un-showable menu notices classify as blocked (#1294)", () => {
|
|
67
|
+
// Emitted verbatim by notifyCommandMenuUnavailable (next-action-ui.ts / command-feedback.ts).
|
|
68
|
+
const menuUnavailable =
|
|
69
|
+
"gsd — m002: editorial hn menu could not be shown in this session.\nrun /gsd when ready.";
|
|
70
|
+
assert.ok(isInteractiveMenuUnavailableNotice(menuUnavailable));
|
|
71
|
+
assert.ok(isBlockedNoticeMessage(menuUnavailable));
|
|
72
|
+
|
|
73
|
+
// Emitted by notifyPickerCommandNeedsInteractiveMenu (command-feedback.ts).
|
|
74
|
+
const pickerGuidance = "/gsd did not start: milestone menu needs an interactive session";
|
|
75
|
+
assert.ok(isInteractiveMenuUnavailableNotice(pickerGuidance));
|
|
76
|
+
assert.ok(isBlockedNoticeMessage(pickerGuidance));
|
|
77
|
+
|
|
78
|
+
// Unrelated notices are not swept up.
|
|
79
|
+
assert.equal(isInteractiveMenuUnavailableNotice("auto-mode complete"), false);
|
|
80
|
+
});
|
|
81
|
+
|
|
65
82
|
test("terminal prefixes cover the known stop vocabulary", () => {
|
|
66
83
|
for (const message of ["auto-mode stopped.", "auto-mode complete", "auto-mode idle", "no active milestone"]) {
|
|
67
84
|
assert.ok(TERMINAL_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix)), message);
|
|
@@ -174,3 +174,22 @@ test('sync-lock: contended fresh lock fails fast without honoring long sync time
|
|
|
174
174
|
cleanupDir(base);
|
|
175
175
|
}
|
|
176
176
|
});
|
|
177
|
+
|
|
178
|
+
test('sync-lock: uncreatable lock path fails open instead of spinning forever', () => {
|
|
179
|
+
const base = tempDir();
|
|
180
|
+
try {
|
|
181
|
+
// `.gsd` is a dangling symlink to a missing target: the O_EXCL open lands
|
|
182
|
+
// on a missing parent and throws non-EEXIST on every attempt. Without the
|
|
183
|
+
// fail-open guard the retry loop spins forever, blocking the event loop.
|
|
184
|
+
fs.symlinkSync(path.join(base, 'missing-external-state'), path.join(base, '.gsd'), 'junction');
|
|
185
|
+
|
|
186
|
+
const startedAt = performance.now();
|
|
187
|
+
const result = acquireSyncLock(base, 0, 'write-gate.lock');
|
|
188
|
+
const elapsedMs = performance.now() - startedAt;
|
|
189
|
+
|
|
190
|
+
assert.strictEqual(result.acquired, false, 'uncreatable lock path must fail open, not acquire');
|
|
191
|
+
assert.ok(elapsedMs < 250, `must return promptly, not spin; elapsed=${elapsedMs.toFixed(1)}ms`);
|
|
192
|
+
} finally {
|
|
193
|
+
cleanupDir(base);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
import { describe, test } from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
buildContextMessage,
|
|
9
|
+
GSD_CONTEXT_MESSAGE_SENTINEL,
|
|
10
|
+
stripVolatileCodebaseMetadata,
|
|
11
|
+
} from "../bootstrap/system-context.ts";
|
|
12
|
+
|
|
13
|
+
const SENTINEL = `${GSD_CONTEXT_MESSAGE_SENTINEL}\n`;
|
|
8
14
|
|
|
9
15
|
describe("stripVolatileCodebaseMetadata (#847 — KV cache stability)", () => {
|
|
10
16
|
const map = [
|
|
@@ -63,7 +69,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
63
69
|
});
|
|
64
70
|
assert.ok(result, "expected a context message");
|
|
65
71
|
assert.equal(result.customType, "gsd-memory");
|
|
66
|
-
assert.equal(result.content,
|
|
72
|
+
assert.equal(result.content, `${SENTINEL}[GSD Context Metadata]\n- Memory supplied: yes\n\n[MEMORY]\nrule one\nrule two`);
|
|
67
73
|
assert.equal(result.display, false);
|
|
68
74
|
});
|
|
69
75
|
|
|
@@ -75,7 +81,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
75
81
|
});
|
|
76
82
|
assert.ok(result);
|
|
77
83
|
assert.equal(result.customType, "gsd-guided-context");
|
|
78
|
-
assert.equal(result.content,
|
|
84
|
+
assert.equal(result.content, `${SENTINEL}[GUIDED]\nexecute T01`);
|
|
79
85
|
});
|
|
80
86
|
|
|
81
87
|
test("forensics injection alone emits gsd-forensics", () => {
|
|
@@ -86,7 +92,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
86
92
|
});
|
|
87
93
|
assert.ok(result);
|
|
88
94
|
assert.equal(result.customType, "gsd-forensics");
|
|
89
|
-
assert.equal(result.content,
|
|
95
|
+
assert.equal(result.content, `${SENTINEL}[FORENSICS]\ninvestigation context`);
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
test("memory + guided injection: memory prepended, customType is gsd-guided-context", () => {
|
|
@@ -97,7 +103,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
97
103
|
});
|
|
98
104
|
assert.ok(result);
|
|
99
105
|
assert.equal(result.customType, "gsd-guided-context");
|
|
100
|
-
assert.equal(result.content, `${markedMemory}\n\n[GUIDED]\nexecute T01`);
|
|
106
|
+
assert.equal(result.content, `${SENTINEL}${markedMemory}\n\n[GUIDED]\nexecute T01`);
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
test("memory + forensics: memory prepended, customType is gsd-forensics", () => {
|
|
@@ -108,7 +114,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
108
114
|
});
|
|
109
115
|
assert.ok(result);
|
|
110
116
|
assert.equal(result.customType, "gsd-forensics");
|
|
111
|
-
assert.equal(result.content, `${markedMemory}\n\n[FORENSICS]\ninvestigation context`);
|
|
117
|
+
assert.equal(result.content, `${SENTINEL}${markedMemory}\n\n[FORENSICS]\ninvestigation context`);
|
|
112
118
|
});
|
|
113
119
|
|
|
114
120
|
test("guided takes precedence over forensics when both are somehow present", () => {
|
|
@@ -122,6 +128,6 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
122
128
|
});
|
|
123
129
|
assert.ok(result);
|
|
124
130
|
assert.equal(result.customType, "gsd-guided-context");
|
|
125
|
-
assert.equal(result.content,
|
|
131
|
+
assert.equal(result.content, `${SENTINEL}[GUIDED]`);
|
|
126
132
|
});
|
|
127
133
|
});
|
|
@@ -25,8 +25,16 @@ function makeMockPi() {
|
|
|
25
25
|
|
|
26
26
|
console.log('\n── Tool naming: registration count ──');
|
|
27
27
|
|
|
28
|
+
// Aliases are hidden from the model-facing surface by default (plan 035);
|
|
29
|
+
// opt in here so this file can keep exercising alias-registration behavior.
|
|
30
|
+
const previousAdvertiseAliases = process.env.GSD_ADVERTISE_TOOL_ALIASES;
|
|
31
|
+
process.env.GSD_ADVERTISE_TOOL_ALIASES = "1";
|
|
32
|
+
|
|
28
33
|
const pi = makeMockPi();
|
|
29
34
|
registerDbTools(pi);
|
|
35
|
+
|
|
36
|
+
if (previousAdvertiseAliases === undefined) delete process.env.GSD_ADVERTISE_TOOL_ALIASES;
|
|
37
|
+
else process.env.GSD_ADVERTISE_TOOL_ALIASES = previousAdvertiseAliases;
|
|
30
38
|
const toolByName = new Map<string, any>(pi.tools.map((tool: any) => [tool.name, tool]));
|
|
31
39
|
const registeredCanonicalNames = new Set<string>(
|
|
32
40
|
WORKFLOW_TOOL_CONTRACTS
|
|
@@ -43,7 +43,10 @@ import {
|
|
|
43
43
|
insertMilestone,
|
|
44
44
|
upsertMilestonePlanning,
|
|
45
45
|
insertSlice,
|
|
46
|
+
insertTask,
|
|
47
|
+
saveReworkBrief,
|
|
46
48
|
} from "../gsd-db.ts";
|
|
49
|
+
import { clearGSDPreferencesCache, getProjectGSDPreferencesPath } from "../preferences.ts";
|
|
47
50
|
|
|
48
51
|
// ─── Pure composer tests ──────────────────────────────────────────────────
|
|
49
52
|
|
|
@@ -416,6 +419,44 @@ test("Tool Surface composer: planning-dispatch lists allowed subagents", () => {
|
|
|
416
419
|
assert.match(out, /\*\*planner\*\*/);
|
|
417
420
|
});
|
|
418
421
|
|
|
422
|
+
test("Tool Surface composer: planning_subagents updates plan-milestone dispatch guidance", (t) => {
|
|
423
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
424
|
+
const tempProject = mkdtempSync(join(tmpdir(), "gsd-tool-surface-planning-subagents-"));
|
|
425
|
+
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-tool-surface-planning-subagents-home-"));
|
|
426
|
+
|
|
427
|
+
t.after(() => {
|
|
428
|
+
clearGSDPreferencesCache();
|
|
429
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
430
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
431
|
+
rmSync(tempProject, { recursive: true, force: true });
|
|
432
|
+
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
436
|
+
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
437
|
+
clearGSDPreferencesCache();
|
|
438
|
+
writeFileSync(
|
|
439
|
+
getProjectGSDPreferencesPath(tempProject),
|
|
440
|
+
[
|
|
441
|
+
"---",
|
|
442
|
+
"version: 1",
|
|
443
|
+
"planning_subagents:",
|
|
444
|
+
" plan-milestone:",
|
|
445
|
+
" allowed: [security]",
|
|
446
|
+
"---",
|
|
447
|
+
"",
|
|
448
|
+
].join("\n"),
|
|
449
|
+
"utf-8",
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
const out = composeToolSurfaceInstructions("plan-milestone", {
|
|
453
|
+
renderMode: "standalone",
|
|
454
|
+
basePath: tempProject,
|
|
455
|
+
});
|
|
456
|
+
assert.match(out, /Dispatch subagents only to \*\*security\*\*/);
|
|
457
|
+
assert.doesNotMatch(out, /Do not dispatch subagents/);
|
|
458
|
+
});
|
|
459
|
+
|
|
419
460
|
test("Tool Surface composer: execute-task warns against slice/milestone closeout tools", () => {
|
|
420
461
|
const out = composeToolSurfaceInstructions("execute-task", { renderMode: "nested" });
|
|
421
462
|
assert.match(out, /^Tool surface: /);
|
|
@@ -518,6 +559,38 @@ test("#4782 phase 2: buildReassessRoadmapPrompt emits composer-shaped context wi
|
|
|
518
559
|
assert.ok(!prompt.includes("Slice Context (from discussion)"));
|
|
519
560
|
});
|
|
520
561
|
|
|
562
|
+
|
|
563
|
+
test("execute-task prompt injects unresolved blocking rework findings", async (t) => {
|
|
564
|
+
const base = makeFixtureBase();
|
|
565
|
+
t.after(() => cleanup(base));
|
|
566
|
+
invalidateAllCaches();
|
|
567
|
+
|
|
568
|
+
seed(base, "M001");
|
|
569
|
+
writeArtifacts(base);
|
|
570
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", title: "Task", status: "pending" });
|
|
571
|
+
saveReworkBrief({
|
|
572
|
+
briefId: "RB-001",
|
|
573
|
+
milestoneId: "M001",
|
|
574
|
+
sliceId: "S01",
|
|
575
|
+
taskId: "T01",
|
|
576
|
+
findings: [{
|
|
577
|
+
findingId: "F1",
|
|
578
|
+
severity: "blocking",
|
|
579
|
+
description: "Compile regression",
|
|
580
|
+
requiredFix: "Restore typecheck",
|
|
581
|
+
verificationCommands: ["pnpm run typecheck:extensions"],
|
|
582
|
+
}],
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
const prompt = await buildExecuteTaskPrompt("M001", "S01", "First", "T01", "Task", base);
|
|
586
|
+
|
|
587
|
+
assert.match(prompt, /Blocking Rework Findings \(non-optional\)/);
|
|
588
|
+
assert.match(prompt, /F1/);
|
|
589
|
+
assert.match(prompt, /Compile regression/);
|
|
590
|
+
assert.match(prompt, /pnpm run typecheck:extensions/);
|
|
591
|
+
assert.match(prompt, /reworkResolution/);
|
|
592
|
+
});
|
|
593
|
+
|
|
521
594
|
test("execute-task prompt omits on-demand slice research when the artifact is absent", async (t) => {
|
|
522
595
|
const base = makeFixtureBase();
|
|
523
596
|
t.after(() => cleanup(base));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { mkdtempSync, mkdirSync, readFileSync, rmSync, statSync, utimesSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
@@ -239,6 +239,98 @@ test("plan-v2 ensure rejects empty executable graph", () => {
|
|
|
239
239
|
assert.equal(isEmptyPlanV2GraphResult(compiled), true);
|
|
240
240
|
});
|
|
241
241
|
|
|
242
|
+
function seedMultiSliceRows(): void {
|
|
243
|
+
insertMilestone({ id: MILESTONE_ID, title: "Milestone", status: "active" });
|
|
244
|
+
const slices: Array<[string, number, Array<[string, number]>]> = [
|
|
245
|
+
["S01", 1, [["T01", 1], ["T02", 2]]],
|
|
246
|
+
["S02", 2, [["T03", 1], ["T04", 2]]],
|
|
247
|
+
];
|
|
248
|
+
for (const [sid, sseq, tasks] of slices) {
|
|
249
|
+
insertSlice({ id: sid, milestoneId: MILESTONE_ID, title: `Slice ${sid}`, status: "in_progress", sequence: sseq });
|
|
250
|
+
for (const [tid, tseq] of tasks) {
|
|
251
|
+
insertTask({
|
|
252
|
+
id: tid,
|
|
253
|
+
milestoneId: MILESTONE_ID,
|
|
254
|
+
sliceId: sid,
|
|
255
|
+
title: `Task ${tid}`,
|
|
256
|
+
status: "pending",
|
|
257
|
+
keyFiles: [`src/${tid}.ts`],
|
|
258
|
+
sequence: tseq,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
test("plan-v2 batched compile preserves node ids, order, and count", () => {
|
|
265
|
+
const basePath = createBasePath();
|
|
266
|
+
seedMultiSliceRows();
|
|
267
|
+
writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
|
|
268
|
+
|
|
269
|
+
const compiled = ensurePlanV2Graph(basePath, buildState("executing"));
|
|
270
|
+
assert.equal(compiled.ok, true);
|
|
271
|
+
|
|
272
|
+
const graph = JSON.parse(readFileSync(compiled.graphPath ?? "", "utf-8")) as {
|
|
273
|
+
nodes: Array<{ id: string }>;
|
|
274
|
+
};
|
|
275
|
+
assert.deepEqual(
|
|
276
|
+
graph.nodes.map((n) => n.id),
|
|
277
|
+
[
|
|
278
|
+
"execute-task:M001:S01:T01",
|
|
279
|
+
"execute-task:M001:S01:T02",
|
|
280
|
+
"complete-slice:M001:S01",
|
|
281
|
+
"execute-task:M001:S02:T03",
|
|
282
|
+
"execute-task:M001:S02:T04",
|
|
283
|
+
"complete-slice:M001:S02",
|
|
284
|
+
],
|
|
285
|
+
);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
test("plan-v2 skips the disk write when the graph is unchanged", () => {
|
|
289
|
+
const basePath = createBasePath();
|
|
290
|
+
seedMultiSliceRows();
|
|
291
|
+
writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
|
|
292
|
+
|
|
293
|
+
const first = ensurePlanV2Graph(basePath, buildState("executing"));
|
|
294
|
+
assert.equal(first.ok, true);
|
|
295
|
+
const graphPath = first.graphPath ?? "";
|
|
296
|
+
const before = readFileSync(graphPath, "utf-8");
|
|
297
|
+
|
|
298
|
+
// Backdate mtime so a rewrite is detectable even within the same millisecond.
|
|
299
|
+
utimesSync(graphPath, 1000, 1000);
|
|
300
|
+
const backdatedMtime = statSync(graphPath).mtimeMs;
|
|
301
|
+
|
|
302
|
+
const second = ensurePlanV2Graph(basePath, buildState("executing"));
|
|
303
|
+
assert.equal(second.ok, true);
|
|
304
|
+
assert.equal(statSync(graphPath).mtimeMs, backdatedMtime, "identical state must not rewrite the graph");
|
|
305
|
+
assert.equal(readFileSync(graphPath, "utf-8"), before);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test("plan-v2 rewrites the graph when it changes", () => {
|
|
309
|
+
const basePath = createBasePath();
|
|
310
|
+
seedMultiSliceRows();
|
|
311
|
+
writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
|
|
312
|
+
|
|
313
|
+
const first = ensurePlanV2Graph(basePath, buildState("executing"));
|
|
314
|
+
const graphPath = first.graphPath ?? "";
|
|
315
|
+
const before = readFileSync(graphPath, "utf-8");
|
|
316
|
+
utimesSync(graphPath, 1000, 1000);
|
|
317
|
+
|
|
318
|
+
insertTask({
|
|
319
|
+
id: "T05",
|
|
320
|
+
milestoneId: MILESTONE_ID,
|
|
321
|
+
sliceId: "S02",
|
|
322
|
+
title: "Added task",
|
|
323
|
+
status: "pending",
|
|
324
|
+
keyFiles: ["src/T05.ts"],
|
|
325
|
+
sequence: 3,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const second = ensurePlanV2Graph(basePath, buildState("executing"));
|
|
329
|
+
assert.equal(second.ok, true);
|
|
330
|
+
assert.notEqual(statSync(graphPath).mtimeMs, 1000000, "changed graph must rewrite");
|
|
331
|
+
assert.notEqual(readFileSync(graphPath, "utf-8"), before);
|
|
332
|
+
});
|
|
333
|
+
|
|
242
334
|
test("plan-v2 allows empty graph for milestone terminal phases", () => {
|
|
243
335
|
const basePath = createBasePath();
|
|
244
336
|
writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
|
|
@@ -94,6 +94,8 @@ test("complete-slice requires status, closeout, and execution handoff tools", ()
|
|
|
94
94
|
"gsd_slice_complete",
|
|
95
95
|
"gsd_task_reopen",
|
|
96
96
|
"gsd_replan_slice",
|
|
97
|
+
"gsd_replan_task",
|
|
98
|
+
"gsd_rework_brief_save",
|
|
97
99
|
"gsd_requirement_update",
|
|
98
100
|
"gsd_summary_save",
|
|
99
101
|
];
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// GSD Extension - Auto-migration gate tests (plan 026).
|
|
2
|
+
// Covers needsAutoMigration's trigger (empty milestones table + .gsd/milestones
|
|
3
|
+
// present) and validateMigration's engine-vs-markdown count comparison.
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'node:test';
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { tmpdir } from 'node:os';
|
|
10
|
+
|
|
11
|
+
import { openDatabase, closeDatabase, insertMilestone, insertSlice } from '../gsd-db.ts';
|
|
12
|
+
import { needsAutoMigration, validateMigration } from '../workflow-migration.ts';
|
|
13
|
+
|
|
14
|
+
function makeProject(): string {
|
|
15
|
+
return mkdtempSync(join(tmpdir(), 'gsd-migration-gates-'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function openProjectDb(base: string): string {
|
|
19
|
+
const gsdDir = join(base, '.gsd');
|
|
20
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
21
|
+
const dbPath = join(gsdDir, 'gsd.db');
|
|
22
|
+
assert.ok(openDatabase(dbPath), 'openDatabase should succeed');
|
|
23
|
+
return dbPath;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function cleanup(base: string): void {
|
|
27
|
+
closeDatabase();
|
|
28
|
+
rmSync(base, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function writeRoadmap(base: string, mId: string, sliceLines: string[]): void {
|
|
32
|
+
const mDir = join(base, '.gsd', 'milestones', mId);
|
|
33
|
+
mkdirSync(mDir, { recursive: true });
|
|
34
|
+
writeFileSync(join(mDir, 'ROADMAP.md'), [
|
|
35
|
+
`# ${mId}: Test`,
|
|
36
|
+
'',
|
|
37
|
+
'## Slices',
|
|
38
|
+
'',
|
|
39
|
+
...sliceLines,
|
|
40
|
+
'',
|
|
41
|
+
].join('\n'));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe('needsAutoMigration', () => {
|
|
45
|
+
test('false for a fresh project with no legacy markdown', () => {
|
|
46
|
+
const base = makeProject();
|
|
47
|
+
try {
|
|
48
|
+
openProjectDb(base);
|
|
49
|
+
assert.equal(needsAutoMigration(base), false, 'no .gsd/milestones dir → no migration');
|
|
50
|
+
} finally {
|
|
51
|
+
cleanup(base);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('true when engine tables are empty and .gsd/milestones exists', () => {
|
|
56
|
+
const base = makeProject();
|
|
57
|
+
try {
|
|
58
|
+
openProjectDb(base);
|
|
59
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
60
|
+
assert.equal(needsAutoMigration(base), true, 'legacy markdown + empty engine → migrate');
|
|
61
|
+
} finally {
|
|
62
|
+
cleanup(base);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('false once the milestones table has rows (migration already done)', () => {
|
|
67
|
+
const base = makeProject();
|
|
68
|
+
try {
|
|
69
|
+
openProjectDb(base);
|
|
70
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
71
|
+
insertMilestone({ id: 'M001', title: 'Migrated' });
|
|
72
|
+
assert.equal(needsAutoMigration(base), false, 'engine rows present → migration already done');
|
|
73
|
+
} finally {
|
|
74
|
+
cleanup(base);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('false when no database connection is open', () => {
|
|
79
|
+
const base = makeProject();
|
|
80
|
+
try {
|
|
81
|
+
mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
82
|
+
closeDatabase();
|
|
83
|
+
assert.equal(needsAutoMigration(base), false, 'no DB → cannot migrate');
|
|
84
|
+
} finally {
|
|
85
|
+
cleanup(base);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('validateMigration', () => {
|
|
91
|
+
test('reports no discrepancies when engine counts match markdown', () => {
|
|
92
|
+
const base = makeProject();
|
|
93
|
+
try {
|
|
94
|
+
openProjectDb(base);
|
|
95
|
+
writeRoadmap(base, 'M001', ['- [ ] **S01: Test Slice** `risk:low` `depends:[]`']);
|
|
96
|
+
insertMilestone({ id: 'M001', title: 'Test' });
|
|
97
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice' });
|
|
98
|
+
|
|
99
|
+
const result = validateMigration(base);
|
|
100
|
+
assert.deepEqual(result.discrepancies, [], 'matching engine/markdown counts → clean');
|
|
101
|
+
} finally {
|
|
102
|
+
cleanup(base);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('reports discrepancies when engine counts diverge from markdown', () => {
|
|
107
|
+
const base = makeProject();
|
|
108
|
+
try {
|
|
109
|
+
openProjectDb(base);
|
|
110
|
+
writeRoadmap(base, 'M001', [
|
|
111
|
+
'- [ ] **S01: Test Slice** `risk:low` `depends:[]`',
|
|
112
|
+
'- [ ] **S02: Second Slice** `risk:low` `depends:[]`',
|
|
113
|
+
]);
|
|
114
|
+
// Engine has no rows at all → milestone and slice counts both diverge.
|
|
115
|
+
const result = validateMigration(base);
|
|
116
|
+
assert.ok(
|
|
117
|
+
result.discrepancies.some((d) => d.includes('Milestone count mismatch')),
|
|
118
|
+
`expected milestone mismatch, got: ${result.discrepancies.join('; ')}`,
|
|
119
|
+
);
|
|
120
|
+
assert.ok(
|
|
121
|
+
result.discrepancies.some((d) => d.includes('Slice count mismatch')),
|
|
122
|
+
`expected slice mismatch, got: ${result.discrepancies.join('; ')}`,
|
|
123
|
+
);
|
|
124
|
+
} finally {
|
|
125
|
+
cleanup(base);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('reports a validation failure when no database connection is open', () => {
|
|
130
|
+
const base = makeProject();
|
|
131
|
+
try {
|
|
132
|
+
closeDatabase();
|
|
133
|
+
const result = validateMigration(base);
|
|
134
|
+
assert.deepEqual(result.discrepancies, ['No database connection for validation']);
|
|
135
|
+
} finally {
|
|
136
|
+
cleanup(base);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
@@ -352,7 +352,7 @@ test('workflow-projections: regenerateIfMissing SUMMARY is idempotent for flat-p
|
|
|
352
352
|
keyDecisions: ['Use centralized task summary paths.'],
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
-
const summaryPath = join(phaseDir, 'T01-SUMMARY.md');
|
|
355
|
+
const summaryPath = join(phaseDir, 'S01-T01-SUMMARY.md');
|
|
356
356
|
assert.ok(!existsSync(summaryPath), 'precondition: flat-phase task summary absent');
|
|
357
357
|
|
|
358
358
|
const first = await regenerateIfMissing(base, 'M001', 'S01', 'SUMMARY');
|
|
@@ -399,7 +399,7 @@ test('workflow-projections: flat-phase SUMMARY regeneration ignores stale nested
|
|
|
399
399
|
status: 'complete',
|
|
400
400
|
});
|
|
401
401
|
|
|
402
|
-
const rootSummaryPath = join(phaseDir, 'T01-SUMMARY.md');
|
|
402
|
+
const rootSummaryPath = join(phaseDir, 'S01-T01-SUMMARY.md');
|
|
403
403
|
assert.ok(!existsSync(rootSummaryPath), 'precondition: canonical flat-phase task summary absent');
|
|
404
404
|
|
|
405
405
|
const regenerated = await regenerateIfMissing(base, 'M001', 'S01', 'SUMMARY');
|
|
@@ -440,8 +440,8 @@ test('workflow-projections: renderSummaryProjection uses milestone title when cr
|
|
|
440
440
|
status: 'complete',
|
|
441
441
|
});
|
|
442
442
|
|
|
443
|
-
const titleSummaryPath = join(base, '.gsd', 'phases', '01-milestone', 'T01-SUMMARY.md');
|
|
444
|
-
const idSummaryPath = join(base, '.gsd', 'phases', '01-m001', 'T01-SUMMARY.md');
|
|
443
|
+
const titleSummaryPath = join(base, '.gsd', 'phases', '01-milestone', 'S01-T01-SUMMARY.md');
|
|
444
|
+
const idSummaryPath = join(base, '.gsd', 'phases', '01-m001', 'S01-T01-SUMMARY.md');
|
|
445
445
|
|
|
446
446
|
renderSummaryProjection(base, 'M001', 'S01', 'T01');
|
|
447
447
|
|