@iloom/cli 0.3.4 → 0.4.1

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 (181) hide show
  1. package/README.md +13 -3
  2. package/dist/{BranchNamingService-A77VI6AI.js → BranchNamingService-GCCWB3LK.js} +4 -3
  3. package/dist/ClaudeContextManager-DK77227F.js +16 -0
  4. package/dist/ClaudeService-W3SA7HVG.js +15 -0
  5. package/dist/GitHubService-RPM27GWD.js +12 -0
  6. package/dist/{LoomLauncher-ZV3ZZIBA.js → LoomLauncher-S3YGJRJQ.js} +43 -27
  7. package/dist/LoomLauncher-S3YGJRJQ.js.map +1 -0
  8. package/dist/PromptTemplateManager-2TDZAUC6.js +9 -0
  9. package/dist/README.md +13 -3
  10. package/dist/{SettingsManager-I2LRCW2A.js → SettingsManager-FJFU6JJD.js} +7 -3
  11. package/dist/SettingsMigrationManager-EH3J2TCN.js +10 -0
  12. package/dist/{chunk-5Q3NDNNV.js → chunk-2W2FBL5G.js} +153 -6
  13. package/dist/chunk-2W2FBL5G.js.map +1 -0
  14. package/dist/{chunk-OXAM2WVC.js → chunk-55TB3FSG.js} +21 -1
  15. package/dist/chunk-55TB3FSG.js.map +1 -0
  16. package/dist/chunk-6UIGZD2N.js +20 -0
  17. package/dist/chunk-6UIGZD2N.js.map +1 -0
  18. package/dist/{chunk-RIEO2WML.js → chunk-74VMN2KC.js} +26 -2
  19. package/dist/chunk-74VMN2KC.js.map +1 -0
  20. package/dist/{chunk-2MAIX45J.js → chunk-BIIQHEXJ.js} +104 -43
  21. package/dist/chunk-BIIQHEXJ.js.map +1 -0
  22. package/dist/{chunk-UAN4A3YU.js → chunk-G6CIIJLT.js} +11 -11
  23. package/dist/{chunk-DLHA5VQ3.js → chunk-HD5SUKI2.js} +36 -179
  24. package/dist/chunk-HD5SUKI2.js.map +1 -0
  25. package/dist/{chunk-2IJEMXOB.js → chunk-IARWMDAX.js} +427 -428
  26. package/dist/chunk-IARWMDAX.js.map +1 -0
  27. package/dist/chunk-IJ7IGJT3.js +192 -0
  28. package/dist/chunk-IJ7IGJT3.js.map +1 -0
  29. package/dist/{chunk-2CXREBLZ.js → chunk-JC5HXN75.js} +8 -6
  30. package/dist/chunk-JC5HXN75.js.map +1 -0
  31. package/dist/{chunk-3RUPPQRG.js → chunk-KO2FOMHL.js} +43 -2
  32. package/dist/{chunk-3RUPPQRG.js.map → chunk-KO2FOMHL.js.map} +1 -1
  33. package/dist/{chunk-4XIDC3NF.js → chunk-MD6HA5IK.js} +2 -2
  34. package/dist/{chunk-OC4H6HJD.js → chunk-O7WHXLCB.js} +2 -2
  35. package/dist/{chunk-M7JJCX53.js → chunk-OEGECBFS.js} +20 -20
  36. package/dist/chunk-OEGECBFS.js.map +1 -0
  37. package/dist/{chunk-MKWYLDFK.js → chunk-OF7BNW4D.js} +43 -3
  38. package/dist/chunk-OF7BNW4D.js.map +1 -0
  39. package/dist/{chunk-PGPI5LR4.js → chunk-POI7KLBH.js} +7 -21
  40. package/dist/chunk-POI7KLBH.js.map +1 -0
  41. package/dist/{chunk-PA6Q6AWM.js → chunk-PSFVTBM7.js} +2 -2
  42. package/dist/chunk-QHA67Q7A.js +281 -0
  43. package/dist/chunk-QHA67Q7A.js.map +1 -0
  44. package/dist/{chunk-SUOXY5WJ.js → chunk-QIUJPPJQ.js} +5 -5
  45. package/dist/chunk-QIUJPPJQ.js.map +1 -0
  46. package/dist/{chunk-ZM3CFL5L.js → chunk-QRBOPFAA.js} +3 -3
  47. package/dist/{chunk-OYF4VIFI.js → chunk-RUC7OULH.js} +147 -22
  48. package/dist/chunk-RUC7OULH.js.map +1 -0
  49. package/dist/{chunk-CE26YH2U.js → chunk-SJ2GZ6RF.js} +48 -50
  50. package/dist/chunk-SJ2GZ6RF.js.map +1 -0
  51. package/dist/{chunk-SSCQCCJ7.js → chunk-THF25ICZ.js} +2 -2
  52. package/dist/chunk-TMZAVPGF.js +667 -0
  53. package/dist/chunk-TMZAVPGF.js.map +1 -0
  54. package/dist/{chunk-5VK4NRSF.js → chunk-UNXRACJ7.js} +35 -36
  55. package/dist/chunk-UNXRACJ7.js.map +1 -0
  56. package/dist/{chunk-AKUJXDNW.js → chunk-UPUAQYAW.js} +3 -3
  57. package/dist/{chunk-GEHQXLEI.js → chunk-UYVWLISQ.js} +18 -35
  58. package/dist/chunk-UYVWLISQ.js.map +1 -0
  59. package/dist/{chunk-OSCLCMDG.js → chunk-UYWAESOT.js} +3 -3
  60. package/dist/{chunk-RW54ZMBM.js → chunk-VAYGNQTE.js} +2 -2
  61. package/dist/{chunk-ZT3YZB4K.js → chunk-VBFDVGAE.js} +12 -12
  62. package/dist/chunk-VBFDVGAE.js.map +1 -0
  63. package/dist/{chunk-IFB4Z76W.js → chunk-VTXCGKV5.js} +13 -12
  64. package/dist/chunk-VTXCGKV5.js.map +1 -0
  65. package/dist/{chunk-CDZERT7Z.js → chunk-VWNS6DH5.js} +48 -4
  66. package/dist/chunk-VWNS6DH5.js.map +1 -0
  67. package/dist/{chunk-CFFQ2Z7A.js → chunk-WUQQNE63.js} +2 -2
  68. package/dist/{chunk-UJL4HI2R.js → chunk-Z5NXYJIG.js} +20 -2
  69. package/dist/chunk-Z5NXYJIG.js.map +1 -0
  70. package/dist/{claude-W52VKI6L.js → claude-ACVXNB6N.js} +8 -5
  71. package/dist/{cleanup-H4VXU3C3.js → cleanup-KDLVTT7M.js} +133 -122
  72. package/dist/cleanup-KDLVTT7M.js.map +1 -0
  73. package/dist/cli.js +953 -430
  74. package/dist/cli.js.map +1 -1
  75. package/dist/{color-F7RU6B6Z.js → color-ZPIIUADB.js} +3 -3
  76. package/dist/{contribute-Y7IQV5QY.js → contribute-HY372S6F.js} +8 -6
  77. package/dist/{contribute-Y7IQV5QY.js.map → contribute-HY372S6F.js.map} +1 -1
  78. package/dist/dev-server-JCJGQ3PV.js +298 -0
  79. package/dist/dev-server-JCJGQ3PV.js.map +1 -0
  80. package/dist/{feedback-XTUCKJNT.js → feedback-7PVBQNLJ.js} +13 -12
  81. package/dist/{feedback-XTUCKJNT.js.map → feedback-7PVBQNLJ.js.map} +1 -1
  82. package/dist/{git-IYA53VIC.js → git-4BVOOOOV.js} +16 -4
  83. package/dist/hooks/iloom-hook.js +258 -0
  84. package/dist/{ignite-T74RYXCA.js → ignite-3B264M7K.js} +245 -39
  85. package/dist/ignite-3B264M7K.js.map +1 -0
  86. package/dist/index.d.ts +461 -124
  87. package/dist/index.js +743 -210
  88. package/dist/index.js.map +1 -1
  89. package/dist/init-LBA6NUK2.js +21 -0
  90. package/dist/{installation-detector-VARGFFRZ.js → installation-detector-6R6YOFVZ.js} +3 -3
  91. package/dist/mcp/issue-management-server.js +2 -1
  92. package/dist/mcp/issue-management-server.js.map +1 -1
  93. package/dist/neon-helpers-L5CXQ5CT.js +11 -0
  94. package/dist/{open-UMXANW5S.js → open-OGCV32Z4.js} +15 -13
  95. package/dist/{open-UMXANW5S.js.map → open-OGCV32Z4.js.map} +1 -1
  96. package/dist/projects-P55273AB.js +73 -0
  97. package/dist/projects-P55273AB.js.map +1 -0
  98. package/dist/{prompt-QALMYTVC.js → prompt-A7GGRHSY.js} +3 -3
  99. package/dist/prompts/init-prompt.txt +49 -0
  100. package/dist/prompts/issue-prompt.txt +110 -8
  101. package/dist/prompts/regular-prompt.txt +90 -0
  102. package/dist/prompts/session-summary-prompt.txt +82 -0
  103. package/dist/{rebase-VJ2VKR6R.js → rebase-4T5FQHNH.js} +11 -9
  104. package/dist/{rebase-VJ2VKR6R.js.map → rebase-4T5FQHNH.js.map} +1 -1
  105. package/dist/{remote-VUNCQZ6J.js → remote-73TZ2ADI.js} +3 -3
  106. package/dist/{run-MJYY4PUT.js → run-HNOP6WE2.js} +15 -13
  107. package/dist/{run-MJYY4PUT.js.map → run-HNOP6WE2.js.map} +1 -1
  108. package/dist/schema/settings.schema.json +49 -0
  109. package/dist/shell-DE3HKJSM.js +240 -0
  110. package/dist/shell-DE3HKJSM.js.map +1 -0
  111. package/dist/summary-GDT7DTRI.js +244 -0
  112. package/dist/summary-GDT7DTRI.js.map +1 -0
  113. package/dist/{test-git-IT5EWQ5C.js → test-git-YMAE57UP.js} +6 -4
  114. package/dist/{test-git-IT5EWQ5C.js.map → test-git-YMAE57UP.js.map} +1 -1
  115. package/dist/{test-prefix-NPWDPUUH.js → test-prefix-YCKL6CMT.js} +6 -4
  116. package/dist/{test-prefix-NPWDPUUH.js.map → test-prefix-YCKL6CMT.js.map} +1 -1
  117. package/dist/{test-tabs-PRMRSHKI.js → test-tabs-3SCJWRKT.js} +4 -4
  118. package/dist/{test-webserver-DAHONWCS.js → test-webserver-VPNLAFZ3.js} +2 -2
  119. package/dist/{update-4TDDUR5K.js → update-LETF5ASC.js} +4 -4
  120. package/dist/{update-notifier-QEX3CJHA.js → update-notifier-H55ZK7NU.js} +3 -3
  121. package/package.json +6 -6
  122. package/dist/ClaudeContextManager-BN7RE5ZQ.js +0 -15
  123. package/dist/ClaudeService-DLYLJUPA.js +0 -14
  124. package/dist/GitHubService-FZHHBOFG.js +0 -11
  125. package/dist/LoomLauncher-ZV3ZZIBA.js.map +0 -1
  126. package/dist/PromptTemplateManager-6HH3PVXV.js +0 -9
  127. package/dist/SettingsMigrationManager-TJ7UWZG5.js +0 -10
  128. package/dist/chunk-2CXREBLZ.js.map +0 -1
  129. package/dist/chunk-2IJEMXOB.js.map +0 -1
  130. package/dist/chunk-2MAIX45J.js.map +0 -1
  131. package/dist/chunk-5Q3NDNNV.js.map +0 -1
  132. package/dist/chunk-5VK4NRSF.js.map +0 -1
  133. package/dist/chunk-CDZERT7Z.js.map +0 -1
  134. package/dist/chunk-CE26YH2U.js.map +0 -1
  135. package/dist/chunk-DLHA5VQ3.js.map +0 -1
  136. package/dist/chunk-GEHQXLEI.js.map +0 -1
  137. package/dist/chunk-IFB4Z76W.js.map +0 -1
  138. package/dist/chunk-M7JJCX53.js.map +0 -1
  139. package/dist/chunk-MKWYLDFK.js.map +0 -1
  140. package/dist/chunk-OXAM2WVC.js.map +0 -1
  141. package/dist/chunk-OYF4VIFI.js.map +0 -1
  142. package/dist/chunk-PGPI5LR4.js.map +0 -1
  143. package/dist/chunk-RIEO2WML.js.map +0 -1
  144. package/dist/chunk-SUOXY5WJ.js.map +0 -1
  145. package/dist/chunk-UJL4HI2R.js.map +0 -1
  146. package/dist/chunk-ZT3YZB4K.js.map +0 -1
  147. package/dist/cleanup-H4VXU3C3.js.map +0 -1
  148. package/dist/ignite-T74RYXCA.js.map +0 -1
  149. package/dist/init-4FHTAM3F.js +0 -19
  150. package/dist/logger-MKYH4UDV.js +0 -12
  151. package/dist/neon-helpers-77PBPGJ5.js +0 -10
  152. package/dist/update-notifier-QEX3CJHA.js.map +0 -1
  153. /package/dist/{BranchNamingService-A77VI6AI.js.map → BranchNamingService-GCCWB3LK.js.map} +0 -0
  154. /package/dist/{ClaudeContextManager-BN7RE5ZQ.js.map → ClaudeContextManager-DK77227F.js.map} +0 -0
  155. /package/dist/{ClaudeService-DLYLJUPA.js.map → ClaudeService-W3SA7HVG.js.map} +0 -0
  156. /package/dist/{GitHubService-FZHHBOFG.js.map → GitHubService-RPM27GWD.js.map} +0 -0
  157. /package/dist/{PromptTemplateManager-6HH3PVXV.js.map → PromptTemplateManager-2TDZAUC6.js.map} +0 -0
  158. /package/dist/{SettingsManager-I2LRCW2A.js.map → SettingsManager-FJFU6JJD.js.map} +0 -0
  159. /package/dist/{SettingsMigrationManager-TJ7UWZG5.js.map → SettingsMigrationManager-EH3J2TCN.js.map} +0 -0
  160. /package/dist/{chunk-UAN4A3YU.js.map → chunk-G6CIIJLT.js.map} +0 -0
  161. /package/dist/{chunk-4XIDC3NF.js.map → chunk-MD6HA5IK.js.map} +0 -0
  162. /package/dist/{chunk-OC4H6HJD.js.map → chunk-O7WHXLCB.js.map} +0 -0
  163. /package/dist/{chunk-PA6Q6AWM.js.map → chunk-PSFVTBM7.js.map} +0 -0
  164. /package/dist/{chunk-ZM3CFL5L.js.map → chunk-QRBOPFAA.js.map} +0 -0
  165. /package/dist/{chunk-SSCQCCJ7.js.map → chunk-THF25ICZ.js.map} +0 -0
  166. /package/dist/{chunk-AKUJXDNW.js.map → chunk-UPUAQYAW.js.map} +0 -0
  167. /package/dist/{chunk-OSCLCMDG.js.map → chunk-UYWAESOT.js.map} +0 -0
  168. /package/dist/{chunk-RW54ZMBM.js.map → chunk-VAYGNQTE.js.map} +0 -0
  169. /package/dist/{chunk-CFFQ2Z7A.js.map → chunk-WUQQNE63.js.map} +0 -0
  170. /package/dist/{claude-W52VKI6L.js.map → claude-ACVXNB6N.js.map} +0 -0
  171. /package/dist/{color-F7RU6B6Z.js.map → color-ZPIIUADB.js.map} +0 -0
  172. /package/dist/{git-IYA53VIC.js.map → git-4BVOOOOV.js.map} +0 -0
  173. /package/dist/{init-4FHTAM3F.js.map → init-LBA6NUK2.js.map} +0 -0
  174. /package/dist/{installation-detector-VARGFFRZ.js.map → installation-detector-6R6YOFVZ.js.map} +0 -0
  175. /package/dist/{logger-MKYH4UDV.js.map → neon-helpers-L5CXQ5CT.js.map} +0 -0
  176. /package/dist/{neon-helpers-77PBPGJ5.js.map → prompt-A7GGRHSY.js.map} +0 -0
  177. /package/dist/{prompt-QALMYTVC.js.map → remote-73TZ2ADI.js.map} +0 -0
  178. /package/dist/{test-tabs-PRMRSHKI.js.map → test-tabs-3SCJWRKT.js.map} +0 -0
  179. /package/dist/{test-webserver-DAHONWCS.js.map → test-webserver-VPNLAFZ3.js.map} +0 -0
  180. /package/dist/{update-4TDDUR5K.js.map → update-LETF5ASC.js.map} +0 -0
  181. /package/dist/{remote-VUNCQZ6J.js.map → update-notifier-H55ZK7NU.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/claude.ts"],"sourcesContent":["import { execa } from 'execa'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { createHash } 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\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}\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 } = 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// Add JSON streaming output for progress tracking\n\t\targs.push('--output-format', 'stream-json')\n\t\targs.push('--verbose')\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\ttry {\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\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\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 (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\tconst result = await subprocess\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\n\t\t\t\tif (!isDebugMode) {\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\tawait 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})\n\t\t\t\treturn\n\t\t\t} catch (interactiveError) {\n\t\t\t\tconst interactiveExecaError = interactiveError as { stderr?: string; message?: string }\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\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})\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// 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\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\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 (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) {\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})\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\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})) 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":[]}
@@ -1,40 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger
4
- } from "./chunk-GEHQXLEI.js";
4
+ } from "./chunk-UYVWLISQ.js";
5
5
 
6
6
  // src/utils/prompt.ts
7
7
  import * as readline from "readline";
8
8
  async function promptConfirmation(message, defaultValue = false) {
9
- const rl = readline.createInterface({
10
- input: process.stdin,
11
- output: process.stdout
12
- });
13
9
  const suffix = defaultValue ? "[Y/n]" : "[y/N]";
14
10
  const fullMessage = `${message} ${suffix}: `;
15
- return new Promise((resolve) => {
16
- rl.question(fullMessage, (answer) => {
17
- rl.close();
18
- const normalized = answer.trim().toLowerCase();
19
- if (normalized === "") {
20
- resolve(defaultValue);
21
- return;
22
- }
23
- if (normalized === "y" || normalized === "yes") {
24
- resolve(true);
25
- return;
26
- }
27
- if (normalized === "n" || normalized === "no") {
28
- resolve(false);
29
- return;
30
- }
31
- logger.warn("Invalid input, using default value", {
32
- input: answer,
33
- defaultValue
11
+ while (true) {
12
+ const rl = readline.createInterface({
13
+ input: process.stdin,
14
+ output: process.stdout
15
+ });
16
+ const answer = await new Promise((resolve) => {
17
+ rl.question(fullMessage, (ans) => {
18
+ rl.close();
19
+ resolve(ans);
34
20
  });
35
- resolve(defaultValue);
36
21
  });
37
- });
22
+ const normalized = answer.trim().toLowerCase();
23
+ if (normalized === "") {
24
+ return defaultValue;
25
+ }
26
+ if (normalized === "y" || normalized === "yes") {
27
+ return true;
28
+ }
29
+ if (normalized === "n" || normalized === "no") {
30
+ return false;
31
+ }
32
+ logger.warn("Invalid input. Please enter y/yes or n/no.");
33
+ }
38
34
  }
39
35
  async function promptInput(message, defaultValue) {
40
36
  const rl = readline.createInterface({
@@ -56,6 +52,9 @@ async function promptInput(message, defaultValue) {
56
52
  });
57
53
  }
58
54
  async function waitForKeypress(message = "Press any key to continue...") {
55
+ if (!process.stdin.isTTY || typeof process.stdin.setRawMode !== "function") {
56
+ return "";
57
+ }
59
58
  process.stdout.write(message);
60
59
  return new Promise((resolve) => {
61
60
  process.stdin.setRawMode(true);
@@ -85,30 +84,29 @@ async function promptCommitAction(message) {
85
84
  process.stdout.write("=".repeat(60) + "\n");
86
85
  process.stdout.write(message + "\n");
87
86
  process.stdout.write("=".repeat(60) + "\n\n");
88
- const rl = readline.createInterface({
89
- input: process.stdin,
90
- output: process.stdout
91
- });
92
- return new Promise((resolve) => {
93
- rl.question("[A]ccept as-is, [E]dit in editor, A[b]ort? [A/e/b]: ", (answer) => {
94
- rl.close();
95
- const normalized = answer.trim().toLowerCase();
96
- if (normalized === "" || normalized === "a") {
97
- resolve("accept");
98
- return;
99
- }
100
- if (normalized === "e") {
101
- resolve("edit");
102
- return;
103
- }
104
- if (normalized === "b") {
105
- resolve("abort");
106
- return;
107
- }
108
- logger.warn("Invalid input, defaulting to accept", { input: answer });
109
- resolve("accept");
87
+ while (true) {
88
+ const rl = readline.createInterface({
89
+ input: process.stdin,
90
+ output: process.stdout
110
91
  });
111
- });
92
+ const answer = await new Promise((resolve) => {
93
+ rl.question("[A]ccept as-is, [E]dit in editor, A[b]ort? [A/e/b]: ", (ans) => {
94
+ rl.close();
95
+ resolve(ans);
96
+ });
97
+ });
98
+ const normalized = answer.trim().toLowerCase();
99
+ if (normalized === "" || normalized === "a" || normalized === "accept") {
100
+ return "accept";
101
+ }
102
+ if (normalized === "e" || normalized === "edit") {
103
+ return "edit";
104
+ }
105
+ if (normalized === "b" || normalized === "abort") {
106
+ return "abort";
107
+ }
108
+ logger.warn("Invalid input. Please enter A (accept), E (edit), or B (abort).");
109
+ }
112
110
  }
113
111
 
114
112
  export {
@@ -118,4 +116,4 @@ export {
118
116
  isInteractiveEnvironment,
119
117
  promptCommitAction
120
118
  };
121
- //# sourceMappingURL=chunk-CE26YH2U.js.map
119
+ //# sourceMappingURL=chunk-SJ2GZ6RF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/prompt.ts"],"sourcesContent":["import * as readline from 'node:readline'\nimport { logger } from './logger.js'\n\n/**\n * Prompt user for confirmation (yes/no)\n * @param message The question to ask the user\n * @param defaultValue Default value if user just presses enter (default: false)\n * @returns Promise<boolean> - true if user confirms, false otherwise\n */\nexport async function promptConfirmation(\n\tmessage: string,\n\tdefaultValue = false\n): Promise<boolean> {\n\tconst suffix = defaultValue ? '[Y/n]' : '[y/N]'\n\tconst fullMessage = `${message} ${suffix}: `\n\n\t// Loop until valid input is received\n\twhile (true) {\n\t\tconst rl = readline.createInterface({\n\t\t\tinput: process.stdin,\n\t\t\toutput: process.stdout,\n\t\t})\n\n\t\tconst answer = await new Promise<string>((resolve) => {\n\t\t\trl.question(fullMessage, (ans) => {\n\t\t\t\trl.close()\n\t\t\t\tresolve(ans)\n\t\t\t})\n\t\t})\n\n\t\tconst normalized = answer.trim().toLowerCase()\n\n\t\tif (normalized === '') {\n\t\t\treturn defaultValue\n\t\t}\n\n\t\tif (normalized === 'y' || normalized === 'yes') {\n\t\t\treturn true\n\t\t}\n\n\t\tif (normalized === 'n' || normalized === 'no') {\n\t\t\treturn false\n\t\t}\n\n\t\t// Invalid input - show warning and re-prompt\n\t\tlogger.warn('Invalid input. Please enter y/yes or n/no.')\n\t}\n}\n\n/**\n * Prompt user for text input\n * @param message The prompt message\n * @param defaultValue Optional default value\n * @returns Promise<string> - the user's input\n */\nexport async function promptInput(\n\tmessage: string,\n\tdefaultValue?: string\n): Promise<string> {\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t})\n\n\tconst suffix = defaultValue ? ` [${defaultValue}]` : ''\n\tconst fullMessage = `${message}${suffix}: `\n\n\treturn new Promise((resolve) => {\n\t\trl.question(fullMessage, (answer) => {\n\t\t\trl.close()\n\n\t\t\tconst trimmed = answer.trim()\n\n\t\t\tif (trimmed === '' && defaultValue !== undefined) {\n\t\t\t\tresolve(defaultValue)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tresolve(trimmed)\n\t\t})\n\t})\n}\n\n/**\n * Wait for the user to press any key\n * @param message Optional message to display (default: \"Press any key to continue...\")\n * @returns Promise<string> - resolves with the key that was pressed, or empty string in non-interactive environments\n */\nexport async function waitForKeypress(\n\tmessage = 'Press any key to continue...'\n): Promise<string> {\n\t// Check if we can use raw mode (only available in TTY)\n\tif (!process.stdin.isTTY || typeof process.stdin.setRawMode !== 'function') {\n\t\t// Non-interactive environment - skip keypress wait\n\t\treturn ''\n\t}\n\n\t// Display message first\n\tprocess.stdout.write(message)\n\n\treturn new Promise((resolve) => {\n\t\t// Enable raw mode to capture single keypresses\n\t\tprocess.stdin.setRawMode(true)\n\t\tprocess.stdin.resume()\n\n\t\t// Listen for single data event\n\t\tprocess.stdin.once('data', (chunk: Buffer) => {\n\t\t\tconst key = chunk.toString('utf8')\n\n\t\t\t// Restore normal mode first (cleanup before any exit)\n\t\t\tprocess.stdin.setRawMode(false)\n\t\t\tprocess.stdin.pause()\n\n\t\t\t// Handle Ctrl+C (ETX character \\x03)\n\t\t\tif (key === '\\x03') {\n\t\t\t\tprocess.stdout.write('\\n')\n\t\t\t\tprocess.exit(130) // Standard exit code for SIGINT (128 + 2)\n\t\t\t}\n\n\t\t\t// Add newline after keypress for clean output\n\t\t\tprocess.stdout.write('\\n')\n\t\t\tresolve(key)\n\t\t})\n\t})\n}\n\n/**\n * Check if running in an interactive environment\n * Returns false if CI environment or no TTY\n */\nexport function isInteractiveEnvironment(): boolean {\n\treturn process.stdin.isTTY === true && process.env.CI !== 'true'\n}\n\n// Commit action type for type safety\nexport type CommitAction = 'accept' | 'edit' | 'abort'\n\n/**\n * Display commit message and prompt for action\n * @param message The commit message to display\n * @returns Promise<CommitAction> - 'accept', 'edit', or 'abort'\n */\nexport async function promptCommitAction(message: string): Promise<CommitAction> {\n\t// Check for non-interactive environment first\n\tif (!isInteractiveEnvironment()) {\n\t\treturn 'accept'\n\t}\n\n\t// Display the commit message with clear demarcation\n\tprocess.stdout.write('\\n' + '='.repeat(60) + '\\n')\n\tprocess.stdout.write('COMMIT MESSAGE:\\n')\n\tprocess.stdout.write('='.repeat(60) + '\\n')\n\tprocess.stdout.write(message + '\\n')\n\tprocess.stdout.write('='.repeat(60) + '\\n\\n')\n\n\t// Loop until valid input is received\n\twhile (true) {\n\t\tconst rl = readline.createInterface({\n\t\t\tinput: process.stdin,\n\t\t\toutput: process.stdout,\n\t\t})\n\n\t\tconst answer = await new Promise<string>((resolve) => {\n\t\t\trl.question('[A]ccept as-is, [E]dit in editor, A[b]ort? [A/e/b]: ', (ans) => {\n\t\t\t\trl.close()\n\t\t\t\tresolve(ans)\n\t\t\t})\n\t\t})\n\n\t\tconst normalized = answer.trim().toLowerCase()\n\n\t\tif (normalized === '' || normalized === 'a' || normalized === 'accept') {\n\t\t\treturn 'accept'\n\t\t}\n\n\t\tif (normalized === 'e' || normalized === 'edit') {\n\t\t\treturn 'edit'\n\t\t}\n\n\t\tif (normalized === 'b' || normalized === 'abort') {\n\t\t\treturn 'abort'\n\t\t}\n\n\t\t// Invalid input - show warning and re-prompt\n\t\tlogger.warn('Invalid input. Please enter A (accept), E (edit), or B (abort).')\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger
4
- } from "./chunk-GEHQXLEI.js";
4
+ } from "./chunk-UYVWLISQ.js";
5
5
 
6
6
  // src/utils/installation-detector.ts
7
7
  import { dirname, join } from "path";
@@ -72,4 +72,4 @@ export {
72
72
  detectInstallationMethod,
73
73
  shouldShowUpdateNotification
74
74
  };
75
- //# sourceMappingURL=chunk-SSCQCCJ7.js.map
75
+ //# sourceMappingURL=chunk-THF25ICZ.js.map