@opengsd/gsd-pi 1.5.0-dev.553dc518 → 1.5.0-dev.c4c8885f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
- package/dist/resources/extensions/gsd/activity-log.js +1 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +16 -10
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +7 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
- package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -117
- package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
- package/dist/resources/extensions/gsd/auto-start.js +54 -31
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
- package/dist/resources/extensions/gsd/auto-timers.js +9 -2
- package/dist/resources/extensions/gsd/auto.js +97 -31
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +67 -6
- package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
- package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
- package/dist/resources/extensions/gsd/config-overlay.js +7 -2
- package/dist/resources/extensions/gsd/db/engine.js +33 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
- package/dist/resources/extensions/gsd/db-adapter.js +30 -3
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/dist/resources/extensions/gsd/flat-phase-migration.js +18 -0
- package/dist/resources/extensions/gsd/gsd-db.js +12 -11
- package/dist/resources/extensions/gsd/guided-flow.js +16 -7
- package/dist/resources/extensions/gsd/journal.js +1 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +34 -91
- package/dist/resources/extensions/gsd/md-importer.js +89 -23
- package/dist/resources/extensions/gsd/metrics.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
- package/dist/resources/extensions/gsd/paths.js +87 -52
- package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
- package/dist/resources/extensions/gsd/preferences-models.js +66 -15
- package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
- package/dist/resources/extensions/gsd/preferences-validation.js +66 -10
- package/dist/resources/extensions/gsd/preferences.js +20 -0
- package/dist/resources/extensions/gsd/rule-registry.js +106 -10
- package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
- package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
- package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
- package/dist/resources/extensions/gsd/uok/audit.js +3 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
- package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
- package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
- package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
- package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
- package/dist/resources/extensions/gsd/workspace.js +5 -14
- package/dist/resources/extensions/shared/gsd-browser-cli.js +29 -0
- package/dist/resources/extensions/shared/interview-ui.js +62 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- 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/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +10 -10
- package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- 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/worktree-cli-create.d.ts +10 -0
- package/dist/worktree-cli-create.js +11 -0
- package/dist/worktree-cli-format.d.ts +12 -0
- package/dist/worktree-cli-format.js +38 -0
- package/dist/worktree-cli-plan.d.ts +16 -0
- package/dist/worktree-cli-plan.js +19 -0
- package/dist/worktree-cli-session.d.ts +13 -0
- package/dist/worktree-cli-session.js +18 -0
- package/dist/worktree-cli-status.d.ts +35 -0
- package/dist/worktree-cli-status.js +54 -0
- package/dist/worktree-cli.d.ts +1 -16
- package/dist/worktree-cli.js +28 -122
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +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/dist/orchestrator-agent.d.ts +21 -0
- package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-agent.js +113 -0
- package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
- package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
- package/packages/daemon/dist/orchestrator-tools.js +137 -0
- package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
- package/packages/daemon/dist/orchestrator.d.ts +4 -56
- package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
- package/packages/daemon/dist/orchestrator.js +13 -303
- package/packages/daemon/dist/orchestrator.js.map +1 -1
- package/packages/daemon/dist/orchestrator.test.js +11 -1
- package/packages/daemon/dist/orchestrator.test.js.map +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
- package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
- package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
- package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +4 -1
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +25 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
- package/src/resources/extensions/gsd/activity-log.ts +1 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +17 -11
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +9 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
- package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +53 -113
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
- package/src/resources/extensions/gsd/auto-start.ts +58 -29
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
- package/src/resources/extensions/gsd/auto-timers.ts +9 -2
- package/src/resources/extensions/gsd/auto.ts +103 -30
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +66 -6
- package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
- package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
- package/src/resources/extensions/gsd/config-overlay.ts +7 -1
- package/src/resources/extensions/gsd/db/engine.ts +36 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
- package/src/resources/extensions/gsd/db-adapter.ts +29 -3
- package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
- package/src/resources/extensions/gsd/flat-phase-migration.ts +20 -0
- package/src/resources/extensions/gsd/gsd-db.ts +20 -11
- package/src/resources/extensions/gsd/guided-flow.ts +19 -7
- package/src/resources/extensions/gsd/journal.ts +1 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +52 -103
- package/src/resources/extensions/gsd/md-importer.ts +93 -22
- package/src/resources/extensions/gsd/metrics.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
- package/src/resources/extensions/gsd/paths.ts +108 -51
- package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
- package/src/resources/extensions/gsd/preferences-models.ts +74 -20
- package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
- package/src/resources/extensions/gsd/preferences-types.ts +24 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +77 -9
- package/src/resources/extensions/gsd/preferences.ts +20 -0
- package/src/resources/extensions/gsd/rule-registry.ts +111 -9
- package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
- package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
- package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
- package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
- package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
- package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
- package/src/resources/extensions/gsd/types.ts +23 -4
- package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
- package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
- package/src/resources/extensions/gsd/uok/audit.ts +2 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
- package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
- package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
- package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
- package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
- package/src/resources/extensions/gsd/workspace.ts +5 -21
- package/src/resources/extensions/shared/gsd-browser-cli.ts +29 -0
- package/src/resources/extensions/shared/interview-ui.ts +58 -11
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
- /package/dist/web/standalone/.next/static/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ZpFDazP-38PXBPiI_LdZf → NPMNi2HV8BuK3baQsEUhk}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d89940a8e727f2ea
|
|
@@ -209,7 +209,7 @@ export default function AskUserQuestions(pi) {
|
|
|
209
209
|
"For single-select: each question must have 2-3 options. Put the recommended option first with '(Recommended)' suffix. Do not include an 'Other' or 'None of the above' option - the client adds one automatically.",
|
|
210
210
|
"For multi-select: set allowMultiple: true. The user can pick any number of options. No 'None of the above' is added.",
|
|
211
211
|
"When options involve code patterns, config choices, or architecture decisions, add a 'preview' field with markdown content (code blocks, lists, headers, etc.). The preview renders in a side-by-side panel when the option is highlighted.",
|
|
212
|
-
"Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content
|
|
212
|
+
"Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content stays fully accessible: the user scrolls it with PgUp/PgDn, with '▲/▼ N more' indicators marking hidden rows.",
|
|
213
213
|
],
|
|
214
214
|
parameters: AskUserQuestionsParams,
|
|
215
215
|
async execute(_toolCallId, params, signal, _onUpdate, ctx) {
|
|
@@ -4,8 +4,6 @@ import { Type } from "@sinclair/typebox";
|
|
|
4
4
|
import { BROWSER_CONTRACT_TOOL_NAMES } from "../../shared/browser-contract.js";
|
|
5
5
|
import { resolveGsdBrowserMcpLaunchConfig } from "../../shared/gsd-browser-cli.js";
|
|
6
6
|
import { buildMcpChildEnv } from "../../mcp-client/manager.js";
|
|
7
|
-
const connections = new Map();
|
|
8
|
-
const pendingConnections = new Map();
|
|
9
7
|
const DEFAULT_MAX_LINES = 2_000;
|
|
10
8
|
const DEFAULT_MAX_BYTES = 50 * 1024;
|
|
11
9
|
const MCP_CALL_TIMEOUT_MS = 60_000;
|
|
@@ -297,6 +295,103 @@ function buildConnectionKey(launch) {
|
|
|
297
295
|
env: launch.env ?? {},
|
|
298
296
|
});
|
|
299
297
|
}
|
|
298
|
+
function combineAbortSignals(poolSignal, callerSignal) {
|
|
299
|
+
if (!callerSignal)
|
|
300
|
+
return poolSignal;
|
|
301
|
+
if (typeof AbortSignal.any === "function") {
|
|
302
|
+
return AbortSignal.any([poolSignal, callerSignal]);
|
|
303
|
+
}
|
|
304
|
+
const controller = new AbortController();
|
|
305
|
+
const abort = () => {
|
|
306
|
+
if (!controller.signal.aborted)
|
|
307
|
+
controller.abort();
|
|
308
|
+
};
|
|
309
|
+
if (poolSignal.aborted || callerSignal.aborted) {
|
|
310
|
+
abort();
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
poolSignal.addEventListener("abort", abort, { once: true });
|
|
314
|
+
callerSignal.addEventListener("abort", abort, { once: true });
|
|
315
|
+
}
|
|
316
|
+
return controller.signal;
|
|
317
|
+
}
|
|
318
|
+
export class ManagedGsdBrowserConnectionPool {
|
|
319
|
+
connections = new Map();
|
|
320
|
+
pendingConnections = new Map();
|
|
321
|
+
connect;
|
|
322
|
+
closeConnection;
|
|
323
|
+
generation = 0;
|
|
324
|
+
closing = false;
|
|
325
|
+
constructor(connect, closeConnection) {
|
|
326
|
+
this.connect = connect;
|
|
327
|
+
this.closeConnection = closeConnection;
|
|
328
|
+
}
|
|
329
|
+
get activeCount() {
|
|
330
|
+
return this.connections.size;
|
|
331
|
+
}
|
|
332
|
+
get pendingCount() {
|
|
333
|
+
return this.pendingConnections.size;
|
|
334
|
+
}
|
|
335
|
+
getOrConnect(launch, signal) {
|
|
336
|
+
if (this.closing) {
|
|
337
|
+
return Promise.reject(new Error("gsd-browser connection pool is closing"));
|
|
338
|
+
}
|
|
339
|
+
const key = buildConnectionKey(launch);
|
|
340
|
+
const existing = this.connections.get(key);
|
|
341
|
+
if (existing)
|
|
342
|
+
return Promise.resolve(existing);
|
|
343
|
+
const pending = this.pendingConnections.get(key);
|
|
344
|
+
if (pending)
|
|
345
|
+
return pending.promise;
|
|
346
|
+
const generation = this.generation;
|
|
347
|
+
const abortController = new AbortController();
|
|
348
|
+
const connectionSignal = combineAbortSignals(abortController.signal, signal);
|
|
349
|
+
const connectionPromise = this.connect(launch, connectionSignal)
|
|
350
|
+
.then(async (connection) => {
|
|
351
|
+
if (this.closing || this.generation !== generation) {
|
|
352
|
+
await this.closeConnection(connection);
|
|
353
|
+
throw new Error("gsd-browser connection closed during startup");
|
|
354
|
+
}
|
|
355
|
+
this.connections.set(key, connection);
|
|
356
|
+
return connection;
|
|
357
|
+
})
|
|
358
|
+
.finally(() => {
|
|
359
|
+
if (this.pendingConnections.get(key)?.promise === connectionPromise) {
|
|
360
|
+
this.pendingConnections.delete(key);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
this.pendingConnections.set(key, { promise: connectionPromise, abortController });
|
|
364
|
+
return connectionPromise;
|
|
365
|
+
}
|
|
366
|
+
async closeAll() {
|
|
367
|
+
this.closing = true;
|
|
368
|
+
this.generation += 1;
|
|
369
|
+
const activeConnections = Array.from(this.connections.values());
|
|
370
|
+
const pendingConnections = Array.from(this.pendingConnections.values());
|
|
371
|
+
this.connections.clear();
|
|
372
|
+
this.pendingConnections.clear();
|
|
373
|
+
for (const pending of pendingConnections) {
|
|
374
|
+
pending.abortController.abort();
|
|
375
|
+
}
|
|
376
|
+
const closingActive = activeConnections.map((connection) => this.closeConnection(connection));
|
|
377
|
+
const closingPending = pendingConnections.map(async (pending) => {
|
|
378
|
+
try {
|
|
379
|
+
const connection = await pending.promise;
|
|
380
|
+
await this.closeConnection(connection);
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// Failed or invalidated connection attempts have already cleaned up.
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
try {
|
|
387
|
+
await Promise.allSettled([...closingActive, ...closingPending]);
|
|
388
|
+
}
|
|
389
|
+
finally {
|
|
390
|
+
this.closing = false;
|
|
391
|
+
this.generation += 1;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
300
395
|
async function connectManagedGsdBrowser(launch, signal) {
|
|
301
396
|
const client = new Client({ name: "gsd-pi-browser-tools", version: "1.0.0" });
|
|
302
397
|
const transport = new StdioClientTransport({
|
|
@@ -326,27 +421,26 @@ async function connectManagedGsdBrowser(launch, signal) {
|
|
|
326
421
|
throw error;
|
|
327
422
|
}
|
|
328
423
|
}
|
|
424
|
+
async function closeManagedGsdBrowserConnection(connection) {
|
|
425
|
+
try {
|
|
426
|
+
await connection.client.close();
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// Best-effort cleanup.
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
await connection.transport.close();
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
// Best-effort cleanup.
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const connectionPool = new ManagedGsdBrowserConnectionPool(connectManagedGsdBrowser, closeManagedGsdBrowserConnection);
|
|
329
439
|
async function getOrConnectManagedGsdBrowser(ctx, signal) {
|
|
330
440
|
const launch = resolveGsdBrowserMcpLaunchConfig(resolveProjectRoot(ctx), process.env, {
|
|
331
441
|
sessionSuffix: resolveManagedSessionSuffix(ctx),
|
|
332
442
|
});
|
|
333
|
-
|
|
334
|
-
const existing = connections.get(key);
|
|
335
|
-
if (existing)
|
|
336
|
-
return existing;
|
|
337
|
-
const pending = pendingConnections.get(key);
|
|
338
|
-
if (pending)
|
|
339
|
-
return pending;
|
|
340
|
-
const connectionPromise = connectManagedGsdBrowser(launch, signal);
|
|
341
|
-
pendingConnections.set(key, connectionPromise);
|
|
342
|
-
try {
|
|
343
|
-
const connection = await connectionPromise;
|
|
344
|
-
connections.set(key, connection);
|
|
345
|
-
return connection;
|
|
346
|
-
}
|
|
347
|
-
finally {
|
|
348
|
-
pendingConnections.delete(key);
|
|
349
|
-
}
|
|
443
|
+
return connectionPool.getOrConnect(launch, signal);
|
|
350
444
|
}
|
|
351
445
|
function isUnknownMcpToolError(error) {
|
|
352
446
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -609,23 +703,7 @@ export function registerManagedGsdBrowserTools(pi) {
|
|
|
609
703
|
}
|
|
610
704
|
}
|
|
611
705
|
export async function closeManagedGsdBrowser() {
|
|
612
|
-
|
|
613
|
-
try {
|
|
614
|
-
await connection.client.close();
|
|
615
|
-
}
|
|
616
|
-
catch {
|
|
617
|
-
// Best-effort cleanup.
|
|
618
|
-
}
|
|
619
|
-
try {
|
|
620
|
-
await connection.transport.close();
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
// Best-effort cleanup.
|
|
624
|
-
}
|
|
625
|
-
connections.delete(key);
|
|
626
|
-
});
|
|
627
|
-
await Promise.allSettled(closing);
|
|
628
|
-
pendingConnections.clear();
|
|
706
|
+
await connectionPool.closeAll();
|
|
629
707
|
}
|
|
630
708
|
export async function _resetManagedGsdBrowserForTest() {
|
|
631
709
|
await closeManagedGsdBrowser();
|
|
@@ -115,7 +115,7 @@ export function saveActivityLog(ctx, basePath, unitType, unitId) {
|
|
|
115
115
|
}
|
|
116
116
|
state.nextSeq += 1;
|
|
117
117
|
state.lastSnapshotKeyByUnit.set(unitKey, key);
|
|
118
|
-
if (isUnifiedAuditEnabled()) {
|
|
118
|
+
if (isUnifiedAuditEnabled(basePath)) {
|
|
119
119
|
emitUokAuditEvent(basePath, buildAuditEnvelope({
|
|
120
120
|
traceId: `activity:${unitType}:${unitId}`,
|
|
121
121
|
turnId: unitId,
|
|
@@ -999,16 +999,22 @@ export class AutoOrchestrator {
|
|
|
999
999
|
this.postAdvanceRecord(skipped);
|
|
1000
1000
|
return skipped;
|
|
1001
1001
|
}
|
|
1002
|
-
// Stuck-loop detection:
|
|
1003
|
-
//
|
|
1004
|
-
//
|
|
1005
|
-
//
|
|
1006
|
-
//
|
|
1007
|
-
//
|
|
1008
|
-
//
|
|
1009
|
-
//
|
|
1010
|
-
//
|
|
1011
|
-
|
|
1002
|
+
// Stuck-loop detection: consult the Dispatch History module's full
|
|
1003
|
+
// detect-stuck rule set once the window is *full* — not only when a
|
|
1004
|
+
// single key saturates it. Gating on a single key's saturation count
|
|
1005
|
+
// (matchingCount >= STUCK_WINDOW_SIZE) let two-unit oscillations slip
|
|
1006
|
+
// through forever: an execute-task ↔ complete-slice loop (a slice gate
|
|
1007
|
+
// that keeps reopening the same task, #1225) fills the window with two
|
|
1008
|
+
// alternating keys, so neither key ever reaches the saturation count and
|
|
1009
|
+
// detect-stuck's oscillation/repeat rules were never even invoked. Firing
|
|
1010
|
+
// on window saturation instead covers both shapes. Consecutive same-key
|
|
1011
|
+
// re-advances (the benign pause/resume churn the old count gate guarded
|
|
1012
|
+
// against) are already short-circuited above by the idempotency skip, and
|
|
1013
|
+
// legitimate retry backoff is still suppressed inside detect-stuck via the
|
|
1014
|
+
// dispatch ledger — a saturated window with no verdict means we are inside
|
|
1015
|
+
// the unit's retry-backoff budget, so let the retry proceed.
|
|
1016
|
+
const windowSaturated = this.dispatchHistory.getRecentWindow().length >= STUCK_WINDOW_SIZE;
|
|
1017
|
+
const stuckVerdict = windowSaturated ? this.dispatchHistory.detectStuck() : null;
|
|
1012
1018
|
if (stuckVerdict) {
|
|
1013
1019
|
// #442: before declaring a stuck loop, verify the unit didn't actually
|
|
1014
1020
|
// complete on disk (stale DB) and recover if so — legacy graduated
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
// resolveExpectedArtifactPath and diagnoseExpectedArtifact moved here from
|
|
6
6
|
// auto-recovery.ts (Phase 5 dead-code cleanup). The artifact verification
|
|
7
7
|
// function was removed entirely — callers now query WorkflowEngine directly.
|
|
8
|
-
import { gsdRoot, resolveDir, resolveFile, resolveMilestonePath, resolveMilestoneFile, resolveSliceFile, relMilestoneFile, relSliceFile, buildTaskFileName, resolveSlicePath, resolveTasksDir, dirIsMetaOnlyLegacyMilestone, } from "./paths.js";
|
|
8
|
+
import { gsdRoot, resolveDir, resolveFile, resolveMilestonePath, resolveMilestoneFile, resolveSliceFile, relMilestoneFile, relSliceFile, buildTaskFileName, resolveSlicePath, resolveTasksDir, dirIsMetaOnlyLegacyMilestone, normalizeRealPath, } from "./paths.js";
|
|
9
9
|
import { milestoneIdToPhaseNum } from "./layout-policy.js";
|
|
10
10
|
import { parseUnitId } from "./unit-id.js";
|
|
11
|
-
import { dirname, join, relative } from "node:path";
|
|
11
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
12
12
|
import { existsSync } from "node:fs";
|
|
13
13
|
function resolveMilestoneArtifactPath(base, mid, suffix) {
|
|
14
14
|
const existing = resolveProjectedMilestoneFile(base, mid, suffix) ?? resolveProjectMilestoneFile(base, mid, suffix);
|
|
@@ -193,8 +193,17 @@ export function resolveExpectedArtifactPath(unitType, unitId, base) {
|
|
|
193
193
|
?? resolveSlicePath(base, mid, sid);
|
|
194
194
|
if (!slicePath || !tid)
|
|
195
195
|
return null;
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
// Legacy layout: slice dirs live under slices/<SID>/ and task summaries
|
|
197
|
+
// live in a tasks/ subdir. Flat-phase layout: slicePath IS the phase dir
|
|
198
|
+
// and task summaries live beside the plan files at the phase root. A
|
|
199
|
+
// tasks/ subdir may still exist in flat-phase for auxiliary task-scoped
|
|
200
|
+
// artifacts (e.g. T01-VERIFY.json gate outputs) — its mere existence must
|
|
201
|
+
// NOT redirect summary resolution into tasks/ (#1208).
|
|
202
|
+
const isLegacySlice = basename(dirname(slicePath)) === "slices";
|
|
203
|
+
const summaryDir = isLegacySlice
|
|
204
|
+
? (resolveTasksDir(base, mid, sid) ?? slicePath)
|
|
205
|
+
: slicePath;
|
|
206
|
+
return join(summaryDir, buildTaskFileName(tid, "SUMMARY"));
|
|
198
207
|
}
|
|
199
208
|
case "complete-slice": {
|
|
200
209
|
return resolveSliceArtifactPath(base, mid, sid, "SUMMARY");
|
|
@@ -299,7 +308,7 @@ export function resolveSliceResearchLocation(basePath, mid, sid) {
|
|
|
299
308
|
if (canonicalPath && existsSync(canonicalPath)) {
|
|
300
309
|
return {
|
|
301
310
|
absolutePath: canonicalPath,
|
|
302
|
-
relativePath: relative(basePath, canonicalPath),
|
|
311
|
+
relativePath: relative(normalizeRealPath(basePath), canonicalPath),
|
|
303
312
|
};
|
|
304
313
|
}
|
|
305
314
|
return { absolutePath: null, relativePath: null };
|
|
@@ -7,7 +7,7 @@ import { loadFile } from "./files.js";
|
|
|
7
7
|
import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
|
|
8
8
|
import { resolveSliceFile, relSliceFile, } from "./paths.js";
|
|
9
9
|
import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
|
|
10
|
-
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
10
|
+
import { loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
11
11
|
import { pauseAuto } from "./auto.js";
|
|
12
12
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
13
13
|
import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
|
|
@@ -231,5 +231,10 @@ export async function dispatchDirectPhase(ctx, pi, phase, base, opts = {}) {
|
|
|
231
231
|
ctx.ui.notify("Session creation cancelled.", "warning");
|
|
232
232
|
return;
|
|
233
233
|
}
|
|
234
|
-
|
|
234
|
+
// Inject the configured response language into the dispatched prompt content
|
|
235
|
+
// — the new session's system prompt does not carry the preferences block, so
|
|
236
|
+
// the language setting would otherwise never reach the unit (#1210).
|
|
237
|
+
const languageDirective = renderLanguageDirectiveForPrompt(loadEffectiveGSDPreferences(dispatchBase)?.preferences);
|
|
238
|
+
const dispatchContent = languageDirective ? `${languageDirective}\n\n${prompt}` : prompt;
|
|
239
|
+
pi.sendMessage({ customType: "gsd-dispatch", content: dispatchContent, display: false }, { triggerTurn: true });
|
|
235
240
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Declarative auto-mode dispatch rules and dispatch resolver.
|
|
3
|
+
import { renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
3
4
|
import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
|
|
4
5
|
import { getUatBrowserToolSupportError } from "./uat-policy.js";
|
|
5
6
|
import { isDbAvailable, getMilestoneSlices, getMilestoneSliceSummaries, getClosedSliceIds, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, getSliceRunUatAssessment, } from "./gsd-db.js";
|
|
@@ -11,8 +12,9 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, readdir
|
|
|
11
12
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
12
13
|
import { dirname, join, sep } from "node:path";
|
|
13
14
|
import { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
|
|
14
|
-
import { buildDiscussMilestonePrompt, buildDiscussProjectPrompt, buildDiscussRequirementsPrompt, buildResearchDecisionPrompt, buildResearchProjectPrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildRefineSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, buildParallelResearchSlicesPrompt, checkNeedsReassessment,
|
|
15
|
-
import {
|
|
15
|
+
import { buildDiscussMilestonePrompt, buildDiscussProjectPrompt, buildDiscussRequirementsPrompt, buildResearchDecisionPrompt, buildResearchProjectPrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildRefineSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, buildParallelResearchSlicesPrompt, checkNeedsReassessment, loadRoadmapCompletedSliceCandidates, } from "./auto-prompts.js";
|
|
16
|
+
import { checkNeedsRunUat } from "./uat-dispatch.js";
|
|
17
|
+
import { normalizeModelFieldConfig, resolveModelWithFallbacksForUnit, resolveThinkingLevelForUnit } from "./preferences-models.js";
|
|
16
18
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
17
19
|
import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
|
|
18
20
|
import { getMilestonePipelineVariant } from "./milestone-scope-classifier.js";
|
|
@@ -141,12 +143,21 @@ export async function readUatGateVerdict(basePath, mid, sliceId) {
|
|
|
141
143
|
if (assessmentScope === "roadmap") {
|
|
142
144
|
return null;
|
|
143
145
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
// Backfilled assessments (#1258) are placeholders created during milestone
|
|
147
|
+
// validation for completed slices that never produced a real UAT ASSESSMENT
|
|
148
|
+
// (e.g. artifact-driven UAT that was never dispatched). Their fabricated
|
|
149
|
+
// verdict must not be treated as a genuine UAT sign-off — otherwise "never
|
|
150
|
+
// checked" is silently read as "passed". Skip the placeholder and fall
|
|
151
|
+
// through to the authoritative run-uat DB row (which stays null unless a
|
|
152
|
+
// real UAT was actually recorded).
|
|
153
|
+
if (assessmentScope !== BACKFILL_ASSESSMENT_SCOPE) {
|
|
154
|
+
const assessmentVerdict = extractVerdict(assessmentContent);
|
|
155
|
+
if (assessmentVerdict) {
|
|
156
|
+
return {
|
|
157
|
+
verdict: assessmentVerdict,
|
|
158
|
+
uatType: uatType ?? extractUatType(assessmentContent),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
150
161
|
}
|
|
151
162
|
}
|
|
152
163
|
if (uatContent) {
|
|
@@ -290,11 +301,20 @@ function stringField(row, key) {
|
|
|
290
301
|
function stripGsdPrefix(path) {
|
|
291
302
|
return path.startsWith(".gsd/") ? path.slice(".gsd/".length) : path;
|
|
292
303
|
}
|
|
293
|
-
|
|
304
|
+
// Scope marker for assessments fabricated by the milestone-validation backfill
|
|
305
|
+
// (#1258). It keeps these placeholders distinguishable from genuine `run-uat`
|
|
306
|
+
// sign-offs so `readUatGateVerdict` never mistakes "never checked" for "passed".
|
|
307
|
+
const BACKFILL_ASSESSMENT_SCOPE = "backfill";
|
|
308
|
+
function persistSliceAssessmentBackfill(assessmentRelPath, mid, sliceId, content, fabricated) {
|
|
294
309
|
const artifactPath = stripGsdPrefix(assessmentRelPath);
|
|
295
310
|
const existingAssessment = getAssessment(assessmentRelPath) ??
|
|
296
311
|
getAssessment(artifactPath);
|
|
297
|
-
|
|
312
|
+
// A newly fabricated placeholder is filed under a distinct scope; a pre-existing
|
|
313
|
+
// on-disk ASSESSMENT keeps its real scope (default `run-uat`) so genuine
|
|
314
|
+
// sign-offs are still honored.
|
|
315
|
+
const scope = fabricated
|
|
316
|
+
? BACKFILL_ASSESSMENT_SCOPE
|
|
317
|
+
: stringField(existingAssessment, "scope") ?? "run-uat";
|
|
298
318
|
const status = stringField(existingAssessment, "status") ??
|
|
299
319
|
extractVerdict(content)?.toLowerCase() ??
|
|
300
320
|
"unknown";
|
|
@@ -342,18 +362,24 @@ function backfillMissingAssessmentsFromSummaries(basePath, mid) {
|
|
|
342
362
|
"---",
|
|
343
363
|
`sliceId: ${sliceId}`,
|
|
344
364
|
"verdict: PASS",
|
|
365
|
+
// Distinguishing marker (#1258): this ASSESSMENT was fabricated to satisfy
|
|
366
|
+
// the per-slice artifact requirement, NOT produced by a real UAT run. It
|
|
367
|
+
// must not be read as a genuine UAT sign-off.
|
|
368
|
+
"backfilled: true",
|
|
369
|
+
"verified: false",
|
|
345
370
|
`date: ${now}`,
|
|
346
371
|
"---",
|
|
347
372
|
"",
|
|
348
373
|
`# Assessment — ${sliceId}`,
|
|
349
374
|
"",
|
|
350
375
|
"Auto-created during milestone validation because this completed slice had a SUMMARY but no ASSESSMENT artifact.",
|
|
376
|
+
"This is a placeholder: no UAT was executed for this slice, so its verdict is not an independent sign-off.",
|
|
351
377
|
"No additional reassessment changes were detected in this backfill step.",
|
|
352
378
|
"",
|
|
353
379
|
].join("\n") : readFileSync(assessmentPath, "utf-8");
|
|
354
380
|
if (isDbAvailable()) {
|
|
355
381
|
try {
|
|
356
|
-
persistSliceAssessmentBackfill(assessmentRelPath, mid, sliceId, content);
|
|
382
|
+
persistSliceAssessmentBackfill(assessmentRelPath, mid, sliceId, content, didCreateAssessment);
|
|
357
383
|
}
|
|
358
384
|
catch (err) {
|
|
359
385
|
logWarning("dispatch", `failed to backfill assessment DB rows for ${mid}/${sliceId}: ${err.message}`);
|
|
@@ -533,7 +559,7 @@ export const DISPATCH_RULES = [
|
|
|
533
559
|
{
|
|
534
560
|
name: "run-uat (post-completion)",
|
|
535
561
|
match: async ({ state, mid, basePath, prefs, sessionProvider, sessionAuthMode, activeTools, registeredTools, sessionBaseUrl, }) => {
|
|
536
|
-
const needsRunUat = await checkNeedsRunUat(basePath, mid,
|
|
562
|
+
const needsRunUat = await checkNeedsRunUat(basePath, mid, prefs, await loadRoadmapCompletedSliceCandidates(basePath, mid));
|
|
537
563
|
if (!needsRunUat)
|
|
538
564
|
return null;
|
|
539
565
|
const { sliceId, uatType } = needsRunUat;
|
|
@@ -1167,8 +1193,15 @@ export const DISPATCH_RULES = [
|
|
|
1167
1193
|
if (resolveSliceFile(basePath, mid, sid, "REACTIVE-BLOCKER"))
|
|
1168
1194
|
return null;
|
|
1169
1195
|
const maxParallel = reactiveConfig?.max_parallel ?? 2;
|
|
1170
|
-
|
|
1171
|
-
|
|
1196
|
+
// `subagent_model` accepts the phase-bucket object form (#1229); honor the
|
|
1197
|
+
// full primary→fallbacks chain in the dispatch prompt (the reactive
|
|
1198
|
+
// subagent model is embedded there rather than set as the session model).
|
|
1199
|
+
const subagentModelConfig = normalizeModelFieldConfig(reactiveConfig?.subagent_model)
|
|
1200
|
+
?? resolveModelWithFallbacksForUnit("subagent");
|
|
1201
|
+
const subagentModel = subagentModelConfig?.primary;
|
|
1202
|
+
// Prefer the per-field `thinking` carried on `reactive_execution.subagent_model`'s
|
|
1203
|
+
// object form over the phase-bucket `subagent` level (#1269).
|
|
1204
|
+
const subagentThinking = subagentModelConfig?.thinking ?? resolveThinkingLevelForUnit("subagent");
|
|
1172
1205
|
// Default-on safety threshold: only activate reactive dispatch when at
|
|
1173
1206
|
// least N tasks are ready. Users who explicitly enabled reactive_execution
|
|
1174
1207
|
// keep the legacy threshold of 2 (matches the prior "any parallelism is
|
|
@@ -1228,7 +1261,13 @@ export const DISPATCH_RULES = [
|
|
|
1228
1261
|
action: "dispatch",
|
|
1229
1262
|
unitType: "reactive-execute",
|
|
1230
1263
|
unitId: `${mid}/${sid}/reactive+${batchSuffix}`,
|
|
1231
|
-
prompt: await buildReactiveExecutePrompt(mid, midTitle, sid, sTitle, selected, basePath, subagentModel, {
|
|
1264
|
+
prompt: await buildReactiveExecutePrompt(mid, midTitle, sid, sTitle, selected, basePath, subagentModel, {
|
|
1265
|
+
sessionContextWindow,
|
|
1266
|
+
modelRegistry,
|
|
1267
|
+
sessionProvider,
|
|
1268
|
+
subagentThinking,
|
|
1269
|
+
subagentModelFallbacks: subagentModelConfig?.fallbacks,
|
|
1270
|
+
}),
|
|
1232
1271
|
};
|
|
1233
1272
|
}
|
|
1234
1273
|
catch (err) {
|
|
@@ -1500,6 +1539,19 @@ export const DISPATCH_RULES = [
|
|
|
1500
1539
|
},
|
|
1501
1540
|
];
|
|
1502
1541
|
import { getRegistry } from "./rule-registry.js";
|
|
1542
|
+
/**
|
|
1543
|
+
* Prepend the configured response-language directive to a dispatched unit
|
|
1544
|
+
* prompt so auto-execution units respond in the language set in PREFERENCES.md
|
|
1545
|
+
* (#1210). No-op for non-dispatch actions or when no language is configured.
|
|
1546
|
+
*/
|
|
1547
|
+
function applyLanguageDirectiveToDispatch(action, prefs) {
|
|
1548
|
+
if (action.action !== "dispatch" || !action.prompt)
|
|
1549
|
+
return action;
|
|
1550
|
+
const directive = renderLanguageDirectiveForPrompt(prefs);
|
|
1551
|
+
if (!directive)
|
|
1552
|
+
return action;
|
|
1553
|
+
return { ...action, prompt: `${directive}\n\n${action.prompt}` };
|
|
1554
|
+
}
|
|
1503
1555
|
// ─── Resolver ─────────────────────────────────────────────────────────────
|
|
1504
1556
|
/**
|
|
1505
1557
|
* Evaluate dispatch rules in order. Returns the first matching action,
|
|
@@ -1551,7 +1603,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1551
1603
|
level: "error",
|
|
1552
1604
|
};
|
|
1553
1605
|
}
|
|
1554
|
-
return action;
|
|
1606
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1555
1607
|
}
|
|
1556
1608
|
catch (err) {
|
|
1557
1609
|
// Registry not initialized — fall back to inline loop
|
|
@@ -1572,7 +1624,7 @@ export async function resolveDispatch(ctx) {
|
|
|
1572
1624
|
matchedRule: rule.name,
|
|
1573
1625
|
};
|
|
1574
1626
|
}
|
|
1575
|
-
return action;
|
|
1627
|
+
return applyLanguageDirectiveToDispatch(action, ctx.prefs);
|
|
1576
1628
|
}
|
|
1577
1629
|
}
|
|
1578
1630
|
// No rule matched — unhandled phase.
|
|
@@ -219,10 +219,37 @@ function buildModelPolicyBlockReasons(policyDenyReasons, availableModels, routin
|
|
|
219
219
|
reason: `configured model(s) did not resolve against policy-eligible registry [${eligibleSummary}]`,
|
|
220
220
|
}];
|
|
221
221
|
}
|
|
222
|
-
function isModelUnavailable(basePath, provider, id) {
|
|
222
|
+
export function isModelUnavailable(basePath, provider, id) {
|
|
223
223
|
return isModelBlocked(basePath, provider, id) ||
|
|
224
224
|
isModelTemporarilyUnavailable(basePath, provider, id);
|
|
225
225
|
}
|
|
226
|
+
/** Apply `auto_supervisor.model`, walking configured fallbacks on unavailability (#1229). */
|
|
227
|
+
export async function applySupervisorModelIfConfigured(ctx, pi, basePath) {
|
|
228
|
+
const modelConfig = resolveModelWithFallbacksForUnit("supervisor", basePath);
|
|
229
|
+
if (!modelConfig)
|
|
230
|
+
return;
|
|
231
|
+
const availableModels = ctx.modelRegistry.getAvailable();
|
|
232
|
+
for (const candidate of [modelConfig.primary, ...modelConfig.fallbacks]) {
|
|
233
|
+
const match = resolveModelId(candidate, availableModels, ctx.model?.provider);
|
|
234
|
+
if (!match)
|
|
235
|
+
continue;
|
|
236
|
+
if (isModelUnavailable(basePath, match.provider, match.id))
|
|
237
|
+
continue;
|
|
238
|
+
try {
|
|
239
|
+
if (await pi.setModel(match, { persist: false })) {
|
|
240
|
+
// Prefer the per-field `thinking` from `auto_supervisor.model`'s object
|
|
241
|
+
// form over the session level so a configured supervisor level actually
|
|
242
|
+
// applies (#1269).
|
|
243
|
+
applyThinkingLevelForModel(pi, modelConfig.thinking ?? pi.getThinkingLevel(), match, ctx);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
// Non-fatal — try the next fallback.
|
|
249
|
+
logWarning("dispatch", `supervisor model set failed for ${candidate}: ${err instanceof Error ? err.message : String(err)}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
226
253
|
function restoreToolBaseline(pi) {
|
|
227
254
|
const key = pi;
|
|
228
255
|
const baseline = TOOL_BASELINE.get(key);
|
|
@@ -17,7 +17,7 @@ import { logWarning, logError } from "./workflow-logger.js";
|
|
|
17
17
|
import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
18
18
|
import { loadPrompt } from "./prompt-loader.js";
|
|
19
19
|
import { isAwaitingUserInput } from "./consent-question.js";
|
|
20
|
-
import { resolveSliceFile, resolveSlicePath, relSlicePath, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, resolveFile, relMilestoneFile, relSliceFile, relTaskFile, } from "./paths.js";
|
|
20
|
+
import { resolveSliceFile, resolveSlicePath, relSlicePath, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, resolveFile, relMilestoneFile, relSliceFile, relTaskFile, normalizeRealPath, } from "./paths.js";
|
|
21
21
|
import { invalidateAllCaches } from "./cache.js";
|
|
22
22
|
import { rebuildState } from "./doctor.js";
|
|
23
23
|
import { parseUnitId } from "./unit-id.js";
|
|
@@ -770,7 +770,7 @@ function describeArtifactVerificationFailure(unitType, unitId, basePath, agentEn
|
|
|
770
770
|
if (!artifactPath) {
|
|
771
771
|
return `Artifact verification failed: ${unitType} "${unitId}" has no resolvable artifact path.`;
|
|
772
772
|
}
|
|
773
|
-
const relPath = relative(basePath, artifactPath);
|
|
773
|
+
const relPath = relative(normalizeRealPath(basePath), artifactPath);
|
|
774
774
|
if (!existsSync(artifactPath)) {
|
|
775
775
|
const completionToolHint = unitType === "execute-task" && !hasTaskCompletionToolCall(agentEndMessages)
|
|
776
776
|
? " No completion tool call detected (`gsd_task_complete`/alias)."
|
|
@@ -1987,7 +1987,8 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1987
1987
|
persistHookState(s.basePath);
|
|
1988
1988
|
const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
|
|
1989
1989
|
const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
|
|
1990
|
-
const message = `Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}
|
|
1990
|
+
const message = `Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId} ` +
|
|
1991
|
+
`(detected on completion of ${s.currentUnit.type} ${s.currentUnit.id}):` +
|
|
1991
1992
|
`${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
|
|
1992
1993
|
ctx.ui.notify(message, "warning");
|
|
1993
1994
|
await pauseAuto(ctx, pi);
|