ccmanager 4.1.14 → 4.1.15

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.
@@ -37,9 +37,8 @@ const ConfigureMerge = ({ onComplete }) => {
37
37
  onComplete();
38
38
  return;
39
39
  }
40
- const field = item.value;
41
- setEditField(field);
42
- switch (field) {
40
+ setEditField(item.value);
41
+ switch (item.value) {
43
42
  case 'mergeArgs':
44
43
  setInputValue(getMergeArgs().join(' '));
45
44
  break;
@@ -442,7 +442,12 @@ const Dashboard = ({ projectsDir, onSelectSession, onSelectProject, error, onDis
442
442
  });
443
443
  }
444
444
  };
445
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, flexDirection: "column", children: _jsxs(Text, { bold: true, color: "green", children: ["CCManager - Dashboard v", version] }) }), loading ? (_jsx(Box, { children: _jsx(Text, { color: "yellow", children: "Discovering projects..." }) })) : projects.length === 0 && !displayError ? (_jsx(Box, { children: _jsxs(Text, { color: "yellow", children: ["No git repositories found in ", projectsDir] }) })) : (_jsx(SearchableList, { isSearchMode: isSearchMode, searchQuery: searchQuery, onSearchQueryChange: setSearchQuery, selectedIndex: selectedIndex, items: items, limit: limit, placeholder: "Type to filter...", noMatchMessage: "No matches found", children: _jsx(SelectInput, { items: items, onSelect: item => handleSelect(item), isFocused: !displayError, limit: limit, initialIndex: selectedIndex }) })), displayError && (_jsx(Box, { marginTop: 1, paddingX: 1, borderStyle: "round", borderColor: "red", children: _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", bold: true, children: ["Error: ", displayError] }), _jsx(Text, { color: "gray", dimColor: true, children: "Press any key to dismiss" })] }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["Status: ", STATUS_ICONS.BUSY, " ", STATUS_LABELS.BUSY, ' ', STATUS_ICONS.WAITING, " ", STATUS_LABELS.WAITING, " ", STATUS_ICONS.IDLE, ' ', STATUS_LABELS.IDLE] }), _jsx(Text, { dimColor: true, children: isSearchMode
445
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, flexDirection: "column", children: _jsxs(Text, { bold: true, color: "green", children: ["CCManager - Dashboard v", version] }) }), loading ? (_jsx(Box, { children: _jsx(Text, { color: "yellow", children: "Discovering projects..." }) })) : projects.length === 0 && !displayError ? (_jsx(Box, { children: _jsxs(Text, { color: "yellow", children: ["No git repositories found in ", projectsDir] }) })) : (_jsx(SearchableList, { isSearchMode: isSearchMode, searchQuery: searchQuery, onSearchQueryChange: setSearchQuery, selectedIndex: selectedIndex, items: items, limit: limit, placeholder: "Type to filter...", noMatchMessage: "No matches found", children: _jsx(SelectInput, { items: items, onSelect: raw => {
446
+ const item = items.find(i => i.value === raw?.value);
447
+ if (!item)
448
+ return;
449
+ handleSelect(item);
450
+ }, isFocused: !displayError, limit: limit, initialIndex: selectedIndex }) })), displayError && (_jsx(Box, { marginTop: 1, paddingX: 1, borderStyle: "round", borderColor: "red", children: _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", bold: true, children: ["Error: ", displayError] }), _jsx(Text, { color: "gray", dimColor: true, children: "Press any key to dismiss" })] }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["Status: ", STATUS_ICONS.BUSY, " ", STATUS_LABELS.BUSY, ' ', STATUS_ICONS.WAITING, " ", STATUS_LABELS.WAITING, " ", STATUS_ICONS.IDLE, ' ', STATUS_LABELS.IDLE] }), _jsx(Text, { dimColor: true, children: isSearchMode
446
451
  ? 'Search Mode: Type to filter, Enter to exit search, ESC to exit search'
447
452
  : searchQuery
448
453
  ? `Filtered: "${searchQuery}" | ↑↓ Navigate Enter Select | /-Search ESC-Clear 0-9 Quick Select R-Refresh Q-Quit`
@@ -430,16 +430,18 @@ const Menu = ({ sessionManager, worktreeService, onMenuAction, onSelectRecentPro
430
430
  });
431
431
  }
432
432
  };
433
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsxs(Text, { bold: true, color: "green", children: ["CCManager - Claude Code Worktree Manager v", version] }), projectName && (_jsx(Text, { bold: true, color: "green", children: projectName }))] }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Select a worktree to start or resume a Claude Code session:" }) }), _jsx(SearchableList, { isSearchMode: isSearchMode, searchQuery: searchQuery, onSearchQueryChange: setSearchQuery, selectedIndex: selectedIndex, items: items, limit: limit, placeholder: "Type to filter worktrees...", noMatchMessage: "No worktrees match your search", children: _jsx(SelectInput, { items: items, onSelect: item => handleSelect(item), onHighlight: item => {
434
- // ink-select-input may call onHighlight with undefined when items are empty
435
- // (e.g., during menu re-mount after returning from a session), so guard it.
436
- if (!item) {
433
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsxs(Text, { bold: true, color: "green", children: ["CCManager - Claude Code Worktree Manager v", version] }), projectName && (_jsx(Text, { bold: true, color: "green", children: projectName }))] }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Select a worktree to start or resume a Claude Code session:" }) }), _jsx(SearchableList, { isSearchMode: isSearchMode, searchQuery: searchQuery, onSearchQueryChange: setSearchQuery, selectedIndex: selectedIndex, items: items, limit: limit, placeholder: "Type to filter worktrees...", noMatchMessage: "No worktrees match your search", children: _jsx(SelectInput, { items: items, onSelect: raw => {
434
+ const item = items.find(i => i.value === raw?.value);
435
+ if (!item)
437
436
  return;
438
- }
439
- const menuItem = item;
440
- if (menuItem.type === 'worktree') {
441
- setHighlightedWorktreePath(menuItem.worktree.path);
442
- setHighlightedSession(menuItem.session);
437
+ handleSelect(item);
438
+ }, onHighlight: raw => {
439
+ const item = items.find(i => i.value === raw?.value);
440
+ if (!item)
441
+ return;
442
+ if (item.type === 'worktree') {
443
+ setHighlightedWorktreePath(item.worktree.path);
444
+ setHighlightedSession(item.session);
443
445
  }
444
446
  }, isFocused: !error, initialIndex: selectedIndex, limit: limit }) }), (error || loadError) && (_jsx(Box, { marginTop: 1, paddingX: 1, borderStyle: "round", borderColor: "red", children: _jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", bold: true, children: ["Error: ", error || loadError] }), _jsx(Text, { color: "gray", dimColor: true, children: "Press any key to dismiss" })] }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["Status: ", STATUS_ICONS.BUSY, " ", STATUS_LABELS.BUSY, ' ', STATUS_ICONS.WAITING, " ", STATUS_LABELS.WAITING, " ", STATUS_ICONS.IDLE, ' ', STATUS_LABELS.IDLE, configReader.isAutoApprovalEnabled() && (_jsxs(_Fragment, { children: [' | ', _jsx(Text, { color: "green", children: "Auto Approval Enabled" })] }))] }), _jsx(Text, { dimColor: true, children: isSearchMode
445
447
  ? 'Search Mode: Type to filter, Enter to exit search, ESC to exit search'
@@ -566,7 +566,7 @@ export class AutoApprovalVerifier {
566
566
  : await this.runClaudePrompt(prompt, jsonSchema, signal);
567
567
  return JSON.parse(responseText);
568
568
  },
569
- catch: (error) => error,
569
+ catch: (error) => error instanceof Error ? error : new Error(String(error)),
570
570
  });
571
571
  return Effect.catchAll(attemptVerification, (error) => {
572
572
  if (error.name === 'AbortError') {
@@ -183,7 +183,10 @@ export class ProjectManager {
183
183
  }
184
184
  catch (error) {
185
185
  // Silently skip directories we can't read
186
- if (error.code !== 'EACCES') {
186
+ if (!(typeof error === 'object' &&
187
+ error !== null &&
188
+ 'code' in error &&
189
+ error.code === 'EACCES')) {
187
190
  console.error(`Error scanning directory ${dir}:`, error);
188
191
  }
189
192
  }
@@ -267,7 +270,7 @@ export class ProjectManager {
267
270
  }
268
271
  }
269
272
  catch (error) {
270
- result.error = `Failed to process: ${error.message}`;
273
+ result.error = `Failed to process: ${error instanceof Error ? error.message : String(error)}`;
271
274
  }
272
275
  return result;
273
276
  }
@@ -363,8 +366,11 @@ export class ProjectManager {
363
366
  if (error instanceof FileSystemError) {
364
367
  return error;
365
368
  }
366
- const nodeError = error;
367
- const cause = nodeError.code === 'ENOENT'
369
+ const isEnoent = typeof error === 'object' &&
370
+ error !== null &&
371
+ 'code' in error &&
372
+ error.code === 'ENOENT';
373
+ const cause = isEnoent
368
374
  ? `Projects directory does not exist: ${projectsDir}`
369
375
  : String(error);
370
376
  return new FileSystemError({
@@ -144,7 +144,7 @@ export class SessionManager extends EventEmitter {
144
144
  })
145
145
  .catch(async (error) => {
146
146
  if (abortController.signal.aborted) {
147
- logger.debug(`[${session.id}] Auto-approval verification aborted (${error?.message ?? 'aborted'})`);
147
+ logger.debug(`[${session.id}] Auto-approval verification aborted (${error instanceof Error ? error.message : 'aborted'})`);
148
148
  return;
149
149
  }
150
150
  // On failure, fall back to requiring explicit permission
@@ -153,8 +153,9 @@ export class SessionManager extends EventEmitter {
153
153
  if (currentState === 'pending_auto_approval') {
154
154
  await this.updateSessionState(session, 'waiting_input', {
155
155
  autoApprovalFailed: true,
156
- autoApprovalReason: error?.message ??
157
- 'Auto-approval verification failed',
156
+ autoApprovalReason: error instanceof Error
157
+ ? error.message
158
+ : 'Auto-approval verification failed',
158
159
  });
159
160
  }
160
161
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccmanager",
3
- "version": "4.1.14",
3
+ "version": "4.1.15",
4
4
  "description": "TUI application for managing multiple Claude Code sessions across Git worktrees",
5
5
  "license": "MIT",
6
6
  "author": "Kodai Kabasawa",
@@ -41,11 +41,11 @@
41
41
  "bin"
42
42
  ],
43
43
  "optionalDependencies": {
44
- "@kodaikabasawa/ccmanager-darwin-arm64": "4.1.14",
45
- "@kodaikabasawa/ccmanager-darwin-x64": "4.1.14",
46
- "@kodaikabasawa/ccmanager-linux-arm64": "4.1.14",
47
- "@kodaikabasawa/ccmanager-linux-x64": "4.1.14",
48
- "@kodaikabasawa/ccmanager-win32-x64": "4.1.14"
44
+ "@kodaikabasawa/ccmanager-darwin-arm64": "4.1.15",
45
+ "@kodaikabasawa/ccmanager-darwin-x64": "4.1.15",
46
+ "@kodaikabasawa/ccmanager-linux-arm64": "4.1.15",
47
+ "@kodaikabasawa/ccmanager-linux-x64": "4.1.15",
48
+ "@kodaikabasawa/ccmanager-win32-x64": "4.1.15"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@eslint/js": "^9.28.0",