gsd-pi 2.81.0 → 2.82.0-dev.ed17d078d
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/README.md +60 -30
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
- package/dist/resources/extensions/gsd/auto/loop.js +111 -8
- package/dist/resources/extensions/gsd/auto/orchestrator.js +113 -6
- package/dist/resources/extensions/gsd/auto/phases.js +199 -97
- package/dist/resources/extensions/gsd/auto/run-unit.js +66 -3
- package/dist/resources/extensions/gsd/auto/session.js +9 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +182 -178
- package/dist/resources/extensions/gsd/auto-dispatch.js +14 -11
- package/dist/resources/extensions/gsd/auto-post-unit.js +7 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +11 -3
- package/dist/resources/extensions/gsd/auto-recovery.js +6 -181
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
- package/dist/resources/extensions/gsd/auto-start.js +20 -23
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
- package/dist/resources/extensions/gsd/auto-verification.js +12 -6
- package/dist/resources/extensions/gsd/auto-worktree.js +8 -0
- package/dist/resources/extensions/gsd/auto.js +386 -106
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +13 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +13 -2
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
- package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -1
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +9 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
- package/dist/resources/extensions/gsd/context-store.js +112 -0
- package/dist/resources/extensions/gsd/db-writer.js +150 -84
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
- package/dist/resources/extensions/gsd/git-service.js +2 -1
- package/dist/resources/extensions/gsd/gsd-db.js +7 -23
- package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
- package/dist/resources/extensions/gsd/health-widget.js +4 -10
- package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
- package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
- package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
- package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +6 -96
- package/dist/resources/extensions/gsd/md-importer.js +1 -1
- package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
- package/dist/resources/extensions/gsd/migrate/command.js +5 -0
- package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
- package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
- package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
- package/dist/resources/extensions/gsd/native-git-bridge.js +14 -14
- package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
- package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/dist/resources/extensions/gsd/prompts/system.md +2 -2
- package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +15 -1
- package/dist/resources/extensions/gsd/session-lock.js +40 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +131 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +247 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +87 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.js +50 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +124 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-worker.js +32 -0
- package/dist/resources/extensions/gsd/state-reconciliation/errors.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +99 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +24 -0
- package/dist/resources/extensions/gsd/state-reconciliation/spawn-gate.js +43 -0
- package/dist/resources/extensions/gsd/state-reconciliation/types.js +3 -0
- package/dist/resources/extensions/gsd/state-reconciliation.js +5 -26
- package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
- package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +722 -316
- package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
- 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 +6 -6
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- 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.js +2 -2
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- 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 +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +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/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/dist/welcome-screen.d.ts +0 -7
- package/dist/welcome-screen.js +60 -69
- package/package.json +3 -2
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/README.md +2 -0
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/index.d.ts +2 -2
- package/packages/pi-ai/dist/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/index.js +1 -1
- package/packages/pi-ai/dist/index.js.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
- package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
- package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/index.ts +7 -2
- package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +76 -9
- 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/__tests__/user-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +0 -1
- 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 +86 -82
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +113 -9
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -104
- package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
- package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +9 -6
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +5 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
- package/packages/pi-tui/src/overlay-layout.ts +10 -7
- package/packages/pi-tui/src/tui.ts +6 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +105 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +27 -26
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +46 -11
- package/src/resources/extensions/gsd/auto/loop-deps.ts +9 -5
- package/src/resources/extensions/gsd/auto/loop.ts +113 -9
- package/src/resources/extensions/gsd/auto/orchestrator.ts +118 -6
- package/src/resources/extensions/gsd/auto/phases.ts +158 -19
- package/src/resources/extensions/gsd/auto/run-unit.ts +69 -4
- package/src/resources/extensions/gsd/auto/session.ts +10 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +230 -183
- package/src/resources/extensions/gsd/auto-dispatch.ts +15 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +7 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +11 -3
- package/src/resources/extensions/gsd/auto-recovery.ts +7 -209
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +22 -22
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
- package/src/resources/extensions/gsd/auto-verification.ts +12 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -0
- package/src/resources/extensions/gsd/auto.ts +424 -106
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -6
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +12 -2
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
- package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -1
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +12 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
- package/src/resources/extensions/gsd/context-store.ts +120 -1
- package/src/resources/extensions/gsd/db-writer.ts +167 -84
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/git-service.ts +2 -0
- package/src/resources/extensions/gsd/gsd-db.ts +7 -23
- package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
- package/src/resources/extensions/gsd/health-widget.ts +6 -10
- package/src/resources/extensions/gsd/journal.ts +2 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
- package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
- package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
- package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +10 -96
- package/src/resources/extensions/gsd/md-importer.ts +1 -1
- package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
- package/src/resources/extensions/gsd/migrate/command.ts +5 -0
- package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
- package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
- package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
- package/src/resources/extensions/gsd/native-git-bridge.ts +14 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
- package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
- package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/src/resources/extensions/gsd/prompts/system.md +2 -2
- package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +18 -1
- package/src/resources/extensions/gsd/session-lock.ts +41 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +172 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +337 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +69 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +109 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/sketch-flag.ts +68 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +185 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-worker.ts +46 -0
- package/src/resources/extensions/gsd/state-reconciliation/errors.ts +67 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +142 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +27 -0
- package/src/resources/extensions/gsd/state-reconciliation/spawn-gate.ts +60 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +83 -0
- package/src/resources/extensions/gsd/state-reconciliation.ts +21 -53
- package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +729 -176
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +408 -4
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +291 -4
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +20 -5
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +28 -1
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
- package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
- package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
- package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
- package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +46 -11
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -217
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
- package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +65 -58
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +952 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +158 -58
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +572 -118
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
- package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
- package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +1151 -524
- package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
- package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1544
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → YEvjuT-fsFfYQhDSWtueS}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{drLMkgfHQ8lzS229_HWYR → YEvjuT-fsFfYQhDSWtueS}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Diff from "diff";
|
|
2
|
-
import { theme } from "../theme/theme.js";
|
|
2
|
+
import { getLanguageFromPath, highlightCode, theme } from "../theme/theme.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Parse diff line to extract prefix, line number, and content.
|
|
@@ -66,19 +66,25 @@ function renderIntraLineDiff(oldContent: string, newContent: string): { removedL
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
export interface RenderDiffOptions {
|
|
69
|
-
/** File path
|
|
69
|
+
/** File path used to choose syntax highlighting for changed content. */
|
|
70
70
|
filePath?: string;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
function syntaxLine(content: string, lang: string | undefined): string {
|
|
74
|
+
if (!lang) return content;
|
|
75
|
+
return highlightCode(content, lang)[0] ?? content;
|
|
76
|
+
}
|
|
77
|
+
|
|
73
78
|
/**
|
|
74
79
|
* Render a diff string with colored lines and intra-line change highlighting.
|
|
75
80
|
* - Context lines: dim/gray
|
|
76
81
|
* - Removed lines: red, with inverse on changed tokens
|
|
77
82
|
* - Added lines: green, with inverse on changed tokens
|
|
78
83
|
*/
|
|
79
|
-
export function renderDiff(diffText: string,
|
|
84
|
+
export function renderDiff(diffText: string, options: RenderDiffOptions = {}): string {
|
|
80
85
|
const lines = diffText.split("\n");
|
|
81
86
|
const result: string[] = [];
|
|
87
|
+
const lang = options.filePath ? getLanguageFromPath(options.filePath) : undefined;
|
|
82
88
|
|
|
83
89
|
let i = 0;
|
|
84
90
|
while (i < lines.length) {
|
|
@@ -126,19 +132,19 @@ export function renderDiff(diffText: string, _options: RenderDiffOptions = {}):
|
|
|
126
132
|
} else {
|
|
127
133
|
// Show all removed lines first, then all added lines
|
|
128
134
|
for (const removed of removedLines) {
|
|
129
|
-
result.push(theme.fg("toolDiffRemoved", `-${removed.lineNum} ${replaceTabs(removed.content)}`)
|
|
135
|
+
result.push(`${theme.fg("toolDiffRemoved", `-${removed.lineNum} `)}${syntaxLine(replaceTabs(removed.content), lang)}`);
|
|
130
136
|
}
|
|
131
137
|
for (const added of addedLines) {
|
|
132
|
-
result.push(theme.fg("toolDiffAdded", `+${added.lineNum} ${replaceTabs(added.content)}`)
|
|
138
|
+
result.push(`${theme.fg("toolDiffAdded", `+${added.lineNum} `)}${syntaxLine(replaceTabs(added.content), lang)}`);
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
141
|
} else if (parsed.prefix === "+") {
|
|
136
142
|
// Standalone added line
|
|
137
|
-
result.push(theme.fg("toolDiffAdded", `+${parsed.lineNum} ${replaceTabs(parsed.content)}`)
|
|
143
|
+
result.push(`${theme.fg("toolDiffAdded", `+${parsed.lineNum} `)}${syntaxLine(replaceTabs(parsed.content), lang)}`);
|
|
138
144
|
i++;
|
|
139
145
|
} else {
|
|
140
146
|
// Context line
|
|
141
|
-
result.push(theme.fg("toolDiffContext", ` ${parsed.lineNum} ${replaceTabs(parsed.content)}`)
|
|
147
|
+
result.push(`${theme.fg("toolDiffContext", ` ${parsed.lineNum} `)}${syntaxLine(replaceTabs(parsed.content), lang)}`);
|
|
142
148
|
i++;
|
|
143
149
|
}
|
|
144
150
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Interactive terminal footer renderer for workspace, model, usage, context, and extension status.
|
|
3
|
+
|
|
1
4
|
import { type Component, truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
2
5
|
import type { AgentSession } from "../../../core/agent-session.js";
|
|
3
6
|
import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.js";
|
|
4
7
|
import { theme } from "../theme/theme.js";
|
|
5
8
|
import { providerAuthBadge, providerDisplayName } from "./model-selector.js";
|
|
9
|
+
import { renderFooterStrip } from "./transcript-design.js";
|
|
6
10
|
|
|
7
11
|
/**
|
|
8
12
|
* Sanitize text for display in a single-line status.
|
|
@@ -155,8 +159,8 @@ export class FooterComponent implements Component {
|
|
|
155
159
|
? Math.max(0, Math.min(BAR_WIDTH, Math.round((contextPercentValue / 100) * BAR_WIDTH)))
|
|
156
160
|
: 0;
|
|
157
161
|
const bar =
|
|
158
|
-
theme.fg(barColor, "
|
|
159
|
-
theme.fg("dim", "
|
|
162
|
+
theme.fg(barColor, "█".repeat(filled)) +
|
|
163
|
+
theme.fg("dim", "░".repeat(Math.max(0, BAR_WIDTH - filled)));
|
|
160
164
|
const pctText = contextPercent === "?" ? "?" : `${contextPercent}%`;
|
|
161
165
|
const suffix = `/${formatTokens(contextWindow)}${autoIndicator}`;
|
|
162
166
|
const colorizedPct =
|
|
@@ -218,34 +222,9 @@ export class FooterComponent implements Component {
|
|
|
218
222
|
}
|
|
219
223
|
}
|
|
220
224
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
let statsLine: string;
|
|
225
|
-
if (totalNeeded <= width) {
|
|
226
|
-
// Both fit - add padding to right-align model
|
|
227
|
-
const padding = " ".repeat(width - statsLeftWidth - rightSideWidth);
|
|
228
|
-
statsLine = statsLeft + padding + rightSide;
|
|
229
|
-
} else {
|
|
230
|
-
// Need to truncate right side
|
|
231
|
-
const availableForRight = width - statsLeftWidth - minPadding;
|
|
232
|
-
if (availableForRight > 0) {
|
|
233
|
-
const truncatedRight = truncateToWidth(rightSide, availableForRight, "");
|
|
234
|
-
const truncatedRightWidth = visibleWidth(truncatedRight);
|
|
235
|
-
const padding = " ".repeat(Math.max(0, width - statsLeftWidth - truncatedRightWidth));
|
|
236
|
-
statsLine = statsLeft + padding + truncatedRight;
|
|
237
|
-
} else {
|
|
238
|
-
// Not enough space for right side at all
|
|
239
|
-
statsLine = statsLeft;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Apply dim to each part separately. statsLeft may contain color codes (for context %)
|
|
244
|
-
// that end with a reset, which would clear an outer dim wrapper. So we dim the parts
|
|
245
|
-
// before and after the colored section independently.
|
|
225
|
+
// Apply dim to the stats group before handing it to the shared footer strip.
|
|
226
|
+
// statsLeft may contain color codes for context %, so keep coloring local to the group.
|
|
246
227
|
const dimStatsLeft = theme.fg("dim", statsLeft);
|
|
247
|
-
const remainder = statsLine.slice(statsLeft.length); // padding + rightSide
|
|
248
|
-
const dimRemainder = theme.fg("dim", remainder);
|
|
249
228
|
|
|
250
229
|
// Extension statuses right-aligned on the pwd line (sorted by key).
|
|
251
230
|
// Keeps the footer compact by avoiding a dedicated row when the content
|
|
@@ -260,18 +239,12 @@ export class FooterComponent implements Component {
|
|
|
260
239
|
.join(" ")
|
|
261
240
|
: "";
|
|
262
241
|
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
pwdLine = truncateToWidth(theme.fg("dim", pwd), width, theme.fg("dim", "..."));
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const lines = [pwdLine, dimStatsLeft + dimRemainder];
|
|
274
|
-
|
|
275
|
-
return lines;
|
|
242
|
+
const leftSegments = [
|
|
243
|
+
theme.fg("accent", "● GSD"),
|
|
244
|
+
theme.fg("dim", pwd),
|
|
245
|
+
dimStatsLeft,
|
|
246
|
+
];
|
|
247
|
+
const footerRight = [rightSide, extStatusText].filter(Boolean).join(" ");
|
|
248
|
+
return renderFooterStrip(leftSegments, footerRight, width);
|
|
276
249
|
}
|
|
277
250
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// GSD-2
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Interactive terminal tool execution renderer for commands, tool calls, diffs, images, and summaries.
|
|
2
3
|
import {
|
|
3
4
|
Box,
|
|
4
5
|
Container,
|
|
@@ -24,6 +25,7 @@ import { getLanguageFromPath, highlightCode, theme } from "../theme/theme.js";
|
|
|
24
25
|
import { shortenPath } from "../utils/shorten-path.js";
|
|
25
26
|
import { renderDiff } from "./diff.js";
|
|
26
27
|
import { keyHint } from "./keybinding-hints.js";
|
|
28
|
+
import { renderCommandCard, renderToolLineCard, renderTranscriptCard, type StatusTone } from "./transcript-design.js";
|
|
27
29
|
import { truncateToVisualLines } from "./visual-truncate.js";
|
|
28
30
|
|
|
29
31
|
// Preview line limit for bash when not expanded
|
|
@@ -83,73 +85,6 @@ function prettifyToolName(name: string, label?: string): string {
|
|
|
83
85
|
.join(" ");
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
type ToolFrameTone = "pending" | "success" | "error";
|
|
87
|
-
|
|
88
|
-
function trimOuterBlankLines(lines: string[]): string[] {
|
|
89
|
-
let start = 0;
|
|
90
|
-
let end = lines.length;
|
|
91
|
-
while (start < end && lines[start].trim().length === 0) start++;
|
|
92
|
-
while (end > start && lines[end - 1].trim().length === 0) end--;
|
|
93
|
-
return lines.slice(start, end);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function renderToolFrame(
|
|
97
|
-
contentLines: string[],
|
|
98
|
-
width: number,
|
|
99
|
-
opts: {
|
|
100
|
-
label: string;
|
|
101
|
-
status: string;
|
|
102
|
-
tone: ToolFrameTone;
|
|
103
|
-
},
|
|
104
|
-
): string[] {
|
|
105
|
-
const outerWidth = Math.max(20, width);
|
|
106
|
-
const contentWidth = Math.max(1, outerWidth - 2); // "│ " + content
|
|
107
|
-
|
|
108
|
-
const borderColor = opts.tone === "error" ? "toolError" : opts.tone === "pending" ? "toolRunning" : "toolSuccess";
|
|
109
|
-
const topColor = borderColor;
|
|
110
|
-
const labelColor = opts.tone === "error" ? "toolError" : opts.tone === "pending" ? "toolRunning" : "toolSuccess";
|
|
111
|
-
const statusColor = opts.tone === "error" ? "toolError" : opts.tone === "pending" ? "toolRunning" : "toolSuccess";
|
|
112
|
-
const leftStyled = theme.fg(labelColor, theme.bold(opts.label));
|
|
113
|
-
const rightStyled = theme.fg(statusColor, opts.status);
|
|
114
|
-
const titleWidth = Math.max(1, outerWidth - 4);
|
|
115
|
-
const gap = Math.max(1, titleWidth - visibleWidth(leftStyled) - visibleWidth(rightStyled));
|
|
116
|
-
const headerRow = `${leftStyled}${" ".repeat(gap)}${rightStyled}`;
|
|
117
|
-
const headerPad = Math.max(0, titleWidth - visibleWidth(headerRow));
|
|
118
|
-
|
|
119
|
-
const sourceLines = trimOuterBlankLines(contentLines);
|
|
120
|
-
const bodyLines = (sourceLines.length > 0 ? sourceLines : [""]).map((line) => {
|
|
121
|
-
const clipped = truncateToWidth(line, contentWidth, "");
|
|
122
|
-
return clipped;
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
return style()
|
|
126
|
-
.border("rounded")
|
|
127
|
-
.borderColor((line) => theme.fg(line.startsWith("─") ? topColor : borderColor, line))
|
|
128
|
-
.title(headerRow + " ".repeat(headerPad))
|
|
129
|
-
.render(bodyLines, outerWidth);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function renderCollapsedToolRow(
|
|
133
|
-
label: string,
|
|
134
|
-
status: string,
|
|
135
|
-
width: number,
|
|
136
|
-
tone: Extract<ToolFrameTone, "success">,
|
|
137
|
-
): string[] {
|
|
138
|
-
const outerWidth = Math.max(20, width);
|
|
139
|
-
const contentWidth = Math.max(1, outerWidth - 2);
|
|
140
|
-
const statusColor = tone === "success" ? "toolSuccess" : "toolMuted";
|
|
141
|
-
const labelStyled = theme.fg(statusColor, label);
|
|
142
|
-
const statusStyled = theme.fg(statusColor, status);
|
|
143
|
-
const labelWidth = Math.max(1, contentWidth - visibleWidth(statusStyled) - 1);
|
|
144
|
-
const clippedLabel = truncateToWidth(labelStyled, labelWidth, "");
|
|
145
|
-
const gap = Math.max(1, contentWidth - visibleWidth(clippedLabel) - visibleWidth(statusStyled));
|
|
146
|
-
const line = `${clippedLabel}${" ".repeat(gap)}${statusStyled}`;
|
|
147
|
-
return style()
|
|
148
|
-
.border("minimal")
|
|
149
|
-
.borderColor((text) => theme.fg(statusColor, text))
|
|
150
|
-
.render([line], outerWidth);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
88
|
const COMPACT_ARG_VALUE_LIMIT = 60;
|
|
154
89
|
const GENERIC_OUTPUT_PREVIEW_LINES = 10;
|
|
155
90
|
const GENERIC_ARGS_JSON_PREVIEW_LINES = 10;
|
|
@@ -213,6 +148,40 @@ function formatToolTarget(target: ToolTargetMetadata): string | undefined {
|
|
|
213
148
|
return appendLineOrRange(displayPath, target);
|
|
214
149
|
}
|
|
215
150
|
|
|
151
|
+
function directDetailsTarget(details: unknown, action: string): ToolTargetMetadata | undefined {
|
|
152
|
+
if (!details || typeof details !== "object") return undefined;
|
|
153
|
+
const record = details as Record<string, unknown>;
|
|
154
|
+
const rawPath = record.resolvedPath ?? record.inputPath ?? record.file_path ?? record.path;
|
|
155
|
+
if (typeof rawPath !== "string" || rawPath.trim().length === 0) return undefined;
|
|
156
|
+
const target: ToolTargetMetadata = {
|
|
157
|
+
kind: "file",
|
|
158
|
+
action,
|
|
159
|
+
resolvedPath: typeof record.resolvedPath === "string" ? record.resolvedPath : rawPath,
|
|
160
|
+
inputPath: typeof record.inputPath === "string" ? record.inputPath : rawPath,
|
|
161
|
+
};
|
|
162
|
+
if (typeof record.line === "number") {
|
|
163
|
+
target.line = record.line;
|
|
164
|
+
}
|
|
165
|
+
const range = record.range;
|
|
166
|
+
if (range && typeof range === "object") {
|
|
167
|
+
const rangeRecord = range as Record<string, unknown>;
|
|
168
|
+
target.range = {
|
|
169
|
+
start: typeof rangeRecord.start === "number" ? rangeRecord.start : undefined,
|
|
170
|
+
end: typeof rangeRecord.end === "number" ? rangeRecord.end : undefined,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return target;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function firstStringArg(args: Record<string, unknown>, keys: string[]): string | null {
|
|
177
|
+
for (const key of keys) {
|
|
178
|
+
const value = str(args[key]);
|
|
179
|
+
if (value === null) continue;
|
|
180
|
+
if (value) return value;
|
|
181
|
+
}
|
|
182
|
+
return "";
|
|
183
|
+
}
|
|
184
|
+
|
|
216
185
|
function formatArgsPathTarget(path: string | null, args: Record<string, unknown>): string | undefined {
|
|
217
186
|
if (!path) return undefined;
|
|
218
187
|
const start = typeof args.offset === "number" ? args.offset : undefined;
|
|
@@ -692,22 +661,47 @@ export class ToolExecutionComponent extends Container {
|
|
|
692
661
|
}
|
|
693
662
|
const frameWidth = Math.max(20, width);
|
|
694
663
|
const contentWidth = Math.max(1, frameWidth - 4);
|
|
695
|
-
const frameTone:
|
|
664
|
+
const frameTone: "pending" | "success" | "error" =
|
|
696
665
|
this.result?.isError ? "error" : this.isPartial || !this.result ? "pending" : "success";
|
|
697
666
|
const elapsed = formatElapsed((this.endedAt ?? Date.now()) - this.startedAt);
|
|
698
|
-
const
|
|
667
|
+
const statusWord = this.isPartial || !this.result ? "running" : this.result.isError ? "failed" : "success";
|
|
668
|
+
const frameStatus = `${statusWord} · ${elapsed}`;
|
|
699
669
|
const parsed = parseMcpToolName(this.toolName);
|
|
700
670
|
const frameLabel = parsed
|
|
701
671
|
? `${parsed.server}·${parsed.tool}`
|
|
702
672
|
: prettifyToolName(this.toolName, this.toolDefinition?.label) || "unknown";
|
|
703
|
-
|
|
704
|
-
|
|
673
|
+
const recommendedTone: StatusTone =
|
|
674
|
+
frameTone === "pending" ? "running" : frameTone === "error" ? "error" : "success";
|
|
675
|
+
|
|
676
|
+
if (this.normalizedToolName === "bash" && !this.expanded && !this.result?.isError) {
|
|
677
|
+
const command = str(this.args?.command);
|
|
678
|
+
return [
|
|
679
|
+
"",
|
|
680
|
+
...renderCommandCard(command && command.length > 0 ? formatCommandPreview(command) : frameLabel, frameWidth, {
|
|
681
|
+
status: frameStatus,
|
|
682
|
+
tone: recommendedTone,
|
|
683
|
+
}),
|
|
684
|
+
];
|
|
685
|
+
}
|
|
686
|
+
const hasImages = this.result?.content?.some((block) => block.type === "image") ?? false;
|
|
687
|
+
if (!this.expanded && !this.result?.isError && !hasImages) {
|
|
688
|
+
const compactTarget = this.getCompactTarget();
|
|
689
|
+
return [
|
|
690
|
+
"",
|
|
691
|
+
...renderToolLineCard(frameLabel, compactTarget, frameWidth, {
|
|
692
|
+
status: frameStatus,
|
|
693
|
+
tone: recommendedTone,
|
|
694
|
+
hidden: !this.isPartial && !!this.result,
|
|
695
|
+
}),
|
|
696
|
+
];
|
|
705
697
|
}
|
|
706
698
|
const lines = super.render(contentWidth);
|
|
707
|
-
const framed =
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
tone:
|
|
699
|
+
const framed = renderTranscriptCard(lines, frameWidth, {
|
|
700
|
+
title: frameLabel,
|
|
701
|
+
right: frameStatus,
|
|
702
|
+
tone: recommendedTone,
|
|
703
|
+
footerLeft: this.expanded ? "output expanded" : undefined,
|
|
704
|
+
footerRight: this.expanded ? "ctrl+o collapse" : undefined,
|
|
711
705
|
});
|
|
712
706
|
return framed.length > 0 ? ["", ...framed] : framed;
|
|
713
707
|
}
|
|
@@ -748,15 +742,6 @@ export class ToolExecutionComponent extends Container {
|
|
|
748
742
|
return "Other tool actions";
|
|
749
743
|
}
|
|
750
744
|
|
|
751
|
-
private getCompactSummary(frameLabel: string): string {
|
|
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
745
|
private getCompactAction(): string {
|
|
761
746
|
const target = this.getTargetMetadata();
|
|
762
747
|
if (target?.action) return target.action === "list" ? "ls" : target.action;
|
|
@@ -765,7 +750,8 @@ export class ToolExecutionComponent extends Container {
|
|
|
765
750
|
|
|
766
751
|
private getTargetMetadata(): ToolTargetMetadata | undefined {
|
|
767
752
|
const target = this.result?.details?.target;
|
|
768
|
-
|
|
753
|
+
if (target && typeof target === "object") return target;
|
|
754
|
+
return directDetailsTarget(this.result?.details, this.normalizedToolName);
|
|
769
755
|
}
|
|
770
756
|
|
|
771
757
|
private getCompactTarget(): string | undefined {
|
|
@@ -773,7 +759,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
773
759
|
const metadataTarget = metadata ? formatToolTarget(metadata) : undefined;
|
|
774
760
|
if (metadataTarget) return metadataTarget;
|
|
775
761
|
|
|
776
|
-
const path =
|
|
762
|
+
const path = firstStringArg(this.args ?? {}, ["file_path", "path", "notebook_path"]);
|
|
777
763
|
if (path === null) return undefined;
|
|
778
764
|
if (this.normalizedToolName === "read" || this.normalizedToolName === "hashline_read") {
|
|
779
765
|
return formatArgsPathTarget(path, this.args);
|
|
@@ -782,16 +768,18 @@ export class ToolExecutionComponent extends Container {
|
|
|
782
768
|
return path ? shortenPath(path) : undefined;
|
|
783
769
|
}
|
|
784
770
|
if (this.normalizedToolName === "ls") {
|
|
785
|
-
return shortenPath(path
|
|
771
|
+
return path ? shortenPath(path) : undefined;
|
|
786
772
|
}
|
|
787
773
|
if (this.normalizedToolName === "find") {
|
|
788
774
|
const pattern = str(this.args?.pattern);
|
|
789
|
-
|
|
775
|
+
if (pattern) return path ? `${pattern} in ${shortenPath(path)}` : pattern;
|
|
776
|
+
return path ? shortenPath(path) : undefined;
|
|
790
777
|
}
|
|
791
778
|
if (this.normalizedToolName === "grep") {
|
|
792
779
|
const pattern = str(this.args?.pattern);
|
|
793
780
|
const glob = str(this.args?.glob);
|
|
794
|
-
const label = pattern ? `${pattern} in ${shortenPath(path
|
|
781
|
+
const label = pattern ? (path ? `${pattern} in ${shortenPath(path)}` : pattern) : path ? shortenPath(path) : undefined;
|
|
782
|
+
if (!label) return glob || undefined;
|
|
795
783
|
return glob ? `${label} (${glob})` : label;
|
|
796
784
|
}
|
|
797
785
|
return undefined;
|
|
@@ -1410,23 +1398,14 @@ export class ToolExecutionComponent extends Container {
|
|
|
1410
1398
|
}
|
|
1411
1399
|
} else {
|
|
1412
1400
|
// Generic tool / MCP tool without a registered renderer.
|
|
1413
|
-
//
|
|
1414
|
-
//
|
|
1415
|
-
// cleanly. GSD-registered MCP tools have already had their prefix
|
|
1416
|
-
// stripped upstream in partial-builder.ts and won't reach this branch.
|
|
1417
|
-
const parsed = parseMcpToolName(this.toolName);
|
|
1418
|
-
const displayName = parsed
|
|
1419
|
-
? parsed.tool
|
|
1420
|
-
: prettifyToolName(this.toolName, this.toolDefinition?.label);
|
|
1421
|
-
const serverPrefix = parsed ? theme.fg("muted", `${parsed.server}\u00b7`) : "";
|
|
1422
|
-
text = serverPrefix + theme.fg("toolTitle", theme.bold(displayName));
|
|
1423
|
-
|
|
1401
|
+
// The frame header already contains the tool identity, so the body
|
|
1402
|
+
// should show only arguments and output.
|
|
1424
1403
|
const argsText = formatCompactArgs(this.args, this.expanded);
|
|
1425
1404
|
if (argsText) {
|
|
1426
1405
|
if (argsText.includes("\n")) {
|
|
1427
|
-
text
|
|
1406
|
+
text = theme.fg("toolOutput", argsText);
|
|
1428
1407
|
} else {
|
|
1429
|
-
text
|
|
1408
|
+
text = theme.fg("toolOutput", argsText);
|
|
1430
1409
|
}
|
|
1431
1410
|
}
|
|
1432
1411
|
|
|
@@ -1437,7 +1416,8 @@ export class ToolExecutionComponent extends Container {
|
|
|
1437
1416
|
const maxLines = this.expanded ? lines.length : GENERIC_OUTPUT_PREVIEW_LINES;
|
|
1438
1417
|
const displayLines = lines.slice(0, maxLines);
|
|
1439
1418
|
const remaining = lines.length - maxLines;
|
|
1440
|
-
|
|
1419
|
+
const outputText = displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n");
|
|
1420
|
+
text += `${text ? "\n\n" : ""}${outputText}`;
|
|
1441
1421
|
if (remaining > 0) {
|
|
1442
1422
|
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
|
|
1443
1423
|
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// Project/App: GSD-2
|
|
2
|
+
// File Purpose: Shared recommended transcript rendering primitives for assistant, tool, command, footer, and auto-mode TUI surfaces.
|
|
3
|
+
|
|
4
|
+
import { truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
5
|
+
import { theme, type ThemeBg, type ThemeColor } from "../theme/theme.js";
|
|
6
|
+
import { alignRight, padRight, roundedPanel } from "./tui-style-kit.js";
|
|
7
|
+
|
|
8
|
+
export type StatusTone = "running" | "success" | "error" | "warning" | "muted";
|
|
9
|
+
|
|
10
|
+
export function chatMessageWidth(width: number): number {
|
|
11
|
+
return Math.max(24, Math.min(width, Math.floor(width * 0.72)));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function trimOuterBlankLines(lines: string[]): string[] {
|
|
15
|
+
let start = 0;
|
|
16
|
+
let end = lines.length;
|
|
17
|
+
while (start < end && lines[start].trim().length === 0) start++;
|
|
18
|
+
while (end > start && lines[end - 1].trim().length === 0) end--;
|
|
19
|
+
return lines.slice(start, end);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function toneColor(tone: StatusTone): ThemeColor {
|
|
23
|
+
switch (tone) {
|
|
24
|
+
case "running": return "toolRunning";
|
|
25
|
+
case "success": return "border";
|
|
26
|
+
case "error": return "toolError";
|
|
27
|
+
case "warning": return "warning";
|
|
28
|
+
case "muted":
|
|
29
|
+
default: return "toolMuted";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function rightAlign(left: string, right: string, width: number): string {
|
|
34
|
+
return alignRight(left, right, width);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function renderAssistantRail(
|
|
38
|
+
lines: string[],
|
|
39
|
+
width: number,
|
|
40
|
+
opts: { label: string; meta?: string; railColor?: ThemeColor } = { label: "GSD" },
|
|
41
|
+
): string[] {
|
|
42
|
+
const outerWidth = Math.max(20, width);
|
|
43
|
+
const indent = " ";
|
|
44
|
+
const rail = theme.fg(opts.railColor ?? "borderAccent", "┃");
|
|
45
|
+
const blockWidth = Math.max(1, outerWidth - visibleWidth(indent));
|
|
46
|
+
const contentWidth = Math.max(1, blockWidth - 2);
|
|
47
|
+
const header = opts.meta
|
|
48
|
+
? `${theme.fg("borderAccent", theme.bold(opts.label))} ${theme.fg("dim", opts.meta)}`
|
|
49
|
+
: theme.fg("borderAccent", theme.bold(opts.label));
|
|
50
|
+
const source = lines.length > 0 ? lines : [""];
|
|
51
|
+
const row = (line: string) => `${indent}${theme.bg("customMessageBg", padRight(`${rail} ${line}`, blockWidth))}`;
|
|
52
|
+
return [
|
|
53
|
+
row(""),
|
|
54
|
+
row(truncateToWidth(header, contentWidth, "")),
|
|
55
|
+
...source.map((line) => row(truncateToWidth(line, contentWidth, ""))),
|
|
56
|
+
row(""),
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function renderUserRail(
|
|
61
|
+
lines: string[],
|
|
62
|
+
width: number,
|
|
63
|
+
opts: { label: string; meta?: string },
|
|
64
|
+
): string[] {
|
|
65
|
+
const outerWidth = Math.max(20, width);
|
|
66
|
+
const maxMessageWidth = chatMessageWidth(outerWidth);
|
|
67
|
+
const rawBodyLines = trimOuterBlankLines(lines).length > 0 ? trimOuterBlankLines(lines) : [""];
|
|
68
|
+
const rail = theme.fg("border", "┃");
|
|
69
|
+
const contentWidth = Math.max(1, Math.min(maxMessageWidth, outerWidth - 2));
|
|
70
|
+
const header = opts.meta
|
|
71
|
+
? `${theme.fg("border", theme.bold(opts.label))} ${theme.fg("dim", opts.meta)}`
|
|
72
|
+
: theme.fg("border", theme.bold(opts.label));
|
|
73
|
+
const bodyLines = rawBodyLines.map((line) =>
|
|
74
|
+
theme.fg("userMessageText", truncateToWidth(line.trimEnd(), contentWidth, ""))
|
|
75
|
+
);
|
|
76
|
+
const row = (line: string) => theme.bg("userMessageBg", padRight(`${rail} ${line}`, outerWidth));
|
|
77
|
+
return [
|
|
78
|
+
row(""),
|
|
79
|
+
row(truncateToWidth(header, contentWidth, "")),
|
|
80
|
+
...bodyLines.map((line) => row(truncateToWidth(line, contentWidth, ""))),
|
|
81
|
+
row(""),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function cardRow(line: string, contentWidth: number, paddingX: number, border: (text: string) => string): string {
|
|
86
|
+
const padded = " ".repeat(paddingX) + padRight(line, contentWidth) + " ".repeat(paddingX);
|
|
87
|
+
return `${border("│")}${padded}${border("│")}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function renderTranscriptCard(
|
|
91
|
+
lines: string[],
|
|
92
|
+
width: number,
|
|
93
|
+
opts: {
|
|
94
|
+
title: string;
|
|
95
|
+
right?: string;
|
|
96
|
+
tone: StatusTone;
|
|
97
|
+
footerLeft?: string;
|
|
98
|
+
footerRight?: string;
|
|
99
|
+
},
|
|
100
|
+
): string[] {
|
|
101
|
+
const outerWidth = Math.max(20, width);
|
|
102
|
+
const innerWidth = Math.max(1, outerWidth - 2);
|
|
103
|
+
const paddingX = 2;
|
|
104
|
+
const contentWidth = Math.max(1, innerWidth - paddingX * 2);
|
|
105
|
+
const borderColor = toneColor(opts.tone);
|
|
106
|
+
const border = (text: string) => theme.fg(borderColor, text);
|
|
107
|
+
const title = theme.fg("borderAccent", opts.title);
|
|
108
|
+
const right = opts.right ? theme.fg(toneColor(opts.tone), opts.right) : "";
|
|
109
|
+
const header = rightAlign(title, right, contentWidth);
|
|
110
|
+
const body = lines.map((line) => padRight(line, contentWidth));
|
|
111
|
+
const footer =
|
|
112
|
+
opts.footerLeft || opts.footerRight
|
|
113
|
+
? [rightAlign(theme.fg("dim", opts.footerLeft ?? ""), theme.fg("dim", opts.footerRight ?? ""), contentWidth)]
|
|
114
|
+
: [];
|
|
115
|
+
return [
|
|
116
|
+
border("╭" + "─".repeat(outerWidth - 2) + "╮"),
|
|
117
|
+
cardRow(header, contentWidth, paddingX, border),
|
|
118
|
+
...body.map((line) => cardRow(line, contentWidth, paddingX, border)),
|
|
119
|
+
...footer.map((line) => cardRow(line, contentWidth, paddingX, border)),
|
|
120
|
+
border("╰" + "─".repeat(outerWidth - 2) + "╯"),
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function renderToolLineCard(
|
|
125
|
+
title: string,
|
|
126
|
+
target: string | undefined,
|
|
127
|
+
width: number,
|
|
128
|
+
opts: { status: string; tone: StatusTone; hidden?: boolean; titlePrefix?: string; bg?: ThemeBg },
|
|
129
|
+
): string[] {
|
|
130
|
+
const outerWidth = Math.max(20, width);
|
|
131
|
+
const innerWidth = Math.max(1, outerWidth - 2);
|
|
132
|
+
const paddingX = 2;
|
|
133
|
+
const contentWidth = Math.max(1, innerWidth - paddingX * 2);
|
|
134
|
+
const borderColor = toneColor(opts.tone);
|
|
135
|
+
const border = (text: string) => theme.fg(borderColor, text);
|
|
136
|
+
const titleText = `${opts.titlePrefix ?? ""}${theme.fg("borderAccent", title)}`;
|
|
137
|
+
const targetText = target ? ` ${theme.fg("text", target)}` : "";
|
|
138
|
+
const left = `${titleText}${targetText}`;
|
|
139
|
+
const statusText = opts.hidden
|
|
140
|
+
? `${opts.status} · output hidden · ctrl+o expand`
|
|
141
|
+
: opts.status;
|
|
142
|
+
const right = theme.fg(opts.tone === "success" ? "success" : borderColor, statusText);
|
|
143
|
+
const line = rightAlign(left, right, contentWidth);
|
|
144
|
+
const row = cardRow(line, contentWidth, paddingX, border);
|
|
145
|
+
return [
|
|
146
|
+
border("╭" + "─".repeat(outerWidth - 2) + "╮"),
|
|
147
|
+
opts.bg ? theme.bg(opts.bg, row) : row,
|
|
148
|
+
border("╰" + "─".repeat(outerWidth - 2) + "╯"),
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function renderCommandCard(
|
|
153
|
+
command: string,
|
|
154
|
+
width: number,
|
|
155
|
+
opts: { status: string; tone: StatusTone; progress?: string },
|
|
156
|
+
): string[] {
|
|
157
|
+
const outerWidth = Math.max(20, width);
|
|
158
|
+
const innerWidth = Math.max(1, outerWidth - 2);
|
|
159
|
+
const paddingX = 2;
|
|
160
|
+
const contentWidth = Math.max(1, innerWidth - paddingX * 2);
|
|
161
|
+
const borderColor = toneColor(opts.tone);
|
|
162
|
+
const left = `${theme.fg("accent", "$")} ${theme.fg("text", command)}`;
|
|
163
|
+
const statusText = opts.progress
|
|
164
|
+
? `${opts.progress} ${opts.status}`
|
|
165
|
+
: `${opts.status} · output hidden · ctrl+o expand`;
|
|
166
|
+
const right = theme.fg(opts.tone === "success" ? "success" : borderColor, statusText);
|
|
167
|
+
const line = rightAlign(left, right, contentWidth);
|
|
168
|
+
const border = (text: string) => theme.fg(borderColor, text);
|
|
169
|
+
return [
|
|
170
|
+
border("╭" + "─".repeat(outerWidth - 2) + "╮"),
|
|
171
|
+
cardRow(line, contentWidth, paddingX, border),
|
|
172
|
+
border("╰" + "─".repeat(outerWidth - 2) + "╯"),
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function renderProgressBar(done: number, total: number, width: number, tone: StatusTone = "success"): string {
|
|
177
|
+
const clampedWidth = Math.max(0, width);
|
|
178
|
+
const pct = total > 0 ? Math.max(0, Math.min(1, done / total)) : 0;
|
|
179
|
+
const filled = Math.round(pct * clampedWidth);
|
|
180
|
+
return (
|
|
181
|
+
theme.fg(toneColor(tone), "█".repeat(filled)) +
|
|
182
|
+
theme.fg("dim", "░".repeat(clampedWidth - filled))
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function renderFooterStrip(leftSegments: string[], right: string, width: number): string[] {
|
|
187
|
+
const outerWidth = Math.max(20, width);
|
|
188
|
+
const innerWidth = Math.max(1, outerWidth - 2);
|
|
189
|
+
const sep = theme.fg("dim", " │ ");
|
|
190
|
+
const rightStyled = theme.fg("dim", right);
|
|
191
|
+
const rightWidth = visibleWidth(rightStyled);
|
|
192
|
+
const leftBudget = right ? Math.max(1, innerWidth - rightWidth - 3) : innerWidth;
|
|
193
|
+
const left = truncateToWidth(leftSegments.filter(Boolean).join(sep), leftBudget, "");
|
|
194
|
+
const content = rightAlign(left, rightStyled, innerWidth);
|
|
195
|
+
return roundedPanel([content], outerWidth);
|
|
196
|
+
}
|