ccmanager 1.4.1 → 1.4.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.
- package/dist/components/ConfigureCommand.js +3 -3
- package/dist/components/ConfigureHooks.js +2 -2
- package/dist/components/ConfigureWorktree.js +2 -2
- package/dist/components/NewWorktree.js +4 -4
- package/dist/components/TextInputWrapper.d.ts +13 -0
- package/dist/components/TextInputWrapper.js +15 -0
- package/dist/utils/worktreeUtils.js +1 -2
- package/package.json +3 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Box, Text, useInput } from 'ink';
|
|
3
|
-
import
|
|
3
|
+
import TextInputWrapper from './TextInputWrapper.js';
|
|
4
4
|
import SelectInput from 'ink-select-input';
|
|
5
5
|
import { configurationManager } from '../services/configurationManager.js';
|
|
6
6
|
import { shortcutManager } from '../services/shortcutManager.js';
|
|
@@ -294,7 +294,7 @@ const ConfigureCommand = ({ onComplete }) => {
|
|
|
294
294
|
errorMessage && (React.createElement(Box, { marginBottom: 1 },
|
|
295
295
|
React.createElement(Text, { color: "red" }, errorMessage))),
|
|
296
296
|
React.createElement(Box, null,
|
|
297
|
-
React.createElement(
|
|
297
|
+
React.createElement(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleFieldUpdate, placeholder: editField === 'args' || editField === 'fallbackArgs'
|
|
298
298
|
? 'e.g., --resume or leave empty'
|
|
299
299
|
: '' })),
|
|
300
300
|
React.createElement(Box, { marginTop: 1 },
|
|
@@ -339,7 +339,7 @@ const ConfigureCommand = ({ onComplete }) => {
|
|
|
339
339
|
errorMessage && (React.createElement(Box, { marginBottom: 1 },
|
|
340
340
|
React.createElement(Text, { color: "red" }, errorMessage))),
|
|
341
341
|
React.createElement(Box, null,
|
|
342
|
-
React.createElement(
|
|
342
|
+
React.createElement(TextInputWrapper, { value: inputValue, onChange: setInputValue, onSubmit: handleAddPresetInput, placeholder: addStep === 'args' || addStep === 'fallbackArgs'
|
|
343
343
|
? 'e.g., --resume or leave empty'
|
|
344
344
|
: addStep === 'name'
|
|
345
345
|
? 'e.g., Development'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { Box, Text, useInput } from 'ink';
|
|
3
|
-
import
|
|
3
|
+
import TextInputWrapper from './TextInputWrapper.js';
|
|
4
4
|
import SelectInput from 'ink-select-input';
|
|
5
5
|
import { configurationManager } from '../services/configurationManager.js';
|
|
6
6
|
const STATUS_LABELS = {
|
|
@@ -108,7 +108,7 @@ const ConfigureHooks = ({ onComplete }) => {
|
|
|
108
108
|
STATUS_LABELS[selectedStatus],
|
|
109
109
|
":")),
|
|
110
110
|
React.createElement(Box, { marginBottom: 1 },
|
|
111
|
-
React.createElement(
|
|
111
|
+
React.createElement(TextInputWrapper, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., notify-send 'Claude is idle')" })),
|
|
112
112
|
React.createElement(Box, { marginBottom: 1 },
|
|
113
113
|
React.createElement(Text, null,
|
|
114
114
|
"Enabled: ",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { Box, Text, useInput } from 'ink';
|
|
3
3
|
import SelectInput from 'ink-select-input';
|
|
4
|
-
import
|
|
4
|
+
import TextInputWrapper from './TextInputWrapper.js';
|
|
5
5
|
import { configurationManager } from '../services/configurationManager.js';
|
|
6
6
|
import { shortcutManager } from '../services/shortcutManager.js';
|
|
7
7
|
const ConfigureWorktree = ({ onComplete }) => {
|
|
@@ -84,7 +84,7 @@ const ConfigureWorktree = ({ onComplete }) => {
|
|
|
84
84
|
" - full branch name")),
|
|
85
85
|
React.createElement(Box, null,
|
|
86
86
|
React.createElement(Text, { color: "cyan" }, '> '),
|
|
87
|
-
React.createElement(
|
|
87
|
+
React.createElement(TextInputWrapper, { value: tempPattern, onChange: setTempPattern, onSubmit: handlePatternSubmit, placeholder: "../{branch}" })),
|
|
88
88
|
React.createElement(Box, { marginTop: 1 },
|
|
89
89
|
React.createElement(Text, { dimColor: true }, "Press Enter to save or Escape to cancel"))));
|
|
90
90
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useMemo } from 'react';
|
|
2
2
|
import { Box, Text, useInput } from 'ink';
|
|
3
|
-
import
|
|
3
|
+
import TextInputWrapper from './TextInputWrapper.js';
|
|
4
4
|
import SelectInput from 'ink-select-input';
|
|
5
5
|
import { shortcutManager } from '../services/shortcutManager.js';
|
|
6
6
|
import { configurationManager } from '../services/configurationManager.js';
|
|
@@ -84,7 +84,7 @@ const NewWorktree = ({ onComplete, onCancel }) => {
|
|
|
84
84
|
React.createElement(Text, null, "Enter worktree path (relative to repository root):")),
|
|
85
85
|
React.createElement(Box, null,
|
|
86
86
|
React.createElement(Text, { color: "cyan" }, '> '),
|
|
87
|
-
React.createElement(
|
|
87
|
+
React.createElement(TextInputWrapper, { value: path, onChange: setPath, onSubmit: handlePathSubmit, placeholder: "e.g., ../myproject-feature" })))) : step === 'branch' && !isAutoDirectory ? (React.createElement(Box, { flexDirection: "column" },
|
|
88
88
|
React.createElement(Box, { marginBottom: 1 },
|
|
89
89
|
React.createElement(Text, null,
|
|
90
90
|
"Enter branch name for worktree at ",
|
|
@@ -92,12 +92,12 @@ const NewWorktree = ({ onComplete, onCancel }) => {
|
|
|
92
92
|
":")),
|
|
93
93
|
React.createElement(Box, null,
|
|
94
94
|
React.createElement(Text, { color: "cyan" }, '> '),
|
|
95
|
-
React.createElement(
|
|
95
|
+
React.createElement(TextInputWrapper, { value: branch, onChange: setBranch, onSubmit: handleBranchSubmit, placeholder: "e.g., feature/new-feature" })))) : step === 'branch' ? (React.createElement(Box, { flexDirection: "column" },
|
|
96
96
|
React.createElement(Box, { marginBottom: 1 },
|
|
97
97
|
React.createElement(Text, null, "Enter branch name (directory will be auto-generated):")),
|
|
98
98
|
React.createElement(Box, null,
|
|
99
99
|
React.createElement(Text, { color: "cyan" }, '> '),
|
|
100
|
-
React.createElement(
|
|
100
|
+
React.createElement(TextInputWrapper, { value: branch, onChange: setBranch, onSubmit: handleBranchSubmit, placeholder: "e.g., feature/new-feature" })),
|
|
101
101
|
generatedPath && (React.createElement(Box, { marginTop: 1 },
|
|
102
102
|
React.createElement(Text, { dimColor: true },
|
|
103
103
|
"Worktree will be created at:",
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface TextInputWrapperProps {
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (value: string) => void;
|
|
5
|
+
onSubmit?: (value: string) => void;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
focus?: boolean;
|
|
8
|
+
mask?: string;
|
|
9
|
+
showCursor?: boolean;
|
|
10
|
+
highlightPastedText?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const TextInputWrapper: React.FC<TextInputWrapperProps>;
|
|
13
|
+
export default TextInputWrapper;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import TextInput from 'ink-text-input';
|
|
3
|
+
import stripAnsi from 'strip-ansi';
|
|
4
|
+
const TextInputWrapper = ({ value, onChange, ...props }) => {
|
|
5
|
+
const handleChange = (newValue) => {
|
|
6
|
+
// First strip all ANSI escape sequences
|
|
7
|
+
let cleanedValue = stripAnsi(newValue);
|
|
8
|
+
// Then specifically remove bracketed paste mode markers that might remain
|
|
9
|
+
// These sometimes appear as literal text after ANSI stripping
|
|
10
|
+
cleanedValue = cleanedValue.replace(/\[200~/g, '').replace(/\[201~/g, '');
|
|
11
|
+
onChange(cleanedValue);
|
|
12
|
+
};
|
|
13
|
+
return React.createElement(TextInput, { value: value, onChange: handleChange, ...props });
|
|
14
|
+
};
|
|
15
|
+
export default TextInputWrapper;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
import stripAnsi from 'strip-ansi';
|
|
2
3
|
import { getStatusDisplay } from '../constants/statusIcons.js';
|
|
3
4
|
import { formatGitFileChanges, formatGitAheadBehind, formatParentBranch, } from './gitStatus.js';
|
|
4
5
|
// Constants
|
|
5
6
|
const MAX_BRANCH_NAME_LENGTH = 40; // Maximum characters for branch name display
|
|
6
7
|
const MIN_COLUMN_PADDING = 2; // Minimum spaces between columns
|
|
7
|
-
// Strip ANSI escape codes for length calculation
|
|
8
|
-
const stripAnsi = (str) => str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
9
8
|
// Utility function to truncate strings with ellipsis
|
|
10
9
|
export function truncateString(str, maxLength) {
|
|
11
10
|
if (str.length <= maxLength)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccmanager",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "TUI application for managing multiple Claude Code sessions across Git worktrees",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kodai Kabasawa",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"ink-text-input": "^5.0.1",
|
|
46
46
|
"meow": "^11.0.0",
|
|
47
47
|
"node-pty": "^1.0.0",
|
|
48
|
-
"react": "^18.2.0"
|
|
48
|
+
"react": "^18.2.0",
|
|
49
|
+
"strip-ansi": "^7.1.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "^9.28.0",
|