@alumbwe/anvil 1.0.0
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 +84 -0
- package/bin/anvil +2 -0
- package/bin/tree-sitter.wasm +0 -0
- package/package.json +67 -0
- package/src/__tests__/README.md +256 -0
- package/src/__tests__/bash-mode.test.ts +442 -0
- package/src/__tests__/cli-args.test.ts +181 -0
- package/src/__tests__/cli-harness.test.ts +52 -0
- package/src/__tests__/e2e/first-time-login.test.ts +173 -0
- package/src/__tests__/e2e/logout-relogin-flow.test.ts +110 -0
- package/src/__tests__/e2e/returning-user-auth.test.ts +113 -0
- package/src/__tests__/e2e-cli.test.ts +183 -0
- package/src/__tests__/helpers/launcher-disconnect-fixture.cjs +176 -0
- package/src/__tests__/helpers/mock-api-client.ts +64 -0
- package/src/__tests__/helpers/renderer-cleanup-fixture.tsx +89 -0
- package/src/__tests__/helpers/terminal-watchdog-fixture.ts +75 -0
- package/src/__tests__/home-directory-detection.test.ts +213 -0
- package/src/__tests__/integration/api-integration.test.ts +288 -0
- package/src/__tests__/integration/credentials-storage.test.ts +486 -0
- package/src/__tests__/integration/local-agents.test.ts +1187 -0
- package/src/__tests__/integration/login-flow-instrumentation.test.ts +134 -0
- package/src/__tests__/integration/login-polling-working.test.ts +285 -0
- package/src/__tests__/integration/queue-editing.test.tsx +261 -0
- package/src/__tests__/integration/usage-refresh-on-completion.test.ts +168 -0
- package/src/__tests__/integration-tmux.test.ts +188 -0
- package/src/__tests__/launcher-avx2-fallback.test.ts +630 -0
- package/src/__tests__/launcher-disconnect.test.ts +104 -0
- package/src/__tests__/mocks/hover-toggle-controller.ts +71 -0
- package/src/__tests__/open-tui-native-bundle.test.ts +378 -0
- package/src/__tests__/path-completion.test.ts +243 -0
- package/src/__tests__/project-files-chat-id.test.ts +34 -0
- package/src/__tests__/release/proxy-http-get.test.ts +667 -0
- package/src/__tests__/release/wrapper-safety.test.ts +412 -0
- package/src/__tests__/renderer-cleanup.test.ts +174 -0
- package/src/__tests__/rerender-perf.integration.test.ts +283 -0
- package/src/__tests__/terminal-reset-sequences.test.ts +36 -0
- package/src/__tests__/terminal-watchdog.test.ts +388 -0
- package/src/__tests__/test-utils.ts +271 -0
- package/src/__tests__/tmux-poc.ts +150 -0
- package/src/__tests__/unit/agent-mode-toggle.test.ts +137 -0
- package/src/__tests__/unit/copy-button.test.ts +157 -0
- package/src/__tests__/unit/create-run-config.test.ts +66 -0
- package/src/__tests__/unit/publish-confirmation.test.ts +70 -0
- package/src/__tests__/unit/segmented-control.test.ts +152 -0
- package/src/__tests__/utils/env.test.ts +169 -0
- package/src/__tests__/utils/project-picker.test.ts +39 -0
- package/src/agents/bundled-agents.generated.d.ts +14 -0
- package/src/agents/bundled-agents.generated.ts +3692 -0
- package/src/app.tsx +399 -0
- package/src/chat.tsx +1698 -0
- package/src/cli-args.ts +134 -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__/freebuff-command-aliases.test.ts +56 -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__/chat-input-bar.test.tsx +130 -0
- package/src/components/__tests__/freebuff-landing-heading-row.test.tsx +91 -0
- package/src/components/__tests__/freebuff-model-selector.test.tsx +519 -0
- package/src/components/__tests__/freebuff-offer-invariants.test.ts +54 -0
- package/src/components/__tests__/freebuff-takeover-prompt.test.tsx +212 -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-mark.tsx +52 -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/freebuff-active-session-summary.tsx +63 -0
- package/src/components/freebuff-landing-screen.tsx +865 -0
- package/src/components/freebuff-model-selector.tsx +1087 -0
- package/src/components/freebuff-referral-banner.tsx +604 -0
- package/src/components/freebuff-superseded-screen.tsx +62 -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-freebuff-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-ask-user-bridge.ts +92 -0
- package/src/hooks/use-auth-query.ts +253 -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-freebuff-ctrl-c-exit.ts +23 -0
- package/src/hooks/use-freebuff-session-progress.ts +34 -0
- package/src/hooks/use-freebuff-session.ts +806 -0
- package/src/hooks/use-freebuff-streak-query.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 +441 -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/smoke/terminal-command-broker.ts +439 -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/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/freebuff-model-store.ts +42 -0
- package/src/state/freebuff-session-store.ts +53 -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/testing/env.ts +46 -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/freebuff-session.ts +17 -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__/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__/freebuff-instance-owner.test.ts +69 -0
- package/src/utils/__tests__/freebuff-model-navigation.test.ts +102 -0
- package/src/utils/__tests__/freebuff-premium-reset.test.ts +79 -0
- package/src/utils/__tests__/freebuff-referral-cache.test.ts +116 -0
- package/src/utils/__tests__/freebuff-session-api.test.ts +215 -0
- package/src/utils/__tests__/freebuff-session-display.test.ts +23 -0
- package/src/utils/__tests__/freebuff-streak-line.test.ts +217 -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-api.ts +612 -0
- package/src/utils/anvil-client.ts +217 -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/freebuff-agent-selection.ts +33 -0
- package/src/utils/freebuff-instance-owner.ts +66 -0
- package/src/utils/freebuff-model-navigation.ts +50 -0
- package/src/utils/freebuff-premium-reset.ts +55 -0
- package/src/utils/freebuff-referral-cache.ts +51 -0
- package/src/utils/freebuff-session-api.ts +243 -0
- package/src/utils/freebuff-session-display.ts +21 -0
- package/src/utils/freebuff-streak-line.ts +93 -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
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
|
|
4
|
+
import { getConfigDir } from './auth'
|
|
5
|
+
import { logger } from './logger'
|
|
6
|
+
|
|
7
|
+
const MAX_RECENT_PROJECTS = 10
|
|
8
|
+
|
|
9
|
+
export interface RecentProject {
|
|
10
|
+
path: string
|
|
11
|
+
lastOpened: number
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get the recent projects file path
|
|
16
|
+
*/
|
|
17
|
+
export const getRecentProjectsPath = (): string => {
|
|
18
|
+
return path.join(getConfigDir(), 'recent-projects.json')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Load recent projects from file system
|
|
23
|
+
* @returns Array of recent projects, sorted by most recent first
|
|
24
|
+
*/
|
|
25
|
+
export const loadRecentProjects = (): RecentProject[] => {
|
|
26
|
+
const recentProjectsPath = getRecentProjectsPath()
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(recentProjectsPath)) {
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const fileContent = fs.readFileSync(recentProjectsPath, 'utf8')
|
|
34
|
+
const parsed = JSON.parse(fileContent)
|
|
35
|
+
|
|
36
|
+
if (!Array.isArray(parsed)) {
|
|
37
|
+
return []
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Validate and filter entries
|
|
41
|
+
const validProjects = parsed.filter(
|
|
42
|
+
(item): item is RecentProject =>
|
|
43
|
+
typeof item === 'object' &&
|
|
44
|
+
item !== null &&
|
|
45
|
+
typeof item.path === 'string' &&
|
|
46
|
+
typeof item.lastOpened === 'number',
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
// Filter out projects that no longer exist on disk
|
|
50
|
+
const existingProjects = validProjects.filter((project) => {
|
|
51
|
+
try {
|
|
52
|
+
return fs.existsSync(project.path)
|
|
53
|
+
} catch {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
// Sort by most recent first
|
|
59
|
+
return existingProjects.sort((a, b) => b.lastOpened - a.lastOpened)
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.debug(
|
|
62
|
+
{ error: error instanceof Error ? error.message : String(error) },
|
|
63
|
+
'Error reading recent projects',
|
|
64
|
+
)
|
|
65
|
+
return []
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Clear all recent projects
|
|
71
|
+
*/
|
|
72
|
+
export const clearRecentProjects = (): void => {
|
|
73
|
+
const recentProjectsPath = getRecentProjectsPath()
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
if (fs.existsSync(recentProjectsPath)) {
|
|
77
|
+
fs.writeFileSync(recentProjectsPath, JSON.stringify([], null, 2))
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
logger.debug(
|
|
81
|
+
{ error: error instanceof Error ? error.message : String(error) },
|
|
82
|
+
'Error clearing recent projects',
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Remove a specific project from the recent projects list
|
|
89
|
+
*/
|
|
90
|
+
export const removeRecentProject = (projectPath: string): void => {
|
|
91
|
+
const recentProjectsPath = getRecentProjectsPath()
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const existingProjects = loadRecentProjects()
|
|
95
|
+
const filteredProjects = existingProjects.filter(
|
|
96
|
+
(p) => p.path !== projectPath,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
fs.writeFileSync(
|
|
100
|
+
recentProjectsPath,
|
|
101
|
+
JSON.stringify(filteredProjects, null, 2),
|
|
102
|
+
)
|
|
103
|
+
} catch (error) {
|
|
104
|
+
logger.debug(
|
|
105
|
+
{ error: error instanceof Error ? error.message : String(error) },
|
|
106
|
+
'Error removing recent project',
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Save a project to the recent projects list.
|
|
113
|
+
* Updates the timestamp if the project already exists, otherwise adds it.
|
|
114
|
+
* Keeps only the most recent MAX_RECENT_PROJECTS projects.
|
|
115
|
+
* Validates that the path exists before saving.
|
|
116
|
+
*/
|
|
117
|
+
export const saveRecentProject = (projectPath: string): void => {
|
|
118
|
+
// Validate path exists before saving
|
|
119
|
+
if (!fs.existsSync(projectPath)) {
|
|
120
|
+
logger.debug({ projectPath }, 'Skipping save for non-existent project path')
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const configDir = getConfigDir()
|
|
125
|
+
const recentProjectsPath = getRecentProjectsPath()
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
if (!fs.existsSync(configDir)) {
|
|
129
|
+
fs.mkdirSync(configDir, { recursive: true })
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Load existing projects
|
|
133
|
+
const existingProjects = loadRecentProjects()
|
|
134
|
+
|
|
135
|
+
// Remove the project if it already exists (we'll add it back at the top)
|
|
136
|
+
const filteredProjects = existingProjects.filter(
|
|
137
|
+
(p) => p.path !== projectPath,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
// Add the new/updated project at the beginning
|
|
141
|
+
const updatedProjects: RecentProject[] = [
|
|
142
|
+
{ path: projectPath, lastOpened: Date.now() },
|
|
143
|
+
...filteredProjects,
|
|
144
|
+
].slice(0, MAX_RECENT_PROJECTS)
|
|
145
|
+
|
|
146
|
+
fs.writeFileSync(
|
|
147
|
+
recentProjectsPath,
|
|
148
|
+
JSON.stringify(updatedProjects, null, 2),
|
|
149
|
+
)
|
|
150
|
+
} catch (error) {
|
|
151
|
+
logger.debug(
|
|
152
|
+
{ error: error instanceof Error ? error.message : String(error) },
|
|
153
|
+
'Error saving recent project',
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { execFile } from 'child_process'
|
|
2
|
+
|
|
3
|
+
import { resetTerminalTitle } from './terminal-title'
|
|
4
|
+
import { stopActiveRun } from './active-run'
|
|
5
|
+
import { getCliEnv } from './env'
|
|
6
|
+
import { exitCliCleanly, registerExitCleanup } from './exit-cleanly'
|
|
7
|
+
import { flushLiveChatState } from './run-state-storage'
|
|
8
|
+
import { reportFatalErrorSync, writeTerminalControlSync } from './terminal-io'
|
|
9
|
+
import { TERMINAL_RESET_SEQUENCES } from './terminal-reset-sequences'
|
|
10
|
+
import { stopTerminalWatchdog } from './terminal-watchdog'
|
|
11
|
+
|
|
12
|
+
import type { CliRenderer } from '@opentui/core'
|
|
13
|
+
|
|
14
|
+
let renderer: CliRenderer | null = null
|
|
15
|
+
let handlersInstalled = false
|
|
16
|
+
let cleanupStarted = false
|
|
17
|
+
|
|
18
|
+
function isProcessRunning(pid: number, onResult: (running: boolean) => void) {
|
|
19
|
+
if (process.platform === 'win32') {
|
|
20
|
+
execFile(
|
|
21
|
+
'tasklist',
|
|
22
|
+
['/FI', `PID eq ${pid}`, '/FO', 'CSV', '/NH'],
|
|
23
|
+
{ windowsHide: true },
|
|
24
|
+
(error, stdout) => {
|
|
25
|
+
// A failed probe should never terminate a healthy CLI.
|
|
26
|
+
if (error) {
|
|
27
|
+
onResult(true)
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
onResult(new RegExp(`(?:^|\\D)${pid}(?:\\D|$)`).test(stdout))
|
|
31
|
+
},
|
|
32
|
+
)
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
process.kill(pid, 0)
|
|
38
|
+
onResult(true)
|
|
39
|
+
} catch (error) {
|
|
40
|
+
onResult((error as NodeJS.ErrnoException).code === 'EPERM')
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Reset terminal state by writing escape sequences to the controlling terminal.
|
|
46
|
+
* This is called after renderer.destroy() so buffered renderer output cannot
|
|
47
|
+
* land on the restored main screen after the reset.
|
|
48
|
+
*
|
|
49
|
+
* This is especially important on Windows where signals like SIGTERM and SIGHUP
|
|
50
|
+
* don't work, so we rely on the 'exit' event which is guaranteed to run.
|
|
51
|
+
*/
|
|
52
|
+
function resetTerminalState(): boolean {
|
|
53
|
+
try {
|
|
54
|
+
if (process.stdin.isTTY && process.stdin.setRawMode) {
|
|
55
|
+
process.stdin.setRawMode(false)
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
// Ignore errors - stdin may already be closed
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
// Reset terminal title to default
|
|
62
|
+
resetTerminalTitle()
|
|
63
|
+
if (!process.stdout.isTTY) return true
|
|
64
|
+
|
|
65
|
+
const resetCompletedSynchronously = writeTerminalControlSync(
|
|
66
|
+
TERMINAL_RESET_SEQUENCES,
|
|
67
|
+
)
|
|
68
|
+
if (!resetCompletedSynchronously) {
|
|
69
|
+
// Best-effort immediate reset. Keep the watchdog armed below so it can
|
|
70
|
+
// retry after this process exits if the buffered write is lost.
|
|
71
|
+
process.stdout.write(TERMINAL_RESET_SEQUENCES)
|
|
72
|
+
}
|
|
73
|
+
return resetCompletedSynchronously
|
|
74
|
+
} catch {
|
|
75
|
+
// Ignore errors - stdout may already be closed
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Destroy OpenTUI before resetting the terminal. destroy() can finalize
|
|
82
|
+
* synchronously or defer until an active frame finishes; in the deferred case,
|
|
83
|
+
* schedule the reset after the destroy event's remaining synchronous work.
|
|
84
|
+
*/
|
|
85
|
+
function destroyRendererAndResetTerminal(): boolean {
|
|
86
|
+
const activeRenderer = renderer
|
|
87
|
+
renderer = null
|
|
88
|
+
try {
|
|
89
|
+
if (!activeRenderer || activeRenderer.isDestroyed) {
|
|
90
|
+
return resetTerminalState()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let destroyReturned = false
|
|
94
|
+
let destroyFinalized = false
|
|
95
|
+
activeRenderer.once('destroy', () => {
|
|
96
|
+
destroyFinalized = true
|
|
97
|
+
if (destroyReturned) {
|
|
98
|
+
queueMicrotask(resetTerminalState)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
activeRenderer.destroy()
|
|
103
|
+
destroyReturned = true
|
|
104
|
+
return destroyFinalized ? resetTerminalState() : false
|
|
105
|
+
} catch {
|
|
106
|
+
// A direct reset is still safe if renderer teardown itself failed.
|
|
107
|
+
return resetTerminalState()
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Clean up the renderer by calling destroy().
|
|
113
|
+
* This resets terminal state to prevent garbled output after exit.
|
|
114
|
+
*/
|
|
115
|
+
function cleanup(): boolean {
|
|
116
|
+
if (cleanupStarted) {
|
|
117
|
+
// The process 'exit' handler deliberately reaches this branch to make the
|
|
118
|
+
// terminal reset the final write, even if destroy was deferred above.
|
|
119
|
+
return resetTerminalState()
|
|
120
|
+
}
|
|
121
|
+
cleanupStarted = true
|
|
122
|
+
|
|
123
|
+
// Finalize the active message before reading the live provider. This makes
|
|
124
|
+
// the synchronous flush include the interruption UI and prevents a late
|
|
125
|
+
// SDK callback from continuing to own the chat while shutdown proceeds.
|
|
126
|
+
try {
|
|
127
|
+
stopActiveRun('process-exit')
|
|
128
|
+
} catch {
|
|
129
|
+
// Continue restoring the terminal even if run finalization fails.
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Persist any in-flight chat state first (synchronous, best-effort) so
|
|
133
|
+
// closing the terminal or killing the process mid-run doesn't lose the turn.
|
|
134
|
+
try {
|
|
135
|
+
flushLiveChatState()
|
|
136
|
+
} catch {
|
|
137
|
+
// Persistence is best-effort during process teardown.
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return destroyRendererAndResetTerminal()
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Restore the terminal, report a fatal error synchronously, and exit. */
|
|
144
|
+
export function exitCliWithFatalError(label: string, error: unknown): never {
|
|
145
|
+
const resetCompletedSynchronously = cleanup() || resetTerminalState()
|
|
146
|
+
if (resetCompletedSynchronously) {
|
|
147
|
+
stopTerminalWatchdog()
|
|
148
|
+
}
|
|
149
|
+
reportFatalErrorSync(label, error)
|
|
150
|
+
process.exit(1)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Install process-level signal handlers to ensure terminal cleanup on all exit scenarios.
|
|
155
|
+
* Call this once after creating the renderer in index.tsx.
|
|
156
|
+
*
|
|
157
|
+
* This handles:
|
|
158
|
+
* - SIGTERM (kill)
|
|
159
|
+
* - SIGHUP (terminal hangup)
|
|
160
|
+
* - SIGINT (Ctrl+C)
|
|
161
|
+
* - release launcher exit
|
|
162
|
+
* - beforeExit / exit events
|
|
163
|
+
* - uncaughtException / unhandledRejection
|
|
164
|
+
*
|
|
165
|
+
* Note: SIGKILL cannot be caught - it's an immediate termination signal.
|
|
166
|
+
*/
|
|
167
|
+
export function installProcessCleanupHandlers(cliRenderer: CliRenderer): void {
|
|
168
|
+
if (handlersInstalled) return
|
|
169
|
+
handlersInstalled = true
|
|
170
|
+
renderer = cliRenderer
|
|
171
|
+
registerExitCleanup(cleanup)
|
|
172
|
+
|
|
173
|
+
const handleExitRequest = () => {
|
|
174
|
+
void exitCliCleanly()
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// A broad `taskkill node.exe` can kill the package's Node launcher without
|
|
178
|
+
// killing its Bun child. Polling avoids Bun's Windows behavior of terminating
|
|
179
|
+
// before JavaScript can handle a broken IPC channel or inherited pipe.
|
|
180
|
+
const launcherPid = Number(getCliEnv().ANVIL_LAUNCHER_PID)
|
|
181
|
+
if (
|
|
182
|
+
Number.isInteger(launcherPid) &&
|
|
183
|
+
launcherPid > 0 &&
|
|
184
|
+
launcherPid !== process.pid
|
|
185
|
+
) {
|
|
186
|
+
let launcherCheckInFlight = false
|
|
187
|
+
const launcherMonitor = setInterval(() => {
|
|
188
|
+
if (launcherCheckInFlight) return
|
|
189
|
+
launcherCheckInFlight = true
|
|
190
|
+
isProcessRunning(launcherPid, (running) => {
|
|
191
|
+
launcherCheckInFlight = false
|
|
192
|
+
if (running) return
|
|
193
|
+
clearInterval(launcherMonitor)
|
|
194
|
+
handleExitRequest()
|
|
195
|
+
})
|
|
196
|
+
}, 500)
|
|
197
|
+
launcherMonitor.unref()
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// SIGTERM - Default kill signal (e.g., `kill <pid>`)
|
|
201
|
+
process.on('SIGTERM', handleExitRequest)
|
|
202
|
+
|
|
203
|
+
// SIGHUP - Terminal hangup (e.g., closing the terminal window)
|
|
204
|
+
process.on('SIGHUP', handleExitRequest)
|
|
205
|
+
|
|
206
|
+
// SIGINT - Ctrl+C
|
|
207
|
+
process.on('SIGINT', handleExitRequest)
|
|
208
|
+
|
|
209
|
+
// beforeExit - Called when the event loop is empty and about to exit
|
|
210
|
+
process.on('beforeExit', () => {
|
|
211
|
+
cleanup()
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
// exit - Last chance to run synchronous cleanup code
|
|
215
|
+
process.on('exit', () => {
|
|
216
|
+
// Only silence the external fallback after the final reset bytes were
|
|
217
|
+
// synchronously accepted. If direct terminal access failed, leave it armed
|
|
218
|
+
// to repair the terminal after this process disappears.
|
|
219
|
+
if (cleanup()) {
|
|
220
|
+
stopTerminalWatchdog()
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
// uncaughtException - Safety net for unhandled errors
|
|
225
|
+
process.on('uncaughtException', (error) => {
|
|
226
|
+
exitCliWithFatalError('Uncaught exception', error)
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// unhandledRejection - Safety net for unhandled promise rejections
|
|
230
|
+
process.on('unhandledRejection', (reason) => {
|
|
231
|
+
exitCliWithFatalError('Unhandled rejection', reason)
|
|
232
|
+
})
|
|
233
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@anvil/common/util/response-ad-positions'
|