@alumbwe/anvil 1.0.19 → 1.0.20
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 +28 -30
- package/bin/anvil +2 -0
- package/package.json +71 -75
- package/src/agents/bundled-agents.generated.d.ts +14 -0
- package/src/agents/bundled-agents.generated.ts +3760 -0
- package/src/app.tsx +399 -0
- package/src/chat.tsx +1698 -0
- package/src/cli-args.ts +134 -0
- package/src/commands/__tests__/anvil-command-aliases.test.ts +56 -0
- package/src/commands/__tests__/bash-command.test.ts +445 -0
- package/src/commands/__tests__/command-args.test.ts +349 -0
- package/src/commands/__tests__/copy-conversation-clipboard.test.ts +108 -0
- package/src/commands/__tests__/copy-conversation.test.ts +226 -0
- package/src/commands/__tests__/diagnostics-command.test.ts +35 -0
- package/src/commands/__tests__/image.test.ts +99 -0
- package/src/commands/__tests__/init.test.ts +456 -0
- package/src/commands/__tests__/new-command-rotates-chat.test.ts +91 -0
- package/src/commands/__tests__/process-diagnostics.test.ts +54 -0
- package/src/commands/__tests__/prompt-builders.test.ts +28 -0
- package/src/commands/__tests__/router-input.test.ts +298 -0
- package/src/commands/ads.ts +44 -0
- package/src/commands/command-registry.ts +726 -0
- package/src/commands/copy-conversation.ts +392 -0
- package/src/commands/help.ts +13 -0
- package/src/commands/image.ts +20 -0
- package/src/commands/init.ts +121 -0
- package/src/commands/process-diagnostics.ts +120 -0
- package/src/commands/prompt-builders.ts +100 -0
- package/src/commands/publish.ts +203 -0
- package/src/commands/router-utils.ts +80 -0
- package/src/commands/router.ts +487 -0
- package/src/commands/usage.ts +26 -0
- package/src/components/__tests__/ad-banner.test.tsx +83 -0
- package/src/components/__tests__/anvil-landing-heading-row.test.tsx +91 -0
- package/src/components/__tests__/anvil-model-selector.test.tsx +519 -0
- package/src/components/__tests__/anvil-offer-invariants.test.ts +54 -0
- package/src/components/__tests__/anvil-takeover-prompt.test.tsx +212 -0
- package/src/components/__tests__/chat-input-bar.test.tsx +130 -0
- package/src/components/__tests__/grid-layout.integration.test.tsx +304 -0
- package/src/components/__tests__/grid-layout.test.tsx +1051 -0
- package/src/components/__tests__/message-block.completion.test.tsx +104 -0
- package/src/components/__tests__/message-block.streaming.test.tsx +78 -0
- package/src/components/__tests__/message-with-agents.test.tsx +579 -0
- package/src/components/__tests__/multiline-input.test.tsx +1132 -0
- package/src/components/__tests__/queue-panel.test.tsx +398 -0
- package/src/components/__tests__/selectable-list.test.ts +232 -0
- package/src/components/__tests__/status-bar.test.tsx +44 -0
- package/src/components/__tests__/status-indicator.test.tsx +204 -0
- package/src/components/__tests__/terminal-thinking-orb.test.tsx +111 -0
- package/src/components/__tests__/user-error-banner.test.tsx +102 -0
- package/src/components/ad-banner.tsx +323 -0
- package/src/components/agent-checklist.tsx +350 -0
- package/src/components/agent-mode-toggle.tsx +241 -0
- package/src/components/anvil-active-session-summary.tsx +63 -0
- package/src/components/anvil-landing-screen.tsx +865 -0
- package/src/components/anvil-mark.tsx +52 -0
- package/src/components/anvil-model-selector.tsx +1087 -0
- package/src/components/anvil-referral-banner.tsx +604 -0
- package/src/components/anvil-superseded-screen.tsx +62 -0
- package/src/components/ask-user/__tests__/multiple-choice-form.test.ts +432 -0
- package/src/components/ask-user/__tests__/validation.test.ts +213 -0
- package/src/components/ask-user/components/accordion-question.tsx +153 -0
- package/src/components/ask-user/components/custom-answer-input.tsx +66 -0
- package/src/components/ask-user/components/options-list.tsx +133 -0
- package/src/components/ask-user/components/question-header.tsx +80 -0
- package/src/components/ask-user/components/question-option.tsx +89 -0
- package/src/components/ask-user/constants.ts +38 -0
- package/src/components/ask-user/index.tsx +631 -0
- package/src/components/ask-user/utils/validation.ts +85 -0
- package/src/components/attachment-card.tsx +65 -0
- package/src/components/blocks/agent-block-grid.tsx +58 -0
- package/src/components/blocks/agent-branch-item.tsx +311 -0
- package/src/components/blocks/agent-branch-wrapper.tsx +493 -0
- package/src/components/blocks/agent-list-branch.tsx +77 -0
- package/src/components/blocks/ask-user-branch.tsx +81 -0
- package/src/components/blocks/block-helpers.ts +11 -0
- package/src/components/blocks/blocks-renderer.tsx +289 -0
- package/src/components/blocks/content-with-markdown.tsx +33 -0
- package/src/components/blocks/image-block.tsx +128 -0
- package/src/components/blocks/implementor-row.tsx +429 -0
- package/src/components/blocks/single-block.tsx +201 -0
- package/src/components/blocks/thinking-block.tsx +67 -0
- package/src/components/blocks/tool-block-group.tsx +57 -0
- package/src/components/blocks/tool-branch.tsx +206 -0
- package/src/components/blocks/user-content-copy.tsx +157 -0
- package/src/components/bottom-banner.tsx +136 -0
- package/src/components/build-mode-buttons.tsx +110 -0
- package/src/components/button.tsx +66 -0
- package/src/components/chat-header.tsx +77 -0
- package/src/components/chat-history-screen.tsx +413 -0
- package/src/components/chat-input-bar.tsx +523 -0
- package/src/components/clickable-title-box.tsx +66 -0
- package/src/components/clickable.tsx +119 -0
- package/src/components/collapse-button.tsx +34 -0
- package/src/components/copy-button.tsx +203 -0
- package/src/components/elapsed-timer.tsx +55 -0
- package/src/components/error-boundary.tsx +55 -0
- package/src/components/feedback-container.tsx +181 -0
- package/src/components/feedback-icon-button.tsx +89 -0
- package/src/components/feedback-input-mode.tsx +344 -0
- package/src/components/file-attachment-card.tsx +98 -0
- package/src/components/grid-layout.tsx +80 -0
- package/src/components/help-banner.tsx +127 -0
- package/src/components/highlighted-text.tsx +52 -0
- package/src/components/image-card.tsx +167 -0
- package/src/components/image-thumbnail.tsx +114 -0
- package/src/components/input-cursor.tsx +77 -0
- package/src/components/input-mode-banner.tsx +57 -0
- package/src/components/load-previous-button.tsx +48 -0
- package/src/components/login-modal.tsx +475 -0
- package/src/components/message-block.tsx +346 -0
- package/src/components/message-footer.tsx +258 -0
- package/src/components/message-with-agents.tsx +506 -0
- package/src/components/mode-divider.tsx +43 -0
- package/src/components/multiline-input.tsx +1241 -0
- package/src/components/out-of-credits-banner.tsx +160 -0
- package/src/components/pending-attachments-banner.tsx +116 -0
- package/src/components/pending-bash-message.tsx +59 -0
- package/src/components/progress-bar.tsx +81 -0
- package/src/components/project-picker-screen.tsx +485 -0
- package/src/components/publish-confirmation.tsx +493 -0
- package/src/components/publish-container.tsx +687 -0
- package/src/components/queue-panel.tsx +310 -0
- package/src/components/raised-pill.tsx +95 -0
- package/src/components/renderers/plan-box.tsx +59 -0
- package/src/components/review-screen.tsx +112 -0
- package/src/components/scroll-to-bottom-button.tsx +34 -0
- package/src/components/segmented-control.tsx +187 -0
- package/src/components/selectable-list.tsx +248 -0
- package/src/components/selected-chips.tsx +80 -0
- package/src/components/separator.tsx +40 -0
- package/src/components/session-ended-banner.tsx +226 -0
- package/src/components/shimmer-text.tsx +248 -0
- package/src/components/status-bar.tsx +313 -0
- package/src/components/subscription-limit-banner.tsx +206 -0
- package/src/components/suggested-prompts.tsx +184 -0
- package/src/components/suggestion-menu.tsx +215 -0
- package/src/components/terminal-command-display.tsx +151 -0
- package/src/components/terminal-link.tsx +97 -0
- package/src/components/terminal-thinking-orb.tsx +95 -0
- package/src/components/text-attachment-card.tsx +77 -0
- package/src/components/thinking.tsx +109 -0
- package/src/components/tools/__tests__/apply-patch.test.tsx +84 -0
- package/src/components/tools/__tests__/code-search.test.tsx +45 -0
- package/src/components/tools/__tests__/gravity-index.test.ts +76 -0
- package/src/components/tools/__tests__/render-ui.test.tsx +92 -0
- package/src/components/tools/__tests__/run-terminal-command.test.ts +233 -0
- package/src/components/tools/apply-patch.tsx +95 -0
- package/src/components/tools/code-search.tsx +45 -0
- package/src/components/tools/composio.tsx +152 -0
- package/src/components/tools/diff-viewer.tsx +76 -0
- package/src/components/tools/glob.tsx +61 -0
- package/src/components/tools/gravity-index.tsx +77 -0
- package/src/components/tools/list-directory.tsx +61 -0
- package/src/components/tools/read-docs.tsx +37 -0
- package/src/components/tools/read-files.tsx +91 -0
- package/src/components/tools/read-subtree.tsx +44 -0
- package/src/components/tools/read-url.tsx +33 -0
- package/src/components/tools/registry.ts +126 -0
- package/src/components/tools/render-ui.tsx +122 -0
- package/src/components/tools/run-terminal-command.tsx +79 -0
- package/src/components/tools/skill.tsx +29 -0
- package/src/components/tools/str-replace.tsx +77 -0
- package/src/components/tools/suggest-followups.tsx +369 -0
- package/src/components/tools/task-completed.tsx +16 -0
- package/src/components/tools/tool-call-item.tsx +273 -0
- package/src/components/tools/types.ts +55 -0
- package/src/components/tools/web-search.tsx +33 -0
- package/src/components/tools/write-file.tsx +16 -0
- package/src/components/tools/write-todos.tsx +95 -0
- package/src/components/top-banner.tsx +178 -0
- package/src/components/usage-banner.tsx +244 -0
- package/src/components/user-error-banner.tsx +56 -0
- package/src/components/validation-error-popover.tsx +192 -0
- package/src/contexts/__tests__/chat-runtime-context.test.tsx +149 -0
- package/src/contexts/chat-runtime-context.tsx +240 -0
- package/src/data/slash-commands.test.ts +24 -0
- package/src/data/slash-commands.ts +249 -0
- package/src/entry.ts +12 -0
- package/src/hooks/__tests__/holds-live-anvil-slot.test.ts +49 -0
- package/src/hooks/__tests__/session-fetch-signal.test.ts +63 -0
- package/src/hooks/__tests__/use-activity-query.test.ts +1000 -0
- package/src/hooks/__tests__/use-ask-user-bridge.test.ts +176 -0
- package/src/hooks/__tests__/use-auth-query.test.ts +21 -0
- package/src/hooks/__tests__/use-chat-input-remount.test.tsx +66 -0
- package/src/hooks/__tests__/use-clipboard.test.tsx +73 -0
- package/src/hooks/__tests__/use-connection-status.test.ts +112 -0
- package/src/hooks/__tests__/use-directory-browser.test.ts +203 -0
- package/src/hooks/__tests__/use-gravity-ad.test.ts +73 -0
- package/src/hooks/__tests__/use-grid-layout.test.ts +349 -0
- package/src/hooks/__tests__/use-input-history.test.ts +699 -0
- package/src/hooks/__tests__/use-message-queue-editing.test.tsx +209 -0
- package/src/hooks/__tests__/use-message-queue.test.tsx +71 -0
- package/src/hooks/__tests__/use-path-tab-completion.test.ts +315 -0
- package/src/hooks/__tests__/use-queue-controls.test.ts +68 -0
- package/src/hooks/__tests__/use-queue-ui.test.tsx +83 -0
- package/src/hooks/__tests__/use-searchable-list.test.ts +359 -0
- package/src/hooks/__tests__/use-send-message-timer.test.ts +146 -0
- package/src/hooks/__tests__/use-suggestion-engine-mention.test.ts +361 -0
- package/src/hooks/__tests__/use-suggestion-engine.test.ts +485 -0
- package/src/hooks/__tests__/use-terminal-focus.test.ts +66 -0
- package/src/hooks/__tests__/use-terminal-layout.test.ts +675 -0
- package/src/hooks/__tests__/use-timeout.test.ts +330 -0
- package/src/hooks/__tests__/use-usage-query.test.ts +502 -0
- package/src/hooks/__tests__/use-user-details-query.test.ts +195 -0
- package/src/hooks/helpers/__tests__/send-message.test.ts +1918 -0
- package/src/hooks/helpers/send-message.ts +654 -0
- package/src/hooks/stream-state.ts +83 -0
- package/src/hooks/use-activity-query.ts +668 -0
- package/src/hooks/use-agent-validation.ts +74 -0
- package/src/hooks/use-anvil-ctrl-c-exit.ts +23 -0
- package/src/hooks/use-anvil-session-progress.ts +34 -0
- package/src/hooks/use-anvil-session.ts +806 -0
- package/src/hooks/use-anvil-streak-query.ts +61 -0
- package/src/hooks/use-ask-user-bridge.ts +92 -0
- package/src/hooks/use-auth-query.ts +262 -0
- package/src/hooks/use-auth-state.ts +152 -0
- package/src/hooks/use-chat-input.ts +105 -0
- package/src/hooks/use-chat-keyboard.ts +321 -0
- package/src/hooks/use-chat-messages.ts +254 -0
- package/src/hooks/use-chat-state.ts +165 -0
- package/src/hooks/use-chat-streaming.ts +180 -0
- package/src/hooks/use-chat-ui.ts +131 -0
- package/src/hooks/use-clipboard.ts +151 -0
- package/src/hooks/use-connection-status.ts +142 -0
- package/src/hooks/use-directory-browser.ts +88 -0
- package/src/hooks/use-elapsed-time.ts +116 -0
- package/src/hooks/use-event.ts +34 -0
- package/src/hooks/use-exit-handler.ts +66 -0
- package/src/hooks/use-fetch-login-url.ts +65 -0
- package/src/hooks/use-fingerprint.ts +61 -0
- package/src/hooks/use-gravity-ad.ts +656 -0
- package/src/hooks/use-grid-layout.ts +73 -0
- package/src/hooks/use-input-history.ts +173 -0
- package/src/hooks/use-login-keyboard-handlers.ts +75 -0
- package/src/hooks/use-login-polling.ts +114 -0
- package/src/hooks/use-logo.tsx +161 -0
- package/src/hooks/use-message-queue.ts +387 -0
- package/src/hooks/use-now.ts +20 -0
- package/src/hooks/use-path-tab-completion.ts +88 -0
- package/src/hooks/use-publish-mutation.ts +60 -0
- package/src/hooks/use-queue-controls.ts +68 -0
- package/src/hooks/use-queue-ui.ts +74 -0
- package/src/hooks/use-scroll-management.ts +184 -0
- package/src/hooks/use-searchable-list.ts +98 -0
- package/src/hooks/use-send-message.ts +773 -0
- package/src/hooks/use-sheen-animation.tsx +88 -0
- package/src/hooks/use-subscription-query.ts +71 -0
- package/src/hooks/use-suggestion-engine.ts +783 -0
- package/src/hooks/use-terminal-breakpoints.ts +77 -0
- package/src/hooks/use-terminal-dimensions.ts +46 -0
- package/src/hooks/use-terminal-focus.ts +29 -0
- package/src/hooks/use-terminal-layout.ts +189 -0
- package/src/hooks/use-theme.tsx +140 -0
- package/src/hooks/use-timeout.ts +85 -0
- package/src/hooks/use-update-preference.ts +66 -0
- package/src/hooks/use-usage-monitor.ts +55 -0
- package/src/hooks/use-usage-query.ts +124 -0
- package/src/hooks/use-user-details-query.ts +93 -0
- package/src/hooks/use-why-did-you-update.ts +177 -0
- package/src/index.tsx +473 -0
- package/src/init/__tests__/init-direnv.test.ts +526 -0
- package/src/init/init-app.ts +34 -0
- package/src/init/init-direnv.ts +133 -0
- package/src/login/constants.ts +60 -0
- package/src/login/login-flow.ts +204 -0
- package/src/login/plain-login.ts +108 -0
- package/src/login/utils.ts +183 -0
- package/src/native/ripgrep.ts +80 -0
- package/src/polyfills/bun-strip-ansi.ts +12 -0
- package/src/pre-init/tree-sitter-wasm.ts +96 -0
- package/src/project-files.ts +102 -0
- package/src/setup/key-setup.ts +295 -0
- package/src/setup/load-env.ts +106 -0
- package/src/state/__tests__/chat-store-focus.test.ts +22 -0
- package/src/state/__tests__/feedback-store.test.ts +257 -0
- package/src/state/anvil-model-store.ts +42 -0
- package/src/state/anvil-session-store.ts +53 -0
- package/src/state/chat-history-store.ts +30 -0
- package/src/state/chat-store.ts +544 -0
- package/src/state/feedback-store.ts +160 -0
- package/src/state/login-store.ts +150 -0
- package/src/state/message-block-store.ts +149 -0
- package/src/state/publish-store.ts +146 -0
- package/src/state/queue-panel-store.ts +26 -0
- package/src/state/review-store.ts +24 -0
- package/src/types/anvil-session.ts +17 -0
- package/src/types/chat-state.ts +15 -0
- package/src/types/chat.ts +241 -0
- package/src/types/contracts/send-message.ts +12 -0
- package/src/types/env.ts +98 -0
- package/src/types/function-params.ts +28 -0
- package/src/types/react19-compat.d.ts +19 -0
- package/src/types/store.ts +111 -0
- package/src/types/theme-system.ts +144 -0
- package/src/types/utils.ts +3 -0
- package/src/utils/__tests__/active-run.test.ts +140 -0
- package/src/utils/__tests__/activity-tracker.test.ts +440 -0
- package/src/utils/__tests__/agent-display.test.ts +139 -0
- package/src/utils/__tests__/analytics-client.test.ts +262 -0
- package/src/utils/__tests__/anonymous-id.test.ts +74 -0
- package/src/utils/__tests__/anvil-api.test.ts +578 -0
- package/src/utils/__tests__/anvil-instance-owner.test.ts +69 -0
- package/src/utils/__tests__/anvil-model-navigation.test.ts +102 -0
- package/src/utils/__tests__/anvil-premium-reset.test.ts +79 -0
- package/src/utils/__tests__/anvil-referral-cache.test.ts +116 -0
- package/src/utils/__tests__/anvil-session-api.test.ts +215 -0
- package/src/utils/__tests__/anvil-session-display.test.ts +23 -0
- package/src/utils/__tests__/anvil-streak-line.test.ts +217 -0
- package/src/utils/__tests__/arrays.test.ts +264 -0
- package/src/utils/__tests__/bash-context-processor.test.ts +38 -0
- package/src/utils/__tests__/block-processor.test.ts +810 -0
- package/src/utils/__tests__/chat-history.test.ts +203 -0
- package/src/utils/__tests__/chat-input-key-intercept.test.ts +40 -0
- package/src/utils/__tests__/chat-meta.test.ts +130 -0
- package/src/utils/__tests__/clipboard-linux.test.ts +359 -0
- package/src/utils/__tests__/clipboard.test.ts +910 -0
- package/src/utils/__tests__/code-search-summary.test.ts +84 -0
- package/src/utils/__tests__/collapse-helpers.test.ts +1109 -0
- package/src/utils/__tests__/error-handling.test.ts +658 -0
- package/src/utils/__tests__/exit-cleanly.test.ts +110 -0
- package/src/utils/__tests__/feedback-helpers.test.ts +444 -0
- package/src/utils/__tests__/feedback-submission.test.ts +26 -0
- package/src/utils/__tests__/fetch-usage.test.ts +355 -0
- package/src/utils/__tests__/fingerprint.test.ts +144 -0
- package/src/utils/__tests__/fixtures/terminal-command-broker-child.ts +7 -0
- package/src/utils/__tests__/fixtures/terminal-command-broker-entry.ts +3 -0
- package/src/utils/__tests__/fixtures/terminal-command-broker-owner.ts +33 -0
- package/src/utils/__tests__/format-elapsed-time.test.ts +103 -0
- package/src/utils/__tests__/format-timeout.test.ts +87 -0
- package/src/utils/__tests__/image-dimensions.test.ts +249 -0
- package/src/utils/__tests__/image-processor.test.ts +209 -0
- package/src/utils/__tests__/implementor-helpers.test.ts +1458 -0
- package/src/utils/__tests__/keyboard-actions.test.ts +660 -0
- package/src/utils/__tests__/layout-helpers.test.ts +36 -0
- package/src/utils/__tests__/lazy-response-ads.test.ts +167 -0
- package/src/utils/__tests__/log-shipper.test.ts +53 -0
- package/src/utils/__tests__/markdown-renderer.test.tsx +421 -0
- package/src/utils/__tests__/message-block-helpers.test.ts +1263 -0
- package/src/utils/__tests__/message-updater.test.ts +645 -0
- package/src/utils/__tests__/osc-timeout-scenarios.test.ts +172 -0
- package/src/utils/__tests__/pending-attachments.test.ts +277 -0
- package/src/utils/__tests__/polling-backoff.test.ts +51 -0
- package/src/utils/__tests__/queue-panel-actions.test.ts +148 -0
- package/src/utils/__tests__/run-state-storage.test.ts +919 -0
- package/src/utils/__tests__/safe-json.test.ts +77 -0
- package/src/utils/__tests__/sdk-event-handlers.test.ts +685 -0
- package/src/utils/__tests__/send-message-helpers.test.ts +1898 -0
- package/src/utils/__tests__/send-message-timer.test.ts +64 -0
- package/src/utils/__tests__/settings.test.ts +99 -0
- package/src/utils/__tests__/strings.test.ts +192 -0
- package/src/utils/__tests__/terminal-color-detection.test.ts +425 -0
- package/src/utils/__tests__/terminal-command-broker.test.ts +528 -0
- package/src/utils/__tests__/terminal-enter-detection.test.ts +77 -0
- package/src/utils/__tests__/terminal-io.test.ts +137 -0
- package/src/utils/__tests__/terminal-protocol-controller.test.ts +119 -0
- package/src/utils/__tests__/text-layout.test.ts +82 -0
- package/src/utils/__tests__/theme-platform-detection.test.ts +125 -0
- package/src/utils/__tests__/think-tag-parser.test.ts +159 -0
- package/src/utils/__tests__/trace-writer.test.ts +223 -0
- package/src/utils/__tests__/trim-chat-logs.test.ts +78 -0
- package/src/utils/__tests__/usage-banner-state.test.ts +298 -0
- package/src/utils/__tests__/validation-error-formatting.test.ts +126 -0
- package/src/utils/__tests__/windows-terminal-health.test.ts +101 -0
- package/src/utils/__tests__/write-file-atomic.test.ts +127 -0
- package/src/utils/active-run.ts +131 -0
- package/src/utils/activity-tracker.ts +66 -0
- package/src/utils/agent-display.ts +87 -0
- package/src/utils/agent-helpers.ts +27 -0
- package/src/utils/agent-id-utils.ts +14 -0
- package/src/utils/ai-message-id.ts +12 -0
- package/src/utils/analytics.ts +361 -0
- package/src/utils/anonymous-id.ts +87 -0
- package/src/utils/anvil-agent-selection.ts +33 -0
- package/src/utils/anvil-api.ts +612 -0
- package/src/utils/anvil-client.ts +217 -0
- package/src/utils/anvil-instance-owner.ts +66 -0
- package/src/utils/anvil-model-navigation.ts +50 -0
- package/src/utils/anvil-premium-reset.ts +55 -0
- package/src/utils/anvil-referral-cache.ts +51 -0
- package/src/utils/anvil-session-api.ts +243 -0
- package/src/utils/anvil-session-display.ts +21 -0
- package/src/utils/anvil-streak-line.ts +93 -0
- package/src/utils/arrays.ts +117 -0
- package/src/utils/auth.ts +258 -0
- package/src/utils/bash-context-processor.ts +47 -0
- package/src/utils/bash-messages.ts +108 -0
- package/src/utils/block-margins.ts +35 -0
- package/src/utils/block-operations.ts +523 -0
- package/src/utils/block-processor.ts +213 -0
- package/src/utils/chat-history.ts +253 -0
- package/src/utils/chat-input-key-intercept.ts +52 -0
- package/src/utils/chat-meta.ts +90 -0
- package/src/utils/chat-scroll-accel.ts +151 -0
- package/src/utils/clipboard-image.ts +588 -0
- package/src/utils/clipboard.ts +397 -0
- package/src/utils/code-search-summary.ts +70 -0
- package/src/utils/collapse-helpers.ts +256 -0
- package/src/utils/config-dir.ts +24 -0
- package/src/utils/constants.ts +190 -0
- package/src/utils/create-event-handler-state.ts +73 -0
- package/src/utils/create-run-config.ts +121 -0
- package/src/utils/detect-shell.ts +116 -0
- package/src/utils/directory-browser.ts +72 -0
- package/src/utils/engagement.ts +55 -0
- package/src/utils/env.ts +92 -0
- package/src/utils/error-handling.ts +255 -0
- package/src/utils/error-messages.ts +62 -0
- package/src/utils/exit-cleanly.ts +86 -0
- package/src/utils/feedback-helpers.ts +103 -0
- package/src/utils/feedback-submission.ts +22 -0
- package/src/utils/fetch-usage.ts +76 -0
- package/src/utils/fingerprint.ts +245 -0
- package/src/utils/format-elapsed-time.ts +33 -0
- package/src/utils/format-session-units.ts +6 -0
- package/src/utils/format-timeout.ts +28 -0
- package/src/utils/format-validation-errors-for-message.ts +84 -0
- package/src/utils/git.ts +17 -0
- package/src/utils/helpers.ts +47 -0
- package/src/utils/image-display.ts +67 -0
- package/src/utils/image-handler.ts +325 -0
- package/src/utils/image-processor.ts +133 -0
- package/src/utils/image-thumbnail.ts +78 -0
- package/src/utils/implementor-helpers.ts +787 -0
- package/src/utils/input-modes.ts +174 -0
- package/src/utils/keyboard-actions.ts +392 -0
- package/src/utils/keypad-keys.ts +47 -0
- package/src/utils/layout-helpers.ts +33 -0
- package/src/utils/lazy-response-ads.ts +1 -0
- package/src/utils/local-agent-registry.ts +474 -0
- package/src/utils/log-shipper.ts +126 -0
- package/src/utils/logger.ts +327 -0
- package/src/utils/markdown-renderer.tsx +1090 -0
- package/src/utils/math.ts +3 -0
- package/src/utils/message-block-helpers.ts +684 -0
- package/src/utils/message-history.ts +143 -0
- package/src/utils/message-tree-utils.ts +67 -0
- package/src/utils/message-updater.ts +279 -0
- package/src/utils/open-file.ts +146 -0
- package/src/utils/open-url.ts +63 -0
- package/src/utils/path-completion.ts +111 -0
- package/src/utils/path-helpers.ts +38 -0
- package/src/utils/pending-attachments.ts +360 -0
- package/src/utils/polling-backoff.ts +59 -0
- package/src/utils/project-picker.ts +12 -0
- package/src/utils/queue-panel-actions.ts +70 -0
- package/src/utils/recent-projects.ts +156 -0
- package/src/utils/renderer-cleanup.ts +233 -0
- package/src/utils/response-ad-positions.ts +1 -0
- package/src/utils/run-state-storage.ts +603 -0
- package/src/utils/safe-json.ts +153 -0
- package/src/utils/sdk-event-handlers.ts +571 -0
- package/src/utils/send-message-helpers.ts +210 -0
- package/src/utils/send-message-timer.ts +110 -0
- package/src/utils/settings.ts +226 -0
- package/src/utils/skill-registry.ts +94 -0
- package/src/utils/spawn-agent-matcher.ts +55 -0
- package/src/utils/status-indicator-state.ts +107 -0
- package/src/utils/stream-chunk-processor.ts +57 -0
- package/src/utils/strings.ts +271 -0
- package/src/utils/subscription.ts +31 -0
- package/src/utils/syntax-highlighter.tsx +19 -0
- package/src/utils/terminal-color-detection.ts +474 -0
- package/src/utils/terminal-command-broker.ts +467 -0
- package/src/utils/terminal-enter-detection.ts +63 -0
- package/src/utils/terminal-images.ts +229 -0
- package/src/utils/terminal-io.ts +85 -0
- package/src/utils/terminal-protocol-controller.ts +173 -0
- package/src/utils/terminal-reset-sequences.ts +33 -0
- package/src/utils/terminal-title.ts +84 -0
- package/src/utils/terminal-watchdog.ts +366 -0
- package/src/utils/text-layout.ts +149 -0
- package/src/utils/theme-config.ts +141 -0
- package/src/utils/theme-system.ts +1206 -0
- package/src/utils/think-tag-parser.ts +95 -0
- package/src/utils/time-format.ts +21 -0
- package/src/utils/trace-writer.ts +162 -0
- package/src/utils/ui-constants.ts +69 -0
- package/src/utils/update-checker.ts +110 -0
- package/src/utils/usage-banner-state.ts +146 -0
- package/src/utils/validation-error-formatting.ts +86 -0
- package/src/utils/validation-error-helpers.ts +19 -0
- package/src/utils/windows-terminal-health.ts +124 -0
- package/src/utils/word-wrap-utils.ts +53 -0
- package/src/utils/write-file-atomic.ts +54 -0
- package/src/utils/yield-to-event-loop.ts +9 -0
- package/bin/anvil.cjs +0 -40
- package/dist/bundled.js +0 -123508
- package/dist/bundled.js.map +0 -828
- package/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/arm64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-darwin/rg +0 -0
- package/dist/vendor/ripgrep/x64-linux/rg +0 -0
- package/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { TextAttributes } from '@opentui/core'
|
|
2
|
+
|
|
3
|
+
import { DiffViewer } from './diff-viewer'
|
|
4
|
+
import { defineToolComponent } from './types'
|
|
5
|
+
import { useTheme } from '../../hooks/use-theme'
|
|
6
|
+
|
|
7
|
+
import type { ToolRenderConfig } from './types'
|
|
8
|
+
|
|
9
|
+
type PatchOperation =
|
|
10
|
+
| { type: 'create_file'; path: string; diff: string }
|
|
11
|
+
| { type: 'update_file'; path: string; diff: string }
|
|
12
|
+
| { type: 'delete_file'; path: string }
|
|
13
|
+
|
|
14
|
+
function parseOperation(input: unknown): PatchOperation | null {
|
|
15
|
+
if (!input || typeof input !== 'object') return null
|
|
16
|
+
const op = (input as { operation?: unknown }).operation
|
|
17
|
+
if (!op || typeof op !== 'object') return null
|
|
18
|
+
const { type, path, diff } = op as Record<string, unknown>
|
|
19
|
+
if (typeof type !== 'string' || typeof path !== 'string') return null
|
|
20
|
+
if (type === 'create_file' && typeof diff === 'string') {
|
|
21
|
+
return { type: 'create_file', path, diff }
|
|
22
|
+
}
|
|
23
|
+
if (type === 'update_file' && typeof diff === 'string') {
|
|
24
|
+
return { type: 'update_file', path, diff }
|
|
25
|
+
}
|
|
26
|
+
if (type === 'delete_file') {
|
|
27
|
+
return { type: 'delete_file', path }
|
|
28
|
+
}
|
|
29
|
+
return null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface EditHeaderProps {
|
|
33
|
+
name: string
|
|
34
|
+
filePath: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const EditHeader = ({ name, filePath }: EditHeaderProps) => {
|
|
38
|
+
const theme = useTheme()
|
|
39
|
+
const bulletChar = '• '
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<box style={{ flexDirection: 'row', alignItems: 'center', width: '100%' }}>
|
|
43
|
+
<text style={{ wrapMode: 'word' }}>
|
|
44
|
+
<span fg={theme.foreground}>{bulletChar}</span>
|
|
45
|
+
<span fg={theme.foreground} attributes={TextAttributes.BOLD}>
|
|
46
|
+
{name}
|
|
47
|
+
</span>
|
|
48
|
+
<span fg={theme.foreground}>{` ${filePath}`}</span>
|
|
49
|
+
</text>
|
|
50
|
+
</box>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface PatchOperationItemProps {
|
|
55
|
+
operation: PatchOperation
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const PatchOperationItem = ({ operation }: PatchOperationItemProps) => {
|
|
59
|
+
if (operation.type === 'create_file') {
|
|
60
|
+
return <EditHeader name="Create" filePath={operation.path} />
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (operation.type === 'delete_file') {
|
|
64
|
+
return <EditHeader name="Delete" filePath={operation.path} />
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<box style={{ flexDirection: 'column', width: '100%' }}>
|
|
69
|
+
<EditHeader name="Edit" filePath={operation.path} />
|
|
70
|
+
<box style={{ paddingLeft: 2, width: '100%' }}>
|
|
71
|
+
<DiffViewer diffText={operation.diff} />
|
|
72
|
+
</box>
|
|
73
|
+
</box>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const ApplyPatchComponent = defineToolComponent({
|
|
78
|
+
toolName: 'apply_patch',
|
|
79
|
+
|
|
80
|
+
render(toolBlock): ToolRenderConfig {
|
|
81
|
+
const operation = parseOperation(toolBlock.input)
|
|
82
|
+
|
|
83
|
+
if (!operation) {
|
|
84
|
+
return { content: null }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
content: (
|
|
89
|
+
<box style={{ flexDirection: 'column', gap: 0, width: '100%' }}>
|
|
90
|
+
<PatchOperationItem operation={operation} />
|
|
91
|
+
</box>
|
|
92
|
+
),
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
4
|
+
import { defineToolComponent } from './types'
|
|
5
|
+
import { countCodeSearchResults } from '../../utils/code-search-summary'
|
|
6
|
+
|
|
7
|
+
import type { ToolRenderConfig } from './types'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* UI component for code_search tool.
|
|
11
|
+
* Displays a single line showing the search pattern, flags, and number of results.
|
|
12
|
+
* Does not support expand/collapse - always shows as a single line.
|
|
13
|
+
*/
|
|
14
|
+
export const CodeSearchComponent = defineToolComponent({
|
|
15
|
+
toolName: 'code_search',
|
|
16
|
+
|
|
17
|
+
render(toolBlock): ToolRenderConfig {
|
|
18
|
+
const input = toolBlock.input as any
|
|
19
|
+
const pattern = input?.pattern ?? ''
|
|
20
|
+
const cwd = input?.cwd ?? ''
|
|
21
|
+
|
|
22
|
+
const totalResults = countCodeSearchResults(toolBlock.output)
|
|
23
|
+
|
|
24
|
+
// Build single-line summary
|
|
25
|
+
let summary = ''
|
|
26
|
+
|
|
27
|
+
summary += `${pattern}`
|
|
28
|
+
|
|
29
|
+
if (cwd) {
|
|
30
|
+
summary += ` in ${cwd}`
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Disable showing flags since they are noisy.
|
|
34
|
+
// if (flags) {
|
|
35
|
+
// summary += ` ${flags}`
|
|
36
|
+
// }
|
|
37
|
+
|
|
38
|
+
summary += ` (${totalResults} result${totalResults === 1 ? '' : 's'})`
|
|
39
|
+
|
|
40
|
+
// Return as content using SimpleToolCallItem
|
|
41
|
+
return {
|
|
42
|
+
content: <SimpleToolCallItem name="Search" description={summary} />,
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
})
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
2
|
+
import { defineToolComponent } from './types'
|
|
3
|
+
|
|
4
|
+
import type { ToolBlock, ToolRenderConfig } from './types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Formats an array of items as a comma-separated list, truncated to maxItems.
|
|
8
|
+
*/
|
|
9
|
+
function formatList(items: string[], maxItems = 3): string {
|
|
10
|
+
if (items.length === 0) return ''
|
|
11
|
+
const shown = items.slice(0, maxItems)
|
|
12
|
+
const remainder = items.length - shown.length
|
|
13
|
+
const suffix = remainder > 0 ? ` +${remainder} more` : ''
|
|
14
|
+
return shown.join(', ') + suffix
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* UI component for composio_manage_connections tool.
|
|
19
|
+
* Shows "App Connections" with the toolkit names being connected.
|
|
20
|
+
*/
|
|
21
|
+
export const ManageConnectionsComponent = defineToolComponent({
|
|
22
|
+
toolName: 'composio_manage_connections',
|
|
23
|
+
|
|
24
|
+
render(toolBlock: ToolBlock & { toolName: 'composio_manage_connections' }): ToolRenderConfig {
|
|
25
|
+
const input = toolBlock.input as {
|
|
26
|
+
toolkits?: string[]
|
|
27
|
+
reinitiate_all?: boolean
|
|
28
|
+
} | undefined
|
|
29
|
+
const toolkits = input?.toolkits ?? []
|
|
30
|
+
const description = toolkits.length > 0 ? formatList(toolkits) : ''
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
content: (
|
|
34
|
+
<SimpleToolCallItem name="App Connections" description={description} />
|
|
35
|
+
),
|
|
36
|
+
collapsedPreview: description,
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Stringify a non-string tool value for display, breaking cycles so a raw
|
|
43
|
+
* composio result can't throw during the TUI render.
|
|
44
|
+
*/
|
|
45
|
+
function stringifyToolValue(value: unknown): string {
|
|
46
|
+
if (typeof value === 'string') return value
|
|
47
|
+
try {
|
|
48
|
+
return JSON.stringify(value)
|
|
49
|
+
} catch {
|
|
50
|
+
const ancestors: unknown[] = []
|
|
51
|
+
return JSON.stringify(value, function (this: unknown, _key, val) {
|
|
52
|
+
if (ancestors.length > 0) {
|
|
53
|
+
const thisPos = ancestors.indexOf(this)
|
|
54
|
+
if (thisPos !== -1) {
|
|
55
|
+
ancestors.splice(thisPos + 1)
|
|
56
|
+
} else {
|
|
57
|
+
ancestors.push(this)
|
|
58
|
+
}
|
|
59
|
+
if (
|
|
60
|
+
typeof val === 'object' &&
|
|
61
|
+
val !== null &&
|
|
62
|
+
ancestors.includes(val)
|
|
63
|
+
) {
|
|
64
|
+
return '[Circular]'
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
ancestors.push(val)
|
|
68
|
+
}
|
|
69
|
+
return val
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* UI component for composio_multi_execute_tool tool.
|
|
76
|
+
* Shows "App Action" with the thought or tool slugs being executed.
|
|
77
|
+
*/
|
|
78
|
+
export const ExecuteToolComponent = defineToolComponent({
|
|
79
|
+
toolName: 'composio_multi_execute_tool',
|
|
80
|
+
|
|
81
|
+
render(toolBlock: ToolBlock & { toolName: 'composio_multi_execute_tool' }): ToolRenderConfig {
|
|
82
|
+
const input = toolBlock.input as {
|
|
83
|
+
tools?: Array<Record<string, unknown>>
|
|
84
|
+
thought?: string
|
|
85
|
+
} | undefined
|
|
86
|
+
const tools = input?.tools ?? []
|
|
87
|
+
const thought = input?.thought
|
|
88
|
+
|
|
89
|
+
// Prefer the thought as description, otherwise extract tool slugs
|
|
90
|
+
const description =
|
|
91
|
+
thought ??
|
|
92
|
+
(tools.length > 0
|
|
93
|
+
? formatList(tools.map((t) => stringifyToolValue(t.slug)))
|
|
94
|
+
: '')
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
content: (
|
|
98
|
+
<SimpleToolCallItem name="App Action" description={description} />
|
|
99
|
+
),
|
|
100
|
+
collapsedPreview: description,
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* UI component for composio_search_tools tool.
|
|
107
|
+
* Shows "App Search" with the search queries.
|
|
108
|
+
*/
|
|
109
|
+
export const SearchToolsComponent = defineToolComponent({
|
|
110
|
+
toolName: 'composio_search_tools',
|
|
111
|
+
|
|
112
|
+
render(toolBlock: ToolBlock & { toolName: 'composio_search_tools' }): ToolRenderConfig {
|
|
113
|
+
const input = toolBlock.input as {
|
|
114
|
+
queries?: unknown[]
|
|
115
|
+
} | undefined
|
|
116
|
+
const queries = input?.queries ?? []
|
|
117
|
+
const description =
|
|
118
|
+
queries.length > 0
|
|
119
|
+
? formatList(queries.map((q) => stringifyToolValue(q)))
|
|
120
|
+
: ''
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
content: (
|
|
124
|
+
<SimpleToolCallItem name="App Search" description={description} />
|
|
125
|
+
),
|
|
126
|
+
collapsedPreview: description,
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* UI component for composio_get_tool_schemas tool.
|
|
133
|
+
* Shows "App Schemas" with the tool slugs being queried.
|
|
134
|
+
*/
|
|
135
|
+
export const GetToolSchemasComponent = defineToolComponent({
|
|
136
|
+
toolName: 'composio_get_tool_schemas',
|
|
137
|
+
|
|
138
|
+
render(toolBlock: ToolBlock & { toolName: 'composio_get_tool_schemas' }): ToolRenderConfig {
|
|
139
|
+
const input = toolBlock.input as {
|
|
140
|
+
tool_slugs?: string[]
|
|
141
|
+
} | undefined
|
|
142
|
+
const toolSlugs = input?.tool_slugs ?? []
|
|
143
|
+
const description = toolSlugs.length > 0 ? formatList(toolSlugs) : ''
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
content: (
|
|
147
|
+
<SimpleToolCallItem name="App Schemas" description={description} />
|
|
148
|
+
),
|
|
149
|
+
collapsedPreview: description,
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
})
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { TextAttributes } from '@opentui/core'
|
|
2
|
+
|
|
3
|
+
import { useTheme } from '../../hooks/use-theme'
|
|
4
|
+
|
|
5
|
+
interface DiffViewerProps {
|
|
6
|
+
diffText: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const DIFF_LINE_COLORS = {
|
|
10
|
+
dark: {
|
|
11
|
+
added: '#7ACC35',
|
|
12
|
+
removed: '#BF6C69',
|
|
13
|
+
},
|
|
14
|
+
light: {
|
|
15
|
+
added: '#4A9E1C',
|
|
16
|
+
removed: '#C53030',
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const lineColor = (
|
|
21
|
+
line: string,
|
|
22
|
+
themeName: 'dark' | 'light',
|
|
23
|
+
mutedColor: string,
|
|
24
|
+
): { fg: string; attrs?: number } => {
|
|
25
|
+
if (line.startsWith('@@')) {
|
|
26
|
+
return { fg: 'cyan', attrs: TextAttributes.BOLD }
|
|
27
|
+
}
|
|
28
|
+
if (line.startsWith('+++') || line.startsWith('---')) {
|
|
29
|
+
return { fg: mutedColor, attrs: TextAttributes.BOLD }
|
|
30
|
+
}
|
|
31
|
+
if (
|
|
32
|
+
line.startsWith('diff ') ||
|
|
33
|
+
line.startsWith('index ') ||
|
|
34
|
+
line.startsWith('rename ') ||
|
|
35
|
+
line.startsWith('similarity ')
|
|
36
|
+
) {
|
|
37
|
+
return { fg: mutedColor }
|
|
38
|
+
}
|
|
39
|
+
if (line.startsWith('+')) {
|
|
40
|
+
return { fg: DIFF_LINE_COLORS[themeName].added }
|
|
41
|
+
}
|
|
42
|
+
if (line.startsWith('-')) {
|
|
43
|
+
return { fg: DIFF_LINE_COLORS[themeName].removed }
|
|
44
|
+
}
|
|
45
|
+
if (line.startsWith('\\')) {
|
|
46
|
+
return { fg: mutedColor }
|
|
47
|
+
}
|
|
48
|
+
return { fg: '' }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export const DiffViewer = ({ diffText }: DiffViewerProps) => {
|
|
52
|
+
const theme = useTheme()
|
|
53
|
+
|
|
54
|
+
const lines = diffText.trim().split('\n')
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<box
|
|
58
|
+
style={{ flexDirection: 'column', gap: 0, width: '100%', flexGrow: 1 }}
|
|
59
|
+
>
|
|
60
|
+
{lines
|
|
61
|
+
.filter((rawLine) => !rawLine.startsWith('@@'))
|
|
62
|
+
.map((rawLine, idx) => {
|
|
63
|
+
const line = rawLine.length === 0 ? ' ' : rawLine
|
|
64
|
+
const { fg, attrs } = lineColor(line, theme.name, theme.muted)
|
|
65
|
+
const resolvedFg = fg || theme.foreground
|
|
66
|
+
return (
|
|
67
|
+
<text key={`diff-line-${idx}`} style={{ wrapMode: 'none' }}>
|
|
68
|
+
<span fg={resolvedFg} attributes={attrs}>
|
|
69
|
+
{line}
|
|
70
|
+
</span>
|
|
71
|
+
</text>
|
|
72
|
+
)
|
|
73
|
+
})}
|
|
74
|
+
</box>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
2
|
+
import { defineToolComponent } from './types'
|
|
3
|
+
|
|
4
|
+
import type { ToolRenderConfig } from './types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* UI component for glob tool.
|
|
8
|
+
* Displays a single line showing the glob pattern and number of matching files.
|
|
9
|
+
* Does not support expand/collapse - always shows as a single line.
|
|
10
|
+
*/
|
|
11
|
+
export const GlobComponent = defineToolComponent({
|
|
12
|
+
toolName: 'glob',
|
|
13
|
+
|
|
14
|
+
render(toolBlock): ToolRenderConfig {
|
|
15
|
+
const input = toolBlock.input as any
|
|
16
|
+
const pattern = input?.pattern ?? ''
|
|
17
|
+
const cwd = input?.cwd ?? ''
|
|
18
|
+
|
|
19
|
+
// Parse output to check for errors
|
|
20
|
+
let hasError = false
|
|
21
|
+
|
|
22
|
+
if (toolBlock.output) {
|
|
23
|
+
const outputArray = Array.isArray(toolBlock.output)
|
|
24
|
+
? toolBlock.output
|
|
25
|
+
: [toolBlock.output]
|
|
26
|
+
|
|
27
|
+
for (const item of outputArray) {
|
|
28
|
+
const output = item as any
|
|
29
|
+
if (output?.type === 'json' && output?.value) {
|
|
30
|
+
const value = output.value as any
|
|
31
|
+
if (value.errorMessage) {
|
|
32
|
+
hasError = true
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!pattern) {
|
|
39
|
+
return { content: null }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Build single-line summary
|
|
43
|
+
let summary = pattern
|
|
44
|
+
|
|
45
|
+
if (cwd) {
|
|
46
|
+
summary += ` in ${cwd}`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (hasError) {
|
|
50
|
+
summary += ' (error)'
|
|
51
|
+
}
|
|
52
|
+
// TODO(James): Reenable when we pass tool results as an object
|
|
53
|
+
// else {
|
|
54
|
+
// summary += ` (${fileCount} file${fileCount === 1 ? '' : 's'})`
|
|
55
|
+
// }
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
content: <SimpleToolCallItem name="Glob" description={summary} />,
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
2
|
+
import { defineToolComponent } from './types'
|
|
3
|
+
|
|
4
|
+
import type { ToolRenderConfig } from './types'
|
|
5
|
+
|
|
6
|
+
const asTrimmedString = (value: unknown): string =>
|
|
7
|
+
typeof value === 'string' ? value.trim() : ''
|
|
8
|
+
|
|
9
|
+
const DEFAULT_NAME = 'Services'
|
|
10
|
+
|
|
11
|
+
export interface GravityIndexParts {
|
|
12
|
+
/** Bold label naming the action in plain verb-first language. */
|
|
13
|
+
name: string
|
|
14
|
+
/** Non-bold target the action operates on (query, slug, category). May be empty. */
|
|
15
|
+
description: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Splits a gravity_index tool call into a bold verb-first label (e.g.
|
|
20
|
+
* "Search services") and the plain target it acts on, so the action reads as
|
|
21
|
+
* a single natural phrase instead of a "Brand · Verb" subcommand.
|
|
22
|
+
*/
|
|
23
|
+
export const getGravityIndexParts = (input: unknown): GravityIndexParts => {
|
|
24
|
+
if (!input || typeof input !== 'object') {
|
|
25
|
+
return { name: DEFAULT_NAME, description: '' }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const params = input as Record<string, unknown>
|
|
29
|
+
const action = asTrimmedString(params.action)
|
|
30
|
+
|
|
31
|
+
switch (action) {
|
|
32
|
+
case 'search':
|
|
33
|
+
return {
|
|
34
|
+
name: 'Search services',
|
|
35
|
+
description: asTrimmedString(params.query),
|
|
36
|
+
}
|
|
37
|
+
case 'browse': {
|
|
38
|
+
const category = asTrimmedString(params.category)
|
|
39
|
+
const keyword = asTrimmedString(params.q)
|
|
40
|
+
return {
|
|
41
|
+
name: 'Browse services',
|
|
42
|
+
description: [category, keyword].filter(Boolean).join(' · '),
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
case 'list_categories':
|
|
46
|
+
return { name: 'List service categories', description: '' }
|
|
47
|
+
case 'get_service':
|
|
48
|
+
return {
|
|
49
|
+
name: 'Fetch service',
|
|
50
|
+
description: asTrimmedString(params.slug),
|
|
51
|
+
}
|
|
52
|
+
case 'report_integration': {
|
|
53
|
+
const slug = asTrimmedString(params.integrated_slug)
|
|
54
|
+
return {
|
|
55
|
+
name: 'Report integration',
|
|
56
|
+
description: slug ? `${slug} integration` : 'integration',
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
default:
|
|
60
|
+
return { name: DEFAULT_NAME, description: '' }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* UI component for gravity_index.
|
|
66
|
+
* Displays a one-line summary of what Gravity Index is searching or doing.
|
|
67
|
+
*/
|
|
68
|
+
export const GravityIndexComponent = defineToolComponent({
|
|
69
|
+
toolName: 'gravity_index',
|
|
70
|
+
|
|
71
|
+
render(toolBlock): ToolRenderConfig {
|
|
72
|
+
const { name, description } = getGravityIndexParts(toolBlock.input)
|
|
73
|
+
return {
|
|
74
|
+
content: <SimpleToolCallItem name={name} description={description} />,
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
4
|
+
import { defineToolComponent } from './types'
|
|
5
|
+
import { useTheme } from '../../hooks/use-theme'
|
|
6
|
+
|
|
7
|
+
import type { ToolRenderConfig } from './types'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* UI component for list_directory tool.
|
|
11
|
+
* Displays a single line showing the directories being listed.
|
|
12
|
+
* Does not support expand/collapse - always shows as a single line.
|
|
13
|
+
*/
|
|
14
|
+
export const ListDirectoryComponent = defineToolComponent({
|
|
15
|
+
toolName: 'list_directory',
|
|
16
|
+
|
|
17
|
+
render(toolBlock): ToolRenderConfig {
|
|
18
|
+
const input = toolBlock.input as any
|
|
19
|
+
|
|
20
|
+
// Extract directories from input
|
|
21
|
+
let directories: string[] = []
|
|
22
|
+
|
|
23
|
+
if (Array.isArray(input?.directories)) {
|
|
24
|
+
directories = input.directories
|
|
25
|
+
.map((dir: any) =>
|
|
26
|
+
typeof dir === 'object' && dir.path ? dir.path : dir,
|
|
27
|
+
)
|
|
28
|
+
.filter(
|
|
29
|
+
(path: any) => typeof path === 'string' && path.trim().length > 0,
|
|
30
|
+
)
|
|
31
|
+
} else if (
|
|
32
|
+
typeof input?.path === 'string' &&
|
|
33
|
+
input.path.trim().length > 0
|
|
34
|
+
) {
|
|
35
|
+
directories = [input.path.trim()]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (directories.length === 0) {
|
|
39
|
+
return { content: null }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Format directory list
|
|
43
|
+
const description = directories.join(', ')
|
|
44
|
+
|
|
45
|
+
// Use a wrapper component to access theme
|
|
46
|
+
const ListDirectoryContent = () => {
|
|
47
|
+
const theme = useTheme()
|
|
48
|
+
return (
|
|
49
|
+
<SimpleToolCallItem
|
|
50
|
+
name="List"
|
|
51
|
+
description={description}
|
|
52
|
+
descriptionColor={theme.directory}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
content: <ListDirectoryContent />,
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
2
|
+
import { defineToolComponent } from './types'
|
|
3
|
+
|
|
4
|
+
import type { ToolRenderConfig } from './types'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* UI component for read_docs tool.
|
|
8
|
+
* Displays library name and topic in a compact format.
|
|
9
|
+
* Does not support expand/collapse - always shows as a simple line.
|
|
10
|
+
*/
|
|
11
|
+
export const ReadDocsComponent = defineToolComponent({
|
|
12
|
+
toolName: 'read_docs',
|
|
13
|
+
|
|
14
|
+
render(toolBlock): ToolRenderConfig {
|
|
15
|
+
const input = toolBlock.input as any
|
|
16
|
+
|
|
17
|
+
// Extract library and topic from input
|
|
18
|
+
const libraryTitle =
|
|
19
|
+
typeof input?.libraryTitle === 'string' ? input.libraryTitle.trim() : ''
|
|
20
|
+
const topic = typeof input?.topic === 'string' ? input.topic.trim() : ''
|
|
21
|
+
|
|
22
|
+
if (!libraryTitle && !topic) {
|
|
23
|
+
return { content: null }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const description =
|
|
27
|
+
libraryTitle && topic
|
|
28
|
+
? `${libraryTitle}: ${topic}`
|
|
29
|
+
: libraryTitle || topic
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
content: (
|
|
33
|
+
<SimpleToolCallItem name="Read Docs" description={description} />
|
|
34
|
+
),
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
})
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { readFilePathsOf } from '@anvil/common/tools/params/tool/read-files'
|
|
2
|
+
import { isEnvTemplateFilePath } from '@anvil/common/util/env-file-path'
|
|
3
|
+
import { TextAttributes } from '@opentui/core'
|
|
4
|
+
|
|
5
|
+
import { SimpleToolCallItem } from './tool-call-item'
|
|
6
|
+
import { defineToolComponent } from './types'
|
|
7
|
+
import { useTheme } from '../../hooks/use-theme'
|
|
8
|
+
import { isSensitiveFile } from '../../utils/create-run-config'
|
|
9
|
+
|
|
10
|
+
import type { ToolRenderConfig } from './types'
|
|
11
|
+
|
|
12
|
+
function FilePathsDescription({ filePaths }: { filePaths: string[] }) {
|
|
13
|
+
const theme = useTheme()
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
{filePaths.map((fp, idx) => {
|
|
18
|
+
const isLast = idx === filePaths.length - 1
|
|
19
|
+
const separator = isLast ? '' : ', '
|
|
20
|
+
|
|
21
|
+
if (isSensitiveFile(fp)) {
|
|
22
|
+
return (
|
|
23
|
+
<span key={fp}>
|
|
24
|
+
<span fg={theme.muted} attributes={TextAttributes.STRIKETHROUGH}>
|
|
25
|
+
{fp}
|
|
26
|
+
</span>
|
|
27
|
+
<span fg={theme.muted}> (blocked)</span>
|
|
28
|
+
<span fg={theme.foreground}>{separator}</span>
|
|
29
|
+
</span>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (isEnvTemplateFilePath(fp)) {
|
|
34
|
+
return (
|
|
35
|
+
<span key={fp}>
|
|
36
|
+
<span fg={theme.foreground}>{fp}</span>
|
|
37
|
+
<span fg={theme.muted}> (allowed - example only)</span>
|
|
38
|
+
<span fg={theme.foreground}>{separator}</span>
|
|
39
|
+
</span>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<span key={fp} fg={theme.foreground}>
|
|
45
|
+
{fp}
|
|
46
|
+
{separator}
|
|
47
|
+
</span>
|
|
48
|
+
)
|
|
49
|
+
})}
|
|
50
|
+
</>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* UI component for read_files tool.
|
|
56
|
+
* Displays file paths with labels for blocked/template files.
|
|
57
|
+
*/
|
|
58
|
+
export const ReadFilesComponent = defineToolComponent({
|
|
59
|
+
toolName: 'read_files',
|
|
60
|
+
|
|
61
|
+
render(toolBlock): ToolRenderConfig {
|
|
62
|
+
const input = toolBlock.input as any
|
|
63
|
+
|
|
64
|
+
// Extract file paths from input
|
|
65
|
+
const filePaths: string[] = readFilePathsOf(input?.paths)
|
|
66
|
+
|
|
67
|
+
if (filePaths.length === 0) {
|
|
68
|
+
return { content: null }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check if any files need special labels
|
|
72
|
+
const hasSpecialFiles = filePaths.some(
|
|
73
|
+
(fp) => isSensitiveFile(fp) || isEnvTemplateFilePath(fp),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
content: (
|
|
78
|
+
<SimpleToolCallItem
|
|
79
|
+
name="Read"
|
|
80
|
+
description={
|
|
81
|
+
hasSpecialFiles ? (
|
|
82
|
+
<FilePathsDescription filePaths={filePaths} />
|
|
83
|
+
) : (
|
|
84
|
+
filePaths.join(', ')
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
/>
|
|
88
|
+
),
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
})
|