wave-code 0.9.1 → 0.9.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAczC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAsO5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAezC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEpE,eAAO,MAAM,sBAAsB,mDACe,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAGzC,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAC/C,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAE1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE/D,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAClD;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAgP5C,CAAC"}
@@ -10,12 +10,13 @@ import { McpManager } from "./McpManager.js";
10
10
  import { RewindCommand } from "./RewindCommand.js";
11
11
  import { HelpView } from "./HelpView.js";
12
12
  import { StatusCommand } from "./StatusCommand.js";
13
+ import { PluginManagerShell } from "./PluginManagerShell.js";
13
14
  import { useInputManager } from "../hooks/useInputManager.js";
14
15
  import { useChat } from "../contexts/useChat.js";
15
16
  export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
16
17
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
17
18
  export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
18
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, clearMessages, sessionId, } = useChat();
19
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, clearMessages, sessionId, workingDirectory, } = useChat();
19
20
  // Input manager with all input state and functionality (including images)
20
21
  const { inputText, cursorPosition,
21
22
  // Image management
@@ -27,7 +28,7 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
27
28
  // History search
28
29
  showHistorySearch, historySearchQuery,
29
30
  // Task/MCP Manager
30
- showBackgroundTaskManager, showMcpManager, showRewindManager, showHelp, showStatusCommand, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager, setShowHelp, setShowStatusCommand,
31
+ showBackgroundTaskManager, showMcpManager, showRewindManager, showHelp, showStatusCommand, showPluginManager, setShowBackgroundTaskManager, setShowMcpManager, setShowRewindManager, setShowHelp, setShowStatusCommand, setShowPluginManager,
31
32
  // Permission mode
32
33
  permissionMode, setPermissionMode,
33
34
  // Main handler
@@ -41,6 +42,8 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
41
42
  onPermissionModeChange: setChatPermissionMode,
42
43
  onClearMessages: clearMessages,
43
44
  sessionId,
45
+ workdir: workingDirectory,
46
+ getFullMessageThread,
44
47
  });
45
48
  // Sync permission mode from useChat to InputManager
46
49
  useEffect(() => {
@@ -85,9 +88,13 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
85
88
  if (showStatusCommand) {
86
89
  return _jsx(StatusCommand, { onCancel: () => setShowStatusCommand(false) });
87
90
  }
91
+ if (showPluginManager) {
92
+ return _jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false) });
93
+ }
88
94
  return (_jsxs(Box, { flexDirection: "column", children: [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 })), showBackgroundTaskManager ||
89
95
  showMcpManager ||
90
96
  showRewindManager ||
91
97
  showHelp ||
92
- showStatusCommand || (_jsxs(Box, { flexDirection: "column", children: [_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) }) }), _jsx(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: isShellCommand ? (_jsxs(Text, { color: "gray", children: ["Shell: ", _jsx(Text, { color: "yellow", children: "Run shell command" })] })) : (_jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] })) })] }))] }));
98
+ showStatusCommand ||
99
+ showPluginManager || (_jsxs(Box, { flexDirection: "column", children: [_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) }) }), _jsx(Box, { paddingRight: 1, justifyContent: "space-between", width: "100%", children: isShellCommand ? (_jsxs(Text, { color: "gray", children: ["Shell: ", _jsx(Text, { color: "yellow", children: "Run shell command" })] })) : (_jsxs(Text, { color: "gray", children: ["Mode:", " ", _jsx(Text, { color: permissionMode === "plan" ? "yellow" : "cyan", children: permissionMode }), " ", "(Shift+Tab to cycle)"] })) })] }))] }));
93
100
  };
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  export declare const PluginManagerShell: React.FC<{
3
3
  children?: React.ReactNode;
4
+ onCancel?: () => void;
4
5
  }>;
5
6
  //# sourceMappingURL=PluginManagerShell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PluginManagerShell.d.ts","sourceRoot":"","sources":["../../src/components/PluginManagerShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAkMvE,CAAC"}
1
+ {"version":3,"file":"PluginManagerShell.d.ts","sourceRoot":"","sources":["../../src/components/PluginManagerShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAkMA,CAAC"}
@@ -8,7 +8,7 @@ import { MarketplaceDetail } from "./MarketplaceDetail.js";
8
8
  import { PluginDetail } from "./PluginDetail.js";
9
9
  import { MarketplaceAddForm } from "./MarketplaceAddForm.js";
10
10
  import { PluginManagerContext } from "../contexts/PluginManagerContext.js";
11
- export const PluginManagerShell = ({ children, }) => {
11
+ export const PluginManagerShell = ({ children, onCancel }) => {
12
12
  const pluginManager = usePluginManager();
13
13
  const { state, actions, discoverablePlugins } = pluginManager;
14
14
  const setView = (view) => {
@@ -48,6 +48,9 @@ export const PluginManagerShell = ({ children, }) => {
48
48
  state.currentView === "ADD_MARKETPLACE") {
49
49
  setView("MARKETPLACES");
50
50
  }
51
+ else {
52
+ onCancel?.();
53
+ }
51
54
  }
52
55
  });
53
56
  const renderView = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAsC5C,CAAC"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/constants/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,eAAO,MAAM,kBAAkB,EAAE,YAAY,EA4C5C,CAAC"}
@@ -35,4 +35,10 @@ export const AVAILABLE_COMMANDS = [
35
35
  description: "Show agent status and configuration",
36
36
  handler: () => { }, // Handler here won't be used, actual processing is in the hook
37
37
  },
38
+ {
39
+ id: "plugin",
40
+ name: "plugin",
41
+ description: "View and manage plugins",
42
+ handler: () => { }, // Handler here won't be used, actual processing is in the hook
43
+ },
38
44
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useCallback, useRef, useEffect, useState, } from "react";
3
3
  import { useInput } from "ink";
4
4
  import { useAppConfig } from "./useAppConfig.js";
5
- import { Agent, } from "wave-agent-sdk";
5
+ import { Agent, OPERATION_CANCELLED_BY_USER, } from "wave-agent-sdk";
6
6
  import { logger } from "../utils/logger.js";
7
7
  import { displayUsageSummary } from "../utils/usageSummary.js";
8
8
  const ChatContext = createContext(null);
@@ -129,7 +129,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
129
129
  // If confirmation was cancelled or failed, deny the operation
130
130
  return {
131
131
  behavior: "deny",
132
- message: "Operation cancelled by user",
132
+ message: OPERATION_CANCELLED_BY_USER,
133
133
  };
134
134
  }
135
135
  };
@@ -19,6 +19,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
19
19
  showRewindManager: boolean;
20
20
  showHelp: boolean;
21
21
  showStatusCommand: boolean;
22
+ showPluginManager: boolean;
22
23
  permissionMode: PermissionMode;
23
24
  attachedImages: import("../managers/inputReducer.js").AttachedImage[];
24
25
  isManagerReady: boolean;
@@ -55,6 +56,7 @@ export declare const useInputManager: (callbacks?: Partial<InputManagerCallbacks
55
56
  setShowRewindManager: (show: boolean) => void;
56
57
  setShowHelp: (show: boolean) => void;
57
58
  setShowStatusCommand: (show: boolean) => void;
59
+ setShowPluginManager: (show: boolean) => void;
58
60
  setPermissionMode: (mode: PermissionMode) => void;
59
61
  addImage: (imagePath: string, mimeType: string) => void;
60
62
  removeImage: (imageId: number) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;+BAsIA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;uCAQN,WAAW;;iCAQjB,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;8BAIV,cAAc;0BAKlB,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBAxFY,MAAM;kCAIG,MAAM;;CAoLxD,CAAC"}
1
+ {"version":3,"file":"useInputManager.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAGL,qBAAqB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,cAAc,EACd,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAGxB,eAAO,MAAM,eAAe,GAC1B,YAAW,OAAO,CAAC,qBAAqB,CAAM;;;;;;;;;;;;;;;;;;;;;;+BA0IA,MAAM;;;;;qCAoBA,MAAM;iCAIV,MAAM;;;;;mCAaJ,MAAM;oCAIL,MAAM;wCAIF,MAAM;mCAIX,MAAM;;;;mCASN,MAAM;;;;;sCAkCH,MAAM;uCAIL,MAAM;uCAQN,WAAW;;iCAQjB,MAAM;yCAYE,OAAO;8BAIlB,OAAO;iCAIJ,OAAO;wBAIhB,OAAO;iCAIE,OAAO;iCAIP,OAAO;8BAIV,cAAc;0BAKlB,MAAM,YAAY,MAAM;2BAIvB,MAAM;;;8BAYH,MAAM;mCAW/B,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;uCAYnB,MAAM;;yBAajD,MAAM,OACR,GAAG,kBACQ,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,gBACvD,MAAM,IAAI;yBA5FY,MAAM;kCAIG,MAAM;;CA0LxD,CAAC"}
@@ -94,6 +94,9 @@ export const useInputManager = (callbacks = {}) => {
94
94
  useEffect(() => {
95
95
  callbacksRef.current.onStatusCommandStateChange?.(state.showStatusCommand);
96
96
  }, [state.showStatusCommand]);
97
+ useEffect(() => {
98
+ callbacksRef.current.onPluginManagerStateChange?.(state.showPluginManager);
99
+ }, [state.showPluginManager]);
97
100
  useEffect(() => {
98
101
  callbacksRef.current.onImagesStateChange?.(state.attachedImages);
99
102
  }, [state.attachedImages]);
@@ -193,6 +196,9 @@ export const useInputManager = (callbacks = {}) => {
193
196
  const setShowStatusCommand = useCallback((show) => {
194
197
  dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: show });
195
198
  }, []);
199
+ const setShowPluginManager = useCallback((show) => {
200
+ dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
201
+ }, []);
196
202
  const setPermissionMode = useCallback((mode) => {
197
203
  dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
198
204
  callbacksRef.current.onPermissionModeChange?.(mode);
@@ -243,6 +249,7 @@ export const useInputManager = (callbacks = {}) => {
243
249
  showRewindManager: state.showRewindManager,
244
250
  showHelp: state.showHelp,
245
251
  showStatusCommand: state.showStatusCommand,
252
+ showPluginManager: state.showPluginManager,
246
253
  permissionMode: state.permissionMode,
247
254
  attachedImages: state.attachedImages,
248
255
  isManagerReady: true,
@@ -276,6 +283,7 @@ export const useInputManager = (callbacks = {}) => {
276
283
  setShowRewindManager,
277
284
  setShowHelp,
278
285
  setShowStatusCommand,
286
+ setShowPluginManager,
279
287
  setPermissionMode,
280
288
  // Image management
281
289
  addImage,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAsB,IAAI,kBAqUzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAsB,IAAI,kBAuSzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -69,13 +69,6 @@ export async function main() {
69
69
  .command("plugin", "Manage plugins and marketplaces", (yargs) => {
70
70
  return yargs
71
71
  .help()
72
- .command("ui", "Open interactive plugin manager UI", {}, async () => {
73
- const { startPluginManagerCli } = await import("./plugin-manager-cli.js");
74
- const shouldExit = await startPluginManagerCli();
75
- if (shouldExit) {
76
- process.exit(0);
77
- }
78
- })
79
72
  .command("marketplace", "Manage plugin marketplaces", (yargs) => {
80
73
  return yargs
81
74
  .help()
@@ -141,15 +134,6 @@ export async function main() {
141
134
  const { updatePluginCommand } = await import("./commands/plugin/update.js");
142
135
  await updatePluginCommand(argv);
143
136
  });
144
- }, async (argv) => {
145
- // If no subcommand is provided, launch the UI
146
- if (argv._.length === 1 && argv._[0] === "plugin") {
147
- const { startPluginManagerCli } = await import("./plugin-manager-cli.js");
148
- const shouldExit = await startPluginManagerCli();
149
- if (shouldExit) {
150
- process.exit(0);
151
- }
152
- }
153
137
  })
154
138
  .version()
155
139
  .alias("v", "version")
@@ -1 +1 @@
1
- {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAwB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,OAAO,EACL,UAAU,EACV,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,0BAA0B,GACrC,MAAM,MAAM,EACZ,aAAa,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,MAcF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,yBAAyB,KAAK,CAAC;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,KACD,OAAO,CAAC,IAAI,CAmCd,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KACpC,OAAO,CAAC,OAAO,CAiBjB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,aAAa,cAAc,EAC3B,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,SAc1C,CAAC;AAgCF,eAAO,MAAM,qBAAqB,GAChC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,MAAM,MAAM,EACZ,gBAAgB,MAAM,KACrB,MAaF,CAAC;AAEF,eAAO,MAAM,qCAAqC,GAChD,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,MAAM,EACjB,gBAAgB,MAAM,KACrB,IAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,MAAM,MAAM,KACX,IAkDF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,KACZ,IA2BF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAM3D,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,SAAS,MAAM;;;CAiDhB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,UAAU,MAAM;;;CAmBjB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAChC,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,gBAAgB,MAAM,KACrB,OAMF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,KACP,OAwEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CA8IjB,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,OAAO,UAAU,EACjB,UAAU,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,OAAO,CAAC,qBAAqB,CAAC,EACzC,OAAO,MAAM,EACb,KAAK,GAAG,EACR,cAAc,MAAM,IAAI,KACvB,OAAO,CAAC,OAAO,CAmFjB,CAAC"}
1
+ {"version":3,"file":"inputHandlers.d.ts","sourceRoot":"","sources":["../../src/managers/inputHandlers.ts"],"names":[],"mappings":"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"}
@@ -25,9 +25,11 @@ export const handleSubmit = async (state, dispatch, callbacks, attachedImagesOve
25
25
  })
26
26
  .filter((img) => img !== undefined)
27
27
  .map((img) => ({ path: img.path, mimeType: img.mimeType }));
28
- let cleanContent = state.inputText.replace(imageRegex, "").trim();
29
- cleanContent = expandLongTextPlaceholders(cleanContent, state.longTextMap);
30
- PromptHistoryManager.addEntry(cleanContent, callbacks.sessionId, state.longTextMap).catch((err) => {
28
+ const contentWithPlaceholders = state.inputText
29
+ .replace(imageRegex, "")
30
+ .trim();
31
+ const cleanContent = expandLongTextPlaceholders(contentWithPlaceholders, state.longTextMap);
32
+ PromptHistoryManager.addEntry(contentWithPlaceholders, callbacks.sessionId, state.longTextMap, callbacks.workdir).catch((err) => {
31
33
  callbacks.logger?.error("Failed to save prompt history", err);
32
34
  });
33
35
  callbacks.onSendMessage?.(cleanContent, referencedImages.length > 0 ? referencedImages : undefined);
@@ -190,7 +192,6 @@ export const handlePasteInput = (state, dispatch, callbacks, input) => {
190
192
  if (char === "!" && state.cursorPosition === 0) {
191
193
  char = "!";
192
194
  }
193
- dispatch({ type: "RESET_HISTORY_NAVIGATION" });
194
195
  dispatch({ type: "INSERT_TEXT", payload: char });
195
196
  processSelectorInput(state, dispatch, char);
196
197
  }
@@ -243,6 +244,9 @@ export const handleCommandSelect = (state, dispatch, callbacks, command) => {
243
244
  else if (command === "status") {
244
245
  dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
245
246
  }
247
+ else if (command === "plugin") {
248
+ dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
249
+ }
246
250
  }
247
251
  })();
248
252
  dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
@@ -315,8 +319,13 @@ export const handleSelectorInput = (state, dispatch, callbacks, input, key) => {
315
319
  checkForSlashDeletion(state, dispatch, newCursorPosition);
316
320
  return true;
317
321
  }
318
- if (input === " " && state.showFileSelector) {
319
- dispatch({ type: "CANCEL_FILE_SELECTOR" });
322
+ if (input === " ") {
323
+ if (state.showFileSelector) {
324
+ dispatch({ type: "CANCEL_FILE_SELECTOR" });
325
+ }
326
+ else if (state.showCommandSelector) {
327
+ dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
328
+ }
320
329
  }
321
330
  if (input &&
322
331
  !key.ctrl &&
@@ -355,7 +364,22 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
355
364
  }
356
365
  if (key.upArrow) {
357
366
  if (state.history.length === 0) {
358
- const history = await PromptHistoryManager.getHistory(callbacks.sessionId);
367
+ let sessionIds = callbacks.sessionId
368
+ ? [callbacks.sessionId]
369
+ : undefined;
370
+ if (callbacks.getFullMessageThread) {
371
+ try {
372
+ const thread = await callbacks.getFullMessageThread();
373
+ sessionIds = thread.sessionIds;
374
+ }
375
+ catch (error) {
376
+ callbacks.logger?.error("Failed to fetch ancestor session IDs", error);
377
+ }
378
+ }
379
+ const history = await PromptHistoryManager.getHistory({
380
+ sessionId: sessionIds,
381
+ workdir: callbacks.workdir,
382
+ });
359
383
  dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
360
384
  }
361
385
  dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
@@ -372,7 +396,6 @@ export const handleNormalInput = async (state, dispatch, callbacks, input, key,
372
396
  const afterCursor = state.inputText.substring(state.cursorPosition);
373
397
  const newInputText = beforeCursor + afterCursor;
374
398
  dispatch({ type: "DELETE_CHAR" });
375
- dispatch({ type: "RESET_HISTORY_NAVIGATION" });
376
399
  checkForAtDeletion(state, dispatch, newCursorPosition);
377
400
  checkForSlashDeletion(state, dispatch, newCursorPosition);
378
401
  // Reactivate file selector if cursor is now within an @word
@@ -461,7 +484,8 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
461
484
  state.showMcpManager ||
462
485
  state.showRewindManager ||
463
486
  state.showHelp ||
464
- state.showStatusCommand)) {
487
+ state.showStatusCommand ||
488
+ state.showPluginManager)) {
465
489
  callbacks.onAbortMessage?.();
466
490
  return true;
467
491
  }
@@ -477,12 +501,14 @@ export const handleInput = async (state, dispatch, callbacks, input, key, clearI
477
501
  state.showMcpManager ||
478
502
  state.showRewindManager ||
479
503
  state.showHelp ||
480
- state.showStatusCommand) {
504
+ state.showStatusCommand ||
505
+ state.showPluginManager) {
481
506
  if (state.showBackgroundTaskManager ||
482
507
  state.showMcpManager ||
483
508
  state.showRewindManager ||
484
509
  state.showHelp ||
485
- state.showStatusCommand) {
510
+ state.showStatusCommand ||
511
+ state.showPluginManager) {
486
512
  return true;
487
513
  }
488
514
  if (state.showHistorySearch) {
@@ -1,4 +1,4 @@
1
- import { FileItem, PermissionMode, Logger, PromptEntry } from "wave-agent-sdk";
1
+ import { FileItem, PermissionMode, Logger, PromptEntry, Message } from "wave-agent-sdk";
2
2
  export interface AttachedImage {
3
3
  id: number;
4
4
  path: string;
@@ -15,6 +15,7 @@ export interface InputManagerCallbacks {
15
15
  onRewindManagerStateChange?: (show: boolean) => void;
16
16
  onHelpStateChange?: (show: boolean) => void;
17
17
  onStatusCommandStateChange?: (show: boolean) => void;
18
+ onPluginManagerStateChange?: (show: boolean) => void;
18
19
  onImagesStateChange?: (images: AttachedImage[]) => void;
19
20
  onSendMessage?: (content: string, images?: Array<{
20
21
  path: string;
@@ -26,6 +27,11 @@ export interface InputManagerCallbacks {
26
27
  onBackgroundCurrentTask?: () => void;
27
28
  onPermissionModeChange?: (mode: PermissionMode) => void;
28
29
  sessionId?: string;
30
+ workdir?: string;
31
+ getFullMessageThread?: () => Promise<{
32
+ messages: Message[];
33
+ sessionIds: string[];
34
+ }>;
29
35
  logger?: Logger;
30
36
  }
31
37
  export interface InputState {
@@ -49,6 +55,7 @@ export interface InputState {
49
55
  showRewindManager: boolean;
50
56
  showHelp: boolean;
51
57
  showStatusCommand: boolean;
58
+ showPluginManager: boolean;
52
59
  permissionMode: PermissionMode;
53
60
  selectorJustUsed: boolean;
54
61
  isPasting: boolean;
@@ -127,6 +134,9 @@ export type InputAction = {
127
134
  } | {
128
135
  type: "SET_SHOW_STATUS_COMMAND";
129
136
  payload: boolean;
137
+ } | {
138
+ type: "SET_SHOW_PLUGIN_MANAGER";
139
+ payload: boolean;
130
140
  } | {
131
141
  type: "SET_PERMISSION_MODE";
132
142
  payload: PermissionMode;
@@ -1 +1 @@
1
- {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inputReducer.d.ts","sourceRoot":"","sources":["../../src/managers/inputReducer.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ export const initialState = {
19
19
  showRewindManager: false,
20
20
  showHelp: false,
21
21
  showStatusCommand: false,
22
+ showPluginManager: false,
22
23
  permissionMode: "default",
23
24
  selectorJustUsed: false,
24
25
  isPasting: false,
@@ -186,6 +187,12 @@ export function inputReducer(state, action) {
186
187
  showStatusCommand: action.payload,
187
188
  selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
188
189
  };
190
+ case "SET_SHOW_PLUGIN_MANAGER":
191
+ return {
192
+ ...state,
193
+ showPluginManager: action.payload,
194
+ selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
195
+ };
189
196
  case "SET_PERMISSION_MODE":
190
197
  return { ...state, permissionMode: action.payload };
191
198
  case "SET_SELECTOR_JUST_USED":
@@ -275,6 +282,9 @@ export function inputReducer(state, action) {
275
282
  newIndex = Math.min(state.history.length - 1, newIndex + 1);
276
283
  }
277
284
  else {
285
+ if (newIndex === -1) {
286
+ return state;
287
+ }
278
288
  newIndex = Math.max(-1, newIndex - 1);
279
289
  }
280
290
  if (newIndex === -1) {
@@ -284,8 +294,8 @@ export function inputReducer(state, action) {
284
294
  inputText: newOriginalInputText,
285
295
  longTextMap: newOriginalLongTextMap,
286
296
  cursorPosition: newOriginalInputText.length,
287
- originalInputText: newOriginalInputText,
288
- originalLongTextMap: newOriginalLongTextMap,
297
+ originalInputText: "",
298
+ originalLongTextMap: {},
289
299
  };
290
300
  }
291
301
  else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-code",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "CLI-based code assistant powered by AI, built with React and Ink",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,7 +39,7 @@
39
39
  "react": "^19.2.4",
40
40
  "react-dom": "19.2.4",
41
41
  "yargs": "^17.7.2",
42
- "wave-agent-sdk": "0.9.1"
42
+ "wave-agent-sdk": "0.9.3"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/react": "^19.1.8",
@@ -9,6 +9,7 @@ import { McpManager } from "./McpManager.js";
9
9
  import { RewindCommand } from "./RewindCommand.js";
10
10
  import { HelpView } from "./HelpView.js";
11
11
  import { StatusCommand } from "./StatusCommand.js";
12
+ import { PluginManagerShell } from "./PluginManagerShell.js";
12
13
  import { useInputManager } from "../hooks/useInputManager.js";
13
14
  import { useChat } from "../contexts/useChat.js";
14
15
 
@@ -58,6 +59,7 @@ export const InputBox: React.FC<InputBoxProps> = ({
58
59
  getFullMessageThread,
59
60
  clearMessages,
60
61
  sessionId,
62
+ workingDirectory,
61
63
  } = useChat();
62
64
 
63
65
  // Input manager with all input state and functionality (including images)
@@ -91,11 +93,13 @@ export const InputBox: React.FC<InputBoxProps> = ({
91
93
  showRewindManager,
92
94
  showHelp,
93
95
  showStatusCommand,
96
+ showPluginManager,
94
97
  setShowBackgroundTaskManager,
95
98
  setShowMcpManager,
96
99
  setShowRewindManager,
97
100
  setShowHelp,
98
101
  setShowStatusCommand,
102
+ setShowPluginManager,
99
103
  // Permission mode
100
104
  permissionMode,
101
105
  setPermissionMode,
@@ -111,6 +115,8 @@ export const InputBox: React.FC<InputBoxProps> = ({
111
115
  onPermissionModeChange: setChatPermissionMode,
112
116
  onClearMessages: clearMessages,
113
117
  sessionId,
118
+ workdir: workingDirectory,
119
+ getFullMessageThread,
114
120
  });
115
121
 
116
122
  // Sync permission mode from useChat to InputManager
@@ -180,6 +186,10 @@ export const InputBox: React.FC<InputBoxProps> = ({
180
186
  return <StatusCommand onCancel={() => setShowStatusCommand(false)} />;
181
187
  }
182
188
 
189
+ if (showPluginManager) {
190
+ return <PluginManagerShell onCancel={() => setShowPluginManager(false)} />;
191
+ }
192
+
183
193
  return (
184
194
  <Box flexDirection="column">
185
195
  {showFileSelector && (
@@ -229,7 +239,8 @@ export const InputBox: React.FC<InputBoxProps> = ({
229
239
  showMcpManager ||
230
240
  showRewindManager ||
231
241
  showHelp ||
232
- showStatusCommand || (
242
+ showStatusCommand ||
243
+ showPluginManager || (
233
244
  <Box flexDirection="column">
234
245
  <Box
235
246
  borderStyle="single"
@@ -10,9 +10,10 @@ import { PluginDetail } from "./PluginDetail.js";
10
10
  import { MarketplaceAddForm } from "./MarketplaceAddForm.js";
11
11
  import { PluginManagerContext } from "../contexts/PluginManagerContext.js";
12
12
 
13
- export const PluginManagerShell: React.FC<{ children?: React.ReactNode }> = ({
14
- children,
15
- }) => {
13
+ export const PluginManagerShell: React.FC<{
14
+ children?: React.ReactNode;
15
+ onCancel?: () => void;
16
+ }> = ({ children, onCancel }) => {
16
17
  const pluginManager = usePluginManager();
17
18
  const { state, actions, discoverablePlugins } = pluginManager;
18
19
 
@@ -62,6 +63,8 @@ export const PluginManagerShell: React.FC<{ children?: React.ReactNode }> = ({
62
63
  state.currentView === "ADD_MARKETPLACE"
63
64
  ) {
64
65
  setView("MARKETPLACES");
66
+ } else {
67
+ onCancel?.();
65
68
  }
66
69
  }
67
70
  });
@@ -38,4 +38,10 @@ export const AVAILABLE_COMMANDS: SlashCommand[] = [
38
38
  description: "Show agent status and configuration",
39
39
  handler: () => {}, // Handler here won't be used, actual processing is in the hook
40
40
  },
41
+ {
42
+ id: "plugin",
43
+ name: "plugin",
44
+ description: "View and manage plugins",
45
+ handler: () => {}, // Handler here won't be used, actual processing is in the hook
46
+ },
41
47
  ];
@@ -21,6 +21,7 @@ import {
21
21
  Agent,
22
22
  AgentCallbacks,
23
23
  type ToolPermissionContext,
24
+ OPERATION_CANCELLED_BY_USER,
24
25
  } from "wave-agent-sdk";
25
26
  import { logger } from "../utils/logger.js";
26
27
  import { displayUsageSummary } from "../utils/usageSummary.js";
@@ -317,7 +318,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
317
318
  // If confirmation was cancelled or failed, deny the operation
318
319
  return {
319
320
  behavior: "deny",
320
- message: "Operation cancelled by user",
321
+ message: OPERATION_CANCELLED_BY_USER,
321
322
  };
322
323
  }
323
324
  };
@@ -142,6 +142,10 @@ export const useInputManager = (
142
142
  callbacksRef.current.onStatusCommandStateChange?.(state.showStatusCommand);
143
143
  }, [state.showStatusCommand]);
144
144
 
145
+ useEffect(() => {
146
+ callbacksRef.current.onPluginManagerStateChange?.(state.showPluginManager);
147
+ }, [state.showPluginManager]);
148
+
145
149
  useEffect(() => {
146
150
  callbacksRef.current.onImagesStateChange?.(state.attachedImages);
147
151
  }, [state.attachedImages]);
@@ -291,6 +295,10 @@ export const useInputManager = (
291
295
  dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: show });
292
296
  }, []);
293
297
 
298
+ const setShowPluginManager = useCallback((show: boolean) => {
299
+ dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: show });
300
+ }, []);
301
+
294
302
  const setPermissionMode = useCallback((mode: PermissionMode) => {
295
303
  dispatch({ type: "SET_PERMISSION_MODE", payload: mode });
296
304
  callbacksRef.current.onPermissionModeChange?.(mode);
@@ -384,6 +392,7 @@ export const useInputManager = (
384
392
  showRewindManager: state.showRewindManager,
385
393
  showHelp: state.showHelp,
386
394
  showStatusCommand: state.showStatusCommand,
395
+ showPluginManager: state.showPluginManager,
387
396
  permissionMode: state.permissionMode,
388
397
  attachedImages: state.attachedImages,
389
398
  isManagerReady: true,
@@ -423,6 +432,7 @@ export const useInputManager = (
423
432
  setShowRewindManager,
424
433
  setShowHelp,
425
434
  setShowStatusCommand,
435
+ setShowPluginManager,
426
436
  setPermissionMode,
427
437
 
428
438
  // Image management
package/src/index.ts CHANGED
@@ -70,165 +70,135 @@ export async function main() {
70
70
  type: "string",
71
71
  global: false,
72
72
  })
73
- .command(
74
- "plugin",
75
- "Manage plugins and marketplaces",
76
- (yargs) => {
77
- return yargs
78
- .help()
79
- .command(
80
- "ui",
81
- "Open interactive plugin manager UI",
82
- {},
83
- async () => {
84
- const { startPluginManagerCli } = await import(
85
- "./plugin-manager-cli.js"
86
- );
87
- const shouldExit = await startPluginManagerCli();
88
- if (shouldExit) {
89
- process.exit(0);
90
- }
91
- },
92
- )
93
- .command(
94
- "marketplace",
95
- "Manage plugin marketplaces",
96
- (yargs) => {
97
- return yargs
98
- .help()
99
- .command(
100
- "add <input>",
101
- "Add a plugin marketplace (local path, owner/repo, or Git URL)",
102
- (yargs) => {
103
- return yargs.positional("input", {
104
- describe:
105
- "Path to local marketplace, GitHub owner/repo, or full Git URL (with optional #ref)",
106
- type: "string",
107
- });
108
- },
109
- async (argv) => {
110
- const { addMarketplaceCommand } = await import(
111
- "./commands/plugin/marketplace.js"
112
- );
113
- await addMarketplaceCommand(argv as { input: string });
114
- },
115
- )
116
- .command(
117
- "update [name]",
118
- "Update registered marketplace(s)",
119
- (yargs) => {
120
- return yargs.positional("name", {
121
- describe: "Name of the marketplace to update",
122
- type: "string",
123
- });
124
- },
125
- async (argv) => {
126
- const { updateMarketplaceCommand } = await import(
127
- "./commands/plugin/marketplace.js"
128
- );
129
- await updateMarketplaceCommand(argv as { name?: string });
130
- },
131
- )
132
- .command(
133
- "list",
134
- "List registered marketplaces",
135
- {},
136
- async () => {
137
- const { listMarketplacesCommand } = await import(
138
- "./commands/plugin/marketplace.js"
139
- );
140
- await listMarketplacesCommand();
141
- },
142
- )
143
- .demandCommand(1, "Please specify a marketplace subcommand");
144
- },
145
- () => {},
146
- )
147
- .command(
148
- "install <plugin>",
149
- "Install a plugin from a marketplace",
150
- (yargs) => {
151
- return yargs
152
- .positional("plugin", {
153
- describe: "Plugin to install (format: name@marketplace)",
154
- type: "string",
155
- })
156
- .option("scope", {
157
- alias: "s",
158
- describe: "Scope to enable the plugin in",
159
- choices: ["user", "project", "local"],
160
- type: "string",
161
- });
162
- },
163
- async (argv) => {
164
- const { installPluginCommand } = await import(
165
- "./commands/plugin/install.js"
166
- );
167
- await installPluginCommand(
168
- argv as {
169
- plugin: string;
170
- scope?: Scope;
73
+ .command("plugin", "Manage plugins and marketplaces", (yargs) => {
74
+ return yargs
75
+ .help()
76
+ .command(
77
+ "marketplace",
78
+ "Manage plugin marketplaces",
79
+ (yargs) => {
80
+ return yargs
81
+ .help()
82
+ .command(
83
+ "add <input>",
84
+ "Add a plugin marketplace (local path, owner/repo, or Git URL)",
85
+ (yargs) => {
86
+ return yargs.positional("input", {
87
+ describe:
88
+ "Path to local marketplace, GitHub owner/repo, or full Git URL (with optional #ref)",
89
+ type: "string",
90
+ });
171
91
  },
172
- );
173
- },
174
- )
175
- .command(
176
- "list",
177
- "List all available plugins from marketplaces",
178
- {},
179
- async () => {
180
- const { listPluginsCommand } = await import(
181
- "./commands/plugin/list.js"
182
- );
183
- await listPluginsCommand();
184
- },
185
- )
186
- .command(
187
- "uninstall <plugin>",
188
- "Uninstall a plugin",
189
- (yargs) => {
190
- return yargs.positional("plugin", {
191
- describe: "Plugin to uninstall (format: name@marketplace)",
92
+ async (argv) => {
93
+ const { addMarketplaceCommand } = await import(
94
+ "./commands/plugin/marketplace.js"
95
+ );
96
+ await addMarketplaceCommand(argv as { input: string });
97
+ },
98
+ )
99
+ .command(
100
+ "update [name]",
101
+ "Update registered marketplace(s)",
102
+ (yargs) => {
103
+ return yargs.positional("name", {
104
+ describe: "Name of the marketplace to update",
105
+ type: "string",
106
+ });
107
+ },
108
+ async (argv) => {
109
+ const { updateMarketplaceCommand } = await import(
110
+ "./commands/plugin/marketplace.js"
111
+ );
112
+ await updateMarketplaceCommand(argv as { name?: string });
113
+ },
114
+ )
115
+ .command(
116
+ "list",
117
+ "List registered marketplaces",
118
+ {},
119
+ async () => {
120
+ const { listMarketplacesCommand } = await import(
121
+ "./commands/plugin/marketplace.js"
122
+ );
123
+ await listMarketplacesCommand();
124
+ },
125
+ )
126
+ .demandCommand(1, "Please specify a marketplace subcommand");
127
+ },
128
+ () => {},
129
+ )
130
+ .command(
131
+ "install <plugin>",
132
+ "Install a plugin from a marketplace",
133
+ (yargs) => {
134
+ return yargs
135
+ .positional("plugin", {
136
+ describe: "Plugin to install (format: name@marketplace)",
192
137
  type: "string",
193
- });
194
- },
195
- async (argv) => {
196
- const { uninstallPluginCommand } = await import(
197
- "./commands/plugin/uninstall.js"
198
- );
199
- await uninstallPluginCommand(argv as { plugin: string });
200
- },
201
- )
202
- .command(
203
- "update <plugin>",
204
- "Update a plugin (uninstall followed by install)",
205
- (yargs) => {
206
- return yargs.positional("plugin", {
207
- describe: "Plugin to update (format: name@marketplace)",
138
+ })
139
+ .option("scope", {
140
+ alias: "s",
141
+ describe: "Scope to enable the plugin in",
142
+ choices: ["user", "project", "local"],
208
143
  type: "string",
209
144
  });
210
- },
211
- async (argv) => {
212
- const { updatePluginCommand } = await import(
213
- "./commands/plugin/update.js"
214
- );
215
- await updatePluginCommand(argv as { plugin: string });
216
- },
217
- );
218
- },
219
- async (argv) => {
220
- // If no subcommand is provided, launch the UI
221
- if (argv._.length === 1 && argv._[0] === "plugin") {
222
- const { startPluginManagerCli } = await import(
223
- "./plugin-manager-cli.js"
224
- );
225
- const shouldExit = await startPluginManagerCli();
226
- if (shouldExit) {
227
- process.exit(0);
228
- }
229
- }
230
- },
231
- )
145
+ },
146
+ async (argv) => {
147
+ const { installPluginCommand } = await import(
148
+ "./commands/plugin/install.js"
149
+ );
150
+ await installPluginCommand(
151
+ argv as {
152
+ plugin: string;
153
+ scope?: Scope;
154
+ },
155
+ );
156
+ },
157
+ )
158
+ .command(
159
+ "list",
160
+ "List all available plugins from marketplaces",
161
+ {},
162
+ async () => {
163
+ const { listPluginsCommand } = await import(
164
+ "./commands/plugin/list.js"
165
+ );
166
+ await listPluginsCommand();
167
+ },
168
+ )
169
+ .command(
170
+ "uninstall <plugin>",
171
+ "Uninstall a plugin",
172
+ (yargs) => {
173
+ return yargs.positional("plugin", {
174
+ describe: "Plugin to uninstall (format: name@marketplace)",
175
+ type: "string",
176
+ });
177
+ },
178
+ async (argv) => {
179
+ const { uninstallPluginCommand } = await import(
180
+ "./commands/plugin/uninstall.js"
181
+ );
182
+ await uninstallPluginCommand(argv as { plugin: string });
183
+ },
184
+ )
185
+ .command(
186
+ "update <plugin>",
187
+ "Update a plugin (uninstall followed by install)",
188
+ (yargs) => {
189
+ return yargs.positional("plugin", {
190
+ describe: "Plugin to update (format: name@marketplace)",
191
+ type: "string",
192
+ });
193
+ },
194
+ async (argv) => {
195
+ const { updatePluginCommand } = await import(
196
+ "./commands/plugin/update.js"
197
+ );
198
+ await updatePluginCommand(argv as { plugin: string });
199
+ },
200
+ );
201
+ })
232
202
  .version()
233
203
  .alias("v", "version")
234
204
  .example("$0", "Start CLI with default settings")
@@ -51,13 +51,19 @@ export const handleSubmit = async (
51
51
  )
52
52
  .map((img) => ({ path: img.path, mimeType: img.mimeType }));
53
53
 
54
- let cleanContent = state.inputText.replace(imageRegex, "").trim();
55
- cleanContent = expandLongTextPlaceholders(cleanContent, state.longTextMap);
54
+ const contentWithPlaceholders = state.inputText
55
+ .replace(imageRegex, "")
56
+ .trim();
57
+ const cleanContent = expandLongTextPlaceholders(
58
+ contentWithPlaceholders,
59
+ state.longTextMap,
60
+ );
56
61
 
57
62
  PromptHistoryManager.addEntry(
58
- cleanContent,
63
+ contentWithPlaceholders,
59
64
  callbacks.sessionId,
60
65
  state.longTextMap,
66
+ callbacks.workdir,
61
67
  ).catch((err: unknown) => {
62
68
  callbacks.logger?.error("Failed to save prompt history", err);
63
69
  });
@@ -280,7 +286,6 @@ export const handlePasteInput = (
280
286
  char = "!";
281
287
  }
282
288
 
283
- dispatch({ type: "RESET_HISTORY_NAVIGATION" });
284
289
  dispatch({ type: "INSERT_TEXT", payload: char });
285
290
 
286
291
  processSelectorInput(state, dispatch, char);
@@ -337,6 +342,8 @@ export const handleCommandSelect = (
337
342
  dispatch({ type: "SET_SHOW_HELP", payload: true });
338
343
  } else if (command === "status") {
339
344
  dispatch({ type: "SET_SHOW_STATUS_COMMAND", payload: true });
345
+ } else if (command === "plugin") {
346
+ dispatch({ type: "SET_SHOW_PLUGIN_MANAGER", payload: true });
340
347
  }
341
348
  }
342
349
  })();
@@ -453,8 +460,12 @@ export const handleSelectorInput = (
453
460
  return true;
454
461
  }
455
462
 
456
- if (input === " " && state.showFileSelector) {
457
- dispatch({ type: "CANCEL_FILE_SELECTOR" });
463
+ if (input === " ") {
464
+ if (state.showFileSelector) {
465
+ dispatch({ type: "CANCEL_FILE_SELECTOR" });
466
+ } else if (state.showCommandSelector) {
467
+ dispatch({ type: "CANCEL_COMMAND_SELECTOR" });
468
+ }
458
469
  }
459
470
 
460
471
  if (
@@ -506,9 +517,26 @@ export const handleNormalInput = async (
506
517
 
507
518
  if (key.upArrow) {
508
519
  if (state.history.length === 0) {
509
- const history = await PromptHistoryManager.getHistory(
510
- callbacks.sessionId,
511
- );
520
+ let sessionIds: string[] | undefined = callbacks.sessionId
521
+ ? [callbacks.sessionId]
522
+ : undefined;
523
+
524
+ if (callbacks.getFullMessageThread) {
525
+ try {
526
+ const thread = await callbacks.getFullMessageThread();
527
+ sessionIds = thread.sessionIds;
528
+ } catch (error) {
529
+ callbacks.logger?.error(
530
+ "Failed to fetch ancestor session IDs",
531
+ error,
532
+ );
533
+ }
534
+ }
535
+
536
+ const history = await PromptHistoryManager.getHistory({
537
+ sessionId: sessionIds,
538
+ workdir: callbacks.workdir,
539
+ });
512
540
  dispatch({ type: "SET_HISTORY_ENTRIES", payload: history });
513
541
  }
514
542
  dispatch({ type: "NAVIGATE_HISTORY", payload: "up" });
@@ -531,7 +559,6 @@ export const handleNormalInput = async (
531
559
  const newInputText = beforeCursor + afterCursor;
532
560
 
533
561
  dispatch({ type: "DELETE_CHAR" });
534
- dispatch({ type: "RESET_HISTORY_NAVIGATION" });
535
562
 
536
563
  checkForAtDeletion(state, dispatch, newCursorPosition);
537
564
  checkForSlashDeletion(state, dispatch, newCursorPosition);
@@ -652,7 +679,8 @@ export const handleInput = async (
652
679
  state.showMcpManager ||
653
680
  state.showRewindManager ||
654
681
  state.showHelp ||
655
- state.showStatusCommand
682
+ state.showStatusCommand ||
683
+ state.showPluginManager
656
684
  )
657
685
  ) {
658
686
  callbacks.onAbortMessage?.();
@@ -673,14 +701,16 @@ export const handleInput = async (
673
701
  state.showMcpManager ||
674
702
  state.showRewindManager ||
675
703
  state.showHelp ||
676
- state.showStatusCommand
704
+ state.showStatusCommand ||
705
+ state.showPluginManager
677
706
  ) {
678
707
  if (
679
708
  state.showBackgroundTaskManager ||
680
709
  state.showMcpManager ||
681
710
  state.showRewindManager ||
682
711
  state.showHelp ||
683
- state.showStatusCommand
712
+ state.showStatusCommand ||
713
+ state.showPluginManager
684
714
  ) {
685
715
  return true;
686
716
  }
@@ -1,4 +1,10 @@
1
- import { FileItem, PermissionMode, Logger, PromptEntry } from "wave-agent-sdk";
1
+ import {
2
+ FileItem,
3
+ PermissionMode,
4
+ Logger,
5
+ PromptEntry,
6
+ Message,
7
+ } from "wave-agent-sdk";
2
8
 
3
9
  export interface AttachedImage {
4
10
  id: number;
@@ -26,6 +32,7 @@ export interface InputManagerCallbacks {
26
32
  onRewindManagerStateChange?: (show: boolean) => void;
27
33
  onHelpStateChange?: (show: boolean) => void;
28
34
  onStatusCommandStateChange?: (show: boolean) => void;
35
+ onPluginManagerStateChange?: (show: boolean) => void;
29
36
  onImagesStateChange?: (images: AttachedImage[]) => void;
30
37
  onSendMessage?: (
31
38
  content: string,
@@ -37,6 +44,11 @@ export interface InputManagerCallbacks {
37
44
  onBackgroundCurrentTask?: () => void;
38
45
  onPermissionModeChange?: (mode: PermissionMode) => void;
39
46
  sessionId?: string;
47
+ workdir?: string;
48
+ getFullMessageThread?: () => Promise<{
49
+ messages: Message[];
50
+ sessionIds: string[];
51
+ }>;
40
52
  logger?: Logger;
41
53
  }
42
54
 
@@ -61,6 +73,7 @@ export interface InputState {
61
73
  showRewindManager: boolean;
62
74
  showHelp: boolean;
63
75
  showStatusCommand: boolean;
76
+ showPluginManager: boolean;
64
77
  permissionMode: PermissionMode;
65
78
  selectorJustUsed: boolean;
66
79
  isPasting: boolean;
@@ -94,6 +107,7 @@ export const initialState: InputState = {
94
107
  showRewindManager: false,
95
108
  showHelp: false,
96
109
  showStatusCommand: false,
110
+ showPluginManager: false,
97
111
  permissionMode: "default",
98
112
  selectorJustUsed: false,
99
113
  isPasting: false,
@@ -130,6 +144,7 @@ export type InputAction =
130
144
  | { type: "SET_SHOW_REWIND_MANAGER"; payload: boolean }
131
145
  | { type: "SET_SHOW_HELP"; payload: boolean }
132
146
  | { type: "SET_SHOW_STATUS_COMMAND"; payload: boolean }
147
+ | { type: "SET_SHOW_PLUGIN_MANAGER"; payload: boolean }
133
148
  | { type: "SET_PERMISSION_MODE"; payload: PermissionMode }
134
149
  | { type: "SET_SELECTOR_JUST_USED"; payload: boolean }
135
150
  | { type: "COMPRESS_AND_INSERT_TEXT"; payload: string }
@@ -317,6 +332,12 @@ export function inputReducer(
317
332
  showStatusCommand: action.payload,
318
333
  selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
319
334
  };
335
+ case "SET_SHOW_PLUGIN_MANAGER":
336
+ return {
337
+ ...state,
338
+ showPluginManager: action.payload,
339
+ selectorJustUsed: !action.payload ? true : state.selectorJustUsed,
340
+ };
320
341
  case "SET_PERMISSION_MODE":
321
342
  return { ...state, permissionMode: action.payload };
322
343
  case "SET_SELECTOR_JUST_USED":
@@ -409,6 +430,9 @@ export function inputReducer(
409
430
  }
410
431
  newIndex = Math.min(state.history.length - 1, newIndex + 1);
411
432
  } else {
433
+ if (newIndex === -1) {
434
+ return state;
435
+ }
412
436
  newIndex = Math.max(-1, newIndex - 1);
413
437
  }
414
438
 
@@ -419,8 +443,8 @@ export function inputReducer(
419
443
  inputText: newOriginalInputText,
420
444
  longTextMap: newOriginalLongTextMap,
421
445
  cursorPosition: newOriginalInputText.length,
422
- originalInputText: newOriginalInputText,
423
- originalLongTextMap: newOriginalLongTextMap,
446
+ originalInputText: "",
447
+ originalLongTextMap: {},
424
448
  };
425
449
  } else {
426
450
  const entry = state.history[newIndex];