ccmanager 3.2.4 → 3.2.5
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.
|
@@ -54,6 +54,28 @@ describe('CodexStateDetector', () => {
|
|
|
54
54
|
// Assert
|
|
55
55
|
expect(state).toBe('waiting_input');
|
|
56
56
|
});
|
|
57
|
+
it('should detect waiting_input state for "Press enter to confirm or esc to cancel" pattern', () => {
|
|
58
|
+
// Arrange
|
|
59
|
+
terminal = createMockTerminal([
|
|
60
|
+
'Some output',
|
|
61
|
+
'Press enter to confirm or esc to cancel',
|
|
62
|
+
]);
|
|
63
|
+
// Act
|
|
64
|
+
const state = detector.detectState(terminal, 'idle');
|
|
65
|
+
// Assert
|
|
66
|
+
expect(state).toBe('waiting_input');
|
|
67
|
+
});
|
|
68
|
+
it('should prioritize "Press enter to confirm" over busy state with esc interrupt', () => {
|
|
69
|
+
// Arrange
|
|
70
|
+
terminal = createMockTerminal([
|
|
71
|
+
'esc to interrupt',
|
|
72
|
+
'Press enter to confirm or esc to cancel',
|
|
73
|
+
]);
|
|
74
|
+
// Act
|
|
75
|
+
const state = detector.detectState(terminal, 'idle');
|
|
76
|
+
// Assert
|
|
77
|
+
expect(state).toBe('waiting_input');
|
|
78
|
+
});
|
|
57
79
|
it('should detect busy state for Esc to interrupt pattern', () => {
|
|
58
80
|
// Arrange
|
|
59
81
|
terminal = createMockTerminal([
|
|
@@ -94,4 +116,31 @@ describe('CodexStateDetector', () => {
|
|
|
94
116
|
// Assert
|
|
95
117
|
expect(state).toBe('waiting_input');
|
|
96
118
|
});
|
|
119
|
+
it('should detect waiting_input state for "Confirm with ... Enter" pattern', () => {
|
|
120
|
+
// Arrange
|
|
121
|
+
terminal = createMockTerminal(['Some output', 'Confirm with Y Enter']);
|
|
122
|
+
// Act
|
|
123
|
+
const state = detector.detectState(terminal, 'idle');
|
|
124
|
+
// Assert
|
|
125
|
+
expect(state).toBe('waiting_input');
|
|
126
|
+
});
|
|
127
|
+
it('should detect waiting_input for "Confirm with" pattern with longer text', () => {
|
|
128
|
+
// Arrange
|
|
129
|
+
terminal = createMockTerminal([
|
|
130
|
+
'Some output',
|
|
131
|
+
'Confirm with Shift + Y Enter',
|
|
132
|
+
]);
|
|
133
|
+
// Act
|
|
134
|
+
const state = detector.detectState(terminal, 'idle');
|
|
135
|
+
// Assert
|
|
136
|
+
expect(state).toBe('waiting_input');
|
|
137
|
+
});
|
|
138
|
+
it('should prioritize "Confirm with ... Enter" over busy state', () => {
|
|
139
|
+
// Arrange
|
|
140
|
+
terminal = createMockTerminal(['Esc to interrupt', 'Confirm with Y Enter']);
|
|
141
|
+
// Act
|
|
142
|
+
const state = detector.detectState(terminal, 'idle');
|
|
143
|
+
// Assert
|
|
144
|
+
expect(state).toBe('waiting_input');
|
|
145
|
+
});
|
|
97
146
|
});
|
|
@@ -20,6 +20,18 @@ describe('GeminiStateDetector', () => {
|
|
|
20
20
|
// Assert
|
|
21
21
|
expect(state).toBe('waiting_input');
|
|
22
22
|
});
|
|
23
|
+
it('should detect waiting_input when "Apply this change" prompt is present (without ?)', () => {
|
|
24
|
+
// Arrange
|
|
25
|
+
terminal = createMockTerminal([
|
|
26
|
+
'Some output from Gemini',
|
|
27
|
+
'│ Apply this change',
|
|
28
|
+
'│ > ',
|
|
29
|
+
]);
|
|
30
|
+
// Act
|
|
31
|
+
const state = detector.detectState(terminal, 'idle');
|
|
32
|
+
// Assert
|
|
33
|
+
expect(state).toBe('waiting_input');
|
|
34
|
+
});
|
|
23
35
|
it('should detect waiting_input when "Allow execution?" prompt is present', () => {
|
|
24
36
|
// Arrange
|
|
25
37
|
terminal = createMockTerminal([
|
|
@@ -32,6 +44,18 @@ describe('GeminiStateDetector', () => {
|
|
|
32
44
|
// Assert
|
|
33
45
|
expect(state).toBe('waiting_input');
|
|
34
46
|
});
|
|
47
|
+
it('should detect waiting_input when "Allow execution" prompt is present (without ?)', () => {
|
|
48
|
+
// Arrange
|
|
49
|
+
terminal = createMockTerminal([
|
|
50
|
+
'Command found: npm install',
|
|
51
|
+
'│ Allow execution',
|
|
52
|
+
'│ > ',
|
|
53
|
+
]);
|
|
54
|
+
// Act
|
|
55
|
+
const state = detector.detectState(terminal, 'idle');
|
|
56
|
+
// Assert
|
|
57
|
+
expect(state).toBe('waiting_input');
|
|
58
|
+
});
|
|
35
59
|
it('should detect waiting_input when "Do you want to proceed?" prompt is present', () => {
|
|
36
60
|
// Arrange
|
|
37
61
|
terminal = createMockTerminal([
|
|
@@ -44,6 +68,40 @@ describe('GeminiStateDetector', () => {
|
|
|
44
68
|
// Assert
|
|
45
69
|
expect(state).toBe('waiting_input');
|
|
46
70
|
});
|
|
71
|
+
it('should detect waiting_input when "Do you want to proceed" prompt is present (without ?)', () => {
|
|
72
|
+
// Arrange
|
|
73
|
+
terminal = createMockTerminal([
|
|
74
|
+
'Changes detected',
|
|
75
|
+
'│ Do you want to proceed',
|
|
76
|
+
'│ > ',
|
|
77
|
+
]);
|
|
78
|
+
// Act
|
|
79
|
+
const state = detector.detectState(terminal, 'idle');
|
|
80
|
+
// Assert
|
|
81
|
+
expect(state).toBe('waiting_input');
|
|
82
|
+
});
|
|
83
|
+
it('should detect waiting_input when "Waiting for user confirmation..." is present', () => {
|
|
84
|
+
// Arrange
|
|
85
|
+
terminal = createMockTerminal([
|
|
86
|
+
'Processing...',
|
|
87
|
+
'Waiting for user confirmation...',
|
|
88
|
+
]);
|
|
89
|
+
// Act
|
|
90
|
+
const state = detector.detectState(terminal, 'idle');
|
|
91
|
+
// Assert
|
|
92
|
+
expect(state).toBe('waiting_input');
|
|
93
|
+
});
|
|
94
|
+
it('should prioritize "Waiting for user confirmation" over busy state', () => {
|
|
95
|
+
// Arrange
|
|
96
|
+
terminal = createMockTerminal([
|
|
97
|
+
'Press ESC to cancel',
|
|
98
|
+
'Waiting for user confirmation...',
|
|
99
|
+
]);
|
|
100
|
+
// Act
|
|
101
|
+
const state = detector.detectState(terminal, 'idle');
|
|
102
|
+
// Assert
|
|
103
|
+
expect(state).toBe('waiting_input');
|
|
104
|
+
});
|
|
47
105
|
it('should detect waiting_input for multiline confirmation ending with "yes"', () => {
|
|
48
106
|
// Arrange
|
|
49
107
|
terminal = createMockTerminal([
|
|
@@ -19,6 +19,36 @@ describe('GitHubCopilotStateDetector', () => {
|
|
|
19
19
|
// Assert
|
|
20
20
|
expect(state).toBe('waiting_input');
|
|
21
21
|
});
|
|
22
|
+
it('detects waiting_input when "Confirm with ... Enter" pattern is present', () => {
|
|
23
|
+
// Arrange
|
|
24
|
+
terminal = createMockTerminal(['Some output', 'Confirm with Y Enter']);
|
|
25
|
+
// Act
|
|
26
|
+
const state = detector.detectState(terminal, 'idle');
|
|
27
|
+
// Assert
|
|
28
|
+
expect(state).toBe('waiting_input');
|
|
29
|
+
});
|
|
30
|
+
it('detects waiting_input for "Confirm with" pattern with longer text', () => {
|
|
31
|
+
// Arrange
|
|
32
|
+
terminal = createMockTerminal([
|
|
33
|
+
'Some output',
|
|
34
|
+
'Confirm with Shift + Y Enter',
|
|
35
|
+
]);
|
|
36
|
+
// Act
|
|
37
|
+
const state = detector.detectState(terminal, 'idle');
|
|
38
|
+
// Assert
|
|
39
|
+
expect(state).toBe('waiting_input');
|
|
40
|
+
});
|
|
41
|
+
it('prioritizes "Confirm with ... Enter" over busy state', () => {
|
|
42
|
+
// Arrange
|
|
43
|
+
terminal = createMockTerminal([
|
|
44
|
+
'Press Esc to cancel',
|
|
45
|
+
'Confirm with Y Enter',
|
|
46
|
+
]);
|
|
47
|
+
// Act
|
|
48
|
+
const state = detector.detectState(terminal, 'idle');
|
|
49
|
+
// Assert
|
|
50
|
+
expect(state).toBe('waiting_input');
|
|
51
|
+
});
|
|
22
52
|
it('detects busy when "Esc to cancel" is present', () => {
|
|
23
53
|
// Arrange
|
|
24
54
|
terminal = createMockTerminal([
|
|
@@ -63,10 +63,14 @@ export class GeminiStateDetector extends BaseStateDetector {
|
|
|
63
63
|
detectState(terminal, _currentState) {
|
|
64
64
|
const content = this.getTerminalContent(terminal);
|
|
65
65
|
const lowerContent = content.toLowerCase();
|
|
66
|
+
// Check for explicit user confirmation message - highest priority
|
|
67
|
+
if (lowerContent.includes('waiting for user confirmation')) {
|
|
68
|
+
return 'waiting_input';
|
|
69
|
+
}
|
|
66
70
|
// Check for waiting prompts with box character
|
|
67
|
-
if (content.includes('│ Apply this change
|
|
68
|
-
content.includes('│ Allow execution
|
|
69
|
-
content.includes('│ Do you want to proceed
|
|
71
|
+
if (content.includes('│ Apply this change') ||
|
|
72
|
+
content.includes('│ Allow execution') ||
|
|
73
|
+
content.includes('│ Do you want to proceed')) {
|
|
70
74
|
return 'waiting_input';
|
|
71
75
|
}
|
|
72
76
|
// Check for multiline confirmation prompts ending with "yes"
|
|
@@ -85,6 +89,11 @@ export class CodexStateDetector extends BaseStateDetector {
|
|
|
85
89
|
detectState(terminal, _currentState) {
|
|
86
90
|
const content = this.getTerminalContent(terminal);
|
|
87
91
|
const lowerContent = content.toLowerCase();
|
|
92
|
+
// Check for confirmation prompt patterns - highest priority
|
|
93
|
+
if (lowerContent.includes('press enter to confirm or esc to cancel') ||
|
|
94
|
+
/confirm with .+ enter/i.test(content)) {
|
|
95
|
+
return 'waiting_input';
|
|
96
|
+
}
|
|
88
97
|
// Check for waiting prompts
|
|
89
98
|
if (lowerContent.includes('allow command?') ||
|
|
90
99
|
lowerContent.includes('[y/n]') ||
|
|
@@ -124,15 +133,19 @@ export class GitHubCopilotStateDetector extends BaseStateDetector {
|
|
|
124
133
|
detectState(terminal, _currentState) {
|
|
125
134
|
const content = this.getTerminalContent(terminal);
|
|
126
135
|
const lowerContent = content.toLowerCase();
|
|
127
|
-
//
|
|
136
|
+
// Check for confirmation prompt pattern - highest priority
|
|
137
|
+
if (/confirm with .+ enter/i.test(content)) {
|
|
138
|
+
return 'waiting_input';
|
|
139
|
+
}
|
|
140
|
+
// Waiting prompt has priority 2
|
|
128
141
|
if (lowerContent.includes('│ do you want')) {
|
|
129
142
|
return 'waiting_input';
|
|
130
143
|
}
|
|
131
|
-
// Busy state detection has priority
|
|
144
|
+
// Busy state detection has priority 3
|
|
132
145
|
if (lowerContent.includes('esc to cancel')) {
|
|
133
146
|
return 'busy';
|
|
134
147
|
}
|
|
135
|
-
// Otherwise idle as priority
|
|
148
|
+
// Otherwise idle as priority 4
|
|
136
149
|
return 'idle';
|
|
137
150
|
}
|
|
138
151
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccmanager",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.5",
|
|
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": "3.2.
|
|
45
|
-
"@kodaikabasawa/ccmanager-darwin-x64": "3.2.
|
|
46
|
-
"@kodaikabasawa/ccmanager-linux-arm64": "3.2.
|
|
47
|
-
"@kodaikabasawa/ccmanager-linux-x64": "3.2.
|
|
48
|
-
"@kodaikabasawa/ccmanager-win32-x64": "3.2.
|
|
44
|
+
"@kodaikabasawa/ccmanager-darwin-arm64": "3.2.5",
|
|
45
|
+
"@kodaikabasawa/ccmanager-darwin-x64": "3.2.5",
|
|
46
|
+
"@kodaikabasawa/ccmanager-linux-arm64": "3.2.5",
|
|
47
|
+
"@kodaikabasawa/ccmanager-linux-x64": "3.2.5",
|
|
48
|
+
"@kodaikabasawa/ccmanager-win32-x64": "3.2.5"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@eslint/js": "^9.28.0",
|