yzcode-cli 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/QueryEngine.ts +1295 -0
- package/Task.ts +125 -0
- package/Tool.ts +792 -0
- package/bin/yzcode-init.js +31 -0
- package/bin/yzcode.js +35 -0
- package/cli/exit.ts +31 -0
- package/cli/handlers/agents.ts +70 -0
- package/cli/handlers/auth.ts +330 -0
- package/cli/handlers/autoMode.ts +170 -0
- package/cli/handlers/mcp.tsx +362 -0
- package/cli/handlers/plugins.ts +878 -0
- package/cli/handlers/util.tsx +110 -0
- package/cli/ndjsonSafeStringify.ts +32 -0
- package/cli/print.ts +5594 -0
- package/cli/remoteIO.ts +255 -0
- package/cli/structuredIO.ts +859 -0
- package/cli/transports/HybridTransport.ts +282 -0
- package/cli/transports/SSETransport.ts +711 -0
- package/cli/transports/SerialBatchEventUploader.ts +275 -0
- package/cli/transports/WebSocketTransport.ts +800 -0
- package/cli/transports/WorkerStateUploader.ts +131 -0
- package/cli/transports/ccrClient.ts +998 -0
- package/cli/transports/transportUtils.ts +45 -0
- package/cli/update.ts +422 -0
- package/commands/add-dir/add-dir.tsx +126 -0
- package/commands/add-dir/index.ts +11 -0
- package/commands/add-dir/validation.ts +110 -0
- package/commands/advisor.ts +109 -0
- package/commands/agents/agents.tsx +12 -0
- package/commands/agents/index.ts +10 -0
- package/commands/ant-trace/index.js +1 -0
- package/commands/autofix-pr/index.js +1 -0
- package/commands/backfill-sessions/index.js +1 -0
- package/commands/branch/branch.ts +296 -0
- package/commands/branch/index.ts +14 -0
- package/commands/break-cache/index.js +1 -0
- package/commands/bridge/bridge.tsx +509 -0
- package/commands/bridge/index.ts +26 -0
- package/commands/bridge-kick.ts +200 -0
- package/commands/brief.ts +130 -0
- package/commands/btw/btw.tsx +243 -0
- package/commands/btw/index.ts +13 -0
- package/commands/bughunter/index.js +1 -0
- package/commands/chrome/chrome.tsx +285 -0
- package/commands/chrome/index.ts +13 -0
- package/commands/clear/caches.ts +144 -0
- package/commands/clear/clear.ts +7 -0
- package/commands/clear/conversation.ts +251 -0
- package/commands/clear/index.ts +19 -0
- package/commands/color/color.ts +93 -0
- package/commands/color/index.ts +16 -0
- package/commands/commit-push-pr.ts +158 -0
- package/commands/commit.ts +92 -0
- package/commands/compact/compact.ts +287 -0
- package/commands/compact/index.ts +15 -0
- package/commands/config/config.tsx +7 -0
- package/commands/config/index.ts +11 -0
- package/commands/context/context-noninteractive.ts +325 -0
- package/commands/context/context.tsx +64 -0
- package/commands/context/index.ts +24 -0
- package/commands/copy/copy.tsx +371 -0
- package/commands/copy/index.ts +15 -0
- package/commands/cost/cost.ts +24 -0
- package/commands/cost/index.ts +23 -0
- package/commands/createMovedToPluginCommand.ts +65 -0
- package/commands/ctx_viz/index.js +1 -0
- package/commands/debug-tool-call/index.js +1 -0
- package/commands/desktop/desktop.tsx +9 -0
- package/commands/desktop/index.ts +26 -0
- package/commands/diff/diff.tsx +9 -0
- package/commands/diff/index.ts +8 -0
- package/commands/doctor/doctor.tsx +7 -0
- package/commands/doctor/index.ts +12 -0
- package/commands/effort/effort.tsx +183 -0
- package/commands/effort/index.ts +13 -0
- package/commands/env/index.js +1 -0
- package/commands/exit/exit.tsx +33 -0
- package/commands/exit/index.ts +12 -0
- package/commands/export/export.tsx +91 -0
- package/commands/export/index.ts +11 -0
- package/commands/extra-usage/extra-usage-core.ts +118 -0
- package/commands/extra-usage/extra-usage-noninteractive.ts +16 -0
- package/commands/extra-usage/extra-usage.tsx +17 -0
- package/commands/extra-usage/index.ts +31 -0
- package/commands/fast/fast.tsx +269 -0
- package/commands/fast/index.ts +26 -0
- package/commands/feedback/feedback.tsx +25 -0
- package/commands/feedback/index.ts +26 -0
- package/commands/files/files.ts +19 -0
- package/commands/files/index.ts +12 -0
- package/commands/good-claude/index.js +1 -0
- package/commands/heapdump/heapdump.ts +17 -0
- package/commands/heapdump/index.ts +12 -0
- package/commands/help/help.tsx +11 -0
- package/commands/help/index.ts +10 -0
- package/commands/hooks/hooks.tsx +13 -0
- package/commands/hooks/index.ts +11 -0
- package/commands/ide/ide.tsx +646 -0
- package/commands/ide/index.ts +11 -0
- package/commands/init-verifiers.ts +262 -0
- package/commands/init.ts +256 -0
- package/commands/insights.ts +3200 -0
- package/commands/install-github-app/ApiKeyStep.tsx +231 -0
- package/commands/install-github-app/CheckExistingSecretStep.tsx +190 -0
- package/commands/install-github-app/CheckGitHubStep.tsx +15 -0
- package/commands/install-github-app/ChooseRepoStep.tsx +211 -0
- package/commands/install-github-app/CreatingStep.tsx +65 -0
- package/commands/install-github-app/ErrorStep.tsx +85 -0
- package/commands/install-github-app/ExistingWorkflowStep.tsx +103 -0
- package/commands/install-github-app/InstallAppStep.tsx +94 -0
- package/commands/install-github-app/OAuthFlowStep.tsx +276 -0
- package/commands/install-github-app/SuccessStep.tsx +96 -0
- package/commands/install-github-app/WarningsStep.tsx +73 -0
- package/commands/install-github-app/index.ts +13 -0
- package/commands/install-github-app/install-github-app.tsx +587 -0
- package/commands/install-github-app/setupGitHubActions.ts +325 -0
- package/commands/install-slack-app/index.ts +12 -0
- package/commands/install-slack-app/install-slack-app.ts +30 -0
- package/commands/install.tsx +300 -0
- package/commands/issue/index.js +1 -0
- package/commands/keybindings/index.ts +13 -0
- package/commands/keybindings/keybindings.ts +53 -0
- package/commands/login/index.ts +14 -0
- package/commands/login/login.tsx +104 -0
- package/commands/logout/index.ts +10 -0
- package/commands/logout/logout.tsx +82 -0
- package/commands/mcp/addCommand.ts +280 -0
- package/commands/mcp/index.ts +12 -0
- package/commands/mcp/mcp.tsx +85 -0
- package/commands/mcp/xaaIdpCommand.ts +266 -0
- package/commands/memory/index.ts +10 -0
- package/commands/memory/memory.tsx +90 -0
- package/commands/mobile/index.ts +11 -0
- package/commands/mobile/mobile.tsx +274 -0
- package/commands/mock-limits/index.js +1 -0
- package/commands/model/index.ts +16 -0
- package/commands/model/model.tsx +297 -0
- package/commands/oauth-refresh/index.js +1 -0
- package/commands/onboarding/index.js +1 -0
- package/commands/output-style/index.ts +11 -0
- package/commands/output-style/output-style.tsx +7 -0
- package/commands/passes/index.ts +22 -0
- package/commands/passes/passes.tsx +24 -0
- package/commands/perf-issue/index.js +1 -0
- package/commands/permissions/index.ts +11 -0
- package/commands/permissions/permissions.tsx +10 -0
- package/commands/plan/index.ts +11 -0
- package/commands/plan/plan.tsx +122 -0
- package/commands/plugin/AddMarketplace.tsx +162 -0
- package/commands/plugin/BrowseMarketplace.tsx +802 -0
- package/commands/plugin/DiscoverPlugins.tsx +781 -0
- package/commands/plugin/ManageMarketplaces.tsx +838 -0
- package/commands/plugin/ManagePlugins.tsx +2215 -0
- package/commands/plugin/PluginErrors.tsx +124 -0
- package/commands/plugin/PluginOptionsDialog.tsx +357 -0
- package/commands/plugin/PluginOptionsFlow.tsx +135 -0
- package/commands/plugin/PluginSettings.tsx +1072 -0
- package/commands/plugin/PluginTrustWarning.tsx +32 -0
- package/commands/plugin/UnifiedInstalledCell.tsx +565 -0
- package/commands/plugin/ValidatePlugin.tsx +98 -0
- package/commands/plugin/index.tsx +11 -0
- package/commands/plugin/parseArgs.ts +103 -0
- package/commands/plugin/plugin.tsx +7 -0
- package/commands/plugin/pluginDetailsHelpers.tsx +117 -0
- package/commands/plugin/usePagination.ts +171 -0
- package/commands/pr_comments/index.ts +50 -0
- package/commands/privacy-settings/index.ts +14 -0
- package/commands/privacy-settings/privacy-settings.tsx +58 -0
- package/commands/rate-limit-options/index.ts +19 -0
- package/commands/rate-limit-options/rate-limit-options.tsx +210 -0
- package/commands/release-notes/index.ts +11 -0
- package/commands/release-notes/release-notes.ts +50 -0
- package/commands/reload-plugins/index.ts +18 -0
- package/commands/reload-plugins/reload-plugins.ts +61 -0
- package/commands/remote-env/index.ts +15 -0
- package/commands/remote-env/remote-env.tsx +7 -0
- package/commands/remote-setup/api.ts +182 -0
- package/commands/remote-setup/index.ts +20 -0
- package/commands/remote-setup/remote-setup.tsx +187 -0
- package/commands/rename/generateSessionName.ts +67 -0
- package/commands/rename/index.ts +12 -0
- package/commands/rename/rename.ts +87 -0
- package/commands/reset-limits/index.js +4 -0
- package/commands/resume/index.ts +12 -0
- package/commands/resume/resume.tsx +275 -0
- package/commands/review/UltrareviewOverageDialog.tsx +96 -0
- package/commands/review/reviewRemote.ts +316 -0
- package/commands/review/ultrareviewCommand.tsx +58 -0
- package/commands/review/ultrareviewEnabled.ts +14 -0
- package/commands/review.ts +57 -0
- package/commands/rewind/index.ts +13 -0
- package/commands/rewind/rewind.ts +13 -0
- package/commands/sandbox-toggle/index.ts +50 -0
- package/commands/sandbox-toggle/sandbox-toggle.tsx +83 -0
- package/commands/security-review.ts +243 -0
- package/commands/session/index.ts +16 -0
- package/commands/session/session.tsx +140 -0
- package/commands/share/index.js +1 -0
- package/commands/skills/index.ts +10 -0
- package/commands/skills/skills.tsx +8 -0
- package/commands/stats/index.ts +10 -0
- package/commands/stats/stats.tsx +7 -0
- package/commands/status/index.ts +12 -0
- package/commands/status/status.tsx +8 -0
- package/commands/statusline.tsx +24 -0
- package/commands/stickers/index.ts +11 -0
- package/commands/stickers/stickers.ts +16 -0
- package/commands/summary/index.js +1 -0
- package/commands/tag/index.ts +12 -0
- package/commands/tag/tag.tsx +215 -0
- package/commands/tasks/index.ts +11 -0
- package/commands/tasks/tasks.tsx +8 -0
- package/commands/teleport/index.js +1 -0
- package/commands/terminalSetup/index.ts +23 -0
- package/commands/terminalSetup/terminalSetup.tsx +531 -0
- package/commands/theme/index.ts +10 -0
- package/commands/theme/theme.tsx +57 -0
- package/commands/thinkback/index.ts +13 -0
- package/commands/thinkback/thinkback.tsx +554 -0
- package/commands/thinkback-play/index.ts +17 -0
- package/commands/thinkback-play/thinkback-play.ts +43 -0
- package/commands/ultraplan.tsx +471 -0
- package/commands/upgrade/index.ts +16 -0
- package/commands/upgrade/upgrade.tsx +38 -0
- package/commands/usage/index.ts +9 -0
- package/commands/usage/usage.tsx +7 -0
- package/commands/version.ts +22 -0
- package/commands/vim/index.ts +11 -0
- package/commands/vim/vim.ts +38 -0
- package/commands/voice/index.ts +20 -0
- package/commands/voice/voice.ts +150 -0
- package/commands.ts +754 -0
- package/components/AgentProgressLine.tsx +136 -0
- package/components/App.tsx +56 -0
- package/components/ApproveApiKey.tsx +123 -0
- package/components/AutoModeOptInDialog.tsx +142 -0
- package/components/AutoUpdater.tsx +198 -0
- package/components/AutoUpdaterWrapper.tsx +91 -0
- package/components/AwsAuthStatusBox.tsx +82 -0
- package/components/BaseTextInput.tsx +136 -0
- package/components/BashModeProgress.tsx +56 -0
- package/components/BridgeDialog.tsx +401 -0
- package/components/BypassPermissionsModeDialog.tsx +87 -0
- package/components/ChannelDowngradeDialog.tsx +102 -0
- package/components/ClaudeCodeHint/PluginHintMenu.tsx +78 -0
- package/components/ClaudeInChromeOnboarding.tsx +121 -0
- package/components/ClaudeMdExternalIncludesDialog.tsx +137 -0
- package/components/ClickableImageRef.tsx +73 -0
- package/components/CompactSummary.tsx +118 -0
- package/components/ConfigurableShortcutHint.tsx +57 -0
- package/components/ConsoleOAuthFlow.tsx +631 -0
- package/components/ContextSuggestions.tsx +47 -0
- package/components/ContextVisualization.tsx +489 -0
- package/components/CoordinatorAgentStatus.tsx +273 -0
- package/components/CostThresholdDialog.tsx +50 -0
- package/components/CtrlOToExpand.tsx +51 -0
- package/components/CustomSelect/SelectMulti.tsx +213 -0
- package/components/CustomSelect/index.ts +3 -0
- package/components/CustomSelect/option-map.ts +50 -0
- package/components/CustomSelect/select-input-option.tsx +488 -0
- package/components/CustomSelect/select-option.tsx +68 -0
- package/components/CustomSelect/select.tsx +690 -0
- package/components/CustomSelect/use-multi-select-state.ts +414 -0
- package/components/CustomSelect/use-select-input.ts +287 -0
- package/components/CustomSelect/use-select-navigation.ts +653 -0
- package/components/CustomSelect/use-select-state.ts +157 -0
- package/components/DesktopHandoff.tsx +193 -0
- package/components/DesktopUpsell/DesktopUpsellStartup.tsx +171 -0
- package/components/DevBar.tsx +49 -0
- package/components/DevChannelsDialog.tsx +105 -0
- package/components/DiagnosticsDisplay.tsx +95 -0
- package/components/EffortCallout.tsx +265 -0
- package/components/EffortIndicator.ts +42 -0
- package/components/ExitFlow.tsx +48 -0
- package/components/ExportDialog.tsx +128 -0
- package/components/FallbackToolUseErrorMessage.tsx +116 -0
- package/components/FallbackToolUseRejectedMessage.tsx +16 -0
- package/components/FastIcon.tsx +46 -0
- package/components/Feedback.tsx +592 -0
- package/components/FeedbackSurvey/FeedbackSurvey.tsx +174 -0
- package/components/FeedbackSurvey/FeedbackSurveyView.tsx +108 -0
- package/components/FeedbackSurvey/TranscriptSharePrompt.tsx +88 -0
- package/components/FeedbackSurvey/submitTranscriptShare.ts +112 -0
- package/components/FeedbackSurvey/useDebouncedDigitInput.ts +82 -0
- package/components/FeedbackSurvey/useFeedbackSurvey.tsx +296 -0
- package/components/FeedbackSurvey/useMemorySurvey.tsx +213 -0
- package/components/FeedbackSurvey/usePostCompactSurvey.tsx +206 -0
- package/components/FeedbackSurvey/useSurveyState.tsx +100 -0
- package/components/FileEditToolDiff.tsx +181 -0
- package/components/FileEditToolUpdatedMessage.tsx +124 -0
- package/components/FileEditToolUseRejectedMessage.tsx +170 -0
- package/components/FilePathLink.tsx +43 -0
- package/components/FullscreenLayout.tsx +637 -0
- package/components/GlobalSearchDialog.tsx +343 -0
- package/components/HelpV2/Commands.tsx +82 -0
- package/components/HelpV2/General.tsx +23 -0
- package/components/HelpV2/HelpV2.tsx +184 -0
- package/components/HighlightedCode/Fallback.tsx +193 -0
- package/components/HighlightedCode.tsx +190 -0
- package/components/HistorySearchDialog.tsx +118 -0
- package/components/IdeAutoConnectDialog.tsx +154 -0
- package/components/IdeOnboardingDialog.tsx +167 -0
- package/components/IdeStatusIndicator.tsx +58 -0
- package/components/IdleReturnDialog.tsx +118 -0
- package/components/InterruptedByUser.tsx +15 -0
- package/components/InvalidConfigDialog.tsx +156 -0
- package/components/InvalidSettingsDialog.tsx +89 -0
- package/components/KeybindingWarnings.tsx +55 -0
- package/components/LanguagePicker.tsx +86 -0
- package/components/LogSelector.tsx +1575 -0
- package/components/LogoV2/AnimatedAsterisk.tsx +50 -0
- package/components/LogoV2/AnimatedClawd.tsx +124 -0
- package/components/LogoV2/ChannelsNotice.tsx +266 -0
- package/components/LogoV2/Clawd.tsx +240 -0
- package/components/LogoV2/CondensedLogo.tsx +161 -0
- package/components/LogoV2/EmergencyTip.tsx +58 -0
- package/components/LogoV2/Feed.tsx +112 -0
- package/components/LogoV2/FeedColumn.tsx +59 -0
- package/components/LogoV2/GuestPassesUpsell.tsx +70 -0
- package/components/LogoV2/LogoV2.tsx +543 -0
- package/components/LogoV2/Opus1mMergeNotice.tsx +55 -0
- package/components/LogoV2/OverageCreditUpsell.tsx +166 -0
- package/components/LogoV2/VoiceModeNotice.tsx +68 -0
- package/components/LogoV2/WelcomeV2.tsx +433 -0
- package/components/LogoV2/feedConfigs.tsx +92 -0
- package/components/LspRecommendation/LspRecommendationMenu.tsx +88 -0
- package/components/MCPServerApprovalDialog.tsx +115 -0
- package/components/MCPServerDesktopImportDialog.tsx +203 -0
- package/components/MCPServerDialogCopy.tsx +15 -0
- package/components/MCPServerMultiselectDialog.tsx +133 -0
- package/components/ManagedSettingsSecurityDialog/ManagedSettingsSecurityDialog.tsx +149 -0
- package/components/ManagedSettingsSecurityDialog/utils.ts +144 -0
- package/components/Markdown.tsx +236 -0
- package/components/MarkdownTable.tsx +322 -0
- package/components/MemoryUsageIndicator.tsx +37 -0
- package/components/Message.tsx +627 -0
- package/components/MessageModel.tsx +43 -0
- package/components/MessageResponse.tsx +78 -0
- package/components/MessageRow.tsx +383 -0
- package/components/MessageSelector.tsx +831 -0
- package/components/MessageTimestamp.tsx +63 -0
- package/components/Messages.tsx +834 -0
- package/components/ModelPicker.tsx +448 -0
- package/components/NativeAutoUpdater.tsx +193 -0
- package/components/NotebookEditToolUseRejectedMessage.tsx +92 -0
- package/components/OffscreenFreeze.tsx +44 -0
- package/components/Onboarding.tsx +244 -0
- package/components/OutputStylePicker.tsx +112 -0
- package/components/PackageManagerAutoUpdater.tsx +104 -0
- package/components/Passes/Passes.tsx +184 -0
- package/components/PrBadge.tsx +97 -0
- package/components/PressEnterToContinue.tsx +15 -0
- package/components/PromptInput/HistorySearchInput.tsx +51 -0
- package/components/PromptInput/IssueFlagBanner.tsx +12 -0
- package/components/PromptInput/Notifications.tsx +332 -0
- package/components/PromptInput/PromptInput.tsx +2339 -0
- package/components/PromptInput/PromptInputFooter.tsx +191 -0
- package/components/PromptInput/PromptInputFooterLeftSide.tsx +517 -0
- package/components/PromptInput/PromptInputFooterSuggestions.tsx +293 -0
- package/components/PromptInput/PromptInputHelpMenu.tsx +358 -0
- package/components/PromptInput/PromptInputModeIndicator.tsx +93 -0
- package/components/PromptInput/PromptInputQueuedCommands.tsx +117 -0
- package/components/PromptInput/PromptInputStashNotice.tsx +25 -0
- package/components/PromptInput/SandboxPromptFooterHint.tsx +64 -0
- package/components/PromptInput/ShimmeredInput.tsx +143 -0
- package/components/PromptInput/VoiceIndicator.tsx +137 -0
- package/components/PromptInput/inputModes.ts +33 -0
- package/components/PromptInput/inputPaste.ts +90 -0
- package/components/PromptInput/useMaybeTruncateInput.ts +58 -0
- package/components/PromptInput/usePromptInputPlaceholder.ts +76 -0
- package/components/PromptInput/useShowFastIconHint.ts +31 -0
- package/components/PromptInput/useSwarmBanner.ts +155 -0
- package/components/PromptInput/utils.ts +60 -0
- package/components/QuickOpenDialog.tsx +244 -0
- package/components/RemoteCallout.tsx +76 -0
- package/components/RemoteEnvironmentDialog.tsx +340 -0
- package/components/ResumeTask.tsx +268 -0
- package/components/SandboxViolationExpandedView.tsx +99 -0
- package/components/ScrollKeybindingHandler.tsx +1012 -0
- package/components/SearchBox.tsx +72 -0
- package/components/SentryErrorBoundary.ts +28 -0
- package/components/SessionBackgroundHint.tsx +108 -0
- package/components/SessionPreview.tsx +194 -0
- package/components/Settings/Config.tsx +1822 -0
- package/components/Settings/Settings.tsx +137 -0
- package/components/Settings/Status.tsx +241 -0
- package/components/Settings/Usage.tsx +377 -0
- package/components/ShowInIDEPrompt.tsx +170 -0
- package/components/SkillImprovementSurvey.tsx +152 -0
- package/components/Spinner/FlashingChar.tsx +61 -0
- package/components/Spinner/GlimmerMessage.tsx +328 -0
- package/components/Spinner/ShimmerChar.tsx +36 -0
- package/components/Spinner/SpinnerAnimationRow.tsx +265 -0
- package/components/Spinner/SpinnerGlyph.tsx +80 -0
- package/components/Spinner/TeammateSpinnerLine.tsx +233 -0
- package/components/Spinner/TeammateSpinnerTree.tsx +272 -0
- package/components/Spinner/index.ts +10 -0
- package/components/Spinner/teammateSelectHint.ts +1 -0
- package/components/Spinner/useShimmerAnimation.ts +31 -0
- package/components/Spinner/useStalledAnimation.ts +75 -0
- package/components/Spinner/utils.ts +84 -0
- package/components/Spinner.tsx +562 -0
- package/components/Stats.tsx +1228 -0
- package/components/StatusLine.tsx +324 -0
- package/components/StatusNotices.tsx +55 -0
- package/components/StructuredDiff/Fallback.tsx +487 -0
- package/components/StructuredDiff/colorDiff.ts +37 -0
- package/components/StructuredDiff.tsx +190 -0
- package/components/StructuredDiffList.tsx +30 -0
- package/components/TagTabs.tsx +139 -0
- package/components/TaskListV2.tsx +378 -0
- package/components/TeammateViewHeader.tsx +82 -0
- package/components/TeleportError.tsx +189 -0
- package/components/TeleportProgress.tsx +140 -0
- package/components/TeleportRepoMismatchDialog.tsx +104 -0
- package/components/TeleportResumeWrapper.tsx +167 -0
- package/components/TeleportStash.tsx +116 -0
- package/components/TextInput.tsx +124 -0
- package/components/ThemePicker.tsx +333 -0
- package/components/ThinkingToggle.tsx +153 -0
- package/components/TokenWarning.tsx +179 -0
- package/components/ToolUseLoader.tsx +42 -0
- package/components/TrustDialog/TrustDialog.tsx +290 -0
- package/components/TrustDialog/utils.ts +245 -0
- package/components/ValidationErrorsList.tsx +148 -0
- package/components/VimTextInput.tsx +140 -0
- package/components/VirtualMessageList.tsx +1082 -0
- package/components/WorkflowMultiselectDialog.tsx +128 -0
- package/components/WorktreeExitDialog.tsx +231 -0
- package/components/agents/AgentDetail.tsx +220 -0
- package/components/agents/AgentEditor.tsx +178 -0
- package/components/agents/AgentNavigationFooter.tsx +26 -0
- package/components/agents/AgentsList.tsx +440 -0
- package/components/agents/AgentsMenu.tsx +800 -0
- package/components/agents/ColorPicker.tsx +112 -0
- package/components/agents/ModelSelector.tsx +68 -0
- package/components/agents/ToolSelector.tsx +562 -0
- package/components/agents/agentFileUtils.ts +272 -0
- package/components/agents/generateAgent.ts +197 -0
- package/components/agents/new-agent-creation/CreateAgentWizard.tsx +97 -0
- package/components/agents/new-agent-creation/wizard-steps/ColorStep.tsx +84 -0
- package/components/agents/new-agent-creation/wizard-steps/ConfirmStep.tsx +378 -0
- package/components/agents/new-agent-creation/wizard-steps/ConfirmStepWrapper.tsx +74 -0
- package/components/agents/new-agent-creation/wizard-steps/DescriptionStep.tsx +123 -0
- package/components/agents/new-agent-creation/wizard-steps/GenerateStep.tsx +143 -0
- package/components/agents/new-agent-creation/wizard-steps/LocationStep.tsx +80 -0
- package/components/agents/new-agent-creation/wizard-steps/MemoryStep.tsx +113 -0
- package/components/agents/new-agent-creation/wizard-steps/MethodStep.tsx +80 -0
- package/components/agents/new-agent-creation/wizard-steps/ModelStep.tsx +52 -0
- package/components/agents/new-agent-creation/wizard-steps/PromptStep.tsx +128 -0
- package/components/agents/new-agent-creation/wizard-steps/ToolsStep.tsx +61 -0
- package/components/agents/new-agent-creation/wizard-steps/TypeStep.tsx +103 -0
- package/components/agents/types.ts +27 -0
- package/components/agents/utils.ts +18 -0
- package/components/agents/validateAgent.ts +109 -0
- package/components/design-system/Byline.tsx +77 -0
- package/components/design-system/Dialog.tsx +138 -0
- package/components/design-system/Divider.tsx +149 -0
- package/components/design-system/FuzzyPicker.tsx +312 -0
- package/components/design-system/KeyboardShortcutHint.tsx +81 -0
- package/components/design-system/ListItem.tsx +244 -0
- package/components/design-system/LoadingState.tsx +94 -0
- package/components/design-system/Pane.tsx +77 -0
- package/components/design-system/ProgressBar.tsx +86 -0
- package/components/design-system/Ratchet.tsx +80 -0
- package/components/design-system/StatusIcon.tsx +95 -0
- package/components/design-system/Tabs.tsx +340 -0
- package/components/design-system/ThemeProvider.tsx +170 -0
- package/components/design-system/ThemedBox.tsx +156 -0
- package/components/design-system/ThemedText.tsx +124 -0
- package/components/design-system/color.ts +30 -0
- package/components/diff/DiffDetailView.tsx +281 -0
- package/components/diff/DiffDialog.tsx +383 -0
- package/components/diff/DiffFileList.tsx +292 -0
- package/components/grove/Grove.tsx +463 -0
- package/components/hooks/HooksConfigMenu.tsx +578 -0
- package/components/hooks/PromptDialog.tsx +90 -0
- package/components/hooks/SelectEventMode.tsx +127 -0
- package/components/hooks/SelectHookMode.tsx +112 -0
- package/components/hooks/SelectMatcherMode.tsx +144 -0
- package/components/hooks/ViewHookMode.tsx +199 -0
- package/components/mcp/CapabilitiesSection.tsx +61 -0
- package/components/mcp/ElicitationDialog.tsx +1169 -0
- package/components/mcp/MCPAgentServerMenu.tsx +183 -0
- package/components/mcp/MCPListPanel.tsx +504 -0
- package/components/mcp/MCPReconnect.tsx +167 -0
- package/components/mcp/MCPRemoteServerMenu.tsx +649 -0
- package/components/mcp/MCPSettings.tsx +398 -0
- package/components/mcp/MCPStdioServerMenu.tsx +177 -0
- package/components/mcp/MCPToolDetailView.tsx +212 -0
- package/components/mcp/MCPToolListView.tsx +141 -0
- package/components/mcp/McpParsingWarnings.tsx +213 -0
- package/components/mcp/index.ts +9 -0
- package/components/mcp/utils/reconnectHelpers.tsx +49 -0
- package/components/memory/MemoryFileSelector.tsx +438 -0
- package/components/memory/MemoryUpdateNotification.tsx +45 -0
- package/components/messageActions.tsx +450 -0
- package/components/messages/AdvisorMessage.tsx +158 -0
- package/components/messages/AssistantRedactedThinkingMessage.tsx +31 -0
- package/components/messages/AssistantTextMessage.tsx +270 -0
- package/components/messages/AssistantThinkingMessage.tsx +86 -0
- package/components/messages/AssistantToolUseMessage.tsx +368 -0
- package/components/messages/AttachmentMessage.tsx +536 -0
- package/components/messages/CollapsedReadSearchContent.tsx +484 -0
- package/components/messages/CompactBoundaryMessage.tsx +18 -0
- package/components/messages/GroupedToolUseContent.tsx +58 -0
- package/components/messages/HighlightedThinkingText.tsx +162 -0
- package/components/messages/HookProgressMessage.tsx +116 -0
- package/components/messages/PlanApprovalMessage.tsx +222 -0
- package/components/messages/RateLimitMessage.tsx +161 -0
- package/components/messages/ShutdownMessage.tsx +132 -0
- package/components/messages/SystemAPIErrorMessage.tsx +141 -0
- package/components/messages/SystemTextMessage.tsx +827 -0
- package/components/messages/TaskAssignmentMessage.tsx +76 -0
- package/components/messages/UserAgentNotificationMessage.tsx +83 -0
- package/components/messages/UserBashInputMessage.tsx +58 -0
- package/components/messages/UserBashOutputMessage.tsx +54 -0
- package/components/messages/UserChannelMessage.tsx +137 -0
- package/components/messages/UserCommandMessage.tsx +108 -0
- package/components/messages/UserImageMessage.tsx +59 -0
- package/components/messages/UserLocalCommandOutputMessage.tsx +167 -0
- package/components/messages/UserMemoryInputMessage.tsx +75 -0
- package/components/messages/UserPlanMessage.tsx +42 -0
- package/components/messages/UserPromptMessage.tsx +80 -0
- package/components/messages/UserResourceUpdateMessage.tsx +121 -0
- package/components/messages/UserTeammateMessage.tsx +206 -0
- package/components/messages/UserTextMessage.tsx +275 -0
- package/components/messages/UserToolResultMessage/RejectedPlanMessage.tsx +31 -0
- package/components/messages/UserToolResultMessage/RejectedToolUseMessage.tsx +16 -0
- package/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +16 -0
- package/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +103 -0
- package/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +95 -0
- package/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +106 -0
- package/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +104 -0
- package/components/messages/UserToolResultMessage/utils.tsx +44 -0
- package/components/messages/nullRenderingAttachments.ts +70 -0
- package/components/messages/teamMemCollapsed.tsx +140 -0
- package/components/messages/teamMemSaved.ts +19 -0
- package/components/permissions/AskUserQuestionPermissionRequest/AskUserQuestionPermissionRequest.tsx +645 -0
- package/components/permissions/AskUserQuestionPermissionRequest/PreviewBox.tsx +229 -0
- package/components/permissions/AskUserQuestionPermissionRequest/PreviewQuestionView.tsx +328 -0
- package/components/permissions/AskUserQuestionPermissionRequest/QuestionNavigationBar.tsx +178 -0
- package/components/permissions/AskUserQuestionPermissionRequest/QuestionView.tsx +465 -0
- package/components/permissions/AskUserQuestionPermissionRequest/SubmitQuestionsView.tsx +144 -0
- package/components/permissions/AskUserQuestionPermissionRequest/use-multiple-choice-state.ts +179 -0
- package/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +482 -0
- package/components/permissions/BashPermissionRequest/bashToolUseOptions.tsx +147 -0
- package/components/permissions/ComputerUseApproval/ComputerUseApproval.tsx +441 -0
- package/components/permissions/EnterPlanModePermissionRequest/EnterPlanModePermissionRequest.tsx +122 -0
- package/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx +768 -0
- package/components/permissions/FallbackPermissionRequest.tsx +333 -0
- package/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +182 -0
- package/components/permissions/FilePermissionDialog/FilePermissionDialog.tsx +204 -0
- package/components/permissions/FilePermissionDialog/ideDiffConfig.ts +42 -0
- package/components/permissions/FilePermissionDialog/permissionOptions.tsx +177 -0
- package/components/permissions/FilePermissionDialog/useFilePermissionDialog.ts +212 -0
- package/components/permissions/FilePermissionDialog/usePermissionHandler.ts +185 -0
- package/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +161 -0
- package/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +89 -0
- package/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +115 -0
- package/components/permissions/NotebookEditPermissionRequest/NotebookEditPermissionRequest.tsx +166 -0
- package/components/permissions/NotebookEditPermissionRequest/NotebookEditToolDiff.tsx +235 -0
- package/components/permissions/PermissionDecisionDebugInfo.tsx +460 -0
- package/components/permissions/PermissionDialog.tsx +72 -0
- package/components/permissions/PermissionExplanation.tsx +272 -0
- package/components/permissions/PermissionPrompt.tsx +336 -0
- package/components/permissions/PermissionRequest.tsx +217 -0
- package/components/permissions/PermissionRequestTitle.tsx +66 -0
- package/components/permissions/PermissionRuleExplanation.tsx +121 -0
- package/components/permissions/PowerShellPermissionRequest/PowerShellPermissionRequest.tsx +235 -0
- package/components/permissions/PowerShellPermissionRequest/powershellToolUseOptions.tsx +91 -0
- package/components/permissions/SandboxPermissionRequest.tsx +163 -0
- package/components/permissions/SedEditPermissionRequest/SedEditPermissionRequest.tsx +230 -0
- package/components/permissions/SkillPermissionRequest/SkillPermissionRequest.tsx +369 -0
- package/components/permissions/WebFetchPermissionRequest/WebFetchPermissionRequest.tsx +258 -0
- package/components/permissions/WorkerBadge.tsx +49 -0
- package/components/permissions/WorkerPendingPermission.tsx +105 -0
- package/components/permissions/hooks.ts +209 -0
- package/components/permissions/rules/AddPermissionRules.tsx +180 -0
- package/components/permissions/rules/AddWorkspaceDirectory.tsx +340 -0
- package/components/permissions/rules/PermissionRuleDescription.tsx +76 -0
- package/components/permissions/rules/PermissionRuleInput.tsx +138 -0
- package/components/permissions/rules/PermissionRuleList.tsx +1179 -0
- package/components/permissions/rules/RecentDenialsTab.tsx +207 -0
- package/components/permissions/rules/RemoveWorkspaceDirectory.tsx +110 -0
- package/components/permissions/rules/WorkspaceTab.tsx +150 -0
- package/components/permissions/shellPermissionHelpers.tsx +164 -0
- package/components/permissions/useShellPermissionFeedback.ts +148 -0
- package/components/permissions/utils.ts +25 -0
- package/components/sandbox/SandboxConfigTab.tsx +45 -0
- package/components/sandbox/SandboxDependenciesTab.tsx +120 -0
- package/components/sandbox/SandboxDoctorSection.tsx +46 -0
- package/components/sandbox/SandboxOverridesTab.tsx +193 -0
- package/components/sandbox/SandboxSettings.tsx +296 -0
- package/components/shell/ExpandShellOutputContext.tsx +36 -0
- package/components/shell/OutputLine.tsx +118 -0
- package/components/shell/ShellProgressMessage.tsx +150 -0
- package/components/shell/ShellTimeDisplay.tsx +74 -0
- package/components/skills/SkillsMenu.tsx +237 -0
- package/components/tasks/AsyncAgentDetailDialog.tsx +229 -0
- package/components/tasks/BackgroundTask.tsx +345 -0
- package/components/tasks/BackgroundTaskStatus.tsx +429 -0
- package/components/tasks/BackgroundTasksDialog.tsx +652 -0
- package/components/tasks/DreamDetailDialog.tsx +251 -0
- package/components/tasks/InProcessTeammateDetailDialog.tsx +266 -0
- package/components/tasks/RemoteSessionDetailDialog.tsx +904 -0
- package/components/tasks/RemoteSessionProgress.tsx +243 -0
- package/components/tasks/ShellDetailDialog.tsx +404 -0
- package/components/tasks/ShellProgress.tsx +87 -0
- package/components/tasks/renderToolActivity.tsx +33 -0
- package/components/tasks/taskStatusUtils.tsx +107 -0
- package/components/teams/TeamStatus.tsx +80 -0
- package/components/teams/TeamsDialog.tsx +715 -0
- package/components/ui/OrderedList.tsx +71 -0
- package/components/ui/OrderedListItem.tsx +45 -0
- package/components/ui/TreeSelect.tsx +397 -0
- package/components/wizard/WizardDialogLayout.tsx +65 -0
- package/components/wizard/WizardNavigationFooter.tsx +24 -0
- package/components/wizard/WizardProvider.tsx +213 -0
- package/components/wizard/index.ts +9 -0
- package/components/wizard/useWizard.ts +13 -0
- package/constants/apiLimits.ts +94 -0
- package/constants/betas.ts +52 -0
- package/constants/common.ts +33 -0
- package/constants/cyberRiskInstruction.ts +24 -0
- package/constants/errorIds.ts +15 -0
- package/constants/figures.ts +45 -0
- package/constants/files.ts +156 -0
- package/constants/github-app.ts +144 -0
- package/constants/keys.ts +11 -0
- package/constants/messages.ts +1 -0
- package/constants/oauth.ts +234 -0
- package/constants/outputStyles.ts +216 -0
- package/constants/product.ts +76 -0
- package/constants/prompts.ts +914 -0
- package/constants/spinnerVerbs.ts +204 -0
- package/constants/system.ts +95 -0
- package/constants/systemPromptSections.ts +68 -0
- package/constants/toolLimits.ts +56 -0
- package/constants/tools.ts +112 -0
- package/constants/turnCompletionVerbs.ts +12 -0
- package/constants/xml.ts +86 -0
- package/context/QueuedMessageContext.tsx +63 -0
- package/context/fpsMetrics.tsx +30 -0
- package/context/mailbox.tsx +38 -0
- package/context/modalContext.tsx +58 -0
- package/context/notifications.tsx +240 -0
- package/context/overlayContext.tsx +151 -0
- package/context/promptOverlayContext.tsx +125 -0
- package/context/stats.tsx +220 -0
- package/context/voice.tsx +88 -0
- package/context.ts +189 -0
- package/cost-tracker.ts +323 -0
- package/costHook.ts +22 -0
- package/dialogLaunchers.tsx +133 -0
- package/entrypoints/agentSdkTypes.ts +443 -0
- package/entrypoints/cli.tsx +310 -0
- package/entrypoints/init.ts +340 -0
- package/entrypoints/mcp.ts +196 -0
- package/entrypoints/sandboxTypes.ts +156 -0
- package/entrypoints/sdk/controlSchemas.ts +663 -0
- package/entrypoints/sdk/coreSchemas.ts +1889 -0
- package/entrypoints/sdk/coreTypes.generated.ts +73 -0
- package/entrypoints/sdk/coreTypes.ts +62 -0
- package/entrypoints/sdk/runtimeTypes.ts +74 -0
- package/entrypoints/sdk/toolTypes.ts +12 -0
- package/global.d.ts +18 -0
- package/history.ts +464 -0
- package/hooks/fileSuggestions.ts +811 -0
- package/hooks/notifs/useAutoModeUnavailableNotification.ts +56 -0
- package/hooks/notifs/useCanSwitchToExistingSubscription.tsx +60 -0
- package/hooks/notifs/useDeprecationWarningNotification.tsx +44 -0
- package/hooks/notifs/useFastModeNotification.tsx +162 -0
- package/hooks/notifs/useIDEStatusIndicator.tsx +186 -0
- package/hooks/notifs/useInstallMessages.tsx +26 -0
- package/hooks/notifs/useLspInitializationNotification.tsx +143 -0
- package/hooks/notifs/useMcpConnectivityStatus.tsx +88 -0
- package/hooks/notifs/useModelMigrationNotifications.tsx +52 -0
- package/hooks/notifs/useNpmDeprecationNotification.tsx +25 -0
- package/hooks/notifs/usePluginAutoupdateNotification.tsx +83 -0
- package/hooks/notifs/usePluginInstallationStatus.tsx +128 -0
- package/hooks/notifs/useRateLimitWarningNotification.tsx +114 -0
- package/hooks/notifs/useSettingsErrors.tsx +69 -0
- package/hooks/notifs/useStartupNotification.ts +41 -0
- package/hooks/notifs/useTeammateShutdownNotification.ts +78 -0
- package/hooks/renderPlaceholder.ts +51 -0
- package/hooks/toolPermission/PermissionContext.ts +388 -0
- package/hooks/toolPermission/handlers/coordinatorHandler.ts +65 -0
- package/hooks/toolPermission/handlers/interactiveHandler.ts +536 -0
- package/hooks/toolPermission/handlers/swarmWorkerHandler.ts +159 -0
- package/hooks/toolPermission/permissionLogging.ts +238 -0
- package/hooks/unifiedSuggestions.ts +202 -0
- package/hooks/useAfterFirstRender.ts +17 -0
- package/hooks/useApiKeyVerification.ts +84 -0
- package/hooks/useArrowKeyHistory.tsx +229 -0
- package/hooks/useAssistantHistory.ts +250 -0
- package/hooks/useAwaySummary.ts +125 -0
- package/hooks/useBackgroundTaskNavigation.ts +251 -0
- package/hooks/useBlink.ts +34 -0
- package/hooks/useCanUseTool.tsx +204 -0
- package/hooks/useCancelRequest.ts +276 -0
- package/hooks/useChromeExtensionNotification.tsx +50 -0
- package/hooks/useClaudeCodeHintRecommendation.tsx +129 -0
- package/hooks/useClipboardImageHint.ts +77 -0
- package/hooks/useCommandKeybindings.tsx +108 -0
- package/hooks/useCommandQueue.ts +15 -0
- package/hooks/useCopyOnSelect.ts +98 -0
- package/hooks/useDeferredHookMessages.ts +46 -0
- package/hooks/useDiffData.ts +110 -0
- package/hooks/useDiffInIDE.ts +379 -0
- package/hooks/useDirectConnect.ts +229 -0
- package/hooks/useDoublePress.ts +62 -0
- package/hooks/useDynamicConfig.ts +22 -0
- package/hooks/useElapsedTime.ts +37 -0
- package/hooks/useExitOnCtrlCD.ts +95 -0
- package/hooks/useExitOnCtrlCDWithKeybindings.ts +24 -0
- package/hooks/useFileHistorySnapshotInit.ts +25 -0
- package/hooks/useGlobalKeybindings.tsx +249 -0
- package/hooks/useHistorySearch.ts +303 -0
- package/hooks/useIDEIntegration.tsx +70 -0
- package/hooks/useIdeAtMentioned.ts +76 -0
- package/hooks/useIdeConnectionStatus.ts +33 -0
- package/hooks/useIdeLogging.ts +41 -0
- package/hooks/useIdeSelection.ts +150 -0
- package/hooks/useInboxPoller.ts +969 -0
- package/hooks/useInputBuffer.ts +132 -0
- package/hooks/useIssueFlagBanner.ts +133 -0
- package/hooks/useLogMessages.ts +119 -0
- package/hooks/useLspPluginRecommendation.tsx +194 -0
- package/hooks/useMailboxBridge.ts +21 -0
- package/hooks/useMainLoopModel.ts +34 -0
- package/hooks/useManagePlugins.ts +304 -0
- package/hooks/useMemoryUsage.ts +39 -0
- package/hooks/useMergedClients.ts +23 -0
- package/hooks/useMergedCommands.ts +15 -0
- package/hooks/useMergedTools.ts +44 -0
- package/hooks/useMinDisplayTime.ts +35 -0
- package/hooks/useNotifyAfterTimeout.ts +65 -0
- package/hooks/useOfficialMarketplaceNotification.tsx +48 -0
- package/hooks/usePasteHandler.ts +285 -0
- package/hooks/usePluginRecommendationBase.tsx +105 -0
- package/hooks/usePrStatus.ts +106 -0
- package/hooks/usePromptSuggestion.ts +177 -0
- package/hooks/usePromptsFromClaudeInChrome.tsx +71 -0
- package/hooks/useQueueProcessor.ts +68 -0
- package/hooks/useRemoteSession.ts +605 -0
- package/hooks/useReplBridge.tsx +723 -0
- package/hooks/useSSHSession.ts +241 -0
- package/hooks/useScheduledTasks.ts +139 -0
- package/hooks/useSearchInput.ts +364 -0
- package/hooks/useSessionBackgrounding.ts +158 -0
- package/hooks/useSettings.ts +17 -0
- package/hooks/useSettingsChange.ts +25 -0
- package/hooks/useSkillImprovementSurvey.ts +105 -0
- package/hooks/useSkillsChange.ts +62 -0
- package/hooks/useSwarmInitialization.ts +81 -0
- package/hooks/useSwarmPermissionPoller.ts +330 -0
- package/hooks/useTaskListWatcher.ts +221 -0
- package/hooks/useTasksV2.ts +250 -0
- package/hooks/useTeammateViewAutoExit.ts +63 -0
- package/hooks/useTeleportResume.tsx +85 -0
- package/hooks/useTerminalSize.ts +15 -0
- package/hooks/useTextInput.ts +529 -0
- package/hooks/useTimeout.ts +14 -0
- package/hooks/useTurnDiffs.ts +213 -0
- package/hooks/useTypeahead.tsx +1385 -0
- package/hooks/useUpdateNotification.ts +34 -0
- package/hooks/useVimInput.ts +316 -0
- package/hooks/useVirtualScroll.ts +721 -0
- package/hooks/useVoice.ts +1144 -0
- package/hooks/useVoiceEnabled.ts +25 -0
- package/hooks/useVoiceIntegration.tsx +677 -0
- package/ink/Ansi.tsx +292 -0
- package/ink/bidi.ts +139 -0
- package/ink/clearTerminal.ts +74 -0
- package/ink/colorize.ts +231 -0
- package/ink/components/AlternateScreen.tsx +80 -0
- package/ink/components/App.tsx +658 -0
- package/ink/components/AppContext.ts +21 -0
- package/ink/components/Box.tsx +214 -0
- package/ink/components/Button.tsx +192 -0
- package/ink/components/ClockContext.tsx +112 -0
- package/ink/components/CursorDeclarationContext.ts +32 -0
- package/ink/components/ErrorOverview.tsx +109 -0
- package/ink/components/Link.tsx +42 -0
- package/ink/components/Newline.tsx +39 -0
- package/ink/components/NoSelect.tsx +68 -0
- package/ink/components/RawAnsi.tsx +57 -0
- package/ink/components/ScrollBox.tsx +237 -0
- package/ink/components/Spacer.tsx +20 -0
- package/ink/components/StdinContext.ts +49 -0
- package/ink/components/TerminalFocusContext.tsx +52 -0
- package/ink/components/TerminalSizeContext.tsx +7 -0
- package/ink/components/Text.tsx +254 -0
- package/ink/constants.ts +2 -0
- package/ink/dom.ts +484 -0
- package/ink/events/click-event.ts +38 -0
- package/ink/events/dispatcher.ts +235 -0
- package/ink/events/emitter.ts +39 -0
- package/ink/events/event-handlers.ts +73 -0
- package/ink/events/event.ts +11 -0
- package/ink/events/focus-event.ts +21 -0
- package/ink/events/input-event.ts +205 -0
- package/ink/events/keyboard-event.ts +51 -0
- package/ink/events/terminal-event.ts +107 -0
- package/ink/events/terminal-focus-event.ts +19 -0
- package/ink/focus.ts +181 -0
- package/ink/frame.ts +124 -0
- package/ink/get-max-width.ts +27 -0
- package/ink/global.d.ts +14 -0
- package/ink/hit-test.ts +130 -0
- package/ink/hooks/use-animation-frame.ts +57 -0
- package/ink/hooks/use-app.ts +8 -0
- package/ink/hooks/use-declared-cursor.ts +73 -0
- package/ink/hooks/use-input.ts +92 -0
- package/ink/hooks/use-interval.ts +67 -0
- package/ink/hooks/use-search-highlight.ts +53 -0
- package/ink/hooks/use-selection.ts +104 -0
- package/ink/hooks/use-stdin.ts +8 -0
- package/ink/hooks/use-tab-status.ts +72 -0
- package/ink/hooks/use-terminal-focus.ts +16 -0
- package/ink/hooks/use-terminal-title.ts +31 -0
- package/ink/hooks/use-terminal-viewport.ts +96 -0
- package/ink/ink.tsx +1723 -0
- package/ink/instances.ts +10 -0
- package/ink/layout/engine.ts +6 -0
- package/ink/layout/geometry.ts +97 -0
- package/ink/layout/node.ts +152 -0
- package/ink/layout/yoga.ts +308 -0
- package/ink/line-width-cache.ts +24 -0
- package/ink/log-update.ts +773 -0
- package/ink/measure-element.ts +23 -0
- package/ink/measure-text.ts +47 -0
- package/ink/node-cache.ts +54 -0
- package/ink/optimizer.ts +93 -0
- package/ink/output.ts +797 -0
- package/ink/parse-keypress.ts +801 -0
- package/ink/reconciler.ts +512 -0
- package/ink/render-border.ts +231 -0
- package/ink/render-node-to-output.ts +1462 -0
- package/ink/render-to-screen.ts +231 -0
- package/ink/renderer.ts +178 -0
- package/ink/root.ts +184 -0
- package/ink/screen.ts +1486 -0
- package/ink/searchHighlight.ts +93 -0
- package/ink/selection.ts +917 -0
- package/ink/squash-text-nodes.ts +92 -0
- package/ink/stringWidth.ts +222 -0
- package/ink/styles.ts +771 -0
- package/ink/supports-hyperlinks.ts +57 -0
- package/ink/tabstops.ts +46 -0
- package/ink/terminal-focus-state.ts +47 -0
- package/ink/terminal-querier.ts +212 -0
- package/ink/terminal.ts +248 -0
- package/ink/termio/ansi.ts +75 -0
- package/ink/termio/csi.ts +319 -0
- package/ink/termio/dec.ts +60 -0
- package/ink/termio/esc.ts +67 -0
- package/ink/termio/osc.ts +493 -0
- package/ink/termio/parser.ts +394 -0
- package/ink/termio/sgr.ts +308 -0
- package/ink/termio/tokenize.ts +319 -0
- package/ink/termio/types.ts +236 -0
- package/ink/termio.ts +42 -0
- package/ink/useTerminalNotification.ts +126 -0
- package/ink/warn.ts +9 -0
- package/ink/widest-line.ts +19 -0
- package/ink/wrap-text.ts +74 -0
- package/ink/wrapAnsi.ts +20 -0
- package/ink.ts +85 -0
- package/interactiveHelpers.tsx +366 -0
- package/main.tsx +4702 -0
- package/package.json +95 -0
- package/projectOnboardingState.ts +83 -0
- package/query/config.ts +46 -0
- package/query/deps.ts +40 -0
- package/query/stopHooks.ts +473 -0
- package/query/tokenBudget.ts +93 -0
- package/query.ts +1729 -0
- package/replLauncher.tsx +23 -0
- package/services/AgentSummary/agentSummary.ts +179 -0
- package/services/MagicDocs/magicDocs.ts +254 -0
- package/services/MagicDocs/prompts.ts +127 -0
- package/services/PromptSuggestion/promptSuggestion.ts +523 -0
- package/services/PromptSuggestion/speculation.ts +991 -0
- package/services/SessionMemory/prompts.ts +324 -0
- package/services/SessionMemory/sessionMemory.ts +495 -0
- package/services/SessionMemory/sessionMemoryUtils.ts +207 -0
- package/services/analytics/config.ts +38 -0
- package/services/analytics/datadog.ts +307 -0
- package/services/analytics/firstPartyEventLogger.ts +449 -0
- package/services/analytics/firstPartyEventLoggingExporter.ts +806 -0
- package/services/analytics/growthbook.ts +1155 -0
- package/services/analytics/index.ts +173 -0
- package/services/analytics/metadata.ts +973 -0
- package/services/analytics/sink.ts +114 -0
- package/services/analytics/sinkKillswitch.ts +25 -0
- package/services/api/adminRequests.ts +119 -0
- package/services/api/bootstrap.ts +141 -0
- package/services/api/claude.ts +3419 -0
- package/services/api/client.ts +389 -0
- package/services/api/dumpPrompts.ts +226 -0
- package/services/api/emptyUsage.ts +22 -0
- package/services/api/errorUtils.ts +260 -0
- package/services/api/errors.ts +1207 -0
- package/services/api/filesApi.ts +748 -0
- package/services/api/firstTokenDate.ts +60 -0
- package/services/api/grove.ts +357 -0
- package/services/api/logging.ts +788 -0
- package/services/api/metricsOptOut.ts +159 -0
- package/services/api/overageCreditGrant.ts +137 -0
- package/services/api/promptCacheBreakDetection.ts +727 -0
- package/services/api/referral.ts +281 -0
- package/services/api/sessionIngress.ts +514 -0
- package/services/api/ultrareviewQuota.ts +38 -0
- package/services/api/usage.ts +63 -0
- package/services/api/withRetry.ts +822 -0
- package/services/autoDream/autoDream.ts +324 -0
- package/services/autoDream/config.ts +21 -0
- package/services/autoDream/consolidationLock.ts +140 -0
- package/services/autoDream/consolidationPrompt.ts +65 -0
- package/services/awaySummary.ts +74 -0
- package/services/claudeAiLimits.ts +515 -0
- package/services/claudeAiLimitsHook.ts +23 -0
- package/services/compact/apiMicrocompact.ts +153 -0
- package/services/compact/autoCompact.ts +351 -0
- package/services/compact/compact.ts +1705 -0
- package/services/compact/compactWarningHook.ts +16 -0
- package/services/compact/compactWarningState.ts +18 -0
- package/services/compact/grouping.ts +63 -0
- package/services/compact/microCompact.ts +530 -0
- package/services/compact/postCompactCleanup.ts +77 -0
- package/services/compact/prompt.ts +374 -0
- package/services/compact/sessionMemoryCompact.ts +630 -0
- package/services/compact/timeBasedMCConfig.ts +43 -0
- package/services/diagnosticTracking.ts +397 -0
- package/services/extractMemories/extractMemories.ts +615 -0
- package/services/extractMemories/prompts.ts +154 -0
- package/services/internalLogging.ts +90 -0
- package/services/lsp/LSPClient.ts +447 -0
- package/services/lsp/LSPDiagnosticRegistry.ts +386 -0
- package/services/lsp/LSPServerInstance.ts +511 -0
- package/services/lsp/LSPServerManager.ts +420 -0
- package/services/lsp/config.ts +79 -0
- package/services/lsp/manager.ts +289 -0
- package/services/lsp/passiveFeedback.ts +328 -0
- package/services/mcp/InProcessTransport.ts +63 -0
- package/services/mcp/MCPConnectionManager.tsx +73 -0
- package/services/mcp/SdkControlTransport.ts +136 -0
- package/services/mcp/auth.ts +2465 -0
- package/services/mcp/channelAllowlist.ts +76 -0
- package/services/mcp/channelNotification.ts +316 -0
- package/services/mcp/channelPermissions.ts +240 -0
- package/services/mcp/claudeai.ts +164 -0
- package/services/mcp/client.ts +3348 -0
- package/services/mcp/config.ts +1578 -0
- package/services/mcp/elicitationHandler.ts +313 -0
- package/services/mcp/envExpansion.ts +38 -0
- package/services/mcp/headersHelper.ts +138 -0
- package/services/mcp/mcpStringUtils.ts +106 -0
- package/services/mcp/normalization.ts +23 -0
- package/services/mcp/oauthPort.ts +78 -0
- package/services/mcp/officialRegistry.ts +72 -0
- package/services/mcp/types.ts +258 -0
- package/services/mcp/useManageMCPConnections.ts +1141 -0
- package/services/mcp/utils.ts +575 -0
- package/services/mcp/vscodeSdkMcp.ts +112 -0
- package/services/mcp/xaa.ts +511 -0
- package/services/mcp/xaaIdpLogin.ts +487 -0
- package/services/mcpServerApproval.tsx +41 -0
- package/services/mockRateLimits.ts +882 -0
- package/services/notifier.ts +156 -0
- package/services/oauth/auth-code-listener.ts +211 -0
- package/services/oauth/client.ts +566 -0
- package/services/oauth/crypto.ts +23 -0
- package/services/oauth/getOauthProfile.ts +53 -0
- package/services/oauth/index.ts +198 -0
- package/services/plugins/PluginInstallationManager.ts +184 -0
- package/services/plugins/pluginCliCommands.ts +344 -0
- package/services/plugins/pluginOperations.ts +1088 -0
- package/services/policyLimits/index.ts +663 -0
- package/services/policyLimits/types.ts +27 -0
- package/services/preventSleep.ts +165 -0
- package/services/rateLimitMessages.ts +344 -0
- package/services/rateLimitMocking.ts +144 -0
- package/services/remoteManagedSettings/index.ts +638 -0
- package/services/remoteManagedSettings/securityCheck.tsx +74 -0
- package/services/remoteManagedSettings/syncCache.ts +112 -0
- package/services/remoteManagedSettings/syncCacheState.ts +96 -0
- package/services/remoteManagedSettings/types.ts +31 -0
- package/services/settingsSync/index.ts +581 -0
- package/services/settingsSync/types.ts +67 -0
- package/services/teamMemorySync/index.ts +1256 -0
- package/services/teamMemorySync/secretScanner.ts +324 -0
- package/services/teamMemorySync/teamMemSecretGuard.ts +44 -0
- package/services/teamMemorySync/types.ts +156 -0
- package/services/teamMemorySync/watcher.ts +387 -0
- package/services/tips/tipHistory.ts +17 -0
- package/services/tips/tipRegistry.ts +686 -0
- package/services/tips/tipScheduler.ts +58 -0
- package/services/tokenEstimation.ts +495 -0
- package/services/toolUseSummary/toolUseSummaryGenerator.ts +112 -0
- package/services/tools/StreamingToolExecutor.ts +530 -0
- package/services/tools/toolExecution.ts +1745 -0
- package/services/tools/toolHooks.ts +650 -0
- package/services/tools/toolOrchestration.ts +188 -0
- package/services/vcr.ts +406 -0
- package/services/voice.ts +525 -0
- package/services/voiceKeyterms.ts +106 -0
- package/services/voiceStreamSTT.ts +544 -0
- package/setup.ts +477 -0
- package/state/AppState.tsx +200 -0
- package/state/AppStateStore.ts +569 -0
- package/state/onChangeAppState.ts +171 -0
- package/state/selectors.ts +76 -0
- package/state/store.ts +34 -0
- package/state/teammateViewHelpers.ts +141 -0
- package/tasks.ts +39 -0
- package/tools/AgentTool/AgentTool.tsx +1398 -0
- package/tools/AgentTool/UI.tsx +872 -0
- package/tools/AgentTool/agentColorManager.ts +66 -0
- package/tools/AgentTool/agentDisplay.ts +104 -0
- package/tools/AgentTool/agentMemory.ts +177 -0
- package/tools/AgentTool/agentMemorySnapshot.ts +197 -0
- package/tools/AgentTool/agentToolUtils.ts +686 -0
- package/tools/AgentTool/built-in/claudeCodeGuideAgent.ts +205 -0
- package/tools/AgentTool/built-in/exploreAgent.ts +83 -0
- package/tools/AgentTool/built-in/generalPurposeAgent.ts +34 -0
- package/tools/AgentTool/built-in/planAgent.ts +92 -0
- package/tools/AgentTool/built-in/statuslineSetup.ts +144 -0
- package/tools/AgentTool/built-in/verificationAgent.ts +152 -0
- package/tools/AgentTool/builtInAgents.ts +72 -0
- package/tools/AgentTool/constants.ts +12 -0
- package/tools/AgentTool/forkSubagent.ts +210 -0
- package/tools/AgentTool/loadAgentsDir.ts +755 -0
- package/tools/AgentTool/prompt.ts +287 -0
- package/tools/AgentTool/resumeAgent.ts +265 -0
- package/tools/AgentTool/runAgent.ts +973 -0
- package/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +266 -0
- package/tools/AskUserQuestionTool/prompt.ts +44 -0
- package/tools/BashTool/BashTool.tsx +1144 -0
- package/tools/BashTool/BashToolResultMessage.tsx +191 -0
- package/tools/BashTool/UI.tsx +185 -0
- package/tools/BashTool/bashCommandHelpers.ts +265 -0
- package/tools/BashTool/bashPermissions.ts +2621 -0
- package/tools/BashTool/bashSecurity.ts +2592 -0
- package/tools/BashTool/commandSemantics.ts +140 -0
- package/tools/BashTool/commentLabel.ts +13 -0
- package/tools/BashTool/destructiveCommandWarning.ts +102 -0
- package/tools/BashTool/modeValidation.ts +115 -0
- package/tools/BashTool/pathValidation.ts +1303 -0
- package/tools/BashTool/prompt.ts +369 -0
- package/tools/BashTool/readOnlyValidation.ts +1990 -0
- package/tools/BashTool/sedEditParser.ts +322 -0
- package/tools/BashTool/sedValidation.ts +684 -0
- package/tools/BashTool/shouldUseSandbox.ts +153 -0
- package/tools/BashTool/toolName.ts +2 -0
- package/tools/BashTool/utils.ts +223 -0
- package/tools/BriefTool/BriefTool.ts +204 -0
- package/tools/BriefTool/UI.tsx +101 -0
- package/tools/BriefTool/attachments.ts +110 -0
- package/tools/BriefTool/prompt.ts +22 -0
- package/tools/BriefTool/upload.ts +174 -0
- package/tools/ConfigTool/ConfigTool.ts +467 -0
- package/tools/ConfigTool/UI.tsx +38 -0
- package/tools/ConfigTool/constants.ts +1 -0
- package/tools/ConfigTool/prompt.ts +93 -0
- package/tools/ConfigTool/supportedSettings.ts +211 -0
- package/tools/EnterPlanModeTool/EnterPlanModeTool.ts +126 -0
- package/tools/EnterPlanModeTool/UI.tsx +33 -0
- package/tools/EnterPlanModeTool/constants.ts +1 -0
- package/tools/EnterPlanModeTool/prompt.ts +170 -0
- package/tools/EnterWorktreeTool/EnterWorktreeTool.ts +127 -0
- package/tools/EnterWorktreeTool/UI.tsx +20 -0
- package/tools/EnterWorktreeTool/constants.ts +1 -0
- package/tools/EnterWorktreeTool/prompt.ts +30 -0
- package/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts +493 -0
- package/tools/ExitPlanModeTool/UI.tsx +82 -0
- package/tools/ExitPlanModeTool/constants.ts +2 -0
- package/tools/ExitPlanModeTool/prompt.ts +29 -0
- package/tools/ExitWorktreeTool/ExitWorktreeTool.ts +329 -0
- package/tools/ExitWorktreeTool/UI.tsx +25 -0
- package/tools/ExitWorktreeTool/constants.ts +1 -0
- package/tools/ExitWorktreeTool/prompt.ts +32 -0
- package/tools/FileEditTool/FileEditTool.ts +625 -0
- package/tools/FileEditTool/UI.tsx +289 -0
- package/tools/FileEditTool/constants.ts +11 -0
- package/tools/FileEditTool/prompt.ts +28 -0
- package/tools/FileEditTool/types.ts +85 -0
- package/tools/FileEditTool/utils.ts +775 -0
- package/tools/FileReadTool/FileReadTool.ts +1183 -0
- package/tools/FileReadTool/UI.tsx +185 -0
- package/tools/FileReadTool/imageProcessor.ts +94 -0
- package/tools/FileReadTool/limits.ts +92 -0
- package/tools/FileReadTool/prompt.ts +49 -0
- package/tools/FileWriteTool/FileWriteTool.ts +434 -0
- package/tools/FileWriteTool/UI.tsx +405 -0
- package/tools/FileWriteTool/prompt.ts +18 -0
- package/tools/GlobTool/GlobTool.ts +198 -0
- package/tools/GlobTool/UI.tsx +63 -0
- package/tools/GlobTool/prompt.ts +7 -0
- package/tools/GrepTool/GrepTool.ts +577 -0
- package/tools/GrepTool/UI.tsx +201 -0
- package/tools/GrepTool/prompt.ts +18 -0
- package/tools/LSPTool/LSPTool.ts +860 -0
- package/tools/LSPTool/UI.tsx +228 -0
- package/tools/LSPTool/formatters.ts +592 -0
- package/tools/LSPTool/prompt.ts +21 -0
- package/tools/LSPTool/schemas.ts +215 -0
- package/tools/LSPTool/symbolContext.ts +90 -0
- package/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +123 -0
- package/tools/ListMcpResourcesTool/UI.tsx +29 -0
- package/tools/ListMcpResourcesTool/prompt.ts +20 -0
- package/tools/MCPTool/MCPTool.ts +77 -0
- package/tools/MCPTool/UI.tsx +403 -0
- package/tools/MCPTool/classifyForCollapse.ts +604 -0
- package/tools/MCPTool/prompt.ts +3 -0
- package/tools/McpAuthTool/McpAuthTool.ts +215 -0
- package/tools/NotebookEditTool/NotebookEditTool.ts +490 -0
- package/tools/NotebookEditTool/UI.tsx +93 -0
- package/tools/NotebookEditTool/constants.ts +2 -0
- package/tools/NotebookEditTool/prompt.ts +3 -0
- package/tools/PowerShellTool/PowerShellTool.tsx +1001 -0
- package/tools/PowerShellTool/UI.tsx +131 -0
- package/tools/PowerShellTool/clmTypes.ts +211 -0
- package/tools/PowerShellTool/commandSemantics.ts +142 -0
- package/tools/PowerShellTool/commonParameters.ts +30 -0
- package/tools/PowerShellTool/destructiveCommandWarning.ts +109 -0
- package/tools/PowerShellTool/gitSafety.ts +176 -0
- package/tools/PowerShellTool/modeValidation.ts +404 -0
- package/tools/PowerShellTool/pathValidation.ts +2049 -0
- package/tools/PowerShellTool/powershellPermissions.ts +1648 -0
- package/tools/PowerShellTool/powershellSecurity.ts +1090 -0
- package/tools/PowerShellTool/prompt.ts +145 -0
- package/tools/PowerShellTool/readOnlyValidation.ts +1823 -0
- package/tools/PowerShellTool/toolName.ts +2 -0
- package/tools/REPLTool/constants.ts +46 -0
- package/tools/REPLTool/primitiveTools.ts +39 -0
- package/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +158 -0
- package/tools/ReadMcpResourceTool/UI.tsx +37 -0
- package/tools/ReadMcpResourceTool/prompt.ts +16 -0
- package/tools/RemoteTriggerTool/RemoteTriggerTool.ts +161 -0
- package/tools/RemoteTriggerTool/UI.tsx +17 -0
- package/tools/RemoteTriggerTool/prompt.ts +15 -0
- package/tools/ScheduleCronTool/CronCreateTool.ts +157 -0
- package/tools/ScheduleCronTool/CronDeleteTool.ts +95 -0
- package/tools/ScheduleCronTool/CronListTool.ts +97 -0
- package/tools/ScheduleCronTool/UI.tsx +60 -0
- package/tools/ScheduleCronTool/prompt.ts +135 -0
- package/tools/SendMessageTool/SendMessageTool.ts +917 -0
- package/tools/SendMessageTool/UI.tsx +31 -0
- package/tools/SendMessageTool/constants.ts +1 -0
- package/tools/SendMessageTool/prompt.ts +49 -0
- package/tools/SkillTool/SkillTool.ts +1108 -0
- package/tools/SkillTool/UI.tsx +128 -0
- package/tools/SkillTool/constants.ts +1 -0
- package/tools/SkillTool/prompt.ts +241 -0
- package/tools/SleepTool/prompt.ts +17 -0
- package/tools/SyntheticOutputTool/SyntheticOutputTool.ts +163 -0
- package/tools/TaskCreateTool/TaskCreateTool.ts +138 -0
- package/tools/TaskCreateTool/constants.ts +1 -0
- package/tools/TaskCreateTool/prompt.ts +56 -0
- package/tools/TaskGetTool/TaskGetTool.ts +128 -0
- package/tools/TaskGetTool/constants.ts +1 -0
- package/tools/TaskGetTool/prompt.ts +24 -0
- package/tools/TaskListTool/TaskListTool.ts +116 -0
- package/tools/TaskListTool/constants.ts +1 -0
- package/tools/TaskListTool/prompt.ts +49 -0
- package/tools/TaskOutputTool/TaskOutputTool.tsx +584 -0
- package/tools/TaskOutputTool/constants.ts +1 -0
- package/tools/TaskStopTool/TaskStopTool.ts +131 -0
- package/tools/TaskStopTool/UI.tsx +41 -0
- package/tools/TaskStopTool/prompt.ts +8 -0
- package/tools/TaskUpdateTool/TaskUpdateTool.ts +406 -0
- package/tools/TaskUpdateTool/constants.ts +1 -0
- package/tools/TaskUpdateTool/prompt.ts +77 -0
- package/tools/TeamCreateTool/TeamCreateTool.ts +240 -0
- package/tools/TeamCreateTool/UI.tsx +6 -0
- package/tools/TeamCreateTool/constants.ts +1 -0
- package/tools/TeamCreateTool/prompt.ts +113 -0
- package/tools/TeamDeleteTool/TeamDeleteTool.ts +139 -0
- package/tools/TeamDeleteTool/UI.tsx +20 -0
- package/tools/TeamDeleteTool/constants.ts +1 -0
- package/tools/TeamDeleteTool/prompt.ts +16 -0
- package/tools/TodoWriteTool/TodoWriteTool.ts +115 -0
- package/tools/TodoWriteTool/constants.ts +1 -0
- package/tools/TodoWriteTool/prompt.ts +184 -0
- package/tools/ToolSearchTool/ToolSearchTool.ts +471 -0
- package/tools/ToolSearchTool/constants.ts +1 -0
- package/tools/ToolSearchTool/prompt.ts +121 -0
- package/tools/WebFetchTool/UI.tsx +72 -0
- package/tools/WebFetchTool/WebFetchTool.ts +318 -0
- package/tools/WebFetchTool/preapproved.ts +166 -0
- package/tools/WebFetchTool/prompt.ts +46 -0
- package/tools/WebFetchTool/utils.ts +530 -0
- package/tools/WebSearchTool/UI.tsx +101 -0
- package/tools/WebSearchTool/WebSearchTool.ts +435 -0
- package/tools/WebSearchTool/prompt.ts +34 -0
- package/tools/WorkflowTool/constants.ts +5 -0
- package/tools/shared/gitOperationTracking.ts +277 -0
- package/tools/shared/spawnMultiAgent.ts +1093 -0
- package/tools/testing/TestingPermissionTool.tsx +74 -0
- package/tools/utils.ts +40 -0
- package/tools.ts +392 -0
- package/types/command.ts +216 -0
- package/types/connectorText.ts +21 -0
- package/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +865 -0
- package/types/generated/events_mono/common/v1/auth.ts +100 -0
- package/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +223 -0
- package/types/generated/google/protobuf/timestamp.ts +187 -0
- package/types/hooks.ts +290 -0
- package/types/ids.ts +44 -0
- package/types/logs.ts +330 -0
- package/types/permissions.ts +441 -0
- package/types/plugin.ts +363 -0
- package/types/textInputTypes.ts +387 -0
- package/utils/CircularBuffer.ts +84 -0
- package/utils/Cursor.ts +1530 -0
- package/utils/QueryGuard.ts +121 -0
- package/utils/Shell.ts +474 -0
- package/utils/ShellCommand.ts +465 -0
- package/utils/abortController.ts +99 -0
- package/utils/activityManager.ts +164 -0
- package/utils/advisor.ts +145 -0
- package/utils/agentContext.ts +178 -0
- package/utils/agentId.ts +99 -0
- package/utils/agentSwarmsEnabled.ts +44 -0
- package/utils/agenticSessionSearch.ts +307 -0
- package/utils/analyzeContext.ts +1382 -0
- package/utils/ansiToPng.ts +334 -0
- package/utils/ansiToSvg.ts +272 -0
- package/utils/api.ts +718 -0
- package/utils/apiPreconnect.ts +71 -0
- package/utils/appleTerminalBackup.ts +124 -0
- package/utils/argumentSubstitution.ts +145 -0
- package/utils/array.ts +13 -0
- package/utils/asciicast.ts +239 -0
- package/utils/attachments.ts +3997 -0
- package/utils/attribution.ts +393 -0
- package/utils/auth.ts +2002 -0
- package/utils/authFileDescriptor.ts +196 -0
- package/utils/authPortable.ts +19 -0
- package/utils/autoModeDenials.ts +26 -0
- package/utils/autoRunIssue.tsx +122 -0
- package/utils/autoUpdater.ts +561 -0
- package/utils/aws.ts +74 -0
- package/utils/awsAuthStatusManager.ts +81 -0
- package/utils/background/remote/preconditions.ts +235 -0
- package/utils/background/remote/remoteSession.ts +98 -0
- package/utils/backgroundHousekeeping.ts +94 -0
- package/utils/bash/ParsedCommand.ts +318 -0
- package/utils/bash/ShellSnapshot.ts +582 -0
- package/utils/bash/ast.ts +2679 -0
- package/utils/bash/bashParser.ts +4436 -0
- package/utils/bash/bashPipeCommand.ts +294 -0
- package/utils/bash/commands.ts +1339 -0
- package/utils/bash/heredoc.ts +733 -0
- package/utils/bash/parser.ts +230 -0
- package/utils/bash/prefix.ts +204 -0
- package/utils/bash/registry.ts +53 -0
- package/utils/bash/shellCompletion.ts +259 -0
- package/utils/bash/shellPrefix.ts +28 -0
- package/utils/bash/shellQuote.ts +304 -0
- package/utils/bash/shellQuoting.ts +128 -0
- package/utils/bash/specs/alias.ts +14 -0
- package/utils/bash/specs/index.ts +18 -0
- package/utils/bash/specs/nohup.ts +13 -0
- package/utils/bash/specs/pyright.ts +91 -0
- package/utils/bash/specs/sleep.ts +13 -0
- package/utils/bash/specs/srun.ts +31 -0
- package/utils/bash/specs/time.ts +13 -0
- package/utils/bash/specs/timeout.ts +20 -0
- package/utils/bash/treeSitterAnalysis.ts +506 -0
- package/utils/betas.ts +434 -0
- package/utils/billing.ts +78 -0
- package/utils/binaryCheck.ts +53 -0
- package/utils/browser.ts +68 -0
- package/utils/bufferedWriter.ts +100 -0
- package/utils/bundledMode.ts +22 -0
- package/utils/caCerts.ts +115 -0
- package/utils/caCertsConfig.ts +88 -0
- package/utils/cachePaths.ts +38 -0
- package/utils/classifierApprovals.ts +88 -0
- package/utils/classifierApprovalsHook.ts +17 -0
- package/utils/claudeCodeHints.ts +193 -0
- package/utils/claudeDesktop.ts +152 -0
- package/utils/claudeInChrome/chromeNativeHost.ts +527 -0
- package/utils/claudeInChrome/common.ts +540 -0
- package/utils/claudeInChrome/mcpServer.ts +293 -0
- package/utils/claudeInChrome/prompt.ts +83 -0
- package/utils/claudeInChrome/setup.ts +400 -0
- package/utils/claudeInChrome/setupPortable.ts +233 -0
- package/utils/claudeInChrome/toolRendering.tsx +262 -0
- package/utils/claudemd.ts +1479 -0
- package/utils/cleanup.ts +602 -0
- package/utils/cleanupRegistry.ts +25 -0
- package/utils/cliArgs.ts +60 -0
- package/utils/cliHighlight.ts +54 -0
- package/utils/codeIndexing.ts +206 -0
- package/utils/collapseBackgroundBashNotifications.ts +84 -0
- package/utils/collapseHookSummaries.ts +59 -0
- package/utils/collapseReadSearch.ts +1109 -0
- package/utils/collapseTeammateShutdowns.ts +55 -0
- package/utils/combinedAbortSignal.ts +47 -0
- package/utils/commandLifecycle.ts +21 -0
- package/utils/commitAttribution.ts +961 -0
- package/utils/completionCache.ts +166 -0
- package/utils/computerUse/appNames.ts +196 -0
- package/utils/computerUse/cleanup.ts +86 -0
- package/utils/computerUse/common.ts +61 -0
- package/utils/computerUse/computerUseLock.ts +215 -0
- package/utils/computerUse/drainRunLoop.ts +79 -0
- package/utils/computerUse/escHotkey.ts +54 -0
- package/utils/computerUse/executor.ts +658 -0
- package/utils/computerUse/gates.ts +72 -0
- package/utils/computerUse/hostAdapter.ts +69 -0
- package/utils/computerUse/inputLoader.ts +30 -0
- package/utils/computerUse/mcpServer.ts +106 -0
- package/utils/computerUse/setup.ts +53 -0
- package/utils/computerUse/swiftLoader.ts +23 -0
- package/utils/computerUse/toolRendering.tsx +125 -0
- package/utils/computerUse/wrapper.tsx +336 -0
- package/utils/concurrentSessions.ts +204 -0
- package/utils/config.ts +1817 -0
- package/utils/configConstants.ts +21 -0
- package/utils/contentArray.ts +51 -0
- package/utils/context.ts +221 -0
- package/utils/contextAnalysis.ts +272 -0
- package/utils/contextSuggestions.ts +235 -0
- package/utils/controlMessageCompat.ts +32 -0
- package/utils/conversationRecovery.ts +597 -0
- package/utils/cron.ts +308 -0
- package/utils/cronJitterConfig.ts +75 -0
- package/utils/cronScheduler.ts +565 -0
- package/utils/cronTasks.ts +458 -0
- package/utils/cronTasksLock.ts +195 -0
- package/utils/crossProjectResume.ts +75 -0
- package/utils/crypto.ts +13 -0
- package/utils/cwd.ts +32 -0
- package/utils/debug.ts +268 -0
- package/utils/debugFilter.ts +157 -0
- package/utils/deepLink/banner.ts +123 -0
- package/utils/deepLink/parseDeepLink.ts +170 -0
- package/utils/deepLink/protocolHandler.ts +136 -0
- package/utils/deepLink/registerProtocol.ts +348 -0
- package/utils/deepLink/terminalLauncher.ts +557 -0
- package/utils/deepLink/terminalPreference.ts +54 -0
- package/utils/desktopDeepLink.ts +236 -0
- package/utils/detectRepository.ts +178 -0
- package/utils/diagLogs.ts +94 -0
- package/utils/diff.ts +177 -0
- package/utils/directMemberMessage.ts +69 -0
- package/utils/displayTags.ts +51 -0
- package/utils/doctorContextWarnings.ts +265 -0
- package/utils/doctorDiagnostic.ts +625 -0
- package/utils/dxt/helpers.ts +88 -0
- package/utils/dxt/zip.ts +226 -0
- package/utils/earlyInput.ts +191 -0
- package/utils/editor.ts +183 -0
- package/utils/effort.ts +329 -0
- package/utils/embeddedTools.ts +29 -0
- package/utils/env.ts +347 -0
- package/utils/envDynamic.ts +151 -0
- package/utils/envUtils.ts +183 -0
- package/utils/envValidation.ts +38 -0
- package/utils/errorLogSink.ts +235 -0
- package/utils/errors.ts +238 -0
- package/utils/exampleCommands.ts +184 -0
- package/utils/execFileNoThrow.ts +150 -0
- package/utils/execFileNoThrowPortable.ts +89 -0
- package/utils/execSyncWrapper.ts +38 -0
- package/utils/exportRenderer.tsx +98 -0
- package/utils/extraUsage.ts +23 -0
- package/utils/fastMode.ts +532 -0
- package/utils/file.ts +584 -0
- package/utils/fileHistory.ts +1115 -0
- package/utils/fileOperationAnalytics.ts +71 -0
- package/utils/filePersistence/filePersistence.ts +287 -0
- package/utils/filePersistence/outputsScanner.ts +126 -0
- package/utils/filePersistence/types.ts +28 -0
- package/utils/fileRead.ts +102 -0
- package/utils/fileReadCache.ts +96 -0
- package/utils/fileStateCache.ts +142 -0
- package/utils/findExecutable.ts +17 -0
- package/utils/fingerprint.ts +76 -0
- package/utils/forkedAgent.ts +689 -0
- package/utils/format.ts +308 -0
- package/utils/formatBriefTimestamp.ts +81 -0
- package/utils/fpsTracker.ts +47 -0
- package/utils/frontmatterParser.ts +370 -0
- package/utils/fsOperations.ts +770 -0
- package/utils/fullscreen.ts +202 -0
- package/utils/generatedFiles.ts +136 -0
- package/utils/generators.ts +88 -0
- package/utils/genericProcessUtils.ts +184 -0
- package/utils/getWorktreePaths.ts +70 -0
- package/utils/getWorktreePathsPortable.ts +27 -0
- package/utils/ghPrStatus.ts +106 -0
- package/utils/git/gitConfigParser.ts +277 -0
- package/utils/git/gitFilesystem.ts +699 -0
- package/utils/git/gitignore.ts +99 -0
- package/utils/git.ts +926 -0
- package/utils/gitDiff.ts +532 -0
- package/utils/gitSettings.ts +18 -0
- package/utils/github/ghAuthStatus.ts +29 -0
- package/utils/githubRepoPathMapping.ts +162 -0
- package/utils/glob.ts +130 -0
- package/utils/gracefulShutdown.ts +529 -0
- package/utils/groupToolUses.ts +182 -0
- package/utils/handlePromptSubmit.ts +610 -0
- package/utils/hash.ts +46 -0
- package/utils/headlessProfiler.ts +178 -0
- package/utils/heapDumpService.ts +303 -0
- package/utils/heatmap.ts +198 -0
- package/utils/highlightMatch.tsx +28 -0
- package/utils/hooks/AsyncHookRegistry.ts +309 -0
- package/utils/hooks/apiQueryHookHelper.ts +141 -0
- package/utils/hooks/execAgentHook.ts +339 -0
- package/utils/hooks/execHttpHook.ts +242 -0
- package/utils/hooks/execPromptHook.ts +211 -0
- package/utils/hooks/fileChangedWatcher.ts +191 -0
- package/utils/hooks/hookEvents.ts +192 -0
- package/utils/hooks/hookHelpers.ts +83 -0
- package/utils/hooks/hooksConfigManager.ts +400 -0
- package/utils/hooks/hooksConfigSnapshot.ts +133 -0
- package/utils/hooks/hooksSettings.ts +271 -0
- package/utils/hooks/postSamplingHooks.ts +70 -0
- package/utils/hooks/registerFrontmatterHooks.ts +67 -0
- package/utils/hooks/registerSkillHooks.ts +64 -0
- package/utils/hooks/sessionHooks.ts +447 -0
- package/utils/hooks/skillImprovement.ts +267 -0
- package/utils/hooks/ssrfGuard.ts +294 -0
- package/utils/hooks.ts +5022 -0
- package/utils/horizontalScroll.ts +137 -0
- package/utils/http.ts +136 -0
- package/utils/hyperlink.ts +39 -0
- package/utils/iTermBackup.ts +73 -0
- package/utils/ide.ts +1494 -0
- package/utils/idePathConversion.ts +90 -0
- package/utils/idleTimeout.ts +53 -0
- package/utils/imagePaste.ts +416 -0
- package/utils/imageResizer.ts +880 -0
- package/utils/imageStore.ts +167 -0
- package/utils/imageValidation.ts +104 -0
- package/utils/immediateCommand.ts +15 -0
- package/utils/inProcessTeammateHelpers.ts +102 -0
- package/utils/ink.ts +26 -0
- package/utils/intl.ts +94 -0
- package/utils/jetbrains.ts +191 -0
- package/utils/json.ts +277 -0
- package/utils/jsonRead.ts +16 -0
- package/utils/keyboardShortcuts.ts +14 -0
- package/utils/lazySchema.ts +8 -0
- package/utils/listSessionsImpl.ts +454 -0
- package/utils/localInstaller.ts +162 -0
- package/utils/lockfile.ts +43 -0
- package/utils/log.ts +362 -0
- package/utils/logoV2Utils.ts +350 -0
- package/utils/mailbox.ts +73 -0
- package/utils/managedEnv.ts +199 -0
- package/utils/managedEnvConstants.ts +191 -0
- package/utils/markdown.ts +381 -0
- package/utils/markdownConfigLoader.ts +600 -0
- package/utils/mcp/dateTimeParser.ts +121 -0
- package/utils/mcp/elicitationValidation.ts +336 -0
- package/utils/mcpInstructionsDelta.ts +130 -0
- package/utils/mcpOutputStorage.ts +189 -0
- package/utils/mcpValidation.ts +208 -0
- package/utils/mcpWebSocketTransport.ts +200 -0
- package/utils/memoize.ts +269 -0
- package/utils/memory/types.ts +12 -0
- package/utils/memory/versions.ts +8 -0
- package/utils/memoryFileDetection.ts +289 -0
- package/utils/messagePredicates.ts +8 -0
- package/utils/messageQueueManager.ts +547 -0
- package/utils/messages/mappers.ts +290 -0
- package/utils/messages/systemInit.ts +96 -0
- package/utils/messages.ts +5512 -0
- package/utils/model/agent.ts +157 -0
- package/utils/model/aliases.ts +25 -0
- package/utils/model/antModels.ts +64 -0
- package/utils/model/bedrock.ts +265 -0
- package/utils/model/check1mAccess.ts +72 -0
- package/utils/model/configs.ts +118 -0
- package/utils/model/contextWindowUpgradeCheck.ts +47 -0
- package/utils/model/deprecation.ts +101 -0
- package/utils/model/model.ts +618 -0
- package/utils/model/modelAllowlist.ts +170 -0
- package/utils/model/modelCapabilities.ts +118 -0
- package/utils/model/modelOptions.ts +540 -0
- package/utils/model/modelStrings.ts +166 -0
- package/utils/model/modelSupportOverrides.ts +50 -0
- package/utils/model/providers.ts +40 -0
- package/utils/model/validateModel.ts +159 -0
- package/utils/modelCost.ts +231 -0
- package/utils/modifiers.ts +36 -0
- package/utils/mtls.ts +179 -0
- package/utils/nativeInstaller/download.ts +523 -0
- package/utils/nativeInstaller/index.ts +18 -0
- package/utils/nativeInstaller/installer.ts +1708 -0
- package/utils/nativeInstaller/packageManagers.ts +336 -0
- package/utils/nativeInstaller/pidLock.ts +433 -0
- package/utils/notebook.ts +224 -0
- package/utils/objectGroupBy.ts +18 -0
- package/utils/pasteStore.ts +104 -0
- package/utils/path.ts +155 -0
- package/utils/pdf.ts +300 -0
- package/utils/pdfUtils.ts +70 -0
- package/utils/peerAddress.ts +21 -0
- package/utils/permissions/PermissionMode.ts +141 -0
- package/utils/permissions/PermissionPromptToolResultSchema.ts +127 -0
- package/utils/permissions/PermissionResult.ts +35 -0
- package/utils/permissions/PermissionRule.ts +40 -0
- package/utils/permissions/PermissionUpdate.ts +389 -0
- package/utils/permissions/PermissionUpdateSchema.ts +78 -0
- package/utils/permissions/autoModeState.ts +39 -0
- package/utils/permissions/bashClassifier.ts +61 -0
- package/utils/permissions/bypassPermissionsKillswitch.ts +155 -0
- package/utils/permissions/classifierDecision.ts +98 -0
- package/utils/permissions/classifierShared.ts +39 -0
- package/utils/permissions/dangerousPatterns.ts +80 -0
- package/utils/permissions/denialTracking.ts +45 -0
- package/utils/permissions/filesystem.ts +1777 -0
- package/utils/permissions/getNextPermissionMode.ts +101 -0
- package/utils/permissions/pathValidation.ts +485 -0
- package/utils/permissions/permissionExplainer.ts +250 -0
- package/utils/permissions/permissionRuleParser.ts +198 -0
- package/utils/permissions/permissionSetup.ts +1532 -0
- package/utils/permissions/permissions.ts +1486 -0
- package/utils/permissions/permissionsLoader.ts +296 -0
- package/utils/permissions/shadowedRuleDetection.ts +234 -0
- package/utils/permissions/shellRuleMatching.ts +228 -0
- package/utils/permissions/yoloClassifier.ts +1495 -0
- package/utils/planModeV2.ts +95 -0
- package/utils/plans.ts +397 -0
- package/utils/platform.ts +150 -0
- package/utils/plugins/addDirPluginSettings.ts +71 -0
- package/utils/plugins/cacheUtils.ts +196 -0
- package/utils/plugins/dependencyResolver.ts +305 -0
- package/utils/plugins/fetchTelemetry.ts +135 -0
- package/utils/plugins/gitAvailability.ts +69 -0
- package/utils/plugins/headlessPluginInstall.ts +174 -0
- package/utils/plugins/hintRecommendation.ts +164 -0
- package/utils/plugins/installCounts.ts +292 -0
- package/utils/plugins/installedPluginsManager.ts +1268 -0
- package/utils/plugins/loadPluginAgents.ts +348 -0
- package/utils/plugins/loadPluginCommands.ts +946 -0
- package/utils/plugins/loadPluginHooks.ts +287 -0
- package/utils/plugins/loadPluginOutputStyles.ts +178 -0
- package/utils/plugins/lspPluginIntegration.ts +387 -0
- package/utils/plugins/lspRecommendation.ts +374 -0
- package/utils/plugins/managedPlugins.ts +27 -0
- package/utils/plugins/marketplaceHelpers.ts +592 -0
- package/utils/plugins/marketplaceManager.ts +2643 -0
- package/utils/plugins/mcpPluginIntegration.ts +634 -0
- package/utils/plugins/mcpbHandler.ts +968 -0
- package/utils/plugins/officialMarketplace.ts +25 -0
- package/utils/plugins/officialMarketplaceGcs.ts +216 -0
- package/utils/plugins/officialMarketplaceStartupCheck.ts +439 -0
- package/utils/plugins/orphanedPluginFilter.ts +114 -0
- package/utils/plugins/parseMarketplaceInput.ts +162 -0
- package/utils/plugins/performStartupChecks.tsx +70 -0
- package/utils/plugins/pluginAutoupdate.ts +284 -0
- package/utils/plugins/pluginBlocklist.ts +127 -0
- package/utils/plugins/pluginDirectories.ts +178 -0
- package/utils/plugins/pluginFlagging.ts +208 -0
- package/utils/plugins/pluginIdentifier.ts +123 -0
- package/utils/plugins/pluginInstallationHelpers.ts +595 -0
- package/utils/plugins/pluginLoader.ts +3302 -0
- package/utils/plugins/pluginOptionsStorage.ts +400 -0
- package/utils/plugins/pluginPolicy.ts +20 -0
- package/utils/plugins/pluginStartupCheck.ts +341 -0
- package/utils/plugins/pluginVersioning.ts +157 -0
- package/utils/plugins/reconciler.ts +265 -0
- package/utils/plugins/refresh.ts +215 -0
- package/utils/plugins/schemas.ts +1681 -0
- package/utils/plugins/validatePlugin.ts +903 -0
- package/utils/plugins/walkPluginMarkdown.ts +69 -0
- package/utils/plugins/zipCache.ts +406 -0
- package/utils/plugins/zipCacheAdapters.ts +164 -0
- package/utils/powershell/dangerousCmdlets.ts +185 -0
- package/utils/powershell/parser.ts +1804 -0
- package/utils/powershell/staticPrefix.ts +316 -0
- package/utils/preflightChecks.tsx +151 -0
- package/utils/privacyLevel.ts +55 -0
- package/utils/process.ts +68 -0
- package/utils/processUserInput/processBashCommand.tsx +140 -0
- package/utils/processUserInput/processSlashCommand.tsx +922 -0
- package/utils/processUserInput/processTextPrompt.ts +100 -0
- package/utils/processUserInput/processUserInput.ts +605 -0
- package/utils/profilerBase.ts +46 -0
- package/utils/promptCategory.ts +49 -0
- package/utils/promptEditor.ts +188 -0
- package/utils/promptShellExecution.ts +183 -0
- package/utils/proxy.ts +426 -0
- package/utils/queryContext.ts +179 -0
- package/utils/queryHelpers.ts +552 -0
- package/utils/queryProfiler.ts +301 -0
- package/utils/queueProcessor.ts +95 -0
- package/utils/readEditContext.ts +227 -0
- package/utils/readFileInRange.ts +383 -0
- package/utils/releaseNotes.ts +360 -0
- package/utils/renderOptions.ts +77 -0
- package/utils/ripgrep.ts +679 -0
- package/utils/sandbox/sandbox-adapter.ts +987 -0
- package/utils/sandbox/sandbox-ui-utils.ts +12 -0
- package/utils/sanitization.ts +91 -0
- package/utils/screenshotClipboard.ts +121 -0
- package/utils/sdkEventQueue.ts +134 -0
- package/utils/secureStorage/fallbackStorage.ts +70 -0
- package/utils/secureStorage/index.ts +17 -0
- package/utils/secureStorage/keychainPrefetch.ts +116 -0
- package/utils/secureStorage/macOsKeychainHelpers.ts +111 -0
- package/utils/secureStorage/macOsKeychainStorage.ts +231 -0
- package/utils/secureStorage/plainTextStorage.ts +84 -0
- package/utils/semanticBoolean.ts +29 -0
- package/utils/semanticNumber.ts +36 -0
- package/utils/semver.ts +59 -0
- package/utils/sequential.ts +56 -0
- package/utils/sessionActivity.ts +133 -0
- package/utils/sessionEnvVars.ts +22 -0
- package/utils/sessionEnvironment.ts +166 -0
- package/utils/sessionFileAccessHooks.ts +250 -0
- package/utils/sessionIngressAuth.ts +140 -0
- package/utils/sessionRestore.ts +551 -0
- package/utils/sessionStart.ts +232 -0
- package/utils/sessionState.ts +150 -0
- package/utils/sessionStorage.ts +5105 -0
- package/utils/sessionStoragePortable.ts +793 -0
- package/utils/sessionTitle.ts +129 -0
- package/utils/sessionUrl.ts +64 -0
- package/utils/set.ts +53 -0
- package/utils/settings/allErrors.ts +32 -0
- package/utils/settings/applySettingsChange.ts +92 -0
- package/utils/settings/changeDetector.ts +488 -0
- package/utils/settings/constants.ts +202 -0
- package/utils/settings/internalWrites.ts +37 -0
- package/utils/settings/managedPath.ts +34 -0
- package/utils/settings/mdm/constants.ts +81 -0
- package/utils/settings/mdm/rawRead.ts +130 -0
- package/utils/settings/mdm/settings.ts +316 -0
- package/utils/settings/permissionValidation.ts +262 -0
- package/utils/settings/pluginOnlyPolicy.ts +60 -0
- package/utils/settings/schemaOutput.ts +8 -0
- package/utils/settings/settings.ts +1015 -0
- package/utils/settings/settingsCache.ts +80 -0
- package/utils/settings/toolValidationConfig.ts +103 -0
- package/utils/settings/types.ts +1148 -0
- package/utils/settings/validateEditTool.ts +45 -0
- package/utils/settings/validation.ts +265 -0
- package/utils/settings/validationTips.ts +164 -0
- package/utils/shell/bashProvider.ts +255 -0
- package/utils/shell/outputLimits.ts +14 -0
- package/utils/shell/powershellDetection.ts +107 -0
- package/utils/shell/powershellProvider.ts +123 -0
- package/utils/shell/prefix.ts +367 -0
- package/utils/shell/readOnlyCommandValidation.ts +1893 -0
- package/utils/shell/resolveDefaultShell.ts +14 -0
- package/utils/shell/shellProvider.ts +33 -0
- package/utils/shell/shellToolUtils.ts +22 -0
- package/utils/shell/specPrefix.ts +241 -0
- package/utils/shellConfig.ts +167 -0
- package/utils/sideQuery.ts +222 -0
- package/utils/sideQuestion.ts +155 -0
- package/utils/signal.ts +43 -0
- package/utils/sinks.ts +16 -0
- package/utils/skills/skillChangeDetector.ts +311 -0
- package/utils/slashCommandParsing.ts +60 -0
- package/utils/sleep.ts +84 -0
- package/utils/sliceAnsi.ts +91 -0
- package/utils/slowOperations.ts +286 -0
- package/utils/standaloneAgent.ts +23 -0
- package/utils/startupProfiler.ts +194 -0
- package/utils/staticRender.tsx +116 -0
- package/utils/stats.ts +1061 -0
- package/utils/statsCache.ts +434 -0
- package/utils/status.tsx +362 -0
- package/utils/statusNoticeDefinitions.tsx +198 -0
- package/utils/statusNoticeHelpers.ts +20 -0
- package/utils/stream.ts +76 -0
- package/utils/streamJsonStdoutGuard.ts +123 -0
- package/utils/streamlinedTransform.ts +201 -0
- package/utils/stringUtils.ts +235 -0
- package/utils/subprocessEnv.ts +99 -0
- package/utils/suggestions/commandSuggestions.ts +567 -0
- package/utils/suggestions/directoryCompletion.ts +263 -0
- package/utils/suggestions/shellHistoryCompletion.ts +119 -0
- package/utils/suggestions/skillUsageTracking.ts +55 -0
- package/utils/suggestions/slackChannelSuggestions.ts +209 -0
- package/utils/swarm/It2SetupPrompt.tsx +380 -0
- package/utils/swarm/backends/ITermBackend.ts +370 -0
- package/utils/swarm/backends/InProcessBackend.ts +339 -0
- package/utils/swarm/backends/PaneBackendExecutor.ts +354 -0
- package/utils/swarm/backends/TmuxBackend.ts +764 -0
- package/utils/swarm/backends/detection.ts +128 -0
- package/utils/swarm/backends/it2Setup.ts +245 -0
- package/utils/swarm/backends/registry.ts +464 -0
- package/utils/swarm/backends/teammateModeSnapshot.ts +87 -0
- package/utils/swarm/backends/types.ts +311 -0
- package/utils/swarm/constants.ts +33 -0
- package/utils/swarm/inProcessRunner.ts +1552 -0
- package/utils/swarm/leaderPermissionBridge.ts +54 -0
- package/utils/swarm/permissionSync.ts +928 -0
- package/utils/swarm/reconnection.ts +119 -0
- package/utils/swarm/spawnInProcess.ts +328 -0
- package/utils/swarm/spawnUtils.ts +146 -0
- package/utils/swarm/teamHelpers.ts +683 -0
- package/utils/swarm/teammateInit.ts +129 -0
- package/utils/swarm/teammateLayoutManager.ts +107 -0
- package/utils/swarm/teammateModel.ts +10 -0
- package/utils/swarm/teammatePromptAddendum.ts +18 -0
- package/utils/systemDirectories.ts +74 -0
- package/utils/systemPrompt.ts +123 -0
- package/utils/systemPromptType.ts +14 -0
- package/utils/systemTheme.ts +119 -0
- package/utils/taggedId.ts +54 -0
- package/utils/task/TaskOutput.ts +390 -0
- package/utils/task/diskOutput.ts +451 -0
- package/utils/task/framework.ts +308 -0
- package/utils/task/outputFormatting.ts +38 -0
- package/utils/task/sdkProgress.ts +36 -0
- package/utils/tasks.ts +862 -0
- package/utils/teamDiscovery.ts +81 -0
- package/utils/teamMemoryOps.ts +88 -0
- package/utils/teammate.ts +292 -0
- package/utils/teammateContext.ts +96 -0
- package/utils/teammateMailbox.ts +1183 -0
- package/utils/telemetry/betaSessionTracing.ts +491 -0
- package/utils/telemetry/bigqueryExporter.ts +252 -0
- package/utils/telemetry/events.ts +75 -0
- package/utils/telemetry/instrumentation.ts +825 -0
- package/utils/telemetry/logger.ts +26 -0
- package/utils/telemetry/perfettoTracing.ts +1120 -0
- package/utils/telemetry/pluginTelemetry.ts +289 -0
- package/utils/telemetry/sessionTracing.ts +927 -0
- package/utils/telemetry/skillLoadedEvent.ts +39 -0
- package/utils/telemetryAttributes.ts +71 -0
- package/utils/teleport/api.ts +466 -0
- package/utils/teleport/environmentSelection.ts +77 -0
- package/utils/teleport/environments.ts +120 -0
- package/utils/teleport/gitBundle.ts +292 -0
- package/utils/teleport.tsx +1226 -0
- package/utils/tempfile.ts +31 -0
- package/utils/terminal.ts +131 -0
- package/utils/terminalPanel.ts +191 -0
- package/utils/textHighlighting.ts +166 -0
- package/utils/theme.ts +639 -0
- package/utils/thinking.ts +162 -0
- package/utils/timeouts.ts +39 -0
- package/utils/tmuxSocket.ts +427 -0
- package/utils/todo/types.ts +18 -0
- package/utils/tokenBudget.ts +73 -0
- package/utils/tokens.ts +261 -0
- package/utils/toolErrors.ts +132 -0
- package/utils/toolPool.ts +79 -0
- package/utils/toolResultStorage.ts +1040 -0
- package/utils/toolSchemaCache.ts +26 -0
- package/utils/toolSearch.ts +756 -0
- package/utils/transcriptSearch.ts +202 -0
- package/utils/treeify.ts +170 -0
- package/utils/truncate.ts +179 -0
- package/utils/ultraplan/ccrSession.ts +349 -0
- package/utils/ultraplan/keyword.ts +127 -0
- package/utils/unaryLogging.ts +39 -0
- package/utils/undercover.ts +89 -0
- package/utils/user.ts +194 -0
- package/utils/userAgent.ts +10 -0
- package/utils/userConfig.ts +181 -0
- package/utils/userPromptKeywords.ts +27 -0
- package/utils/uuid.ts +27 -0
- package/utils/warningHandler.ts +121 -0
- package/utils/which.ts +82 -0
- package/utils/windowsPaths.ts +173 -0
- package/utils/withResolvers.ts +13 -0
- package/utils/words.ts +800 -0
- package/utils/workloadContext.ts +57 -0
- package/utils/worktree.ts +1519 -0
- package/utils/worktreeModeEnabled.ts +11 -0
- package/utils/xdg.ts +65 -0
- package/utils/xml.ts +16 -0
- package/utils/yaml.ts +15 -0
- package/utils/zodToJsonSchema.ts +23 -0
package/utils/Cursor.ts
ADDED
|
@@ -0,0 +1,1530 @@
|
|
|
1
|
+
import { stringWidth } from '../ink/stringWidth.js'
|
|
2
|
+
import { wrapAnsi } from '../ink/wrapAnsi.js'
|
|
3
|
+
import {
|
|
4
|
+
firstGrapheme,
|
|
5
|
+
getGraphemeSegmenter,
|
|
6
|
+
getWordSegmenter,
|
|
7
|
+
} from './intl.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Kill ring for storing killed (cut) text that can be yanked (pasted) with Ctrl+Y.
|
|
11
|
+
* This is global state that shares one kill ring across all input fields.
|
|
12
|
+
*
|
|
13
|
+
* Consecutive kills accumulate in the kill ring until the user types some
|
|
14
|
+
* other key. Alt+Y cycles through previous kills after a yank.
|
|
15
|
+
*/
|
|
16
|
+
const KILL_RING_MAX_SIZE = 10
|
|
17
|
+
let killRing: string[] = []
|
|
18
|
+
let killRingIndex = 0
|
|
19
|
+
let lastActionWasKill = false
|
|
20
|
+
|
|
21
|
+
// Track yank state for yank-pop (alt-y)
|
|
22
|
+
let lastYankStart = 0
|
|
23
|
+
let lastYankLength = 0
|
|
24
|
+
let lastActionWasYank = false
|
|
25
|
+
|
|
26
|
+
export function pushToKillRing(
|
|
27
|
+
text: string,
|
|
28
|
+
direction: 'prepend' | 'append' = 'append',
|
|
29
|
+
): void {
|
|
30
|
+
if (text.length > 0) {
|
|
31
|
+
if (lastActionWasKill && killRing.length > 0) {
|
|
32
|
+
// Accumulate with the most recent kill
|
|
33
|
+
if (direction === 'prepend') {
|
|
34
|
+
killRing[0] = text + killRing[0]
|
|
35
|
+
} else {
|
|
36
|
+
killRing[0] = killRing[0] + text
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// Add new entry to front of ring
|
|
40
|
+
killRing.unshift(text)
|
|
41
|
+
if (killRing.length > KILL_RING_MAX_SIZE) {
|
|
42
|
+
killRing.pop()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
lastActionWasKill = true
|
|
46
|
+
// Reset yank state when killing new text
|
|
47
|
+
lastActionWasYank = false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getLastKill(): string {
|
|
52
|
+
return killRing[0] ?? ''
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getKillRingItem(index: number): string {
|
|
56
|
+
if (killRing.length === 0) return ''
|
|
57
|
+
const normalizedIndex =
|
|
58
|
+
((index % killRing.length) + killRing.length) % killRing.length
|
|
59
|
+
return killRing[normalizedIndex] ?? ''
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function getKillRingSize(): number {
|
|
63
|
+
return killRing.length
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function clearKillRing(): void {
|
|
67
|
+
killRing = []
|
|
68
|
+
killRingIndex = 0
|
|
69
|
+
lastActionWasKill = false
|
|
70
|
+
lastActionWasYank = false
|
|
71
|
+
lastYankStart = 0
|
|
72
|
+
lastYankLength = 0
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function resetKillAccumulation(): void {
|
|
76
|
+
lastActionWasKill = false
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Yank tracking for yank-pop
|
|
80
|
+
export function recordYank(start: number, length: number): void {
|
|
81
|
+
lastYankStart = start
|
|
82
|
+
lastYankLength = length
|
|
83
|
+
lastActionWasYank = true
|
|
84
|
+
killRingIndex = 0
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function canYankPop(): boolean {
|
|
88
|
+
return lastActionWasYank && killRing.length > 1
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function yankPop(): {
|
|
92
|
+
text: string
|
|
93
|
+
start: number
|
|
94
|
+
length: number
|
|
95
|
+
} | null {
|
|
96
|
+
if (!lastActionWasYank || killRing.length <= 1) {
|
|
97
|
+
return null
|
|
98
|
+
}
|
|
99
|
+
// Cycle to next item in kill ring
|
|
100
|
+
killRingIndex = (killRingIndex + 1) % killRing.length
|
|
101
|
+
const text = killRing[killRingIndex] ?? ''
|
|
102
|
+
return { text, start: lastYankStart, length: lastYankLength }
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function updateYankLength(length: number): void {
|
|
106
|
+
lastYankLength = length
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function resetYankState(): void {
|
|
110
|
+
lastActionWasYank = false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Text Processing Flow for Unicode Normalization:
|
|
115
|
+
*
|
|
116
|
+
* User Input (raw text, potentially mixed NFD/NFC)
|
|
117
|
+
* ↓
|
|
118
|
+
* MeasuredText (normalizes to NFC + builds grapheme info)
|
|
119
|
+
* ↓
|
|
120
|
+
* All cursor operations use normalized text/offsets
|
|
121
|
+
* ↓
|
|
122
|
+
* Display uses normalized text from wrappedLines
|
|
123
|
+
*
|
|
124
|
+
* This flow ensures consistent Unicode handling:
|
|
125
|
+
* - NFD/NFC normalization differences don't break cursor movement
|
|
126
|
+
* - Grapheme clusters (like 👨👩👧👦) are treated as single units
|
|
127
|
+
* - Display width calculations are accurate for CJK characters
|
|
128
|
+
*
|
|
129
|
+
* RULE: Once text enters MeasuredText, all operations
|
|
130
|
+
* work on the normalized version.
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
// Pre-compiled regex patterns for Vim word detection (avoid creating in hot loops)
|
|
134
|
+
export const VIM_WORD_CHAR_REGEX = /^[\p{L}\p{N}\p{M}_]$/u
|
|
135
|
+
export const WHITESPACE_REGEX = /\s/
|
|
136
|
+
|
|
137
|
+
// Exported helper functions for Vim character classification
|
|
138
|
+
export const isVimWordChar = (ch: string): boolean =>
|
|
139
|
+
VIM_WORD_CHAR_REGEX.test(ch)
|
|
140
|
+
export const isVimWhitespace = (ch: string): boolean =>
|
|
141
|
+
WHITESPACE_REGEX.test(ch)
|
|
142
|
+
export const isVimPunctuation = (ch: string): boolean =>
|
|
143
|
+
ch.length > 0 && !isVimWhitespace(ch) && !isVimWordChar(ch)
|
|
144
|
+
|
|
145
|
+
type WrappedText = string[]
|
|
146
|
+
type Position = {
|
|
147
|
+
line: number
|
|
148
|
+
column: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export class Cursor {
|
|
152
|
+
readonly offset: number
|
|
153
|
+
constructor(
|
|
154
|
+
readonly measuredText: MeasuredText,
|
|
155
|
+
offset: number = 0,
|
|
156
|
+
readonly selection: number = 0,
|
|
157
|
+
) {
|
|
158
|
+
// it's ok for the cursor to be 1 char beyond the end of the string
|
|
159
|
+
this.offset = Math.max(0, Math.min(this.text.length, offset))
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static fromText(
|
|
163
|
+
text: string,
|
|
164
|
+
columns: number,
|
|
165
|
+
offset: number = 0,
|
|
166
|
+
selection: number = 0,
|
|
167
|
+
): Cursor {
|
|
168
|
+
// make MeasuredText on less than columns width, to account for cursor
|
|
169
|
+
return new Cursor(new MeasuredText(text, columns - 1), offset, selection)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
getViewportStartLine(maxVisibleLines?: number): number {
|
|
173
|
+
if (maxVisibleLines === undefined || maxVisibleLines <= 0) return 0
|
|
174
|
+
const { line } = this.getPosition()
|
|
175
|
+
const allLines = this.measuredText.getWrappedText()
|
|
176
|
+
if (allLines.length <= maxVisibleLines) return 0
|
|
177
|
+
const half = Math.floor(maxVisibleLines / 2)
|
|
178
|
+
let startLine = Math.max(0, line - half)
|
|
179
|
+
const endLine = Math.min(allLines.length, startLine + maxVisibleLines)
|
|
180
|
+
if (endLine - startLine < maxVisibleLines) {
|
|
181
|
+
startLine = Math.max(0, endLine - maxVisibleLines)
|
|
182
|
+
}
|
|
183
|
+
return startLine
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getViewportCharOffset(maxVisibleLines?: number): number {
|
|
187
|
+
const startLine = this.getViewportStartLine(maxVisibleLines)
|
|
188
|
+
if (startLine === 0) return 0
|
|
189
|
+
const wrappedLines = this.measuredText.getWrappedLines()
|
|
190
|
+
return wrappedLines[startLine]?.startOffset ?? 0
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
getViewportCharEnd(maxVisibleLines?: number): number {
|
|
194
|
+
const startLine = this.getViewportStartLine(maxVisibleLines)
|
|
195
|
+
const allLines = this.measuredText.getWrappedLines()
|
|
196
|
+
if (maxVisibleLines === undefined || maxVisibleLines <= 0)
|
|
197
|
+
return this.text.length
|
|
198
|
+
const endLine = Math.min(allLines.length, startLine + maxVisibleLines)
|
|
199
|
+
if (endLine >= allLines.length) return this.text.length
|
|
200
|
+
return allLines[endLine]?.startOffset ?? this.text.length
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
render(
|
|
204
|
+
cursorChar: string,
|
|
205
|
+
mask: string,
|
|
206
|
+
invert: (text: string) => string,
|
|
207
|
+
ghostText?: { text: string; dim: (text: string) => string },
|
|
208
|
+
maxVisibleLines?: number,
|
|
209
|
+
) {
|
|
210
|
+
const { line, column } = this.getPosition()
|
|
211
|
+
const allLines = this.measuredText.getWrappedText()
|
|
212
|
+
|
|
213
|
+
const startLine = this.getViewportStartLine(maxVisibleLines)
|
|
214
|
+
const endLine =
|
|
215
|
+
maxVisibleLines !== undefined && maxVisibleLines > 0
|
|
216
|
+
? Math.min(allLines.length, startLine + maxVisibleLines)
|
|
217
|
+
: allLines.length
|
|
218
|
+
|
|
219
|
+
return allLines
|
|
220
|
+
.slice(startLine, endLine)
|
|
221
|
+
.map((text, i) => {
|
|
222
|
+
const currentLine = i + startLine
|
|
223
|
+
let displayText = text
|
|
224
|
+
if (mask) {
|
|
225
|
+
const graphemes = Array.from(getGraphemeSegmenter().segment(text))
|
|
226
|
+
if (currentLine === allLines.length - 1) {
|
|
227
|
+
// Last line: mask all but the trailing 6 chars so the user can
|
|
228
|
+
// confirm they pasted the right thing without exposing the full token
|
|
229
|
+
const visibleCount = Math.min(6, graphemes.length)
|
|
230
|
+
const maskCount = graphemes.length - visibleCount
|
|
231
|
+
const splitOffset =
|
|
232
|
+
graphemes.length > visibleCount ? graphemes[maskCount]!.index : 0
|
|
233
|
+
displayText = mask.repeat(maskCount) + text.slice(splitOffset)
|
|
234
|
+
} else {
|
|
235
|
+
// Earlier wrapped lines: fully mask. Previously only the last line
|
|
236
|
+
// was masked, leaking the start of the token on narrow terminals
|
|
237
|
+
// where the pasted OAuth code wraps across multiple lines.
|
|
238
|
+
displayText = mask.repeat(graphemes.length)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// looking for the line with the cursor
|
|
242
|
+
if (line !== currentLine) return displayText.trimEnd()
|
|
243
|
+
|
|
244
|
+
// Split the line into before/at/after cursor in a single pass over the
|
|
245
|
+
// graphemes, accumulating display width until we reach the cursor column.
|
|
246
|
+
// This replaces a two-pass approach (displayWidthToStringIndex + a second
|
|
247
|
+
// segmenter pass) — the intermediate stringIndex from that approach is
|
|
248
|
+
// always a grapheme boundary, so the "cursor in the middle of a
|
|
249
|
+
// multi-codepoint character" branch was unreachable.
|
|
250
|
+
let beforeCursor = ''
|
|
251
|
+
let atCursor = cursorChar
|
|
252
|
+
let afterCursor = ''
|
|
253
|
+
let currentWidth = 0
|
|
254
|
+
let cursorFound = false
|
|
255
|
+
|
|
256
|
+
for (const { segment } of getGraphemeSegmenter().segment(displayText)) {
|
|
257
|
+
if (cursorFound) {
|
|
258
|
+
afterCursor += segment
|
|
259
|
+
continue
|
|
260
|
+
}
|
|
261
|
+
const nextWidth = currentWidth + stringWidth(segment)
|
|
262
|
+
if (nextWidth > column) {
|
|
263
|
+
atCursor = segment
|
|
264
|
+
cursorFound = true
|
|
265
|
+
} else {
|
|
266
|
+
currentWidth = nextWidth
|
|
267
|
+
beforeCursor += segment
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Only invert the cursor if we have a cursor character to show
|
|
272
|
+
// When ghost text is present and cursor is at end, show first ghost char in cursor
|
|
273
|
+
let renderedCursor: string
|
|
274
|
+
let ghostSuffix = ''
|
|
275
|
+
if (
|
|
276
|
+
ghostText &&
|
|
277
|
+
currentLine === allLines.length - 1 &&
|
|
278
|
+
this.isAtEnd() &&
|
|
279
|
+
ghostText.text.length > 0
|
|
280
|
+
) {
|
|
281
|
+
// First ghost character goes in the inverted cursor (grapheme-safe)
|
|
282
|
+
const firstGhostChar =
|
|
283
|
+
firstGrapheme(ghostText.text) || ghostText.text[0]!
|
|
284
|
+
renderedCursor = cursorChar ? invert(firstGhostChar) : firstGhostChar
|
|
285
|
+
// Rest of ghost text is dimmed after cursor
|
|
286
|
+
const ghostRest = ghostText.text.slice(firstGhostChar.length)
|
|
287
|
+
if (ghostRest.length > 0) {
|
|
288
|
+
ghostSuffix = ghostText.dim(ghostRest)
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
renderedCursor = cursorChar ? invert(atCursor) : atCursor
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
beforeCursor + renderedCursor + ghostSuffix + afterCursor.trimEnd()
|
|
296
|
+
)
|
|
297
|
+
})
|
|
298
|
+
.join('\n')
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
left(): Cursor {
|
|
302
|
+
if (this.offset === 0) return this
|
|
303
|
+
|
|
304
|
+
const chip = this.imageRefEndingAt(this.offset)
|
|
305
|
+
if (chip) return new Cursor(this.measuredText, chip.start)
|
|
306
|
+
|
|
307
|
+
const prevOffset = this.measuredText.prevOffset(this.offset)
|
|
308
|
+
return new Cursor(this.measuredText, prevOffset)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
right(): Cursor {
|
|
312
|
+
if (this.offset >= this.text.length) return this
|
|
313
|
+
|
|
314
|
+
const chip = this.imageRefStartingAt(this.offset)
|
|
315
|
+
if (chip) return new Cursor(this.measuredText, chip.end)
|
|
316
|
+
|
|
317
|
+
const nextOffset = this.measuredText.nextOffset(this.offset)
|
|
318
|
+
return new Cursor(this.measuredText, Math.min(nextOffset, this.text.length))
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* If an [Image #N] chip ends at `offset`, return its bounds. Used by left()
|
|
323
|
+
* to hop the cursor over the chip instead of stepping into it.
|
|
324
|
+
*/
|
|
325
|
+
imageRefEndingAt(offset: number): { start: number; end: number } | null {
|
|
326
|
+
const m = this.text.slice(0, offset).match(/\[Image #\d+\]$/)
|
|
327
|
+
return m ? { start: offset - m[0].length, end: offset } : null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
imageRefStartingAt(offset: number): { start: number; end: number } | null {
|
|
331
|
+
const m = this.text.slice(offset).match(/^\[Image #\d+\]/)
|
|
332
|
+
return m ? { start: offset, end: offset + m[0].length } : null
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* If offset lands strictly inside an [Image #N] chip, snap it to the given
|
|
337
|
+
* boundary. Used by word-movement methods so Ctrl+W / Alt+D never leave a
|
|
338
|
+
* partial chip.
|
|
339
|
+
*/
|
|
340
|
+
snapOutOfImageRef(offset: number, toward: 'start' | 'end'): number {
|
|
341
|
+
const re = /\[Image #\d+\]/g
|
|
342
|
+
let m
|
|
343
|
+
while ((m = re.exec(this.text)) !== null) {
|
|
344
|
+
const start = m.index
|
|
345
|
+
const end = start + m[0].length
|
|
346
|
+
if (offset > start && offset < end) {
|
|
347
|
+
return toward === 'start' ? start : end
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return offset
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
up(): Cursor {
|
|
354
|
+
const { line, column } = this.getPosition()
|
|
355
|
+
if (line === 0) {
|
|
356
|
+
return this
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const prevLine = this.measuredText.getWrappedText()[line - 1]
|
|
360
|
+
if (prevLine === undefined) {
|
|
361
|
+
return this
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const prevLineDisplayWidth = stringWidth(prevLine)
|
|
365
|
+
if (column > prevLineDisplayWidth) {
|
|
366
|
+
const newOffset = this.getOffset({
|
|
367
|
+
line: line - 1,
|
|
368
|
+
column: prevLineDisplayWidth,
|
|
369
|
+
})
|
|
370
|
+
return new Cursor(this.measuredText, newOffset, 0)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const newOffset = this.getOffset({ line: line - 1, column })
|
|
374
|
+
return new Cursor(this.measuredText, newOffset, 0)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
down(): Cursor {
|
|
378
|
+
const { line, column } = this.getPosition()
|
|
379
|
+
if (line >= this.measuredText.lineCount - 1) {
|
|
380
|
+
return this
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// If there is no next line, stay on the current line,
|
|
384
|
+
// and let the caller handle it (e.g. for prompt input,
|
|
385
|
+
// we move to the next history entry)
|
|
386
|
+
const nextLine = this.measuredText.getWrappedText()[line + 1]
|
|
387
|
+
if (nextLine === undefined) {
|
|
388
|
+
return this
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// If the current column is past the end of the next line,
|
|
392
|
+
// move to the end of the next line
|
|
393
|
+
const nextLineDisplayWidth = stringWidth(nextLine)
|
|
394
|
+
if (column > nextLineDisplayWidth) {
|
|
395
|
+
const newOffset = this.getOffset({
|
|
396
|
+
line: line + 1,
|
|
397
|
+
column: nextLineDisplayWidth,
|
|
398
|
+
})
|
|
399
|
+
return new Cursor(this.measuredText, newOffset, 0)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Otherwise, move to the same column on the next line
|
|
403
|
+
const newOffset = this.getOffset({
|
|
404
|
+
line: line + 1,
|
|
405
|
+
column,
|
|
406
|
+
})
|
|
407
|
+
return new Cursor(this.measuredText, newOffset, 0)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Move to the start of the current line (column 0).
|
|
412
|
+
* This is the raw version used internally by startOfLine.
|
|
413
|
+
*/
|
|
414
|
+
private startOfCurrentLine(): Cursor {
|
|
415
|
+
const { line } = this.getPosition()
|
|
416
|
+
return new Cursor(
|
|
417
|
+
this.measuredText,
|
|
418
|
+
this.getOffset({
|
|
419
|
+
line,
|
|
420
|
+
column: 0,
|
|
421
|
+
}),
|
|
422
|
+
0,
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
startOfLine(): Cursor {
|
|
427
|
+
const { line, column } = this.getPosition()
|
|
428
|
+
|
|
429
|
+
// If already at start of line and not at first line, move to previous line
|
|
430
|
+
if (column === 0 && line > 0) {
|
|
431
|
+
return new Cursor(
|
|
432
|
+
this.measuredText,
|
|
433
|
+
this.getOffset({
|
|
434
|
+
line: line - 1,
|
|
435
|
+
column: 0,
|
|
436
|
+
}),
|
|
437
|
+
0,
|
|
438
|
+
)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return this.startOfCurrentLine()
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
firstNonBlankInLine(): Cursor {
|
|
445
|
+
const { line } = this.getPosition()
|
|
446
|
+
const lineText = this.measuredText.getWrappedText()[line] || ''
|
|
447
|
+
|
|
448
|
+
const match = lineText.match(/^\s*\S/)
|
|
449
|
+
const column = match?.index ? match.index + match[0].length - 1 : 0
|
|
450
|
+
const offset = this.getOffset({ line, column })
|
|
451
|
+
|
|
452
|
+
return new Cursor(this.measuredText, offset, 0)
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
endOfLine(): Cursor {
|
|
456
|
+
const { line } = this.getPosition()
|
|
457
|
+
const column = this.measuredText.getLineLength(line)
|
|
458
|
+
const offset = this.getOffset({ line, column })
|
|
459
|
+
return new Cursor(this.measuredText, offset, 0)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Helper methods for finding logical line boundaries
|
|
463
|
+
private findLogicalLineStart(fromOffset: number = this.offset): number {
|
|
464
|
+
const prevNewline = this.text.lastIndexOf('\n', fromOffset - 1)
|
|
465
|
+
return prevNewline === -1 ? 0 : prevNewline + 1
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
private findLogicalLineEnd(fromOffset: number = this.offset): number {
|
|
469
|
+
const nextNewline = this.text.indexOf('\n', fromOffset)
|
|
470
|
+
return nextNewline === -1 ? this.text.length : nextNewline
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Helper to get logical line bounds for current position
|
|
474
|
+
private getLogicalLineBounds(): { start: number; end: number } {
|
|
475
|
+
return {
|
|
476
|
+
start: this.findLogicalLineStart(),
|
|
477
|
+
end: this.findLogicalLineEnd(),
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Helper to create cursor with preserved column, clamped to line length
|
|
482
|
+
// Snaps to grapheme boundary to avoid landing mid-grapheme
|
|
483
|
+
private createCursorWithColumn(
|
|
484
|
+
lineStart: number,
|
|
485
|
+
lineEnd: number,
|
|
486
|
+
targetColumn: number,
|
|
487
|
+
): Cursor {
|
|
488
|
+
const lineLength = lineEnd - lineStart
|
|
489
|
+
const clampedColumn = Math.min(targetColumn, lineLength)
|
|
490
|
+
const rawOffset = lineStart + clampedColumn
|
|
491
|
+
const offset = this.measuredText.snapToGraphemeBoundary(rawOffset)
|
|
492
|
+
return new Cursor(this.measuredText, offset, 0)
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
endOfLogicalLine(): Cursor {
|
|
496
|
+
return new Cursor(this.measuredText, this.findLogicalLineEnd(), 0)
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
startOfLogicalLine(): Cursor {
|
|
500
|
+
return new Cursor(this.measuredText, this.findLogicalLineStart(), 0)
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
firstNonBlankInLogicalLine(): Cursor {
|
|
504
|
+
const { start, end } = this.getLogicalLineBounds()
|
|
505
|
+
const lineText = this.text.slice(start, end)
|
|
506
|
+
const match = lineText.match(/\S/)
|
|
507
|
+
const offset = start + (match?.index ?? 0)
|
|
508
|
+
return new Cursor(this.measuredText, offset, 0)
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
upLogicalLine(): Cursor {
|
|
512
|
+
const { start: currentStart } = this.getLogicalLineBounds()
|
|
513
|
+
|
|
514
|
+
// At first line - stay at beginning
|
|
515
|
+
if (currentStart === 0) {
|
|
516
|
+
return new Cursor(this.measuredText, 0, 0)
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Calculate target column position
|
|
520
|
+
const currentColumn = this.offset - currentStart
|
|
521
|
+
|
|
522
|
+
// Find previous line bounds
|
|
523
|
+
const prevLineEnd = currentStart - 1
|
|
524
|
+
const prevLineStart = this.findLogicalLineStart(prevLineEnd)
|
|
525
|
+
|
|
526
|
+
return this.createCursorWithColumn(
|
|
527
|
+
prevLineStart,
|
|
528
|
+
prevLineEnd,
|
|
529
|
+
currentColumn,
|
|
530
|
+
)
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
downLogicalLine(): Cursor {
|
|
534
|
+
const { start: currentStart, end: currentEnd } = this.getLogicalLineBounds()
|
|
535
|
+
|
|
536
|
+
// At last line - stay at end
|
|
537
|
+
if (currentEnd >= this.text.length) {
|
|
538
|
+
return new Cursor(this.measuredText, this.text.length, 0)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Calculate target column position
|
|
542
|
+
const currentColumn = this.offset - currentStart
|
|
543
|
+
|
|
544
|
+
// Find next line bounds
|
|
545
|
+
const nextLineStart = currentEnd + 1
|
|
546
|
+
const nextLineEnd = this.findLogicalLineEnd(nextLineStart)
|
|
547
|
+
|
|
548
|
+
return this.createCursorWithColumn(
|
|
549
|
+
nextLineStart,
|
|
550
|
+
nextLineEnd,
|
|
551
|
+
currentColumn,
|
|
552
|
+
)
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Vim word vs WORD movements:
|
|
556
|
+
// - word (lowercase w/b/e): sequences of letters, digits, and underscores
|
|
557
|
+
// - WORD (uppercase W/B/E): sequences of non-whitespace characters
|
|
558
|
+
// For example, in "hello-world!", word movements see 3 words: "hello", "world", and nothing
|
|
559
|
+
// But WORD movements see 1 WORD: "hello-world!"
|
|
560
|
+
|
|
561
|
+
nextWord(): Cursor {
|
|
562
|
+
if (this.isAtEnd()) {
|
|
563
|
+
return this
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Use Intl.Segmenter for proper word boundary detection (including CJK)
|
|
567
|
+
const wordBoundaries = this.measuredText.getWordBoundaries()
|
|
568
|
+
|
|
569
|
+
// Find the next word start boundary after current position
|
|
570
|
+
for (const boundary of wordBoundaries) {
|
|
571
|
+
if (boundary.isWordLike && boundary.start > this.offset) {
|
|
572
|
+
return new Cursor(this.measuredText, boundary.start)
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// If no next word found, go to end
|
|
577
|
+
return new Cursor(this.measuredText, this.text.length)
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
endOfWord(): Cursor {
|
|
581
|
+
if (this.isAtEnd()) {
|
|
582
|
+
return this
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Use Intl.Segmenter for proper word boundary detection (including CJK)
|
|
586
|
+
const wordBoundaries = this.measuredText.getWordBoundaries()
|
|
587
|
+
|
|
588
|
+
// Find the current word boundary we're in
|
|
589
|
+
for (const boundary of wordBoundaries) {
|
|
590
|
+
if (!boundary.isWordLike) continue
|
|
591
|
+
|
|
592
|
+
// If we're inside this word but NOT at the last character
|
|
593
|
+
if (this.offset >= boundary.start && this.offset < boundary.end - 1) {
|
|
594
|
+
// Move to end of this word (last character position)
|
|
595
|
+
return new Cursor(this.measuredText, boundary.end - 1)
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// If we're at the last character of a word (end - 1), find the next word's end
|
|
599
|
+
if (this.offset === boundary.end - 1) {
|
|
600
|
+
// Find next word
|
|
601
|
+
for (const nextBoundary of wordBoundaries) {
|
|
602
|
+
if (nextBoundary.isWordLike && nextBoundary.start > this.offset) {
|
|
603
|
+
return new Cursor(this.measuredText, nextBoundary.end - 1)
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return this
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// If not in a word, find the next word and go to its end
|
|
611
|
+
for (const boundary of wordBoundaries) {
|
|
612
|
+
if (boundary.isWordLike && boundary.start > this.offset) {
|
|
613
|
+
return new Cursor(this.measuredText, boundary.end - 1)
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
return this
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
prevWord(): Cursor {
|
|
621
|
+
if (this.isAtStart()) {
|
|
622
|
+
return this
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Use Intl.Segmenter for proper word boundary detection (including CJK)
|
|
626
|
+
const wordBoundaries = this.measuredText.getWordBoundaries()
|
|
627
|
+
|
|
628
|
+
// Find the previous word start boundary before current position
|
|
629
|
+
// We need to iterate in reverse to find the previous word
|
|
630
|
+
let prevWordStart: number | null = null
|
|
631
|
+
|
|
632
|
+
for (const boundary of wordBoundaries) {
|
|
633
|
+
if (!boundary.isWordLike) continue
|
|
634
|
+
|
|
635
|
+
// If we're at or after the start of this word, but this word starts before us
|
|
636
|
+
if (boundary.start < this.offset) {
|
|
637
|
+
// If we're inside this word (not at the start), go to its start
|
|
638
|
+
if (this.offset > boundary.start && this.offset <= boundary.end) {
|
|
639
|
+
return new Cursor(this.measuredText, boundary.start)
|
|
640
|
+
}
|
|
641
|
+
// Otherwise, remember this as a candidate for previous word
|
|
642
|
+
prevWordStart = boundary.start
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (prevWordStart !== null) {
|
|
647
|
+
return new Cursor(this.measuredText, prevWordStart)
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return new Cursor(this.measuredText, 0)
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Vim-specific word methods
|
|
654
|
+
// In Vim, a "word" is either:
|
|
655
|
+
// 1. A sequence of word characters (letters, digits, underscore) - including Unicode
|
|
656
|
+
// 2. A sequence of non-blank, non-word characters (punctuation/symbols)
|
|
657
|
+
|
|
658
|
+
nextVimWord(): Cursor {
|
|
659
|
+
if (this.isAtEnd()) {
|
|
660
|
+
return this
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
let pos = this.offset
|
|
664
|
+
const advance = (p: number): number => this.measuredText.nextOffset(p)
|
|
665
|
+
|
|
666
|
+
const currentGrapheme = this.graphemeAt(pos)
|
|
667
|
+
if (!currentGrapheme) {
|
|
668
|
+
return this
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
if (isVimWordChar(currentGrapheme)) {
|
|
672
|
+
while (pos < this.text.length && isVimWordChar(this.graphemeAt(pos))) {
|
|
673
|
+
pos = advance(pos)
|
|
674
|
+
}
|
|
675
|
+
} else if (isVimPunctuation(currentGrapheme)) {
|
|
676
|
+
while (pos < this.text.length && isVimPunctuation(this.graphemeAt(pos))) {
|
|
677
|
+
pos = advance(pos)
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
while (
|
|
682
|
+
pos < this.text.length &&
|
|
683
|
+
WHITESPACE_REGEX.test(this.graphemeAt(pos))
|
|
684
|
+
) {
|
|
685
|
+
pos = advance(pos)
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
return new Cursor(this.measuredText, pos)
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
endOfVimWord(): Cursor {
|
|
692
|
+
if (this.isAtEnd()) {
|
|
693
|
+
return this
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const text = this.text
|
|
697
|
+
let pos = this.offset
|
|
698
|
+
const advance = (p: number): number => this.measuredText.nextOffset(p)
|
|
699
|
+
|
|
700
|
+
if (this.graphemeAt(pos) === '') {
|
|
701
|
+
return this
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
pos = advance(pos)
|
|
705
|
+
|
|
706
|
+
while (pos < text.length && WHITESPACE_REGEX.test(this.graphemeAt(pos))) {
|
|
707
|
+
pos = advance(pos)
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if (pos >= text.length) {
|
|
711
|
+
return new Cursor(this.measuredText, text.length)
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const charAtPos = this.graphemeAt(pos)
|
|
715
|
+
if (isVimWordChar(charAtPos)) {
|
|
716
|
+
while (pos < text.length) {
|
|
717
|
+
const nextPos = advance(pos)
|
|
718
|
+
if (nextPos >= text.length || !isVimWordChar(this.graphemeAt(nextPos)))
|
|
719
|
+
break
|
|
720
|
+
pos = nextPos
|
|
721
|
+
}
|
|
722
|
+
} else if (isVimPunctuation(charAtPos)) {
|
|
723
|
+
while (pos < text.length) {
|
|
724
|
+
const nextPos = advance(pos)
|
|
725
|
+
if (
|
|
726
|
+
nextPos >= text.length ||
|
|
727
|
+
!isVimPunctuation(this.graphemeAt(nextPos))
|
|
728
|
+
)
|
|
729
|
+
break
|
|
730
|
+
pos = nextPos
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return new Cursor(this.measuredText, pos)
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
prevVimWord(): Cursor {
|
|
738
|
+
if (this.isAtStart()) {
|
|
739
|
+
return this
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
let pos = this.offset
|
|
743
|
+
const retreat = (p: number): number => this.measuredText.prevOffset(p)
|
|
744
|
+
|
|
745
|
+
pos = retreat(pos)
|
|
746
|
+
|
|
747
|
+
while (pos > 0 && WHITESPACE_REGEX.test(this.graphemeAt(pos))) {
|
|
748
|
+
pos = retreat(pos)
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// At position 0 with whitespace means no previous word exists, go to start
|
|
752
|
+
if (pos === 0 && WHITESPACE_REGEX.test(this.graphemeAt(0))) {
|
|
753
|
+
return new Cursor(this.measuredText, 0)
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
const charAtPos = this.graphemeAt(pos)
|
|
757
|
+
if (isVimWordChar(charAtPos)) {
|
|
758
|
+
while (pos > 0) {
|
|
759
|
+
const prevPos = retreat(pos)
|
|
760
|
+
if (!isVimWordChar(this.graphemeAt(prevPos))) break
|
|
761
|
+
pos = prevPos
|
|
762
|
+
}
|
|
763
|
+
} else if (isVimPunctuation(charAtPos)) {
|
|
764
|
+
while (pos > 0) {
|
|
765
|
+
const prevPos = retreat(pos)
|
|
766
|
+
if (!isVimPunctuation(this.graphemeAt(prevPos))) break
|
|
767
|
+
pos = prevPos
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
return new Cursor(this.measuredText, pos)
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
nextWORD(): Cursor {
|
|
775
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
776
|
+
let nextCursor: Cursor = this
|
|
777
|
+
// If we're on a non-whitespace character, move to the next whitespace
|
|
778
|
+
while (!nextCursor.isOverWhitespace() && !nextCursor.isAtEnd()) {
|
|
779
|
+
nextCursor = nextCursor.right()
|
|
780
|
+
}
|
|
781
|
+
// now move to the next non-whitespace character
|
|
782
|
+
while (nextCursor.isOverWhitespace() && !nextCursor.isAtEnd()) {
|
|
783
|
+
nextCursor = nextCursor.right()
|
|
784
|
+
}
|
|
785
|
+
return nextCursor
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
endOfWORD(): Cursor {
|
|
789
|
+
if (this.isAtEnd()) {
|
|
790
|
+
return this
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
794
|
+
let cursor: Cursor = this
|
|
795
|
+
|
|
796
|
+
// Check if we're already at the end of a WORD
|
|
797
|
+
// (current character is non-whitespace, but next character is whitespace or we're at the end)
|
|
798
|
+
const atEndOfWORD =
|
|
799
|
+
!cursor.isOverWhitespace() &&
|
|
800
|
+
(cursor.right().isOverWhitespace() || cursor.right().isAtEnd())
|
|
801
|
+
|
|
802
|
+
if (atEndOfWORD) {
|
|
803
|
+
// We're already at the end of a WORD, move to the next WORD
|
|
804
|
+
cursor = cursor.right()
|
|
805
|
+
return cursor.endOfWORD()
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// If we're on a whitespace character, find the next WORD
|
|
809
|
+
if (cursor.isOverWhitespace()) {
|
|
810
|
+
cursor = cursor.nextWORD()
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// Now move to the end of the current WORD
|
|
814
|
+
while (!cursor.right().isOverWhitespace() && !cursor.isAtEnd()) {
|
|
815
|
+
cursor = cursor.right()
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
return cursor
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
prevWORD(): Cursor {
|
|
822
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
823
|
+
let cursor: Cursor = this
|
|
824
|
+
|
|
825
|
+
// if we are already at the beginning of a WORD, step off it
|
|
826
|
+
if (cursor.left().isOverWhitespace()) {
|
|
827
|
+
cursor = cursor.left()
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// Move left over any whitespace characters
|
|
831
|
+
while (cursor.isOverWhitespace() && !cursor.isAtStart()) {
|
|
832
|
+
cursor = cursor.left()
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// If we're over a non-whitespace character, move to the start of this WORD
|
|
836
|
+
if (!cursor.isOverWhitespace()) {
|
|
837
|
+
while (!cursor.left().isOverWhitespace() && !cursor.isAtStart()) {
|
|
838
|
+
cursor = cursor.left()
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
return cursor
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
modifyText(end: Cursor, insertString: string = ''): Cursor {
|
|
846
|
+
const startOffset = this.offset
|
|
847
|
+
const endOffset = end.offset
|
|
848
|
+
|
|
849
|
+
const newText =
|
|
850
|
+
this.text.slice(0, startOffset) +
|
|
851
|
+
insertString +
|
|
852
|
+
this.text.slice(endOffset)
|
|
853
|
+
|
|
854
|
+
return Cursor.fromText(
|
|
855
|
+
newText,
|
|
856
|
+
this.columns,
|
|
857
|
+
startOffset + insertString.normalize('NFC').length,
|
|
858
|
+
)
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
insert(insertString: string): Cursor {
|
|
862
|
+
const newCursor = this.modifyText(this, insertString)
|
|
863
|
+
return newCursor
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
del(): Cursor {
|
|
867
|
+
if (this.isAtEnd()) {
|
|
868
|
+
return this
|
|
869
|
+
}
|
|
870
|
+
return this.modifyText(this.right())
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
backspace(): Cursor {
|
|
874
|
+
if (this.isAtStart()) {
|
|
875
|
+
return this
|
|
876
|
+
}
|
|
877
|
+
return this.left().modifyText(this)
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
deleteToLineStart(): { cursor: Cursor; killed: string } {
|
|
881
|
+
// If cursor is right after a newline (at start of line), delete just that
|
|
882
|
+
// newline — symmetric with deleteToLineEnd's newline handling. This lets
|
|
883
|
+
// repeated ctrl+u clear across lines.
|
|
884
|
+
if (this.offset > 0 && this.text[this.offset - 1] === '\n') {
|
|
885
|
+
return { cursor: this.left().modifyText(this), killed: '\n' }
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Use startOfLine() so that at column 0 of a wrapped visual line,
|
|
889
|
+
// the cursor moves to the previous visual line's start instead of
|
|
890
|
+
// getting stuck.
|
|
891
|
+
const startCursor = this.startOfLine()
|
|
892
|
+
const killed = this.text.slice(startCursor.offset, this.offset)
|
|
893
|
+
return { cursor: startCursor.modifyText(this), killed }
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
deleteToLineEnd(): { cursor: Cursor; killed: string } {
|
|
897
|
+
// If cursor is on a newline character, delete just that character
|
|
898
|
+
if (this.text[this.offset] === '\n') {
|
|
899
|
+
return { cursor: this.modifyText(this.right()), killed: '\n' }
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
const endCursor = this.endOfLine()
|
|
903
|
+
const killed = this.text.slice(this.offset, endCursor.offset)
|
|
904
|
+
return { cursor: this.modifyText(endCursor), killed }
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
deleteToLogicalLineEnd(): Cursor {
|
|
908
|
+
// If cursor is on a newline character, delete just that character
|
|
909
|
+
if (this.text[this.offset] === '\n') {
|
|
910
|
+
return this.modifyText(this.right())
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
return this.modifyText(this.endOfLogicalLine())
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
deleteWordBefore(): { cursor: Cursor; killed: string } {
|
|
917
|
+
if (this.isAtStart()) {
|
|
918
|
+
return { cursor: this, killed: '' }
|
|
919
|
+
}
|
|
920
|
+
const target = this.snapOutOfImageRef(this.prevWord().offset, 'start')
|
|
921
|
+
const prevWordCursor = new Cursor(this.measuredText, target)
|
|
922
|
+
const killed = this.text.slice(prevWordCursor.offset, this.offset)
|
|
923
|
+
return { cursor: prevWordCursor.modifyText(this), killed }
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* Deletes a token before the cursor if one exists.
|
|
928
|
+
* Supports pasted text refs: [Pasted text #1], [Pasted text #1 +10 lines],
|
|
929
|
+
* [...Truncated text #1 +10 lines...]
|
|
930
|
+
*
|
|
931
|
+
* Note: @mentions are NOT tokenized since users may want to correct typos
|
|
932
|
+
* in file paths. Use Ctrl/Cmd+backspace for word-deletion on mentions.
|
|
933
|
+
*
|
|
934
|
+
* Returns null if no token found at cursor position.
|
|
935
|
+
* Only triggers when cursor is at end of token (followed by whitespace or EOL).
|
|
936
|
+
*/
|
|
937
|
+
deleteTokenBefore(): Cursor | null {
|
|
938
|
+
// Cursor at chip.start is the "selected" state — backspace deletes the
|
|
939
|
+
// chip forward, not the char before it.
|
|
940
|
+
const chipAfter = this.imageRefStartingAt(this.offset)
|
|
941
|
+
if (chipAfter) {
|
|
942
|
+
const end =
|
|
943
|
+
this.text[chipAfter.end] === ' ' ? chipAfter.end + 1 : chipAfter.end
|
|
944
|
+
return this.modifyText(new Cursor(this.measuredText, end))
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
if (this.isAtStart()) {
|
|
948
|
+
return null
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// Only trigger if cursor is at a word boundary (whitespace or end of string after cursor)
|
|
952
|
+
const charAfter = this.text[this.offset]
|
|
953
|
+
if (charAfter !== undefined && !/\s/.test(charAfter)) {
|
|
954
|
+
return null
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
const textBefore = this.text.slice(0, this.offset)
|
|
958
|
+
|
|
959
|
+
// Check for pasted/truncated text refs: [Pasted text #1] or [...Truncated text #1 +50 lines...]
|
|
960
|
+
const pasteMatch = textBefore.match(
|
|
961
|
+
/(^|\s)\[(Pasted text #\d+(?: \+\d+ lines)?|Image #\d+|\.\.\.Truncated text #\d+ \+\d+ lines\.\.\.)\]$/,
|
|
962
|
+
)
|
|
963
|
+
if (pasteMatch) {
|
|
964
|
+
const matchStart = pasteMatch.index! + pasteMatch[1]!.length
|
|
965
|
+
return new Cursor(this.measuredText, matchStart).modifyText(this)
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
return null
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
deleteWordAfter(): Cursor {
|
|
972
|
+
if (this.isAtEnd()) {
|
|
973
|
+
return this
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const target = this.snapOutOfImageRef(this.nextWord().offset, 'end')
|
|
977
|
+
return this.modifyText(new Cursor(this.measuredText, target))
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
private graphemeAt(pos: number): string {
|
|
981
|
+
if (pos >= this.text.length) return ''
|
|
982
|
+
const nextOff = this.measuredText.nextOffset(pos)
|
|
983
|
+
return this.text.slice(pos, nextOff)
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
private isOverWhitespace(): boolean {
|
|
987
|
+
const currentChar = this.text[this.offset] ?? ''
|
|
988
|
+
return /\s/.test(currentChar)
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
equals(other: Cursor): boolean {
|
|
992
|
+
return (
|
|
993
|
+
this.offset === other.offset && this.measuredText === other.measuredText
|
|
994
|
+
)
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
isAtStart(): boolean {
|
|
998
|
+
return this.offset === 0
|
|
999
|
+
}
|
|
1000
|
+
isAtEnd(): boolean {
|
|
1001
|
+
return this.offset >= this.text.length
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
startOfFirstLine(): Cursor {
|
|
1005
|
+
// Go to the very beginning of the text (first character of first line)
|
|
1006
|
+
return new Cursor(this.measuredText, 0, 0)
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
startOfLastLine(): Cursor {
|
|
1010
|
+
// Go to the beginning of the last line
|
|
1011
|
+
const lastNewlineIndex = this.text.lastIndexOf('\n')
|
|
1012
|
+
|
|
1013
|
+
if (lastNewlineIndex === -1) {
|
|
1014
|
+
// If there are no newlines, the text is a single line
|
|
1015
|
+
return this.startOfLine()
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// Position after the last newline character
|
|
1019
|
+
return new Cursor(this.measuredText, lastNewlineIndex + 1, 0)
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
goToLine(lineNumber: number): Cursor {
|
|
1023
|
+
// Go to the beginning of the specified logical line (1-indexed, like vim)
|
|
1024
|
+
// Uses logical lines (separated by \n), not wrapped display lines
|
|
1025
|
+
const lines = this.text.split('\n')
|
|
1026
|
+
const targetLine = Math.min(Math.max(0, lineNumber - 1), lines.length - 1)
|
|
1027
|
+
let offset = 0
|
|
1028
|
+
for (let i = 0; i < targetLine; i++) {
|
|
1029
|
+
offset += (lines[i]?.length ?? 0) + 1 // +1 for newline
|
|
1030
|
+
}
|
|
1031
|
+
return new Cursor(this.measuredText, offset, 0)
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
endOfFile(): Cursor {
|
|
1035
|
+
return new Cursor(this.measuredText, this.text.length, 0)
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
public get text(): string {
|
|
1039
|
+
return this.measuredText.text
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
private get columns(): number {
|
|
1043
|
+
return this.measuredText.columns + 1
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
getPosition(): Position {
|
|
1047
|
+
return this.measuredText.getPositionFromOffset(this.offset)
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
private getOffset(position: Position): number {
|
|
1051
|
+
return this.measuredText.getOffsetFromPosition(position)
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Find a character using vim f/F/t/T semantics.
|
|
1056
|
+
*
|
|
1057
|
+
* @param char - The character to find
|
|
1058
|
+
* @param type - 'f' (forward to), 'F' (backward to), 't' (forward till), 'T' (backward till)
|
|
1059
|
+
* @param count - Find the Nth occurrence
|
|
1060
|
+
* @returns The target offset, or null if not found
|
|
1061
|
+
*/
|
|
1062
|
+
findCharacter(
|
|
1063
|
+
char: string,
|
|
1064
|
+
type: 'f' | 'F' | 't' | 'T',
|
|
1065
|
+
count: number = 1,
|
|
1066
|
+
): number | null {
|
|
1067
|
+
const text = this.text
|
|
1068
|
+
const forward = type === 'f' || type === 't'
|
|
1069
|
+
const till = type === 't' || type === 'T'
|
|
1070
|
+
let found = 0
|
|
1071
|
+
|
|
1072
|
+
if (forward) {
|
|
1073
|
+
let pos = this.measuredText.nextOffset(this.offset)
|
|
1074
|
+
while (pos < text.length) {
|
|
1075
|
+
const grapheme = this.graphemeAt(pos)
|
|
1076
|
+
if (grapheme === char) {
|
|
1077
|
+
found++
|
|
1078
|
+
if (found === count) {
|
|
1079
|
+
return till
|
|
1080
|
+
? Math.max(this.offset, this.measuredText.prevOffset(pos))
|
|
1081
|
+
: pos
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
pos = this.measuredText.nextOffset(pos)
|
|
1085
|
+
}
|
|
1086
|
+
} else {
|
|
1087
|
+
if (this.offset === 0) return null
|
|
1088
|
+
let pos = this.measuredText.prevOffset(this.offset)
|
|
1089
|
+
while (pos >= 0) {
|
|
1090
|
+
const grapheme = this.graphemeAt(pos)
|
|
1091
|
+
if (grapheme === char) {
|
|
1092
|
+
found++
|
|
1093
|
+
if (found === count) {
|
|
1094
|
+
return till
|
|
1095
|
+
? Math.min(this.offset, this.measuredText.nextOffset(pos))
|
|
1096
|
+
: pos
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
if (pos === 0) break
|
|
1100
|
+
pos = this.measuredText.prevOffset(pos)
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
return null
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
class WrappedLine {
|
|
1109
|
+
constructor(
|
|
1110
|
+
public readonly text: string,
|
|
1111
|
+
public readonly startOffset: number,
|
|
1112
|
+
public readonly isPrecededByNewline: boolean,
|
|
1113
|
+
public readonly endsWithNewline: boolean = false,
|
|
1114
|
+
) {}
|
|
1115
|
+
|
|
1116
|
+
equals(other: WrappedLine): boolean {
|
|
1117
|
+
return this.text === other.text && this.startOffset === other.startOffset
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
get length(): number {
|
|
1121
|
+
return this.text.length + (this.endsWithNewline ? 1 : 0)
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
export class MeasuredText {
|
|
1126
|
+
private _wrappedLines?: WrappedLine[]
|
|
1127
|
+
public readonly text: string
|
|
1128
|
+
private navigationCache: Map<string, number>
|
|
1129
|
+
private graphemeBoundaries?: number[]
|
|
1130
|
+
|
|
1131
|
+
constructor(
|
|
1132
|
+
text: string,
|
|
1133
|
+
readonly columns: number,
|
|
1134
|
+
) {
|
|
1135
|
+
this.text = text.normalize('NFC')
|
|
1136
|
+
this.navigationCache = new Map()
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/**
|
|
1140
|
+
* Lazily computes and caches wrapped lines.
|
|
1141
|
+
* This expensive operation is deferred until actually needed.
|
|
1142
|
+
*/
|
|
1143
|
+
private get wrappedLines(): WrappedLine[] {
|
|
1144
|
+
if (!this._wrappedLines) {
|
|
1145
|
+
this._wrappedLines = this.measureWrappedText()
|
|
1146
|
+
}
|
|
1147
|
+
return this._wrappedLines
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
private getGraphemeBoundaries(): number[] {
|
|
1151
|
+
if (!this.graphemeBoundaries) {
|
|
1152
|
+
this.graphemeBoundaries = []
|
|
1153
|
+
for (const { index } of getGraphemeSegmenter().segment(this.text)) {
|
|
1154
|
+
this.graphemeBoundaries.push(index)
|
|
1155
|
+
}
|
|
1156
|
+
// Add the end of text as a boundary
|
|
1157
|
+
this.graphemeBoundaries.push(this.text.length)
|
|
1158
|
+
}
|
|
1159
|
+
return this.graphemeBoundaries
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
private wordBoundariesCache?: Array<{
|
|
1163
|
+
start: number
|
|
1164
|
+
end: number
|
|
1165
|
+
isWordLike: boolean
|
|
1166
|
+
}>
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* Get word boundaries using Intl.Segmenter for proper Unicode word segmentation.
|
|
1170
|
+
* This correctly handles CJK (Chinese, Japanese, Korean) text where each character
|
|
1171
|
+
* is typically its own word, as well as scripts that use spaces between words.
|
|
1172
|
+
*/
|
|
1173
|
+
public getWordBoundaries(): Array<{
|
|
1174
|
+
start: number
|
|
1175
|
+
end: number
|
|
1176
|
+
isWordLike: boolean
|
|
1177
|
+
}> {
|
|
1178
|
+
if (!this.wordBoundariesCache) {
|
|
1179
|
+
this.wordBoundariesCache = []
|
|
1180
|
+
for (const segment of getWordSegmenter().segment(this.text)) {
|
|
1181
|
+
this.wordBoundariesCache.push({
|
|
1182
|
+
start: segment.index,
|
|
1183
|
+
end: segment.index + segment.segment.length,
|
|
1184
|
+
isWordLike: segment.isWordLike ?? false,
|
|
1185
|
+
})
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
return this.wordBoundariesCache
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Binary search for boundaries.
|
|
1193
|
+
* @param boundaries: Sorted array of boundaries
|
|
1194
|
+
* @param target: Target offset
|
|
1195
|
+
* @param findNext: If true, finds first boundary > target. If false, finds last boundary < target.
|
|
1196
|
+
* @returns The found boundary index, or appropriate default
|
|
1197
|
+
*/
|
|
1198
|
+
private binarySearchBoundary(
|
|
1199
|
+
boundaries: number[],
|
|
1200
|
+
target: number,
|
|
1201
|
+
findNext: boolean,
|
|
1202
|
+
): number {
|
|
1203
|
+
let left = 0
|
|
1204
|
+
let right = boundaries.length - 1
|
|
1205
|
+
let result = findNext ? this.text.length : 0
|
|
1206
|
+
|
|
1207
|
+
while (left <= right) {
|
|
1208
|
+
const mid = Math.floor((left + right) / 2)
|
|
1209
|
+
const boundary = boundaries[mid]
|
|
1210
|
+
if (boundary === undefined) break
|
|
1211
|
+
|
|
1212
|
+
if (findNext) {
|
|
1213
|
+
if (boundary > target) {
|
|
1214
|
+
result = boundary
|
|
1215
|
+
right = mid - 1
|
|
1216
|
+
} else {
|
|
1217
|
+
left = mid + 1
|
|
1218
|
+
}
|
|
1219
|
+
} else {
|
|
1220
|
+
if (boundary < target) {
|
|
1221
|
+
result = boundary
|
|
1222
|
+
left = mid + 1
|
|
1223
|
+
} else {
|
|
1224
|
+
right = mid - 1
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
return result
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// Convert string index to display width
|
|
1233
|
+
public stringIndexToDisplayWidth(text: string, index: number): number {
|
|
1234
|
+
if (index <= 0) return 0
|
|
1235
|
+
if (index >= text.length) return stringWidth(text)
|
|
1236
|
+
return stringWidth(text.substring(0, index))
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
// Convert display width to string index
|
|
1240
|
+
public displayWidthToStringIndex(text: string, targetWidth: number): number {
|
|
1241
|
+
if (targetWidth <= 0) return 0
|
|
1242
|
+
if (!text) return 0
|
|
1243
|
+
|
|
1244
|
+
// If the text matches our text, use the precomputed graphemes
|
|
1245
|
+
if (text === this.text) {
|
|
1246
|
+
return this.offsetAtDisplayWidth(targetWidth)
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// Otherwise compute on the fly
|
|
1250
|
+
let currentWidth = 0
|
|
1251
|
+
let currentOffset = 0
|
|
1252
|
+
|
|
1253
|
+
for (const { segment, index } of getGraphemeSegmenter().segment(text)) {
|
|
1254
|
+
const segmentWidth = stringWidth(segment)
|
|
1255
|
+
|
|
1256
|
+
if (currentWidth + segmentWidth > targetWidth) {
|
|
1257
|
+
break
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
currentWidth += segmentWidth
|
|
1261
|
+
currentOffset = index + segment.length
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
return currentOffset
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* Find the string offset that corresponds to a target display width.
|
|
1269
|
+
*/
|
|
1270
|
+
private offsetAtDisplayWidth(targetWidth: number): number {
|
|
1271
|
+
if (targetWidth <= 0) return 0
|
|
1272
|
+
|
|
1273
|
+
let currentWidth = 0
|
|
1274
|
+
const boundaries = this.getGraphemeBoundaries()
|
|
1275
|
+
|
|
1276
|
+
// Iterate through grapheme boundaries
|
|
1277
|
+
for (let i = 0; i < boundaries.length - 1; i++) {
|
|
1278
|
+
const start = boundaries[i]
|
|
1279
|
+
const end = boundaries[i + 1]
|
|
1280
|
+
if (start === undefined || end === undefined) continue
|
|
1281
|
+
const segment = this.text.substring(start, end)
|
|
1282
|
+
const segmentWidth = stringWidth(segment)
|
|
1283
|
+
|
|
1284
|
+
if (currentWidth + segmentWidth > targetWidth) {
|
|
1285
|
+
return start
|
|
1286
|
+
}
|
|
1287
|
+
currentWidth += segmentWidth
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
return this.text.length
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
private measureWrappedText(): WrappedLine[] {
|
|
1294
|
+
const wrappedText = wrapAnsi(this.text, this.columns, {
|
|
1295
|
+
hard: true,
|
|
1296
|
+
trim: false,
|
|
1297
|
+
})
|
|
1298
|
+
|
|
1299
|
+
const wrappedLines: WrappedLine[] = []
|
|
1300
|
+
let searchOffset = 0
|
|
1301
|
+
let lastNewLinePos = -1
|
|
1302
|
+
|
|
1303
|
+
const lines = wrappedText.split('\n')
|
|
1304
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1305
|
+
const text = lines[i]!
|
|
1306
|
+
const isPrecededByNewline = (startOffset: number) =>
|
|
1307
|
+
i === 0 || (startOffset > 0 && this.text[startOffset - 1] === '\n')
|
|
1308
|
+
|
|
1309
|
+
if (text.length === 0) {
|
|
1310
|
+
// For blank lines, find the next newline character after the last one
|
|
1311
|
+
lastNewLinePos = this.text.indexOf('\n', lastNewLinePos + 1)
|
|
1312
|
+
|
|
1313
|
+
if (lastNewLinePos !== -1) {
|
|
1314
|
+
const startOffset = lastNewLinePos
|
|
1315
|
+
const endsWithNewline = true
|
|
1316
|
+
|
|
1317
|
+
wrappedLines.push(
|
|
1318
|
+
new WrappedLine(
|
|
1319
|
+
text,
|
|
1320
|
+
startOffset,
|
|
1321
|
+
isPrecededByNewline(startOffset),
|
|
1322
|
+
endsWithNewline,
|
|
1323
|
+
),
|
|
1324
|
+
)
|
|
1325
|
+
} else {
|
|
1326
|
+
// If we can't find another newline, this must be the end of text
|
|
1327
|
+
const startOffset = this.text.length
|
|
1328
|
+
wrappedLines.push(
|
|
1329
|
+
new WrappedLine(
|
|
1330
|
+
text,
|
|
1331
|
+
startOffset,
|
|
1332
|
+
isPrecededByNewline(startOffset),
|
|
1333
|
+
false,
|
|
1334
|
+
),
|
|
1335
|
+
)
|
|
1336
|
+
}
|
|
1337
|
+
} else {
|
|
1338
|
+
// For non-blank lines, find the text in this.text
|
|
1339
|
+
const startOffset = this.text.indexOf(text, searchOffset)
|
|
1340
|
+
|
|
1341
|
+
if (startOffset === -1) {
|
|
1342
|
+
throw new Error('Failed to find wrapped line in text')
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
searchOffset = startOffset + text.length
|
|
1346
|
+
|
|
1347
|
+
// Check if this line ends with a newline in this.text
|
|
1348
|
+
const potentialNewlinePos = startOffset + text.length
|
|
1349
|
+
const endsWithNewline =
|
|
1350
|
+
potentialNewlinePos < this.text.length &&
|
|
1351
|
+
this.text[potentialNewlinePos] === '\n'
|
|
1352
|
+
|
|
1353
|
+
if (endsWithNewline) {
|
|
1354
|
+
lastNewLinePos = potentialNewlinePos
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
wrappedLines.push(
|
|
1358
|
+
new WrappedLine(
|
|
1359
|
+
text,
|
|
1360
|
+
startOffset,
|
|
1361
|
+
isPrecededByNewline(startOffset),
|
|
1362
|
+
endsWithNewline,
|
|
1363
|
+
),
|
|
1364
|
+
)
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
return wrappedLines
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
public getWrappedText(): WrappedText {
|
|
1372
|
+
return this.wrappedLines.map(line =>
|
|
1373
|
+
line.isPrecededByNewline ? line.text : line.text.trimStart(),
|
|
1374
|
+
)
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
public getWrappedLines(): WrappedLine[] {
|
|
1378
|
+
return this.wrappedLines
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
private getLine(line: number): WrappedLine {
|
|
1382
|
+
const lines = this.wrappedLines
|
|
1383
|
+
return lines[Math.max(0, Math.min(line, lines.length - 1))]!
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
public getOffsetFromPosition(position: Position): number {
|
|
1387
|
+
const wrappedLine = this.getLine(position.line)
|
|
1388
|
+
|
|
1389
|
+
// Handle blank lines specially
|
|
1390
|
+
if (wrappedLine.text.length === 0 && wrappedLine.endsWithNewline) {
|
|
1391
|
+
return wrappedLine.startOffset
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// Account for leading whitespace
|
|
1395
|
+
const leadingWhitespace = wrappedLine.isPrecededByNewline
|
|
1396
|
+
? 0
|
|
1397
|
+
: wrappedLine.text.length - wrappedLine.text.trimStart().length
|
|
1398
|
+
|
|
1399
|
+
// Convert display column to string index
|
|
1400
|
+
const displayColumnWithLeading = position.column + leadingWhitespace
|
|
1401
|
+
const stringIndex = this.displayWidthToStringIndex(
|
|
1402
|
+
wrappedLine.text,
|
|
1403
|
+
displayColumnWithLeading,
|
|
1404
|
+
)
|
|
1405
|
+
|
|
1406
|
+
// Calculate the actual offset
|
|
1407
|
+
const offset = wrappedLine.startOffset + stringIndex
|
|
1408
|
+
|
|
1409
|
+
// For normal lines
|
|
1410
|
+
const lineEnd = wrappedLine.startOffset + wrappedLine.text.length
|
|
1411
|
+
|
|
1412
|
+
// Don't allow going past the end of the current line into the next line
|
|
1413
|
+
// unless we're at the very end of the text
|
|
1414
|
+
let maxOffset = lineEnd
|
|
1415
|
+
const lineDisplayWidth = stringWidth(wrappedLine.text)
|
|
1416
|
+
if (wrappedLine.endsWithNewline && position.column > lineDisplayWidth) {
|
|
1417
|
+
// Allow positioning after the newline
|
|
1418
|
+
maxOffset = lineEnd + 1
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
return Math.min(offset, maxOffset)
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
public getLineLength(line: number): number {
|
|
1425
|
+
const wrappedLine = this.getLine(line)
|
|
1426
|
+
return stringWidth(wrappedLine.text)
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
public getPositionFromOffset(offset: number): Position {
|
|
1430
|
+
const lines = this.wrappedLines
|
|
1431
|
+
for (let line = 0; line < lines.length; line++) {
|
|
1432
|
+
const currentLine = lines[line]!
|
|
1433
|
+
const nextLine = lines[line + 1]
|
|
1434
|
+
if (
|
|
1435
|
+
offset >= currentLine.startOffset &&
|
|
1436
|
+
(!nextLine || offset < nextLine.startOffset)
|
|
1437
|
+
) {
|
|
1438
|
+
// Calculate string position within the line
|
|
1439
|
+
const stringPosInLine = offset - currentLine.startOffset
|
|
1440
|
+
|
|
1441
|
+
// Handle leading whitespace for wrapped lines
|
|
1442
|
+
let displayColumn: number
|
|
1443
|
+
if (currentLine.isPrecededByNewline) {
|
|
1444
|
+
// For lines preceded by newline, calculate display width directly
|
|
1445
|
+
displayColumn = this.stringIndexToDisplayWidth(
|
|
1446
|
+
currentLine.text,
|
|
1447
|
+
stringPosInLine,
|
|
1448
|
+
)
|
|
1449
|
+
} else {
|
|
1450
|
+
// For wrapped lines, we need to account for trimmed whitespace
|
|
1451
|
+
const leadingWhitespace =
|
|
1452
|
+
currentLine.text.length - currentLine.text.trimStart().length
|
|
1453
|
+
if (stringPosInLine < leadingWhitespace) {
|
|
1454
|
+
// Cursor is in the trimmed whitespace area, position at start
|
|
1455
|
+
displayColumn = 0
|
|
1456
|
+
} else {
|
|
1457
|
+
// Calculate display width from the trimmed text
|
|
1458
|
+
const trimmedText = currentLine.text.trimStart()
|
|
1459
|
+
const posInTrimmed = stringPosInLine - leadingWhitespace
|
|
1460
|
+
displayColumn = this.stringIndexToDisplayWidth(
|
|
1461
|
+
trimmedText,
|
|
1462
|
+
posInTrimmed,
|
|
1463
|
+
)
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
return {
|
|
1468
|
+
line,
|
|
1469
|
+
column: Math.max(0, displayColumn),
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// If we're past the last character, return the end of the last line
|
|
1475
|
+
const line = lines.length - 1
|
|
1476
|
+
const lastLine = this.wrappedLines[line]!
|
|
1477
|
+
return {
|
|
1478
|
+
line,
|
|
1479
|
+
column: stringWidth(lastLine.text),
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
public get lineCount(): number {
|
|
1484
|
+
return this.wrappedLines.length
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
private withCache<T>(key: string, compute: () => T): T {
|
|
1488
|
+
const cached = this.navigationCache.get(key)
|
|
1489
|
+
if (cached !== undefined) return cached as T
|
|
1490
|
+
|
|
1491
|
+
const result = compute()
|
|
1492
|
+
this.navigationCache.set(key, result as number)
|
|
1493
|
+
return result
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
nextOffset(offset: number): number {
|
|
1497
|
+
return this.withCache(`next:${offset}`, () => {
|
|
1498
|
+
const boundaries = this.getGraphemeBoundaries()
|
|
1499
|
+
return this.binarySearchBoundary(boundaries, offset, true)
|
|
1500
|
+
})
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
prevOffset(offset: number): number {
|
|
1504
|
+
if (offset <= 0) return 0
|
|
1505
|
+
|
|
1506
|
+
return this.withCache(`prev:${offset}`, () => {
|
|
1507
|
+
const boundaries = this.getGraphemeBoundaries()
|
|
1508
|
+
return this.binarySearchBoundary(boundaries, offset, false)
|
|
1509
|
+
})
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* Snap an arbitrary code-unit offset to the start of the containing grapheme.
|
|
1514
|
+
* If offset is already on a boundary, returns it unchanged.
|
|
1515
|
+
*/
|
|
1516
|
+
snapToGraphemeBoundary(offset: number): number {
|
|
1517
|
+
if (offset <= 0) return 0
|
|
1518
|
+
if (offset >= this.text.length) return this.text.length
|
|
1519
|
+
const boundaries = this.getGraphemeBoundaries()
|
|
1520
|
+
// Binary search for largest boundary <= offset
|
|
1521
|
+
let lo = 0
|
|
1522
|
+
let hi = boundaries.length - 1
|
|
1523
|
+
while (lo < hi) {
|
|
1524
|
+
const mid = (lo + hi + 1) >> 1
|
|
1525
|
+
if (boundaries[mid]! <= offset) lo = mid
|
|
1526
|
+
else hi = mid - 1
|
|
1527
|
+
}
|
|
1528
|
+
return boundaries[lo]!
|
|
1529
|
+
}
|
|
1530
|
+
}
|