ccmanager 0.2.0 → 0.2.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.
@@ -6,9 +6,11 @@ import NewWorktree from './NewWorktree.js';
6
6
  import DeleteWorktree from './DeleteWorktree.js';
7
7
  import MergeWorktree from './MergeWorktree.js';
8
8
  import Configuration from './Configuration.js';
9
+ import PresetSelector from './PresetSelector.js';
9
10
  import { SessionManager } from '../services/sessionManager.js';
10
11
  import { WorktreeService } from '../services/worktreeService.js';
11
12
  import { shortcutManager } from '../services/shortcutManager.js';
13
+ import { configurationManager } from '../services/configurationManager.js';
12
14
  const App = () => {
13
15
  const { exit } = useApp();
14
16
  const [view, setView] = useState('menu');
@@ -17,6 +19,7 @@ const App = () => {
17
19
  const [activeSession, setActiveSession] = useState(null);
18
20
  const [error, setError] = useState(null);
19
21
  const [menuKey, setMenuKey] = useState(0); // Force menu refresh
22
+ const [selectedWorktree, setSelectedWorktree] = useState(null); // Store selected worktree for preset selection
20
23
  useEffect(() => {
21
24
  // Listen for session exits to return to menu automatically
22
25
  const handleSessionExit = (session) => {
@@ -76,8 +79,15 @@ const App = () => {
76
79
  // Get or create session for this worktree
77
80
  let session = sessionManager.getSession(worktree.path);
78
81
  if (!session) {
82
+ // Check if we should show preset selector
83
+ if (configurationManager.getSelectPresetOnStart()) {
84
+ setSelectedWorktree(worktree);
85
+ setView('preset-selector');
86
+ return;
87
+ }
79
88
  try {
80
- session = await sessionManager.createSession(worktree.path);
89
+ // Use preset-based session creation with default preset
90
+ session = await sessionManager.createSessionWithPreset(worktree.path);
81
91
  }
82
92
  catch (error) {
83
93
  setError(`Failed to create session: ${error}`);
@@ -87,6 +97,27 @@ const App = () => {
87
97
  setActiveSession(session);
88
98
  setView('session');
89
99
  };
100
+ const handlePresetSelected = async (presetId) => {
101
+ if (!selectedWorktree)
102
+ return;
103
+ try {
104
+ // Create session with selected preset
105
+ const session = await sessionManager.createSessionWithPreset(selectedWorktree.path, presetId);
106
+ setActiveSession(session);
107
+ setView('session');
108
+ setSelectedWorktree(null);
109
+ }
110
+ catch (error) {
111
+ setError(`Failed to create session: ${error}`);
112
+ setView('menu');
113
+ setSelectedWorktree(null);
114
+ }
115
+ };
116
+ const handlePresetSelectorCancel = () => {
117
+ setSelectedWorktree(null);
118
+ setView('menu');
119
+ setMenuKey(prev => prev + 1);
120
+ };
90
121
  const handleReturnToMenu = () => {
91
122
  setActiveSession(null);
92
123
  setError(null);
@@ -229,6 +260,9 @@ const App = () => {
229
260
  if (view === 'configuration') {
230
261
  return React.createElement(Configuration, { onComplete: handleReturnToMenu });
231
262
  }
263
+ if (view === 'preset-selector') {
264
+ return (React.createElement(PresetSelector, { onSelect: handlePresetSelected, onCancel: handlePresetSelectorCancel }));
265
+ }
232
266
  return null;
233
267
  };
234
268
  export default App;
@@ -1,150 +1,240 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import TextInput from 'ink-text-input';
4
+ import SelectInput from 'ink-select-input';
4
5
  import { configurationManager } from '../services/configurationManager.js';
5
6
  import { shortcutManager } from '../services/shortcutManager.js';
6
7
  const ConfigureCommand = ({ onComplete }) => {
7
- // Load current configuration once
8
- const currentConfig = configurationManager.getCommandConfig();
9
- const [originalConfig] = useState(currentConfig);
10
- const [config, setConfig] = useState(currentConfig);
11
- const [editMode, setEditMode] = useState('menu');
8
+ const presetsConfig = configurationManager.getCommandPresets();
9
+ const [presets, setPresets] = useState(presetsConfig.presets);
10
+ const [defaultPresetId, setDefaultPresetId] = useState(presetsConfig.defaultPresetId);
11
+ const [selectPresetOnStart, setSelectPresetOnStart] = useState(configurationManager.getSelectPresetOnStart());
12
+ const [viewMode, setViewMode] = useState('list');
13
+ const [selectedPresetId, setSelectedPresetId] = useState(null);
12
14
  const [selectedIndex, setSelectedIndex] = useState(0);
15
+ const [editField, setEditField] = useState(null);
13
16
  const [inputValue, setInputValue] = useState('');
14
- const [hasChanges, setHasChanges] = useState(false);
15
- const menuItems = [
16
- {
17
- label: 'Command',
18
- value: config.command,
19
- key: 'command',
20
- isButton: false,
21
- disabled: false,
22
- },
23
- {
24
- label: 'Arguments',
25
- value: config.args?.join(' ') || '(none)',
26
- key: 'args',
27
- isButton: false,
28
- disabled: false,
29
- },
30
- {
31
- label: 'Fallback Arguments',
32
- value: config.fallbackArgs?.join(' ') || '(none)',
33
- key: 'fallbackArgs',
34
- isButton: false,
35
- disabled: false,
36
- },
37
- {
38
- label: hasChanges ? '💾 Save Changes' : '💾 Save Changes (no changes)',
39
- value: '',
40
- key: 'save',
41
- isButton: true,
42
- disabled: !hasChanges,
43
- },
44
- {
45
- label: '❌ Exit Without Saving',
46
- value: '',
47
- key: 'exit',
48
- isButton: true,
49
- disabled: false,
50
- },
51
- ];
52
- const handleMenuNavigation = (key) => {
17
+ const [newPreset, setNewPreset] = useState({});
18
+ const [addStep, setAddStep] = useState('name');
19
+ const [errorMessage, setErrorMessage] = useState(null);
20
+ // Remove handleListNavigation as SelectInput handles navigation internally
21
+ // Remove handleListSelection as we now use handleSelectItem
22
+ const handleEditNavigation = (key) => {
23
+ const menuItems = 7; // name, command, args, fallbackArgs, set default, delete, back
53
24
  if (key.upArrow) {
54
- setSelectedIndex(prev => (prev > 0 ? prev - 1 : menuItems.length - 1));
25
+ setSelectedIndex(prev => (prev > 0 ? prev - 1 : menuItems - 1));
55
26
  }
56
27
  else if (key.downArrow) {
57
- setSelectedIndex(prev => (prev < menuItems.length - 1 ? prev + 1 : 0));
28
+ setSelectedIndex(prev => (prev < menuItems - 1 ? prev + 1 : 0));
58
29
  }
59
30
  };
60
- const getInitialInputValue = (key) => {
61
- switch (key) {
31
+ const handleEditSelection = () => {
32
+ const preset = presets.find(p => p.id === selectedPresetId);
33
+ if (!preset)
34
+ return;
35
+ switch (selectedIndex) {
36
+ case 0: // Name
37
+ setEditField('name');
38
+ setInputValue(preset.name);
39
+ break;
40
+ case 1: // Command
41
+ setEditField('command');
42
+ setInputValue(preset.command);
43
+ break;
44
+ case 2: // Args
45
+ setEditField('args');
46
+ setInputValue(preset.args?.join(' ') || '');
47
+ break;
48
+ case 3: // Fallback Args
49
+ setEditField('fallbackArgs');
50
+ setInputValue(preset.fallbackArgs?.join(' ') || '');
51
+ break;
52
+ case 4: // Set as Default
53
+ setDefaultPresetId(preset.id);
54
+ configurationManager.setDefaultPreset(preset.id);
55
+ break;
56
+ case 5: // Delete
57
+ if (presets.length > 1) {
58
+ setViewMode('delete-confirm');
59
+ setSelectedIndex(0);
60
+ }
61
+ break;
62
+ case 6: // Back
63
+ setViewMode('list');
64
+ setSelectedIndex(presets.findIndex(p => p.id === selectedPresetId));
65
+ break;
66
+ }
67
+ };
68
+ const handleFieldUpdate = (value) => {
69
+ const preset = presets.find(p => p.id === selectedPresetId);
70
+ if (!preset || !editField)
71
+ return;
72
+ const updatedPreset = { ...preset };
73
+ switch (editField) {
74
+ case 'name':
75
+ // Prevent using "Default" as a name to avoid confusion
76
+ if (value.trim().toLowerCase() === 'default') {
77
+ setErrorMessage('Cannot use "Default" as a preset name. Please choose a different name.');
78
+ return;
79
+ }
80
+ updatedPreset.name = value;
81
+ break;
62
82
  case 'command':
63
- return config.command;
83
+ updatedPreset.command = value || 'claude';
84
+ break;
64
85
  case 'args':
65
- return config.args?.join(' ') || '';
86
+ updatedPreset.args = value.trim()
87
+ ? value.trim().split(/\s+/)
88
+ : undefined;
89
+ break;
66
90
  case 'fallbackArgs':
67
- return config.fallbackArgs?.join(' ') || '';
68
- default:
69
- return '';
91
+ updatedPreset.fallbackArgs = value.trim()
92
+ ? value.trim().split(/\s+/)
93
+ : undefined;
94
+ break;
70
95
  }
96
+ const updatedPresets = presets.map(p => p.id === preset.id ? updatedPreset : p);
97
+ setPresets(updatedPresets);
98
+ configurationManager.addPreset(updatedPreset);
99
+ setEditField(null);
100
+ setInputValue('');
101
+ setErrorMessage(null);
71
102
  };
72
- const handleMenuItemSelect = () => {
73
- const selectedItem = menuItems[selectedIndex];
74
- if (!selectedItem || selectedItem.disabled)
75
- return;
76
- switch (selectedItem.key) {
77
- case 'save':
78
- configurationManager.setCommandConfig(config);
79
- onComplete();
103
+ const handleAddPresetInput = (value) => {
104
+ switch (addStep) {
105
+ case 'name':
106
+ // Prevent using "Default" as a name to avoid confusion
107
+ if (value.trim().toLowerCase() === 'default') {
108
+ setErrorMessage('Cannot use "Default" as a preset name. Please choose a different name.');
109
+ return;
110
+ }
111
+ setNewPreset({ ...newPreset, name: value });
112
+ setAddStep('command');
113
+ setInputValue('');
114
+ setErrorMessage(null);
80
115
  break;
81
- case 'exit':
82
- onComplete();
116
+ case 'command':
117
+ setNewPreset({ ...newPreset, command: value || 'claude' });
118
+ setAddStep('args');
119
+ setInputValue('');
120
+ break;
121
+ case 'args': {
122
+ const args = value.trim() ? value.trim().split(/\s+/) : undefined;
123
+ setNewPreset({ ...newPreset, args });
124
+ setAddStep('fallbackArgs');
125
+ setInputValue('');
83
126
  break;
84
- default:
85
- if (!selectedItem.isButton) {
86
- setEditMode(selectedItem.key);
87
- setInputValue(getInitialInputValue(selectedItem.key));
127
+ }
128
+ case 'fallbackArgs': {
129
+ const fallbackArgs = value.trim()
130
+ ? value.trim().split(/\s+/)
131
+ : undefined;
132
+ const id = Date.now().toString();
133
+ const completePreset = {
134
+ id,
135
+ name: newPreset.name || 'New Preset',
136
+ command: newPreset.command || 'claude',
137
+ args: newPreset.args,
138
+ fallbackArgs,
139
+ };
140
+ const updatedPresets = [...presets, completePreset];
141
+ setPresets(updatedPresets);
142
+ configurationManager.addPreset(completePreset);
143
+ setViewMode('list');
144
+ setSelectedIndex(updatedPresets.length - 1);
145
+ break;
146
+ }
147
+ }
148
+ };
149
+ const handleDeleteConfirm = () => {
150
+ if (selectedIndex === 0) {
151
+ // Yes, delete
152
+ const newPresets = presets.filter(p => p.id !== selectedPresetId);
153
+ setPresets(newPresets);
154
+ // Update default if needed
155
+ if (defaultPresetId === selectedPresetId && newPresets.length > 0) {
156
+ const firstPreset = newPresets[0];
157
+ if (firstPreset) {
158
+ setDefaultPresetId(firstPreset.id);
159
+ configurationManager.setDefaultPreset(firstPreset.id);
88
160
  }
161
+ }
162
+ configurationManager.deletePreset(selectedPresetId);
163
+ setViewMode('list');
164
+ setSelectedIndex(0);
165
+ }
166
+ else {
167
+ // Cancel
168
+ setViewMode('edit');
169
+ setSelectedIndex(5); // Back to delete option
89
170
  }
90
171
  };
91
172
  useInput((input, key) => {
92
- // Handle cancel shortcut in any mode
93
173
  if (shortcutManager.matchesShortcut('cancel', input, key)) {
94
- if (editMode === 'menu') {
95
- onComplete(); // Exit without saving
174
+ if (editField) {
175
+ setEditField(null);
176
+ setInputValue('');
177
+ setErrorMessage(null);
178
+ }
179
+ else if (viewMode === 'edit') {
180
+ setViewMode('list');
181
+ setSelectedIndex(presets.findIndex(p => p.id === selectedPresetId));
182
+ setErrorMessage(null);
183
+ }
184
+ else if (viewMode === 'add') {
185
+ setViewMode('list');
186
+ setSelectedIndex(presets.length);
187
+ setErrorMessage(null);
188
+ }
189
+ else if (viewMode === 'delete-confirm') {
190
+ setViewMode('edit');
191
+ setSelectedIndex(5);
96
192
  }
97
193
  else {
98
- setEditMode('menu');
99
- setInputValue('');
194
+ onComplete();
100
195
  }
101
196
  return;
102
197
  }
103
- // Handle menu mode inputs
104
- if (editMode === 'menu') {
105
- handleMenuNavigation(key);
198
+ if (editField || (viewMode === 'add' && inputValue !== undefined)) {
199
+ // In input mode, let TextInput handle it
200
+ return;
201
+ }
202
+ if (viewMode === 'list') {
203
+ // SelectInput handles navigation and selection
204
+ return;
205
+ }
206
+ else if (viewMode === 'edit') {
207
+ handleEditNavigation(key);
106
208
  if (key.return) {
107
- handleMenuItemSelect();
209
+ handleEditSelection();
210
+ }
211
+ }
212
+ else if (viewMode === 'delete-confirm') {
213
+ if (key.upArrow || key.downArrow) {
214
+ setSelectedIndex(prev => (prev === 0 ? 1 : 0));
215
+ }
216
+ else if (key.return) {
217
+ handleDeleteConfirm();
108
218
  }
109
219
  }
110
220
  });
111
- const handleInputSubmit = (value) => {
112
- let updatedConfig = { ...config };
113
- if (editMode === 'command') {
114
- updatedConfig.command = value || 'claude';
115
- }
116
- else if (editMode === 'args') {
117
- // Parse arguments, handling empty string as no arguments
118
- const args = value.trim() ? value.trim().split(/\s+/) : undefined;
119
- updatedConfig.args = args;
120
- }
121
- else if (editMode === 'fallbackArgs') {
122
- // Parse fallback arguments, handling empty string as no arguments
123
- const fallbackArgs = value.trim() ? value.trim().split(/\s+/) : undefined;
124
- updatedConfig.fallbackArgs = fallbackArgs;
125
- }
126
- // Update state only (don't save to file yet)
127
- setConfig(updatedConfig);
128
- // Check if there are changes
129
- const hasChanges = JSON.stringify(updatedConfig) !== JSON.stringify(originalConfig);
130
- setHasChanges(hasChanges);
131
- // Return to menu
132
- setEditMode('menu');
133
- setInputValue('');
134
- };
135
- if (editMode !== 'menu') {
221
+ // Render input field
222
+ if (editField) {
136
223
  const titles = {
224
+ name: 'Enter preset name:',
137
225
  command: 'Enter command (e.g., claude):',
138
226
  args: 'Enter command arguments (space-separated):',
139
227
  fallbackArgs: 'Enter fallback arguments (space-separated):',
140
228
  };
141
229
  return (React.createElement(Box, { flexDirection: "column" },
142
230
  React.createElement(Box, { marginBottom: 1 },
143
- React.createElement(Text, { bold: true, color: "green" }, "Configure Command")),
231
+ React.createElement(Text, { bold: true, color: "green" }, "Edit Preset")),
144
232
  React.createElement(Box, { marginBottom: 1 },
145
- React.createElement(Text, null, titles[editMode])),
233
+ React.createElement(Text, null, titles[editField])),
234
+ errorMessage && (React.createElement(Box, { marginBottom: 1 },
235
+ React.createElement(Text, { color: "red" }, errorMessage))),
146
236
  React.createElement(Box, null,
147
- React.createElement(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleInputSubmit, placeholder: editMode === 'args' || editMode === 'fallbackArgs'
237
+ React.createElement(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleFieldUpdate, placeholder: editField === 'args' || editField === 'fallbackArgs'
148
238
  ? 'e.g., --resume or leave empty'
149
239
  : '' })),
150
240
  React.createElement(Box, { marginTop: 1 },
@@ -154,29 +244,185 @@ const ConfigureCommand = ({ onComplete }) => {
154
244
  ' ',
155
245
  "to cancel"))));
156
246
  }
247
+ // Render add preset form
248
+ if (viewMode === 'add') {
249
+ const titles = {
250
+ name: 'Enter preset name:',
251
+ command: 'Enter command (e.g., claude):',
252
+ args: 'Enter command arguments (space-separated):',
253
+ fallbackArgs: 'Enter fallback arguments (space-separated):',
254
+ };
255
+ return (React.createElement(Box, { flexDirection: "column" },
256
+ React.createElement(Box, { marginBottom: 1 },
257
+ React.createElement(Text, { bold: true, color: "green" }, "Add New Preset")),
258
+ React.createElement(Box, { marginBottom: 1 },
259
+ React.createElement(Text, null, titles[addStep])),
260
+ errorMessage && (React.createElement(Box, { marginBottom: 1 },
261
+ React.createElement(Text, { color: "red" }, errorMessage))),
262
+ React.createElement(Box, null,
263
+ React.createElement(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleAddPresetInput, placeholder: addStep === 'args' || addStep === 'fallbackArgs'
264
+ ? 'e.g., --resume or leave empty'
265
+ : addStep === 'name'
266
+ ? 'e.g., Development'
267
+ : '' })),
268
+ React.createElement(Box, { marginTop: 1 },
269
+ React.createElement(Text, { dimColor: true },
270
+ "Press Enter to continue,",
271
+ ' ',
272
+ shortcutManager.getShortcutDisplay('cancel'),
273
+ " to cancel"))));
274
+ }
275
+ // Render delete confirmation
276
+ if (viewMode === 'delete-confirm') {
277
+ const preset = presets.find(p => p.id === selectedPresetId);
278
+ return (React.createElement(Box, { flexDirection: "column" },
279
+ React.createElement(Box, { marginBottom: 1 },
280
+ React.createElement(Text, { bold: true, color: "red" }, "Confirm Delete")),
281
+ React.createElement(Box, { marginBottom: 1 },
282
+ React.createElement(Text, null,
283
+ "Delete preset \"",
284
+ preset?.name,
285
+ "\"?")),
286
+ React.createElement(Box, { flexDirection: "column" },
287
+ React.createElement(Box, null,
288
+ React.createElement(Text, { color: selectedIndex === 0 ? 'red' : undefined },
289
+ selectedIndex === 0 ? '> ' : ' ',
290
+ "Yes, delete")),
291
+ React.createElement(Box, null,
292
+ React.createElement(Text, { color: selectedIndex === 1 ? 'cyan' : undefined },
293
+ selectedIndex === 1 ? '> ' : ' ',
294
+ "Cancel"))),
295
+ React.createElement(Box, { marginTop: 1 },
296
+ React.createElement(Text, { dimColor: true }, "Press \u2191\u2193 to navigate, Enter to confirm"))));
297
+ }
298
+ // Render edit preset view
299
+ if (viewMode === 'edit') {
300
+ const preset = presets.find(p => p.id === selectedPresetId);
301
+ if (!preset)
302
+ return null;
303
+ const isDefault = preset.id === defaultPresetId;
304
+ const canDelete = presets.length > 1;
305
+ const menuItems = [
306
+ { label: 'Name', value: preset.name },
307
+ { label: 'Command', value: preset.command },
308
+ { label: 'Arguments', value: preset.args?.join(' ') || '(none)' },
309
+ {
310
+ label: 'Fallback Arguments',
311
+ value: preset.fallbackArgs?.join(' ') || '(none)',
312
+ },
313
+ {
314
+ label: isDefault ? 'Already Default' : 'Set as Default',
315
+ value: '',
316
+ isButton: true,
317
+ disabled: isDefault,
318
+ },
319
+ {
320
+ label: canDelete
321
+ ? 'Delete Preset'
322
+ : 'Delete Preset (cannot delete last preset)',
323
+ value: '',
324
+ isButton: true,
325
+ disabled: !canDelete,
326
+ },
327
+ { label: 'Back to List', value: '', isButton: true, disabled: false },
328
+ ];
329
+ return (React.createElement(Box, { flexDirection: "column" },
330
+ React.createElement(Box, { marginBottom: 1 },
331
+ React.createElement(Text, { bold: true, color: "green" },
332
+ "Edit Preset: ",
333
+ preset.name)),
334
+ isDefault && (React.createElement(Box, { marginBottom: 1 },
335
+ React.createElement(Text, { color: "yellow" }, "\u2B50 This is the default preset"))),
336
+ React.createElement(Box, { flexDirection: "column" }, menuItems.map((item, index) => {
337
+ const isSelected = selectedIndex === index;
338
+ const color = item.disabled
339
+ ? 'gray'
340
+ : isSelected
341
+ ? 'cyan'
342
+ : undefined;
343
+ return (React.createElement(Box, { key: index, marginTop: item.isButton && index > 0 ? 1 : 0 },
344
+ React.createElement(Text, { color: color },
345
+ isSelected ? '> ' : ' ',
346
+ item.isButton ? (React.createElement(Text, { bold: isSelected && !item.disabled, dimColor: item.disabled }, item.label)) : (`${item.label}: ${item.value}`))));
347
+ })),
348
+ React.createElement(Box, { marginTop: 1 },
349
+ React.createElement(Text, { dimColor: true },
350
+ "Press \u2191\u2193 to navigate, Enter to edit/select,",
351
+ ' ',
352
+ shortcutManager.getShortcutDisplay('cancel'),
353
+ " to go back"))));
354
+ }
355
+ // Render preset list (default view)
356
+ const selectItems = [
357
+ ...presets.map(preset => {
358
+ const isDefault = preset.id === defaultPresetId;
359
+ const args = preset.args?.join(' ') || '';
360
+ const fallback = preset.fallbackArgs?.join(' ') || '';
361
+ let label = preset.name;
362
+ if (isDefault)
363
+ label += ' (default)';
364
+ label += `\n Command: ${preset.command}`;
365
+ if (args)
366
+ label += `\n Args: ${args}`;
367
+ if (fallback)
368
+ label += `\n Fallback: ${fallback}`;
369
+ return {
370
+ label,
371
+ value: preset.id,
372
+ };
373
+ }),
374
+ { label: '─────────────────────────', value: 'separator1' },
375
+ {
376
+ label: `Select preset before session start: ${selectPresetOnStart ? '✅ Enabled' : '❌ Disabled'}`,
377
+ value: 'toggle-select-on-start',
378
+ },
379
+ { label: '─────────────────────────', value: 'separator2' },
380
+ { label: 'Add New Preset', value: 'add' },
381
+ { label: '← Cancel', value: 'exit' },
382
+ ];
383
+ const handleSelectItem = (item) => {
384
+ if (item.value === 'add') {
385
+ // Add New Preset
386
+ setViewMode('add');
387
+ setNewPreset({});
388
+ setAddStep('name');
389
+ setInputValue('');
390
+ }
391
+ else if (item.value === 'exit') {
392
+ // Exit
393
+ onComplete();
394
+ }
395
+ else if (item.value === 'toggle-select-on-start') {
396
+ // Toggle select preset on start
397
+ const newValue = !selectPresetOnStart;
398
+ setSelectPresetOnStart(newValue);
399
+ configurationManager.setSelectPresetOnStart(newValue);
400
+ }
401
+ else if (item.value.startsWith('separator')) {
402
+ // Ignore separator selections
403
+ return;
404
+ }
405
+ else {
406
+ // Selected a preset
407
+ const preset = presets.find(p => p.id === item.value);
408
+ if (preset) {
409
+ setSelectedPresetId(preset.id);
410
+ setViewMode('edit');
411
+ setSelectedIndex(0);
412
+ }
413
+ }
414
+ };
157
415
  return (React.createElement(Box, { flexDirection: "column" },
158
416
  React.createElement(Box, { marginBottom: 1 },
159
- React.createElement(Text, { bold: true, color: "green" }, "Configure Command")),
417
+ React.createElement(Text, { bold: true, color: "green" }, "Command Presets")),
160
418
  React.createElement(Box, { marginBottom: 1 },
161
- React.createElement(Text, { dimColor: true }, "Configure the command and arguments for running code sessions")),
162
- hasChanges && (React.createElement(Box, { marginBottom: 1 },
163
- React.createElement(Text, { color: "yellow" }, "\u26A0\uFE0F You have unsaved changes"))),
164
- React.createElement(Box, { flexDirection: "column" }, menuItems.map((item, index) => {
165
- const isSelected = selectedIndex === index;
166
- const isDisabled = item.disabled || false;
167
- const color = isDisabled ? 'gray' : isSelected ? 'cyan' : undefined;
168
- return (React.createElement(Box, { key: item.key, marginTop: item.isButton && index > 0 ? 1 : 0 },
169
- React.createElement(Text, { color: color },
170
- isSelected ? '> ' : ' ',
171
- item.isButton ? (React.createElement(Text, { bold: isSelected && !isDisabled, dimColor: isDisabled }, item.label)) : (`${item.label}: ${item.value}`))));
172
- })),
419
+ React.createElement(Text, { dimColor: true }, "Configure command presets for running code sessions")),
420
+ React.createElement(SelectInput, { items: selectItems, onSelect: handleSelectItem, initialIndex: selectedIndex }),
173
421
  React.createElement(Box, { marginTop: 1 },
174
422
  React.createElement(Text, { dimColor: true },
175
- "Press \u2191\u2193 to navigate, Enter to edit,",
423
+ "Press \u2191\u2193 to navigate, Enter to select,",
176
424
  ' ',
177
425
  shortcutManager.getShortcutDisplay('cancel'),
178
- " to go back")),
179
- React.createElement(Box, { marginTop: 1 },
180
- React.createElement(Text, { dimColor: true }, "Note: If command fails with main args, fallback args will be tried"))));
426
+ " to exit"))));
181
427
  };
182
428
  export default ConfigureCommand;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ interface PresetSelectorProps {
3
+ onSelect: (presetId: string) => void;
4
+ onCancel: () => void;
5
+ }
6
+ declare const PresetSelector: React.FC<PresetSelectorProps>;
7
+ export default PresetSelector;