gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.e146beb20
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/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/github-sync/templates.js +39 -8
- package/dist/resources/extensions/gsd/auto/loop.js +48 -10
- package/dist/resources/extensions/gsd/auto/phases.js +37 -30
- package/dist/resources/extensions/gsd/auto/run-unit.js +19 -15
- package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
- package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +111 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +154 -8
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- package/dist/resources/extensions/gsd/auto.js +9 -1
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +15 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -1
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
- package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
- package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
- package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
- package/dist/resources/extensions/gsd/db-base-schema.js +14 -0
- package/dist/resources/extensions/gsd/db-migration-steps.js +16 -0
- package/dist/resources/extensions/gsd/detection.js +106 -0
- package/dist/resources/extensions/gsd/graph.js +9 -3
- package/dist/resources/extensions/gsd/gsd-db.js +102 -2
- package/dist/resources/extensions/gsd/guided-flow.js +49 -12
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/unit-runtime.js +11 -0
- package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
- 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 +16 -16
- 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 +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.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/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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-paths-manifest.json +16 -16
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- 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/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
- package/package.json +10 -6
- package/packages/contracts/package.json +1 -1
- package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
- package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
- package/packages/pi-ai/dist/models/fake-model.js +27 -0
- package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
- package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/index.js +8 -0
- package/packages/pi-ai/dist/models/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
- package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/fake.js +319 -0
- package/packages/pi-ai/dist/providers/fake.js.map +1 -0
- package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
- package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
- package/packages/pi-ai/src/models/fake-model.ts +30 -0
- package/packages/pi-ai/src/models/index.ts +9 -0
- package/packages/pi-ai/src/providers/fake.ts +376 -0
- package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +74 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +14 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +97 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +4 -0
- 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/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
- package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +106 -17
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +60 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +40 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +23 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +87 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +16 -1
- package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +12 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +118 -17
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +43 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +25 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
- package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
- package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
- package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/index.d.ts +1 -0
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +2 -0
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/style.d.ts +41 -0
- package/packages/pi-tui/dist/style.d.ts.map +1 -0
- package/packages/pi-tui/dist/style.js +158 -0
- package/packages/pi-tui/dist/style.js.map +1 -0
- package/packages/pi-tui/dist/tui.d.ts +0 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +3 -8
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
- package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
- package/packages/pi-tui/src/index.ts +9 -0
- package/packages/pi-tui/src/style.ts +225 -0
- package/packages/pi-tui/src/tui.ts +3 -8
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
- package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +18 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +36 -27
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/github-sync/templates.ts +38 -8
- package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +67 -18
- package/src/resources/extensions/gsd/auto/phases.ts +42 -28
- package/src/resources/extensions/gsd/auto/run-unit.ts +24 -14
- package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
- package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
- package/src/resources/extensions/gsd/auto-prompts.ts +116 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +153 -7
- package/src/resources/extensions/gsd/auto-start.ts +7 -6
- package/src/resources/extensions/gsd/auto.ts +12 -1
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +16 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +17 -1
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
- package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
- package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
- package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
- package/src/resources/extensions/gsd/db-base-schema.ts +15 -0
- package/src/resources/extensions/gsd/db-migration-steps.ts +17 -0
- package/src/resources/extensions/gsd/detection.ts +128 -0
- package/src/resources/extensions/gsd/graph.ts +12 -5
- package/src/resources/extensions/gsd/gsd-db.ts +119 -1
- package/src/resources/extensions/gsd/guided-flow.ts +49 -12
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +7 -8
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +84 -5
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +170 -1
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
- package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +112 -6
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
- package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
- package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +46 -2
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
- package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/unit-runtime.ts +14 -0
- package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
- package/packages/contracts/tsconfig.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → y73quA-XdLo9n41nxphjW}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → y73quA-XdLo9n41nxphjW}/_ssgManifest.js +0 -0
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
import test from "node:test";
|
|
12
12
|
import assert from "node:assert/strict";
|
|
13
13
|
import { mkdirSync, writeFileSync, rmSync, existsSync } from "node:fs";
|
|
14
|
+
import { execFileSync } from "node:child_process";
|
|
14
15
|
import { join } from "node:path";
|
|
15
16
|
import { tmpdir } from "node:os";
|
|
16
17
|
import {
|
|
17
18
|
detectProjectState,
|
|
18
19
|
detectV1Planning,
|
|
19
20
|
detectProjectSignals,
|
|
21
|
+
classifyProject,
|
|
20
22
|
scanProjectFiles,
|
|
21
23
|
} from "../detection.ts";
|
|
22
24
|
|
|
@@ -37,6 +39,18 @@ function cleanup(dir: string): void {
|
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
function git(dir: string, args: string[]): void {
|
|
43
|
+
execFileSync("git", args, { cwd: dir, stdio: "ignore" });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function makeGitRepo(prefix: string): string {
|
|
47
|
+
const dir = makeTempDir(prefix);
|
|
48
|
+
git(dir, ["init"]);
|
|
49
|
+
git(dir, ["config", "user.email", "test@example.com"]);
|
|
50
|
+
git(dir, ["config", "user.name", "Test User"]);
|
|
51
|
+
return dir;
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
// ─── detectProjectState ─────────────────────────────────────────────────────────
|
|
41
55
|
|
|
42
56
|
test("detectProjectState: empty directory returns state=none", (t) => {
|
|
@@ -49,6 +63,132 @@ test("detectProjectState: empty directory returns state=none", (t) => {
|
|
|
49
63
|
assert.equal(result.v2, undefined);
|
|
50
64
|
});
|
|
51
65
|
|
|
66
|
+
test("classifyProject: no git repo is invalid", (t) => {
|
|
67
|
+
const dir = makeTempDir("classify-invalid");
|
|
68
|
+
t.after(() => cleanup(dir));
|
|
69
|
+
|
|
70
|
+
const classification = classifyProject(dir);
|
|
71
|
+
assert.equal(classification.kind, "invalid-repo");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("classifyProject: empty git repo is greenfield", (t) => {
|
|
75
|
+
const dir = makeGitRepo("classify-greenfield");
|
|
76
|
+
t.after(() => cleanup(dir));
|
|
77
|
+
|
|
78
|
+
const classification = classifyProject(dir);
|
|
79
|
+
assert.equal(classification.kind, "greenfield");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("classifyProject: nested empty git repo does not inherit ancestor markers", (t) => {
|
|
83
|
+
const parent = makeGitRepo("classify-parent-marker");
|
|
84
|
+
t.after(() => cleanup(parent));
|
|
85
|
+
|
|
86
|
+
writeFileSync(join(parent, "package.json"), JSON.stringify({ name: "parent" }), "utf-8");
|
|
87
|
+
git(parent, ["add", "package.json"]);
|
|
88
|
+
git(parent, ["commit", "-m", "add parent marker"]);
|
|
89
|
+
const child = join(parent, "nested");
|
|
90
|
+
mkdirSync(child, { recursive: true });
|
|
91
|
+
git(child, ["init"]);
|
|
92
|
+
git(child, ["config", "user.email", "test@example.com"]);
|
|
93
|
+
git(child, ["config", "user.name", "Test User"]);
|
|
94
|
+
|
|
95
|
+
const classification = classifyProject(child);
|
|
96
|
+
assert.equal(classification.kind, "greenfield");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("classifyProject: tracked static HTML is existing untyped content", (t) => {
|
|
100
|
+
const dir = makeGitRepo("classify-index");
|
|
101
|
+
t.after(() => cleanup(dir));
|
|
102
|
+
|
|
103
|
+
writeFileSync(join(dir, "index.html"), "<main></main>\n", "utf-8");
|
|
104
|
+
git(dir, ["add", "index.html"]);
|
|
105
|
+
git(dir, ["commit", "-m", "add static page"]);
|
|
106
|
+
|
|
107
|
+
const classification = classifyProject(dir);
|
|
108
|
+
assert.equal(classification.kind, "untyped-existing");
|
|
109
|
+
assert.deepEqual(classification.contentFiles, ["index.html"]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("classifyProject: README-only repo is existing untyped content", (t) => {
|
|
113
|
+
const dir = makeGitRepo("classify-readme");
|
|
114
|
+
t.after(() => cleanup(dir));
|
|
115
|
+
|
|
116
|
+
writeFileSync(join(dir, "README.md"), "# docs\n", "utf-8");
|
|
117
|
+
git(dir, ["add", "README.md"]);
|
|
118
|
+
git(dir, ["commit", "-m", "add docs"]);
|
|
119
|
+
|
|
120
|
+
const classification = classifyProject(dir);
|
|
121
|
+
assert.equal(classification.kind, "untyped-existing");
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("classifyProject: src-only content is untyped existing, not typed marker", (t) => {
|
|
125
|
+
const dir = makeGitRepo("classify-src-only");
|
|
126
|
+
t.after(() => cleanup(dir));
|
|
127
|
+
|
|
128
|
+
mkdirSync(join(dir, "src"), { recursive: true });
|
|
129
|
+
writeFileSync(join(dir, "src", "index.txt"), "content\n", "utf-8");
|
|
130
|
+
git(dir, ["add", "src/index.txt"]);
|
|
131
|
+
git(dir, ["commit", "-m", "add source content"]);
|
|
132
|
+
|
|
133
|
+
const classification = classifyProject(dir);
|
|
134
|
+
assert.equal(classification.kind, "untyped-existing");
|
|
135
|
+
assert.deepEqual(classification.contentFiles, ["src/index.txt"]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("classifyProject: nested untracked files count as project content", (t) => {
|
|
139
|
+
const dir = makeGitRepo("classify-untracked-nested");
|
|
140
|
+
t.after(() => cleanup(dir));
|
|
141
|
+
|
|
142
|
+
mkdirSync(join(dir, "docs"), { recursive: true });
|
|
143
|
+
writeFileSync(join(dir, "docs", "index.html"), "<main></main>\n", "utf-8");
|
|
144
|
+
|
|
145
|
+
const classification = classifyProject(dir);
|
|
146
|
+
assert.equal(classification.kind, "untyped-existing");
|
|
147
|
+
assert.deepEqual(classification.untrackedFiles, ["docs/index.html"]);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("classifyProject: known markers produce typed existing project", (t) => {
|
|
151
|
+
const dir = makeGitRepo("classify-typed");
|
|
152
|
+
t.after(() => cleanup(dir));
|
|
153
|
+
|
|
154
|
+
writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "typed" }), "utf-8");
|
|
155
|
+
git(dir, ["add", "package.json"]);
|
|
156
|
+
git(dir, ["commit", "-m", "add package"]);
|
|
157
|
+
|
|
158
|
+
const classification = classifyProject(dir);
|
|
159
|
+
assert.equal(classification.kind, "typed-existing");
|
|
160
|
+
assert.ok(classification.markers.includes("package.json"));
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("classifyProject: ignored build/cache-only files do not count as content", (t) => {
|
|
164
|
+
const dir = makeGitRepo("classify-ignored");
|
|
165
|
+
t.after(() => cleanup(dir));
|
|
166
|
+
|
|
167
|
+
writeFileSync(join(dir, ".gitignore"), "dist/\n.cache/\n", "utf-8");
|
|
168
|
+
git(dir, ["add", ".gitignore"]);
|
|
169
|
+
git(dir, ["commit", "-m", "ignore generated files"]);
|
|
170
|
+
mkdirSync(join(dir, "dist"), { recursive: true });
|
|
171
|
+
writeFileSync(join(dir, "dist", "bundle.js"), "generated\n", "utf-8");
|
|
172
|
+
mkdirSync(join(dir, ".cache"), { recursive: true });
|
|
173
|
+
writeFileSync(join(dir, ".cache", "x"), "cache\n", "utf-8");
|
|
174
|
+
|
|
175
|
+
const classification = classifyProject(dir);
|
|
176
|
+
assert.equal(classification.kind, "greenfield");
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test("classifyProject: generated framework/cache dirs do not count as content", (t) => {
|
|
180
|
+
const dir = makeGitRepo("classify-generated-dirs");
|
|
181
|
+
t.after(() => cleanup(dir));
|
|
182
|
+
|
|
183
|
+
mkdirSync(join(dir, ".next", "server"), { recursive: true });
|
|
184
|
+
writeFileSync(join(dir, ".next", "server", "page.js"), "generated\n", "utf-8");
|
|
185
|
+
mkdirSync(join(dir, ".venv", "lib"), { recursive: true });
|
|
186
|
+
writeFileSync(join(dir, ".venv", "lib", "site.py"), "generated\n", "utf-8");
|
|
187
|
+
|
|
188
|
+
const classification = classifyProject(dir);
|
|
189
|
+
assert.equal(classification.kind, "greenfield");
|
|
190
|
+
});
|
|
191
|
+
|
|
52
192
|
test("detectProjectState: directory with .gsd/milestones/M001 returns v2-gsd", (t) => {
|
|
53
193
|
const dir = makeTempDir("v2-gsd");
|
|
54
194
|
t.after(() => cleanup(dir));
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
## TL;DR
|
|
2
|
+
|
|
3
|
+
**What:** Ship milestone M001 - Authentication
|
|
4
|
+
**Why:** Users need to authenticate before accessing protected resources.
|
|
5
|
+
**How:** Added password hash check and session token issuance.
|
|
6
|
+
|
|
7
|
+
## What
|
|
8
|
+
|
|
9
|
+
### S01
|
|
10
|
+
Implemented login flow.
|
|
11
|
+
|
|
12
|
+
## Why
|
|
13
|
+
|
|
14
|
+
Users need to authenticate before accessing protected resources.
|
|
15
|
+
|
|
16
|
+
## How
|
|
17
|
+
|
|
18
|
+
Added password hash check and session token issuance.
|
|
19
|
+
|
|
20
|
+
## Linked Issue
|
|
21
|
+
|
|
22
|
+
Closes #123
|
|
23
|
+
|
|
24
|
+
## Roadmap
|
|
25
|
+
|
|
26
|
+
- [x] **S01: Login**
|
|
27
|
+
|
|
28
|
+
## Metrics
|
|
29
|
+
|
|
30
|
+
- **Units executed:** 3
|
|
31
|
+
|
|
32
|
+
## Tests Run
|
|
33
|
+
|
|
34
|
+
- npm test
|
|
35
|
+
- npm run typecheck:extensions
|
|
36
|
+
|
|
37
|
+
## Change Type
|
|
38
|
+
|
|
39
|
+
- [x] `feat` - New feature or capability
|
|
40
|
+
- [ ] `fix` - Bug fix
|
|
41
|
+
- [ ] `refactor` - Code restructuring
|
|
42
|
+
- [ ] `test` - Adding or updating tests
|
|
43
|
+
- [ ] `docs` - Documentation only
|
|
44
|
+
- [ ] `chore` - Build, CI, or tooling changes
|
|
45
|
+
|
|
46
|
+
## Rollback And Compatibility
|
|
47
|
+
|
|
48
|
+
- Revert the merge commit.
|
|
49
|
+
|
|
50
|
+
## AI Assistance Disclosure
|
|
51
|
+
|
|
52
|
+
This PR was prepared with AI assistance.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## TL;DR
|
|
2
|
+
|
|
3
|
+
**What:** Ship milestone M001 - Authentication
|
|
4
|
+
**Why:** Milestone work is complete and ready for review.
|
|
5
|
+
**How:** Generated from GSD evidence and local workflow artifacts.
|
|
6
|
+
|
|
7
|
+
## What
|
|
8
|
+
|
|
9
|
+
Milestone M001 completed.
|
|
10
|
+
|
|
11
|
+
## Why
|
|
12
|
+
|
|
13
|
+
Milestone work is complete and ready for review.
|
|
14
|
+
|
|
15
|
+
## How
|
|
16
|
+
|
|
17
|
+
Generated from GSD evidence and local workflow artifacts.
|
|
18
|
+
|
|
19
|
+
## Linked Issue
|
|
20
|
+
|
|
21
|
+
Not specified. Add an issue link before marking this PR ready if CONTRIBUTING.md requires one.
|
|
22
|
+
|
|
23
|
+
## Tests Run
|
|
24
|
+
|
|
25
|
+
- Not specified. Add exact verification commands before requesting review.
|
|
26
|
+
|
|
27
|
+
## Change Type
|
|
28
|
+
|
|
29
|
+
- [x] `feat` - New feature or capability
|
|
30
|
+
- [ ] `fix` - Bug fix
|
|
31
|
+
- [ ] `refactor` - Code restructuring
|
|
32
|
+
- [ ] `test` - Adding or updating tests
|
|
33
|
+
- [ ] `docs` - Documentation only
|
|
34
|
+
- [ ] `chore` - Build, CI, or tooling changes
|
|
35
|
+
|
|
36
|
+
## Rollback And Compatibility
|
|
37
|
+
|
|
38
|
+
- No behavior-changing rollback notes recorded.
|
|
39
|
+
|
|
40
|
+
## AI Assistance Disclosure
|
|
41
|
+
|
|
42
|
+
This PR was prepared with AI assistance.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
## TL;DR
|
|
2
|
+
|
|
3
|
+
**What:** Ship workflow lane/writer - lane/writer
|
|
4
|
+
**Why:** Workflow work is complete and ready for review.
|
|
5
|
+
**How:** Generated by GSD GitHub Sync swarm routines from lane evidence.
|
|
6
|
+
|
|
7
|
+
## What
|
|
8
|
+
|
|
9
|
+
### Swarm lane
|
|
10
|
+
**Lane:** `lane/writer`
|
|
11
|
+
**Branch:** `lane/single-writer`
|
|
12
|
+
**Owner:** @owner
|
|
13
|
+
**Latest commit:** `abc1234`
|
|
14
|
+
|
|
15
|
+
### Impact area
|
|
16
|
+
Single-writer UOK metadata.
|
|
17
|
+
|
|
18
|
+
### Changed contracts
|
|
19
|
+
- [ ] WriterToken
|
|
20
|
+
|
|
21
|
+
### Transition risks
|
|
22
|
+
- [ ] Writer token lifecycle regression
|
|
23
|
+
|
|
24
|
+
## Why
|
|
25
|
+
|
|
26
|
+
Workflow work is complete and ready for review.
|
|
27
|
+
|
|
28
|
+
## How
|
|
29
|
+
|
|
30
|
+
Generated by GSD GitHub Sync swarm routines from lane evidence.
|
|
31
|
+
|
|
32
|
+
## Linked Issue
|
|
33
|
+
|
|
34
|
+
Closes #123
|
|
35
|
+
|
|
36
|
+
## Tests Run
|
|
37
|
+
|
|
38
|
+
- npm run typecheck:extensions
|
|
39
|
+
|
|
40
|
+
## Change Type
|
|
41
|
+
|
|
42
|
+
- [ ] `feat` - New feature or capability
|
|
43
|
+
- [ ] `fix` - Bug fix
|
|
44
|
+
- [x] `refactor` - Code restructuring
|
|
45
|
+
- [ ] `test` - Adding or updating tests
|
|
46
|
+
- [ ] `docs` - Documentation only
|
|
47
|
+
- [ ] `chore` - Build, CI, or tooling changes
|
|
48
|
+
|
|
49
|
+
## Rollback And Compatibility
|
|
50
|
+
|
|
51
|
+
- Disable writer sequence enrichment
|
|
52
|
+
|
|
53
|
+
## AI Assistance Disclosure
|
|
54
|
+
|
|
55
|
+
This PR was prepared with AI assistance.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
## TL;DR
|
|
2
|
+
|
|
3
|
+
**What:** Ship workflow lane/writer - lane/writer
|
|
4
|
+
**Why:** Workflow work is complete and ready for review.
|
|
5
|
+
**How:** Generated by GSD GitHub Sync swarm routines from lane evidence.
|
|
6
|
+
|
|
7
|
+
## What
|
|
8
|
+
|
|
9
|
+
### Swarm lane
|
|
10
|
+
**Lane:** `lane/writer`
|
|
11
|
+
**Branch:** `lane/single-writer`
|
|
12
|
+
**Owner:** @owner
|
|
13
|
+
**Latest commit:** `abc1234`
|
|
14
|
+
|
|
15
|
+
### Impact area
|
|
16
|
+
Single-writer UOK metadata.
|
|
17
|
+
|
|
18
|
+
### Changed contracts
|
|
19
|
+
- [ ] WriterToken
|
|
20
|
+
|
|
21
|
+
### Transition risks
|
|
22
|
+
- [ ] Writer token lifecycle regression
|
|
23
|
+
|
|
24
|
+
## Blockers
|
|
25
|
+
|
|
26
|
+
- Awaiting state-lane writer-sequence merge
|
|
27
|
+
- Parity report incomplete
|
|
28
|
+
|
|
29
|
+
## Why
|
|
30
|
+
|
|
31
|
+
Workflow work is complete and ready for review.
|
|
32
|
+
|
|
33
|
+
## How
|
|
34
|
+
|
|
35
|
+
Generated by GSD GitHub Sync swarm routines from lane evidence.
|
|
36
|
+
|
|
37
|
+
## Linked Issue
|
|
38
|
+
|
|
39
|
+
Closes #123
|
|
40
|
+
|
|
41
|
+
## Tests Run
|
|
42
|
+
|
|
43
|
+
- npm run typecheck:extensions
|
|
44
|
+
|
|
45
|
+
## Change Type
|
|
46
|
+
|
|
47
|
+
- [ ] `feat` - New feature or capability
|
|
48
|
+
- [ ] `fix` - Bug fix
|
|
49
|
+
- [x] `refactor` - Code restructuring
|
|
50
|
+
- [ ] `test` - Adding or updating tests
|
|
51
|
+
- [ ] `docs` - Documentation only
|
|
52
|
+
- [ ] `chore` - Build, CI, or tooling changes
|
|
53
|
+
|
|
54
|
+
## Rollback And Compatibility
|
|
55
|
+
|
|
56
|
+
- Disable writer sequence enrichment
|
|
57
|
+
|
|
58
|
+
## AI Assistance Disclosure
|
|
59
|
+
|
|
60
|
+
This PR was prepared with AI assistance.
|
|
@@ -233,6 +233,16 @@ describe("getNextPendingStep", () => {
|
|
|
233
233
|
const next = getNextPendingStep(graph);
|
|
234
234
|
assert.equal(next?.id, "b");
|
|
235
235
|
});
|
|
236
|
+
|
|
237
|
+
it("treats expanded dependencies as satisfied", (t) => {
|
|
238
|
+
const graph = makeGraph([
|
|
239
|
+
makeStep({ id: "iter", status: "expanded" }),
|
|
240
|
+
makeStep({ id: "after", dependsOn: ["iter"] }),
|
|
241
|
+
]);
|
|
242
|
+
|
|
243
|
+
const next = getNextPendingStep(graph);
|
|
244
|
+
assert.equal(next?.id, "after");
|
|
245
|
+
});
|
|
236
246
|
});
|
|
237
247
|
|
|
238
248
|
// ─── markStepComplete ────────────────────────────────────────────────────
|
|
@@ -30,6 +30,10 @@ import {
|
|
|
30
30
|
insertTask,
|
|
31
31
|
getTask,
|
|
32
32
|
getSliceTasks,
|
|
33
|
+
deleteMilestone,
|
|
34
|
+
clearEngineHierarchy,
|
|
35
|
+
recordMilestoneCommitAttribution,
|
|
36
|
+
getMilestoneCommitAttributionShas,
|
|
33
37
|
checkpointDatabase,
|
|
34
38
|
refreshOpenDatabaseFromDisk,
|
|
35
39
|
tryCreateMemoriesFts,
|
|
@@ -1047,6 +1051,46 @@ describe('gsd-db', () => {
|
|
|
1047
1051
|
});
|
|
1048
1052
|
});
|
|
1049
1053
|
|
|
1054
|
+
// ─── milestone_commit_attributions teardown ───────────────────────────────
|
|
1055
|
+
|
|
1056
|
+
describe('milestone commit attribution teardown', () => {
|
|
1057
|
+
test('deleteMilestone removes persisted milestone commit attributions', () => {
|
|
1058
|
+
openDatabase(':memory:');
|
|
1059
|
+
insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
|
|
1060
|
+
recordMilestoneCommitAttribution({
|
|
1061
|
+
commitSha: '0123456789abcdef0123456789abcdef01234567',
|
|
1062
|
+
milestoneId: 'M001',
|
|
1063
|
+
source: 'backfill',
|
|
1064
|
+
confidence: 0.8,
|
|
1065
|
+
files: ['app.js'],
|
|
1066
|
+
createdAt: '2026-05-05T00:00:00.000Z',
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
assert.deepEqual(getMilestoneCommitAttributionShas('M001'), ['0123456789abcdef0123456789abcdef01234567']);
|
|
1070
|
+
deleteMilestone('M001');
|
|
1071
|
+
assert.deepEqual(getMilestoneCommitAttributionShas('M001'), []);
|
|
1072
|
+
closeDatabase();
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
test('clearEngineHierarchy removes persisted milestone commit attributions', () => {
|
|
1076
|
+
openDatabase(':memory:');
|
|
1077
|
+
insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
|
|
1078
|
+
recordMilestoneCommitAttribution({
|
|
1079
|
+
commitSha: 'fedcba9876543210fedcba9876543210fedcba98',
|
|
1080
|
+
milestoneId: 'M001',
|
|
1081
|
+
source: 'backfill',
|
|
1082
|
+
confidence: 0.8,
|
|
1083
|
+
files: ['app.js'],
|
|
1084
|
+
createdAt: '2026-05-05T00:00:00.000Z',
|
|
1085
|
+
});
|
|
1086
|
+
|
|
1087
|
+
assert.deepEqual(getMilestoneCommitAttributionShas('M001'), ['fedcba9876543210fedcba9876543210fedcba98']);
|
|
1088
|
+
clearEngineHierarchy();
|
|
1089
|
+
assert.deepEqual(getMilestoneCommitAttributionShas('M001'), []);
|
|
1090
|
+
closeDatabase();
|
|
1091
|
+
});
|
|
1092
|
+
});
|
|
1093
|
+
|
|
1050
1094
|
// ─── getDbStatus ───────────────────────────────────────────────────────────
|
|
1051
1095
|
|
|
1052
1096
|
describe('getDbStatus', () => {
|
|
@@ -15,7 +15,7 @@ import { tmpdir } from "node:os";
|
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import { randomUUID } from "node:crypto";
|
|
17
17
|
|
|
18
|
-
import { hasPendingDeepStage } from "../auto-dispatch.ts";
|
|
18
|
+
import { hasPendingDeepStage, shouldRunDeepProjectSetup } from "../auto-dispatch.ts";
|
|
19
19
|
import type { GSDPreferences } from "../preferences.ts";
|
|
20
20
|
import { loadEffectiveGSDPreferences } from "../preferences.ts";
|
|
21
21
|
|
|
@@ -57,6 +57,38 @@ test("hasPendingDeepStage: returns true in deep mode when nothing has been captu
|
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
test("shouldRunDeepProjectSetup: complete state wins over pending deep setup", async () => {
|
|
61
|
+
const base = makeBase();
|
|
62
|
+
try {
|
|
63
|
+
assert.equal(hasPendingDeepStage(deepPrefs, base), true);
|
|
64
|
+
assert.equal(
|
|
65
|
+
shouldRunDeepProjectSetup({ phase: "complete" }, deepPrefs, base),
|
|
66
|
+
false,
|
|
67
|
+
"completed projects must not restart deep setup and loop through auto-mode",
|
|
68
|
+
);
|
|
69
|
+
} finally {
|
|
70
|
+
rmSync(base, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("shouldRunDeepProjectSetup: only setup phases can trigger pending deep setup", () => {
|
|
75
|
+
const base = makeBase();
|
|
76
|
+
try {
|
|
77
|
+
assert.equal(hasPendingDeepStage(deepPrefs, base), true);
|
|
78
|
+
assert.equal(shouldRunDeepProjectSetup({ phase: "pre-planning" }, deepPrefs, base), true);
|
|
79
|
+
assert.equal(shouldRunDeepProjectSetup({ phase: "needs-discussion" }, deepPrefs, base), true);
|
|
80
|
+
assert.equal(shouldRunDeepProjectSetup({ phase: "planning" }, deepPrefs, base), true);
|
|
81
|
+
assert.equal(shouldRunDeepProjectSetup({ phase: "executing" }, deepPrefs, base), false);
|
|
82
|
+
assert.equal(shouldRunDeepProjectSetup({ phase: "blocked" }, deepPrefs, base), false);
|
|
83
|
+
assert.equal(
|
|
84
|
+
shouldRunDeepProjectSetup({ phase: "pre-planning" }, deepPrefs, base, { hasSurvivorBranch: true }),
|
|
85
|
+
false,
|
|
86
|
+
);
|
|
87
|
+
} finally {
|
|
88
|
+
rmSync(base, { recursive: true, force: true });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
60
92
|
test("hasPendingDeepStage: returns true in deep mode when only some gates pass", () => {
|
|
61
93
|
// workflow-preferences captured but PROJECT.md still missing.
|
|
62
94
|
const base = makeBase();
|
|
@@ -172,6 +172,56 @@ test('handlePlanSlice rejects invalid payloads', async () => {
|
|
|
172
172
|
}
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
+
test('handlePlanSlice rejects absolute task IO paths outside the active worktree', async () => {
|
|
176
|
+
const base = makeTmpBase();
|
|
177
|
+
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
seedParentSlice();
|
|
181
|
+
const outside = join(tmpdir(), 'outside-checkout', 'index.html');
|
|
182
|
+
const result = await handlePlanSlice({
|
|
183
|
+
...validParams(),
|
|
184
|
+
tasks: [
|
|
185
|
+
{
|
|
186
|
+
...validParams().tasks[0],
|
|
187
|
+
inputs: [outside],
|
|
188
|
+
expectedOutput: [outside],
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
}, base);
|
|
192
|
+
|
|
193
|
+
assert.ok('error' in result);
|
|
194
|
+
assert.match(result.error, /validation failed: tasks\[0\]\.inputs contains absolute path outside working directory/);
|
|
195
|
+
assert.equal(getSliceTasks('M001', 'S02').length, 0, 'invalid planning IO must not persist tasks');
|
|
196
|
+
} finally {
|
|
197
|
+
cleanup(base);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('handlePlanSlice accepts absolute task IO paths inside the active worktree', async () => {
|
|
202
|
+
const base = makeTmpBase();
|
|
203
|
+
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
204
|
+
|
|
205
|
+
try {
|
|
206
|
+
seedParentSlice();
|
|
207
|
+
const inside = join(base, 'index.html');
|
|
208
|
+
const result = await handlePlanSlice({
|
|
209
|
+
...validParams(),
|
|
210
|
+
tasks: [
|
|
211
|
+
{
|
|
212
|
+
...validParams().tasks[0],
|
|
213
|
+
inputs: [inside],
|
|
214
|
+
expectedOutput: [inside],
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
}, base);
|
|
218
|
+
|
|
219
|
+
assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
|
|
220
|
+
} finally {
|
|
221
|
+
cleanup(base);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
175
225
|
test('handlePlanSlice rejects missing parent slice', async () => {
|
|
176
226
|
const base = makeTmpBase();
|
|
177
227
|
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
@@ -79,6 +79,27 @@ test('handlePlanTask rejects invalid payloads', async () => {
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
+
test('handlePlanTask rejects absolute task IO paths outside the active worktree', async () => {
|
|
83
|
+
const base = makeTmpBase();
|
|
84
|
+
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
seedParent();
|
|
88
|
+
const outside = join(tmpdir(), 'outside-checkout', 'index.html');
|
|
89
|
+
const result = await handlePlanTask({
|
|
90
|
+
...validParams(),
|
|
91
|
+
inputs: [outside],
|
|
92
|
+
expectedOutput: [outside],
|
|
93
|
+
}, base);
|
|
94
|
+
|
|
95
|
+
assert.ok('error' in result);
|
|
96
|
+
assert.match(result.error, /validation failed: inputs contains absolute path outside working directory/);
|
|
97
|
+
assert.equal(getTask('M001', 'S02', 'T02'), null, 'invalid planning IO must not persist the task');
|
|
98
|
+
} finally {
|
|
99
|
+
cleanup(base);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
82
103
|
test('handlePlanTask rejects missing parent slice', async () => {
|
|
83
104
|
const base = makeTmpBase();
|
|
84
105
|
openDatabase(join(base, '.gsd', 'gsd.db'));
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Golden-fixture equivalence tests pinning PR-body output for buildPrEvidence and formatSwarmLanePRBody.
|
|
3
|
+
|
|
4
|
+
import test from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { dirname, join } from "node:path";
|
|
9
|
+
|
|
10
|
+
import { buildPrEvidence, type PrEvidenceInput } from "../pr-evidence.ts";
|
|
11
|
+
import {
|
|
12
|
+
formatSwarmLanePRBody,
|
|
13
|
+
type SwarmLanePRData,
|
|
14
|
+
} from "../../github-sync/templates.ts";
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const FIXTURES_DIR = join(__dirname, "fixtures", "pr-body");
|
|
18
|
+
|
|
19
|
+
const UPDATE = process.env.UPDATE_GOLDENS === "1";
|
|
20
|
+
|
|
21
|
+
function compareGolden(name: string, actual: string): void {
|
|
22
|
+
const path = join(FIXTURES_DIR, name);
|
|
23
|
+
if (UPDATE) {
|
|
24
|
+
writeFileSync(path, actual, "utf8");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const expected = readFileSync(path, "utf8");
|
|
28
|
+
assert.equal(actual, expected, `golden mismatch for ${name}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const SHIP_BASIC: PrEvidenceInput = {
|
|
32
|
+
milestoneId: "M001",
|
|
33
|
+
milestoneTitle: "Authentication",
|
|
34
|
+
changeType: "feat",
|
|
35
|
+
linkedIssue: "Closes #123",
|
|
36
|
+
summaries: ["### S01\nImplemented login flow."],
|
|
37
|
+
roadmapItems: ["- [x] **S01: Login**"],
|
|
38
|
+
metrics: ["**Units executed:** 3"],
|
|
39
|
+
testsRun: ["npm test", "npm run typecheck:extensions"],
|
|
40
|
+
why: "Users need to authenticate before accessing protected resources.",
|
|
41
|
+
how: "Added password hash check and session token issuance.",
|
|
42
|
+
rollbackNotes: ["Revert the merge commit."],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const SHIP_EMPTY_OPTIONALS: PrEvidenceInput = {
|
|
46
|
+
milestoneId: "M001",
|
|
47
|
+
milestoneTitle: "Authentication",
|
|
48
|
+
changeType: "feat",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const SWARM_WITH_BLOCKERS: SwarmLanePRData = {
|
|
52
|
+
lane: {
|
|
53
|
+
id: "writer",
|
|
54
|
+
branch: "lane/single-writer",
|
|
55
|
+
owner: "@owner",
|
|
56
|
+
latestCommit: "abc1234",
|
|
57
|
+
changedContracts: ["WriterToken"],
|
|
58
|
+
testEvidence: ["npm run typecheck:extensions"],
|
|
59
|
+
blockers: ["Awaiting state-lane writer-sequence merge", "Parity report incomplete"],
|
|
60
|
+
},
|
|
61
|
+
impactArea: "Single-writer UOK metadata.",
|
|
62
|
+
transitionRisks: ["Writer token lifecycle regression"],
|
|
63
|
+
rollbackPlan: ["Disable writer sequence enrichment"],
|
|
64
|
+
linkedIssue: 123,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const SWARM_NO_BLOCKERS: SwarmLanePRData = {
|
|
68
|
+
lane: {
|
|
69
|
+
id: "writer",
|
|
70
|
+
branch: "lane/single-writer",
|
|
71
|
+
owner: "@owner",
|
|
72
|
+
latestCommit: "abc1234",
|
|
73
|
+
changedContracts: ["WriterToken"],
|
|
74
|
+
testEvidence: ["npm run typecheck:extensions"],
|
|
75
|
+
},
|
|
76
|
+
impactArea: "Single-writer UOK metadata.",
|
|
77
|
+
transitionRisks: ["Writer token lifecycle regression"],
|
|
78
|
+
rollbackPlan: ["Disable writer sequence enrichment"],
|
|
79
|
+
linkedIssue: 123,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
test("pr-evidence golden: commands-ship basic", () => {
|
|
83
|
+
compareGolden("commands-ship-basic.md", buildPrEvidence(SHIP_BASIC).body);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("pr-evidence golden: commands-ship empty optionals", () => {
|
|
87
|
+
compareGolden("commands-ship-empty-optionals.md", buildPrEvidence(SHIP_EMPTY_OPTIONALS).body);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("pr-evidence golden: swarm-lane with blockers", () => {
|
|
91
|
+
const body = formatSwarmLanePRBody(SWARM_WITH_BLOCKERS);
|
|
92
|
+
compareGolden("swarm-lane-with-blockers.md", body);
|
|
93
|
+
// Cross-check: top-level ## Blockers heading must appear (regression guard
|
|
94
|
+
// for the silent-drop fixed in this PR).
|
|
95
|
+
assert.ok(body.includes("\n## Blockers\n"), "swarm-lane body must emit a top-level ## Blockers heading");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test("pr-evidence golden: swarm-lane no blockers (no Blockers heading)", () => {
|
|
99
|
+
const body = formatSwarmLanePRBody(SWARM_NO_BLOCKERS);
|
|
100
|
+
compareGolden("swarm-lane-no-blockers.md", body);
|
|
101
|
+
assert.ok(!body.includes("## Blockers"), "swarm-lane body without blockers must not emit ## Blockers heading");
|
|
102
|
+
});
|