gsd-pi 2.80.0-dev.42bd34838 → 2.80.0-dev.488219eb6
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/claude-cli-check.d.ts +30 -0
- package/dist/claude-cli-check.js +18 -7
- package/dist/cli.js +0 -19
- package/dist/headless-query.d.ts +10 -0
- package/dist/headless-query.js +6 -4
- package/dist/loader-entrypoint.d.ts +8 -0
- package/dist/loader-entrypoint.js +27 -0
- package/dist/loader.js +2 -11
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +6 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
- package/dist/resources/extensions/github-sync/sync.js +4 -1
- package/dist/resources/extensions/gsd/auto/loop.js +71 -8
- package/dist/resources/extensions/gsd/auto/phases.js +179 -99
- package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +10 -30
- package/dist/resources/extensions/gsd/auto/session.js +8 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +94 -76
- package/dist/resources/extensions/gsd/auto-prompts.js +90 -15
- package/dist/resources/extensions/gsd/auto-start.js +238 -12
- package/dist/resources/extensions/gsd/auto-worktree.js +209 -81
- package/dist/resources/extensions/gsd/auto.js +95 -44
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +96 -26
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +6 -3
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +298 -54
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
- package/dist/resources/extensions/gsd/commands-config.js +1 -1
- package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +37 -1
- package/dist/resources/extensions/gsd/guided-flow.js +61 -32
- package/dist/resources/extensions/gsd/init-wizard.js +4 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +57 -5
- package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
- 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 +2 -2
- package/dist/web/standalone/.next/required-server-files.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- 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/page_client-reference-manifest.js +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 +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- 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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
- 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/middleware.js +3 -3
- 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/8359.e059d86b255fce1c.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.d.ts +2 -0
- package/dist/welcome-screen.js +9 -7
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +9 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +8 -0
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +14 -0
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +9 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
- package/packages/pi-ai/src/providers/anthropic.ts +22 -9
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +36 -7
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -6
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +3 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +34 -3
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
- package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
- package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +153 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +18 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +23 -5
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +19 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +23 -5
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +40 -7
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +3 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +5 -5
- package/packages/pi-coding-agent/src/core/extensions/types.ts +37 -2
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
- package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
- package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
- package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
- package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
- package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
- package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
- package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +177 -8
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +24 -5
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +21 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +25 -8
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
- package/src/resources/extensions/github-sync/sync.ts +8 -1
- package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
- package/src/resources/extensions/gsd/auto/loop.ts +84 -8
- package/src/resources/extensions/gsd/auto/phases.ts +258 -159
- package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -29
- package/src/resources/extensions/gsd/auto/session.ts +8 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +107 -78
- package/src/resources/extensions/gsd/auto-prompts.ts +95 -14
- package/src/resources/extensions/gsd/auto-start.ts +286 -15
- package/src/resources/extensions/gsd/auto-worktree.ts +241 -72
- package/src/resources/extensions/gsd/auto.ts +132 -40
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +116 -24
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -3
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +347 -54
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
- package/src/resources/extensions/gsd/commands-config.ts +1 -1
- package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +41 -2
- package/src/resources/extensions/gsd/guided-flow.ts +71 -39
- package/src/resources/extensions/gsd/init-wizard.ts +5 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -4
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +361 -10
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +106 -0
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
- package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
- package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +35 -31
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
- package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -125
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
- package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -97
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +33 -47
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +140 -3
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
- package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/worktree-resolver.ts +83 -5
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
- package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
- /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tht0ltP8EIjsohPOA_WZf → G68KoLv5claox_Dyd4pZn}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// GSD-2 - Shared target metadata for tool output rendering.
|
|
2
|
+
|
|
3
|
+
export type ToolTargetKind = "file" | "directory" | "search" | "command";
|
|
4
|
+
|
|
5
|
+
export type ToolTargetAction = "read" | "write" | "edit" | "list" | "find" | "grep" | "bash";
|
|
6
|
+
|
|
7
|
+
export interface ToolTargetRange {
|
|
8
|
+
start: number;
|
|
9
|
+
end?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ToolTargetMetadata {
|
|
13
|
+
kind: ToolTargetKind;
|
|
14
|
+
action: ToolTargetAction;
|
|
15
|
+
inputPath?: string;
|
|
16
|
+
resolvedPath?: string;
|
|
17
|
+
pattern?: string;
|
|
18
|
+
glob?: string;
|
|
19
|
+
line?: number;
|
|
20
|
+
range?: ToolTargetRange;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function createToolTarget(target: ToolTargetMetadata): ToolTargetMetadata {
|
|
24
|
+
return target;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createReadFileTarget(
|
|
28
|
+
inputPath: string,
|
|
29
|
+
resolvedPath: string,
|
|
30
|
+
offset?: number,
|
|
31
|
+
limit?: number,
|
|
32
|
+
): ToolTargetMetadata {
|
|
33
|
+
const effectiveOffset = Math.max(1, offset ?? 1);
|
|
34
|
+
|
|
35
|
+
return createToolTarget({
|
|
36
|
+
kind: "file",
|
|
37
|
+
action: "read",
|
|
38
|
+
inputPath,
|
|
39
|
+
resolvedPath,
|
|
40
|
+
range:
|
|
41
|
+
offset !== undefined || limit !== undefined
|
|
42
|
+
? {
|
|
43
|
+
start: effectiveOffset,
|
|
44
|
+
end: limit !== undefined ? effectiveOffset + Math.max(0, limit - 1) : undefined,
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -4,6 +4,7 @@ import { mkdir as fsMkdir, writeFile as fsWriteFile } from "fs/promises";
|
|
|
4
4
|
import { dirname } from "path";
|
|
5
5
|
import { notifyFileChanged } from "../lsp/client.js";
|
|
6
6
|
import { resolveToCwd } from "./path-utils.js";
|
|
7
|
+
import { createToolTarget, type ToolTargetMetadata } from "./tool-target.js";
|
|
7
8
|
|
|
8
9
|
const writeSchema = Type.Object({
|
|
9
10
|
path: Type.String({ description: "Path to the file to write (relative or absolute)" }),
|
|
@@ -12,6 +13,10 @@ const writeSchema = Type.Object({
|
|
|
12
13
|
|
|
13
14
|
export type WriteToolInput = Static<typeof writeSchema>;
|
|
14
15
|
|
|
16
|
+
export interface WriteToolDetails {
|
|
17
|
+
target?: ToolTargetMetadata;
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* Pluggable operations for the write tool.
|
|
17
22
|
* Override these to delegate file writing to remote systems (e.g., SSH).
|
|
@@ -50,7 +55,7 @@ export function createWriteTool(cwd: string, options?: WriteToolOptions): AgentT
|
|
|
50
55
|
const absolutePath = resolveToCwd(path, cwd);
|
|
51
56
|
const dir = dirname(absolutePath);
|
|
52
57
|
|
|
53
|
-
return new Promise<{ content: Array<{ type: "text"; text: string }>; details: undefined }>(
|
|
58
|
+
return new Promise<{ content: Array<{ type: "text"; text: string }>; details: WriteToolDetails | undefined }>(
|
|
54
59
|
(resolve, reject) => {
|
|
55
60
|
// Check if already aborted
|
|
56
61
|
if (signal?.aborted) {
|
|
@@ -98,7 +103,14 @@ export function createWriteTool(cwd: string, options?: WriteToolOptions): AgentT
|
|
|
98
103
|
|
|
99
104
|
resolve({
|
|
100
105
|
content: [{ type: "text", text: `Successfully wrote ${content.length} bytes to ${path}` }],
|
|
101
|
-
details:
|
|
106
|
+
details: {
|
|
107
|
+
target: createToolTarget({
|
|
108
|
+
kind: "file",
|
|
109
|
+
action: "write",
|
|
110
|
+
inputPath: path,
|
|
111
|
+
resolvedPath: absolutePath,
|
|
112
|
+
}),
|
|
113
|
+
},
|
|
102
114
|
});
|
|
103
115
|
} catch (error: any) {
|
|
104
116
|
// Clean up abort handler
|
package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts
CHANGED
|
@@ -113,10 +113,124 @@ describe("ToolExecutionComponent", () => {
|
|
|
113
113
|
assert.deepEqual(component.getRollupPhase()?.label, "Other tool actions");
|
|
114
114
|
});
|
|
115
115
|
|
|
116
|
+
test("renders compact read rows with target metadata", () => {
|
|
117
|
+
const rendered = renderToolCollapsed(
|
|
118
|
+
"read",
|
|
119
|
+
{ path: "src/Inspector.tsx" },
|
|
120
|
+
{
|
|
121
|
+
content: [{ type: "text", text: "source" }],
|
|
122
|
+
isError: false,
|
|
123
|
+
details: {
|
|
124
|
+
target: {
|
|
125
|
+
kind: "file",
|
|
126
|
+
action: "read",
|
|
127
|
+
inputPath: "src/Inspector.tsx",
|
|
128
|
+
resolvedPath: "/tmp/project/src/Inspector.tsx",
|
|
129
|
+
range: { start: 4, end: 12 },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
assert.match(rendered, /read .*src\/Inspector\.tsx:4-12/);
|
|
136
|
+
assert.doesNotMatch(rendered, /source/);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("renders compact edit rows with target metadata", () => {
|
|
140
|
+
const rendered = renderToolCollapsed(
|
|
141
|
+
"edit",
|
|
142
|
+
{ path: "src/Inspector.tsx" },
|
|
143
|
+
{
|
|
144
|
+
content: [{ type: "text", text: "Updated src/Inspector.tsx" }],
|
|
145
|
+
isError: false,
|
|
146
|
+
details: {
|
|
147
|
+
target: {
|
|
148
|
+
kind: "file",
|
|
149
|
+
action: "edit",
|
|
150
|
+
inputPath: "src/Inspector.tsx",
|
|
151
|
+
resolvedPath: "/tmp/project/src/Inspector.tsx",
|
|
152
|
+
line: 42,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
assert.match(rendered, /edit .*src\/Inspector\.tsx:42/);
|
|
159
|
+
assert.doesNotMatch(rendered, /Updated src\/Inspector\.tsx/);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("renders compact write rows with target metadata", () => {
|
|
163
|
+
const rendered = renderToolCollapsed(
|
|
164
|
+
"write",
|
|
165
|
+
{ path: "src/output.ts", content: "ok" },
|
|
166
|
+
{
|
|
167
|
+
content: [{ type: "text", text: "Successfully wrote 2 bytes to src/output.ts" }],
|
|
168
|
+
isError: false,
|
|
169
|
+
details: {
|
|
170
|
+
target: {
|
|
171
|
+
kind: "file",
|
|
172
|
+
action: "write",
|
|
173
|
+
inputPath: "src/output.ts",
|
|
174
|
+
resolvedPath: "/tmp/project/src/output.ts",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
assert.match(rendered, /write .*src\/output\.ts/);
|
|
181
|
+
assert.doesNotMatch(rendered, /Successfully wrote/);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("renders compact bash rows with command preview", () => {
|
|
185
|
+
const rendered = renderToolCollapsed(
|
|
186
|
+
"bash",
|
|
187
|
+
{ command: "npm run typecheck -- --watch false" },
|
|
188
|
+
{ content: [{ type: "text", text: "ok" }], isError: false, details: { cwd: "/tmp/project" } },
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
assert.match(rendered, /bash npm run typecheck -- --watch false/);
|
|
192
|
+
assert.doesNotMatch(rendered, /\bok\b/);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("keeps failed tools expanded and error visible", () => {
|
|
196
|
+
const rendered = renderToolCollapsed(
|
|
197
|
+
"edit",
|
|
198
|
+
{ path: "src/Inspector.tsx" },
|
|
199
|
+
{
|
|
200
|
+
content: [{ type: "text", text: "Could not find target text" }],
|
|
201
|
+
isError: true,
|
|
202
|
+
details: {
|
|
203
|
+
target: {
|
|
204
|
+
kind: "file",
|
|
205
|
+
action: "edit",
|
|
206
|
+
inputPath: "src/Inspector.tsx",
|
|
207
|
+
resolvedPath: "/tmp/project/src/Inspector.tsx",
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
assert.match(rendered, /Could not find target text/);
|
|
214
|
+
assert.match(rendered, /edit/);
|
|
215
|
+
});
|
|
216
|
+
|
|
116
217
|
test("renders phase-based summaries for rolled-up tool executions", () => {
|
|
117
218
|
const phases: ToolExecutionPhase[] = [
|
|
118
219
|
{ label: "Setup / shell", count: 6, durationMs: 12 },
|
|
119
|
-
{
|
|
220
|
+
{
|
|
221
|
+
label: "Context reads",
|
|
222
|
+
count: 4,
|
|
223
|
+
durationMs: 6,
|
|
224
|
+
actionLabel: "read",
|
|
225
|
+
targets: ["/tmp/project/src/a.ts", "/tmp/project/src/b.ts"],
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
label: "File changes",
|
|
229
|
+
count: 3,
|
|
230
|
+
durationMs: 5,
|
|
231
|
+
actionLabel: "edit",
|
|
232
|
+
targets: ["/tmp/project/src/Inspector.tsx:42", "/tmp/project/src/CompareView.tsx:8"],
|
|
233
|
+
},
|
|
120
234
|
{ label: "Requirement writes", count: 4, durationMs: 4 },
|
|
121
235
|
{ label: "Memory lookups", count: 4, durationMs: 4 },
|
|
122
236
|
{ label: "Finalization", count: 1, durationMs: 1 },
|
|
@@ -124,7 +238,10 @@ describe("ToolExecutionComponent", () => {
|
|
|
124
238
|
const rendered = stripAnsi(new ToolPhaseSummaryComponent(phases).render(120).join("\n"));
|
|
125
239
|
|
|
126
240
|
assert.match(rendered, /Setup \/ shell 6 actions\s+success · 12ms/);
|
|
127
|
-
assert.match(rendered, /Context reads
|
|
241
|
+
assert.match(rendered, /Context reads · 2 files\s+success · 6ms/);
|
|
242
|
+
assert.match(rendered, /src\/a\.ts/);
|
|
243
|
+
assert.match(rendered, /File changes · 2 files, 3 edits\s+success · 5ms/);
|
|
244
|
+
assert.match(rendered, /src\/Inspector\.tsx:42/);
|
|
128
245
|
assert.match(rendered, /Requirement writes 4 actions\s+success · 4ms/);
|
|
129
246
|
assert.match(rendered, /Memory lookups 4 actions\s+success · 4ms/);
|
|
130
247
|
assert.match(rendered, /Finalization 1 action\s+success · 1ms/);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Runtime tests for TUI tool cards, success notifications, and blocking errors.
|
|
1
3
|
// GSD2 TUI Tests - Runtime coverage for tool-card cleanup and success notification rendering.
|
|
2
4
|
// Runtime regression tests for the post-compaction tool-card cleanup and the
|
|
3
5
|
// green-bordered success-notification rendering. Replaces the source-grep
|
|
@@ -18,7 +20,7 @@ import { Container, Text } from "@gsd/pi-tui";
|
|
|
18
20
|
import stripAnsi from "strip-ansi";
|
|
19
21
|
|
|
20
22
|
import { initTheme, theme } from "../theme/theme.js";
|
|
21
|
-
import { renderExtensionNotifyInChat, shouldRenderExtensionNotifyInChat } from "../interactive-mode.js";
|
|
23
|
+
import { renderBlockingErrorBanner, renderExtensionNotifyInChat, shouldRenderExtensionNotifyInChat } from "../interactive-mode.js";
|
|
22
24
|
import { DynamicBorder } from "./dynamic-border.js";
|
|
23
25
|
import { ToolExecutionComponent } from "./tool-execution.js";
|
|
24
26
|
|
|
@@ -58,6 +60,34 @@ describe("Extension warning notifications", () => {
|
|
|
58
60
|
});
|
|
59
61
|
});
|
|
60
62
|
|
|
63
|
+
describe("Blocking error banner", () => {
|
|
64
|
+
it("keeps full error notifications renderable outside chat history", () => {
|
|
65
|
+
const banner = new Container();
|
|
66
|
+
const message = [
|
|
67
|
+
"Pre-execution checks failed: 3 blocking issues found",
|
|
68
|
+
" - [file] lib/types.ts: Task T01 references 'lib/types.ts'",
|
|
69
|
+
"See .gsd/milestones/M001/slices/S02/S02-PRE-EXEC-VERIFY.json for full details.",
|
|
70
|
+
].join("\n");
|
|
71
|
+
|
|
72
|
+
renderBlockingErrorBanner(banner, message);
|
|
73
|
+
|
|
74
|
+
const rendered = banner.render(140).map(stripAnsi).join("\n");
|
|
75
|
+
assert.match(rendered, /Error: Pre-execution checks failed: 3 blocking issues found/);
|
|
76
|
+
assert.match(rendered, /Task T01 references 'lib\/types\.ts'/);
|
|
77
|
+
assert.match(rendered, /S02-PRE-EXEC-VERIFY\.json/);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("clears the sticky banner when the blocking error is cleared", () => {
|
|
81
|
+
const banner = new Container();
|
|
82
|
+
|
|
83
|
+
renderBlockingErrorBanner(banner, "Provider failed");
|
|
84
|
+
assert.match(banner.render(80).map(stripAnsi).join("\n"), /Provider failed/);
|
|
85
|
+
|
|
86
|
+
renderBlockingErrorBanner(banner, undefined);
|
|
87
|
+
assert.equal(banner.render(80).map(stripAnsi).join("\n"), "");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
61
91
|
interface MockTui {
|
|
62
92
|
renderCount: number;
|
|
63
93
|
requestRender(): void;
|
|
@@ -111,9 +111,10 @@ function renderToolFrame(
|
|
|
111
111
|
const statusColor = opts.tone === "error" ? "toolError" : opts.tone === "pending" ? "toolRunning" : "toolSuccess";
|
|
112
112
|
const leftStyled = theme.fg(labelColor, theme.bold(opts.label));
|
|
113
113
|
const rightStyled = theme.fg(statusColor, opts.status);
|
|
114
|
-
const
|
|
114
|
+
const titleWidth = Math.max(1, outerWidth - 4);
|
|
115
|
+
const gap = Math.max(1, titleWidth - visibleWidth(leftStyled) - visibleWidth(rightStyled));
|
|
115
116
|
const headerRow = `${leftStyled}${" ".repeat(gap)}${rightStyled}`;
|
|
116
|
-
const headerPad = Math.max(0,
|
|
117
|
+
const headerPad = Math.max(0, titleWidth - visibleWidth(headerRow));
|
|
117
118
|
|
|
118
119
|
const sourceLines = trimOuterBlankLines(contentLines);
|
|
119
120
|
const bodyLines = (sourceLines.length > 0 ? sourceLines : [""]).map((line) => {
|
|
@@ -122,7 +123,7 @@ function renderToolFrame(
|
|
|
122
123
|
});
|
|
123
124
|
|
|
124
125
|
return style()
|
|
125
|
-
.border("
|
|
126
|
+
.border("rounded")
|
|
126
127
|
.borderColor((line) => theme.fg(line.startsWith("─") ? topColor : borderColor, line))
|
|
127
128
|
.title(headerRow + " ".repeat(headerPad))
|
|
128
129
|
.render(bodyLines, outerWidth);
|
|
@@ -157,6 +158,22 @@ export type ToolExecutionPhase = {
|
|
|
157
158
|
label: string;
|
|
158
159
|
count: number;
|
|
159
160
|
durationMs: number;
|
|
161
|
+
targets?: string[];
|
|
162
|
+
actionLabel?: string;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
type ToolTargetMetadata = {
|
|
166
|
+
kind?: string;
|
|
167
|
+
action?: string;
|
|
168
|
+
inputPath?: string;
|
|
169
|
+
resolvedPath?: string;
|
|
170
|
+
pattern?: string;
|
|
171
|
+
glob?: string;
|
|
172
|
+
line?: number;
|
|
173
|
+
range?: {
|
|
174
|
+
start?: number;
|
|
175
|
+
end?: number;
|
|
176
|
+
};
|
|
160
177
|
};
|
|
161
178
|
|
|
162
179
|
function formatElapsed(ms: number): string {
|
|
@@ -164,6 +181,104 @@ function formatElapsed(ms: number): string {
|
|
|
164
181
|
return `${Math.max(1, Math.round(ms / 1000))}s`;
|
|
165
182
|
}
|
|
166
183
|
|
|
184
|
+
function formatCommandPreview(command: string): string {
|
|
185
|
+
return truncateToWidth(command.replace(/\s+/g, " ").trim(), 64, "");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function appendLineOrRange(displayPath: string | undefined, target: ToolTargetMetadata): string | undefined {
|
|
189
|
+
if (!displayPath) return undefined;
|
|
190
|
+
if (typeof target.line === "number" && Number.isFinite(target.line)) {
|
|
191
|
+
return `${displayPath}:${target.line}`;
|
|
192
|
+
}
|
|
193
|
+
const start = target.range?.start;
|
|
194
|
+
if (typeof start === "number" && Number.isFinite(start)) {
|
|
195
|
+
const end = target.range?.end;
|
|
196
|
+
const suffix =
|
|
197
|
+
typeof end === "number" && Number.isFinite(end) && end !== start
|
|
198
|
+
? `${start}-${end}`
|
|
199
|
+
: `${start}`;
|
|
200
|
+
return `${displayPath}:${suffix}`;
|
|
201
|
+
}
|
|
202
|
+
return displayPath;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function formatToolTarget(target: ToolTargetMetadata): string | undefined {
|
|
206
|
+
const path = target.resolvedPath || target.inputPath;
|
|
207
|
+
const displayPath = path ? shortenPath(path) : undefined;
|
|
208
|
+
if (target.kind === "search") {
|
|
209
|
+
const searchTarget = displayPath ?? target.inputPath ?? ".";
|
|
210
|
+
const label = target.pattern ? `${target.pattern} in ${searchTarget}` : searchTarget;
|
|
211
|
+
return target.glob ? `${label} (${target.glob})` : label;
|
|
212
|
+
}
|
|
213
|
+
return appendLineOrRange(displayPath, target);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function formatArgsPathTarget(path: string | null, args: Record<string, unknown>): string | undefined {
|
|
217
|
+
if (!path) return undefined;
|
|
218
|
+
const start = typeof args.offset === "number" ? args.offset : undefined;
|
|
219
|
+
const limit = typeof args.limit === "number" ? args.limit : undefined;
|
|
220
|
+
const range =
|
|
221
|
+
start !== undefined || limit !== undefined
|
|
222
|
+
? {
|
|
223
|
+
start: start ?? 1,
|
|
224
|
+
end: limit !== undefined ? (start ?? 1) + Math.max(0, limit - 1) : undefined,
|
|
225
|
+
}
|
|
226
|
+
: undefined;
|
|
227
|
+
return appendLineOrRange(shortenPath(path), { range });
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function stripLineSuffix(target: string): string {
|
|
231
|
+
return target.replace(/:\d+(?:-\d+)?$/, "");
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function uniqueTargets(targets: string[] | undefined): string[] {
|
|
235
|
+
const seen = new Set<string>();
|
|
236
|
+
const unique: string[] = [];
|
|
237
|
+
for (const target of targets ?? []) {
|
|
238
|
+
if (!target || seen.has(target)) continue;
|
|
239
|
+
seen.add(target);
|
|
240
|
+
unique.push(target);
|
|
241
|
+
}
|
|
242
|
+
return unique;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function summarizePhaseLabel(phase: ToolExecutionPhase): string {
|
|
246
|
+
const phaseTargets = uniqueTargets(phase.targets);
|
|
247
|
+
const baseTargets = uniqueTargets(phaseTargets.map(stripLineSuffix));
|
|
248
|
+
if (phase.label === "File changes" && baseTargets.length > 0) {
|
|
249
|
+
const fileWord = baseTargets.length === 1 ? "file" : "files";
|
|
250
|
+
const actionWord =
|
|
251
|
+
phase.actionLabel === "write"
|
|
252
|
+
? phase.count === 1
|
|
253
|
+
? "write"
|
|
254
|
+
: "writes"
|
|
255
|
+
: phase.actionLabel === undefined
|
|
256
|
+
? phase.count === 1
|
|
257
|
+
? "action"
|
|
258
|
+
: "actions"
|
|
259
|
+
: phase.count === 1
|
|
260
|
+
? "edit"
|
|
261
|
+
: "edits";
|
|
262
|
+
return `${phase.label} · ${baseTargets.length} ${fileWord}, ${phase.count} ${actionWord}`;
|
|
263
|
+
}
|
|
264
|
+
if (phase.label === "Context reads" && baseTargets.length > 0) {
|
|
265
|
+
const fileWord = baseTargets.length === 1 ? "file" : "files";
|
|
266
|
+
return `${phase.label} · ${baseTargets.length} ${fileWord}`;
|
|
267
|
+
}
|
|
268
|
+
if (phase.label === "Setup / shell" && phaseTargets.length > 0) {
|
|
269
|
+
return `${phase.label} · ${phase.count} ${phase.count === 1 ? "command" : "commands"}`;
|
|
270
|
+
}
|
|
271
|
+
return `${phase.label} ${phase.count} ${phase.count === 1 ? "action" : "actions"}`;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function summarizePhaseTargets(phase: ToolExecutionPhase, width: number): string | undefined {
|
|
275
|
+
const phaseTargets = uniqueTargets(phase.targets);
|
|
276
|
+
if (phaseTargets.length === 0) return undefined;
|
|
277
|
+
const shown = phaseTargets.slice(0, 3);
|
|
278
|
+
const suffix = phaseTargets.length > shown.length ? ` +${phaseTargets.length - shown.length} more` : "";
|
|
279
|
+
return truncateToWidth(shown.join(" · ") + suffix, width, "");
|
|
280
|
+
}
|
|
281
|
+
|
|
167
282
|
/**
|
|
168
283
|
* Format tool args for the generic-renderer fallback. Produces a one-line
|
|
169
284
|
* `k=v, k=v` summary when every value is a primitive that fits inline; falls
|
|
@@ -607,10 +722,13 @@ export class ToolExecutionComponent extends Container {
|
|
|
607
722
|
if (!this.shouldRenderCompactSuccess()) return null;
|
|
608
723
|
const label = this.getPhaseLabel();
|
|
609
724
|
const endedAt = this.endedAt ?? Date.now();
|
|
725
|
+
const target = this.getCompactTarget();
|
|
610
726
|
return {
|
|
611
727
|
label,
|
|
612
728
|
count: 1,
|
|
613
729
|
durationMs: Math.max(0, endedAt - this.startedAt),
|
|
730
|
+
targets: target ? [target] : undefined,
|
|
731
|
+
actionLabel: this.getCompactAction(),
|
|
614
732
|
};
|
|
615
733
|
}
|
|
616
734
|
|
|
@@ -631,7 +749,52 @@ export class ToolExecutionComponent extends Container {
|
|
|
631
749
|
}
|
|
632
750
|
|
|
633
751
|
private getCompactSummary(frameLabel: string): string {
|
|
634
|
-
|
|
752
|
+
if (this.normalizedToolName === "bash") {
|
|
753
|
+
const command = str(this.args?.command);
|
|
754
|
+
return command ? `bash ${formatCommandPreview(command)}` : frameLabel;
|
|
755
|
+
}
|
|
756
|
+
const target = this.getCompactTarget();
|
|
757
|
+
return target ? `${this.getCompactAction()} ${target}` : frameLabel;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
private getCompactAction(): string {
|
|
761
|
+
const target = this.getTargetMetadata();
|
|
762
|
+
if (target?.action) return target.action === "list" ? "ls" : target.action;
|
|
763
|
+
return this.normalizedToolName;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
private getTargetMetadata(): ToolTargetMetadata | undefined {
|
|
767
|
+
const target = this.result?.details?.target;
|
|
768
|
+
return target && typeof target === "object" ? target : undefined;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
private getCompactTarget(): string | undefined {
|
|
772
|
+
const metadata = this.getTargetMetadata();
|
|
773
|
+
const metadataTarget = metadata ? formatToolTarget(metadata) : undefined;
|
|
774
|
+
if (metadataTarget) return metadataTarget;
|
|
775
|
+
|
|
776
|
+
const path = str(this.args?.file_path ?? this.args?.path);
|
|
777
|
+
if (path === null) return undefined;
|
|
778
|
+
if (this.normalizedToolName === "read" || this.normalizedToolName === "hashline_read") {
|
|
779
|
+
return formatArgsPathTarget(path, this.args);
|
|
780
|
+
}
|
|
781
|
+
if (this.normalizedToolName === "write" || this.normalizedToolName === "edit") {
|
|
782
|
+
return path ? shortenPath(path) : undefined;
|
|
783
|
+
}
|
|
784
|
+
if (this.normalizedToolName === "ls") {
|
|
785
|
+
return shortenPath(path || ".");
|
|
786
|
+
}
|
|
787
|
+
if (this.normalizedToolName === "find") {
|
|
788
|
+
const pattern = str(this.args?.pattern);
|
|
789
|
+
return pattern ? `${pattern} in ${shortenPath(path || ".")}` : shortenPath(path || ".");
|
|
790
|
+
}
|
|
791
|
+
if (this.normalizedToolName === "grep") {
|
|
792
|
+
const pattern = str(this.args?.pattern);
|
|
793
|
+
const glob = str(this.args?.glob);
|
|
794
|
+
const label = pattern ? `${pattern} in ${shortenPath(path || ".")}` : shortenPath(path || ".");
|
|
795
|
+
return glob ? `${label} (${glob})` : label;
|
|
796
|
+
}
|
|
797
|
+
return undefined;
|
|
635
798
|
}
|
|
636
799
|
|
|
637
800
|
private updateDisplay(): void {
|
|
@@ -861,6 +1024,10 @@ export class ToolExecutionComponent extends Container {
|
|
|
861
1024
|
// Truncation warnings
|
|
862
1025
|
const truncation = this.result.details?.truncation;
|
|
863
1026
|
const fullOutputPath = this.result.details?.fullOutputPath;
|
|
1027
|
+
const cwd = this.result.details?.cwd;
|
|
1028
|
+
if (this.expanded && typeof cwd === "string" && cwd.length > 0) {
|
|
1029
|
+
this.contentBox.addChild(new Text(`\n${theme.fg("muted", `cwd ${shortenPath(cwd)}`)}`, 0, 0));
|
|
1030
|
+
}
|
|
864
1031
|
if (truncation?.truncated || fullOutputPath) {
|
|
865
1032
|
const warnings: string[] = [];
|
|
866
1033
|
if (fullOutputPath) {
|
|
@@ -1288,19 +1455,21 @@ export class ToolPhaseSummaryComponent extends Container {
|
|
|
1288
1455
|
}
|
|
1289
1456
|
|
|
1290
1457
|
getPhases(): ToolExecutionPhase[] {
|
|
1291
|
-
return this.phases.map((phase) => ({ ...phase }));
|
|
1458
|
+
return this.phases.map((phase) => ({ ...phase, targets: phase.targets ? [...phase.targets] : undefined }));
|
|
1292
1459
|
}
|
|
1293
1460
|
|
|
1294
1461
|
override render(width: number): string[] {
|
|
1295
1462
|
const frameWidth = Math.max(20, width);
|
|
1296
|
-
const rows = this.phases.
|
|
1297
|
-
const left =
|
|
1463
|
+
const rows = this.phases.flatMap((phase) => {
|
|
1464
|
+
const left = summarizePhaseLabel(phase);
|
|
1298
1465
|
const right = `success · ${formatElapsed(phase.durationMs)}`;
|
|
1299
1466
|
const contentWidth = Math.max(1, frameWidth - 2);
|
|
1300
1467
|
const leftWidth = Math.max(1, contentWidth - visibleWidth(right) - 1);
|
|
1301
1468
|
const leftText = truncateToWidth(left, leftWidth, "");
|
|
1302
1469
|
const gap = Math.max(1, contentWidth - visibleWidth(leftText) - visibleWidth(right));
|
|
1303
|
-
|
|
1470
|
+
const summaryRow = `${theme.fg("toolSuccess", leftText)}${" ".repeat(gap)}${theme.fg("toolSuccess", right)}`;
|
|
1471
|
+
const targetRow = summarizePhaseTargets(phase, contentWidth);
|
|
1472
|
+
return targetRow ? [summaryRow, theme.fg("muted", targetRow)] : [summaryRow];
|
|
1304
1473
|
});
|
|
1305
1474
|
|
|
1306
1475
|
return ["", ...style().border("minimal").borderColor((text) => theme.fg("toolSuccess", text)).render(rows, frameWidth)];
|
|
@@ -146,24 +146,43 @@ test("handleAgentEvent: standalone completed tool events roll up incrementally",
|
|
|
146
146
|
["read-2", "read"],
|
|
147
147
|
["edit-1", "edit"],
|
|
148
148
|
] as const) {
|
|
149
|
+
const target =
|
|
150
|
+
toolName === "edit"
|
|
151
|
+
? {
|
|
152
|
+
kind: "file",
|
|
153
|
+
action: "edit",
|
|
154
|
+
inputPath: `src/${toolCallId}.txt`,
|
|
155
|
+
resolvedPath: `/tmp/project/src/${toolCallId}.txt`,
|
|
156
|
+
line: 10,
|
|
157
|
+
}
|
|
158
|
+
: {
|
|
159
|
+
kind: "file",
|
|
160
|
+
action: "read",
|
|
161
|
+
inputPath: `src/${toolCallId}.txt`,
|
|
162
|
+
resolvedPath: `/tmp/project/src/${toolCallId}.txt`,
|
|
163
|
+
};
|
|
149
164
|
await handleAgentEvent(host, {
|
|
150
165
|
type: "tool_execution_start",
|
|
151
166
|
toolCallId,
|
|
152
167
|
toolName,
|
|
153
|
-
args: { path:
|
|
168
|
+
args: { path: `src/${toolCallId}.txt` },
|
|
154
169
|
} as any);
|
|
155
170
|
await handleAgentEvent(host, {
|
|
156
171
|
type: "tool_execution_end",
|
|
157
172
|
toolCallId,
|
|
158
173
|
toolName,
|
|
159
|
-
result: { content: [], isError: false },
|
|
174
|
+
result: { content: [], details: { target }, isError: false },
|
|
160
175
|
isError: false,
|
|
161
176
|
} as any);
|
|
162
177
|
}
|
|
163
178
|
|
|
164
179
|
const rendered = stripAnsi(chatContainer.render(100).join("\n"));
|
|
165
|
-
assert.match(rendered, /Context reads 2
|
|
166
|
-
assert.match(rendered, /
|
|
167
|
-
assert.
|
|
180
|
+
assert.match(rendered, /Context reads · 2 files\s+success · \d+(ms|s)/);
|
|
181
|
+
assert.match(rendered, /src\/read-1\.txt/);
|
|
182
|
+
assert.match(rendered, /src\/read-2\.txt/);
|
|
183
|
+
assert.match(rendered, /File changes · 1 file, 1 edit\s+success · \d+(ms|s)/);
|
|
184
|
+
assert.match(rendered, /src\/edit-1\.txt:10/);
|
|
185
|
+
assert.doesNotMatch(rendered, /^\s*│?\s*read\s+success ·/m);
|
|
186
|
+
assert.doesNotMatch(rendered, /^\s*│?\s*edit\s+success ·/m);
|
|
168
187
|
assert.ok(renderCount > 0);
|
|
169
188
|
});
|
|
@@ -113,13 +113,29 @@ function mergeToolPhases(phases: ToolExecutionPhase[]): ToolExecutionPhase[] {
|
|
|
113
113
|
if (previous?.label === phase.label) {
|
|
114
114
|
previous.count += phase.count;
|
|
115
115
|
previous.durationMs += phase.durationMs;
|
|
116
|
+
previous.targets = mergeTargets(previous.targets, phase.targets);
|
|
117
|
+
if (previous.actionLabel !== phase.actionLabel) {
|
|
118
|
+
previous.actionLabel = undefined;
|
|
119
|
+
}
|
|
116
120
|
} else {
|
|
117
|
-
merged.push({ ...phase });
|
|
121
|
+
merged.push({ ...phase, targets: phase.targets ? [...phase.targets] : undefined });
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
return merged;
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
function mergeTargets(existing: string[] | undefined, incoming: string[] | undefined): string[] | undefined {
|
|
128
|
+
if (!existing && !incoming) return undefined;
|
|
129
|
+
const seen = new Set<string>();
|
|
130
|
+
const merged: string[] = [];
|
|
131
|
+
for (const target of [...(existing ?? []), ...(incoming ?? [])]) {
|
|
132
|
+
if (!target || seen.has(target)) continue;
|
|
133
|
+
seen.add(target);
|
|
134
|
+
merged.push(target);
|
|
135
|
+
}
|
|
136
|
+
return merged;
|
|
137
|
+
}
|
|
138
|
+
|
|
123
139
|
function replaceCompactToolRowsWithPhaseSummary(
|
|
124
140
|
host: InteractiveModeStateHost & { ui: { requestRender: () => void } },
|
|
125
141
|
): void {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Interactive TUI mode and session UI rendering.
|
|
3
|
+
// GSD2 - Interactive TUI mode for coding-agent sessions.
|
|
1
4
|
/**
|
|
2
5
|
* Interactive mode for the coding agent.
|
|
3
6
|
* Handles TUI rendering and user interaction, delegating business logic to AgentSession.
|
|
@@ -212,6 +215,14 @@ export function renderExtensionNotifyInChat(
|
|
|
212
215
|
return { rendered: true, statusSpacer: spacer, statusText };
|
|
213
216
|
}
|
|
214
217
|
|
|
218
|
+
export function renderBlockingErrorBanner(container: Container, message: string | undefined): void {
|
|
219
|
+
container.clear();
|
|
220
|
+
if (message === undefined) return;
|
|
221
|
+
|
|
222
|
+
container.addChild(new Spacer(1));
|
|
223
|
+
container.addChild(new Text(theme.fg("error", `Error: ${message}`), 1, 0));
|
|
224
|
+
}
|
|
225
|
+
|
|
215
226
|
/**
|
|
216
227
|
* Options for InteractiveMode initialization.
|
|
217
228
|
*/
|
|
@@ -250,6 +261,7 @@ export class InteractiveMode {
|
|
|
250
261
|
private adaptiveLayout: AdaptiveLayoutComponent;
|
|
251
262
|
private statusContainer: Container;
|
|
252
263
|
private pinnedMessageContainer: Container;
|
|
264
|
+
private blockingErrorContainer: Container;
|
|
253
265
|
private defaultEditor: CustomEditor;
|
|
254
266
|
private editor: EditorComponent;
|
|
255
267
|
private autocompleteProvider: CombinedAutocompleteProvider | undefined;
|
|
@@ -380,6 +392,7 @@ export class InteractiveMode {
|
|
|
380
392
|
}));
|
|
381
393
|
this.statusContainer = new Container();
|
|
382
394
|
this.pinnedMessageContainer = new Container();
|
|
395
|
+
this.blockingErrorContainer = new Container();
|
|
383
396
|
this.widgetContainerAbove = new Container();
|
|
384
397
|
this.widgetContainerBelow = new Container();
|
|
385
398
|
this.keybindings = KeybindingsManager.create();
|
|
@@ -587,6 +600,7 @@ export class InteractiveMode {
|
|
|
587
600
|
this.ui.addChild(this.pendingMessagesContainer);
|
|
588
601
|
this.ui.addChild(this.statusContainer);
|
|
589
602
|
this.ui.addChild(this.pinnedMessageContainer);
|
|
603
|
+
this.ui.addChild(this.blockingErrorContainer);
|
|
590
604
|
this.renderWidgets(); // Initialize with default spacer
|
|
591
605
|
this.ui.addChild(this.widgetContainerAbove);
|
|
592
606
|
this.ui.addChild(this.editorContainer);
|
|
@@ -1891,6 +1905,10 @@ export class InteractiveMode {
|
|
|
1891
1905
|
* Show a notification for extensions.
|
|
1892
1906
|
*/
|
|
1893
1907
|
private showExtensionNotify(message: string, type?: ExtensionNotifyType): void {
|
|
1908
|
+
if (type === "error") {
|
|
1909
|
+
this.lastBlockingError = message;
|
|
1910
|
+
renderBlockingErrorBanner(this.blockingErrorContainer, this.lastBlockingError);
|
|
1911
|
+
}
|
|
1894
1912
|
const result = renderExtensionNotifyInChat(this.chatContainer, message, type);
|
|
1895
1913
|
if (!result.rendered) {
|
|
1896
1914
|
return;
|
|
@@ -2897,6 +2915,7 @@ export class InteractiveMode {
|
|
|
2897
2915
|
|
|
2898
2916
|
showError(errorMessage: string): void {
|
|
2899
2917
|
this.lastBlockingError = errorMessage;
|
|
2918
|
+
renderBlockingErrorBanner(this.blockingErrorContainer, this.lastBlockingError);
|
|
2900
2919
|
this.chatContainer.addChild(new Spacer(1));
|
|
2901
2920
|
this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), 1, 0));
|
|
2902
2921
|
this.ui.requestRender();
|
|
@@ -2904,6 +2923,8 @@ export class InteractiveMode {
|
|
|
2904
2923
|
|
|
2905
2924
|
clearBlockingError(): void {
|
|
2906
2925
|
this.lastBlockingError = undefined;
|
|
2926
|
+
renderBlockingErrorBanner(this.blockingErrorContainer, undefined);
|
|
2927
|
+
this.ui.requestRender();
|
|
2907
2928
|
}
|
|
2908
2929
|
|
|
2909
2930
|
showWarning(warningMessage: string): void {
|