claude-issue-solver 1.43.1 → 1.43.3
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/utils/helpers.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ export declare function checkRequirements(): {
|
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* Generate AppleScript for opening a script in iTerm2.
|
|
8
|
+
* Changes to the script's directory first so the session path matches the worktree.
|
|
8
9
|
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
9
10
|
*/
|
|
10
11
|
export declare function generateITermOpenScript(script: string): string;
|
|
11
12
|
/**
|
|
12
13
|
* Generate AppleScript for opening a script in Terminal.app.
|
|
14
|
+
* Changes to the script's directory first so the session path matches the worktree.
|
|
13
15
|
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
14
16
|
*/
|
|
15
17
|
export declare function generateTerminalOpenScript(script: string): string;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -75,11 +75,16 @@ function checkRequirements() {
|
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Generate AppleScript for opening a script in iTerm2.
|
|
78
|
+
* Changes to the script's directory first so the session path matches the worktree.
|
|
78
79
|
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
79
80
|
*/
|
|
80
81
|
function generateITermOpenScript(script) {
|
|
81
82
|
const escapedScript = script.replace(/"/g, '\\"');
|
|
82
|
-
|
|
83
|
+
// Extract directory from script path to set as working directory
|
|
84
|
+
const scriptDir = path.dirname(script.replace(/'/g, ''));
|
|
85
|
+
const escapedDir = scriptDir.replace(/"/g, '\\"');
|
|
86
|
+
// cd to the script's directory first, so session path matches worktree
|
|
87
|
+
const bashCommand = `cd "${escapedDir}" && /bin/bash "${escapedScript}"`;
|
|
83
88
|
return `
|
|
84
89
|
tell application "iTerm"
|
|
85
90
|
activate
|
|
@@ -94,11 +99,16 @@ function generateITermOpenScript(script) {
|
|
|
94
99
|
}
|
|
95
100
|
/**
|
|
96
101
|
* Generate AppleScript for opening a script in Terminal.app.
|
|
102
|
+
* Changes to the script's directory first so the session path matches the worktree.
|
|
97
103
|
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
98
104
|
*/
|
|
99
105
|
function generateTerminalOpenScript(script) {
|
|
100
106
|
const escapedScript = script.replace(/"/g, '\\"');
|
|
101
|
-
|
|
107
|
+
// Extract directory from script path to set as working directory
|
|
108
|
+
const scriptDir = path.dirname(script.replace(/'/g, ''));
|
|
109
|
+
const escapedDir = scriptDir.replace(/"/g, '\\"');
|
|
110
|
+
// cd to the script's directory first, so session path matches worktree
|
|
111
|
+
const bashCommand = `cd "${escapedDir}" && /bin/bash "${escapedScript}"`;
|
|
102
112
|
return `
|
|
103
113
|
tell application "Terminal"
|
|
104
114
|
activate
|
|
@@ -99,4 +99,24 @@ const helpers_1 = require("./helpers");
|
|
|
99
99
|
(0, vitest_1.expect)(script).toMatch(/do script "n;.*\/bin\/bash/);
|
|
100
100
|
});
|
|
101
101
|
});
|
|
102
|
+
(0, vitest_1.describe)('working directory for terminal closing', () => {
|
|
103
|
+
(0, vitest_1.it)('iTerm script should cd to script directory before running', () => {
|
|
104
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/worktree/.claude-runner.sh');
|
|
105
|
+
// Should cd to the script's directory first (quotes are escaped in AppleScript)
|
|
106
|
+
(0, vitest_1.expect)(script).toContain('cd \\"/path/to/worktree\\"');
|
|
107
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
108
|
+
});
|
|
109
|
+
(0, vitest_1.it)('Terminal script should cd to script directory before running', () => {
|
|
110
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/to/worktree/.claude-runner.sh');
|
|
111
|
+
// Should cd to the script's directory first (quotes are escaped in AppleScript)
|
|
112
|
+
(0, vitest_1.expect)(script).toContain('cd \\"/path/to/worktree\\"');
|
|
113
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.it)('should handle script paths with quotes', () => {
|
|
116
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/work"tree/.script.sh');
|
|
117
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
118
|
+
// Path should be escaped
|
|
119
|
+
(0, vitest_1.expect)(script).toContain('work');
|
|
120
|
+
});
|
|
121
|
+
});
|
|
102
122
|
});
|
package/dist/utils/terminal.d.ts
CHANGED
|
@@ -25,6 +25,14 @@ export declare function generateVSCodeCloseScript(patterns: string[]): string;
|
|
|
25
25
|
* Execute AppleScript and handle errors gracefully
|
|
26
26
|
*/
|
|
27
27
|
export declare function executeAppleScript(script: string, timeout?: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Find TTYs associated with processes in the given directory
|
|
30
|
+
*/
|
|
31
|
+
export declare function findTTYsInDirectory(dirPath: string): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Generate AppleScript to close iTerm2 windows by TTY
|
|
34
|
+
*/
|
|
35
|
+
export declare function generateITermCloseByTTYScript(ttys: string[]): string;
|
|
28
36
|
/**
|
|
29
37
|
* Find and terminate shell processes running in the given directory
|
|
30
38
|
* This is a fallback approach when AppleScript matching fails
|
package/dist/utils/terminal.js
CHANGED
|
@@ -38,6 +38,8 @@ exports.generateITermCloseScript = generateITermCloseScript;
|
|
|
38
38
|
exports.generateTerminalCloseScript = generateTerminalCloseScript;
|
|
39
39
|
exports.generateVSCodeCloseScript = generateVSCodeCloseScript;
|
|
40
40
|
exports.executeAppleScript = executeAppleScript;
|
|
41
|
+
exports.findTTYsInDirectory = findTTYsInDirectory;
|
|
42
|
+
exports.generateITermCloseByTTYScript = generateITermCloseByTTYScript;
|
|
41
43
|
exports.killProcessesInDirectory = killProcessesInDirectory;
|
|
42
44
|
exports.closeWindowsForWorktree = closeWindowsForWorktree;
|
|
43
45
|
const child_process_1 = require("child_process");
|
|
@@ -208,6 +210,84 @@ function executeAppleScript(script, timeout = 5000) {
|
|
|
208
210
|
return false;
|
|
209
211
|
}
|
|
210
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Find TTYs associated with processes in the given directory
|
|
215
|
+
*/
|
|
216
|
+
function findTTYsInDirectory(dirPath) {
|
|
217
|
+
if (os.platform() !== 'darwin' && os.platform() !== 'linux') {
|
|
218
|
+
return [];
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
// Use lsof to find processes with files open in the directory
|
|
222
|
+
const output = (0, child_process_1.execSync)(`lsof +D "${dirPath}" 2>/dev/null || true`, {
|
|
223
|
+
encoding: 'utf8',
|
|
224
|
+
timeout: 5000,
|
|
225
|
+
});
|
|
226
|
+
if (!output.trim()) {
|
|
227
|
+
return [];
|
|
228
|
+
}
|
|
229
|
+
// Parse lsof output to get TTYs
|
|
230
|
+
const lines = output.split('\n').slice(1); // Skip header
|
|
231
|
+
const ttys = new Set();
|
|
232
|
+
for (const line of lines) {
|
|
233
|
+
const parts = line.split(/\s+/);
|
|
234
|
+
// lsof output: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
|
|
235
|
+
// We want to find the FD column that shows the tty
|
|
236
|
+
if (parts.length >= 9) {
|
|
237
|
+
const fd = parts[3];
|
|
238
|
+
const type = parts[4];
|
|
239
|
+
const name = parts[8];
|
|
240
|
+
// Look for tty file descriptors
|
|
241
|
+
if ((fd === '0u' || fd === '1u' || fd === '2u') && name.startsWith('/dev/ttys')) {
|
|
242
|
+
ttys.add(name);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return Array.from(ttys);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return [];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Generate AppleScript to close iTerm2 windows by TTY
|
|
254
|
+
*/
|
|
255
|
+
function generateITermCloseByTTYScript(ttys) {
|
|
256
|
+
if (ttys.length === 0)
|
|
257
|
+
return '';
|
|
258
|
+
const ttyConditions = ttys.map(tty => `tty of s is "${tty}"`).join(' or ');
|
|
259
|
+
return `
|
|
260
|
+
tell application "iTerm"
|
|
261
|
+
set windowsToClose to {}
|
|
262
|
+
|
|
263
|
+
repeat with w in windows
|
|
264
|
+
set windowId to id of w
|
|
265
|
+
repeat with t in tabs of w
|
|
266
|
+
repeat with s in sessions of t
|
|
267
|
+
try
|
|
268
|
+
if ${ttyConditions} then
|
|
269
|
+
if windowsToClose does not contain windowId then
|
|
270
|
+
set end of windowsToClose to windowId
|
|
271
|
+
end if
|
|
272
|
+
end if
|
|
273
|
+
end try
|
|
274
|
+
end repeat
|
|
275
|
+
end repeat
|
|
276
|
+
end repeat
|
|
277
|
+
|
|
278
|
+
repeat with targetWindowId in windowsToClose
|
|
279
|
+
try
|
|
280
|
+
repeat with w in windows
|
|
281
|
+
if id of w is targetWindowId then
|
|
282
|
+
close w
|
|
283
|
+
exit repeat
|
|
284
|
+
end if
|
|
285
|
+
end repeat
|
|
286
|
+
end try
|
|
287
|
+
end repeat
|
|
288
|
+
end tell
|
|
289
|
+
`;
|
|
290
|
+
}
|
|
211
291
|
/**
|
|
212
292
|
* Find and terminate shell processes running in the given directory
|
|
213
293
|
* This is a fallback approach when AppleScript matching fails
|
|
@@ -264,10 +344,21 @@ function closeWindowsForWorktree(options) {
|
|
|
264
344
|
return { iTerm: false, terminal: false, vscode: false, processes: false };
|
|
265
345
|
}
|
|
266
346
|
const patterns = getSearchPatterns(options);
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
347
|
+
// First, find TTYs associated with processes in the worktree
|
|
348
|
+
// This is the most reliable way to identify the terminal
|
|
349
|
+
const ttys = findTTYsInDirectory(options.folderPath);
|
|
350
|
+
let iTermResult = false;
|
|
351
|
+
// Try to close iTerm2 by TTY first (most reliable)
|
|
352
|
+
if (ttys.length > 0) {
|
|
353
|
+
const iTermTTYScript = generateITermCloseByTTYScript(ttys);
|
|
354
|
+
iTermResult = executeAppleScript(iTermTTYScript);
|
|
355
|
+
}
|
|
356
|
+
// Fall back to pattern-based matching if TTY approach didn't work
|
|
357
|
+
if (!iTermResult) {
|
|
358
|
+
const iTermScript = generateITermCloseScript(patterns);
|
|
359
|
+
iTermResult = executeAppleScript(iTermScript);
|
|
360
|
+
}
|
|
361
|
+
// Try to close Terminal.app windows (pattern-based)
|
|
271
362
|
const terminalScript = generateTerminalCloseScript(patterns);
|
|
272
363
|
const terminalResult = executeAppleScript(terminalScript);
|
|
273
364
|
// Try to close VS Code windows
|
|
@@ -218,4 +218,30 @@ const terminal_1 = require("./terminal");
|
|
|
218
218
|
(0, vitest_1.expect)(typeof result).toBe('boolean');
|
|
219
219
|
});
|
|
220
220
|
});
|
|
221
|
+
(0, vitest_1.describe)('findTTYsInDirectory', () => {
|
|
222
|
+
(0, vitest_1.it)('should return empty array for non-existent directory', () => {
|
|
223
|
+
const result = (0, terminal_1.findTTYsInDirectory)('/nonexistent/path/that/does/not/exist');
|
|
224
|
+
(0, vitest_1.expect)(result).toEqual([]);
|
|
225
|
+
});
|
|
226
|
+
(0, vitest_1.it)('should return array', () => {
|
|
227
|
+
const result = (0, terminal_1.findTTYsInDirectory)('/tmp');
|
|
228
|
+
(0, vitest_1.expect)(Array.isArray(result)).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
(0, vitest_1.describe)('generateITermCloseByTTYScript', () => {
|
|
232
|
+
(0, vitest_1.it)('should return empty string for empty TTY array', () => {
|
|
233
|
+
const script = (0, terminal_1.generateITermCloseByTTYScript)([]);
|
|
234
|
+
(0, vitest_1.expect)(script).toBe('');
|
|
235
|
+
});
|
|
236
|
+
(0, vitest_1.it)('should generate valid AppleScript for single TTY', () => {
|
|
237
|
+
const script = (0, terminal_1.generateITermCloseByTTYScript)(['/dev/ttys001']);
|
|
238
|
+
(0, vitest_1.expect)(script).toContain('tell application "iTerm"');
|
|
239
|
+
(0, vitest_1.expect)(script).toContain('tty of s is "/dev/ttys001"');
|
|
240
|
+
(0, vitest_1.expect)(script).toContain('close w');
|
|
241
|
+
});
|
|
242
|
+
(0, vitest_1.it)('should generate OR conditions for multiple TTYs', () => {
|
|
243
|
+
const script = (0, terminal_1.generateITermCloseByTTYScript)(['/dev/ttys001', '/dev/ttys002']);
|
|
244
|
+
(0, vitest_1.expect)(script).toContain('tty of s is "/dev/ttys001" or tty of s is "/dev/ttys002"');
|
|
245
|
+
});
|
|
246
|
+
});
|
|
221
247
|
});
|