claudeup 0.6.0 → 0.6.2

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 (72) hide show
  1. package/dist/data/cli-tools.d.ts +13 -0
  2. package/dist/data/cli-tools.d.ts.map +1 -0
  3. package/dist/data/cli-tools.js +124 -0
  4. package/dist/data/cli-tools.js.map +1 -0
  5. package/dist/data/marketplaces.d.ts +4 -0
  6. package/dist/data/marketplaces.d.ts.map +1 -0
  7. package/dist/data/marketplaces.js +26 -0
  8. package/dist/data/marketplaces.js.map +1 -0
  9. package/dist/data/mcp-servers.d.ts +8 -0
  10. package/dist/data/mcp-servers.d.ts.map +1 -0
  11. package/dist/data/mcp-servers.js +421 -0
  12. package/dist/data/mcp-servers.js.map +1 -0
  13. package/dist/data/statuslines.d.ts +10 -0
  14. package/dist/data/statuslines.d.ts.map +1 -0
  15. package/dist/data/statuslines.js +160 -0
  16. package/dist/data/statuslines.js.map +1 -0
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/services/claude-settings.d.ts +49 -0
  21. package/dist/services/claude-settings.d.ts.map +1 -0
  22. package/dist/services/claude-settings.js +299 -0
  23. package/dist/services/claude-settings.js.map +1 -0
  24. package/dist/services/mcp-registry.d.ts +10 -0
  25. package/dist/services/mcp-registry.d.ts.map +1 -0
  26. package/dist/services/mcp-registry.js +88 -0
  27. package/dist/services/mcp-registry.js.map +1 -0
  28. package/dist/services/plugin-manager.d.ts +23 -0
  29. package/dist/services/plugin-manager.d.ts.map +1 -0
  30. package/dist/services/plugin-manager.js +151 -0
  31. package/dist/services/plugin-manager.js.map +1 -0
  32. package/dist/types/index.d.ts +86 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/index.js +2 -0
  35. package/dist/types/index.js.map +1 -0
  36. package/dist/ui/app.d.ts +38 -0
  37. package/dist/ui/app.d.ts.map +1 -0
  38. package/dist/ui/app.js +590 -0
  39. package/dist/ui/app.js.map +1 -0
  40. package/dist/ui/screens/cli-tools.d.ts +4 -0
  41. package/dist/ui/screens/cli-tools.d.ts.map +1 -0
  42. package/dist/ui/screens/cli-tools.js +369 -0
  43. package/dist/ui/screens/cli-tools.js.map +1 -0
  44. package/dist/ui/screens/env-vars.d.ts +3 -0
  45. package/dist/ui/screens/env-vars.d.ts.map +1 -0
  46. package/dist/ui/screens/env-vars.js +119 -0
  47. package/dist/ui/screens/env-vars.js.map +1 -0
  48. package/dist/ui/screens/main-menu.d.ts +3 -0
  49. package/dist/ui/screens/main-menu.d.ts.map +1 -0
  50. package/dist/ui/screens/main-menu.js +110 -0
  51. package/dist/ui/screens/main-menu.js.map +1 -0
  52. package/dist/ui/screens/marketplace.d.ts +3 -0
  53. package/dist/ui/screens/marketplace.d.ts.map +1 -0
  54. package/dist/ui/screens/marketplace.js +132 -0
  55. package/dist/ui/screens/marketplace.js.map +1 -0
  56. package/dist/ui/screens/mcp-registry.d.ts +10 -0
  57. package/dist/ui/screens/mcp-registry.d.ts.map +1 -0
  58. package/dist/ui/screens/mcp-registry.js +310 -0
  59. package/dist/ui/screens/mcp-registry.js.map +1 -0
  60. package/dist/ui/screens/mcp-setup.d.ts +4 -0
  61. package/dist/ui/screens/mcp-setup.d.ts.map +1 -0
  62. package/dist/ui/screens/mcp-setup.js +492 -0
  63. package/dist/ui/screens/mcp-setup.js.map +1 -0
  64. package/dist/ui/screens/plugins.d.ts +3 -0
  65. package/dist/ui/screens/plugins.d.ts.map +1 -0
  66. package/dist/ui/screens/plugins.js +443 -0
  67. package/dist/ui/screens/plugins.js.map +1 -0
  68. package/dist/ui/screens/statusline.d.ts +5 -0
  69. package/dist/ui/screens/statusline.d.ts.map +1 -0
  70. package/dist/ui/screens/statusline.js +235 -0
  71. package/dist/ui/screens/statusline.js.map +1 -0
  72. package/package.json +2 -2
@@ -0,0 +1,369 @@
1
+ import blessed from 'neo-blessed';
2
+ import { exec, execSync } from 'child_process';
3
+ import { promisify } from 'util';
4
+ import { createHeader, createFooter, showMessage, showLoading } from '../app.js';
5
+ import { cliTools } from '../../data/cli-tools.js';
6
+ const execAsync = promisify(exec);
7
+ // Session-level cache for tool statuses (persists until explicit refresh)
8
+ let cachedToolStatuses = null;
9
+ let cacheInitialized = false;
10
+ export function clearCliToolsCache() {
11
+ cachedToolStatuses = null;
12
+ cacheInitialized = false;
13
+ }
14
+ function parseVersion(versionOutput) {
15
+ // Extract version number from various formats like "v1.2.3", "1.2.3", "aider 0.82.0"
16
+ const match = versionOutput.match(/v?(\d+\.\d+\.\d+(?:-[\w.]+)?)/);
17
+ return match ? match[1] : undefined;
18
+ }
19
+ async function isInstalledViaHomebrew(toolName) {
20
+ try {
21
+ // Get list of installed Homebrew formulas (no shell interpolation for safety)
22
+ const { stdout } = await execAsync('brew list --formula 2>/dev/null', {
23
+ timeout: 2000,
24
+ shell: '/bin/bash',
25
+ });
26
+ // Programmatic matching instead of shell grep to avoid injection risk
27
+ const formulas = stdout.trim().split('\n');
28
+ return formulas.some((f) => f.trim() === toolName);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ async function getInstalledVersion(tool) {
35
+ try {
36
+ const { stdout } = await execAsync(tool.checkCommand, { timeout: 5000 });
37
+ return parseVersion(stdout.trim());
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ }
43
+ async function getLatestNpmVersion(packageName) {
44
+ try {
45
+ const { stdout } = await execAsync(`npm view ${packageName} version 2>/dev/null`, { timeout: 10000 });
46
+ return stdout.trim() || undefined;
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ }
52
+ async function getLatestPipVersion(packageName) {
53
+ try {
54
+ const { stdout } = await execAsync(`pip index versions ${packageName} 2>/dev/null | head -1`, {
55
+ timeout: 10000,
56
+ shell: '/bin/bash',
57
+ });
58
+ const match = stdout.trim().match(/\(([^)]+)\)/);
59
+ return match ? match[1] : undefined;
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ }
65
+ async function getLatestVersion(tool) {
66
+ if (tool.packageManager === 'npm') {
67
+ return getLatestNpmVersion(tool.packageName);
68
+ }
69
+ else {
70
+ return getLatestPipVersion(tool.packageName);
71
+ }
72
+ }
73
+ function compareVersions(v1, v2) {
74
+ const parts1 = v1.split(/[-.]/).map((p) => parseInt(p, 10) || 0);
75
+ const parts2 = v2.split(/[-.]/).map((p) => parseInt(p, 10) || 0);
76
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
77
+ const p1 = parts1[i] || 0;
78
+ const p2 = parts2[i] || 0;
79
+ if (p1 < p2)
80
+ return -1;
81
+ if (p1 > p2)
82
+ return 1;
83
+ }
84
+ return 0;
85
+ }
86
+ export async function createCliToolsScreen(state) {
87
+ createHeader(state, 'CLI Tools');
88
+ // Use cached tool statuses if available, otherwise initialize
89
+ const toolStatuses = cachedToolStatuses || cliTools.map((tool) => ({
90
+ tool,
91
+ installed: false,
92
+ installedVersion: undefined,
93
+ checking: true,
94
+ }));
95
+ // Store reference for caching
96
+ if (!cachedToolStatuses) {
97
+ cachedToolStatuses = toolStatuses;
98
+ }
99
+ // Build list items
100
+ const buildListItems = () => {
101
+ return toolStatuses.map((status) => {
102
+ let icon;
103
+ let versionInfo = '';
104
+ let badge = '';
105
+ if (!status.installed) {
106
+ icon = '{gray-fg}○{/gray-fg}';
107
+ if (status.checking) {
108
+ badge = ' {gray-fg}...{/gray-fg}';
109
+ }
110
+ else if (status.latestVersion) {
111
+ versionInfo = ` {gray-fg}v${status.latestVersion}{/gray-fg}`;
112
+ }
113
+ }
114
+ else if (status.checking) {
115
+ icon = '{green-fg}●{/green-fg}';
116
+ versionInfo = ` {green-fg}v${status.installedVersion}{/green-fg}`;
117
+ badge = ' {gray-fg}...{/gray-fg}';
118
+ }
119
+ else if (status.hasUpdate) {
120
+ icon = '{yellow-fg}↑{/yellow-fg}';
121
+ versionInfo = ` {yellow-fg}v${status.installedVersion}{/yellow-fg}`;
122
+ badge = ` {cyan-fg}→ v${status.latestVersion}{/cyan-fg}`;
123
+ }
124
+ else {
125
+ icon = '{green-fg}●{/green-fg}';
126
+ versionInfo = ` {green-fg}v${status.installedVersion}{/green-fg}`;
127
+ badge = ' {cyan-fg}(up-to-date){/cyan-fg}';
128
+ }
129
+ return `${icon} {bold}${status.tool.displayName}{/bold}${versionInfo}${badge}`;
130
+ });
131
+ };
132
+ // List
133
+ const list = blessed.list({
134
+ parent: state.screen,
135
+ top: 3,
136
+ left: 2,
137
+ width: '50%-2',
138
+ height: '100%-5',
139
+ items: buildListItems(),
140
+ keys: true,
141
+ vi: false,
142
+ mouse: true,
143
+ tags: true,
144
+ scrollable: true,
145
+ border: { type: 'line' },
146
+ style: {
147
+ selected: { bg: 'magenta', fg: 'white' },
148
+ border: { fg: 'gray' },
149
+ },
150
+ scrollbar: { ch: '|', style: { bg: 'gray' } },
151
+ label: ' AI Coding Tools ',
152
+ });
153
+ // Detail panel
154
+ const detailBox = blessed.box({
155
+ parent: state.screen,
156
+ top: 3,
157
+ right: 2,
158
+ width: '50%-2',
159
+ height: '100%-5',
160
+ content: '',
161
+ tags: true,
162
+ border: { type: 'line' },
163
+ style: { border: { fg: 'gray' } },
164
+ label: ' Details ',
165
+ });
166
+ // Update detail panel
167
+ const updateDetail = () => {
168
+ const selected = list.selected;
169
+ const status = toolStatuses[selected];
170
+ if (!status)
171
+ return;
172
+ const { tool, installed, installedVersion, latestVersion, hasUpdate, checking } = status;
173
+ let statusText;
174
+ if (!installed) {
175
+ statusText = '{gray-fg}Not installed{/gray-fg}';
176
+ }
177
+ else if (checking) {
178
+ statusText = '{green-fg}Installed{/green-fg} {gray-fg}(checking for updates...){/gray-fg}';
179
+ }
180
+ else if (hasUpdate) {
181
+ statusText = '{yellow-fg}Update available{/yellow-fg}';
182
+ }
183
+ else {
184
+ statusText = '{green-fg}Up to date{/green-fg}';
185
+ }
186
+ let versionText = '';
187
+ if (installedVersion) {
188
+ versionText += `{bold}Installed:{/bold} {green-fg}v${installedVersion}{/green-fg}\n`;
189
+ }
190
+ if (latestVersion) {
191
+ versionText += `{bold}Latest:{/bold} {cyan-fg}v${latestVersion}{/cyan-fg}\n`;
192
+ }
193
+ else if (checking) {
194
+ versionText += `{bold}Latest:{/bold} {gray-fg}checking...{/gray-fg}\n`;
195
+ }
196
+ let actionText;
197
+ if (!installed) {
198
+ actionText = '{green-fg}Press Enter to install{/green-fg}';
199
+ }
200
+ else if (hasUpdate) {
201
+ actionText = '{yellow-fg}Press Enter to update{/yellow-fg}';
202
+ }
203
+ else {
204
+ actionText = '{gray-fg}Press Enter to reinstall{/gray-fg}';
205
+ }
206
+ const content = `
207
+ {bold}{cyan-fg}${tool.displayName}{/cyan-fg}{/bold}
208
+
209
+ ${tool.description}
210
+
211
+ {bold}Status:{/bold} ${statusText}
212
+ ${versionText}
213
+ {bold}Install:{/bold}
214
+ {gray-fg}${tool.installCommand}{/gray-fg}
215
+
216
+ {bold}Website:{/bold}
217
+ {cyan-fg}${tool.website}{/cyan-fg}
218
+
219
+ ${actionText}
220
+ `.trim();
221
+ detailBox.setContent(content);
222
+ state.screen.render();
223
+ };
224
+ list.on('select item', updateDetail);
225
+ setTimeout(updateDetail, 0);
226
+ // Refresh list display
227
+ const refreshList = () => {
228
+ const items = buildListItems();
229
+ for (let i = 0; i < items.length; i++) {
230
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
231
+ list.setItem(i, items[i]);
232
+ }
233
+ updateDetail();
234
+ state.screen.render();
235
+ };
236
+ // Fetch all version info asynchronously
237
+ const fetchVersionInfo = async () => {
238
+ // First, check installed versions in parallel (fast, local)
239
+ const installedChecks = toolStatuses.map(async (status) => {
240
+ const installed = await getInstalledVersion(status.tool);
241
+ status.installedVersion = installed;
242
+ status.installed = installed !== undefined;
243
+ refreshList();
244
+ });
245
+ // Don't wait for all installed checks - start fetching latest versions immediately
246
+ // This runs both in parallel for maximum speed
247
+ const latestChecks = toolStatuses.map(async (status) => {
248
+ try {
249
+ const latest = await getLatestVersion(status.tool);
250
+ status.latestVersion = latest;
251
+ status.checking = false;
252
+ if (status.installedVersion && latest) {
253
+ status.hasUpdate = compareVersions(status.installedVersion, latest) < 0;
254
+ }
255
+ }
256
+ catch {
257
+ status.checking = false;
258
+ }
259
+ refreshList();
260
+ });
261
+ // Wait for all to complete
262
+ await Promise.all([...installedChecks, ...latestChecks]);
263
+ };
264
+ // Start async version fetching only if not already cached
265
+ if (!cacheInitialized) {
266
+ cacheInitialized = true;
267
+ fetchVersionInfo();
268
+ }
269
+ // Install/Update on Enter - with Homebrew detection
270
+ list.on('select', async (_item, index) => {
271
+ const status = toolStatuses[index];
272
+ if (!status)
273
+ return;
274
+ const { tool, installed, hasUpdate } = status;
275
+ const action = !installed ? 'Installing' : hasUpdate ? 'Updating' : 'Reinstalling';
276
+ // Detect installation method for existing installations
277
+ const viaHomebrew = installed ? await isInstalledViaHomebrew(tool.name) : false;
278
+ // Choose appropriate command
279
+ let command;
280
+ if (!installed) {
281
+ // New installations always use npm
282
+ command = tool.installCommand;
283
+ }
284
+ else if (viaHomebrew) {
285
+ // Homebrew-installed tools use brew upgrade
286
+ command = `brew upgrade ${tool.name}`;
287
+ }
288
+ else {
289
+ // npm-installed tools use npm install -g (handles updates)
290
+ command = tool.installCommand;
291
+ }
292
+ const loading = showLoading(state, `${action} ${tool.displayName}...`);
293
+ try {
294
+ execSync(command, {
295
+ encoding: 'utf-8',
296
+ stdio: 'inherit',
297
+ shell: '/bin/bash',
298
+ });
299
+ }
300
+ catch (error) {
301
+ loading.stop();
302
+ // Keep error messages - critical for user to see failures
303
+ await showMessage(state, 'Error', `Failed to ${action.toLowerCase()} ${tool.displayName}.\n\nTry running manually:\n${command}`, 'error');
304
+ return; // Don't refresh on error
305
+ }
306
+ loading.stop();
307
+ // Success: immediate refresh, no confirmation needed
308
+ clearCliToolsCache();
309
+ createCliToolsScreen(state);
310
+ });
311
+ // Navigation
312
+ list.key(['j'], () => {
313
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
314
+ list.down();
315
+ state.screen.render();
316
+ });
317
+ list.key(['k'], () => {
318
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
319
+ list.up();
320
+ state.screen.render();
321
+ });
322
+ // Refresh - clear cache and reload
323
+ list.key(['r'], () => {
324
+ clearCliToolsCache();
325
+ createCliToolsScreen(state);
326
+ });
327
+ // Update all - with Homebrew detection, no confirmations
328
+ list.key(['a'], async () => {
329
+ const updatable = toolStatuses.filter((s) => s.hasUpdate);
330
+ if (updatable.length === 0) {
331
+ return; // Silent no-op if all up-to-date
332
+ }
333
+ const loading = showLoading(state, `Updating ${updatable.length} tool(s)...`);
334
+ for (const status of updatable) {
335
+ // Detect installation method per tool
336
+ const viaHomebrew = await isInstalledViaHomebrew(status.tool.name);
337
+ const command = viaHomebrew
338
+ ? `brew upgrade ${status.tool.name}`
339
+ : status.tool.installCommand;
340
+ try {
341
+ execSync(command, {
342
+ encoding: 'utf-8',
343
+ stdio: 'inherit',
344
+ shell: '/bin/bash',
345
+ });
346
+ }
347
+ catch {
348
+ // Continue with other updates (silent failure)
349
+ }
350
+ }
351
+ loading.stop();
352
+ clearCliToolsCache();
353
+ createCliToolsScreen(state);
354
+ });
355
+ // Legend
356
+ blessed.box({
357
+ parent: state.screen,
358
+ bottom: 1,
359
+ right: 2,
360
+ width: 55,
361
+ height: 1,
362
+ content: '{green-fg}●{/green-fg} Up-to-date {yellow-fg}↑{/yellow-fg} Update available {gray-fg}○{/gray-fg} Not installed',
363
+ tags: true,
364
+ });
365
+ createFooter(state, '↑↓ Navigate │ Enter Install/Update │ a Update All │ r Refresh │ q Back');
366
+ list.focus();
367
+ state.screen.render();
368
+ }
369
+ //# 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,WAAW,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAgB,MAAM,yBAAyB,CAAC;AAEjE,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAWlC,0EAA0E;AAC1E,IAAI,kBAAkB,GAAwB,IAAI,CAAC;AACnD,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B,MAAM,UAAU,kBAAkB;IAChC,kBAAkB,GAAG,IAAI,CAAC;IAC1B,gBAAgB,GAAG,KAAK,CAAC;AAC3B,CAAC;AAED,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,sBAAsB,CAAC,QAAgB;IACpD,IAAI,CAAC;QACH,8EAA8E;QAC9E,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,iCAAiC,EAAE;YACpE,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,WAAW;SACnB,CAAC,CAAC;QACH,sEAAsE;QACtE,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,QAAQ,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,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,8DAA8D;IAC9D,MAAM,YAAY,GAAiB,kBAAkB,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/E,IAAI;QACJ,SAAS,EAAE,KAAK;QAChB,gBAAgB,EAAE,SAAS;QAC3B,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC,CAAC;IAEJ,8BAA8B;IAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,kBAAkB,GAAG,YAAY,CAAC;IACpC,CAAC;IAED,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,0DAA0D;IAC1D,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,gBAAgB,GAAG,IAAI,CAAC;QACxB,gBAAgB,EAAE,CAAC;IACrB,CAAC;IAED,oDAAoD;IACpD,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,wDAAwD;QACxD,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAEhF,6BAA6B;QAC7B,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,mCAAmC;YACnC,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;QAChC,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,4CAA4C;YAC5C,OAAO,GAAG,gBAAgB,IAAI,CAAC,IAAI,EAAE,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,2DAA2D;YAC3D,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC;QAChC,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,MAAM,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC;QAEvE,IAAI,CAAC;YACH,QAAQ,CAAC,OAAO,EAAE;gBAChB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,SAAS;gBAChB,KAAK,EAAE,WAAW;aACnB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,0DAA0D;YAC1D,MAAM,WAAW,CACf,KAAK,EACL,OAAO,EACP,aAAa,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,WAAW,+BAA+B,OAAO,EAAE,EAC7F,OAAO,CACR,CAAC;YACF,OAAO,CAAC,yBAAyB;QACnC,CAAC;QAED,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,qDAAqD;QACrD,kBAAkB,EAAE,CAAC;QACrB,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,mCAAmC;IACnC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;QACnB,kBAAkB,EAAE,CAAC;QACrB,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,yDAAyD;IACzD,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,OAAO,CAAC,iCAAiC;QAC3C,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,YAAY,SAAS,CAAC,MAAM,aAAa,CAAC,CAAC;QAE9E,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,sCAAsC;YACtC,MAAM,WAAW,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,WAAW;gBACzB,CAAC,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;gBACpC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;YAE/B,IAAI,CAAC;gBACH,QAAQ,CAAC,OAAO,EAAE;oBAChB,QAAQ,EAAE,OAAO;oBACjB,KAAK,EAAE,SAAS;oBAChB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,+CAA+C;YACjD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,kBAAkB,EAAE,CAAC;QACrB,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 createEnvVarsScreen(state: AppState): Promise<void>;
3
+ //# sourceMappingURL=env-vars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.d.ts","sourceRoot":"","sources":["../../../src/ui/screens/env-vars.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAc1C,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA6IxE"}
@@ -0,0 +1,119 @@
1
+ import blessed from 'neo-blessed';
2
+ import { createHeader, createFooter, showMessage, showConfirm, showInput, } from '../app.js';
3
+ import { getMcpEnvVars, setMcpEnvVar, removeMcpEnvVar, } from '../../services/claude-settings.js';
4
+ export async function createEnvVarsScreen(state) {
5
+ createHeader(state, 'Environment Variables');
6
+ const envVars = await getMcpEnvVars(state.projectPath);
7
+ const envVarNames = Object.keys(envVars);
8
+ // Info box
9
+ blessed.box({
10
+ parent: state.screen,
11
+ top: 3,
12
+ left: 2,
13
+ width: '100%-4',
14
+ height: 3,
15
+ tags: true,
16
+ border: { type: 'line' },
17
+ style: { border: { fg: 'gray' } },
18
+ content: '{gray-fg}Environment variables stored in .claude/settings.local.json{/gray-fg}',
19
+ });
20
+ const listItems = [];
21
+ if (envVarNames.length === 0) {
22
+ listItems.push({
23
+ label: '{gray-fg}No environment variables configured{/gray-fg}',
24
+ });
25
+ }
26
+ else {
27
+ for (const varName of envVarNames) {
28
+ const value = envVars[varName];
29
+ const masked = value.length > 30 ? value.slice(0, 30) + '...' : value;
30
+ listItems.push({
31
+ label: `{cyan-fg}${varName}{/cyan-fg} = {gray-fg}"${masked}"{/gray-fg}`,
32
+ varName,
33
+ });
34
+ }
35
+ }
36
+ const list = blessed.list({
37
+ parent: state.screen,
38
+ top: 6,
39
+ left: 2,
40
+ width: '100%-4',
41
+ height: '100%-9',
42
+ items: listItems.map((item) => item.label),
43
+ keys: true,
44
+ mouse: true,
45
+ tags: true,
46
+ scrollable: true,
47
+ border: { type: 'line' },
48
+ style: {
49
+ selected: { bg: 'blue', fg: 'white' },
50
+ border: { fg: 'gray' },
51
+ },
52
+ scrollbar: { ch: '|', style: { bg: 'gray' } },
53
+ });
54
+ // Add new variable with 'a' key
55
+ list.key(['a'], async () => {
56
+ const varName = await showInput(state, 'Add Variable', 'Variable name:');
57
+ if (varName === null || !varName.trim())
58
+ return;
59
+ const cleanName = varName.trim().toUpperCase().replace(/[^A-Z0-9_]/g, '_');
60
+ // Check if already exists
61
+ if (envVars[cleanName]) {
62
+ const overwrite = await showConfirm(state, `${cleanName} exists`, 'Overwrite existing value?');
63
+ if (!overwrite)
64
+ return;
65
+ }
66
+ const value = await showInput(state, `Set ${cleanName}`, 'Value:');
67
+ if (value === null)
68
+ return;
69
+ await setMcpEnvVar(cleanName, value, state.projectPath);
70
+ await showMessage(state, 'Added', `${cleanName} added.\nRestart Claude Code to apply.`, 'success');
71
+ createEnvVarsScreen(state);
72
+ });
73
+ // Edit selected variable with Enter or 'e'
74
+ const editSelected = async () => {
75
+ const selected = list.selected;
76
+ const item = listItems[selected];
77
+ if (!item?.varName)
78
+ return;
79
+ const varName = item.varName;
80
+ const currentValue = envVars[varName];
81
+ const newValue = await showInput(state, `Edit ${varName}`, 'New value:', currentValue);
82
+ if (newValue === null)
83
+ return;
84
+ await setMcpEnvVar(varName, newValue, state.projectPath);
85
+ await showMessage(state, 'Updated', `${varName} updated.\nRestart Claude Code to apply.`, 'success');
86
+ createEnvVarsScreen(state);
87
+ };
88
+ list.on('select', editSelected);
89
+ list.key(['e'], editSelected);
90
+ // Delete with 'd' key
91
+ list.key(['d'], async () => {
92
+ const selected = list.selected;
93
+ const item = listItems[selected];
94
+ if (!item?.varName)
95
+ return;
96
+ const varName = item.varName;
97
+ const confirmDelete = await showConfirm(state, `Delete ${varName}?`, 'This will remove the variable from configuration.');
98
+ if (confirmDelete) {
99
+ await removeMcpEnvVar(varName, state.projectPath);
100
+ await showMessage(state, 'Deleted', `${varName} removed.`, 'success');
101
+ createEnvVarsScreen(state);
102
+ }
103
+ });
104
+ // Navigation
105
+ list.key(['j'], () => {
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ list.down();
108
+ state.screen.render();
109
+ });
110
+ list.key(['k'], () => {
111
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
+ list.up();
113
+ state.screen.render();
114
+ });
115
+ createFooter(state, '↑↓ Navigate │ Enter/e Edit │ a Add │ d Delete │ q Back');
116
+ list.focus();
117
+ state.screen.render();
118
+ }
119
+ //# sourceMappingURL=env-vars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.js","sourceRoot":"","sources":["../../../src/ui/screens/env-vars.ts"],"names":[],"mappings":"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"}
@@ -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"}