@opengsd/gsd-pi 1.0.2-dev.867e002 → 1.0.2-dev.aed3486
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/onboarding.js +22 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- 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 +62 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +37 -0
- 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 +21 -11
- 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.js +6 -1
- 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 +17 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
- 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-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-providers.js +54 -24
- package/dist/resources/extensions/gsd/doctor.js +6 -1
- 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/milestone-reopen-events.js +28 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
- 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/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -3
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
- package/dist/resources/extensions/gsd/repository-registry.js +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +11 -4
- 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.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/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/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +4 -4
- 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/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 +4 -4
- 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/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- 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/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.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/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +10 -5
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +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/dist/models.generated.d.ts +8 -59
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +21 -72
- 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/package.json +1 -1
- 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/package.json +7 -7
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- 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 +74 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +46 -0
- 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 +43 -14
- 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.ts +6 -1
- 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 +18 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
- 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-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-providers.ts +55 -27
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +6 -1
- 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/milestone-reopen-events.ts +28 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
- 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/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -3
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
- package/src/resources/extensions/gsd/repository-registry.ts +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -4
- 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.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 +21 -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 +12 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -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/context-chart.test.ts +9 -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-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/key-manager.test.ts +23 -4
- 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/post-unit-retry-on-orchestrator-bridge.test.ts +93 -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/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 +19 -0
- 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 +74 -1
- 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/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/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/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- /package/dist/web/standalone/.next/static/{praHP_OATcjBkvAVejjGK → _LIEWYP8ISVAPKAEEXxFr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{praHP_OATcjBkvAVejjGK → _LIEWYP8ISVAPKAEEXxFr}/_ssgManifest.js +0 -0
|
@@ -191,6 +191,32 @@ test("resolveAgentEnd resolves a pending runUnit promise", async () => {
|
|
|
191
191
|
assert.deepEqual(result.event, event);
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
+
test("runUnit clears scoped skill visibility after a manifest-scoped unit completes", async () => {
|
|
195
|
+
_resetPendingResolve();
|
|
196
|
+
|
|
197
|
+
const ctx = makeMockCtx();
|
|
198
|
+
const pi = makeMockPi();
|
|
199
|
+
const skillVisibilityCalls: Array<string[] | undefined> = [];
|
|
200
|
+
let visibleSkills: string[] | undefined;
|
|
201
|
+
pi.setVisibleSkills = (names: string[] | undefined) => {
|
|
202
|
+
visibleSkills = names;
|
|
203
|
+
skillVisibilityCalls.push(names);
|
|
204
|
+
};
|
|
205
|
+
const s = makeMockSession();
|
|
206
|
+
|
|
207
|
+
const resultPromise = runUnit(ctx, pi, s, "plan-slice", "M001/S01", "prompt");
|
|
208
|
+
|
|
209
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
210
|
+
assert.ok(Array.isArray(visibleSkills), "unit dispatch should scope skills before the turn starts");
|
|
211
|
+
|
|
212
|
+
resolveAgentEnd(makeEvent());
|
|
213
|
+
|
|
214
|
+
const result = await resultPromise;
|
|
215
|
+
assert.equal(result.status, "completed");
|
|
216
|
+
assert.equal(visibleSkills, undefined);
|
|
217
|
+
assert.equal(skillVisibilityCalls.at(-1), undefined);
|
|
218
|
+
});
|
|
219
|
+
|
|
194
220
|
test("runUnit honors ScheduleWakeup by continuing the same unit session", async () => {
|
|
195
221
|
_resetPendingResolve();
|
|
196
222
|
_resetAutoWakeupsForTest();
|
|
@@ -1773,6 +1799,11 @@ test("autoLoop dev path dispatches orchestration.advance results without legacy
|
|
|
1773
1799
|
const ctx = makeMockCtx();
|
|
1774
1800
|
ctx.ui.setStatus = () => {};
|
|
1775
1801
|
ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
|
|
1802
|
+
ctx.modelRegistry = {
|
|
1803
|
+
getAvailable: () => [{ provider: "test", id: "hook-model" }],
|
|
1804
|
+
getProviderAuthMode: () => undefined,
|
|
1805
|
+
isProviderRequestReady: () => true,
|
|
1806
|
+
};
|
|
1776
1807
|
const pi = makeMockPi();
|
|
1777
1808
|
const stateSnapshot = {
|
|
1778
1809
|
phase: "executing",
|
|
@@ -1784,6 +1815,7 @@ test("autoLoop dev path dispatches orchestration.advance results without legacy
|
|
|
1784
1815
|
} as any;
|
|
1785
1816
|
let advanceCalls = 0;
|
|
1786
1817
|
const finalizedUnits: string[] = [];
|
|
1818
|
+
const journalEvents: any[] = [];
|
|
1787
1819
|
let s: any;
|
|
1788
1820
|
s = makeLoopSession({
|
|
1789
1821
|
currentMilestoneId: "M002",
|
|
@@ -1821,6 +1853,15 @@ test("autoLoop dev path dispatches orchestration.advance results without legacy
|
|
|
1821
1853
|
deps.callLog.push("resolveDispatch");
|
|
1822
1854
|
throw new Error("legacy resolveDispatch must not run when orchestration is wired");
|
|
1823
1855
|
},
|
|
1856
|
+
runPreDispatchHooks: () => ({
|
|
1857
|
+
firedHooks: ["complete-slice-policies"],
|
|
1858
|
+
action: "proceed",
|
|
1859
|
+
prompt: "hooked prompt",
|
|
1860
|
+
model: "hook-model",
|
|
1861
|
+
}),
|
|
1862
|
+
emitJournalEvent: (entry: any) => {
|
|
1863
|
+
journalEvents.push(entry);
|
|
1864
|
+
},
|
|
1824
1865
|
postUnitPostVerification: async () => {
|
|
1825
1866
|
deps.callLog.push("postUnitPostVerification");
|
|
1826
1867
|
s.active = false;
|
|
@@ -1841,11 +1882,115 @@ test("autoLoop dev path dispatches orchestration.advance results without legacy
|
|
|
1841
1882
|
);
|
|
1842
1883
|
assert.equal(
|
|
1843
1884
|
(pi.calls[0] as any[])[0].content,
|
|
1844
|
-
"
|
|
1845
|
-
"runUnit should receive the dispatch prompt
|
|
1885
|
+
"hooked prompt",
|
|
1886
|
+
"runUnit should receive the dispatch prompt after pre-dispatch hooks",
|
|
1887
|
+
);
|
|
1888
|
+
assert.deepEqual(
|
|
1889
|
+
pi.setModelCalls.map((call: any[]) => call[0]),
|
|
1890
|
+
[
|
|
1891
|
+
{ provider: "test", id: "hook-model" },
|
|
1892
|
+
{ provider: "test", id: "hook-model" },
|
|
1893
|
+
],
|
|
1894
|
+
"proceed hooks should apply model overrides before dispatch",
|
|
1846
1895
|
);
|
|
1847
1896
|
assert.deepEqual(finalizedUnits, ["execute-task:M002/S03/T05"]);
|
|
1848
1897
|
assert.equal(s.pendingOrchestrationDispatch, null, "pending dispatch should be one-shot");
|
|
1898
|
+
assert.equal(
|
|
1899
|
+
journalEvents.filter((entry) => entry.eventType === "pre-dispatch-hook").length,
|
|
1900
|
+
1,
|
|
1901
|
+
"hook dispatch should emit one pre-dispatch-hook journal event",
|
|
1902
|
+
);
|
|
1903
|
+
});
|
|
1904
|
+
|
|
1905
|
+
test("autoLoop pauses once when orchestration reports reconciliation drift error", async () => {
|
|
1906
|
+
_resetPendingResolve();
|
|
1907
|
+
|
|
1908
|
+
const ctx = makeMockCtx();
|
|
1909
|
+
ctx.ui.setStatus = () => {};
|
|
1910
|
+
ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
|
|
1911
|
+
const pi = makeMockPi();
|
|
1912
|
+
let advanceCalls = 0;
|
|
1913
|
+
const s = makeLoopSession({
|
|
1914
|
+
currentMilestoneId: "M002",
|
|
1915
|
+
orchestration: {
|
|
1916
|
+
start: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1917
|
+
advance: async () => {
|
|
1918
|
+
advanceCalls++;
|
|
1919
|
+
return {
|
|
1920
|
+
kind: "error" as const,
|
|
1921
|
+
reason: "Reconciliation drift: Reconciliation repair failed in pass 0",
|
|
1922
|
+
};
|
|
1923
|
+
},
|
|
1924
|
+
completeActiveUnit: async () => {},
|
|
1925
|
+
retryActiveUnit: async () => {},
|
|
1926
|
+
resume: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1927
|
+
stop: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1928
|
+
getStatus: () => ({ phase: "error" as const, transitionCount: 1 }),
|
|
1929
|
+
},
|
|
1930
|
+
});
|
|
1931
|
+
|
|
1932
|
+
const deps = makeMockDeps({
|
|
1933
|
+
resolveDispatch: async () => {
|
|
1934
|
+
deps.callLog.push("resolveDispatch");
|
|
1935
|
+
throw new Error("legacy resolveDispatch must not run after orchestration error");
|
|
1936
|
+
},
|
|
1937
|
+
});
|
|
1938
|
+
|
|
1939
|
+
await autoLoop(ctx, pi, s, deps);
|
|
1940
|
+
|
|
1941
|
+
assert.equal(advanceCalls, 1, "orchestration error must not be retried in the same loop");
|
|
1942
|
+
assert.ok(deps.callLog.includes("pauseAuto"), "orchestration error should pause auto-mode");
|
|
1943
|
+
assert.equal(
|
|
1944
|
+
deps.callLog.includes("resolveDispatch"),
|
|
1945
|
+
false,
|
|
1946
|
+
"orchestration error must not fall back to legacy dispatch",
|
|
1947
|
+
);
|
|
1948
|
+
assert.equal(s.pendingOrchestrationDispatch, null, "no orchestration dispatch should remain pending");
|
|
1949
|
+
});
|
|
1950
|
+
|
|
1951
|
+
test("autoLoop retries next iteration when orchestration reports paused", async () => {
|
|
1952
|
+
_resetPendingResolve();
|
|
1953
|
+
|
|
1954
|
+
const ctx = makeMockCtx();
|
|
1955
|
+
ctx.ui.setStatus = () => {};
|
|
1956
|
+
ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
|
|
1957
|
+
const pi = makeMockPi();
|
|
1958
|
+
let advanceCalls = 0;
|
|
1959
|
+
const s = makeLoopSession({
|
|
1960
|
+
currentMilestoneId: "M002",
|
|
1961
|
+
orchestration: {
|
|
1962
|
+
start: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1963
|
+
advance: async () => {
|
|
1964
|
+
advanceCalls++;
|
|
1965
|
+
return advanceCalls === 1
|
|
1966
|
+
? { kind: "paused" as const, reason: "provider transient; retry" }
|
|
1967
|
+
: { kind: "stopped" as const, reason: "done retrying" };
|
|
1968
|
+
},
|
|
1969
|
+
completeActiveUnit: async () => {},
|
|
1970
|
+
retryActiveUnit: async () => {},
|
|
1971
|
+
resume: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1972
|
+
stop: async () => ({ kind: "stopped" as const, reason: "unused" }),
|
|
1973
|
+
getStatus: () => ({ phase: "running" as const, transitionCount: advanceCalls }),
|
|
1974
|
+
},
|
|
1975
|
+
});
|
|
1976
|
+
|
|
1977
|
+
const deps = makeMockDeps({
|
|
1978
|
+
resolveDispatch: async () => {
|
|
1979
|
+
deps.callLog.push("resolveDispatch");
|
|
1980
|
+
throw new Error("legacy resolveDispatch must not run after orchestration paused");
|
|
1981
|
+
},
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
await autoLoop(ctx, pi, s, deps);
|
|
1985
|
+
|
|
1986
|
+
assert.equal(advanceCalls, 2, "orchestration paused should retry on the next loop iteration");
|
|
1987
|
+
assert.equal(deps.callLog.includes("pauseAuto"), false, "orchestration paused should not pause auto-mode");
|
|
1988
|
+
assert.equal(
|
|
1989
|
+
deps.callLog.includes("resolveDispatch"),
|
|
1990
|
+
false,
|
|
1991
|
+
"orchestration paused must not fall back to legacy dispatch",
|
|
1992
|
+
);
|
|
1993
|
+
assert.equal(s.pendingOrchestrationDispatch, null, "no orchestration dispatch should remain pending");
|
|
1849
1994
|
});
|
|
1850
1995
|
|
|
1851
1996
|
test("autoLoop consumes pending orchestration dispatch without advancing twice", async () => {
|
|
@@ -4453,6 +4598,101 @@ test("autoLoop rejects execute-task with 0 tool calls as hallucinated (#1833)",
|
|
|
4453
4598
|
);
|
|
4454
4599
|
});
|
|
4455
4600
|
|
|
4601
|
+
test("runUnitPhase retries 0-tool units with ordinary network-related assistant text", async (t) => {
|
|
4602
|
+
_resetPendingResolve();
|
|
4603
|
+
|
|
4604
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-zero-tool-network-text-"));
|
|
4605
|
+
t.after(() => {
|
|
4606
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
4607
|
+
});
|
|
4608
|
+
|
|
4609
|
+
const ctx = {
|
|
4610
|
+
...makeMockCtx(),
|
|
4611
|
+
ui: {
|
|
4612
|
+
notify: () => {},
|
|
4613
|
+
setStatus: () => {},
|
|
4614
|
+
setWorkingMessage: () => {},
|
|
4615
|
+
},
|
|
4616
|
+
sessionManager: {
|
|
4617
|
+
getEntries: () => [],
|
|
4618
|
+
},
|
|
4619
|
+
modelRegistry: {
|
|
4620
|
+
getProviderAuthMode: () => undefined,
|
|
4621
|
+
isProviderRequestReady: () => true,
|
|
4622
|
+
},
|
|
4623
|
+
} as any;
|
|
4624
|
+
const pi = {
|
|
4625
|
+
...makeMockPi(),
|
|
4626
|
+
sendMessage: () => {
|
|
4627
|
+
queueMicrotask(() => resolveAgentEnd(makeEvent([
|
|
4628
|
+
{
|
|
4629
|
+
role: "assistant",
|
|
4630
|
+
content: [
|
|
4631
|
+
{ type: "text", text: "Error: I'll investigate the network error handling next." },
|
|
4632
|
+
],
|
|
4633
|
+
},
|
|
4634
|
+
])));
|
|
4635
|
+
},
|
|
4636
|
+
} as any;
|
|
4637
|
+
const s = makeLoopSession({
|
|
4638
|
+
basePath,
|
|
4639
|
+
canonicalProjectRoot: basePath,
|
|
4640
|
+
originalBasePath: basePath,
|
|
4641
|
+
});
|
|
4642
|
+
const mockLedger = {
|
|
4643
|
+
version: 1,
|
|
4644
|
+
projectStartedAt: Date.now(),
|
|
4645
|
+
units: [] as any[],
|
|
4646
|
+
};
|
|
4647
|
+
const deps = makeMockDeps({
|
|
4648
|
+
closeoutUnit: async () => {
|
|
4649
|
+
mockLedger.units.push({
|
|
4650
|
+
type: "execute-task",
|
|
4651
|
+
id: "M001/S01/T01",
|
|
4652
|
+
startedAt: s.currentUnit?.startedAt ?? Date.now(),
|
|
4653
|
+
toolCalls: 0,
|
|
4654
|
+
assistantMessages: 1,
|
|
4655
|
+
tokens: { input: 100, output: 20, total: 120, cacheRead: 0, cacheWrite: 0 },
|
|
4656
|
+
cost: 0.01,
|
|
4657
|
+
});
|
|
4658
|
+
},
|
|
4659
|
+
getLedger: () => mockLedger,
|
|
4660
|
+
});
|
|
4661
|
+
let seq = 0;
|
|
4662
|
+
|
|
4663
|
+
const result = await runUnitPhase(
|
|
4664
|
+
{ ctx, pi, s, deps, prefs: undefined, iteration: 1, flowId: "flow-zero-tool-network-text", nextSeq: () => ++seq },
|
|
4665
|
+
{
|
|
4666
|
+
unitType: "execute-task",
|
|
4667
|
+
unitId: "M001/S01/T01",
|
|
4668
|
+
prompt: "do work",
|
|
4669
|
+
finalPrompt: "do work",
|
|
4670
|
+
pauseAfterUatDispatch: false,
|
|
4671
|
+
state: {
|
|
4672
|
+
phase: "executing",
|
|
4673
|
+
activeMilestone: { id: "M001", title: "Milestone" },
|
|
4674
|
+
activeSlice: { id: "S01", title: "Slice" },
|
|
4675
|
+
activeTask: { id: "T01", title: "Task" },
|
|
4676
|
+
registry: [{ id: "M001", title: "Milestone", status: "active" }],
|
|
4677
|
+
recentDecisions: [],
|
|
4678
|
+
blockers: [],
|
|
4679
|
+
nextAction: "",
|
|
4680
|
+
progress: { milestones: { done: 0, total: 1 } },
|
|
4681
|
+
requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 },
|
|
4682
|
+
} as any,
|
|
4683
|
+
mid: "M001",
|
|
4684
|
+
midTitle: "Milestone",
|
|
4685
|
+
isRetry: false,
|
|
4686
|
+
previousTier: undefined,
|
|
4687
|
+
},
|
|
4688
|
+
{ recentUnits: [{ key: "execute-task/M001/S01/T01" }], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 },
|
|
4689
|
+
);
|
|
4690
|
+
|
|
4691
|
+
assert.equal(result.action, "retry");
|
|
4692
|
+
assert.equal((result as any).reason, "zero-tool-calls");
|
|
4693
|
+
assert.equal(deps.callLog.includes("pauseAuto"), false);
|
|
4694
|
+
});
|
|
4695
|
+
|
|
4456
4696
|
test("autoLoop pauses user-driven deep question instead of flagging 0 tool calls", async () => {
|
|
4457
4697
|
_resetPendingResolve();
|
|
4458
4698
|
|
|
@@ -4640,6 +4880,92 @@ test("autoLoop rejects complete-slice with 0 tool calls as context-exhausted (#2
|
|
|
4640
4880
|
);
|
|
4641
4881
|
});
|
|
4642
4882
|
|
|
4883
|
+
test("autoLoop pauses on zero-tool-call rate-limit assistant messages instead of immediate retry", async (t) => {
|
|
4884
|
+
_resetPendingResolve();
|
|
4885
|
+
|
|
4886
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-zero-tool-rate-limit-"));
|
|
4887
|
+
t.after(() => {
|
|
4888
|
+
_resetPendingResolve();
|
|
4889
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
4890
|
+
});
|
|
4891
|
+
|
|
4892
|
+
const originalSetTimeout = globalThis.setTimeout;
|
|
4893
|
+
const timers: Array<{ fn: () => void; delay: number }> = [];
|
|
4894
|
+
globalThis.setTimeout = ((fn: () => void, delay?: number) => {
|
|
4895
|
+
timers.push({ fn, delay: delay ?? 0 });
|
|
4896
|
+
return 0 as unknown as ReturnType<typeof setTimeout>;
|
|
4897
|
+
}) as typeof setTimeout;
|
|
4898
|
+
|
|
4899
|
+
try {
|
|
4900
|
+
const ctx = makeMockCtx();
|
|
4901
|
+
ctx.ui.setStatus = () => {};
|
|
4902
|
+
const notifications: string[] = [];
|
|
4903
|
+
ctx.ui.notify = (msg: string) => { notifications.push(msg); };
|
|
4904
|
+
ctx.sessionManager = { getSessionFile: () => "/tmp/session.json" };
|
|
4905
|
+
ctx.modelRegistry = {
|
|
4906
|
+
getProviderAuthMode: () => undefined,
|
|
4907
|
+
isProviderRequestReady: () => true,
|
|
4908
|
+
};
|
|
4909
|
+
const pi = makeMockPi();
|
|
4910
|
+
const s = makeLoopSession({
|
|
4911
|
+
basePath,
|
|
4912
|
+
canonicalProjectRoot: basePath,
|
|
4913
|
+
originalBasePath: basePath,
|
|
4914
|
+
});
|
|
4915
|
+
|
|
4916
|
+
const mockLedger = {
|
|
4917
|
+
version: 1,
|
|
4918
|
+
projectStartedAt: Date.now(),
|
|
4919
|
+
units: [] as any[],
|
|
4920
|
+
};
|
|
4921
|
+
|
|
4922
|
+
const deps = makeMockDeps({
|
|
4923
|
+
closeoutUnit: async () => {
|
|
4924
|
+
mockLedger.units.push({
|
|
4925
|
+
type: "execute-task",
|
|
4926
|
+
id: "M001/S01/T01",
|
|
4927
|
+
startedAt: s.currentUnit?.startedAt ?? Date.now(),
|
|
4928
|
+
toolCalls: 0,
|
|
4929
|
+
assistantMessages: 1,
|
|
4930
|
+
tokens: { input: 100, output: 100, total: 200, cacheRead: 0, cacheWrite: 0 },
|
|
4931
|
+
cost: 0.05,
|
|
4932
|
+
});
|
|
4933
|
+
},
|
|
4934
|
+
getLedger: () => mockLedger,
|
|
4935
|
+
});
|
|
4936
|
+
|
|
4937
|
+
const loopPromise = autoLoop(ctx as any, pi as any, s, deps);
|
|
4938
|
+
|
|
4939
|
+
await new Promise((r) => originalSetTimeout(r, 50));
|
|
4940
|
+
resolveAgentEnd(makeEvent([
|
|
4941
|
+
{
|
|
4942
|
+
role: "assistant",
|
|
4943
|
+
content: [{ type: "text", text: "You've hit your limit · resets Jun 1 at 8am" }],
|
|
4944
|
+
},
|
|
4945
|
+
]));
|
|
4946
|
+
|
|
4947
|
+
await loopPromise;
|
|
4948
|
+
|
|
4949
|
+
assert.equal(deps.callLog.includes("pauseAuto"), true);
|
|
4950
|
+
assert.ok(
|
|
4951
|
+
timers.some((timer) => timer.delay === 60_000),
|
|
4952
|
+
"rate-limit message should schedule delayed auto-resume instead of immediate retry",
|
|
4953
|
+
);
|
|
4954
|
+
assert.ok(
|
|
4955
|
+
notifications.some((msg) => msg.includes("Auto-resuming in 60s")),
|
|
4956
|
+
"rate-limit pause should announce delayed resume",
|
|
4957
|
+
);
|
|
4958
|
+
assert.ok(
|
|
4959
|
+
!notifications.some((msg) => msg.includes("context exhaustion")),
|
|
4960
|
+
"rate-limit message should not be classified as context exhaustion",
|
|
4961
|
+
);
|
|
4962
|
+
const deriveCount = deps.callLog.filter((entry) => entry === "deriveState").length;
|
|
4963
|
+
assert.equal(deriveCount, 1, "loop should pause after first iteration instead of redispatching");
|
|
4964
|
+
} finally {
|
|
4965
|
+
globalThis.setTimeout = originalSetTimeout;
|
|
4966
|
+
}
|
|
4967
|
+
});
|
|
4968
|
+
|
|
4643
4969
|
// ─── Worktree health check (#1833) ────────────────────────────────────────
|
|
4644
4970
|
|
|
4645
4971
|
test("autoLoop stops when Worktree Safety finds no .git marker for execute-task (#1833)", async (t) => {
|
|
@@ -592,6 +592,27 @@ test("retryActiveUnit clears in-flight idempotency without marking the unit fina
|
|
|
592
592
|
assert.equal(prepareCalls, 2, "retry should intentionally redispatch the same unit");
|
|
593
593
|
});
|
|
594
594
|
|
|
595
|
+
test("retryActiveUnit clears finalized same-unit guard for post-hook retries", async () => {
|
|
596
|
+
const { deps, calls } = makeDeps();
|
|
597
|
+
const orchestrator = createAutoOrchestrator(deps);
|
|
598
|
+
|
|
599
|
+
const first = await orchestrator.advance();
|
|
600
|
+
assert.equal(first.kind, "advanced");
|
|
601
|
+
if (first.kind !== "advanced") throw new Error("expected first advance");
|
|
602
|
+
|
|
603
|
+
await orchestrator.completeActiveUnit(first.unit);
|
|
604
|
+
await orchestrator.retryActiveUnit(first.unit);
|
|
605
|
+
const second = await orchestrator.advance();
|
|
606
|
+
|
|
607
|
+
assert.equal(second.kind, "advanced");
|
|
608
|
+
if (second.kind !== "advanced") throw new Error("expected retry advance");
|
|
609
|
+
assert.deepEqual(second.unit, first.unit);
|
|
610
|
+
assert.ok(calls.includes("journal:unit-finalized"));
|
|
611
|
+
assert.ok(calls.includes("journal:unit-retry"));
|
|
612
|
+
const prepareCalls = calls.filter((c) => c === "worktree.prepare").length;
|
|
613
|
+
assert.equal(prepareCalls, 2, "post-hook retry should redispatch the finalized unit");
|
|
614
|
+
});
|
|
615
|
+
|
|
595
616
|
test("resume() re-enters running phase", async () => {
|
|
596
617
|
const { deps } = makeDeps();
|
|
597
618
|
const orchestrator = createAutoOrchestrator(deps);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
_describeArtifactVerificationFailureForTest,
|
|
8
|
+
maybeWriteParallelResearchCostSpikeBlocker,
|
|
9
|
+
} from "../auto-post-unit.ts";
|
|
10
|
+
import { resolveExpectedArtifactPath } from "../auto-recovery.ts";
|
|
7
11
|
|
|
8
12
|
test("missing execute-task artifact includes completion contract and completion-tool hint", () => {
|
|
9
13
|
const base = mkdtempSync(join(tmpdir(), "gsd-artifact-diag-"));
|
|
@@ -30,3 +34,25 @@ test("missing execute-task artifact skips completion-tool hint when completion t
|
|
|
30
34
|
assert.match(msg, /was not found on disk after unit execution/);
|
|
31
35
|
assert.doesNotMatch(msg, /No completion tool call detected \(`gsd_task_complete`\/alias\)/);
|
|
32
36
|
});
|
|
37
|
+
|
|
38
|
+
test("parallel research cost spike writes durable PARALLEL-BLOCKER", () => {
|
|
39
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-parallel-cost-blocker-"));
|
|
40
|
+
try {
|
|
41
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
42
|
+
const blocker = maybeWriteParallelResearchCostSpikeBlocker(
|
|
43
|
+
"research-slice",
|
|
44
|
+
"M001/parallel-research",
|
|
45
|
+
base,
|
|
46
|
+
3.73,
|
|
47
|
+
1.02,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const expected = resolveExpectedArtifactPath("research-slice", "M001/parallel-research", base);
|
|
51
|
+
assert.match(blocker ?? "", /M001-PARALLEL-BLOCKER\.md/);
|
|
52
|
+
assert.ok(expected);
|
|
53
|
+
assert.equal(existsSync(expected!), true);
|
|
54
|
+
assert.match(readFileSync(expected!, "utf-8"), /cost spike detected \(3\.73 vs avg 1\.02\)/);
|
|
55
|
+
} finally {
|
|
56
|
+
rmSync(base, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
@@ -58,3 +58,33 @@ test("detects top-level bash tool call via toolName field", () => {
|
|
|
58
58
|
|
|
59
59
|
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), true);
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
test("detects session execution tools supported by the evidence collector", () => {
|
|
63
|
+
const entries = [
|
|
64
|
+
{
|
|
65
|
+
type: "message",
|
|
66
|
+
message: {
|
|
67
|
+
role: "assistant",
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: "toolCall",
|
|
71
|
+
toolName: "async_bash",
|
|
72
|
+
arguments: { command: "npm test" },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "toolCall",
|
|
76
|
+
toolName: "PowerShell",
|
|
77
|
+
arguments: { command: "Get-ChildItem" },
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: "toolCall",
|
|
81
|
+
toolName: "functions.exec_command",
|
|
82
|
+
arguments: { cmd: "pnpm test" },
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
assert.equal(_hasExecutionToolCallsInSessionForTest(entries), true);
|
|
90
|
+
});
|
|
@@ -1837,3 +1837,44 @@ test("#4414: verifyExpectedArtifact parallel-research succeeds when all research
|
|
|
1837
1837
|
cleanup(base);
|
|
1838
1838
|
}
|
|
1839
1839
|
});
|
|
1840
|
+
|
|
1841
|
+
test("parallel-research verification accepts canonical project artifacts from a worktree base", () => {
|
|
1842
|
+
const base = makeTmpBase();
|
|
1843
|
+
try {
|
|
1844
|
+
const milestoneDir = join(base, ".gsd", "milestones", "M001");
|
|
1845
|
+
mkdirSync(join(milestoneDir, "slices", "S02", "tasks"), { recursive: true });
|
|
1846
|
+
mkdirSync(join(milestoneDir, "slices", "S03", "tasks"), { recursive: true });
|
|
1847
|
+
|
|
1848
|
+
writeFileSync(
|
|
1849
|
+
join(milestoneDir, "M001-ROADMAP.md"),
|
|
1850
|
+
[
|
|
1851
|
+
"# M001: Regression",
|
|
1852
|
+
"",
|
|
1853
|
+
"## Slices",
|
|
1854
|
+
"",
|
|
1855
|
+
"- [ ] **S01: Alpha** `risk:low` `depends:[]`",
|
|
1856
|
+
"- [ ] **S02: Beta** `risk:low` `depends:[]`",
|
|
1857
|
+
"- [ ] **S03: Gamma** `risk:low` `depends:[]`",
|
|
1858
|
+
"",
|
|
1859
|
+
].join("\n"),
|
|
1860
|
+
"utf-8",
|
|
1861
|
+
);
|
|
1862
|
+
writeFileSync(join(milestoneDir, "M001-RESEARCH.md"), "# milestone research\n", "utf-8");
|
|
1863
|
+
writeFileSync(join(milestoneDir, "slices", "S02", "S02-RESEARCH.md"), "# research\n", "utf-8");
|
|
1864
|
+
writeFileSync(join(milestoneDir, "slices", "S03", "S03-RESEARCH.md"), "# research\n", "utf-8");
|
|
1865
|
+
|
|
1866
|
+
const worktree = join(base, ".gsd", "worktrees", "M001");
|
|
1867
|
+
mkdirSync(join(worktree, ".gsd", "milestones", "M001"), { recursive: true });
|
|
1868
|
+
writeFileSync(join(worktree, ".git"), "gitdir: ../../../../.git/worktrees/M001\n", "utf-8");
|
|
1869
|
+
|
|
1870
|
+
clearParseCache();
|
|
1871
|
+
invalidateAllCaches();
|
|
1872
|
+
assert.equal(
|
|
1873
|
+
verifyExpectedArtifact("research-slice", "M001/parallel-research", worktree),
|
|
1874
|
+
true,
|
|
1875
|
+
"worktree verification should use the same canonical artifacts as dispatch",
|
|
1876
|
+
);
|
|
1877
|
+
} finally {
|
|
1878
|
+
cleanup(base);
|
|
1879
|
+
}
|
|
1880
|
+
});
|
|
@@ -95,4 +95,16 @@ describe("evidence-collector: toolCallId-based matching (A-3)", () => {
|
|
|
95
95
|
assert.equal(entries[1].kind, "bash");
|
|
96
96
|
assert.equal(entries[1].command, "npm run build");
|
|
97
97
|
});
|
|
98
|
+
|
|
99
|
+
it("treats Codex exec_command tool names as execution evidence", () => {
|
|
100
|
+
recordToolCall("tc-exec", "exec_command", { cmd: "pnpm test" });
|
|
101
|
+
recordToolCall("tc-namespaced-exec", "functions.exec_command", { cmd: "pnpm lint" });
|
|
102
|
+
|
|
103
|
+
const entries = getEvidence() as readonly BashEvidence[];
|
|
104
|
+
assert.equal(entries.length, 2);
|
|
105
|
+
assert.equal(entries[0].kind, "bash");
|
|
106
|
+
assert.equal(entries[0].command, "pnpm test");
|
|
107
|
+
assert.equal(entries[1].kind, "bash");
|
|
108
|
+
assert.equal(entries[1].command, "pnpm lint");
|
|
109
|
+
});
|
|
98
110
|
});
|