@iloom/cli 0.9.1 → 0.10.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 (222) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +179 -41
  3. package/dist/{BranchNamingService-K6XNWQ6C.js → BranchNamingService-ECJHBB67.js} +2 -2
  4. package/dist/ClaudeContextManager-QXX6ZFST.js +14 -0
  5. package/dist/ClaudeService-NJNK2SUH.js +13 -0
  6. package/dist/{GitHubService-O7T6CFAJ.js → GitHubService-MEHKHUQP.js} +4 -4
  7. package/dist/IssueTrackerFactory-NG53YX5S.js +14 -0
  8. package/dist/{LoomLauncher-3I47SUPV.js → LoomLauncher-L64HHS3T.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-DULSVRRE.js} +2 -2
  12. package/dist/README.md +179 -41
  13. package/dist/{SettingsManager-QR7V2IW2.js → SettingsManager-BQDQA3FK.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-IC4CJRMP.js → build-5GO3XW26.js} +9 -9
  23. package/dist/{chunk-USSL2X4A.js → chunk-3D7WQM7I.js} +2 -2
  24. package/dist/chunk-4232AHNQ.js +35 -0
  25. package/dist/chunk-4232AHNQ.js.map +1 -0
  26. package/dist/{chunk-QN47QVBX.js → chunk-4WJNIR5O.js} +1 -1
  27. package/dist/chunk-4WJNIR5O.js.map +1 -0
  28. package/dist/{chunk-2JPXGGP4.js → chunk-5MWV33NN.js} +4 -4
  29. package/dist/{chunk-POU2UMWN.js → chunk-6EU6TCF6.js} +10 -10
  30. package/dist/chunk-6EU6TCF6.js.map +1 -0
  31. package/dist/{chunk-Y5O2ALDZ.js → chunk-FB47TIJG.js} +29 -11
  32. package/dist/chunk-FB47TIJG.js.map +1 -0
  33. package/dist/chunk-HEXKPKCK.js +1396 -0
  34. package/dist/chunk-HEXKPKCK.js.map +1 -0
  35. package/dist/{chunk-KAYXR544.js → chunk-J5S7DFYC.js} +2 -2
  36. package/dist/{chunk-OK7LUTRW.js → chunk-JO2LZ6EQ.js} +476 -5
  37. package/dist/chunk-JO2LZ6EQ.js.map +1 -0
  38. package/dist/{chunk-KBEIQP4G.js → chunk-KB64WNBZ.js} +43 -3
  39. package/dist/chunk-KB64WNBZ.js.map +1 -0
  40. package/dist/{chunk-Y5HSSIK2.js → chunk-KXDRI47U.js} +71 -13
  41. package/dist/chunk-KXDRI47U.js.map +1 -0
  42. package/dist/{chunk-HZXBHMVM.js → chunk-LXLMMXXY.js} +54 -14
  43. package/dist/chunk-LXLMMXXY.js.map +1 -0
  44. package/dist/{chunk-H6ST2TGP.js → chunk-MNHZB4Z2.js} +4 -4
  45. package/dist/{chunk-TL72BGP6.js → chunk-MORRVYPT.js} +2 -2
  46. package/dist/{chunk-TGRK3CHF.js → chunk-NRSWLOAZ.js} +8 -8
  47. package/dist/chunk-NRSWLOAZ.js.map +1 -0
  48. package/dist/{chunk-FO5GGFOV.js → chunk-ONQYPICO.js} +13 -5
  49. package/dist/chunk-ONQYPICO.js.map +1 -0
  50. package/dist/{chunk-7ZEHSSUP.js → chunk-P4O6EH46.js} +4 -4
  51. package/dist/chunk-QZWEJVWV.js +207 -0
  52. package/dist/chunk-QZWEJVWV.js.map +1 -0
  53. package/dist/chunk-RSYT7MVI.js +202 -0
  54. package/dist/chunk-RSYT7MVI.js.map +1 -0
  55. package/dist/{chunk-OAVJR4PM.js → chunk-RYWFS37M.js} +6 -6
  56. package/dist/chunk-RYWFS37M.js.map +1 -0
  57. package/dist/{chunk-B7U6OKUR.js → chunk-SF2P22EE.js} +11 -3
  58. package/dist/chunk-SF2P22EE.js.map +1 -0
  59. package/dist/{chunk-MZPRBNYC.js → chunk-SN3SQCFK.js} +10 -8
  60. package/dist/{chunk-MZPRBNYC.js.map → chunk-SN3SQCFK.js.map} +1 -1
  61. package/dist/{chunk-4ZIHFUPN.js → chunk-UD3WJDIV.js} +145 -107
  62. package/dist/chunk-UD3WJDIV.js.map +1 -0
  63. package/dist/{chunk-3P6J4IZZ.js → chunk-UKBAJ2QQ.js} +61 -7
  64. package/dist/chunk-UKBAJ2QQ.js.map +1 -0
  65. package/dist/{chunk-RD7OPXZK.js → chunk-UVD4CZKS.js} +3 -3
  66. package/dist/chunk-UWGVCXRF.js +207 -0
  67. package/dist/chunk-UWGVCXRF.js.map +1 -0
  68. package/dist/{chunk-JT5LZRMI.js → chunk-VECNX6VX.js} +2 -2
  69. package/dist/{chunk-TRUMP4DA.js → chunk-VG45TUYK.js} +75 -6
  70. package/dist/chunk-VG45TUYK.js.map +1 -0
  71. package/dist/{chunk-4GAJJUYS.js → chunk-VGGST52X.js} +2 -2
  72. package/dist/{chunk-4LKGCFGG.js → chunk-WWKOVDWC.js} +2 -2
  73. package/dist/{chunk-2HZX6AMR.js → chunk-WY4QBK43.js} +7 -7
  74. package/dist/chunk-WY4QBK43.js.map +1 -0
  75. package/dist/chunk-Y4YZTHZE.js +73 -0
  76. package/dist/chunk-Y4YZTHZE.js.map +1 -0
  77. package/dist/{chunk-VOGGLPG5.js → chunk-YQ57ORTV.js} +14 -1
  78. package/dist/chunk-YQ57ORTV.js.map +1 -0
  79. package/dist/{chunk-XFEK2X2D.js → chunk-YYAKPQBT.js} +73 -20
  80. package/dist/chunk-YYAKPQBT.js.map +1 -0
  81. package/dist/{chunk-NTTSUAVM.js → chunk-ZEWU5PZK.js} +2 -2
  82. package/dist/{chunk-5LVVQGB3.js → chunk-ZHPNZC75.js} +17 -17
  83. package/dist/chunk-ZHPNZC75.js.map +1 -0
  84. package/dist/{chunk-I3HMNWQQ.js → chunk-ZW2LKWWE.js} +9 -9
  85. package/dist/chunk-ZW2LKWWE.js.map +1 -0
  86. package/dist/{claude-TP2QO3BU.js → claude-P3NQR6IJ.js} +2 -2
  87. package/dist/{cleanup-D3CSRBBZ.js → cleanup-6UCPVMFG.js} +81 -32
  88. package/dist/cleanup-6UCPVMFG.js.map +1 -0
  89. package/dist/cli.js +640 -350
  90. package/dist/cli.js.map +1 -1
  91. package/dist/{commit-IWGT42XN.js → commit-L3EPY5QG.js} +23 -21
  92. package/dist/commit-L3EPY5QG.js.map +1 -0
  93. package/dist/{compile-EOWJORKO.js → compile-ZS4HYRX5.js} +9 -9
  94. package/dist/{contribute-WSJTV2RX.js → contribute-ORDDQGSL.js} +14 -6
  95. package/dist/contribute-ORDDQGSL.js.map +1 -0
  96. package/dist/{dev-server-Q6M62ATG.js → dev-server-FYZ2AQIH.js} +29 -15
  97. package/dist/dev-server-FYZ2AQIH.js.map +1 -0
  98. package/dist/{feedback-QPNDZQRV.js → feedback-TMBXSCM5.js} +15 -15
  99. package/dist/{git-W3XUIFTR.js → git-ET64COO3.js} +4 -4
  100. package/dist/hooks/iloom-hook.js +15 -0
  101. package/dist/ignite-CGOV3TD4.js +1393 -0
  102. package/dist/ignite-CGOV3TD4.js.map +1 -0
  103. package/dist/index.d.ts +397 -53
  104. package/dist/index.js +1178 -40
  105. package/dist/index.js.map +1 -1
  106. package/dist/{init-ALYWKNWG.js → init-GFQ5W7GK.js} +57 -21
  107. package/dist/init-GFQ5W7GK.js.map +1 -0
  108. package/dist/issues-T4ZZSPEG.js +179 -0
  109. package/dist/issues-T4ZZSPEG.js.map +1 -0
  110. package/dist/{lint-IHUH45OC.js → lint-6TQXDZ3T.js} +9 -9
  111. package/dist/mcp/issue-management-server.js +2472 -257
  112. package/dist/mcp/issue-management-server.js.map +1 -1
  113. package/dist/mcp/recap-server.js +144 -21
  114. package/dist/mcp/recap-server.js.map +1 -1
  115. package/dist/{neon-helpers-VVFFTLXE.js → neon-helpers-CQN2PB4S.js} +3 -3
  116. package/dist/neon-helpers-CQN2PB4S.js.map +1 -0
  117. package/dist/{open-KWOV2OFO.js → open-5QZGXQRF.js} +15 -15
  118. package/dist/open-5QZGXQRF.js.map +1 -0
  119. package/dist/{plan-BRJBFJHF.js → plan-U7ZQWLFY.js} +41 -25
  120. package/dist/plan-U7ZQWLFY.js.map +1 -0
  121. package/dist/{projects-LH362JZQ.js → projects-2UOXFLNZ.js} +4 -4
  122. package/dist/prompts/CLAUDE.md +62 -0
  123. package/dist/prompts/init-prompt.txt +386 -47
  124. package/dist/prompts/issue-prompt.txt +427 -54
  125. package/dist/prompts/plan-prompt.txt +97 -16
  126. package/dist/prompts/pr-prompt.txt +44 -1
  127. package/dist/prompts/regular-prompt.txt +42 -1
  128. package/dist/prompts/session-summary-prompt.txt +14 -0
  129. package/dist/prompts/swarm-orchestrator-prompt.txt +437 -0
  130. package/dist/{rebase-AJOJOZUG.js → rebase-DWIB77KV.js} +10 -10
  131. package/dist/{recap-GKJXMDXW.js → recap-MX63HAKV.js} +47 -19
  132. package/dist/recap-MX63HAKV.js.map +1 -0
  133. package/dist/{run-QEUVZF7J.js → run-O3TFNQFC.js} +15 -15
  134. package/dist/run-O3TFNQFC.js.map +1 -0
  135. package/dist/schema/package-iloom.schema.json +58 -0
  136. package/dist/schema/settings.schema.json +130 -15
  137. package/dist/{shell-DAAVG4YN.js → shell-G6VC2CYR.js} +14 -7
  138. package/dist/shell-G6VC2CYR.js.map +1 -0
  139. package/dist/{summary-ZKOA35PT.js → summary-FWHAX55O.js} +27 -25
  140. package/dist/summary-FWHAX55O.js.map +1 -0
  141. package/dist/{test-5GPWWO3P.js → test-F7JNJZYP.js} +9 -9
  142. package/dist/{test-git-EJUKDB7F.js → test-git-BTAOIUE2.js} +4 -4
  143. package/dist/test-jira-CHYNV33F.js +96 -0
  144. package/dist/test-jira-CHYNV33F.js.map +1 -0
  145. package/dist/{test-prefix-23TOBUXY.js → test-prefix-Q6TFSU6F.js} +4 -4
  146. package/dist/{test-webserver-CKROHFBQ.js → test-webserver-EONCG7E7.js} +6 -6
  147. package/dist/{vscode-6TOLFCI2.js → vscode-VA5X4P25.js} +7 -7
  148. package/package.json +5 -1
  149. package/dist/ClaudeContextManager-X2Y72GRL.js +0 -14
  150. package/dist/ClaudeService-7P32TTES.js +0 -13
  151. package/dist/chunk-2HZX6AMR.js.map +0 -1
  152. package/dist/chunk-3P6J4IZZ.js.map +0 -1
  153. package/dist/chunk-4ZIHFUPN.js.map +0 -1
  154. package/dist/chunk-5LVVQGB3.js.map +0 -1
  155. package/dist/chunk-B7U6OKUR.js.map +0 -1
  156. package/dist/chunk-ENGCJIYQ.js +0 -520
  157. package/dist/chunk-ENGCJIYQ.js.map +0 -1
  158. package/dist/chunk-FO5GGFOV.js.map +0 -1
  159. package/dist/chunk-HZXBHMVM.js.map +0 -1
  160. package/dist/chunk-I3HMNWQQ.js.map +0 -1
  161. package/dist/chunk-J7FJ6PUT.js +0 -121
  162. package/dist/chunk-J7FJ6PUT.js.map +0 -1
  163. package/dist/chunk-KBEIQP4G.js.map +0 -1
  164. package/dist/chunk-OAVJR4PM.js.map +0 -1
  165. package/dist/chunk-OK7LUTRW.js.map +0 -1
  166. package/dist/chunk-POU2UMWN.js.map +0 -1
  167. package/dist/chunk-QN47QVBX.js.map +0 -1
  168. package/dist/chunk-TGRK3CHF.js.map +0 -1
  169. package/dist/chunk-TRUMP4DA.js.map +0 -1
  170. package/dist/chunk-VOGGLPG5.js.map +0 -1
  171. package/dist/chunk-XFEK2X2D.js.map +0 -1
  172. package/dist/chunk-Y5HSSIK2.js.map +0 -1
  173. package/dist/chunk-Y5O2ALDZ.js.map +0 -1
  174. package/dist/cleanup-D3CSRBBZ.js.map +0 -1
  175. package/dist/commit-IWGT42XN.js.map +0 -1
  176. package/dist/contribute-WSJTV2RX.js.map +0 -1
  177. package/dist/dev-server-Q6M62ATG.js.map +0 -1
  178. package/dist/ignite-OPO6EDYT.js +0 -784
  179. package/dist/ignite-OPO6EDYT.js.map +0 -1
  180. package/dist/init-ALYWKNWG.js.map +0 -1
  181. package/dist/issues-L7TBUPXT.js +0 -116
  182. package/dist/issues-L7TBUPXT.js.map +0 -1
  183. package/dist/open-KWOV2OFO.js.map +0 -1
  184. package/dist/plan-BRJBFJHF.js.map +0 -1
  185. package/dist/recap-GKJXMDXW.js.map +0 -1
  186. package/dist/run-QEUVZF7J.js.map +0 -1
  187. package/dist/shell-DAAVG4YN.js.map +0 -1
  188. package/dist/summary-ZKOA35PT.js.map +0 -1
  189. /package/dist/{BranchNamingService-K6XNWQ6C.js.map → BranchNamingService-ECJHBB67.js.map} +0 -0
  190. /package/dist/{ClaudeContextManager-X2Y72GRL.js.map → ClaudeContextManager-QXX6ZFST.js.map} +0 -0
  191. /package/dist/{ClaudeService-7P32TTES.js.map → ClaudeService-NJNK2SUH.js.map} +0 -0
  192. /package/dist/{GitHubService-O7T6CFAJ.js.map → GitHubService-MEHKHUQP.js.map} +0 -0
  193. /package/dist/{MetadataManager-W3C54UYT.js.map → IssueTrackerFactory-NG53YX5S.js.map} +0 -0
  194. /package/dist/{LoomLauncher-3I47SUPV.js.map → LoomLauncher-L64HHS3T.js.map} +0 -0
  195. /package/dist/{ProjectCapabilityDetector-N5L7T4IY.js.map → MetadataManager-5QZSTKNN.js.map} +0 -0
  196. /package/dist/{PromptTemplateManager-36YLQRHP.js.map → ProjectCapabilityDetector-5KSYUTBJ.js.map} +0 -0
  197. /package/dist/{SettingsManager-QR7V2IW2.js.map → PromptTemplateManager-DULSVRRE.js.map} +0 -0
  198. /package/dist/{claude-TP2QO3BU.js.map → SettingsManager-BQDQA3FK.js.map} +0 -0
  199. /package/dist/{build-IC4CJRMP.js.map → build-5GO3XW26.js.map} +0 -0
  200. /package/dist/{chunk-USSL2X4A.js.map → chunk-3D7WQM7I.js.map} +0 -0
  201. /package/dist/{chunk-2JPXGGP4.js.map → chunk-5MWV33NN.js.map} +0 -0
  202. /package/dist/{chunk-KAYXR544.js.map → chunk-J5S7DFYC.js.map} +0 -0
  203. /package/dist/{chunk-H6ST2TGP.js.map → chunk-MNHZB4Z2.js.map} +0 -0
  204. /package/dist/{chunk-TL72BGP6.js.map → chunk-MORRVYPT.js.map} +0 -0
  205. /package/dist/{chunk-7ZEHSSUP.js.map → chunk-P4O6EH46.js.map} +0 -0
  206. /package/dist/{chunk-RD7OPXZK.js.map → chunk-UVD4CZKS.js.map} +0 -0
  207. /package/dist/{chunk-JT5LZRMI.js.map → chunk-VECNX6VX.js.map} +0 -0
  208. /package/dist/{chunk-4GAJJUYS.js.map → chunk-VGGST52X.js.map} +0 -0
  209. /package/dist/{chunk-4LKGCFGG.js.map → chunk-WWKOVDWC.js.map} +0 -0
  210. /package/dist/{chunk-NTTSUAVM.js.map → chunk-ZEWU5PZK.js.map} +0 -0
  211. /package/dist/{git-W3XUIFTR.js.map → claude-P3NQR6IJ.js.map} +0 -0
  212. /package/dist/{compile-EOWJORKO.js.map → compile-ZS4HYRX5.js.map} +0 -0
  213. /package/dist/{feedback-QPNDZQRV.js.map → feedback-TMBXSCM5.js.map} +0 -0
  214. /package/dist/{neon-helpers-VVFFTLXE.js.map → git-ET64COO3.js.map} +0 -0
  215. /package/dist/{lint-IHUH45OC.js.map → lint-6TQXDZ3T.js.map} +0 -0
  216. /package/dist/{projects-LH362JZQ.js.map → projects-2UOXFLNZ.js.map} +0 -0
  217. /package/dist/{rebase-AJOJOZUG.js.map → rebase-DWIB77KV.js.map} +0 -0
  218. /package/dist/{test-5GPWWO3P.js.map → test-F7JNJZYP.js.map} +0 -0
  219. /package/dist/{test-git-EJUKDB7F.js.map → test-git-BTAOIUE2.js.map} +0 -0
  220. /package/dist/{test-prefix-23TOBUXY.js.map → test-prefix-Q6TFSU6F.js.map} +0 -0
  221. /package/dist/{test-webserver-CKROHFBQ.js.map → test-webserver-EONCG7E7.js.map} +0 -0
  222. /package/dist/{vscode-6TOLFCI2.js.map → vscode-VA5X4P25.js.map} +0 -0
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScriptCommandBase
4
- } from "./chunk-TGRK3CHF.js";
5
- import "./chunk-2HZX6AMR.js";
6
- import "./chunk-4LKGCFGG.js";
7
- import "./chunk-4GAJJUYS.js";
8
- import "./chunk-VOGGLPG5.js";
9
- import "./chunk-H6ST2TGP.js";
10
- import "./chunk-XFEK2X2D.js";
11
- import "./chunk-KBEIQP4G.js";
4
+ } from "./chunk-NRSWLOAZ.js";
5
+ import "./chunk-WWKOVDWC.js";
6
+ import "./chunk-WY4QBK43.js";
7
+ import "./chunk-VGGST52X.js";
8
+ import "./chunk-YQ57ORTV.js";
9
+ import "./chunk-MNHZB4Z2.js";
10
+ import "./chunk-YYAKPQBT.js";
11
+ import "./chunk-KB64WNBZ.js";
12
12
  import "./chunk-6MLEBAYZ.js";
13
13
  import "./chunk-VT4PDUYT.js";
14
14
 
@@ -24,4 +24,4 @@ var TestCommand = class extends ScriptCommandBase {
24
24
  export {
25
25
  TestCommand
26
26
  };
27
- //# sourceMappingURL=test-5GPWWO3P.js.map
27
+ //# sourceMappingURL=test-F7JNJZYP.js.map
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  findMainWorktreePath
4
- } from "./chunk-H6ST2TGP.js";
4
+ } from "./chunk-MNHZB4Z2.js";
5
5
  import {
6
6
  SettingsManager
7
- } from "./chunk-XFEK2X2D.js";
8
- import "./chunk-KBEIQP4G.js";
7
+ } from "./chunk-YYAKPQBT.js";
8
+ import "./chunk-KB64WNBZ.js";
9
9
  import "./chunk-6MLEBAYZ.js";
10
10
  import {
11
11
  logger
@@ -51,4 +51,4 @@ var TestGitCommand = class {
51
51
  export {
52
52
  TestGitCommand
53
53
  };
54
- //# sourceMappingURL=test-git-EJUKDB7F.js.map
54
+ //# sourceMappingURL=test-git-BTAOIUE2.js.map
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ IssueManagementProviderFactory
4
+ } from "./chunk-JO2LZ6EQ.js";
5
+ import "./chunk-4232AHNQ.js";
6
+ import {
7
+ SettingsManager
8
+ } from "./chunk-YYAKPQBT.js";
9
+ import "./chunk-HEXKPKCK.js";
10
+ import "./chunk-VG45TUYK.js";
11
+ import "./chunk-6MLEBAYZ.js";
12
+ import "./chunk-7JDMYTFZ.js";
13
+ import {
14
+ logger
15
+ } from "./chunk-VT4PDUYT.js";
16
+
17
+ // src/commands/test-jira.ts
18
+ var TestJiraCommand = class {
19
+ constructor(settingsManager) {
20
+ this.settingsManager = settingsManager ?? new SettingsManager();
21
+ }
22
+ async createProvider() {
23
+ const settings = await this.settingsManager.loadSettings();
24
+ return IssueManagementProviderFactory.create("jira", settings);
25
+ }
26
+ async createChildIssue(parentKey) {
27
+ const provider = await this.createProvider();
28
+ logger.info(`Creating test child issue under ${parentKey}...`);
29
+ const result = await provider.createChildIssue({
30
+ parentId: parentKey,
31
+ title: `[Test] Child issue of ${parentKey}`,
32
+ body: "This is a test child issue created by iloom test-jira."
33
+ });
34
+ logger.success(`Child issue created: ${result.id}`);
35
+ logger.info(` URL: ${result.url}`);
36
+ }
37
+ async createDependency(blockingKey, blockedKey) {
38
+ const provider = await this.createProvider();
39
+ logger.info(`Creating dependency: ${blockingKey} blocks ${blockedKey}...`);
40
+ await provider.createDependency({
41
+ blockingIssue: blockingKey,
42
+ blockedIssue: blockedKey
43
+ });
44
+ logger.success(`Dependency created: ${blockingKey} blocks ${blockedKey}`);
45
+ }
46
+ async getDependencies(issueKey) {
47
+ const provider = await this.createProvider();
48
+ logger.info(`Fetching dependencies for ${issueKey}...`);
49
+ const result = await provider.getDependencies({
50
+ number: issueKey,
51
+ direction: "both"
52
+ });
53
+ logger.info(`Blocking (${issueKey} blocks):`);
54
+ if (result.blocking.length === 0) {
55
+ logger.info(" (none)");
56
+ } else {
57
+ for (const dep of result.blocking) {
58
+ logger.info(` ${dep.id}: ${dep.title} [${dep.state}]`);
59
+ }
60
+ }
61
+ logger.info(`Blocked by (blocks ${issueKey}):`);
62
+ if (result.blockedBy.length === 0) {
63
+ logger.info(" (none)");
64
+ } else {
65
+ for (const dep of result.blockedBy) {
66
+ logger.info(` ${dep.id}: ${dep.title} [${dep.state}]`);
67
+ }
68
+ }
69
+ }
70
+ async removeDependency(blockingKey, blockedKey) {
71
+ const provider = await this.createProvider();
72
+ logger.info(`Removing dependency: ${blockingKey} blocks ${blockedKey}...`);
73
+ await provider.removeDependency({
74
+ blockingIssue: blockingKey,
75
+ blockedIssue: blockedKey
76
+ });
77
+ logger.success(`Dependency removed: ${blockingKey} no longer blocks ${blockedKey}`);
78
+ }
79
+ async getChildIssues(issueKey) {
80
+ const provider = await this.createProvider();
81
+ logger.info(`Fetching child issues of ${issueKey}...`);
82
+ const children = await provider.getChildIssues({ number: issueKey });
83
+ if (children.length === 0) {
84
+ logger.info("No child issues found");
85
+ } else {
86
+ logger.info(`Child issues (${children.length}):`);
87
+ for (const child of children) {
88
+ logger.info(` ${child.id}: ${child.title} [${child.state}] ${child.url}`);
89
+ }
90
+ }
91
+ }
92
+ };
93
+ export {
94
+ TestJiraCommand
95
+ };
96
+ //# sourceMappingURL=test-jira-CHYNV33F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/test-jira.ts"],"sourcesContent":["import { logger } from '../utils/logger.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { IssueManagementProviderFactory } from '../mcp/IssueManagementProviderFactory.js'\nimport type { IssueManagementProvider } from '../mcp/types.js'\n\n/**\n * Test command for Jira integration\n * Tests various Jira API operations against a real Jira instance\n */\nexport class TestJiraCommand {\n private readonly settingsManager: SettingsManager\n\n constructor(settingsManager?: SettingsManager) {\n this.settingsManager = settingsManager ?? new SettingsManager()\n }\n\n private async createProvider(): Promise<IssueManagementProvider> {\n const settings = await this.settingsManager.loadSettings()\n return IssueManagementProviderFactory.create('jira', settings)\n }\n\n async createChildIssue(parentKey: string): Promise<void> {\n const provider = await this.createProvider()\n\n logger.info(`Creating test child issue under ${parentKey}...`)\n const result = await provider.createChildIssue({\n parentId: parentKey,\n title: `[Test] Child issue of ${parentKey}`,\n body: 'This is a test child issue created by iloom test-jira.',\n })\n\n logger.success(`Child issue created: ${result.id}`)\n logger.info(` URL: ${result.url}`)\n }\n\n async createDependency(blockingKey: string, blockedKey: string): Promise<void> {\n const provider = await this.createProvider()\n\n logger.info(`Creating dependency: ${blockingKey} blocks ${blockedKey}...`)\n await provider.createDependency({\n blockingIssue: blockingKey,\n blockedIssue: blockedKey,\n })\n\n logger.success(`Dependency created: ${blockingKey} blocks ${blockedKey}`)\n }\n\n async getDependencies(issueKey: string): Promise<void> {\n const provider = await this.createProvider()\n\n logger.info(`Fetching dependencies for ${issueKey}...`)\n const result = await provider.getDependencies({\n number: issueKey,\n direction: 'both',\n })\n\n logger.info(`Blocking (${issueKey} blocks):`)\n if (result.blocking.length === 0) {\n logger.info(' (none)')\n } else {\n for (const dep of result.blocking) {\n logger.info(` ${dep.id}: ${dep.title} [${dep.state}]`)\n }\n }\n\n logger.info(`Blocked by (blocks ${issueKey}):`)\n if (result.blockedBy.length === 0) {\n logger.info(' (none)')\n } else {\n for (const dep of result.blockedBy) {\n logger.info(` ${dep.id}: ${dep.title} [${dep.state}]`)\n }\n }\n }\n\n async removeDependency(blockingKey: string, blockedKey: string): Promise<void> {\n const provider = await this.createProvider()\n\n logger.info(`Removing dependency: ${blockingKey} blocks ${blockedKey}...`)\n await provider.removeDependency({\n blockingIssue: blockingKey,\n blockedIssue: blockedKey,\n })\n\n logger.success(`Dependency removed: ${blockingKey} no longer blocks ${blockedKey}`)\n }\n\n async getChildIssues(issueKey: string): Promise<void> {\n const provider = await this.createProvider()\n\n logger.info(`Fetching child issues of ${issueKey}...`)\n const children = await provider.getChildIssues({ number: issueKey })\n\n if (children.length === 0) {\n logger.info('No child issues found')\n } else {\n logger.info(`Child issues (${children.length}):`)\n for (const child of children) {\n logger.info(` ${child.id}: ${child.title} [${child.state}] ${child.url}`)\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AASO,IAAM,kBAAN,MAAsB;AAAA,EAG3B,YAAY,iBAAmC;AAC7C,SAAK,kBAAkB,mBAAmB,IAAI,gBAAgB;AAAA,EAChE;AAAA,EAEA,MAAc,iBAAmD;AAC/D,UAAM,WAAW,MAAM,KAAK,gBAAgB,aAAa;AACzD,WAAO,+BAA+B,OAAO,QAAQ,QAAQ;AAAA,EAC/D;AAAA,EAEA,MAAM,iBAAiB,WAAkC;AACvD,UAAM,WAAW,MAAM,KAAK,eAAe;AAE3C,WAAO,KAAK,mCAAmC,SAAS,KAAK;AAC7D,UAAM,SAAS,MAAM,SAAS,iBAAiB;AAAA,MAC7C,UAAU;AAAA,MACV,OAAO,yBAAyB,SAAS;AAAA,MACzC,MAAM;AAAA,IACR,CAAC;AAED,WAAO,QAAQ,wBAAwB,OAAO,EAAE,EAAE;AAClD,WAAO,KAAK,UAAU,OAAO,GAAG,EAAE;AAAA,EACpC;AAAA,EAEA,MAAM,iBAAiB,aAAqB,YAAmC;AAC7E,UAAM,WAAW,MAAM,KAAK,eAAe;AAE3C,WAAO,KAAK,wBAAwB,WAAW,WAAW,UAAU,KAAK;AACzE,UAAM,SAAS,iBAAiB;AAAA,MAC9B,eAAe;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAED,WAAO,QAAQ,uBAAuB,WAAW,WAAW,UAAU,EAAE;AAAA,EAC1E;AAAA,EAEA,MAAM,gBAAgB,UAAiC;AACrD,UAAM,WAAW,MAAM,KAAK,eAAe;AAE3C,WAAO,KAAK,6BAA6B,QAAQ,KAAK;AACtD,UAAM,SAAS,MAAM,SAAS,gBAAgB;AAAA,MAC5C,QAAQ;AAAA,MACR,WAAW;AAAA,IACb,CAAC;AAED,WAAO,KAAK,aAAa,QAAQ,WAAW;AAC5C,QAAI,OAAO,SAAS,WAAW,GAAG;AAChC,aAAO,KAAK,UAAU;AAAA,IACxB,OAAO;AACL,iBAAW,OAAO,OAAO,UAAU;AACjC,eAAO,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG;AAAA,MACxD;AAAA,IACF;AAEA,WAAO,KAAK,sBAAsB,QAAQ,IAAI;AAC9C,QAAI,OAAO,UAAU,WAAW,GAAG;AACjC,aAAO,KAAK,UAAU;AAAA,IACxB,OAAO;AACL,iBAAW,OAAO,OAAO,WAAW;AAClC,eAAO,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,aAAqB,YAAmC;AAC7E,UAAM,WAAW,MAAM,KAAK,eAAe;AAE3C,WAAO,KAAK,wBAAwB,WAAW,WAAW,UAAU,KAAK;AACzE,UAAM,SAAS,iBAAiB;AAAA,MAC9B,eAAe;AAAA,MACf,cAAc;AAAA,IAChB,CAAC;AAED,WAAO,QAAQ,uBAAuB,WAAW,qBAAqB,UAAU,EAAE;AAAA,EACpF;AAAA,EAEA,MAAM,eAAe,UAAiC;AACpD,UAAM,WAAW,MAAM,KAAK,eAAe;AAE3C,WAAO,KAAK,4BAA4B,QAAQ,KAAK;AACrD,UAAM,WAAW,MAAM,SAAS,eAAe,EAAE,QAAQ,SAAS,CAAC;AAEnE,QAAI,SAAS,WAAW,GAAG;AACzB,aAAO,KAAK,uBAAuB;AAAA,IACrC,OAAO;AACL,aAAO,KAAK,iBAAiB,SAAS,MAAM,IAAI;AAChD,iBAAW,SAAS,UAAU;AAC5B,eAAO,KAAK,KAAK,MAAM,EAAE,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generateWorktreePath
4
- } from "./chunk-H6ST2TGP.js";
4
+ } from "./chunk-MNHZB4Z2.js";
5
5
  import {
6
6
  SettingsManager
7
- } from "./chunk-XFEK2X2D.js";
8
- import "./chunk-KBEIQP4G.js";
7
+ } from "./chunk-YYAKPQBT.js";
8
+ import "./chunk-KB64WNBZ.js";
9
9
  import "./chunk-6MLEBAYZ.js";
10
10
  import {
11
11
  logger
@@ -67,4 +67,4 @@ var TestPrefixCommand = class {
67
67
  export {
68
68
  TestPrefixCommand
69
69
  };
70
- //# sourceMappingURL=test-prefix-23TOBUXY.js.map
70
+ //# sourceMappingURL=test-prefix-Q6TFSU6F.js.map
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ProcessManager
4
- } from "./chunk-NTTSUAVM.js";
5
- import "./chunk-USSL2X4A.js";
6
- import "./chunk-H6ST2TGP.js";
4
+ } from "./chunk-ZEWU5PZK.js";
5
+ import "./chunk-3D7WQM7I.js";
6
+ import "./chunk-MNHZB4Z2.js";
7
7
  import {
8
8
  SettingsManager
9
- } from "./chunk-XFEK2X2D.js";
10
- import "./chunk-KBEIQP4G.js";
9
+ } from "./chunk-YYAKPQBT.js";
10
+ import "./chunk-KB64WNBZ.js";
11
11
  import "./chunk-6MLEBAYZ.js";
12
12
  import {
13
13
  logger
@@ -81,4 +81,4 @@ var TestWebserverCommand = class {
81
81
  export {
82
82
  TestWebserverCommand
83
83
  };
84
- //# sourceMappingURL=test-webserver-CKROHFBQ.js.map
84
+ //# sourceMappingURL=test-webserver-EONCG7E7.js.map
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  IdentifierParser
4
- } from "./chunk-2HZX6AMR.js";
4
+ } from "./chunk-WY4QBK43.js";
5
5
  import {
6
6
  GitWorktreeManager
7
- } from "./chunk-4GAJJUYS.js";
7
+ } from "./chunk-VGGST52X.js";
8
8
  import {
9
9
  getInstallHint,
10
10
  isIdeAvailable
11
11
  } from "./chunk-O7VL5N6S.js";
12
12
  import {
13
13
  extractIssueNumber
14
- } from "./chunk-H6ST2TGP.js";
15
- import "./chunk-XFEK2X2D.js";
16
- import "./chunk-KBEIQP4G.js";
14
+ } from "./chunk-MNHZB4Z2.js";
15
+ import "./chunk-YYAKPQBT.js";
16
+ import "./chunk-KB64WNBZ.js";
17
+ import "./chunk-6MLEBAYZ.js";
17
18
  import {
18
19
  waitForKeypress
19
20
  } from "./chunk-7JDMYTFZ.js";
20
- import "./chunk-6MLEBAYZ.js";
21
21
  import {
22
22
  logger
23
23
  } from "./chunk-VT4PDUYT.js";
@@ -161,4 +161,4 @@ var VSCodeCommand = class {
161
161
  export {
162
162
  VSCodeCommand
163
163
  };
164
- //# sourceMappingURL=vscode-6TOLFCI2.js.map
164
+ //# sourceMappingURL=vscode-VA5X4P25.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iloom/cli",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "Control plane for maintaining alignment between you and Claude Code 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",
@@ -73,6 +73,7 @@
73
73
  "deepmerge": "^4.3.1",
74
74
  "dotenv-flow": "^4.1.0",
75
75
  "execa": "^8.0.1",
76
+ "extended-markdown-adf-parser": "^2.4.0",
76
77
  "fast-glob": "^3.3.3",
77
78
  "fs-extra": "^11.1.1",
78
79
  "handlebars": "^4.7.8",
@@ -81,6 +82,8 @@
81
82
  "omelette": "^0.4.17",
82
83
  "ora": "^7.0.1",
83
84
  "string-width": "^6.1.0",
85
+ "posthog-node": "^4.0.0",
86
+ "uuid": "^11.1.0",
84
87
  "zod": "^3.23.8"
85
88
  },
86
89
  "devDependencies": {
@@ -90,6 +93,7 @@
90
93
  "@types/handlebars": "^4.1.0",
91
94
  "@types/inquirer": "^9.0.7",
92
95
  "@types/node": "^20.8.10",
96
+ "@types/uuid": "^10.0.0",
93
97
  "@typescript-eslint/eslint-plugin": "^8.43.0",
94
98
  "@typescript-eslint/parser": "^8.43.0",
95
99
  "@vitest/coverage-v8": "^2.1.0",
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ClaudeContextManager
4
- } from "./chunk-OAVJR4PM.js";
5
- import "./chunk-MZPRBNYC.js";
6
- import "./chunk-QN47QVBX.js";
7
- import "./chunk-XFEK2X2D.js";
8
- import "./chunk-FO5GGFOV.js";
9
- import "./chunk-6MLEBAYZ.js";
10
- import "./chunk-VT4PDUYT.js";
11
- export {
12
- ClaudeContextManager
13
- };
14
- //# sourceMappingURL=ClaudeContextManager-X2Y72GRL.js.map
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ClaudeService
4
- } from "./chunk-MZPRBNYC.js";
5
- import "./chunk-QN47QVBX.js";
6
- import "./chunk-XFEK2X2D.js";
7
- import "./chunk-FO5GGFOV.js";
8
- import "./chunk-6MLEBAYZ.js";
9
- import "./chunk-VT4PDUYT.js";
10
- export {
11
- ClaudeService
12
- };
13
- //# sourceMappingURL=ClaudeService-7P32TTES.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/IdentifierParser.ts"],"sourcesContent":["import type { ParsedInput } from '../commands/start.js'\nimport type { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { extractIssueNumber, extractPRNumber } from './git.js'\n\n/**\n * Result of parsing an issue identifier input\n */\nexport interface IssueIdentifierMatch {\n /** Whether the input matches an issue identifier pattern */\n isIssueIdentifier: boolean\n /** The type of identifier: 'numeric' (GitHub) or 'linear' (Linear format) */\n type?: 'numeric' | 'linear'\n /** The extracted identifier (without # prefix for numeric) */\n identifier?: string\n}\n\n/**\n * Check if a string looks like an issue identifier\n *\n * Matches:\n * - Numeric patterns: \"123\", \"#123\" (GitHub format)\n * - Linear patterns: \"ENG-123\", \"PLAT-456\" (requires at least 2 letters before dash)\n *\n * This is a pure pattern match - it does NOT validate that the issue exists.\n * Use IssueTracker.detectInputType() to validate existence.\n *\n * @param input - The input string to check\n * @returns Object with isIssueIdentifier flag and optional type/identifier\n */\nexport function matchIssueIdentifier(input: string): IssueIdentifierMatch {\n const trimmed = input.trim()\n\n // Check for Linear identifier format (TEAM-NUMBER, e.g., ENG-123, PLAT-456)\n // Requires at least 2 letters before dash to avoid conflict with PR-123 format\n const linearPattern = /^([A-Z]{2,}-\\d+)$/i\n const linearMatch = trimmed.match(linearPattern)\n if (linearMatch?.[1]) {\n return {\n isIssueIdentifier: true,\n type: 'linear',\n identifier: linearMatch[1].toUpperCase(),\n }\n }\n\n // Check for numeric pattern (GitHub format: 123 or #123)\n const numericPattern = /^#?(\\d+)$/\n const numericMatch = trimmed.match(numericPattern)\n if (numericMatch?.[1]) {\n return {\n isIssueIdentifier: true,\n type: 'numeric',\n identifier: numericMatch[1],\n }\n }\n\n return { isIssueIdentifier: false }\n}\n\n/**\n * IdentifierParser provides consistent identifier parsing across commands\n * using pattern-based detection without GitHub API calls.\n *\n * Detection Strategy:\n * 1. For numeric input (e.g., \"42\", \"#66\"):\n * - Check for PR worktree first (_pr_N pattern in path)\n * - Then check for issue worktree (issue-N pattern in branch)\n * 2. For alphanumeric input (e.g., \"ENG-123\"):\n * - Check for issue worktree with alphanumeric identifier\n * 3. For branch-style input (e.g., \"feat/issue-42__description\", \"pr/123\"):\n * - Find matching worktree by branch name\n * - Extract PR number from branch name if present (priority)\n * - Extract issue number from branch name if present\n * - Return as PR/issue type if number found, otherwise branch type\n *\n * This ensures:\n * - No unnecessary GitHub API calls\n * - Consistent behavior across finish/cleanup commands\n * - PR detection takes priority over issue detection\n * - Issue numbers are extracted from branch names for \"Fixes #N\" commit trailers\n */\nexport class IdentifierParser {\n\tconstructor(private gitWorktreeManager: GitWorktreeManager) {}\n\n\t/**\n\t * Parse identifier using pattern-based detection on existing worktrees.\n\t * Does NOT make GitHub API calls - only checks local worktree patterns.\n\t *\n\t * @param identifier - The identifier to parse (e.g., \"42\", \"#66\", \"ENG-123\", \"my-branch\")\n\t * @returns ParsedInput with type, number/branchName, and originalInput\n\t * @throws Error if no matching worktree is found\n\t */\n\tasync parseForPatternDetection(identifier: string): Promise<ParsedInput> {\n\t\t// Remove # prefix if present and trim whitespace\n\t\tconst cleanId = identifier.replace(/^#/, '').trim()\n\t\tconst originalInput = identifier\n\n\t\t// Check if input is numeric (GitHub-style issue/PR numbers)\n\t\tconst numericMatch = cleanId.match(/^(\\d+)$/)\n\n\t\tif (numericMatch?.[1]) {\n\t\t\tconst number = parseInt(numericMatch[1], 10)\n\n\t\t\t// Priority 1: Check for PR worktree (_pr_N pattern)\n\t\t\t// Pass empty string for branch name since we don't know it yet\n\t\t\tconst prWorktree = await this.gitWorktreeManager.findWorktreeForPR(number, '')\n\t\t\tif (prWorktree) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'pr',\n\t\t\t\t\tnumber,\n\t\t\t\t\toriginalInput,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Priority 2: Check for issue worktree (issue-N pattern)\n\t\t\tconst issueWorktree = await this.gitWorktreeManager.findWorktreeForIssue(number)\n\t\t\tif (issueWorktree) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'issue',\n\t\t\t\t\tnumber,\n\t\t\t\t\toriginalInput,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No matching worktree found for numeric input\n\t\t\tthrow new Error(`No worktree found for identifier: ${identifier}`)\n\t\t}\n\n\t\t// Check if input is alphanumeric issue identifier (Linear/Jira-style: ABC-123, ENG-42)\n\t\tconst alphanumericMatch = cleanId.match(/^([A-Za-z]+-\\d+)$/)\n\n\t\tif (alphanumericMatch?.[1]) {\n\t\t\tconst alphanumericId = alphanumericMatch[1]\n\n\t\t\t// Check for issue worktree with alphanumeric identifier\n\t\t\tconst issueWorktree = await this.gitWorktreeManager.findWorktreeForIssue(alphanumericId)\n\t\t\tif (issueWorktree) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'issue',\n\t\t\t\t\tnumber: alphanumericId,\n\t\t\t\t\toriginalInput,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// No matching worktree found for alphanumeric identifier\n\t\t\tthrow new Error(`No worktree found for identifier: ${identifier}`)\n\t\t}\n\n\t\t// Non-numeric/non-alphanumeric input: treat as branch name\n\t\tconst branchWorktree = await this.gitWorktreeManager.findWorktreeForBranch(cleanId)\n\t\tif (branchWorktree) {\n\t\t\t// Priority 1: Check for PR pattern in the input\n\t\t\tconst prFromBranch = extractPRNumber(cleanId)\n\t\t\tif (prFromBranch !== null) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'pr',\n\t\t\t\t\tnumber: prFromBranch,\n\t\t\t\t\toriginalInput,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Priority 2: Try to extract issue number from branch name\n\t\t\t// This handles cases like \"feat/issue-42__description\" passed as explicit input\n\t\t\tconst issueFromBranch = extractIssueNumber(cleanId)\n\t\t\tif (issueFromBranch !== null) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'issue',\n\t\t\t\t\tnumber: issueFromBranch,\n\t\t\t\t\toriginalInput,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttype: 'branch',\n\t\t\t\tbranchName: cleanId,\n\t\t\t\toriginalInput,\n\t\t\t}\n\t\t}\n\n\t\t// No matching worktree found for branch name\n\t\tthrow new Error(`No worktree found for identifier: ${identifier}`)\n\t}\n}\n"],"mappings":";;;;;;;AA6BO,SAAS,qBAAqB,OAAqC;AACxE,QAAM,UAAU,MAAM,KAAK;AAI3B,QAAM,gBAAgB;AACtB,QAAM,cAAc,QAAQ,MAAM,aAAa;AAC/C,MAAI,2CAAc,IAAI;AACpB,WAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,MAAM;AAAA,MACN,YAAY,YAAY,CAAC,EAAE,YAAY;AAAA,IACzC;AAAA,EACF;AAGA,QAAM,iBAAiB;AACvB,QAAM,eAAe,QAAQ,MAAM,cAAc;AACjD,MAAI,6CAAe,IAAI;AACrB,WAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,MAAM;AAAA,MACN,YAAY,aAAa,CAAC;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO,EAAE,mBAAmB,MAAM;AACpC;AAwBO,IAAM,mBAAN,MAAuB;AAAA,EAC7B,YAAoB,oBAAwC;AAAxC;AAAA,EAAyC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7D,MAAM,yBAAyB,YAA0C;AAExE,UAAM,UAAU,WAAW,QAAQ,MAAM,EAAE,EAAE,KAAK;AAClD,UAAM,gBAAgB;AAGtB,UAAM,eAAe,QAAQ,MAAM,SAAS;AAE5C,QAAI,6CAAe,IAAI;AACtB,YAAM,SAAS,SAAS,aAAa,CAAC,GAAG,EAAE;AAI3C,YAAM,aAAa,MAAM,KAAK,mBAAmB,kBAAkB,QAAQ,EAAE;AAC7E,UAAI,YAAY;AACf,eAAO;AAAA,UACN,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAGA,YAAM,gBAAgB,MAAM,KAAK,mBAAmB,qBAAqB,MAAM;AAC/E,UAAI,eAAe;AAClB,eAAO;AAAA,UACN,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAGA,YAAM,IAAI,MAAM,qCAAqC,UAAU,EAAE;AAAA,IAClE;AAGA,UAAM,oBAAoB,QAAQ,MAAM,mBAAmB;AAE3D,QAAI,uDAAoB,IAAI;AAC3B,YAAM,iBAAiB,kBAAkB,CAAC;AAG1C,YAAM,gBAAgB,MAAM,KAAK,mBAAmB,qBAAqB,cAAc;AACvF,UAAI,eAAe;AAClB,eAAO;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AAGA,YAAM,IAAI,MAAM,qCAAqC,UAAU,EAAE;AAAA,IAClE;AAGA,UAAM,iBAAiB,MAAM,KAAK,mBAAmB,sBAAsB,OAAO;AAClF,QAAI,gBAAgB;AAEnB,YAAM,eAAe,gBAAgB,OAAO;AAC5C,UAAI,iBAAiB,MAAM;AAC1B,eAAO;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AAIA,YAAM,kBAAkB,mBAAmB,OAAO;AAClD,UAAI,oBAAoB,MAAM;AAC7B,eAAO;AAAA,UACN,MAAM;AAAA,UACN,QAAQ;AAAA,UACR;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAGA,UAAM,IAAI,MAAM,qCAAqC,UAAU,EAAE;AAAA,EAClE;AACD;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/LinearService.ts","../src/lib/IssueTrackerFactory.ts"],"sourcesContent":["/**\n * LinearService - IssueTracker implementation for Linear\n * Implements issue tracking operations using the @linear/sdk\n */\n\nimport type { Issue, PullRequest, IssueTrackerInputDetection } from '../types/index.js'\nimport type { LinearIssue } from '../types/linear.js'\nimport { LinearServiceError } from '../types/linear.js'\nimport {\n fetchLinearIssue,\n createLinearIssue,\n updateLinearIssueState,\n} from '../utils/linear.js'\nimport { promptConfirmation } from '../utils/prompt.js'\nimport type { IssueTracker } from './IssueTracker.js'\nimport { getLogger } from '../utils/logger-context.js'\n\n/**\n * Linear service configuration options\n */\nexport interface LinearServiceConfig {\n /** Linear team key (e.g., \"ENG\", \"PLAT\") */\n teamId?: string\n /** Branch naming template (e.g., \"feat/{{key}}__{{title}}\") */\n branchFormat?: string\n /** Linear API token (lin_api_...). If provided, sets process.env.LINEAR_API_TOKEN */\n apiToken?: string\n}\n\n/**\n * Linear implementation of IssueTracker interface\n */\nexport class LinearService implements IssueTracker {\n // IssueTracker interface implementation\n readonly providerName = 'linear'\n readonly supportsPullRequests = false // Linear doesn't have pull requests\n\n private config: LinearServiceConfig\n private prompter: (message: string) => Promise<boolean>\n\n constructor(\n config?: LinearServiceConfig,\n options?: { prompter?: (message: string) => Promise<boolean> },\n ) {\n this.config = config ?? {}\n this.prompter = options?.prompter ?? promptConfirmation\n\n // Set API token from config if provided (follows mcp.ts pattern)\n if (this.config.apiToken) {\n process.env.LINEAR_API_TOKEN = this.config.apiToken\n }\n }\n\n /**\n * Detect if input matches Linear identifier format (TEAM-NUMBER)\n * @param input - User input string\n * @param _repo - Repository (unused for Linear)\n * @returns Detection result with type and identifier\n */\n public async detectInputType(\n input: string,\n _repo?: string,\n ): Promise<IssueTrackerInputDetection> {\n getLogger().debug(`LinearService.detectInputType called with input: \"${input}\"`)\n\n // Pattern: TEAM-NUMBER (e.g., ENG-123, PLAT-456)\n // Requires at least 2 letters before dash to avoid conflict with PR-123 format\n const linearPattern = /^([A-Z]{2,}-\\d+)$/i\n const match = input.match(linearPattern)\n\n if (!match?.[1]) {\n getLogger().debug(`LinearService: Input \"${input}\" does not match Linear pattern`)\n return { type: 'unknown', identifier: null, rawInput: input }\n }\n\n const identifier = match[1].toUpperCase()\n getLogger().debug(`LinearService: Matched Linear identifier: ${identifier}`)\n\n // Validate the issue exists in Linear\n getLogger().debug(`LinearService: Checking if ${identifier} is a valid Linear issue via SDK`)\n const issue = await this.isValidIssue(identifier)\n\n if (issue) {\n getLogger().debug(`LinearService: Issue ${identifier} found: \"${issue.title}\"`)\n return { type: 'issue', identifier, rawInput: input }\n }\n\n // Not found\n getLogger().debug(`LinearService: Issue ${identifier} NOT found by SDK`)\n return { type: 'unknown', identifier: null, rawInput: input }\n }\n\n /**\n * Fetch a Linear issue by identifier\n * @param identifier - Linear issue identifier (string or number)\n * @param _repo - Repository (unused for Linear)\n * @returns Generic Issue type\n * @throws LinearServiceError if issue not found\n */\n public async fetchIssue(identifier: string | number, _repo?: string): Promise<Issue> {\n const linearIssue = await fetchLinearIssue(String(identifier))\n return this.mapLinearIssueToIssue(linearIssue)\n }\n\n /**\n * Check if an issue identifier is valid (silent validation)\n * @param identifier - Linear issue identifier\n * @param _repo - Repository (unused for Linear)\n * @returns Issue if valid, false if not found\n */\n public async isValidIssue(identifier: string | number, _repo?: string): Promise<Issue | false> {\n try {\n return await this.fetchIssue(identifier)\n } catch (error) {\n // Return false for NOT_FOUND errors (expected during detection)\n if (error instanceof LinearServiceError && error.code === 'NOT_FOUND') {\n return false\n }\n // Re-throw unexpected errors\n throw error\n }\n }\n\n /**\n * Validate issue state and prompt user if closed\n * @param issue - Issue to validate\n * @throws LinearServiceError if user cancels due to closed issue\n */\n public async validateIssueState(issue: Issue): Promise<void> {\n if (issue.state === 'closed') {\n const shouldContinue = await this.prompter(\n `Issue ${issue.number} is closed. Continue anyway?`,\n )\n\n if (!shouldContinue) {\n throw new LinearServiceError('INVALID_STATE', 'User cancelled due to closed issue')\n }\n }\n }\n\n /**\n * Create a new Linear issue\n * @param title - Issue title\n * @param body - Issue description (markdown)\n * @param _repository - Repository (unused for Linear)\n * @param labels - Optional label names\n * @returns Created issue identifier and URL\n * @throws LinearServiceError if teamId not configured or creation fails\n */\n public async createIssue(\n title: string,\n body: string,\n _repository?: string,\n labels?: string[],\n ): Promise<{ number: string | number; url: string }> {\n // Require teamId configuration\n if (!this.config.teamId) {\n throw new LinearServiceError(\n 'INVALID_STATE',\n 'Linear teamId not configured. Run `il init` to configure Linear settings.',\n )\n }\n\n getLogger().info(`Creating Linear issue in team ${this.config.teamId}: ${title}`)\n\n const result = await createLinearIssue(title, body, this.config.teamId, labels)\n\n return {\n number: result.identifier,\n url: result.url,\n }\n }\n\n /**\n * Get the web URL for a Linear issue\n * @param identifier - Linear issue identifier\n * @param _repo - Repository (unused for Linear)\n * @returns Issue URL\n */\n public async getIssueUrl(identifier: string | number, _repo?: string): Promise<string> {\n const issue = await this.fetchIssue(identifier)\n return issue.url\n }\n\n /**\n * Move a Linear issue to \"In Progress\" state\n * @param identifier - Linear issue identifier\n * @throws LinearServiceError if state update fails\n */\n public async moveIssueToInProgress(identifier: string | number): Promise<void> {\n getLogger().info(`Moving Linear issue ${identifier} to In Progress`)\n await updateLinearIssueState(String(identifier), 'In Progress')\n }\n\n /**\n * Extract issue context for AI prompts\n * @param entity - Issue (Linear doesn't have PRs)\n * @returns Formatted context string\n */\n public extractContext(entity: Issue | PullRequest): string {\n // Linear doesn't have PRs, always an issue\n const issue = entity as Issue\n return `Linear Issue ${issue.number}: ${issue.title}\\nState: ${issue.state}\\n\\n${issue.body}`\n }\n\n /**\n * Map Linear API issue to generic Issue type\n * @param linear - Linear issue from SDK\n * @returns Generic Issue type\n */\n private mapLinearIssueToIssue(linear: LinearIssue): Issue {\n return {\n number: linear.identifier, // Keep as string (e.g., \"ENG-123\")\n title: linear.title,\n body: linear.description ?? '',\n state: linear.state ? (linear.state.toLowerCase().includes('done') || linear.state.toLowerCase().includes('completed') || linear.state.toLowerCase().includes('canceled') ? 'closed' : 'open') : 'open',\n labels: [],\n assignees: [],\n url: linear.url,\n }\n }\n}\n","// IssueTrackerFactory - creates appropriate IssueTracker based on settings\n// Follows pattern from database provider instantiation\n\nimport type { IssueTracker } from './IssueTracker.js'\nimport { GitHubService } from './GitHubService.js'\nimport { LinearService, type LinearServiceConfig } from './LinearService.js'\nimport type { IloomSettings } from './SettingsManager.js'\nimport { getLogger } from '../utils/logger-context.js'\n\nexport type IssueTrackerProviderType = 'github' | 'linear'\n\n/**\n * Factory for creating IssueTracker instances based on settings\n * Provides a single point of provider instantiation\n *\n * Usage:\n * const tracker = IssueTrackerFactory.create(settings, { useClaude: true })\n * const issue = await tracker.fetchIssue(123)\n */\nexport class IssueTrackerFactory {\n\t/**\n\t * Create an IssueTracker instance based on settings configuration\n\t * Defaults to GitHub if no provider specified\n\t *\n\t * @param settings - iloom settings containing issueManagement.provider\n\t * @returns IssueTracker instance configured for the specified provider\n\t * @throws Error if provider type is not supported\n\t */\n\tstatic create(settings: IloomSettings): IssueTracker {\n\t\tconst provider = settings.issueManagement?.provider ?? 'github'\n\n\t\tgetLogger().debug(`IssueTrackerFactory: Creating tracker for provider \"${provider}\"`)\n\t\tgetLogger().debug(`IssueTrackerFactory: issueManagement settings:`, JSON.stringify(settings.issueManagement, null, 2))\n\n\t\tswitch (provider) {\n\t\t\tcase 'github':\n\t\t\t\tgetLogger().debug('IssueTrackerFactory: Creating GitHubService')\n\t\t\t\treturn new GitHubService()\n\t\t\tcase 'linear': {\n\t\t\t\tconst linearSettings = settings.issueManagement?.linear\n\t\t\t\tconst linearConfig: LinearServiceConfig = {}\n\n\t\t\t\tif (linearSettings?.teamId) {\n\t\t\t\t\tlinearConfig.teamId = linearSettings.teamId\n\t\t\t\t}\n\t\t\t\tif (linearSettings?.branchFormat) {\n\t\t\t\t\tlinearConfig.branchFormat = linearSettings.branchFormat\n\t\t\t\t}\n\t\t\t\tif (linearSettings?.apiToken) {\n\t\t\t\t\tlinearConfig.apiToken = linearSettings.apiToken\n\t\t\t\t}\n\n\t\t\t\tgetLogger().debug(`IssueTrackerFactory: Creating LinearService with config:`, JSON.stringify(linearConfig, null, 2))\n\t\t\t\treturn new LinearService(linearConfig)\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported issue tracker provider: ${provider}`)\n\t\t}\n\t}\n\n\t/**\n\t * Get the configured provider name from settings\n\t * Defaults to 'github' if not configured\n\t *\n\t * @param settings - iloom settings\n\t * @returns Provider type string\n\t */\n\tstatic getProviderName(settings: IloomSettings): IssueTrackerProviderType {\n\t\treturn (settings.issueManagement?.provider ?? 'github') as IssueTrackerProviderType\n\t}\n}\n"],"mappings":"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","names":[]}