@iloom/cli 0.1.18 → 0.2.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.
Files changed (106) hide show
  1. package/README.md +53 -6
  2. package/dist/ClaudeContextManager-LVCYRM6Q.js +13 -0
  3. package/dist/ClaudeService-WVTWB3DK.js +12 -0
  4. package/dist/{GitHubService-SH4H6VS5.js → GitHubService-7E2S5NNZ.js} +3 -3
  5. package/dist/{LoomLauncher-FB2MV2ZI.js → LoomLauncher-CTSWJL35.js} +7 -7
  6. package/dist/{PromptTemplateManager-WM5GIPEF.js → PromptTemplateManager-WII75TKH.js} +2 -2
  7. package/dist/README.md +771 -0
  8. package/dist/{SettingsManager-SKLUVE3K.js → SettingsManager-XOYCLH3D.js} +2 -2
  9. package/dist/{add-issue-L5HX6LEV.js → add-issue-OBI325W7.js} +7 -7
  10. package/dist/{chunk-SLIMABFA.js → chunk-2PLUQT6J.js} +2 -2
  11. package/dist/{chunk-VVH3ANF2.js → chunk-4IV6W4U5.js} +4 -4
  12. package/dist/{chunk-PV3GAXQO.js → chunk-6LEQW46Y.js} +2 -2
  13. package/dist/{chunk-6OTVPRXH.js → chunk-CVLAZRNB.js} +2 -2
  14. package/dist/{chunk-FXV24OYZ.js → chunk-DJUGYNQE.js} +9 -2
  15. package/dist/{chunk-FXV24OYZ.js.map → chunk-DJUGYNQE.js.map} +1 -1
  16. package/dist/{chunk-KOCQAD2E.js → chunk-HBVFXN7R.js} +3 -3
  17. package/dist/{chunk-HURVAQRK.js → chunk-LHP6ROUM.js} +4 -4
  18. package/dist/{chunk-PXZBAC2M.js → chunk-MFU53H6J.js} +2 -2
  19. package/dist/{chunk-L4QGC27H.js → chunk-PVAVNJKS.js} +13 -1
  20. package/dist/chunk-PVAVNJKS.js.map +1 -0
  21. package/dist/{chunk-PR7FKQBG.js → chunk-RF2YI2XJ.js} +2 -2
  22. package/dist/{chunk-DGEKUT7Q.js → chunk-SWCRXDZC.js} +34 -6
  23. package/dist/chunk-SWCRXDZC.js.map +1 -0
  24. package/dist/{chunk-Q2KYPAH2.js → chunk-SYOSCMIT.js} +6 -6
  25. package/dist/{chunk-VYQLLHZ7.js → chunk-T3KEIB4D.js} +6 -2
  26. package/dist/{chunk-VYQLLHZ7.js.map → chunk-T3KEIB4D.js.map} +1 -1
  27. package/dist/{chunk-IIPTBZQW.js → chunk-TS6DL67T.js} +2 -2
  28. package/dist/{chunk-IO4WFTL2.js → chunk-VETG35MF.js} +2 -2
  29. package/dist/{chunk-RSRO7564.js → chunk-ZE74H5BR.js} +28 -3
  30. package/dist/chunk-ZE74H5BR.js.map +1 -0
  31. package/dist/{claude-7LUVDZZ4.js → claude-ZIWDG4XG.js} +2 -2
  32. package/dist/{cleanup-ZHROIBSQ.js → cleanup-FEIVZSIV.js} +5 -5
  33. package/dist/cli.js +41 -31
  34. package/dist/cli.js.map +1 -1
  35. package/dist/contribute-EMZKCAC6.js +259 -0
  36. package/dist/contribute-EMZKCAC6.js.map +1 -0
  37. package/dist/{enhance-VVMAKMVZ.js → enhance-MNA4ZGXW.js} +7 -7
  38. package/dist/{feedback-AKHD7QIM.js → feedback-LFNMQBAZ.js} +6 -6
  39. package/dist/{finish-WGPISUEH.js → finish-TX5CJICB.js} +411 -17
  40. package/dist/finish-TX5CJICB.js.map +1 -0
  41. package/dist/{git-OUYMVYJX.js → git-WC6HZLOT.js} +2 -2
  42. package/dist/{ignite-JEN3K3OT.js → ignite-MQWVJEAB.js} +125 -10
  43. package/dist/ignite-MQWVJEAB.js.map +1 -0
  44. package/dist/index.d.ts +23 -0
  45. package/dist/index.js +75 -7
  46. package/dist/index.js.map +1 -1
  47. package/dist/{init-EVUT4ZQJ.js → init-GJDYN2IK.js} +7 -7
  48. package/dist/mcp/{claude-YHHHLSXH.js → claude-NDFOCQQQ.js} +2 -2
  49. package/dist/mcp/github-comment-server.js.map +1 -1
  50. package/dist/mcp/{terminal-SDCMDVD7.js → terminal-OMNRFWB3.js} +28 -3
  51. package/dist/mcp/terminal-OMNRFWB3.js.map +1 -0
  52. package/dist/{open-ETZUFSE4.js → open-NXSN7XOC.js} +4 -4
  53. package/dist/prompts/init-prompt.txt +32 -1
  54. package/dist/prompts/issue-prompt.txt +141 -9
  55. package/dist/{rebase-KBWFDZCN.js → rebase-DUNFOJVS.js} +6 -6
  56. package/dist/{remote-GJEZWRCC.js → remote-ZCXJVVNW.js} +4 -2
  57. package/dist/{run-4SVQ3WEU.js → run-O7ZK7CKA.js} +4 -4
  58. package/dist/schema/settings.schema.json +18 -0
  59. package/dist/{start-2NEZU7SE.js → start-73I5W7WW.js} +16 -16
  60. package/dist/{terminal-3D6TUAKJ.js → terminal-BIRBZ4AZ.js} +2 -2
  61. package/dist/{test-git-MKZATGZN.js → test-git-T76HOTIA.js} +3 -3
  62. package/dist/{test-prefix-ZNLWDI3K.js → test-prefix-6HJUVQMH.js} +3 -3
  63. package/dist/{test-tabs-JRKY3QMM.js → test-tabs-RXDBZ6J7.js} +2 -2
  64. package/package.json +3 -2
  65. package/dist/ClaudeContextManager-LD3VB6EM.js +0 -13
  66. package/dist/ClaudeService-CFFI7DD5.js +0 -12
  67. package/dist/chunk-DGEKUT7Q.js.map +0 -1
  68. package/dist/chunk-L4QGC27H.js.map +0 -1
  69. package/dist/chunk-RSRO7564.js.map +0 -1
  70. package/dist/finish-WGPISUEH.js.map +0 -1
  71. package/dist/ignite-JEN3K3OT.js.map +0 -1
  72. package/dist/mcp/terminal-SDCMDVD7.js.map +0 -1
  73. /package/dist/{ClaudeContextManager-LD3VB6EM.js.map → ClaudeContextManager-LVCYRM6Q.js.map} +0 -0
  74. /package/dist/{ClaudeService-CFFI7DD5.js.map → ClaudeService-WVTWB3DK.js.map} +0 -0
  75. /package/dist/{GitHubService-SH4H6VS5.js.map → GitHubService-7E2S5NNZ.js.map} +0 -0
  76. /package/dist/{LoomLauncher-FB2MV2ZI.js.map → LoomLauncher-CTSWJL35.js.map} +0 -0
  77. /package/dist/{PromptTemplateManager-WM5GIPEF.js.map → PromptTemplateManager-WII75TKH.js.map} +0 -0
  78. /package/dist/{SettingsManager-SKLUVE3K.js.map → SettingsManager-XOYCLH3D.js.map} +0 -0
  79. /package/dist/{add-issue-L5HX6LEV.js.map → add-issue-OBI325W7.js.map} +0 -0
  80. /package/dist/{chunk-SLIMABFA.js.map → chunk-2PLUQT6J.js.map} +0 -0
  81. /package/dist/{chunk-VVH3ANF2.js.map → chunk-4IV6W4U5.js.map} +0 -0
  82. /package/dist/{chunk-PV3GAXQO.js.map → chunk-6LEQW46Y.js.map} +0 -0
  83. /package/dist/{chunk-6OTVPRXH.js.map → chunk-CVLAZRNB.js.map} +0 -0
  84. /package/dist/{chunk-KOCQAD2E.js.map → chunk-HBVFXN7R.js.map} +0 -0
  85. /package/dist/{chunk-HURVAQRK.js.map → chunk-LHP6ROUM.js.map} +0 -0
  86. /package/dist/{chunk-PXZBAC2M.js.map → chunk-MFU53H6J.js.map} +0 -0
  87. /package/dist/{chunk-PR7FKQBG.js.map → chunk-RF2YI2XJ.js.map} +0 -0
  88. /package/dist/{chunk-Q2KYPAH2.js.map → chunk-SYOSCMIT.js.map} +0 -0
  89. /package/dist/{chunk-IIPTBZQW.js.map → chunk-TS6DL67T.js.map} +0 -0
  90. /package/dist/{chunk-IO4WFTL2.js.map → chunk-VETG35MF.js.map} +0 -0
  91. /package/dist/{claude-7LUVDZZ4.js.map → claude-ZIWDG4XG.js.map} +0 -0
  92. /package/dist/{cleanup-ZHROIBSQ.js.map → cleanup-FEIVZSIV.js.map} +0 -0
  93. /package/dist/{enhance-VVMAKMVZ.js.map → enhance-MNA4ZGXW.js.map} +0 -0
  94. /package/dist/{feedback-AKHD7QIM.js.map → feedback-LFNMQBAZ.js.map} +0 -0
  95. /package/dist/{git-OUYMVYJX.js.map → git-WC6HZLOT.js.map} +0 -0
  96. /package/dist/{init-EVUT4ZQJ.js.map → init-GJDYN2IK.js.map} +0 -0
  97. /package/dist/mcp/{claude-YHHHLSXH.js.map → claude-NDFOCQQQ.js.map} +0 -0
  98. /package/dist/{open-ETZUFSE4.js.map → open-NXSN7XOC.js.map} +0 -0
  99. /package/dist/{rebase-KBWFDZCN.js.map → rebase-DUNFOJVS.js.map} +0 -0
  100. /package/dist/{remote-GJEZWRCC.js.map → remote-ZCXJVVNW.js.map} +0 -0
  101. /package/dist/{run-4SVQ3WEU.js.map → run-O7ZK7CKA.js.map} +0 -0
  102. /package/dist/{start-2NEZU7SE.js.map → start-73I5W7WW.js.map} +0 -0
  103. /package/dist/{terminal-3D6TUAKJ.js.map → terminal-BIRBZ4AZ.js.map} +0 -0
  104. /package/dist/{test-git-MKZATGZN.js.map → test-git-T76HOTIA.js.map} +0 -0
  105. /package/dist/{test-prefix-ZNLWDI3K.js.map → test-prefix-6HJUVQMH.js.map} +0 -0
  106. /package/dist/{test-tabs-JRKY3QMM.js.map → test-tabs-RXDBZ6J7.js.map} +0 -0
@@ -11,7 +11,7 @@ import {
11
11
  isPRBranch,
12
12
  isValidGitRepo,
13
13
  parseWorktreeList
14
- } from "./chunk-KOCQAD2E.js";
14
+ } from "./chunk-HBVFXN7R.js";
15
15
 
16
16
  // src/lib/GitWorktreeManager.ts
17
17
  import path from "path";
@@ -386,4 +386,4 @@ var GitWorktreeManager = class {
386
386
  export {
387
387
  GitWorktreeManager
388
388
  };
389
- //# sourceMappingURL=chunk-IO4WFTL2.js.map
389
+ //# sourceMappingURL=chunk-VETG35MF.js.map
@@ -22,10 +22,13 @@ async function openTerminalWindow(options) {
22
22
  `Terminal window launching not yet supported on ${platform}. Currently only macOS is supported.`
23
23
  );
24
24
  }
25
- const applescript = buildAppleScript(options);
25
+ const hasITerm2 = await detectITerm2();
26
+ const applescript = hasITerm2 ? buildITerm2SingleTabScript(options) : buildAppleScript(options);
26
27
  try {
27
28
  await execa("osascript", ["-e", applescript]);
28
- await execa("osascript", ["-e", 'tell application "Terminal" to activate']);
29
+ if (!hasITerm2) {
30
+ await execa("osascript", ["-e", 'tell application "Terminal" to activate']);
31
+ }
29
32
  } catch (error) {
30
33
  throw new Error(
31
34
  `Failed to open terminal window: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -74,6 +77,28 @@ function escapePathForAppleScript(path) {
74
77
  function escapeForAppleScript(command) {
75
78
  return command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
76
79
  }
80
+ function buildITerm2SingleTabScript(options) {
81
+ const command = buildCommandSequence(options);
82
+ let script = 'tell application id "com.googlecode.iterm2"\n';
83
+ script += " create window with default profile\n";
84
+ script += " set s1 to current session of current window\n\n";
85
+ if (options.backgroundColor) {
86
+ const { r, g, b } = options.backgroundColor;
87
+ script += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
88
+ `;
89
+ }
90
+ script += ` tell s1 to write text "${escapeForAppleScript(command)}"
91
+
92
+ `;
93
+ if (options.title) {
94
+ script += ` set name of s1 to "${escapeForAppleScript(options.title)}"
95
+
96
+ `;
97
+ }
98
+ script += " activate\n";
99
+ script += "end tell";
100
+ return script;
101
+ }
77
102
  function buildCommandSequence(options) {
78
103
  const {
79
104
  workspacePath,
@@ -200,4 +225,4 @@ export {
200
225
  openMultipleTerminalWindows,
201
226
  openDualTerminalWindow
202
227
  };
203
- //# sourceMappingURL=chunk-RSRO7564.js.map
228
+ //# sourceMappingURL=chunk-ZE74H5BR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/terminal.ts"],"sourcesContent":["import { execa } from 'execa'\nimport { existsSync } from 'node:fs'\nimport type { Platform } from '../types/index.js'\n\nexport interface TerminalWindowOptions {\n\tworkspacePath?: string\n\tcommand?: string\n\tbackgroundColor?: { r: number; g: number; b: number }\n\tport?: number\n\tincludeEnvSetup?: boolean // source .env\n\tincludePortExport?: boolean // export PORT=<port>\n\ttitle?: string // Terminal tab title\n}\n\n/**\n * Detect current platform\n */\nexport function detectPlatform(): Platform {\n\tconst platform = process.platform\n\tif (platform === 'darwin') return 'darwin'\n\tif (platform === 'linux') return 'linux'\n\tif (platform === 'win32') return 'win32'\n\treturn 'unsupported'\n}\n\n/**\n * Detect if iTerm2 is installed on macOS\n * Returns false on non-macOS platforms\n */\nexport async function detectITerm2(): Promise<boolean> {\n\tconst platform = detectPlatform()\n\tif (platform !== 'darwin') return false\n\n\t// Check if iTerm.app exists at standard location\n\treturn existsSync('/Applications/iTerm.app')\n}\n\n/**\n * Open new terminal window with specified options\n * Currently supports macOS only\n */\nexport async function openTerminalWindow(\n\toptions: TerminalWindowOptions\n): Promise<void> {\n\tconst platform = detectPlatform()\n\n\tif (platform !== 'darwin') {\n\t\tthrow new Error(\n\t\t\t`Terminal window launching not yet supported on ${platform}. ` +\n\t\t\t\t`Currently only macOS is supported.`\n\t\t)\n\t}\n\n\t// Detect if iTerm2 is available\n\tconst hasITerm2 = await detectITerm2()\n\n\t// Build appropriate AppleScript based on terminal availability\n\tconst applescript = hasITerm2\n\t\t? buildITerm2SingleTabScript(options)\n\t\t: buildAppleScript(options)\n\n\ttry {\n\t\tawait execa('osascript', ['-e', applescript])\n\n\t\t// Activate the appropriate terminal application (only needed for Terminal.app)\n\t\t// iTerm2 script includes its own activation\n\t\tif (!hasITerm2) {\n\t\t\tawait execa('osascript', ['-e', 'tell application \"Terminal\" to activate'])\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to open terminal window: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t)\n\t}\n}\n\n/**\n * Build AppleScript for macOS Terminal.app\n */\nfunction buildAppleScript(options: TerminalWindowOptions): string {\n\tconst {\n\t\tworkspacePath,\n\t\tcommand,\n\t\tbackgroundColor,\n\t\tport,\n\t\tincludeEnvSetup,\n\t\tincludePortExport,\n\t} = options\n\n\t// Build command sequence\n\tconst commands: string[] = []\n\n\t// Navigate to workspace\n\tif (workspacePath) {\n\t\tcommands.push(`cd '${escapePathForAppleScript(workspacePath)}'`)\n\t}\n\n\t// Source .env file\n\tif (includeEnvSetup) {\n\t\tcommands.push('source .env')\n\t}\n\n\t// Export PORT variable\n\tif (includePortExport && port !== undefined) {\n\t\tcommands.push(`export PORT=${port}`)\n\t}\n\n\t// Add custom command\n\tif (command) {\n\t\tcommands.push(command)\n\t}\n\n\t// Join with &&\n\tconst fullCommand = commands.join(' && ')\n\n\t// Prefix with space to prevent shell history pollution\n\t// Most shells (bash/zsh) ignore commands starting with space when HISTCONTROL=ignorespace\n\tconst historyFreeCommand = ` ${fullCommand}`\n\n\t// Build AppleScript\n\tlet script = `tell application \"Terminal\"\\n`\n\tscript += ` set newTab to do script \"${escapeForAppleScript(historyFreeCommand)}\"\\n`\n\n\t// Apply background color if provided\n\tif (backgroundColor) {\n\t\tconst { r, g, b } = backgroundColor\n\t\t// Convert 8-bit RGB (0-255) to 16-bit RGB (0-65535)\n\t\tscript += ` set background color of newTab to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}\\n`\n\t}\n\n\tscript += `end tell`\n\n\treturn script\n}\n\n/**\n * Escape path for AppleScript string\n * Single quotes in path need special escaping\n */\nfunction escapePathForAppleScript(path: string): string {\n\t// Replace single quote with '\\''\n\treturn path.replace(/'/g, \"'\\\\''\")\n}\n\n/**\n * Escape command for AppleScript do script\n * Must handle double quotes and backslashes\n */\nfunction escapeForAppleScript(command: string): string {\n\treturn (\n\t\tcommand\n\t\t\t.replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n\t\t\t.replace(/\"/g, '\\\\\"') // Escape double quotes\n\t)\n}\n\n/**\n * Build iTerm2 AppleScript for single tab\n */\nfunction buildITerm2SingleTabScript(options: TerminalWindowOptions): string {\n\tconst command = buildCommandSequence(options)\n\n\tlet script = 'tell application id \"com.googlecode.iterm2\"\\n'\n\tscript += ' create window with default profile\\n'\n\tscript += ' set s1 to current session of current window\\n\\n'\n\n\t// Set background color\n\tif (options.backgroundColor) {\n\t\tconst { r, g, b } = options.backgroundColor\n\t\tscript += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}\\n`\n\t}\n\n\t// Execute command\n\tscript += ` tell s1 to write text \"${escapeForAppleScript(command)}\"\\n\\n`\n\n\t// Set session name (tab title)\n\tif (options.title) {\n\t\tscript += ` set name of s1 to \"${escapeForAppleScript(options.title)}\"\\n\\n`\n\t}\n\n\t// Activate iTerm2\n\tscript += ' activate\\n'\n\tscript += 'end tell'\n\n\treturn script\n}\n\n/**\n * Build command sequence for terminal\n */\nfunction buildCommandSequence(options: TerminalWindowOptions): string {\n\tconst {\n\t\tworkspacePath,\n\t\tcommand,\n\t\tport,\n\t\tincludeEnvSetup,\n\t\tincludePortExport,\n\t} = options\n\n\tconst commands: string[] = []\n\n\t// Navigate to workspace\n\tif (workspacePath) {\n\t\tcommands.push(`cd '${escapePathForAppleScript(workspacePath)}'`)\n\t}\n\n\t// Source .env file\n\tif (includeEnvSetup) {\n\t\tcommands.push('source .env')\n\t}\n\n\t// Export PORT variable\n\tif (includePortExport && port !== undefined) {\n\t\tcommands.push(`export PORT=${port}`)\n\t}\n\n\t// Add custom command\n\tif (command) {\n\t\tcommands.push(command)\n\t}\n\n\t// Join with &&\n\tconst fullCommand = commands.join(' && ')\n\n\t// Prefix with space to prevent shell history pollution\n\treturn ` ${fullCommand}`\n}\n\n/**\n * Build iTerm2 AppleScript for multiple tabs (2+) in single window\n */\nfunction buildITerm2MultiTabScript(\n\toptionsArray: TerminalWindowOptions[]\n): string {\n\tif (optionsArray.length < 2) {\n\t\tthrow new Error('buildITerm2MultiTabScript requires at least 2 terminal options')\n\t}\n\n\tlet script = 'tell application id \"com.googlecode.iterm2\"\\n'\n\tscript += ' create window with default profile\\n'\n\tscript += ' set newWindow to current window\\n'\n\n\t// First tab\n\tconst options1 = optionsArray[0]\n\tif (!options1) {\n\t\tthrow new Error('First terminal option is undefined')\n\t}\n\tconst command1 = buildCommandSequence(options1)\n\n\tscript += ' set s1 to current session of newWindow\\n\\n'\n\n\t// Set background color for first tab\n\tif (options1.backgroundColor) {\n\t\tconst { r, g, b } = options1.backgroundColor\n\t\tscript += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}\\n`\n\t}\n\n\t// Execute command in first tab\n\tscript += ` tell s1 to write text \"${escapeForAppleScript(command1)}\"\\n\\n`\n\n\t// Set tab title for first tab\n\tif (options1.title) {\n\t\tscript += ` set name of s1 to \"${escapeForAppleScript(options1.title)}\"\\n\\n`\n\t}\n\n\t// Subsequent tabs (2, 3, ...)\n\tfor (let i = 1; i < optionsArray.length; i++) {\n\t\tconst options = optionsArray[i]\n\t\tif (!options) {\n\t\t\tthrow new Error(`Terminal option at index ${i} is undefined`)\n\t\t}\n\t\tconst command = buildCommandSequence(options)\n\t\tconst sessionVar = `s${i + 1}`\n\n\t\t// Create tab\n\t\tscript += ' tell newWindow\\n'\n\t\tscript += ` set newTab${i} to (create tab with default profile)\\n`\n\t\tscript += ' end tell\\n'\n\t\tscript += ` set ${sessionVar} to current session of newTab${i}\\n\\n`\n\n\t\t// Set background color\n\t\tif (options.backgroundColor) {\n\t\t\tconst { r, g, b } = options.backgroundColor\n\t\t\tscript += ` set background color of ${sessionVar} to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}\\n`\n\t\t}\n\n\t\t// Execute command\n\t\tscript += ` tell ${sessionVar} to write text \"${escapeForAppleScript(command)}\"\\n\\n`\n\n\t\t// Set tab title\n\t\tif (options.title) {\n\t\t\tscript += ` set name of ${sessionVar} to \"${escapeForAppleScript(options.title)}\"\\n\\n`\n\t\t}\n\t}\n\n\t// Activate iTerm2\n\tscript += ' activate\\n'\n\tscript += 'end tell'\n\n\treturn script\n}\n\n/**\n * Open multiple terminal windows/tabs (2+) with specified options\n * If iTerm2 is available on macOS, creates single window with multiple tabs\n * Otherwise falls back to multiple separate Terminal.app windows\n */\nexport async function openMultipleTerminalWindows(\n\toptionsArray: TerminalWindowOptions[]\n): Promise<void> {\n\tif (optionsArray.length < 2) {\n\t\tthrow new Error('openMultipleTerminalWindows requires at least 2 terminal options. Use openTerminalWindow for single terminal.')\n\t}\n\n\tconst platform = detectPlatform()\n\n\tif (platform !== 'darwin') {\n\t\tthrow new Error(\n\t\t\t`Terminal window launching not yet supported on ${platform}. ` +\n\t\t\t\t`Currently only macOS is supported.`\n\t\t)\n\t}\n\n\t// Detect if iTerm2 is available\n\tconst hasITerm2 = await detectITerm2()\n\n\tif (hasITerm2) {\n\t\t// Use iTerm2 with multiple tabs in single window\n\t\tconst applescript = buildITerm2MultiTabScript(optionsArray)\n\n\t\ttry {\n\t\t\tawait execa('osascript', ['-e', applescript])\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to open iTerm2 window: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t}\n\t} else {\n\t\t// Fall back to multiple Terminal.app windows\n\t\tfor (let i = 0; i < optionsArray.length; i++) {\n\t\t\tconst options = optionsArray[i]\n\t\t\tif (!options) {\n\t\t\t\tthrow new Error(`Terminal option at index ${i} is undefined`)\n\t\t\t}\n\t\t\tawait openTerminalWindow(options)\n\n\t\t\t// Brief pause between terminals (except after last one)\n\t\t\tif (i < optionsArray.length - 1) {\n\t\t\t\t// eslint-disable-next-line no-undef\n\t\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, 1000))\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Open dual terminal windows/tabs with specified options\n * If iTerm2 is available on macOS, creates single window with two tabs\n * Otherwise falls back to two separate Terminal.app windows\n */\nexport async function openDualTerminalWindow(\n\toptions1: TerminalWindowOptions,\n\toptions2: TerminalWindowOptions\n): Promise<void> {\n\t// Delegate to openMultipleTerminalWindows for consistency\n\tawait openMultipleTerminalWindows([options1, options2])\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  getClaudeVersion,
6
6
  launchClaude,
7
7
  launchClaudeInNewTerminalWindow
8
- } from "./chunk-PXZBAC2M.js";
8
+ } from "./chunk-MFU53H6J.js";
9
9
  import "./chunk-GEHQXLEI.js";
10
10
  export {
11
11
  detectClaudeCli,
@@ -14,4 +14,4 @@ export {
14
14
  launchClaude,
15
15
  launchClaudeInNewTerminalWindow
16
16
  };
17
- //# sourceMappingURL=claude-7LUVDZZ4.js.map
17
+ //# sourceMappingURL=claude-ZIWDG4XG.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ResourceCleanup
4
- } from "./chunk-Q2KYPAH2.js";
4
+ } from "./chunk-SYOSCMIT.js";
5
5
  import {
6
6
  IdentifierParser
7
7
  } from "./chunk-H4E4THUZ.js";
@@ -23,11 +23,11 @@ import {
23
23
  import "./chunk-2ZPFJQ3B.js";
24
24
  import {
25
25
  GitWorktreeManager
26
- } from "./chunk-IO4WFTL2.js";
26
+ } from "./chunk-VETG35MF.js";
27
27
  import {
28
28
  SettingsManager
29
- } from "./chunk-VYQLLHZ7.js";
30
- import "./chunk-KOCQAD2E.js";
29
+ } from "./chunk-T3KEIB4D.js";
30
+ import "./chunk-HBVFXN7R.js";
31
31
  import {
32
32
  promptConfirmation
33
33
  } from "./chunk-JNKJ7NJV.js";
@@ -405,4 +405,4 @@ var CleanupCommand = class {
405
405
  export {
406
406
  CleanupCommand
407
407
  };
408
- //# sourceMappingURL=cleanup-ZHROIBSQ.js.map
408
+ //# sourceMappingURL=cleanup-FEIVZSIV.js.map
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ShellCompletion
4
- } from "./chunk-PV3GAXQO.js";
4
+ } from "./chunk-6LEQW46Y.js";
5
5
  import {
6
6
  GitWorktreeManager
7
- } from "./chunk-IO4WFTL2.js";
8
- import "./chunk-KOCQAD2E.js";
7
+ } from "./chunk-VETG35MF.js";
8
+ import "./chunk-HBVFXN7R.js";
9
9
  import {
10
10
  logger
11
11
  } from "./chunk-GEHQXLEI.js";
@@ -71,15 +71,15 @@ program.name("iloom").description(packageJson.description).version(packageJson.v
71
71
  async function validateSettingsForCommand(command) {
72
72
  var _a, _b;
73
73
  const commandName = command.args[0] ?? "";
74
- const bypassCommands = ["help", "init", "update"];
74
+ const bypassCommands = ["help", "init", "update", "contribute"];
75
75
  if (bypassCommands.includes(commandName)) {
76
76
  return;
77
77
  }
78
78
  try {
79
- const { SettingsManager } = await import("./SettingsManager-SKLUVE3K.js");
79
+ const { SettingsManager } = await import("./SettingsManager-XOYCLH3D.js");
80
80
  const settingsManager = new SettingsManager();
81
81
  const settings = await settingsManager.loadSettings();
82
- const { hasMultipleRemotes } = await import("./remote-GJEZWRCC.js");
82
+ const { hasMultipleRemotes } = await import("./remote-ZCXJVVNW.js");
83
83
  const multipleRemotes = await hasMultipleRemotes();
84
84
  if (multipleRemotes && !((_b = (_a = settings.issueManagement) == null ? void 0 : _a.github) == null ? void 0 : _b.remote)) {
85
85
  await autoLaunchInitForMultipleRemotes();
@@ -102,17 +102,17 @@ async function autoLaunchInitForMultipleRemotes() {
102
102
  await waitForKeypress("Press any key to start configuration...");
103
103
  logger.info("");
104
104
  try {
105
- const { InitCommand } = await import("./init-EVUT4ZQJ.js");
105
+ const { InitCommand } = await import("./init-GJDYN2IK.js");
106
106
  const initCommand = new InitCommand();
107
107
  const customInitialMessage = "Help me configure which git remote iloom should use for GitHub operations. I have multiple remotes and need to select the correct one.";
108
108
  await initCommand.execute(customInitialMessage);
109
109
  logger.info("");
110
110
  logger.info("Configuration complete! Continuing with your original command...");
111
111
  logger.info("");
112
- const { SettingsManager } = await import("./SettingsManager-SKLUVE3K.js");
112
+ const { SettingsManager } = await import("./SettingsManager-XOYCLH3D.js");
113
113
  const settingsManager = new SettingsManager();
114
114
  const settings = await settingsManager.loadSettings();
115
- const { hasMultipleRemotes } = await import("./remote-GJEZWRCC.js");
115
+ const { hasMultipleRemotes } = await import("./remote-ZCXJVVNW.js");
116
116
  const multipleRemotes = await hasMultipleRemotes();
117
117
  if (multipleRemotes && !((_b = (_a = settings.issueManagement) == null ? void 0 : _a.github) == null ? void 0 : _b.remote)) {
118
118
  logger.error("Configuration incomplete: GitHub remote is still not configured.");
@@ -141,7 +141,7 @@ program.command("start").alias("create").alias("up").description("Create isolate
141
141
  process.exit(1);
142
142
  }
143
143
  }
144
- const { StartCommand } = await import("./start-2NEZU7SE.js");
144
+ const { StartCommand } = await import("./start-73I5W7WW.js");
145
145
  const command = new StartCommand();
146
146
  await command.execute({ identifier: finalIdentifier, options });
147
147
  } catch (error) {
@@ -151,7 +151,7 @@ program.command("start").alias("create").alias("up").description("Create isolate
151
151
  });
152
152
  program.command("add-issue").alias("a").description("Create and enhance GitHub issue without starting workspace").argument("<description>", "Natural language description of the issue (>50 chars, >2 spaces)").action(async (description) => {
153
153
  try {
154
- const { AddIssueCommand } = await import("./add-issue-L5HX6LEV.js");
154
+ const { AddIssueCommand } = await import("./add-issue-OBI325W7.js");
155
155
  const command = new AddIssueCommand();
156
156
  const issueNumber = await command.execute({
157
157
  description,
@@ -166,7 +166,7 @@ program.command("add-issue").alias("a").description("Create and enhance GitHub i
166
166
  });
167
167
  program.command("feedback").alias("f").description("Submit feedback/bug report to iloom-cli repository").argument("<description>", "Natural language description of feedback (>50 chars, >2 spaces)").action(async (description) => {
168
168
  try {
169
- const { FeedbackCommand } = await import("./feedback-AKHD7QIM.js");
169
+ const { FeedbackCommand } = await import("./feedback-LFNMQBAZ.js");
170
170
  const command = new FeedbackCommand();
171
171
  const issueNumber = await command.execute({
172
172
  description,
@@ -181,7 +181,7 @@ program.command("feedback").alias("f").description("Submit feedback/bug report t
181
181
  });
182
182
  program.command("enhance").description("Apply enhancement agent to existing GitHub issue").argument("<issue-number>", "GitHub issue number to enhance", parseInt).option("--no-browser", "Skip browser opening prompt").option("--author <username>", "GitHub username to tag in questions (for CI usage)").action(async (issueNumber, options) => {
183
183
  try {
184
- const { EnhanceCommand } = await import("./enhance-VVMAKMVZ.js");
184
+ const { EnhanceCommand } = await import("./enhance-MNA4ZGXW.js");
185
185
  const command = new EnhanceCommand();
186
186
  await command.execute({
187
187
  issueNumber,
@@ -197,9 +197,9 @@ program.command("enhance").description("Apply enhancement agent to existing GitH
197
197
  process.exit(1);
198
198
  }
199
199
  });
200
- program.command("finish").alias("dn").description("Merge work and cleanup workspace").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").option("--pr <number>", "Treat input as PR number", parseFloat).option("--skip-build", "Skip post-merge build verification").action(async (identifier, options) => {
200
+ program.command("finish").alias("dn").description("Merge work and cleanup workspace").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").option("--pr <number>", "Treat input as PR number", parseFloat).option("--skip-build", "Skip post-merge build verification").option("--no-browser", "Skip opening PR in browser (github-pr mode only)").option("--cleanup", "Clean up worktree after PR creation (github-pr mode only)").option("--no-cleanup", "Keep worktree after PR creation (github-pr mode only)").action(async (identifier, options) => {
201
201
  try {
202
- const { FinishCommand } = await import("./finish-WGPISUEH.js");
202
+ const { FinishCommand } = await import("./finish-TX5CJICB.js");
203
203
  const command = new FinishCommand();
204
204
  await command.execute({ identifier, options });
205
205
  } catch (error) {
@@ -209,7 +209,7 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
209
209
  });
210
210
  program.command("rebase").description("Rebase current branch on main with Claude-assisted conflict resolution").option("-f, --force", "Skip confirmation prompts").option("-n, --dry-run", "Preview actions without executing").action(async (options) => {
211
211
  try {
212
- const { RebaseCommand } = await import("./rebase-KBWFDZCN.js");
212
+ const { RebaseCommand } = await import("./rebase-DUNFOJVS.js");
213
213
  const command = new RebaseCommand();
214
214
  await command.execute(options);
215
215
  } catch (error) {
@@ -221,7 +221,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
221
221
  new Option("--one-shot <mode>", "One-shot automation mode").choices(["default", "noReview", "bypassPermissions"]).default("default")
222
222
  ).action(async (options) => {
223
223
  try {
224
- const { IgniteCommand } = await import("./ignite-JEN3K3OT.js");
224
+ const { IgniteCommand } = await import("./ignite-MQWVJEAB.js");
225
225
  const command = new IgniteCommand();
226
226
  await command.execute(options.oneShot ?? "default");
227
227
  } catch (error) {
@@ -232,7 +232,7 @@ program.command("spin").alias("ignite").description("Launch Claude with auto-det
232
232
  program.command("open").description("Open workspace in browser or run CLI tool").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
233
233
  try {
234
234
  const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
235
- const { OpenCommand } = await import("./open-ETZUFSE4.js");
235
+ const { OpenCommand } = await import("./open-NXSN7XOC.js");
236
236
  const cmd = new OpenCommand();
237
237
  const input = identifier ? { identifier, args } : { args };
238
238
  await cmd.execute(input);
@@ -244,7 +244,7 @@ program.command("open").description("Open workspace in browser or run CLI tool")
244
244
  program.command("run").description("Run CLI tool or open workspace in browser").argument("[identifier]", "Issue number, PR number, or branch name (auto-detected if omitted)").allowUnknownOption().action(async (identifier, _options, command) => {
245
245
  try {
246
246
  const args = (command == null ? void 0 : command.args) ? command.args.slice(identifier ? 1 : 0) : [];
247
- const { RunCommand } = await import("./run-4SVQ3WEU.js");
247
+ const { RunCommand } = await import("./run-O7ZK7CKA.js");
248
248
  const cmd = new RunCommand();
249
249
  const input = identifier ? { identifier, args } : { args };
250
250
  await cmd.execute(input);
@@ -255,7 +255,7 @@ program.command("run").description("Run CLI tool or open workspace in browser").
255
255
  });
256
256
  program.command("cleanup").description("Remove workspaces").argument("[identifier]", "Branch name or issue number to cleanup (auto-detected)").option("-l, --list", "List all worktrees").option("-a, --all", "Remove all worktrees (interactive confirmation)").option("-i, --issue <number>", "Cleanup by issue number", parseInt).option("-f, --force", "Skip confirmations and force removal").option("--dry-run", "Show what would be done without doing it").action(async (identifier, options) => {
257
257
  try {
258
- const { CleanupCommand } = await import("./cleanup-ZHROIBSQ.js");
258
+ const { CleanupCommand } = await import("./cleanup-FEIVZSIV.js");
259
259
  const command = new CleanupCommand();
260
260
  const input = {
261
261
  options: options ?? {}
@@ -293,9 +293,9 @@ program.command("list").description("Show active workspaces").option("--json", "
293
293
  process.exit(1);
294
294
  }
295
295
  });
296
- program.command("init").description("Initialize iloom configuration and setup shell autocomplete").action(async () => {
296
+ program.command("init").alias("config").description("Initialize iloom configuration and setup shell autocomplete").action(async () => {
297
297
  try {
298
- const { InitCommand } = await import("./init-EVUT4ZQJ.js");
298
+ const { InitCommand } = await import("./init-GJDYN2IK.js");
299
299
  const command = new InitCommand();
300
300
  await command.execute();
301
301
  } catch (error) {
@@ -303,6 +303,16 @@ program.command("init").description("Initialize iloom configuration and setup sh
303
303
  process.exit(1);
304
304
  }
305
305
  });
306
+ program.command("contribute").description("Set up local development environment for contributing to iloom").action(async () => {
307
+ try {
308
+ const { ContributeCommand } = await import("./contribute-EMZKCAC6.js");
309
+ const command = new ContributeCommand();
310
+ await command.execute();
311
+ } catch (error) {
312
+ logger.error(`Failed to set up contributor environment: ${error instanceof Error ? error.message : "Unknown error"}`);
313
+ process.exit(1);
314
+ }
315
+ });
306
316
  program.command("update").description("Update iloom-cli to the latest version").option("--dry-run", "Show what would be done without actually updating").action(async (options) => {
307
317
  try {
308
318
  const { UpdateCommand } = await import("./update-4TDDUR5K.js");
@@ -315,7 +325,7 @@ program.command("update").description("Update iloom-cli to the latest version").
315
325
  });
316
326
  program.command("test-github").description("Test GitHub integration (Issue #3)").argument("<identifier>", "Issue number or PR number").option("--no-claude", "Skip Claude for branch name generation").action(async (identifier, options) => {
317
327
  try {
318
- const { GitHubService } = await import("./GitHubService-SH4H6VS5.js");
328
+ const { GitHubService } = await import("./GitHubService-7E2S5NNZ.js");
319
329
  logger.info("Testing GitHub Integration\n");
320
330
  const service = new GitHubService(options.claude !== void 0 ? { useClaude: options.claude } : {});
321
331
  logger.info("Detecting input type...");
@@ -370,10 +380,10 @@ program.command("test-github").description("Test GitHub integration (Issue #3)")
370
380
  });
371
381
  program.command("test-claude").description("Test Claude integration (Issue #10)").option("--detect", "Test Claude CLI detection").option("--version", "Get Claude CLI version").option("--branch <title>", "Test branch name generation with given title").option("--issue <number>", "Issue number for branch generation", "123").option("--launch <prompt>", "Launch Claude with a prompt (headless)").option("--interactive", "Launch Claude interactively (requires --launch)").option("--template <name>", "Test template loading").action(async (options) => {
372
382
  try {
373
- const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import("./claude-7LUVDZZ4.js");
374
- const { PromptTemplateManager } = await import("./PromptTemplateManager-WM5GIPEF.js");
375
- const { ClaudeService } = await import("./ClaudeService-CFFI7DD5.js");
376
- const { ClaudeContextManager } = await import("./ClaudeContextManager-LD3VB6EM.js");
383
+ const { detectClaudeCli, getClaudeVersion, generateBranchName, launchClaude } = await import("./claude-ZIWDG4XG.js");
384
+ const { PromptTemplateManager } = await import("./PromptTemplateManager-WII75TKH.js");
385
+ const { ClaudeService } = await import("./ClaudeService-WVTWB3DK.js");
386
+ const { ClaudeContextManager } = await import("./ClaudeContextManager-LVCYRM6Q.js");
377
387
  logger.info("Testing Claude Integration\n");
378
388
  if (options.detect) {
379
389
  logger.info("Detecting Claude CLI...");
@@ -521,7 +531,7 @@ program.command("test-webserver").description("Test if a web server is running o
521
531
  });
522
532
  program.command("test-git").description("Test Git integration - findMainWorktreePath() function (reads .iloom/settings.json)").action(async () => {
523
533
  try {
524
- const { TestGitCommand } = await import("./test-git-MKZATGZN.js");
534
+ const { TestGitCommand } = await import("./test-git-T76HOTIA.js");
525
535
  const command = new TestGitCommand();
526
536
  await command.execute();
527
537
  } catch (error) {
@@ -534,7 +544,7 @@ program.command("test-git").description("Test Git integration - findMainWorktree
534
544
  });
535
545
  program.command("test-tabs").description("Test iTerm2 dual tab functionality - opens two tabs with test commands").action(async () => {
536
546
  try {
537
- const { TestTabsCommand } = await import("./test-tabs-JRKY3QMM.js");
547
+ const { TestTabsCommand } = await import("./test-tabs-RXDBZ6J7.js");
538
548
  const command = new TestTabsCommand();
539
549
  await command.execute();
540
550
  } catch (error) {
@@ -547,7 +557,7 @@ program.command("test-tabs").description("Test iTerm2 dual tab functionality - o
547
557
  });
548
558
  program.command("test-prefix").description("Test worktree prefix configuration - preview worktree paths (reads .iloom/settings.json)").action(async () => {
549
559
  try {
550
- const { TestPrefixCommand } = await import("./test-prefix-ZNLWDI3K.js");
560
+ const { TestPrefixCommand } = await import("./test-prefix-6HJUVQMH.js");
551
561
  const command = new TestPrefixCommand();
552
562
  await command.execute();
553
563
  } catch (error) {
@@ -561,7 +571,7 @@ program.command("test-prefix").description("Test worktree prefix configuration -
561
571
  program.command("test-neon").description("Test Neon integration and debug configuration").action(async () => {
562
572
  var _a;
563
573
  try {
564
- const { SettingsManager } = await import("./SettingsManager-SKLUVE3K.js");
574
+ const { SettingsManager } = await import("./SettingsManager-XOYCLH3D.js");
565
575
  const { createNeonProviderFromSettings } = await import("./neon-helpers-ZVIRPKCI.js");
566
576
  logger.info("Testing Neon Integration\n");
567
577
  logger.info("1. Settings Configuration:");