ccmanager 3.5.1 → 3.5.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 (60) hide show
  1. package/dist/cli.js +3 -2
  2. package/dist/components/App.d.ts +1 -0
  3. package/dist/components/App.js +17 -39
  4. package/dist/components/App.test.js +12 -44
  5. package/dist/components/Configuration.js +10 -15
  6. package/dist/components/ConfigureCommand.js +18 -106
  7. package/dist/components/ConfigureCustomCommand.js +2 -17
  8. package/dist/components/ConfigureOther.js +5 -23
  9. package/dist/components/ConfigureOther.test.js +7 -31
  10. package/dist/components/ConfigureShortcuts.js +4 -31
  11. package/dist/components/ConfigureStatusHooks.js +5 -44
  12. package/dist/components/ConfigureStatusHooks.test.js +7 -31
  13. package/dist/components/ConfigureTimeout.js +2 -14
  14. package/dist/components/ConfigureWorktree.js +4 -47
  15. package/dist/components/ConfigureWorktreeHooks.js +5 -37
  16. package/dist/components/ConfigureWorktreeHooks.test.js +8 -33
  17. package/dist/components/Confirmation.js +9 -21
  18. package/dist/components/CustomCommandSummary.js +2 -5
  19. package/dist/components/DeleteConfirmation.js +10 -47
  20. package/dist/components/DeleteWorktree.js +14 -42
  21. package/dist/components/DeleteWorktree.test.js +6 -6
  22. package/dist/components/LoadingSpinner.js +3 -6
  23. package/dist/components/LoadingSpinner.test.js +22 -22
  24. package/dist/components/Menu.d.ts +1 -0
  25. package/dist/components/Menu.js +10 -42
  26. package/dist/components/Menu.recent-projects.test.js +8 -8
  27. package/dist/components/Menu.test.js +10 -10
  28. package/dist/components/MergeWorktree.js +16 -88
  29. package/dist/components/MergeWorktree.test.js +5 -5
  30. package/dist/components/NewWorktree.js +25 -105
  31. package/dist/components/NewWorktree.test.js +8 -8
  32. package/dist/components/PresetSelector.js +3 -9
  33. package/dist/components/ProjectList.js +9 -38
  34. package/dist/components/ProjectList.recent-projects.test.js +7 -7
  35. package/dist/components/ProjectList.test.js +37 -37
  36. package/dist/components/RemoteBranchSelector.js +2 -21
  37. package/dist/components/RemoteBranchSelector.test.js +8 -8
  38. package/dist/components/TextInputWrapper.d.ts +5 -0
  39. package/dist/components/TextInputWrapper.js +138 -11
  40. package/dist/contexts/ConfigEditorContext.d.ts +1 -1
  41. package/dist/contexts/ConfigEditorContext.js +3 -2
  42. package/dist/services/autoApprovalVerifier.js +1 -8
  43. package/dist/services/bunTerminal.js +41 -136
  44. package/dist/services/config/configEditor.js +2 -12
  45. package/dist/services/config/globalConfigManager.js +4 -24
  46. package/dist/services/config/projectConfigManager.js +3 -18
  47. package/dist/services/globalSessionOrchestrator.js +3 -12
  48. package/dist/services/globalSessionOrchestrator.test.js +1 -8
  49. package/dist/services/projectManager.js +13 -68
  50. package/dist/services/sessionManager.effect.test.js +9 -37
  51. package/dist/services/sessionManager.js +3 -18
  52. package/dist/services/sessionManager.test.js +9 -37
  53. package/dist/services/shortcutManager.js +7 -13
  54. package/dist/services/worktreeConfigManager.js +3 -8
  55. package/dist/services/worktreeService.js +2 -12
  56. package/dist/types/index.js +4 -12
  57. package/dist/utils/logger.js +12 -33
  58. package/dist/utils/mutex.js +3 -18
  59. package/dist/utils/worktreeUtils.js +3 -3
  60. package/package.json +12 -12
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import React from 'react';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { render } from 'ink';
4
4
  import meow from 'meow';
5
5
  import App from './components/App.js';
@@ -67,8 +67,9 @@ const devcontainerConfig = cli.flags.devcUpCommand && cli.flags.devcExecCommand
67
67
  const appProps = {
68
68
  ...(devcontainerConfig ? { devcontainerConfig } : {}),
69
69
  multiProject: cli.flags.multiProject,
70
+ version,
70
71
  };
71
- const app = render(React.createElement(App, { ...appProps }));
72
+ const app = render(_jsx(App, { ...appProps }));
72
73
  // Clean up sessions on exit
73
74
  process.on('SIGINT', () => {
74
75
  globalSessionOrchestrator.destroyAllSessions();
@@ -3,6 +3,7 @@ import { DevcontainerConfig } from '../types/index.js';
3
3
  interface AppProps {
4
4
  devcontainerConfig?: DevcontainerConfig;
5
5
  multiProject?: boolean;
6
+ version: string;
6
7
  }
7
8
  declare const App: React.FC<AppProps>;
8
9
  export default App;
@@ -1,4 +1,5 @@
1
- import React, { useState, useEffect, useCallback } from 'react';
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from 'react';
2
3
  import { useApp, Box, Text } from 'ink';
3
4
  import { Effect } from 'effect';
4
5
  import Menu from './Menu.js';
@@ -18,7 +19,7 @@ import { configReader } from '../services/config/configReader.js';
18
19
  import { ENV_VARS } from '../constants/env.js';
19
20
  import { MULTI_PROJECT_ERRORS } from '../constants/error.js';
20
21
  import { projectManager } from '../services/projectManager.js';
21
- const App = ({ devcontainerConfig, multiProject }) => {
22
+ const App = ({ devcontainerConfig, multiProject, version, }) => {
22
23
  const { exit } = useApp();
23
24
  const [view, setView] = useState(multiProject ? 'project-list' : 'menu');
24
25
  const [sessionManager, setSessionManager] = useState(() => globalSessionOrchestrator.getManagerForProject());
@@ -383,68 +384,47 @@ const App = ({ devcontainerConfig, multiProject }) => {
383
384
  if (view === 'project-list' && multiProject) {
384
385
  const projectsDir = process.env[ENV_VARS.MULTI_PROJECT_ROOT];
385
386
  if (!projectsDir) {
386
- return (React.createElement(Box, null,
387
- React.createElement(Text, { color: "red" },
388
- "Error: ",
389
- MULTI_PROJECT_ERRORS.NO_PROJECTS_DIR)));
387
+ return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", MULTI_PROJECT_ERRORS.NO_PROJECTS_DIR] }) }));
390
388
  }
391
- return (React.createElement(ProjectList, { projectsDir: projectsDir, onSelectProject: handleSelectProject, error: error, onDismissError: () => setError(null) }));
389
+ return (_jsx(ProjectList, { projectsDir: projectsDir, onSelectProject: handleSelectProject, error: error, onDismissError: () => setError(null) }));
392
390
  }
393
391
  if (view === 'menu') {
394
- return (React.createElement(Menu, { key: menuKey, sessionManager: sessionManager, worktreeService: worktreeService, onSelectWorktree: handleSelectWorktree, onSelectRecentProject: handleSelectProject, error: error, onDismissError: () => setError(null), projectName: selectedProject?.name, multiProject: multiProject }));
392
+ return (_jsx(Menu, { sessionManager: sessionManager, worktreeService: worktreeService, onSelectWorktree: handleSelectWorktree, onSelectRecentProject: handleSelectProject, error: error, onDismissError: () => setError(null), projectName: selectedProject?.name, multiProject: multiProject, version: version }, menuKey));
395
393
  }
396
394
  if (view === 'session' && activeSession) {
397
- return (React.createElement(Box, { flexDirection: "column" },
398
- React.createElement(Session, { key: activeSession.id, session: activeSession, sessionManager: sessionManager, onReturnToMenu: handleReturnToMenu })));
395
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Session, { session: activeSession, sessionManager: sessionManager, onReturnToMenu: handleReturnToMenu }, activeSession.id) }));
399
396
  }
400
397
  if (view === 'new-worktree') {
401
- return (React.createElement(Box, { flexDirection: "column" },
402
- error && (React.createElement(Box, { marginBottom: 1 },
403
- React.createElement(Text, { color: "red" },
404
- "Error: ",
405
- error))),
406
- React.createElement(NewWorktree, { projectPath: selectedProject?.path || process.cwd(), onComplete: handleCreateWorktree, onCancel: handleCancelNewWorktree })));
398
+ return (_jsxs(Box, { flexDirection: "column", children: [error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), _jsx(NewWorktree, { projectPath: selectedProject?.path || process.cwd(), onComplete: handleCreateWorktree, onCancel: handleCancelNewWorktree })] }));
407
399
  }
408
400
  if (view === 'creating-worktree') {
409
401
  // Compose message based on loading context
410
402
  const message = loadingContext.copySessionData
411
403
  ? 'Creating worktree and copying session data...'
412
404
  : 'Creating worktree...';
413
- return (React.createElement(Box, { flexDirection: "column" },
414
- React.createElement(LoadingSpinner, { message: message, color: "cyan" })));
405
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(LoadingSpinner, { message: message, color: "cyan" }) }));
415
406
  }
416
407
  if (view === 'delete-worktree') {
417
- return (React.createElement(Box, { flexDirection: "column" },
418
- error && (React.createElement(Box, { marginBottom: 1 },
419
- React.createElement(Text, { color: "red" },
420
- "Error: ",
421
- error))),
422
- React.createElement(DeleteWorktree, { projectPath: selectedProject?.path, onComplete: handleDeleteWorktrees, onCancel: handleCancelDeleteWorktree })));
408
+ return (_jsxs(Box, { flexDirection: "column", children: [error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), _jsx(DeleteWorktree, { projectPath: selectedProject?.path, onComplete: handleDeleteWorktrees, onCancel: handleCancelDeleteWorktree })] }));
423
409
  }
424
410
  if (view === 'deleting-worktree') {
425
411
  // Compose message based on loading context
426
412
  const message = loadingContext.deleteBranch
427
413
  ? 'Deleting worktrees and branches...'
428
414
  : 'Deleting worktrees...';
429
- return (React.createElement(Box, { flexDirection: "column" },
430
- React.createElement(LoadingSpinner, { message: message, color: "cyan" })));
415
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(LoadingSpinner, { message: message, color: "cyan" }) }));
431
416
  }
432
417
  if (view === 'merge-worktree') {
433
- return (React.createElement(Box, { flexDirection: "column" },
434
- error && (React.createElement(Box, { marginBottom: 1 },
435
- React.createElement(Text, { color: "red" },
436
- "Error: ",
437
- error))),
438
- React.createElement(MergeWorktree, { onComplete: handleReturnToMenu, onCancel: handleReturnToMenu })));
418
+ return (_jsxs(Box, { flexDirection: "column", children: [error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), _jsx(MergeWorktree, { onComplete: handleReturnToMenu, onCancel: handleReturnToMenu })] }));
439
419
  }
440
420
  if (view === 'configuration') {
441
- return (React.createElement(Configuration, { scope: configScope, onComplete: handleReturnToMenu }));
421
+ return (_jsx(Configuration, { scope: configScope, onComplete: handleReturnToMenu }));
442
422
  }
443
423
  if (view === 'preset-selector') {
444
- return (React.createElement(PresetSelector, { onSelect: handlePresetSelected, onCancel: handlePresetSelectorCancel }));
424
+ return (_jsx(PresetSelector, { onSelect: handlePresetSelected, onCancel: handlePresetSelectorCancel }));
445
425
  }
446
426
  if (view === 'remote-branch-selector' && pendingWorktreeCreation) {
447
- return (React.createElement(RemoteBranchSelector, { branchName: pendingWorktreeCreation.ambiguousError.branchName, matches: pendingWorktreeCreation.ambiguousError.matches, onSelect: handleRemoteBranchSelected, onCancel: handleRemoteBranchSelectorCancel }));
427
+ return (_jsx(RemoteBranchSelector, { branchName: pendingWorktreeCreation.ambiguousError.branchName, matches: pendingWorktreeCreation.ambiguousError.matches, onSelect: handleRemoteBranchSelected, onCancel: handleRemoteBranchSelectorCancel }));
448
428
  }
449
429
  if (view === 'creating-session') {
450
430
  // Compose message based on devcontainerConfig presence
@@ -455,8 +435,7 @@ const App = ({ devcontainerConfig, multiProject }) => {
455
435
  // Use yellow color for devcontainer operations (longer duration),
456
436
  // cyan for standard session creation
457
437
  const color = devcontainerConfig ? 'yellow' : 'cyan';
458
- return (React.createElement(Box, { flexDirection: "column" },
459
- React.createElement(LoadingSpinner, { message: message, color: color })));
438
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(LoadingSpinner, { message: message, color: color }) }));
460
439
  }
461
440
  if (view === 'creating-session-preset') {
462
441
  // Always display preset-specific message
@@ -466,8 +445,7 @@ const App = ({ devcontainerConfig, multiProject }) => {
466
445
  : 'Creating session with preset...';
467
446
  // Use yellow color for devcontainer, cyan for standard
468
447
  const color = devcontainerConfig ? 'yellow' : 'cyan';
469
- return (React.createElement(Box, { flexDirection: "column" },
470
- React.createElement(LoadingSpinner, { message: message, color: color })));
448
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(LoadingSpinner, { message: message, color: color }) }));
471
449
  }
472
450
  if (view === 'clearing') {
473
451
  // Render nothing during the clearing phase to ensure clean transition
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { render } from 'ink-testing-library';
3
3
  import { beforeAll, beforeEach, afterEach, describe, expect, it, vi, } from 'vitest';
4
4
  import { Effect } from 'effect';
@@ -14,44 +14,12 @@ const mockSession = {
14
14
  id: 'session-1',
15
15
  };
16
16
  class MockSessionManager {
17
- constructor() {
18
- Object.defineProperty(this, "on", {
19
- enumerable: true,
20
- configurable: true,
21
- writable: true,
22
- value: vi.fn((_, __) => this)
23
- });
24
- Object.defineProperty(this, "off", {
25
- enumerable: true,
26
- configurable: true,
27
- writable: true,
28
- value: vi.fn((_, __) => this)
29
- });
30
- Object.defineProperty(this, "getSession", {
31
- enumerable: true,
32
- configurable: true,
33
- writable: true,
34
- value: vi.fn((_) => null)
35
- });
36
- Object.defineProperty(this, "getAllSessions", {
37
- enumerable: true,
38
- configurable: true,
39
- writable: true,
40
- value: vi.fn(() => [])
41
- });
42
- Object.defineProperty(this, "createSessionWithPresetEffect", {
43
- enumerable: true,
44
- configurable: true,
45
- writable: true,
46
- value: vi.fn((_, __) => Effect.succeed(mockSession))
47
- });
48
- Object.defineProperty(this, "createSessionWithDevcontainerEffect", {
49
- enumerable: true,
50
- configurable: true,
51
- writable: true,
52
- value: vi.fn((_, __) => Effect.succeed(mockSession))
53
- });
54
- }
17
+ on = vi.fn((_, __) => this);
18
+ off = vi.fn((_, __) => this);
19
+ getSession = vi.fn((_) => null);
20
+ getAllSessions = vi.fn(() => []);
21
+ createSessionWithPresetEffect = vi.fn((_, __) => Effect.succeed(mockSession));
22
+ createSessionWithDevcontainerEffect = vi.fn((_, __) => Effect.succeed(mockSession));
55
23
  }
56
24
  const sessionManagers = [];
57
25
  const getManagerForProjectMock = vi.fn((_) => {
@@ -161,7 +129,7 @@ afterEach(() => {
161
129
  });
162
130
  describe('App component view state', () => {
163
131
  it('renders the menu view by default', async () => {
164
- const { lastFrame, unmount } = render(React.createElement(App, null));
132
+ const { lastFrame, unmount } = render(_jsx(App, { version: "test" }));
165
133
  await flush(40);
166
134
  expect(lastFrame()).toContain('Menu View');
167
135
  unmount();
@@ -169,7 +137,7 @@ describe('App component view state', () => {
169
137
  it('renders the project list view first in multi-project mode', async () => {
170
138
  const original = process.env[ENV_VARS.MULTI_PROJECT_ROOT];
171
139
  process.env[ENV_VARS.MULTI_PROJECT_ROOT] = '/tmp/projects';
172
- const { lastFrame, unmount } = render(React.createElement(App, { multiProject: true }));
140
+ const { lastFrame, unmount } = render(_jsx(App, { multiProject: true, version: "test" }));
173
141
  await flush();
174
142
  expect(lastFrame()).toContain('Project List View');
175
143
  unmount();
@@ -187,7 +155,7 @@ describe('App component loading state machine', () => {
187
155
  }),
188
156
  catch: (error) => error,
189
157
  }));
190
- const { lastFrame, unmount } = render(React.createElement(App, null));
158
+ const { lastFrame, unmount } = render(_jsx(App, { version: "test" }));
191
159
  await waitForCondition(() => Boolean(menuProps));
192
160
  const menu = menuProps;
193
161
  const selectPromise = Promise.resolve(menu.onSelectWorktree({
@@ -216,7 +184,7 @@ describe('App component loading state machine', () => {
216
184
  }),
217
185
  catch: (error) => error,
218
186
  }));
219
- const { lastFrame, unmount } = render(React.createElement(App, null));
187
+ const { lastFrame, unmount } = render(_jsx(App, { version: "test" }));
220
188
  await waitForCondition(() => Boolean(menuProps));
221
189
  const menu = menuProps;
222
190
  const selectPromise = Promise.resolve(menu.onSelectWorktree({
@@ -239,7 +207,7 @@ describe('App component loading state machine', () => {
239
207
  });
240
208
  it('shows devcontainer spinner while creating a session with config', async () => {
241
209
  let resolveSession;
242
- const { lastFrame, unmount } = render(React.createElement(App, { devcontainerConfig: {
210
+ const { lastFrame, unmount } = render(_jsx(App, { version: "test", devcontainerConfig: {
243
211
  upCommand: 'podman up',
244
212
  execCommand: 'podman exec',
245
213
  } }));
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
2
3
  import { Box, Text, useInput } from 'ink';
3
4
  import SelectInput from 'ink-select-input';
4
5
  import ConfigureShortcuts from './ConfigureShortcuts.js';
@@ -102,30 +103,24 @@ const ConfigurationContent = ({ scope, onComplete }) => {
102
103
  }
103
104
  });
104
105
  if (view === 'shortcuts') {
105
- return React.createElement(ConfigureShortcuts, { onComplete: handleSubMenuComplete });
106
+ return _jsx(ConfigureShortcuts, { onComplete: handleSubMenuComplete });
106
107
  }
107
108
  if (view === 'statusHooks') {
108
- return React.createElement(ConfigureStatusHooks, { onComplete: handleSubMenuComplete });
109
+ return _jsx(ConfigureStatusHooks, { onComplete: handleSubMenuComplete });
109
110
  }
110
111
  if (view === 'worktreeHooks') {
111
- return React.createElement(ConfigureWorktreeHooks, { onComplete: handleSubMenuComplete });
112
+ return _jsx(ConfigureWorktreeHooks, { onComplete: handleSubMenuComplete });
112
113
  }
113
114
  if (view === 'worktree') {
114
- return React.createElement(ConfigureWorktree, { onComplete: handleSubMenuComplete });
115
+ return _jsx(ConfigureWorktree, { onComplete: handleSubMenuComplete });
115
116
  }
116
117
  if (view === 'presets') {
117
- return React.createElement(ConfigureCommand, { onComplete: handleSubMenuComplete });
118
+ return _jsx(ConfigureCommand, { onComplete: handleSubMenuComplete });
118
119
  }
119
120
  if (view === 'other') {
120
- return React.createElement(ConfigureOther, { onComplete: handleSubMenuComplete });
121
+ return _jsx(ConfigureOther, { onComplete: handleSubMenuComplete });
121
122
  }
122
- return (React.createElement(Box, { flexDirection: "column" },
123
- React.createElement(Box, { marginBottom: 1 },
124
- React.createElement(Text, { bold: true, color: "green" }, title)),
125
- React.createElement(Box, { marginBottom: 1 },
126
- React.createElement(Text, { dimColor: true }, "Select a configuration option:")),
127
- React.createElement(SelectInput, { items: menuItems, onSelect: handleSelect, isFocused: true, limit: 10 })));
123
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: title }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Select a configuration option:" }) }), _jsx(SelectInput, { items: menuItems, onSelect: handleSelect, isFocused: true, limit: 10 })] }));
128
124
  };
129
- const Configuration = ({ scope, onComplete }) => (React.createElement(ConfigEditorProvider, { scope: scope },
130
- React.createElement(ConfigurationContent, { scope: scope, onComplete: onComplete })));
125
+ const Configuration = ({ scope, onComplete }) => (_jsx(ConfigEditorProvider, { scope: scope, children: _jsx(ConfigurationContent, { scope: scope, onComplete: onComplete }) }));
131
126
  export default Configuration;
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
2
3
  import { Box, Text, useInput } from 'ink';
3
4
  import TextInputWrapper from './TextInputWrapper.js';
4
5
  import SelectInput from 'ink-select-input';
@@ -324,18 +325,7 @@ const ConfigureCommand = ({ onComplete }) => {
324
325
  const strategyItems = ALL_STRATEGY_ITEMS;
325
326
  const currentStrategy = preset.detectionStrategy || 'claude';
326
327
  const initialIndex = strategyItems.findIndex(item => item.value === currentStrategy);
327
- return (React.createElement(Box, { flexDirection: "column" },
328
- React.createElement(Box, { marginBottom: 1 },
329
- React.createElement(Text, { bold: true, color: "green" }, "Select Detection Strategy")),
330
- React.createElement(Box, { marginBottom: 1 },
331
- React.createElement(Text, null, "Choose the state detection strategy for this preset:")),
332
- React.createElement(SelectInput, { items: strategyItems, onSelect: handleStrategySelect, initialIndex: initialIndex }),
333
- React.createElement(Box, { marginTop: 1 },
334
- React.createElement(Text, { dimColor: true },
335
- "Press Enter to select,",
336
- ' ',
337
- shortcutManager.getShortcutDisplay('cancel'),
338
- " to cancel"))));
328
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Select Detection Strategy" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Choose the state detection strategy for this preset:" }) }), _jsx(SelectInput, { items: strategyItems, onSelect: handleStrategySelect, initialIndex: initialIndex }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press Enter to select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }) })] }));
339
329
  }
340
330
  // Render input field
341
331
  if (editField) {
@@ -345,42 +335,15 @@ const ConfigureCommand = ({ onComplete }) => {
345
335
  args: 'Enter command arguments (space-separated):',
346
336
  fallbackArgs: 'Enter fallback arguments (space-separated):',
347
337
  };
348
- return (React.createElement(Box, { flexDirection: "column" },
349
- React.createElement(Box, { marginBottom: 1 },
350
- React.createElement(Text, { bold: true, color: "green" }, "Edit Preset")),
351
- React.createElement(Box, { marginBottom: 1 },
352
- React.createElement(Text, null, titles[editField])),
353
- errorMessage && (React.createElement(Box, { marginBottom: 1 },
354
- React.createElement(Text, { color: "red" }, errorMessage))),
355
- React.createElement(Box, null,
356
- React.createElement(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleFieldUpdate, placeholder: editField === 'args' || editField === 'fallbackArgs'
357
- ? 'e.g., --resume or leave empty'
358
- : '' })),
359
- React.createElement(Box, { marginTop: 1 },
360
- React.createElement(Text, { dimColor: true },
361
- "Press Enter to save, ",
362
- shortcutManager.getShortcutDisplay('cancel'),
363
- ' ',
364
- "to cancel"))));
338
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Edit Preset" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: titles[editField] }) }), errorMessage && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", children: errorMessage }) })), _jsx(Box, { children: _jsx(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleFieldUpdate, placeholder: editField === 'args' || editField === 'fallbackArgs'
339
+ ? 'e.g., --resume or leave empty'
340
+ : '' }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press Enter to save, ", shortcutManager.getShortcutDisplay('cancel'), ' ', "to cancel"] }) })] }));
365
341
  }
366
342
  // Render add preset form
367
343
  if (viewMode === 'add') {
368
344
  if (isSelectingStrategyInAdd) {
369
345
  const strategyItems = ALL_STRATEGY_ITEMS;
370
- return (React.createElement(Box, { flexDirection: "column" },
371
- React.createElement(Box, { marginBottom: 1 },
372
- React.createElement(Text, { bold: true, color: "green" }, "Add New Preset - Detection Strategy")),
373
- React.createElement(Box, { marginBottom: 1 },
374
- React.createElement(Text, null, "Choose the state detection strategy for this preset:")),
375
- React.createElement(Box, { marginBottom: 1 },
376
- React.createElement(Text, { dimColor: true }, "The command will be auto-set based on the strategy (can be changed later)")),
377
- React.createElement(SelectInput, { items: strategyItems, onSelect: handleAddStrategySelect, initialIndex: 0 }),
378
- React.createElement(Box, { marginTop: 1 },
379
- React.createElement(Text, { dimColor: true },
380
- "Press Enter to select,",
381
- ' ',
382
- shortcutManager.getShortcutDisplay('cancel'),
383
- " to cancel"))));
346
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Add New Preset - Detection Strategy" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Choose the state detection strategy for this preset:" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "The command will be auto-set based on the strategy (can be changed later)" }) }), _jsx(SelectInput, { items: strategyItems, onSelect: handleAddStrategySelect, initialIndex: 0 }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press Enter to select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }) })] }));
384
347
  }
385
348
  const titles = {
386
349
  detectionStrategy: 'Select detection strategy:',
@@ -389,27 +352,11 @@ const ConfigureCommand = ({ onComplete }) => {
389
352
  fallbackArgs: 'Enter fallback arguments (space-separated):',
390
353
  name: 'Enter preset name (freely customizable):',
391
354
  };
392
- return (React.createElement(Box, { flexDirection: "column" },
393
- React.createElement(Box, { marginBottom: 1 },
394
- React.createElement(Text, { bold: true, color: "green" }, "Add New Preset")),
395
- React.createElement(Box, { marginBottom: 1 },
396
- React.createElement(Text, null, titles[addStep])),
397
- addStep === 'command' && (React.createElement(Box, { marginBottom: 1 },
398
- React.createElement(Text, { dimColor: true }, "Auto-filled from your strategy selection. You can change this if needed."))),
399
- errorMessage && (React.createElement(Box, { marginBottom: 1 },
400
- React.createElement(Text, { color: "red" }, errorMessage))),
401
- React.createElement(Box, null,
402
- React.createElement(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleAddPresetInput, placeholder: addStep === 'name'
403
- ? 'e.g., Development'
404
- : addStep === 'args' || addStep === 'fallbackArgs'
405
- ? 'e.g., --resume or leave empty'
406
- : '' })),
407
- React.createElement(Box, { marginTop: 1 },
408
- React.createElement(Text, { dimColor: true },
409
- "Press Enter to continue,",
410
- ' ',
411
- shortcutManager.getShortcutDisplay('cancel'),
412
- " to cancel"))));
355
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Add New Preset" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: titles[addStep] }) }), addStep === 'command' && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Auto-filled from your strategy selection. You can change this if needed." }) })), errorMessage && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "red", children: errorMessage }) })), _jsx(Box, { children: _jsx(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleAddPresetInput, placeholder: addStep === 'name'
356
+ ? 'e.g., Development'
357
+ : addStep === 'args' || addStep === 'fallbackArgs'
358
+ ? 'e.g., --resume or leave empty'
359
+ : '' }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press Enter to continue,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }) })] }));
413
360
  }
414
361
  // Render delete confirmation
415
362
  if (viewMode === 'delete-confirm') {
@@ -423,13 +370,10 @@ const ConfigureCommand = ({ onComplete }) => {
423
370
  setSelectedIndex(6); // Return to delete option in edit menu
424
371
  }
425
372
  };
426
- const title = (React.createElement(Text, { bold: true, color: "red" }, "Confirm Delete"));
427
- const message = React.createElement(Text, null,
428
- "Delete preset \"",
429
- preset?.name,
430
- "\"?");
431
- const hint = (React.createElement(Text, { dimColor: true }, "Press \u2191\u2193/j/k to navigate, Enter to confirm"));
432
- return (React.createElement(Confirmation, { title: title, message: message, options: [
373
+ const title = (_jsx(Text, { bold: true, color: "red", children: "Confirm Delete" }));
374
+ const message = _jsxs(Text, { children: ["Delete preset \"", preset?.name, "\"?"] });
375
+ const hint = (_jsx(Text, { dimColor: true, children: "Press \u2191\u2193/j/k to navigate, Enter to confirm" }));
376
+ return (_jsx(Confirmation, { title: title, message: message, options: [
433
377
  { label: 'Yes, delete', value: 'yes', color: 'red' },
434
378
  { label: 'Cancel', value: 'cancel', color: 'cyan' },
435
379
  ], onSelect: handleConfirmSelect, initialIndex: 1, indicatorColor: "red", hint: hint }));
@@ -484,20 +428,7 @@ const ConfigureCommand = ({ onComplete }) => {
484
428
  return false;
485
429
  return true;
486
430
  });
487
- return (React.createElement(Box, { flexDirection: "column" },
488
- React.createElement(Box, { marginBottom: 1 },
489
- React.createElement(Text, { bold: true, color: "green" },
490
- "Edit Preset: ",
491
- preset.name)),
492
- isDefault && (React.createElement(Box, { marginBottom: 1 },
493
- React.createElement(Text, { color: "yellow" }, "\u2B50 This is the default preset"))),
494
- React.createElement(SelectInput, { items: selectableItems, onSelect: handleEditMenuSelect }),
495
- React.createElement(Box, { marginTop: 1 },
496
- React.createElement(Text, { dimColor: true },
497
- "Press \u2191\u2193 to navigate, Enter to edit/select,",
498
- ' ',
499
- shortcutManager.getShortcutDisplay('cancel'),
500
- " to go back"))));
431
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Edit Preset: ", preset.name] }) }), isDefault && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "yellow", children: "\u2B50 This is the default preset" }) })), _jsx(SelectInput, { items: selectableItems, onSelect: handleEditMenuSelect }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press \u2191\u2193 to navigate, Enter to edit/select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to go back"] }) })] }));
501
432
  }
502
433
  // Render preset list (default view)
503
434
  const selectItems = [
@@ -562,25 +493,6 @@ const ConfigureCommand = ({ onComplete }) => {
562
493
  }
563
494
  };
564
495
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
565
- return (React.createElement(Box, { flexDirection: "column" },
566
- React.createElement(Box, { marginBottom: 1 },
567
- React.createElement(Text, { bold: true, color: "green" },
568
- "Command Presets (",
569
- scopeLabel,
570
- ")")),
571
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
572
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
573
- ' ',
574
- "\uD83D\uDCCB Inheriting from global configuration",
575
- ' '))),
576
- React.createElement(Box, { marginBottom: 1 },
577
- React.createElement(Text, { dimColor: true }, "Configure command presets for running code sessions")),
578
- React.createElement(SelectInput, { items: selectItems, onSelect: handleSelectItem, initialIndex: selectedIndex }),
579
- React.createElement(Box, { marginTop: 1 },
580
- React.createElement(Text, { dimColor: true },
581
- "Press \u2191\u2193 to navigate, Enter to select,",
582
- ' ',
583
- shortcutManager.getShortcutDisplay('cancel'),
584
- " to exit"))));
496
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Command Presets (", scopeLabel, ")"] }) }), isInheriting && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { backgroundColor: "cyan", color: "black", children: [' ', "\uD83D\uDCCB Inheriting from global configuration", ' '] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Configure command presets for running code sessions" }) }), _jsx(SelectInput, { items: selectItems, onSelect: handleSelectItem, initialIndex: selectedIndex }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press \u2191\u2193 to navigate, Enter to select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to exit"] }) })] }));
585
497
  };
586
498
  export default ConfigureCommand;
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
2
  import React from 'react';
2
3
  import { Box, Text, useInput } from 'ink';
3
4
  import TextInputWrapper from './TextInputWrapper.js';
@@ -23,22 +24,6 @@ const ConfigureCustomCommand = ({ value, onChange, onSubmit, onCancel, }) => {
23
24
  onChange('');
24
25
  }
25
26
  });
26
- return (React.createElement(Box, { flexDirection: "column" },
27
- React.createElement(Box, { marginBottom: 1 },
28
- React.createElement(Text, { bold: true, color: "green" }, "Custom Auto-Approval Command")),
29
- React.createElement(Box, { marginBottom: 1 },
30
- React.createElement(Text, null,
31
- "Enter the command that returns ",
32
- '{needsPermission:boolean}',
33
- " JSON:")),
34
- React.createElement(Box, { marginBottom: 1 },
35
- React.createElement(TextInputWrapper, { value: value, onChange: handleChange, onSubmit: () => onSubmit(value), placeholder: `e.g. jq -n '{"needsPermission":true}'`, focus: true })),
36
- React.createElement(Box, { marginBottom: 1 },
37
- React.createElement(Text, { dimColor: true }, "Env provided: $DEFAULT_PROMPT, $TERMINAL_OUTPUT")),
38
- React.createElement(Box, null,
39
- React.createElement(Text, { dimColor: true },
40
- "Press Enter to save, ",
41
- shortcutManager.getShortcutDisplay('cancel'),
42
- " to go back, Ctrl+K to clear input"))));
27
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Custom Auto-Approval Command" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Enter the command that returns ", '{needsPermission:boolean}', " JSON:"] }) }), _jsx(Box, { marginBottom: 1, children: _jsx(TextInputWrapper, { value: value, onChange: handleChange, onSubmit: () => onSubmit(value), placeholder: `e.g. jq -n '{"needsPermission":true}'`, focus: true }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Env provided: $DEFAULT_PROMPT, $TERMINAL_OUTPUT" }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["Press Enter to save, ", shortcutManager.getShortcutDisplay('cancel'), " to go back, Ctrl+K to clear input"] }) })] }));
43
28
  };
44
29
  export default ConfigureCustomCommand;
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
2
3
  import { Box, Text, useInput } from 'ink';
3
4
  import SelectInput from 'ink-select-input';
4
5
  import { useConfigEditor } from '../contexts/ConfigEditorContext.js';
@@ -85,7 +86,7 @@ const ConfigureOther = ({ onComplete }) => {
85
86
  }
86
87
  };
87
88
  if (view === 'customCommand') {
88
- return (React.createElement(ConfigureCustomCommand, { value: customCommandDraft, onChange: setCustomCommandDraft, onCancel: () => {
89
+ return (_jsx(ConfigureCustomCommand, { value: customCommandDraft, onChange: setCustomCommandDraft, onCancel: () => {
89
90
  setCustomCommandDraft(customCommand);
90
91
  setView('main');
91
92
  }, onSubmit: value => {
@@ -94,7 +95,7 @@ const ConfigureOther = ({ onComplete }) => {
94
95
  } }));
95
96
  }
96
97
  if (view === 'timeout') {
97
- return (React.createElement(ConfigureTimeout, { value: timeoutDraft, onChange: setTimeoutDraft, onCancel: () => {
98
+ return (_jsx(ConfigureTimeout, { value: timeoutDraft, onChange: setTimeoutDraft, onCancel: () => {
98
99
  setTimeoutDraft(timeout);
99
100
  setView('main');
100
101
  }, onSubmit: value => {
@@ -103,25 +104,6 @@ const ConfigureOther = ({ onComplete }) => {
103
104
  } }));
104
105
  }
105
106
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
106
- return (React.createElement(Box, { flexDirection: "column" },
107
- React.createElement(Box, { marginBottom: 1 },
108
- React.createElement(Text, { bold: true, color: "green" },
109
- "Other & Experimental Settings (",
110
- scopeLabel,
111
- ")")),
112
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
113
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
114
- ' ',
115
- "\uD83D\uDCCB Inheriting from global configuration",
116
- ' '))),
117
- React.createElement(Box, { marginBottom: 1 },
118
- React.createElement(Text, { dimColor: true }, "Toggle experimental capabilities and other miscellaneous options.")),
119
- React.createElement(CustomCommandSummary, { command: customCommand }),
120
- React.createElement(SelectInput, { items: menuItems, onSelect: handleSelect, isFocused: true }),
121
- React.createElement(Box, { marginTop: 1 },
122
- React.createElement(Text, { dimColor: true },
123
- "Press ",
124
- shortcutManager.getShortcutDisplay('cancel'),
125
- " to return without saving"))));
107
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Other & Experimental Settings (", scopeLabel, ")"] }) }), isInheriting && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { backgroundColor: "cyan", color: "black", children: [' ', "\uD83D\uDCCB Inheriting from global configuration", ' '] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Toggle experimental capabilities and other miscellaneous options." }) }), _jsx(CustomCommandSummary, { command: customCommand }), _jsx(SelectInput, { items: menuItems, onSelect: handleSelect, isFocused: true }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press ", shortcutManager.getShortcutDisplay('cancel'), " to return without saving"] }) })] }));
126
108
  };
127
109
  export default ConfigureOther;
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { render } from 'ink-testing-library';
3
3
  import { describe, it, expect, vi, beforeEach } from 'vitest';
4
4
  import ConfigureOther from './ConfigureOther.js';
@@ -29,32 +29,10 @@ const mockFns = {
29
29
  vi.mock('../services/config/configEditor.js', () => {
30
30
  return {
31
31
  ConfigEditor: class {
32
- constructor() {
33
- Object.defineProperty(this, "getAutoApprovalConfig", {
34
- enumerable: true,
35
- configurable: true,
36
- writable: true,
37
- value: mockFns.getAutoApprovalConfig
38
- });
39
- Object.defineProperty(this, "setAutoApprovalConfig", {
40
- enumerable: true,
41
- configurable: true,
42
- writable: true,
43
- value: mockFns.setAutoApprovalConfig
44
- });
45
- Object.defineProperty(this, "hasProjectOverride", {
46
- enumerable: true,
47
- configurable: true,
48
- writable: true,
49
- value: mockFns.hasProjectOverride
50
- });
51
- Object.defineProperty(this, "getScope", {
52
- enumerable: true,
53
- configurable: true,
54
- writable: true,
55
- value: mockFns.getScope
56
- });
57
- }
32
+ getAutoApprovalConfig = mockFns.getAutoApprovalConfig;
33
+ setAutoApprovalConfig = mockFns.setAutoApprovalConfig;
34
+ hasProjectOverride = mockFns.hasProjectOverride;
35
+ getScope = mockFns.getScope;
58
36
  },
59
37
  };
60
38
  });
@@ -93,8 +71,7 @@ describe('ConfigureOther', () => {
93
71
  customCommand: '',
94
72
  timeout: 30,
95
73
  });
96
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
97
- React.createElement(ConfigureOther, { onComplete: vi.fn() })));
74
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureOther, { onComplete: vi.fn() }) }));
98
75
  expect(lastFrame()).toContain('Other & Experimental Settings');
99
76
  expect(lastFrame()).toContain('Auto Approval (experimental): ✅ Enabled');
100
77
  expect(lastFrame()).toContain('Custom auto-approval command: Empty');
@@ -107,8 +84,7 @@ describe('ConfigureOther', () => {
107
84
  customCommand: 'jq -n \'{"needsPermission":true}\'',
108
85
  timeout: 30,
109
86
  });
110
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
111
- React.createElement(ConfigureOther, { onComplete: vi.fn() })));
87
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureOther, { onComplete: vi.fn() }) }));
112
88
  expect(lastFrame()).toContain('Custom auto-approval command:');
113
89
  expect(lastFrame()).toContain('jq -n');
114
90
  expect(lastFrame()).toContain('Edit Custom Command');