@opengsd/gsd-pi 1.0.2-dev.e9a1b49 → 1.0.2-dev.fb7ddf1
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 +63 -12
- package/dist/headless-answers.js +2 -1
- package/dist/headless-events.d.ts +1 -0
- package/dist/headless-events.js +8 -1
- package/dist/onboarding.js +22 -3
- package/dist/resource-loader.d.ts +7 -0
- package/dist/resource-loader.js +44 -9
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
- package/dist/resources/extensions/context7/index.js +12 -2
- package/dist/resources/extensions/get-secrets-from-user.js +16 -16
- package/dist/resources/extensions/google-cli/index.js +30 -0
- package/dist/resources/extensions/google-cli/models.js +55 -0
- package/dist/resources/extensions/google-cli/package.json +11 -0
- package/dist/resources/extensions/google-cli/readiness.js +12 -0
- package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
- package/dist/resources/extensions/gsd/auto/loop.js +81 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +38 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
- package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
- package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-start.js +232 -49
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
- package/dist/resources/extensions/gsd/auto-verification.js +14 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +36 -55
- package/dist/resources/extensions/gsd/auto.js +40 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
- package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/commands-usage.js +105 -1
- package/dist/resources/extensions/gsd/config-overlay.js +20 -14
- package/dist/resources/extensions/gsd/context-overlay.js +22 -16
- package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
- package/dist/resources/extensions/gsd/doctor.js +7 -2
- package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
- package/dist/resources/extensions/gsd/guided-flow.js +5 -6
- package/dist/resources/extensions/gsd/key-manager.js +45 -13
- package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
- package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
- package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
- package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
- package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
- package/dist/resources/extensions/gsd/preferences.js +14 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +3 -20
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
- package/dist/resources/extensions/gsd/repo-identity.js +36 -6
- package/dist/resources/extensions/gsd/repository-registry.js +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
- package/dist/resources/extensions/gsd/skill-activation.js +233 -0
- package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
- package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
- package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
- package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
- package/dist/resources/extensions/gsd/skill-scope.js +52 -0
- package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/skills.js +60 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
- package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
- package/dist/resources/extensions/gsd/vision-ask.js +22 -0
- package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
- package/dist/resources/extensions/gsd/worktree-post-create-hook.js +117 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
- package/dist/resources/extensions/search-the-web/native-search.js +57 -8
- package/dist/resources/extensions/shared/confirm-ui.js +9 -6
- package/dist/resources/extensions/shared/dialog-frame.js +42 -0
- package/dist/resources/extensions/shared/interview-ui.js +42 -30
- package/dist/resources/extensions/shared/next-action-ui.js +6 -6
- package/dist/resources/extensions/subagent/index.js +8 -15
- package/dist/resources/shared/package-manager-detection.js +36 -0
- package/dist/resources/skills/agent-browser/SKILL.md +1 -1
- package/dist/resources/skills/api-design/SKILL.md +1 -1
- package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
- package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/dist/resources/skills/forensics/SKILL.md +2 -2
- package/dist/resources/skills/grill-me/SKILL.md +1 -1
- package/dist/resources/skills/handoff/SKILL.md +1 -1
- package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/dist/resources/skills/observability/SKILL.md +1 -1
- package/dist/resources/skills/security-review/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/dist/resources/skills/tdd/SKILL.md +1 -1
- package/dist/resources/skills/write-docs/SKILL.md +1 -1
- package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +7 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +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 +8 -8
- package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-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/node_modules/node-pty/build/Makefile +1 -1
- package/dist/worktree-cli.d.ts +0 -2
- package/dist/worktree-cli.js +21 -9
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
- package/packages/cloud-mcp-gateway/package.json +4 -3
- package/packages/contracts/dist/rpc.test.js +5 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +15 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/dist/workflow.test.js +1 -0
- package/packages/contracts/dist/workflow.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/bin/gsd-mcp-server.js +14 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +7 -1
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +47 -8
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +16 -14
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.js +6 -0
- package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/bin/pi-ai.js +14 -0
- package/packages/pi-ai/dist/models.generated.d.ts +48 -206
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +73 -226
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +50 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
- package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
- package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/README.md +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +3 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +8 -8
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/deps.js +10 -0
- package/scripts/install/detect-existing.js +17 -3
- package/scripts/install/npm-global.js +103 -33
- package/scripts/install.js +1 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
- package/src/resources/extensions/context7/index.ts +15 -2
- package/src/resources/extensions/get-secrets-from-user.ts +17 -16
- package/src/resources/extensions/google-cli/index.ts +34 -0
- package/src/resources/extensions/google-cli/models.ts +57 -0
- package/src/resources/extensions/google-cli/package.json +11 -0
- package/src/resources/extensions/google-cli/readiness.ts +15 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
- package/src/resources/extensions/gsd/auto/loop.ts +96 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +47 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
- package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
- package/src/resources/extensions/gsd/auto-start.ts +307 -56
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
- package/src/resources/extensions/gsd/auto-verification.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +47 -57
- package/src/resources/extensions/gsd/auto.ts +50 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
- package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-usage.ts +110 -5
- package/src/resources/extensions/gsd/config-overlay.ts +19 -16
- package/src/resources/extensions/gsd/context-overlay.ts +24 -19
- package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +7 -2
- package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
- package/src/resources/extensions/gsd/guided-flow.ts +5 -6
- package/src/resources/extensions/gsd/key-manager.ts +57 -14
- package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
- package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
- package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
- package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
- package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
- package/src/resources/extensions/gsd/preferences.ts +17 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +3 -20
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
- package/src/resources/extensions/gsd/repo-identity.ts +35 -7
- package/src/resources/extensions/gsd/repository-registry.ts +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
- package/src/resources/extensions/gsd/skill-activation.ts +292 -0
- package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
- package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
- package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
- package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
- package/src/resources/extensions/gsd/skill-scope.ts +63 -0
- package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/src/resources/extensions/gsd/skills.ts +75 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
- package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
- package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +141 -1
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
- package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
- package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
- package/src/resources/extensions/gsd/vision-ask.ts +28 -0
- package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
- package/src/resources/extensions/gsd/worktree-post-create-hook.ts +127 -0
- package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
- package/src/resources/extensions/search-the-web/native-search.ts +60 -8
- package/src/resources/extensions/shared/confirm-ui.ts +8 -12
- package/src/resources/extensions/shared/dialog-frame.ts +71 -0
- package/src/resources/extensions/shared/interview-ui.ts +43 -42
- package/src/resources/extensions/shared/next-action-ui.ts +6 -6
- package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
- package/src/resources/extensions/subagent/index.ts +8 -15
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/src/resources/skills/agent-browser/SKILL.md +1 -1
- package/src/resources/skills/api-design/SKILL.md +1 -1
- package/src/resources/skills/code-optimizer/SKILL.md +6 -11
- package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/src/resources/skills/forensics/SKILL.md +2 -2
- package/src/resources/skills/grill-me/SKILL.md +1 -1
- package/src/resources/skills/handoff/SKILL.md +1 -1
- package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/src/resources/skills/observability/SKILL.md +1 -1
- package/src/resources/skills/security-review/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/src/resources/skills/tdd/SKILL.md +1 -1
- package/src/resources/skills/write-docs/SKILL.md +1 -1
- package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -37,7 +37,7 @@ import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures
|
|
|
37
37
|
import { debugLog } from "./debug-logger.js";
|
|
38
38
|
import { runSafely } from "./auto-utils.js";
|
|
39
39
|
import { isMilestoneCloseoutSettled, runMilestoneCloseoutGitHub, } from "./milestone-closeout.js";
|
|
40
|
-
import { getEvidence, clearEvidenceFromDisk } from "./safety/evidence-collector.js";
|
|
40
|
+
import { getEvidence, clearEvidenceFromDisk, isExecutionToolName } from "./safety/evidence-collector.js";
|
|
41
41
|
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
42
42
|
import { crossReferenceEvidence } from "./safety/evidence-cross-ref.js";
|
|
43
43
|
import { validateContent } from "./safety/content-validator.js";
|
|
@@ -74,6 +74,15 @@ const MAX_VERIFICATION_RETRIES = 3;
|
|
|
74
74
|
/** Keep failure toasts short while still showing concrete examples. */
|
|
75
75
|
const MAX_NOTIFICATION_DETAILS = 3;
|
|
76
76
|
const NOTIFICATION_BULLET = "•";
|
|
77
|
+
function isParallelResearchUnit(unitType, unitId) {
|
|
78
|
+
return unitType === "research-slice" && unitId.endsWith("/parallel-research");
|
|
79
|
+
}
|
|
80
|
+
export function maybeWriteParallelResearchCostSpikeBlocker(unitType, unitId, basePath, unitCostUsd, rollingAvgUsd) {
|
|
81
|
+
if (!isParallelResearchUnit(unitType, unitId))
|
|
82
|
+
return null;
|
|
83
|
+
return writeBlockerPlaceholder(unitType, unitId, basePath, `Parallel slice research cost spike detected (${unitCostUsd.toFixed(2)} vs avg ${rollingAvgUsd.toFixed(2)}). ` +
|
|
84
|
+
"Skipping the aggregate sentinel so dispatch can fall back to per-slice research.");
|
|
85
|
+
}
|
|
77
86
|
export function resolveCloseoutGitAction(uokFlags) {
|
|
78
87
|
return uokFlags.gitops ? uokFlags.gitopsTurnAction : null;
|
|
79
88
|
}
|
|
@@ -170,12 +179,35 @@ function completeSliceReopenReplanHandoffDetected(s, agentEndMessages) {
|
|
|
170
179
|
agentEndMessagesIncludeToolCall(agentEndMessages, "gsd_task_reopen") ||
|
|
171
180
|
agentEndMessagesMentionTool(agentEndMessages, "gsd_task_reopen") ||
|
|
172
181
|
unitActivityMentionsTool(s.basePath, unitType, unitId, "gsd_task_reopen") ||
|
|
173
|
-
unitActivityMentionsTool(s.canonicalProjectRoot, unitType, unitId, "gsd_task_reopen")
|
|
174
|
-
|
|
182
|
+
unitActivityMentionsTool(s.canonicalProjectRoot, unitType, unitId, "gsd_task_reopen"));
|
|
183
|
+
}
|
|
184
|
+
function completeSliceReplanSignalDetected(s, agentEndMessages) {
|
|
185
|
+
if (s.currentUnit?.type !== "complete-slice")
|
|
186
|
+
return false;
|
|
187
|
+
return (agentEndMessagesIncludeSuccessfulToolResult(agentEndMessages, "gsd_replan_slice") ||
|
|
175
188
|
agentEndMessagesIncludeToolCall(agentEndMessages, "gsd_replan_slice") ||
|
|
176
189
|
agentEndMessagesMentionTool(agentEndMessages, "gsd_replan_slice") ||
|
|
177
|
-
unitActivityMentionsTool(s.basePath,
|
|
178
|
-
unitActivityMentionsTool(s.canonicalProjectRoot,
|
|
190
|
+
unitActivityMentionsTool(s.basePath, s.currentUnit.type, s.currentUnit.id, "gsd_replan_slice") ||
|
|
191
|
+
unitActivityMentionsTool(s.canonicalProjectRoot, s.currentUnit.type, s.currentUnit.id, "gsd_replan_slice"));
|
|
192
|
+
}
|
|
193
|
+
function completeSliceValidReplanOutcomeDetected(s, agentEndMessages) {
|
|
194
|
+
if (s.currentUnit?.type !== "complete-slice")
|
|
195
|
+
return false;
|
|
196
|
+
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
197
|
+
if (!mid || !sid)
|
|
198
|
+
return false;
|
|
199
|
+
if (!completeSliceReplanSignalDetected(s, agentEndMessages))
|
|
200
|
+
return false;
|
|
201
|
+
const replanPath = resolveSliceFile(s.basePath, mid, sid, "REPLAN");
|
|
202
|
+
const canonicalReplanPath = resolveSliceFile(s.canonicalProjectRoot, mid, sid, "REPLAN");
|
|
203
|
+
const hasReplanArtifact = (Boolean(replanPath && existsSync(replanPath)) ||
|
|
204
|
+
Boolean(canonicalReplanPath && existsSync(canonicalReplanPath)));
|
|
205
|
+
if (!hasReplanArtifact)
|
|
206
|
+
return false;
|
|
207
|
+
if (!isDbAvailable())
|
|
208
|
+
return true;
|
|
209
|
+
const slice = getSlice(mid, sid);
|
|
210
|
+
return Boolean(slice && !isClosedStatus(slice.status));
|
|
179
211
|
}
|
|
180
212
|
function formatPreExecutionCheckDetail(check) {
|
|
181
213
|
const category = check.category?.trim() || "unknown category";
|
|
@@ -396,12 +428,6 @@ export function _shouldDispatchQuickTaskForTest(state) {
|
|
|
396
428
|
!!state.currentUnit &&
|
|
397
429
|
state.currentUnit.type !== "quick-task";
|
|
398
430
|
}
|
|
399
|
-
function isExecutionToolName(name) {
|
|
400
|
-
if (typeof name !== "string")
|
|
401
|
-
return false;
|
|
402
|
-
const normalized = name.trim().toLowerCase();
|
|
403
|
-
return normalized === "bash" || normalized === "gsd_exec";
|
|
404
|
-
}
|
|
405
431
|
export function _hasExecutionToolCallsInSessionForTest(entries) {
|
|
406
432
|
for (const entry of entries) {
|
|
407
433
|
const e = entry;
|
|
@@ -1235,8 +1261,8 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1235
1261
|
});
|
|
1236
1262
|
}
|
|
1237
1263
|
else {
|
|
1238
|
-
logWarning("safety", `evidence mismatch: ${missingCommandMismatches.length} claimed command(s) not found in
|
|
1239
|
-
ctx.ui.notify(`Safety: task ${sTid} claimed ${missingCommandMismatches.length} command(s) not found in recorded
|
|
1264
|
+
logWarning("safety", `evidence mismatch: ${missingCommandMismatches.length} claimed command(s) not found in recorded execution calls`);
|
|
1265
|
+
ctx.ui.notify(`Safety: task ${sTid} claimed ${missingCommandMismatches.length} command(s) not found in recorded execution calls`, "warning");
|
|
1240
1266
|
}
|
|
1241
1267
|
}
|
|
1242
1268
|
const blockingMismatch = mismatches.find((mismatch) => mismatch.severity === "error");
|
|
@@ -1360,7 +1386,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1360
1386
|
if (!triggerArtifactVerified) {
|
|
1361
1387
|
try {
|
|
1362
1388
|
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
|
1363
|
-
if (mid && sid) {
|
|
1389
|
+
if (mid && sid && !isParallelResearchUnit(s.currentUnit.type, s.currentUnit.id)) {
|
|
1364
1390
|
// Phase C: write to the canonical project root (#5236 scope)
|
|
1365
1391
|
// so non-symlinked worktrees no longer maintain a separate
|
|
1366
1392
|
// local .gsd/ projection. copyPlanningArtifacts has been
|
|
@@ -1518,7 +1544,23 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1518
1544
|
ctx.ui.notify(`complete-slice ${s.currentUnit.id} intentionally handed off via reopen/replan; continuing orchestration instead of retrying closeout.`, "warning");
|
|
1519
1545
|
return "continue";
|
|
1520
1546
|
}
|
|
1521
|
-
else if (!triggerArtifactVerified &&
|
|
1547
|
+
else if (!triggerArtifactVerified &&
|
|
1548
|
+
completeSliceValidReplanOutcomeDetected(s, opts?.agentEndMessages)) {
|
|
1549
|
+
const retryKey = `${s.currentUnit.type}:${s.currentUnit.id}`;
|
|
1550
|
+
s.pendingVerificationRetry = null;
|
|
1551
|
+
s.verificationRetryCount.delete(retryKey);
|
|
1552
|
+
s.verificationRetryFailureHashes.delete(retryKey);
|
|
1553
|
+
debugLog("postUnit", {
|
|
1554
|
+
phase: "artifact-verify-complete-slice-replan-outcome",
|
|
1555
|
+
unitType: s.currentUnit.type,
|
|
1556
|
+
unitId: s.currentUnit.id,
|
|
1557
|
+
});
|
|
1558
|
+
ctx.ui.notify(`complete-slice ${s.currentUnit.id} produced a valid replan outcome; continuing orchestration instead of retrying closeout.`, "warning");
|
|
1559
|
+
return "continue";
|
|
1560
|
+
}
|
|
1561
|
+
else if (!triggerArtifactVerified &&
|
|
1562
|
+
!isDbAvailable() &&
|
|
1563
|
+
!completeSliceReplanSignalDetected(s, opts?.agentEndMessages)) {
|
|
1522
1564
|
debugLog("postUnit", { phase: "artifact-verify-skip-db-unavailable", unitType: s.currentUnit.type, unitId: s.currentUnit.id });
|
|
1523
1565
|
const dbSkipDiag = diagnoseExpectedArtifact(s.currentUnit.type, s.currentUnit.id, verificationBasePath);
|
|
1524
1566
|
ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} — DB unavailable, skipping retry.${dbSkipDiag ? ` Expected: ${dbSkipDiag}` : ""}`, "error");
|
|
@@ -1582,7 +1624,10 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1582
1624
|
ctx.ui.notify(`Unit ${s.currentUnit.id} cost spike detected (${unitCostUsd.toFixed(2)} vs avg ${rollingAvgUsd.toFixed(2)}) after state advanced; continuing closeout.`, "warning");
|
|
1583
1625
|
return "continue";
|
|
1584
1626
|
}
|
|
1585
|
-
|
|
1627
|
+
const parallelBlocker = maybeWriteParallelResearchCostSpikeBlocker(s.currentUnit.type, s.currentUnit.id, verificationBasePath, unitCostUsd, rollingAvgUsd);
|
|
1628
|
+
ctx.ui.notify(parallelBlocker
|
|
1629
|
+
? `Unit ${s.currentUnit.id} cost spike detected (${unitCostUsd.toFixed(2)} vs avg ${rollingAvgUsd.toFixed(2)}) — wrote parallel blocker and pausing auto-mode.`
|
|
1630
|
+
: `Unit ${s.currentUnit.id} cost spike detected (${unitCostUsd.toFixed(2)} vs avg ${rollingAvgUsd.toFixed(2)}) — pausing auto-mode.`, "error");
|
|
1586
1631
|
await pauseAuto(ctx, pi);
|
|
1587
1632
|
return "dispatched";
|
|
1588
1633
|
}
|
|
@@ -1712,6 +1757,10 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1712
1757
|
const trigger = consumeRetryTrigger();
|
|
1713
1758
|
if (trigger) {
|
|
1714
1759
|
ctx.ui.notify(`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting task state.`, "info");
|
|
1760
|
+
await s.orchestration?.retryActiveUnit({
|
|
1761
|
+
unitType: trigger.unitType,
|
|
1762
|
+
unitId: trigger.unitId,
|
|
1763
|
+
});
|
|
1715
1764
|
// ── State reset: undo the completion so deriveState re-derives the unit ──
|
|
1716
1765
|
try {
|
|
1717
1766
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(trigger.unitId);
|
|
@@ -7,15 +7,14 @@
|
|
|
7
7
|
* state, no globals — every dependency is passed as a parameter or imported as a
|
|
8
8
|
* utility.
|
|
9
9
|
*/
|
|
10
|
-
import { loadFile, parseContinue, parseSummary, loadActiveOverrides, formatOverridesSection
|
|
10
|
+
import { loadFile, parseContinue, parseSummary, loadActiveOverrides, formatOverridesSection } from "./files.js";
|
|
11
11
|
import { hasVerdict, getUatType, extractVerdict } from "./verdict-parser.js";
|
|
12
12
|
import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
13
13
|
import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, resolveTaskFiles, resolveTaskFile, relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath, resolveGsdRootFile, relGsdRootFile, resolveRuntimeFile, } from "./paths.js";
|
|
14
|
-
import {
|
|
14
|
+
import { resolveInlineLevel, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
15
15
|
import { isContextModeEnabled } from "./preferences-types.js";
|
|
16
16
|
import { parseRoadmap } from "./parsers-legacy.js";
|
|
17
|
-
import {
|
|
18
|
-
import { join, basename } from "node:path";
|
|
17
|
+
import { join } from "node:path";
|
|
19
18
|
import { existsSync } from "node:fs";
|
|
20
19
|
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary } from "./context-budget.js";
|
|
21
20
|
import { getPendingGatesForTurn } from "./gsd-db.js";
|
|
@@ -27,10 +26,11 @@ import { readCompactionSnapshot } from "./compaction-snapshot.js";
|
|
|
27
26
|
import { logWarning } from "./workflow-logger.js";
|
|
28
27
|
import { inlineGraphSubgraph } from "./graph-context.js";
|
|
29
28
|
import { buildExtractionStepsBlock } from "./commands-extract-learnings.js";
|
|
30
|
-
import { resolveSkillManifest, warnIfManifestHasMissingSkills } from "./skill-manifest.js";
|
|
31
29
|
import { classifyProject } from "./detection.js";
|
|
32
30
|
import { hasBrowserRequiredText } from "./browser-evidence.js";
|
|
33
31
|
import { debugLog } from "./debug-logger.js";
|
|
32
|
+
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
33
|
+
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
34
34
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
35
35
|
/**
|
|
36
36
|
* Static ceiling for the preamble cap. Kept as an upper bound even
|
|
@@ -1033,237 +1033,6 @@ export async function inlineRoadmapExcerpt(base, mid, sid) {
|
|
|
1033
1033
|
return null;
|
|
1034
1034
|
return `### Milestone Roadmap (excerpt)\nSource: \`${roadmapRel}\`\n\n${excerpt}`;
|
|
1035
1035
|
}
|
|
1036
|
-
// ─── Skill Activation & Discovery ─────────────────────────────────────────
|
|
1037
|
-
function normalizeSkillReference(ref) {
|
|
1038
|
-
const normalized = ref.replace(/\\/g, "/").trim();
|
|
1039
|
-
const base = basename(normalized).replace(/\.md$/i, "");
|
|
1040
|
-
const name = /^SKILL$/i.test(base)
|
|
1041
|
-
? basename(normalized.replace(/\/SKILL(?:\.md)?$/i, ""))
|
|
1042
|
-
: base;
|
|
1043
|
-
return name.trim().toLowerCase();
|
|
1044
|
-
}
|
|
1045
|
-
function tokenizeSkillContext(...parts) {
|
|
1046
|
-
const tokens = new Set();
|
|
1047
|
-
const addVariants = (raw) => {
|
|
1048
|
-
const value = raw.trim().toLowerCase();
|
|
1049
|
-
if (!value || value.length < 2)
|
|
1050
|
-
return;
|
|
1051
|
-
tokens.add(value);
|
|
1052
|
-
tokens.add(value.replace(/[-_]+/g, " "));
|
|
1053
|
-
tokens.add(value.replace(/\s+/g, "-"));
|
|
1054
|
-
tokens.add(value.replace(/\s+/g, ""));
|
|
1055
|
-
};
|
|
1056
|
-
for (const part of parts) {
|
|
1057
|
-
if (!part)
|
|
1058
|
-
continue;
|
|
1059
|
-
const text = part.toLowerCase();
|
|
1060
|
-
const phraseMatches = text.match(/[a-z0-9][a-z0-9+.#/_-]{1,}/g) ?? [];
|
|
1061
|
-
for (const match of phraseMatches) {
|
|
1062
|
-
addVariants(match);
|
|
1063
|
-
for (const piece of match.split(/[^a-z0-9+.#]+/g)) {
|
|
1064
|
-
if (piece.length >= 3)
|
|
1065
|
-
addVariants(piece);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
return tokens;
|
|
1070
|
-
}
|
|
1071
|
-
function skillMatchesContext(skill, contextTokens) {
|
|
1072
|
-
const haystacks = [
|
|
1073
|
-
skill.name.toLowerCase(),
|
|
1074
|
-
skill.name.toLowerCase().replace(/[-_]+/g, " "),
|
|
1075
|
-
skill.description.toLowerCase(),
|
|
1076
|
-
];
|
|
1077
|
-
return [...contextTokens].some(token => token.length >= 3 && haystacks.some(haystack => haystack.includes(token)));
|
|
1078
|
-
}
|
|
1079
|
-
function resolvePreferenceSkillNames(refs, base) {
|
|
1080
|
-
if (refs.length === 0)
|
|
1081
|
-
return [];
|
|
1082
|
-
const prefs = { always_use_skills: refs };
|
|
1083
|
-
const report = resolveAllSkillReferences(prefs, base);
|
|
1084
|
-
return refs.map(ref => {
|
|
1085
|
-
const resolution = report.resolutions.get(ref);
|
|
1086
|
-
return normalizeSkillReference(resolution?.resolvedPath ?? ref);
|
|
1087
|
-
}).filter(Boolean);
|
|
1088
|
-
}
|
|
1089
|
-
function ruleMatchesContext(when, contextTokens) {
|
|
1090
|
-
const whenTokens = tokenizeSkillContext(when);
|
|
1091
|
-
return [...whenTokens].some(token => contextTokens.has(token) || [...contextTokens].some(ctx => ctx.includes(token) || token.includes(ctx)));
|
|
1092
|
-
}
|
|
1093
|
-
function resolveSkillRuleMatches(prefs, contextTokens, base) {
|
|
1094
|
-
if (!prefs?.skill_rules?.length)
|
|
1095
|
-
return { include: [], avoid: [] };
|
|
1096
|
-
const include = [];
|
|
1097
|
-
const avoid = [];
|
|
1098
|
-
for (const rule of prefs.skill_rules) {
|
|
1099
|
-
if (!ruleMatchesContext(rule.when, contextTokens))
|
|
1100
|
-
continue;
|
|
1101
|
-
include.push(...resolvePreferenceSkillNames([...(rule.use ?? []), ...(rule.prefer ?? [])], base));
|
|
1102
|
-
avoid.push(...resolvePreferenceSkillNames(rule.avoid ?? [], base));
|
|
1103
|
-
}
|
|
1104
|
-
return { include, avoid };
|
|
1105
|
-
}
|
|
1106
|
-
function resolvePreferredSkillNames(prefs, visibleSkills, contextTokens, base) {
|
|
1107
|
-
if (!prefs?.prefer_skills?.length)
|
|
1108
|
-
return [];
|
|
1109
|
-
const preferred = new Set(resolvePreferenceSkillNames(prefs.prefer_skills, base));
|
|
1110
|
-
return visibleSkills
|
|
1111
|
-
.filter(skill => preferred.has(normalizeSkillReference(skill.name)) && skillMatchesContext(skill, contextTokens))
|
|
1112
|
-
.map(skill => normalizeSkillReference(skill.name));
|
|
1113
|
-
}
|
|
1114
|
-
/** Skill names must be lowercase alphanumeric with hyphens — reject anything else
|
|
1115
|
-
* to prevent prompt injection via crafted directory names. */
|
|
1116
|
-
const SAFE_SKILL_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
1117
|
-
function formatSkillActivationBlock(skillNames) {
|
|
1118
|
-
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
1119
|
-
if (safe.length === 0)
|
|
1120
|
-
return "";
|
|
1121
|
-
// Use explicit parameter syntax so LLMs pass { skill: "..." } instead of { name: "..." }.
|
|
1122
|
-
// The function-call-like syntax `Skill('name')` led LLMs to infer a positional
|
|
1123
|
-
// parameter name, causing tool validation failures — see #2224.
|
|
1124
|
-
const calls = safe.map(name => `Call Skill({ skill: '${name}' })`).join('. ');
|
|
1125
|
-
return `<skill_activation>${calls}.</skill_activation>`;
|
|
1126
|
-
}
|
|
1127
|
-
/**
|
|
1128
|
-
* Manifest-driven recommendations block — informational only, does NOT
|
|
1129
|
-
* auto-invoke. Lists per-unit-type skills that are installed but not already
|
|
1130
|
-
* activated by explicit user intent (always_use_skills / prefer_skills /
|
|
1131
|
-
* skill_rules / task-plan skills_used). Surfaces relevant skills to the
|
|
1132
|
-
* model so they can be invoked when the model judges them useful.
|
|
1133
|
-
*
|
|
1134
|
-
* This is the additive complement to the existing activation directive:
|
|
1135
|
-
* activation force-invokes (explicit intent), recommendations remind
|
|
1136
|
-
* (manifest defaults). User intent is preserved as the stronger signal
|
|
1137
|
-
* (RFC #4779 design principle); this block only adds visibility.
|
|
1138
|
-
*/
|
|
1139
|
-
function formatSkillRecommendationsBlock(unitType, skillNames) {
|
|
1140
|
-
if (!unitType)
|
|
1141
|
-
return "";
|
|
1142
|
-
const safe = skillNames.filter(name => SAFE_SKILL_NAME.test(name));
|
|
1143
|
-
if (safe.length === 0)
|
|
1144
|
-
return "";
|
|
1145
|
-
return `<skill_recommendations unit="${unitType}">For this unit type, also consider invoking: ${safe.join(", ")}. Use Skill({ skill: 'name' }) when relevant — these are recommendations, not requirements.</skill_recommendations>`;
|
|
1146
|
-
}
|
|
1147
|
-
export function buildSkillActivationBlock(params) {
|
|
1148
|
-
const prefs = params.preferences ?? loadEffectiveGSDPreferences(params.base)?.preferences;
|
|
1149
|
-
const contextTokens = tokenizeSkillContext(params.milestoneId, params.milestoneTitle, params.sliceId, params.sliceTitle, params.taskId, params.taskTitle);
|
|
1150
|
-
const loaded = (typeof getLoadedSkills === 'function' ? getLoadedSkills() : []).filter(skill => !skill.disableModelInvocation);
|
|
1151
|
-
// Skill activation here is driven entirely by explicit sources
|
|
1152
|
-
// (always_use_skills, prefer_skills, skill_rules, task-plan skills_used).
|
|
1153
|
-
// Every match is an explicit user/project intent and must not be dropped
|
|
1154
|
-
// by the unit-type manifest — user intent is stronger signal than
|
|
1155
|
-
// defaults. The manifest's real home is the skill catalog rendering
|
|
1156
|
-
// layer (pi-coding-agent `formatSkillsForPrompt`); that wiring is tracked
|
|
1157
|
-
// as the "load-time short-circuit" follow-up to RFC #4779.
|
|
1158
|
-
//
|
|
1159
|
-
// `unitType` stays plumbed so the strict-mode warning can surface
|
|
1160
|
-
// manifest entries that reference uninstalled skills, and so the
|
|
1161
|
-
// activation-block site is ready to opt in once PR B lands.
|
|
1162
|
-
const visibleSkills = loaded;
|
|
1163
|
-
const installedNames = new Set(visibleSkills.map(skill => normalizeSkillReference(skill.name)));
|
|
1164
|
-
warnIfManifestHasMissingSkills(params.unitType, installedNames);
|
|
1165
|
-
const avoided = new Set(resolvePreferenceSkillNames(prefs?.avoid_skills ?? [], params.base));
|
|
1166
|
-
const matched = new Set();
|
|
1167
|
-
for (const name of resolvePreferenceSkillNames(prefs?.always_use_skills ?? [], params.base)) {
|
|
1168
|
-
matched.add(name);
|
|
1169
|
-
}
|
|
1170
|
-
const ruleMatches = resolveSkillRuleMatches(prefs, contextTokens, params.base);
|
|
1171
|
-
for (const name of ruleMatches.include)
|
|
1172
|
-
matched.add(name);
|
|
1173
|
-
for (const name of ruleMatches.avoid)
|
|
1174
|
-
avoided.add(name);
|
|
1175
|
-
for (const name of resolvePreferredSkillNames(prefs, visibleSkills, contextTokens, params.base)) {
|
|
1176
|
-
matched.add(name);
|
|
1177
|
-
}
|
|
1178
|
-
if (params.taskPlanContent) {
|
|
1179
|
-
try {
|
|
1180
|
-
const taskPlan = parseTaskPlanFile(params.taskPlanContent);
|
|
1181
|
-
for (const skillName of taskPlan.frontmatter.skills_used) {
|
|
1182
|
-
matched.add(normalizeSkillReference(skillName));
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
catch (err) {
|
|
1186
|
-
logWarning("prompt", `parseTaskPlanFile failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
// Heuristic auto-match (gated on skill_discovery: "auto").
|
|
1190
|
-
// For each installed skill, check if its name or description appears in the
|
|
1191
|
-
// unit's context tokens (milestone/slice/task titles). Only consider skills
|
|
1192
|
-
// already on the unit-type manifest allowlist — this keeps the heuristic
|
|
1193
|
-
// narrow and avoids wildly off-topic activations.
|
|
1194
|
-
// Users who set `skill_discovery: "off"` or "suggest" do not get
|
|
1195
|
-
// auto-matched skills (the recommendations block still surfaces manifest
|
|
1196
|
-
// skills passively); only "auto" actually adds them to the activation
|
|
1197
|
-
// directive set. Default `skill_discovery` is "suggest", so this is opt-in.
|
|
1198
|
-
if ((prefs?.skill_discovery ?? "suggest") === "auto") {
|
|
1199
|
-
const manifestAllow = resolveSkillManifest(params.unitType);
|
|
1200
|
-
const allowSet = manifestAllow ? new Set(manifestAllow) : null;
|
|
1201
|
-
for (const skill of visibleSkills) {
|
|
1202
|
-
const normalized = normalizeSkillReference(skill.name);
|
|
1203
|
-
if (matched.has(normalized) || avoided.has(normalized))
|
|
1204
|
-
continue;
|
|
1205
|
-
// Respect the manifest allowlist when present; wildcard (null) lets all
|
|
1206
|
-
// installed skills compete for keyword match.
|
|
1207
|
-
if (allowSet && !allowSet.has(normalized))
|
|
1208
|
-
continue;
|
|
1209
|
-
if (skillMatchesContext(skill, contextTokens)) {
|
|
1210
|
-
matched.add(normalized);
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
const ordered = [...matched]
|
|
1215
|
-
.filter(name => installedNames.has(name) && !avoided.has(name))
|
|
1216
|
-
.sort();
|
|
1217
|
-
const activationBlock = formatSkillActivationBlock(ordered);
|
|
1218
|
-
// Manifest-driven recommendations (additive, does not override explicit intent).
|
|
1219
|
-
// Only surface skills the manifest declares for this unit type that are
|
|
1220
|
-
// installed and not already in matched/avoided.
|
|
1221
|
-
const matchedSet = new Set(ordered);
|
|
1222
|
-
const manifestList = resolveSkillManifest(params.unitType);
|
|
1223
|
-
const recommendations = (manifestList ?? [])
|
|
1224
|
-
.filter(name => installedNames.has(name) && !avoided.has(name) && !matchedSet.has(name))
|
|
1225
|
-
.sort();
|
|
1226
|
-
const recommendationsBlock = formatSkillRecommendationsBlock(params.unitType, recommendations);
|
|
1227
|
-
if (!activationBlock && !recommendationsBlock)
|
|
1228
|
-
return "";
|
|
1229
|
-
if (!activationBlock)
|
|
1230
|
-
return recommendationsBlock;
|
|
1231
|
-
if (!recommendationsBlock)
|
|
1232
|
-
return activationBlock;
|
|
1233
|
-
return `${activationBlock}\n${recommendationsBlock}`;
|
|
1234
|
-
}
|
|
1235
|
-
/**
|
|
1236
|
-
* Build the skill discovery template variables for research prompts.
|
|
1237
|
-
* Returns { skillDiscoveryMode, skillDiscoveryInstructions } for template substitution.
|
|
1238
|
-
*/
|
|
1239
|
-
export function buildSkillDiscoveryVars() {
|
|
1240
|
-
const mode = resolveSkillDiscoveryMode();
|
|
1241
|
-
if (mode === "off") {
|
|
1242
|
-
return {
|
|
1243
|
-
skillDiscoveryMode: "off",
|
|
1244
|
-
skillDiscoveryInstructions: " Skill discovery is disabled. Skip this step.",
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
const autoInstall = mode === "auto";
|
|
1248
|
-
const instructions = `
|
|
1249
|
-
Identify the key technologies, frameworks, and services this work depends on (e.g. Stripe, Clerk, Supabase, JUCE, SwiftUI).
|
|
1250
|
-
For each, check if a professional agent skill already exists:
|
|
1251
|
-
- First check \`<available_skills>\` in your system prompt — a skill may already be installed.
|
|
1252
|
-
- For technologies without an installed skill, run: \`npx skills find "<technology>"\`
|
|
1253
|
-
- Only consider skills that are **directly relevant** to core technologies — not tangentially related.
|
|
1254
|
-
- Evaluate results by install count and relevance to the actual work.${autoInstall
|
|
1255
|
-
? `
|
|
1256
|
-
- Install relevant skills: \`npx skills add <owner/repo@skill> -g -y\`
|
|
1257
|
-
- Record installed skills in the "Skills Discovered" section of your research output.
|
|
1258
|
-
- Installed skills will automatically appear in subsequent units' system prompts — no manual steps needed.`
|
|
1259
|
-
: `
|
|
1260
|
-
- Note promising skills in your research output with their install commands, but do NOT install them.
|
|
1261
|
-
- The user will decide which to install.`}`;
|
|
1262
|
-
return {
|
|
1263
|
-
skillDiscoveryMode: mode,
|
|
1264
|
-
skillDiscoveryInstructions: instructions,
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
1036
|
// ─── Text Helpers ──────────────────────────────────────────────────────────
|
|
1268
1037
|
export function extractMarkdownSection(content, heading) {
|
|
1269
1038
|
const match = new RegExp(`^## ${escapeRegExp(heading)}\\s*$`, "m").exec(content);
|
|
@@ -352,23 +352,28 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
352
352
|
if (blockerPath && existsSync(blockerPath)) {
|
|
353
353
|
return true;
|
|
354
354
|
}
|
|
355
|
-
const roadmapFile =
|
|
355
|
+
const roadmapFile = resolveExpectedArtifactPath("plan-milestone", mid, base);
|
|
356
356
|
if (!roadmapFile || !existsSync(roadmapFile)) {
|
|
357
357
|
logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap missing`);
|
|
358
358
|
return false;
|
|
359
359
|
}
|
|
360
360
|
try {
|
|
361
361
|
const roadmap = parseLegacyRoadmap(readFileSync(roadmapFile, "utf-8"));
|
|
362
|
-
const milestoneResearchFile =
|
|
362
|
+
const milestoneResearchFile = resolveExpectedArtifactPath("research-milestone", mid, base);
|
|
363
|
+
const hasMilestoneResearch = !!milestoneResearchFile && existsSync(milestoneResearchFile);
|
|
363
364
|
for (const slice of roadmap.slices) {
|
|
364
365
|
if (slice.done)
|
|
365
366
|
continue;
|
|
366
|
-
if (
|
|
367
|
+
if (hasMilestoneResearch && slice.id === "S01")
|
|
367
368
|
continue;
|
|
368
|
-
const depsComplete = (slice.depends ?? []).every((depId) =>
|
|
369
|
+
const depsComplete = (slice.depends ?? []).every((depId) => {
|
|
370
|
+
const summaryPath = resolveExpectedArtifactPath("complete-slice", `${mid}/${depId}`, base);
|
|
371
|
+
return !!summaryPath && existsSync(summaryPath);
|
|
372
|
+
});
|
|
369
373
|
if (!depsComplete)
|
|
370
374
|
continue;
|
|
371
|
-
|
|
375
|
+
const researchPath = resolveExpectedArtifactPath("research-slice", `${mid}/${slice.id}`, base);
|
|
376
|
+
if (!researchPath || !existsSync(researchPath)) {
|
|
372
377
|
logWarning("recovery", `verify-fail ${unitType} ${unitId}: slice ${slice.id} missing RESEARCH`);
|
|
373
378
|
return false;
|
|
374
379
|
}
|