@aria-cli/cli 1.0.50 → 1.0.51
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/bin/aria.mjs +1 -1
- package/dist/.tsbuildinfo +1 -0
- package/dist/attached-local-control-client.js +826 -0
- package/dist/bootstrap-local-control-client.js +2 -0
- package/dist/capability-aware-method-proxy.js +42 -0
- package/dist/cli-context.js +160 -0
- package/dist/commands/arions.js +174 -0
- package/dist/commands/auth.js +123 -0
- package/dist/commands/daemon.js +245 -0
- package/dist/commands/definitions.js +176 -0
- package/dist/commands/index.js +74 -0
- package/dist/commands/login-handler.js +1108 -0
- package/dist/commands/logout-handler.js +92 -0
- package/dist/commands/memory-handlers.js +89 -0
- package/dist/commands/pairing.js +60 -0
- package/dist/commands/runtime-cutover-reset-command.js +12 -0
- package/dist/commands/runtime-cutover-reset.js +265 -0
- package/dist/commands/terminal-setup.js +84 -0
- package/dist/config/aria-config.js +238 -0
- package/dist/config/index.js +3 -0
- package/dist/config/loader.js +97 -0
- package/dist/config.js +142 -0
- package/dist/daemon-info.js +10 -0
- package/dist/ensure-daemon.js +128 -0
- package/dist/entrypoints/command-mode.js +5 -0
- package/dist/entrypoints/daemon.js +50 -0
- package/dist/entrypoints/headless-stdio.js +25 -0
- package/dist/entrypoints/interactive.js +80 -0
- package/dist/event-loop-watchdog.js +73 -0
- package/dist/headless/auth-orchestrator.js +508 -0
- package/dist/headless/auth-service.js +43 -0
- package/dist/headless/bootstrap-fast-path.js +112 -0
- package/dist/headless/call-command.js +143 -0
- package/dist/headless/daemon-service.js +318 -0
- package/dist/headless/hook-actions.js +235 -0
- package/dist/headless/hook-service.js +42 -0
- package/dist/headless/kernel-services.js +216 -0
- package/dist/headless/kernel.js +785 -0
- package/dist/headless/operations/arion.js +119 -0
- package/dist/headless/operations/auth.js +45 -0
- package/dist/headless/operations/client.js +31 -0
- package/dist/headless/operations/config.js +69 -0
- package/dist/headless/operations/daemon.js +47 -0
- package/dist/headless/operations/hook.js +56 -0
- package/dist/headless/operations/index.js +11 -0
- package/dist/headless/operations/memory.js +102 -0
- package/dist/headless/operations/message.js +279 -0
- package/dist/headless/operations/model.js +100 -0
- package/dist/headless/operations/peer.js +56 -0
- package/dist/headless/operations/run.js +24 -0
- package/dist/headless/operations/session.js +90 -0
- package/dist/headless/operations/system.js +19 -0
- package/dist/headless/operations/utils.js +35 -0
- package/dist/headless/run-orchestrator.js +703 -0
- package/dist/headless/stdio-server.js +439 -0
- package/dist/history/SessionHistory.js +8 -0
- package/dist/history/SessionHistoryClient.js +186 -0
- package/dist/history/conversation-message.js +112 -0
- package/dist/history/index.js +8 -0
- package/dist/history/jsonl-replay.js +154 -0
- package/dist/history/repair-tool-pairing.js +84 -0
- package/dist/history/stall-phase-bridge.js +11 -0
- package/dist/history/turn-accumulator.js +427 -0
- package/dist/index.js +7 -0
- package/dist/ink-repl.js +4183 -0
- package/dist/local-control-bootstrap.js +26 -0
- package/dist/local-control-client.js +2 -0
- package/dist/local-control-error-reporting.js +34 -0
- package/dist/local-control-http-client.js +362 -0
- package/dist/local-control-lazy-wrapper.js +363 -0
- package/dist/local-control-manager.js +146 -0
- package/dist/main.js +38 -0
- package/dist/network-security.js +62 -0
- package/dist/networking-server.js +38 -0
- package/dist/peer-identity.js +23 -0
- package/dist/polling-subscription.js +34 -0
- package/dist/relaunch.js +588 -0
- package/dist/release-notes.js +35 -0
- package/dist/repl-cleanup.js +47 -0
- package/dist/runtime/configure-bun-sqlite.js +3 -0
- package/dist/runtime/crash-handlers.js +111 -0
- package/dist/runtime/interactive-invocation.js +39 -0
- package/dist/runtime/internal-mode.js +14 -0
- package/dist/runtime/launch-spec.js +64 -0
- package/dist/runtime/owner-lease.js +44 -0
- package/dist/runtime/public-mode.js +20 -0
- package/dist/runtime/run-internal-mode.js +18 -0
- package/dist/runtime/runtime-kind.js +32 -0
- package/dist/runtime/spawn-aria.js +38 -0
- package/dist/selectable-client.js +2 -0
- package/dist/selectable-peer.js +2 -0
- package/dist/session.js +203 -0
- package/dist/slash-commands.js +80 -0
- package/dist/sounds.js +210 -0
- package/dist/ui/App.js +526 -0
- package/dist/ui/components/AnthropicMethodPicker.js +6 -0
- package/dist/ui/components/ArionPrompt.js +15 -0
- package/dist/ui/components/AutocompleteDropdown.js +23 -0
- package/dist/ui/components/AutonomySelector.js +55 -0
- package/dist/ui/components/Banner.js +98 -0
- package/dist/ui/components/ConversationHistory.js +175 -0
- package/dist/ui/components/CopilotDeviceLoginFlow.js +88 -0
- package/dist/ui/components/CopilotSourcePicker.js +50 -0
- package/dist/ui/components/Cost.js +10 -0
- package/dist/ui/components/CustomSelect/option-map.js +30 -0
- package/dist/ui/components/CustomSelect/select-option.js +13 -0
- package/dist/ui/components/CustomSelect/select.js +42 -0
- package/dist/ui/components/CustomSelect/use-select-state.js +179 -0
- package/dist/ui/components/CustomSelect/use-select.js +15 -0
- package/dist/ui/components/ErrorDisplay.js +35 -0
- package/dist/ui/components/FallbackToolUseRejectedMessage.js +7 -0
- package/dist/ui/components/FileEditToolUpdatedMessage.js +57 -0
- package/dist/ui/components/HandoffMarker.js +18 -0
- package/dist/ui/components/HighlightedCode.js +21 -0
- package/dist/ui/components/InputArea.js +187 -0
- package/dist/ui/components/Message.js +25 -0
- package/dist/ui/components/OAuthLoginFlow.js +113 -0
- package/dist/ui/components/OutputTruncation.js +35 -0
- package/dist/ui/components/PermissionPrompt.js +79 -0
- package/dist/ui/components/PipelineTimingPanel.js +15 -0
- package/dist/ui/components/ProviderMethodPicker.js +61 -0
- package/dist/ui/components/ProviderPicker.js +63 -0
- package/dist/ui/components/RenderItemView.js +71 -0
- package/dist/ui/components/Spinner.js +46 -0
- package/dist/ui/components/StatusBar.js +95 -0
- package/dist/ui/components/StreamingIndicator.js +55 -0
- package/dist/ui/components/StructuredDiff.js +168 -0
- package/dist/ui/components/TextInputOverlay.js +43 -0
- package/dist/ui/components/ThinkingBlock.js +82 -0
- package/dist/ui/components/ToolCost.js +17 -0
- package/dist/ui/components/ToolExecution.js +61 -0
- package/dist/ui/components/ToolHeader.js +51 -0
- package/dist/ui/components/ToolRenderLayoutContext.js +14 -0
- package/dist/ui/components/ToolResultWrapper.js +6 -0
- package/dist/ui/components/ToolUseLoader.js +35 -0
- package/dist/ui/components/TraceWaterfall.js +91 -0
- package/dist/ui/components/index.js +33 -0
- package/dist/ui/components/messages/AssistantTextMessage.js +25 -0
- package/dist/ui/components/messages/UserImageMessage.js +12 -0
- package/dist/ui/components/messages/UserTextMessage.js +12 -0
- package/dist/ui/components/overlays/ArionSelector.js +68 -0
- package/dist/ui/components/overlays/ClientSelector.js +62 -0
- package/dist/ui/components/overlays/CommandPalette.js +67 -0
- package/dist/ui/components/overlays/DaemonControl.js +87 -0
- package/dist/ui/components/overlays/InviteShareOverlay.js +15 -0
- package/dist/ui/components/overlays/JoinInviteOverlay.js +32 -0
- package/dist/ui/components/overlays/MemoryBrowser.js +100 -0
- package/dist/ui/components/overlays/MessageSelector.js +123 -0
- package/dist/ui/components/overlays/ModelSelector.js +211 -0
- package/dist/ui/components/overlays/PairRequestOverlay.js +42 -0
- package/dist/ui/components/overlays/PeerSelector.js +84 -0
- package/dist/ui/components/overlays/SessionSelector.js +102 -0
- package/dist/ui/components/overlays/SoundSelector.js +86 -0
- package/dist/ui/components/overlays/ThemeSelector.js +139 -0
- package/dist/ui/components/overlays/index.js +15 -0
- package/dist/ui/components/permissions/BashPermissionRequest/BashPermissionRequest.js +53 -0
- package/dist/ui/components/permissions/FallbackPermissionRequest.js +56 -0
- package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.js +76 -0
- package/dist/ui/components/permissions/FileEditPermissionRequest/FileEditToolDiff.js +18 -0
- package/dist/ui/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.js +64 -0
- package/dist/ui/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.js +26 -0
- package/dist/ui/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +141 -0
- package/dist/ui/components/permissions/PermissionRequest.js +70 -0
- package/dist/ui/components/permissions/PermissionRequestTitle.js +41 -0
- package/dist/ui/components/permissions/hooks.js +10 -0
- package/dist/ui/components/permissions/toolUseOptions.js +68 -0
- package/dist/ui/components/permissions/utils.js +10 -0
- package/dist/ui/components/text-input/Cursor.js +326 -0
- package/dist/ui/components/text-input/TextInput.js +231 -0
- package/dist/ui/components/text-input/imagePaste.js +28 -0
- package/dist/ui/components/text-input/index.js +6 -0
- package/dist/ui/components/text-input/useDoublePress.js +30 -0
- package/dist/ui/components/text-input/useTextInput.js +245 -0
- package/dist/ui/components/tool-types.js +9 -0
- package/dist/ui/constants/figures.js +4 -0
- package/dist/ui/constants/index.js +3 -0
- package/dist/ui/display-mode.js +93 -0
- package/dist/ui/display-policy.js +19 -0
- package/dist/ui/hooks/index.js +6 -0
- package/dist/ui/hooks/useCommandAutocomplete.js +93 -0
- package/dist/ui/hooks/useDoublePress.js +37 -0
- package/dist/ui/hooks/useIndicatorState.js +55 -0
- package/dist/ui/hooks/useInterval.js +23 -0
- package/dist/ui/hooks/useKeyboardShortcuts.js +127 -0
- package/dist/ui/hooks/useTerminalSize.js +55 -0
- package/dist/ui/hooks/useUnifiedMessages.js +117 -0
- package/dist/ui/indicator-state.js +44 -0
- package/dist/ui/markdown/highlight.js +44 -0
- package/dist/ui/markdown/index.js +1460 -0
- package/dist/ui/markdown/tokenizer.js +24 -0
- package/dist/ui/render-item.js +5 -0
- package/dist/ui/screens/REPL.js +119 -0
- package/dist/ui/screens/approval-lifecycle.js +38 -0
- package/dist/ui/status-line.js +72 -0
- package/dist/ui/theme/index.js +51 -0
- package/dist/ui/theme/themes/claude-dark-daltonized.js +51 -0
- package/dist/ui/theme/themes/claude-dark.js +50 -0
- package/dist/ui/theme/themes/claude-light-daltonized.js +51 -0
- package/dist/ui/theme/themes/claude-light.js +50 -0
- package/dist/ui/theme/themes/dark-accessible.js +18 -0
- package/dist/ui/theme/themes/dark.js +49 -0
- package/dist/ui/theme/themes/light-accessible.js +18 -0
- package/dist/ui/theme/themes/light.js +49 -0
- package/dist/ui/theme/types.js +3 -0
- package/dist/ui/theme.js +142 -0
- package/dist/ui/to-render-items.js +145 -0
- package/dist/ui/tools/AgentTool/index.js +30 -0
- package/dist/ui/tools/ArchitectTool/index.js +31 -0
- package/dist/ui/tools/AskUserTool/index.js +46 -0
- package/dist/ui/tools/BashTool/BashToolResultMessage.js +11 -0
- package/dist/ui/tools/BashTool/OutputLine.js +21 -0
- package/dist/ui/tools/BashTool/index.js +91 -0
- package/dist/ui/tools/BrowseTool/index.js +43 -0
- package/dist/ui/tools/BrowserTool/index.js +47 -0
- package/dist/ui/tools/CbmTool/index.js +188 -0
- package/dist/ui/tools/CheckDelegationTool/index.js +46 -0
- package/dist/ui/tools/CheckMessagesTool/index.js +85 -0
- package/dist/ui/tools/CreateQuipTool/index.js +30 -0
- package/dist/ui/tools/CreateSkillTool/index.js +22 -0
- package/dist/ui/tools/CreateToolTool/index.js +31 -0
- package/dist/ui/tools/DelegateRemoteTool/index.js +42 -0
- package/dist/ui/tools/DeployTool/index.js +47 -0
- package/dist/ui/tools/FffTool/index.js +103 -0
- package/dist/ui/tools/FileEditTool/index.js +67 -0
- package/dist/ui/tools/FileReadTool/index.js +68 -0
- package/dist/ui/tools/FileWriteTool/index.js +61 -0
- package/dist/ui/tools/ForkTool/index.js +47 -0
- package/dist/ui/tools/FrgTool/index.js +96 -0
- package/dist/ui/tools/GetThreadTool/index.js +39 -0
- package/dist/ui/tools/GlobTool/index.js +50 -0
- package/dist/ui/tools/GrepTool/index.js +84 -0
- package/dist/ui/tools/HatchArionTool/index.js +36 -0
- package/dist/ui/tools/LearnSkillTool/index.js +22 -0
- package/dist/ui/tools/LearnTool/index.js +43 -0
- package/dist/ui/tools/LearnToolTool/index.js +22 -0
- package/dist/ui/tools/ListClientsTool/index.js +39 -0
- package/dist/ui/tools/LspTool/index.js +261 -0
- package/dist/ui/tools/MCPTool/index.js +33 -0
- package/dist/ui/tools/ManageNetworkTool/index.js +53 -0
- package/dist/ui/tools/MemoryReadTool/index.js +64 -0
- package/dist/ui/tools/MemoryWriteTool/index.js +20 -0
- package/dist/ui/tools/NotebookEditTool/index.js +33 -0
- package/dist/ui/tools/NotebookReadTool/index.js +25 -0
- package/dist/ui/tools/OutlookReadTool/index.js +66 -0
- package/dist/ui/tools/OutlookReplyTool/index.js +49 -0
- package/dist/ui/tools/OutlookSendTool/index.js +49 -0
- package/dist/ui/tools/PauseDelegationTool/index.js +35 -0
- package/dist/ui/tools/ProbeTool/index.js +121 -0
- package/dist/ui/tools/ProcessTool/index.js +66 -0
- package/dist/ui/tools/QuestListTool/index.js +46 -0
- package/dist/ui/tools/QuestReportTool/index.js +49 -0
- package/dist/ui/tools/QuestUpdateTool/index.js +87 -0
- package/dist/ui/tools/QuipCommentTool/index.js +69 -0
- package/dist/ui/tools/QuipReadTool/index.js +71 -0
- package/dist/ui/tools/RestArionTool/index.js +32 -0
- package/dist/ui/tools/RestartTool/index.js +35 -0
- package/dist/ui/tools/ResumeDelegationTool/index.js +35 -0
- package/dist/ui/tools/RetireArionTool/index.js +32 -0
- package/dist/ui/tools/RgTool/index.js +73 -0
- package/dist/ui/tools/SearchKnowledgeTool/index.js +43 -0
- package/dist/ui/tools/SearchMessagesTool/index.js +43 -0
- package/dist/ui/tools/SelfDiagnoseTool/index.js +61 -0
- package/dist/ui/tools/SendMessageTool/index.js +45 -0
- package/dist/ui/tools/SerenaTool/index.js +124 -0
- package/dist/ui/tools/SessionHistoryTool/index.js +52 -0
- package/dist/ui/tools/SgTool/index.js +80 -0
- package/dist/ui/tools/SlackReactTool/index.js +41 -0
- package/dist/ui/tools/SlackReadTool/index.js +48 -0
- package/dist/ui/tools/SlackSendTool/index.js +45 -0
- package/dist/ui/tools/SpawnWorkerTool/index.js +33 -0
- package/dist/ui/tools/StickerRequestTool/index.js +19 -0
- package/dist/ui/tools/ThinkTool/index.js +17 -0
- package/dist/ui/tools/UgTool/index.js +108 -0
- package/dist/ui/tools/UseSkillTool/index.js +22 -0
- package/dist/ui/tools/WakeArionTool/index.js +32 -0
- package/dist/ui/tools/WebFetchTool/index.js +56 -0
- package/dist/ui/tools/WebSearchTool/index.js +44 -0
- package/dist/ui/tools/lsTool/index.js +58 -0
- package/dist/ui/tools/registry.js +197 -0
- package/dist/ui/tools/tool-renderer.js +11 -0
- package/dist/ui/tools/truncation.js +35 -0
- package/dist/ui/types/anthropic.js +4 -0
- package/dist/ui/types/index.js +2 -0
- package/dist/ui/types/message.js +3 -0
- package/dist/ui/types/tool.js +4 -0
- package/dist/ui/utils/array.js +4 -0
- package/dist/ui/utils/cursor.js +131 -0
- package/dist/ui/utils/diff.js +120 -0
- package/dist/ui/utils/format.js +42 -0
- package/dist/ui/utils/fuzzy.js +59 -0
- package/dist/ui/utils/index.js +11 -0
- package/dist/ui/utils/keys.js +8 -0
- package/dist/ui/utils/patch.js +17 -0
- package/dist/ui/utils/risk.js +114 -0
- package/dist/ui/utils/terminal-image.js +70 -0
- package/dist/ui/utils/validation.js +48 -0
- package/dist/ui/verb-pairs.js +248 -0
- package/dist/ui.js +131 -0
- package/package.json +73 -14
- package/src/entrypoints/command-mode.ts +5 -0
- package/src/entrypoints/daemon.ts +54 -0
- package/src/entrypoints/headless-stdio.ts +27 -0
- package/src/entrypoints/interactive.ts +112 -0
- package/src/main.ts +44 -0
- package/src/runtime/configure-bun-sqlite.ts +3 -0
- package/src/runtime/crash-handlers.ts +128 -0
- package/src/runtime/interactive-invocation.test.ts +42 -0
- package/src/runtime/interactive-invocation.ts +51 -0
- package/src/runtime/internal-mode.test.ts +19 -0
- package/src/runtime/internal-mode.ts +24 -0
- package/src/runtime/launch-spec.test.ts +26 -0
- package/src/runtime/launch-spec.ts +84 -0
- package/src/runtime/owner-lease.ts +52 -0
- package/src/runtime/public-mode.test.ts +18 -0
- package/src/runtime/public-mode.ts +19 -0
- package/src/runtime/run-internal-mode.ts +19 -0
- package/src/runtime/runtime-kind.test.ts +23 -0
- package/src/runtime/runtime-kind.ts +41 -0
- package/src/runtime/spawn-aria.ts +62 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// packages/cli/src/ui/hooks/index.ts
|
|
2
|
+
export { useKeyboardShortcuts } from "./useKeyboardShortcuts.js";
|
|
3
|
+
export { useDoublePress } from "./useDoublePress.js";
|
|
4
|
+
export { useCommandAutocomplete, } from "./useCommandAutocomplete.js";
|
|
5
|
+
export { useTerminalSize } from "./useTerminalSize.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// packages/cli/src/ui/hooks/useCommandAutocomplete.ts
|
|
2
|
+
import { useState, useMemo, useCallback, useEffect } from "react";
|
|
3
|
+
import { useInput } from "ink";
|
|
4
|
+
import { fuzzySort } from "../utils/fuzzy.js";
|
|
5
|
+
import { isEscapeInput } from "../utils/keys.js";
|
|
6
|
+
// Helper function to compute suggestions from input
|
|
7
|
+
function computeSuggestions(input, commands, maxSuggestions) {
|
|
8
|
+
if (!input.startsWith("/") || input.includes(" ")) {
|
|
9
|
+
return { suggestions: [], isOpen: false };
|
|
10
|
+
}
|
|
11
|
+
const query = input.slice(1); // Remove leading /
|
|
12
|
+
if (!query) {
|
|
13
|
+
// Show all commands when just "/" is typed
|
|
14
|
+
const all = commands
|
|
15
|
+
.map((cmd) => ({
|
|
16
|
+
command: cmd.name,
|
|
17
|
+
args: cmd.args,
|
|
18
|
+
description: cmd.description,
|
|
19
|
+
score: 1,
|
|
20
|
+
}))
|
|
21
|
+
.slice(0, maxSuggestions);
|
|
22
|
+
return { suggestions: all, isOpen: true };
|
|
23
|
+
}
|
|
24
|
+
const matches = fuzzySort(commands, query, (cmd) => cmd.name)
|
|
25
|
+
.slice(0, maxSuggestions)
|
|
26
|
+
.map((cmd) => ({
|
|
27
|
+
command: cmd.name,
|
|
28
|
+
args: cmd.args,
|
|
29
|
+
description: cmd.description,
|
|
30
|
+
score: cmd.score,
|
|
31
|
+
}));
|
|
32
|
+
return { suggestions: matches, isOpen: matches.length > 0 };
|
|
33
|
+
}
|
|
34
|
+
export function useCommandAutocomplete(input, { commands, maxSuggestions = 5, isActive = true }) {
|
|
35
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
36
|
+
const [manuallyClosedFor, setManuallyClosedFor] = useState(null);
|
|
37
|
+
// Compute suggestions synchronously using useMemo
|
|
38
|
+
const { suggestions, isOpen: shouldBeOpen } = useMemo(() => computeSuggestions(input, commands, maxSuggestions), [input, commands, maxSuggestions]);
|
|
39
|
+
// Reset selection when suggestions change
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
setSelectedIndex(0);
|
|
42
|
+
// Reset manually closed state when input changes
|
|
43
|
+
if (manuallyClosedFor !== input) {
|
|
44
|
+
setManuallyClosedFor(null);
|
|
45
|
+
}
|
|
46
|
+
}, [input, suggestions.length, manuallyClosedFor]);
|
|
47
|
+
// Check if manually closed for current input
|
|
48
|
+
const isOpen = shouldBeOpen && manuallyClosedFor !== input;
|
|
49
|
+
const selectNext = useCallback(() => {
|
|
50
|
+
setSelectedIndex((i) => Math.min(i + 1, suggestions.length - 1));
|
|
51
|
+
}, [suggestions.length]);
|
|
52
|
+
const selectPrev = useCallback(() => {
|
|
53
|
+
setSelectedIndex((i) => Math.max(i - 1, 0));
|
|
54
|
+
}, []);
|
|
55
|
+
const complete = useCallback(() => {
|
|
56
|
+
if (!isOpen || suggestions.length === 0)
|
|
57
|
+
return null;
|
|
58
|
+
const selected = suggestions[selectedIndex];
|
|
59
|
+
const completed = `/${selected.command}`;
|
|
60
|
+
// Add space if command takes arguments
|
|
61
|
+
if (selected.args.length > 0) {
|
|
62
|
+
return completed + " ";
|
|
63
|
+
}
|
|
64
|
+
return completed;
|
|
65
|
+
}, [isOpen, suggestions, selectedIndex]);
|
|
66
|
+
const close = useCallback(() => {
|
|
67
|
+
setManuallyClosedFor(input);
|
|
68
|
+
}, [input]);
|
|
69
|
+
// Handle keyboard input for navigation
|
|
70
|
+
useInput((input, key) => {
|
|
71
|
+
if (!isOpen)
|
|
72
|
+
return;
|
|
73
|
+
if (key.downArrow) {
|
|
74
|
+
selectNext();
|
|
75
|
+
}
|
|
76
|
+
else if (key.upArrow) {
|
|
77
|
+
selectPrev();
|
|
78
|
+
}
|
|
79
|
+
else if (isEscapeInput(input, key)) {
|
|
80
|
+
close();
|
|
81
|
+
}
|
|
82
|
+
}, { isActive: isActive && isOpen });
|
|
83
|
+
return {
|
|
84
|
+
suggestions,
|
|
85
|
+
selectedIndex,
|
|
86
|
+
isOpen,
|
|
87
|
+
selectNext,
|
|
88
|
+
selectPrev,
|
|
89
|
+
complete,
|
|
90
|
+
close,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=useCommandAutocomplete.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// packages/cli/src/ui/hooks/useDoublePress.ts
|
|
2
|
+
import { useRef, useCallback, useEffect } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Hook to detect double key presses (e.g., Ctrl+C twice to exit)
|
|
5
|
+
*/
|
|
6
|
+
export function useDoublePress({ timeout = 500, onFirstPress, onDoublePress, }) {
|
|
7
|
+
const lastPressTime = useRef(0);
|
|
8
|
+
const timeoutRef = useRef(undefined);
|
|
9
|
+
// Cleanup timer on unmount
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
return () => {
|
|
12
|
+
clearTimeout(timeoutRef.current);
|
|
13
|
+
};
|
|
14
|
+
}, []);
|
|
15
|
+
const handlePress = useCallback(() => {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
const elapsed = now - lastPressTime.current;
|
|
18
|
+
if (elapsed < timeout) {
|
|
19
|
+
// Double press detected
|
|
20
|
+
clearTimeout(timeoutRef.current);
|
|
21
|
+
lastPressTime.current = 0;
|
|
22
|
+
onDoublePress();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// First press
|
|
26
|
+
lastPressTime.current = now;
|
|
27
|
+
onFirstPress?.();
|
|
28
|
+
// Reset after timeout
|
|
29
|
+
clearTimeout(timeoutRef.current);
|
|
30
|
+
timeoutRef.current = setTimeout(() => {
|
|
31
|
+
lastPressTime.current = 0;
|
|
32
|
+
}, timeout);
|
|
33
|
+
}
|
|
34
|
+
}, [timeout, onFirstPress, onDoublePress]);
|
|
35
|
+
return handlePress;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=useDoublePress.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useReducer, useEffect, useRef } from "react";
|
|
2
|
+
import { transition, initialState } from "../indicator-state.js";
|
|
3
|
+
import { pickRandomVerbPair, toolDisplayName } from "../verb-pairs.js";
|
|
4
|
+
export function useIndicatorState(obsCtx, isStreaming) {
|
|
5
|
+
const [state, dispatch] = useReducer(transition, initialState);
|
|
6
|
+
const prevStreaming = useRef(false);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (isStreaming && !prevStreaming.current) {
|
|
9
|
+
dispatch({ type: "STREAM_START", verb: pickRandomVerbPair() });
|
|
10
|
+
}
|
|
11
|
+
else if (!isStreaming && prevStreaming.current) {
|
|
12
|
+
dispatch({ type: "STREAM_END" });
|
|
13
|
+
}
|
|
14
|
+
prevStreaming.current = isStreaming;
|
|
15
|
+
}, [isStreaming]);
|
|
16
|
+
// Reset state when obsCtx changes (new run session). Without this, the state
|
|
17
|
+
// machine retains stale state from the previous obsCtx's events.
|
|
18
|
+
const prevObsCtx = useRef(null);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (obsCtx !== prevObsCtx.current) {
|
|
21
|
+
if (prevObsCtx.current !== null) {
|
|
22
|
+
dispatch({ type: "STREAM_END" });
|
|
23
|
+
}
|
|
24
|
+
prevObsCtx.current = obsCtx;
|
|
25
|
+
}
|
|
26
|
+
}, [obsCtx]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!obsCtx)
|
|
29
|
+
return;
|
|
30
|
+
const onThinkingStart = () => dispatch({ type: "THINKING_START", verb: pickRandomVerbPair(), startedAt: Date.now() });
|
|
31
|
+
const onThinkingEnd = (data) => dispatch({
|
|
32
|
+
type: "THINKING_END",
|
|
33
|
+
verb: pickRandomVerbPair(),
|
|
34
|
+
durationSeconds: Math.round(data.durationMs / 1000),
|
|
35
|
+
});
|
|
36
|
+
const onToolStart = (event) => dispatch({
|
|
37
|
+
type: "TOOL_START",
|
|
38
|
+
callId: event.id,
|
|
39
|
+
displayName: toolDisplayName(event.name, true),
|
|
40
|
+
});
|
|
41
|
+
const onToolResult = (record) => dispatch({ type: "TOOL_END", callId: record.id, verb: pickRandomVerbPair() });
|
|
42
|
+
obsCtx.on("thinking_start", onThinkingStart);
|
|
43
|
+
obsCtx.on("thinking_end", onThinkingEnd);
|
|
44
|
+
obsCtx.on("tool_start", onToolStart);
|
|
45
|
+
obsCtx.on("tool_result", onToolResult);
|
|
46
|
+
return () => {
|
|
47
|
+
obsCtx.off("thinking_start", onThinkingStart);
|
|
48
|
+
obsCtx.off("thinking_end", onThinkingEnd);
|
|
49
|
+
obsCtx.off("tool_start", onToolStart);
|
|
50
|
+
obsCtx.off("tool_result", onToolResult);
|
|
51
|
+
};
|
|
52
|
+
}, [obsCtx]);
|
|
53
|
+
return state;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=useIndicatorState.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// packages/cli/src/ui/hooks/useInterval.ts
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* A custom hook that runs a callback at a specified interval.
|
|
5
|
+
* The interval is cleared when the component unmounts.
|
|
6
|
+
* The interval is also cleared and restarted if the delay changes.
|
|
7
|
+
*/
|
|
8
|
+
export function useInterval(callback, delay) {
|
|
9
|
+
const savedCallback = useRef(callback);
|
|
10
|
+
// Remember the latest callback
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
savedCallback.current = callback;
|
|
13
|
+
}, [callback]);
|
|
14
|
+
// Set up the interval
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
function tick() {
|
|
17
|
+
savedCallback.current();
|
|
18
|
+
}
|
|
19
|
+
const id = setInterval(tick, delay);
|
|
20
|
+
return () => clearInterval(id);
|
|
21
|
+
}, [delay]);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=useInterval.js.map
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// packages/cli/src/ui/hooks/useKeyboardShortcuts.ts
|
|
2
|
+
import { useInput } from "ink";
|
|
3
|
+
import { Cursor } from "../utils/cursor.js";
|
|
4
|
+
/**
|
|
5
|
+
* Hook providing Emacs-style keyboard shortcuts
|
|
6
|
+
*/
|
|
7
|
+
export function useKeyboardShortcuts({ cursor, setCursor, history, onExit, isActive = true, }) {
|
|
8
|
+
useInput((input, key) => {
|
|
9
|
+
// Ctrl key combinations
|
|
10
|
+
if (key.ctrl) {
|
|
11
|
+
switch (input.toLowerCase()) {
|
|
12
|
+
// Navigation
|
|
13
|
+
case "a":
|
|
14
|
+
setCursor(cursor.moveToStart());
|
|
15
|
+
return;
|
|
16
|
+
case "e":
|
|
17
|
+
setCursor(cursor.moveToEnd());
|
|
18
|
+
return;
|
|
19
|
+
case "b":
|
|
20
|
+
setCursor(cursor.moveLeft());
|
|
21
|
+
return;
|
|
22
|
+
case "f":
|
|
23
|
+
setCursor(cursor.moveRight());
|
|
24
|
+
return;
|
|
25
|
+
// Deletion
|
|
26
|
+
case "k":
|
|
27
|
+
setCursor(cursor.deleteToEnd());
|
|
28
|
+
return;
|
|
29
|
+
case "u":
|
|
30
|
+
setCursor(cursor.deleteToStart());
|
|
31
|
+
return;
|
|
32
|
+
case "w":
|
|
33
|
+
setCursor(cursor.deletePrevWord());
|
|
34
|
+
return;
|
|
35
|
+
case "h":
|
|
36
|
+
setCursor(cursor.deleteLeft());
|
|
37
|
+
return;
|
|
38
|
+
case "d":
|
|
39
|
+
if (cursor.isEmpty && onExit) {
|
|
40
|
+
onExit();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
setCursor(cursor.deleteRight());
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
// History
|
|
47
|
+
case "p":
|
|
48
|
+
if (history && history.index < history.items.length - 1) {
|
|
49
|
+
const newIndex = history.index + 1;
|
|
50
|
+
history.setIndex(newIndex);
|
|
51
|
+
setCursor(new Cursor(history.items[newIndex], history.items[newIndex].length));
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
case "n":
|
|
55
|
+
if (history && history.index > 0) {
|
|
56
|
+
const newIndex = history.index - 1;
|
|
57
|
+
history.setIndex(newIndex);
|
|
58
|
+
setCursor(new Cursor(history.items[newIndex], history.items[newIndex].length));
|
|
59
|
+
}
|
|
60
|
+
else if (history && history.index === 0) {
|
|
61
|
+
history.setIndex(-1);
|
|
62
|
+
setCursor(new Cursor("", 0));
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
// Clear
|
|
66
|
+
case "l":
|
|
67
|
+
setCursor(cursor.clear());
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Meta/Alt key combinations
|
|
72
|
+
if (key.meta) {
|
|
73
|
+
switch (input.toLowerCase()) {
|
|
74
|
+
case "b":
|
|
75
|
+
setCursor(cursor.moveToPrevWord());
|
|
76
|
+
return;
|
|
77
|
+
case "f":
|
|
78
|
+
setCursor(cursor.moveToNextWord());
|
|
79
|
+
return;
|
|
80
|
+
case "d":
|
|
81
|
+
setCursor(cursor.deleteNextWord());
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Arrow keys (with modifiers for word navigation)
|
|
86
|
+
if (key.leftArrow) {
|
|
87
|
+
if (key.ctrl || key.meta) {
|
|
88
|
+
setCursor(cursor.moveToPrevWord());
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
setCursor(cursor.moveLeft());
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (key.rightArrow) {
|
|
96
|
+
if (key.ctrl || key.meta) {
|
|
97
|
+
setCursor(cursor.moveToNextWord());
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
setCursor(cursor.moveRight());
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// History with arrow keys
|
|
105
|
+
if (key.upArrow && history) {
|
|
106
|
+
if (history.index < history.items.length - 1) {
|
|
107
|
+
const newIndex = history.index + 1;
|
|
108
|
+
history.setIndex(newIndex);
|
|
109
|
+
setCursor(new Cursor(history.items[newIndex], history.items[newIndex].length));
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (key.downArrow && history) {
|
|
114
|
+
if (history.index > 0) {
|
|
115
|
+
const newIndex = history.index - 1;
|
|
116
|
+
history.setIndex(newIndex);
|
|
117
|
+
setCursor(new Cursor(history.items[newIndex], history.items[newIndex].length));
|
|
118
|
+
}
|
|
119
|
+
else if (history.index === 0) {
|
|
120
|
+
history.setIndex(-1);
|
|
121
|
+
setCursor(new Cursor("", 0));
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}, { isActive });
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=useKeyboardShortcuts.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
function readTerminalSize() {
|
|
3
|
+
return {
|
|
4
|
+
columns: process.stdout.columns || 80,
|
|
5
|
+
rows: process.stdout.rows || 24,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
let snapshot = readTerminalSize();
|
|
9
|
+
let isListening = false;
|
|
10
|
+
const subscribers = new Set();
|
|
11
|
+
function syncSnapshotWithTerminal() {
|
|
12
|
+
const next = readTerminalSize();
|
|
13
|
+
if (next.columns === snapshot.columns && next.rows === snapshot.rows)
|
|
14
|
+
return false;
|
|
15
|
+
snapshot = next;
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
function notifySubscribers() {
|
|
19
|
+
for (const subscriber of subscribers)
|
|
20
|
+
subscriber();
|
|
21
|
+
}
|
|
22
|
+
function handleResize() {
|
|
23
|
+
if (!syncSnapshotWithTerminal())
|
|
24
|
+
return;
|
|
25
|
+
notifySubscribers();
|
|
26
|
+
}
|
|
27
|
+
function ensureListener() {
|
|
28
|
+
if (isListening)
|
|
29
|
+
return;
|
|
30
|
+
process.stdout.on("resize", handleResize);
|
|
31
|
+
isListening = true;
|
|
32
|
+
}
|
|
33
|
+
function releaseListener() {
|
|
34
|
+
if (!isListening || subscribers.size !== 0)
|
|
35
|
+
return;
|
|
36
|
+
process.stdout.off("resize", handleResize);
|
|
37
|
+
isListening = false;
|
|
38
|
+
}
|
|
39
|
+
function subscribe(onStoreChange) {
|
|
40
|
+
subscribers.add(onStoreChange);
|
|
41
|
+
syncSnapshotWithTerminal();
|
|
42
|
+
ensureListener();
|
|
43
|
+
return () => {
|
|
44
|
+
subscribers.delete(onStoreChange);
|
|
45
|
+
releaseListener();
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function getSnapshot() {
|
|
49
|
+
syncSnapshotWithTerminal();
|
|
50
|
+
return snapshot;
|
|
51
|
+
}
|
|
52
|
+
export function useTerminalSize() {
|
|
53
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=useTerminalSize.js.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified message state — single array + streaming cursor.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the dual messages/previewMessages state machine that caused
|
|
5
|
+
* preview-committed race conditions (text cutoff, ghost preview, abort freeze).
|
|
6
|
+
*
|
|
7
|
+
* Invariant: `isStreaming === (streamCursor !== null)` — derived, never separate state.
|
|
8
|
+
*
|
|
9
|
+
* Generic over item type T (defaults to RenderItem for rendering, but can be
|
|
10
|
+
* used with ConversationMessage for state management in ink-repl).
|
|
11
|
+
*/
|
|
12
|
+
import { useReducer, useMemo, useCallback } from "react";
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Reducer
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export function turnReducer(state, action) {
|
|
17
|
+
switch (action.type) {
|
|
18
|
+
case "START_TURN":
|
|
19
|
+
return {
|
|
20
|
+
items: state.items,
|
|
21
|
+
streamCursor: state.items.length,
|
|
22
|
+
};
|
|
23
|
+
case "UPDATE_STREAM": {
|
|
24
|
+
if (state.streamCursor === null)
|
|
25
|
+
return state;
|
|
26
|
+
return {
|
|
27
|
+
items: [...state.items.slice(0, state.streamCursor), ...action.snapshot],
|
|
28
|
+
streamCursor: state.streamCursor,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
case "COMMIT_TURN": {
|
|
32
|
+
const cursor = state.streamCursor ?? state.items.length;
|
|
33
|
+
const committed = [...state.items.slice(0, cursor), ...action.flushed];
|
|
34
|
+
return {
|
|
35
|
+
items: committed,
|
|
36
|
+
streamCursor: committed.length,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
case "END_TURN":
|
|
40
|
+
return {
|
|
41
|
+
items: state.items,
|
|
42
|
+
streamCursor: null,
|
|
43
|
+
};
|
|
44
|
+
case "APPEND_COMMITTED": {
|
|
45
|
+
if (state.streamCursor !== null) {
|
|
46
|
+
// Insert before the streaming zone so committed items stay in Static
|
|
47
|
+
const before = state.items.slice(0, state.streamCursor);
|
|
48
|
+
const streaming = state.items.slice(state.streamCursor);
|
|
49
|
+
return {
|
|
50
|
+
items: [...before, ...action.items, ...streaming],
|
|
51
|
+
streamCursor: state.streamCursor + action.items.length,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
items: [...state.items, ...action.items],
|
|
56
|
+
streamCursor: null,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
case "RESET":
|
|
60
|
+
return {
|
|
61
|
+
items: action.items ?? [],
|
|
62
|
+
streamCursor: null,
|
|
63
|
+
};
|
|
64
|
+
case "DISCARD_STREAMING": {
|
|
65
|
+
if (state.streamCursor === null)
|
|
66
|
+
return state;
|
|
67
|
+
return {
|
|
68
|
+
items: state.items.slice(0, state.streamCursor),
|
|
69
|
+
streamCursor: null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
case "FUNCTIONAL_UPDATE": {
|
|
73
|
+
if (state.streamCursor !== null) {
|
|
74
|
+
const committed = state.items.slice(0, state.streamCursor);
|
|
75
|
+
const streaming = state.items.slice(state.streamCursor);
|
|
76
|
+
const updated = action.updater(committed);
|
|
77
|
+
return {
|
|
78
|
+
items: [...updated, ...streaming],
|
|
79
|
+
streamCursor: updated.length,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
items: action.updater(state.items),
|
|
84
|
+
streamCursor: null,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
case "COMMIT_AND_END": {
|
|
88
|
+
const cursor = state.streamCursor ?? state.items.length;
|
|
89
|
+
return {
|
|
90
|
+
items: [...state.items.slice(0, cursor), ...action.flushed],
|
|
91
|
+
streamCursor: null,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
default:
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export function useUnifiedMessages(initialItems) {
|
|
99
|
+
const initial = initialItems
|
|
100
|
+
? { items: initialItems, streamCursor: null }
|
|
101
|
+
: { items: [], streamCursor: null };
|
|
102
|
+
const reducer = turnReducer;
|
|
103
|
+
const [state, dispatch] = useReducer(reducer, initial);
|
|
104
|
+
const committedItems = useMemo(() => (state.streamCursor !== null ? state.items.slice(0, state.streamCursor) : state.items), [state.items, state.streamCursor]);
|
|
105
|
+
const streamingItems = useMemo(() => (state.streamCursor !== null ? state.items.slice(state.streamCursor) : []), [state.items, state.streamCursor]);
|
|
106
|
+
const isStreaming = state.streamCursor !== null;
|
|
107
|
+
const setItems = useCallback((action) => {
|
|
108
|
+
if (typeof action === "function") {
|
|
109
|
+
dispatch({ type: "FUNCTIONAL_UPDATE", updater: action });
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
dispatch({ type: "RESET", items: action });
|
|
113
|
+
}
|
|
114
|
+
}, [dispatch]);
|
|
115
|
+
return { items: state.items, committedItems, streamingItems, isStreaming, dispatch, setItems };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=useUnifiedMessages.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const initialState = { kind: "idle" };
|
|
2
|
+
/**
|
|
3
|
+
* Pure state machine transition function.
|
|
4
|
+
* All randomness (verb selection, timestamps) must be computed by the caller
|
|
5
|
+
* and passed in the event payload. This keeps the reducer deterministic and
|
|
6
|
+
* safe for React StrictMode double-invocation.
|
|
7
|
+
*/
|
|
8
|
+
export function transition(state, event) {
|
|
9
|
+
switch (event.type) {
|
|
10
|
+
case "STREAM_START":
|
|
11
|
+
return { kind: "composing", verb: event.verb };
|
|
12
|
+
case "THINKING_START":
|
|
13
|
+
// Allowed from composing (normal) and idle (race safety net: obsCtx may fire
|
|
14
|
+
// thinking_start before the React useEffect dispatches STREAM_START).
|
|
15
|
+
// Guarded from tool_running to avoid dropping tool tracking state.
|
|
16
|
+
if (state.kind !== "composing" && state.kind !== "idle")
|
|
17
|
+
return state;
|
|
18
|
+
return { kind: "thinking", verb: event.verb, startedAt: event.startedAt };
|
|
19
|
+
case "THINKING_END":
|
|
20
|
+
if (state.kind !== "thinking")
|
|
21
|
+
return state;
|
|
22
|
+
return { kind: "composing", verb: event.verb, thoughtForSeconds: event.durationSeconds };
|
|
23
|
+
case "TOOL_START": {
|
|
24
|
+
const tools = new Map(state.kind === "tool_running" ? state.tools : []);
|
|
25
|
+
tools.set(event.callId, event.displayName);
|
|
26
|
+
return { kind: "tool_running", tools };
|
|
27
|
+
}
|
|
28
|
+
case "TOOL_END": {
|
|
29
|
+
if (state.kind !== "tool_running")
|
|
30
|
+
return state;
|
|
31
|
+
const tools = new Map(state.tools);
|
|
32
|
+
tools.delete(event.callId);
|
|
33
|
+
if (tools.size === 0) {
|
|
34
|
+
return { kind: "composing", verb: event.verb };
|
|
35
|
+
}
|
|
36
|
+
return { kind: "tool_running", tools };
|
|
37
|
+
}
|
|
38
|
+
case "STREAM_END":
|
|
39
|
+
return { kind: "idle" };
|
|
40
|
+
default:
|
|
41
|
+
return state;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=indicator-state.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { highlight, supportsLanguage } from "cli-highlight";
|
|
2
|
+
/**
|
|
3
|
+
* Highlight code with syntax coloring
|
|
4
|
+
*/
|
|
5
|
+
export function highlightCode(code, language) {
|
|
6
|
+
const lang = normalizeLanguage(language);
|
|
7
|
+
if (!supportsLanguage(lang)) {
|
|
8
|
+
if (supportsLanguage("markdown")) {
|
|
9
|
+
return highlight(code, { language: "markdown" });
|
|
10
|
+
}
|
|
11
|
+
return code;
|
|
12
|
+
}
|
|
13
|
+
return highlight(code, { language: lang });
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Normalize language aliases to cli-highlight supported names
|
|
17
|
+
*/
|
|
18
|
+
function normalizeLanguage(lang) {
|
|
19
|
+
const aliases = {
|
|
20
|
+
js: "javascript",
|
|
21
|
+
jsx: "javascript",
|
|
22
|
+
ts: "typescript",
|
|
23
|
+
tsx: "typescript",
|
|
24
|
+
sh: "bash",
|
|
25
|
+
shell: "bash",
|
|
26
|
+
zsh: "bash",
|
|
27
|
+
yml: "yaml",
|
|
28
|
+
py: "python",
|
|
29
|
+
rb: "ruby",
|
|
30
|
+
rs: "rust",
|
|
31
|
+
go: "go",
|
|
32
|
+
md: "markdown",
|
|
33
|
+
dockerfile: "docker",
|
|
34
|
+
};
|
|
35
|
+
const normalized = lang.toLowerCase().trim();
|
|
36
|
+
return aliases[normalized] ?? normalized;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a language is supported for highlighting
|
|
40
|
+
*/
|
|
41
|
+
export function isLanguageSupported(language) {
|
|
42
|
+
return supportsLanguage(normalizeLanguage(language));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=highlight.js.map
|