wave-code 0.14.0 → 0.14.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.
Files changed (53) hide show
  1. package/dist/components/BackgroundTaskManager.d.ts.map +1 -1
  2. package/dist/components/BackgroundTaskManager.js +36 -25
  3. package/dist/components/InputBox.d.ts.map +1 -1
  4. package/dist/components/InputBox.js +2 -2
  5. package/dist/components/MarketplaceAddForm.d.ts.map +1 -1
  6. package/dist/components/MarketplaceAddForm.js +48 -17
  7. package/dist/components/MarketplaceDetail.d.ts.map +1 -1
  8. package/dist/components/MarketplaceDetail.js +2 -1
  9. package/dist/components/MarketplaceList.d.ts.map +1 -1
  10. package/dist/components/MarketplaceList.js +2 -1
  11. package/dist/components/McpManager.d.ts.map +1 -1
  12. package/dist/components/McpManager.js +22 -27
  13. package/dist/components/PluginDetail.d.ts.map +1 -1
  14. package/dist/components/PluginDetail.js +22 -22
  15. package/dist/components/PluginManagerShell.d.ts +1 -0
  16. package/dist/components/PluginManagerShell.d.ts.map +1 -1
  17. package/dist/components/PluginManagerShell.js +2 -2
  18. package/dist/components/PluginManagerTypes.d.ts +2 -2
  19. package/dist/components/PluginManagerTypes.d.ts.map +1 -1
  20. package/dist/contexts/useChat.d.ts +1 -0
  21. package/dist/contexts/useChat.d.ts.map +1 -1
  22. package/dist/contexts/useChat.js +125 -98
  23. package/dist/hooks/usePluginManager.d.ts +3 -1
  24. package/dist/hooks/usePluginManager.d.ts.map +1 -1
  25. package/dist/hooks/usePluginManager.js +16 -7
  26. package/dist/reducers/backgroundTaskManagerReducer.d.ts +43 -0
  27. package/dist/reducers/backgroundTaskManagerReducer.d.ts.map +1 -0
  28. package/dist/reducers/backgroundTaskManagerReducer.js +23 -0
  29. package/dist/reducers/marketplaceAddFormReducer.d.ts +24 -0
  30. package/dist/reducers/marketplaceAddFormReducer.d.ts.map +1 -0
  31. package/dist/reducers/marketplaceAddFormReducer.js +18 -0
  32. package/dist/reducers/mcpManagerReducer.d.ts +16 -0
  33. package/dist/reducers/mcpManagerReducer.d.ts.map +1 -0
  34. package/dist/reducers/mcpManagerReducer.js +15 -0
  35. package/dist/reducers/pluginDetailReducer.d.ts +25 -0
  36. package/dist/reducers/pluginDetailReducer.d.ts.map +1 -0
  37. package/dist/reducers/pluginDetailReducer.js +38 -0
  38. package/package.json +2 -2
  39. package/src/components/BackgroundTaskManager.tsx +32 -34
  40. package/src/components/InputBox.tsx +7 -1
  41. package/src/components/MarketplaceAddForm.tsx +76 -22
  42. package/src/components/MarketplaceDetail.tsx +4 -0
  43. package/src/components/MarketplaceList.tsx +4 -0
  44. package/src/components/McpManager.tsx +30 -34
  45. package/src/components/PluginDetail.tsx +25 -33
  46. package/src/components/PluginManagerShell.tsx +3 -2
  47. package/src/components/PluginManagerTypes.ts +8 -2
  48. package/src/contexts/useChat.tsx +54 -20
  49. package/src/hooks/usePluginManager.ts +18 -7
  50. package/src/reducers/backgroundTaskManagerReducer.ts +60 -0
  51. package/src/reducers/marketplaceAddFormReducer.ts +35 -0
  52. package/src/reducers/mcpManagerReducer.ts +31 -0
  53. package/src/reducers/pluginDetailReducer.ts +58 -0
@@ -1 +1 @@
1
- {"version":3,"file":"BackgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/components/BackgroundTaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAgBnD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAyUtE,CAAC"}
1
+ {"version":3,"file":"BackgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/components/BackgroundTaskManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AASrD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CA8UtE,CAAC"}
@@ -1,34 +1,41 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
2
+ import { useEffect, useReducer } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import { useChat } from "../contexts/useChat.js";
5
5
  import { getLastLines } from "wave-agent-sdk";
6
+ import { backgroundTaskManagerReducer, } from "../reducers/backgroundTaskManagerReducer.js";
6
7
  export const BackgroundTaskManager = ({ onCancel, }) => {
7
8
  const { backgroundTasks, getBackgroundTaskOutput, stopBackgroundTask } = useChat();
8
- const [tasks, setTasks] = useState([]);
9
- const [selectedIndex, setSelectedIndex] = useState(0);
10
9
  const MAX_VISIBLE_ITEMS = 3;
11
- const [viewMode, setViewMode] = useState("list");
12
- const [detailTaskId, setDetailTaskId] = useState(null);
13
- const [detailOutput, setDetailOutput] = useState(null);
10
+ const [state, dispatch] = useReducer(backgroundTaskManagerReducer, {
11
+ tasks: [],
12
+ selectedIndex: 0,
13
+ viewMode: "list",
14
+ detailTaskId: null,
15
+ detailOutput: null,
16
+ });
17
+ const { tasks, selectedIndex, viewMode, detailTaskId, detailOutput } = state;
14
18
  // Convert backgroundTasks to local Task format
15
19
  useEffect(() => {
16
- setTasks(backgroundTasks.map((task) => ({
17
- id: task.id,
18
- type: task.type,
19
- description: task.description,
20
- status: task.status,
21
- startTime: task.startTime,
22
- exitCode: task.exitCode,
23
- runtime: task.runtime,
24
- outputPath: task.outputPath,
25
- })));
20
+ dispatch({
21
+ type: "SET_TASKS",
22
+ tasks: backgroundTasks.map((task) => ({
23
+ id: task.id,
24
+ type: task.type,
25
+ description: task.description,
26
+ status: task.status,
27
+ startTime: task.startTime,
28
+ exitCode: task.exitCode,
29
+ runtime: task.runtime,
30
+ outputPath: task.outputPath,
31
+ })),
32
+ });
26
33
  }, [backgroundTasks]);
27
34
  // Load detail output for selected task
28
35
  useEffect(() => {
29
36
  if (viewMode === "detail" && detailTaskId) {
30
37
  const output = getBackgroundTaskOutput(detailTaskId);
31
- setDetailOutput(output);
38
+ dispatch({ type: "SET_DETAIL_OUTPUT", output });
32
39
  }
33
40
  }, [viewMode, detailTaskId, getBackgroundTaskOutput]);
34
41
  const formatDuration = (ms) => {
@@ -55,8 +62,8 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
55
62
  if (key.return) {
56
63
  if (tasks.length > 0 && selectedIndex < tasks.length) {
57
64
  const selectedTask = tasks[selectedIndex];
58
- setDetailTaskId(selectedTask.id);
59
- setViewMode("detail");
65
+ dispatch({ type: "SET_DETAIL_TASK_ID", id: selectedTask.id });
66
+ dispatch({ type: "SET_VIEW_MODE", mode: "detail" });
60
67
  }
61
68
  return;
62
69
  }
@@ -65,11 +72,17 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
65
72
  return;
66
73
  }
67
74
  if (key.upArrow) {
68
- setSelectedIndex(Math.max(0, selectedIndex - 1));
75
+ dispatch({
76
+ type: "SELECT_INDEX",
77
+ index: Math.max(0, selectedIndex - 1),
78
+ });
69
79
  return;
70
80
  }
71
81
  if (key.downArrow) {
72
- setSelectedIndex(Math.min(tasks.length - 1, selectedIndex + 1));
82
+ dispatch({
83
+ type: "SELECT_INDEX",
84
+ index: Math.min(tasks.length - 1, selectedIndex + 1),
85
+ });
73
86
  return;
74
87
  }
75
88
  if (input === "k" && tasks.length > 0 && selectedIndex < tasks.length) {
@@ -83,9 +96,7 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
83
96
  else if (viewMode === "detail") {
84
97
  // Detail mode navigation
85
98
  if (key.escape) {
86
- setViewMode("list");
87
- setDetailTaskId(null);
88
- setDetailOutput(null);
99
+ dispatch({ type: "RESET_DETAIL" });
89
100
  return;
90
101
  }
91
102
  if (input === "k" && detailTaskId) {
@@ -100,7 +111,7 @@ export const BackgroundTaskManager = ({ onCancel, }) => {
100
111
  if (viewMode === "detail" && detailTaskId && detailOutput) {
101
112
  const task = tasks.find((t) => t.id === detailTaskId);
102
113
  if (!task) {
103
- setViewMode("list");
114
+ dispatch({ type: "RESET_DETAIL" });
104
115
  return null;
105
116
  }
106
117
  return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["Background Task Details: ", task.id] }) }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Type:" }), " ", task.type] }) }), task.description && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Description:" }), " ", task.description] }) })), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Status:" }), " ", task.status, task.exitCode !== undefined && ` (exit code: ${task.exitCode})`] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Started:" }), " ", formatTime(task.startTime), task.runtime !== undefined && (_jsxs(Text, { children: [" ", "| ", _jsx(Text, { color: "blue", children: "Runtime:" }), " ", formatDuration(task.runtime)] }))] }) }), task.outputPath && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Log File:" }), " ", task.outputPath] }) }))] }), detailOutput.stdout && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "green", bold: true, children: "OUTPUT (last 10 lines):" }), _jsx(Box, { borderStyle: "single", borderColor: "green", padding: 1, children: _jsx(Text, { children: getLastLines(detailOutput.stdout, 10) }) })] })), detailOutput.stderr && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "red", bold: true, children: "ERRORS:" }), _jsx(Box, { borderStyle: "single", borderColor: "red", padding: 1, children: _jsx(Text, { color: "red", children: getLastLines(detailOutput.stderr, 10) }) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [task.status === "running" ? "k to stop · " : "", "Esc to go back"] }) })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAkBzC,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,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,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,CAuQ5C,CAAC"}
1
+ {"version":3,"file":"InputBox.d.ts","sourceRoot":"","sources":["../../src/components/InputBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAkBzC,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,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,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,CA6Q5C,CAAC"}
@@ -19,7 +19,7 @@ import { useChat } from "../contexts/useChat.js";
19
19
  export const INPUT_PLACEHOLDER_TEXT = "Type your message (use /help for more info)...";
20
20
  export const INPUT_PLACEHOLDER_TEXT_PREFIX = INPUT_PLACEHOLDER_TEXT.substring(0, 10);
21
21
  export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mcpServers = [], connectMcpServer = async () => false, disconnectMcpServer = async () => false, slashCommands = [], hasSlashCommand = () => false, }) => {
22
- const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, allowBypassInCycle: chatAllowBypassInCycle, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, currentModel, configuredModels, setModel, } = useChat();
22
+ const { permissionMode: chatPermissionMode, setPermissionMode: setChatPermissionMode, allowBypassInCycle: chatAllowBypassInCycle, handleRewindSelect, backgroundCurrentTask, messages, getFullMessageThread, sessionId, workingDirectory, askBtw, currentModel, configuredModels, setModel, recreateAgent, } = useChat();
23
23
  // Input manager with all input state and functionality (including images)
24
24
  const { inputText, cursorPosition,
25
25
  // Image management
@@ -98,7 +98,7 @@ export const InputBox = ({ sendMessage = () => { }, abortMessage = () => { }, mc
98
98
  return _jsx(StatusCommand, { onCancel: () => setShowStatusCommand(false) });
99
99
  }
100
100
  if (showPluginManager) {
101
- return _jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false) });
101
+ return (_jsx(PluginManagerShell, { onCancel: () => setShowPluginManager(false), onPluginInstalled: recreateAgent }));
102
102
  }
103
103
  if (showModelSelector) {
104
104
  return (_jsx(ModelSelector, { onCancel: () => setShowModelSelector(false), currentModel: currentModel, configuredModels: configuredModels, onSelectModel: setModel }));
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceAddForm.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceAddForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAkDtC,CAAC"}
1
+ {"version":3,"file":"MarketplaceAddForm.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceAddForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAW1C,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAiGtC,CAAC"}
@@ -1,35 +1,66 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect } from "react";
2
+ import { useReducer } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
5
+ import { marketplaceAddFormReducer } from "../reducers/marketplaceAddFormReducer.js";
6
+ const SCOPES = [
7
+ { value: "user", label: "user" },
8
+ { value: "project", label: "project" },
9
+ { value: "local", label: "local" },
10
+ ];
5
11
  export const MarketplaceAddForm = () => {
6
12
  const { state, actions } = usePluginManagerContext();
7
- const [source, setSource] = useState("");
8
- const sourceRef = useRef(source);
9
- // Keep ref in sync with state
10
- useEffect(() => {
11
- sourceRef.current = source;
12
- }, [source]);
13
+ const [{ source, scopeIndex, step }, dispatch] = useReducer(marketplaceAddFormReducer, { source: "", scopeIndex: 0, step: "source" });
13
14
  useInput((input, key) => {
14
15
  if (key.escape) {
15
- actions.setView("MARKETPLACES");
16
+ if (step === "scope") {
17
+ dispatch({ type: "BACK_TO_SOURCE" });
18
+ }
19
+ else {
20
+ actions.setView("MARKETPLACES");
21
+ }
16
22
  }
17
23
  else if (state.isLoading) {
18
24
  return;
19
25
  }
20
- else if (key.return) {
21
- if (sourceRef.current.trim()) {
22
- actions.addMarketplace(sourceRef.current.trim());
26
+ else if (step === "source" && key.return) {
27
+ if (source.trim()) {
28
+ dispatch({ type: "SET_STEP", step: "scope" });
23
29
  }
24
30
  }
25
- else if (key.backspace || key.delete) {
26
- setSource((prev) => prev.slice(0, -1));
31
+ else if (step === "source" && (key.backspace || key.delete)) {
32
+ dispatch({ type: "DELETE_CHAR" });
33
+ }
34
+ else if (step === "source" &&
35
+ input &&
36
+ !key.ctrl &&
37
+ !key.meta &&
38
+ !("alt" in key && key.alt)) {
39
+ dispatch({ type: "INSERT_CHAR", text: input });
27
40
  }
28
- else if (input.length === 1) {
29
- setSource((prev) => prev + input);
41
+ else if (step === "scope") {
42
+ if (key.upArrow) {
43
+ dispatch({
44
+ type: "SET_SCOPE_INDEX",
45
+ index: Math.max(0, scopeIndex - 1),
46
+ });
47
+ }
48
+ else if (key.downArrow) {
49
+ dispatch({
50
+ type: "SET_SCOPE_INDEX",
51
+ index: Math.min(SCOPES.length - 1, scopeIndex + 1),
52
+ });
53
+ }
54
+ else if (key.return) {
55
+ const scope = SCOPES[scopeIndex].value;
56
+ actions.addMarketplace(source.trim(), scope);
57
+ }
30
58
  }
31
59
  });
32
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Add Marketplace" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "Source (URL or Path): " }), _jsx(Text, { color: state.isLoading ? "gray" : "yellow", children: source }), !state.isLoading && _jsx(Text, { color: "yellow", children: "_" })] }), state.isLoading && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "\u231B Adding marketplace..." }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
60
+ if (step === "source") {
61
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Step 1/2: Enter marketplace source" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { children: "Source: " }), _jsx(Text, { color: "yellow", children: source }), !state.isLoading && _jsx(Text, { color: "yellow", children: "_" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter to continue, Esc to cancel" }) })] }));
62
+ }
63
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Step 2/2: Select scope" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Source: " }), _jsx(Text, { dimColor: true, children: source })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: SCOPES.map((s, i) => (_jsxs(Text, { color: i === scopeIndex ? "yellow" : "dim", children: [i === scopeIndex ? "> " : " ", s.label] }, s.value))) }), state.isLoading && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "yellow", children: "Adding marketplace..." }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
33
64
  ? "Please wait..."
34
- : "Press Enter to add, Esc to cancel" }) })] }));
65
+ : "Enter to confirm, \u2191/\u2193 to navigate, Esc to go back" }) })] }));
35
66
  };
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceDetail.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAmHrC,CAAC"}
1
+ {"version":3,"file":"MarketplaceDetail.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAuHrC,CAAC"}
@@ -40,7 +40,8 @@ export const MarketplaceDetail = () => {
40
40
  if (!marketplace) {
41
41
  return (_jsx(Box, { children: _jsx(Text, { color: "red", children: "Marketplace not found." }) }));
42
42
  }
43
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: marketplace.name }), marketplace.isBuiltin && _jsx(Text, { dimColor: true, children: " (Built-in)" })] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Source: ", JSON.stringify(marketplace.source)] }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Auto-update:", " ", _jsx(Text, { color: marketplace.autoUpdate ? "green" : "red", children: marketplace.autoUpdate ? "Enabled" : "Disabled" })] }) }), marketplace.lastUpdated && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Last updated:", " ", _jsx(Text, { color: "cyan", children: new Date(marketplace.lastUpdated).toLocaleString() })] }) })), state.isLoading && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u231B Processing operation..." }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Marketplace Actions:" }), ACTIONS.map((action, index) => (_jsxs(Text, { color: index === selectedActionIndex
43
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: marketplace.name }), marketplace.isBuiltin && _jsx(Text, { dimColor: true, children: " (Built-in)" }), marketplace.declaredScope &&
44
+ marketplace.declaredScope !== "builtin" && (_jsxs(Text, { dimColor: true, children: [" (", marketplace.declaredScope, " scope)"] }))] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Source: ", JSON.stringify(marketplace.source)] }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Auto-update:", " ", _jsx(Text, { color: marketplace.autoUpdate ? "green" : "red", children: marketplace.autoUpdate ? "Enabled" : "Disabled" })] }) }), marketplace.lastUpdated && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Last updated:", " ", _jsx(Text, { color: "cyan", children: new Date(marketplace.lastUpdated).toLocaleString() })] }) })), state.isLoading && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u231B Processing operation..." }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Marketplace Actions:" }), ACTIONS.map((action, index) => (_jsxs(Text, { color: index === selectedActionIndex
44
45
  ? state.isLoading
45
46
  ? "gray"
46
47
  : "yellow"
@@ -1 +1 @@
1
- {"version":3,"file":"MarketplaceList.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,oBAAoB;IAC5B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAgD1D,CAAC"}
1
+ {"version":3,"file":"MarketplaceList.d.ts","sourceRoot":"","sources":["../../src/components/MarketplaceList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,UAAU,oBAAoB;IAC5B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAoD1D,CAAC"}
@@ -11,6 +11,7 @@ export const MarketplaceList = ({ marketplaces, selectedIndex, }) => {
11
11
  : marketplace.source.source === "github"
12
12
  ? marketplace.source.repo
13
13
  : marketplace.source.url;
14
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: marketplace.name }), marketplace.isBuiltin && (_jsx(Text, { color: "yellow", children: " [Built-in]" }))] }) }), _jsxs(Box, { marginLeft: 4, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["Source: ", sourceStr] }), marketplace.lastUpdated && (_jsxs(Text, { dimColor: true, children: ["Last updated:", " ", new Date(marketplace.lastUpdated).toLocaleString()] }))] })] }, marketplace.name));
14
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: isSelected ? "cyan" : undefined, children: [isSelected ? "> " : " ", _jsx(Text, { bold: true, children: marketplace.name }), marketplace.isBuiltin && (_jsx(Text, { color: "yellow", children: " [Built-in]" })), marketplace.declaredScope &&
15
+ marketplace.declaredScope !== "builtin" && (_jsxs(Text, { color: "magenta", children: [" [", marketplace.declaredScope, "]"] }))] }) }), _jsxs(Box, { marginLeft: 4, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["Source: ", sourceStr] }), marketplace.lastUpdated && (_jsxs(Text, { dimColor: true, children: ["Last updated:", " ", new Date(marketplace.lastUpdated).toLocaleString()] }))] })] }, marketplace.name));
15
16
  }) }));
16
17
  };
@@ -1 +1 @@
1
- {"version":3,"file":"McpManager.d.ts","sourceRoot":"","sources":["../../src/components/McpManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAoThD,CAAC"}
1
+ {"version":3,"file":"McpManager.d.ts","sourceRoot":"","sources":["../../src/components/McpManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D;AAOD,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAuShD,CAAC"}
@@ -1,23 +1,18 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect } from "react";
2
+ import { useReducer } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
+ import { mcpManagerReducer, } from "../reducers/mcpManagerReducer.js";
5
+ const initialState = {
6
+ selectedIndex: 0,
7
+ viewMode: "list",
8
+ };
4
9
  export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectServer, }) => {
5
- const [selectedIndex, setSelectedIndex] = useState(0);
6
- const [viewMode, setViewMode] = useState("list");
7
- // Keep ref in sync with state to avoid stale closures in useInput
8
- const selectedIndexRef = useRef(selectedIndex);
9
- const viewModeRef = useRef(viewMode);
10
- useEffect(() => {
11
- selectedIndexRef.current = selectedIndex;
12
- }, [selectedIndex]);
13
- useEffect(() => {
14
- viewModeRef.current = viewMode;
15
- }, [viewMode]);
10
+ const [state, dispatch] = useReducer(mcpManagerReducer, initialState);
16
11
  // Dynamically calculate selectedServer based on selectedIndex and servers
17
- const selectedServer = viewMode === "detail" &&
12
+ const selectedServer = state.viewMode === "detail" &&
18
13
  servers.length > 0 &&
19
- selectedIndex < servers.length
20
- ? servers[selectedIndex]
14
+ state.selectedIndex < servers.length
15
+ ? servers[state.selectedIndex]
21
16
  : null;
22
17
  const formatTime = (timestamp) => {
23
18
  return new Date(timestamp).toLocaleTimeString();
@@ -54,14 +49,14 @@ export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectSer
54
49
  };
55
50
  useInput((input, key) => {
56
51
  if (key.return) {
57
- if (viewModeRef.current === "list") {
58
- setViewMode("detail");
52
+ if (state.viewMode === "list") {
53
+ dispatch({ type: "SET_VIEW_MODE", viewMode: "detail" });
59
54
  }
60
55
  return;
61
56
  }
62
57
  if (key.escape) {
63
- if (viewModeRef.current === "detail") {
64
- setViewMode("list");
58
+ if (state.viewMode === "detail") {
59
+ dispatch({ type: "SET_VIEW_MODE", viewMode: "list" });
65
60
  }
66
61
  else {
67
62
  onCancel();
@@ -69,16 +64,16 @@ export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectSer
69
64
  return;
70
65
  }
71
66
  if (key.upArrow) {
72
- setSelectedIndex((prev) => Math.max(0, prev - 1));
67
+ dispatch({ type: "MOVE_UP", serverCount: servers.length });
73
68
  return;
74
69
  }
75
70
  if (key.downArrow) {
76
- setSelectedIndex((prev) => Math.min(servers.length - 1, prev + 1));
71
+ dispatch({ type: "MOVE_DOWN", serverCount: servers.length });
77
72
  return;
78
73
  }
79
74
  // Hotkeys for server actions
80
75
  if (input === "c") {
81
- const server = servers[selectedIndexRef.current];
76
+ const server = servers[state.selectedIndex];
82
77
  if (server &&
83
78
  (server.status === "disconnected" || server.status === "error")) {
84
79
  handleConnect(server.name);
@@ -86,14 +81,14 @@ export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectSer
86
81
  return;
87
82
  }
88
83
  if (input === "d") {
89
- const server = servers[selectedIndexRef.current];
84
+ const server = servers[state.selectedIndex];
90
85
  if (server && server.status === "connected") {
91
86
  handleDisconnect(server.name);
92
87
  }
93
88
  return;
94
89
  }
95
90
  });
96
- if (viewMode === "detail" && selectedServer) {
91
+ if (state.viewMode === "detail" && selectedServer) {
97
92
  return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "cyan", bold: true, children: ["MCP Server Details: ", selectedServer.name] }) }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Status:" }), " ", _jsxs(Text, { color: getStatusColor(selectedServer.status), children: [getStatusIcon(selectedServer.status), " ", selectedServer.status] })] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Command:" }), " ", selectedServer.config.command] }) }), selectedServer.config.args && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Args:" }), " ", selectedServer.config.args.join(" ")] }) })), selectedServer.toolCount !== undefined && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Tools:" }), " ", selectedServer.toolCount, " ", "tools"] }) })), selectedServer.capabilities && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Capabilities:" }), " ", selectedServer.capabilities.join(", ")] }) })), selectedServer.lastConnected && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "blue", children: "Last Connected:" }), " ", formatTime(selectedServer.lastConnected)] }) })), selectedServer.error && (_jsx(Box, { children: _jsxs(Text, { children: [_jsx(Text, { color: "red", children: "Error:" }), " ", selectedServer.error] }) }))] }), selectedServer.config.env &&
98
93
  Object.keys(selectedServer.config.env).length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "blue", bold: true, children: "Environment Variables:" }), _jsx(Box, { borderStyle: "single", borderColor: "blue", padding: 1, children: Object.entries(selectedServer.config.env).map(([key, value]) => (_jsxs(Text, { children: [key, "=", value] }, key))) })] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [selectedServer.status === "disconnected" ||
99
94
  selectedServer.status === "error"
@@ -103,10 +98,10 @@ export const McpManager = ({ onCancel, servers, onConnectServer, onDisconnectSer
103
98
  if (servers.length === 0) {
104
99
  return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Manage MCP servers" }), _jsx(Text, { children: "No MCP servers configured" }), _jsx(Text, { dimColor: true, children: "Create a .mcp.json file in your project root to add servers" }), _jsx(Text, { dimColor: true, children: "Press Escape to close" })] }));
105
100
  }
106
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Manage MCP servers" }) }), _jsx(Text, { dimColor: true, children: "Select a server to view details" }), servers.map((server, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: index === selectedIndex ? "black" : "white", backgroundColor: index === selectedIndex ? "cyan" : undefined, children: [index === selectedIndex ? "▶ " : " ", index + 1, ".", " ", _jsx(Text, { color: getStatusColor(server.status), children: getStatusIcon(server.status) }), " ", server.name, server.status === "connected" && server.toolCount && (_jsxs(Text, { color: "green", children: [" \u00B7 ", server.toolCount, " tools"] }))] }), index === selectedIndex && (_jsxs(Box, { marginLeft: 4, flexDirection: "column", children: [_jsxs(Text, { color: "gray", dimColor: true, children: [server.config.command, server.config.args ? ` ${server.config.args.join(" ")}` : ""] }), server.lastConnected && (_jsxs(Text, { color: "gray", dimColor: true, children: ["Last connected: ", formatTime(server.lastConnected)] }))] }))] }, server.name))), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\u2191/\u2193 to select \u00B7 Enter to view \u00B7", " ", servers[selectedIndex]?.status === "disconnected" ||
107
- servers[selectedIndex]?.status === "error"
101
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "cyan", borderBottom: false, borderLeft: false, borderRight: false, paddingTop: 1, gap: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "cyan", bold: true, children: "Manage MCP servers" }) }), _jsx(Text, { dimColor: true, children: "Select a server to view details" }), servers.map((server, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: index === state.selectedIndex ? "black" : "white", backgroundColor: index === state.selectedIndex ? "cyan" : undefined, children: [index === state.selectedIndex ? "▶ " : " ", index + 1, ".", " ", _jsx(Text, { color: getStatusColor(server.status), children: getStatusIcon(server.status) }), " ", server.name, server.status === "connected" && server.toolCount && (_jsxs(Text, { color: "green", children: [" \u00B7 ", server.toolCount, " tools"] }))] }), index === state.selectedIndex && (_jsxs(Box, { marginLeft: 4, flexDirection: "column", children: [_jsxs(Text, { color: "gray", dimColor: true, children: [server.config.command, server.config.args ? ` ${server.config.args.join(" ")}` : ""] }), server.lastConnected && (_jsxs(Text, { color: "gray", dimColor: true, children: ["Last connected: ", formatTime(server.lastConnected)] }))] }))] }, server.name))), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\u2191/\u2193 to select \u00B7 Enter to view \u00B7", " ", servers[state.selectedIndex]?.status === "disconnected" ||
102
+ servers[state.selectedIndex]?.status === "error"
108
103
  ? "c to connect · "
109
- : "", servers[selectedIndex]?.status === "connected"
104
+ : "", servers[state.selectedIndex]?.status === "connected"
110
105
  ? "d to disconnect · "
111
106
  : "", "Esc to close"] }) })] }));
112
107
  };
@@ -1 +1 @@
1
- {"version":3,"file":"PluginDetail.d.ts","sourceRoot":"","sources":["../../src/components/PluginDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAU3D,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAqKhC,CAAC"}
1
+ {"version":3,"file":"PluginDetail.d.ts","sourceRoot":"","sources":["../../src/components/PluginDetail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAc1C,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAyJhC,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect } from "react";
2
+ import { useReducer } from "react";
3
3
  import { Box, Text, useInput } from "ink";
4
4
  import { usePluginManagerContext } from "../contexts/PluginManagerContext.js";
5
+ import { pluginDetailReducer, } from "../reducers/pluginDetailReducer.js";
5
6
  const SCOPES = [
6
7
  { id: "project", label: "Install for all collaborators (project scope)" },
7
8
  { id: "user", label: "Install for you (user scope)" },
@@ -9,17 +10,10 @@ const SCOPES = [
9
10
  ];
10
11
  export const PluginDetail = () => {
11
12
  const { state, discoverablePlugins, installedPlugins, actions } = usePluginManagerContext();
12
- const [selectedScopeIndex, setSelectedScopeIndex] = useState(0);
13
- const [selectedActionIndex, setSelectedActionIndex] = useState(0);
14
- // Keep refs in sync with state to avoid stale closures in useInput
15
- const selectedScopeIndexRef = useRef(selectedScopeIndex);
16
- const selectedActionIndexRef = useRef(selectedActionIndex);
17
- useEffect(() => {
18
- selectedScopeIndexRef.current = selectedScopeIndex;
19
- }, [selectedScopeIndex]);
20
- useEffect(() => {
21
- selectedActionIndexRef.current = selectedActionIndex;
22
- }, [selectedActionIndex]);
13
+ const [detailState, dispatch] = useReducer(pluginDetailReducer, {
14
+ selectedScopeIndex: 0,
15
+ selectedActionIndex: 0,
16
+ });
23
17
  const plugin = discoverablePlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId) ||
24
18
  installedPlugins.find((p) => `${p.name}@${p.marketplace}` === state.selectedId);
25
19
  const INSTALLED_ACTIONS = [
@@ -33,16 +27,22 @@ export const PluginDetail = () => {
33
27
  actions.setView(isFromDiscover ? "DISCOVER" : "INSTALLED");
34
28
  }
35
29
  else if (key.upArrow) {
36
- setSelectedActionIndex((prev) => prev > 0 ? prev - 1 : INSTALLED_ACTIONS.length - 1);
37
- setSelectedScopeIndex((prev) => prev > 0 ? prev - 1 : SCOPES.length - 1);
30
+ dispatch({
31
+ type: "MOVE_ACTION_UP",
32
+ maxIndex: INSTALLED_ACTIONS.length - 1,
33
+ });
34
+ dispatch({ type: "MOVE_SCOPE_UP", maxIndex: SCOPES.length - 1 });
38
35
  }
39
36
  else if (key.downArrow) {
40
- setSelectedActionIndex((prev) => prev < INSTALLED_ACTIONS.length - 1 ? prev + 1 : 0);
41
- setSelectedScopeIndex((prev) => prev < SCOPES.length - 1 ? prev + 1 : 0);
37
+ dispatch({
38
+ type: "MOVE_ACTION_DOWN",
39
+ maxIndex: INSTALLED_ACTIONS.length - 1,
40
+ });
41
+ dispatch({ type: "MOVE_SCOPE_DOWN", maxIndex: SCOPES.length - 1 });
42
42
  }
43
43
  else if (key.return && plugin && !state.isLoading) {
44
44
  if (isInstalledAndEnabled) {
45
- const action = INSTALLED_ACTIONS[selectedActionIndexRef.current].id;
45
+ const action = INSTALLED_ACTIONS[detailState.selectedActionIndex].id;
46
46
  if (action === "uninstall") {
47
47
  actions.uninstallPlugin(plugin.name, plugin.marketplace);
48
48
  }
@@ -51,24 +51,24 @@ export const PluginDetail = () => {
51
51
  }
52
52
  }
53
53
  else {
54
- actions.installPlugin(plugin.name, plugin.marketplace, SCOPES[selectedScopeIndexRef.current].id);
54
+ actions.installPlugin(plugin.name, plugin.marketplace, SCOPES[detailState.selectedScopeIndex].id);
55
55
  }
56
56
  }
57
57
  });
58
58
  if (!plugin) {
59
59
  return (_jsx(Box, { children: _jsx(Text, { color: "red", children: "Plugin not found." }) }));
60
60
  }
61
- return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] })] }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "description" in plugin ? plugin.description : "" }) }), plugin.version && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Version: ", _jsx(Text, { color: "blue", children: plugin.version })] }) })), state.isLoading && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u231B Processing operation..." }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [isInstalledAndEnabled ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Plugin Actions:" }), INSTALLED_ACTIONS.map((action, index) => (_jsxs(Text, { color: index === selectedActionIndex
61
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: plugin.name }), _jsxs(Text, { dimColor: true, children: [" @", plugin.marketplace] })] }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "description" in plugin ? plugin.description : "" }) }), plugin.version && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Version: ", _jsx(Text, { color: "blue", children: plugin.version })] }) })), state.isLoading && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u231B Processing operation..." }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [isInstalledAndEnabled ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Plugin Actions:" }), INSTALLED_ACTIONS.map((action, index) => (_jsxs(Text, { color: index === detailState.selectedActionIndex
62
62
  ? state.isLoading
63
63
  ? "gray"
64
64
  : "yellow"
65
- : undefined, children: [index === selectedActionIndex ? "> " : " ", action.label] }, action.id))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
65
+ : undefined, children: [index === detailState.selectedActionIndex ? "> " : " ", action.label] }, action.id))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
66
66
  ? "Please wait..."
67
- : "Use ↑/↓ to select, Enter to confirm" }) })] })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Select Installation Scope:" }), SCOPES.map((scope, index) => (_jsxs(Text, { color: index === selectedScopeIndex
67
+ : "Use ↑/↓ to select, Enter to confirm" }) })] })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Select Installation Scope:" }), SCOPES.map((scope, index) => (_jsxs(Text, { color: index === detailState.selectedScopeIndex
68
68
  ? state.isLoading
69
69
  ? "gray"
70
70
  : "green"
71
- : undefined, children: [index === selectedScopeIndex ? "> " : " ", scope.label] }, scope.id))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
71
+ : undefined, children: [index === detailState.selectedScopeIndex ? "> " : " ", scope.label] }, scope.id))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: state.isLoading
72
72
  ? "Please wait..."
73
73
  : "Use ↑/↓ to select, Enter to install" }) })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Esc to go back" }) })] })] }));
74
74
  };
@@ -2,5 +2,6 @@ import React from "react";
2
2
  export declare const PluginManagerShell: React.FC<{
3
3
  children?: React.ReactNode;
4
4
  onCancel?: () => void;
5
+ onPluginInstalled?: () => void;
5
6
  }>;
6
7
  //# 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;IACxC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAkMA,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;IACtB,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC,CAkMA,CAAC"}
@@ -8,8 +8,8 @@ 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, onCancel }) => {
12
- const pluginManager = usePluginManager();
11
+ export const PluginManagerShell = ({ children, onCancel, onPluginInstalled }) => {
12
+ const pluginManager = usePluginManager({ onPluginInstalled });
13
13
  const { state, actions, discoverablePlugins } = pluginManager;
14
14
  const setView = (view) => {
15
15
  if (view !== "PLUGIN_DETAIL" &&
@@ -22,8 +22,8 @@ export interface PluginManagerContextType {
22
22
  actions: {
23
23
  setView: (view: ViewType) => void;
24
24
  setSelectedId: (id: string | null) => void;
25
- addMarketplace: (source: string) => Promise<void>;
26
- removeMarketplace: (name: string) => Promise<void>;
25
+ addMarketplace: (source: string, scope?: "user" | "project" | "local") => Promise<void>;
26
+ removeMarketplace: (name: string, scope?: "user" | "project" | "local") => Promise<void>;
27
27
  updateMarketplace: (name: string) => Promise<void>;
28
28
  installPlugin: (name: string, marketplace: string, scope?: "user" | "project" | "local") => Promise<void>;
29
29
  uninstallPlugin: (name: string, marketplace: string) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"PluginManagerTypes.d.ts","sourceRoot":"","sources":["../../src/components/PluginManagerTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,WAAW,GACX,cAAc,GACd,eAAe,GACf,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,QAAQ,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,gBAAgB,EAAE,CAAC,eAAe,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,CAAC;IAC7D,mBAAmB,EAAE,CAAC,sBAAsB,GAAG;QAC7C,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,EAAE,CAAC;IACL,OAAO,EAAE;QACP,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;QAClC,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;QAC3C,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,aAAa,EAAE,CACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,mBAAmB,EAAE,MAAM,IAAI,CAAC;KACjC,CAAC;CACH"}
1
+ {"version":3,"file":"PluginManagerTypes.d.ts","sourceRoot":"","sources":["../../src/components/PluginManagerTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,WAAW,GACX,cAAc,GACd,eAAe,GACf,oBAAoB,GACpB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,QAAQ,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,gBAAgB,EAAE,CAAC,eAAe,GAAG;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,CAAC;IAC7D,mBAAmB,EAAE,CAAC,sBAAsB,GAAG;QAC7C,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,EAAE,CAAC;IACL,OAAO,EAAE;QACP,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;QAClC,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;QAC3C,cAAc,EAAE,CACd,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,iBAAiB,EAAE,CACjB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,aAAa,EAAE,CACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtE,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7B,mBAAmB,EAAE,MAAM,IAAI,CAAC;KACjC,CAAC;CACH"}
@@ -65,6 +65,7 @@ export interface ChatContextType {
65
65
  workingDirectory: string;
66
66
  version?: string;
67
67
  workdir?: string;
68
+ recreateAgent: () => void;
68
69
  }
69
70
  export declare const useChat: () => ChatContextType;
70
71
  export interface ChatProviderProps extends BaseAppProps {
@@ -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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"}