@iloom/cli 0.9.2 → 0.10.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 (231) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +160 -41
  3. package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-25KSZAEM.js} +2 -2
  4. package/dist/ClaudeContextManager-66GR4BGM.js +14 -0
  5. package/dist/ClaudeService-7KM5NA5Z.js +13 -0
  6. package/dist/{GitHubService-TGWJN4V4.js → GitHubService-MEHKHUQP.js} +4 -4
  7. package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
  8. package/dist/{LoomLauncher-73NXL2CL.js → LoomLauncher-TDLZSYG2.js} +9 -9
  9. package/dist/{MetadataManager-W3C54UYT.js → MetadataManager-5QZSTKNN.js} +2 -2
  10. package/dist/{ProjectCapabilityDetector-N5L7T4IY.js → ProjectCapabilityDetector-5KSYUTBJ.js} +3 -3
  11. package/dist/{PromptTemplateManager-36YLQRHP.js → PromptTemplateManager-YOE2SIPG.js} +2 -2
  12. package/dist/README.md +160 -41
  13. package/dist/{SettingsManager-AW3JTJHD.js → SettingsManager-FNKCOZMQ.js} +4 -2
  14. package/dist/agents/iloom-artifact-reviewer.md +11 -0
  15. package/dist/agents/iloom-code-reviewer.md +14 -0
  16. package/dist/agents/iloom-issue-analyze-and-plan.md +55 -12
  17. package/dist/agents/iloom-issue-analyzer.md +49 -6
  18. package/dist/agents/iloom-issue-complexity-evaluator.md +47 -6
  19. package/dist/agents/iloom-issue-enhancer.md +86 -7
  20. package/dist/agents/iloom-issue-implementer.md +48 -7
  21. package/dist/agents/iloom-issue-planner.md +115 -62
  22. package/dist/{build-THZI572G.js → build-VHGEMXBA.js} +9 -9
  23. package/dist/chunk-4232AHNQ.js +35 -0
  24. package/dist/chunk-4232AHNQ.js.map +1 -0
  25. package/dist/chunk-4E7LCFUG.js +24 -0
  26. package/dist/chunk-4E7LCFUG.js.map +1 -0
  27. package/dist/{chunk-AR5QKYNE.js → chunk-4FGEGQW4.js} +4 -4
  28. package/dist/{chunk-R4YWBGY6.js → chunk-5FJWO4IT.js} +67 -22
  29. package/dist/chunk-5FJWO4IT.js.map +1 -0
  30. package/dist/{chunk-VPTAX5TR.js → chunk-5RPBYK5Q.js} +35 -30
  31. package/dist/chunk-5RPBYK5Q.js.map +1 -0
  32. package/dist/{chunk-YKFCCV6S.js → chunk-63QWFWH3.js} +7 -7
  33. package/dist/chunk-63QWFWH3.js.map +1 -0
  34. package/dist/{chunk-RI2YL6TK.js → chunk-7VHJNVLF.js} +80 -23
  35. package/dist/chunk-7VHJNVLF.js.map +1 -0
  36. package/dist/{chunk-B7U6OKUR.js → chunk-C6HNNJIV.js} +11 -3
  37. package/dist/chunk-C6HNNJIV.js.map +1 -0
  38. package/dist/{chunk-A7NJF73J.js → chunk-CVCTIDDK.js} +4 -4
  39. package/dist/{chunk-Z2TWEXR7.js → chunk-E6KOWMKA.js} +6 -6
  40. package/dist/chunk-E6KOWMKA.js.map +1 -0
  41. package/dist/{chunk-3I4ONZRT.js → chunk-EVPZFV3K.js} +10 -10
  42. package/dist/chunk-EVPZFV3K.js.map +1 -0
  43. package/dist/{chunk-IZIYLYPK.js → chunk-G5V75JD5.js} +2 -2
  44. package/dist/chunk-GRISNU6G.js +651 -0
  45. package/dist/chunk-GRISNU6G.js.map +1 -0
  46. package/dist/chunk-HEXKPKCK.js +1396 -0
  47. package/dist/chunk-HEXKPKCK.js.map +1 -0
  48. package/dist/{chunk-TC7APDKU.js → chunk-I5T677EA.js} +2 -2
  49. package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
  50. package/dist/chunk-KB64WNBZ.js.map +1 -0
  51. package/dist/{chunk-NWMORW3U.js → chunk-KIK2ZFAL.js} +2 -2
  52. package/dist/{chunk-CWRI4JC3.js → chunk-KKV5WH5M.js} +30 -31
  53. package/dist/chunk-KKV5WH5M.js.map +1 -0
  54. package/dist/{chunk-DGG2VY7B.js → chunk-KVHIAWVT.js} +9 -9
  55. package/dist/chunk-KVHIAWVT.js.map +1 -0
  56. package/dist/{chunk-OFDN5NKS.js → chunk-KXDRI47U.js} +69 -12
  57. package/dist/chunk-KXDRI47U.js.map +1 -0
  58. package/dist/{chunk-NUACL52E.js → chunk-LLHXQS3C.js} +2 -2
  59. package/dist/chunk-LUKXJSRI.js +73 -0
  60. package/dist/chunk-LUKXJSRI.js.map +1 -0
  61. package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
  62. package/dist/chunk-OTGH2HRS.js +1427 -0
  63. package/dist/chunk-OTGH2HRS.js.map +1 -0
  64. package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
  65. package/dist/{chunk-KAYXR544.js → chunk-QVLPWNE3.js} +2 -2
  66. package/dist/chunk-QZWEJVWV.js +207 -0
  67. package/dist/chunk-QZWEJVWV.js.map +1 -0
  68. package/dist/chunk-RJ3VBUFK.js +781 -0
  69. package/dist/chunk-RJ3VBUFK.js.map +1 -0
  70. package/dist/chunk-RSYT7MVI.js +202 -0
  71. package/dist/chunk-RSYT7MVI.js.map +1 -0
  72. package/dist/{chunk-6IIL5M2L.js → chunk-S7PZA6IV.js} +10 -8
  73. package/dist/{chunk-6IIL5M2L.js.map → chunk-S7PZA6IV.js.map} +1 -1
  74. package/dist/chunk-SKSYYBCU.js +229 -0
  75. package/dist/chunk-SKSYYBCU.js.map +1 -0
  76. package/dist/{chunk-ULSWCPQG.js → chunk-SWSJWA2S.js} +476 -5
  77. package/dist/chunk-SWSJWA2S.js.map +1 -0
  78. package/dist/{chunk-KXGQYLFZ.js → chunk-UKBAJ2QQ.js} +61 -7
  79. package/dist/chunk-UKBAJ2QQ.js.map +1 -0
  80. package/dist/{chunk-FO5GGFOV.js → chunk-UR5DGNUO.js} +71 -9
  81. package/dist/chunk-UR5DGNUO.js.map +1 -0
  82. package/dist/{chunk-QN47QVBX.js → chunk-UUEW5KWB.js} +1 -1
  83. package/dist/chunk-UUEW5KWB.js.map +1 -0
  84. package/dist/{chunk-4CO6KG5S.js → chunk-VG45TUYK.js} +53 -7
  85. package/dist/{chunk-4CO6KG5S.js.map → chunk-VG45TUYK.js.map} +1 -1
  86. package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
  87. package/dist/{chunk-KJTVU3HZ.js → chunk-WXIM2WS7.js} +8 -8
  88. package/dist/chunk-WXIM2WS7.js.map +1 -0
  89. package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
  90. package/dist/chunk-YQ57ORTV.js.map +1 -0
  91. package/dist/{chunk-SOSQILHO.js → chunk-ZNMPGMHY.js} +44 -797
  92. package/dist/chunk-ZNMPGMHY.js.map +1 -0
  93. package/dist/{claude-TP2QO3BU.js → claude-7GGEWVEM.js} +2 -2
  94. package/dist/{cleanup-PJRIFFU4.js → cleanup-6PVAC4NI.js} +85 -34
  95. package/dist/cleanup-6PVAC4NI.js.map +1 -0
  96. package/dist/cli.js +630 -801
  97. package/dist/cli.js.map +1 -1
  98. package/dist/{commit-IVP3M4HG.js → commit-FZR5XDQG.js} +26 -23
  99. package/dist/commit-FZR5XDQG.js.map +1 -0
  100. package/dist/{compile-R2J65HBQ.js → compile-7ALJHZ4N.js} +9 -9
  101. package/dist/{contribute-VDZXHK5Y.js → contribute-5GKLK3BQ.js} +14 -6
  102. package/dist/contribute-5GKLK3BQ.js.map +1 -0
  103. package/dist/{dev-server-7F622OEO.js → dev-server-7SMIB7OF.js} +29 -15
  104. package/dist/dev-server-7SMIB7OF.js.map +1 -0
  105. package/dist/{feedback-E7VET7CL.js → feedback-G2GJFN2F.js} +18 -16
  106. package/dist/{feedback-E7VET7CL.js.map → feedback-G2GJFN2F.js.map} +1 -1
  107. package/dist/{git-2QDQ2X2S.js → git-GTLKAZRJ.js} +4 -4
  108. package/dist/hooks/iloom-hook.js +15 -0
  109. package/dist/ignite-H2O5Y5A2.js +34 -0
  110. package/dist/ignite-H2O5Y5A2.js.map +1 -0
  111. package/dist/index.d.ts +482 -58
  112. package/dist/index.js +1340 -44
  113. package/dist/index.js.map +1 -1
  114. package/dist/{init-676DHF6R.js → init-32YOKXRL.js} +57 -21
  115. package/dist/init-32YOKXRL.js.map +1 -0
  116. package/dist/{issues-PJSOLOBJ.js → issues-4UUAQ5K6.js} +61 -20
  117. package/dist/issues-4UUAQ5K6.js.map +1 -0
  118. package/dist/{lint-CJM7BAIM.js → lint-AAN2NZWG.js} +9 -9
  119. package/dist/mcp/harness-server.js +140 -0
  120. package/dist/mcp/harness-server.js.map +1 -0
  121. package/dist/mcp/issue-management-server.js +2599 -262
  122. package/dist/mcp/issue-management-server.js.map +1 -1
  123. package/dist/mcp/recap-server.js +144 -21
  124. package/dist/mcp/recap-server.js.map +1 -1
  125. package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
  126. package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
  127. package/dist/{open-544H7JF5.js → open-FXWW3VI4.js} +15 -15
  128. package/dist/open-FXWW3VI4.js.map +1 -0
  129. package/dist/{plan-Q7ELXDLC.js → plan-RQ5FPIGF.js} +358 -40
  130. package/dist/plan-RQ5FPIGF.js.map +1 -0
  131. package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
  132. package/dist/prompts/CLAUDE.md +62 -0
  133. package/dist/prompts/init-prompt.txt +430 -34
  134. package/dist/prompts/issue-prompt.txt +473 -54
  135. package/dist/prompts/plan-prompt.txt +140 -19
  136. package/dist/prompts/pr-prompt.txt +44 -1
  137. package/dist/prompts/regular-prompt.txt +42 -1
  138. package/dist/prompts/session-summary-prompt.txt +14 -0
  139. package/dist/prompts/swarm-orchestrator-prompt.txt +464 -0
  140. package/dist/{rebase-YND35CIE.js → rebase-6NVLX5V7.js} +21 -12
  141. package/dist/rebase-6NVLX5V7.js.map +1 -0
  142. package/dist/{recap-3W7COH7D.js → recap-OMBOKJST.js} +47 -19
  143. package/dist/recap-OMBOKJST.js.map +1 -0
  144. package/dist/{run-QUXJKDQQ.js → run-BBXLRIZB.js} +15 -15
  145. package/dist/run-BBXLRIZB.js.map +1 -0
  146. package/dist/schema/package-iloom.schema.json +58 -0
  147. package/dist/schema/settings.schema.json +149 -15
  148. package/dist/{shell-QGECBLST.js → shell-RF7LTND5.js} +14 -7
  149. package/dist/shell-RF7LTND5.js.map +1 -0
  150. package/dist/{summary-G2T4452H.js → summary-WTQZ7XG2.js} +27 -25
  151. package/dist/summary-WTQZ7XG2.js.map +1 -0
  152. package/dist/{test-EA5NQFDC.js → test-SGO6I5Z7.js} +9 -9
  153. package/dist/{test-git-M7LSLEFL.js → test-git-XM4TM65W.js} +4 -4
  154. package/dist/test-jira-LDTOYFSD.js +96 -0
  155. package/dist/test-jira-LDTOYFSD.js.map +1 -0
  156. package/dist/{test-prefix-64NAAUON.js → test-prefix-GBO37XCN.js} +4 -4
  157. package/dist/{test-webserver-OK6Z5FJM.js → test-webserver-NZ3JTVLL.js} +6 -6
  158. package/dist/{vscode-AR5NNXXI.js → vscode-6XUGHJKL.js} +7 -7
  159. package/package.json +5 -1
  160. package/dist/ClaudeContextManager-HR5JQKAI.js +0 -14
  161. package/dist/ClaudeService-TK7FMC2X.js +0 -13
  162. package/dist/chunk-3I4ONZRT.js.map +0 -1
  163. package/dist/chunk-B7U6OKUR.js.map +0 -1
  164. package/dist/chunk-CWRI4JC3.js.map +0 -1
  165. package/dist/chunk-DGG2VY7B.js.map +0 -1
  166. package/dist/chunk-FJDRTVJX.js +0 -520
  167. package/dist/chunk-FJDRTVJX.js.map +0 -1
  168. package/dist/chunk-FO5GGFOV.js.map +0 -1
  169. package/dist/chunk-KBEIQP4G.js.map +0 -1
  170. package/dist/chunk-KJTVU3HZ.js.map +0 -1
  171. package/dist/chunk-KXGQYLFZ.js.map +0 -1
  172. package/dist/chunk-OFDN5NKS.js.map +0 -1
  173. package/dist/chunk-QN47QVBX.js.map +0 -1
  174. package/dist/chunk-R4YWBGY6.js.map +0 -1
  175. package/dist/chunk-RI2YL6TK.js.map +0 -1
  176. package/dist/chunk-SOSQILHO.js.map +0 -1
  177. package/dist/chunk-ULSWCPQG.js.map +0 -1
  178. package/dist/chunk-VOGGLPG5.js.map +0 -1
  179. package/dist/chunk-VPTAX5TR.js.map +0 -1
  180. package/dist/chunk-W6DP5RVR.js +0 -101
  181. package/dist/chunk-W6DP5RVR.js.map +0 -1
  182. package/dist/chunk-WHI5KEOX.js +0 -121
  183. package/dist/chunk-WHI5KEOX.js.map +0 -1
  184. package/dist/chunk-YKFCCV6S.js.map +0 -1
  185. package/dist/chunk-Z2TWEXR7.js.map +0 -1
  186. package/dist/cleanup-PJRIFFU4.js.map +0 -1
  187. package/dist/commit-IVP3M4HG.js.map +0 -1
  188. package/dist/contribute-VDZXHK5Y.js.map +0 -1
  189. package/dist/dev-server-7F622OEO.js.map +0 -1
  190. package/dist/ignite-IW35CDBD.js +0 -784
  191. package/dist/ignite-IW35CDBD.js.map +0 -1
  192. package/dist/init-676DHF6R.js.map +0 -1
  193. package/dist/issues-PJSOLOBJ.js.map +0 -1
  194. package/dist/open-544H7JF5.js.map +0 -1
  195. package/dist/plan-Q7ELXDLC.js.map +0 -1
  196. package/dist/rebase-YND35CIE.js.map +0 -1
  197. package/dist/recap-3W7COH7D.js.map +0 -1
  198. package/dist/run-QUXJKDQQ.js.map +0 -1
  199. package/dist/shell-QGECBLST.js.map +0 -1
  200. package/dist/summary-G2T4452H.js.map +0 -1
  201. /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-25KSZAEM.js.map} +0 -0
  202. /package/dist/{ClaudeContextManager-HR5JQKAI.js.map → ClaudeContextManager-66GR4BGM.js.map} +0 -0
  203. /package/dist/{ClaudeService-TK7FMC2X.js.map → ClaudeService-7KM5NA5Z.js.map} +0 -0
  204. /package/dist/{GitHubService-TGWJN4V4.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
  205. /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
  206. /package/dist/{LoomLauncher-73NXL2CL.js.map → LoomLauncher-TDLZSYG2.js.map} +0 -0
  207. /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
  208. /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
  209. /package/dist/{SettingsManager-AW3JTJHD.js.map → PromptTemplateManager-YOE2SIPG.js.map} +0 -0
  210. /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-FNKCOZMQ.js.map} +0 -0
  211. /package/dist/{build-THZI572G.js.map → build-VHGEMXBA.js.map} +0 -0
  212. /package/dist/{chunk-AR5QKYNE.js.map → chunk-4FGEGQW4.js.map} +0 -0
  213. /package/dist/{chunk-A7NJF73J.js.map → chunk-CVCTIDDK.js.map} +0 -0
  214. /package/dist/{chunk-IZIYLYPK.js.map → chunk-G5V75JD5.js.map} +0 -0
  215. /package/dist/{chunk-TC7APDKU.js.map → chunk-I5T677EA.js.map} +0 -0
  216. /package/dist/{chunk-NWMORW3U.js.map → chunk-KIK2ZFAL.js.map} +0 -0
  217. /package/dist/{chunk-NUACL52E.js.map → chunk-LLHXQS3C.js.map} +0 -0
  218. /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
  219. /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
  220. /package/dist/{chunk-KAYXR544.js.map → chunk-QVLPWNE3.js.map} +0 -0
  221. /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
  222. /package/dist/{git-2QDQ2X2S.js.map → claude-7GGEWVEM.js.map} +0 -0
  223. /package/dist/{compile-R2J65HBQ.js.map → compile-7ALJHZ4N.js.map} +0 -0
  224. /package/dist/{neon-helpers-VVFFTLXE.js.map → git-GTLKAZRJ.js.map} +0 -0
  225. /package/dist/{lint-CJM7BAIM.js.map → lint-AAN2NZWG.js.map} +0 -0
  226. /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
  227. /package/dist/{test-EA5NQFDC.js.map → test-SGO6I5Z7.js.map} +0 -0
  228. /package/dist/{test-git-M7LSLEFL.js.map → test-git-XM4TM65W.js.map} +0 -0
  229. /package/dist/{test-prefix-64NAAUON.js.map → test-prefix-GBO37XCN.js.map} +0 -0
  230. /package/dist/{test-webserver-OK6Z5FJM.js.map → test-webserver-NZ3JTVLL.js.map} +0 -0
  231. /package/dist/{vscode-AR5NNXXI.js.map → vscode-6XUGHJKL.js.map} +0 -0
@@ -0,0 +1,651 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ CLIIsolationManager,
4
+ DatabaseManager,
5
+ EnvironmentManager,
6
+ LoomManager
7
+ } from "./chunk-ZNMPGMHY.js";
8
+ import {
9
+ buildDependencyMap,
10
+ fetchChildIssueDetails,
11
+ fetchChildIssues
12
+ } from "./chunk-QZWEJVWV.js";
13
+ import {
14
+ matchIssueIdentifier
15
+ } from "./chunk-63QWFWH3.js";
16
+ import {
17
+ createNeonProviderFromSettings
18
+ } from "./chunk-P4O6EH46.js";
19
+ import {
20
+ TelemetryService
21
+ } from "./chunk-RSYT7MVI.js";
22
+ import {
23
+ GitWorktreeManager
24
+ } from "./chunk-I5T677EA.js";
25
+ import {
26
+ FirstRunManager
27
+ } from "./chunk-Q7POFB5Q.js";
28
+ import {
29
+ capitalizeFirstLetter
30
+ } from "./chunk-4E7LCFUG.js";
31
+ import {
32
+ ProjectCapabilityDetector
33
+ } from "./chunk-MORRVYPT.js";
34
+ import {
35
+ getConfiguredRepoFromSettings,
36
+ hasMultipleRemotes
37
+ } from "./chunk-FXDYIV3K.js";
38
+ import {
39
+ ClaudeContextManager
40
+ } from "./chunk-E6KOWMKA.js";
41
+ import {
42
+ extractSettingsOverrides
43
+ } from "./chunk-GYCR2LOU.js";
44
+ import {
45
+ DefaultBranchNamingService
46
+ } from "./chunk-QVLPWNE3.js";
47
+ import {
48
+ findMainWorktreePathWithSettings,
49
+ getRepoRoot
50
+ } from "./chunk-4FGEGQW4.js";
51
+ import {
52
+ SettingsManager
53
+ } from "./chunk-7VHJNVLF.js";
54
+ import {
55
+ IssueTrackerFactory
56
+ } from "./chunk-UKBAJ2QQ.js";
57
+ import {
58
+ GitHubService
59
+ } from "./chunk-KXDRI47U.js";
60
+ import {
61
+ getLogger
62
+ } from "./chunk-6MLEBAYZ.js";
63
+ import {
64
+ isInteractiveEnvironment,
65
+ promptConfirmation,
66
+ waitForKeypress
67
+ } from "./chunk-7JDMYTFZ.js";
68
+ import {
69
+ loadEnvIntoProcess,
70
+ logger
71
+ } from "./chunk-VT4PDUYT.js";
72
+
73
+ // src/utils/first-run-setup.ts
74
+ import { existsSync } from "fs";
75
+ import { readFile } from "fs/promises";
76
+ import path from "path";
77
+ import chalk from "chalk";
78
+ async function getProjectRoot() {
79
+ const repoRoot = await getRepoRoot();
80
+ if (repoRoot) {
81
+ logger.debug(`getProjectRoot: Using git repo root: ${repoRoot}`);
82
+ return repoRoot;
83
+ }
84
+ const cwd = process.cwd();
85
+ logger.debug(`getProjectRoot: Not in git repo, using cwd: ${cwd}`);
86
+ return cwd;
87
+ }
88
+ async function needsFirstRunSetup() {
89
+ const projectRoot = await getProjectRoot();
90
+ const firstRunManager = new FirstRunManager();
91
+ const isConfigured = await firstRunManager.isProjectConfigured(projectRoot);
92
+ if (isConfigured) {
93
+ logger.debug("needsFirstRunSetup: Project is tracked as configured globally");
94
+ return false;
95
+ }
96
+ const iloomDir = path.join(projectRoot, ".iloom");
97
+ if (!existsSync(iloomDir)) {
98
+ return true;
99
+ }
100
+ const settingsPath = path.join(iloomDir, "settings.json");
101
+ const settingsLocalPath = path.join(iloomDir, "settings.local.json");
102
+ const hasSettings = await hasNonEmptySettings(settingsPath);
103
+ const hasLocalSettings = await hasNonEmptySettings(settingsLocalPath);
104
+ return !hasSettings && !hasLocalSettings;
105
+ }
106
+ async function hasNonEmptySettings(filePath) {
107
+ if (!existsSync(filePath)) return false;
108
+ try {
109
+ const content = await readFile(filePath, "utf-8");
110
+ const parsed = JSON.parse(content);
111
+ return Object.keys(parsed).length > 0;
112
+ } catch {
113
+ return false;
114
+ }
115
+ }
116
+ function displayDefaultsBox() {
117
+ logger.info(chalk.bold("Default Configuration:"));
118
+ logger.info("");
119
+ logger.info(` ${chalk.cyan("Main Branch:")} main`);
120
+ logger.info(` ${chalk.cyan("IDE:")} vscode`);
121
+ logger.info(` ${chalk.cyan("Issue Tracker:")} GitHub Issues`);
122
+ logger.info(` ${chalk.cyan("Merge Mode:")} local ${chalk.dim("(merge locally)")}`);
123
+ logger.info(` ${chalk.cyan("Base Port:")} 3000`);
124
+ }
125
+ async function launchFirstRunSetup() {
126
+ logger.info("First-time project setup detected.");
127
+ logger.info("");
128
+ displayDefaultsBox();
129
+ logger.info("");
130
+ const acceptDefaults = await promptConfirmation(
131
+ "Are these defaults OK?",
132
+ true
133
+ // default to true, so Enter accepts
134
+ );
135
+ if (acceptDefaults) {
136
+ const projectRoot = await getProjectRoot();
137
+ const firstRunManager = new FirstRunManager();
138
+ await firstRunManager.markProjectAsConfigured(projectRoot);
139
+ logger.info(chalk.green("Configuration complete! Using defaults."));
140
+ logger.info("You can run `il init` anytime to customize settings.");
141
+ return;
142
+ }
143
+ logger.info("");
144
+ logger.info("iloom will now launch an interactive configuration session with Claude.");
145
+ await waitForKeypress("Press any key to start configuration...");
146
+ const { InitCommand } = await import("./init-32YOKXRL.js");
147
+ const initCommand = new InitCommand();
148
+ await initCommand.execute(
149
+ "Help me configure iloom settings for this project. This is my first time using iloom here. Note: Your iloom command will execute once we are done with configuration changes."
150
+ );
151
+ logger.info("Configuration complete! Continuing with your original command...");
152
+ }
153
+
154
+ // src/commands/start.ts
155
+ import path2 from "path";
156
+ var StartCommand = class {
157
+ constructor(issueTracker, loomManager, _agentManager, settingsManager) {
158
+ this.loomManager = null;
159
+ this.githubService = null;
160
+ this.issueTracker = issueTracker;
161
+ this.settingsManager = settingsManager ?? new SettingsManager();
162
+ this.providedLoomManager = loomManager;
163
+ const envResult = loadEnvIntoProcess();
164
+ if (envResult.error) {
165
+ getLogger().debug(`Environment loading warning: ${envResult.error.message}`);
166
+ }
167
+ if (envResult.parsed) {
168
+ getLogger().debug(`Loaded ${Object.keys(envResult.parsed).length} environment variables`);
169
+ }
170
+ }
171
+ /**
172
+ * Get or create a GitHubService instance for PR operations
173
+ * Used when the configured issue tracker doesn't support PRs (e.g., Linear)
174
+ */
175
+ getGitHubService() {
176
+ this.githubService ??= new GitHubService();
177
+ return this.githubService;
178
+ }
179
+ /**
180
+ * Initialize LoomManager with the main worktree path
181
+ * Uses lazy initialization to ensure we have the correct path
182
+ */
183
+ async initializeLoomManager() {
184
+ var _a, _b;
185
+ if (this.loomManager) {
186
+ return this.loomManager;
187
+ }
188
+ if (this.providedLoomManager) {
189
+ this.loomManager = this.providedLoomManager;
190
+ return this.loomManager;
191
+ }
192
+ const mainWorktreePath = await findMainWorktreePathWithSettings();
193
+ const settings = await this.settingsManager.loadSettings();
194
+ const environmentManager = new EnvironmentManager();
195
+ const neonProvider = createNeonProviderFromSettings(settings);
196
+ const databaseUrlEnvVarName = ((_b = (_a = settings.capabilities) == null ? void 0 : _a.database) == null ? void 0 : _b.databaseUrlEnvVarName) ?? "DATABASE_URL";
197
+ const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
198
+ const branchNaming = new DefaultBranchNamingService({ useClaude: true });
199
+ this.loomManager = new LoomManager(
200
+ new GitWorktreeManager(mainWorktreePath),
201
+ this.issueTracker,
202
+ branchNaming,
203
+ // Add branch naming service
204
+ environmentManager,
205
+ // Reuse same instance
206
+ new ClaudeContextManager(),
207
+ new ProjectCapabilityDetector(),
208
+ new CLIIsolationManager(),
209
+ this.settingsManager,
210
+ // Use same instance with CLI overrides
211
+ databaseManager
212
+ // Add database manager
213
+ );
214
+ return this.loomManager;
215
+ }
216
+ /**
217
+ * Main entry point for the start command
218
+ */
219
+ async execute(input) {
220
+ var _a, _b, _c, _d, _e;
221
+ const isJsonMode = input.options.json === true;
222
+ try {
223
+ const initialSettings = await this.settingsManager.loadSettings();
224
+ if (!isJsonMode && (process.env.FORCE_FIRST_TIME_SETUP === "true" || await needsFirstRunSetup())) {
225
+ await launchFirstRunSetup();
226
+ const newSettings = await this.settingsManager.loadSettings();
227
+ const newProvider = ((_a = newSettings.issueManagement) == null ? void 0 : _a.provider) ?? "github";
228
+ if (newProvider !== this.issueTracker.providerName) {
229
+ getLogger().debug(`Reinitializing issue tracker: provider changed to "${newProvider}"`);
230
+ this.issueTracker = IssueTrackerFactory.create(newSettings);
231
+ }
232
+ }
233
+ let repo;
234
+ if (this.issueTracker.providerName === "github" && await hasMultipleRemotes()) {
235
+ repo = await getConfiguredRepoFromSettings(initialSettings);
236
+ getLogger().info(`Using GitHub repository: ${repo}`);
237
+ }
238
+ const loomManager = await this.initializeLoomManager();
239
+ let parentLoom = await this.detectParentLoom(loomManager);
240
+ const parsed = await this.parseInput(input.identifier, repo);
241
+ await this.validateInput(parsed, repo);
242
+ if (parentLoom) {
243
+ const parentDisplay = parentLoom.type === "issue" ? `issue #${parentLoom.identifier}` : parentLoom.type === "pr" ? `PR #${parentLoom.identifier}` : `branch ${parentLoom.identifier}`;
244
+ if (input.options.childLoom === true) {
245
+ getLogger().info(`Creating as child loom of ${parentDisplay} (--child-loom flag)`);
246
+ } else if (input.options.childLoom === false) {
247
+ parentLoom = null;
248
+ getLogger().info("Creating as independent loom (--no-child-loom flag)");
249
+ } else {
250
+ if (isJsonMode) {
251
+ throw new Error("JSON mode requires explicit --child-loom or --no-child-loom flag when running from inside a loom");
252
+ }
253
+ let createAsChild = true;
254
+ if (isInteractiveEnvironment()) {
255
+ createAsChild = await promptConfirmation(
256
+ `You are not in your main worktree. Create as a child loom of ${parentDisplay}?`,
257
+ true
258
+ // Default yes
259
+ );
260
+ } else {
261
+ throw new Error("Non-interactive environment detected, use either --child-loom or --no-child-loom to specify behavior");
262
+ }
263
+ if (!createAsChild) {
264
+ parentLoom = null;
265
+ getLogger().info("Creating as independent loom");
266
+ }
267
+ }
268
+ } else if (input.options.childLoom === true) {
269
+ getLogger().debug("--child-loom flag provided but not running from inside an existing loom (ignored)");
270
+ }
271
+ if (parsed.type === "description") {
272
+ getLogger().info("Creating issue from description...");
273
+ const title = capitalizeFirstLetter(parsed.originalInput);
274
+ const body = input.options.body ? capitalizeFirstLetter(input.options.body) : "";
275
+ const result = await this.issueTracker.createIssue(
276
+ title,
277
+ // Use capitalized description as title
278
+ body
279
+ // Use capitalized body or empty
280
+ );
281
+ getLogger().success(`Created issue #${result.number}: ${result.url}`);
282
+ parsed.type = "issue";
283
+ parsed.number = result.number;
284
+ }
285
+ let childIssueNumbers = [];
286
+ let childIssues = [];
287
+ let dependencyMap = {};
288
+ if (parsed.type === "issue" && parsed.number) {
289
+ const settings2 = await this.settingsManager.loadSettings();
290
+ const epicIssueTracker = IssueTrackerFactory.create(settings2);
291
+ let children = [];
292
+ try {
293
+ children = await fetchChildIssues(String(parsed.number), epicIssueTracker, repo);
294
+ } catch (error) {
295
+ getLogger().warn(`Failed to check for child issues: ${error instanceof Error ? error.message : "Unknown error"}. Proceeding as normal loom.`);
296
+ }
297
+ if (children.length > 0) {
298
+ childIssueNumbers = children.map((c) => c.id);
299
+ let createAsEpic = false;
300
+ if (input.options.epic === true) {
301
+ createAsEpic = true;
302
+ getLogger().info(`Creating as epic loom with ${children.length} child issue(s) (--epic flag)`);
303
+ } else if (input.options.epic === false) {
304
+ createAsEpic = false;
305
+ getLogger().info("Creating as normal loom (--no-epic flag)");
306
+ } else {
307
+ if (isJsonMode) {
308
+ throw new Error("JSON mode requires explicit --epic or --no-epic flag when issue has child issues");
309
+ }
310
+ if (isInteractiveEnvironment()) {
311
+ createAsEpic = await promptConfirmation(
312
+ `This issue has ${children.length} child issue(s). Create as epic loom?`,
313
+ true
314
+ // Default yes
315
+ );
316
+ } else {
317
+ throw new Error("Non-interactive environment detected, use either --epic or --no-epic to specify behavior");
318
+ }
319
+ }
320
+ if (createAsEpic) {
321
+ parsed.type = "epic";
322
+ try {
323
+ const [details, depMap] = await Promise.all([
324
+ fetchChildIssueDetails(String(parsed.number), epicIssueTracker, repo),
325
+ buildDependencyMap(childIssueNumbers, settings2, repo)
326
+ ]);
327
+ childIssues = details ?? [];
328
+ dependencyMap = depMap ?? {};
329
+ getLogger().info(`Fetched ${childIssues.length} child issue details and dependency map`);
330
+ } catch (error) {
331
+ parsed.type = "issue";
332
+ childIssueNumbers = [];
333
+ getLogger().warn(`Failed to fetch epic child data, reverting to normal loom: ${error instanceof Error ? error.message : String(error)}`);
334
+ }
335
+ } else {
336
+ childIssueNumbers = [];
337
+ }
338
+ }
339
+ }
340
+ if (input.options.oneShot === "bypassPermissions" && input.options.claude !== false && !isJsonMode) {
341
+ const confirmed = await promptConfirmation(
342
+ "WARNING: bypassPermissions mode will allow Claude to execute all tool calls without confirmation. This can be dangerous. Do you want to proceed?"
343
+ );
344
+ if (!confirmed) {
345
+ getLogger().info("Operation cancelled by user");
346
+ process.exit(0);
347
+ }
348
+ }
349
+ const cliOverrides = extractSettingsOverrides();
350
+ const settings = await this.settingsManager.loadSettings(void 0, cliOverrides);
351
+ const workflowType = parsed.type === "branch" ? "regular" : parsed.type === "epic" ? "issue" : parsed.type;
352
+ const workflowConfig = (_b = settings.workflows) == null ? void 0 : _b[workflowType];
353
+ const { extractRawSetArguments, getExecutablePath } = await import("./cli-overrides-XFZWY7CM.js");
354
+ const setArguments = extractRawSetArguments();
355
+ const executablePath = getExecutablePath();
356
+ getLogger().info(`Validated input: ${this.formatParsedInput(parsed)}`);
357
+ const identifier = parsed.type === "branch" ? parsed.branchName ?? "" : parsed.number ?? 0;
358
+ const enableClaude = input.options.claude ?? (workflowConfig == null ? void 0 : workflowConfig.startAiAgent) ?? true;
359
+ const enableCode = input.options.code ?? (workflowConfig == null ? void 0 : workflowConfig.startIde) ?? true;
360
+ const enableDevServer = input.options.devServer ?? (workflowConfig == null ? void 0 : workflowConfig.startDevServer) ?? true;
361
+ const enableTerminal = input.options.terminal ?? (workflowConfig == null ? void 0 : workflowConfig.startTerminal) ?? false;
362
+ getLogger().debug("Final workflow config values:", {
363
+ enableClaude,
364
+ enableCode,
365
+ enableDevServer,
366
+ enableTerminal
367
+ });
368
+ const loom = await loomManager.createIloom({
369
+ type: parsed.type,
370
+ identifier,
371
+ originalInput: parsed.originalInput,
372
+ ...parentLoom && { parentLoom },
373
+ options: {
374
+ enableClaude,
375
+ enableCode,
376
+ enableDevServer,
377
+ enableTerminal,
378
+ ...input.options.oneShot && { oneShot: input.options.oneShot },
379
+ ...setArguments.length > 0 && { setArguments },
380
+ ...executablePath && { executablePath },
381
+ ...childIssueNumbers.length > 0 && { childIssueNumbers },
382
+ ...childIssues.length > 0 && { childIssues },
383
+ ...Object.keys(dependencyMap).length > 0 && { dependencyMap }
384
+ }
385
+ });
386
+ getLogger().success(`Created loom: ${loom.id} at ${loom.path}`);
387
+ try {
388
+ const oneShotMap = {
389
+ noReview: "skip-reviews",
390
+ bypassPermissions: "yolo"
391
+ };
392
+ TelemetryService.getInstance().track("loom.created", {
393
+ source_type: parsed.type === "epic" ? "issue" : parsed.type,
394
+ tracker: this.issueTracker.providerName,
395
+ is_child_loom: !!parentLoom,
396
+ one_shot_mode: oneShotMap[input.options.oneShot ?? ""] ?? "default"
397
+ });
398
+ } catch (error) {
399
+ getLogger().debug(`Failed to track loom.created telemetry: ${error instanceof Error ? error.message : String(error)}`);
400
+ }
401
+ getLogger().info(` Branch: ${loom.branch}`);
402
+ if ((_c = loom.capabilities) == null ? void 0 : _c.includes("web")) {
403
+ getLogger().info(` Port: ${loom.port}`);
404
+ }
405
+ if ((_d = loom.issueData) == null ? void 0 : _d.title) {
406
+ getLogger().info(` Title: ${loom.issueData.title}`);
407
+ }
408
+ if (parsed.type === "epic") {
409
+ getLogger().info(` Epic: yes (${childIssueNumbers.length} child issue(s))`);
410
+ }
411
+ if (isJsonMode) {
412
+ return {
413
+ id: loom.id,
414
+ path: loom.path,
415
+ branch: loom.branch,
416
+ type: parsed.type,
417
+ identifier: loom.identifier,
418
+ ...loom.port !== void 0 && { port: loom.port },
419
+ ...((_e = loom.issueData) == null ? void 0 : _e.title) && { title: loom.issueData.title },
420
+ ...loom.capabilities && { capabilities: loom.capabilities },
421
+ ...childIssueNumbers.length > 0 && { childIssueNumbers }
422
+ };
423
+ }
424
+ } catch (error) {
425
+ if (error instanceof Error) {
426
+ getLogger().error(`${error.message}`);
427
+ } else {
428
+ getLogger().error("An unknown error occurred");
429
+ }
430
+ throw error;
431
+ }
432
+ }
433
+ /**
434
+ * Parse input to determine type and extract relevant data
435
+ */
436
+ async parseInput(identifier, repo) {
437
+ const hasLeadingSpace = identifier.startsWith(" ");
438
+ const trimmedIdentifier = identifier.trim();
439
+ if (!trimmedIdentifier) {
440
+ throw new Error("Missing required argument: identifier");
441
+ }
442
+ const spaceCount = (trimmedIdentifier.match(/ /g) ?? []).length;
443
+ if (trimmedIdentifier.length > 15 && spaceCount >= 1) {
444
+ return {
445
+ type: "description",
446
+ originalInput: hasLeadingSpace ? " " + trimmedIdentifier : trimmedIdentifier
447
+ };
448
+ }
449
+ const prPattern = /^pr[/-](\d+)$/i;
450
+ const prMatch = trimmedIdentifier.match(prPattern);
451
+ if (prMatch == null ? void 0 : prMatch[1]) {
452
+ return {
453
+ type: "pr",
454
+ number: parseInt(prMatch[1], 10),
455
+ originalInput: trimmedIdentifier
456
+ };
457
+ }
458
+ const identifierMatch = matchIssueIdentifier(trimmedIdentifier);
459
+ if (identifierMatch.type === "project-key" && identifierMatch.identifier) {
460
+ const detection = await this.issueTracker.detectInputType(
461
+ trimmedIdentifier,
462
+ repo
463
+ );
464
+ if (detection.type === "issue" && detection.identifier) {
465
+ return {
466
+ type: "issue",
467
+ number: detection.identifier,
468
+ // Keep as string for project key identifiers
469
+ originalInput: trimmedIdentifier
470
+ };
471
+ }
472
+ throw new Error(
473
+ `Could not find issue matching identifier ${identifierMatch.identifier}`
474
+ );
475
+ }
476
+ if (identifierMatch.type === "numeric" && identifierMatch.identifier) {
477
+ const number = parseInt(identifierMatch.identifier, 10);
478
+ if (this.issueTracker.supportsPullRequests) {
479
+ const detection = await this.issueTracker.detectInputType(
480
+ trimmedIdentifier,
481
+ repo
482
+ );
483
+ if (detection.type === "pr") {
484
+ return {
485
+ type: "pr",
486
+ number: detection.identifier ? parseInt(detection.identifier, 10) : number,
487
+ originalInput: trimmedIdentifier
488
+ };
489
+ } else if (detection.type === "issue") {
490
+ return {
491
+ type: "issue",
492
+ number: detection.identifier ? parseInt(detection.identifier, 10) : number,
493
+ originalInput: trimmedIdentifier
494
+ };
495
+ } else {
496
+ throw new Error(`Could not find issue or PR #${number}`);
497
+ }
498
+ } else {
499
+ const githubService = this.getGitHubService();
500
+ const detection = await githubService.detectInputType(trimmedIdentifier, repo);
501
+ if (detection.type === "pr") {
502
+ return {
503
+ type: "pr",
504
+ number: detection.identifier ? parseInt(detection.identifier, 10) : number,
505
+ originalInput: trimmedIdentifier
506
+ };
507
+ } else {
508
+ return {
509
+ type: "issue",
510
+ number,
511
+ originalInput: trimmedIdentifier
512
+ };
513
+ }
514
+ }
515
+ }
516
+ return {
517
+ type: "branch",
518
+ branchName: trimmedIdentifier,
519
+ originalInput: trimmedIdentifier
520
+ };
521
+ }
522
+ /**
523
+ * Validate the parsed input based on its type
524
+ */
525
+ async validateInput(parsed, repo) {
526
+ switch (parsed.type) {
527
+ case "pr": {
528
+ if (!parsed.number) {
529
+ throw new Error("Invalid PR number");
530
+ }
531
+ if (this.issueTracker.supportsPullRequests && this.issueTracker.fetchPR && this.issueTracker.validatePRState) {
532
+ const pr = await this.issueTracker.fetchPR(parsed.number, repo);
533
+ await this.issueTracker.validatePRState(pr);
534
+ } else {
535
+ const githubService = this.getGitHubService();
536
+ const pr = await githubService.fetchPR(parsed.number, repo);
537
+ await githubService.validatePRState(pr);
538
+ }
539
+ getLogger().debug(`Validated PR #${parsed.number}`);
540
+ break;
541
+ }
542
+ case "issue": {
543
+ if (!parsed.number) {
544
+ throw new Error("Invalid issue number");
545
+ }
546
+ const issue = await this.issueTracker.fetchIssue(parsed.number, repo);
547
+ await this.issueTracker.validateIssueState(issue);
548
+ getLogger().debug(`Validated issue #${parsed.number}`);
549
+ break;
550
+ }
551
+ case "branch": {
552
+ if (!parsed.branchName) {
553
+ throw new Error("Invalid branch name");
554
+ }
555
+ if (!this.isValidBranchName(parsed.branchName)) {
556
+ throw new Error(
557
+ "Invalid branch name. Use only letters, numbers, hyphens, underscores, and slashes"
558
+ );
559
+ }
560
+ getLogger().debug(`Validated branch name: ${parsed.branchName}`);
561
+ break;
562
+ }
563
+ case "description": {
564
+ getLogger().debug("Detected description input", {
565
+ length: parsed.originalInput.length
566
+ });
567
+ break;
568
+ }
569
+ default: {
570
+ const unknownType = parsed;
571
+ throw new Error(`Unknown input type: ${unknownType.type}`);
572
+ }
573
+ }
574
+ }
575
+ /**
576
+ * Validate branch name format
577
+ */
578
+ isValidBranchName(branch) {
579
+ return /^[a-zA-Z0-9/_-]+$/.test(branch);
580
+ }
581
+ /**
582
+ * Format parsed input for display
583
+ */
584
+ formatParsedInput(parsed) {
585
+ switch (parsed.type) {
586
+ case "pr":
587
+ return `PR #${parsed.number}`;
588
+ case "issue":
589
+ return `Issue #${parsed.number}`;
590
+ case "epic":
591
+ return `Epic #${parsed.number}`;
592
+ case "branch":
593
+ return `Branch '${parsed.branchName}'`;
594
+ case "description":
595
+ return `Description: ${parsed.originalInput.slice(0, 50)}...`;
596
+ default:
597
+ return "Unknown input";
598
+ }
599
+ }
600
+ /**
601
+ * Detect if running from inside an existing loom worktree
602
+ * Returns parent loom info if detected, null otherwise
603
+ */
604
+ async detectParentLoom(loomManager) {
605
+ try {
606
+ const cwd = process.cwd();
607
+ const looms = await loomManager.listLooms();
608
+ if (!looms) {
609
+ return null;
610
+ }
611
+ const mainWorktreePath = await findMainWorktreePathWithSettings();
612
+ const parentLoom = looms.find((loom) => {
613
+ if (loom.path === mainWorktreePath) {
614
+ return false;
615
+ }
616
+ return cwd === loom.path || cwd.startsWith(loom.path + path2.sep);
617
+ });
618
+ if (!parentLoom) {
619
+ return null;
620
+ }
621
+ getLogger().debug(`Detected parent loom: ${parentLoom.type} ${parentLoom.identifier} at ${parentLoom.path}`);
622
+ const result = {
623
+ type: parentLoom.type,
624
+ identifier: parentLoom.identifier,
625
+ branchName: parentLoom.branch,
626
+ worktreePath: parentLoom.path
627
+ };
628
+ if (parentLoom.databaseBranch) {
629
+ result.databaseBranch = parentLoom.databaseBranch;
630
+ }
631
+ if (!result.databaseBranch) {
632
+ const databaseBranch = await loomManager.getDatabaseBranchForLoom(parentLoom.path);
633
+ if (databaseBranch) {
634
+ result.databaseBranch = databaseBranch;
635
+ getLogger().debug(`Detected parent database branch: ${databaseBranch}`);
636
+ }
637
+ }
638
+ return result;
639
+ } catch (error) {
640
+ getLogger().debug(`Failed to detect parent loom: ${error instanceof Error ? error.message : "Unknown error"}`);
641
+ return null;
642
+ }
643
+ }
644
+ };
645
+
646
+ export {
647
+ needsFirstRunSetup,
648
+ launchFirstRunSetup,
649
+ StartCommand
650
+ };
651
+ //# sourceMappingURL=chunk-GRISNU6G.js.map