@iloom/cli 0.3.0 → 0.3.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.
Files changed (102) hide show
  1. package/README.md +207 -882
  2. package/dist/{BranchNamingService-3OQPRSWT.js → BranchNamingService-JYO746H7.js} +2 -2
  3. package/dist/ClaudeContextManager-5WPRJIIW.js +15 -0
  4. package/dist/ClaudeService-Z4KA7QOW.js +14 -0
  5. package/dist/{GitHubService-EBOETDIW.js → GitHubService-UAMH7DMF.js} +2 -2
  6. package/dist/{LoomLauncher-FLEMBCSQ.js → LoomLauncher-FVZECY3C.js} +24 -13
  7. package/dist/LoomLauncher-FVZECY3C.js.map +1 -0
  8. package/dist/README.md +207 -882
  9. package/dist/{SettingsManager-WHHFGSL7.js → SettingsManager-MTVX57WR.js} +2 -2
  10. package/dist/{chunk-MAVL6PJF.js → chunk-5NTD4MCZ.js} +23 -7
  11. package/dist/chunk-5NTD4MCZ.js.map +1 -0
  12. package/dist/{chunk-FIAT22G7.js → chunk-A2P7NZTB.js} +7 -7
  13. package/dist/{chunk-C5QCTEQK.js → chunk-C7ASXK6J.js} +2 -2
  14. package/dist/{chunk-G2IEYOLQ.js → chunk-F4ENT6AC.js} +16 -1
  15. package/dist/chunk-F4ENT6AC.js.map +1 -0
  16. package/dist/{chunk-AWOFAD5O.js → chunk-FOV7RRQ2.js} +8 -8
  17. package/dist/{chunk-RO26VS3W.js → chunk-FXMLNKLT.js} +2 -2
  18. package/dist/{chunk-47KSHUCR.js → chunk-GOG3ZB7O.js} +16 -10
  19. package/dist/chunk-GOG3ZB7O.js.map +1 -0
  20. package/dist/{chunk-JQFO7QQN.js → chunk-GVICXJHW.js} +2 -2
  21. package/dist/{chunk-JQFO7QQN.js.map → chunk-GVICXJHW.js.map} +1 -1
  22. package/dist/{chunk-5EF7Z346.js → chunk-KG343GSG.js} +93 -48
  23. package/dist/chunk-KG343GSG.js.map +1 -0
  24. package/dist/{chunk-4HHRTA7Q.js → chunk-OAP6SASD.js} +3 -3
  25. package/dist/{chunk-4HHRTA7Q.js.map → chunk-OAP6SASD.js.map} +1 -1
  26. package/dist/chunk-OXAM2WVC.js +68 -0
  27. package/dist/chunk-OXAM2WVC.js.map +1 -0
  28. package/dist/{chunk-VAYCCUXW.js → chunk-PRE7KTM4.js} +2 -2
  29. package/dist/{chunk-ZE74H5BR.js → chunk-RW54ZMBM.js} +26 -20
  30. package/dist/chunk-RW54ZMBM.js.map +1 -0
  31. package/dist/{chunk-ML3NRPNB.js → chunk-UCZ24SUE.js} +5 -5
  32. package/dist/chunk-UCZ24SUE.js.map +1 -0
  33. package/dist/{chunk-3KATJIKO.js → chunk-UERERX6M.js} +2 -2
  34. package/dist/chunk-UERERX6M.js.map +1 -0
  35. package/dist/{chunk-IP7SMKIF.js → chunk-UJL4HI2R.js} +59 -60
  36. package/dist/chunk-UJL4HI2R.js.map +1 -0
  37. package/dist/{chunk-XXV3UFZL.js → chunk-ZLIHIUDQ.js} +8 -6
  38. package/dist/chunk-ZLIHIUDQ.js.map +1 -0
  39. package/dist/{claude-GOP6PFC7.js → claude-KIZYXTSG.js} +4 -2
  40. package/dist/{cleanup-7RWLBSLE.js → cleanup-6WYUD5SN.js} +19 -17
  41. package/dist/{cleanup-7RWLBSLE.js.map → cleanup-6WYUD5SN.js.map} +1 -1
  42. package/dist/cli.js +209 -73
  43. package/dist/cli.js.map +1 -1
  44. package/dist/{contribute-BS2L4FZR.js → contribute-7YJHZTO7.js} +3 -2
  45. package/dist/{contribute-BS2L4FZR.js.map → contribute-7YJHZTO7.js.map} +1 -1
  46. package/dist/{feedback-N4ECWIPF.js → feedback-752MGDPG.js} +10 -8
  47. package/dist/{feedback-N4ECWIPF.js.map → feedback-752MGDPG.js.map} +1 -1
  48. package/dist/{git-TDXKRTXM.js → git-TAFVDB3J.js} +5 -2
  49. package/dist/{ignite-VM64QO3J.js → ignite-OAMDUN27.js} +13 -11
  50. package/dist/{ignite-VM64QO3J.js.map → ignite-OAMDUN27.js.map} +1 -1
  51. package/dist/index.d.ts +20 -7
  52. package/dist/index.js +279 -297
  53. package/dist/index.js.map +1 -1
  54. package/dist/{init-G3T64SC4.js → init-7IIM35LQ.js} +12 -9
  55. package/dist/{init-G3T64SC4.js.map → init-7IIM35LQ.js.map} +1 -1
  56. package/dist/mcp/issue-management-server.js +8 -1
  57. package/dist/mcp/issue-management-server.js.map +1 -1
  58. package/dist/{neon-helpers-WPUACUVC.js → neon-helpers-5HBYO2VP.js} +2 -2
  59. package/dist/{open-KXDXEKRZ.js → open-FCHKQ77R.js} +27 -14
  60. package/dist/open-FCHKQ77R.js.map +1 -0
  61. package/dist/prompts/init-prompt.txt +10 -4
  62. package/dist/{rebase-Q7GMM7EI.js → rebase-Q7WXK566.js} +10 -8
  63. package/dist/{rebase-Q7GMM7EI.js.map → rebase-Q7WXK566.js.map} +1 -1
  64. package/dist/{run-PAWJJCSX.js → run-SJPM6YRI.js} +27 -14
  65. package/dist/run-SJPM6YRI.js.map +1 -0
  66. package/dist/schema/settings.schema.json +4 -4
  67. package/dist/{test-git-3WDLNQCA.js → test-git-DEUE656D.js} +5 -5
  68. package/dist/{test-prefix-EVGAWAJW.js → test-prefix-Y6Z6ZHSF.js} +5 -5
  69. package/dist/{test-tabs-RXDBZ6J7.js → test-tabs-PRMRSHKI.js} +3 -2
  70. package/dist/{test-tabs-RXDBZ6J7.js.map → test-tabs-PRMRSHKI.js.map} +1 -1
  71. package/package.json +2 -2
  72. package/dist/ClaudeContextManager-MUQSDY2E.js +0 -13
  73. package/dist/ClaudeService-HG4VQ7AW.js +0 -12
  74. package/dist/LoomLauncher-FLEMBCSQ.js.map +0 -1
  75. package/dist/chunk-3KATJIKO.js.map +0 -1
  76. package/dist/chunk-47KSHUCR.js.map +0 -1
  77. package/dist/chunk-5EF7Z346.js.map +0 -1
  78. package/dist/chunk-G2IEYOLQ.js.map +0 -1
  79. package/dist/chunk-IP7SMKIF.js.map +0 -1
  80. package/dist/chunk-MAVL6PJF.js.map +0 -1
  81. package/dist/chunk-ML3NRPNB.js.map +0 -1
  82. package/dist/chunk-XXV3UFZL.js.map +0 -1
  83. package/dist/chunk-ZE74H5BR.js.map +0 -1
  84. package/dist/open-KXDXEKRZ.js.map +0 -1
  85. package/dist/run-PAWJJCSX.js.map +0 -1
  86. package/dist/terminal-BIRBZ4AZ.js +0 -16
  87. package/dist/terminal-BIRBZ4AZ.js.map +0 -1
  88. /package/dist/{BranchNamingService-3OQPRSWT.js.map → BranchNamingService-JYO746H7.js.map} +0 -0
  89. /package/dist/{ClaudeContextManager-MUQSDY2E.js.map → ClaudeContextManager-5WPRJIIW.js.map} +0 -0
  90. /package/dist/{ClaudeService-HG4VQ7AW.js.map → ClaudeService-Z4KA7QOW.js.map} +0 -0
  91. /package/dist/{GitHubService-EBOETDIW.js.map → GitHubService-UAMH7DMF.js.map} +0 -0
  92. /package/dist/{SettingsManager-WHHFGSL7.js.map → SettingsManager-MTVX57WR.js.map} +0 -0
  93. /package/dist/{chunk-FIAT22G7.js.map → chunk-A2P7NZTB.js.map} +0 -0
  94. /package/dist/{chunk-C5QCTEQK.js.map → chunk-C7ASXK6J.js.map} +0 -0
  95. /package/dist/{chunk-AWOFAD5O.js.map → chunk-FOV7RRQ2.js.map} +0 -0
  96. /package/dist/{chunk-RO26VS3W.js.map → chunk-FXMLNKLT.js.map} +0 -0
  97. /package/dist/{chunk-VAYCCUXW.js.map → chunk-PRE7KTM4.js.map} +0 -0
  98. /package/dist/{claude-GOP6PFC7.js.map → claude-KIZYXTSG.js.map} +0 -0
  99. /package/dist/{git-TDXKRTXM.js.map → git-TAFVDB3J.js.map} +0 -0
  100. /package/dist/{neon-helpers-WPUACUVC.js.map → neon-helpers-5HBYO2VP.js.map} +0 -0
  101. /package/dist/{test-git-3WDLNQCA.js.map → test-git-DEUE656D.js.map} +0 -0
  102. /package/dist/{test-prefix-EVGAWAJW.js.map → test-prefix-Y6Z6ZHSF.js.map} +0 -0
@@ -3,11 +3,11 @@ import {
3
3
  ClaudeBranchNameStrategy,
4
4
  DefaultBranchNamingService,
5
5
  SimpleBranchNameStrategy
6
- } from "./chunk-3KATJIKO.js";
6
+ } from "./chunk-UERERX6M.js";
7
7
  import "./chunk-GEHQXLEI.js";
8
8
  export {
9
9
  ClaudeBranchNameStrategy,
10
10
  DefaultBranchNamingService,
11
11
  SimpleBranchNameStrategy
12
12
  };
13
- //# sourceMappingURL=BranchNamingService-3OQPRSWT.js.map
13
+ //# sourceMappingURL=BranchNamingService-JYO746H7.js.map
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ClaudeContextManager
4
+ } from "./chunk-C7ASXK6J.js";
5
+ import "./chunk-A2P7NZTB.js";
6
+ import "./chunk-WEN5C5DM.js";
7
+ import "./chunk-UCZ24SUE.js";
8
+ import "./chunk-ZLIHIUDQ.js";
9
+ import "./chunk-RW54ZMBM.js";
10
+ import "./chunk-UJL4HI2R.js";
11
+ import "./chunk-GEHQXLEI.js";
12
+ export {
13
+ ClaudeContextManager
14
+ };
15
+ //# sourceMappingURL=ClaudeContextManager-5WPRJIIW.js.map
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ClaudeService
4
+ } from "./chunk-A2P7NZTB.js";
5
+ import "./chunk-WEN5C5DM.js";
6
+ import "./chunk-UCZ24SUE.js";
7
+ import "./chunk-ZLIHIUDQ.js";
8
+ import "./chunk-RW54ZMBM.js";
9
+ import "./chunk-UJL4HI2R.js";
10
+ import "./chunk-GEHQXLEI.js";
11
+ export {
12
+ ClaudeService
13
+ };
14
+ //# sourceMappingURL=ClaudeService-Z4KA7QOW.js.map
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  GitHubService
4
- } from "./chunk-G2IEYOLQ.js";
4
+ } from "./chunk-F4ENT6AC.js";
5
5
  import "./chunk-3RUPPQRG.js";
6
6
  import "./chunk-JKXJ7BGL.js";
7
7
  import "./chunk-GEHQXLEI.js";
8
8
  export {
9
9
  GitHubService
10
10
  };
11
- //# sourceMappingURL=GitHubService-EBOETDIW.js.map
11
+ //# sourceMappingURL=GitHubService-UAMH7DMF.js.map
@@ -5,18 +5,21 @@ import {
5
5
  import "./chunk-ZT3YZB4K.js";
6
6
  import {
7
7
  ClaudeContextManager
8
- } from "./chunk-C5QCTEQK.js";
9
- import "./chunk-FIAT22G7.js";
10
- import "./chunk-XXV3UFZL.js";
8
+ } from "./chunk-C7ASXK6J.js";
9
+ import "./chunk-A2P7NZTB.js";
11
10
  import "./chunk-WEN5C5DM.js";
12
- import "./chunk-ML3NRPNB.js";
11
+ import "./chunk-UCZ24SUE.js";
12
+ import {
13
+ generateColorFromBranchName
14
+ } from "./chunk-ZZZWQGTS.js";
15
+ import "./chunk-ZLIHIUDQ.js";
13
16
  import {
14
17
  openMultipleTerminalWindows,
15
18
  openTerminalWindow
16
- } from "./chunk-ZE74H5BR.js";
19
+ } from "./chunk-RW54ZMBM.js";
17
20
  import {
18
- generateColorFromBranchName
19
- } from "./chunk-ZZZWQGTS.js";
21
+ getDotenvFlowFiles
22
+ } from "./chunk-UJL4HI2R.js";
20
23
  import {
21
24
  logger
22
25
  } from "./chunk-GEHQXLEI.js";
@@ -182,7 +185,7 @@ var LoomLauncher = class {
182
185
  workspacePath: options.worktreePath,
183
186
  command: devServerCommand,
184
187
  backgroundColor: colorData.rgb,
185
- includeEnvSetup: (options.sourceEnvOnStart ?? false) && existsSync(join(options.worktreePath, ".env")),
188
+ includeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),
186
189
  includePortExport: options.capabilities.includes("web"),
187
190
  ...options.port !== void 0 && { port: options.port }
188
191
  });
@@ -196,7 +199,7 @@ var LoomLauncher = class {
196
199
  await openTerminalWindow({
197
200
  workspacePath: options.worktreePath,
198
201
  backgroundColor: colorData.rgb,
199
- includeEnvSetup: (options.sourceEnvOnStart ?? false) && existsSync(join(options.worktreePath, ".env")),
202
+ includeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),
200
203
  includePortExport: options.capabilities.includes("web"),
201
204
  ...options.port !== void 0 && { port: options.port }
202
205
  });
@@ -207,7 +210,7 @@ var LoomLauncher = class {
207
210
  */
208
211
  async buildClaudeTerminalOptions(options) {
209
212
  const colorData = generateColorFromBranchName(options.branchName);
210
- const hasEnvFile = existsSync(join(options.worktreePath, ".env"));
213
+ const hasEnvFile = this.hasAnyEnvFiles(options.worktreePath);
211
214
  const claudeTitle = `Claude - ${this.formatIdentifier(options.workflowType, options.identifier)}`;
212
215
  const executable = options.executablePath ?? "iloom";
213
216
  let claudeCommand = `${executable} spin`;
@@ -238,7 +241,7 @@ var LoomLauncher = class {
238
241
  options.port,
239
242
  options.capabilities
240
243
  );
241
- const hasEnvFile = existsSync(join(options.worktreePath, ".env"));
244
+ const hasEnvFile = this.hasAnyEnvFiles(options.worktreePath);
242
245
  const devServerTitle = `Dev Server - ${this.formatIdentifier(options.workflowType, options.identifier)}`;
243
246
  return {
244
247
  workspacePath: options.worktreePath,
@@ -255,7 +258,7 @@ var LoomLauncher = class {
255
258
  */
256
259
  buildStandaloneTerminalOptions(options) {
257
260
  const colorData = generateColorFromBranchName(options.branchName);
258
- const hasEnvFile = existsSync(join(options.worktreePath, ".env"));
261
+ const hasEnvFile = this.hasAnyEnvFiles(options.worktreePath);
259
262
  const terminalTitle = `Terminal - ${this.formatIdentifier(options.workflowType, options.identifier)}`;
260
263
  return {
261
264
  workspacePath: options.worktreePath,
@@ -275,6 +278,14 @@ var LoomLauncher = class {
275
278
  const terminalTypes = terminals.map((t) => t.type).join(" + ");
276
279
  logger.info(`Multiple terminals opened: ${terminalTypes}`);
277
280
  }
281
+ /**
282
+ * Check if any dotenv-flow files exist in the workspace
283
+ * Checks all files: .env, .env.local, .env.{NODE_ENV}, .env.{NODE_ENV}.local
284
+ */
285
+ hasAnyEnvFiles(workspacePath) {
286
+ const envFiles = getDotenvFlowFiles();
287
+ return envFiles.some((file) => existsSync(join(workspacePath, file)));
288
+ }
278
289
  /**
279
290
  * Format identifier for terminal tab titles
280
291
  */
@@ -291,4 +302,4 @@ var LoomLauncher = class {
291
302
  export {
292
303
  LoomLauncher
293
304
  };
294
- //# sourceMappingURL=LoomLauncher-FLEMBCSQ.js.map
305
+ //# sourceMappingURL=LoomLauncher-FVZECY3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/LoomLauncher.ts","../src/utils/ide.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { openTerminalWindow, openMultipleTerminalWindows } from '../utils/terminal.js'\nimport type { TerminalWindowOptions } from '../utils/terminal.js'\nimport { openIdeWindow } from '../utils/ide.js'\nimport { getDevServerLaunchCommand } from '../utils/dev-server.js'\nimport { generateColorFromBranchName } from '../utils/color.js'\nimport { logger } from '../utils/logger.js'\nimport { ClaudeContextManager } from './ClaudeContextManager.js'\nimport type { SettingsManager } from './SettingsManager.js'\nimport type { Capability } from '../types/loom.js'\nimport { getDotenvFlowFiles } from '../utils/env.js'\n\nexport interface LaunchLoomOptions {\n\tenableClaude: boolean\n\tenableCode: boolean\n\tenableDevServer: boolean\n\tenableTerminal: boolean\n\tworktreePath: string\n\tbranchName: string\n\tport?: number\n\tcapabilities: Capability[]\n\tworkflowType: 'issue' | 'pr' | 'regular'\n\tidentifier: string | number\n\ttitle?: string\n\toneShot?: import('../types/index.js').OneShotMode\n\tsetArguments?: string[] // Raw --set arguments to forward\n\texecutablePath?: string // Executable path to use for spin command\n\tsourceEnvOnStart?: boolean // defaults to false if undefined\n}\n\n/**\n * LoomLauncher orchestrates opening loom components\n */\nexport class LoomLauncher {\n\tprivate claudeContext: ClaudeContextManager\n\tprivate settings?: SettingsManager\n\n\tconstructor(claudeContext?: ClaudeContextManager, settings?: SettingsManager) {\n\t\tthis.claudeContext = claudeContext ?? new ClaudeContextManager()\n\t\tif (settings !== undefined) {\n\t\t\tthis.settings = settings\n\t\t}\n\t}\n\n\t/**\n\t * Launch loom components based on individual flags\n\t */\n\tasync launchLoom(options: LaunchLoomOptions): Promise<void> {\n\t\tconst { enableClaude, enableCode, enableDevServer, enableTerminal } = options\n\n\t\tlogger.debug(`Launching loom components: Claude=${enableClaude}, Code=${enableCode}, DevServer=${enableDevServer}, Terminal=${enableTerminal}`)\n\n\t\tconst launchPromises: Promise<void>[] = []\n\n\t\t// Launch VSCode if enabled\n\t\tif (enableCode) {\n\t\t\tlogger.debug('Launching VSCode')\n\t\t\tlaunchPromises.push(this.launchVSCode(options))\n\t\t}\n\n\t\t// Build array of terminals to launch\n\t\tconst terminalsToLaunch: Array<{\n\t\t\ttype: 'claude' | 'devServer' | 'terminal'\n\t\t\toptions: TerminalWindowOptions\n\t\t}> = []\n\n\t\tif (enableDevServer) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'devServer',\n\t\t\t\toptions: await this.buildDevServerTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableTerminal) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'terminal',\n\t\t\t\toptions: this.buildStandaloneTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\tif (enableClaude) {\n\t\t\tterminalsToLaunch.push({\n\t\t\t\ttype: 'claude',\n\t\t\t\toptions: await this.buildClaudeTerminalOptions(options),\n\t\t\t})\n\t\t}\n\n\t\t// Launch terminals based on count\n\t\tif (terminalsToLaunch.length > 1) {\n\t\t\t// Multiple terminals - launch as tabs in single window\n\t\t\tlogger.debug(`Launching ${terminalsToLaunch.length} terminals in single window`)\n\t\t\tlaunchPromises.push(this.launchMultipleTerminals(terminalsToLaunch, options))\n\t\t} else if (terminalsToLaunch.length === 1) {\n\t\t\t// Single terminal - launch standalone\n\t\t\tconst terminal = terminalsToLaunch[0]\n\t\t\tif (!terminal) {\n\t\t\t\tthrow new Error('Terminal configuration is undefined')\n\t\t\t}\n\t\t\tconst terminalType = terminal.type\n\t\t\tlogger.debug(`Launching single ${terminalType} terminal`)\n\n\t\t\tif (terminalType === 'claude') {\n\t\t\t\tlaunchPromises.push(this.launchClaudeTerminal(options))\n\t\t\t} else if (terminalType === 'devServer') {\n\t\t\t\tlaunchPromises.push(this.launchDevServerTerminal(options))\n\t\t\t} else {\n\t\t\t\tlaunchPromises.push(this.launchStandaloneTerminal(options))\n\t\t\t}\n\t\t}\n\n\t\t// Wait for all components to launch\n\t\tawait Promise.all(launchPromises)\n\n\t\tlogger.success('loom launched successfully')\n\t}\n\n\t/**\n\t * Launch IDE (VSCode or configured alternative)\n\t */\n\tprivate async launchVSCode(options: LaunchLoomOptions): Promise<void> {\n\t\tconst ideConfig = await this.settings?.loadSettings().then((s) => s.ide)\n\t\tawait openIdeWindow(options.worktreePath, ideConfig)\n\t\tlogger.info('IDE opened')\n\t}\n\n\t/**\n\t * Launch Claude terminal\n\t */\n\tprivate async launchClaudeTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tawait this.claudeContext.launchWithContext({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\ttype: options.workflowType,\n\t\t\tidentifier: options.identifier,\n\t\t\tbranchName: options.branchName,\n\t\t\t...(options.title && { title: options.title }),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t\toneShot: options.oneShot ?? 'default',\n\t\t\t...(options.setArguments && { setArguments: options.setArguments }),\n\t\t\t...(options.executablePath && { executablePath: options.executablePath }),\n\t\t})\n\t\tlogger.info('Claude terminal opened')\n\t}\n\n\t/**\n\t * Launch dev server terminal\n\t */\n\tprivate async launchDevServerTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tconst colorData = generateColorFromBranchName(options.branchName)\n\t\tconst devServerCommand = await getDevServerLaunchCommand(\n\t\t\toptions.worktreePath,\n\t\t\toptions.port,\n\t\t\toptions.capabilities\n\t\t)\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\tbackgroundColor: colorData.rgb,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tlogger.info('Dev server terminal opened')\n\t}\n\n\t/**\n\t * Launch standalone terminal (no command, just workspace with env vars)\n\t */\n\tprivate async launchStandaloneTerminal(options: LaunchLoomOptions): Promise<void> {\n\t\tconst colorData = generateColorFromBranchName(options.branchName)\n\n\t\tawait openTerminalWindow({\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tbackgroundColor: colorData.rgb,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && this.hasAnyEnvFiles(options.worktreePath),\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t})\n\t\tlogger.info('Standalone terminal opened')\n\t}\n\n\t/**\n\t * Build terminal options for Claude\n\t */\n\tprivate async buildClaudeTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): Promise<TerminalWindowOptions> {\n\t\tconst colorData = generateColorFromBranchName(options.branchName)\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst claudeTitle = `Claude - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\tconst executable = options.executablePath ?? 'iloom'\n\t\tlet claudeCommand = `${executable} spin`\n\t\tif (options.oneShot !== undefined && options.oneShot !== 'default') {\n\t\t\tclaudeCommand += ` --one-shot=${options.oneShot}`\n\t\t}\n\t\tif (options.setArguments && options.setArguments.length > 0) {\n\t\t\tfor (const setArg of options.setArguments) {\n\t\t\t\tclaudeCommand += ` --set ${setArg}`\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: claudeCommand,\n\t\t\tbackgroundColor: colorData.rgb,\n\t\t\ttitle: claudeTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\t...(options.port !== undefined && { port: options.port, includePortExport: true }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for dev server\n\t */\n\tprivate async buildDevServerTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): Promise<TerminalWindowOptions> {\n\t\tconst colorData = generateColorFromBranchName(options.branchName)\n\t\tconst devServerCommand = await getDevServerLaunchCommand(\n\t\t\toptions.worktreePath,\n\t\t\toptions.port,\n\t\t\toptions.capabilities\n\t\t)\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst devServerTitle = `Dev Server - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tcommand: devServerCommand,\n\t\t\tbackgroundColor: colorData.rgb,\n\t\t\ttitle: devServerTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Build terminal options for standalone terminal (no command)\n\t */\n\tprivate buildStandaloneTerminalOptions(\n\t\toptions: LaunchLoomOptions\n\t): TerminalWindowOptions {\n\t\tconst colorData = generateColorFromBranchName(options.branchName)\n\t\tconst hasEnvFile = this.hasAnyEnvFiles(options.worktreePath)\n\t\tconst terminalTitle = `Terminal - ${this.formatIdentifier(options.workflowType, options.identifier)}`\n\n\t\treturn {\n\t\t\tworkspacePath: options.worktreePath,\n\t\t\tbackgroundColor: colorData.rgb,\n\t\t\ttitle: terminalTitle,\n\t\t\tincludeEnvSetup: (options.sourceEnvOnStart ?? false) && hasEnvFile,\n\t\t\tincludePortExport: options.capabilities.includes('web'),\n\t\t\t...(options.port !== undefined && { port: options.port }),\n\t\t}\n\t}\n\n\t/**\n\t * Launch multiple terminals (2+) as tabs in single window\n\t */\n\tprivate async launchMultipleTerminals(\n\t\tterminals: Array<{ type: string; options: TerminalWindowOptions }>,\n\t\t_options: LaunchLoomOptions\n\t): Promise<void> {\n\t\tconst terminalOptions = terminals.map((t) => t.options)\n\n\t\tawait openMultipleTerminalWindows(terminalOptions)\n\n\t\tconst terminalTypes = terminals.map((t) => t.type).join(' + ')\n\t\tlogger.info(`Multiple terminals opened: ${terminalTypes}`)\n\t}\n\n\t/**\n\t * Check if any dotenv-flow files exist in the workspace\n\t * Checks all files: .env, .env.local, .env.{NODE_ENV}, .env.{NODE_ENV}.local\n\t */\n\tprivate hasAnyEnvFiles(workspacePath: string): boolean {\n\t\tconst envFiles = getDotenvFlowFiles()\n\t\treturn envFiles.some(file => existsSync(join(workspacePath, file)))\n\t}\n\n\t/**\n\t * Format identifier for terminal tab titles\n\t */\n\tprivate formatIdentifier(workflowType: 'issue' | 'pr' | 'regular', identifier: string | number): string {\n\t\tif (workflowType === 'issue') {\n\t\t\treturn `Issue #${identifier}`\n\t\t} else if (workflowType === 'pr') {\n\t\t\treturn `PR #${identifier}`\n\t\t} else {\n\t\t\treturn `Branch: ${identifier}`\n\t\t}\n\t}\n}\n","import { execa } from 'execa'\nimport { logger } from './logger.js'\nimport type { IdeSettings } from '../lib/SettingsManager.js'\n\n// IDE preset configuration\nconst IDE_PRESETS = {\n\tvscode: { command: 'code', name: 'Visual Studio Code', args: [] },\n\tcursor: { command: 'cursor', name: 'Cursor', args: [] },\n\twebstorm: { command: 'webstorm', name: 'WebStorm', args: ['--nosplash'] },\n\tsublime: { command: 'subl', name: 'Sublime Text', args: [] },\n\tintellij: { command: 'idea', name: 'IntelliJ IDEA', args: ['--nosplash'] },\n\twindsurf: { command: 'surf', name: 'Windsurf', args: [] },\n} as const\n\ntype IdePreset = keyof typeof IDE_PRESETS\n\n// Resolve IDE configuration to command and args\nexport function getIdeConfig(ideSettings?: IdeSettings): {\n\tcommand: string\n\targs: string[]\n\tname: string\n} {\n\t// Default to vscode if not configured\n\tconst type = ideSettings?.type ?? 'vscode'\n\n\tconst preset = IDE_PRESETS[type as IdePreset]\n\treturn {\n\t\tcommand: preset.command,\n\t\targs: [...preset.args],\n\t\tname: preset.name,\n\t}\n}\n\n// Check if IDE is available\nexport async function isIdeAvailable(command: string): Promise<boolean> {\n\ttry {\n\t\tawait execa('command', ['-v', command], { shell: true, timeout: 5000 })\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// Get installation hint for IDE\nfunction getInstallHint(type: string): string {\n\tconst hints: Record<string, string> = {\n\t\tvscode:\n\t\t\t'Install command-line tools: Open VSCode > Command Palette > \"Shell Command: Install \\'code\\' command in PATH\"',\n\t\tcursor:\n\t\t\t'Install command-line tools: Open Cursor > Command Palette > \"Install \\'cursor\\' command in PATH\"',\n\t\twebstorm: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\tsublime:\n\t\t\t'Create symlink: ln -s \"/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl\" /usr/local/bin/subl',\n\t\tintellij: 'Install via JetBrains Toolbox > Settings > Shell Scripts > Enable',\n\t\twindsurf:\n\t\t\t'Install command-line tools during Windsurf installation or create symlink manually',\n\t}\n\treturn hints[type] ?? `Ensure the IDE command is available in your PATH`\n}\n\n// Open IDE window for workspace\nexport async function openIdeWindow(\n\tworkspacePath: string,\n\tideSettings?: IdeSettings\n): Promise<void> {\n\tconst config = getIdeConfig(ideSettings)\n\tconst available = await isIdeAvailable(config.command)\n\n\tif (!available) {\n\t\tconst type = ideSettings?.type ?? 'vscode'\n\t\tthrow new Error(\n\t\t\t`${config.name} is not available. The \"${config.command}\" command was not found in PATH.\\n` +\n\t\t\t\tgetInstallHint(type)\n\t\t)\n\t}\n\n\ttry {\n\t\tawait execa(config.command, [...config.args, workspacePath])\n\t\tlogger.debug(`Opened ${config.name} for workspace: ${workspacePath}`)\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to open ${config.name}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t)\n\t}\n}\n"],"mappings":"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","names":[]}