@iloom/cli 0.1.19 → 0.3.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 (176) hide show
  1. package/README.md +290 -30
  2. package/dist/BranchNamingService-3OQPRSWT.js +13 -0
  3. package/dist/ClaudeContextManager-MUQSDY2E.js +13 -0
  4. package/dist/ClaudeService-HG4VQ7AW.js +12 -0
  5. package/dist/GitHubService-EBOETDIW.js +11 -0
  6. package/dist/{LoomLauncher-UMMLPIZO.js → LoomLauncher-FLEMBCSQ.js} +64 -33
  7. package/dist/LoomLauncher-FLEMBCSQ.js.map +1 -0
  8. package/dist/ProjectCapabilityDetector-34LU7JJ4.js +9 -0
  9. package/dist/{PromptTemplateManager-WII75TKH.js → PromptTemplateManager-A52RUAMS.js} +2 -2
  10. package/dist/README.md +290 -30
  11. package/dist/{SettingsManager-SKLUVE3K.js → SettingsManager-WHHFGSL7.js} +12 -4
  12. package/dist/SettingsMigrationManager-AGIIIPDQ.js +10 -0
  13. package/dist/agents/iloom-issue-analyze-and-plan.md +125 -35
  14. package/dist/agents/iloom-issue-analyzer.md +284 -32
  15. package/dist/agents/iloom-issue-complexity-evaluator.md +40 -21
  16. package/dist/agents/iloom-issue-enhancer.md +69 -48
  17. package/dist/agents/iloom-issue-implementer.md +36 -25
  18. package/dist/agents/iloom-issue-planner.md +35 -24
  19. package/dist/agents/iloom-issue-reviewer.md +62 -9
  20. package/dist/chunk-3KATJIKO.js +55 -0
  21. package/dist/chunk-3KATJIKO.js.map +1 -0
  22. package/dist/{chunk-JXQXSC45.js → chunk-3RUPPQRG.js} +1 -18
  23. package/dist/chunk-3RUPPQRG.js.map +1 -0
  24. package/dist/{chunk-PR7FKQBG.js → chunk-47KSHUCR.js} +3 -3
  25. package/dist/chunk-47KSHUCR.js.map +1 -0
  26. package/dist/{chunk-IO4WFTL2.js → chunk-4HHRTA7Q.js} +3 -3
  27. package/dist/{chunk-IO4WFTL2.js.map → chunk-4HHRTA7Q.js.map} +1 -1
  28. package/dist/chunk-5EF7Z346.js +1987 -0
  29. package/dist/chunk-5EF7Z346.js.map +1 -0
  30. package/dist/{chunk-VVH3ANF2.js → chunk-AWOFAD5O.js} +12 -12
  31. package/dist/chunk-AWOFAD5O.js.map +1 -0
  32. package/dist/{chunk-DEPYQRRB.js → chunk-C5QCTEQK.js} +2 -2
  33. package/dist/{chunk-CWR2SANQ.js → chunk-EBISESAP.js} +1 -1
  34. package/dist/{chunk-ELFT36PV.js → chunk-FIAT22G7.js} +4 -16
  35. package/dist/chunk-FIAT22G7.js.map +1 -0
  36. package/dist/{chunk-ZWXJBSUW.js → chunk-G2IEYOLQ.js} +11 -38
  37. package/dist/chunk-G2IEYOLQ.js.map +1 -0
  38. package/dist/{chunk-ZMNQBJUI.js → chunk-IP7SMKIF.js} +61 -22
  39. package/dist/chunk-IP7SMKIF.js.map +1 -0
  40. package/dist/{chunk-JNKJ7NJV.js → chunk-JKXJ7BGL.js} +6 -2
  41. package/dist/{chunk-JNKJ7NJV.js.map → chunk-JKXJ7BGL.js.map} +1 -1
  42. package/dist/{chunk-LAPY6NAE.js → chunk-JQFO7QQN.js} +68 -12
  43. package/dist/{chunk-LAPY6NAE.js.map → chunk-JQFO7QQN.js.map} +1 -1
  44. package/dist/{SettingsMigrationManager-MTQIMI54.js → chunk-KLBYVHPK.js} +3 -2
  45. package/dist/{chunk-KOCQAD2E.js → chunk-MAVL6PJF.js} +26 -3
  46. package/dist/chunk-MAVL6PJF.js.map +1 -0
  47. package/dist/{chunk-USVVV3FP.js → chunk-MKWYLDFK.js} +5 -5
  48. package/dist/chunk-ML3NRPNB.js +396 -0
  49. package/dist/chunk-ML3NRPNB.js.map +1 -0
  50. package/dist/{chunk-FXV24OYZ.js → chunk-PA6Q6AWM.js} +24 -4
  51. package/dist/chunk-PA6Q6AWM.js.map +1 -0
  52. package/dist/chunk-RO26VS3W.js +444 -0
  53. package/dist/chunk-RO26VS3W.js.map +1 -0
  54. package/dist/{chunk-PV3GAXQO.js → chunk-VAYCCUXW.js} +72 -2
  55. package/dist/{chunk-PV3GAXQO.js.map → chunk-VAYCCUXW.js.map} +1 -1
  56. package/dist/{chunk-SPYPLHMK.js → chunk-VU3QMIP2.js} +34 -2
  57. package/dist/chunk-VU3QMIP2.js.map +1 -0
  58. package/dist/{chunk-PVAVNJKS.js → chunk-WEN5C5DM.js} +10 -1
  59. package/dist/chunk-WEN5C5DM.js.map +1 -0
  60. package/dist/{chunk-PXZBAC2M.js → chunk-XXV3UFZL.js} +4 -4
  61. package/dist/{chunk-PXZBAC2M.js.map → chunk-XXV3UFZL.js.map} +1 -1
  62. package/dist/{chunk-RSRO7564.js → chunk-ZE74H5BR.js} +28 -3
  63. package/dist/chunk-ZE74H5BR.js.map +1 -0
  64. package/dist/{chunk-GZP4UGGM.js → chunk-ZM3CFL5L.js} +2 -2
  65. package/dist/{chunk-BLCTGFZN.js → chunk-ZT3YZB4K.js} +3 -4
  66. package/dist/chunk-ZT3YZB4K.js.map +1 -0
  67. package/dist/{claude-7LUVDZZ4.js → claude-GOP6PFC7.js} +2 -2
  68. package/dist/{cleanup-ZHROIBSQ.js → cleanup-7RWLBSLE.js} +86 -25
  69. package/dist/cleanup-7RWLBSLE.js.map +1 -0
  70. package/dist/cli.js +2513 -64
  71. package/dist/cli.js.map +1 -1
  72. package/dist/{contribute-3MQJ3XAQ.js → contribute-BS2L4FZR.js} +9 -6
  73. package/dist/{contribute-3MQJ3XAQ.js.map → contribute-BS2L4FZR.js.map} +1 -1
  74. package/dist/{feedback-ZOUCCHN4.js → feedback-N4ECWIPF.js} +15 -14
  75. package/dist/{feedback-ZOUCCHN4.js.map → feedback-N4ECWIPF.js.map} +1 -1
  76. package/dist/{git-OUYMVYJX.js → git-TDXKRTXM.js} +4 -2
  77. package/dist/{ignite-HICLZEYU.js → ignite-VM64QO3J.js} +32 -27
  78. package/dist/ignite-VM64QO3J.js.map +1 -0
  79. package/dist/index.d.ts +379 -45
  80. package/dist/index.js +1241 -448
  81. package/dist/index.js.map +1 -1
  82. package/dist/{init-UMKNHNV5.js → init-G3T64SC4.js} +104 -40
  83. package/dist/init-G3T64SC4.js.map +1 -0
  84. package/dist/mcp/issue-management-server.js +934 -0
  85. package/dist/mcp/issue-management-server.js.map +1 -0
  86. package/dist/{neon-helpers-ZVIRPKCI.js → neon-helpers-WPUACUVC.js} +3 -3
  87. package/dist/{open-ETZUFSE4.js → open-KXDXEKRZ.js} +39 -36
  88. package/dist/open-KXDXEKRZ.js.map +1 -0
  89. package/dist/{prompt-ANTQWHUF.js → prompt-7INJ7YRU.js} +4 -2
  90. package/dist/prompt-7INJ7YRU.js.map +1 -0
  91. package/dist/prompts/init-prompt.txt +563 -91
  92. package/dist/prompts/issue-prompt.txt +27 -27
  93. package/dist/{rebase-KBWFDZCN.js → rebase-Q7GMM7EI.js} +6 -6
  94. package/dist/{remote-GJEZWRCC.js → remote-VUNCQZ6J.js} +5 -2
  95. package/dist/remote-VUNCQZ6J.js.map +1 -0
  96. package/dist/{run-4SVQ3WEU.js → run-PAWJJCSX.js} +39 -36
  97. package/dist/run-PAWJJCSX.js.map +1 -0
  98. package/dist/schema/settings.schema.json +74 -0
  99. package/dist/{terminal-3D6TUAKJ.js → terminal-BIRBZ4AZ.js} +2 -2
  100. package/dist/terminal-BIRBZ4AZ.js.map +1 -0
  101. package/dist/{test-git-MKZATGZN.js → test-git-3WDLNQCA.js} +3 -3
  102. package/dist/{test-prefix-ZNLWDI3K.js → test-prefix-EVGAWAJW.js} +3 -3
  103. package/dist/{test-tabs-JRKY3QMM.js → test-tabs-RXDBZ6J7.js} +2 -2
  104. package/dist/{test-webserver-M2I3EV4J.js → test-webserver-DAHONWCS.js} +4 -4
  105. package/dist/test-webserver-DAHONWCS.js.map +1 -0
  106. package/package.json +2 -1
  107. package/dist/ClaudeContextManager-JKR4WGNU.js +0 -13
  108. package/dist/ClaudeService-55DQGB7T.js +0 -12
  109. package/dist/GitHubService-LWP4GKGH.js +0 -11
  110. package/dist/LoomLauncher-UMMLPIZO.js.map +0 -1
  111. package/dist/add-issue-X56V3XPB.js +0 -69
  112. package/dist/add-issue-X56V3XPB.js.map +0 -1
  113. package/dist/chunk-BLCTGFZN.js.map +0 -1
  114. package/dist/chunk-ELFT36PV.js.map +0 -1
  115. package/dist/chunk-FXV24OYZ.js.map +0 -1
  116. package/dist/chunk-H4E4THUZ.js +0 -55
  117. package/dist/chunk-H4E4THUZ.js.map +0 -1
  118. package/dist/chunk-H5LDRGVK.js +0 -642
  119. package/dist/chunk-H5LDRGVK.js.map +0 -1
  120. package/dist/chunk-JXQXSC45.js.map +0 -1
  121. package/dist/chunk-KOCQAD2E.js.map +0 -1
  122. package/dist/chunk-PR7FKQBG.js.map +0 -1
  123. package/dist/chunk-PVAVNJKS.js.map +0 -1
  124. package/dist/chunk-Q2KYPAH2.js +0 -545
  125. package/dist/chunk-Q2KYPAH2.js.map +0 -1
  126. package/dist/chunk-RSRO7564.js.map +0 -1
  127. package/dist/chunk-SPYPLHMK.js.map +0 -1
  128. package/dist/chunk-VCMMAFXQ.js +0 -54
  129. package/dist/chunk-VCMMAFXQ.js.map +0 -1
  130. package/dist/chunk-VVH3ANF2.js.map +0 -1
  131. package/dist/chunk-VYQLLHZ7.js +0 -239
  132. package/dist/chunk-VYQLLHZ7.js.map +0 -1
  133. package/dist/chunk-ZMNQBJUI.js.map +0 -1
  134. package/dist/chunk-ZWXJBSUW.js.map +0 -1
  135. package/dist/cleanup-ZHROIBSQ.js.map +0 -1
  136. package/dist/enhance-VGWUX474.js +0 -176
  137. package/dist/enhance-VGWUX474.js.map +0 -1
  138. package/dist/finish-QJSK6Z7J.js +0 -1355
  139. package/dist/finish-QJSK6Z7J.js.map +0 -1
  140. package/dist/ignite-HICLZEYU.js.map +0 -1
  141. package/dist/init-UMKNHNV5.js.map +0 -1
  142. package/dist/mcp/chunk-6SDFJ42P.js +0 -62
  143. package/dist/mcp/chunk-6SDFJ42P.js.map +0 -1
  144. package/dist/mcp/claude-YHHHLSXH.js +0 -249
  145. package/dist/mcp/claude-YHHHLSXH.js.map +0 -1
  146. package/dist/mcp/color-QS5BFCNN.js +0 -168
  147. package/dist/mcp/color-QS5BFCNN.js.map +0 -1
  148. package/dist/mcp/github-comment-server.js +0 -168
  149. package/dist/mcp/github-comment-server.js.map +0 -1
  150. package/dist/mcp/terminal-SDCMDVD7.js +0 -202
  151. package/dist/mcp/terminal-SDCMDVD7.js.map +0 -1
  152. package/dist/open-ETZUFSE4.js.map +0 -1
  153. package/dist/run-4SVQ3WEU.js.map +0 -1
  154. package/dist/start-CT2ZEFP2.js +0 -983
  155. package/dist/start-CT2ZEFP2.js.map +0 -1
  156. package/dist/test-webserver-M2I3EV4J.js.map +0 -1
  157. /package/dist/{ClaudeContextManager-JKR4WGNU.js.map → BranchNamingService-3OQPRSWT.js.map} +0 -0
  158. /package/dist/{ClaudeService-55DQGB7T.js.map → ClaudeContextManager-MUQSDY2E.js.map} +0 -0
  159. /package/dist/{GitHubService-LWP4GKGH.js.map → ClaudeService-HG4VQ7AW.js.map} +0 -0
  160. /package/dist/{PromptTemplateManager-WII75TKH.js.map → GitHubService-EBOETDIW.js.map} +0 -0
  161. /package/dist/{SettingsManager-SKLUVE3K.js.map → ProjectCapabilityDetector-34LU7JJ4.js.map} +0 -0
  162. /package/dist/{claude-7LUVDZZ4.js.map → PromptTemplateManager-A52RUAMS.js.map} +0 -0
  163. /package/dist/{git-OUYMVYJX.js.map → SettingsManager-WHHFGSL7.js.map} +0 -0
  164. /package/dist/{neon-helpers-ZVIRPKCI.js.map → SettingsMigrationManager-AGIIIPDQ.js.map} +0 -0
  165. /package/dist/{chunk-DEPYQRRB.js.map → chunk-C5QCTEQK.js.map} +0 -0
  166. /package/dist/{chunk-CWR2SANQ.js.map → chunk-EBISESAP.js.map} +0 -0
  167. /package/dist/{SettingsMigrationManager-MTQIMI54.js.map → chunk-KLBYVHPK.js.map} +0 -0
  168. /package/dist/{chunk-USVVV3FP.js.map → chunk-MKWYLDFK.js.map} +0 -0
  169. /package/dist/{chunk-GZP4UGGM.js.map → chunk-ZM3CFL5L.js.map} +0 -0
  170. /package/dist/{prompt-ANTQWHUF.js.map → claude-GOP6PFC7.js.map} +0 -0
  171. /package/dist/{remote-GJEZWRCC.js.map → git-TDXKRTXM.js.map} +0 -0
  172. /package/dist/{terminal-3D6TUAKJ.js.map → neon-helpers-WPUACUVC.js.map} +0 -0
  173. /package/dist/{rebase-KBWFDZCN.js.map → rebase-Q7GMM7EI.js.map} +0 -0
  174. /package/dist/{test-git-MKZATGZN.js.map → test-git-3WDLNQCA.js.map} +0 -0
  175. /package/dist/{test-prefix-ZNLWDI3K.js.map → test-prefix-EVGAWAJW.js.map} +0 -0
  176. /package/dist/{test-tabs-JRKY3QMM.js.map → test-tabs-RXDBZ6J7.js.map} +0 -0
@@ -35,7 +35,7 @@ iloom is a CLI tool for scaling a human's understanding of the AI's work, as the
35
35
  4. **Planning** - Creates implementation roadmap with file specifications
36
36
  5. **Implementation** - Executes the plan with validation
37
37
 
38
- Each phase creates GitHub comments for team visibility and traceability.
38
+ Each phase creates issue comments for team visibility and traceability.
39
39
 
40
40
  ### Key iloom Commands
41
41
  - `iloom init` / `iloom config` - Interactive configuration wizard
@@ -114,23 +114,23 @@ You are orchestrating a set of agents through a development process, with human
114
114
 
115
115
  **Todo List:**
116
116
  1. Scan issue and determine workflow plan
117
- 2. Run GitHub issue enhancement for ISSUE_NUMBER (if needed) using @agent-iloom-issue-enhancer
118
- 3. Extract github issue link that includes comment id from agent output (if enhancement was needed), display to user
117
+ 2. Run issue enhancement for ISSUE_NUMBER (if needed) using @agent-iloom-issue-enhancer
118
+ 3. Extract issue link that includes comment id from agent output (if enhancement was needed), display to user
119
119
  4. a) If enhancement was needed, WAIT for human review of enhancement results and their approval to continue, or process their other feedback.
120
120
  b) If enhancement was NOT needed, let the user know and move to the next step.
121
121
  5. Run complexity evaluation for ISSUE_NUMBER using @agent-iloom-issue-complexity-evaluator
122
- 6. Extract github issue link that includes comment id from agent output, display complexity assessment to user
122
+ 6. Extract issue link that includes comment id from agent output, display complexity assessment to user
123
123
  7. WAIT for human confirmation of complexity classification before proceeding to next phase
124
124
  8. Route to appropriate workflow based on confirmed complexity (SIMPLE or COMPLEX)
125
125
  9. If SIMPLE: Run combined analysis and planning for ISSUE_NUMBER using @agent-iloom-issue-analyze-and-plan
126
126
  10. If COMPLEX: Run separate analysis for ISSUE_NUMBER using @agent-iloom-issue-analyzer
127
- 11. Extract github issue link that includes comment id from agent output, display to user
127
+ 11. Extract issue link that includes comment id from agent output, display to user
128
128
  12. WAIT for human review and approval to continue, or process their other feedback
129
129
  13. If COMPLEX workflow: Run planning for ISSUE_NUMBER using @agent-iloom-issue-planner
130
- 14. If COMPLEX workflow: Extract github issue link that includes comment id from agent output, display to user
130
+ 14. If COMPLEX workflow: Extract issue link that includes comment id from agent output, display to user
131
131
  15. If COMPLEX workflow: WAIT for human review of planning results and approval to continue
132
- 16. Run GitHub issue implementation for ISSUE_NUMBER (if needed) using @agent-iloom-issue-implementer
133
- 17. Provide final summary with links to all GitHub comments created. Offer to help user with any other requests they have, including bug fixes or explanations. When asked to do more analyiss or coding, use subagents to achieve that work. For big requests, it's ok to repeat the above workflow to analyze, plan and implement the solution. For simple tasks, use a generalized subagent.
132
+ 16. Run issue implementation for ISSUE_NUMBER (if needed) using @agent-iloom-issue-implementer
133
+ 17. Provide final summary with links to all issue comments created. Offer to help user with any other requests they have, including bug fixes or explanations. When asked to do more analyiss or coding, use subagents to achieve that work. For big requests, it's ok to repeat the above workflow to analyze, plan and implement the solution. For simple tasks, use a generalized subagent.
134
134
 
135
135
  ## Workflow Details
136
136
 
@@ -138,7 +138,7 @@ You are orchestrating a set of agents through a development process, with human
138
138
 
139
139
  Perform ONE comprehensive scan to determine which agents need to run:
140
140
 
141
- 1. Fetch complete issue data using `gh issue view ISSUE_NUMBER --json body,title,comments`
141
+ 1. Fetch complete issue data using the MCP tool `mcp__issue_management__get_issue` with `{ number: "ISSUE_NUMBER", includeComments: true }`
142
142
  2. Analyze the issue body and ALL comments in a single pass to determine:
143
143
 
144
144
  **Enhancement Decision:**
@@ -202,11 +202,11 @@ Perform ONE comprehensive scan to determine which agents need to run:
202
202
  **STEP 1 - Enhancement Phase:**
203
203
 
204
204
  Only execute if workflow plan determined NEEDS_ENHANCEMENT:
205
- 1. Execute: @agent-iloom-issue-enhancer ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their GitHub comments. This documents assumptions made during execution.
206
- 2. Upon completion: Extract issue+comment link (including comment ID) from agent output and provide link to GitHub issue comment
205
+ 1. Execute: @agent-iloom-issue-enhancer ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their issue comments. This documents assumptions made during execution.
206
+ 2. Upon completion: Extract issue+comment link (including comment ID) from agent output and provide link to issue comment
207
207
  3. Mark todo #2 and #3 as completed
208
208
  4. Use AskUserQuestion tool with a single question:
209
- - Question: "Enhancement complete. See results at: [GitHub comment URL]. How would you like to proceed?"
209
+ - Question: "Enhancement complete. See results at: [issue comment URL]. How would you like to proceed?"
210
210
  - Options:
211
211
  - "Continue to complexity evaluation" (default)
212
212
  - "Provide feedback on enhancement"
@@ -223,8 +223,8 @@ If workflow plan determined SKIP_ENHANCEMENT:
223
223
  **STEP 1.5 - Complexity Evaluation Phase:**
224
224
 
225
225
  Only execute if workflow plan determined NEEDS_COMPLEXITY_EVAL:
226
- 1. Execute: @agent-iloom-issue-complexity-evaluator ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their GitHub comments. This documents assumptions made during execution.
227
- 2. Upon completion: Extract issue+comment link from agent output and provide link to GitHub issue comment (including comment ID)
226
+ 1. Execute: @agent-iloom-issue-complexity-evaluator ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their issue comments. This documents assumptions made during execution.
227
+ 2. Upon completion: Extract issue+comment link from agent output and provide link to issue comment (including comment ID)
228
228
  3. Extract complexity classification from evaluator output:
229
229
  - Search the evaluator's output for the "Complexity Assessment" section
230
230
  - Extract: Classification (SIMPLE/COMPLEX), Metrics (files, LOC, breaking changes, DB migrations, risk level), and Reasoning
@@ -243,7 +243,7 @@ Only execute if workflow plan determined NEEDS_COMPLEXITY_EVAL:
243
243
  Reasoning: [reasoning text from evaluator]
244
244
  ```
245
245
  5. Use AskUserQuestion tool with a single question:
246
- - Question: "Complexity evaluated as [SIMPLE/COMPLEX]. See assessment at: [GitHub comment URL]. Do you agree with this classification?"
246
+ - Question: "Complexity evaluated as [SIMPLE/COMPLEX]. See assessment at: [issue comment URL]. Do you agree with this classification?"
247
247
  - Options:
248
248
  - "Yes, proceed with [SIMPLE/COMPLEX] workflow" (default)
249
249
  - "No, reclassify as SIMPLE"
@@ -271,11 +271,11 @@ If workflow plan determined SKIP_COMPLEXITY_EVAL:
271
271
  **STEP 2 - Analysis Phase (COMPLEX workflow only):**
272
272
 
273
273
  Only execute if workflow plan determined NEEDS_ANALYSIS AND complexity is COMPLEX:
274
- 1. Execute: @agent-iloom-issue-analyzer ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their GitHub comments. This documents assumptions made during execution.
275
- 2. Upon completion: Extract issue+comment link from agent output and provide link to GitHub issue comment (including comment ID)
274
+ 1. Execute: @agent-iloom-issue-analyzer ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their issue comments. This documents assumptions made during execution.
275
+ 2. Upon completion: Extract issue+comment link from agent output and provide link to issue comment (including comment ID)
276
276
  3. Mark todos #10, #11, and #12 as completed (todo #9 was already marked at routing decision point)
277
277
  4. Use AskUserQuestion tool with a single question:
278
- - Question: "Analysis complete. See findings at: [GitHub comment URL]. How would you like to proceed?"
278
+ - Question: "Analysis complete. See findings at: [issue comment URL]. How would you like to proceed?"
279
279
  - Options:
280
280
  - "Continue to planning phase" (default)
281
281
  - "Provide feedback on analysis"
@@ -319,11 +319,11 @@ After STEP 1.5 completes and complexity is confirmed, determine which workflow p
319
319
 
320
320
  Execute combined analyze-and-plan agent:
321
321
  1. Display: "Executing combined analyze-and-plan agent for SIMPLE task..."
322
- 2. Execute: @agent-iloom-issue-analyze-and-plan ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their GitHub comments. This documents assumptions made during execution.
323
- 3. Upon completion: Extract issue+comment link from agent output and provide link to GitHub issue comment (including comment ID)
322
+ 2. Execute: @agent-iloom-issue-analyze-and-plan ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their issue comments. This documents assumptions made during execution.
323
+ 3. Upon completion: Extract issue+comment link from agent output and provide link to issue comment (including comment ID)
324
324
  4. Mark todo #9 as completed (COMPLEX todos #10-15 were already marked at routing decision point)
325
325
  5. Use AskUserQuestion tool with a single question:
326
- - Question: "Combined analysis and planning complete. See results at: [GitHub comment URL]. How would you like to proceed?"
326
+ - Question: "Combined analysis and planning complete. See results at: [issue comment URL]. How would you like to proceed?"
327
327
  - Options:
328
328
  - "Continue to implementation" (default)
329
329
  - "Provide feedback on plan"
@@ -340,11 +340,11 @@ Execute combined analyze-and-plan agent:
340
340
  **IMPORTANT: Only execute this step if COMPLEX workflow is being followed (not SIMPLE)**
341
341
 
342
342
  Only execute if workflow plan determined NEEDS_PLANNING AND complexity is COMPLEX:
343
- 1. Execute: @agent-iloom-issue-planner ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their GitHub comments. This documents assumptions made during execution.
344
- 2. Upon completion: Extract issue+comment link from agent output and provide link to GitHub issue comment (including comment ID)
343
+ 1. Execute: @agent-iloom-issue-planner ISSUE_NUMBER instructing them to add their own answers to any questions they asked in the question tables they create in their issue comments. This documents assumptions made during execution.
344
+ 2. Upon completion: Extract issue+comment link from agent output and provide link to issue comment (including comment ID)
345
345
  3. Mark todos #13, #14, and #15 as completed (todos #9-12 were already marked at routing decision point and analysis phase)
346
346
  4. Use AskUserQuestion tool with a single question:
347
- - Question: "Planning complete. See implementation plan at: [GitHub comment URL]. How would you like to proceed?"
347
+ - Question: "Planning complete. See implementation plan at: [issue comment URL]. How would you like to proceed?"
348
348
  - Options:
349
349
  - "Continue to implementation" (default)
350
350
  - "Provide feedback on plan"
@@ -365,14 +365,14 @@ If workflow plan determined SKIP_PLANNING AND complexity is COMPLEX:
365
365
  Only execute if workflow plan determined NEEDS_IMPLEMENTATION:
366
366
  1. Before executing implementer, extract the planning comment ID:
367
367
  - Look back at the planning phase output (STEP 3 for COMPLEX or STEP 2-SIMPLE for SIMPLE workflows)
368
- - Extract the comment ID from the GitHub comment URL that was provided
368
+ - Extract the comment ID from the issue comment URL that was provided
369
369
  - The comment ID is the numeric value after "#issuecomment-" in the URL (e.g., https://github.com/org/repo/issues/123#issuecomment-456789 has comment ID 456789)
370
370
  2. Execute: @agent-iloom-issue-implementer ISSUE_NUMBER with these critical instructions:
371
- - Add your own answers to any questions you asked in the question tables you create in your GitHub comments to document assumptions made during execution
371
+ - Add your own answers to any questions you asked in the question tables you create in your issue comments to document assumptions made during execution
372
372
  - **CRITICAL**: The implementation plan in the issue comments contains exact file paths and line numbers. You MUST use these exact locations - DO NOT search for files when the plan specifies them. Extract file locations from the plan in Step 1.5 before implementing.
373
373
  - The implementation plan is located in comment ID [COMMENT_ID] (if planning phase was executed). Read this comment first in Step 1.5 to extract file specifications.
374
374
  3. Upon completion: Mark todo #16 as completed
375
- 4. Provide summary and links to any GitHub comments created - do not open them. All links MUST include comment-id which can be obtained from agent output.
375
+ 4. Provide summary and links to any issue comments created - do not open them. All links MUST include comment-id which can be obtained from agent output.
376
376
  5. Mark todo #17 as completed
377
377
 
378
378
  If workflow plan determined SKIP_IMPLEMENTATION:
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  MergeManager
4
- } from "./chunk-VVH3ANF2.js";
5
- import "./chunk-PXZBAC2M.js";
4
+ } from "./chunk-AWOFAD5O.js";
6
5
  import {
7
6
  GitWorktreeManager
8
- } from "./chunk-IO4WFTL2.js";
7
+ } from "./chunk-4HHRTA7Q.js";
8
+ import "./chunk-XXV3UFZL.js";
9
9
  import {
10
10
  SettingsManager
11
- } from "./chunk-VYQLLHZ7.js";
11
+ } from "./chunk-ML3NRPNB.js";
12
12
  import {
13
13
  getRepoRoot,
14
14
  isValidGitRepo
15
- } from "./chunk-KOCQAD2E.js";
15
+ } from "./chunk-MAVL6PJF.js";
16
16
  import {
17
17
  logger
18
18
  } from "./chunk-GEHQXLEI.js";
@@ -92,4 +92,4 @@ export {
92
92
  RebaseCommand,
93
93
  WorktreeValidationError
94
94
  };
95
- //# sourceMappingURL=rebase-KBWFDZCN.js.map
95
+ //# sourceMappingURL=rebase-Q7GMM7EI.js.map
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getConfiguredRepoFromSettings,
4
+ getEffectivePRTargetRemote,
4
5
  hasMultipleRemotes,
5
6
  parseGitRemotes,
6
7
  validateConfiguredRemote
7
- } from "./chunk-FXV24OYZ.js";
8
+ } from "./chunk-PA6Q6AWM.js";
9
+ import "./chunk-GEHQXLEI.js";
8
10
  export {
9
11
  getConfiguredRepoFromSettings,
12
+ getEffectivePRTargetRemote,
10
13
  hasMultipleRemotes,
11
14
  parseGitRemotes,
12
15
  validateConfiguredRemote
13
16
  };
14
- //# sourceMappingURL=remote-GJEZWRCC.js.map
17
+ //# sourceMappingURL=remote-VUNCQZ6J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,35 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  DevServerManager
4
- } from "./chunk-USVVV3FP.js";
4
+ } from "./chunk-MKWYLDFK.js";
5
+ import "./chunk-ZM3CFL5L.js";
5
6
  import {
6
- IdentifierParser
7
- } from "./chunk-H4E4THUZ.js";
8
- import "./chunk-SPYPLHMK.js";
9
- import "./chunk-GZP4UGGM.js";
10
- import {
11
- calculatePortForBranch,
7
+ IdentifierParser,
12
8
  extractPort,
13
9
  parseEnvFile
14
- } from "./chunk-ZMNQBJUI.js";
15
- import "./chunk-BLCTGFZN.js";
10
+ } from "./chunk-IP7SMKIF.js";
16
11
  import {
17
- extractSettingsOverrides
18
- } from "./chunk-GYCR2LOU.js";
19
- import {
20
- ProjectCapabilityDetector
21
- } from "./chunk-CWR2SANQ.js";
22
- import "./chunk-2ZPFJQ3B.js";
12
+ calculatePortForBranch
13
+ } from "./chunk-VU3QMIP2.js";
23
14
  import {
24
15
  openBrowser
25
16
  } from "./chunk-YETJNRQM.js";
26
17
  import {
27
18
  GitWorktreeManager
28
- } from "./chunk-IO4WFTL2.js";
19
+ } from "./chunk-4HHRTA7Q.js";
20
+ import "./chunk-ZT3YZB4K.js";
21
+ import {
22
+ ProjectCapabilityDetector
23
+ } from "./chunk-EBISESAP.js";
24
+ import "./chunk-2ZPFJQ3B.js";
25
+ import {
26
+ extractSettingsOverrides
27
+ } from "./chunk-GYCR2LOU.js";
29
28
  import {
30
29
  SettingsManager
31
- } from "./chunk-VYQLLHZ7.js";
32
- import "./chunk-KOCQAD2E.js";
30
+ } from "./chunk-ML3NRPNB.js";
31
+ import {
32
+ extractIssueNumber
33
+ } from "./chunk-MAVL6PJF.js";
33
34
  import {
34
35
  logger
35
36
  } from "./chunk-GEHQXLEI.js";
@@ -102,10 +103,8 @@ var RunCommand = class {
102
103
  autoDetected: true
103
104
  };
104
105
  }
105
- const issuePattern = /issue-(\d+)/;
106
- const issueMatch = currentDir.match(issuePattern);
107
- if (issueMatch == null ? void 0 : issueMatch[1]) {
108
- const issueNumber = parseInt(issueMatch[1], 10);
106
+ const issueNumber = extractIssueNumber(currentDir);
107
+ if (issueNumber !== null) {
109
108
  logger.debug(`Auto-detected issue #${issueNumber} from directory: ${currentDir}`);
110
109
  return {
111
110
  type: "issue",
@@ -121,13 +120,12 @@ var RunCommand = class {
121
120
  "Could not auto-detect identifier. Please provide an issue number, PR number, or branch name.\nExpected directory pattern: feat/issue-XX-description OR worktree with _pr_N suffix"
122
121
  );
123
122
  }
124
- const branchIssueMatch = currentBranch.match(issuePattern);
125
- if (branchIssueMatch == null ? void 0 : branchIssueMatch[1]) {
126
- const issueNumber = parseInt(branchIssueMatch[1], 10);
127
- logger.debug(`Auto-detected issue #${issueNumber} from branch: ${currentBranch}`);
123
+ const branchIssueNumber = extractIssueNumber(currentBranch);
124
+ if (branchIssueNumber !== null) {
125
+ logger.debug(`Auto-detected issue #${branchIssueNumber} from branch: ${currentBranch}`);
128
126
  return {
129
127
  type: "issue",
130
- number: issueNumber,
128
+ number: branchIssueNumber,
131
129
  originalInput: currentBranch,
132
130
  autoDetected: true
133
131
  };
@@ -147,7 +145,11 @@ var RunCommand = class {
147
145
  if (parsed.type === "issue" && parsed.number !== void 0) {
148
146
  worktree = await this.gitWorktreeManager.findWorktreeForIssue(parsed.number);
149
147
  } else if (parsed.type === "pr" && parsed.number !== void 0) {
150
- worktree = await this.gitWorktreeManager.findWorktreeForPR(parsed.number, "");
148
+ const prNumber = typeof parsed.number === "number" ? parsed.number : Number(parsed.number);
149
+ if (isNaN(prNumber) || !isFinite(prNumber)) {
150
+ throw new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`);
151
+ }
152
+ worktree = await this.gitWorktreeManager.findWorktreeForPR(prNumber, "");
151
153
  } else if (parsed.type === "branch" && parsed.branchName) {
152
154
  worktree = await this.gitWorktreeManager.findWorktreeForBranch(
153
155
  parsed.branchName
@@ -257,13 +259,14 @@ Make sure the project is built (run 'il start' first)`
257
259
  logger.debug(`Calculated PORT for PR #${prNumber}: ${port2}`);
258
260
  return port2;
259
261
  }
260
- const issuePattern = /issue-(\d+)/;
261
- const issueMatch = dirName.match(issuePattern) ?? worktree.branch.match(issuePattern);
262
- if (issueMatch == null ? void 0 : issueMatch[1]) {
263
- const issueNumber = parseInt(issueMatch[1], 10);
264
- const port2 = basePort + issueNumber;
265
- logger.debug(`Calculated PORT for issue #${issueNumber}: ${port2}`);
266
- return port2;
262
+ const issueId = extractIssueNumber(dirName) ?? extractIssueNumber(worktree.branch);
263
+ if (issueId !== null) {
264
+ const issueNumber = parseInt(issueId, 10);
265
+ if (!isNaN(issueNumber)) {
266
+ const port2 = basePort + issueNumber;
267
+ logger.debug(`Calculated PORT for issue #${issueId}: ${port2}`);
268
+ return port2;
269
+ }
267
270
  }
268
271
  const port = calculatePortForBranch(worktree.branch, basePort);
269
272
  logger.debug(`Calculated PORT for branch "${worktree.branch}": ${port}`);
@@ -273,4 +276,4 @@ Make sure the project is built (run 'il start' first)`
273
276
  export {
274
277
  RunCommand
275
278
  };
276
- //# sourceMappingURL=run-4SVQ3WEU.js.map
279
+ //# sourceMappingURL=run-PAWJJCSX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/run.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { ProjectCapabilityDetector } from '../lib/ProjectCapabilityDetector.js'\nimport { DevServerManager } from '../lib/DevServerManager.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { IdentifierParser } from '../utils/IdentifierParser.js'\nimport { openBrowser } from '../utils/browser.js'\nimport { parseEnvFile, extractPort } from '../utils/env.js'\nimport { calculatePortForBranch } from '../utils/port.js'\nimport { extractIssueNumber } from '../utils/git.js'\nimport { logger } from '../utils/logger.js'\nimport { extractSettingsOverrides } from '../utils/cli-overrides.js'\nimport type { GitWorktree } from '../types/worktree.js'\n\nexport interface RunCommandInput {\n\tidentifier?: string\n\targs?: string[]\n}\n\ninterface ParsedRunInput {\n\ttype: 'issue' | 'pr' | 'branch'\n\tnumber?: string | number // For issues and PRs\n\tbranchName?: string // For branches\n\toriginalInput: string\n\tautoDetected: boolean\n}\n\n/**\n * RunCommand - Runs CLI tool or opens workspace in browser\n * Priority: CLI first, Web fallback\n */\nexport class RunCommand {\n\tconstructor(\n\t\tprivate gitWorktreeManager = new GitWorktreeManager(),\n\t\tprivate capabilityDetector = new ProjectCapabilityDetector(),\n\t\tprivate identifierParser = new IdentifierParser(new GitWorktreeManager()),\n\t\tprivate devServerManager = new DevServerManager(),\n\t\tprivate settingsManager = new SettingsManager()\n\t) {}\n\n\tasync execute(input: RunCommandInput): Promise<void> {\n\t\t// 1. Parse or auto-detect identifier\n\t\tconst parsed = input.identifier\n\t\t\t? await this.parseExplicitInput(input.identifier)\n\t\t\t: await this.autoDetectFromCurrentDirectory()\n\n\t\tlogger.debug(`Parsed input: ${JSON.stringify(parsed)}`)\n\n\t\t// 2. Find worktree path based on identifier\n\t\tconst worktree = await this.findWorktreeForIdentifier(parsed)\n\n\t\tlogger.info(`Found worktree at: ${worktree.path}`)\n\n\t\t// 3. Detect project capabilities\n\t\tconst { capabilities, binEntries } =\n\t\t\tawait this.capabilityDetector.detectCapabilities(worktree.path)\n\n\t\tlogger.debug(`Detected capabilities: ${capabilities.join(', ')}`)\n\n\t\t// 4. Execute based on capabilities (CLI first, web fallback)\n\t\tif (capabilities.includes('cli')) {\n\t\t\tawait this.runCLITool(worktree.path, binEntries, input.args ?? [])\n\t\t} else if (capabilities.includes('web')) {\n\t\t\tawait this.openWebBrowser(worktree.path)\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`No CLI or web capabilities detected for workspace at ${worktree.path}`\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Parse explicit identifier input\n\t */\n\tprivate async parseExplicitInput(identifier: string): Promise<ParsedRunInput> {\n\t\tconst parsed = await this.identifierParser.parseForPatternDetection(identifier)\n\n\t\t// Description type should never reach run command (converted in start)\n\t\tif (parsed.type === 'description') {\n\t\t\tthrow new Error('Description input type is not supported in run command')\n\t\t}\n\n\t\tconst result: ParsedRunInput = {\n\t\t\ttype: parsed.type,\n\t\t\toriginalInput: parsed.originalInput,\n\t\t\tautoDetected: false,\n\t\t}\n\n\t\tif (parsed.number !== undefined) {\n\t\t\tresult.number = parsed.number\n\t\t}\n\t\tif (parsed.branchName !== undefined) {\n\t\t\tresult.branchName = parsed.branchName\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Auto-detect identifier from current directory\n\t * Same logic as FinishCommand.autoDetectFromCurrentDirectory()\n\t */\n\tprivate async autoDetectFromCurrentDirectory(): Promise<ParsedRunInput> {\n\t\tconst currentDir = path.basename(process.cwd())\n\n\t\t// Check for PR worktree pattern: _pr_N suffix\n\t\tconst prPattern = /_pr_(\\d+)$/\n\t\tconst prMatch = currentDir.match(prPattern)\n\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tlogger.debug(`Auto-detected PR #${prNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'pr',\n\t\t\t\tnumber: prNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Check for issue pattern in directory\n\t\tconst issueNumber = extractIssueNumber(currentDir)\n\n\t\tif (issueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${issueNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: issueNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Fallback: get current branch name\n\t\tconst repoInfo = await this.gitWorktreeManager.getRepoInfo()\n\t\tconst currentBranch = repoInfo.currentBranch\n\n\t\tif (!currentBranch) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not auto-detect identifier. Please provide an issue number, PR number, or branch name.\\n' +\n\t\t\t\t\t'Expected directory pattern: feat/issue-XX-description OR worktree with _pr_N suffix'\n\t\t\t)\n\t\t}\n\n\t\t// Try to extract issue from branch name\n\t\tconst branchIssueNumber = extractIssueNumber(currentBranch)\n\t\tif (branchIssueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${branchIssueNumber} from branch: ${currentBranch}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: branchIssueNumber,\n\t\t\t\toriginalInput: currentBranch,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Last resort: use branch name\n\t\treturn {\n\t\t\ttype: 'branch',\n\t\t\tbranchName: currentBranch,\n\t\t\toriginalInput: currentBranch,\n\t\t\tautoDetected: true,\n\t\t}\n\t}\n\n\t/**\n\t * Find worktree for the given identifier\n\t */\n\tprivate async findWorktreeForIdentifier(parsed: ParsedRunInput): Promise<GitWorktree> {\n\t\tlet worktree: GitWorktree | null = null\n\n\t\tif (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForIssue(parsed.number)\n\t\t} else if (parsed.type === 'pr' && parsed.number !== undefined) {\n\t\t\t// For PRs, ensure the number is numeric (PRs are always numeric per GitHub)\n\t\t\tconst prNumber = typeof parsed.number === 'number' ? parsed.number : Number(parsed.number)\n\t\t\tif (isNaN(prNumber) || !isFinite(prNumber)) {\n\t\t\t\tthrow new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`)\n\t\t\t}\n\t\t\t// Pass empty string for branch name since we don't know it yet\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForPR(prNumber, '')\n\t\t} else if (parsed.type === 'branch' && parsed.branchName) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForBranch(\n\t\t\t\tparsed.branchName\n\t\t\t)\n\t\t}\n\n\t\tif (!worktree) {\n\t\t\tthrow new Error(\n\t\t\t\t`No worktree found for ${this.formatParsedInput(parsed)}. ` +\n\t\t\t\t\t`Run 'il start ${parsed.originalInput}' to create one.`\n\t\t\t)\n\t\t}\n\n\t\treturn worktree\n\t}\n\n\t/**\n\t * Format parsed input for display\n\t */\n\tprivate formatParsedInput(parsed: ParsedRunInput): string {\n\t\tconst autoLabel = parsed.autoDetected ? ' (auto-detected)' : ''\n\n\t\tif (parsed.type === 'issue') {\n\t\t\treturn `issue #${parsed.number}${autoLabel}`\n\t\t}\n\t\tif (parsed.type === 'pr') {\n\t\t\treturn `PR #${parsed.number}${autoLabel}`\n\t\t}\n\t\treturn `branch \"${parsed.branchName}\"${autoLabel}`\n\t}\n\n\t/**\n\t * Run CLI tool directly from worktree bin path (NO SYMLINKS!)\n\t */\n\tprivate async runCLITool(\n\t\tworktreePath: string,\n\t\tbinEntries: Record<string, string>,\n\t\targs: string[]\n\t): Promise<void> {\n\t\t// Validate binEntries exist\n\t\tif (Object.keys(binEntries).length === 0) {\n\t\t\tthrow new Error('No bin entries found in package.json')\n\t\t}\n\n\t\t// Get first bin entry (deterministic)\n\t\tconst firstEntry = Object.entries(binEntries)[0]\n\t\tif (!firstEntry) {\n\t\t\tthrow new Error('No bin entries found in package.json')\n\t\t}\n\t\tconst [binName, binPath] = firstEntry\n\t\tlogger.debug(`Using bin entry: ${binName} -> ${binPath}`)\n\n\t\t// CRITICAL: Construct absolute path (NO SYMLINKS!)\n\t\tconst binFilePath = path.resolve(worktreePath, binPath)\n\t\tlogger.debug(`Resolved bin file path: ${binFilePath}`)\n\n\t\t// Verify file exists\n\t\tif (!(await fs.pathExists(binFilePath))) {\n\t\t\tthrow new Error(\n\t\t\t\t`CLI executable not found: ${binFilePath}\\n` +\n\t\t\t\t\t`Make sure the project is built (run 'il start' first)`\n\t\t\t)\n\t\t}\n\n\t\t// Execute with Node.js\n\t\tlogger.info(`Running CLI: node ${binFilePath} ${args.join(' ')}`)\n\t\tawait execa('node', [binFilePath, ...args], {\n\t\t\tstdio: 'inherit', // Allow interactive CLIs (prompts, colors, etc.)\n\t\t\tcwd: worktreePath, // Execute in worktree context\n\t\t\tenv: process.env, // Inherit environment\n\t\t})\n\t}\n\n\t/**\n\t * Open web browser with workspace URL\n\t * Auto-starts dev server if not already running\n\t */\n\tprivate async openWebBrowser(worktreePath: string): Promise<void> {\n\t\tconst port = await this.getWorkspacePort(worktreePath)\n\n\t\t// Ensure dev server is running on the port\n\t\tconst serverReady = await this.devServerManager.ensureServerRunning(\n\t\t\tworktreePath,\n\t\t\tport\n\t\t)\n\n\t\tif (!serverReady) {\n\t\t\tlogger.warn(\n\t\t\t\t`Dev server failed to start on port ${port}. Opening browser anyway...`\n\t\t\t)\n\t\t}\n\n\t\t// Construct URL and open browser\n\t\tconst url = `http://localhost:${port}`\n\t\tlogger.info(`Opening browser: ${url}`)\n\t\tawait openBrowser(url)\n\t\tlogger.success('Browser opened')\n\t}\n\n\t/**\n\t * Get port for workspace - reads from .env or calculates based on workspace type\n\t */\n\tprivate async getWorkspacePort(worktreePath: string): Promise<number> {\n\t\t// Load base port from settings with CLI overrides\n\t\tconst cliOverrides = extractSettingsOverrides()\n\t\tconst settings = await this.settingsManager.loadSettings(undefined, cliOverrides)\n\t\tconst basePort = settings.capabilities?.web?.basePort ?? 3000\n\n\t\t// Try to read PORT from .env file (as override)\n\t\tconst envPath = path.join(worktreePath, '.env')\n\t\tif (await fs.pathExists(envPath)) {\n\t\t\tconst envContent = await fs.readFile(envPath, 'utf8')\n\t\t\tconst envMap = parseEnvFile(envContent)\n\t\t\tconst port = extractPort(envMap)\n\n\t\t\tif (port) {\n\t\t\t\tlogger.debug(`Using PORT from .env: ${port}`)\n\t\t\t\treturn port\n\t\t\t}\n\t\t}\n\n\t\t// PORT not in .env, calculate based on workspace identifier\n\t\tlogger.debug('PORT not found in .env, calculating from workspace identifier')\n\n\t\t// Get worktree to determine type\n\t\tconst worktrees = await this.gitWorktreeManager.listWorktrees()\n\t\tconst worktree = worktrees.find(wt => wt.path === worktreePath)\n\n\t\tif (!worktree) {\n\t\t\tthrow new Error(`Could not find worktree for path: ${worktreePath}`)\n\t\t}\n\n\t\t// Extract identifier from worktree path/branch\n\t\tconst dirName = path.basename(worktreePath)\n\n\t\t// Check for PR pattern: _pr_N\n\t\tconst prPattern = /_pr_(\\d+)$/\n\t\tconst prMatch = dirName.match(prPattern)\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tconst port = basePort + prNumber\n\t\t\tlogger.debug(`Calculated PORT for PR #${prNumber}: ${port}`)\n\t\t\treturn port\n\t\t}\n\n\t\t// Check for issue pattern: issue-N\n\t\tconst issueId = extractIssueNumber(dirName) ?? extractIssueNumber(worktree.branch)\n\t\tif (issueId !== null) {\n\t\t\tconst issueNumber = parseInt(issueId, 10)\n\t\t\tif (!isNaN(issueNumber)) {\n\t\t\t\tconst port = basePort + issueNumber\n\t\t\t\tlogger.debug(`Calculated PORT for issue #${issueId}: ${port}`)\n\t\t\t\treturn port\n\t\t\t}\n\t\t\t// For alphanumeric IDs, fall through to branch-based hash\n\t\t}\n\n\t\t// Branch-based workspace - use deterministic hash\n\t\tconst port = calculatePortForBranch(worktree.branch, basePort)\n\t\tlogger.debug(`Calculated PORT for branch \"${worktree.branch}\": ${port}`)\n\t\treturn port\n\t}\n}\n"],"mappings":"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","names":["port"]}
@@ -9,6 +9,11 @@
9
9
  "minLength": 1,
10
10
  "description": "Name of the main/primary branch for the repository"
11
11
  },
12
+ "sourceEnvOnStart": {
13
+ "type": "boolean",
14
+ "default": false,
15
+ "description": "Source .env file when launching terminal processes (Claude, dev server, terminal). NOTE TO AI AGENTS: Before making changes to settings files, YOU MUST OFFER to check .env compatibility. WARNING: Unquoted values in .env files may break sourcing in bash/zsh shells. Before enabling, verify your .env file does not contain unquoted special characters (e.g., database URLs with ?, &, or other shell metacharacters). Shell compatibility issues may cause processes to fail or behave unexpectedly."
16
+ },
12
17
  "worktreePrefix": {
13
18
  "type": "string",
14
19
  "description": "Prefix for worktree directories. Empty string disables prefix. Defaults to <repo-name>-looms if not set."
@@ -245,6 +250,15 @@
245
250
  "issueManagement": {
246
251
  "type": "object",
247
252
  "properties": {
253
+ "provider": {
254
+ "type": "string",
255
+ "enum": [
256
+ "github",
257
+ "linear"
258
+ ],
259
+ "default": "github",
260
+ "description": "Issue tracker provider (github, linear)"
261
+ },
248
262
  "github": {
249
263
  "type": "object",
250
264
  "properties": {
@@ -258,10 +272,70 @@
258
272
  "remote"
259
273
  ],
260
274
  "additionalProperties": false
275
+ },
276
+ "linear": {
277
+ "type": "object",
278
+ "properties": {
279
+ "teamId": {
280
+ "type": "string",
281
+ "minLength": 1,
282
+ "description": "Linear team identifier (e.g., \"ENG\", \"PLAT\")"
283
+ },
284
+ "branchFormat": {
285
+ "type": "string",
286
+ "description": "Branch naming template for Linear issues"
287
+ },
288
+ "apiToken": {
289
+ "type": "string",
290
+ "description": "Linear API token (lin_api_...). SECURITY: Store in settings.local.json only, never commit to source control."
291
+ }
292
+ },
293
+ "required": [
294
+ "teamId"
295
+ ],
296
+ "additionalProperties": false
261
297
  }
262
298
  },
263
299
  "additionalProperties": false,
264
300
  "description": "Issue management configuration"
301
+ },
302
+ "mergeBehavior": {
303
+ "type": "object",
304
+ "properties": {
305
+ "mode": {
306
+ "type": "string",
307
+ "enum": [
308
+ "local",
309
+ "github-pr"
310
+ ],
311
+ "default": "local"
312
+ },
313
+ "remote": {
314
+ "type": "string"
315
+ }
316
+ },
317
+ "additionalProperties": false,
318
+ "description": "Merge behavior configuration: local (merge locally) or github-pr (create PR)"
319
+ },
320
+ "ide": {
321
+ "type": "object",
322
+ "properties": {
323
+ "type": {
324
+ "type": "string",
325
+ "enum": [
326
+ "vscode",
327
+ "cursor",
328
+ "webstorm",
329
+ "sublime",
330
+ "intellij",
331
+ "windsurf"
332
+ ],
333
+ "default": "vscode",
334
+ "description": "IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), windsurf (Windsurf editor)."
335
+ }
336
+ },
337
+ "additionalProperties": false,
338
+ "description": "IDE configuration for workspace launches. Controls which editor opens when you start a loom. Supports VSCode, Cursor, WebStorm, Sublime Text, IntelliJ, and Windsurf. Note: Color synchronization (title bar colors) only works with VSCode-compatible editors (vscode, cursor, windsurf)."
265
339
  }
266
340
  },
267
341
  "additionalProperties": false
@@ -5,7 +5,7 @@ import {
5
5
  openDualTerminalWindow,
6
6
  openMultipleTerminalWindows,
7
7
  openTerminalWindow
8
- } from "./chunk-RSRO7564.js";
8
+ } from "./chunk-ZE74H5BR.js";
9
9
  export {
10
10
  detectITerm2,
11
11
  detectPlatform,
@@ -13,4 +13,4 @@ export {
13
13
  openMultipleTerminalWindows,
14
14
  openTerminalWindow
15
15
  };
16
- //# sourceMappingURL=terminal-3D6TUAKJ.js.map
16
+ //# sourceMappingURL=terminal-BIRBZ4AZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SettingsManager
4
- } from "./chunk-VYQLLHZ7.js";
4
+ } from "./chunk-ML3NRPNB.js";
5
5
  import {
6
6
  findMainWorktreePath
7
- } from "./chunk-KOCQAD2E.js";
7
+ } from "./chunk-MAVL6PJF.js";
8
8
  import {
9
9
  logger
10
10
  } from "./chunk-GEHQXLEI.js";
@@ -49,4 +49,4 @@ var TestGitCommand = class {
49
49
  export {
50
50
  TestGitCommand
51
51
  };
52
- //# sourceMappingURL=test-git-MKZATGZN.js.map
52
+ //# sourceMappingURL=test-git-3WDLNQCA.js.map
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  SettingsManager
4
- } from "./chunk-VYQLLHZ7.js";
4
+ } from "./chunk-ML3NRPNB.js";
5
5
  import {
6
6
  generateWorktreePath
7
- } from "./chunk-KOCQAD2E.js";
7
+ } from "./chunk-MAVL6PJF.js";
8
8
  import {
9
9
  logger
10
10
  } from "./chunk-GEHQXLEI.js";
@@ -65,4 +65,4 @@ var TestPrefixCommand = class {
65
65
  export {
66
66
  TestPrefixCommand
67
67
  };
68
- //# sourceMappingURL=test-prefix-ZNLWDI3K.js.map
68
+ //# sourceMappingURL=test-prefix-EVGAWAJW.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  detectITerm2,
4
4
  openMultipleTerminalWindows
5
- } from "./chunk-RSRO7564.js";
5
+ } from "./chunk-ZE74H5BR.js";
6
6
  import {
7
7
  logger
8
8
  } from "./chunk-GEHQXLEI.js";
@@ -66,4 +66,4 @@ var TestTabsCommand = class {
66
66
  export {
67
67
  TestTabsCommand
68
68
  };
69
- //# sourceMappingURL=test-tabs-JRKY3QMM.js.map
69
+ //# sourceMappingURL=test-tabs-RXDBZ6J7.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ProcessManager
4
- } from "./chunk-SPYPLHMK.js";
4
+ } from "./chunk-VU3QMIP2.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-GEHQXLEI.js";
@@ -16,8 +16,8 @@ var TestWebserverCommand = class {
16
16
  */
17
17
  async execute(input) {
18
18
  const { issueNumber, options } = input;
19
- if (!Number.isInteger(issueNumber) || issueNumber <= 0) {
20
- throw new Error("Issue number must be a positive integer");
19
+ if (typeof issueNumber !== "number" || !Number.isInteger(issueNumber) || issueNumber <= 0) {
20
+ throw new Error("Issue number must be a positive integer for port calculation");
21
21
  }
22
22
  const port = this.processManager.calculatePort(issueNumber);
23
23
  logger.info(`Checking port ${port} (issue #${issueNumber})...`);
@@ -59,4 +59,4 @@ var TestWebserverCommand = class {
59
59
  export {
60
60
  TestWebserverCommand
61
61
  };
62
- //# sourceMappingURL=test-webserver-M2I3EV4J.js.map
62
+ //# sourceMappingURL=test-webserver-DAHONWCS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/test-webserver.ts"],"sourcesContent":["import { logger } from '../utils/logger.js'\nimport { ProcessManager } from '../lib/process/ProcessManager.js'\n\nexport interface TestWebserverOptions {\n\tkill?: boolean\n}\n\nexport interface TestWebserverCommandInput {\n\tissueNumber: string | number\n\toptions: TestWebserverOptions\n}\n\n/**\n * Command to test if a web server is running on a workspace port\n * and optionally kill it if detected.\n *\n * This uses the ProcessManager to detect processes on ports and\n * safely terminate web servers when requested.\n */\nexport class TestWebserverCommand {\n\tprivate readonly processManager: ProcessManager\n\n\tconstructor(processManager?: ProcessManager) {\n\t\tthis.processManager = processManager ?? new ProcessManager()\n\t}\n\n\t/**\n\t * Main entry point for the test-webserver command\n\t */\n\tpublic async execute(input: TestWebserverCommandInput): Promise<void> {\n\t\tconst { issueNumber, options } = input\n\n\t\t// Validate issue number - test-webserver requires numeric for port calculation\n\t\tif (typeof issueNumber !== 'number' || !Number.isInteger(issueNumber) || issueNumber <= 0) {\n\t\t\tthrow new Error('Issue number must be a positive integer for port calculation')\n\t\t}\n\n\t\t// Calculate port from issue number\n\t\tconst port = this.processManager.calculatePort(issueNumber)\n\t\tlogger.info(`Checking port ${port} (issue #${issueNumber})...`)\n\n\t\t// Detect what's running on the port\n\t\tconst processInfo = await this.processManager.detectDevServer(port)\n\n\t\tif (!processInfo) {\n\t\t\tlogger.info(`No process found on port ${port}`)\n\t\t\treturn\n\t\t}\n\n\t\t// Report what we found\n\t\tlogger.info(`Found process on port ${port}:`)\n\t\tlogger.info(` PID: ${processInfo.pid}`)\n\t\tlogger.info(` Name: ${processInfo.name}`)\n\t\tlogger.info(` Command: ${processInfo.command}`)\n\n\t\tif (processInfo.isDevServer) {\n\t\t\tlogger.success(`Detected as web server`)\n\t\t} else {\n\t\t\tlogger.warn(`Not detected as web server`)\n\t\t\tlogger.info(`This appears to be a non-web-server process. Skipping for safety.`)\n\t\t}\n\n\t\t// Kill process if requested (and it's a web server)\n\t\tif (options.kill) {\n\t\t\tif (!processInfo.isDevServer) {\n\t\t\t\tlogger.error(`Cannot kill non-web-server process (PID ${processInfo.pid}) for safety reasons`)\n\t\t\t\tlogger.info(`Process must match web server patterns to be killed automatically`)\n\t\t\t\tthrow new Error('Cannot kill non-web-server process')\n\t\t\t}\n\n\t\t\tlogger.info(`Terminating web server (PID ${processInfo.pid})...`)\n\t\t\tconst terminated = await this.processManager.terminateProcess(processInfo.pid)\n\n\t\t\tif (terminated) {\n\t\t\t\tlogger.success(`Web server terminated successfully`)\n\n\t\t\t\t// Verify port is now free\n\t\t\t\tconst isFree = await this.processManager.verifyPortFree(port)\n\t\t\t\tif (isFree) {\n\t\t\t\t\tlogger.success(`Port ${port} is now free`)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.warn(`Port ${port} may still be in use (TIME_WAIT state)`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;AAmBO,IAAM,uBAAN,MAA2B;AAAA,EAGjC,YAAY,gBAAiC;AAC5C,SAAK,iBAAiB,kBAAkB,IAAI,eAAe;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,QAAQ,OAAiD;AACrE,UAAM,EAAE,aAAa,QAAQ,IAAI;AAGjC,QAAI,OAAO,gBAAgB,YAAY,CAAC,OAAO,UAAU,WAAW,KAAK,eAAe,GAAG;AAC1F,YAAM,IAAI,MAAM,8DAA8D;AAAA,IAC/E;AAGA,UAAM,OAAO,KAAK,eAAe,cAAc,WAAW;AAC1D,WAAO,KAAK,iBAAiB,IAAI,YAAY,WAAW,MAAM;AAG9D,UAAM,cAAc,MAAM,KAAK,eAAe,gBAAgB,IAAI;AAElE,QAAI,CAAC,aAAa;AACjB,aAAO,KAAK,4BAA4B,IAAI,EAAE;AAC9C;AAAA,IACD;AAGA,WAAO,KAAK,yBAAyB,IAAI,GAAG;AAC5C,WAAO,KAAK,WAAW,YAAY,GAAG,EAAE;AACxC,WAAO,KAAK,YAAY,YAAY,IAAI,EAAE;AAC1C,WAAO,KAAK,eAAe,YAAY,OAAO,EAAE;AAEhD,QAAI,YAAY,aAAa;AAC5B,aAAO,QAAQ,wBAAwB;AAAA,IACxC,OAAO;AACN,aAAO,KAAK,4BAA4B;AACxC,aAAO,KAAK,mEAAmE;AAAA,IAChF;AAGA,QAAI,QAAQ,MAAM;AACjB,UAAI,CAAC,YAAY,aAAa;AAC7B,eAAO,MAAM,2CAA2C,YAAY,GAAG,sBAAsB;AAC7F,eAAO,KAAK,mEAAmE;AAC/E,cAAM,IAAI,MAAM,oCAAoC;AAAA,MACrD;AAEA,aAAO,KAAK,+BAA+B,YAAY,GAAG,MAAM;AAChE,YAAM,aAAa,MAAM,KAAK,eAAe,iBAAiB,YAAY,GAAG;AAE7E,UAAI,YAAY;AACf,eAAO,QAAQ,oCAAoC;AAGnD,cAAM,SAAS,MAAM,KAAK,eAAe,eAAe,IAAI;AAC5D,YAAI,QAAQ;AACX,iBAAO,QAAQ,QAAQ,IAAI,cAAc;AAAA,QAC1C,OAAO;AACN,iBAAO,KAAK,QAAQ,IAAI,wCAAwC;AAAA,QACjE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iloom/cli",
3
- "version": "0.1.19",
3
+ "version": "0.3.0",
4
4
  "description": "Control plane for maintaining alignment between you and Claude AI as you work across multiple issues using isolated environments, visible context, and multi-agent workflows to scale understanding, not just output",
5
5
  "keywords": [
6
6
  "ai",
@@ -65,6 +65,7 @@
65
65
  "prepare": "husky"
66
66
  },
67
67
  "dependencies": {
68
+ "@linear/sdk": "^65.1.0",
68
69
  "@modelcontextprotocol/sdk": "^1.0.4",
69
70
  "chalk": "^5.3.0",
70
71
  "commander": "^11.1.0",
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ClaudeContextManager
4
- } from "./chunk-DEPYQRRB.js";
5
- import "./chunk-ELFT36PV.js";
6
- import "./chunk-PXZBAC2M.js";
7
- import "./chunk-PVAVNJKS.js";
8
- import "./chunk-VYQLLHZ7.js";
9
- import "./chunk-GEHQXLEI.js";
10
- export {
11
- ClaudeContextManager
12
- };
13
- //# sourceMappingURL=ClaudeContextManager-JKR4WGNU.js.map
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ClaudeService
4
- } from "./chunk-ELFT36PV.js";
5
- import "./chunk-PXZBAC2M.js";
6
- import "./chunk-PVAVNJKS.js";
7
- import "./chunk-VYQLLHZ7.js";
8
- import "./chunk-GEHQXLEI.js";
9
- export {
10
- ClaudeService
11
- };
12
- //# sourceMappingURL=ClaudeService-55DQGB7T.js.map
@@ -1,11 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- GitHubService
4
- } from "./chunk-ZWXJBSUW.js";
5
- import "./chunk-JXQXSC45.js";
6
- import "./chunk-JNKJ7NJV.js";
7
- import "./chunk-GEHQXLEI.js";
8
- export {
9
- GitHubService
10
- };
11
- //# sourceMappingURL=GitHubService-LWP4GKGH.js.map