claudeup 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +91 -0
  2. package/bin/claudeup.js +6 -0
  3. package/dist/data/cli-tools.d.ts +13 -0
  4. package/dist/data/cli-tools.d.ts.map +1 -0
  5. package/dist/data/cli-tools.js +91 -0
  6. package/dist/data/cli-tools.js.map +1 -0
  7. package/dist/data/marketplaces.d.ts +4 -0
  8. package/dist/data/marketplaces.d.ts.map +1 -0
  9. package/dist/data/marketplaces.js +26 -0
  10. package/dist/data/marketplaces.js.map +1 -0
  11. package/dist/data/mcp-servers.d.ts +8 -0
  12. package/dist/data/mcp-servers.d.ts.map +1 -0
  13. package/dist/data/mcp-servers.js +421 -0
  14. package/dist/data/mcp-servers.js.map +1 -0
  15. package/dist/data/statuslines.d.ts +10 -0
  16. package/dist/data/statuslines.d.ts.map +1 -0
  17. package/dist/data/statuslines.js +160 -0
  18. package/dist/data/statuslines.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +12 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/services/claude-settings.d.ts +31 -0
  24. package/dist/services/claude-settings.d.ts.map +1 -0
  25. package/dist/services/claude-settings.js +177 -0
  26. package/dist/services/claude-settings.js.map +1 -0
  27. package/dist/services/mcp-registry.d.ts +10 -0
  28. package/dist/services/mcp-registry.d.ts.map +1 -0
  29. package/dist/services/mcp-registry.js +88 -0
  30. package/dist/services/mcp-registry.js.map +1 -0
  31. package/dist/services/plugin-manager.d.ts +22 -0
  32. package/dist/services/plugin-manager.d.ts.map +1 -0
  33. package/dist/services/plugin-manager.js +115 -0
  34. package/dist/services/plugin-manager.js.map +1 -0
  35. package/dist/types/index.d.ts +83 -0
  36. package/dist/types/index.d.ts.map +1 -0
  37. package/dist/types/index.js +2 -0
  38. package/dist/types/index.js.map +1 -0
  39. package/dist/ui/app.d.ts +28 -0
  40. package/dist/ui/app.d.ts.map +1 -0
  41. package/dist/ui/app.js +408 -0
  42. package/dist/ui/app.js.map +1 -0
  43. package/dist/ui/screens/cli-tools.d.ts +3 -0
  44. package/dist/ui/screens/cli-tools.d.ts.map +1 -0
  45. package/dist/ui/screens/cli-tools.js +314 -0
  46. package/dist/ui/screens/cli-tools.js.map +1 -0
  47. package/dist/ui/screens/main-menu.d.ts +3 -0
  48. package/dist/ui/screens/main-menu.d.ts.map +1 -0
  49. package/dist/ui/screens/main-menu.js +110 -0
  50. package/dist/ui/screens/main-menu.js.map +1 -0
  51. package/dist/ui/screens/marketplace.d.ts +3 -0
  52. package/dist/ui/screens/marketplace.d.ts.map +1 -0
  53. package/dist/ui/screens/marketplace.js +132 -0
  54. package/dist/ui/screens/marketplace.js.map +1 -0
  55. package/dist/ui/screens/mcp-registry.d.ts +10 -0
  56. package/dist/ui/screens/mcp-registry.d.ts.map +1 -0
  57. package/dist/ui/screens/mcp-registry.js +310 -0
  58. package/dist/ui/screens/mcp-registry.js.map +1 -0
  59. package/dist/ui/screens/mcp-setup.d.ts +4 -0
  60. package/dist/ui/screens/mcp-setup.d.ts.map +1 -0
  61. package/dist/ui/screens/mcp-setup.js +417 -0
  62. package/dist/ui/screens/mcp-setup.js.map +1 -0
  63. package/dist/ui/screens/plugins.d.ts +3 -0
  64. package/dist/ui/screens/plugins.d.ts.map +1 -0
  65. package/dist/ui/screens/plugins.js +330 -0
  66. package/dist/ui/screens/plugins.js.map +1 -0
  67. package/dist/ui/screens/statusline.d.ts +5 -0
  68. package/dist/ui/screens/statusline.d.ts.map +1 -0
  69. package/dist/ui/screens/statusline.js +235 -0
  70. package/dist/ui/screens/statusline.js.map +1 -0
  71. package/package.json +58 -0
@@ -0,0 +1,314 @@
1
+ import blessed from 'neo-blessed';
2
+ import { exec, execSync } from 'child_process';
3
+ import { promisify } from 'util';
4
+ import { createHeader, createFooter, showMessage } from '../app.js';
5
+ import { cliTools } from '../../data/cli-tools.js';
6
+ const execAsync = promisify(exec);
7
+ function parseVersion(versionOutput) {
8
+ // Extract version number from various formats like "v1.2.3", "1.2.3", "aider 0.82.0"
9
+ const match = versionOutput.match(/v?(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
10
+ return match ? match[1] : undefined;
11
+ }
12
+ async function getInstalledVersion(tool) {
13
+ try {
14
+ const { stdout } = await execAsync(tool.checkCommand, { timeout: 5000 });
15
+ return parseVersion(stdout.trim());
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ async function getLatestNpmVersion(packageName) {
22
+ try {
23
+ const { stdout } = await execAsync(`npm view ${packageName} version 2>/dev/null`, { timeout: 10000 });
24
+ return stdout.trim() || undefined;
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
30
+ async function getLatestPipVersion(packageName) {
31
+ try {
32
+ const { stdout } = await execAsync(`pip index versions ${packageName} 2>/dev/null | head -1`, {
33
+ timeout: 10000,
34
+ shell: '/bin/bash',
35
+ });
36
+ const match = stdout.trim().match(/\(([^)]+)\)/);
37
+ return match ? match[1] : undefined;
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ }
43
+ async function getLatestVersion(tool) {
44
+ if (tool.packageManager === 'npm') {
45
+ return getLatestNpmVersion(tool.packageName);
46
+ }
47
+ else {
48
+ return getLatestPipVersion(tool.packageName);
49
+ }
50
+ }
51
+ function compareVersions(v1, v2) {
52
+ const parts1 = v1.split(/[-.]/).map((p) => parseInt(p, 10) || 0);
53
+ const parts2 = v2.split(/[-.]/).map((p) => parseInt(p, 10) || 0);
54
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
55
+ const p1 = parts1[i] || 0;
56
+ const p2 = parts2[i] || 0;
57
+ if (p1 < p2)
58
+ return -1;
59
+ if (p1 > p2)
60
+ return 1;
61
+ }
62
+ return 0;
63
+ }
64
+ export async function createCliToolsScreen(state) {
65
+ createHeader(state, 'CLI Tools');
66
+ // Initialize tool statuses - all checking initially
67
+ const toolStatuses = cliTools.map((tool) => ({
68
+ tool,
69
+ installed: false,
70
+ installedVersion: undefined,
71
+ checking: true,
72
+ }));
73
+ // Build list items
74
+ const buildListItems = () => {
75
+ return toolStatuses.map((status) => {
76
+ let icon;
77
+ let versionInfo = '';
78
+ let badge = '';
79
+ if (!status.installed) {
80
+ icon = '{gray-fg}○{/gray-fg}';
81
+ if (status.checking) {
82
+ badge = ' {gray-fg}...{/gray-fg}';
83
+ }
84
+ else if (status.latestVersion) {
85
+ versionInfo = ` {gray-fg}v${status.latestVersion}{/gray-fg}`;
86
+ }
87
+ }
88
+ else if (status.checking) {
89
+ icon = '{green-fg}●{/green-fg}';
90
+ versionInfo = ` {green-fg}v${status.installedVersion}{/green-fg}`;
91
+ badge = ' {gray-fg}...{/gray-fg}';
92
+ }
93
+ else if (status.hasUpdate) {
94
+ icon = '{yellow-fg}↑{/yellow-fg}';
95
+ versionInfo = ` {yellow-fg}v${status.installedVersion}{/yellow-fg}`;
96
+ badge = ` {cyan-fg}→ v${status.latestVersion}{/cyan-fg}`;
97
+ }
98
+ else {
99
+ icon = '{green-fg}●{/green-fg}';
100
+ versionInfo = ` {green-fg}v${status.installedVersion}{/green-fg}`;
101
+ badge = ' {cyan-fg}(up-to-date){/cyan-fg}';
102
+ }
103
+ return `${icon} {bold}${status.tool.displayName}{/bold}${versionInfo}${badge}`;
104
+ });
105
+ };
106
+ // List
107
+ const list = blessed.list({
108
+ parent: state.screen,
109
+ top: 3,
110
+ left: 2,
111
+ width: '50%-2',
112
+ height: '100%-5',
113
+ items: buildListItems(),
114
+ keys: true,
115
+ vi: false,
116
+ mouse: true,
117
+ tags: true,
118
+ scrollable: true,
119
+ border: { type: 'line' },
120
+ style: {
121
+ selected: { bg: 'magenta', fg: 'white' },
122
+ border: { fg: 'gray' },
123
+ },
124
+ scrollbar: { ch: '|', style: { bg: 'gray' } },
125
+ label: ' AI Coding Tools ',
126
+ });
127
+ // Detail panel
128
+ const detailBox = blessed.box({
129
+ parent: state.screen,
130
+ top: 3,
131
+ right: 2,
132
+ width: '50%-2',
133
+ height: '100%-5',
134
+ content: '',
135
+ tags: true,
136
+ border: { type: 'line' },
137
+ style: { border: { fg: 'gray' } },
138
+ label: ' Details ',
139
+ });
140
+ // Update detail panel
141
+ const updateDetail = () => {
142
+ const selected = list.selected;
143
+ const status = toolStatuses[selected];
144
+ if (!status)
145
+ return;
146
+ const { tool, installed, installedVersion, latestVersion, hasUpdate, checking } = status;
147
+ let statusText;
148
+ if (!installed) {
149
+ statusText = '{gray-fg}Not installed{/gray-fg}';
150
+ }
151
+ else if (checking) {
152
+ statusText = '{green-fg}Installed{/green-fg} {gray-fg}(checking for updates...){/gray-fg}';
153
+ }
154
+ else if (hasUpdate) {
155
+ statusText = '{yellow-fg}Update available{/yellow-fg}';
156
+ }
157
+ else {
158
+ statusText = '{green-fg}Up to date{/green-fg}';
159
+ }
160
+ let versionText = '';
161
+ if (installedVersion) {
162
+ versionText += `{bold}Installed:{/bold} {green-fg}v${installedVersion}{/green-fg}\n`;
163
+ }
164
+ if (latestVersion) {
165
+ versionText += `{bold}Latest:{/bold} {cyan-fg}v${latestVersion}{/cyan-fg}\n`;
166
+ }
167
+ else if (checking) {
168
+ versionText += `{bold}Latest:{/bold} {gray-fg}checking...{/gray-fg}\n`;
169
+ }
170
+ let actionText;
171
+ if (!installed) {
172
+ actionText = '{green-fg}Press Enter to install{/green-fg}';
173
+ }
174
+ else if (hasUpdate) {
175
+ actionText = '{yellow-fg}Press Enter to update{/yellow-fg}';
176
+ }
177
+ else {
178
+ actionText = '{gray-fg}Press Enter to reinstall{/gray-fg}';
179
+ }
180
+ const content = `
181
+ {bold}{cyan-fg}${tool.displayName}{/cyan-fg}{/bold}
182
+
183
+ ${tool.description}
184
+
185
+ {bold}Status:{/bold} ${statusText}
186
+ ${versionText}
187
+ {bold}Install:{/bold}
188
+ {gray-fg}${tool.installCommand}{/gray-fg}
189
+
190
+ {bold}Website:{/bold}
191
+ {cyan-fg}${tool.website}{/cyan-fg}
192
+
193
+ ${actionText}
194
+ `.trim();
195
+ detailBox.setContent(content);
196
+ state.screen.render();
197
+ };
198
+ list.on('select item', updateDetail);
199
+ setTimeout(updateDetail, 0);
200
+ // Refresh list display
201
+ const refreshList = () => {
202
+ const items = buildListItems();
203
+ for (let i = 0; i < items.length; i++) {
204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
+ list.setItem(i, items[i]);
206
+ }
207
+ updateDetail();
208
+ state.screen.render();
209
+ };
210
+ // Fetch all version info asynchronously
211
+ const fetchVersionInfo = async () => {
212
+ // First, check installed versions in parallel (fast, local)
213
+ const installedChecks = toolStatuses.map(async (status) => {
214
+ const installed = await getInstalledVersion(status.tool);
215
+ status.installedVersion = installed;
216
+ status.installed = installed !== undefined;
217
+ refreshList();
218
+ });
219
+ // Don't wait for all installed checks - start fetching latest versions immediately
220
+ // This runs both in parallel for maximum speed
221
+ const latestChecks = toolStatuses.map(async (status) => {
222
+ try {
223
+ const latest = await getLatestVersion(status.tool);
224
+ status.latestVersion = latest;
225
+ status.checking = false;
226
+ if (status.installedVersion && latest) {
227
+ status.hasUpdate = compareVersions(status.installedVersion, latest) < 0;
228
+ }
229
+ }
230
+ catch {
231
+ status.checking = false;
232
+ }
233
+ refreshList();
234
+ });
235
+ // Wait for all to complete
236
+ await Promise.all([...installedChecks, ...latestChecks]);
237
+ };
238
+ // Start async version fetching immediately
239
+ fetchVersionInfo();
240
+ // Install/Update on Enter
241
+ list.on('select', async (_item, index) => {
242
+ const status = toolStatuses[index];
243
+ if (!status)
244
+ return;
245
+ const { tool, installed, hasUpdate } = status;
246
+ const action = !installed ? 'Installing' : hasUpdate ? 'Updating' : 'Reinstalling';
247
+ await showMessage(state, action, `Running: ${tool.installCommand}\n\nThis may take a moment...`, 'info');
248
+ try {
249
+ execSync(tool.installCommand, {
250
+ encoding: 'utf-8',
251
+ stdio: 'inherit',
252
+ shell: '/bin/bash',
253
+ });
254
+ await showMessage(state, 'Success', `${tool.displayName} has been ${action.toLowerCase().replace('ing', 'ed')}.`, 'success');
255
+ }
256
+ catch (error) {
257
+ await showMessage(state, 'Error', `Failed to install ${tool.displayName}.\n\nTry running manually:\n${tool.installCommand}`, 'error');
258
+ }
259
+ // Refresh screen
260
+ createCliToolsScreen(state);
261
+ });
262
+ // Navigation
263
+ list.key(['j'], () => {
264
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
+ list.down();
266
+ state.screen.render();
267
+ });
268
+ list.key(['k'], () => {
269
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
270
+ list.up();
271
+ state.screen.render();
272
+ });
273
+ // Refresh
274
+ list.key(['r'], () => {
275
+ createCliToolsScreen(state);
276
+ });
277
+ // Update all
278
+ list.key(['a'], async () => {
279
+ const updatable = toolStatuses.filter((s) => s.hasUpdate);
280
+ if (updatable.length === 0) {
281
+ await showMessage(state, 'All Up to Date', 'All tools are at the latest version.', 'info');
282
+ return;
283
+ }
284
+ await showMessage(state, 'Updating All', `Updating ${updatable.length} tool(s)...\n\nThis may take a while.`, 'info');
285
+ for (const status of updatable) {
286
+ try {
287
+ execSync(status.tool.installCommand, {
288
+ encoding: 'utf-8',
289
+ stdio: 'inherit',
290
+ shell: '/bin/bash',
291
+ });
292
+ }
293
+ catch {
294
+ // Continue with other updates
295
+ }
296
+ }
297
+ await showMessage(state, 'Done', `Updated ${updatable.length} tool(s).`, 'success');
298
+ createCliToolsScreen(state);
299
+ });
300
+ // Legend
301
+ blessed.box({
302
+ parent: state.screen,
303
+ bottom: 1,
304
+ right: 2,
305
+ width: 55,
306
+ height: 1,
307
+ content: '{green-fg}●{/green-fg} Up-to-date {yellow-fg}↑{/yellow-fg} Update available {gray-fg}○{/gray-fg} Not installed',
308
+ tags: true,
309
+ });
310
+ createFooter(state, '↑↓ Navigate │ Enter Install/Update │ a Update All │ r Refresh │ q Back');
311
+ list.focus();
312
+ state.screen.render();
313
+ }
314
+ //# sourceMappingURL=cli-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-tools.js","sourceRoot":"","sources":["../../../src/ui/screens/cli-tools.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAgB,MAAM,yBAAyB,CAAC;AAEjE,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAWlC,SAAS,YAAY,CAAC,aAAqB;IACzC,qFAAqF;IACrF,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAa;IAC9C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,YAAY,WAAW,sBAAsB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACtG,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,sBAAsB,WAAW,wBAAwB,EAAE;YAC5F,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,WAAW;SACnB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAC3C,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;QAClC,OAAO,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EAAU,EAAE,EAAU;IAC7C,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC,CAAC;QACvB,IAAI,EAAE,GAAG,EAAE;YAAE,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAe;IACxD,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAEjC,oDAAoD;IACpD,MAAM,YAAY,GAAiB,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzD,IAAI;QACJ,SAAS,EAAE,KAAK;QAChB,gBAAgB,EAAE,SAAS;QAC3B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,CAAC;IAEJ,mBAAmB;IACnB,MAAM,cAAc,GAAG,GAAa,EAAE;QACpC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACjC,IAAI,IAAY,CAAC;YACjB,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,IAAI,KAAK,GAAG,EAAE,CAAC;YAEf,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,IAAI,GAAG,sBAAsB,CAAC;gBAC9B,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBACpB,KAAK,GAAG,yBAAyB,CAAC;gBACpC,CAAC;qBAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBAChC,WAAW,GAAG,cAAc,MAAM,CAAC,aAAa,YAAY,CAAC;gBAC/D,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,wBAAwB,CAAC;gBAChC,WAAW,GAAG,eAAe,MAAM,CAAC,gBAAgB,aAAa,CAAC;gBAClE,KAAK,GAAG,yBAAyB,CAAC;YACpC,CAAC;iBAAM,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC5B,IAAI,GAAG,0BAA0B,CAAC;gBAClC,WAAW,GAAG,gBAAgB,MAAM,CAAC,gBAAgB,cAAc,CAAC;gBACpE,KAAK,GAAG,gBAAgB,MAAM,CAAC,aAAa,YAAY,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,wBAAwB,CAAC;gBAChC,WAAW,GAAG,eAAe,MAAM,CAAC,gBAAgB,aAAa,CAAC;gBAClE,KAAK,GAAG,kCAAkC,CAAC;YAC7C,CAAC;YAED,OAAO,GAAG,IAAI,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,UAAU,WAAW,GAAG,KAAK,EAAE,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;IACP,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,KAAK,EAAE,cAAc,EAAE;QACvB,IAAI,EAAE,IAAI;QACV,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,UAAU,EAAE,IAAI;QAChB,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACxB,KAAK,EAAE;YACL,QAAQ,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE;YACxC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;SACvB;QACD,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;QAC7C,KAAK,EAAE,mBAAmB;KAC3B,CAAC,CAAC;IAEH,eAAe;IACf,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC;QAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,EAAE,CAAC;QACN,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACxB,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;QACjC,KAAK,EAAE,WAAW;KACnB,CAAC,CAAC;IAEH,sBAAsB;IACtB,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAkB,CAAC;QACzC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QAEzF,IAAI,UAAkB,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,UAAU,GAAG,kCAAkC,CAAC;QAClD,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,UAAU,GAAG,6EAA6E,CAAC;QAC7F,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,UAAU,GAAG,yCAAyC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,iCAAiC,CAAC;QACjD,CAAC;QAED,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,gBAAgB,EAAE,CAAC;YACrB,WAAW,IAAI,sCAAsC,gBAAgB,eAAe,CAAC;QACvF,CAAC;QACD,IAAI,aAAa,EAAE,CAAC;YAClB,WAAW,IAAI,kCAAkC,aAAa,cAAc,CAAC;QAC/E,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,WAAW,IAAI,uDAAuD,CAAC;QACzE,CAAC;QAED,IAAI,UAAkB,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,UAAU,GAAG,6CAA6C,CAAC;QAC7D,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,UAAU,GAAG,8CAA8C,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,6CAA6C,CAAC;QAC7D,CAAC;QAED,MAAM,OAAO,GAAG;iBACH,IAAI,CAAC,WAAW;;EAE/B,IAAI,CAAC,WAAW;;uBAEK,UAAU;EAC/B,WAAW;;WAEF,IAAI,CAAC,cAAc;;;WAGnB,IAAI,CAAC,OAAO;;EAErB,UAAU;KACP,CAAC,IAAI,EAAE,CAAC;QAET,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAC9B,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC;IAEF,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACrC,UAAU,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAE5B,uBAAuB;IACvB,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,8DAA8D;YAC7D,IAAY,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,YAAY,EAAE,CAAC;QACf,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC;IAEF,wCAAwC;IACxC,MAAM,gBAAgB,GAAG,KAAK,IAAmB,EAAE;QACjD,4DAA4D;QAC5D,MAAM,eAAe,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACxD,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,CAAC,gBAAgB,GAAG,SAAS,CAAC;YACpC,MAAM,CAAC,SAAS,GAAG,SAAS,KAAK,SAAS,CAAC;YAC3C,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,mFAAmF;QACnF,+CAA+C;QAC/C,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACrD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACnD,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC;gBAC9B,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACxB,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,EAAE,CAAC;oBACtC,MAAM,CAAC,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1E,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;YAC1B,CAAC;YACD,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEF,2CAA2C;IAC3C,gBAAgB,EAAE,CAAC;IAEnB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAc,EAAE,KAAa,EAAE,EAAE;QACxD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;QAC9C,MAAM,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC;QAEnF,MAAM,WAAW,CACf,KAAK,EACL,MAAM,EACN,YAAY,IAAI,CAAC,cAAc,+BAA+B,EAC9D,MAAM,CACP,CAAC;QAEF,IAAI,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE;gBAC5B,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;YAEH,MAAM,WAAW,CACf,KAAK,EACL,SAAS,EACT,GAAG,IAAI,CAAC,WAAW,aAAa,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAC5E,SAAS,CACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,WAAW,CACf,KAAK,EACL,OAAO,EACP,qBAAqB,IAAI,CAAC,WAAW,+BAA+B,IAAI,CAAC,cAAc,EAAE,EACzF,OAAO,CACR,CAAC;QACJ,CAAC;QAED,iBAAiB;QACjB,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;QACnB,8DAA8D;QAC7D,IAAY,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;QACnB,8DAA8D;QAC7D,IAAY,CAAC,EAAE,EAAE,CAAC;QACnB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,UAAU;IACV,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;QACnB,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,EAAE;QACzB,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,WAAW,CAAC,KAAK,EAAE,gBAAgB,EAAE,sCAAsC,EAAE,MAAM,CAAC,CAAC;YAC3F,OAAO;QACT,CAAC;QAED,MAAM,WAAW,CACf,KAAK,EACL,cAAc,EACd,YAAY,SAAS,CAAC,MAAM,uCAAuC,EACnE,MAAM,CACP,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;oBACnC,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,SAAS;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,8BAA8B;YAChC,CAAC;QACH,CAAC;QAED,MAAM,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,SAAS,CAAC,MAAM,WAAW,EAAE,SAAS,CAAC,CAAC;QACpF,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,SAAS;IACT,OAAO,CAAC,GAAG,CAAC;QACV,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,CAAC;QACT,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,kHAAkH;QAC3H,IAAI,EAAE,IAAI;KACX,CAAC,CAAC;IAEH,YAAY,CAAC,KAAK,EAAE,wEAAwE,CAAC,CAAC;IAE9F,IAAI,CAAC,KAAK,EAAE,CAAC;IACb,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AppState } from '../app.js';
2
+ export declare function createMainMenu(state: AppState): Promise<void>;
3
+ //# sourceMappingURL=main-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-menu.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/main-menu.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAsC1C,wBAAsB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFnE"}
@@ -0,0 +1,110 @@
1
+ import blessed from 'neo-blessed';
2
+ import { navigateTo, createHeader, createFooter } from '../app.js';
3
+ import { hasClaudeDir } from '../../services/claude-settings.js';
4
+ const menuItems = [
5
+ {
6
+ label: 'Plugins & Marketplaces',
7
+ screen: 'plugins',
8
+ description: 'Manage plugin marketplaces and installed plugins',
9
+ icon: '📦',
10
+ },
11
+ {
12
+ label: 'MCP Servers',
13
+ screen: 'mcp',
14
+ description: 'Setup and manage Model Context Protocol servers',
15
+ icon: '🔌',
16
+ },
17
+ {
18
+ label: 'Status Line',
19
+ screen: 'statusline',
20
+ description: 'Configure status line display format',
21
+ icon: '📊',
22
+ },
23
+ {
24
+ label: 'CLI Tools',
25
+ screen: 'cli-tools',
26
+ description: 'Install and update AI coding CLI tools',
27
+ icon: '🛠️',
28
+ },
29
+ ];
30
+ export async function createMainMenu(state) {
31
+ createHeader(state, 'Claude Code Configuration');
32
+ // Project status
33
+ const hasProject = await hasClaudeDir(state.projectPath);
34
+ const statusText = hasProject
35
+ ? '{green-fg}✓ Project configured{/green-fg}'
36
+ : '{yellow-fg}○ New project{/yellow-fg}';
37
+ blessed.box({
38
+ parent: state.screen,
39
+ top: 3,
40
+ left: 2,
41
+ width: '100%-4',
42
+ height: 3,
43
+ content: `Working directory: {bold}${state.projectPath}{/bold}\nStatus: ${statusText}`,
44
+ tags: true,
45
+ });
46
+ // Menu list
47
+ const list = blessed.list({
48
+ parent: state.screen,
49
+ top: 7,
50
+ left: 2,
51
+ width: '100%-4',
52
+ height: menuItems.length + 2,
53
+ items: menuItems.map((item) => ` ${item.icon} ${item.label}`),
54
+ keys: true,
55
+ vi: true,
56
+ mouse: true,
57
+ border: {
58
+ type: 'line',
59
+ },
60
+ style: {
61
+ selected: {
62
+ bg: 'blue',
63
+ fg: 'white',
64
+ bold: true,
65
+ },
66
+ border: {
67
+ fg: 'cyan',
68
+ },
69
+ },
70
+ });
71
+ // Description box
72
+ const descBox = blessed.box({
73
+ parent: state.screen,
74
+ top: 8 + menuItems.length + 2,
75
+ left: 2,
76
+ width: '100%-4',
77
+ height: 3,
78
+ content: '',
79
+ tags: true,
80
+ style: {
81
+ fg: 'gray',
82
+ },
83
+ });
84
+ // Update description on selection change
85
+ const updateDescription = () => {
86
+ const selected = list.selected;
87
+ if (menuItems[selected]) {
88
+ descBox.setContent(` ${menuItems[selected].description}`);
89
+ state.screen.render();
90
+ }
91
+ };
92
+ list.on('select item', updateDescription);
93
+ updateDescription();
94
+ // Handle selection
95
+ list.on('select', (_item, index) => {
96
+ const menuItem = menuItems[index];
97
+ if (menuItem) {
98
+ navigateTo(state, menuItem.screen);
99
+ }
100
+ });
101
+ // Number key shortcuts
102
+ state.screen.key(['1'], () => navigateTo(state, 'plugins'));
103
+ state.screen.key(['2'], () => navigateTo(state, 'mcp'));
104
+ state.screen.key(['3'], () => navigateTo(state, 'statusline'));
105
+ state.screen.key(['4'], () => navigateTo(state, 'cli-tools'));
106
+ createFooter(state, '↑↓ Navigate | Enter Select | 1-4 Quick Jump | q Quit | ? Help');
107
+ list.focus();
108
+ state.screen.render();
109
+ }
110
+ //# sourceMappingURL=main-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main-menu.js","sourceRoot":"","sources":["../../../src/ui/screens/main-menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AppState } from '../app.js';
2
+ export declare function createMarketplaceScreen(state: AppState): Promise<void>;
3
+ //# sourceMappingURL=marketplace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/marketplace.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAS1C,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA6K5E"}
@@ -0,0 +1,132 @@
1
+ import blessed from 'neo-blessed';
2
+ import { createHeader, createFooter, showMessage, showConfirm } from '../app.js';
3
+ import { defaultMarketplaces } from '../../data/marketplaces.js';
4
+ import { addMarketplace, removeMarketplace, getConfiguredMarketplaces, } from '../../services/claude-settings.js';
5
+ export async function createMarketplaceScreen(state) {
6
+ createHeader(state, 'Plugin Marketplaces');
7
+ const configuredMarketplaces = await getConfiguredMarketplaces(state.projectPath);
8
+ // Build list items
9
+ const listItems = [];
10
+ for (const marketplace of defaultMarketplaces) {
11
+ const isInstalled = configuredMarketplaces[marketplace.name] !== undefined;
12
+ const status = isInstalled ? '{green-fg}✓{/green-fg}' : ' ';
13
+ const officialBadge = marketplace.official ? ' {cyan-fg}[Official]{/cyan-fg}' : '';
14
+ listItems.push({
15
+ label: `${status} ${marketplace.displayName}${officialBadge}`,
16
+ marketplace,
17
+ installed: isInstalled,
18
+ });
19
+ }
20
+ // Info box
21
+ blessed.box({
22
+ parent: state.screen,
23
+ top: 3,
24
+ left: 2,
25
+ width: '100%-4',
26
+ height: 4,
27
+ content: `Marketplaces provide plugins for Claude Code.
28
+ Add marketplaces to access their plugins in the Plugins screen.
29
+
30
+ {gray-fg}Note: Changes are saved to .claude/settings.json (shared with team){/gray-fg}`,
31
+ tags: true,
32
+ });
33
+ const list = blessed.list({
34
+ parent: state.screen,
35
+ top: 8,
36
+ left: 2,
37
+ width: '100%-4',
38
+ height: listItems.length + 2,
39
+ items: listItems.map((item) => item.label),
40
+ keys: true,
41
+ vi: true,
42
+ mouse: true,
43
+ tags: true,
44
+ border: {
45
+ type: 'line',
46
+ },
47
+ style: {
48
+ selected: {
49
+ bg: 'blue',
50
+ fg: 'white',
51
+ },
52
+ border: {
53
+ fg: 'cyan',
54
+ },
55
+ },
56
+ });
57
+ // Description box
58
+ const descBox = blessed.box({
59
+ parent: state.screen,
60
+ top: 10 + listItems.length + 2,
61
+ left: 2,
62
+ width: '100%-4',
63
+ height: 4,
64
+ content: '',
65
+ tags: true,
66
+ border: {
67
+ type: 'line',
68
+ },
69
+ style: {
70
+ border: {
71
+ fg: 'gray',
72
+ },
73
+ },
74
+ });
75
+ // Update description on selection change
76
+ const updateDescription = () => {
77
+ const selected = list.selected;
78
+ const item = listItems[selected];
79
+ if (item) {
80
+ const mp = item.marketplace;
81
+ descBox.setContent(`{bold}${mp.displayName}{/bold}\n` +
82
+ `${mp.description}\n` +
83
+ `{gray-fg}Source: github.com/${mp.source.repo}{/gray-fg}`);
84
+ state.screen.render();
85
+ }
86
+ };
87
+ list.on('select item', updateDescription);
88
+ updateDescription();
89
+ // Handle selection
90
+ list.on('select', async (_item, index) => {
91
+ const selected = listItems[index];
92
+ if (!selected)
93
+ return;
94
+ if (selected.installed) {
95
+ // Remove marketplace
96
+ const remove = await showConfirm(state, `Remove ${selected.marketplace.displayName}?`, 'This will remove the marketplace from your settings.\nPlugins from this marketplace will no longer be available.');
97
+ if (remove) {
98
+ await removeMarketplace(selected.marketplace.name, state.projectPath);
99
+ await showMessage(state, 'Removed', `${selected.marketplace.displayName} has been removed.`, 'success');
100
+ createMarketplaceScreen(state);
101
+ }
102
+ }
103
+ else {
104
+ // Add marketplace
105
+ await addMarketplace(selected.marketplace, state.projectPath);
106
+ await showMessage(state, 'Added', `${selected.marketplace.displayName} has been added.\n\nYou can now install plugins from this marketplace.`, 'success');
107
+ createMarketplaceScreen(state);
108
+ }
109
+ });
110
+ // Quick add all - disabled during search
111
+ state.screen.key(['a'], async () => {
112
+ if (state.isSearching)
113
+ return;
114
+ const notInstalled = listItems.filter((item) => !item.installed);
115
+ if (notInstalled.length === 0) {
116
+ await showMessage(state, 'Info', 'All marketplaces are already added.', 'info');
117
+ return;
118
+ }
119
+ const confirm = await showConfirm(state, 'Add All Marketplaces?', `This will add ${notInstalled.length} marketplace(s) to your settings.`);
120
+ if (confirm) {
121
+ for (const item of notInstalled) {
122
+ await addMarketplace(item.marketplace, state.projectPath);
123
+ }
124
+ await showMessage(state, 'Added', `Added ${notInstalled.length} marketplace(s).`, 'success');
125
+ createMarketplaceScreen(state);
126
+ }
127
+ });
128
+ createFooter(state, '↑↓ Navigate | Enter Toggle | a Add All | Esc Back | ? Help');
129
+ list.focus();
130
+ state.screen.render();
131
+ }
132
+ //# sourceMappingURL=marketplace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../../src/ui/screens/marketplace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { AppState } from '../app.js';
2
+ import type { McpRegistryServer } from '../../types/index.js';
3
+ interface RegistryState {
4
+ servers: McpRegistryServer[];
5
+ error: string | null;
6
+ loaded: boolean;
7
+ }
8
+ export declare function createMcpRegistryScreen(state: AppState, initialSearch?: string, registryState?: RegistryState): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=mcp-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-registry.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/mcp-registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAc1C,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,sBAAsB,CAAC;AAE/E,UAAU,aAAa;IACrB,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,QAAQ,EACf,aAAa,GAAE,MAAW,EAC1B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CAwVf"}