@iloom/cli 0.10.1 → 0.10.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/{BranchNamingService-25KSZAEM.js → BranchNamingService-4OP6LOH6.js} +2 -2
- package/dist/{ClaudeContextManager-66GR4BGM.js → ClaudeContextManager-ZKTUVQB2.js} +4 -4
- package/dist/{ClaudeService-7KM5NA5Z.js → ClaudeService-TRWOYQ6O.js} +3 -3
- package/dist/{LoomLauncher-TDLZSYG2.js → LoomLauncher-FRECYMXS.js} +4 -4
- package/dist/{chunk-KVHIAWVT.js → chunk-2VEWSM34.js} +2 -2
- package/dist/{chunk-5FJWO4IT.js → chunk-2YZCWAVZ.js} +2 -2
- package/dist/{chunk-ZNMPGMHY.js → chunk-3F27M7ZD.js} +7 -7
- package/dist/{chunk-GRISNU6G.js → chunk-BFHDVFSK.js} +5 -5
- package/dist/{chunk-KKV5WH5M.js → chunk-BFLMCE2U.js} +2 -2
- package/dist/{chunk-S7PZA6IV.js → chunk-BU53XIGY.js} +2 -2
- package/dist/{chunk-5RPBYK5Q.js → chunk-HYGUPUV5.js} +2 -2
- package/dist/{chunk-UR5DGNUO.js → chunk-PZ5WSR5Z.js} +4 -4
- package/dist/chunk-PZ5WSR5Z.js.map +1 -0
- package/dist/{chunk-QVLPWNE3.js → chunk-QFTDZ5E3.js} +2 -2
- package/dist/{chunk-EVPZFV3K.js → chunk-V3SVMFDQ.js} +2 -2
- package/dist/{chunk-E6KOWMKA.js → chunk-XE4BDRZD.js} +2 -2
- package/dist/{chunk-OTGH2HRS.js → chunk-ZGM2FE2R.js} +2 -4
- package/dist/chunk-ZGM2FE2R.js.map +1 -0
- package/dist/{claude-7GGEWVEM.js → claude-LN7OWVNI.js} +2 -2
- package/dist/{cleanup-6PVAC4NI.js → cleanup-4ZM2AJDC.js} +6 -6
- package/dist/cli.js +42 -29
- package/dist/cli.js.map +1 -1
- package/dist/{commit-FZR5XDQG.js → commit-4CFLXRZ3.js} +3 -3
- package/dist/{feedback-G2GJFN2F.js → feedback-EZWF5CAL.js} +3 -3
- package/dist/{ignite-H2O5Y5A2.js → ignite-MQETGFNA.js} +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/{init-32YOKXRL.js → init-ZB2RITW6.js} +2 -2
- package/dist/install-deps-RLSGSHH7.js +43 -0
- package/dist/install-deps-RLSGSHH7.js.map +1 -0
- package/dist/{plan-RQ5FPIGF.js → plan-D3KSN5MU.js} +10 -10
- package/dist/prompts/swarm-orchestrator-prompt.txt +20 -6
- package/dist/{rebase-6NVLX5V7.js → rebase-62FDLIH4.js} +3 -3
- package/dist/{summary-WTQZ7XG2.js → summary-YZI25KW4.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-OTGH2HRS.js.map +0 -1
- package/dist/chunk-UR5DGNUO.js.map +0 -1
- /package/dist/{BranchNamingService-25KSZAEM.js.map → BranchNamingService-4OP6LOH6.js.map} +0 -0
- /package/dist/{ClaudeContextManager-66GR4BGM.js.map → ClaudeContextManager-ZKTUVQB2.js.map} +0 -0
- /package/dist/{ClaudeService-7KM5NA5Z.js.map → ClaudeService-TRWOYQ6O.js.map} +0 -0
- /package/dist/{LoomLauncher-TDLZSYG2.js.map → LoomLauncher-FRECYMXS.js.map} +0 -0
- /package/dist/{chunk-KVHIAWVT.js.map → chunk-2VEWSM34.js.map} +0 -0
- /package/dist/{chunk-5FJWO4IT.js.map → chunk-2YZCWAVZ.js.map} +0 -0
- /package/dist/{chunk-ZNMPGMHY.js.map → chunk-3F27M7ZD.js.map} +0 -0
- /package/dist/{chunk-GRISNU6G.js.map → chunk-BFHDVFSK.js.map} +0 -0
- /package/dist/{chunk-KKV5WH5M.js.map → chunk-BFLMCE2U.js.map} +0 -0
- /package/dist/{chunk-S7PZA6IV.js.map → chunk-BU53XIGY.js.map} +0 -0
- /package/dist/{chunk-5RPBYK5Q.js.map → chunk-HYGUPUV5.js.map} +0 -0
- /package/dist/{chunk-QVLPWNE3.js.map → chunk-QFTDZ5E3.js.map} +0 -0
- /package/dist/{chunk-EVPZFV3K.js.map → chunk-V3SVMFDQ.js.map} +0 -0
- /package/dist/{chunk-E6KOWMKA.js.map → chunk-XE4BDRZD.js.map} +0 -0
- /package/dist/{claude-7GGEWVEM.js.map → claude-LN7OWVNI.js.map} +0 -0
- /package/dist/{cleanup-6PVAC4NI.js.map → cleanup-4ZM2AJDC.js.map} +0 -0
- /package/dist/{commit-FZR5XDQG.js.map → commit-4CFLXRZ3.js.map} +0 -0
- /package/dist/{feedback-G2GJFN2F.js.map → feedback-EZWF5CAL.js.map} +0 -0
- /package/dist/{ignite-H2O5Y5A2.js.map → ignite-MQETGFNA.js.map} +0 -0
- /package/dist/{init-32YOKXRL.js.map → init-ZB2RITW6.js.map} +0 -0
- /package/dist/{plan-RQ5FPIGF.js.map → plan-D3KSN5MU.js.map} +0 -0
- /package/dist/{rebase-6NVLX5V7.js.map → rebase-62FDLIH4.js.map} +0 -0
- /package/dist/{summary-WTQZ7XG2.js.map → summary-YZI25KW4.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ClaudeBranchNameStrategy,
|
|
4
4
|
DefaultBranchNamingService,
|
|
5
5
|
SimpleBranchNameStrategy
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QFTDZ5E3.js";
|
|
7
7
|
import "./chunk-6MLEBAYZ.js";
|
|
8
8
|
import "./chunk-VT4PDUYT.js";
|
|
9
9
|
export {
|
|
@@ -11,4 +11,4 @@ export {
|
|
|
11
11
|
DefaultBranchNamingService,
|
|
12
12
|
SimpleBranchNameStrategy
|
|
13
13
|
};
|
|
14
|
-
//# sourceMappingURL=BranchNamingService-
|
|
14
|
+
//# sourceMappingURL=BranchNamingService-4OP6LOH6.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ClaudeContextManager
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-XE4BDRZD.js";
|
|
5
|
+
import "./chunk-BU53XIGY.js";
|
|
6
|
+
import "./chunk-PZ5WSR5Z.js";
|
|
7
7
|
import "./chunk-UUEW5KWB.js";
|
|
8
8
|
import "./chunk-7VHJNVLF.js";
|
|
9
9
|
import "./chunk-6MLEBAYZ.js";
|
|
@@ -11,4 +11,4 @@ import "./chunk-VT4PDUYT.js";
|
|
|
11
11
|
export {
|
|
12
12
|
ClaudeContextManager
|
|
13
13
|
};
|
|
14
|
-
//# sourceMappingURL=ClaudeContextManager-
|
|
14
|
+
//# sourceMappingURL=ClaudeContextManager-ZKTUVQB2.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ClaudeService
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-BU53XIGY.js";
|
|
5
|
+
import "./chunk-PZ5WSR5Z.js";
|
|
6
6
|
import "./chunk-UUEW5KWB.js";
|
|
7
7
|
import "./chunk-7VHJNVLF.js";
|
|
8
8
|
import "./chunk-6MLEBAYZ.js";
|
|
@@ -10,4 +10,4 @@ import "./chunk-VT4PDUYT.js";
|
|
|
10
10
|
export {
|
|
11
11
|
ClaudeService
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=ClaudeService-
|
|
13
|
+
//# sourceMappingURL=ClaudeService-TRWOYQ6O.js.map
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
} from "./chunk-O7VL5N6S.js";
|
|
5
5
|
import {
|
|
6
6
|
ClaudeContextManager
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-XE4BDRZD.js";
|
|
8
|
+
import "./chunk-BU53XIGY.js";
|
|
9
|
+
import "./chunk-PZ5WSR5Z.js";
|
|
10
10
|
import "./chunk-UUEW5KWB.js";
|
|
11
11
|
import {
|
|
12
12
|
getExecutablePath
|
|
@@ -252,4 +252,4 @@ var LoomLauncher = class {
|
|
|
252
252
|
export {
|
|
253
253
|
LoomLauncher
|
|
254
254
|
};
|
|
255
|
-
//# sourceMappingURL=LoomLauncher-
|
|
255
|
+
//# sourceMappingURL=LoomLauncher-FRECYMXS.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
detectClaudeCli,
|
|
15
15
|
launchClaude
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
17
17
|
import {
|
|
18
18
|
executeGhCommand
|
|
19
19
|
} from "./chunk-VG45TUYK.js";
|
|
@@ -359,4 +359,4 @@ Then retry: il start`
|
|
|
359
359
|
export {
|
|
360
360
|
PRManager
|
|
361
361
|
};
|
|
362
|
-
//# sourceMappingURL=chunk-
|
|
362
|
+
//# sourceMappingURL=chunk-2VEWSM34.js.map
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
detectClaudeCli,
|
|
15
15
|
launchClaude
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
17
17
|
import {
|
|
18
18
|
GitCommandError,
|
|
19
19
|
executeGitCommand,
|
|
@@ -539,4 +539,4 @@ export {
|
|
|
539
539
|
MergeManager,
|
|
540
540
|
BuildRunner
|
|
541
541
|
};
|
|
542
|
-
//# sourceMappingURL=chunk-
|
|
542
|
+
//# sourceMappingURL=chunk-2YZCWAVZ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
PRManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2VEWSM34.js";
|
|
5
5
|
import {
|
|
6
6
|
calculatePortForBranch,
|
|
7
7
|
calculatePortFromIdentifier
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from "./chunk-YQ57ORTV.js";
|
|
17
17
|
import {
|
|
18
18
|
generateRandomSessionId
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
20
20
|
import {
|
|
21
21
|
GitCommandError,
|
|
22
22
|
PLACEHOLDER_COMMIT_PREFIX,
|
|
@@ -433,8 +433,8 @@ ${issueData.body}` : "";
|
|
|
433
433
|
const setArguments = (_k = input.options) == null ? void 0 : _k.setArguments;
|
|
434
434
|
const executablePath = (_l = input.options) == null ? void 0 : _l.executablePath;
|
|
435
435
|
if (enableClaude || enableCode || enableDevServer || enableTerminal) {
|
|
436
|
-
const { LoomLauncher } = await import("./LoomLauncher-
|
|
437
|
-
const { ClaudeContextManager } = await import("./ClaudeContextManager-
|
|
436
|
+
const { LoomLauncher } = await import("./LoomLauncher-FRECYMXS.js");
|
|
437
|
+
const { ClaudeContextManager } = await import("./ClaudeContextManager-ZKTUVQB2.js");
|
|
438
438
|
const claudeContext = new ClaudeContextManager(void 0, void 0, this.settings);
|
|
439
439
|
const launcher = new LoomLauncher(claudeContext, this.settings);
|
|
440
440
|
await launcher.launchLoom({
|
|
@@ -1137,8 +1137,8 @@ ${issueData.body}` : "";
|
|
|
1137
1137
|
const executablePath = (_i = input.options) == null ? void 0 : _i.executablePath;
|
|
1138
1138
|
if (enableClaude || enableCode || enableDevServer || enableTerminal) {
|
|
1139
1139
|
getLogger().info("Launching workspace components...");
|
|
1140
|
-
const { LoomLauncher } = await import("./LoomLauncher-
|
|
1141
|
-
const { ClaudeContextManager } = await import("./ClaudeContextManager-
|
|
1140
|
+
const { LoomLauncher } = await import("./LoomLauncher-FRECYMXS.js");
|
|
1141
|
+
const { ClaudeContextManager } = await import("./ClaudeContextManager-ZKTUVQB2.js");
|
|
1142
1142
|
const claudeContext = new ClaudeContextManager(void 0, void 0, this.settings);
|
|
1143
1143
|
const launcher = new LoomLauncher(claudeContext, this.settings);
|
|
1144
1144
|
await launcher.launchLoom({
|
|
@@ -1880,4 +1880,4 @@ export {
|
|
|
1880
1880
|
CLIIsolationManager,
|
|
1881
1881
|
DatabaseManager
|
|
1882
1882
|
};
|
|
1883
|
-
//# sourceMappingURL=chunk-
|
|
1883
|
+
//# sourceMappingURL=chunk-3F27M7ZD.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
DatabaseManager,
|
|
5
5
|
EnvironmentManager,
|
|
6
6
|
LoomManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-3F27M7ZD.js";
|
|
8
8
|
import {
|
|
9
9
|
buildDependencyMap,
|
|
10
10
|
fetchChildIssueDetails,
|
|
@@ -37,13 +37,13 @@ import {
|
|
|
37
37
|
} from "./chunk-FXDYIV3K.js";
|
|
38
38
|
import {
|
|
39
39
|
ClaudeContextManager
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-XE4BDRZD.js";
|
|
41
41
|
import {
|
|
42
42
|
extractSettingsOverrides
|
|
43
43
|
} from "./chunk-GYCR2LOU.js";
|
|
44
44
|
import {
|
|
45
45
|
DefaultBranchNamingService
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-QFTDZ5E3.js";
|
|
47
47
|
import {
|
|
48
48
|
findMainWorktreePathWithSettings,
|
|
49
49
|
getRepoRoot
|
|
@@ -143,7 +143,7 @@ async function launchFirstRunSetup() {
|
|
|
143
143
|
logger.info("");
|
|
144
144
|
logger.info("iloom will now launch an interactive configuration session with Claude.");
|
|
145
145
|
await waitForKeypress("Press any key to start configuration...");
|
|
146
|
-
const { InitCommand } = await import("./init-
|
|
146
|
+
const { InitCommand } = await import("./init-ZB2RITW6.js");
|
|
147
147
|
const initCommand = new InitCommand();
|
|
148
148
|
await initCommand.execute(
|
|
149
149
|
"Help me configure iloom settings for this project. This is my first time using iloom here. Note: Your iloom command will execute once we are done with configuration changes."
|
|
@@ -648,4 +648,4 @@ export {
|
|
|
648
648
|
launchFirstRunSetup,
|
|
649
649
|
StartCommand
|
|
650
650
|
};
|
|
651
|
-
//# sourceMappingURL=chunk-
|
|
651
|
+
//# sourceMappingURL=chunk-BFHDVFSK.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-YETJNRQM.js";
|
|
8
8
|
import {
|
|
9
9
|
launchClaude
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
11
11
|
import {
|
|
12
12
|
getLogger
|
|
13
13
|
} from "./chunk-6MLEBAYZ.js";
|
|
@@ -243,4 +243,4 @@ IMPORTANT: When you create your analysis comment, tag @${author} in the "Questio
|
|
|
243
243
|
export {
|
|
244
244
|
IssueEnhancementService
|
|
245
245
|
};
|
|
246
|
-
//# sourceMappingURL=chunk-
|
|
246
|
+
//# sourceMappingURL=chunk-BFLMCE2U.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
detectClaudeCli,
|
|
4
4
|
launchClaude,
|
|
5
5
|
launchClaudeInNewTerminalWindow
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
7
7
|
import {
|
|
8
8
|
PromptTemplateManager
|
|
9
9
|
} from "./chunk-UUEW5KWB.js";
|
|
@@ -121,4 +121,4 @@ var ClaudeService = class {
|
|
|
121
121
|
export {
|
|
122
122
|
ClaudeService
|
|
123
123
|
};
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-BU53XIGY.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
detectClaudeCli,
|
|
12
12
|
launchClaude
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
14
14
|
import {
|
|
15
15
|
executeGitCommand
|
|
16
16
|
} from "./chunk-4FGEGQW4.js";
|
|
@@ -828,4 +828,4 @@ export {
|
|
|
828
828
|
UserAbortedCommitError,
|
|
829
829
|
CommitManager
|
|
830
830
|
};
|
|
831
|
-
//# sourceMappingURL=chunk-
|
|
831
|
+
//# sourceMappingURL=chunk-HYGUPUV5.js.map
|
|
@@ -237,7 +237,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
237
237
|
} catch (interactiveError) {
|
|
238
238
|
if (signal == null ? void 0 : signal.aborted) return;
|
|
239
239
|
const interactiveExecaError = interactiveError;
|
|
240
|
-
const interactiveErrorMessage = interactiveExecaError.stderr
|
|
240
|
+
const interactiveErrorMessage = interactiveExecaError.stderr || interactiveExecaError.message || "";
|
|
241
241
|
const sessionMatch = interactiveErrorMessage.match(/Session ID ([0-9a-f-]+) is already in use/i);
|
|
242
242
|
const conflictSessionId = sessionMatch == null ? void 0 : sessionMatch[1];
|
|
243
243
|
if (sessionMatch && sessionId && conflictSessionId) {
|
|
@@ -270,7 +270,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
270
270
|
} catch (error) {
|
|
271
271
|
if (signal == null ? void 0 : signal.aborted) return;
|
|
272
272
|
const execaError = error;
|
|
273
|
-
const errorMessage = execaError.stderr
|
|
273
|
+
const errorMessage = execaError.stderr || execaError.message || "Unknown Claude CLI error";
|
|
274
274
|
const sessionInUseMatch = errorMessage.match(/Session ID ([0-9a-f-]+) is already in use/i);
|
|
275
275
|
const extractedSessionId = sessionInUseMatch == null ? void 0 : sessionInUseMatch[1];
|
|
276
276
|
if (sessionInUseMatch && sessionId && extractedSessionId) {
|
|
@@ -349,7 +349,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
349
349
|
}
|
|
350
350
|
} catch (retryError) {
|
|
351
351
|
const retryExecaError = retryError;
|
|
352
|
-
const retryErrorMessage = retryExecaError.stderr
|
|
352
|
+
const retryErrorMessage = retryExecaError.stderr || retryExecaError.message || "Unknown Claude CLI error";
|
|
353
353
|
throw new Error(`Claude CLI error: ${retryErrorMessage}`);
|
|
354
354
|
}
|
|
355
355
|
}
|
|
@@ -452,4 +452,4 @@ export {
|
|
|
452
452
|
launchClaudeInNewTerminalWindow,
|
|
453
453
|
generateBranchName
|
|
454
454
|
};
|
|
455
|
-
//# sourceMappingURL=chunk-
|
|
455
|
+
//# sourceMappingURL=chunk-PZ5WSR5Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/claude.ts"],"sourcesContent":["/* global AbortSignal */\nimport { execa, type ExecaChildProcess } from 'execa'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\nimport { logger } from './logger.js'\nimport { getLogger } from './logger-context.js'\nimport { openTerminalWindow } from './terminal.js'\n\n/**\n * Generate a deterministic UUID v5 from a worktree path\n * Uses SHA1 hash with URL namespace to create a consistent session ID\n * that can be used to resume Claude Code sessions\n */\nexport function generateDeterministicSessionId(worktreePath: string): string {\n\t// UUID v5 namespace for URLs (RFC 4122)\n\tconst URL_NAMESPACE = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'\n\n\t// Create SHA1 hash of namespace + path\n\tconst hash = createHash('sha1')\n\n\t// Convert namespace UUID to bytes\n\tconst namespaceBytes = Buffer.from(URL_NAMESPACE.replace(/-/g, ''), 'hex')\n\thash.update(namespaceBytes)\n\thash.update(worktreePath)\n\n\tconst digest = hash.digest()\n\n\t// Format as UUID v5:\n\t// - Set version (bits 12-15 of time_hi_and_version) to 5\n\t// - Set variant (bits 6-7 of clock_seq_hi_and_reserved) to binary 10\n\tconst bytes = Array.from(digest.subarray(0, 16))\n\n\t// Set version to 5 (byte 6, high nibble)\n\tconst byte6 = bytes[6] ?? 0\n\tbytes[6] = (byte6 & 0x0f) | 0x50\n\n\t// Set variant to RFC 4122 (byte 8, high 2 bits = 10)\n\tconst byte8 = bytes[8] ?? 0\n\tbytes[8] = (byte8 & 0x3f) | 0x80\n\n\t// Format as UUID string\n\tconst hex = Buffer.from(bytes).toString('hex')\n\treturn `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`\n}\n\n/**\n * Generate a random UUID v4 for session ID\n * Uses crypto.randomUUID() for cryptographically secure random UUID generation\n * Used to create unique session IDs for each loom, enabling fresh Claude sessions\n */\nexport function generateRandomSessionId(): string {\n\treturn randomUUID()\n}\n\nexport interface ClaudeCliOptions {\n\tmodel?: string\n\tpermissionMode?: 'plan' | 'acceptEdits' | 'bypassPermissions' | 'default'\n\taddDir?: string\n\theadless?: boolean\n\tbranchName?: string // Optional branch name for terminal coloring\n\tport?: number // Optional port for terminal window export\n\ttimeout?: number // Timeout in milliseconds\n\tappendSystemPrompt?: string // System instructions to append to system prompt\n\tmcpConfig?: Record<string, unknown>[] // Array of MCP server configurations\n\tallowedTools?: string[] // Tools to allow via --allowed-tools flag\n\tdisallowedTools?: string[] // Tools to disallow via --disallowed-tools flag\n\tagents?: Record<string, unknown> // Agent configurations for --agents flag\n\toneShot?: import('../types/index.js').OneShotMode // One-shot automation mode\n\tsetArguments?: string[] // Raw --set arguments to forward (e.g., ['workflows.issue.startIde=false'])\n\texecutablePath?: string // Executable path to use for spin command (e.g., 'il', 'il-125', or '/path/to/dist/cli.js')\n\tsessionId?: string // Session ID for Claude Code resume support (must be valid UUID)\n\tnoSessionPersistence?: boolean // Prevent session data from being saved to disk (for utility operations)\n\toutputFormat?: 'json' | 'stream-json' | 'text' // Output format for Claude CLI (headless mode)\n\tverbose?: boolean // Enable verbose output (headless mode) - defaults to true when headless\n\tjsonMode?: 'json' | 'stream' // JSON output mode: 'json' for final object, 'stream' for real-time JSONL\n\tpassthroughStdout?: boolean // In headless mode, pipe stdout to process.stdout instead of capturing\n\tenv?: Record<string, string> // Additional environment variables to pass to the Claude process\n\tsignal?: AbortSignal // Optional AbortSignal for graceful termination of the Claude process\n}\n\n/**\n * Detect if Claude CLI is available on the system\n */\nexport async function detectClaudeCli(): Promise<boolean> {\n\ttry {\n\t\t// Use 'command -v' for cross-platform compatibility (works on macOS/Linux)\n\t\tawait execa('command', ['-v', 'claude'], {\n\t\t\tshell: true,\n\t\t\ttimeout: 5000,\n\t\t})\n\t\treturn true\n\t} catch (error) {\n\t\t// Claude CLI not found\n\t\tlogger.debug('Claude CLI not available', { error })\n\t\treturn false\n\t}\n}\n\n/**\n * Get Claude CLI version\n */\nexport async function getClaudeVersion(): Promise<string | null> {\n\ttry {\n\t\tconst result = await execa('claude', ['--version'], {\n\t\t\ttimeout: 5000,\n\t\t})\n\t\treturn result.stdout.trim()\n\t} catch (error) {\n\t\tlogger.warn('Failed to get Claude version', { error })\n\t\treturn null\n\t}\n}\n\n/**\n * Parse JSON stream output and extract result from last JSON object with type:\"result\"\n */\nfunction parseJsonStreamOutput(output: string): string {\n\ttry {\n\t\t// Split by newlines and filter out empty lines\n\t\tconst lines = output.split('\\n').filter(line => line.trim())\n\n\t\t// Find the last valid JSON object with type:\"result\"\n\t\tlet lastResult = ''\n\t\tfor (const line of lines) {\n\t\t\ttry {\n\t\t\t\tconst jsonObj = JSON.parse(line)\n\t\t\t\tif (jsonObj && typeof jsonObj === 'object' && jsonObj.type === 'result' && 'result' in jsonObj) {\n\t\t\t\t\tlastResult = jsonObj.result\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Skip invalid JSON lines\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\treturn lastResult || output // Fallback to original output if no valid result found\n\t} catch {\n\t\t// If parsing fails completely, return original output\n\t\treturn output\n\t}\n}\n\n/**\n * Launch Claude CLI with specified options\n * In headless mode, returns stdout. In interactive mode, returns void.\n */\nexport async function launchClaude(\n\tprompt: string,\n\toptions: ClaudeCliOptions = {}\n): Promise<string | void> {\n\tconst { model, permissionMode, addDir, headless = false, appendSystemPrompt, mcpConfig, allowedTools, disallowedTools, agents, sessionId, noSessionPersistence, outputFormat, verbose, jsonMode, passthroughStdout, env: extraEnv, signal } = options\n\tconst log = getLogger()\n\n\t// Build command arguments\n\tconst args: string[] = []\n\n\tif (headless) {\n\t\targs.push('-p')\n\n\t\t// Use user-provided outputFormat or default to stream-json for progress tracking\n\t\tconst effectiveOutputFormat = outputFormat ?? 'stream-json'\n\t\targs.push('--output-format', effectiveOutputFormat)\n\n\t\t// Use user-provided verbose setting or default to true\n\t\tif (verbose !== false) {\n\t\t\targs.push('--verbose')\n\t\t}\n\t}\n\n\tif (model) {\n\t\targs.push('--model', model)\n\t}\n\n\tif (permissionMode && permissionMode !== 'default') {\n\t\targs.push('--permission-mode', permissionMode)\n\t}\n\n\tif (addDir) {\n\t\targs.push('--add-dir', addDir)\n\t}\n\n\targs.push('--add-dir', '/tmp') //TODO: Won't work on Windows\n\n\t// Add --append-system-prompt flag if provided\n\tif (appendSystemPrompt) {\n\t\targs.push('--append-system-prompt', appendSystemPrompt)\n\t}\n\n\t// Add --mcp-config flags for each MCP server configuration\n\tif (mcpConfig && mcpConfig.length > 0) {\n\t\tfor (const config of mcpConfig) {\n\t\t\targs.push('--mcp-config', JSON.stringify(config))\n\t\t}\n\t}\n\n\t// Add --allowed-tools flags if provided\n\tif (allowedTools && allowedTools.length > 0) {\n\t\targs.push('--allowed-tools', ...allowedTools)\n\t}\n\n\t// Add --disallowed-tools flags if provided\n\tif (disallowedTools && disallowedTools.length > 0) {\n\t\targs.push('--disallowed-tools', ...disallowedTools)\n\t}\n\n\t// Add --agents flag if provided\n\tif (agents) {\n\t\targs.push('--agents', JSON.stringify(agents))\n\t}\n\n\t// Add --session-id flag if provided (enables Claude Code session resume)\n\tif (sessionId) {\n\t\targs.push('--session-id', sessionId)\n\t}\n\n\t// Add --no-session-persistence flag if requested (for utility operations that don't need session persistence)\n\t// Note: --no-session-persistence can only be used with --print mode (-p), which is only added in headless mode\n\tif (noSessionPersistence && headless) {\n\t\targs.push('--no-session-persistence')\n\t}\n\n\t// Set CLAUDECODE=0 to prevent Claude from detecting it's running inside Claude Code\n\tconst claudeEnv = { ...process.env, CLAUDECODE: '0' }\n\n\t// Helper to attach AbortSignal to a subprocess for graceful termination\n\tfunction attachAbortSignal(subprocess: ExecaChildProcess): void {\n\t\tif (!signal) return\n\t\tconst onAbort = (): void => {\n\t\t\tsubprocess.kill('SIGTERM')\n\t\t}\n\t\tsignal.addEventListener('abort', onAbort, { once: true })\n\t\tsubprocess.on('exit', (): void => {\n\t\t\tsignal.removeEventListener('abort', onAbort)\n\t\t})\n\t}\n\n\ttry {\n\t\tif (headless && passthroughStdout) {\n\t\t\t// Headless + passthrough: Claude's stdout goes directly to process.stdout\n\t\t\t// Used for --json-stream where JSONL must reach the caller's stdout\n\t\t\tconst subprocess = execa('claude', args, {\n\t\t\t\tinput: prompt,\n\t\t\t\ttimeout: 0,\n\t\t\t\t...(addDir && { cwd: addDir }),\n\t\t\t\tenv: { ...claudeEnv, ...extraEnv }, // CLAUDECODE=0 + any extra env vars\n\t\t\t\tstdio: ['pipe', 'inherit', 'pipe'], // stdin: pipe (for prompt), stdout: inherit (passthrough), stderr: pipe (capture errors)\n\t\t\t})\n\n\t\t\tattachAbortSignal(subprocess)\n\t\t\ttry {\n\t\t\t\tawait subprocess\n\t\t\t} catch (err) {\n\t\t\t\tif (signal?.aborted) return\n\t\t\t\tthrow err\n\t\t\t}\n\t\t\treturn // No output to return - it went directly to stdout\n\t\t}\n\n\t\tif (headless) {\n\t\t\t// Headless mode: capture and return output\n\t\t\tconst isDebugMode = logger.isDebugEnabled()\n\n\t\t\t// Set up execa options based on debug mode\n\t\t\tconst execaOptions = {\n\t\t\t\tinput: prompt,\n\t\t\t\ttimeout: 0, // Disable timeout for long responses\n\t\t\t\t...(addDir && { cwd: addDir }), // Run Claude in the worktree directory\n\t\t\t\tverbose: isDebugMode,\n\t\t\t\tenv: { ...claudeEnv, ...extraEnv }, // CLAUDECODE=0 + any extra env vars\n\t\t\t\t...(isDebugMode && { stdio: ['pipe', 'pipe', 'pipe'] as const }), // Enable streaming in debug mode\n\t\t\t}\n\n\t\t\tconst subprocess = execa('claude', args, execaOptions)\n\t\t\tattachAbortSignal(subprocess)\n\n\t\t\t// Check if JSON streaming format is enabled (always true in headless mode)\n\t\t\tconst isJsonStreamFormat = args.includes('--output-format') && args.includes('stream-json')\n\n\t\t\t// Handle real-time streaming (enabled for progress tracking)\n\t\t\tlet outputBuffer = ''\n\t\t\tlet isStreaming = false\n\t\t\tlet isFirstProgress = true\n\t\t\tif (subprocess.stdout && typeof subprocess.stdout.on === 'function') {\n\t\t\t\tisStreaming = true\n\t\t\t\tsubprocess.stdout.on('data', (chunk: Buffer) => {\n\t\t\t\t\tconst text = chunk.toString()\n\t\t\t\t\toutputBuffer += text\n\n\t\t\t\t\tif (jsonMode === 'stream') {\n\t\t\t\t\t\t// --json-stream: Output raw JSONL to stdout immediately\n\t\t\t\t\t\tprocess.stdout.write(text)\n\t\t\t\t\t} else if (jsonMode === 'json') {\n\t\t\t\t\t\t// --json: Suppress all progress output (will return final JSON)\n\t\t\t\t\t\t// Do nothing - just accumulate in buffer\n\t\t\t\t\t} else if (isDebugMode) {\n\t\t\t\t\t\tlog.stdout.write(text) // Full JSON streaming in debug mode\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Progress dots in non-debug mode with robot emoji prefix\n\t\t\t\t\t\tif (isFirstProgress) {\n\t\t\t\t\t\t\tlog.stdout.write('🤖 .')\n\t\t\t\t\t\t\tisFirstProgress = false\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.stdout.write('.')\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tlet result: any\n\t\t\ttry {\n\t\t\t\tresult = await subprocess\n\t\t\t} catch (subprocessError) {\n\t\t\t\t// If aborted intentionally, do not treat as an error\n\t\t\t\tif (signal?.aborted) return\n\t\t\t\tthrow subprocessError\n\t\t\t}\n\n\t\t\t// Return streamed output if we were streaming, otherwise use result.stdout\n\t\t\tif (isStreaming) {\n\t\t\t\tconst rawOutput = outputBuffer.trim()\n\n\t\t\t\t// Clean up progress dots with newline in non-debug mode (skip for json modes)\n\t\t\t\tif (!isDebugMode && !jsonMode) {\n\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t}\n\n\t\t\t\treturn isJsonStreamFormat ? parseJsonStreamOutput(rawOutput) : rawOutput\n\t\t\t} else {\n\t\t\t\t// Fallback for mocked tests or when streaming not available\n\t\t\t\tif (isDebugMode) {\n\t\t\t\t\t// In debug mode, write to stdout even if not streaming (old behavior for tests)\n\t\t\t\t\tlog.stdout.write(result.stdout)\n\t\t\t\t\tif (result.stdout && !result.stdout.endsWith('\\n')) {\n\t\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// In non-debug mode, show a single progress dot even without streaming (for tests)\n\t\t\t\t\tlog.stdout.write('🤖 .')\n\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t}\n\t\t\t\tconst rawOutput = result.stdout.trim()\n\t\t\t\treturn isJsonStreamFormat ? parseJsonStreamOutput(rawOutput) : rawOutput\n\t\t\t}\n\t\t} else {\n\t\t\t// Simple interactive mode: run Claude in current terminal with stdio inherit\n\t\t\t// Used for conflict resolution, error fixing, etc.\n\t\t\t// This is the simple approach: claude -- \"prompt\"\n\n\t\t\t// First attempt: capture stderr to detect session ID conflicts\n\t\t\t// stdin/stdout inherit for interactivity, stderr captured for error detection\n\t\t\ttry {\n\t\t\t\tconst interactiveSubprocess = execa('claude', [...args, '--', prompt], {\n\t\t\t\t\t...(addDir && { cwd: addDir }),\n\t\t\t\t\tstdio: ['inherit', 'inherit', 'pipe'], // Capture stderr to detect session conflicts\n\t\t\t\t\ttimeout: 0, // Disable timeout\n\t\t\t\t\tverbose: logger.isDebugEnabled(),\n\t\t\t\t\tenv: { ...claudeEnv, ...extraEnv }, // CLAUDECODE=0 + any extra env vars\n\t\t\t\t})\n\t\t\t\tattachAbortSignal(interactiveSubprocess)\n\t\t\t\ttry {\n\t\t\t\t\tawait interactiveSubprocess\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (signal?.aborted) return\n\t\t\t\t\tthrow err\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t} catch (interactiveError) {\n\t\t\t\tif (signal?.aborted) return\n\t\t\t\tconst interactiveExecaError = interactiveError as { stderr?: string; message?: string }\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string stderr should fall through to message\n\t\t\t\tconst interactiveErrorMessage = interactiveExecaError.stderr || interactiveExecaError.message || ''\n\n\t\t\t\t// Check for session ID conflict\n\t\t\t\tconst sessionMatch = interactiveErrorMessage.match(/Session ID ([0-9a-f-]+) is already in use/i)\n\t\t\t\tconst conflictSessionId = sessionMatch?.[1]\n\t\t\t\tif (sessionMatch && sessionId && conflictSessionId) {\n\t\t\t\t\tlog.debug(`Session ID ${conflictSessionId} already in use, retrying with --resume`)\n\n\t\t\t\t\t// Rebuild args with --resume instead of --session-id\n\t\t\t\t\tconst resumeArgs = args.filter((arg, idx) => {\n\t\t\t\t\t\tif (arg === '--session-id') return false\n\t\t\t\t\t\tif (idx > 0 && args[idx - 1] === '--session-id') return false\n\t\t\t\t\t\treturn true\n\t\t\t\t\t})\n\t\t\t\t\tresumeArgs.push('--resume', conflictSessionId)\n\n\t\t\t\t\t// Retry with full stdio inherit for proper interactive experience\n\t\t\t\t\t// Note: When using --resume, we omit the prompt since the session already has context\n\t\t\t\t\tconst resumeSubprocess = execa('claude', resumeArgs, {\n\t\t\t\t\t\t...(addDir && { cwd: addDir }),\n\t\t\t\t\t\tstdio: 'inherit',\n\t\t\t\t\t\ttimeout: 0,\n\t\t\t\t\t\tverbose: logger.isDebugEnabled(),\n\t\t\t\t\t\tenv: claudeEnv,\n\t\t\t\t\t})\n\t\t\t\t\tattachAbortSignal(resumeSubprocess)\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait resumeSubprocess\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (signal?.aborted) return\n\t\t\t\t\t\tthrow err\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Not a session conflict, re-throw\n\t\t\t\tthrow interactiveError\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\t// If aborted intentionally, do not treat as an error\n\t\tif (signal?.aborted) return\n\n\t\t// Check for specific Claude CLI errors\n\t\tconst execaError = error as {\n\t\t\tstderr?: string\n\t\t\tmessage?: string\n\t\t\texitCode?: number\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string stderr should fall through to message\n\t\tconst errorMessage = execaError.stderr || execaError.message || 'Unknown Claude CLI error'\n\n\t\t// Check for \"Session ID ... is already in use\" error and retry with --resume\n\t\tconst sessionInUseMatch = errorMessage.match(/Session ID ([0-9a-f-]+) is already in use/i)\n\t\tconst extractedSessionId = sessionInUseMatch?.[1]\n\t\tif (sessionInUseMatch && sessionId && extractedSessionId) {\n\t\t\tlog.debug(`Session ID ${extractedSessionId} already in use, retrying with --resume`)\n\n\t\t\t// Rebuild args with --resume instead of --session-id\n\t\t\tconst resumeArgs = args.filter((arg, idx) => {\n\t\t\t\t// Filter out --session-id and its value\n\t\t\t\tif (arg === '--session-id') return false\n\t\t\t\tif (idx > 0 && args[idx - 1] === '--session-id') return false\n\t\t\t\treturn true\n\t\t\t})\n\t\t\tresumeArgs.push('--resume', extractedSessionId)\n\n\t\t\ttry {\n\t\t\t\tif (headless) {\n\t\t\t\t\tconst isDebugMode = logger.isDebugEnabled()\n\t\t\t\t\t// Note: In headless mode, we still need to pass the prompt even with --resume\n\t\t\t\t\t// because there's no interactive input mechanism\n\t\t\t\t\tconst execaOptions = {\n\t\t\t\t\t\tinput: prompt,\n\t\t\t\t\t\ttimeout: 0,\n\t\t\t\t\t\t...(addDir && { cwd: addDir }),\n\t\t\t\t\t\tverbose: isDebugMode,\n\t\t\t\t\t\tenv: claudeEnv,\n\t\t\t\t\t\t...(isDebugMode && { stdio: ['pipe', 'pipe', 'pipe'] as const }),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subprocess = execa('claude', resumeArgs, execaOptions)\n\t\t\t\t\tconst isJsonStreamFormat = resumeArgs.includes('--output-format') && resumeArgs.includes('stream-json')\n\n\t\t\t\t\tlet outputBuffer = ''\n\t\t\t\t\tlet isStreaming = false\n\t\t\t\t\tlet isFirstProgress = true\n\t\t\t\t\tif (subprocess.stdout && typeof subprocess.stdout.on === 'function') {\n\t\t\t\t\t\tisStreaming = true\n\t\t\t\t\t\tsubprocess.stdout.on('data', (chunk: Buffer) => {\n\t\t\t\t\t\t\tconst text = chunk.toString()\n\t\t\t\t\t\t\toutputBuffer += text\n\t\t\t\t\t\t\tif (jsonMode === 'stream') {\n\t\t\t\t\t\t\t\tprocess.stdout.write(text)\n\t\t\t\t\t\t\t} else if (jsonMode === 'json') {\n\t\t\t\t\t\t\t\t// Suppress progress output for json mode\n\t\t\t\t\t\t\t} else if (isDebugMode) {\n\t\t\t\t\t\t\t\tlog.stdout.write(text)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif (isFirstProgress) {\n\t\t\t\t\t\t\t\t\tlog.stdout.write('🤖 .')\n\t\t\t\t\t\t\t\t\tisFirstProgress = false\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlog.stdout.write('.')\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await subprocess\n\n\t\t\t\t\tif (isStreaming) {\n\t\t\t\t\t\tconst rawOutput = outputBuffer.trim()\n\t\t\t\t\t\tif (!isDebugMode && !jsonMode) {\n\t\t\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn isJsonStreamFormat ? parseJsonStreamOutput(rawOutput) : rawOutput\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (isDebugMode) {\n\t\t\t\t\t\t\tlog.stdout.write(result.stdout)\n\t\t\t\t\t\t\tif (result.stdout && !result.stdout.endsWith('\\n')) {\n\t\t\t\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.stdout.write('🤖 .')\n\t\t\t\t\t\t\tlog.stdout.write('\\n')\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst rawOutput = result.stdout.trim()\n\t\t\t\t\t\treturn isJsonStreamFormat ? parseJsonStreamOutput(rawOutput) : rawOutput\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Note: When using --resume, we omit the prompt since the session already has context\n\t\t\t\t\tawait execa('claude', resumeArgs, {\n\t\t\t\t\t\t...(addDir && { cwd: addDir }),\n\t\t\t\t\t\tstdio: 'inherit',\n\t\t\t\t\t\ttimeout: 0,\n\t\t\t\t\t\tverbose: logger.isDebugEnabled(),\n\t\t\t\t\t\tenv: claudeEnv,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} catch (retryError) {\n\t\t\t\tconst retryExecaError = retryError as { stderr?: string; message?: string }\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- intentional: empty string stderr should fall through to message\n\t\t\t\tconst retryErrorMessage = retryExecaError.stderr || retryExecaError.message || 'Unknown Claude CLI error'\n\t\t\t\tthrow new Error(`Claude CLI error: ${retryErrorMessage}`)\n\t\t\t}\n\t\t}\n\n\t\t// Re-throw with more context\n\t\tthrow new Error(`Claude CLI error: ${errorMessage}`)\n\t}\n}\n\n/**\n * Launch Claude in a new terminal window with rich context\n * This is specifically for \"end of il start\" workflow\n * Ports the terminal window opening, coloring, and .env sourcing behavior\n */\nexport async function launchClaudeInNewTerminalWindow(\n\t_prompt: string,\n\toptions: ClaudeCliOptions & {\n\t\tworkspacePath: string // Required for terminal window launch\n\t}\n): Promise<void> {\n\tconst { workspacePath, branchName, oneShot = 'default', port, setArguments, executablePath } = options\n\n\t// Verify required parameter\n\tif (!workspacePath) {\n\t\tthrow new Error('workspacePath is required for terminal window launch')\n\t}\n\n\t// Build launch command with optional --one-shot flag\n\t// Use provided executable path or fallback to 'il'\n\tconst executable = executablePath ?? 'iloom'\n\tlet launchCommand = `${executable} spin`\n\tif (oneShot !== 'default') {\n\t\tlaunchCommand += ` --one-shot=${oneShot}`\n\t}\n\n\t// Append --set arguments if provided\n\tif (setArguments && setArguments.length > 0) {\n\t\tfor (const setArg of setArguments) {\n\t\t\tlaunchCommand += ` --set ${setArg}`\n\t\t}\n\t}\n\n\t// Apply terminal background color if branch name available\n\tlet backgroundColor: { r: number; g: number; b: number } | undefined\n\tif (branchName) {\n\t\ttry {\n\t\t\tconst { generateColorFromBranchName } = await import('./color.js')\n\t\t\tconst colorData = generateColorFromBranchName(branchName)\n\t\t\tbackgroundColor = colorData.rgb\n\t\t} catch (error) {\n\t\t\tlogger.warn(\n\t\t\t\t`Failed to generate terminal color: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t}\n\t}\n\n\t// Check if .env file exists in workspace\n\tconst hasEnvFile = existsSync(join(workspacePath, '.env'))\n\n\t// Open new terminal window with Claude\n\tawait openTerminalWindow({\n\t\tworkspacePath,\n\t\tcommand: launchCommand,\n\t\t...(backgroundColor && { backgroundColor }),\n\t\tincludeEnvSetup: hasEnvFile, // source .env only if it exists\n\t\t...(port !== undefined && { port, includePortExport: true }),\n\t})\n}\n\n/**\n * Generate a branch name using Claude with fallback\n * This matches the implementation that was working in ClaudeBranchNameStrategy\n */\nexport async function generateBranchName(\n\tissueTitle: string,\n\tissueNumber: string | number,\n\tmodel: string = 'haiku'\n): Promise<string> {\n\ttry {\n\t\t// Check if Claude CLI is available\n\t\tconst isAvailable = await detectClaudeCli()\n\t\tif (!isAvailable) {\n\t\t\tlogger.warn('Claude CLI not available, using fallback branch name')\n\t\t\treturn `feat/issue-${issueNumber}`\n\t\t}\n\n\t\tlogger.debug('Generating branch name with Claude', { issueNumber, issueTitle })\n\n\t\t// Use the proven prompt format from ClaudeBranchNameStrategy\n\t\tconst prompt = `<Task>\nGenerate a git branch name for the following issue:\n<Issue>\n<IssueNumber>${issueNumber}</IssueNumber>\n<IssueTitle>${issueTitle}</IssueTitle>\n</Issue>\n\n<Requirements>\n<IssueNumber>Must use this exact issue number: ${issueNumber}</IssueNumber>\n<Format>Format must be: {prefix}/issue-${issueNumber}__{description}</Format>\n<Prefix>Prefix must be one of: feat, fix, docs, refactor, test, chore</Prefix>\n<MaxLength>Maximum 50 characters total</MaxLength>\n<Characters>Only lowercase letters, numbers, and hyphens allowed</Characters>\n<Output>Reply with ONLY the branch name, nothing else</Output>\n</Requirements>\n</Task>`\n\n\t\tlogger.debug('Sending prompt to Claude', { prompt })\n\n\t\tconst result = (await launchClaude(prompt, {\n\t\t\tmodel,\n\t\t\theadless: true,\n\t\t\tnoSessionPersistence: true, // Utility operation - don't persist session\n\t\t\tenv: { CLAUDE_CODE_SIMPLE: '1' }, // Minimal mode - no MCP, hooks, or CLAUDE.md loading\n\t\t})) as string\n\n\t\t// Normalize to lowercase for consistency (Linear IDs are uppercase but branches should be lowercase)\n\t\tconst branchName = result.trim().toLowerCase()\n\t\tlogger.debug('Claude returned branch name', { branchName, issueNumber })\n\n\t\t// Validate generated name using same validation as ClaudeBranchNameStrategy\n\t\tif (!branchName || !isValidBranchName(branchName, issueNumber)) {\n\t\t\tlogger.warn('Invalid branch name from Claude, using fallback', { branchName })\n\t\t\treturn `feat/issue-${issueNumber}`.toLowerCase()\n\t\t}\n\n\t\treturn branchName\n\t} catch (error) {\n\t\tlogger.warn('Failed to generate branch name with Claude', { error })\n\t\treturn `feat/issue-${issueNumber}`.toLowerCase()\n\t}\n}\n\n/**\n * Validate branch name format\n * Check format: {prefix}/issue-{number}__{description}\n * Uses case-insensitive matching for issue number (Linear uses uppercase like MARK-1)\n */\nfunction isValidBranchName(name: string, issueNumber: string | number): boolean {\n\tconst pattern = new RegExp(`^(feat|fix|docs|refactor|test|chore)/issue-${issueNumber}__[a-z0-9-]+$`, 'i')\n\treturn pattern.test(name) && name.length <= 50\n}\n"],"mappings":"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","names":[]}
|
|
@@ -15,7 +15,7 @@ var ClaudeBranchNameStrategy = class {
|
|
|
15
15
|
this.claudeModel = claudeModel;
|
|
16
16
|
}
|
|
17
17
|
async generate(issueNumber, title) {
|
|
18
|
-
const { generateBranchName } = await import("./claude-
|
|
18
|
+
const { generateBranchName } = await import("./claude-LN7OWVNI.js");
|
|
19
19
|
return generateBranchName(title, issueNumber, this.claudeModel);
|
|
20
20
|
}
|
|
21
21
|
};
|
|
@@ -52,4 +52,4 @@ export {
|
|
|
52
52
|
ClaudeBranchNameStrategy,
|
|
53
53
|
DefaultBranchNamingService
|
|
54
54
|
};
|
|
55
|
-
//# sourceMappingURL=chunk-
|
|
55
|
+
//# sourceMappingURL=chunk-QFTDZ5E3.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
generateDeterministicSessionId,
|
|
13
13
|
launchClaude
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
15
15
|
import {
|
|
16
16
|
PromptTemplateManager
|
|
17
17
|
} from "./chunk-UUEW5KWB.js";
|
|
@@ -369,4 +369,4 @@ var SessionSummaryService = class {
|
|
|
369
369
|
export {
|
|
370
370
|
SessionSummaryService
|
|
371
371
|
};
|
|
372
|
-
//# sourceMappingURL=chunk-
|
|
372
|
+
//# sourceMappingURL=chunk-V3SVMFDQ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ClaudeService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BU53XIGY.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
7
|
} from "./chunk-VT4PDUYT.js";
|
|
@@ -63,4 +63,4 @@ var ClaudeContextManager = class {
|
|
|
63
63
|
export {
|
|
64
64
|
ClaudeContextManager
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-XE4BDRZD.js.map
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
} from "./chunk-C6HNNJIV.js";
|
|
32
32
|
import {
|
|
33
33
|
launchClaude
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-PZ5WSR5Z.js";
|
|
35
35
|
import {
|
|
36
36
|
PromptTemplateManager,
|
|
37
37
|
buildReviewTemplateVariables
|
|
@@ -925,8 +925,6 @@ var IgniteCommand = class {
|
|
|
925
925
|
success: false,
|
|
926
926
|
error: errorMessage
|
|
927
927
|
}));
|
|
928
|
-
} else {
|
|
929
|
-
logger.error(`Failed to launch Claude: ${errorMessage}`);
|
|
930
928
|
}
|
|
931
929
|
throw error;
|
|
932
930
|
}
|
|
@@ -1424,4 +1422,4 @@ export {
|
|
|
1424
1422
|
WorktreeValidationError,
|
|
1425
1423
|
IgniteCommand
|
|
1426
1424
|
};
|
|
1427
|
-
//# sourceMappingURL=chunk-
|
|
1425
|
+
//# sourceMappingURL=chunk-ZGM2FE2R.js.map
|