@opengsd/gsd-pi 1.1.1-dev.a5a2de8 → 1.1.1-dev.b2556262
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/headless-recover.js +56 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +18 -2
- package/dist/resources/extensions/browser-tools/engine/selection.js +1 -1
- package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/dist/resources/extensions/browser-tools/index.js +68 -24
- package/dist/resources/extensions/browser-tools/state.js +12 -0
- package/dist/resources/extensions/browser-tools/tools/session.js +3 -2
- package/dist/resources/extensions/browser-tools/utils.js +3 -3
- package/dist/resources/extensions/browser-tools/web-app-detect.js +52 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +87 -12
- package/dist/resources/extensions/gsd/auto/session.js +22 -1
- package/dist/resources/extensions/gsd/auto/workflow-kernel.js +1 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +81 -13
- package/dist/resources/extensions/gsd/auto-model-selection.js +154 -9
- package/dist/resources/extensions/gsd/auto-post-unit.js +19 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +26 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -2
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +1 -1
- package/dist/resources/extensions/gsd/auto-timers.js +24 -10
- package/dist/resources/extensions/gsd/auto.js +40 -15
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +192 -77
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
- package/dist/resources/extensions/gsd/closeout-wizard.js +32 -9
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -9
- package/dist/resources/extensions/gsd/commands-maintenance.js +93 -15
- package/dist/resources/extensions/gsd/commands-mcp-status.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +2 -2
- package/dist/resources/extensions/gsd/config-overlay.js +1 -0
- package/dist/resources/extensions/gsd/context-masker.js +129 -5
- package/dist/resources/extensions/gsd/db-writer.js +35 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/dist/resources/extensions/gsd/gsd-db.js +480 -172
- package/dist/resources/extensions/gsd/guided-flow.js +4 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +37 -53
- package/dist/resources/extensions/gsd/md-importer.js +38 -3
- package/dist/resources/extensions/gsd/migration-auto-check.js +126 -31
- package/dist/resources/extensions/gsd/parsers-legacy.js +23 -0
- package/dist/resources/extensions/gsd/planner-handoff.js +98 -0
- package/dist/resources/extensions/gsd/planning-path-scope.js +22 -4
- package/dist/resources/extensions/gsd/pre-execution-checks.js +10 -2
- package/dist/resources/extensions/gsd/preferences-models.js +111 -43
- package/dist/resources/extensions/gsd/preferences-types.js +13 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +68 -3
- package/dist/resources/extensions/gsd/preferences.js +4 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +5 -1
- package/dist/resources/extensions/gsd/safety/content-validator.js +6 -4
- package/dist/resources/extensions/gsd/skill-manifest.js +12 -0
- package/dist/resources/extensions/gsd/source-observations.js +306 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +15 -8
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +33 -5
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +34 -13
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +39 -14
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +4 -4
- package/dist/resources/extensions/gsd/state.js +7 -3
- package/dist/resources/extensions/gsd/tool-contract.js +15 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +24 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +28 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +42 -11
- package/dist/resources/extensions/gsd/tools/plan-task.js +7 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +62 -406
- package/dist/resources/extensions/gsd/uat-policy.js +130 -0
- package/dist/resources/extensions/gsd/uat-run.js +414 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +3 -4
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +38 -14
- package/dist/resources/extensions/gsd/verdict-parser.js +3 -8
- package/dist/resources/extensions/gsd/workflow-manifest.js +132 -5
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +8 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +26 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +96 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +18 -17
- package/dist/resources/extensions/shared/gsd-browser-cli.js +6 -0
- package/dist/resources/extensions/subagent/agents.js +1 -0
- package/dist/resources/extensions/subagent/index.js +27 -12
- package/dist/resources/extensions/subagent/launch.js +7 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- 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 +6 -6
- 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/web/standalone/node_modules/@gsd/native/dist/native.js +22 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +4 -4
- 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/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +21 -23
- package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +1 -0
- 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 +66 -12
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +18 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +16 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/dist/native.js +22 -0
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +30 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +174 -29
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +178 -54
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +8 -1
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js +1 -1
- package/packages/pi-coding-agent/dist/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/utils.d.ts +11 -0
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +119 -6
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/themes.js +1 -1
- package/pkg/dist/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install/handoff.js +16 -3
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +21 -2
- package/src/resources/extensions/browser-tools/engine/selection.ts +1 -1
- package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
- package/src/resources/extensions/browser-tools/index.ts +75 -27
- package/src/resources/extensions/browser-tools/state.ts +13 -0
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +2 -2
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +57 -0
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +37 -0
- package/src/resources/extensions/browser-tools/tests/web-app-detect.test.mjs +68 -0
- package/src/resources/extensions/browser-tools/tools/session.ts +4 -2
- package/src/resources/extensions/browser-tools/utils.ts +3 -3
- package/src/resources/extensions/browser-tools/web-app-detect.ts +63 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +89 -15
- package/src/resources/extensions/gsd/auto/session.ts +24 -1
- package/src/resources/extensions/gsd/auto/workflow-kernel.ts +1 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +117 -12
- package/src/resources/extensions/gsd/auto-model-selection.ts +190 -12
- package/src/resources/extensions/gsd/auto-post-unit.ts +20 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +25 -22
- package/src/resources/extensions/gsd/auto-recovery.ts +22 -3
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +1 -1
- package/src/resources/extensions/gsd/auto-timers.ts +25 -9
- package/src/resources/extensions/gsd/auto.ts +41 -14
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +250 -78
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
- package/src/resources/extensions/gsd/closeout-wizard.ts +47 -13
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +2 -17
- package/src/resources/extensions/gsd/commands-maintenance.ts +124 -13
- package/src/resources/extensions/gsd/commands-mcp-status.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +2 -2
- package/src/resources/extensions/gsd/config-overlay.ts +1 -0
- package/src/resources/extensions/gsd/context-masker.ts +152 -5
- package/src/resources/extensions/gsd/db-writer.ts +38 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +50 -1
- package/src/resources/extensions/gsd/gsd-db.ts +564 -186
- package/src/resources/extensions/gsd/guided-flow.ts +4 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +44 -66
- package/src/resources/extensions/gsd/md-importer.ts +49 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +154 -34
- package/src/resources/extensions/gsd/parsers-legacy.ts +20 -0
- package/src/resources/extensions/gsd/planner-handoff.ts +149 -0
- package/src/resources/extensions/gsd/planning-path-scope.ts +22 -4
- package/src/resources/extensions/gsd/pre-execution-checks.ts +9 -2
- package/src/resources/extensions/gsd/preferences-models.ts +113 -43
- package/src/resources/extensions/gsd/preferences-types.ts +47 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +76 -2
- package/src/resources/extensions/gsd/preferences.ts +5 -0
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +2 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +6 -1
- package/src/resources/extensions/gsd/safety/content-validator.ts +8 -5
- package/src/resources/extensions/gsd/skill-manifest.ts +12 -0
- package/src/resources/extensions/gsd/source-observations.ts +402 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +20 -8
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +44 -5
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +39 -11
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +45 -15
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +4 -4
- package/src/resources/extensions/gsd/state.ts +7 -4
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +66 -4
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +299 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +75 -3
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +4 -0
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/closeout-wizard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +118 -0
- package/src/resources/extensions/gsd/tests/content-validator.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +1 -11
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +62 -1
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +99 -2
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/planner-handoff.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +162 -18
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/source-observations.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +76 -21
- package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +203 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +170 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +306 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +77 -10
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +260 -5
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +511 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +44 -0
- package/src/resources/extensions/gsd/tool-contract.ts +29 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +41 -6
- package/src/resources/extensions/gsd/tools/complete-slice.ts +29 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +54 -12
- package/src/resources/extensions/gsd/tools/plan-task.ts +8 -1
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +71 -489
- package/src/resources/extensions/gsd/types.ts +1 -0
- package/src/resources/extensions/gsd/uat-policy.ts +191 -0
- package/src/resources/extensions/gsd/uat-run.ts +550 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +3 -4
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +38 -14
- package/src/resources/extensions/gsd/verdict-parser.ts +3 -10
- package/src/resources/extensions/gsd/workflow-manifest.ts +193 -7
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -3
- package/src/resources/extensions/gsd/workflow-projections.ts +9 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +32 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +103 -0
- package/src/resources/extensions/gsd/worktree-state-projection.ts +22 -22
- package/src/resources/extensions/shared/gsd-browser-cli.ts +6 -0
- package/src/resources/extensions/shared/tests/format-utils.test.ts +8 -3
- package/src/resources/extensions/subagent/agents.ts +4 -0
- package/src/resources/extensions/subagent/index.ts +28 -3
- package/src/resources/extensions/subagent/launch.ts +8 -0
- package/src/resources/extensions/subagent/tests/model-override.test.ts +31 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{9y3LeeR2uGr2yRj9RjY3D → tJOKQbQRO-9MiFDO8DIDS}/_ssgManifest.js +0 -0
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
} from "./auto-tool-tracking.js";
|
|
108
108
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
109
109
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
110
|
-
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
110
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline, getToolBaselineSnapshot } from "./auto-model-selection.js";
|
|
111
111
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
112
112
|
import {
|
|
113
113
|
checkPostUnitHooks,
|
|
@@ -542,8 +542,26 @@ function handlePausedSessionResumeRecovery(
|
|
|
542
542
|
): { skippedReplay: boolean } {
|
|
543
543
|
if (!state.pausedSessionFile) return { skippedReplay: false };
|
|
544
544
|
|
|
545
|
-
const pausedRecoveryUnitType = state.currentUnit?.type ?? state.pausedUnitType ??
|
|
546
|
-
const pausedRecoveryUnitId = state.currentUnit?.id ?? state.pausedUnitId ??
|
|
545
|
+
const pausedRecoveryUnitType = state.currentUnit?.type ?? state.pausedUnitType ?? null;
|
|
546
|
+
const pausedRecoveryUnitId = state.currentUnit?.id ?? state.pausedUnitId ?? null;
|
|
547
|
+
|
|
548
|
+
// When the paused-session metadata never captured the unit identity (the
|
|
549
|
+
// pause happened between units, or the worker died before currentUnit was
|
|
550
|
+
// set), we have nothing to verify against and nothing correct to target. A
|
|
551
|
+
// replay synthesized with an "unknown" unit re-injects an unbounded,
|
|
552
|
+
// mis-identified tool-call blob into the fresh resume context — exactly the
|
|
553
|
+
// thrash that turns one stuck unit into several. Disk state has already been
|
|
554
|
+
// rebuilt (rebuildState + doctor) before this runs, so skip the replay and
|
|
555
|
+
// let the normal dispatcher recompute the next unit from disk.
|
|
556
|
+
if (!pausedRecoveryUnitType || !pausedRecoveryUnitId) {
|
|
557
|
+
state.pausedSessionFile = null;
|
|
558
|
+
state.pausedUnitType = null;
|
|
559
|
+
state.pausedUnitId = null;
|
|
560
|
+
state.pendingCrashRecovery = null;
|
|
561
|
+
notify("Paused session had no recorded unit identity. Skipping tool-call replay and resuming from disk state.");
|
|
562
|
+
return { skippedReplay: true };
|
|
563
|
+
}
|
|
564
|
+
|
|
547
565
|
const completedPausedUnit = verifyExpectedArtifact(
|
|
548
566
|
pausedRecoveryUnitType,
|
|
549
567
|
pausedRecoveryUnitId,
|
|
@@ -1228,7 +1246,7 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1228
1246
|
const preserveStepSurface = s.preserveStepSurfaceAfterLoopExit;
|
|
1229
1247
|
const preserveCompletionSurface = s.completionStopInProgress;
|
|
1230
1248
|
const preservePausedSurface = s.paused;
|
|
1231
|
-
s.
|
|
1249
|
+
s.clearCurrentUnit();
|
|
1232
1250
|
s.active = false;
|
|
1233
1251
|
deactivateGSD();
|
|
1234
1252
|
clearUnitTimeout();
|
|
@@ -1251,11 +1269,14 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1251
1269
|
// A transient provider-error pause intentionally leaves the paused badge
|
|
1252
1270
|
// visible so the user still has a resumable auto-mode signal on screen.
|
|
1253
1271
|
if (!s.paused) {
|
|
1254
|
-
if (
|
|
1255
|
-
s.preserveStepSurfaceAfterLoopExit = false;
|
|
1256
|
-
} else if (preserveCompletionSurface) {
|
|
1272
|
+
if (preserveCompletionSurface) {
|
|
1257
1273
|
ctx.ui.setStatus("gsd-auto", undefined);
|
|
1258
1274
|
s.completionStopInProgress = false;
|
|
1275
|
+
if (preserveStepSurface) {
|
|
1276
|
+
s.preserveStepSurfaceAfterLoopExit = false;
|
|
1277
|
+
}
|
|
1278
|
+
} else if (preserveStepSurface) {
|
|
1279
|
+
s.preserveStepSurfaceAfterLoopExit = false;
|
|
1259
1280
|
} else {
|
|
1260
1281
|
ctx.ui.setStatus("gsd-auto", undefined);
|
|
1261
1282
|
ctx.ui.setWidget("gsd-progress", undefined);
|
|
@@ -1969,7 +1990,7 @@ export async function pauseAuto(
|
|
|
1969
1990
|
// Non-fatal — best-effort closeout on pause
|
|
1970
1991
|
logWarning("engine", `unit closeout on pause failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
|
1971
1992
|
}
|
|
1972
|
-
s.
|
|
1993
|
+
s.clearCurrentUnit();
|
|
1973
1994
|
}
|
|
1974
1995
|
|
|
1975
1996
|
// Keep STATE.md aligned with the DB-backed state before releasing pause state.
|
|
@@ -2154,7 +2175,10 @@ export function createWiredDispatchAdapter(
|
|
|
2154
2175
|
sessionProvider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
|
|
2155
2176
|
? ctx.modelRegistry.getProviderAuthMode(sessionProvider)
|
|
2156
2177
|
: undefined;
|
|
2157
|
-
|
|
2178
|
+
// Use baseline snapshot — same reason as phases.ts:runDispatch: the live
|
|
2179
|
+
// active set may be narrowed by the prior unit before selectAndApplyModel
|
|
2180
|
+
// restores it, causing false transport-preflight failures (#477 follow-up).
|
|
2181
|
+
const activeTools = getToolBaselineSnapshot(pi);
|
|
2158
2182
|
// Mirrors runDispatch: deep-planning keeps approval gates in plain chat
|
|
2159
2183
|
// because structured questions can be cancelled outside the chat turn on
|
|
2160
2184
|
// some transports.
|
|
@@ -2201,6 +2225,9 @@ export function createWiredDispatchAdapter(
|
|
|
2201
2225
|
sessionContextWindow,
|
|
2202
2226
|
sessionProvider,
|
|
2203
2227
|
modelRegistry,
|
|
2228
|
+
activeTools,
|
|
2229
|
+
sessionAuthMode: authMode,
|
|
2230
|
+
sessionBaseUrl: ctx.model?.baseUrl,
|
|
2204
2231
|
});
|
|
2205
2232
|
|
|
2206
2233
|
if (action.action === "stop") {
|
|
@@ -3284,7 +3311,7 @@ export async function dispatchHookUnit(
|
|
|
3284
3311
|
s.stepMode = true;
|
|
3285
3312
|
s.cmdCtx = ctx as ExtensionCommandContext;
|
|
3286
3313
|
s.autoStartTime = Date.now();
|
|
3287
|
-
s.
|
|
3314
|
+
s.clearCurrentUnit();
|
|
3288
3315
|
s.pendingQuickTasks = [];
|
|
3289
3316
|
}
|
|
3290
3317
|
|
|
@@ -3301,12 +3328,12 @@ export async function dispatchHookUnit(
|
|
|
3301
3328
|
const hookUnitType = `hook/${hookName}`;
|
|
3302
3329
|
const hookStartedAt = Date.now();
|
|
3303
3330
|
|
|
3304
|
-
s.
|
|
3331
|
+
s.setCurrentUnit({
|
|
3305
3332
|
type: triggerUnitType,
|
|
3306
3333
|
id: triggerUnitId,
|
|
3307
3334
|
startedAt: hookStartedAt,
|
|
3308
3335
|
workspaceRoot: s.basePath,
|
|
3309
|
-
};
|
|
3336
|
+
});
|
|
3310
3337
|
|
|
3311
3338
|
const result = await s.cmdCtx!.newSession({ workspaceRoot: s.basePath });
|
|
3312
3339
|
if (result.cancelled) {
|
|
@@ -3314,12 +3341,12 @@ export async function dispatchHookUnit(
|
|
|
3314
3341
|
return false;
|
|
3315
3342
|
}
|
|
3316
3343
|
|
|
3317
|
-
s.
|
|
3344
|
+
s.setCurrentUnit({
|
|
3318
3345
|
type: hookUnitType,
|
|
3319
3346
|
id: triggerUnitId,
|
|
3320
3347
|
startedAt: hookStartedAt,
|
|
3321
3348
|
workspaceRoot: s.basePath,
|
|
3322
|
-
};
|
|
3349
|
+
});
|
|
3323
3350
|
|
|
3324
3351
|
if (hookModel) {
|
|
3325
3352
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
@@ -699,7 +699,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
699
699
|
files: Type.Array(Type.String(), { description: "Array<string> of files likely touched; pass [\"path\"] or [], never a single string" }),
|
|
700
700
|
verify: Type.String({ description: "Verification command or block" }),
|
|
701
701
|
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
702
|
-
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of
|
|
702
|
+
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
|
|
703
703
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
704
704
|
}), { description: "Planned tasks for the slice" }),
|
|
705
705
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
@@ -779,7 +779,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
779
779
|
files: Type.Array(Type.String(), { description: "Array<string> of files likely touched; pass [\"path\"] or [], never a single string" }),
|
|
780
780
|
verify: Type.String({ description: "Verification command or block" }),
|
|
781
781
|
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
782
|
-
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of
|
|
782
|
+
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
|
|
783
783
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
784
784
|
// Single-writer v3 audit trail (Stream 2): caller-provided actor identity + causation.
|
|
785
785
|
actorName: Type.Optional(Type.String({ description: "Caller-provided actor identity for the audit trail (e.g. 'executor-01', 'gsd-orchestrator')" })),
|
|
@@ -1160,7 +1160,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1160
1160
|
files: Type.Array(Type.String(), { description: "Files likely touched" }),
|
|
1161
1161
|
verify: Type.String({ description: "Verification command or block" }),
|
|
1162
1162
|
inputs: Type.Array(Type.String(), { description: "Input files or references" }),
|
|
1163
|
-
expectedOutput: Type.Array(Type.String(), { description: "
|
|
1163
|
+
expectedOutput: Type.Array(Type.String(), { description: "Files this task creates or overwrites" }),
|
|
1164
1164
|
}),
|
|
1165
1165
|
{ description: "Tasks to upsert (update existing or insert new)" },
|
|
1166
1166
|
),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Registers GSD extension runtime hooks and token-saving tool policies.
|
|
3
3
|
|
|
4
|
-
import { existsSync } from "node:fs";
|
|
4
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
|
|
@@ -12,12 +12,22 @@ import { ALWAYS_PRESERVED_SHIM_TOOL_NAMES } from "@gsd/pi-ai";
|
|
|
12
12
|
import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-extension-api.js";
|
|
13
13
|
import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
|
|
14
14
|
|
|
15
|
-
import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
15
|
+
import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
16
16
|
import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer, isMilestoneDepthVerified, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
17
17
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
18
18
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
19
19
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
clearToolInvocationError,
|
|
22
|
+
getAutoRuntimeSnapshot,
|
|
23
|
+
getSourceObservationStore,
|
|
24
|
+
isAutoActive,
|
|
25
|
+
isAutoCompletionStopInProgress,
|
|
26
|
+
isAutoPaused,
|
|
27
|
+
markToolEnd,
|
|
28
|
+
markToolStart,
|
|
29
|
+
recordToolInvocationError,
|
|
30
|
+
} from "../auto-runtime-state.js";
|
|
21
31
|
|
|
22
32
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
23
33
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
@@ -39,6 +49,7 @@ import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-rec
|
|
|
39
49
|
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
40
50
|
import { filterToolsForProvider } from "../model-router.js";
|
|
41
51
|
import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
52
|
+
import { injectSourceContextBlockIntoPayload, supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
42
53
|
|
|
43
54
|
let approvalQuestionAbortInFlight = false;
|
|
44
55
|
|
|
@@ -259,7 +270,19 @@ export function buildRunUatGsdToolSet(
|
|
|
259
270
|
...RUN_UAT_BROWSER_TOOL_NAMES,
|
|
260
271
|
],
|
|
261
272
|
);
|
|
262
|
-
|
|
273
|
+
const resolved = [...new Set(scoped)];
|
|
274
|
+
|
|
275
|
+
const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter(
|
|
276
|
+
(tool) => !resolved.some((name) => name === tool || (name.startsWith("mcp__") && name.endsWith(`__${tool}`))),
|
|
277
|
+
);
|
|
278
|
+
if (unresolved.length > 0) {
|
|
279
|
+
safetyLogWarning(
|
|
280
|
+
"bootstrap",
|
|
281
|
+
`buildRunUatGsdToolSet: required run-uat workflow tool(s) not found in active/registered surface: ${unresolved.join(", ")}. Session may lack gsd-workflow MCP connection.`,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return resolved;
|
|
263
286
|
}
|
|
264
287
|
|
|
265
288
|
export function buildMinimalGsdWorkflowToolSet(
|
|
@@ -462,6 +485,55 @@ function contextBasePath(ctx?: { cwd?: string }): string {
|
|
|
462
485
|
return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
|
|
463
486
|
}
|
|
464
487
|
|
|
488
|
+
function beginSourceObservationStoreForCurrentUnit(
|
|
489
|
+
ctx?: { cwd?: string },
|
|
490
|
+
): ReturnType<typeof getSourceObservationStore> | null {
|
|
491
|
+
if (!isAutoActive()) return null;
|
|
492
|
+
const dash = getAutoRuntimeSnapshot();
|
|
493
|
+
if (!dash.currentUnit) return null;
|
|
494
|
+
if (!supportsSourceObservationsForUnit(dash.currentUnit.type)) return null;
|
|
495
|
+
|
|
496
|
+
const store = getSourceObservationStore();
|
|
497
|
+
store.beginUnit({
|
|
498
|
+
unitType: dash.currentUnit.type,
|
|
499
|
+
unitId: dash.currentUnit.id,
|
|
500
|
+
startedAt: dash.currentUnit.startedAt,
|
|
501
|
+
basePath: dash.currentUnit.workspaceRoot ?? (dash.basePath || contextBasePath(ctx)),
|
|
502
|
+
});
|
|
503
|
+
return store;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function refreshSourceObservationAfterMutation(
|
|
507
|
+
canonicalName: string,
|
|
508
|
+
input: unknown,
|
|
509
|
+
ctx?: { cwd?: string },
|
|
510
|
+
): void {
|
|
511
|
+
if (canonicalName !== "edit" && canonicalName !== "write") return;
|
|
512
|
+
if (!input || typeof input !== "object") return;
|
|
513
|
+
|
|
514
|
+
const store = beginSourceObservationStoreForCurrentUnit(ctx);
|
|
515
|
+
if (!store) return;
|
|
516
|
+
store.observeMutation(input as { path?: unknown; file_path?: unknown });
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function clearSourceObservationsAfterShell(
|
|
520
|
+
canonicalName: string,
|
|
521
|
+
): void {
|
|
522
|
+
if (!isAutoActive()) return;
|
|
523
|
+
if (!isShellExecutionTool(canonicalName)) return;
|
|
524
|
+
const dash = getAutoRuntimeSnapshot();
|
|
525
|
+
if (!dash.currentUnit || !supportsSourceObservationsForUnit(dash.currentUnit.type)) return;
|
|
526
|
+
getSourceObservationStore().clear();
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function isShellExecutionTool(canonicalName: string): boolean {
|
|
530
|
+
return canonicalName === "bash" ||
|
|
531
|
+
canonicalName === "bg_shell" ||
|
|
532
|
+
canonicalName === "async_bash" ||
|
|
533
|
+
canonicalName === "shell" ||
|
|
534
|
+
canonicalName === "powershell";
|
|
535
|
+
}
|
|
536
|
+
|
|
465
537
|
function activateDeferredApprovalGate(basePath: string): void {
|
|
466
538
|
if (deferredApprovalGate?.basePath !== basePath) return;
|
|
467
539
|
setPendingGate(deferredApprovalGate.gateId, basePath);
|
|
@@ -485,6 +557,109 @@ function isContextDraftSummarySave(toolName: string, input: unknown): boolean {
|
|
|
485
557
|
return (input as { artifact_type?: unknown }).artifact_type === "CONTEXT-DRAFT";
|
|
486
558
|
}
|
|
487
559
|
|
|
560
|
+
type StructuredQuestion = {
|
|
561
|
+
id?: string;
|
|
562
|
+
header?: string;
|
|
563
|
+
question?: string;
|
|
564
|
+
options?: Array<{ label?: string; description?: string }>;
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
type StructuredAnswer = {
|
|
568
|
+
selected?: unknown;
|
|
569
|
+
notes?: unknown;
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
function selectedAnswerLabel(selected: unknown): string {
|
|
573
|
+
if (Array.isArray(selected)) return selected.map(String).join(", ");
|
|
574
|
+
if (selected == null) return "";
|
|
575
|
+
return String(selected);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function formatQuestionExchange(
|
|
579
|
+
questions: StructuredQuestion[],
|
|
580
|
+
answers: Record<string, StructuredAnswer> | undefined,
|
|
581
|
+
): string {
|
|
582
|
+
const lines: string[] = [];
|
|
583
|
+
for (const question of questions) {
|
|
584
|
+
lines.push(`### ${question.header ?? "Question"}`, "", question.question ?? "");
|
|
585
|
+
if (Array.isArray(question.options)) {
|
|
586
|
+
lines.push("");
|
|
587
|
+
for (const opt of question.options) {
|
|
588
|
+
lines.push(`- **${opt.label ?? ""}** — ${opt.description ?? ""}`);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const answer = question.id ? answers?.[question.id] : undefined;
|
|
593
|
+
if (answer) {
|
|
594
|
+
lines.push("");
|
|
595
|
+
const selected = selectedAnswerLabel(answer.selected);
|
|
596
|
+
if (selected) lines.push(`**Selected:** ${selected}`);
|
|
597
|
+
if (answer.notes) lines.push(`**Notes:** ${String(answer.notes)}`);
|
|
598
|
+
}
|
|
599
|
+
lines.push("");
|
|
600
|
+
}
|
|
601
|
+
return lines.join("\n");
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
async function ensureMilestoneShell(basePath: string, milestoneId: string): Promise<string> {
|
|
605
|
+
const milestoneDir = resolveMilestonePath(basePath, milestoneId)
|
|
606
|
+
?? join(milestonesDir(basePath), milestoneId);
|
|
607
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
608
|
+
clearPathCache();
|
|
609
|
+
|
|
610
|
+
try {
|
|
611
|
+
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
612
|
+
if (await ensureDbOpen(basePath)) {
|
|
613
|
+
const { getMilestone, insertMilestone } = await import("../gsd-db.js");
|
|
614
|
+
if (!getMilestone(milestoneId)) {
|
|
615
|
+
insertMilestone({
|
|
616
|
+
id: milestoneId,
|
|
617
|
+
title: `New milestone ${milestoneId}`,
|
|
618
|
+
status: "queued",
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
} catch (err) {
|
|
623
|
+
safetyLogWarning("guided", `failed to persist milestone shell for ${milestoneId}: ${(err as Error).message}`);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return milestoneDir;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
async function saveDiscussionQuestionRound(
|
|
630
|
+
basePath: string,
|
|
631
|
+
milestoneId: string,
|
|
632
|
+
questions: StructuredQuestion[],
|
|
633
|
+
details: any,
|
|
634
|
+
): Promise<void> {
|
|
635
|
+
const milestoneDir = await ensureMilestoneShell(basePath, milestoneId);
|
|
636
|
+
const answers = details?.response?.answers;
|
|
637
|
+
const timestamp = new Date().toISOString();
|
|
638
|
+
const exchange = formatQuestionExchange(questions, answers);
|
|
639
|
+
|
|
640
|
+
const discussionPath = join(milestoneDir, buildMilestoneFileName(milestoneId, "DISCUSSION"));
|
|
641
|
+
const existingDiscussion = await loadFile(discussionPath) ?? `# ${milestoneId} Discussion Log\n\n`;
|
|
642
|
+
await saveFile(
|
|
643
|
+
discussionPath,
|
|
644
|
+
`${existingDiscussion}## Exchange — ${timestamp}\n\n${exchange}---\n\n`,
|
|
645
|
+
);
|
|
646
|
+
|
|
647
|
+
const draftPath = join(milestoneDir, buildMilestoneFileName(milestoneId, "CONTEXT-DRAFT"));
|
|
648
|
+
const existingDraft = await loadFile(draftPath);
|
|
649
|
+
const draftHeader = existingDraft
|
|
650
|
+
?? [
|
|
651
|
+
`# ${milestoneId}: New milestone ${milestoneId}`,
|
|
652
|
+
"",
|
|
653
|
+
"This draft was captured automatically from structured question responses.",
|
|
654
|
+
"Use it so `/gsd` can resume the in-flight milestone discussion.",
|
|
655
|
+
"",
|
|
656
|
+
].join("\n");
|
|
657
|
+
await saveFile(
|
|
658
|
+
draftPath,
|
|
659
|
+
`${draftHeader.trimEnd()}\n\n## Captured Question Round — ${timestamp}\n\n${exchange}`,
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
|
|
488
663
|
function withDepthGateDisplayReason<T extends { block: boolean; reason?: string }>(
|
|
489
664
|
result: T,
|
|
490
665
|
displayReason = "Depth confirmation is waiting for your answer.",
|
|
@@ -577,6 +752,17 @@ export function registerHooks(
|
|
|
577
752
|
if (isAutoActive() || preserveCloseoutSurface) {
|
|
578
753
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
579
754
|
}
|
|
755
|
+
// Cold start after /quit relaunches with cwd at the project root. When
|
|
756
|
+
// auto-mode is neither active nor paused (its own resume path re-enters the
|
|
757
|
+
// worktree with a lease check — auto.ts:3032), proactively chdir back into
|
|
758
|
+
// the active milestone's worktree so subsequent work isn't stranded at the
|
|
759
|
+
// root. Best-effort and a no-op when already inside a worktree.
|
|
760
|
+
if (!isAutoActive() && !isAutoPaused() && !preserveCloseoutSurface) {
|
|
761
|
+
try {
|
|
762
|
+
const { reenterActiveWorktreeIfNeeded } = await import("../worktree-reentry.js");
|
|
763
|
+
await reenterActiveWorktreeIfNeeded(basePath);
|
|
764
|
+
} catch { /* non-fatal */ }
|
|
765
|
+
}
|
|
580
766
|
});
|
|
581
767
|
|
|
582
768
|
pi.on("session_switch", async (_event, ctx) => {
|
|
@@ -1106,6 +1292,17 @@ export function registerHooks(
|
|
|
1106
1292
|
if (isAutoActive() && typeof event.toolCallId === "string") {
|
|
1107
1293
|
markToolEnd(event.toolCallId);
|
|
1108
1294
|
}
|
|
1295
|
+
const toolName = canonicalToolName(event.toolName);
|
|
1296
|
+
if (isAutoActive() && toolName === "read" && !event.isError) {
|
|
1297
|
+
const store = beginSourceObservationStoreForCurrentUnit(ctx);
|
|
1298
|
+
if (store) {
|
|
1299
|
+
store.observeRead(event.input);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (!event.isError) {
|
|
1303
|
+
refreshSourceObservationAfterMutation(toolName, event.input, ctx);
|
|
1304
|
+
clearSourceObservationsAfterShell(toolName);
|
|
1305
|
+
}
|
|
1109
1306
|
if (isAutoActive() && event.isError) {
|
|
1110
1307
|
const resultPayload = ("result" in event ? event.result : undefined) as any;
|
|
1111
1308
|
const errorText = typeof resultPayload === "string"
|
|
@@ -1121,11 +1318,9 @@ export function registerHooks(
|
|
|
1121
1318
|
} else if (isAutoActive()) {
|
|
1122
1319
|
clearToolInvocationError();
|
|
1123
1320
|
}
|
|
1124
|
-
const toolName = canonicalToolName(event.toolName);
|
|
1125
1321
|
if (toolName !== "ask_user_questions") return;
|
|
1126
1322
|
const basePath = contextBasePath(ctx);
|
|
1127
1323
|
const milestoneId = await getDiscussionMilestoneIdFor(basePath);
|
|
1128
|
-
const queueActive = isQueuePhaseActive(basePath);
|
|
1129
1324
|
|
|
1130
1325
|
const details = event.details as any;
|
|
1131
1326
|
|
|
@@ -1204,36 +1399,8 @@ export function registerHooks(
|
|
|
1204
1399
|
}
|
|
1205
1400
|
}
|
|
1206
1401
|
|
|
1207
|
-
if (!milestoneId && !queueActive) return;
|
|
1208
1402
|
if (!milestoneId) return;
|
|
1209
|
-
|
|
1210
|
-
if (!milestoneDir) return;
|
|
1211
|
-
|
|
1212
|
-
const discussionPath = join(milestoneDir, buildMilestoneFileName(milestoneId, "DISCUSSION"));
|
|
1213
|
-
const timestamp = new Date().toISOString();
|
|
1214
|
-
const lines: string[] = [`## Exchange — ${timestamp}`, ""];
|
|
1215
|
-
for (const question of questions) {
|
|
1216
|
-
lines.push(`### ${question.header ?? "Question"}`, "", question.question ?? "");
|
|
1217
|
-
if (Array.isArray(question.options)) {
|
|
1218
|
-
lines.push("");
|
|
1219
|
-
for (const opt of question.options) {
|
|
1220
|
-
lines.push(`- **${opt.label}** — ${opt.description ?? ""}`);
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
const answer = details.response?.answers?.[question.id];
|
|
1224
|
-
if (answer) {
|
|
1225
|
-
lines.push("");
|
|
1226
|
-
const selected = Array.isArray(answer.selected) ? answer.selected.join(", ") : answer.selected;
|
|
1227
|
-
lines.push(`**Selected:** ${selected}`);
|
|
1228
|
-
if (answer.notes) {
|
|
1229
|
-
lines.push(`**Notes:** ${answer.notes}`);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
lines.push("");
|
|
1233
|
-
}
|
|
1234
|
-
lines.push("---", "");
|
|
1235
|
-
const existing = await loadFile(discussionPath) ?? `# ${milestoneId} Discussion Log\n\n`;
|
|
1236
|
-
await saveFile(discussionPath, existing + lines.join("\n"));
|
|
1403
|
+
await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
|
|
1237
1404
|
});
|
|
1238
1405
|
|
|
1239
1406
|
pi.on("tool_execution_start", async (event, ctx) => {
|
|
@@ -1287,52 +1454,57 @@ export function registerHooks(
|
|
|
1287
1454
|
const payload = event.payload as Record<string, unknown> | null;
|
|
1288
1455
|
if (!payload || typeof payload !== "object") return;
|
|
1289
1456
|
|
|
1290
|
-
// ──
|
|
1291
|
-
//
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1457
|
+
// ── Context Management ──────────────────────────────────────────────
|
|
1458
|
+
// Load preferences once for both masking and truncation.
|
|
1459
|
+
try {
|
|
1460
|
+
const { loadEffectiveGSDPreferences } = await import("../preferences.js");
|
|
1461
|
+
const {
|
|
1462
|
+
createObservationMask,
|
|
1463
|
+
createResponsesInputObservationMask,
|
|
1464
|
+
truncateContextResultMessages,
|
|
1465
|
+
truncateResponsesInputResultItems,
|
|
1466
|
+
} = await import("../context-masker.js");
|
|
1467
|
+
const prefs = loadEffectiveGSDPreferences();
|
|
1468
|
+
const cmConfig = prefs?.preferences.context_management;
|
|
1469
|
+
|
|
1470
|
+
// Observation masking: replace old tool results with placeholders.
|
|
1471
|
+
// Only active during auto-mode when context_management.observation_masking is enabled.
|
|
1472
|
+
if (isAutoActive() && cmConfig?.observation_masking !== false) {
|
|
1473
|
+
const keepTurns = cmConfig?.observation_mask_turns ?? 8;
|
|
1474
|
+
const messages = payload.messages;
|
|
1475
|
+
if (Array.isArray(messages)) {
|
|
1476
|
+
payload.messages = createObservationMask(keepTurns)(messages);
|
|
1308
1477
|
}
|
|
1478
|
+
const input = payload.input;
|
|
1479
|
+
if (Array.isArray(input)) {
|
|
1480
|
+
payload.input = createResponsesInputObservationMask(keepTurns)(input);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1309
1483
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
return msg;
|
|
1332
|
-
});
|
|
1484
|
+
// Tool result truncation: cap individual tool result content length.
|
|
1485
|
+
// Applies in ALL modes (auto + interactive) to prevent context bloat.
|
|
1486
|
+
// In pi-ai format, toolResult messages have role: "toolResult" and content: TextContent[].
|
|
1487
|
+
// Creates new objects to avoid mutating shared conversation state.
|
|
1488
|
+
const maxChars = cmConfig?.tool_result_max_chars ?? 800;
|
|
1489
|
+
const msgs = payload.messages;
|
|
1490
|
+
if (Array.isArray(msgs)) {
|
|
1491
|
+
payload.messages = truncateContextResultMessages(msgs as any, maxChars);
|
|
1492
|
+
}
|
|
1493
|
+
const input = payload.input;
|
|
1494
|
+
if (Array.isArray(input)) {
|
|
1495
|
+
payload.input = truncateResponsesInputResultItems(input as any, maxChars);
|
|
1496
|
+
}
|
|
1497
|
+
} catch { /* non-fatal */ }
|
|
1498
|
+
|
|
1499
|
+
try {
|
|
1500
|
+
if (isAutoActive()) {
|
|
1501
|
+
const sourceContextBlock = getSourceObservationStore().renderActiveBlock();
|
|
1502
|
+
if (sourceContextBlock) {
|
|
1503
|
+
const nextPayload = injectSourceContextBlockIntoPayload(payload, sourceContextBlock);
|
|
1504
|
+
Object.assign(payload, nextPayload);
|
|
1333
1505
|
}
|
|
1334
|
-
}
|
|
1335
|
-
}
|
|
1506
|
+
}
|
|
1507
|
+
} catch { /* non-fatal */ }
|
|
1336
1508
|
|
|
1337
1509
|
// ── Service Tier ────────────────────────────────────────────────────
|
|
1338
1510
|
const modelId = event.model?.id;
|
|
@@ -61,7 +61,7 @@ export const BUNDLED_SKILL_TRIGGERS: Array<{ trigger: string; skill: string }> =
|
|
|
61
61
|
{ trigger: "Core Web Vitals — fix LCP, CLS, INP; layout shifts; page experience optimization", skill: "core-web-vitals" },
|
|
62
62
|
{ trigger: "GitHub Actions CI/CD — write, run, and debug workflow files; live syntax and run monitoring", skill: "github-workflows" },
|
|
63
63
|
{ trigger: "Comprehensive web quality audit — performance, accessibility, SEO, and best-practices (Lighthouse-style)", skill: "web-quality-audit" },
|
|
64
|
-
{ trigger: "gsd-browser
|
|
64
|
+
{ trigger: "gsd-browser opt-in and External MCP UAT — screenshots, assertions, console/network diagnostics", skill: "gsd-browser" },
|
|
65
65
|
{ trigger: "Browser automation — open sites, fill forms, click, screenshot, scrape, or test web apps programmatically", skill: "agent-browser" },
|
|
66
66
|
{ trigger: "Review UI code for Web Interface Guidelines compliance — UX, design, and accessibility patterns", skill: "web-design-guidelines" },
|
|
67
67
|
{ trigger: "UI/UX patterns reference — animations, CSS, typography, prefetching, icons (file:line findings)", skill: "userinterface-wiki" },
|