@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0
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/cli-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/bg-shell/utilities.js +2 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
- package/dist/resources/extensions/gsd/auto/phases.js +34 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -36
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
- package/dist/resources/extensions/gsd/auto.js +15 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
- package/dist/resources/extensions/gsd/captures.js +5 -13
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
- package/dist/resources/extensions/gsd/guided-flow.js +68 -471
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
- package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/paths.js +10 -24
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +161 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/undo.js +8 -7
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +17 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
- 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 +12 -12
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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/middleware-react-loadable-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/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/dist/worktree-status-banner.js +7 -3
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.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 +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +32 -22
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +295 -98
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +309 -154
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- 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 +87 -24
- package/src/resources/extensions/bg-shell/utilities.ts +2 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
- package/src/resources/extensions/gsd/auto/phases.ts +45 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +25 -34
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
- package/src/resources/extensions/gsd/auto.ts +27 -17
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
- package/src/resources/extensions/gsd/captures.ts +5 -14
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
- package/src/resources/extensions/gsd/guided-flow.ts +81 -561
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/paths.ts +9 -22
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +191 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/undo.ts +9 -8
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +17 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/src/resources/skills/gsd-browser/SKILL.md +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
package/dist/cli-web-branch.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export interface CliFlags {
|
|
|
20
20
|
webPort?: number;
|
|
21
21
|
/** Additional allowed origins for CORS: `--allowed-origins http://192.168.1.10:8080` */
|
|
22
22
|
webAllowedOrigins?: string[];
|
|
23
|
+
/** Disable the web launcher's bearer token gate: `--no-auth` */
|
|
24
|
+
webNoAuth?: boolean;
|
|
23
25
|
/** Set by `gsd sessions` when the user picks a specific session to resume */
|
|
24
26
|
_selectedSessionPath?: string;
|
|
25
27
|
}
|
package/dist/cli-web-branch.js
CHANGED
|
@@ -52,6 +52,9 @@ export function parseCliArgs(argv) {
|
|
|
52
52
|
const origins = args[++i].split(',').map(o => o.trim()).filter(Boolean);
|
|
53
53
|
flags.webAllowedOrigins = (flags.webAllowedOrigins ?? []).concat(origins);
|
|
54
54
|
}
|
|
55
|
+
else if (arg === '--no-auth') {
|
|
56
|
+
flags.webNoAuth = true;
|
|
57
|
+
}
|
|
55
58
|
else if (arg === '--model' && i + 1 < args.length) {
|
|
56
59
|
flags.model = args[++i];
|
|
57
60
|
}
|
|
@@ -232,14 +235,18 @@ export async function runWebCliBranch(flags, deps = {}) {
|
|
|
232
235
|
const agentDir = deps.agentDir ?? defaultAgentDir;
|
|
233
236
|
const projectSessionsDir = getProjectSessionsDir(currentCwd, baseSessionsDir);
|
|
234
237
|
migrateLegacyFlatSessions(baseSessionsDir, projectSessionsDir);
|
|
235
|
-
const
|
|
238
|
+
const launchOptions = {
|
|
236
239
|
cwd: currentCwd,
|
|
237
240
|
projectSessionsDir,
|
|
238
241
|
agentDir,
|
|
239
242
|
host: flags.webHost,
|
|
240
243
|
port: flags.webPort,
|
|
241
244
|
allowedOrigins: flags.webAllowedOrigins,
|
|
242
|
-
}
|
|
245
|
+
};
|
|
246
|
+
if (flags.webNoAuth !== undefined) {
|
|
247
|
+
launchOptions.noAuth = flags.webNoAuth;
|
|
248
|
+
}
|
|
249
|
+
const status = await (deps.runWebMode ?? launchWebMode)(launchOptions);
|
|
243
250
|
if (!status.ok) {
|
|
244
251
|
emitWebModeFailure(stderr, status);
|
|
245
252
|
}
|
package/dist/help-text.js
CHANGED
|
@@ -189,6 +189,11 @@ export function printHelp(version) {
|
|
|
189
189
|
process.stdout.write(' --worktree, -w [name] Start in an isolated worktree (auto-named if omitted)\n');
|
|
190
190
|
process.stdout.write(' --model <id> Override model (e.g. provider/model-id)\n');
|
|
191
191
|
process.stdout.write(' --no-session Disable session persistence\n');
|
|
192
|
+
process.stdout.write(' --web [path] Start browser-only web mode\n');
|
|
193
|
+
process.stdout.write(' --host <host> Web mode bind address\n');
|
|
194
|
+
process.stdout.write(' --port <port> Web mode port\n');
|
|
195
|
+
process.stdout.write(' --allowed-origins <csv> Additional allowed web origins\n');
|
|
196
|
+
process.stdout.write(' --no-auth Disable web token auth; requires external access control\n');
|
|
192
197
|
process.stdout.write(' --extension <path> Load additional extension\n');
|
|
193
198
|
process.stdout.write(' --tools <a,b,c> Restrict available tools\n');
|
|
194
199
|
process.stdout.write(' --list-models [search] List available models and exit\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
749698fd346380ec
|
|
@@ -114,6 +114,61 @@ function errorResult(message, questions = [], options) {
|
|
|
114
114
|
details: { questions, response: null, cancelled: true, interrupted: options?.interrupted === true },
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
/** Parse the LLM-facing JSON payload back into a RoundResult for TUI rendering. */
|
|
118
|
+
function parseLlmAnswersContent(text) {
|
|
119
|
+
try {
|
|
120
|
+
const parsed = JSON.parse(text);
|
|
121
|
+
if (!parsed?.answers || typeof parsed.answers !== "object")
|
|
122
|
+
return null;
|
|
123
|
+
const answers = {};
|
|
124
|
+
for (const [id, entry] of Object.entries(parsed.answers)) {
|
|
125
|
+
const list = Array.isArray(entry?.answers) ? [...entry.answers] : [];
|
|
126
|
+
let notes = "";
|
|
127
|
+
const noteIdx = list.findIndex((item) => typeof item === "string" && item.startsWith("user_note:"));
|
|
128
|
+
if (noteIdx >= 0) {
|
|
129
|
+
notes = list.splice(noteIdx, 1)[0].replace(/^user_note:\s*/, "");
|
|
130
|
+
}
|
|
131
|
+
if (list.length === 0)
|
|
132
|
+
continue;
|
|
133
|
+
answers[id] = {
|
|
134
|
+
selected: list.length === 1 ? list[0] : list,
|
|
135
|
+
notes,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (Object.keys(answers).length === 0)
|
|
139
|
+
return null;
|
|
140
|
+
return { endInterview: false, answers };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function isCancelledResultContent(text) {
|
|
147
|
+
return /\bwas cancelled before receiving a response\b/i.test(text)
|
|
148
|
+
|| /\bwas interrupted before receiving a response\b/i.test(text);
|
|
149
|
+
}
|
|
150
|
+
function renderAnswerLines(questions, response, theme) {
|
|
151
|
+
const lines = [];
|
|
152
|
+
for (const q of questions) {
|
|
153
|
+
const answer = response.answers[q.id];
|
|
154
|
+
if (!answer) {
|
|
155
|
+
lines.push(`${theme.fg("accent", q.header)}: ${theme.fg("dim", "(no answer)")}`);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const selected = answer.selected;
|
|
159
|
+
const notes = answer.notes;
|
|
160
|
+
const multiSel = !!q.allowMultiple;
|
|
161
|
+
const answerText = multiSel && Array.isArray(selected)
|
|
162
|
+
? selected.join(", ")
|
|
163
|
+
: (Array.isArray(selected) ? selected[0] : selected) ?? "(no answer)";
|
|
164
|
+
let line = `${theme.fg("success", "✓ ")}${theme.fg("accent", q.header)}: ${answerText}`;
|
|
165
|
+
if (notes) {
|
|
166
|
+
line += ` ${theme.fg("muted", `[note: ${notes}]`)}`;
|
|
167
|
+
}
|
|
168
|
+
lines.push(line);
|
|
169
|
+
}
|
|
170
|
+
return new Text(lines.join("\n"), 0, 0);
|
|
171
|
+
}
|
|
117
172
|
/** Convert the shared RoundResult into the JSON the LLM expects. */
|
|
118
173
|
function formatForLLM(result) {
|
|
119
174
|
const answers = {};
|
|
@@ -318,11 +373,17 @@ export default function AskUserQuestions(pi) {
|
|
|
318
373
|
}
|
|
319
374
|
return new Text(text, 0, 0);
|
|
320
375
|
},
|
|
321
|
-
renderResult(result, _options, theme) {
|
|
376
|
+
renderResult(result, _options, theme, context) {
|
|
322
377
|
const details = result.details;
|
|
378
|
+
const contentText = result.content[0]?.type === "text" ? result.content[0].text : "";
|
|
379
|
+
const questionsFromArgs = context?.args?.questions;
|
|
380
|
+
const parsedResponse = contentText ? parseLlmAnswersContent(contentText) : null;
|
|
323
381
|
if (!details) {
|
|
324
|
-
const
|
|
325
|
-
|
|
382
|
+
const questions = questionsFromArgs;
|
|
383
|
+
if (questions?.length && parsedResponse) {
|
|
384
|
+
return renderAnswerLines(questions, parsedResponse, theme);
|
|
385
|
+
}
|
|
386
|
+
return new Text(contentText, 0, 0);
|
|
326
387
|
}
|
|
327
388
|
// Remote channel result (discriminated on details.remote === true)
|
|
328
389
|
if (details.remote) {
|
|
@@ -352,30 +413,24 @@ export default function AskUserQuestions(pi) {
|
|
|
352
413
|
}
|
|
353
414
|
return new Text(lines.join("\n"), 0, 0);
|
|
354
415
|
}
|
|
355
|
-
|
|
416
|
+
const questions = details.questions ?? questionsFromArgs;
|
|
417
|
+
const response = details.response ?? parsedResponse;
|
|
418
|
+
const explicitCancel = details.cancelled === true || isCancelledResultContent(contentText);
|
|
419
|
+
if (explicitCancel && !response) {
|
|
356
420
|
const interrupted = "interrupted" in details && details.interrupted === true;
|
|
357
421
|
return new Text(theme.fg("warning", interrupted ? "Interrupted" : "Cancelled"), 0, 0);
|
|
358
422
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
const multiSel = !!q.allowMultiple;
|
|
369
|
-
const answerText = multiSel && Array.isArray(selected)
|
|
370
|
-
? selected.join(", ")
|
|
371
|
-
: (Array.isArray(selected) ? selected[0] : selected) ?? "(no answer)";
|
|
372
|
-
let line = `${theme.fg("success", "✓ ")}${theme.fg("accent", q.header)}: ${answerText}`;
|
|
373
|
-
if (notes) {
|
|
374
|
-
line += ` ${theme.fg("muted", `[note: ${notes}]`)}`;
|
|
375
|
-
}
|
|
376
|
-
lines.push(line);
|
|
423
|
+
if (questions?.length && response) {
|
|
424
|
+
return renderAnswerLines(questions, response, theme);
|
|
425
|
+
}
|
|
426
|
+
if (contentText) {
|
|
427
|
+
return new Text(contentText, 0, 0);
|
|
428
|
+
}
|
|
429
|
+
if (details.cancelled || !details.response) {
|
|
430
|
+
const interrupted = "interrupted" in details && details.interrupted === true;
|
|
431
|
+
return new Text(theme.fg("warning", interrupted ? "Interrupted" : "Cancelled"), 0, 0);
|
|
377
432
|
}
|
|
378
|
-
return new Text(
|
|
433
|
+
return new Text("", 0, 0);
|
|
379
434
|
},
|
|
380
435
|
});
|
|
381
436
|
}
|
|
@@ -40,7 +40,7 @@ export function formatTimeAgo(timestamp) {
|
|
|
40
40
|
function deriveProjectRootFromAutoWorktree(cachedCwd) {
|
|
41
41
|
if (!cachedCwd)
|
|
42
42
|
return undefined;
|
|
43
|
-
const match = cachedCwd.match(/^(.*?)[\\/]\.gsd[\\/]worktrees[\\/][^\\/]+(?:[\\/].*)?$/);
|
|
43
|
+
const match = cachedCwd.match(/^(.*?)[\\/]\.gsd(?:-worktrees|[\\/]worktrees)[\\/][^\\/]+(?:[\\/].*)?$/);
|
|
44
44
|
return match?.[1];
|
|
45
45
|
}
|
|
46
46
|
export function getBgShellLiveCwd(cachedCwd, pathExists = existsSync, getCwd = () => process.cwd(), chdir = (path) => process.chdir(path)) {
|
|
@@ -67,7 +67,7 @@ export function getBgShellLiveCwd(cachedCwd, pathExists = existsSync, getCwd = (
|
|
|
67
67
|
}
|
|
68
68
|
export function resolveBgShellPersistenceCwd(cachedCwd, liveCwd = undefined, pathExists = existsSync) {
|
|
69
69
|
const resolvedLiveCwd = liveCwd ?? getBgShellLiveCwd(cachedCwd, pathExists);
|
|
70
|
-
const cachedIsAutoWorktree = /(?:^|[\\/])\.gsd[\\/]worktrees[\\/]/.test(cachedCwd);
|
|
70
|
+
const cachedIsAutoWorktree = /(?:^|[\\/])\.gsd(?:-worktrees|[\\/]worktrees)[\\/]/.test(cachedCwd);
|
|
71
71
|
if (!cachedIsAutoWorktree)
|
|
72
72
|
return cachedCwd;
|
|
73
73
|
if (cachedCwd === resolvedLiveCwd && pathExists(cachedCwd))
|
|
@@ -37,6 +37,15 @@ export const CLAUDE_CODE_MODELS = [
|
|
|
37
37
|
contextWindow: 1_000_000,
|
|
38
38
|
maxTokens: 128_000,
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
id: "claude-fable-5",
|
|
42
|
+
name: "Claude Fable 5 (via Claude Code)",
|
|
43
|
+
reasoning: true,
|
|
44
|
+
input: ["text", "image"],
|
|
45
|
+
cost: ZERO_COST,
|
|
46
|
+
contextWindow: 1_000_000,
|
|
47
|
+
maxTokens: 128_000,
|
|
48
|
+
},
|
|
40
49
|
{
|
|
41
50
|
id: "claude-sonnet-4-6",
|
|
42
51
|
name: "Claude Sonnet 4.6 (via Claude Code)",
|
|
@@ -14,13 +14,18 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { createRequire } from "node:module";
|
|
16
16
|
import { dirname, join } from "node:path";
|
|
17
|
-
import {
|
|
17
|
+
import { ZERO_USAGE, mapUsage } from "./partial-builder.js";
|
|
18
|
+
import { attachExternalResultsToToolBlocks, buildFinalAssistantContent, extractToolResultsFromSdkUserMessage, handleClaudeCodePartialStreamEvent, } from "./turn-assembler.js";
|
|
18
19
|
import { buildWorkflowMcpServers, getRequiredWorkflowToolsForAutoUnit, resolveWorkflowMcpProjectRoot, } from "../gsd/workflow-mcp.js";
|
|
20
|
+
import { resolveWorkflowQuestionToolSurface } from "../gsd/question-transport.js";
|
|
19
21
|
import { buildProjectGsdMcpServers, ensureProjectWorkflowMcpConfig } from "../gsd/mcp-project-config.js";
|
|
20
22
|
import { loadProjectGSDPreferences } from "../gsd/preferences.js";
|
|
23
|
+
import { markToolStart, markToolEnd } from "../gsd/auto.js";
|
|
24
|
+
import { markInteractiveElicitationStart, markInteractiveElicitationEnd, } from "../gsd/auto-tool-tracking.js";
|
|
21
25
|
import { discoverBrowserMcpServerName, discoverMcpServers, discoverMcpServerNames, discoverUserMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools, } from "../gsd/mcp-filter.js";
|
|
22
26
|
import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
|
|
23
27
|
import { showInterviewRound } from "../shared/tui.js";
|
|
28
|
+
export { buildFinalAssistantContent, extractToolResultsFromSdkUserMessage, handleClaudeCodePartialStreamEvent, mergePendingToolCalls, } from "./turn-assembler.js";
|
|
24
29
|
export function serverToolUseToToolCallLike(block) {
|
|
25
30
|
const argumentsValue = block.input && typeof block.input === "object" && !Array.isArray(block.input)
|
|
26
31
|
? block.input
|
|
@@ -1078,7 +1083,26 @@ export function createClaudeCodeCanUseToolHandler(ui) {
|
|
|
1078
1083
|
// ---------------------------------------------------------------------------
|
|
1079
1084
|
// Elicitation handler
|
|
1080
1085
|
// ---------------------------------------------------------------------------
|
|
1081
|
-
/**
|
|
1086
|
+
/**
|
|
1087
|
+
* Create an SDK elicitation handler that routes requests through the extension UI dialogs, or undefined if no UI is available.
|
|
1088
|
+
*
|
|
1089
|
+
* For structured (AskUserQuestion) elicitations, the interview round's result
|
|
1090
|
+
* disambiguates two cases that must not be conflated: an `undefined` result
|
|
1091
|
+
* means the custom UI is unavailable, so we fall back to the simpler `select`
|
|
1092
|
+
* dialogs; an empty-answers result means the user dismissed the question, which
|
|
1093
|
+
* is treated as a clean cancel. Falling back to dialogs on dismissal would
|
|
1094
|
+
* re-ask the same questions (the duplicate-question bug).
|
|
1095
|
+
*/
|
|
1096
|
+
/**
|
|
1097
|
+
* Monotonic counter so concurrent/sequential elicitations resolved within the
|
|
1098
|
+
* same millisecond get distinct synthetic in-flight-tool ids (the `cc-elicit-*`
|
|
1099
|
+
* namespace never collides with real MCP toolCallIds).
|
|
1100
|
+
*/
|
|
1101
|
+
let _elicitationSeq = 0;
|
|
1102
|
+
function nextElicitationSeq() {
|
|
1103
|
+
_elicitationSeq = (_elicitationSeq + 1) % Number.MAX_SAFE_INTEGER;
|
|
1104
|
+
return _elicitationSeq;
|
|
1105
|
+
}
|
|
1082
1106
|
export function createClaudeCodeElicitationHandler(ui) {
|
|
1083
1107
|
if (!ui)
|
|
1084
1108
|
return undefined;
|
|
@@ -1091,18 +1115,64 @@ export function createClaudeCodeElicitationHandler(ui) {
|
|
|
1091
1115
|
const headlessAnswer = answerElicitationFromHeadlessAnswers(questions, loadHeadlessAnswers());
|
|
1092
1116
|
if (headlessAnswer)
|
|
1093
1117
|
return headlessAnswer;
|
|
1094
|
-
|
|
1095
|
-
|
|
1118
|
+
// The SDK elicitation blocks waiting for human input, but it is not an
|
|
1119
|
+
// MCP tool dispatch, so markToolStart/markToolEnd are never called for
|
|
1120
|
+
// it. Without this the soft/context/idle/hard watchdogs see zero
|
|
1121
|
+
// in-flight tools and re-dispatch (and ultimately abort) the agent
|
|
1122
|
+
// turn hosting this elicitation, tearing the question down (#2676 /
|
|
1123
|
+
// claude-code-cli self-cancel loop). Bracketing the human wait with
|
|
1124
|
+
// the s.active-gated interactive-tool guard makes it visible to
|
|
1125
|
+
// hasInteractiveToolInFlight()/getInFlightToolCount() so those
|
|
1126
|
+
// watchdogs exempt it. No-op outside auto-mode (wrapper self-gates).
|
|
1127
|
+
//
|
|
1128
|
+
// markInteractiveElicitationStart/End is a SEPARATE, ungated signal that
|
|
1129
|
+
// is observable in FOREGROUND (where the s.active-gated markToolStart is a
|
|
1130
|
+
// no-op). The foreground approval-gate pause path (register-hooks
|
|
1131
|
+
// message_update) consults isInteractiveElicitationInFlight() and bails so
|
|
1132
|
+
// it does not tear down the very elicitation that IS the human boundary
|
|
1133
|
+
// (#cc-elicitation-self-cancel). It clears in the finally on every exit.
|
|
1134
|
+
const elicId = "cc-elicit-" + (request.id ?? `${Date.now()}-${nextElicitationSeq()}`);
|
|
1135
|
+
markInteractiveElicitationStart();
|
|
1136
|
+
markToolStart(elicId, "ask_user_questions");
|
|
1137
|
+
try {
|
|
1138
|
+
const interviewResult = await showInterviewRound(questions, { signal, overlay: true }, { ui }).catch(() => undefined);
|
|
1139
|
+
if (interviewResult === undefined) {
|
|
1140
|
+
// `await` so the dialog human-wait stays inside try/finally and the
|
|
1141
|
+
// in-flight guard is held until the dialog resolves. Without it,
|
|
1142
|
+
// `finally` runs the moment the promise is created and the fallback
|
|
1143
|
+
// wait runs with zero in-flight tools — reintroducing the
|
|
1144
|
+
// self-cancel on this path (Bugbot #1c00624d).
|
|
1145
|
+
return await promptElicitationWithDialogs(request, questions, ui, signal);
|
|
1146
|
+
}
|
|
1147
|
+
if (Object.keys(interviewResult.answers).length === 0) {
|
|
1148
|
+
// A system/host teardown (compaction, session_switch, true
|
|
1149
|
+
// interrupt) that aborted the signal mid-wait sets `interrupted`.
|
|
1150
|
+
// Surface that as a non-affirmative `decline` so it is not
|
|
1151
|
+
// laundered into a clean user-declined `cancel` the model re-asks
|
|
1152
|
+
// against. A genuine user dismissal leaves `interrupted` falsy and
|
|
1153
|
+
// keeps the prior `cancel` semantics.
|
|
1154
|
+
return interviewResult.interrupted ? { action: "decline" } : { action: "cancel" };
|
|
1155
|
+
}
|
|
1096
1156
|
return {
|
|
1097
1157
|
action: "accept",
|
|
1098
1158
|
content: roundResultToElicitationContent(questions, interviewResult),
|
|
1099
1159
|
};
|
|
1100
1160
|
}
|
|
1101
|
-
|
|
1161
|
+
finally {
|
|
1162
|
+
markToolEnd(elicId);
|
|
1163
|
+
markInteractiveElicitationEnd();
|
|
1164
|
+
}
|
|
1102
1165
|
}
|
|
1103
1166
|
const textFields = parseTextInputElicitation(request);
|
|
1104
1167
|
if (textFields) {
|
|
1105
|
-
|
|
1168
|
+
const elicId = "cc-elicit-" + (request.id ?? `${Date.now()}-${nextElicitationSeq()}`);
|
|
1169
|
+
markToolStart(elicId, "secure_env_collect");
|
|
1170
|
+
try {
|
|
1171
|
+
return await promptTextInputElicitation(request, textFields, ui, signal);
|
|
1172
|
+
}
|
|
1173
|
+
finally {
|
|
1174
|
+
markToolEnd(elicId);
|
|
1175
|
+
}
|
|
1106
1176
|
}
|
|
1107
1177
|
return { action: "decline" };
|
|
1108
1178
|
};
|
|
@@ -1172,6 +1242,8 @@ function modelSupportsAdaptiveThinking(modelId) {
|
|
|
1172
1242
|
|| modelId.includes("opus-4.7")
|
|
1173
1243
|
|| modelId.includes("opus-4-8")
|
|
1174
1244
|
|| modelId.includes("opus-4.8")
|
|
1245
|
+
|| modelId.includes("fable-5")
|
|
1246
|
+
|| modelId.includes("fable.5")
|
|
1175
1247
|
|| modelId.includes("sonnet-4-6")
|
|
1176
1248
|
|| modelId.includes("sonnet-4.6")
|
|
1177
1249
|
|| modelId.includes("sonnet-4-7")
|
|
@@ -1193,7 +1265,9 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
|
|
|
1193
1265
|
if (modelId.includes("opus-4-7")
|
|
1194
1266
|
|| modelId.includes("opus-4.7")
|
|
1195
1267
|
|| modelId.includes("opus-4-8")
|
|
1196
|
-
|| modelId.includes("opus-4.8")
|
|
1268
|
+
|| modelId.includes("opus-4.8")
|
|
1269
|
+
|| modelId.includes("fable-5")
|
|
1270
|
+
|| modelId.includes("fable.5"))
|
|
1197
1271
|
return "xhigh";
|
|
1198
1272
|
if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6"))
|
|
1199
1273
|
return "max";
|
|
@@ -1417,6 +1491,13 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1417
1491
|
// leave allowed mcp__... tools with no registered backing tool.
|
|
1418
1492
|
const settingSources = strictMcpConfig ? [] : ["user", "project", "local"];
|
|
1419
1493
|
const exactWorkflowMcpTools = resolveExactWorkflowMcpToolsForPhase(gsdPhase, workflowServerName, workflowExplicitlyBlocked);
|
|
1494
|
+
const questionToolSurface = resolveWorkflowQuestionToolSurface({
|
|
1495
|
+
workflowServerName,
|
|
1496
|
+
workflowExplicitlyBlocked,
|
|
1497
|
+
workflowMcpTools,
|
|
1498
|
+
exactWorkflowMcpTools,
|
|
1499
|
+
env: process.env,
|
|
1500
|
+
});
|
|
1420
1501
|
const runUatDisallowedTools = gsdPhase === "run-uat" && workflowServerName
|
|
1421
1502
|
? [
|
|
1422
1503
|
...RUN_UAT_FORBIDDEN_TOOL_NAMES.filter((toolName) => !toolName.startsWith("mcp__")),
|
|
@@ -1430,6 +1511,7 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1430
1511
|
const disallowedTools = [...new Set([
|
|
1431
1512
|
"ToolSearch",
|
|
1432
1513
|
...(workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
|
|
1514
|
+
...questionToolSurface.disallowedTools,
|
|
1433
1515
|
...runUatDisallowedTools,
|
|
1434
1516
|
...extraDisallowedTools,
|
|
1435
1517
|
])];
|
|
@@ -1486,234 +1568,14 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1486
1568
|
|| modelId.includes("opus-4-7")
|
|
1487
1569
|
|| modelId.includes("opus-4.7")
|
|
1488
1570
|
|| modelId.includes("opus-4-8")
|
|
1489
|
-
|| modelId.includes("opus-4.8")
|
|
1571
|
+
|| modelId.includes("opus-4.8")
|
|
1572
|
+
|| modelId.includes("fable-5")
|
|
1573
|
+
|| modelId.includes("fable.5")) ? ["context-1m-2025-08-07"] : [],
|
|
1490
1574
|
...(thinkingConfig ?? {}),
|
|
1491
1575
|
...(effort ? { effort } : {}),
|
|
1492
1576
|
...sdkExtraOptions,
|
|
1493
1577
|
};
|
|
1494
1578
|
}
|
|
1495
|
-
/** Normalise heterogeneous SDK tool-result content (string, array, or object) into a uniform `ExternalToolResultContentBlock[]`. */
|
|
1496
|
-
function normalizeToolResultContent(content) {
|
|
1497
|
-
if (typeof content === "string") {
|
|
1498
|
-
return [{ type: "text", text: content }];
|
|
1499
|
-
}
|
|
1500
|
-
if (!Array.isArray(content)) {
|
|
1501
|
-
if (content == null)
|
|
1502
|
-
return [{ type: "text", text: "" }];
|
|
1503
|
-
return [{ type: "text", text: JSON.stringify(content) }];
|
|
1504
|
-
}
|
|
1505
|
-
const blocks = [];
|
|
1506
|
-
for (const item of content) {
|
|
1507
|
-
if (typeof item === "string") {
|
|
1508
|
-
blocks.push({ type: "text", text: item });
|
|
1509
|
-
continue;
|
|
1510
|
-
}
|
|
1511
|
-
if (!item || typeof item !== "object") {
|
|
1512
|
-
blocks.push({ type: "text", text: String(item) });
|
|
1513
|
-
continue;
|
|
1514
|
-
}
|
|
1515
|
-
const block = item;
|
|
1516
|
-
if (block.type === "text") {
|
|
1517
|
-
blocks.push({ type: "text", text: typeof block.text === "string" ? block.text : "" });
|
|
1518
|
-
continue;
|
|
1519
|
-
}
|
|
1520
|
-
if (block.type === "image"
|
|
1521
|
-
&& typeof block.data === "string"
|
|
1522
|
-
&& typeof block.mimeType === "string") {
|
|
1523
|
-
blocks.push({ type: "image", data: block.data, mimeType: block.mimeType });
|
|
1524
|
-
continue;
|
|
1525
|
-
}
|
|
1526
|
-
blocks.push({ type: "text", text: JSON.stringify(block) });
|
|
1527
|
-
}
|
|
1528
|
-
return blocks.length > 0 ? blocks : [{ type: "text", text: "" }];
|
|
1529
|
-
}
|
|
1530
|
-
/**
|
|
1531
|
-
* Extract a `details` payload from an MCP tool-result block.
|
|
1532
|
-
*
|
|
1533
|
-
* MCP's `CallToolResult` carries structured data in `structuredContent` — the
|
|
1534
|
-
* protocol's supported channel for non-text payloads. Claude Code's synthetic
|
|
1535
|
-
* user message may surface that field in one of two shapes depending on SDK
|
|
1536
|
-
* version: as a sibling on the `mcp_tool_result` block itself, or as a
|
|
1537
|
-
* dedicated content sub-block with `type: "structuredContent"`. Snake-case
|
|
1538
|
-
* (`structured_content`) is accepted defensively in case a transport hop
|
|
1539
|
-
* rewrites casing. All other shapes fall back to an empty object so callers
|
|
1540
|
-
* can rely on `details` being present.
|
|
1541
|
-
*/
|
|
1542
|
-
function extractStructuredDetailsFromBlock(block) {
|
|
1543
|
-
const sibling = block.structuredContent ?? block.structured_content;
|
|
1544
|
-
if (sibling && typeof sibling === "object" && !Array.isArray(sibling)) {
|
|
1545
|
-
return sibling;
|
|
1546
|
-
}
|
|
1547
|
-
if (Array.isArray(block.content)) {
|
|
1548
|
-
for (const item of block.content) {
|
|
1549
|
-
if (!item || typeof item !== "object")
|
|
1550
|
-
continue;
|
|
1551
|
-
const sub = item;
|
|
1552
|
-
if (sub.type !== "structuredContent" && sub.type !== "structured_content")
|
|
1553
|
-
continue;
|
|
1554
|
-
const payload = sub.structuredContent ?? sub.structured_content ?? sub.data ?? sub.value;
|
|
1555
|
-
if (payload && typeof payload === "object" && !Array.isArray(payload)) {
|
|
1556
|
-
return payload;
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
// Return undefined (not {}) when no structured payload is present, matching
|
|
1561
|
-
// the pre-#4477 contract where `details` was nullable. An empty-object
|
|
1562
|
-
// sentinel is truthy and breaks downstream consumers that gate on
|
|
1563
|
-
// `if (details)`. `undefined` matches the type of the field these results
|
|
1564
|
-
// flow into (`Record<string, unknown> | undefined`).
|
|
1565
|
-
return undefined;
|
|
1566
|
-
}
|
|
1567
|
-
/**
|
|
1568
|
-
* True for items that are MCP `structuredContent` pseudo-blocks living inside
|
|
1569
|
-
* a tool-result `content[]` array. These blocks carry the structured payload
|
|
1570
|
-
* (extracted separately by `extractStructuredDetailsFromBlock`) and must NOT
|
|
1571
|
-
* leak into the visible content rendered to the user — otherwise the renderer
|
|
1572
|
-
* stringifies the JSON pseudo-block and shows it next to the actual tool
|
|
1573
|
-
* output. See PR #4477 review (post-fix-round).
|
|
1574
|
-
*/
|
|
1575
|
-
function isStructuredContentPseudoBlock(item) {
|
|
1576
|
-
if (!item || typeof item !== "object")
|
|
1577
|
-
return false;
|
|
1578
|
-
const type = item.type;
|
|
1579
|
-
return type === "structuredContent" || type === "structured_content";
|
|
1580
|
-
}
|
|
1581
|
-
/**
|
|
1582
|
-
* Strip `structuredContent` pseudo-blocks from a tool-result content array
|
|
1583
|
-
* before normalization. The structured payload is extracted via the sibling
|
|
1584
|
-
* `structuredContent` field (or a dedicated extractor pass on the raw block);
|
|
1585
|
-
* the visible content path must not include the pseudo-block itself.
|
|
1586
|
-
*/
|
|
1587
|
-
function stripStructuredContentPseudoBlocks(content) {
|
|
1588
|
-
if (!Array.isArray(content))
|
|
1589
|
-
return content;
|
|
1590
|
-
return content.filter((item) => !isStructuredContentPseudoBlock(item));
|
|
1591
|
-
}
|
|
1592
|
-
/** Extract tool result payloads from an SDK synthetic user message, keyed by tool-use ID. */
|
|
1593
|
-
export function extractToolResultsFromSdkUserMessage(message) {
|
|
1594
|
-
const extracted = [];
|
|
1595
|
-
const seen = new Set();
|
|
1596
|
-
const rawMessage = message.message;
|
|
1597
|
-
const content = Array.isArray(rawMessage?.content) ? rawMessage.content : [];
|
|
1598
|
-
for (const item of content) {
|
|
1599
|
-
if (!item || typeof item !== "object")
|
|
1600
|
-
continue;
|
|
1601
|
-
const block = item;
|
|
1602
|
-
const type = typeof block.type === "string" ? block.type : "";
|
|
1603
|
-
if (type !== "tool_result" && type !== "mcp_tool_result")
|
|
1604
|
-
continue;
|
|
1605
|
-
const toolUseId = typeof block.tool_use_id === "string" ? block.tool_use_id : "";
|
|
1606
|
-
if (!toolUseId || seen.has(toolUseId))
|
|
1607
|
-
continue;
|
|
1608
|
-
seen.add(toolUseId);
|
|
1609
|
-
extracted.push({
|
|
1610
|
-
toolUseId,
|
|
1611
|
-
result: {
|
|
1612
|
-
content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(block.content)),
|
|
1613
|
-
details: extractStructuredDetailsFromBlock(block),
|
|
1614
|
-
isError: block.is_error === true,
|
|
1615
|
-
},
|
|
1616
|
-
});
|
|
1617
|
-
}
|
|
1618
|
-
if (extracted.length === 0) {
|
|
1619
|
-
const fallback = message.tool_use_result;
|
|
1620
|
-
if (fallback && typeof fallback === "object") {
|
|
1621
|
-
const toolResult = fallback;
|
|
1622
|
-
const toolUseId = typeof toolResult.tool_use_id === "string" ? toolResult.tool_use_id : "";
|
|
1623
|
-
if (toolUseId) {
|
|
1624
|
-
extracted.push({
|
|
1625
|
-
toolUseId,
|
|
1626
|
-
result: {
|
|
1627
|
-
content: normalizeToolResultContent(stripStructuredContentPseudoBlocks(toolResult.content)),
|
|
1628
|
-
details: extractStructuredDetailsFromBlock(toolResult),
|
|
1629
|
-
isError: toolResult.is_error === true,
|
|
1630
|
-
},
|
|
1631
|
-
});
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
return extracted;
|
|
1636
|
-
}
|
|
1637
|
-
/** Attach external tool results from the SDK synthetic user message to their corresponding tool-call blocks by ID. */
|
|
1638
|
-
function attachExternalResultsToToolBlocks(toolBlocks, toolResultsById) {
|
|
1639
|
-
for (const block of toolBlocks) {
|
|
1640
|
-
if (block.type !== "toolCall" && block.type !== "serverToolUse")
|
|
1641
|
-
continue;
|
|
1642
|
-
const externalResult = toolResultsById.get(block.id);
|
|
1643
|
-
if (!externalResult)
|
|
1644
|
-
continue;
|
|
1645
|
-
block.externalResult = externalResult;
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
|
-
/**
|
|
1649
|
-
* Build the final assistant content that Agent Core consumes in
|
|
1650
|
-
* `externalToolExecution` mode. This preserves tool-call blocks, attaches any
|
|
1651
|
-
* SDK-produced external results by tool-call id, and then appends the final
|
|
1652
|
-
* text/thinking blocks for the completed turn.
|
|
1653
|
-
*/
|
|
1654
|
-
export function buildFinalAssistantContent(params) {
|
|
1655
|
-
const mergedToolBlocks = [...params.intermediateToolBlocks];
|
|
1656
|
-
if (params.pendingContent) {
|
|
1657
|
-
mergePendingToolCalls(mergedToolBlocks, params.pendingContent);
|
|
1658
|
-
}
|
|
1659
|
-
attachExternalResultsToToolBlocks(mergedToolBlocks, params.toolResultsById);
|
|
1660
|
-
const finalContent = [...mergedToolBlocks];
|
|
1661
|
-
if (params.pendingContent && params.pendingContent.length > 0) {
|
|
1662
|
-
for (const block of params.pendingContent) {
|
|
1663
|
-
if (block.type === "text" || block.type === "thinking") {
|
|
1664
|
-
finalContent.push(block);
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
else {
|
|
1669
|
-
if (params.lastThinkingContent) {
|
|
1670
|
-
finalContent.push({ type: "thinking", thinking: params.lastThinkingContent });
|
|
1671
|
-
}
|
|
1672
|
-
if (params.lastTextContent) {
|
|
1673
|
-
finalContent.push({ type: "text", text: params.lastTextContent });
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
if (finalContent.length === 0 && params.fallbackResultText) {
|
|
1677
|
-
finalContent.push({ type: "text", text: params.fallbackResultText });
|
|
1678
|
-
}
|
|
1679
|
-
return finalContent;
|
|
1680
|
-
}
|
|
1681
|
-
/**
|
|
1682
|
-
* Merge tool-call blocks from the active partial-message builder into the
|
|
1683
|
-
* running list of intermediate tool calls, preserving order and de-duping
|
|
1684
|
-
* by tool-call id. Exposed for testing the F3 fix (final-turn tool calls
|
|
1685
|
-
* dropped when `result` arrives without a preceding synthetic `user`).
|
|
1686
|
-
*/
|
|
1687
|
-
export function mergePendingToolCalls(intermediate, pending) {
|
|
1688
|
-
const alreadyIncluded = new Set();
|
|
1689
|
-
for (const block of intermediate) {
|
|
1690
|
-
if (block.type === "toolCall")
|
|
1691
|
-
alreadyIncluded.add(block.id);
|
|
1692
|
-
}
|
|
1693
|
-
for (const block of pending) {
|
|
1694
|
-
if (block.type !== "toolCall")
|
|
1695
|
-
continue;
|
|
1696
|
-
if (alreadyIncluded.has(block.id))
|
|
1697
|
-
continue;
|
|
1698
|
-
alreadyIncluded.add(block.id);
|
|
1699
|
-
intermediate.push(block);
|
|
1700
|
-
}
|
|
1701
|
-
return intermediate;
|
|
1702
|
-
}
|
|
1703
|
-
export function handleClaudeCodePartialStreamEvent(builder, event, modelId) {
|
|
1704
|
-
if (event.type === "message_start") {
|
|
1705
|
-
// Claude Code can emit repeated SDK message_start events inside one
|
|
1706
|
-
// logical assistant response. Keep appending until a synthetic user
|
|
1707
|
-
// tool-result boundary explicitly clears the builder.
|
|
1708
|
-
return {
|
|
1709
|
-
builder: builder ?? new PartialMessageBuilder(event.message?.model ?? modelId),
|
|
1710
|
-
assistantEvent: null,
|
|
1711
|
-
};
|
|
1712
|
-
}
|
|
1713
|
-
if (!builder)
|
|
1714
|
-
return { builder, assistantEvent: null };
|
|
1715
|
-
return { builder, assistantEvent: builder.handleEvent(event) };
|
|
1716
|
-
}
|
|
1717
1579
|
// ---------------------------------------------------------------------------
|
|
1718
1580
|
// streamSimple implementation
|
|
1719
1581
|
// ---------------------------------------------------------------------------
|