gsd-pi 2.41.0 → 2.42.0-dev.eedc83f
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 +92 -29
- package/dist/cli-web-branch.d.ts +6 -0
- package/dist/cli-web-branch.js +17 -0
- package/dist/cli.js +15 -1
- package/dist/onboarding.js +2 -1
- package/dist/resource-loader.js +39 -6
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
- package/dist/resources/extensions/gsd/auto/loop.js +89 -1
- package/dist/resources/extensions/gsd/auto/phases.js +28 -10
- package/dist/resources/extensions/gsd/auto/session.js +6 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
- package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
- package/dist/resources/extensions/gsd/auto-start.js +8 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
- package/dist/resources/extensions/gsd/auto.js +64 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
- package/dist/resources/extensions/gsd/context-injector.js +74 -0
- package/dist/resources/extensions/gsd/context-store.js +4 -3
- package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
- package/dist/resources/extensions/gsd/custom-verification.js +145 -0
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
- package/dist/resources/extensions/gsd/db-writer.js +5 -2
- package/dist/resources/extensions/gsd/definition-loader.js +352 -0
- package/dist/resources/extensions/gsd/detection.js +20 -1
- package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
- package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
- package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
- package/dist/resources/extensions/gsd/doctor.js +11 -1
- package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
- package/dist/resources/extensions/gsd/engine-types.js +8 -0
- package/dist/resources/extensions/gsd/execution-policy.js +8 -0
- package/dist/resources/extensions/gsd/exit-command.js +12 -2
- package/dist/resources/extensions/gsd/export.js +9 -13
- package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
- package/dist/resources/extensions/gsd/files.js +28 -11
- package/dist/resources/extensions/gsd/forensics.js +94 -3
- package/dist/resources/extensions/gsd/git-constants.js +1 -0
- package/dist/resources/extensions/gsd/git-service.js +73 -3
- package/dist/resources/extensions/gsd/graph.js +225 -0
- package/dist/resources/extensions/gsd/gsd-db.js +25 -8
- package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
- package/dist/resources/extensions/gsd/guided-flow.js +7 -3
- package/dist/resources/extensions/gsd/journal.js +85 -0
- package/dist/resources/extensions/gsd/md-importer.js +5 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences.js +60 -8
- package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
- package/dist/resources/extensions/gsd/repo-identity.js +92 -7
- package/dist/resources/extensions/gsd/rule-registry.js +489 -0
- package/dist/resources/extensions/gsd/rule-types.js +6 -0
- package/dist/resources/extensions/gsd/run-manager.js +134 -0
- package/dist/resources/extensions/gsd/service-tier.js +147 -0
- package/dist/resources/extensions/gsd/session-lock.js +2 -2
- package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
- package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
- package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
- package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
- package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
- package/dist/resources/extensions/mcp-client/index.js +2 -1
- package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
- package/dist/resources/extensions/subagent/index.js +7 -3
- package/dist/resources/extensions/voice/index.js +4 -4
- package/dist/resources/skills/create-workflow/SKILL.md +103 -0
- package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- 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/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 +2 -2
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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/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/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/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 +5 -5
- 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/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 +2 -2
- 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 +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +13 -13
- package/dist/web/standalone/.next/server/chunks/229.js +3 -3
- package/dist/web/standalone/.next/server/chunks/471.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/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +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/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/web-mode.d.ts +4 -0
- package/dist/web-mode.js +69 -11
- package/package.json +1 -1
- package/packages/native/src/__tests__/text.test.mjs +33 -0
- 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/dist/types.d.ts +6 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent.test.ts +53 -0
- package/packages/pi-agent-core/src/agent.ts +3 -0
- package/packages/pi-agent-core/src/types.ts +6 -0
- package/packages/pi-agent-core/tsconfig.json +1 -1
- package/packages/pi-ai/dist/models.d.ts +5 -3
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +1135 -1588
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +1543 -0
- package/packages/pi-ai/src/models.generated.ts +1140 -1593
- package/packages/pi-ai/src/models.ts +7 -4
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.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 +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- 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 +34 -10
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
- package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
- package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
- package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
- package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
- package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
- package/src/resources/extensions/gsd/auto/loop.ts +101 -1
- package/src/resources/extensions/gsd/auto/phases.ts +30 -10
- package/src/resources/extensions/gsd/auto/session.ts +6 -0
- package/src/resources/extensions/gsd/auto/types.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
- package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
- package/src/resources/extensions/gsd/auto-start.ts +8 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
- package/src/resources/extensions/gsd/auto.ts +71 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
- package/src/resources/extensions/gsd/context-injector.ts +100 -0
- package/src/resources/extensions/gsd/context-store.ts +4 -3
- package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
- package/src/resources/extensions/gsd/custom-verification.ts +180 -0
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
- package/src/resources/extensions/gsd/db-writer.ts +6 -2
- package/src/resources/extensions/gsd/definition-loader.ts +462 -0
- package/src/resources/extensions/gsd/detection.ts +20 -1
- package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
- package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
- package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
- package/src/resources/extensions/gsd/doctor-types.ts +1 -0
- package/src/resources/extensions/gsd/doctor.ts +12 -1
- package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
- package/src/resources/extensions/gsd/engine-types.ts +71 -0
- package/src/resources/extensions/gsd/execution-policy.ts +43 -0
- package/src/resources/extensions/gsd/exit-command.ts +14 -2
- package/src/resources/extensions/gsd/export.ts +8 -15
- package/src/resources/extensions/gsd/extension-manifest.json +2 -2
- package/src/resources/extensions/gsd/files.ts +29 -12
- package/src/resources/extensions/gsd/forensics.ts +101 -3
- package/src/resources/extensions/gsd/git-constants.ts +1 -0
- package/src/resources/extensions/gsd/git-service.ts +76 -6
- package/src/resources/extensions/gsd/graph.ts +312 -0
- package/src/resources/extensions/gsd/gsd-db.ts +37 -8
- package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
- package/src/resources/extensions/gsd/guided-flow.ts +7 -3
- package/src/resources/extensions/gsd/journal.ts +134 -0
- package/src/resources/extensions/gsd/md-importer.ts +6 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
- package/src/resources/extensions/gsd/preferences-types.ts +6 -0
- package/src/resources/extensions/gsd/preferences.ts +63 -6
- package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
- package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
- package/src/resources/extensions/gsd/prompts/queue.md +1 -1
- package/src/resources/extensions/gsd/repo-identity.ts +95 -7
- package/src/resources/extensions/gsd/rule-registry.ts +599 -0
- package/src/resources/extensions/gsd/rule-types.ts +68 -0
- package/src/resources/extensions/gsd/run-manager.ts +180 -0
- package/src/resources/extensions/gsd/service-tier.ts +184 -0
- package/src/resources/extensions/gsd/session-lock.ts +2 -2
- package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
- package/src/resources/extensions/gsd/templates/decisions.md +2 -2
- package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
- package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
- package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
- package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
- package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
- package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
- package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
- package/src/resources/extensions/gsd/types.ts +3 -0
- package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
- package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
- package/src/resources/extensions/gsd/worktree-resolver.ts +32 -11
- package/src/resources/extensions/mcp-client/index.ts +5 -1
- package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
- package/src/resources/extensions/subagent/index.ts +7 -3
- package/src/resources/extensions/voice/index.ts +4 -4
- package/src/resources/skills/create-workflow/SKILL.md +103 -0
- package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
- package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
- package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
- package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
- package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
- package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
- package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
- package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
- package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
- /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dev-engine-wrapper.test.ts — Contract tests for the dev engine wrapper layer (S02).
|
|
3
|
+
*
|
|
4
|
+
* Tests bridgeDispatchAction mapping, DevWorkflowEngine delegation,
|
|
5
|
+
* DevExecutionPolicy stubs, resolver routing, kill switch, and
|
|
6
|
+
* auto.ts engine ID accessors.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import test, { describe, before, after } from "node:test";
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
import { mkdtempSync, mkdirSync, rmSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
|
|
15
|
+
// ── bridgeDispatchAction mapping ────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
describe("bridgeDispatchAction", () => {
|
|
18
|
+
test("maps dispatch action with step fields", async () => {
|
|
19
|
+
const { bridgeDispatchAction } = await import(
|
|
20
|
+
"../dev-workflow-engine.ts"
|
|
21
|
+
);
|
|
22
|
+
const result = bridgeDispatchAction({
|
|
23
|
+
action: "dispatch",
|
|
24
|
+
unitType: "execute-task",
|
|
25
|
+
unitId: "T01",
|
|
26
|
+
prompt: "do stuff",
|
|
27
|
+
matchedRule: "foo",
|
|
28
|
+
} as any);
|
|
29
|
+
|
|
30
|
+
assert.equal(result.action, "dispatch");
|
|
31
|
+
assert.ok("step" in result);
|
|
32
|
+
const step = (result as any).step;
|
|
33
|
+
assert.equal(step.unitType, "execute-task");
|
|
34
|
+
assert.equal(step.unitId, "T01");
|
|
35
|
+
assert.equal(step.prompt, "do stuff");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("maps stop action with reason and level", async () => {
|
|
39
|
+
const { bridgeDispatchAction } = await import(
|
|
40
|
+
"../dev-workflow-engine.ts"
|
|
41
|
+
);
|
|
42
|
+
const result = bridgeDispatchAction({
|
|
43
|
+
action: "stop",
|
|
44
|
+
reason: "done",
|
|
45
|
+
level: "info",
|
|
46
|
+
matchedRule: "bar",
|
|
47
|
+
} as any);
|
|
48
|
+
|
|
49
|
+
assert.equal(result.action, "stop");
|
|
50
|
+
assert.equal((result as any).reason, "done");
|
|
51
|
+
assert.equal((result as any).level, "info");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("maps skip action", async () => {
|
|
55
|
+
const { bridgeDispatchAction } = await import(
|
|
56
|
+
"../dev-workflow-engine.ts"
|
|
57
|
+
);
|
|
58
|
+
const result = bridgeDispatchAction({
|
|
59
|
+
action: "skip",
|
|
60
|
+
matchedRule: "baz",
|
|
61
|
+
} as any);
|
|
62
|
+
|
|
63
|
+
assert.equal(result.action, "skip");
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ── DevWorkflowEngine ───────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
describe("DevWorkflowEngine", () => {
|
|
70
|
+
test("engineId is 'dev'", async () => {
|
|
71
|
+
const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
|
|
72
|
+
const engine = new DevWorkflowEngine();
|
|
73
|
+
assert.equal(engine.engineId, "dev");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("deriveState returns EngineState with expected fields", async () => {
|
|
77
|
+
const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
|
|
78
|
+
const engine = new DevWorkflowEngine();
|
|
79
|
+
|
|
80
|
+
// Create a minimal temp .gsd structure for deriveState
|
|
81
|
+
const tempDir = mkdtempSync(join(tmpdir(), "gsd-engine-test-"));
|
|
82
|
+
mkdirSync(join(tempDir, ".gsd", "milestones"), { recursive: true });
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const state = await engine.deriveState(tempDir);
|
|
86
|
+
|
|
87
|
+
assert.equal(typeof state.phase, "string", "phase should be a string");
|
|
88
|
+
assert.ok(
|
|
89
|
+
"currentMilestoneId" in state,
|
|
90
|
+
"state should have currentMilestoneId",
|
|
91
|
+
);
|
|
92
|
+
assert.ok(
|
|
93
|
+
"activeSliceId" in state,
|
|
94
|
+
"state should have activeSliceId",
|
|
95
|
+
);
|
|
96
|
+
assert.ok(
|
|
97
|
+
"activeTaskId" in state,
|
|
98
|
+
"state should have activeTaskId",
|
|
99
|
+
);
|
|
100
|
+
assert.equal(
|
|
101
|
+
typeof state.isComplete,
|
|
102
|
+
"boolean",
|
|
103
|
+
"isComplete should be boolean",
|
|
104
|
+
);
|
|
105
|
+
assert.ok("raw" in state, "state should have raw field");
|
|
106
|
+
} finally {
|
|
107
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("reconcile returns continue for non-complete state", async () => {
|
|
112
|
+
const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
|
|
113
|
+
const engine = new DevWorkflowEngine();
|
|
114
|
+
|
|
115
|
+
const state = {
|
|
116
|
+
phase: "executing",
|
|
117
|
+
currentMilestoneId: "M001",
|
|
118
|
+
activeSliceId: "S01",
|
|
119
|
+
activeTaskId: "T01",
|
|
120
|
+
isComplete: false,
|
|
121
|
+
raw: {},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const result = await engine.reconcile(state, {
|
|
125
|
+
unitType: "execute-task",
|
|
126
|
+
unitId: "T01",
|
|
127
|
+
startedAt: Date.now() - 1000,
|
|
128
|
+
finishedAt: Date.now(),
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
assert.equal(result.outcome, "continue");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test("reconcile returns milestone-complete for complete state", async () => {
|
|
135
|
+
const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
|
|
136
|
+
const engine = new DevWorkflowEngine();
|
|
137
|
+
|
|
138
|
+
const state = {
|
|
139
|
+
phase: "complete",
|
|
140
|
+
currentMilestoneId: "M001",
|
|
141
|
+
activeSliceId: null,
|
|
142
|
+
activeTaskId: null,
|
|
143
|
+
isComplete: true,
|
|
144
|
+
raw: {},
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const result = await engine.reconcile(state, {
|
|
148
|
+
unitType: "execute-task",
|
|
149
|
+
unitId: "T01",
|
|
150
|
+
startedAt: Date.now() - 1000,
|
|
151
|
+
finishedAt: Date.now(),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
assert.equal(result.outcome, "milestone-complete");
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test("getDisplayMetadata returns expected fields", async () => {
|
|
158
|
+
const { DevWorkflowEngine } = await import("../dev-workflow-engine.ts");
|
|
159
|
+
const engine = new DevWorkflowEngine();
|
|
160
|
+
|
|
161
|
+
const state = {
|
|
162
|
+
phase: "executing",
|
|
163
|
+
currentMilestoneId: "M001",
|
|
164
|
+
activeSliceId: "S01",
|
|
165
|
+
activeTaskId: "T01",
|
|
166
|
+
isComplete: false,
|
|
167
|
+
raw: {},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const meta = engine.getDisplayMetadata(state);
|
|
171
|
+
|
|
172
|
+
assert.ok("engineLabel" in meta, "should have engineLabel");
|
|
173
|
+
assert.ok("currentPhase" in meta, "should have currentPhase");
|
|
174
|
+
assert.ok("progressSummary" in meta, "should have progressSummary");
|
|
175
|
+
assert.ok("stepCount" in meta, "should have stepCount");
|
|
176
|
+
assert.equal(meta.engineLabel, "GSD Dev");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// ── DevExecutionPolicy stubs ────────────────────────────────────────────────
|
|
181
|
+
|
|
182
|
+
describe("DevExecutionPolicy", () => {
|
|
183
|
+
test("verify returns 'continue'", async () => {
|
|
184
|
+
const { DevExecutionPolicy } = await import(
|
|
185
|
+
"../dev-execution-policy.ts"
|
|
186
|
+
);
|
|
187
|
+
const policy = new DevExecutionPolicy();
|
|
188
|
+
const result = await policy.verify("execute-task", "T01", {
|
|
189
|
+
basePath: "/tmp",
|
|
190
|
+
});
|
|
191
|
+
assert.equal(result, "continue");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("selectModel returns null", async () => {
|
|
195
|
+
const { DevExecutionPolicy } = await import(
|
|
196
|
+
"../dev-execution-policy.ts"
|
|
197
|
+
);
|
|
198
|
+
const policy = new DevExecutionPolicy();
|
|
199
|
+
const result = await policy.selectModel("execute-task", "T01", {
|
|
200
|
+
basePath: "/tmp",
|
|
201
|
+
});
|
|
202
|
+
assert.equal(result, null);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("recover returns { outcome: 'retry' }", async () => {
|
|
206
|
+
const { DevExecutionPolicy } = await import(
|
|
207
|
+
"../dev-execution-policy.ts"
|
|
208
|
+
);
|
|
209
|
+
const policy = new DevExecutionPolicy();
|
|
210
|
+
const result = await policy.recover("execute-task", "T01", {
|
|
211
|
+
basePath: "/tmp",
|
|
212
|
+
});
|
|
213
|
+
assert.deepEqual(result, { outcome: "retry" });
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("closeout returns { committed: false, artifacts: [] }", async () => {
|
|
217
|
+
const { DevExecutionPolicy } = await import(
|
|
218
|
+
"../dev-execution-policy.ts"
|
|
219
|
+
);
|
|
220
|
+
const policy = new DevExecutionPolicy();
|
|
221
|
+
const result = await policy.closeout("execute-task", "T01", {
|
|
222
|
+
basePath: "/tmp",
|
|
223
|
+
startedAt: Date.now(),
|
|
224
|
+
});
|
|
225
|
+
assert.deepEqual(result, { committed: false, artifacts: [] });
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("prepareWorkspace resolves without error", async () => {
|
|
229
|
+
const { DevExecutionPolicy } = await import(
|
|
230
|
+
"../dev-execution-policy.ts"
|
|
231
|
+
);
|
|
232
|
+
const policy = new DevExecutionPolicy();
|
|
233
|
+
await assert.doesNotReject(
|
|
234
|
+
() => policy.prepareWorkspace("/tmp", "M001"),
|
|
235
|
+
"prepareWorkspace should resolve without error",
|
|
236
|
+
);
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// ── Resolver routing ────────────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
describe("Resolver routing", () => {
|
|
243
|
+
test("resolveEngine returns dev engine for null activeEngineId", async () => {
|
|
244
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
245
|
+
const result = resolveEngine({ activeEngineId: null });
|
|
246
|
+
assert.ok(result.engine, "should return engine");
|
|
247
|
+
assert.ok(result.policy, "should return policy");
|
|
248
|
+
assert.equal(result.engine.engineId, "dev");
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test("resolveEngine returns dev engine for 'dev' activeEngineId", async () => {
|
|
252
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
253
|
+
const result = resolveEngine({ activeEngineId: "dev" });
|
|
254
|
+
assert.ok(result.engine, "should return engine");
|
|
255
|
+
assert.ok(result.policy, "should return policy");
|
|
256
|
+
assert.equal(result.engine.engineId, "dev");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("resolveEngine throws for unknown activeEngineId without activeRunDir", async () => {
|
|
260
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
261
|
+
assert.throws(
|
|
262
|
+
() => resolveEngine({ activeEngineId: "unknown" }),
|
|
263
|
+
/requires activeRunDir/,
|
|
264
|
+
"should throw when activeRunDir is missing for non-dev engine",
|
|
265
|
+
);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// ── Kill switch ─────────────────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
describe("Kill switch (GSD_ENGINE_BYPASS)", () => {
|
|
272
|
+
const originalBypass = process.env.GSD_ENGINE_BYPASS;
|
|
273
|
+
|
|
274
|
+
after(() => {
|
|
275
|
+
// Restore original env var state
|
|
276
|
+
if (originalBypass === undefined) {
|
|
277
|
+
delete process.env.GSD_ENGINE_BYPASS;
|
|
278
|
+
} else {
|
|
279
|
+
process.env.GSD_ENGINE_BYPASS = originalBypass;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("GSD_ENGINE_BYPASS=1 does not affect resolveEngine (bypass checked in autoLoop)", async () => {
|
|
284
|
+
const { resolveEngine } = await import("../engine-resolver.ts");
|
|
285
|
+
process.env.GSD_ENGINE_BYPASS = "1";
|
|
286
|
+
try {
|
|
287
|
+
// resolveEngine should still resolve normally — bypass is checked in autoLoop
|
|
288
|
+
const { engine } = resolveEngine({ activeEngineId: null });
|
|
289
|
+
assert.ok(engine, "should return an engine even with bypass set");
|
|
290
|
+
} finally {
|
|
291
|
+
delete process.env.GSD_ENGINE_BYPASS;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// ── auto.ts engine ID accessors ─────────────────────────────────────────────
|
|
297
|
+
|
|
298
|
+
describe("auto.ts engine ID accessors", () => {
|
|
299
|
+
test("setActiveEngineId / getActiveEngineId round-trip", async () => {
|
|
300
|
+
const { setActiveEngineId, getActiveEngineId } = await import(
|
|
301
|
+
"../auto.ts"
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
setActiveEngineId("dev");
|
|
305
|
+
assert.equal(
|
|
306
|
+
getActiveEngineId(),
|
|
307
|
+
"dev",
|
|
308
|
+
"getActiveEngineId should return 'dev' after setting",
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
setActiveEngineId(null);
|
|
312
|
+
assert.equal(
|
|
313
|
+
getActiveEngineId(),
|
|
314
|
+
null,
|
|
315
|
+
"getActiveEngineId should return null after setting null",
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
@@ -80,7 +80,7 @@ test("COMPLETION_TRANSITION_CODES only contains slice summary code", () => {
|
|
|
80
80
|
);
|
|
81
81
|
});
|
|
82
82
|
|
|
83
|
-
test("fixLevel:task — fixes
|
|
83
|
+
test("fixLevel:task — fixes UAT stub immediately, defers summary and roadmap checkbox (#1808, #1910)", async () => {
|
|
84
84
|
const tmp = makeTmp("partial-deferral");
|
|
85
85
|
try {
|
|
86
86
|
buildScaffold(tmp);
|
|
@@ -101,15 +101,16 @@ test("fixLevel:task — fixes roadmap checkbox and UAT stub immediately, defers
|
|
|
101
101
|
const sliceUatPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-UAT.md");
|
|
102
102
|
assert.ok(existsSync(sliceUatPath), "should have created UAT stub immediately");
|
|
103
103
|
|
|
104
|
-
// Roadmap checkbox
|
|
104
|
+
// Roadmap checkbox must NOT be checked without summary on disk (#1910).
|
|
105
|
+
// Checking it without the summary causes deriveState() to skip complete-slice.
|
|
105
106
|
const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
|
|
106
|
-
assert.ok(roadmapContent.includes("- [
|
|
107
|
+
assert.ok(roadmapContent.includes("- [ ] **S01"), "roadmap must NOT be checked without summary on disk (#1910)");
|
|
107
108
|
} finally {
|
|
108
109
|
rmSync(tmp, { recursive: true, force: true });
|
|
109
110
|
}
|
|
110
111
|
});
|
|
111
112
|
|
|
112
|
-
test("fixLevel:task — session crash after last task leaves roadmap
|
|
113
|
+
test("fixLevel:task — session crash after last task leaves UAT consistent, roadmap deferred with summary (#1808, #1910)", async () => {
|
|
113
114
|
const tmp = makeTmp("crash-consistency");
|
|
114
115
|
try {
|
|
115
116
|
buildScaffold(tmp);
|
|
@@ -121,13 +122,7 @@ test("fixLevel:task — session crash after last task leaves roadmap and UAT con
|
|
|
121
122
|
// A new session starts and runs doctor again at task level.
|
|
122
123
|
const report2 = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
|
|
123
124
|
|
|
124
|
-
// The only remaining issue should be the deferred summary.
|
|
125
|
-
// Roadmap and UAT should already be fixed from the first run.
|
|
126
125
|
const remainingCodes = report2.issues.map(i => i.code);
|
|
127
|
-
assert.ok(
|
|
128
|
-
!remainingCodes.includes("all_tasks_done_roadmap_not_checked"),
|
|
129
|
-
"roadmap should already be fixed from first doctor run"
|
|
130
|
-
);
|
|
131
126
|
assert.ok(
|
|
132
127
|
!remainingCodes.includes("all_tasks_done_missing_slice_uat"),
|
|
133
128
|
"UAT should already be fixed from first doctor run"
|
|
@@ -137,6 +132,16 @@ test("fixLevel:task — session crash after last task leaves roadmap and UAT con
|
|
|
137
132
|
remainingCodes.includes("all_tasks_done_missing_slice_summary"),
|
|
138
133
|
"summary should still be detected as missing (deferred)"
|
|
139
134
|
);
|
|
135
|
+
// Roadmap should still be unchecked because summary doesn't exist (#1910)
|
|
136
|
+
assert.ok(
|
|
137
|
+
remainingCodes.includes("all_tasks_done_roadmap_not_checked"),
|
|
138
|
+
"roadmap should still be unchecked — summary does not exist on disk (#1910)"
|
|
139
|
+
);
|
|
140
|
+
// Must NOT produce the cascade error from checking roadmap without summary
|
|
141
|
+
assert.ok(
|
|
142
|
+
!remainingCodes.includes("slice_checked_missing_summary"),
|
|
143
|
+
"must not produce slice_checked_missing_summary (#1910)"
|
|
144
|
+
);
|
|
140
145
|
} finally {
|
|
141
146
|
rmSync(tmp, { recursive: true, force: true });
|
|
142
147
|
}
|
|
@@ -63,7 +63,7 @@ Done.
|
|
|
63
63
|
`);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
test("fixLevel:task — defers
|
|
66
|
+
test("fixLevel:task — defers summary stub and roadmap checkbox, fixes UAT immediately (#1808, #1910)", async () => {
|
|
67
67
|
const tmp = makeTmp("task-level");
|
|
68
68
|
try {
|
|
69
69
|
buildScaffold(tmp);
|
|
@@ -79,13 +79,14 @@ test("fixLevel:task — defers only summary stub, fixes roadmap and UAT immediat
|
|
|
79
79
|
const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
80
80
|
assert.ok(!existsSync(sliceSummaryPath), "should NOT have created summary stub");
|
|
81
81
|
|
|
82
|
-
// Roadmap
|
|
82
|
+
// Roadmap must NOT be checked without summary on disk (#1910)
|
|
83
83
|
const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
|
|
84
|
-
assert.ok(roadmapContent.includes("- [
|
|
84
|
+
assert.ok(roadmapContent.includes("- [ ] **S01"), "roadmap must NOT be checked without summary (#1910)");
|
|
85
85
|
|
|
86
|
-
// Fixes applied should NOT include summary
|
|
86
|
+
// Fixes applied should NOT include summary or roadmap
|
|
87
87
|
for (const f of report.fixesApplied) {
|
|
88
88
|
assert.ok(!f.includes("SUMMARY"), `should not have fixed summary: ${f}`);
|
|
89
|
+
assert.ok(!f.includes("ROADMAP") && !f.includes("roadmap"), `should not have fixed roadmap: ${f}`);
|
|
89
90
|
}
|
|
90
91
|
} finally {
|
|
91
92
|
rmSync(tmp, { recursive: true, force: true });
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for #1910: Doctor marks roadmap checkbox at fixLevel="task"
|
|
3
|
+
* without summary on disk, causing deriveState() to skip complete-slice and
|
|
4
|
+
* hard-stop at validating-milestone.
|
|
5
|
+
*
|
|
6
|
+
* The roadmap checkbox must only be marked when the slice summary actually
|
|
7
|
+
* exists on disk (either pre-existing or created in the current doctor run).
|
|
8
|
+
* At fixLevel="task", the summary is deferred (COMPLETION_TRANSITION_CODES),
|
|
9
|
+
* so the roadmap checkbox must also be deferred.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { mkdirSync, writeFileSync, rmSync, readFileSync, existsSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import { runGSDDoctor } from "../doctor.ts";
|
|
18
|
+
|
|
19
|
+
function makeTmp(name: string): string {
|
|
20
|
+
const dir = join(tmpdir(), `doctor-roadmap-summary-${name}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
21
|
+
mkdirSync(dir, { recursive: true });
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Build a minimal .gsd structure: milestone with one slice, one task
|
|
27
|
+
* marked done with a summary — but no slice summary and roadmap unchecked.
|
|
28
|
+
* This is the state after the last task completes.
|
|
29
|
+
*/
|
|
30
|
+
function buildScaffold(base: string) {
|
|
31
|
+
const gsd = join(base, ".gsd");
|
|
32
|
+
const m = join(gsd, "milestones", "M001");
|
|
33
|
+
const s = join(m, "slices", "S01", "tasks");
|
|
34
|
+
mkdirSync(s, { recursive: true });
|
|
35
|
+
|
|
36
|
+
writeFileSync(join(m, "M001-ROADMAP.md"), `# M001: Test
|
|
37
|
+
|
|
38
|
+
## Slices
|
|
39
|
+
|
|
40
|
+
- [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
|
|
41
|
+
> Demo text
|
|
42
|
+
`);
|
|
43
|
+
|
|
44
|
+
writeFileSync(join(m, "slices", "S01", "S01-PLAN.md"), `# S01: Test Slice
|
|
45
|
+
|
|
46
|
+
**Goal:** test
|
|
47
|
+
|
|
48
|
+
## Tasks
|
|
49
|
+
|
|
50
|
+
- [x] **T01: Do stuff** \`est:5m\`
|
|
51
|
+
`);
|
|
52
|
+
|
|
53
|
+
writeFileSync(join(s, "T01-SUMMARY.md"), `---
|
|
54
|
+
id: T01
|
|
55
|
+
parent: S01
|
|
56
|
+
milestone: M001
|
|
57
|
+
duration: 5m
|
|
58
|
+
verification_result: passed
|
|
59
|
+
completed_at: 2026-01-01
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
# T01: Do stuff
|
|
63
|
+
|
|
64
|
+
Done.
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
test("fixLevel:task — must NOT mark roadmap checkbox when summary does not exist on disk (#1910)", async () => {
|
|
69
|
+
const tmp = makeTmp("no-roadmap-without-summary");
|
|
70
|
+
try {
|
|
71
|
+
buildScaffold(tmp);
|
|
72
|
+
|
|
73
|
+
const report = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
|
|
74
|
+
|
|
75
|
+
// Doctor should detect both issues
|
|
76
|
+
const codes = report.issues.map(i => i.code);
|
|
77
|
+
assert.ok(codes.includes("all_tasks_done_missing_slice_summary"), "should detect missing summary");
|
|
78
|
+
assert.ok(codes.includes("all_tasks_done_roadmap_not_checked"), "should detect unchecked roadmap");
|
|
79
|
+
|
|
80
|
+
// Summary should NOT exist (deferred at task level)
|
|
81
|
+
const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
82
|
+
assert.ok(!existsSync(sliceSummaryPath), "summary should NOT be created (deferred)");
|
|
83
|
+
|
|
84
|
+
// CRITICAL: Roadmap checkbox must NOT be checked without summary on disk.
|
|
85
|
+
// If it is checked, deriveState() sees the milestone as complete and skips
|
|
86
|
+
// the summarizing phase, causing a hard-stop at validating-milestone.
|
|
87
|
+
const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
|
|
88
|
+
assert.ok(
|
|
89
|
+
roadmapContent.includes("- [ ] **S01"),
|
|
90
|
+
"roadmap must NOT mark S01 as checked when summary does not exist on disk"
|
|
91
|
+
);
|
|
92
|
+
} finally {
|
|
93
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("fixLevel:task — consecutive runs must not produce slice_checked_missing_summary (#1910)", async () => {
|
|
98
|
+
const tmp = makeTmp("no-cascade-error");
|
|
99
|
+
try {
|
|
100
|
+
buildScaffold(tmp);
|
|
101
|
+
|
|
102
|
+
// First doctor run at task level
|
|
103
|
+
await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
|
|
104
|
+
|
|
105
|
+
// Second doctor run — if the first run incorrectly checked the roadmap,
|
|
106
|
+
// this run would detect slice_checked_missing_summary (the cascade error
|
|
107
|
+
// described in the issue's forensic evidence).
|
|
108
|
+
const report2 = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
|
|
109
|
+
const codes2 = report2.issues.map(i => i.code);
|
|
110
|
+
|
|
111
|
+
assert.ok(
|
|
112
|
+
!codes2.includes("slice_checked_missing_summary"),
|
|
113
|
+
"must not produce slice_checked_missing_summary — roadmap should not have been checked without summary"
|
|
114
|
+
);
|
|
115
|
+
} finally {
|
|
116
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("fixLevel:all — roadmap checkbox IS marked because summary is created in same run (#1910)", async () => {
|
|
121
|
+
const tmp = makeTmp("all-level-creates-both");
|
|
122
|
+
try {
|
|
123
|
+
buildScaffold(tmp);
|
|
124
|
+
|
|
125
|
+
const report = await runGSDDoctor(tmp, { fix: true });
|
|
126
|
+
|
|
127
|
+
// At fixLevel:all, summary stub is created first, then roadmap is checked.
|
|
128
|
+
// Both should be fixed.
|
|
129
|
+
const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
130
|
+
assert.ok(existsSync(sliceSummaryPath), "summary should be created at fixLevel:all");
|
|
131
|
+
|
|
132
|
+
const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
|
|
133
|
+
assert.ok(roadmapContent.includes("- [x] **S01"), "roadmap should show S01 as checked at fixLevel:all");
|
|
134
|
+
} finally {
|
|
135
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("fixLevel:task — roadmap IS marked when summary already exists on disk (#1910)", async () => {
|
|
140
|
+
const tmp = makeTmp("summary-preexists");
|
|
141
|
+
try {
|
|
142
|
+
buildScaffold(tmp);
|
|
143
|
+
|
|
144
|
+
// Pre-create the slice summary (as if complete-slice already ran)
|
|
145
|
+
const sliceSummaryPath = join(tmp, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
146
|
+
writeFileSync(sliceSummaryPath, `---
|
|
147
|
+
id: S01
|
|
148
|
+
milestone: M001
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
# S01: Test Slice
|
|
152
|
+
|
|
153
|
+
Summary content.
|
|
154
|
+
`);
|
|
155
|
+
|
|
156
|
+
const report = await runGSDDoctor(tmp, { fix: true, fixLevel: "task" });
|
|
157
|
+
|
|
158
|
+
// Summary exists, so roadmap SHOULD be checked even at task level
|
|
159
|
+
const roadmapContent = readFileSync(join(tmp, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "utf8");
|
|
160
|
+
assert.ok(
|
|
161
|
+
roadmapContent.includes("- [x] **S01"),
|
|
162
|
+
"roadmap should be checked when summary already exists on disk"
|
|
163
|
+
);
|
|
164
|
+
} finally {
|
|
165
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
166
|
+
}
|
|
167
|
+
});
|