@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
@@ -1,983 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- CLIIsolationManager,
4
- DatabaseManager,
5
- EnvironmentManager
6
- } from "./chunk-H5LDRGVK.js";
7
- import {
8
- loadEnvIntoProcess
9
- } from "./chunk-ZMNQBJUI.js";
10
- import {
11
- installDependencies
12
- } from "./chunk-BLCTGFZN.js";
13
- import {
14
- ClaudeContextManager
15
- } from "./chunk-DEPYQRRB.js";
16
- import {
17
- extractSettingsOverrides
18
- } from "./chunk-GYCR2LOU.js";
19
- import {
20
- createNeonProviderFromSettings
21
- } from "./chunk-LAPY6NAE.js";
22
- import {
23
- ProjectCapabilityDetector
24
- } from "./chunk-CWR2SANQ.js";
25
- import "./chunk-2ZPFJQ3B.js";
26
- import {
27
- IssueEnhancementService
28
- } from "./chunk-PR7FKQBG.js";
29
- import {
30
- AgentManager
31
- } from "./chunk-OC4H6HJD.js";
32
- import "./chunk-YETJNRQM.js";
33
- import {
34
- getConfiguredRepoFromSettings,
35
- hasMultipleRemotes
36
- } from "./chunk-FXV24OYZ.js";
37
- import {
38
- calculateForegroundColor,
39
- generateColorFromBranchName,
40
- hexToRgb,
41
- lightenColor,
42
- rgbToHex
43
- } from "./chunk-ZZZWQGTS.js";
44
- import {
45
- GitHubService
46
- } from "./chunk-ZWXJBSUW.js";
47
- import "./chunk-JXQXSC45.js";
48
- import "./chunk-ELFT36PV.js";
49
- import "./chunk-PXZBAC2M.js";
50
- import "./chunk-PVAVNJKS.js";
51
- import {
52
- GitWorktreeManager
53
- } from "./chunk-IO4WFTL2.js";
54
- import {
55
- SettingsManager
56
- } from "./chunk-VYQLLHZ7.js";
57
- import {
58
- branchExists,
59
- ensureRepositoryHasCommits,
60
- executeGitCommand,
61
- findMainWorktreePathWithSettings
62
- } from "./chunk-KOCQAD2E.js";
63
- import "./chunk-JNKJ7NJV.js";
64
- import {
65
- logger
66
- } from "./chunk-GEHQXLEI.js";
67
-
68
- // src/lib/LoomManager.ts
69
- import path2 from "path";
70
- import fs2 from "fs-extra";
71
-
72
- // src/lib/VSCodeIntegration.ts
73
- import fs from "fs-extra";
74
- import path from "path";
75
- import { parse, modify, applyEdits } from "jsonc-parser";
76
- var VSCodeIntegration = class {
77
- /**
78
- * Set VSCode title bar color for a workspace
79
- *
80
- * @param workspacePath - Path to workspace directory
81
- * @param hexColor - Hex color string (e.g., "#dcebf8")
82
- */
83
- async setTitleBarColor(workspacePath, hexColor) {
84
- const vscodeDir = path.join(workspacePath, ".vscode");
85
- const settingsPath = path.join(vscodeDir, "settings.json");
86
- try {
87
- await fs.ensureDir(vscodeDir);
88
- const settings = await this.readSettings(settingsPath);
89
- const updatedSettings = this.mergeColorSettings(settings, hexColor);
90
- await this.writeSettings(settingsPath, updatedSettings);
91
- logger.debug(`Set VSCode title bar color to ${hexColor} for ${workspacePath}`);
92
- } catch (error) {
93
- throw new Error(
94
- `Failed to set VSCode title bar color: ${error instanceof Error ? error.message : "Unknown error"}`
95
- );
96
- }
97
- }
98
- /**
99
- * Read VSCode settings from file
100
- * Supports JSONC (JSON with Comments)
101
- *
102
- * @param settingsPath - Path to settings.json file
103
- * @returns Parsed settings object
104
- */
105
- async readSettings(settingsPath) {
106
- try {
107
- if (!await fs.pathExists(settingsPath)) {
108
- return {};
109
- }
110
- const content = await fs.readFile(settingsPath, "utf8");
111
- const errors = [];
112
- const settings = parse(content, errors, { allowTrailingComma: true });
113
- if (errors.length > 0) {
114
- const firstError = errors[0];
115
- throw new Error(`Invalid JSON: ${firstError ? firstError.error : "Unknown parse error"}`);
116
- }
117
- return settings ?? {};
118
- } catch (error) {
119
- throw new Error(
120
- `Failed to parse settings.json: ${error instanceof Error ? error.message : "Unknown error"}`
121
- );
122
- }
123
- }
124
- /**
125
- * Write VSCode settings to file atomically
126
- * Preserves comments if present (using JSONC parser)
127
- *
128
- * @param settingsPath - Path to settings.json file
129
- * @param settings - Settings object to write
130
- */
131
- async writeSettings(settingsPath, settings) {
132
- try {
133
- let content;
134
- if (await fs.pathExists(settingsPath)) {
135
- const existingContent = await fs.readFile(settingsPath, "utf8");
136
- if (existingContent.includes("//") || existingContent.includes("/*")) {
137
- content = await this.modifyWithCommentsPreserved(existingContent, settings);
138
- } else {
139
- content = JSON.stringify(settings, null, 2) + "\n";
140
- }
141
- } else {
142
- content = JSON.stringify(settings, null, 2) + "\n";
143
- }
144
- const tempPath = `${settingsPath}.tmp`;
145
- await fs.writeFile(tempPath, content, "utf8");
146
- await fs.rename(tempPath, settingsPath);
147
- } catch (error) {
148
- throw new Error(
149
- `Failed to write settings.json: ${error instanceof Error ? error.message : "Unknown error"}`
150
- );
151
- }
152
- }
153
- /**
154
- * Modify JSONC content while preserving comments
155
- *
156
- * @param existingContent - Original JSONC content
157
- * @param newSettings - New settings to apply
158
- * @returns Modified JSONC content with comments preserved
159
- */
160
- async modifyWithCommentsPreserved(existingContent, newSettings) {
161
- let modifiedContent = existingContent;
162
- for (const [key, value] of Object.entries(newSettings)) {
163
- const edits = modify(modifiedContent, [key], value, {});
164
- modifiedContent = applyEdits(modifiedContent, edits);
165
- }
166
- return modifiedContent;
167
- }
168
- /**
169
- * Merge color settings into existing settings object
170
- *
171
- * @param existing - Existing settings object
172
- * @param hexColor - Hex color to apply (subtle palette color)
173
- * @returns Updated settings object with color merged
174
- */
175
- mergeColorSettings(existing, hexColor) {
176
- const updated = { ...existing };
177
- updated["workbench.colorCustomizations"] ??= {};
178
- const colors = updated["workbench.colorCustomizations"];
179
- const baseRgb = hexToRgb(hexColor);
180
- const foreground = calculateForegroundColor(baseRgb);
181
- const foregroundTransparent = foreground.replace("#", "#") + "99";
182
- const lighterRgb = lightenColor(baseRgb, 0.05);
183
- const lighterHex = rgbToHex(lighterRgb.r, lighterRgb.g, lighterRgb.b);
184
- colors["titleBar.activeBackground"] = hexColor;
185
- colors["titleBar.inactiveBackground"] = hexColor + "99";
186
- colors["titleBar.activeForeground"] = foreground;
187
- colors["titleBar.inactiveForeground"] = foregroundTransparent;
188
- colors["statusBar.background"] = hexColor;
189
- colors["statusBar.foreground"] = foreground;
190
- colors["statusBarItem.hoverBackground"] = lighterHex;
191
- colors["statusBarItem.remoteBackground"] = hexColor;
192
- colors["statusBarItem.remoteForeground"] = foreground;
193
- colors["sash.hoverBorder"] = hexColor;
194
- colors["commandCenter.border"] = foregroundTransparent;
195
- return updated;
196
- }
197
- };
198
-
199
- // src/lib/LoomManager.ts
200
- var LoomManager = class {
201
- constructor(gitWorktree, github, environment, _claude, capabilityDetector, cliIsolation, settings, database) {
202
- this.gitWorktree = gitWorktree;
203
- this.github = github;
204
- this.environment = environment;
205
- this.capabilityDetector = capabilityDetector;
206
- this.cliIsolation = cliIsolation;
207
- this.settings = settings;
208
- this.database = database;
209
- }
210
- /**
211
- * Create a new loom (isolated workspace)
212
- * Orchestrates worktree creation, environment setup, and Claude context generation
213
- * NEW: Checks for existing worktrees and reuses them if found
214
- */
215
- async createIloom(input) {
216
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
217
- logger.info("Fetching GitHub data...");
218
- const githubData = await this.fetchGitHubData(input);
219
- if (input.type === "issue" || input.type === "pr") {
220
- logger.info("Checking for existing worktree...");
221
- const existing = await this.findExistingIloom(input, githubData);
222
- if (existing) {
223
- logger.success(`Found existing worktree, reusing: ${existing.path}`);
224
- return await this.reuseIloom(existing, input, githubData);
225
- }
226
- logger.info("No existing worktree found, creating new one...");
227
- }
228
- logger.info("Preparing branch name...");
229
- const branchName = await this.prepareBranchName(input, githubData);
230
- logger.info("Creating git worktree...");
231
- const worktreePath = await this.createWorktreeOnly(input, branchName);
232
- this.loadMainEnvFile();
233
- const { capabilities, binEntries } = await this.capabilityDetector.detectCapabilities(worktreePath);
234
- await this.copyEnvironmentFiles(worktreePath);
235
- await this.copyIloomSettings(worktreePath);
236
- const settingsData = await this.settings.loadSettings();
237
- const basePort = ((_b = (_a = settingsData.capabilities) == null ? void 0 : _a.web) == null ? void 0 : _b.basePort) ?? 3e3;
238
- let port = basePort;
239
- if (capabilities.includes("web")) {
240
- port = await this.setupPortForWeb(worktreePath, input, basePort);
241
- }
242
- try {
243
- await installDependencies(worktreePath, true);
244
- } catch (error) {
245
- logger.warn(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`, error);
246
- }
247
- let databaseBranch = void 0;
248
- if (this.database && !((_c = input.options) == null ? void 0 : _c.skipDatabase)) {
249
- try {
250
- const connectionString = await this.database.createBranchIfConfigured(
251
- branchName,
252
- path2.join(worktreePath, ".env")
253
- );
254
- if (connectionString) {
255
- await this.environment.setEnvVar(
256
- path2.join(worktreePath, ".env"),
257
- this.database.getConfiguredVariableName(),
258
- connectionString
259
- );
260
- logger.success("Database branch configured");
261
- databaseBranch = branchName;
262
- }
263
- } catch (error) {
264
- logger.error(
265
- `Failed to setup database branch: ${error instanceof Error ? error.message : "Unknown error"}`
266
- );
267
- throw error;
268
- }
269
- }
270
- let cliSymlinks = void 0;
271
- if (capabilities.includes("cli")) {
272
- try {
273
- cliSymlinks = await this.cliIsolation.setupCLIIsolation(
274
- worktreePath,
275
- input.identifier,
276
- binEntries
277
- );
278
- } catch (error) {
279
- logger.warn(
280
- `Failed to setup CLI isolation: ${error instanceof Error ? error.message : "Unknown error"}`,
281
- error
282
- );
283
- }
284
- }
285
- if (!((_d = input.options) == null ? void 0 : _d.skipColorSync)) {
286
- try {
287
- await this.applyColorSynchronization(worktreePath, branchName);
288
- } catch (error) {
289
- logger.warn(
290
- `Failed to apply color synchronization: ${error instanceof Error ? error.message : "Unknown error"}`,
291
- error
292
- );
293
- }
294
- }
295
- if (input.type === "issue") {
296
- try {
297
- logger.info("Moving issue to In Progress...");
298
- await this.github.moveIssueToInProgress(input.identifier);
299
- } catch (error) {
300
- logger.warn(
301
- `Failed to move issue to In Progress: ${error instanceof Error ? error.message : "Unknown error"}`,
302
- error
303
- );
304
- }
305
- }
306
- const enableClaude = ((_e = input.options) == null ? void 0 : _e.enableClaude) !== false;
307
- const enableCode = ((_f = input.options) == null ? void 0 : _f.enableCode) !== false;
308
- const enableDevServer = ((_g = input.options) == null ? void 0 : _g.enableDevServer) !== false;
309
- const enableTerminal = ((_h = input.options) == null ? void 0 : _h.enableTerminal) ?? false;
310
- const oneShot = ((_i = input.options) == null ? void 0 : _i.oneShot) ?? "default";
311
- const setArguments = (_j = input.options) == null ? void 0 : _j.setArguments;
312
- const executablePath = (_k = input.options) == null ? void 0 : _k.executablePath;
313
- if (enableClaude || enableCode || enableDevServer || enableTerminal) {
314
- const { LoomLauncher } = await import("./LoomLauncher-UMMLPIZO.js");
315
- const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-JKR4WGNU.js");
316
- const claudeContext = new ClaudeContextManager2(void 0, void 0, this.settings);
317
- const launcher = new LoomLauncher(claudeContext);
318
- await launcher.launchLoom({
319
- enableClaude,
320
- enableCode,
321
- enableDevServer,
322
- enableTerminal,
323
- worktreePath,
324
- branchName,
325
- port,
326
- capabilities,
327
- workflowType: input.type === "branch" ? "regular" : input.type,
328
- identifier: input.identifier,
329
- ...(githubData == null ? void 0 : githubData.title) && { title: githubData.title },
330
- oneShot,
331
- ...setArguments && { setArguments },
332
- ...executablePath && { executablePath }
333
- });
334
- }
335
- const loom = {
336
- id: this.generateLoomId(input),
337
- path: worktreePath,
338
- branch: branchName,
339
- type: input.type,
340
- identifier: input.identifier,
341
- port,
342
- createdAt: /* @__PURE__ */ new Date(),
343
- lastAccessed: /* @__PURE__ */ new Date(),
344
- ...databaseBranch !== void 0 && { databaseBranch },
345
- ...capabilities.length > 0 && { capabilities },
346
- ...Object.keys(binEntries).length > 0 && { binEntries },
347
- ...cliSymlinks && cliSymlinks.length > 0 && { cliSymlinks },
348
- ...githubData !== null && {
349
- githubData: {
350
- title: githubData.title,
351
- body: githubData.body,
352
- url: githubData.url,
353
- state: githubData.state
354
- }
355
- }
356
- };
357
- logger.success(`Created loom: ${loom.id} at ${loom.path}`);
358
- return loom;
359
- }
360
- /**
361
- * Finish a loom (merge work and cleanup)
362
- * Not yet implemented - see Issue #7
363
- */
364
- async finishIloom(_identifier) {
365
- throw new Error("Not implemented - see Issue #7");
366
- }
367
- /**
368
- * List all active looms
369
- */
370
- async listLooms() {
371
- const worktrees = await this.gitWorktree.listWorktrees();
372
- return await this.mapWorktreesToLooms(worktrees);
373
- }
374
- /**
375
- * Find a specific loom by identifier
376
- */
377
- async findIloom(identifier) {
378
- const looms = await this.listLooms();
379
- return looms.find(
380
- (h) => h.id === identifier || h.identifier.toString() === identifier || h.branch === identifier
381
- ) ?? null;
382
- }
383
- /**
384
- * Fetch GitHub data based on input type
385
- */
386
- async fetchGitHubData(input) {
387
- if (input.type === "issue") {
388
- return await this.github.fetchIssue(input.identifier);
389
- } else if (input.type === "pr") {
390
- return await this.github.fetchPR(input.identifier);
391
- }
392
- return null;
393
- }
394
- /**
395
- * Prepare branch name based on input type and GitHub data
396
- */
397
- async prepareBranchName(input, githubData) {
398
- if (input.type === "branch") {
399
- return input.identifier;
400
- }
401
- if (input.type === "pr" && githubData && "branch" in githubData) {
402
- return githubData.branch;
403
- }
404
- if (input.type === "issue" && githubData) {
405
- const branchName = await this.github.generateBranchName({
406
- issueNumber: input.identifier,
407
- title: githubData.title
408
- });
409
- return branchName;
410
- }
411
- if (input.type === "pr") {
412
- return `pr-${input.identifier}`;
413
- }
414
- throw new Error(`Unable to determine branch name for input type: ${input.type}`);
415
- }
416
- /**
417
- * Create worktree for the loom (without dependency installation)
418
- */
419
- async createWorktreeOnly(input, branchName) {
420
- logger.info("Ensuring repository has initial commit...");
421
- await ensureRepositoryHasCommits(this.gitWorktree.workingDirectory);
422
- const settingsData = await this.settings.loadSettings();
423
- const worktreePrefix = settingsData.worktreePrefix;
424
- const pathOptions = input.type === "pr" ? { isPR: true, prNumber: input.identifier } : {};
425
- if (worktreePrefix !== void 0) {
426
- pathOptions.prefix = worktreePrefix;
427
- }
428
- const worktreePath = this.gitWorktree.generateWorktreePath(
429
- branchName,
430
- void 0,
431
- pathOptions
432
- );
433
- if (input.type === "pr") {
434
- logger.info("Fetching all remote branches...");
435
- try {
436
- await executeGitCommand(["fetch", "origin"], { cwd: this.gitWorktree.workingDirectory });
437
- logger.success("Successfully fetched from remote");
438
- } catch (error) {
439
- throw new Error(
440
- `Failed to fetch from remote: ${error instanceof Error ? error.message : "Unknown error"}. Make sure you have access to the repository.`
441
- );
442
- }
443
- }
444
- const branchExistedLocally = await branchExists(branchName);
445
- if (input.type !== "pr" && branchExistedLocally) {
446
- throw new Error(
447
- `Cannot create worktree: branch '${branchName}' already exists. Use 'git branch -D ${branchName}' to delete it first if needed.`
448
- );
449
- }
450
- await this.gitWorktree.createWorktree({
451
- path: worktreePath,
452
- branch: branchName,
453
- createBranch: input.type !== "pr",
454
- // PRs use existing branches
455
- ...input.baseBranch && { baseBranch: input.baseBranch }
456
- });
457
- if (input.type === "pr" && !branchExistedLocally) {
458
- logger.info("Resetting new PR branch to match remote exactly...");
459
- try {
460
- await executeGitCommand(["reset", "--hard", `origin/${branchName}`], { cwd: worktreePath });
461
- await executeGitCommand(["branch", "--set-upstream-to", `origin/${branchName}`], { cwd: worktreePath });
462
- logger.success("Successfully reset to match remote");
463
- } catch (error) {
464
- logger.warn(`Failed to reset to match remote: ${error instanceof Error ? error.message : "Unknown error"}`);
465
- }
466
- }
467
- return worktreePath;
468
- }
469
- /**
470
- * Copy user application environment files (.env) from main repo to worktree
471
- * Always called regardless of project capabilities
472
- */
473
- async copyEnvironmentFiles(worktreePath) {
474
- const envFilePath = path2.join(worktreePath, ".env");
475
- try {
476
- const mainEnvPath = path2.join(process.cwd(), ".env");
477
- if (await fs2.pathExists(envFilePath)) {
478
- logger.warn(".env file already exists in worktree, skipping copy");
479
- } else {
480
- await this.environment.copyIfExists(mainEnvPath, envFilePath);
481
- }
482
- } catch (error) {
483
- logger.warn(`Warning: Failed to copy main .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
484
- }
485
- }
486
- /**
487
- * Copy iloom configuration (settings.local.json) from main repo to worktree
488
- * Always called regardless of project capabilities
489
- */
490
- async copyIloomSettings(worktreePath) {
491
- const mainSettingsLocalPath = path2.join(process.cwd(), ".iloom", "settings.local.json");
492
- try {
493
- const worktreeIloomDir = path2.join(worktreePath, ".iloom");
494
- await fs2.ensureDir(worktreeIloomDir);
495
- const worktreeSettingsLocalPath = path2.join(worktreeIloomDir, "settings.local.json");
496
- if (await fs2.pathExists(worktreeSettingsLocalPath)) {
497
- logger.warn("settings.local.json already exists in worktree, skipping copy");
498
- } else {
499
- await this.environment.copyIfExists(mainSettingsLocalPath, worktreeSettingsLocalPath);
500
- }
501
- } catch (error) {
502
- logger.warn(`Warning: Failed to copy settings.local.json: ${error instanceof Error ? error.message : "Unknown error"}`);
503
- }
504
- }
505
- /**
506
- * Setup PORT environment variable for web projects
507
- * Only called when project has web capabilities
508
- */
509
- async setupPortForWeb(worktreePath, input, basePort) {
510
- const envFilePath = path2.join(worktreePath, ".env");
511
- const options = { basePort };
512
- if (input.type === "issue") {
513
- options.issueNumber = input.identifier;
514
- } else if (input.type === "pr") {
515
- options.prNumber = input.identifier;
516
- } else if (input.type === "branch") {
517
- options.branchName = input.identifier;
518
- }
519
- const port = this.environment.calculatePort(options);
520
- await this.environment.setEnvVar(envFilePath, "PORT", String(port));
521
- return port;
522
- }
523
- /**
524
- * Load environment variables from main .env file into process.env
525
- * Uses dotenv-flow to handle various .env file patterns
526
- */
527
- loadMainEnvFile() {
528
- const result = loadEnvIntoProcess({ path: process.cwd() });
529
- if (result.error) {
530
- logger.warn(`Warning: Could not load .env files: ${result.error.message}`);
531
- } else {
532
- logger.info("Loaded environment variables using dotenv-flow");
533
- if (result.parsed && Object.keys(result.parsed).length > 0) {
534
- logger.debug(`Loaded ${Object.keys(result.parsed).length} environment variables`);
535
- }
536
- }
537
- }
538
- /**
539
- * Generate a unique loom ID
540
- */
541
- generateLoomId(input) {
542
- const prefix = input.type;
543
- return `${prefix}-${input.identifier}`;
544
- }
545
- /**
546
- * Calculate port for the loom
547
- * Base port: configurable via settings.capabilities.web.basePort (default 3000) + issue/PR number (or deterministic hash for branches)
548
- */
549
- async calculatePort(input) {
550
- var _a, _b;
551
- const settingsData = await this.settings.loadSettings();
552
- const basePort = ((_b = (_a = settingsData.capabilities) == null ? void 0 : _a.web) == null ? void 0 : _b.basePort) ?? 3e3;
553
- if (input.type === "issue" && typeof input.identifier === "number") {
554
- return this.environment.calculatePort({ basePort, issueNumber: input.identifier });
555
- }
556
- if (input.type === "pr" && typeof input.identifier === "number") {
557
- return this.environment.calculatePort({ basePort, prNumber: input.identifier });
558
- }
559
- if (input.type === "branch" && typeof input.identifier === "string") {
560
- return this.environment.calculatePort({ basePort, branchName: input.identifier });
561
- }
562
- throw new Error(`Unknown input type: ${input.type}`);
563
- }
564
- /**
565
- * Apply color synchronization to both VSCode and terminal
566
- * Colors are cosmetic - errors are logged but don't block workflow
567
- */
568
- async applyColorSynchronization(worktreePath, branchName) {
569
- const colorData = generateColorFromBranchName(branchName);
570
- const vscode = new VSCodeIntegration();
571
- await vscode.setTitleBarColor(worktreePath, colorData.hex);
572
- logger.info(`Applied VSCode title bar color: ${colorData.hex} for branch: ${branchName}`);
573
- }
574
- /**
575
- * Map worktrees to loom objects
576
- * This is a simplified conversion - in production we'd store loom metadata
577
- */
578
- async mapWorktreesToLooms(worktrees) {
579
- return await Promise.all(worktrees.map(async (wt) => {
580
- let type = "branch";
581
- let identifier = wt.branch;
582
- if (wt.branch.startsWith("issue-")) {
583
- type = "issue";
584
- identifier = parseInt(wt.branch.replace("issue-", ""), 10);
585
- } else if (wt.branch.startsWith("pr-")) {
586
- type = "pr";
587
- identifier = parseInt(wt.branch.replace("pr-", ""), 10);
588
- }
589
- return {
590
- id: `${type}-${identifier}`,
591
- path: wt.path,
592
- branch: wt.branch,
593
- type,
594
- identifier,
595
- port: await this.calculatePort({ type, identifier, originalInput: "" }),
596
- createdAt: /* @__PURE__ */ new Date(),
597
- lastAccessed: /* @__PURE__ */ new Date()
598
- };
599
- }));
600
- }
601
- /**
602
- * NEW: Find existing loom for the given input
603
- * Checks for worktrees matching the issue/PR identifier
604
- */
605
- async findExistingIloom(input, githubData) {
606
- if (input.type === "issue") {
607
- return await this.gitWorktree.findWorktreeForIssue(input.identifier);
608
- } else if (input.type === "pr" && githubData && "branch" in githubData) {
609
- return await this.gitWorktree.findWorktreeForPR(
610
- input.identifier,
611
- githubData.branch
612
- );
613
- }
614
- return null;
615
- }
616
- /**
617
- * NEW: Reuse an existing loom
618
- * Includes environment setup and database branching for existing worktrees
619
- * Ports: handle_existing_worktree() from bash script lines 168-215
620
- */
621
- async reuseIloom(worktree, input, githubData) {
622
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
623
- const worktreePath = worktree.path;
624
- const branchName = worktree.branch;
625
- this.loadMainEnvFile();
626
- const { capabilities, binEntries } = await this.capabilityDetector.detectCapabilities(worktreePath);
627
- await this.copyEnvironmentFiles(worktreePath);
628
- await this.copyIloomSettings(worktreePath);
629
- const settingsData = await this.settings.loadSettings();
630
- const basePort = ((_b = (_a = settingsData.capabilities) == null ? void 0 : _a.web) == null ? void 0 : _b.basePort) ?? 3e3;
631
- let port = basePort;
632
- if (capabilities.includes("web")) {
633
- port = await this.setupPortForWeb(worktreePath, input, basePort);
634
- }
635
- logger.info("Database branch assumed to be already configured for existing worktree");
636
- const databaseBranch = void 0;
637
- if (input.type === "issue") {
638
- try {
639
- logger.info("Moving issue to In Progress...");
640
- await this.github.moveIssueToInProgress(input.identifier);
641
- } catch (error) {
642
- logger.warn(
643
- `Failed to move issue to In Progress: ${error instanceof Error ? error.message : "Unknown error"}`,
644
- error
645
- );
646
- }
647
- }
648
- const enableClaude = ((_c = input.options) == null ? void 0 : _c.enableClaude) !== false;
649
- const enableCode = ((_d = input.options) == null ? void 0 : _d.enableCode) !== false;
650
- const enableDevServer = ((_e = input.options) == null ? void 0 : _e.enableDevServer) !== false;
651
- const enableTerminal = ((_f = input.options) == null ? void 0 : _f.enableTerminal) ?? false;
652
- const oneShot = ((_g = input.options) == null ? void 0 : _g.oneShot) ?? "default";
653
- const setArguments = (_h = input.options) == null ? void 0 : _h.setArguments;
654
- const executablePath = (_i = input.options) == null ? void 0 : _i.executablePath;
655
- if (enableClaude || enableCode || enableDevServer || enableTerminal) {
656
- logger.info("Launching workspace components...");
657
- const { LoomLauncher } = await import("./LoomLauncher-UMMLPIZO.js");
658
- const { ClaudeContextManager: ClaudeContextManager2 } = await import("./ClaudeContextManager-JKR4WGNU.js");
659
- const claudeContext = new ClaudeContextManager2(void 0, void 0, this.settings);
660
- const launcher = new LoomLauncher(claudeContext);
661
- await launcher.launchLoom({
662
- enableClaude,
663
- enableCode,
664
- enableDevServer,
665
- enableTerminal,
666
- worktreePath,
667
- branchName,
668
- port,
669
- capabilities,
670
- workflowType: input.type === "branch" ? "regular" : input.type,
671
- identifier: input.identifier,
672
- ...(githubData == null ? void 0 : githubData.title) && { title: githubData.title },
673
- oneShot,
674
- ...setArguments && { setArguments },
675
- ...executablePath && { executablePath }
676
- });
677
- }
678
- const loom = {
679
- id: this.generateLoomId(input),
680
- path: worktreePath,
681
- branch: branchName,
682
- type: input.type,
683
- identifier: input.identifier,
684
- port,
685
- createdAt: /* @__PURE__ */ new Date(),
686
- // We don't have actual creation date, use now
687
- lastAccessed: /* @__PURE__ */ new Date(),
688
- ...databaseBranch !== void 0 && { databaseBranch },
689
- ...capabilities.length > 0 && { capabilities },
690
- ...Object.keys(binEntries).length > 0 && { binEntries },
691
- ...githubData !== null && {
692
- githubData: {
693
- title: githubData.title,
694
- body: githubData.body,
695
- url: githubData.url,
696
- state: githubData.state
697
- }
698
- }
699
- };
700
- logger.success(`Reused existing loom: ${loom.id} at ${loom.path}`);
701
- return loom;
702
- }
703
- };
704
-
705
- // src/commands/start.ts
706
- var StartCommand = class {
707
- constructor(gitHubService, loomManager, agentManager, settingsManager) {
708
- this.loomManager = null;
709
- this.gitHubService = gitHubService ?? new GitHubService();
710
- this.agentManager = agentManager ?? new AgentManager();
711
- this.settingsManager = settingsManager ?? new SettingsManager();
712
- this.enhancementService = new IssueEnhancementService(
713
- this.gitHubService,
714
- this.agentManager,
715
- this.settingsManager
716
- );
717
- this.providedLoomManager = loomManager;
718
- const envResult = loadEnvIntoProcess();
719
- if (envResult.error) {
720
- logger.debug(`Environment loading warning: ${envResult.error.message}`);
721
- }
722
- if (envResult.parsed) {
723
- logger.debug(`Loaded ${Object.keys(envResult.parsed).length} environment variables`);
724
- }
725
- }
726
- /**
727
- * Initialize LoomManager with the main worktree path
728
- * Uses lazy initialization to ensure we have the correct path
729
- */
730
- async initializeLoomManager() {
731
- var _a, _b;
732
- if (this.loomManager) {
733
- return this.loomManager;
734
- }
735
- if (this.providedLoomManager) {
736
- this.loomManager = this.providedLoomManager;
737
- return this.loomManager;
738
- }
739
- const mainWorktreePath = await findMainWorktreePathWithSettings();
740
- const settings = await this.settingsManager.loadSettings();
741
- const environmentManager = new EnvironmentManager();
742
- const neonProvider = createNeonProviderFromSettings(settings);
743
- const databaseUrlEnvVarName = ((_b = (_a = settings.capabilities) == null ? void 0 : _a.database) == null ? void 0 : _b.databaseUrlEnvVarName) ?? "DATABASE_URL";
744
- const databaseManager = new DatabaseManager(neonProvider, environmentManager, databaseUrlEnvVarName);
745
- this.loomManager = new LoomManager(
746
- new GitWorktreeManager(mainWorktreePath),
747
- this.gitHubService,
748
- environmentManager,
749
- // Reuse same instance
750
- new ClaudeContextManager(),
751
- new ProjectCapabilityDetector(),
752
- new CLIIsolationManager(),
753
- this.settingsManager,
754
- // Use same instance with CLI overrides
755
- databaseManager
756
- // Add database manager
757
- );
758
- return this.loomManager;
759
- }
760
- /**
761
- * Main entry point for the start command
762
- */
763
- async execute(input) {
764
- var _a, _b, _c;
765
- try {
766
- const initialSettings = await this.settingsManager.loadSettings();
767
- let repo;
768
- const multipleRemotes = await hasMultipleRemotes();
769
- if (multipleRemotes) {
770
- repo = await getConfiguredRepoFromSettings(initialSettings);
771
- logger.info(`Using GitHub repository: ${repo}`);
772
- }
773
- const loomManager = await this.initializeLoomManager();
774
- const parsed = await this.parseInput(input.identifier, repo);
775
- await this.validateInput(parsed, repo);
776
- if (parsed.type === "description") {
777
- const issueNumber = await this.enhanceAndCreateIssue(parsed.originalInput);
778
- parsed.type = "issue";
779
- parsed.number = issueNumber;
780
- }
781
- if (input.options.oneShot === "bypassPermissions") {
782
- const { promptConfirmation } = await import("./prompt-ANTQWHUF.js");
783
- const confirmed = await promptConfirmation(
784
- "\u26A0\uFE0F WARNING: bypassPermissions mode will allow Claude to execute all tool calls without confirmation. This can be dangerous. Do you want to proceed?"
785
- );
786
- if (!confirmed) {
787
- logger.info("Operation cancelled by user");
788
- process.exit(0);
789
- }
790
- }
791
- const cliOverrides = extractSettingsOverrides();
792
- const settings = await this.settingsManager.loadSettings(void 0, cliOverrides);
793
- const workflowType = parsed.type === "branch" ? "regular" : parsed.type;
794
- const workflowConfig = (_a = settings.workflows) == null ? void 0 : _a[workflowType];
795
- const { extractRawSetArguments, getExecutablePath } = await import("./cli-overrides-XFZWY7CM.js");
796
- const setArguments = extractRawSetArguments();
797
- const executablePath = getExecutablePath();
798
- logger.info(`\u2705 Validated input: ${this.formatParsedInput(parsed)}`);
799
- const identifier = parsed.type === "branch" ? parsed.branchName ?? "" : parsed.number ?? 0;
800
- const enableClaude = input.options.claude ?? (workflowConfig == null ? void 0 : workflowConfig.startAiAgent) ?? true;
801
- const enableCode = input.options.code ?? (workflowConfig == null ? void 0 : workflowConfig.startIde) ?? true;
802
- const enableDevServer = input.options.devServer ?? (workflowConfig == null ? void 0 : workflowConfig.startDevServer) ?? true;
803
- const enableTerminal = input.options.terminal ?? (workflowConfig == null ? void 0 : workflowConfig.startTerminal) ?? false;
804
- logger.debug("Final workflow config values:", {
805
- enableClaude,
806
- enableCode,
807
- enableDevServer,
808
- enableTerminal
809
- });
810
- const loom = await loomManager.createIloom({
811
- type: parsed.type,
812
- identifier,
813
- originalInput: parsed.originalInput,
814
- options: {
815
- enableClaude,
816
- enableCode,
817
- enableDevServer,
818
- enableTerminal,
819
- ...input.options.oneShot && { oneShot: input.options.oneShot },
820
- ...setArguments.length > 0 && { setArguments },
821
- ...executablePath && { executablePath }
822
- }
823
- });
824
- logger.success(`\u2705 Created loom: ${loom.id} at ${loom.path}`);
825
- logger.info(` Branch: ${loom.branch}`);
826
- if ((_b = loom.capabilities) == null ? void 0 : _b.includes("web")) {
827
- logger.info(` Port: ${loom.port}`);
828
- }
829
- if ((_c = loom.githubData) == null ? void 0 : _c.title) {
830
- logger.info(` Title: ${loom.githubData.title}`);
831
- }
832
- } catch (error) {
833
- if (error instanceof Error) {
834
- logger.error(`\u274C ${error.message}`);
835
- } else {
836
- logger.error("\u274C An unknown error occurred");
837
- }
838
- throw error;
839
- }
840
- }
841
- /**
842
- * Parse input to determine type and extract relevant data
843
- */
844
- async parseInput(identifier, repo) {
845
- const trimmedIdentifier = identifier.trim();
846
- if (!trimmedIdentifier) {
847
- throw new Error("Missing required argument: identifier");
848
- }
849
- const spaceCount = (trimmedIdentifier.match(/ /g) ?? []).length;
850
- if (trimmedIdentifier.length > 25 && spaceCount > 2) {
851
- return {
852
- type: "description",
853
- originalInput: trimmedIdentifier
854
- };
855
- }
856
- const prPattern = /^(?:pr|PR)[/-](\d+)$/;
857
- const prMatch = trimmedIdentifier.match(prPattern);
858
- if (prMatch == null ? void 0 : prMatch[1]) {
859
- return {
860
- type: "pr",
861
- number: parseInt(prMatch[1], 10),
862
- originalInput: trimmedIdentifier
863
- };
864
- }
865
- const numericPattern = /^#?(\d+)$/;
866
- const numericMatch = trimmedIdentifier.match(numericPattern);
867
- if (numericMatch == null ? void 0 : numericMatch[1]) {
868
- const number = parseInt(numericMatch[1], 10);
869
- const detection = await this.gitHubService.detectInputType(
870
- trimmedIdentifier,
871
- repo
872
- );
873
- if (detection.type === "pr") {
874
- return {
875
- type: "pr",
876
- number: detection.number ?? number,
877
- originalInput: trimmedIdentifier
878
- };
879
- } else if (detection.type === "issue") {
880
- return {
881
- type: "issue",
882
- number: detection.number ?? number,
883
- originalInput: trimmedIdentifier
884
- };
885
- } else {
886
- throw new Error(`Could not find issue or PR #${number}`);
887
- }
888
- }
889
- return {
890
- type: "branch",
891
- branchName: trimmedIdentifier,
892
- originalInput: trimmedIdentifier
893
- };
894
- }
895
- /**
896
- * Validate the parsed input based on its type
897
- */
898
- async validateInput(parsed, repo) {
899
- switch (parsed.type) {
900
- case "pr": {
901
- if (!parsed.number) {
902
- throw new Error("Invalid PR number");
903
- }
904
- const pr = await this.gitHubService.fetchPR(parsed.number, repo);
905
- await this.gitHubService.validatePRState(pr);
906
- logger.debug(`Validated PR #${parsed.number}`);
907
- break;
908
- }
909
- case "issue": {
910
- if (!parsed.number) {
911
- throw new Error("Invalid issue number");
912
- }
913
- const issue = await this.gitHubService.fetchIssue(parsed.number, repo);
914
- await this.gitHubService.validateIssueState(issue);
915
- logger.debug(`Validated issue #${parsed.number}`);
916
- break;
917
- }
918
- case "branch": {
919
- if (!parsed.branchName) {
920
- throw new Error("Invalid branch name");
921
- }
922
- if (!this.isValidBranchName(parsed.branchName)) {
923
- throw new Error(
924
- "Invalid branch name. Use only letters, numbers, hyphens, underscores, and slashes"
925
- );
926
- }
927
- const exists = await branchExists(parsed.branchName);
928
- if (exists) {
929
- throw new Error(`Branch '${parsed.branchName}' already exists`);
930
- }
931
- logger.debug(`Validated branch name: ${parsed.branchName}`);
932
- break;
933
- }
934
- case "description": {
935
- logger.debug("Detected description input", {
936
- length: parsed.originalInput.length
937
- });
938
- break;
939
- }
940
- default: {
941
- const unknownType = parsed;
942
- throw new Error(`Unknown input type: ${unknownType.type}`);
943
- }
944
- }
945
- }
946
- /**
947
- * Validate branch name format
948
- */
949
- isValidBranchName(branch) {
950
- return /^[a-zA-Z0-9/_-]+$/.test(branch);
951
- }
952
- /**
953
- * Format parsed input for display
954
- */
955
- formatParsedInput(parsed) {
956
- switch (parsed.type) {
957
- case "pr":
958
- return `PR #${parsed.number}`;
959
- case "issue":
960
- return `Issue #${parsed.number}`;
961
- case "branch":
962
- return `Branch '${parsed.branchName}'`;
963
- case "description":
964
- return `Description: ${parsed.originalInput.slice(0, 50)}...`;
965
- default:
966
- return "Unknown input";
967
- }
968
- }
969
- /**
970
- * Enhance description using Claude AI and create GitHub issue
971
- * Returns the new issue number
972
- */
973
- async enhanceAndCreateIssue(description) {
974
- const enhancedDescription = await this.enhancementService.enhanceDescription(description);
975
- const result = await this.enhancementService.createEnhancedIssue(description, enhancedDescription);
976
- await this.enhancementService.waitForReviewAndOpen(result.number, true);
977
- return result.number;
978
- }
979
- };
980
- export {
981
- StartCommand
982
- };
983
- //# sourceMappingURL=start-CT2ZEFP2.js.map