ccmanager 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ import React, { useState } from 'react';
2
+ import { Box, Text, useInput } from 'ink';
3
+ import SelectInput from 'ink-select-input';
4
+ import { configurationManager } from '../services/configurationManager.js';
5
+ const PresetSelector = ({ onSelect, onCancel, }) => {
6
+ const presetsConfig = configurationManager.getCommandPresets();
7
+ const [presets] = useState(presetsConfig.presets);
8
+ const defaultPresetId = presetsConfig.defaultPresetId;
9
+ const selectItems = presets.map(preset => {
10
+ const isDefault = preset.id === defaultPresetId;
11
+ const args = preset.args?.join(' ') || '';
12
+ const fallback = preset.fallbackArgs?.join(' ') || '';
13
+ let label = preset.name;
14
+ if (isDefault)
15
+ label += ' (default)';
16
+ label += `\n Command: ${preset.command}`;
17
+ if (args)
18
+ label += `\n Args: ${args}`;
19
+ if (fallback)
20
+ label += `\n Fallback: ${fallback}`;
21
+ return {
22
+ label,
23
+ value: preset.id,
24
+ };
25
+ });
26
+ // Add cancel option
27
+ selectItems.push({ label: '← Cancel', value: 'cancel' });
28
+ const handleSelectItem = (item) => {
29
+ if (item.value === 'cancel') {
30
+ onCancel();
31
+ }
32
+ else {
33
+ onSelect(item.value);
34
+ }
35
+ };
36
+ // Find initial index based on default preset
37
+ const initialIndex = selectItems.findIndex(item => item.value === defaultPresetId);
38
+ useInput((input, key) => {
39
+ if (key.escape) {
40
+ onCancel();
41
+ }
42
+ });
43
+ return (React.createElement(Box, { flexDirection: "column" },
44
+ React.createElement(Box, { marginBottom: 1 },
45
+ React.createElement(Text, { bold: true, color: "green" }, "Select Command Preset")),
46
+ React.createElement(Box, { marginBottom: 1 },
47
+ React.createElement(Text, { dimColor: true }, "Choose a preset to start the session with")),
48
+ React.createElement(SelectInput, { items: selectItems, onSelect: handleSelectItem, initialIndex: initialIndex >= 0 ? initialIndex : 0 }),
49
+ React.createElement(Box, { marginTop: 1 },
50
+ React.createElement(Text, { dimColor: true }, "Press \u2191\u2193 to navigate, Enter to select, ESC to cancel"))));
51
+ };
52
+ export default PresetSelector;
@@ -1,4 +1,4 @@
1
- import { ConfigurationData, StatusHookConfig, ShortcutConfig, WorktreeConfig, CommandConfig } from '../types/index.js';
1
+ import { ConfigurationData, StatusHookConfig, ShortcutConfig, WorktreeConfig, CommandConfig, CommandPreset, CommandPresetsConfig } from '../types/index.js';
2
2
  export declare class ConfigurationManager {
3
3
  private configPath;
4
4
  private legacyShortcutsPath;
@@ -17,5 +17,15 @@ export declare class ConfigurationManager {
17
17
  setWorktreeConfig(worktreeConfig: WorktreeConfig): void;
18
18
  getCommandConfig(): CommandConfig;
19
19
  setCommandConfig(commandConfig: CommandConfig): void;
20
+ private migrateLegacyCommandToPresets;
21
+ getCommandPresets(): CommandPresetsConfig;
22
+ setCommandPresets(presets: CommandPresetsConfig): void;
23
+ getDefaultPreset(): CommandPreset;
24
+ getPresetById(id: string): CommandPreset | undefined;
25
+ addPreset(preset: CommandPreset): void;
26
+ deletePreset(id: string): void;
27
+ setDefaultPreset(id: string): void;
28
+ getSelectPresetOnStart(): boolean;
29
+ setSelectPresetOnStart(enabled: boolean): void;
20
30
  }
21
31
  export declare const configurationManager: ConfigurationManager;
@@ -73,6 +73,8 @@ export class ConfigurationManager {
73
73
  command: 'claude',
74
74
  };
75
75
  }
76
+ // Migrate legacy command config to presets if needed
77
+ this.migrateLegacyCommandToPresets();
76
78
  }
77
79
  migrateLegacyShortcuts() {
78
80
  if (existsSync(this.legacyShortcutsPath)) {
@@ -131,13 +133,119 @@ export class ConfigurationManager {
131
133
  this.saveConfig();
132
134
  }
133
135
  getCommandConfig() {
134
- return (this.config.command || {
135
- command: 'claude',
136
- });
136
+ // For backward compatibility, return the default preset as CommandConfig
137
+ const defaultPreset = this.getDefaultPreset();
138
+ return {
139
+ command: defaultPreset.command,
140
+ args: defaultPreset.args,
141
+ fallbackArgs: defaultPreset.fallbackArgs,
142
+ };
137
143
  }
138
144
  setCommandConfig(commandConfig) {
139
145
  this.config.command = commandConfig;
146
+ // Also update the default preset for backward compatibility
147
+ if (this.config.commandPresets) {
148
+ const defaultPreset = this.config.commandPresets.presets.find(p => p.id === this.config.commandPresets.defaultPresetId);
149
+ if (defaultPreset) {
150
+ defaultPreset.command = commandConfig.command;
151
+ defaultPreset.args = commandConfig.args;
152
+ defaultPreset.fallbackArgs = commandConfig.fallbackArgs;
153
+ }
154
+ }
155
+ this.saveConfig();
156
+ }
157
+ migrateLegacyCommandToPresets() {
158
+ // Only migrate if we have legacy command config but no presets
159
+ if (this.config.command && !this.config.commandPresets) {
160
+ const defaultPreset = {
161
+ id: '1',
162
+ name: 'Main',
163
+ command: this.config.command.command,
164
+ args: this.config.command.args,
165
+ fallbackArgs: this.config.command.fallbackArgs,
166
+ };
167
+ this.config.commandPresets = {
168
+ presets: [defaultPreset],
169
+ defaultPresetId: '1',
170
+ };
171
+ this.saveConfig();
172
+ }
173
+ // Ensure default presets if none exist
174
+ if (!this.config.commandPresets) {
175
+ this.config.commandPresets = {
176
+ presets: [
177
+ {
178
+ id: '1',
179
+ name: 'Main',
180
+ command: 'claude',
181
+ },
182
+ ],
183
+ defaultPresetId: '1',
184
+ };
185
+ }
186
+ }
187
+ getCommandPresets() {
188
+ if (!this.config.commandPresets) {
189
+ this.migrateLegacyCommandToPresets();
190
+ }
191
+ return this.config.commandPresets;
192
+ }
193
+ setCommandPresets(presets) {
194
+ this.config.commandPresets = presets;
140
195
  this.saveConfig();
141
196
  }
197
+ getDefaultPreset() {
198
+ const presets = this.getCommandPresets();
199
+ const defaultPreset = presets.presets.find(p => p.id === presets.defaultPresetId);
200
+ // If default preset not found, return the first one
201
+ return defaultPreset || presets.presets[0];
202
+ }
203
+ getPresetById(id) {
204
+ const presets = this.getCommandPresets();
205
+ return presets.presets.find(p => p.id === id);
206
+ }
207
+ addPreset(preset) {
208
+ const presets = this.getCommandPresets();
209
+ // Replace if exists, otherwise add
210
+ const existingIndex = presets.presets.findIndex(p => p.id === preset.id);
211
+ if (existingIndex >= 0) {
212
+ presets.presets[existingIndex] = preset;
213
+ }
214
+ else {
215
+ presets.presets.push(preset);
216
+ }
217
+ this.setCommandPresets(presets);
218
+ }
219
+ deletePreset(id) {
220
+ const presets = this.getCommandPresets();
221
+ // Don't delete if it's the last preset
222
+ if (presets.presets.length <= 1) {
223
+ return;
224
+ }
225
+ // Remove the preset
226
+ presets.presets = presets.presets.filter(p => p.id !== id);
227
+ // Update default if needed
228
+ if (presets.defaultPresetId === id && presets.presets.length > 0) {
229
+ presets.defaultPresetId = presets.presets[0].id;
230
+ }
231
+ this.setCommandPresets(presets);
232
+ }
233
+ setDefaultPreset(id) {
234
+ const presets = this.getCommandPresets();
235
+ // Only update if preset exists
236
+ if (presets.presets.some(p => p.id === id)) {
237
+ presets.defaultPresetId = id;
238
+ this.setCommandPresets(presets);
239
+ }
240
+ }
241
+ getSelectPresetOnStart() {
242
+ const presets = this.getCommandPresets();
243
+ return presets.selectPresetOnStart ?? false;
244
+ }
245
+ setSelectPresetOnStart(enabled) {
246
+ const presets = this.getCommandPresets();
247
+ presets.selectPresetOnStart = enabled;
248
+ this.setCommandPresets(presets);
249
+ }
142
250
  }
143
251
  export const configurationManager = new ConfigurationManager();
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
+ import { ConfigurationManager } from './configurationManager.js';
4
+ // Mock fs module
5
+ vi.mock('fs', () => ({
6
+ existsSync: vi.fn(),
7
+ mkdirSync: vi.fn(),
8
+ readFileSync: vi.fn(),
9
+ writeFileSync: vi.fn(),
10
+ }));
11
+ // Mock os module
12
+ vi.mock('os', () => ({
13
+ homedir: vi.fn(() => '/home/test'),
14
+ }));
15
+ describe('ConfigurationManager - selectPresetOnStart', () => {
16
+ let configManager;
17
+ let mockConfigData;
18
+ beforeEach(() => {
19
+ // Reset all mocks
20
+ vi.clearAllMocks();
21
+ // Default mock config data
22
+ mockConfigData = {
23
+ shortcuts: {
24
+ returnToMenu: { ctrl: true, key: 'e' },
25
+ cancel: { key: 'escape' },
26
+ },
27
+ commandPresets: {
28
+ presets: [
29
+ {
30
+ id: '1',
31
+ name: 'Main',
32
+ command: 'claude',
33
+ },
34
+ {
35
+ id: '2',
36
+ name: 'Development',
37
+ command: 'claude',
38
+ args: ['--resume'],
39
+ },
40
+ ],
41
+ defaultPresetId: '1',
42
+ },
43
+ };
44
+ // Mock file system operations
45
+ existsSync.mockImplementation((path) => {
46
+ return path.includes('config.json');
47
+ });
48
+ readFileSync.mockImplementation(() => {
49
+ return JSON.stringify(mockConfigData);
50
+ });
51
+ mkdirSync.mockImplementation(() => { });
52
+ writeFileSync.mockImplementation(() => { });
53
+ // Create new instance for each test
54
+ configManager = new ConfigurationManager();
55
+ });
56
+ afterEach(() => {
57
+ vi.resetAllMocks();
58
+ });
59
+ describe('getSelectPresetOnStart', () => {
60
+ it('should return false by default', () => {
61
+ const result = configManager.getSelectPresetOnStart();
62
+ expect(result).toBe(false);
63
+ });
64
+ it('should return true when configured', () => {
65
+ mockConfigData.commandPresets.selectPresetOnStart = true;
66
+ configManager = new ConfigurationManager();
67
+ const result = configManager.getSelectPresetOnStart();
68
+ expect(result).toBe(true);
69
+ });
70
+ it('should return false when explicitly set to false', () => {
71
+ mockConfigData.commandPresets.selectPresetOnStart = false;
72
+ configManager = new ConfigurationManager();
73
+ const result = configManager.getSelectPresetOnStart();
74
+ expect(result).toBe(false);
75
+ });
76
+ });
77
+ describe('setSelectPresetOnStart', () => {
78
+ it('should set selectPresetOnStart to true', () => {
79
+ configManager.setSelectPresetOnStart(true);
80
+ const result = configManager.getSelectPresetOnStart();
81
+ expect(result).toBe(true);
82
+ // Verify that config was saved
83
+ expect(writeFileSync).toHaveBeenCalledWith(expect.stringContaining('config.json'), expect.stringContaining('"selectPresetOnStart": true'));
84
+ });
85
+ it('should set selectPresetOnStart to false', () => {
86
+ // First set to true
87
+ configManager.setSelectPresetOnStart(true);
88
+ // Then set to false
89
+ configManager.setSelectPresetOnStart(false);
90
+ const result = configManager.getSelectPresetOnStart();
91
+ expect(result).toBe(false);
92
+ // Verify that config was saved
93
+ expect(writeFileSync).toHaveBeenLastCalledWith(expect.stringContaining('config.json'), expect.stringContaining('"selectPresetOnStart": false'));
94
+ });
95
+ it('should preserve other preset configuration when setting selectPresetOnStart', () => {
96
+ configManager.setSelectPresetOnStart(true);
97
+ const presets = configManager.getCommandPresets();
98
+ expect(presets.presets).toHaveLength(2);
99
+ expect(presets.defaultPresetId).toBe('1');
100
+ expect(presets.selectPresetOnStart).toBe(true);
101
+ });
102
+ });
103
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,313 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
3
+ import { ConfigurationManager } from './configurationManager.js';
4
+ // Mock fs module
5
+ vi.mock('fs', () => ({
6
+ existsSync: vi.fn(),
7
+ mkdirSync: vi.fn(),
8
+ readFileSync: vi.fn(),
9
+ writeFileSync: vi.fn(),
10
+ }));
11
+ // Mock os module
12
+ vi.mock('os', () => ({
13
+ homedir: vi.fn(() => '/home/test'),
14
+ }));
15
+ describe('ConfigurationManager - Command Presets', () => {
16
+ let configManager;
17
+ let mockConfigData;
18
+ beforeEach(() => {
19
+ // Reset all mocks
20
+ vi.clearAllMocks();
21
+ // Default mock config data
22
+ mockConfigData = {
23
+ shortcuts: {
24
+ returnToMenu: { ctrl: true, key: 'e' },
25
+ cancel: { key: 'escape' },
26
+ },
27
+ command: {
28
+ command: 'claude',
29
+ args: ['--existing'],
30
+ },
31
+ };
32
+ // Mock file system operations
33
+ existsSync.mockImplementation((path) => {
34
+ return path.includes('config.json');
35
+ });
36
+ readFileSync.mockImplementation(() => {
37
+ return JSON.stringify(mockConfigData);
38
+ });
39
+ mkdirSync.mockImplementation(() => { });
40
+ writeFileSync.mockImplementation(() => { });
41
+ // Create new instance for each test
42
+ configManager = new ConfigurationManager();
43
+ });
44
+ afterEach(() => {
45
+ vi.resetAllMocks();
46
+ });
47
+ describe('getCommandPresets', () => {
48
+ it('should return default presets when no presets are configured', () => {
49
+ // Remove command config for this test
50
+ delete mockConfigData.command;
51
+ configManager = new ConfigurationManager();
52
+ const presets = configManager.getCommandPresets();
53
+ expect(presets).toBeDefined();
54
+ expect(presets.presets).toHaveLength(1);
55
+ expect(presets.presets[0]).toEqual({
56
+ id: '1',
57
+ name: 'Main',
58
+ command: 'claude',
59
+ });
60
+ expect(presets.defaultPresetId).toBe('1');
61
+ });
62
+ it('should return configured presets', () => {
63
+ mockConfigData.commandPresets = {
64
+ presets: [
65
+ { id: '1', name: 'Main', command: 'claude' },
66
+ { id: '2', name: 'Development', command: 'claude', args: ['--resume'] },
67
+ ],
68
+ defaultPresetId: '2',
69
+ };
70
+ configManager = new ConfigurationManager();
71
+ const presets = configManager.getCommandPresets();
72
+ expect(presets.presets).toHaveLength(2);
73
+ expect(presets.defaultPresetId).toBe('2');
74
+ });
75
+ it('should migrate legacy command config to presets on first access', () => {
76
+ // Config has legacy command but no presets
77
+ mockConfigData.command = {
78
+ command: 'claude',
79
+ args: ['--resume'],
80
+ fallbackArgs: ['--no-mcp'],
81
+ };
82
+ delete mockConfigData.commandPresets;
83
+ configManager = new ConfigurationManager();
84
+ const presets = configManager.getCommandPresets();
85
+ expect(presets.presets).toHaveLength(1);
86
+ expect(presets.presets[0]).toEqual({
87
+ id: '1',
88
+ name: 'Main',
89
+ command: 'claude',
90
+ args: ['--resume'],
91
+ fallbackArgs: ['--no-mcp'],
92
+ });
93
+ expect(presets.defaultPresetId).toBe('1');
94
+ // Verify that writeFileSync was called to save the migration
95
+ expect(writeFileSync).toHaveBeenCalled();
96
+ });
97
+ });
98
+ describe('setCommandPresets', () => {
99
+ it('should save new presets configuration', () => {
100
+ const newPresets = {
101
+ presets: [
102
+ { id: '1', name: 'Main', command: 'claude' },
103
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
104
+ ],
105
+ defaultPresetId: '2',
106
+ };
107
+ configManager.setCommandPresets(newPresets);
108
+ expect(writeFileSync).toHaveBeenCalledWith(expect.stringContaining('config.json'), expect.stringContaining('commandPresets'));
109
+ });
110
+ });
111
+ describe('getDefaultPreset', () => {
112
+ it('should return the default preset', () => {
113
+ mockConfigData.commandPresets = {
114
+ presets: [
115
+ { id: '1', name: 'Main', command: 'claude' },
116
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
117
+ ],
118
+ defaultPresetId: '2',
119
+ };
120
+ configManager = new ConfigurationManager();
121
+ const defaultPreset = configManager.getDefaultPreset();
122
+ expect(defaultPreset).toEqual({
123
+ id: '2',
124
+ name: 'Custom',
125
+ command: 'claude',
126
+ args: ['--custom'],
127
+ });
128
+ });
129
+ it('should return first preset if defaultPresetId is invalid', () => {
130
+ mockConfigData.commandPresets = {
131
+ presets: [
132
+ { id: '1', name: 'Main', command: 'claude' },
133
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
134
+ ],
135
+ defaultPresetId: 'invalid',
136
+ };
137
+ configManager = new ConfigurationManager();
138
+ const defaultPreset = configManager.getDefaultPreset();
139
+ expect(defaultPreset).toEqual({
140
+ id: '1',
141
+ name: 'Main',
142
+ command: 'claude',
143
+ });
144
+ });
145
+ });
146
+ describe('getPresetById', () => {
147
+ it('should return preset by id', () => {
148
+ mockConfigData.commandPresets = {
149
+ presets: [
150
+ { id: '1', name: 'Main', command: 'claude' },
151
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
152
+ ],
153
+ defaultPresetId: '1',
154
+ };
155
+ configManager = new ConfigurationManager();
156
+ const preset = configManager.getPresetById('2');
157
+ expect(preset).toEqual({
158
+ id: '2',
159
+ name: 'Custom',
160
+ command: 'claude',
161
+ args: ['--custom'],
162
+ });
163
+ });
164
+ it('should return undefined for non-existent id', () => {
165
+ mockConfigData.commandPresets = {
166
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
167
+ defaultPresetId: '1',
168
+ };
169
+ configManager = new ConfigurationManager();
170
+ const preset = configManager.getPresetById('999');
171
+ expect(preset).toBeUndefined();
172
+ });
173
+ });
174
+ describe('addPreset', () => {
175
+ it('should add a new preset', () => {
176
+ mockConfigData.commandPresets = {
177
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
178
+ defaultPresetId: '1',
179
+ };
180
+ configManager = new ConfigurationManager();
181
+ const newPreset = {
182
+ id: '2',
183
+ name: 'New Preset',
184
+ command: 'claude',
185
+ args: ['--new'],
186
+ };
187
+ configManager.addPreset(newPreset);
188
+ const presets = configManager.getCommandPresets();
189
+ expect(presets.presets).toHaveLength(2);
190
+ expect(presets.presets[1]).toEqual(newPreset);
191
+ });
192
+ it('should replace preset with same id', () => {
193
+ mockConfigData.commandPresets = {
194
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
195
+ defaultPresetId: '1',
196
+ };
197
+ configManager = new ConfigurationManager();
198
+ const updatedPreset = {
199
+ id: '1',
200
+ name: 'Updated Default',
201
+ command: 'claude',
202
+ args: ['--updated'],
203
+ };
204
+ configManager.addPreset(updatedPreset);
205
+ const presets = configManager.getCommandPresets();
206
+ expect(presets.presets).toHaveLength(1);
207
+ expect(presets.presets[0]).toEqual(updatedPreset);
208
+ });
209
+ });
210
+ describe('deletePreset', () => {
211
+ it('should delete preset by id', () => {
212
+ mockConfigData.commandPresets = {
213
+ presets: [
214
+ { id: '1', name: 'Main', command: 'claude' },
215
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
216
+ ],
217
+ defaultPresetId: '1',
218
+ };
219
+ configManager = new ConfigurationManager();
220
+ configManager.deletePreset('2');
221
+ const presets = configManager.getCommandPresets();
222
+ expect(presets.presets).toHaveLength(1);
223
+ expect(presets.presets[0].id).toBe('1');
224
+ });
225
+ it('should not delete the last preset', () => {
226
+ mockConfigData.commandPresets = {
227
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
228
+ defaultPresetId: '1',
229
+ };
230
+ configManager = new ConfigurationManager();
231
+ configManager.deletePreset('1');
232
+ const presets = configManager.getCommandPresets();
233
+ expect(presets.presets).toHaveLength(1);
234
+ });
235
+ it('should update defaultPresetId if default preset is deleted', () => {
236
+ mockConfigData.commandPresets = {
237
+ presets: [
238
+ { id: '1', name: 'Main', command: 'claude' },
239
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
240
+ ],
241
+ defaultPresetId: '2',
242
+ };
243
+ configManager = new ConfigurationManager();
244
+ configManager.deletePreset('2');
245
+ const presets = configManager.getCommandPresets();
246
+ expect(presets.defaultPresetId).toBe('1');
247
+ });
248
+ });
249
+ describe('setDefaultPreset', () => {
250
+ it('should update default preset id', () => {
251
+ mockConfigData.commandPresets = {
252
+ presets: [
253
+ { id: '1', name: 'Main', command: 'claude' },
254
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
255
+ ],
256
+ defaultPresetId: '1',
257
+ };
258
+ configManager = new ConfigurationManager();
259
+ configManager.setDefaultPreset('2');
260
+ const presets = configManager.getCommandPresets();
261
+ expect(presets.defaultPresetId).toBe('2');
262
+ });
263
+ it('should not update if preset id does not exist', () => {
264
+ mockConfigData.commandPresets = {
265
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
266
+ defaultPresetId: '1',
267
+ };
268
+ configManager = new ConfigurationManager();
269
+ configManager.setDefaultPreset('999');
270
+ const presets = configManager.getCommandPresets();
271
+ expect(presets.defaultPresetId).toBe('1');
272
+ });
273
+ });
274
+ describe('backward compatibility', () => {
275
+ it('should maintain getCommandConfig for backward compatibility', () => {
276
+ mockConfigData.commandPresets = {
277
+ presets: [
278
+ { id: '1', name: 'Main', command: 'claude', args: ['--resume'] },
279
+ { id: '2', name: 'Custom', command: 'claude', args: ['--custom'] },
280
+ ],
281
+ defaultPresetId: '1',
282
+ };
283
+ configManager = new ConfigurationManager();
284
+ const commandConfig = configManager.getCommandConfig();
285
+ // Should return the default preset as CommandConfig
286
+ expect(commandConfig).toEqual({
287
+ command: 'claude',
288
+ args: ['--resume'],
289
+ });
290
+ });
291
+ it('should update default preset when setCommandConfig is called', () => {
292
+ mockConfigData.commandPresets = {
293
+ presets: [{ id: '1', name: 'Main', command: 'claude' }],
294
+ defaultPresetId: '1',
295
+ };
296
+ configManager = new ConfigurationManager();
297
+ const newConfig = {
298
+ command: 'claude',
299
+ args: ['--new-args'],
300
+ fallbackArgs: ['--new-fallback'],
301
+ };
302
+ configManager.setCommandConfig(newConfig);
303
+ const presets = configManager.getCommandPresets();
304
+ expect(presets.presets[0]).toEqual({
305
+ id: '1',
306
+ name: 'Main',
307
+ command: 'claude',
308
+ args: ['--new-args'],
309
+ fallbackArgs: ['--new-fallback'],
310
+ });
311
+ });
312
+ });
313
+ });
@@ -1,15 +1,14 @@
1
1
  import { Session, SessionManager as ISessionManager, SessionState } from '../types/index.js';
2
2
  import { EventEmitter } from 'events';
3
- import pkg from '@xterm/headless';
4
- declare const Terminal: typeof pkg.Terminal;
5
3
  export declare class SessionManager extends EventEmitter implements ISessionManager {
6
4
  sessions: Map<string, Session>;
7
5
  private waitingWithBottomBorder;
8
6
  private busyTimers;
9
7
  private spawn;
10
- detectTerminalState(terminal: InstanceType<typeof Terminal>): SessionState;
8
+ detectTerminalState(session: Session): SessionState;
11
9
  constructor();
12
10
  createSession(worktreePath: string): Promise<Session>;
11
+ createSessionWithPreset(worktreePath: string, presetId?: string): Promise<Session>;
13
12
  private setupDataHandler;
14
13
  private setupExitHandler;
15
14
  private setupBackgroundHandler;
@@ -21,4 +20,3 @@ export declare class SessionManager extends EventEmitter implements ISessionMana
21
20
  private executeStatusHook;
22
21
  destroy(): void;
23
22
  }
24
- export {};