claude-issue-solver 1.42.1 → 1.43.0
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 +10 -0
- package/dist/utils/helpers.js +26 -12
- package/dist/utils/helpers.test.d.ts +1 -0
- package/dist/utils/helpers.test.js +102 -0
- package/dist/utils/terminal.d.ts +7 -0
- package/dist/utils/terminal.js +65 -2
- package/dist/utils/terminal.test.js +34 -1
- package/package.json +1 -1
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -3,6 +3,16 @@ export declare function checkRequirements(): {
|
|
|
3
3
|
ok: boolean;
|
|
4
4
|
missing: string[];
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* Generate AppleScript for opening a script in iTerm2.
|
|
8
|
+
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateITermOpenScript(script: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Generate AppleScript for opening a script in Terminal.app.
|
|
13
|
+
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateTerminalOpenScript(script: string): string;
|
|
6
16
|
export declare function openInNewTerminal(script: string): void;
|
|
7
17
|
export declare function copyEnvFiles(from: string, to: string): void;
|
|
8
18
|
export declare function symlinkNodeModules(from: string, to: string): void;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.slugify = slugify;
|
|
37
37
|
exports.checkRequirements = checkRequirements;
|
|
38
|
+
exports.generateITermOpenScript = generateITermOpenScript;
|
|
39
|
+
exports.generateTerminalOpenScript = generateTerminalOpenScript;
|
|
38
40
|
exports.openInNewTerminal = openInNewTerminal;
|
|
39
41
|
exports.copyEnvFiles = copyEnvFiles;
|
|
40
42
|
exports.symlinkNodeModules = symlinkNodeModules;
|
|
@@ -71,16 +73,14 @@ function checkRequirements() {
|
|
|
71
73
|
}
|
|
72
74
|
return { ok: missing.length === 0, missing };
|
|
73
75
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// For iTerm: send 'n' to dismiss any prompt, wait briefly, then run the command
|
|
83
|
-
const iTermScript = `
|
|
76
|
+
/**
|
|
77
|
+
* Generate AppleScript for opening a script in iTerm2.
|
|
78
|
+
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
79
|
+
*/
|
|
80
|
+
function generateITermOpenScript(script) {
|
|
81
|
+
const escapedScript = script.replace(/"/g, '\\"');
|
|
82
|
+
const bashCommand = `/bin/bash "${escapedScript}"`;
|
|
83
|
+
return `
|
|
84
84
|
tell application "iTerm"
|
|
85
85
|
activate
|
|
86
86
|
set newWindow to (create window with default profile)
|
|
@@ -91,13 +91,27 @@ function openInNewTerminal(script) {
|
|
|
91
91
|
end tell
|
|
92
92
|
end tell
|
|
93
93
|
`;
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Generate AppleScript for opening a script in Terminal.app.
|
|
97
|
+
* Sends 'n' first to dismiss any oh-my-zsh update prompts, then runs the script with bash.
|
|
98
|
+
*/
|
|
99
|
+
function generateTerminalOpenScript(script) {
|
|
100
|
+
const escapedScript = script.replace(/"/g, '\\"');
|
|
101
|
+
const bashCommand = `/bin/bash "${escapedScript}"`;
|
|
102
|
+
return `
|
|
96
103
|
tell application "Terminal"
|
|
97
104
|
activate
|
|
98
105
|
do script "n; ${bashCommand.replace(/"/g, '\\"')}"
|
|
99
106
|
end tell
|
|
100
107
|
`;
|
|
108
|
+
}
|
|
109
|
+
function openInNewTerminal(script) {
|
|
110
|
+
const platform = os.platform();
|
|
111
|
+
if (platform === 'darwin') {
|
|
112
|
+
// macOS - try iTerm2 first, then Terminal
|
|
113
|
+
const iTermScript = generateITermOpenScript(script);
|
|
114
|
+
const terminalScript = generateTerminalOpenScript(script);
|
|
101
115
|
try {
|
|
102
116
|
// Check if iTerm is installed
|
|
103
117
|
if (fs.existsSync('/Applications/iTerm.app')) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
(0, vitest_1.describe)('helpers utilities', () => {
|
|
6
|
+
(0, vitest_1.describe)('slugify', () => {
|
|
7
|
+
(0, vitest_1.it)('should convert text to lowercase slug', () => {
|
|
8
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)('Hello World')).toBe('hello-world');
|
|
9
|
+
});
|
|
10
|
+
(0, vitest_1.it)('should remove brackets prefix', () => {
|
|
11
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)('[Bug] Fix login issue')).toBe('fix-login-issue');
|
|
12
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)('[FAQ] How to reset password')).toBe('how-to-reset-password');
|
|
13
|
+
});
|
|
14
|
+
(0, vitest_1.it)('should remove special characters', () => {
|
|
15
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)('Fix: issue #123!')).toBe('fix-issue-123');
|
|
16
|
+
});
|
|
17
|
+
(0, vitest_1.it)('should remove duplicate consecutive words', () => {
|
|
18
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)('[FAQ] FAQ question')).toBe('faq-question');
|
|
19
|
+
});
|
|
20
|
+
(0, vitest_1.it)('should limit slug to 30 characters', () => {
|
|
21
|
+
const longTitle = 'This is a very long issue title that should be truncated';
|
|
22
|
+
(0, vitest_1.expect)((0, helpers_1.slugify)(longTitle).length).toBeLessThanOrEqual(30);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
(0, vitest_1.describe)('generateITermOpenScript', () => {
|
|
26
|
+
(0, vitest_1.it)('should generate valid AppleScript for iTerm', () => {
|
|
27
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/script.sh');
|
|
28
|
+
(0, vitest_1.expect)(script).toContain('tell application "iTerm"');
|
|
29
|
+
(0, vitest_1.expect)(script).toContain('create window with default profile');
|
|
30
|
+
(0, vitest_1.expect)(script).toContain('write text');
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)('should send "n" to dismiss oh-my-zsh update prompts', () => {
|
|
33
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/script.sh');
|
|
34
|
+
(0, vitest_1.expect)(script).toContain('write text "n"');
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.it)('should include delay after dismissing prompt', () => {
|
|
37
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/script.sh');
|
|
38
|
+
(0, vitest_1.expect)(script).toContain('delay 0.3');
|
|
39
|
+
});
|
|
40
|
+
(0, vitest_1.it)('should use /bin/bash to run the script', () => {
|
|
41
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/script.sh');
|
|
42
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
43
|
+
(0, vitest_1.expect)(script).toContain('/path/to/script.sh');
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)('should handle double quotes in script path without breaking AppleScript', () => {
|
|
46
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/to/"quoted"/script.sh');
|
|
47
|
+
// Should still contain the path and be valid AppleScript structure
|
|
48
|
+
(0, vitest_1.expect)(script).toContain('tell application "iTerm"');
|
|
49
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
50
|
+
(0, vitest_1.expect)(script).toContain('quoted');
|
|
51
|
+
});
|
|
52
|
+
(0, vitest_1.it)('should handle paths with spaces', () => {
|
|
53
|
+
const script = (0, helpers_1.generateITermOpenScript)('/path/with spaces/script.sh');
|
|
54
|
+
(0, vitest_1.expect)(script).toContain('/path/with spaces/script.sh');
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
(0, vitest_1.describe)('generateTerminalOpenScript', () => {
|
|
58
|
+
(0, vitest_1.it)('should generate valid AppleScript for Terminal.app', () => {
|
|
59
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/to/script.sh');
|
|
60
|
+
(0, vitest_1.expect)(script).toContain('tell application "Terminal"');
|
|
61
|
+
(0, vitest_1.expect)(script).toContain('do script');
|
|
62
|
+
});
|
|
63
|
+
(0, vitest_1.it)('should send "n" to dismiss oh-my-zsh update prompts', () => {
|
|
64
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/to/script.sh');
|
|
65
|
+
(0, vitest_1.expect)(script).toContain('n;');
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.it)('should use /bin/bash to run the script', () => {
|
|
68
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/to/script.sh');
|
|
69
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
70
|
+
(0, vitest_1.expect)(script).toContain('/path/to/script.sh');
|
|
71
|
+
});
|
|
72
|
+
(0, vitest_1.it)('should handle double quotes in script path without breaking AppleScript', () => {
|
|
73
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/to/"quoted"/script.sh');
|
|
74
|
+
// Should still contain the path and be valid AppleScript structure
|
|
75
|
+
(0, vitest_1.expect)(script).toContain('tell application "Terminal"');
|
|
76
|
+
(0, vitest_1.expect)(script).toContain('/bin/bash');
|
|
77
|
+
(0, vitest_1.expect)(script).toContain('quoted');
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.it)('should handle paths with spaces', () => {
|
|
80
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/path/with spaces/script.sh');
|
|
81
|
+
(0, vitest_1.expect)(script).toContain('/path/with spaces/script.sh');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
(0, vitest_1.describe)('oh-my-zsh bypass behavior', () => {
|
|
85
|
+
(0, vitest_1.it)('iTerm script should have prompt dismissal before command execution', () => {
|
|
86
|
+
const script = (0, helpers_1.generateITermOpenScript)('/test/script.sh');
|
|
87
|
+
const lines = script.split('\n');
|
|
88
|
+
// Find the indices of the relevant lines
|
|
89
|
+
const dismissIndex = lines.findIndex(line => line.includes('write text "n"'));
|
|
90
|
+
const commandIndex = lines.findIndex(line => line.includes('/bin/bash'));
|
|
91
|
+
// Dismissal should come before command
|
|
92
|
+
(0, vitest_1.expect)(dismissIndex).toBeGreaterThan(-1);
|
|
93
|
+
(0, vitest_1.expect)(commandIndex).toBeGreaterThan(-1);
|
|
94
|
+
(0, vitest_1.expect)(dismissIndex).toBeLessThan(commandIndex);
|
|
95
|
+
});
|
|
96
|
+
(0, vitest_1.it)('Terminal script should combine dismiss and command in single do script', () => {
|
|
97
|
+
const script = (0, helpers_1.generateTerminalOpenScript)('/test/script.sh');
|
|
98
|
+
// Should have "n; /bin/bash..." in a single do script call
|
|
99
|
+
(0, vitest_1.expect)(script).toMatch(/do script "n;.*\/bin\/bash/);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
package/dist/utils/terminal.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export declare function getSearchPatterns(options: CloseTerminalOptions): string
|
|
|
10
10
|
/**
|
|
11
11
|
* Generate AppleScript to close iTerm2 windows/tabs matching patterns
|
|
12
12
|
* Uses a two-pass approach: first collect IDs, then close them
|
|
13
|
+
* Matches both window names AND session working directories for reliability
|
|
13
14
|
*/
|
|
14
15
|
export declare function generateITermCloseScript(patterns: string[]): string;
|
|
15
16
|
/**
|
|
@@ -24,6 +25,11 @@ export declare function generateVSCodeCloseScript(patterns: string[]): string;
|
|
|
24
25
|
* Execute AppleScript and handle errors gracefully
|
|
25
26
|
*/
|
|
26
27
|
export declare function executeAppleScript(script: string, timeout?: number): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Find and terminate shell processes running in the given directory
|
|
30
|
+
* This is a fallback approach when AppleScript matching fails
|
|
31
|
+
*/
|
|
32
|
+
export declare function killProcessesInDirectory(dirPath: string): boolean;
|
|
27
33
|
/**
|
|
28
34
|
* Close terminal windows and VS Code windows associated with a worktree
|
|
29
35
|
* Returns an object indicating which applications had windows closed
|
|
@@ -32,4 +38,5 @@ export declare function closeWindowsForWorktree(options: CloseTerminalOptions):
|
|
|
32
38
|
iTerm: boolean;
|
|
33
39
|
terminal: boolean;
|
|
34
40
|
vscode: boolean;
|
|
41
|
+
processes: boolean;
|
|
35
42
|
};
|
package/dist/utils/terminal.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.generateITermCloseScript = generateITermCloseScript;
|
|
|
38
38
|
exports.generateTerminalCloseScript = generateTerminalCloseScript;
|
|
39
39
|
exports.generateVSCodeCloseScript = generateVSCodeCloseScript;
|
|
40
40
|
exports.executeAppleScript = executeAppleScript;
|
|
41
|
+
exports.killProcessesInDirectory = killProcessesInDirectory;
|
|
41
42
|
exports.closeWindowsForWorktree = closeWindowsForWorktree;
|
|
42
43
|
const child_process_1 = require("child_process");
|
|
43
44
|
const os = __importStar(require("os"));
|
|
@@ -48,6 +49,10 @@ function getSearchPatterns(options) {
|
|
|
48
49
|
const { folderPath, issueNumber, prNumber } = options;
|
|
49
50
|
const folderName = folderPath.split('/').pop() || '';
|
|
50
51
|
const patterns = [];
|
|
52
|
+
// Full folder path (most reliable for working directory matching)
|
|
53
|
+
if (folderPath) {
|
|
54
|
+
patterns.push(folderPath);
|
|
55
|
+
}
|
|
51
56
|
// Folder name pattern (e.g., "project-issue-38-slug")
|
|
52
57
|
if (folderName) {
|
|
53
58
|
patterns.push(folderName);
|
|
@@ -66,6 +71,7 @@ function getSearchPatterns(options) {
|
|
|
66
71
|
/**
|
|
67
72
|
* Generate AppleScript to close iTerm2 windows/tabs matching patterns
|
|
68
73
|
* Uses a two-pass approach: first collect IDs, then close them
|
|
74
|
+
* Matches both window names AND session working directories for reliability
|
|
69
75
|
*/
|
|
70
76
|
function generateITermCloseScript(patterns) {
|
|
71
77
|
// Escape patterns for AppleScript string comparison
|
|
@@ -83,13 +89,20 @@ tell application "iTerm"
|
|
|
83
89
|
${escapedPatterns.map((p) => `if windowName contains "${p}" then set end of windowsToClose to windowId`).join('\n ')}
|
|
84
90
|
end try
|
|
85
91
|
|
|
86
|
-
-- Check tabs and sessions
|
|
92
|
+
-- Check tabs and sessions - match by name OR working directory path
|
|
87
93
|
repeat with t in tabs of w
|
|
88
94
|
repeat with s in sessions of t
|
|
89
95
|
try
|
|
90
96
|
set sessionName to name of s
|
|
97
|
+
set sessionPath to ""
|
|
98
|
+
try
|
|
99
|
+
set sessionPath to path of s
|
|
100
|
+
end try
|
|
91
101
|
set sessionId to unique id of s
|
|
102
|
+
-- Match by session name
|
|
92
103
|
${escapedPatterns.map((p) => `if sessionName contains "${p}" then set end of sessionsToClose to {windowId, sessionId}`).join('\n ')}
|
|
104
|
+
-- Match by working directory path (more reliable)
|
|
105
|
+
${escapedPatterns.map((p) => `if sessionPath contains "${p}" then set end of sessionsToClose to {windowId, sessionId}`).join('\n ')}
|
|
93
106
|
end try
|
|
94
107
|
end repeat
|
|
95
108
|
end repeat
|
|
@@ -214,13 +227,60 @@ function executeAppleScript(script, timeout = 5000) {
|
|
|
214
227
|
return false;
|
|
215
228
|
}
|
|
216
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Find and terminate shell processes running in the given directory
|
|
232
|
+
* This is a fallback approach when AppleScript matching fails
|
|
233
|
+
*/
|
|
234
|
+
function killProcessesInDirectory(dirPath) {
|
|
235
|
+
if (os.platform() !== 'darwin' && os.platform() !== 'linux') {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
// Use lsof to find processes with their current working directory in the target path
|
|
240
|
+
// +D flag finds processes with files open in the directory (including cwd)
|
|
241
|
+
const output = (0, child_process_1.execSync)(`lsof +D "${dirPath}" 2>/dev/null || true`, {
|
|
242
|
+
encoding: 'utf8',
|
|
243
|
+
timeout: 5000,
|
|
244
|
+
});
|
|
245
|
+
if (!output.trim()) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
// Parse lsof output to get PIDs of shell processes
|
|
249
|
+
const lines = output.split('\n').slice(1); // Skip header
|
|
250
|
+
const pids = new Set();
|
|
251
|
+
for (const line of lines) {
|
|
252
|
+
const parts = line.split(/\s+/);
|
|
253
|
+
if (parts.length >= 2) {
|
|
254
|
+
const command = parts[0].toLowerCase();
|
|
255
|
+
const pid = parts[1];
|
|
256
|
+
// Only kill shell processes and their children, not system processes
|
|
257
|
+
if (['bash', 'zsh', 'sh', 'fish', 'claude', 'node'].some(s => command.includes(s))) {
|
|
258
|
+
pids.add(pid);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Send SIGTERM to each process
|
|
263
|
+
for (const pid of pids) {
|
|
264
|
+
try {
|
|
265
|
+
(0, child_process_1.execSync)(`kill -TERM ${pid} 2>/dev/null || true`, { stdio: 'pipe' });
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Process may have already exited
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return pids.size > 0;
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
217
277
|
/**
|
|
218
278
|
* Close terminal windows and VS Code windows associated with a worktree
|
|
219
279
|
* Returns an object indicating which applications had windows closed
|
|
220
280
|
*/
|
|
221
281
|
function closeWindowsForWorktree(options) {
|
|
222
282
|
if (os.platform() !== 'darwin') {
|
|
223
|
-
return { iTerm: false, terminal: false, vscode: false };
|
|
283
|
+
return { iTerm: false, terminal: false, vscode: false, processes: false };
|
|
224
284
|
}
|
|
225
285
|
const patterns = getSearchPatterns(options);
|
|
226
286
|
// Try to close iTerm2 windows/sessions
|
|
@@ -232,9 +292,12 @@ function closeWindowsForWorktree(options) {
|
|
|
232
292
|
// Try to close VS Code windows
|
|
233
293
|
const vscodeScript = generateVSCodeCloseScript(patterns);
|
|
234
294
|
const vscodeResult = executeAppleScript(vscodeScript, 10000);
|
|
295
|
+
// Fallback: kill processes running in the worktree directory
|
|
296
|
+
const processResult = killProcessesInDirectory(options.folderPath);
|
|
235
297
|
return {
|
|
236
298
|
iTerm: iTermResult,
|
|
237
299
|
terminal: terminalResult,
|
|
238
300
|
vscode: vscodeResult,
|
|
301
|
+
processes: processResult,
|
|
239
302
|
};
|
|
240
303
|
}
|
|
@@ -10,10 +10,21 @@ const terminal_1 = require("./terminal");
|
|
|
10
10
|
issueNumber: '42',
|
|
11
11
|
};
|
|
12
12
|
const patterns = (0, terminal_1.getSearchPatterns)(options);
|
|
13
|
+
// Should include full path for working directory matching
|
|
14
|
+
(0, vitest_1.expect)(patterns).toContain('/Users/test/project-issue-42-fix-bug');
|
|
13
15
|
(0, vitest_1.expect)(patterns).toContain('project-issue-42-fix-bug');
|
|
14
16
|
(0, vitest_1.expect)(patterns).toContain('Issue #42');
|
|
15
17
|
(0, vitest_1.expect)(patterns).toContain('issue-42-');
|
|
16
18
|
});
|
|
19
|
+
(0, vitest_1.it)('should include full folder path for working directory matching', () => {
|
|
20
|
+
const options = {
|
|
21
|
+
folderPath: '/Users/dev/myproject-issue-123-feature',
|
|
22
|
+
issueNumber: '123',
|
|
23
|
+
};
|
|
24
|
+
const patterns = (0, terminal_1.getSearchPatterns)(options);
|
|
25
|
+
// Full path should be first for best matching
|
|
26
|
+
(0, vitest_1.expect)(patterns[0]).toBe('/Users/dev/myproject-issue-123-feature');
|
|
27
|
+
});
|
|
17
28
|
(0, vitest_1.it)('should include PR patterns when prNumber is provided', () => {
|
|
18
29
|
const options = {
|
|
19
30
|
folderPath: '/Users/test/project-issue-42-fix-bug',
|
|
@@ -68,6 +79,14 @@ const terminal_1 = require("./terminal");
|
|
|
68
79
|
// Third pass closes windows
|
|
69
80
|
(0, vitest_1.expect)(script).toContain('Third pass: close entire windows');
|
|
70
81
|
});
|
|
82
|
+
(0, vitest_1.it)('should match by session working directory path', () => {
|
|
83
|
+
const patterns = ['/Users/test/worktree'];
|
|
84
|
+
const script = (0, terminal_1.generateITermCloseScript)(patterns);
|
|
85
|
+
// Should include path matching
|
|
86
|
+
(0, vitest_1.expect)(script).toContain('set sessionPath to');
|
|
87
|
+
(0, vitest_1.expect)(script).toContain('path of s');
|
|
88
|
+
(0, vitest_1.expect)(script).toContain('sessionPath contains');
|
|
89
|
+
});
|
|
71
90
|
});
|
|
72
91
|
(0, vitest_1.describe)('generateTerminalCloseScript', () => {
|
|
73
92
|
(0, vitest_1.it)('should generate valid AppleScript for Terminal.app', () => {
|
|
@@ -116,9 +135,11 @@ const terminal_1 = require("./terminal");
|
|
|
116
135
|
(0, vitest_1.expect)(result).toHaveProperty('iTerm');
|
|
117
136
|
(0, vitest_1.expect)(result).toHaveProperty('terminal');
|
|
118
137
|
(0, vitest_1.expect)(result).toHaveProperty('vscode');
|
|
138
|
+
(0, vitest_1.expect)(result).toHaveProperty('processes');
|
|
119
139
|
(0, vitest_1.expect)(typeof result.iTerm).toBe('boolean');
|
|
120
140
|
(0, vitest_1.expect)(typeof result.terminal).toBe('boolean');
|
|
121
141
|
(0, vitest_1.expect)(typeof result.vscode).toBe('boolean');
|
|
142
|
+
(0, vitest_1.expect)(typeof result.processes).toBe('boolean');
|
|
122
143
|
});
|
|
123
144
|
(0, vitest_1.it)('should handle prNumber parameter', () => {
|
|
124
145
|
const result = (0, terminal_1.closeWindowsForWorktree)({
|
|
@@ -129,6 +150,7 @@ const terminal_1 = require("./terminal");
|
|
|
129
150
|
(0, vitest_1.expect)(result).toHaveProperty('iTerm');
|
|
130
151
|
(0, vitest_1.expect)(result).toHaveProperty('terminal');
|
|
131
152
|
(0, vitest_1.expect)(result).toHaveProperty('vscode');
|
|
153
|
+
(0, vitest_1.expect)(result).toHaveProperty('processes');
|
|
132
154
|
});
|
|
133
155
|
});
|
|
134
156
|
(0, vitest_1.describe)('pattern matching edge cases', () => {
|
|
@@ -175,7 +197,8 @@ const terminal_1 = require("./terminal");
|
|
|
175
197
|
const script = (0, terminal_1.generateITermCloseScript)(patterns);
|
|
176
198
|
// Script should be syntactically valid (quotes should be escaped)
|
|
177
199
|
(0, vitest_1.expect)(script).toContain('test\\"pattern');
|
|
178
|
-
|
|
200
|
+
// Should not have broken string like contains "" (empty pattern)
|
|
201
|
+
(0, vitest_1.expect)(script).not.toMatch(/contains ""/);
|
|
179
202
|
});
|
|
180
203
|
(0, vitest_1.it)('should not have nested quotes issues in Terminal script', () => {
|
|
181
204
|
const patterns = ['test"pattern'];
|
|
@@ -188,4 +211,14 @@ const terminal_1 = require("./terminal");
|
|
|
188
211
|
(0, vitest_1.expect)(script).toContain('test\\"pattern');
|
|
189
212
|
});
|
|
190
213
|
});
|
|
214
|
+
(0, vitest_1.describe)('killProcessesInDirectory', () => {
|
|
215
|
+
(0, vitest_1.it)('should return false for non-existent directory', () => {
|
|
216
|
+
const result = (0, terminal_1.killProcessesInDirectory)('/nonexistent/path/that/does/not/exist');
|
|
217
|
+
(0, vitest_1.expect)(result).toBe(false);
|
|
218
|
+
});
|
|
219
|
+
(0, vitest_1.it)('should return boolean result', () => {
|
|
220
|
+
const result = (0, terminal_1.killProcessesInDirectory)('/tmp');
|
|
221
|
+
(0, vitest_1.expect)(typeof result).toBe('boolean');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
191
224
|
});
|