ccmanager 3.5.0 → 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 (82) 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/constants/statusIcons.d.ts +2 -1
  41. package/dist/constants/statusIcons.js +13 -4
  42. package/dist/constants/statusIcons.test.js +41 -11
  43. package/dist/contexts/ConfigEditorContext.d.ts +1 -1
  44. package/dist/contexts/ConfigEditorContext.js +3 -2
  45. package/dist/services/autoApprovalVerifier.js +1 -8
  46. package/dist/services/bunTerminal.js +41 -136
  47. package/dist/services/config/configEditor.js +2 -12
  48. package/dist/services/config/globalConfigManager.js +4 -24
  49. package/dist/services/config/projectConfigManager.js +3 -18
  50. package/dist/services/globalSessionOrchestrator.js +3 -12
  51. package/dist/services/globalSessionOrchestrator.test.js +1 -8
  52. package/dist/services/projectManager.js +13 -68
  53. package/dist/services/sessionManager.d.ts +1 -1
  54. package/dist/services/sessionManager.effect.test.js +9 -37
  55. package/dist/services/sessionManager.js +12 -28
  56. package/dist/services/sessionManager.test.js +48 -40
  57. package/dist/services/shortcutManager.js +7 -13
  58. package/dist/services/stateDetector/base.d.ts +1 -1
  59. package/dist/services/stateDetector/claude.d.ts +1 -1
  60. package/dist/services/stateDetector/claude.js +11 -4
  61. package/dist/services/stateDetector/claude.test.js +47 -24
  62. package/dist/services/stateDetector/cline.d.ts +1 -1
  63. package/dist/services/stateDetector/cline.js +1 -1
  64. package/dist/services/stateDetector/codex.d.ts +1 -1
  65. package/dist/services/stateDetector/codex.js +1 -1
  66. package/dist/services/stateDetector/cursor.d.ts +1 -1
  67. package/dist/services/stateDetector/cursor.js +1 -1
  68. package/dist/services/stateDetector/gemini.d.ts +1 -1
  69. package/dist/services/stateDetector/gemini.js +1 -1
  70. package/dist/services/stateDetector/github-copilot.d.ts +1 -1
  71. package/dist/services/stateDetector/github-copilot.js +1 -1
  72. package/dist/services/stateDetector/opencode.d.ts +1 -1
  73. package/dist/services/stateDetector/opencode.js +1 -1
  74. package/dist/services/stateDetector/types.d.ts +1 -1
  75. package/dist/services/worktreeConfigManager.js +3 -8
  76. package/dist/services/worktreeService.js +2 -12
  77. package/dist/types/index.js +4 -12
  78. package/dist/utils/logger.js +12 -33
  79. package/dist/utils/mutex.d.ts +1 -1
  80. package/dist/utils/mutex.js +4 -19
  81. package/dist/utils/worktreeUtils.js +4 -4
  82. package/package.json +12 -12
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import { jsxs as _jsxs, jsx as _jsx } 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';
@@ -119,37 +120,9 @@ const ConfigureShortcuts = ({ onComplete, }) => {
119
120
  setError(null);
120
121
  };
121
122
  if (step === 'capturing') {
122
- return (React.createElement(Box, { flexDirection: "column" },
123
- React.createElement(Text, { bold: true, color: "green" },
124
- "Configure Shortcut: ",
125
- editingShortcut),
126
- React.createElement(Box, { marginTop: 1 },
127
- React.createElement(Text, null, "Press the key combination you want to use")),
128
- React.createElement(Box, { marginTop: 1 },
129
- React.createElement(Text, { dimColor: true }, "Note: Shortcuts must use Ctrl as a modifier key")),
130
- React.createElement(Box, { marginTop: 1 },
131
- React.createElement(Text, { dimColor: true }, "Reserved: Ctrl+C, Ctrl+D, Ctrl+[ (Esc)"))));
123
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, color: "green", children: ["Configure Shortcut: ", editingShortcut] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Press the key combination you want to use" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Note: Shortcuts must use Ctrl as a modifier key" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Reserved: Ctrl+C, Ctrl+D, Ctrl+[ (Esc)" }) })] }));
132
124
  }
133
125
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
134
- return (React.createElement(Box, { flexDirection: "column" },
135
- React.createElement(Box, { marginBottom: 1 },
136
- React.createElement(Text, { bold: true, color: "green" },
137
- "Configure Keyboard Shortcuts (",
138
- scopeLabel,
139
- ")")),
140
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
141
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
142
- ' ',
143
- "\uD83D\uDCCB Inheriting from global configuration",
144
- ' '))),
145
- error && (React.createElement(Box, { marginBottom: 1 },
146
- React.createElement(Text, { color: "red" },
147
- "Error: ",
148
- error))),
149
- React.createElement(Box, { marginBottom: 1 },
150
- React.createElement(Text, { dimColor: true }, "Select a shortcut to change:")),
151
- React.createElement(SelectInput, { items: shortcutItems, onSelect: handleSelect, isFocused: true, limit: 10 }),
152
- React.createElement(Box, { marginTop: 1 },
153
- React.createElement(Text, { dimColor: true }, "Press Esc to exit without saving"))));
126
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Configure Keyboard Shortcuts (", scopeLabel, ")"] }) }), isInheriting && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { backgroundColor: "cyan", color: "black", children: [' ', "\uD83D\uDCCB Inheriting from global configuration", ' '] }) })), error && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: "red", children: ["Error: ", error] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Select a shortcut to change:" }) }), _jsx(SelectInput, { items: shortcutItems, onSelect: handleSelect, isFocused: true, limit: 10 }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Esc to exit without saving" }) })] }));
154
127
  };
155
128
  export default ConfigureShortcuts;
@@ -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';
@@ -101,52 +102,12 @@ const ConfigureStatusHooks = ({ onComplete, }) => {
101
102
  setCurrentEnabled(prev => !prev);
102
103
  };
103
104
  if (showSaveMessage) {
104
- return (React.createElement(Box, { flexDirection: "column" },
105
- React.createElement(Text, { color: "green" }, "\u2713 Configuration saved successfully!")));
105
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { color: "green", children: "\u2713 Configuration saved successfully!" }) }));
106
106
  }
107
107
  if (view === 'edit') {
108
- return (React.createElement(Box, { flexDirection: "column" },
109
- React.createElement(Box, { marginBottom: 1 },
110
- React.createElement(Text, { bold: true, color: "green" },
111
- "Configure ",
112
- STATUS_LABELS[selectedStatus],
113
- " Hook")),
114
- React.createElement(Box, { marginBottom: 1 },
115
- React.createElement(Text, null,
116
- "Command to execute when status changes to",
117
- ' ',
118
- STATUS_LABELS[selectedStatus],
119
- ":")),
120
- React.createElement(Box, { marginBottom: 1 },
121
- React.createElement(TextInputWrapper, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., notify-send 'Claude is idle')" })),
122
- React.createElement(Box, { marginBottom: 1 },
123
- React.createElement(Text, null,
124
- "Enabled: ",
125
- currentEnabled ? '✓' : '✗',
126
- " (Press Tab to toggle)")),
127
- React.createElement(Box, { marginTop: 1 },
128
- React.createElement(Text, { dimColor: true }, "Environment variables available: CCMANAGER_OLD_STATE, CCMANAGER_NEW_STATE,")),
129
- React.createElement(Box, null,
130
- React.createElement(Text, { dimColor: true }, `CCMANAGER_WORKTREE_PATH, CCMANAGER_WORKTREE_BRANCH, CCMANAGER_SESSION_ID`)),
131
- React.createElement(Box, { marginTop: 1 },
132
- React.createElement(Text, { dimColor: true }, "Press Enter to save, Tab to toggle enabled, Esc to cancel"))));
108
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Configure ", STATUS_LABELS[selectedStatus], " Hook"] }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Command to execute when status changes to", ' ', STATUS_LABELS[selectedStatus], ":"] }) }), _jsx(Box, { marginBottom: 1, children: _jsx(TextInputWrapper, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., notify-send 'Claude is idle')" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Enabled: ", currentEnabled ? '✓' : '✗', " (Press Tab to toggle)"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Environment variables available: CCMANAGER_OLD_STATE, CCMANAGER_NEW_STATE," }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: `CCMANAGER_WORKTREE_PATH, CCMANAGER_WORKTREE_BRANCH, CCMANAGER_SESSION_ID` }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to save, Tab to toggle enabled, Esc to cancel" }) })] }));
133
109
  }
134
110
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
135
- return (React.createElement(Box, { flexDirection: "column" },
136
- React.createElement(Box, { marginBottom: 1 },
137
- React.createElement(Text, { bold: true, color: "green" },
138
- "Configure Status Hooks (",
139
- scopeLabel,
140
- ")")),
141
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
142
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
143
- ' ',
144
- "\uD83D\uDCCB Inheriting from global configuration",
145
- ' '))),
146
- React.createElement(Box, { marginBottom: 1 },
147
- React.createElement(Text, { dimColor: true }, "Set commands to run when session status changes:")),
148
- React.createElement(SelectInput, { items: getMenuItems(), onSelect: handleMenuSelect, isFocused: true, limit: 10 }),
149
- React.createElement(Box, { marginTop: 1 },
150
- React.createElement(Text, { dimColor: true }, "Press Esc to go back"))));
111
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Configure Status Hooks (", 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: "Set commands to run when session status changes:" }) }), _jsx(SelectInput, { items: getMenuItems(), onSelect: handleMenuSelect, isFocused: true, limit: 10 }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Esc to go back" }) })] }));
151
112
  };
152
113
  export default ConfigureStatusHooks;
@@ -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 ConfigureStatusHooks from './ConfigureStatusHooks.js';
@@ -31,32 +31,10 @@ const mockFns = {
31
31
  vi.mock('../services/config/configEditor.js', () => {
32
32
  return {
33
33
  ConfigEditor: class {
34
- constructor() {
35
- Object.defineProperty(this, "getStatusHooks", {
36
- enumerable: true,
37
- configurable: true,
38
- writable: true,
39
- value: mockFns.getStatusHooks
40
- });
41
- Object.defineProperty(this, "setStatusHooks", {
42
- enumerable: true,
43
- configurable: true,
44
- writable: true,
45
- value: mockFns.setStatusHooks
46
- });
47
- Object.defineProperty(this, "hasProjectOverride", {
48
- enumerable: true,
49
- configurable: true,
50
- writable: true,
51
- value: mockFns.hasProjectOverride
52
- });
53
- Object.defineProperty(this, "getScope", {
54
- enumerable: true,
55
- configurable: true,
56
- writable: true,
57
- value: mockFns.getScope
58
- });
59
- }
34
+ getStatusHooks = mockFns.getStatusHooks;
35
+ setStatusHooks = mockFns.setStatusHooks;
36
+ hasProjectOverride = mockFns.hasProjectOverride;
37
+ getScope = mockFns.getScope;
60
38
  },
61
39
  };
62
40
  });
@@ -67,8 +45,7 @@ describe('ConfigureStatusHooks', () => {
67
45
  it('should render status hooks configuration screen', () => {
68
46
  mockFns.getStatusHooks.mockReturnValue({});
69
47
  const onComplete = vi.fn();
70
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
71
- React.createElement(ConfigureStatusHooks, { onComplete: onComplete })));
48
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureStatusHooks, { onComplete: onComplete }) }));
72
49
  expect(lastFrame()).toContain('Configure Status Hooks');
73
50
  expect(lastFrame()).toContain('Set commands to run when session status changes');
74
51
  expect(lastFrame()).toContain('Idle:');
@@ -87,8 +64,7 @@ describe('ConfigureStatusHooks', () => {
87
64
  },
88
65
  });
89
66
  const onComplete = vi.fn();
90
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
91
- React.createElement(ConfigureStatusHooks, { onComplete: onComplete })));
67
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureStatusHooks, { onComplete: onComplete }) }));
92
68
  expect(lastFrame()).toContain('Idle: ✓ notify-send "Idle"');
93
69
  expect(lastFrame()).toContain('Busy: ✗ echo "Busy"');
94
70
  expect(lastFrame()).toContain('Waiting for Input: ✗ (not set)');
@@ -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';
@@ -24,19 +25,6 @@ const ConfigureTimeout = ({ value, onChange, onSubmit, onCancel, }) => {
24
25
  onCancel();
25
26
  }
26
27
  });
27
- return (React.createElement(Box, { flexDirection: "column" },
28
- React.createElement(Box, { marginBottom: 1 },
29
- React.createElement(Text, { bold: true, color: "green" }, "Auto-Approval Timeout")),
30
- React.createElement(Box, { marginBottom: 1 },
31
- React.createElement(Text, null, "Enter timeout in seconds for auto-approval verification:")),
32
- React.createElement(Box, { marginBottom: 1 },
33
- React.createElement(TextInputWrapper, { value: inputValue, onChange: handleChange, onSubmit: handleSubmit, placeholder: "e.g. 30", focus: true })),
34
- React.createElement(Box, { marginBottom: 1 },
35
- React.createElement(Text, { dimColor: true }, "Must be a positive integer (minimum: 1 second, default: 30 seconds)")),
36
- React.createElement(Box, null,
37
- React.createElement(Text, { dimColor: true },
38
- "Press Enter to save, ",
39
- shortcutManager.getShortcutDisplay('cancel'),
40
- " to go back"))));
28
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Auto-Approval Timeout" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Enter timeout in seconds for auto-approval verification:" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(TextInputWrapper, { value: inputValue, onChange: handleChange, onSubmit: handleSubmit, placeholder: "e.g. 30", focus: true }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Must be a positive integer (minimum: 1 second, default: 30 seconds)" }) }), _jsx(Box, { children: _jsxs(Text, { dimColor: true, children: ["Press Enter to save, ", shortcutManager.getShortcutDisplay('cancel'), " to go back"] }) })] }));
41
29
  };
42
30
  export default ConfigureTimeout;
@@ -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 TextInputWrapper from './TextInputWrapper.js';
@@ -90,53 +91,9 @@ const ConfigureWorktree = ({ onComplete }) => {
90
91
  setEditMode('menu');
91
92
  };
92
93
  if (editMode === 'pattern') {
93
- return (React.createElement(Box, { flexDirection: "column" },
94
- React.createElement(Box, { marginBottom: 1 },
95
- React.createElement(Text, { bold: true, color: "green" }, "Configure Directory Pattern")),
96
- React.createElement(Box, { marginBottom: 1 },
97
- React.createElement(Text, null, "Enter the pattern for automatic directory generation:")),
98
- React.createElement(Box, { marginBottom: 1 },
99
- React.createElement(Text, { dimColor: true },
100
- "Available placeholders: ",
101
- '{branch}',
102
- " - full branch name,",
103
- ' ',
104
- '{project}',
105
- " - repository name")),
106
- React.createElement(Box, null,
107
- React.createElement(Text, { color: "cyan" }, '> '),
108
- React.createElement(TextInputWrapper, { value: tempPattern, onChange: setTempPattern, onSubmit: handlePatternSubmit, placeholder: "../{branch}" })),
109
- React.createElement(Box, { marginTop: 1 },
110
- React.createElement(Text, { dimColor: true }, "Press Enter to save or Escape to cancel"))));
94
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Configure Directory Pattern" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Enter the pattern for automatic directory generation:" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { dimColor: true, children: ["Available placeholders: ", '{branch}', " - full branch name,", ' ', '{project}', " - repository name"] }) }), _jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: '> ' }), _jsx(TextInputWrapper, { value: tempPattern, onChange: setTempPattern, onSubmit: handlePatternSubmit, placeholder: "../{branch}" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to save or Escape to cancel" }) })] }));
111
95
  }
112
96
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
113
- return (React.createElement(Box, { flexDirection: "column" },
114
- React.createElement(Box, { marginBottom: 1 },
115
- React.createElement(Text, { bold: true, color: "green" },
116
- "Configure Worktree Settings (",
117
- scopeLabel,
118
- ")")),
119
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
120
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
121
- ' ',
122
- "\uD83D\uDCCB Inheriting from global configuration",
123
- ' '))),
124
- React.createElement(Box, { marginBottom: 1 },
125
- React.createElement(Text, { dimColor: true }, "Configure worktree creation settings")),
126
- autoDirectory && (React.createElement(Box, { marginBottom: 1 },
127
- React.createElement(Text, null,
128
- "Example: project \"",
129
- exampleProjectPath,
130
- "\", branch \"",
131
- exampleBranchName,
132
- "\" \u2192 directory \"",
133
- generateWorktreeDirectory(exampleProjectPath, exampleBranchName, pattern),
134
- "\""))),
135
- React.createElement(SelectInput, { items: menuItems, onSelect: handleMenuSelect, isFocused: true }),
136
- React.createElement(Box, { marginTop: 1 },
137
- React.createElement(Text, { dimColor: true },
138
- "Press ",
139
- shortcutManager.getShortcutDisplay('cancel'),
140
- " to cancel without saving"))));
97
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Configure Worktree 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: "Configure worktree creation settings" }) }), autoDirectory && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Example: project \"", exampleProjectPath, "\", branch \"", exampleBranchName, "\" \u2192 directory \"", generateWorktreeDirectory(exampleProjectPath, exampleBranchName, pattern), "\""] }) })), _jsx(SelectInput, { items: menuItems, onSelect: handleMenuSelect, isFocused: true }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Press ", shortcutManager.getShortcutDisplay('cancel'), " to cancel without saving"] }) })] }));
141
98
  };
142
99
  export default ConfigureWorktree;
@@ -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';
@@ -85,45 +86,12 @@ const ConfigureWorktreeHooks = ({ onComplete, }) => {
85
86
  setCurrentEnabled(prev => !prev);
86
87
  };
87
88
  if (showSaveMessage) {
88
- return (React.createElement(Box, { flexDirection: "column" },
89
- React.createElement(Text, { color: "green" }, "\u2713 Configuration saved successfully!")));
89
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { color: "green", children: "\u2713 Configuration saved successfully!" }) }));
90
90
  }
91
91
  if (view === 'edit') {
92
- return (React.createElement(Box, { flexDirection: "column" },
93
- React.createElement(Box, { marginBottom: 1 },
94
- React.createElement(Text, { bold: true, color: "green" }, "Configure Post Worktree Creation Hook")),
95
- React.createElement(Box, { marginBottom: 1 },
96
- React.createElement(Text, null, "Command to execute after creating a new worktree:")),
97
- React.createElement(Box, { marginBottom: 1 },
98
- React.createElement(TextInputWrapper, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., npm install && npm run build)" })),
99
- React.createElement(Box, { marginBottom: 1 },
100
- React.createElement(Text, null,
101
- "Enabled: ",
102
- currentEnabled ? '✓' : '✗',
103
- " (Press Tab to toggle)")),
104
- React.createElement(Box, { marginTop: 1 },
105
- React.createElement(Text, { dimColor: true }, "Environment variables available: CCMANAGER_WORKTREE_PATH, CCMANAGER_WORKTREE_BRANCH,")),
106
- React.createElement(Box, null,
107
- React.createElement(Text, { dimColor: true }, "CCMANAGER_BASE_BRANCH, CCMANAGER_GIT_ROOT")),
108
- React.createElement(Box, { marginTop: 1 },
109
- React.createElement(Text, { dimColor: true }, "Press Enter to save, Tab to toggle enabled, Esc to cancel"))));
92
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "green", children: "Configure Post Worktree Creation Hook" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Command to execute after creating a new worktree:" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(TextInputWrapper, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., npm install && npm run build)" }) }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: ["Enabled: ", currentEnabled ? '✓' : '✗', " (Press Tab to toggle)"] }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Environment variables available: CCMANAGER_WORKTREE_PATH, CCMANAGER_WORKTREE_BRANCH," }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "CCMANAGER_BASE_BRANCH, CCMANAGER_GIT_ROOT" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Enter to save, Tab to toggle enabled, Esc to cancel" }) })] }));
110
93
  }
111
94
  const scopeLabel = scope === 'project' ? 'Project' : 'Global';
112
- return (React.createElement(Box, { flexDirection: "column" },
113
- React.createElement(Box, { marginBottom: 1 },
114
- React.createElement(Text, { bold: true, color: "green" },
115
- "Configure Worktree Hooks (",
116
- scopeLabel,
117
- ")")),
118
- isInheriting && (React.createElement(Box, { marginBottom: 1 },
119
- React.createElement(Text, { backgroundColor: "cyan", color: "black" },
120
- ' ',
121
- "\uD83D\uDCCB Inheriting from global configuration",
122
- ' '))),
123
- React.createElement(Box, { marginBottom: 1 },
124
- React.createElement(Text, { dimColor: true }, "Set commands to run on worktree events:")),
125
- React.createElement(SelectInput, { items: getMenuItems(), onSelect: handleMenuSelect, isFocused: true, limit: 10 }),
126
- React.createElement(Box, { marginTop: 1 },
127
- React.createElement(Text, { dimColor: true }, "Press Esc to go back"))));
95
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "green", children: ["Configure Worktree Hooks (", 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: "Set commands to run on worktree events:" }) }), _jsx(SelectInput, { items: getMenuItems(), onSelect: handleMenuSelect, isFocused: true, limit: 10 }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Press Esc to go back" }) })] }));
128
96
  };
129
97
  export default ConfigureWorktreeHooks;
@@ -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 ConfigureWorktreeHooks from './ConfigureWorktreeHooks.js';
@@ -31,32 +31,10 @@ const mockFns = {
31
31
  vi.mock('../services/config/configEditor.js', () => {
32
32
  return {
33
33
  ConfigEditor: class {
34
- constructor() {
35
- Object.defineProperty(this, "getWorktreeHooks", {
36
- enumerable: true,
37
- configurable: true,
38
- writable: true,
39
- value: mockFns.getWorktreeHooks
40
- });
41
- Object.defineProperty(this, "setWorktreeHooks", {
42
- enumerable: true,
43
- configurable: true,
44
- writable: true,
45
- value: mockFns.setWorktreeHooks
46
- });
47
- Object.defineProperty(this, "hasProjectOverride", {
48
- enumerable: true,
49
- configurable: true,
50
- writable: true,
51
- value: mockFns.hasProjectOverride
52
- });
53
- Object.defineProperty(this, "getScope", {
54
- enumerable: true,
55
- configurable: true,
56
- writable: true,
57
- value: mockFns.getScope
58
- });
59
- }
34
+ getWorktreeHooks = mockFns.getWorktreeHooks;
35
+ setWorktreeHooks = mockFns.setWorktreeHooks;
36
+ hasProjectOverride = mockFns.hasProjectOverride;
37
+ getScope = mockFns.getScope;
60
38
  },
61
39
  };
62
40
  });
@@ -67,8 +45,7 @@ describe('ConfigureWorktreeHooks', () => {
67
45
  it('should render worktree hooks configuration screen', () => {
68
46
  mockFns.getWorktreeHooks.mockReturnValue({});
69
47
  const onComplete = vi.fn();
70
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
71
- React.createElement(ConfigureWorktreeHooks, { onComplete: onComplete })));
48
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureWorktreeHooks, { onComplete: onComplete }) }));
72
49
  expect(lastFrame()).toContain('Configure Worktree Hooks');
73
50
  expect(lastFrame()).toContain('Set commands to run on worktree events');
74
51
  expect(lastFrame()).toContain('Post Creation:');
@@ -81,15 +58,13 @@ describe('ConfigureWorktreeHooks', () => {
81
58
  },
82
59
  });
83
60
  const onComplete = vi.fn();
84
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
85
- React.createElement(ConfigureWorktreeHooks, { onComplete: onComplete })));
61
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureWorktreeHooks, { onComplete: onComplete }) }));
86
62
  expect(lastFrame()).toContain('Post Creation: ✓ npm install');
87
63
  });
88
64
  it('should display not set when no hook configured', () => {
89
65
  mockFns.getWorktreeHooks.mockReturnValue({});
90
66
  const onComplete = vi.fn();
91
- const { lastFrame } = render(React.createElement(ConfigEditorProvider, { scope: "global" },
92
- React.createElement(ConfigureWorktreeHooks, { onComplete: onComplete })));
67
+ const { lastFrame } = render(_jsx(ConfigEditorProvider, { scope: "global", children: _jsx(ConfigureWorktreeHooks, { onComplete: onComplete }) }));
93
68
  expect(lastFrame()).toContain('Post Creation: ✗ (not set)');
94
69
  });
95
70
  });
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import SelectInput from 'ink-select-input';
4
4
  import { shortcutManager } from '../services/shortcutManager.js';
@@ -25,20 +25,12 @@ const Confirmation = ({ title, message, options, onSelect, initialIndex = 0, ind
25
25
  const handleSelect = (item) => {
26
26
  onSelect(item.value);
27
27
  };
28
- return (React.createElement(Box, { flexDirection: "column" },
29
- title && React.createElement(Box, { marginBottom: 1 }, title),
30
- message && React.createElement(Box, { marginBottom: 1 }, message),
31
- React.createElement(Box, { marginTop: 1 },
32
- React.createElement(SelectInput, { items: options, onSelect: handleSelect, initialIndex: initialIndex, indicatorComponent: ({ isSelected }) => (React.createElement(Text, { color: isSelected && indicatorColor ? indicatorColor : undefined }, isSelected ? '>' : ' ')), itemComponent: ({ isSelected, label }) => {
33
- // Find the color for this option
34
- const option = options.find(opt => opt.label === label);
35
- const color = option?.color;
36
- return (React.createElement(Text, { color: isSelected && color ? color : isSelected ? undefined : 'white', inverse: isSelected },
37
- ' ',
38
- label,
39
- ' '));
40
- } })),
41
- hint && React.createElement(Box, { marginTop: 1 }, hint)));
28
+ return (_jsxs(Box, { flexDirection: "column", children: [title && _jsx(Box, { marginBottom: 1, children: title }), message && _jsx(Box, { marginBottom: 1, children: message }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: options, onSelect: handleSelect, initialIndex: initialIndex, indicatorComponent: ({ isSelected }) => (_jsx(Text, { color: isSelected && indicatorColor ? indicatorColor : undefined, children: isSelected ? '>' : ' ' })), itemComponent: ({ isSelected, label }) => {
29
+ // Find the color for this option
30
+ const option = options.find(opt => opt.label === label);
31
+ const color = option?.color;
32
+ return (_jsxs(Text, { color: isSelected && color ? color : isSelected ? undefined : 'white', inverse: isSelected, children: [' ', label, ' '] }));
33
+ } }) }), hint && _jsx(Box, { marginTop: 1, children: hint })] }));
42
34
  };
43
35
  export default Confirmation;
44
36
  export const SimpleConfirmation = ({ message, onConfirm, onCancel, confirmText = 'Yes', cancelText = 'No', confirmColor = 'green', cancelColor = 'red', }) => {
@@ -54,10 +46,6 @@ export const SimpleConfirmation = ({ message, onConfirm, onCancel, confirmText =
54
46
  onCancel();
55
47
  }
56
48
  };
57
- const hint = (React.createElement(Text, { dimColor: true },
58
- "Use \u2191\u2193/j/k to navigate, Enter to select,",
59
- ' ',
60
- shortcutManager.getShortcutDisplay('cancel'),
61
- " to cancel"));
62
- return (React.createElement(Confirmation, { message: message, options: options, onSelect: handleSelect, initialIndex: 0, hint: hint, onCancel: onCancel }));
49
+ const hint = (_jsxs(Text, { dimColor: true, children: ["Use \u2191\u2193/j/k to navigate, Enter to select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }));
50
+ return (_jsx(Confirmation, { message: message, options: options, onSelect: handleSelect, initialIndex: 0, hint: hint, onCancel: onCancel }));
63
51
  };
@@ -1,10 +1,7 @@
1
- import React from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from 'ink';
3
3
  const CustomCommandSummary = ({ command, }) => {
4
4
  const displayValue = command.trim() ? command : 'Empty';
5
- return (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
6
- React.createElement(Text, null, "Custom auto-approval command:"),
7
- React.createElement(Text, { dimColor: true }, displayValue),
8
- React.createElement(Text, { dimColor: true }, "Env provided: $DEFAULT_PROMPT, $TERMINAL_OUTPUT")));
5
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { children: "Custom auto-approval command:" }), _jsx(Text, { dimColor: true, children: displayValue }), _jsx(Text, { dimColor: true, children: "Env provided: $DEFAULT_PROMPT, $TERMINAL_OUTPUT" })] }));
9
6
  };
10
7
  export default CustomCommandSummary;
@@ -1,4 +1,5 @@
1
- import React, { useState } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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 { shortcutManager } from '../services/shortcutManager.js';
@@ -62,56 +63,18 @@ const DeleteConfirmation = ({ worktrees, onConfirm, onCancel, }) => {
62
63
  }
63
64
  });
64
65
  // Title component
65
- const title = (React.createElement(Text, { bold: true, color: "red" }, "\u26A0\uFE0F Delete Confirmation"));
66
+ const title = (_jsx(Text, { bold: true, color: "red", children: "\u26A0\uFE0F Delete Confirmation" }));
66
67
  // Message component
67
- const message = (React.createElement(Box, { flexDirection: "column" },
68
- React.createElement(Text, null, "You are about to delete the following worktrees:"),
69
- worktrees.length <= 10 ? (worktrees.map(wt => (React.createElement(Text, { key: wt.path, color: "red" },
70
- "\u2022 ",
71
- wt.branch ? wt.branch.replace('refs/heads/', '') : 'detached',
72
- " (",
73
- wt.path,
74
- ")")))) : (React.createElement(React.Fragment, null,
75
- worktrees.slice(0, 8).map(wt => (React.createElement(Text, { key: wt.path, color: "red" },
76
- "\u2022 ",
77
- wt.branch ? wt.branch.replace('refs/heads/', '') : 'detached',
78
- ' ',
79
- "(",
80
- wt.path,
81
- ")"))),
82
- React.createElement(Text, { color: "red", dimColor: true },
83
- "... and ",
84
- worktrees.length - 8,
85
- " more worktrees")))));
68
+ const message = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: "You are about to delete the following worktrees:" }), worktrees.length <= 10 ? (worktrees.map(wt => (_jsxs(Text, { color: "red", children: ["\u2022 ", wt.branch ? wt.branch.replace('refs/heads/', '') : 'detached', " (", wt.path, ")"] }, wt.path)))) : (_jsxs(_Fragment, { children: [worktrees.slice(0, 8).map(wt => (_jsxs(Text, { color: "red", children: ["\u2022 ", wt.branch ? wt.branch.replace('refs/heads/', '') : 'detached', ' ', "(", wt.path, ")"] }, wt.path))), _jsxs(Text, { color: "red", dimColor: true, children: ["... and ", worktrees.length - 8, " more worktrees"] })] }))] }));
86
69
  if (hasAnyBranches && view === 'options') {
87
- return (React.createElement(Box, { flexDirection: "column" },
88
- title,
89
- React.createElement(Box, { marginTop: 1, marginBottom: 1 }, message),
90
- React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
91
- React.createElement(Text, { bold: true }, "What do you want to do with the associated branches?"),
92
- React.createElement(Box, { marginTop: 1 },
93
- React.createElement(SelectInput, { items: branchOptions, onSelect: handleBranchSelect, onHighlight: (item) => {
94
- setFocusedOption(item.value);
95
- }, initialIndex: deleteBranch ? 0 : 1, indicatorComponent: ({ isSelected }) => (React.createElement(Text, { color: isSelected ? 'red' : undefined }, isSelected ? '>' : ' ')), itemComponent: ({ isSelected, label }) => (React.createElement(Text, { color: isSelected ? 'red' : undefined, inverse: isSelected }, label)) }))),
96
- React.createElement(Box, { marginTop: 1 },
97
- React.createElement(Text, { dimColor: true },
98
- "Use \u2191\u2193/j/k to navigate, Space to toggle, Enter to continue,",
99
- ' ',
100
- shortcutManager.getShortcutDisplay('cancel'),
101
- " to cancel"))));
70
+ return (_jsxs(Box, { flexDirection: "column", children: [title, _jsx(Box, { marginTop: 1, marginBottom: 1, children: message }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "What do you want to do with the associated branches?" }), _jsx(Box, { marginTop: 1, children: _jsx(SelectInput, { items: branchOptions, onSelect: handleBranchSelect, onHighlight: (item) => {
71
+ setFocusedOption(item.value);
72
+ }, initialIndex: deleteBranch ? 0 : 1, indicatorComponent: ({ isSelected }) => (_jsx(Text, { color: isSelected ? 'red' : undefined, children: isSelected ? '>' : ' ' })), itemComponent: ({ isSelected, label }) => (_jsx(Text, { color: isSelected ? 'red' : undefined, inverse: isSelected, children: label })) }) })] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Use \u2191\u2193/j/k to navigate, Space to toggle, Enter to continue,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }) })] }));
102
73
  }
103
74
  // Confirmation view (either after selecting branch option or if no branches)
104
- const confirmHint = (React.createElement(Text, { dimColor: true },
105
- "Use \u2191\u2193/j/k to navigate, Enter to select,",
106
- ' ',
107
- shortcutManager.getShortcutDisplay('cancel'),
108
- " to cancel"));
109
- const confirmMessage = (React.createElement(Box, { flexDirection: "column" },
110
- message,
111
- hasAnyBranches && view === 'confirm' && (React.createElement(Box, { marginTop: 1, flexDirection: "column" },
112
- React.createElement(Text, { bold: true }, "Branch option selected:"),
113
- React.createElement(Text, { color: "yellow" }, deleteBranch ? '✓ Delete the branches too' : '✓ Keep the branches')))));
114
- return (React.createElement(Confirmation, { title: title, message: confirmMessage, options: [
75
+ const confirmHint = (_jsxs(Text, { dimColor: true, children: ["Use \u2191\u2193/j/k to navigate, Enter to select,", ' ', shortcutManager.getShortcutDisplay('cancel'), " to cancel"] }));
76
+ const confirmMessage = (_jsxs(Box, { flexDirection: "column", children: [message, hasAnyBranches && view === 'confirm' && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Branch option selected:" }), _jsx(Text, { color: "yellow", children: deleteBranch ? '✓ Delete the branches too' : '✓ Keep the branches' })] }))] }));
77
+ return (_jsx(Confirmation, { title: title, message: confirmMessage, options: [
115
78
  { label: 'Confirm', value: 'confirm', color: 'green' },
116
79
  { label: 'Cancel', value: 'cancel', color: 'red' },
117
80
  ], onSelect: handleActionSelect, initialIndex: 1, hint: confirmHint, onCancel: onCancel, onEscape: hasAnyBranches && view === 'confirm'