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.
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from 'react';
2
2
  import { Box, Text, useInput } from 'ink';
3
- import TextInput from 'ink-text-input';
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(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleFieldUpdate, placeholder: editField === 'args' || editField === 'fallbackArgs'
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(TextInput, { value: inputValue, onChange: setInputValue, onSubmit: handleAddPresetInput, placeholder: addStep === 'args' || addStep === 'fallbackArgs'
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 TextInput from 'ink-text-input';
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(TextInput, { value: currentCommand, onChange: setCurrentCommand, onSubmit: handleCommandSubmit, placeholder: "Enter command (e.g., notify-send 'Claude is idle')" })),
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 TextInput from 'ink-text-input';
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(TextInput, { value: tempPattern, onChange: setTempPattern, onSubmit: handlePatternSubmit, placeholder: "../{branch}" })),
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 TextInput from 'ink-text-input';
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(TextInput, { value: path, onChange: setPath, onSubmit: handlePathSubmit, placeholder: "e.g., ../myproject-feature" })))) : step === 'branch' && !isAutoDirectory ? (React.createElement(Box, { flexDirection: "column" },
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(TextInput, { value: branch, onChange: setBranch, onSubmit: handleBranchSubmit, placeholder: "e.g., feature/new-feature" })))) : step === 'branch' ? (React.createElement(Box, { flexDirection: "column" },
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(TextInput, { value: branch, onChange: setBranch, onSubmit: handleBranchSubmit, placeholder: "e.g., feature/new-feature" })),
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.1",
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",