wave-code 1.0.10 → 1.1.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/bin/wave-code.js +8 -2
- package/dist/bundle/wave.mjs +3207 -0
- package/package.json +24 -25
- package/src/commands/update.ts +2 -7
- package/src/components/App.tsx +3 -7
- package/src/components/BtwDisplay.tsx +10 -1
- package/src/components/ChatInterface.tsx +21 -52
- package/src/components/ConfirmationDetails.tsx +144 -37
- package/src/components/DiffDisplay.tsx +335 -301
- package/src/components/InputBox.tsx +3 -1
- package/src/components/LoadingIndicator.tsx +16 -2
- package/src/components/MessageBlockItem.tsx +2 -4
- package/src/components/MessageList.tsx +75 -14
- package/src/components/ReasoningDisplay.tsx +2 -4
- package/src/components/SessionSelector.tsx +82 -11
- package/src/components/StatusCommand.tsx +2 -9
- package/src/components/ToolDisplay.tsx +2 -4
- package/src/contexts/useChat.tsx +156 -335
- package/src/daemon/commands.ts +57 -27
- package/src/daemon/jsonRpcClient.ts +1 -1
- package/src/daemon/socketClient.ts +2 -2
- package/src/hooks/useInputManager.ts +1 -1
- package/src/index.ts +57 -10
- package/src/managers/inputReducer.ts +186 -104
- package/src/print-cli.ts +21 -17
- package/src/reducers/selectorReducer.ts +10 -0
- package/src/session-selector-cli.tsx +269 -28
- package/src/stdio/agentBridge.ts +22 -21
- package/src/stdio/daemonServer.ts +3 -1
- package/src/utils/clipboard.ts +21 -0
- package/src/utils/highlightUtils.ts +46 -1
- package/src/utils/readPackageJson.ts +29 -0
- package/src/utils/streamingText.ts +11 -0
- package/src/utils/worktree.ts +191 -43
- package/dist/cli.d.ts +0 -6
- package/dist/cli.js +0 -53
- package/dist/commands/plugin/disable.d.ts +0 -5
- package/dist/commands/plugin/disable.js +0 -15
- package/dist/commands/plugin/enable.d.ts +0 -5
- package/dist/commands/plugin/enable.js +0 -15
- package/dist/commands/plugin/install.d.ts +0 -5
- package/dist/commands/plugin/install.js +0 -21
- package/dist/commands/plugin/list.d.ts +0 -1
- package/dist/commands/plugin/list.js +0 -31
- package/dist/commands/plugin/marketplace.d.ts +0 -10
- package/dist/commands/plugin/marketplace.js +0 -90
- package/dist/commands/plugin/uninstall.d.ts +0 -3
- package/dist/commands/plugin/uninstall.js +0 -16
- package/dist/commands/plugin/update.d.ts +0 -3
- package/dist/commands/plugin/update.js +0 -15
- package/dist/commands/update.d.ts +0 -1
- package/dist/commands/update.js +0 -97
- package/dist/components/AgentsManager.d.ts +0 -7
- package/dist/components/AgentsManager.js +0 -109
- package/dist/components/App.d.ts +0 -9
- package/dist/components/App.js +0 -76
- package/dist/components/BackgroundTaskManager.d.ts +0 -5
- package/dist/components/BackgroundTaskManager.js +0 -99
- package/dist/components/BangDisplay.d.ts +0 -8
- package/dist/components/BangDisplay.js +0 -17
- package/dist/components/BtwDisplay.d.ts +0 -7
- package/dist/components/BtwDisplay.js +0 -19
- package/dist/components/ChatInterface.d.ts +0 -2
- package/dist/components/ChatInterface.js +0 -61
- package/dist/components/CommandSelector.d.ts +0 -10
- package/dist/components/CommandSelector.js +0 -66
- package/dist/components/CompactDisplay.d.ts +0 -8
- package/dist/components/CompactDisplay.js +0 -13
- package/dist/components/ConfirmationDetails.d.ts +0 -9
- package/dist/components/ConfirmationDetails.js +0 -45
- package/dist/components/ConfirmationSelector.d.ts +0 -13
- package/dist/components/ConfirmationSelector.js +0 -127
- package/dist/components/DiffDisplay.d.ts +0 -8
- package/dist/components/DiffDisplay.js +0 -201
- package/dist/components/DiscoverView.d.ts +0 -2
- package/dist/components/DiscoverView.js +0 -37
- package/dist/components/FileSelector.d.ts +0 -11
- package/dist/components/FileSelector.js +0 -50
- package/dist/components/HelpView.d.ts +0 -7
- package/dist/components/HelpView.js +0 -74
- package/dist/components/HistorySearch.d.ts +0 -8
- package/dist/components/HistorySearch.js +0 -66
- package/dist/components/InputBox.d.ts +0 -24
- package/dist/components/InputBox.js +0 -149
- package/dist/components/InstalledView.d.ts +0 -2
- package/dist/components/InstalledView.js +0 -45
- package/dist/components/LoadingIndicator.d.ts +0 -10
- package/dist/components/LoadingIndicator.js +0 -6
- package/dist/components/LoginCommand.d.ts +0 -5
- package/dist/components/LoginCommand.js +0 -153
- package/dist/components/Markdown.d.ts +0 -5
- package/dist/components/Markdown.js +0 -127
- package/dist/components/MarketplaceAddForm.d.ts +0 -2
- package/dist/components/MarketplaceAddForm.js +0 -55
- package/dist/components/MarketplaceDetail.d.ts +0 -2
- package/dist/components/MarketplaceDetail.js +0 -74
- package/dist/components/MarketplaceList.d.ts +0 -8
- package/dist/components/MarketplaceList.js +0 -17
- package/dist/components/MarketplaceView.d.ts +0 -2
- package/dist/components/MarketplaceView.js +0 -41
- package/dist/components/McpManager.d.ts +0 -9
- package/dist/components/McpManager.js +0 -88
- package/dist/components/MessageBlockItem.d.ts +0 -8
- package/dist/components/MessageBlockItem.js +0 -15
- package/dist/components/MessageList.d.ts +0 -10
- package/dist/components/MessageList.js +0 -80
- package/dist/components/ModelSelector.d.ts +0 -8
- package/dist/components/ModelSelector.js +0 -45
- package/dist/components/Notifications.d.ts +0 -7
- package/dist/components/Notifications.js +0 -9
- package/dist/components/PlanDisplay.d.ts +0 -7
- package/dist/components/PlanDisplay.js +0 -6
- package/dist/components/PluginDetail.d.ts +0 -2
- package/dist/components/PluginDetail.js +0 -87
- package/dist/components/PluginList.d.ts +0 -13
- package/dist/components/PluginList.js +0 -15
- package/dist/components/PluginManagerShell.d.ts +0 -6
- package/dist/components/PluginManagerShell.js +0 -92
- package/dist/components/PluginManagerTypes.d.ts +0 -35
- package/dist/components/PluginManagerTypes.js +0 -1
- package/dist/components/QueuedMessageList.d.ts +0 -2
- package/dist/components/QueuedMessageList.js +0 -18
- package/dist/components/ReasoningDisplay.d.ts +0 -8
- package/dist/components/ReasoningDisplay.js +0 -13
- package/dist/components/RewindCommand.d.ts +0 -12
- package/dist/components/RewindCommand.js +0 -78
- package/dist/components/SessionSelector.d.ts +0 -12
- package/dist/components/SessionSelector.js +0 -47
- package/dist/components/StatusCommand.d.ts +0 -5
- package/dist/components/StatusCommand.js +0 -28
- package/dist/components/StatusLine.d.ts +0 -6
- package/dist/components/StatusLine.js +0 -9
- package/dist/components/TaskList.d.ts +0 -5
- package/dist/components/TaskList.js +0 -197
- package/dist/components/TaskNotificationMessage.d.ts +0 -5
- package/dist/components/TaskNotificationMessage.js +0 -12
- package/dist/components/ToolDisplay.d.ts +0 -9
- package/dist/components/ToolDisplay.js +0 -55
- package/dist/components/WorkflowManager.d.ts +0 -5
- package/dist/components/WorkflowManager.js +0 -102
- package/dist/components/WorktreeExitPrompt.d.ts +0 -12
- package/dist/components/WorktreeExitPrompt.js +0 -35
- package/dist/constants/commands.d.ts +0 -2
- package/dist/constants/commands.js +0 -92
- package/dist/contexts/PluginManagerContext.d.ts +0 -3
- package/dist/contexts/PluginManagerContext.js +0 -9
- package/dist/contexts/useAppConfig.d.ts +0 -10
- package/dist/contexts/useAppConfig.js +0 -13
- package/dist/contexts/useChat.d.ts +0 -101
- package/dist/contexts/useChat.js +0 -993
- package/dist/contracts/status.d.ts +0 -7
- package/dist/contracts/status.js +0 -1
- package/dist/daemon/commands.d.ts +0 -49
- package/dist/daemon/commands.js +0 -341
- package/dist/daemon/jsonRpcClient.d.ts +0 -38
- package/dist/daemon/jsonRpcClient.js +0 -129
- package/dist/daemon/socketClient.d.ts +0 -13
- package/dist/daemon/socketClient.js +0 -26
- package/dist/daemon-cli.d.ts +0 -10
- package/dist/daemon-cli.js +0 -15
- package/dist/hooks/useInputManager.d.ts +0 -75
- package/dist/hooks/useInputManager.js +0 -583
- package/dist/hooks/usePluginManager.d.ts +0 -4
- package/dist/hooks/usePluginManager.js +0 -265
- package/dist/hooks/useTasks.d.ts +0 -1
- package/dist/hooks/useTasks.js +0 -5
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -447
- package/dist/managers/inputHandlers.d.ts +0 -30
- package/dist/managers/inputHandlers.js +0 -625
- package/dist/managers/inputReducer.d.ts +0 -271
- package/dist/managers/inputReducer.js +0 -1121
- package/dist/plugin-manager-cli.d.ts +0 -5
- package/dist/plugin-manager-cli.js +0 -12
- package/dist/print-cli.d.ts +0 -10
- package/dist/print-cli.js +0 -209
- package/dist/reducers/agentsManagerReducer.d.ts +0 -26
- package/dist/reducers/agentsManagerReducer.js +0 -54
- package/dist/reducers/backgroundTaskManagerReducer.d.ts +0 -62
- package/dist/reducers/backgroundTaskManagerReducer.js +0 -106
- package/dist/reducers/confirmationReducer.d.ts +0 -37
- package/dist/reducers/confirmationReducer.js +0 -193
- package/dist/reducers/helpSelectorReducer.d.ts +0 -25
- package/dist/reducers/helpSelectorReducer.js +0 -52
- package/dist/reducers/marketplaceAddFormReducer.d.ts +0 -24
- package/dist/reducers/marketplaceAddFormReducer.js +0 -58
- package/dist/reducers/mcpManagerReducer.d.ts +0 -37
- package/dist/reducers/mcpManagerReducer.js +0 -74
- package/dist/reducers/pluginDetailReducer.d.ts +0 -32
- package/dist/reducers/pluginDetailReducer.js +0 -70
- package/dist/reducers/questionReducer.d.ts +0 -82
- package/dist/reducers/questionReducer.js +0 -375
- package/dist/reducers/rewindSelectorReducer.d.ts +0 -21
- package/dist/reducers/rewindSelectorReducer.js +0 -37
- package/dist/reducers/selectorReducer.d.ts +0 -23
- package/dist/reducers/selectorReducer.js +0 -42
- package/dist/reducers/workflowManagerReducer.d.ts +0 -40
- package/dist/reducers/workflowManagerReducer.js +0 -100
- package/dist/session-selector-cli.d.ts +0 -3
- package/dist/session-selector-cli.js +0 -25
- package/dist/stdio/agentBridge.d.ts +0 -139
- package/dist/stdio/agentBridge.js +0 -999
- package/dist/stdio/daemonServer.d.ts +0 -67
- package/dist/stdio/daemonServer.js +0 -191
- package/dist/stdio/index.d.ts +0 -5
- package/dist/stdio/index.js +0 -5
- package/dist/stdio/jsonRpcConnection.d.ts +0 -39
- package/dist/stdio/jsonRpcConnection.js +0 -135
- package/dist/stdio/protocol.d.ts +0 -41
- package/dist/stdio/protocol.js +0 -26
- package/dist/stdio/stdioServer.d.ts +0 -36
- package/dist/stdio/stdioServer.js +0 -51
- package/dist/stdio-cli.d.ts +0 -8
- package/dist/stdio-cli.js +0 -15
- package/dist/types.d.ts +0 -20
- package/dist/types.js +0 -1
- package/dist/utils/bracketedPaste.d.ts +0 -39
- package/dist/utils/bracketedPaste.js +0 -122
- package/dist/utils/clipboard.d.ts +0 -21
- package/dist/utils/clipboard.js +0 -347
- package/dist/utils/constants.d.ts +0 -16
- package/dist/utils/constants.js +0 -18
- package/dist/utils/highlightUtils.d.ts +0 -1
- package/dist/utils/highlightUtils.js +0 -93
- package/dist/utils/inputUtils.d.ts +0 -17
- package/dist/utils/inputUtils.js +0 -67
- package/dist/utils/logger.d.ts +0 -71
- package/dist/utils/logger.js +0 -259
- package/dist/utils/markdownTable.d.ts +0 -34
- package/dist/utils/markdownTable.js +0 -302
- package/dist/utils/rewindCheckpoints.d.ts +0 -8
- package/dist/utils/rewindCheckpoints.js +0 -17
- package/dist/utils/throttle.d.ts +0 -14
- package/dist/utils/throttle.js +0 -55
- package/dist/utils/toolParameterTransforms.d.ts +0 -18
- package/dist/utils/toolParameterTransforms.js +0 -73
- package/dist/utils/usageSummary.d.ts +0 -28
- package/dist/utils/usageSummary.js +0 -121
- package/dist/utils/version.d.ts +0 -1
- package/dist/utils/version.js +0 -4
- package/dist/utils/worktree.d.ts +0 -35
- package/dist/utils/worktree.js +0 -219
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useReducer, useEffect } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { PromptHistoryManager } from "wave-agent-sdk";
|
|
5
|
-
import { selectorReducer, } from "../reducers/selectorReducer.js";
|
|
6
|
-
export const HistorySearch = ({ searchQuery, onSelect, onCancel, }) => {
|
|
7
|
-
const MAX_VISIBLE_ITEMS = 5;
|
|
8
|
-
const [state, dispatch] = useReducer((selectorReducer), {
|
|
9
|
-
selectedIndex: 0,
|
|
10
|
-
pendingDecision: null,
|
|
11
|
-
items: [],
|
|
12
|
-
});
|
|
13
|
-
const { selectedIndex, pendingDecision, items: entries } = state;
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
const fetchHistory = async () => {
|
|
16
|
-
const results = await PromptHistoryManager.searchHistory(searchQuery);
|
|
17
|
-
dispatch({ type: "SET_ITEMS", items: results.slice(0, 20) });
|
|
18
|
-
};
|
|
19
|
-
fetchHistory();
|
|
20
|
-
}, [searchQuery]);
|
|
21
|
-
// Handle decisions from reducer
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (!pendingDecision)
|
|
24
|
-
return;
|
|
25
|
-
if (pendingDecision === "select") {
|
|
26
|
-
if (entries.length > 0 && selectedIndex < entries.length) {
|
|
27
|
-
onSelect(entries[selectedIndex]);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else if (pendingDecision === "cancel") {
|
|
31
|
-
onCancel();
|
|
32
|
-
}
|
|
33
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
34
|
-
}, [pendingDecision, selectedIndex, entries, onSelect, onCancel]);
|
|
35
|
-
useInput((input, key) => {
|
|
36
|
-
dispatch({ type: "HANDLE_KEY", key, hasInsert: false });
|
|
37
|
-
});
|
|
38
|
-
if (entries.length === 0) {
|
|
39
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", children: ["No history found ", searchQuery && `for "${searchQuery}"`] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] }));
|
|
40
|
-
}
|
|
41
|
-
const formatTimestamp = (timestamp) => {
|
|
42
|
-
const date = new Date(timestamp);
|
|
43
|
-
const now = new Date();
|
|
44
|
-
const diffMs = now.getTime() - date.getTime();
|
|
45
|
-
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
46
|
-
const diffDays = Math.floor(diffHours / 24);
|
|
47
|
-
if (diffDays > 0) {
|
|
48
|
-
return `${diffDays}d ago`;
|
|
49
|
-
}
|
|
50
|
-
else if (diffHours > 0) {
|
|
51
|
-
return `${diffHours}h ago`;
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
const diffMinutes = Math.floor(diffMs / (1000 * 60));
|
|
55
|
-
return diffMinutes > 0 ? `${diffMinutes}m ago` : "just now";
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
// Calculate visible window
|
|
59
|
-
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, entries.length - MAX_VISIBLE_ITEMS)));
|
|
60
|
-
const visibleEntries = entries.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
|
|
61
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "blue", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "blue", bold: true, children: ["Prompt History ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: visibleEntries.map((entry, index) => {
|
|
62
|
-
const actualIndex = startIndex + index;
|
|
63
|
-
const isSelected = actualIndex === selectedIndex;
|
|
64
|
-
return (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsx(Box, { flexShrink: 1, children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "blue" : undefined, wrap: "truncate-end", children: [isSelected ? "> " : " ", entry.prompt.replace(/\n/g, " ")] }) }), isSelected && (_jsx(Box, { marginLeft: 2, flexShrink: 0, children: _jsx(Text, { color: "gray", dimColor: true, children: formatTimestamp(entry.timestamp) }) }))] }, actualIndex));
|
|
65
|
-
}) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 to navigate, Enter to select, Escape to cancel" }) })] }));
|
|
66
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { McpServerStatus, SlashCommand } from "wave-agent-sdk";
|
|
3
|
-
export declare const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
|
|
4
|
-
export declare const INPUT_PLACEHOLDER_TEXT_PREFIX: string;
|
|
5
|
-
export interface InputBoxProps {
|
|
6
|
-
isLoading?: boolean;
|
|
7
|
-
isCommandRunning?: boolean;
|
|
8
|
-
isCompacting?: boolean;
|
|
9
|
-
workdir?: string;
|
|
10
|
-
sendMessage?: (message: string, images?: Array<{
|
|
11
|
-
path: string;
|
|
12
|
-
mimeType: string;
|
|
13
|
-
}>, longTextMap?: Record<string, string>) => void;
|
|
14
|
-
abortMessage?: () => void;
|
|
15
|
-
mcpServers?: McpServerStatus[];
|
|
16
|
-
connectMcpServer?: (serverName: string) => Promise<boolean>;
|
|
17
|
-
disconnectMcpServer?: (serverName: string) => Promise<boolean>;
|
|
18
|
-
slashCommands?: SlashCommand[];
|
|
19
|
-
hasSlashCommand?: (commandId: string) => boolean;
|
|
20
|
-
latestTotalTokens?: number;
|
|
21
|
-
maxInputTokens?: number;
|
|
22
|
-
showLoginHint?: boolean;
|
|
23
|
-
}
|
|
24
|
-
export declare const InputBox: React.FC<InputBoxProps>;
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useCallback } from "react";
|
|
3
|
-
import { Box, Text } from "ink";
|
|
4
|
-
import { useInput } from "ink";
|
|
5
|
-
import { FileSelector } from "./FileSelector.js";
|
|
6
|
-
import { CommandSelector } from "./CommandSelector.js";
|
|
7
|
-
import { HistorySearch } from "./HistorySearch.js";
|
|
8
|
-
import { BackgroundTaskManager } from "./BackgroundTaskManager.js";
|
|
9
|
-
import { McpManager } from "./McpManager.js";
|
|
10
|
-
import { AgentsManager } from "./AgentsManager.js";
|
|
11
|
-
import { RewindCommand } from "./RewindCommand.js";
|
|
12
|
-
import { HelpView } from "./HelpView.js";
|
|
13
|
-
import { StatusCommand } from "./StatusCommand.js";
|
|
14
|
-
import { LoginCommand } from "./LoginCommand.js";
|
|
15
|
-
import { PluginManagerShell } from "./PluginManagerShell.js";
|
|
16
|
-
import { ModelSelector } from "./ModelSelector.js";
|
|
17
|
-
import { WorkflowManager } from "./WorkflowManager.js";
|
|
18
|
-
import { StatusLine } from "./StatusLine.js";
|
|
19
|
-
import { Notifications } from "./Notifications.js";
|
|
20
|
-
import { BtwDisplay } from "./BtwDisplay.js";
|
|
21
|
-
import { useInputManager } from "../hooks/useInputManager.js";
|
|
22
|
-
import { useChat } from "../contexts/useChat.js";
|
|
23
|
-
export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
|
|
24
|
-
export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
|
|
25
|
-
export const InputBox = ({ isLoading, isCommandRunning, isCompacting, sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, latestTotalTokens = 0, maxInputTokens = 200000, showLoginHint = false, }) => {
|
|
26
|
-
const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, clearMessages, compact, addDir, currentModel, configuredModels, setModel, recreateAgent, recallQueuedMessage, queuedMessages, setIsBtwActive, agentDefinitions, } = useChat();
|
|
27
|
-
// Ref to hold setInputText so queue callbacks can access it before useInputManager returns
|
|
28
|
-
const setInputTextRef = useRef(() => { });
|
|
29
|
-
const hasQueuedMessages = (queuedMessages?.length ?? 0) > 0;
|
|
30
|
-
// Idle means no AI work in flight. Esc double-press clear only applies when
|
|
31
|
-
// idle; while busy, Esc keeps its abort semantics.
|
|
32
|
-
const isIdle = !(isLoading || isCommandRunning || isCompacting);
|
|
33
|
-
const onRecallQueuedMessage = useCallback(() => {
|
|
34
|
-
const msg = recallQueuedMessage();
|
|
35
|
-
if (msg) {
|
|
36
|
-
const prefix = msg.type === "bang" ? "!" : "";
|
|
37
|
-
setInputTextRef.current(prefix + msg.content);
|
|
38
|
-
}
|
|
39
|
-
}, [recallQueuedMessage]);
|
|
40
|
-
// Input manager with all input state and functionality (including images)
|
|
41
|
-
const { inputText, cursorPosition,
|
|
42
|
-
// File selector
|
|
43
|
-
showFileSelector, filteredFiles, fileSearchQuery: searchQuery, isFileSearching, handleFileSelect, handleCancelFileSelect,
|
|
44
|
-
// Command selector
|
|
45
|
-
showCommandSelector, commandSearchQuery, handleCommandSelect, handleCommandInsert, handleCancelCommandSelect, handleHistorySearchSelect, handleCancelHistorySearch,
|
|
46
|
-
// History search
|
|
47
|
-
showHistorySearch, historySearchQuery,
|
|
48
|
-
// Task/MCP Manager
|
|
49
|
-
showBackgroundTaskManager, showMcpManager, showAgentsManager, showRewindManager, showHelp, showStatusCommand, showLoginCommand, showPluginManager, showModelSelector, showWorkflowManager, setShowBackgroundTaskManager, setShowMcpManager, setShowAgentsManager, setShowRewindManager, setShowHelp, setShowStatusCommand, setShowLoginCommand, setShowPluginManager, setShowModelSelector, setShowWorkflowManager,
|
|
50
|
-
// Permission mode
|
|
51
|
-
permissionMode, setPermissionMode,
|
|
52
|
-
// BTW state
|
|
53
|
-
btwState,
|
|
54
|
-
// Esc double-press clear pending
|
|
55
|
-
escClearPending,
|
|
56
|
-
// Main handler
|
|
57
|
-
handleInput,
|
|
58
|
-
// Manager ready state
|
|
59
|
-
isManagerReady,
|
|
60
|
-
// Direct state setters
|
|
61
|
-
setInputText, } = useInputManager({
|
|
62
|
-
onSendMessage: sendMessage,
|
|
63
|
-
onAskBtw: askBtw,
|
|
64
|
-
onClearMessages: clearMessages,
|
|
65
|
-
onCompact: compact,
|
|
66
|
-
onAddDir: addDir,
|
|
67
|
-
onHasSlashCommand: hasSlashCommand,
|
|
68
|
-
onAbortMessage: abortMessage,
|
|
69
|
-
onBackgroundCurrentTask: backgroundCurrentTask,
|
|
70
|
-
onPermissionModeChange: setChatPermissionMode,
|
|
71
|
-
sessionId,
|
|
72
|
-
workdir: workingDirectory,
|
|
73
|
-
getFullMessageThread,
|
|
74
|
-
hasQueuedMessages,
|
|
75
|
-
isIdle,
|
|
76
|
-
onRecallQueuedMessage,
|
|
77
|
-
});
|
|
78
|
-
// Keep setInputText ref updated for queue callbacks
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
setInputTextRef.current = setInputText;
|
|
81
|
-
}, [setInputText]);
|
|
82
|
-
// Sync the btw overlay's visibility to ChatContext so siblings (TaskList)
|
|
83
|
-
// can hide while the side-question is on display (aligned with Claude Code,
|
|
84
|
-
// which suppresses the expanded task list while a local-jsx command shows).
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
setIsBtwActive(btwState.question !== "" || btwState.answer !== undefined);
|
|
87
|
-
}, [btwState.question, btwState.answer, setIsBtwActive]);
|
|
88
|
-
// Sync permission mode from useChat to InputManager
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
setPermissionMode(chatPermissionMode);
|
|
91
|
-
}, [chatPermissionMode, setPermissionMode]);
|
|
92
|
-
// Use the InputManager's unified input handler
|
|
93
|
-
useInput(async (input, key) => {
|
|
94
|
-
// These views have their own useInput handlers that handle escape and navigation.
|
|
95
|
-
// If they are active, we should skip InputBox's global input handling to avoid
|
|
96
|
-
// duplicate dispatches or state update conflicts.
|
|
97
|
-
if (showRewindManager ||
|
|
98
|
-
showHelp ||
|
|
99
|
-
showStatusCommand ||
|
|
100
|
-
showLoginCommand ||
|
|
101
|
-
showPluginManager ||
|
|
102
|
-
showModelSelector ||
|
|
103
|
-
showBackgroundTaskManager ||
|
|
104
|
-
showMcpManager ||
|
|
105
|
-
showAgentsManager ||
|
|
106
|
-
showWorkflowManager) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
await handleInput(input, key);
|
|
110
|
-
});
|
|
111
|
-
const handleRewindCancel = () => {
|
|
112
|
-
if (setShowRewindManager) {
|
|
113
|
-
setShowRewindManager(false);
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const isPlaceholder = !inputText;
|
|
117
|
-
const placeholderText = INPUT_PLACEHOLDER_TEXT;
|
|
118
|
-
const isShellCommand = inputText?.startsWith("!") && !inputText.includes("\n");
|
|
119
|
-
// handleCommandSelectorInsert is already memoized in useInputManager, no need to wrap again
|
|
120
|
-
// Split text into three parts: before cursor, cursor position, after cursor
|
|
121
|
-
const displayText = isPlaceholder ? placeholderText : inputText;
|
|
122
|
-
const beforeCursor = displayText.substring(0, cursorPosition);
|
|
123
|
-
const atCursor = cursorPosition < displayText.length ? displayText[cursorPosition] : " ";
|
|
124
|
-
const afterCursor = displayText.substring(cursorPosition + 1);
|
|
125
|
-
// Always show cursor, allow user to continue input during memory mode
|
|
126
|
-
const shouldShowCursor = true;
|
|
127
|
-
// Only show the Box after InputManager is created on first mount
|
|
128
|
-
if (!isManagerReady) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
const handleRewindSelectWithClose = async (index) => {
|
|
132
|
-
if (setShowRewindManager) {
|
|
133
|
-
setShowRewindManager(false);
|
|
134
|
-
}
|
|
135
|
-
await handleRewindSelect(index);
|
|
136
|
-
};
|
|
137
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(BtwDisplay, { btwState: btwState }), showFileSelector && (_jsx(FileSelector, { files: filteredFiles, searchQuery: searchQuery, isLoading: isFileSearching, onSelect: handleFileSelect, onCancel: handleCancelFileSelect })), showCommandSelector && (_jsx(CommandSelector, { searchQuery: commandSearchQuery, onSelect: handleCommandSelect, onInsert: handleCommandInsert, onCancel: handleCancelCommandSelect, commands: slashCommands })), showHistorySearch && (_jsx(HistorySearch, { searchQuery: historySearchQuery, onSelect: handleHistorySearchSelect, onCancel: handleCancelHistorySearch })), showBackgroundTaskManager && (_jsx(BackgroundTaskManager, { onCancel: () => setShowBackgroundTaskManager(false) })), showMcpManager && (_jsx(McpManager, { onCancel: () => setShowMcpManager(false), servers: mcpServers, onConnectServer: connectMcpServer, onDisconnectServer: disconnectMcpServer })), showAgentsManager && (_jsx(AgentsManager, { onCancel: () => setShowAgentsManager(false), agentDefinitions: agentDefinitions })), showWorkflowManager && (_jsx(WorkflowManager, { onCancel: () => setShowWorkflowManager(false) })), showRewindManager && (_jsx(RewindCommand, { messages: messages, onSelect: handleRewindSelectWithClose, onCancel: handleRewindCancel, getFullMessageThread: getFullMessageThread })), showHelp && (_jsx(HelpView, { onCancel: () => setShowHelp(false), commands: slashCommands })), showStatusCommand && (_jsx(StatusCommand, { onCancel: () => setShowStatusCommand(false) })), showLoginCommand && (_jsx(LoginCommand, { onCancel: () => setShowLoginCommand(false) })), showPluginManager && (_jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false), onPluginInstalled: recreateAgent })), showModelSelector && (_jsx(ModelSelector, { onCancel: () => setShowModelSelector(false), currentModel: currentModel, configuredModels: configuredModels, onSelectModel: setModel })), btwState.question || btwState.answer
|
|
138
|
-
? null
|
|
139
|
-
: showBackgroundTaskManager ||
|
|
140
|
-
showMcpManager ||
|
|
141
|
-
showAgentsManager ||
|
|
142
|
-
showRewindManager ||
|
|
143
|
-
showHelp ||
|
|
144
|
-
showStatusCommand ||
|
|
145
|
-
showLoginCommand ||
|
|
146
|
-
showPluginManager ||
|
|
147
|
-
showModelSelector ||
|
|
148
|
-
showWorkflowManager || (_jsxs(Box, { flexDirection: "column", children: [escClearPending && _jsx(Text, { color: "gray", children: "\u518D\u6B21\u6309 Esc \u6E05\u7A7A\u8F93\u5165" }), _jsx(Box, { borderStyle: "single", borderColor: "gray", borderLeft: false, borderRight: false, children: _jsx(Text, { color: isPlaceholder ? "gray" : "white", children: shouldShowCursor ? (_jsxs(_Fragment, { children: [beforeCursor, _jsx(Text, { backgroundColor: "white", color: "black", children: atCursor }), afterCursor] })) : (displayText) }) }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(StatusLine, { permissionMode: permissionMode, isShellCommand: isShellCommand }), _jsx(Notifications, { latestTotalTokens: latestTotalTokens, maxInputTokens: maxInputTokens, showLoginHint: showLoginHint })] })] }))] }));
|
|
149
|
-
};
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useReducer, useEffect } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
|
|
5
|
-
import { selectorReducer, } from "../reducers/selectorReducer.js";
|
|
6
|
-
export const InstalledView = () => {
|
|
7
|
-
const { installedPlugins, actions } = usePluginManagerContext();
|
|
8
|
-
const [state, dispatch] = useReducer((selectorReducer), {
|
|
9
|
-
selectedIndex: 0,
|
|
10
|
-
pendingDecision: null,
|
|
11
|
-
items: [],
|
|
12
|
-
});
|
|
13
|
-
const { selectedIndex, pendingDecision, items } = state;
|
|
14
|
-
// Sync plugins into reducer state
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
dispatch({ type: "SET_ITEMS", items: installedPlugins });
|
|
17
|
-
}, [installedPlugins]);
|
|
18
|
-
useInput((_input, key) => {
|
|
19
|
-
dispatch({
|
|
20
|
-
type: "HANDLE_KEY",
|
|
21
|
-
key,
|
|
22
|
-
hasInsert: false,
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
useEffect(() => {
|
|
26
|
-
if (pendingDecision === "select") {
|
|
27
|
-
const plugin = items[selectedIndex];
|
|
28
|
-
if (plugin) {
|
|
29
|
-
actions.setSelectedId(`${plugin.name}@${plugin.marketplace}`);
|
|
30
|
-
actions.setView("PLUGIN_DETAIL");
|
|
31
|
-
}
|
|
32
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
33
|
-
}
|
|
34
|
-
}, [pendingDecision, selectedIndex, items, actions]);
|
|
35
|
-
if (installedPlugins.length === 0) {
|
|
36
|
-
return (_jsx(Box, { padding: 1, children: _jsx(Text, { dimColor: true, children: "No plugins installed." }) }));
|
|
37
|
-
}
|
|
38
|
-
const MAX_VISIBLE_ITEMS = 3;
|
|
39
|
-
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, installedPlugins.length - MAX_VISIBLE_ITEMS)));
|
|
40
|
-
const visiblePlugins = installedPlugins.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
|
|
41
|
-
return (_jsx(Box, { flexDirection: "column", children: visiblePlugins.map((plugin, index) => {
|
|
42
|
-
const isSelected = index + startIndex === selectedIndex;
|
|
43
|
-
return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] }), plugin.scope && _jsxs(Text, { color: "gray", children: [" (", plugin.scope, ")"] })] }) }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { dimColor: true, children: "Press Enter for actions" }) }))] }, `${plugin.name}@${plugin.marketplace}`));
|
|
44
|
-
}) }));
|
|
45
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface LoadingIndicatorProps {
|
|
2
|
-
isLoading?: boolean;
|
|
3
|
-
isCommandRunning?: boolean;
|
|
4
|
-
isCompacting?: boolean;
|
|
5
|
-
latestTotalTokens?: number;
|
|
6
|
-
}
|
|
7
|
-
export declare const LoadingIndicator: {
|
|
8
|
-
({ isLoading, isCommandRunning, isCompacting, latestTotalTokens, }: LoadingIndicatorProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
displayName: string;
|
|
10
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
export const LoadingIndicator = ({ isLoading = false, isCommandRunning = false, isCompacting = false, latestTotalTokens = 0, }) => {
|
|
4
|
-
return (_jsxs(Box, { flexDirection: "column", children: [isLoading && !isCompacting && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "\u273B AI is thinking... " }), latestTotalTokens > 0 && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "blue", bold: true, children: latestTotalTokens.toLocaleString() }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "tokens", " "] })] })), _jsxs(Text, { color: "gray", dimColor: true, children: ["|", " "] }), _jsx(Text, { color: "red", bold: true, children: "Esc" }), _jsxs(Text, { color: "gray", dimColor: true, children: [" ", "to abort"] })] })), isCommandRunning && _jsx(Text, { color: "blue", children: "\u273B Command is running..." }), isCompacting && (_jsx(Text, { color: "magenta", children: "\u273B Compacting message history..." }))] }));
|
|
5
|
-
};
|
|
6
|
-
LoadingIndicator.displayName = "LoadingIndicator";
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useState } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { execFile } from "child_process";
|
|
5
|
-
import { promisify } from "util";
|
|
6
|
-
import { authService } from "wave-agent-sdk";
|
|
7
|
-
import { createBracketedPasteDetector } from "../utils/bracketedPaste.js";
|
|
8
|
-
const execFileAsync = promisify(execFile);
|
|
9
|
-
function openBrowser(url) {
|
|
10
|
-
const platform = process.platform;
|
|
11
|
-
if (platform === "darwin") {
|
|
12
|
-
execFileAsync("open", [url]).catch(() => { });
|
|
13
|
-
}
|
|
14
|
-
else if (platform === "win32") {
|
|
15
|
-
execFileAsync("cmd", ["/c", "start", "", url]).catch(() => { });
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
execFileAsync("xdg-open", [url]).catch(() => { });
|
|
19
|
-
}
|
|
20
|
-
// Failures are ignored — URL is still displayed in the UI for manual copy
|
|
21
|
-
}
|
|
22
|
-
export const LoginCommand = ({ onCancel }) => {
|
|
23
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
24
|
-
const [message, setMessage] = useState("");
|
|
25
|
-
const [error, setError] = useState("");
|
|
26
|
-
const [authUrl, setAuthUrl] = useState("");
|
|
27
|
-
const [tokenInput, setTokenInput] = useState("");
|
|
28
|
-
const isLoadingRef = useRef(isLoading);
|
|
29
|
-
isLoadingRef.current = isLoading;
|
|
30
|
-
// Detects and strips bracketed paste markers (\x1b[200~ ... \x1b[201~)
|
|
31
|
-
// that terminals wrap pasted text in. Unlike the main InputBox pipeline,
|
|
32
|
-
// this overlay's token input goes through raw ink useInput, which only
|
|
33
|
-
// strips ONE leading ESC, leaving the markers (e.g. "[200~") in the input.
|
|
34
|
-
const pasteDetectorRef = useRef(createBracketedPasteDetector());
|
|
35
|
-
// Resolve/reject refs for the token promise
|
|
36
|
-
const tokenResolveRef = useRef(null);
|
|
37
|
-
const tokenRejectRef = useRef(null);
|
|
38
|
-
// Single useInput handler — branches on isLoading to avoid the
|
|
39
|
-
// isActive transition race that drops stdin between hook swaps.
|
|
40
|
-
useInput((input, key) => {
|
|
41
|
-
if (!isLoadingRef.current) {
|
|
42
|
-
// Pre-loading mode: Enter starts login, Esc cancels
|
|
43
|
-
if (key.escape) {
|
|
44
|
-
onCancel();
|
|
45
|
-
}
|
|
46
|
-
if (key.return) {
|
|
47
|
-
handleEnter();
|
|
48
|
-
}
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
// Token input mode: capture keystrokes while loading
|
|
52
|
-
if (key.escape) {
|
|
53
|
-
tokenRejectRef.current?.(new Error("cancelled"));
|
|
54
|
-
onCancel();
|
|
55
|
-
}
|
|
56
|
-
if (key.return) {
|
|
57
|
-
// Submit token
|
|
58
|
-
const trimmed = tokenInput.trim();
|
|
59
|
-
if (trimmed) {
|
|
60
|
-
tokenResolveRef.current?.(trimmed);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
// Empty: just clear, keep waiting
|
|
64
|
-
setTokenInput("");
|
|
65
|
-
}
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
// Backspace
|
|
69
|
-
if (key.backspace && tokenInput.length > 0) {
|
|
70
|
-
setTokenInput((prev) => prev.slice(0, -1));
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
// Regular character input (single or pasted multi-char). Run through the
|
|
74
|
-
// bracketed paste detector: a pasted token arrives wrapped in
|
|
75
|
-
// \x1b[200~ ... \x1b[201~ markers (possibly split across chunks), which
|
|
76
|
-
// must be stripped instead of being appended to the token.
|
|
77
|
-
if (input && !key.ctrl && !key.meta && !key.return && input.length > 0) {
|
|
78
|
-
const result = pasteDetectorRef.current.process(input);
|
|
79
|
-
if (result.kind === "consume") {
|
|
80
|
-
// In-flight bracketed paste content: hold it; the final chunk
|
|
81
|
-
// delivers the complete text.
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (result.kind === "paste") {
|
|
85
|
-
// Tokens never contain carriage returns — drop \r (CRLF terminals
|
|
86
|
-
// send \r, not \n, in pasted text).
|
|
87
|
-
const leading = result.leadingInput?.replace(/\r/g, "");
|
|
88
|
-
if (leading) {
|
|
89
|
-
setTokenInput((prev) => prev + leading);
|
|
90
|
-
}
|
|
91
|
-
const text = result.text.replace(/\r/g, "");
|
|
92
|
-
if (text) {
|
|
93
|
-
setTokenInput((prev) => prev + text);
|
|
94
|
-
}
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
setTokenInput((prev) => prev + result.input);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
const handleEnter = async () => {
|
|
101
|
-
if (isLoadingRef.current)
|
|
102
|
-
return;
|
|
103
|
-
// A stale-but-present SSO token still counts as logged in; it refreshes
|
|
104
|
-
// lazily on the next API call. Enter toggles logout only when a token exists.
|
|
105
|
-
const isAuthenticated = Boolean(authService.getSSOToken());
|
|
106
|
-
if (isAuthenticated) {
|
|
107
|
-
await authService.clearAuth();
|
|
108
|
-
setMessage("Logged out successfully");
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
setIsLoading(true);
|
|
112
|
-
setError("");
|
|
113
|
-
setAuthUrl("");
|
|
114
|
-
setTokenInput("");
|
|
115
|
-
pasteDetectorRef.current.reset();
|
|
116
|
-
setMessage("Starting authentication...");
|
|
117
|
-
// Promise that resolves when user presses Enter with token input
|
|
118
|
-
const readToken = () => new Promise((resolve, reject) => {
|
|
119
|
-
tokenResolveRef.current = resolve;
|
|
120
|
-
tokenRejectRef.current = reject;
|
|
121
|
-
});
|
|
122
|
-
try {
|
|
123
|
-
await authService.login({
|
|
124
|
-
onAuthUrl: (url) => {
|
|
125
|
-
setAuthUrl(url);
|
|
126
|
-
openBrowser(url);
|
|
127
|
-
setMessage("Paste the authorization code from your browser URL bar:");
|
|
128
|
-
},
|
|
129
|
-
readToken,
|
|
130
|
-
});
|
|
131
|
-
setMessage("Login successful");
|
|
132
|
-
}
|
|
133
|
-
catch (err) {
|
|
134
|
-
const errMessage = err.message;
|
|
135
|
-
if (errMessage !== "cancelled") {
|
|
136
|
-
setError(errMessage);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
tokenResolveRef.current = null;
|
|
141
|
-
tokenRejectRef.current = null;
|
|
142
|
-
setTokenInput("");
|
|
143
|
-
setIsLoading(false);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
const isAuthenticated = Boolean(authService.getSSOToken());
|
|
147
|
-
const token = authService.getSSOToken();
|
|
148
|
-
const serverUrl = authService.getServerUrl();
|
|
149
|
-
const truncatedToken = token && token.length > 14
|
|
150
|
-
? `${token.substring(0, 10)}...${token.substring(token.length - 4)}`
|
|
151
|
-
: (token ?? "");
|
|
152
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, underline: true, children: "SSO Authentication" }) }), error && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", children: error }) })), message && !error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: isLoading ? "yellow" : "green", children: [isLoading ? "⌛ " : "", message] }) })), authUrl && isLoading && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: "Open this URL in your browser:" }), _jsx(Text, { color: "white", children: authUrl })] })), isLoading && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: "Code: " }), _jsx(Text, { color: "white", children: tokenInput || "..." })] })), !isAuthenticated && !isLoading && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Status:" }), _jsx(Text, { color: "white", children: " Not logged in" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to login" }) })] })), isAuthenticated && !isLoading && !message && (_jsxs(_Fragment, { children: [_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Status:" }), _jsx(Text, { color: "green", children: " Authenticated" })] }), _jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Token:" }), _jsxs(Text, { color: "white", children: [" ", truncatedToken] })] }), serverUrl && (_jsxs(Box, { children: [_jsx(Text, { color: "yellow", children: "Server URL:" }), _jsxs(Text, { color: "white", children: [" ", serverUrl] })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to logout" }) })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Esc to cancel" }) })] }));
|
|
153
|
-
};
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import React, { useMemo } from "react";
|
|
3
|
-
import { Box, Text, useStdout } from "ink";
|
|
4
|
-
import { Renderer, marked } from "marked";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import { highlightToAnsi } from "../utils/highlightUtils.js";
|
|
7
|
-
import { renderMarkdownTable } from "../utils/markdownTable.js";
|
|
8
|
-
const unescapeHtml = (html) => {
|
|
9
|
-
return html
|
|
10
|
-
.replace(/&/g, "&")
|
|
11
|
-
.replace(/</g, "<")
|
|
12
|
-
.replace(/>/g, ">")
|
|
13
|
-
.replace(/"/g, '"')
|
|
14
|
-
.replace(/'/g, "'")
|
|
15
|
-
.replace(/'/g, "'");
|
|
16
|
-
};
|
|
17
|
-
class AnsiRenderer extends Renderer {
|
|
18
|
-
constructor(columns) {
|
|
19
|
-
super();
|
|
20
|
-
this.columns = columns;
|
|
21
|
-
}
|
|
22
|
-
code({ text, lang }) {
|
|
23
|
-
const prefix = lang ? `\`\`\`${lang}` : "```";
|
|
24
|
-
const suffix = "```";
|
|
25
|
-
const highlighted = highlightToAnsi(text, lang);
|
|
26
|
-
return `\n${chalk.gray(prefix)}\n${highlighted}\n${chalk.gray(suffix)}\n`;
|
|
27
|
-
}
|
|
28
|
-
blockquote({ tokens }) {
|
|
29
|
-
const body = this.parser.parse(tokens);
|
|
30
|
-
return ("\n" +
|
|
31
|
-
body
|
|
32
|
-
.trim()
|
|
33
|
-
.split("\n")
|
|
34
|
-
.map((line) => chalk.gray("> ") + line)
|
|
35
|
-
.join("\n") +
|
|
36
|
-
"\n");
|
|
37
|
-
}
|
|
38
|
-
heading({ tokens, depth }) {
|
|
39
|
-
const text = this.parser.parseInline(tokens);
|
|
40
|
-
const hashes = "#".repeat(depth);
|
|
41
|
-
return `\n${chalk.cyan(`${hashes} ${text}`)}\n`;
|
|
42
|
-
}
|
|
43
|
-
hr() {
|
|
44
|
-
return `\n${chalk.gray("─".repeat(20))}\n`;
|
|
45
|
-
}
|
|
46
|
-
list(token) {
|
|
47
|
-
const body = token.items
|
|
48
|
-
.map((item, i) => {
|
|
49
|
-
const text = this.listitem(item);
|
|
50
|
-
const prefix = token.ordered
|
|
51
|
-
? chalk.gray(`${(token.start || 1) + i}. `)
|
|
52
|
-
: chalk.gray("• ");
|
|
53
|
-
const lines = text.split("\n");
|
|
54
|
-
const firstLine = prefix + lines[0];
|
|
55
|
-
const restLines = lines
|
|
56
|
-
.slice(1)
|
|
57
|
-
.filter((line) => line.length > 0)
|
|
58
|
-
.map((line) => " " + line);
|
|
59
|
-
return [firstLine, ...restLines].join("\n") + "\n";
|
|
60
|
-
})
|
|
61
|
-
.join("");
|
|
62
|
-
return `\n${body}`;
|
|
63
|
-
}
|
|
64
|
-
listitem(item) {
|
|
65
|
-
return `${this.parser.parse(item.tokens).trim()}\n`;
|
|
66
|
-
}
|
|
67
|
-
checkbox({ checked }) {
|
|
68
|
-
return checked ? chalk.green("[x] ") : chalk.gray("[ ] ");
|
|
69
|
-
}
|
|
70
|
-
paragraph({ tokens }) {
|
|
71
|
-
const text = this.parser.parseInline(tokens);
|
|
72
|
-
return `\n${text}\n`;
|
|
73
|
-
}
|
|
74
|
-
table(token) {
|
|
75
|
-
const table = renderMarkdownTable(token, this.columns, (tokens) => this.parser.parseInline(tokens));
|
|
76
|
-
return `\n${table}\n`;
|
|
77
|
-
}
|
|
78
|
-
strong({ tokens }) {
|
|
79
|
-
const text = this.parser.parseInline(tokens);
|
|
80
|
-
return chalk.bold(text);
|
|
81
|
-
}
|
|
82
|
-
em({ tokens }) {
|
|
83
|
-
const text = this.parser.parseInline(tokens);
|
|
84
|
-
return chalk.italic(text);
|
|
85
|
-
}
|
|
86
|
-
codespan({ text }) {
|
|
87
|
-
return chalk.yellow(text);
|
|
88
|
-
}
|
|
89
|
-
br() {
|
|
90
|
-
return "\n";
|
|
91
|
-
}
|
|
92
|
-
del({ tokens }) {
|
|
93
|
-
const text = this.parser.parseInline(tokens);
|
|
94
|
-
return chalk.strikethrough(text);
|
|
95
|
-
}
|
|
96
|
-
link({ href, tokens }) {
|
|
97
|
-
const text = this.parser.parseInline(tokens);
|
|
98
|
-
const linkText = chalk.blue.underline(text);
|
|
99
|
-
const hrefText = chalk.gray(`(${href})`);
|
|
100
|
-
return `${linkText} ${hrefText}`;
|
|
101
|
-
}
|
|
102
|
-
image({ href, tokens, text }) {
|
|
103
|
-
const alt = this.parser.parseInline(tokens) || text;
|
|
104
|
-
return chalk.gray(``);
|
|
105
|
-
}
|
|
106
|
-
text(token) {
|
|
107
|
-
return "tokens" in token && token.tokens
|
|
108
|
-
? this.parser.parseInline(token.tokens)
|
|
109
|
-
: unescapeHtml(token.text);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const createRenderer = (columns) => new AnsiRenderer(columns);
|
|
113
|
-
// Markdown component using custom ANSI renderer
|
|
114
|
-
export const Markdown = React.memo(({ children }) => {
|
|
115
|
-
const { stdout } = useStdout();
|
|
116
|
-
const columns = stdout?.columns ?? 80;
|
|
117
|
-
const ansiContent = useMemo(() => {
|
|
118
|
-
return marked.parse(children, {
|
|
119
|
-
renderer: createRenderer(columns),
|
|
120
|
-
gfm: true,
|
|
121
|
-
breaks: true,
|
|
122
|
-
});
|
|
123
|
-
}, [children, columns]);
|
|
124
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { children: ansiContent.trim() }) }));
|
|
125
|
-
});
|
|
126
|
-
// Add display name for debugging
|
|
127
|
-
Markdown.displayName = "Markdown";
|