wave-code 1.0.10 → 1.1.1
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 +3231 -0
- package/package.json +24 -25
- package/src/cli.tsx +6 -1
- 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 +17 -2
- 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/SkillsManager.tsx +312 -0
- package/src/components/StatusCommand.tsx +2 -9
- package/src/components/ToolDisplay.tsx +2 -4
- package/src/constants/commands.ts +6 -0
- package/src/contexts/useChat.tsx +245 -301
- 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 +7 -1
- package/src/index.ts +57 -10
- package/src/managers/inputHandlers.ts +2 -0
- package/src/managers/inputReducer.ts +195 -104
- package/src/print-cli.ts +25 -17
- package/src/reducers/selectorReducer.ts +10 -0
- package/src/reducers/skillsManagerReducer.ts +91 -0
- package/src/session-selector-cli.tsx +269 -28
- package/src/stdio/agentBridge.ts +30 -21
- package/src/stdio/daemonServer.ts +3 -1
- package/src/stdio/protocol.ts +2 -0
- 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,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { Box, Text } from "ink";
|
|
4
|
-
export const CompactDisplay = ({ block }) => {
|
|
5
|
-
const { content } = block;
|
|
6
|
-
const { displayContent } = useMemo(() => {
|
|
7
|
-
if (!content) {
|
|
8
|
-
return { displayContent: "" };
|
|
9
|
-
}
|
|
10
|
-
return { displayContent: content };
|
|
11
|
-
}, [content]);
|
|
12
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { children: "Compacted Messages" }) }), content && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: _jsx(Text, { color: "white", children: displayContent }) }) }))] }));
|
|
13
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
export interface ConfirmationDetailsProps {
|
|
3
|
-
toolName: string;
|
|
4
|
-
toolInput?: Record<string, unknown>;
|
|
5
|
-
planContent?: string;
|
|
6
|
-
warning?: string;
|
|
7
|
-
isExpanded?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare const ConfirmationDetails: React.FC<ConfirmationDetailsProps>;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from "ink";
|
|
3
|
-
import { BASH_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, ARTIFACT_TOOL_NAME, } from "wave-agent-sdk";
|
|
4
|
-
import { DiffDisplay } from "./DiffDisplay.js";
|
|
5
|
-
import { PlanDisplay } from "./PlanDisplay.js";
|
|
6
|
-
import { highlightToAnsi } from "../utils/highlightUtils.js";
|
|
7
|
-
// Helper function to generate descriptive action text
|
|
8
|
-
const getActionDescription = (toolName, toolInput) => {
|
|
9
|
-
if (!toolInput) {
|
|
10
|
-
return "Execute operation";
|
|
11
|
-
}
|
|
12
|
-
switch (toolName) {
|
|
13
|
-
case BASH_TOOL_NAME:
|
|
14
|
-
return `Execute command: ${toolInput.command || "unknown command"}`;
|
|
15
|
-
case EDIT_TOOL_NAME:
|
|
16
|
-
return `Edit file: ${toolInput.file_path || "unknown file"}`;
|
|
17
|
-
case WRITE_TOOL_NAME:
|
|
18
|
-
return `Write to file: ${toolInput.file_path || "unknown file"}`;
|
|
19
|
-
case EXIT_PLAN_MODE_TOOL_NAME:
|
|
20
|
-
return "Review and approve the plan";
|
|
21
|
-
case ENTER_PLAN_MODE_TOOL_NAME:
|
|
22
|
-
return "Enter plan mode for complex task planning";
|
|
23
|
-
case ASK_USER_QUESTION_TOOL_NAME:
|
|
24
|
-
return "Answer questions to clarify intent";
|
|
25
|
-
case ARTIFACT_TOOL_NAME:
|
|
26
|
-
return `Publish file: ${toolInput.file_path || "unknown file"}`;
|
|
27
|
-
default:
|
|
28
|
-
return "Execute operation";
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
export const ConfirmationDetails = ({ toolName, toolInput, planContent, warning, isExpanded = false, }) => {
|
|
32
|
-
const startLineNumber = toolInput?.startLineNumber ??
|
|
33
|
-
(toolName === WRITE_TOOL_NAME ? 1 : undefined);
|
|
34
|
-
const content = (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["Tool: ", toolName] }), _jsx(Text, { color: "yellow", children: getActionDescription(toolName, toolInput) }), warning && _jsxs(Text, { color: "red", children: ["\u26A0 ", warning] }), _jsx(DiffDisplay, { toolName: toolName, parameters: JSON.stringify(toolInput), startLineNumber: startLineNumber }), toolName !== WRITE_TOOL_NAME &&
|
|
35
|
-
toolName !== EDIT_TOOL_NAME &&
|
|
36
|
-
toolName !== EXIT_PLAN_MODE_TOOL_NAME &&
|
|
37
|
-
toolName !== ENTER_PLAN_MODE_TOOL_NAME &&
|
|
38
|
-
toolName !== ASK_USER_QUESTION_TOOL_NAME &&
|
|
39
|
-
toolName !== BASH_TOOL_NAME &&
|
|
40
|
-
!!toolInput && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", children: _jsx(Text, { children: highlightToAnsi(JSON.stringify(toolInput, null, 2), "json") }) })), toolName !== ASK_USER_QUESTION_TOOL_NAME &&
|
|
41
|
-
toolName === EXIT_PLAN_MODE_TOOL_NAME &&
|
|
42
|
-
!!planContent && (_jsx(PlanDisplay, { plan: planContent, isExpanded: isExpanded }))] }));
|
|
43
|
-
return content;
|
|
44
|
-
};
|
|
45
|
-
ConfirmationDetails.displayName = "ConfirmationDetails";
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { PermissionDecision, PermissionMode } from "wave-agent-sdk";
|
|
3
|
-
export interface ConfirmationSelectorProps {
|
|
4
|
-
toolName: string;
|
|
5
|
-
toolInput?: Record<string, unknown>;
|
|
6
|
-
suggestedPrefix?: string;
|
|
7
|
-
hidePersistentOption?: boolean;
|
|
8
|
-
permissionMode?: PermissionMode;
|
|
9
|
-
isExpanded?: boolean;
|
|
10
|
-
onDecision: (decision: PermissionDecision) => void;
|
|
11
|
-
onCancel: () => void;
|
|
12
|
-
}
|
|
13
|
-
export declare const ConfirmationSelector: React.FC<ConfirmationSelectorProps>;
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useReducer, useRef } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { BASH_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "wave-agent-sdk";
|
|
5
|
-
import { confirmationReducer } from "../reducers/confirmationReducer.js";
|
|
6
|
-
import { questionReducer } from "../reducers/questionReducer.js";
|
|
7
|
-
import { createBracketedPasteDetector } from "../utils/bracketedPaste.js";
|
|
8
|
-
const getHeaderColor = (header) => {
|
|
9
|
-
const colors = ["red", "green", "blue", "magenta", "cyan"];
|
|
10
|
-
let hash = 0;
|
|
11
|
-
for (let i = 0; i < header.length; i++) {
|
|
12
|
-
hash = header.charCodeAt(i) + ((hash << 5) - hash);
|
|
13
|
-
}
|
|
14
|
-
return colors[Math.abs(hash) % colors.length];
|
|
15
|
-
};
|
|
16
|
-
export const ConfirmationSelector = ({ toolName, toolInput, suggestedPrefix, hidePersistentOption, permissionMode, isExpanded = false, onDecision, onCancel, }) => {
|
|
17
|
-
const [state, dispatch] = useReducer(confirmationReducer, {
|
|
18
|
-
selectedOption: "allow",
|
|
19
|
-
alternativeText: "",
|
|
20
|
-
alternativeCursorPosition: 0,
|
|
21
|
-
hasUserInput: false,
|
|
22
|
-
decision: null,
|
|
23
|
-
});
|
|
24
|
-
const questions = toolInput?.questions || [];
|
|
25
|
-
const [questionState, questionDispatch] = useReducer(questionReducer, {
|
|
26
|
-
currentQuestionIndex: 0,
|
|
27
|
-
selectedOptionIndex: 0,
|
|
28
|
-
selectedOptionIndices: new Set(),
|
|
29
|
-
userAnswers: {},
|
|
30
|
-
otherText: "",
|
|
31
|
-
otherCursorPosition: 0,
|
|
32
|
-
savedStates: {},
|
|
33
|
-
decision: null,
|
|
34
|
-
});
|
|
35
|
-
// Handle decisions from reducers
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
if (state.decision) {
|
|
38
|
-
onDecision(state.decision);
|
|
39
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
40
|
-
}
|
|
41
|
-
}, [state.decision, onDecision]);
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (questionState.decision) {
|
|
44
|
-
onDecision(questionState.decision);
|
|
45
|
-
questionDispatch({ type: "CLEAR_DECISION" });
|
|
46
|
-
}
|
|
47
|
-
}, [questionState.decision, onDecision]);
|
|
48
|
-
const currentQuestion = questions[questionState.currentQuestionIndex];
|
|
49
|
-
const getAutoOptionText = () => {
|
|
50
|
-
if (toolName === EXIT_PLAN_MODE_TOOL_NAME) {
|
|
51
|
-
return "Yes, auto-accept edits";
|
|
52
|
-
}
|
|
53
|
-
if (toolName === BASH_TOOL_NAME) {
|
|
54
|
-
const command = toolInput?.command || "";
|
|
55
|
-
if (command.trim().startsWith("mkdir")) {
|
|
56
|
-
return "Yes, and auto-accept edits";
|
|
57
|
-
}
|
|
58
|
-
if (suggestedPrefix) {
|
|
59
|
-
return `Yes, and don't ask again for: ${suggestedPrefix}`;
|
|
60
|
-
}
|
|
61
|
-
return "Yes, and don't ask again for this command in this workdir";
|
|
62
|
-
}
|
|
63
|
-
if (toolName.startsWith("mcp__")) {
|
|
64
|
-
return `Yes, and don't ask again for: ${toolName}`;
|
|
65
|
-
}
|
|
66
|
-
return "Yes, and auto-accept edits";
|
|
67
|
-
};
|
|
68
|
-
const pasteDetectorRef = useRef(createBracketedPasteDetector());
|
|
69
|
-
useInput((input, key) => {
|
|
70
|
-
if (key.escape) {
|
|
71
|
-
onCancel();
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const result = pasteDetectorRef.current.process(input);
|
|
75
|
-
if (result.kind === "consume") {
|
|
76
|
-
// Content of an in-flight bracketed paste: hold it, never submit.
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
let cleanInput;
|
|
80
|
-
if (result.kind === "paste") {
|
|
81
|
-
cleanInput = (result.leadingInput ?? "") + result.text;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
cleanInput = result.input;
|
|
85
|
-
}
|
|
86
|
-
if (toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
87
|
-
questionDispatch({
|
|
88
|
-
type: "HANDLE_KEY",
|
|
89
|
-
input: cleanInput,
|
|
90
|
-
key,
|
|
91
|
-
questions,
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
dispatch({
|
|
96
|
-
type: "HANDLE_KEY",
|
|
97
|
-
input: cleanInput,
|
|
98
|
-
key,
|
|
99
|
-
toolName,
|
|
100
|
-
toolInput,
|
|
101
|
-
suggestedPrefix,
|
|
102
|
-
hidePersistentOption,
|
|
103
|
-
permissionMode,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
const placeholderText = "Type here to tell Wave what to change";
|
|
108
|
-
const showPlaceholder = state.selectedOption === "alternative" && !state.hasUserInput;
|
|
109
|
-
return (_jsxs(Box, { flexDirection: "column", children: [toolName === ASK_USER_QUESTION_TOOL_NAME &&
|
|
110
|
-
currentQuestion &&
|
|
111
|
-
!isExpanded && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: getHeaderColor(currentQuestion.header), bold: true, children: currentQuestion.header.slice(0, 12).toUpperCase() }), _jsx(Box, { marginLeft: 1, children: _jsx(Text, { bold: true, children: currentQuestion.question }) })] }), _jsx(Box, { flexDirection: "column", children: [...currentQuestion.options, { label: "Other" }].map((option, index) => {
|
|
112
|
-
const isSelected = questionState.selectedOptionIndex === index;
|
|
113
|
-
const isChecked = currentQuestion.multiSelect
|
|
114
|
-
? questionState.selectedOptionIndices.has(index)
|
|
115
|
-
: isSelected;
|
|
116
|
-
const isOther = index === currentQuestion.options.length;
|
|
117
|
-
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "yellow" : undefined, children: [isSelected ? "> " : " ", currentQuestion.multiSelect
|
|
118
|
-
? isChecked
|
|
119
|
-
? "[x] "
|
|
120
|
-
: "[ ] "
|
|
121
|
-
: "", option.label, option.description ? ` - ${option.description}` : "", isOther && isSelected && (_jsxs(Text, { children: [":", " ", questionState.otherText ? (_jsxs(_Fragment, { children: [questionState.otherText.slice(0, questionState.otherCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: questionState.otherText[questionState.otherCursorPosition] || " " }), questionState.otherText.slice(questionState.otherCursorPosition + 1)] })) : (_jsx(Text, { color: "gray", dimColor: true, children: "[Type your answer...]" }))] }))] }) }, index));
|
|
122
|
-
}) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Question ", questionState.currentQuestionIndex + 1, " of", " ", questions.length, " \u2022", currentQuestion.multiSelect ? " Space to toggle •" : "", " Use \u2191\u2193 or Tab to navigate \u2022 Enter to confirm"] }) })] })), toolName !== ASK_USER_QUESTION_TOOL_NAME && !isExpanded && (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Do you want to proceed?" }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "allow" ? "black" : "white", backgroundColor: state.selectedOption === "allow" ? "yellow" : undefined, bold: state.selectedOption === "allow", children: [state.selectedOption === "allow" ? "> " : " ", toolName === EXIT_PLAN_MODE_TOOL_NAME
|
|
123
|
-
? "Yes, manually approve edits"
|
|
124
|
-
: "Yes, proceed"] }) }, "allow-option"), !hidePersistentOption && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "auto" ? "black" : "white", backgroundColor: state.selectedOption === "auto" ? "yellow" : undefined, bold: state.selectedOption === "auto", children: [state.selectedOption === "auto" ? "> " : " ", getAutoOptionText()] }) }, "auto-option")), (toolName === EXIT_PLAN_MODE_TOOL_NAME ||
|
|
125
|
-
(toolName === BASH_TOOL_NAME && permissionMode !== "plan")) && (_jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "bypass" ? "black" : "white", backgroundColor: state.selectedOption === "bypass" ? "yellow" : undefined, bold: state.selectedOption === "bypass", children: [state.selectedOption === "bypass" ? "> " : " ", "Yes, and bypass permissions"] }) }, "bypass-option")), _jsx(Box, { children: _jsxs(Text, { color: state.selectedOption === "alternative" ? "black" : "white", backgroundColor: state.selectedOption === "alternative" ? "yellow" : undefined, bold: state.selectedOption === "alternative", children: [state.selectedOption === "alternative" ? "> " : " ", toolName === ENTER_PLAN_MODE_TOOL_NAME && showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: "No, start implementing now" })) : showPlaceholder ? (_jsx(Text, { color: "gray", dimColor: true, children: placeholderText })) : (_jsx(Text, { children: state.alternativeText ? (_jsxs(_Fragment, { children: [state.alternativeText.slice(0, state.alternativeCursorPosition), _jsx(Text, { backgroundColor: "white", color: "black", children: state.alternativeText[state.alternativeCursorPosition] || " " }), state.alternativeText.slice(state.alternativeCursorPosition + 1)] })) : ("Type here to tell Wave what to change") }))] }) }, "alternative-option")] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Use \u2191\u2193 or Tab to navigate \u2022 ESC to cancel" }) })] }))] }));
|
|
126
|
-
};
|
|
127
|
-
ConfirmationSelector.displayName = "ConfirmationSelector";
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { Box, Text } from "ink";
|
|
4
|
-
import { WRITE_TOOL_NAME, EDIT_TOOL_NAME } from "wave-agent-sdk";
|
|
5
|
-
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
6
|
-
import { diffLines, diffWords } from "diff";
|
|
7
|
-
export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
|
|
8
|
-
const showDiff = toolName && [WRITE_TOOL_NAME, EDIT_TOOL_NAME].includes(toolName);
|
|
9
|
-
// Diff detection and transformation using typed parameters
|
|
10
|
-
const changes = useMemo(() => {
|
|
11
|
-
if (!showDiff || !toolName || !parameters)
|
|
12
|
-
return [];
|
|
13
|
-
try {
|
|
14
|
-
// Use local transformation with JSON parsing and type guards
|
|
15
|
-
return transformToolBlockToChanges(toolName, parameters, startLineNumber);
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
console.warn("Error transforming tool block to changes:", error);
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
}, [toolName, parameters, showDiff, startLineNumber]);
|
|
22
|
-
// Render word-level diff between two lines of text
|
|
23
|
-
const renderWordLevelDiff = (oldLine, newLine, keyPrefix) => {
|
|
24
|
-
try {
|
|
25
|
-
const changes = diffWords(oldLine, newLine);
|
|
26
|
-
const removedParts = [];
|
|
27
|
-
const addedParts = [];
|
|
28
|
-
changes.forEach((part, index) => {
|
|
29
|
-
if (part.removed) {
|
|
30
|
-
removedParts.push(_jsx(Text, { color: "black", backgroundColor: "red", children: part.value }, `removed-${keyPrefix}-${index}`));
|
|
31
|
-
}
|
|
32
|
-
else if (part.added) {
|
|
33
|
-
addedParts.push(_jsx(Text, { color: "black", backgroundColor: "green", children: part.value }, `added-${keyPrefix}-${index}`));
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
// Unchanged parts
|
|
37
|
-
removedParts.push(_jsx(Text, { color: "red", children: part.value }, `removed-unchanged-${keyPrefix}-${index}`));
|
|
38
|
-
addedParts.push(_jsx(Text, { color: "green", children: part.value }, `added-unchanged-${keyPrefix}-${index}`));
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return { removedParts, addedParts };
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
console.warn("Error rendering word-level diff:", error);
|
|
45
|
-
// Fallback to simple line display
|
|
46
|
-
return {
|
|
47
|
-
removedParts: [
|
|
48
|
-
_jsx(Text, { color: "red", children: oldLine }, `fallback-removed-${keyPrefix}`),
|
|
49
|
-
],
|
|
50
|
-
addedParts: [
|
|
51
|
-
_jsx(Text, { color: "green", children: newLine }, `fallback-added-${keyPrefix}`),
|
|
52
|
-
],
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
// Render expanded diff display
|
|
57
|
-
const renderExpandedDiff = () => {
|
|
58
|
-
try {
|
|
59
|
-
if (changes.length === 0)
|
|
60
|
-
return null;
|
|
61
|
-
const maxLineNum = changes.reduce((max, change) => {
|
|
62
|
-
const oldLines = (change.oldContent || "").split("\n").length;
|
|
63
|
-
const newLines = (change.newContent || "").split("\n").length;
|
|
64
|
-
const start = change.startLineNumber || 1;
|
|
65
|
-
// For Edit tool, the diff might show context lines before/after the change.
|
|
66
|
-
// The startLineNumber is the line where old_string starts.
|
|
67
|
-
// diffLines will include context lines if they are part of the change object.
|
|
68
|
-
// However, our transformEditParameters currently only puts old_string/new_string.
|
|
69
|
-
// If we ever support context lines in the Change object, we need to be careful.
|
|
70
|
-
return Math.max(max, start + oldLines, start + newLines);
|
|
71
|
-
}, 0);
|
|
72
|
-
const maxDigits = Math.max(2, maxLineNum.toString().length);
|
|
73
|
-
const renderLine = (oldLineNum, newLineNum, prefix, content, color, key) => {
|
|
74
|
-
const formatNum = (num) => num === null
|
|
75
|
-
? " ".repeat(maxDigits)
|
|
76
|
-
: num.toString().padStart(maxDigits);
|
|
77
|
-
return (_jsxs(Box, { flexDirection: "row", children: [_jsxs(Text, { color: "gray", children: [formatNum(oldLineNum), " "] }), _jsxs(Text, { color: "gray", children: [formatNum(newLineNum), " "] }), _jsx(Text, { color: "gray", children: "| " }), _jsx(Text, { color: color, children: prefix }), _jsx(Text, { color: color, children: content })] }, key));
|
|
78
|
-
};
|
|
79
|
-
const allElements = [];
|
|
80
|
-
changes.forEach((change, changeIndex) => {
|
|
81
|
-
try {
|
|
82
|
-
// Get line-level diff to understand the structure
|
|
83
|
-
const lineDiffs = diffLines(change.oldContent || "", change.newContent || "");
|
|
84
|
-
let oldLineNum = change.startLineNumber || 1;
|
|
85
|
-
let newLineNum = change.startLineNumber || 1;
|
|
86
|
-
// Process line diffs
|
|
87
|
-
const diffElements = [];
|
|
88
|
-
for (let i = 0; i < lineDiffs.length; i++) {
|
|
89
|
-
const part = lineDiffs[i];
|
|
90
|
-
const lines = part.value.split("\n");
|
|
91
|
-
// diffLines might return a trailing empty string if the content ends with a newline
|
|
92
|
-
if (lines[lines.length - 1] === "") {
|
|
93
|
-
lines.pop();
|
|
94
|
-
}
|
|
95
|
-
if (part.removed) {
|
|
96
|
-
// Look ahead for an added block
|
|
97
|
-
if (i + 1 < lineDiffs.length && lineDiffs[i + 1].added) {
|
|
98
|
-
const nextPart = lineDiffs[i + 1];
|
|
99
|
-
const addedLines = nextPart.value.split("\n");
|
|
100
|
-
if (addedLines[addedLines.length - 1] === "") {
|
|
101
|
-
addedLines.pop();
|
|
102
|
-
}
|
|
103
|
-
if (lines.length === addedLines.length) {
|
|
104
|
-
// Word-level diffing
|
|
105
|
-
lines.forEach((line, lineIndex) => {
|
|
106
|
-
const { removedParts, addedParts } = renderWordLevelDiff(line, addedLines[lineIndex], `word-${changeIndex}-${i}-${lineIndex}`);
|
|
107
|
-
diffElements.push(renderLine(oldLineNum++, null, "-", removedParts, "red", `remove-${changeIndex}-${i}-${lineIndex}`));
|
|
108
|
-
diffElements.push(renderLine(null, newLineNum++, "+", addedParts, "green", `add-${changeIndex}-${i}-${lineIndex}`));
|
|
109
|
-
});
|
|
110
|
-
i++; // Skip the added block
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// Fallback to standard removed rendering
|
|
115
|
-
lines.forEach((line, lineIndex) => {
|
|
116
|
-
diffElements.push(renderLine(oldLineNum++, null, "-", line, "red", `remove-${changeIndex}-${i}-${lineIndex}`));
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
else if (part.added) {
|
|
120
|
-
lines.forEach((line, lineIndex) => {
|
|
121
|
-
diffElements.push(renderLine(null, newLineNum++, "+", line, "green", `add-${changeIndex}-${i}-${lineIndex}`));
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// Context lines - show unchanged content
|
|
126
|
-
const isFirstBlock = i === 0;
|
|
127
|
-
const isLastBlock = i === lineDiffs.length - 1;
|
|
128
|
-
let linesToDisplay = lines;
|
|
129
|
-
let showEllipsisTop = false;
|
|
130
|
-
let showEllipsisBottom = false;
|
|
131
|
-
if (isFirstBlock && !isLastBlock) {
|
|
132
|
-
// First block: keep last 3
|
|
133
|
-
if (lines.length > 3) {
|
|
134
|
-
const skipCount = lines.length - 3;
|
|
135
|
-
oldLineNum += skipCount;
|
|
136
|
-
newLineNum += skipCount;
|
|
137
|
-
linesToDisplay = lines.slice(-3);
|
|
138
|
-
showEllipsisTop = true;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
else if (isLastBlock && !isFirstBlock) {
|
|
142
|
-
// Last block: keep first 3
|
|
143
|
-
if (lines.length > 3) {
|
|
144
|
-
linesToDisplay = lines.slice(0, 3);
|
|
145
|
-
showEllipsisBottom = true;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
else if (!isFirstBlock && !isLastBlock) {
|
|
149
|
-
// Middle block: keep first 3 and last 3
|
|
150
|
-
if (lines.length > 6) {
|
|
151
|
-
linesToDisplay = [...lines.slice(0, 3), ...lines.slice(-3)];
|
|
152
|
-
showEllipsisTop = false; // We'll put ellipsis in the middle
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (showEllipsisTop) {
|
|
156
|
-
diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-top-${changeIndex}-${i}`));
|
|
157
|
-
}
|
|
158
|
-
linesToDisplay.forEach((line, lineIndex) => {
|
|
159
|
-
// If it's a middle block and we are at the split point
|
|
160
|
-
if (!isFirstBlock &&
|
|
161
|
-
!isLastBlock &&
|
|
162
|
-
lines.length > 6 &&
|
|
163
|
-
lineIndex === 3) {
|
|
164
|
-
const skipCount = lines.length - 6;
|
|
165
|
-
oldLineNum += skipCount;
|
|
166
|
-
newLineNum += skipCount;
|
|
167
|
-
diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-mid-${changeIndex}-${i}`));
|
|
168
|
-
}
|
|
169
|
-
diffElements.push(renderLine(oldLineNum++, newLineNum++, " ", line, "white", `context-${changeIndex}-${i}-${lineIndex}`));
|
|
170
|
-
});
|
|
171
|
-
if (showEllipsisBottom) {
|
|
172
|
-
const skipCount = lines.length - linesToDisplay.length;
|
|
173
|
-
// We don't increment oldLineNum/newLineNum here because they are already incremented in the loop
|
|
174
|
-
// But we need to account for the lines we skipped at the end of this block
|
|
175
|
-
oldLineNum += skipCount;
|
|
176
|
-
newLineNum += skipCount;
|
|
177
|
-
diffElements.push(_jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ".repeat(maxDigits * 2 + 2), "..."] }) }, `ellipsis-bottom-${changeIndex}-${i}`));
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
allElements.push(...diffElements);
|
|
182
|
-
}
|
|
183
|
-
catch (error) {
|
|
184
|
-
console.warn(`Error rendering diff for change ${changeIndex}:`, error);
|
|
185
|
-
// Fallback to simple display
|
|
186
|
-
allElements.push(_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["-", change.oldContent || ""] }), _jsxs(Text, { color: "green", children: ["+", change.newContent || ""] })] }, `fallback-${changeIndex}`));
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
return _jsx(Box, { flexDirection: "column", children: allElements });
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
console.warn("Error rendering expanded diff:", error);
|
|
193
|
-
return (_jsx(Box, { children: _jsx(Text, { color: "gray", children: "Error rendering diff display" }) }));
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
// Don't render anything if no diff should be shown
|
|
197
|
-
if (!showDiff) {
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: renderExpandedDiff() }) }));
|
|
201
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useReducer, useEffect } from "react";
|
|
3
|
-
import { Box, useInput } from "ink";
|
|
4
|
-
import { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
|
|
5
|
-
import { PluginList } from "./PluginList.js";
|
|
6
|
-
import { selectorReducer, } from "../reducers/selectorReducer.js";
|
|
7
|
-
export const DiscoverView = () => {
|
|
8
|
-
const { discoverablePlugins, actions } = usePluginManagerContext();
|
|
9
|
-
const [state, dispatch] = useReducer((selectorReducer), {
|
|
10
|
-
selectedIndex: 0,
|
|
11
|
-
pendingDecision: null,
|
|
12
|
-
items: [],
|
|
13
|
-
});
|
|
14
|
-
const { selectedIndex, pendingDecision, items } = state;
|
|
15
|
-
// Sync plugins into reducer state
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
dispatch({ type: "SET_ITEMS", items: discoverablePlugins });
|
|
18
|
-
}, [discoverablePlugins]);
|
|
19
|
-
useInput((_input, key) => {
|
|
20
|
-
dispatch({
|
|
21
|
-
type: "HANDLE_KEY",
|
|
22
|
-
key,
|
|
23
|
-
hasInsert: false,
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
if (pendingDecision === "select") {
|
|
28
|
-
const plugin = items[selectedIndex];
|
|
29
|
-
if (plugin) {
|
|
30
|
-
actions.setSelectedId(`${plugin.name}@${plugin.marketplace}`);
|
|
31
|
-
actions.setView("PLUGIN_DETAIL");
|
|
32
|
-
}
|
|
33
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
34
|
-
}
|
|
35
|
-
}, [pendingDecision, selectedIndex, items, actions]);
|
|
36
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(PluginList, { plugins: discoverablePlugins, selectedIndex: selectedIndex }) }));
|
|
37
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { FileItem } from "wave-agent-sdk";
|
|
3
|
-
export { type FileItem } from "wave-agent-sdk";
|
|
4
|
-
export interface FileSelectorProps {
|
|
5
|
-
files: FileItem[];
|
|
6
|
-
searchQuery: string;
|
|
7
|
-
isLoading?: boolean;
|
|
8
|
-
onSelect: (filePath: string) => void;
|
|
9
|
-
onCancel: () => void;
|
|
10
|
-
}
|
|
11
|
-
export declare const FileSelector: React.FC<FileSelectorProps>;
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useReducer, useEffect } from "react";
|
|
3
|
-
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { selectorReducer, } from "../reducers/selectorReducer.js";
|
|
5
|
-
export const FileSelector = ({ files, searchQuery, isLoading = false, onSelect, onCancel, }) => {
|
|
6
|
-
const [state, dispatch] = useReducer((selectorReducer), {
|
|
7
|
-
selectedIndex: 0,
|
|
8
|
-
pendingDecision: null,
|
|
9
|
-
items: [],
|
|
10
|
-
});
|
|
11
|
-
const { selectedIndex, pendingDecision, items: filesInState } = state;
|
|
12
|
-
// Sync files from props into reducer state (SET_ITEMS also resets index)
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
dispatch({ type: "SET_ITEMS", items: files });
|
|
15
|
-
}, [files]);
|
|
16
|
-
// Handle decisions from reducer
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
if (!pendingDecision)
|
|
19
|
-
return;
|
|
20
|
-
if (pendingDecision === "select" || pendingDecision === "insert") {
|
|
21
|
-
if (filesInState.length > 0 && selectedIndex < filesInState.length) {
|
|
22
|
-
onSelect(filesInState[selectedIndex].path);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
else if (pendingDecision === "cancel") {
|
|
26
|
-
onCancel();
|
|
27
|
-
}
|
|
28
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
29
|
-
}, [pendingDecision, selectedIndex, filesInState, onSelect, onCancel]);
|
|
30
|
-
useInput((input, key) => {
|
|
31
|
-
dispatch({
|
|
32
|
-
type: "HANDLE_KEY",
|
|
33
|
-
key,
|
|
34
|
-
hasInsert: true, // For FileSelector, Tab is also select
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
if (files.length === 0) {
|
|
38
|
-
return (_jsx(Box, { flexDirection: "column", borderStyle: "single", borderColor: isLoading ? "cyan" : "yellow", borderBottom: false, borderLeft: false, borderRight: false, children: isLoading ? (_jsx(Text, { color: "cyan", bold: true, children: "Select File/Directory..." })) : (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "yellow", children: ["No files found for \"", searchQuery, "\""] }), _jsx(Text, { dimColor: true, children: "Press Escape to cancel" })] })) }));
|
|
39
|
-
}
|
|
40
|
-
const maxDisplay = 5;
|
|
41
|
-
// Calculate display window start and end positions
|
|
42
|
-
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(maxDisplay / 2), Math.max(0, files.length - maxDisplay)));
|
|
43
|
-
const endIndex = Math.min(files.length, startIndex + maxDisplay);
|
|
44
|
-
const displayFiles = files.slice(startIndex, endIndex);
|
|
45
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["Select File/Directory ", searchQuery && `(filtering: "${searchQuery}")`] }) }), _jsx(Box, { flexDirection: "column", children: displayFiles.map((fileItem, displayIndex) => {
|
|
46
|
-
const actualIndex = startIndex + displayIndex;
|
|
47
|
-
const isSelected = actualIndex === selectedIndex;
|
|
48
|
-
return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "▶ " : " ", fileItem.path] }) }, fileItem.path));
|
|
49
|
-
}) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "\u2191\u2193 navigate \u2022 Enter/Tab select \u2022 Esc cancel" }) })] }));
|
|
50
|
-
};
|
|
@@ -1,74 +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 { AVAILABLE_COMMANDS } from "../constants/commands.js";
|
|
5
|
-
import { helpSelectorReducer } from "../reducers/helpSelectorReducer.js";
|
|
6
|
-
export const HelpView = ({ onCancel, commands = [], }) => {
|
|
7
|
-
const MAX_VISIBLE_ITEMS = 10;
|
|
8
|
-
const tabs = [
|
|
9
|
-
"general",
|
|
10
|
-
"commands",
|
|
11
|
-
];
|
|
12
|
-
if (commands.length > 0) {
|
|
13
|
-
tabs.push("custom-commands");
|
|
14
|
-
}
|
|
15
|
-
const [state, dispatch] = useReducer(helpSelectorReducer, {
|
|
16
|
-
selectedIndex: 0,
|
|
17
|
-
activeTab: "general",
|
|
18
|
-
pendingDecision: null,
|
|
19
|
-
});
|
|
20
|
-
const { selectedIndex, activeTab, pendingDecision } = state;
|
|
21
|
-
// Handle decisions from reducer
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (pendingDecision === "cancel") {
|
|
24
|
-
onCancel();
|
|
25
|
-
dispatch({ type: "CLEAR_DECISION" });
|
|
26
|
-
}
|
|
27
|
-
}, [pendingDecision, onCancel]);
|
|
28
|
-
const currentCommands = activeTab === "commands" ? AVAILABLE_COMMANDS : commands;
|
|
29
|
-
// Calculate visible window for commands
|
|
30
|
-
const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ITEMS / 2), Math.max(0, currentCommands.length - MAX_VISIBLE_ITEMS)));
|
|
31
|
-
const visibleCommands = currentCommands.slice(startIndex, startIndex + MAX_VISIBLE_ITEMS);
|
|
32
|
-
useInput((_, key) => {
|
|
33
|
-
dispatch({
|
|
34
|
-
type: "HANDLE_KEY",
|
|
35
|
-
key,
|
|
36
|
-
maxIndex: activeTab === "general" ? 0 : currentCommands.length - 1,
|
|
37
|
-
tabs,
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
const helpItems = [
|
|
41
|
-
{ key: "@", description: "Reference files" },
|
|
42
|
-
{ key: "/", description: "Commands" },
|
|
43
|
-
{ key: "!", description: "Shell commands (e.g. !ls)" },
|
|
44
|
-
{ key: "Ctrl+R", description: "Search history" },
|
|
45
|
-
{ key: "Ctrl+O", description: "Expand/collapse messages" },
|
|
46
|
-
{ key: "Ctrl+T", description: "Toggle task list" },
|
|
47
|
-
{ key: "Ctrl+B", description: "Background current task" },
|
|
48
|
-
{ key: "Ctrl+V", description: "Paste image" },
|
|
49
|
-
{ key: "Ctrl+J", description: "Newline" },
|
|
50
|
-
{ key: "Ctrl+A", description: "Cursor to line start" },
|
|
51
|
-
{ key: "Ctrl+E", description: "Cursor to line end" },
|
|
52
|
-
{ key: "Ctrl+U", description: "Delete to line start" },
|
|
53
|
-
{ key: "Ctrl+K", description: "Delete to line end" },
|
|
54
|
-
{ key: "Ctrl+W", description: "Delete word before cursor" },
|
|
55
|
-
{ key: "Shift+Tab", description: "Cycle permission mode" },
|
|
56
|
-
{
|
|
57
|
-
key: "Esc",
|
|
58
|
-
description: "Interrupt AI or command / Cancel selector / Close help",
|
|
59
|
-
},
|
|
60
|
-
{ key: "Esc ×2", description: "Clear input (idle)" },
|
|
61
|
-
];
|
|
62
|
-
const footerText = [
|
|
63
|
-
"Tab switch",
|
|
64
|
-
activeTab !== "general" && "↑↓ navigate",
|
|
65
|
-
"Esc close",
|
|
66
|
-
]
|
|
67
|
-
.filter(Boolean)
|
|
68
|
-
.join(" • ");
|
|
69
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, width: "100%", children: [_jsxs(Box, { marginBottom: 1, gap: 2, children: [_jsx(Text, { color: activeTab === "general" ? "cyan" : "gray", bold: true, underline: activeTab === "general", children: "General" }), _jsx(Text, { color: activeTab === "commands" ? "cyan" : "gray", bold: true, underline: activeTab === "commands", children: "Commands" }), commands.length > 0 && (_jsx(Text, { color: activeTab === "custom-commands" ? "cyan" : "gray", bold: true, underline: activeTab === "custom-commands", children: "Custom Commands" }))] }), activeTab === "general" ? (_jsx(Box, { flexDirection: "column", children: helpItems.map((item, index) => (_jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: item.key }) }), _jsx(Text, { color: "white", children: item.description })] }, index))) })) : (_jsx(Box, { flexDirection: "column", children: visibleCommands.map((command, index) => {
|
|
70
|
-
const actualIndex = startIndex + index;
|
|
71
|
-
const isSelected = actualIndex === selectedIndex;
|
|
72
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: isSelected ? "black" : "white", backgroundColor: isSelected ? "cyan" : undefined, children: [isSelected ? "▶ " : " ", "/", command.id] }), isSelected && (_jsx(Box, { marginLeft: 4, children: _jsx(Text, { color: "gray", dimColor: true, children: command.description }) }))] }, command.id));
|
|
73
|
-
}) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: footerText }) })] }));
|
|
74
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { type PromptEntry } from "wave-agent-sdk";
|
|
3
|
-
export interface HistorySearchProps {
|
|
4
|
-
searchQuery: string;
|
|
5
|
-
onSelect: (entry: PromptEntry) => void;
|
|
6
|
-
onCancel: () => void;
|
|
7
|
-
}
|
|
8
|
-
export declare const HistorySearch: React.FC<HistorySearchProps>;
|