@iloom/cli 0.13.1 → 0.13.3

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 (148) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/dist/CLAUDE.md +66 -0
  4. package/dist/{ClaudeContextManager-ZH6LEA5I.js → ClaudeContextManager-KJ4VEA2F.js} +5 -5
  5. package/dist/{ClaudeService-YR66WXZN.js → ClaudeService-WTJO4UW6.js} +4 -4
  6. package/dist/{IssueTrackerFactory-O2ZBA666.js → IssueTrackerFactory-UEJALI4X.js} +3 -3
  7. package/dist/{LoomLauncher-V54ENBEF.js → LoomLauncher-KG2VBNQA.js} +5 -5
  8. package/dist/{PromptTemplateManager-4RFELNYY.js → PromptTemplateManager-QIUVJP6S.js} +2 -2
  9. package/dist/README.md +1 -1
  10. package/dist/{SettingsManager-SLSYEYDZ.js → SettingsManager-PVHBSCMI.js} +2 -2
  11. package/dist/agents/CLAUDE.md +68 -0
  12. package/dist/agents/iloom-code-reviewer.md +1 -0
  13. package/dist/agents/iloom-wave-verifier.md +1 -36
  14. package/dist/{build-ZTGWDHWU.js → build-2FXDYEZQ.js} +6 -6
  15. package/dist/{chunk-LNY2Y32V.js → chunk-2WRD6Y5E.js} +2 -2
  16. package/dist/{chunk-WYDLOQYO.js → chunk-32D4CWWH.js} +2 -2
  17. package/dist/{chunk-KGOBNC5A.js → chunk-5W44AI63.js} +3 -3
  18. package/dist/{chunk-PPQ5LV7U.js → chunk-D6FU4DLN.js} +2 -2
  19. package/dist/{chunk-PS6K2AOV.js → chunk-DMNI225H.js} +4 -4
  20. package/dist/{chunk-55NTREIU.js → chunk-DYLOITSO.js} +55 -35
  21. package/dist/chunk-DYLOITSO.js.map +1 -0
  22. package/dist/{chunk-T4KFKKEB.js → chunk-H4TSDALC.js} +6 -6
  23. package/dist/{chunk-J5JOJPK3.js → chunk-L3P3YJCE.js} +2 -2
  24. package/dist/{chunk-MRPIDNZU.js → chunk-LDE6VNG5.js} +1 -1
  25. package/dist/chunk-LDE6VNG5.js.map +1 -0
  26. package/dist/{chunk-F5NKWLMQ.js → chunk-MNPKEWBQ.js} +9 -5
  27. package/dist/chunk-MNPKEWBQ.js.map +1 -0
  28. package/dist/{chunk-EHAITKLS.js → chunk-MPHSR6GA.js} +3 -3
  29. package/dist/{chunk-HWDQRW3O.js → chunk-OHX3PSAY.js} +2 -2
  30. package/dist/{chunk-C2BVNJW5.js → chunk-OIJNBFMP.js} +2 -2
  31. package/dist/{chunk-TJDKGKQV.js → chunk-OMV47LLA.js} +2 -2
  32. package/dist/{chunk-P5MNWBLH.js → chunk-OVW26FHW.js} +19 -7
  33. package/dist/chunk-OVW26FHW.js.map +1 -0
  34. package/dist/{chunk-QNRXRSKC.js → chunk-RP6MHV24.js} +9 -9
  35. package/dist/chunk-RP6MHV24.js.map +1 -0
  36. package/dist/{chunk-UXBVDD7U.js → chunk-U2OPXZ6E.js} +282 -44
  37. package/dist/chunk-U2OPXZ6E.js.map +1 -0
  38. package/dist/{chunk-T4NESGYB.js → chunk-UMAOVKQX.js} +3 -3
  39. package/dist/{chunk-E5OM25WK.js → chunk-UQWMPQ2Q.js} +2 -2
  40. package/dist/{chunk-ZEFTWM5Z.js → chunk-VUIPDX3T.js} +2 -2
  41. package/dist/{chunk-GQDVH6FA.js → chunk-XC5JKRSH.js} +2 -2
  42. package/dist/{chunk-G2DGDCDP.js → chunk-Y2JHYPMX.js} +15 -13
  43. package/dist/chunk-Y2JHYPMX.js.map +1 -0
  44. package/dist/{chunk-ERMEYFT6.js → chunk-YVNG35OW.js} +2 -2
  45. package/dist/{chunk-7TN5VW4I.js → chunk-Z32HPRZF.js} +2 -1
  46. package/dist/chunk-Z32HPRZF.js.map +1 -0
  47. package/dist/{chunk-KCAWSZUO.js → chunk-Z3ZEJN3W.js} +13 -13
  48. package/dist/{chunk-GPBX2BY2.js → chunk-ZWXJ7G2C.js} +2 -2
  49. package/dist/{cleanup-BCVY7PEF.js → cleanup-W5FP3UKK.js} +16 -16
  50. package/dist/cli.js +115 -68
  51. package/dist/cli.js.map +1 -1
  52. package/dist/{commit-L5JNBU4U.js → commit-7RI2JFFW.js} +6 -6
  53. package/dist/{compile-GPJOHXH4.js → compile-NWTMKAGL.js} +6 -6
  54. package/dist/{contribute-QEGCI4PS.js → contribute-QWPOT4QR.js} +3 -3
  55. package/dist/{dev-server-UQKNKU2S.js → dev-server-U2XUN57X.js} +61 -30
  56. package/dist/dev-server-U2XUN57X.js.map +1 -0
  57. package/dist/{feedback-2LWXKLQZ.js → feedback-M43SGGK2.js} +4 -4
  58. package/dist/{git-IS7AV3ED.js → git-ZTMT6OAI.js} +3 -3
  59. package/dist/{ignite-VQDJQ37S.js → ignite-GUYKYC5G.js} +11 -11
  60. package/dist/index.d.ts +30 -3
  61. package/dist/index.js +8 -4
  62. package/dist/index.js.map +1 -1
  63. package/dist/{init-7SDJUAEZ.js → init-AMLCFVXG.js} +9 -7
  64. package/dist/init-AMLCFVXG.js.map +1 -0
  65. package/dist/{install-deps-NGSFDNUW.js → install-deps-XS2UUCUS.js} +6 -6
  66. package/dist/{issues-4HQKEUP7.js → issues-2IT7PSNZ.js} +4 -4
  67. package/dist/{lint-C5FOVRXY.js → lint-DKWJHET3.js} +6 -6
  68. package/dist/mcp/issue-management-server.js +8 -4
  69. package/dist/mcp/issue-management-server.js.map +1 -1
  70. package/dist/{open-2HL6GV5F.js → open-XIUV5JMJ.js} +16 -15
  71. package/dist/open-XIUV5JMJ.js.map +1 -0
  72. package/dist/{plan-GC3HF73T.js → plan-UPYDB34J.js} +20 -20
  73. package/dist/prompts/epic-report-prompt.txt +145 -0
  74. package/dist/prompts/init-prompt.txt +32 -9
  75. package/dist/prompts/issue-prompt.txt +1 -1
  76. package/dist/prompts/swarm-orchestrator-prompt.txt +50 -6
  77. package/dist/{rebase-MLIN572O.js → rebase-6AXN45AE.js} +5 -5
  78. package/dist/{recap-CKGKFDJL.js → recap-XDKI3MTA.js} +6 -6
  79. package/dist/{run-CUNRQNZS.js → run-VOGGJGPO.js} +19 -19
  80. package/dist/run-VOGGJGPO.js.map +1 -0
  81. package/dist/schema/settings.schema.json +14 -0
  82. package/dist/{shell-M2YYPNGV.js → shell-XOILFEZW.js} +5 -5
  83. package/dist/{summary-XR4CBJEG.js → summary-BVYOM63C.js} +10 -8
  84. package/dist/{summary-XR4CBJEG.js.map → summary-BVYOM63C.js.map} +1 -1
  85. package/dist/{test-ESDAHEVE.js → test-6T2UMQ7T.js} +6 -6
  86. package/dist/{test-git-KWPLHYSI.js → test-git-CQ65OL45.js} +3 -3
  87. package/dist/{test-jira-6NK7UHSV.js → test-jira-CQQHGZ3S.js} +3 -3
  88. package/dist/{test-prefix-VVODGHXP.js → test-prefix-HMTZSS67.js} +3 -3
  89. package/dist/{test-webserver-AHXKC6H4.js → test-webserver-ZN73CM2T.js} +5 -5
  90. package/dist/{vscode-OY7HOVRO.js → vscode-ABQ5ZSH7.js} +5 -5
  91. package/package.json +1 -1
  92. package/dist/chunk-55NTREIU.js.map +0 -1
  93. package/dist/chunk-7TN5VW4I.js.map +0 -1
  94. package/dist/chunk-F5NKWLMQ.js.map +0 -1
  95. package/dist/chunk-G2DGDCDP.js.map +0 -1
  96. package/dist/chunk-MRPIDNZU.js.map +0 -1
  97. package/dist/chunk-P5MNWBLH.js.map +0 -1
  98. package/dist/chunk-QNRXRSKC.js.map +0 -1
  99. package/dist/chunk-UXBVDD7U.js.map +0 -1
  100. package/dist/dev-server-UQKNKU2S.js.map +0 -1
  101. package/dist/init-7SDJUAEZ.js.map +0 -1
  102. package/dist/open-2HL6GV5F.js.map +0 -1
  103. package/dist/run-CUNRQNZS.js.map +0 -1
  104. /package/dist/{ClaudeContextManager-ZH6LEA5I.js.map → ClaudeContextManager-KJ4VEA2F.js.map} +0 -0
  105. /package/dist/{ClaudeService-YR66WXZN.js.map → ClaudeService-WTJO4UW6.js.map} +0 -0
  106. /package/dist/{IssueTrackerFactory-O2ZBA666.js.map → IssueTrackerFactory-UEJALI4X.js.map} +0 -0
  107. /package/dist/{LoomLauncher-V54ENBEF.js.map → LoomLauncher-KG2VBNQA.js.map} +0 -0
  108. /package/dist/{PromptTemplateManager-4RFELNYY.js.map → PromptTemplateManager-QIUVJP6S.js.map} +0 -0
  109. /package/dist/{SettingsManager-SLSYEYDZ.js.map → SettingsManager-PVHBSCMI.js.map} +0 -0
  110. /package/dist/{build-ZTGWDHWU.js.map → build-2FXDYEZQ.js.map} +0 -0
  111. /package/dist/{chunk-LNY2Y32V.js.map → chunk-2WRD6Y5E.js.map} +0 -0
  112. /package/dist/{chunk-WYDLOQYO.js.map → chunk-32D4CWWH.js.map} +0 -0
  113. /package/dist/{chunk-KGOBNC5A.js.map → chunk-5W44AI63.js.map} +0 -0
  114. /package/dist/{chunk-PPQ5LV7U.js.map → chunk-D6FU4DLN.js.map} +0 -0
  115. /package/dist/{chunk-PS6K2AOV.js.map → chunk-DMNI225H.js.map} +0 -0
  116. /package/dist/{chunk-T4KFKKEB.js.map → chunk-H4TSDALC.js.map} +0 -0
  117. /package/dist/{chunk-J5JOJPK3.js.map → chunk-L3P3YJCE.js.map} +0 -0
  118. /package/dist/{chunk-EHAITKLS.js.map → chunk-MPHSR6GA.js.map} +0 -0
  119. /package/dist/{chunk-HWDQRW3O.js.map → chunk-OHX3PSAY.js.map} +0 -0
  120. /package/dist/{chunk-C2BVNJW5.js.map → chunk-OIJNBFMP.js.map} +0 -0
  121. /package/dist/{chunk-TJDKGKQV.js.map → chunk-OMV47LLA.js.map} +0 -0
  122. /package/dist/{chunk-T4NESGYB.js.map → chunk-UMAOVKQX.js.map} +0 -0
  123. /package/dist/{chunk-E5OM25WK.js.map → chunk-UQWMPQ2Q.js.map} +0 -0
  124. /package/dist/{chunk-ZEFTWM5Z.js.map → chunk-VUIPDX3T.js.map} +0 -0
  125. /package/dist/{chunk-GQDVH6FA.js.map → chunk-XC5JKRSH.js.map} +0 -0
  126. /package/dist/{chunk-ERMEYFT6.js.map → chunk-YVNG35OW.js.map} +0 -0
  127. /package/dist/{chunk-KCAWSZUO.js.map → chunk-Z3ZEJN3W.js.map} +0 -0
  128. /package/dist/{chunk-GPBX2BY2.js.map → chunk-ZWXJ7G2C.js.map} +0 -0
  129. /package/dist/{cleanup-BCVY7PEF.js.map → cleanup-W5FP3UKK.js.map} +0 -0
  130. /package/dist/{commit-L5JNBU4U.js.map → commit-7RI2JFFW.js.map} +0 -0
  131. /package/dist/{compile-GPJOHXH4.js.map → compile-NWTMKAGL.js.map} +0 -0
  132. /package/dist/{contribute-QEGCI4PS.js.map → contribute-QWPOT4QR.js.map} +0 -0
  133. /package/dist/{feedback-2LWXKLQZ.js.map → feedback-M43SGGK2.js.map} +0 -0
  134. /package/dist/{git-IS7AV3ED.js.map → git-ZTMT6OAI.js.map} +0 -0
  135. /package/dist/{ignite-VQDJQ37S.js.map → ignite-GUYKYC5G.js.map} +0 -0
  136. /package/dist/{install-deps-NGSFDNUW.js.map → install-deps-XS2UUCUS.js.map} +0 -0
  137. /package/dist/{issues-4HQKEUP7.js.map → issues-2IT7PSNZ.js.map} +0 -0
  138. /package/dist/{lint-C5FOVRXY.js.map → lint-DKWJHET3.js.map} +0 -0
  139. /package/dist/{plan-GC3HF73T.js.map → plan-UPYDB34J.js.map} +0 -0
  140. /package/dist/{rebase-MLIN572O.js.map → rebase-6AXN45AE.js.map} +0 -0
  141. /package/dist/{recap-CKGKFDJL.js.map → recap-XDKI3MTA.js.map} +0 -0
  142. /package/dist/{shell-M2YYPNGV.js.map → shell-XOILFEZW.js.map} +0 -0
  143. /package/dist/{test-ESDAHEVE.js.map → test-6T2UMQ7T.js.map} +0 -0
  144. /package/dist/{test-git-KWPLHYSI.js.map → test-git-CQ65OL45.js.map} +0 -0
  145. /package/dist/{test-jira-6NK7UHSV.js.map → test-jira-CQQHGZ3S.js.map} +0 -0
  146. /package/dist/{test-prefix-VVODGHXP.js.map → test-prefix-HMTZSS67.js.map} +0 -0
  147. /package/dist/{test-webserver-AHXKC6H4.js.map → test-webserver-ZN73CM2T.js.map} +0 -0
  148. /package/dist/{vscode-OY7HOVRO.js.map → vscode-ABQ5ZSH7.js.map} +0 -0
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  CommitManager,
4
4
  ValidationRunner
5
- } from "./chunk-HWDQRW3O.js";
5
+ } from "./chunk-OHX3PSAY.js";
6
6
  import {
7
7
  IssueManagementProviderFactory
8
- } from "./chunk-ZEFTWM5Z.js";
8
+ } from "./chunk-VUIPDX3T.js";
9
9
  import "./chunk-4232AHNQ.js";
10
10
  import "./chunk-OLJ54WGW.js";
11
11
  import {
12
12
  GitWorktreeManager
13
- } from "./chunk-PPQ5LV7U.js";
13
+ } from "./chunk-D6FU4DLN.js";
14
14
  import "./chunk-K3QGG4O2.js";
15
15
  import "./chunk-DMSL5BAP.js";
16
16
  import "./chunk-KV4NU3RP.js";
@@ -20,10 +20,10 @@ import {
20
20
  extractIssueNumber,
21
21
  getWorktreeRoot,
22
22
  isValidGitRepo
23
- } from "./chunk-KGOBNC5A.js";
23
+ } from "./chunk-5W44AI63.js";
24
24
  import {
25
25
  SettingsManager
26
- } from "./chunk-F5NKWLMQ.js";
26
+ } from "./chunk-MNPKEWBQ.js";
27
27
  import {
28
28
  MetadataManager
29
29
  } from "./chunk-XIVLGWUX.js";
@@ -238,4 +238,4 @@ export {
238
238
  CommitCommand,
239
239
  WorktreeValidationError
240
240
  };
241
- //# sourceMappingURL=commit-L5JNBU4U.js.map
241
+ //# sourceMappingURL=commit-7RI2JFFW.js.map
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ScriptCommandBase
4
- } from "./chunk-PS6K2AOV.js";
5
- import "./chunk-GQDVH6FA.js";
4
+ } from "./chunk-DMNI225H.js";
5
+ import "./chunk-XC5JKRSH.js";
6
6
  import {
7
7
  runScript
8
8
  } from "./chunk-OLJ54WGW.js";
9
- import "./chunk-PPQ5LV7U.js";
9
+ import "./chunk-D6FU4DLN.js";
10
10
  import {
11
11
  getPackageScripts
12
12
  } from "./chunk-K3QGG4O2.js";
13
- import "./chunk-KGOBNC5A.js";
14
- import "./chunk-F5NKWLMQ.js";
13
+ import "./chunk-5W44AI63.js";
14
+ import "./chunk-MNPKEWBQ.js";
15
15
  import "./chunk-XIVLGWUX.js";
16
16
  import "./chunk-FTYWGQFM.js";
17
17
  import {
@@ -54,4 +54,4 @@ var CompileCommand = class extends ScriptCommandBase {
54
54
  export {
55
55
  CompileCommand
56
56
  };
57
- //# sourceMappingURL=compile-GPJOHXH4.js.map
57
+ //# sourceMappingURL=compile-NWTMKAGL.js.map
@@ -14,8 +14,8 @@ import {
14
14
  } from "./chunk-NPVA65KS.js";
15
15
  import {
16
16
  executeGitCommand
17
- } from "./chunk-KGOBNC5A.js";
18
- import "./chunk-F5NKWLMQ.js";
17
+ } from "./chunk-5W44AI63.js";
18
+ import "./chunk-MNPKEWBQ.js";
19
19
  import "./chunk-XIVLGWUX.js";
20
20
  import "./chunk-FTYWGQFM.js";
21
21
  import {
@@ -335,4 +335,4 @@ export {
335
335
  validateDirectoryPath,
336
336
  validateRepoExists
337
337
  };
338
- //# sourceMappingURL=contribute-QEGCI4PS.js.map
338
+ //# sourceMappingURL=contribute-QWPOT4QR.js.map
@@ -2,37 +2,39 @@
2
2
  import {
3
3
  DevServerManager,
4
4
  buildDevServerUrl
5
- } from "./chunk-P5MNWBLH.js";
5
+ } from "./chunk-OVW26FHW.js";
6
6
  import {
7
7
  DockerManager
8
- } from "./chunk-7TN5VW4I.js";
9
- import "./chunk-LNY2Y32V.js";
8
+ } from "./chunk-Z32HPRZF.js";
9
+ import {
10
+ ProcessManager
11
+ } from "./chunk-2WRD6Y5E.js";
10
12
  import {
11
13
  getWorkspacePort
12
- } from "./chunk-ERMEYFT6.js";
14
+ } from "./chunk-YVNG35OW.js";
13
15
  import {
14
16
  IdentifierParser
15
- } from "./chunk-GQDVH6FA.js";
17
+ } from "./chunk-XC5JKRSH.js";
16
18
  import "./chunk-OLJ54WGW.js";
17
19
  import {
18
20
  GitWorktreeManager
19
- } from "./chunk-PPQ5LV7U.js";
21
+ } from "./chunk-D6FU4DLN.js";
20
22
  import {
21
23
  openBrowser
22
24
  } from "./chunk-WEBMMJKL.js";
23
- import {
24
- extractSettingsOverrides
25
- } from "./chunk-GYCR2LOU.js";
26
25
  import {
27
26
  ProjectCapabilityDetector
28
27
  } from "./chunk-772N5WCA.js";
29
28
  import "./chunk-K3QGG4O2.js";
29
+ import {
30
+ extractSettingsOverrides
31
+ } from "./chunk-GYCR2LOU.js";
30
32
  import {
31
33
  extractIssueNumber
32
- } from "./chunk-KGOBNC5A.js";
34
+ } from "./chunk-5W44AI63.js";
33
35
  import {
34
36
  SettingsManager
35
- } from "./chunk-F5NKWLMQ.js";
37
+ } from "./chunk-MNPKEWBQ.js";
36
38
  import {
37
39
  MetadataManager
38
40
  } from "./chunk-XIVLGWUX.js";
@@ -46,6 +48,7 @@ import {
46
48
 
47
49
  // src/commands/dev-server.ts
48
50
  import path from "path";
51
+ import { execa as execa2 } from "execa";
49
52
 
50
53
  // src/lib/DevServerTUI.ts
51
54
  import { execa } from "execa";
@@ -281,6 +284,9 @@ var DevServerCommand = class {
281
284
  if (metadata == null ? void 0 : metadata.colorHex) {
282
285
  envOverrides.ILOOM_COLOR_HEX = metadata.colorHex;
283
286
  }
287
+ if (input.env) {
288
+ Object.assign(envOverrides, input.env);
289
+ }
284
290
  const { capabilities } = await this.capabilityDetector.detectCapabilities(worktree.path);
285
291
  logger.debug(`Detected capabilities: ${capabilities.join(", ")}`);
286
292
  if (!capabilities.includes("web")) {
@@ -342,6 +348,7 @@ var DevServerCommand = class {
342
348
  };
343
349
  const useTui = !input.json && process.stdout.isTTY === true && process.stdin.isTTY === true;
344
350
  let tui;
351
+ let restartRequested = false;
345
352
  if (useTui) {
346
353
  tui = new DevServerTUI({
347
354
  url,
@@ -349,6 +356,23 @@ var DevServerCommand = class {
349
356
  containerPort: dockerConfig == null ? void 0 : dockerConfig.containerPort,
350
357
  onQuit: () => {
351
358
  process.kill(process.pid, "SIGINT");
359
+ },
360
+ onRestart: () => {
361
+ restartRequested = true;
362
+ tui == null ? void 0 : tui.updateStatus("Restarting");
363
+ if (dockerConfig) {
364
+ const containerName = DockerManager.buildContainerName(
365
+ dockerConfig.identifier ?? ""
366
+ );
367
+ void execa2("docker", ["stop", containerName], { reject: false });
368
+ } else {
369
+ const processManager = new ProcessManager();
370
+ void processManager.detectDevServer(port).then((processInfo) => {
371
+ if (processInfo == null ? void 0 : processInfo.pid) {
372
+ process.kill(processInfo.pid, "SIGTERM");
373
+ }
374
+ });
375
+ }
352
376
  }
353
377
  });
354
378
  tui.start();
@@ -357,24 +381,31 @@ var DevServerCommand = class {
357
381
  tui == null ? void 0 : tui.handleOutput(data);
358
382
  } : void 0;
359
383
  try {
360
- const processInfo = await this.devServerManager.runServerForeground(
361
- worktree.path,
362
- port,
363
- !!input.json,
364
- // Callback called immediately when process starts (for JSON output)
365
- (pid) => {
366
- if (input.json && pid) {
367
- finalResult.pid = pid;
368
- this.outputJson(finalResult);
369
- }
370
- },
371
- envOverrides,
372
- dockerConfig,
373
- onOutput
374
- );
375
- if (processInfo.pid) {
376
- finalResult.pid = processInfo.pid;
377
- }
384
+ do {
385
+ restartRequested = false;
386
+ const processInfo = await this.devServerManager.runServerForeground(
387
+ worktree.path,
388
+ port,
389
+ !!input.json,
390
+ // Callback called immediately when process starts (for JSON output)
391
+ (pid) => {
392
+ if (input.json && pid) {
393
+ finalResult.pid = pid;
394
+ this.outputJson(finalResult);
395
+ }
396
+ },
397
+ envOverrides,
398
+ dockerConfig,
399
+ onOutput
400
+ );
401
+ if (processInfo.pid) {
402
+ finalResult.pid = processInfo.pid;
403
+ }
404
+ if (restartRequested) {
405
+ logger.info("Restarting dev server...");
406
+ tui == null ? void 0 : tui.updateStatus("Running");
407
+ }
408
+ } while (restartRequested);
378
409
  } finally {
379
410
  if (tui) {
380
411
  tui.cleanup();
@@ -502,4 +533,4 @@ var DevServerCommand = class {
502
533
  export {
503
534
  DevServerCommand
504
535
  };
505
- //# sourceMappingURL=dev-server-UQKNKU2S.js.map
536
+ //# sourceMappingURL=dev-server-U2XUN57X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/dev-server.ts","../src/lib/DevServerTUI.ts"],"sourcesContent":["import path from 'path'\nimport { execa } from 'execa'\nimport { GitWorktreeManager } from '../lib/GitWorktreeManager.js'\nimport { MetadataManager } from '../lib/MetadataManager.js'\nimport { ProjectCapabilityDetector } from '../lib/ProjectCapabilityDetector.js'\nimport { DevServerManager } from '../lib/DevServerManager.js'\nimport { DevServerTUI } from '../lib/DevServerTUI.js'\nimport { DockerManager } from '../lib/DockerManager.js'\nimport { ProcessManager } from '../lib/process/ProcessManager.js'\nimport { SettingsManager } from '../lib/SettingsManager.js'\nimport { IdentifierParser } from '../utils/IdentifierParser.js'\nimport { loadWorkspaceEnv, isNoEnvFilesFoundError } from '../utils/env.js'\nimport { getWorkspacePort } from '../utils/port.js'\nimport { extractIssueNumber } from '../utils/git.js'\nimport { buildDevServerUrl } from '../utils/dev-server.js'\nimport { logger } from '../utils/logger.js'\nimport { extractSettingsOverrides } from '../utils/cli-overrides.js'\nimport type { GitWorktree } from '../types/worktree.js'\n\nexport interface DevServerCommandInput {\n\tidentifier?: string | undefined\n\tjson?: boolean | undefined\n\tenv?: Record<string, string> | undefined\n}\n\nexport interface DevServerResult {\n\tstatus: 'started' | 'already_running' | 'no_web_capability'\n\turl?: string\n\tport?: number\n\tpid?: number\n\tmessage: string\n}\n\ninterface ParsedDevServerInput {\n\ttype: 'issue' | 'pr' | 'branch' | 'epic'\n\tnumber?: string | number\n\tbranchName?: string\n\toriginalInput: string\n\tautoDetected: boolean\n}\n\n/**\n * DevServerCommand - Start dev server for workspace in foreground mode\n * Runs in foreground (blocking terminal until user stops it)\n */\nexport class DevServerCommand {\n\tconstructor(\n\t\tprivate gitWorktreeManager = new GitWorktreeManager(),\n\t\tprivate capabilityDetector = new ProjectCapabilityDetector(),\n\t\tprivate identifierParser = new IdentifierParser(new GitWorktreeManager()),\n\t\tprivate devServerManager = new DevServerManager(),\n\t\tprivate settingsManager = new SettingsManager(),\n\t\tprivate metadataManager = new MetadataManager()\n\t) {}\n\n\t/**\n\t * Output JSON to stdout (used for --json flag)\n\t */\n\tprivate outputJson(data: DevServerResult | Record<string, unknown>): void {\n\t\tprocess.stdout.write(JSON.stringify(data, null, 2) + '\\n')\n\t}\n\n\tasync execute(input: DevServerCommandInput): Promise<DevServerResult> {\n\t\t// 1. Parse or auto-detect identifier\n\t\tconst parsed = input.identifier\n\t\t\t? await this.parseExplicitInput(input.identifier)\n\t\t\t: await this.autoDetectFromCurrentDirectory()\n\n\t\tlogger.debug(`Parsed input: ${JSON.stringify(parsed)}`)\n\n\t\t// 2. Find worktree path based on identifier\n\t\tconst worktree = await this.findWorktreeForIdentifier(parsed)\n\n\t\tlogger.debug(`Found worktree at: ${worktree.path}`)\n\n\t\t// 3. Load settings to check sourceEnvOnStart and Docker config\n\t\tconst settings = await this.settingsManager.loadSettings()\n\t\tconst shouldLoadEnv = settings.sourceEnvOnStart ?? false\n\n\t\t// 3a. Extract Docker configuration if Docker mode is enabled\n\t\tconst identifier = parsed.number?.toString() ?? parsed.branchName ?? parsed.originalInput\n\t\tconst dockerConfig = DockerManager.buildDockerConfigFromSettings(\n\t\t\tsettings.capabilities?.web,\n\t\t\tidentifier\n\t\t)\n\n\t\tif (dockerConfig) {\n\t\t\tawait DockerManager.assertAvailable()\n\t\t\tconst { dockerFile, containerPort, identifier } = dockerConfig\n\t\t\tlogger.debug(`Docker mode enabled with config: ${JSON.stringify({ dockerFile, containerPort, identifier })}`)\n\t\t}\n\n\t\t// Build environment variables\n\t\tlet envOverrides: Record<string, string> = {}\n\n\t\tif (shouldLoadEnv) {\n\t\t\tconst envResult = loadWorkspaceEnv(worktree.path)\n\t\t\tif (envResult.parsed) {\n\t\t\t\tenvOverrides = envResult.parsed\n\t\t\t}\n\t\t\tif (envResult.error && !isNoEnvFilesFoundError(envResult.error)) {\n\t\t\t\tlogger.warn(`Failed to load env files: ${envResult.error.message}`)\n\t\t\t}\n\t\t}\n\n\t\t// 3b. Set ILOOM_LOOM for loom identification\n\t\tenvOverrides.ILOOM_LOOM = this.formatLoomIdentifier(parsed)\n\n\t\t// 3c. Set ILOOM_COLOR_HEX from loom metadata if available\n\t\tconst metadata = await this.metadataManager.readMetadata(worktree.path)\n\t\tif (metadata?.colorHex) {\n\t\t\tenvOverrides.ILOOM_COLOR_HEX = metadata.colorHex\n\t\t}\n\n\t\t// 3d. Merge CLI --env overrides (highest priority for environment variables)\n\t\tif (input.env) {\n\t\t\tObject.assign(envOverrides, input.env)\n\t\t}\n\n\t\t// 4. Detect project capabilities\n\t\tconst { capabilities } =\n\t\t\tawait this.capabilityDetector.detectCapabilities(worktree.path)\n\n\t\tlogger.debug(`Detected capabilities: ${capabilities.join(', ')}`)\n\n\t\t// 4. If no web capability, return gracefully with info message\n\t\tif (!capabilities.includes('web')) {\n\t\t\tconst message = 'No web capability detected in this workspace. Dev server not started.'\n\t\t\tif (input.json) {\n\t\t\t\tthis.outputJson({\n\t\t\t\t\tstatus: 'no_web_capability',\n\t\t\t\t\tmessage,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tlogger.info(message)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: 'no_web_capability',\n\t\t\t\tmessage,\n\t\t\t}\n\t\t}\n\n\t\t// 5. Get port for workspace\n\t\tconst cliOverrides = extractSettingsOverrides()\n\t\tconst settingsForPort = await this.settingsManager.loadSettings(undefined, cliOverrides)\n\t\tconst isMainWorktree = await this.gitWorktreeManager.isMainWorktree(worktree, this.settingsManager)\n\t\tconst port = await getWorkspacePort({\n\t\t\tworktreePath: worktree.path,\n\t\t\tworktreeBranch: worktree.branch,\n\t\t\tbasePort: settingsForPort.capabilities?.web?.basePort,\n\t\t\tcheckEnvFile: true,\n\t\t\tisMainWorktree,\n\t\t})\n\t\tconst protocol = settingsForPort.capabilities?.web?.protocol ?? 'http'\n\t\tconst url = buildDevServerUrl(port, protocol)\n\n\t\t// 6. Check if server already running\n\t\tconst isRunning = await this.devServerManager.isServerRunning(port, dockerConfig)\n\n\t\tif (isRunning) {\n\t\t\tconst message = `Dev server already running at ${url}`\n\t\t\tif (input.json) {\n\t\t\t\tthis.outputJson({\n\t\t\t\t\tstatus: 'already_running',\n\t\t\t\t\turl,\n\t\t\t\t\tport,\n\t\t\t\t\tmessage,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tlogger.info(message)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tstatus: 'already_running',\n\t\t\t\turl,\n\t\t\t\tport,\n\t\t\t\tmessage,\n\t\t\t}\n\t\t}\n\n\t\t// 7. Start server in foreground\n\t\tconst message = `Starting dev server at ${url}`\n\t\tif (!input.json) {\n\t\t\tlogger.info(message)\n\t\t}\n\n\t\tlet finalResult: DevServerResult = {\n\t\t\tstatus: 'started',\n\t\t\turl,\n\t\t\tport,\n\t\t\tmessage,\n\t\t}\n\n\t\t// Determine if TUI should be used:\n\t\t// - Only when TTY is detected on both stdout and stdin\n\t\t// - Disabled in JSON mode (JSON output goes to stdout)\n\t\tconst useTui = !input.json && process.stdout.isTTY === true && process.stdin.isTTY === true\n\n\t\tlet tui: DevServerTUI | undefined\n\t\tlet restartRequested = false\n\n\t\tif (useTui) {\n\t\t\ttui = new DevServerTUI({\n\t\t\t\turl,\n\t\t\t\tport,\n\t\t\t\tcontainerPort: dockerConfig?.containerPort,\n\t\t\t\tonQuit: (): void => {\n\t\t\t\t\t// Send SIGINT to self to trigger normal cleanup flow\n\t\t\t\t\tprocess.kill(process.pid, 'SIGINT')\n\t\t\t\t},\n\t\t\t\tonRestart: (): void => {\n\t\t\t\t\trestartRequested = true\n\t\t\t\t\ttui?.updateStatus('Restarting')\n\n\t\t\t\t\tif (dockerConfig) {\n\t\t\t\t\t\t// Docker: stop the container to trigger exit from runServerForeground\n\t\t\t\t\t\tconst containerName = DockerManager.buildContainerName(\n\t\t\t\t\t\t\tdockerConfig.identifier ?? ''\n\t\t\t\t\t\t)\n\t\t\t\t\t\tvoid execa('docker', ['stop', containerName], { reject: false })\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Native: find and terminate the process on the port\n\t\t\t\t\t\tconst processManager = new ProcessManager()\n\t\t\t\t\t\tvoid processManager.detectDevServer(port).then((processInfo) => {\n\t\t\t\t\t\t\tif (processInfo?.pid) {\n\t\t\t\t\t\t\t\tprocess.kill(processInfo.pid, 'SIGTERM')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t})\n\t\t\ttui.start()\n\t\t}\n\n\t\tconst onOutput = tui\n\t\t\t? (data: Buffer): void => { tui?.handleOutput(data) }\n\t\t\t: undefined\n\n\t\ttry {\n\t\t\tdo {\n\t\t\t\trestartRequested = false\n\n\t\t\t\t// This will block until user stops the server (Ctrl+C)\n\t\t\t\t// In JSON mode, redirect npm output to stderr so JSON can go to stdout\n\t\t\t\tconst processInfo = await this.devServerManager.runServerForeground(\n\t\t\t\t\tworktree.path,\n\t\t\t\t\tport,\n\t\t\t\t\t!!input.json,\n\t\t\t\t\t// Callback called immediately when process starts (for JSON output)\n\t\t\t\t\t(pid) => {\n\t\t\t\t\t\tif (input.json && pid) {\n\t\t\t\t\t\t\tfinalResult.pid = pid\n\t\t\t\t\t\t\tthis.outputJson(finalResult)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tenvOverrides,\n\t\t\t\t\tdockerConfig,\n\t\t\t\t\tonOutput\n\t\t\t\t)\n\n\t\t\t\tif (processInfo.pid) {\n\t\t\t\t\tfinalResult.pid = processInfo.pid\n\t\t\t\t}\n\n\t\t\t\tif (restartRequested) {\n\t\t\t\t\tlogger.info('Restarting dev server...')\n\t\t\t\t\ttui?.updateStatus('Running')\n\t\t\t\t}\n\t\t\t} while (restartRequested)\n\t\t} finally {\n\t\t\tif (tui) {\n\t\t\t\ttui.cleanup()\n\t\t\t}\n\t\t}\n\n\t\treturn finalResult\n\t}\n\n\t/**\n\t * Parse explicit identifier input\n\t */\n\tprivate async parseExplicitInput(identifier: string): Promise<ParsedDevServerInput> {\n\t\tconst parsed = await this.identifierParser.parseForPatternDetection(identifier)\n\n\t\t// Description type should never reach dev-server command\n\t\tif (parsed.type === 'description') {\n\t\t\tthrow new Error('Description input type is not supported in dev-server command')\n\t\t}\n\n\t\tconst result: ParsedDevServerInput = {\n\t\t\ttype: parsed.type,\n\t\t\toriginalInput: parsed.originalInput,\n\t\t\tautoDetected: false,\n\t\t}\n\n\t\tif (parsed.number !== undefined) {\n\t\t\tresult.number = parsed.number\n\t\t}\n\t\tif (parsed.branchName !== undefined) {\n\t\t\tresult.branchName = parsed.branchName\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Auto-detect identifier from current directory\n\t */\n\tprivate async autoDetectFromCurrentDirectory(): Promise<ParsedDevServerInput> {\n\t\tconst currentDir = path.basename(process.cwd())\n\n\t\t// Check for PR worktree pattern: _pr_N suffix\n\t\tconst prPattern = /_pr_(\\d+)$/\n\t\tconst prMatch = currentDir.match(prPattern)\n\n\t\tif (prMatch?.[1]) {\n\t\t\tconst prNumber = parseInt(prMatch[1], 10)\n\t\t\tlogger.debug(`Auto-detected PR #${prNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'pr',\n\t\t\t\tnumber: prNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Check for issue pattern in directory\n\t\tconst issueNumber = extractIssueNumber(currentDir)\n\n\t\tif (issueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${issueNumber} from directory: ${currentDir}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: issueNumber,\n\t\t\t\toriginalInput: currentDir,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Fallback: get current branch name\n\t\tconst repoInfo = await this.gitWorktreeManager.getRepoInfo()\n\t\tconst currentBranch = repoInfo.currentBranch\n\n\t\tif (!currentBranch) {\n\t\t\tthrow new Error(\n\t\t\t\t'Could not auto-detect identifier. Please provide an issue number, PR number, or branch name.\\n' +\n\t\t\t\t\t'Expected directory pattern: feat/issue-XX-description OR worktree with _pr_N suffix'\n\t\t\t)\n\t\t}\n\n\t\t// Try to extract issue from branch name\n\t\tconst branchIssueNumber = extractIssueNumber(currentBranch)\n\t\tif (branchIssueNumber !== null) {\n\t\t\tlogger.debug(`Auto-detected issue #${branchIssueNumber} from branch: ${currentBranch}`)\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: branchIssueNumber,\n\t\t\t\toriginalInput: currentBranch,\n\t\t\t\tautoDetected: true,\n\t\t\t}\n\t\t}\n\n\t\t// Last resort: use branch name\n\t\treturn {\n\t\t\ttype: 'branch',\n\t\t\tbranchName: currentBranch,\n\t\t\toriginalInput: currentBranch,\n\t\t\tautoDetected: true,\n\t\t}\n\t}\n\n\t/**\n\t * Find worktree for the given identifier\n\t */\n\tprivate async findWorktreeForIdentifier(parsed: ParsedDevServerInput): Promise<GitWorktree> {\n\t\tlet worktree: GitWorktree | null = null\n\n\t\tif (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForIssue(parsed.number)\n\t\t} else if (parsed.type === 'pr' && parsed.number !== undefined) {\n\t\t\tconst prNumber = typeof parsed.number === 'number' ? parsed.number : Number(parsed.number)\n\t\t\tif (isNaN(prNumber) || !isFinite(prNumber)) {\n\t\t\t\tthrow new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`)\n\t\t\t}\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForPR(prNumber, '')\n\t\t} else if (parsed.type === 'branch' && parsed.branchName) {\n\t\t\tworktree = await this.gitWorktreeManager.findWorktreeForBranch(\n\t\t\t\tparsed.branchName\n\t\t\t)\n\t\t}\n\n\t\tif (!worktree) {\n\t\t\tthrow new Error(\n\t\t\t\t`No worktree found for ${this.formatParsedInput(parsed)}. ` +\n\t\t\t\t\t`Run 'il start ${parsed.originalInput}' to create one.`\n\t\t\t)\n\t\t}\n\n\t\treturn worktree\n\t}\n\n\t/**\n\t * Format parsed input for display\n\t */\n\tprivate formatParsedInput(parsed: ParsedDevServerInput): string {\n\t\tconst autoLabel = parsed.autoDetected ? ' (auto-detected)' : ''\n\n\t\tif (parsed.type === 'issue') {\n\t\t\treturn `issue #${parsed.number}${autoLabel}`\n\t\t}\n\t\tif (parsed.type === 'pr') {\n\t\t\treturn `PR #${parsed.number}${autoLabel}`\n\t\t}\n\t\treturn `branch \"${parsed.branchName}\"${autoLabel}`\n\t}\n\n\t/**\n\t * Format loom identifier for ILOOM_LOOM env var\n\t */\n\tprivate formatLoomIdentifier(parsed: ParsedDevServerInput): string {\n\t\treturn parsed.originalInput\n\t}\n}\n","import { execa } from 'execa'\nimport { openBrowser } from '../utils/browser.js'\nimport { restoreTerminalState } from '../utils/terminal.js'\nimport { logger } from '../utils/logger.js'\n\n/**\n * ANSI escape sequences used for TUI rendering.\n */\nconst ESC = '\\x1b'\nconst CSI = `${ESC}[`\n\n/** Save cursor position */\nconst CURSOR_SAVE = `${ESC}7`\n/** Restore cursor position */\nconst CURSOR_RESTORE = `${ESC}8`\n/** Hide cursor */\nconst CURSOR_HIDE = `${CSI}?25l`\n/** Show cursor */\nconst CURSOR_SHOW = `${CSI}?25h`\n/** Clear from cursor to end of line */\nconst CLEAR_LINE = `${CSI}K`\n/** Clear entire screen and reset cursor to top-left */\nconst CLEAR_SCREEN = `${CSI}2J${CSI}H`\n/** Reset scroll region to full terminal */\nconst SCROLL_REGION_RESET = `${CSI}r`\n\n/** Move cursor to row,col (1-based) */\nfunction moveTo(row: number, col: number): string {\n\treturn `${CSI}${row};${col}H`\n}\n\n/** Set scroll region to rows top..bottom (1-based, inclusive) */\nfunction setScrollRegion(top: number, bottom: number): string {\n\treturn `${CSI}${top};${bottom}r`\n}\n\nexport type DevServerStatus = 'Running' | 'Stopped' | 'Restarting'\n\nexport interface DevServerTUIOptions {\n\turl: string\n\tport: number\n\tcontainerPort?: number | undefined\n\tstdout?: NodeJS.WriteStream | undefined\n\tstdin?: NodeJS.ReadStream | undefined\n\tonQuit?: (() => void) | undefined\n\tonRestart?: (() => void) | undefined\n}\n\n/**\n * Height of the status bar area (top border + content + bottom border + hint line).\n */\nconst STATUS_BAR_HEIGHT = 4\n\n/**\n * DevServerTUI - Lightweight terminal UI for dev server.\n *\n * Uses ANSI escape sequences to set a scroll region that restricts output\n * to the upper portion of the terminal, keeping a fixed status bar at the\n * bottom showing the external URL, server status, and port mapping.\n *\n * Keyboard shortcuts:\n * o - open URL in browser\n * c - copy URL to clipboard\n * q - quit (stop container and exit)\n * r - restart (if callback provided)\n */\nexport class DevServerTUI {\n\tprivate readonly url: string\n\tprivate readonly port: number\n\tprivate readonly containerPort: number | undefined\n\tprivate readonly stdout: NodeJS.WriteStream\n\tprivate readonly stdin: NodeJS.ReadStream\n\tprivate readonly onQuit: (() => void) | undefined\n\tprivate readonly onRestart: (() => void) | undefined\n\tprivate status: DevServerStatus = 'Running'\n\tprivate started = false\n\tprivate cleanedUp = false\n\tprivate readonly onData: (data: Buffer) => void\n\tprivate readonly onResize: () => void\n\tprivate readonly onProcessExit: () => void\n\n\tconstructor(options: DevServerTUIOptions) {\n\t\tthis.url = options.url\n\t\tthis.port = options.port\n\t\tthis.containerPort = options.containerPort\n\t\tthis.stdout = options.stdout ?? process.stdout\n\t\tthis.stdin = options.stdin ?? process.stdin\n\t\tthis.onQuit = options.onQuit\n\t\tthis.onRestart = options.onRestart\n\n\t\t// Bind handlers so they can be removed later\n\t\tthis.onData = (data: Buffer): void => this.handleKeypress(data)\n\t\tthis.onResize = (): void => this.handleResize()\n\t\tthis.onProcessExit = (): void => this.cleanup()\n\t}\n\n\t/**\n\t * Start the TUI - sets up scroll region, renders status bar, starts keyboard listener.\n\t */\n\tstart(): void {\n\t\tif (this.started) return\n\t\tthis.started = true\n\n\t\tconst rows = this.stdout.rows ?? 24\n\n\t\t// Hide cursor during TUI operation\n\t\tthis.stdout.write(CURSOR_HIDE)\n\n\t\t// Clear the screen so previous output (build logs, startup messages) doesn't\n\t\t// bleed through the scroll region and create a confusing mix of old and new text\n\t\tthis.stdout.write(CLEAR_SCREEN)\n\n\t\t// Set scroll region: top of terminal to (total rows - status bar height)\n\t\tconst scrollBottom = Math.max(1, rows - STATUS_BAR_HEIGHT)\n\t\tthis.stdout.write(setScrollRegion(1, scrollBottom))\n\n\t\t// Move cursor to top-left of scroll region\n\t\tthis.stdout.write(moveTo(1, 1))\n\n\t\t// Render status bar in the fixed area below scroll region\n\t\tthis.renderStatusBar()\n\n\t\t// Start keyboard listener (raw mode)\n\t\tif (this.stdin.isTTY && typeof this.stdin.setRawMode === 'function') {\n\t\t\tthis.stdin.setRawMode(true)\n\t\t\tthis.stdin.resume()\n\t\t\tthis.stdin.on('data', this.onData)\n\t\t}\n\n\t\t// Listen for terminal resize\n\t\tthis.stdout.on('resize', this.onResize)\n\n\t\t// Ensure terminal state is restored on unexpected exit (uncaught exceptions, etc.)\n\t\tprocess.on('exit', this.onProcessExit)\n\t}\n\n\t/**\n\t * Write server output into the scroll region.\n\t * The scroll region constrains the cursor naturally, so output stays\n\t * above the status bar without explicit cursor repositioning.\n\t */\n\thandleOutput(data: Buffer | string): void {\n\t\tif (!this.started || this.cleanedUp) return\n\n\t\tthis.stdout.write(data.toString())\n\t}\n\n\t/**\n\t * Update the status displayed in the status bar.\n\t */\n\tupdateStatus(status: DevServerStatus): void {\n\t\tthis.status = status\n\t\tif (this.started && !this.cleanedUp) {\n\t\t\tthis.renderStatusBar()\n\t\t}\n\t}\n\n\t/**\n\t * Render the status bar in the fixed area below the scroll region.\n\t */\n\tprivate renderStatusBar(): void {\n\t\tconst rows = this.stdout.rows ?? 24\n\t\tconst cols = this.stdout.columns ?? 80\n\n\t\t// Guard: terminal too small for status bar\n\t\tif (rows < STATUS_BAR_HEIGHT + 2) return\n\n\t\t// Status bar starts at row (rows - STATUS_BAR_HEIGHT + 1)\n\t\tconst barStartRow = rows - STATUS_BAR_HEIGHT + 1\n\n\t\t// Build content segments\n\t\tconst urlSegment = ` ${this.url} `\n\t\tconst statusIcon = this.status === 'Running' ? '\\u25A0' : this.status === 'Stopped' ? '\\u25A1' : '\\u25C6'\n\t\tconst statusSegment = ` ${statusIcon} ${this.status} `\n\t\tconst portSegment = this.containerPort\n\t\t\t? ` Port ${this.containerPort} \\u2192 ${this.port} `\n\t\t\t: ` Port ${this.port} `\n\n\t\t// Build content line with separators\n\t\tconst contentParts = `\\u2502${urlSegment}\\u2502${statusSegment}\\u2502${portSegment}\\u2502`\n\t\t// Pad content to fill width\n\t\tconst contentLine = contentParts.length < cols\n\t\t\t? contentParts + ' '.repeat(cols - contentParts.length)\n\t\t\t: contentParts.substring(0, cols)\n\n\t\t// Horizontal border line\n\t\tconst innerWidth = Math.max(0, cols - 2)\n\t\tconst topBorder = `\\u250C${'\\u2500'.repeat(innerWidth)}\\u2510`\n\t\tconst bottomBorder = `\\u2514${'\\u2500'.repeat(innerWidth)}\\u2518`\n\n\t\t// Hint line showing keyboard shortcuts\n\t\tconst hintLine = ' [o] Open [c] Copy URL [r] Restart [q] Quit'\n\t\tconst paddedHint = hintLine.length < cols\n\t\t\t? hintLine + ' '.repeat(cols - hintLine.length)\n\t\t\t: hintLine.substring(0, cols)\n\n\t\t// Save cursor, write status bar, restore cursor\n\t\tthis.stdout.write(CURSOR_SAVE)\n\n\t\t// Row 1: top border\n\t\tthis.stdout.write(moveTo(barStartRow, 1) + CLEAR_LINE + topBorder)\n\t\t// Row 2: content\n\t\tthis.stdout.write(moveTo(barStartRow + 1, 1) + CLEAR_LINE + contentLine)\n\t\t// Row 3: bottom border\n\t\tthis.stdout.write(moveTo(barStartRow + 2, 1) + CLEAR_LINE + bottomBorder)\n\t\t// Row 4: hint line\n\t\tthis.stdout.write(moveTo(barStartRow + 3, 1) + CLEAR_LINE + paddedHint)\n\n\t\tthis.stdout.write(CURSOR_RESTORE)\n\t}\n\n\t/**\n\t * Handle keyboard input.\n\t */\n\tprivate handleKeypress(data: Buffer): void {\n\t\tconst key = data.toString('utf8')\n\n\t\tswitch (key) {\n\t\t\tcase 'o':\n\t\t\tcase 'O':\n\t\t\t\tvoid openBrowser(this.url).catch((err: unknown) => {\n\t\t\t\t\tlogger.warn(`Failed to open browser: ${err instanceof Error ? err.message : 'Unknown error'}`)\n\t\t\t\t})\n\t\t\t\tbreak\n\n\t\t\tcase 'c':\n\t\t\tcase 'C':\n\t\t\t\tvoid this.copyToClipboard(this.url).catch((err: unknown) => {\n\t\t\t\t\tlogger.warn(`Failed to copy to clipboard: ${err instanceof Error ? err.message : 'Unknown error'}`)\n\t\t\t\t})\n\t\t\t\tbreak\n\n\t\t\tcase 'q':\n\t\t\tcase 'Q':\n\t\t\tcase '\\x03': // Ctrl+C\n\t\t\t\tif (this.onQuit) {\n\t\t\t\t\tthis.onQuit()\n\t\t\t\t}\n\t\t\t\tbreak\n\n\t\t\tcase 'r':\n\t\t\tcase 'R':\n\t\t\t\tif (this.onRestart) {\n\t\t\t\t\tthis.onRestart()\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\t/**\n\t * Copy text to clipboard using platform-specific commands.\n\t */\n\tprivate async copyToClipboard(text: string): Promise<void> {\n\t\tconst platform = process.platform\n\n\t\tlet command: string\n\t\tlet args: string[]\n\n\t\tif (platform === 'darwin') {\n\t\t\tcommand = 'pbcopy'\n\t\t\targs = []\n\t\t} else if (platform === 'win32') {\n\t\t\tcommand = 'clip'\n\t\t\targs = []\n\t\t} else {\n\t\t\t// Linux\n\t\t\tcommand = 'xclip'\n\t\t\targs = ['-selection', 'clipboard']\n\t\t}\n\n\t\tawait execa(command, args, { input: text })\n\t}\n\n\t/**\n\t * Handle terminal resize - re-establish scroll region and re-render status bar.\n\t */\n\tprivate handleResize(): void {\n\t\tif (!this.started || this.cleanedUp) return\n\n\t\tconst rows = this.stdout.rows ?? 24\n\n\t\t// Guard: terminal too small for status bar\n\t\tif (rows < STATUS_BAR_HEIGHT + 2) return\n\n\t\tconst scrollBottom = Math.max(1, rows - STATUS_BAR_HEIGHT)\n\n\t\t// Re-establish scroll region for new size\n\t\tthis.stdout.write(setScrollRegion(1, scrollBottom))\n\n\t\t// Re-render status bar at new position\n\t\tthis.renderStatusBar()\n\n\t\t// Move cursor back into scroll region\n\t\tthis.stdout.write(moveTo(scrollBottom, 1))\n\t}\n\n\t/**\n\t * Clean up: restore full scroll region, disable raw mode, restore terminal.\n\t */\n\tcleanup(): void {\n\t\tif (this.cleanedUp) return\n\t\tthis.cleanedUp = true\n\n\t\t// Remove event listeners\n\t\tif (this.stdin.isTTY && typeof this.stdin.setRawMode === 'function') {\n\t\t\tthis.stdin.removeListener('data', this.onData)\n\t\t\tthis.stdin.setRawMode(false)\n\t\t\tthis.stdin.pause()\n\t\t}\n\n\t\tthis.stdout.removeListener('resize', this.onResize)\n\t\tprocess.removeListener('exit', this.onProcessExit)\n\n\t\t// Reset scroll region to full terminal\n\t\tthis.stdout.write(SCROLL_REGION_RESET)\n\n\t\t// Show cursor\n\t\tthis.stdout.write(CURSOR_SHOW)\n\n\t\t// Move cursor to bottom of terminal\n\t\tconst rows = this.stdout.rows ?? 24\n\t\tthis.stdout.write(moveTo(rows, 1))\n\t\tthis.stdout.write('\\n')\n\n\t\t// Restore terminal state\n\t\trestoreTerminalState()\n\t}\n}\n"],"mappings":"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","names":["execa","identifier","message","execa"]}
@@ -8,13 +8,13 @@ import {
8
8
  import "./chunk-CQHHEW2M.js";
9
9
  import {
10
10
  AgentManager
11
- } from "./chunk-QNRXRSKC.js";
11
+ } from "./chunk-RP6MHV24.js";
12
12
  import "./chunk-WEBMMJKL.js";
13
- import "./chunk-MRPIDNZU.js";
14
13
  import {
15
14
  ProjectCapabilityDetector
16
15
  } from "./chunk-772N5WCA.js";
17
16
  import "./chunk-K3QGG4O2.js";
17
+ import "./chunk-LDE6VNG5.js";
18
18
  import {
19
19
  GitHubService
20
20
  } from "./chunk-D4Q7T5KD.js";
@@ -25,7 +25,7 @@ import {
25
25
  } from "./chunk-DDHWZNGL.js";
26
26
  import {
27
27
  SettingsManager
28
- } from "./chunk-F5NKWLMQ.js";
28
+ } from "./chunk-MNPKEWBQ.js";
29
29
  import "./chunk-FTYWGQFM.js";
30
30
  import {
31
31
  logger
@@ -167,4 +167,4 @@ ${userBody}`;
167
167
  export {
168
168
  FeedbackCommand
169
169
  };
170
- //# sourceMappingURL=feedback-2LWXKLQZ.js.map
170
+ //# sourceMappingURL=feedback-M43SGGK2.js.map
@@ -34,8 +34,8 @@ import {
34
34
  pushBranchToRemote,
35
35
  removePlaceholderCommitFromHead,
36
36
  removePlaceholderCommitFromHistory
37
- } from "./chunk-KGOBNC5A.js";
38
- import "./chunk-F5NKWLMQ.js";
37
+ } from "./chunk-5W44AI63.js";
38
+ import "./chunk-MNPKEWBQ.js";
39
39
  import "./chunk-XIVLGWUX.js";
40
40
  import "./chunk-FTYWGQFM.js";
41
41
  import "./chunk-VRPPI6GU.js";
@@ -75,4 +75,4 @@ export {
75
75
  removePlaceholderCommitFromHead,
76
76
  removePlaceholderCommitFromHistory
77
77
  };
78
- //# sourceMappingURL=git-IS7AV3ED.js.map
78
+ //# sourceMappingURL=git-ZTMT6OAI.js.map
@@ -2,27 +2,27 @@
2
2
  import {
3
3
  IgniteCommand,
4
4
  WorktreeValidationError
5
- } from "./chunk-G2DGDCDP.js";
6
- import "./chunk-C2BVNJW5.js";
5
+ } from "./chunk-Y2JHYPMX.js";
6
+ import "./chunk-OIJNBFMP.js";
7
7
  import "./chunk-7UBEHQTP.js";
8
- import "./chunk-ERMEYFT6.js";
8
+ import "./chunk-YVNG35OW.js";
9
9
  import "./chunk-MY2Q3FJ3.js";
10
10
  import "./chunk-EGNUOALL.js";
11
11
  import "./chunk-CQHHEW2M.js";
12
- import "./chunk-QNRXRSKC.js";
13
- import "./chunk-ZEFTWM5Z.js";
12
+ import "./chunk-RP6MHV24.js";
13
+ import "./chunk-VUIPDX3T.js";
14
14
  import "./chunk-4232AHNQ.js";
15
- import "./chunk-PPQ5LV7U.js";
16
- import "./chunk-MRPIDNZU.js";
15
+ import "./chunk-D6FU4DLN.js";
16
+ import "./chunk-LDE6VNG5.js";
17
17
  import "./chunk-GYCR2LOU.js";
18
- import "./chunk-GPBX2BY2.js";
18
+ import "./chunk-ZWXJ7G2C.js";
19
19
  import "./chunk-DMSL5BAP.js";
20
20
  import "./chunk-D4Q7T5KD.js";
21
21
  import "./chunk-KV4NU3RP.js";
22
22
  import "./chunk-NPVA65KS.js";
23
23
  import "./chunk-DDHWZNGL.js";
24
- import "./chunk-KGOBNC5A.js";
25
- import "./chunk-F5NKWLMQ.js";
24
+ import "./chunk-5W44AI63.js";
25
+ import "./chunk-MNPKEWBQ.js";
26
26
  import "./chunk-XIVLGWUX.js";
27
27
  import "./chunk-FTYWGQFM.js";
28
28
  import "./chunk-VRPPI6GU.js";
@@ -30,4 +30,4 @@ export {
30
30
  IgniteCommand,
31
31
  WorktreeValidationError
32
32
  };
33
- //# sourceMappingURL=ignite-VQDJQ37S.js.map
33
+ //# sourceMappingURL=ignite-GUYKYC5G.js.map
package/dist/index.d.ts CHANGED
@@ -335,6 +335,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
335
335
  dockerBuildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
336
336
  dockerBuildSecrets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
337
337
  dockerRunArgs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
338
+ dockerRunEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
338
339
  }, "strip", z.ZodTypeAny, {
339
340
  protocol: "http" | "https";
340
341
  devServer: "docker" | "process";
@@ -344,6 +345,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
344
345
  dockerBuildArgs?: Record<string, string> | undefined;
345
346
  dockerBuildSecrets?: Record<string, string> | undefined;
346
347
  dockerRunArgs?: string[] | undefined;
348
+ dockerRunEnv?: Record<string, string> | undefined;
347
349
  }, {
348
350
  basePort?: number | undefined;
349
351
  protocol?: "http" | "https" | undefined;
@@ -353,6 +355,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
353
355
  dockerBuildArgs?: Record<string, string> | undefined;
354
356
  dockerBuildSecrets?: Record<string, string> | undefined;
355
357
  dockerRunArgs?: string[] | undefined;
358
+ dockerRunEnv?: Record<string, string> | undefined;
356
359
  }>>;
357
360
  database: z.ZodOptional<z.ZodObject<{
358
361
  databaseUrlEnvVarName: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -371,6 +374,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
371
374
  dockerBuildArgs?: Record<string, string> | undefined;
372
375
  dockerBuildSecrets?: Record<string, string> | undefined;
373
376
  dockerRunArgs?: string[] | undefined;
377
+ dockerRunEnv?: Record<string, string> | undefined;
374
378
  } | undefined;
375
379
  database?: {
376
380
  databaseUrlEnvVarName: string;
@@ -385,6 +389,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
385
389
  dockerBuildArgs?: Record<string, string> | undefined;
386
390
  dockerBuildSecrets?: Record<string, string> | undefined;
387
391
  dockerRunArgs?: string[] | undefined;
392
+ dockerRunEnv?: Record<string, string> | undefined;
388
393
  } | undefined;
389
394
  database?: {
390
395
  databaseUrlEnvVarName?: string | undefined;
@@ -397,16 +402,19 @@ declare const IloomSettingsSchema: z.ZodObject<{
397
402
  containerPort: z.ZodOptional<z.ZodNumber>;
398
403
  buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
399
404
  runArgs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
405
+ runEnv: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
400
406
  }, "strip", z.ZodTypeAny, {
401
407
  dockerFile: string;
402
408
  containerPort?: number | undefined;
403
409
  buildArgs?: Record<string, string> | undefined;
404
410
  runArgs?: string[] | undefined;
411
+ runEnv?: Record<string, string> | undefined;
405
412
  }, {
406
413
  dockerFile?: string | undefined;
407
414
  containerPort?: number | undefined;
408
415
  buildArgs?: Record<string, string> | undefined;
409
416
  runArgs?: string[] | undefined;
417
+ runEnv?: Record<string, string> | undefined;
410
418
  }>>;
411
419
  }, "strip", z.ZodTypeAny, {
412
420
  mode: "docker";
@@ -415,6 +423,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
415
423
  containerPort?: number | undefined;
416
424
  buildArgs?: Record<string, string> | undefined;
417
425
  runArgs?: string[] | undefined;
426
+ runEnv?: Record<string, string> | undefined;
418
427
  } | undefined;
419
428
  }, {
420
429
  docker?: {
@@ -422,6 +431,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
422
431
  containerPort?: number | undefined;
423
432
  buildArgs?: Record<string, string> | undefined;
424
433
  runArgs?: string[] | undefined;
434
+ runEnv?: Record<string, string> | undefined;
425
435
  } | undefined;
426
436
  mode?: "docker" | undefined;
427
437
  }>>;
@@ -651,6 +661,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
651
661
  containerPort?: number | undefined;
652
662
  buildArgs?: Record<string, string> | undefined;
653
663
  runArgs?: string[] | undefined;
664
+ runEnv?: Record<string, string> | undefined;
654
665
  } | undefined;
655
666
  } | undefined;
656
667
  mainBranch?: string | undefined;
@@ -707,6 +718,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
707
718
  dockerBuildArgs?: Record<string, string> | undefined;
708
719
  dockerBuildSecrets?: Record<string, string> | undefined;
709
720
  dockerRunArgs?: string[] | undefined;
721
+ dockerRunEnv?: Record<string, string> | undefined;
710
722
  } | undefined;
711
723
  database?: {
712
724
  databaseUrlEnvVarName: string;
@@ -782,6 +794,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
782
794
  containerPort?: number | undefined;
783
795
  buildArgs?: Record<string, string> | undefined;
784
796
  runArgs?: string[] | undefined;
797
+ runEnv?: Record<string, string> | undefined;
785
798
  } | undefined;
786
799
  mode?: "docker" | undefined;
787
800
  } | undefined;
@@ -840,6 +853,7 @@ declare const IloomSettingsSchema: z.ZodObject<{
840
853
  dockerBuildArgs?: Record<string, string> | undefined;
841
854
  dockerBuildSecrets?: Record<string, string> | undefined;
842
855
  dockerRunArgs?: string[] | undefined;
856
+ dockerRunEnv?: Record<string, string> | undefined;
843
857
  } | undefined;
844
858
  database?: {
845
859
  databaseUrlEnvVarName?: string | undefined;
@@ -1505,6 +1519,11 @@ interface AutoSwarmCompletedProperties {
1505
1519
  phase_reached: 'plan' | 'start' | 'spin';
1506
1520
  fallback_to_normal: boolean;
1507
1521
  }
1522
+ interface EpicReportGeneratedProperties {
1523
+ total_children: number;
1524
+ succeeded: number;
1525
+ failed: number;
1526
+ }
1508
1527
  interface DevServerStartedEvent {
1509
1528
  /** Execution mode for the dev server */
1510
1529
  mode: 'docker' | 'process';
@@ -1549,6 +1568,7 @@ interface TelemetryEventMap {
1549
1568
  'init.completed': InitCompletedProperties;
1550
1569
  'auto_swarm.started': AutoSwarmStartedProperties;
1551
1570
  'auto_swarm.completed': AutoSwarmCompletedProperties;
1571
+ 'epic.report_generated': EpicReportGeneratedProperties;
1552
1572
  'devServer.started': DevServerStartedEvent;
1553
1573
  'devServer.stopped': DevServerStoppedEvent;
1554
1574
  }
@@ -2082,6 +2102,7 @@ declare class DatabaseManager {
2082
2102
  private hasDatabaseUrlInEnv;
2083
2103
  }
2084
2104
 
2105
+ type TemplateName = 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan' | 'swarm-orchestrator' | 'epic-report';
2085
2106
  interface TemplateVariables {
2086
2107
  ISSUE_NUMBER?: string | number;
2087
2108
  PR_NUMBER?: number;
@@ -2178,6 +2199,12 @@ interface TemplateVariables {
2178
2199
  IS_GITHUB_TRACKER?: boolean;
2179
2200
  VCS_PROVIDER?: string;
2180
2201
  IS_GITHUB_VCS?: boolean;
2202
+ EPIC_NUMBER?: string;
2203
+ EPIC_TITLE?: string;
2204
+ CHILD_DATA?: string;
2205
+ TOTAL_CHILDREN?: string;
2206
+ TOTAL_SUCCEEDED?: string;
2207
+ TOTAL_FAILED?: string;
2181
2208
  }
2182
2209
  declare class PromptTemplateManager {
2183
2210
  private templateDir;
@@ -2185,7 +2212,7 @@ declare class PromptTemplateManager {
2185
2212
  /**
2186
2213
  * Load a template file by name
2187
2214
  */
2188
- loadTemplate(templateName: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan' | 'swarm-orchestrator'): Promise<string>;
2215
+ loadTemplate(templateName: TemplateName): Promise<string>;
2189
2216
  /**
2190
2217
  * Substitute variables in a template string using Handlebars
2191
2218
  */
@@ -2193,7 +2220,7 @@ declare class PromptTemplateManager {
2193
2220
  /**
2194
2221
  * Get a fully processed prompt for a workflow type
2195
2222
  */
2196
- getPrompt(type: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan' | 'swarm-orchestrator', variables: TemplateVariables): Promise<string>;
2223
+ getPrompt(type: TemplateName, variables: TemplateVariables): Promise<string>;
2197
2224
  }
2198
2225
 
2199
2226
  interface ClaudeWorkflowOptions {
@@ -3017,4 +3044,4 @@ declare class TableFormatter {
3017
3044
  static previewFormatting(headers: string[], options?: TableFormatterOptions): string;
3018
3045
  }
3019
3046
 
3020
- export { type AddIssueOptions, type AddIssueResult, type AutoSwarmCompletedProperties, type AutoSwarmStartedProperties, type BatchCleanupResult, type BranchCleanupTarget, type BranchDeleteOptions, type BranchGenerationOptions, type BranchNameStrategy, type Capability, type ClaudeContext, ClaudeContextManager, type CleanupOptions, type CleanupResult, type CliInstalledProperties, type CliUpgradedProperties, type ColorData, type CommitOptions, type ComplexityOverride, type Config, type ContributeStartedProperties, type CreateLoomInput, type DatabaseDeletionResult, DatabaseManager, type DatabaseProvider, type DemoCompletedProperties, type DemoStartedProperties, type DevServerStartedEvent, type DevServerStoppedEvent, type EnhanceOptions, type EnhanceResult, type EnvFileOptions, type EnvOperationResult, type EnvVariable, EnvironmentManager, type EpicPlannedProperties, type ErrorOccurredProperties, type FeedbackOptions, type FinishOptions, type FinishResult, GitCommandError, GitHubService, type GitStatus, type GitWorktree, GitWorktreeManager, type InitCompletedProperties, type InitStartedProperties, type InstallationMethod, type Issue, type IssueTracker, IssueTrackerFactory, type IssueTrackerInputDetection, type IssueTrackerProviderType, JiraWikiSanitizer, type LaunchMode, LinearMarkupConverter, type ListOptions, type Logger, type LoggerOptions, type Loom, type LoomAbandonedProperties, type LoomCreatedProperties, type LoomFinishedProperties, type LoomSummary, type MergeOptions, type MergeResult, type MockOptions, type OneShotMode, type OperationResult, PLACEHOLDER_COMMIT_PREFIX, type PRWorktreePattern, type Platform, type PortAssignmentOptions, type ProcessInfo, type ProjectCapability, type PullRequest, type RebaseOutcome, type RebaseResult, type RemoteBranchStatus, type ResourceCleanupOptions, type RgbColor, type SafetyCheck, type SessionStartedProperties, type StartOptions, type StartResult, type SummaryResult, type SwarmChildCompletedProperties, type SwarmCompletedProperties, type SwarmStartedProperties, TableFormatter, type TableFormatterOptions, type TableGenerationOptions, type TelemetryConfig, type TelemetryEventMap, type TelemetryEventName, type UpdateCheckCache, type UpdateCheckResult, UserAbortedCommitError, type ValidationOptions, type ValidationResult, type ValidationStepResult, type Workspace, type WorkspaceInput, WorkspaceManager, type WorkspaceSummary, type Worktree, type WorktreeCleanupOptions, type WorktreeCreateOptions, type WorktreeListOptions, type WorktreeOperationResult, type WorktreeStatus, type WorktreeValidation, branchExists, checkRemoteBranchStatus, createLogger, createStderrLogger, ensureRepositoryHasCommits, executeGitCommand, extractIssueNumber, extractPRNumber, fetchOrigin, findAllBranchesForIssue, findMainWorktreePath, findMainWorktreePathWithSettings, findPlaceholderCommitSha, findWorktreeForBranch, generateWorktreePath, getCurrentBranch, getDefaultBranch, getMergeTargetBranch, getRepoRoot, getThemeMode, getWorktreeRoot, hasUncommittedChanges, isBranchMergedIntoMain, isEmptyRepository, isFileGitignored, isFileTrackedByGit, isPRBranch, isPlaceholderCommit, isRemoteBranchUpToDate, isValidGitRepo, isWorktreePath, logger, parseWorktreeList, pushBranchToRemote, removePlaceholderCommitFromHead, removePlaceholderCommitFromHistory, setThemeMode };
3047
+ export { type AddIssueOptions, type AddIssueResult, type AutoSwarmCompletedProperties, type AutoSwarmStartedProperties, type BatchCleanupResult, type BranchCleanupTarget, type BranchDeleteOptions, type BranchGenerationOptions, type BranchNameStrategy, type Capability, type ClaudeContext, ClaudeContextManager, type CleanupOptions, type CleanupResult, type CliInstalledProperties, type CliUpgradedProperties, type ColorData, type CommitOptions, type ComplexityOverride, type Config, type ContributeStartedProperties, type CreateLoomInput, type DatabaseDeletionResult, DatabaseManager, type DatabaseProvider, type DemoCompletedProperties, type DemoStartedProperties, type DevServerStartedEvent, type DevServerStoppedEvent, type EnhanceOptions, type EnhanceResult, type EnvFileOptions, type EnvOperationResult, type EnvVariable, EnvironmentManager, type EpicPlannedProperties, type EpicReportGeneratedProperties, type ErrorOccurredProperties, type FeedbackOptions, type FinishOptions, type FinishResult, GitCommandError, GitHubService, type GitStatus, type GitWorktree, GitWorktreeManager, type InitCompletedProperties, type InitStartedProperties, type InstallationMethod, type Issue, type IssueTracker, IssueTrackerFactory, type IssueTrackerInputDetection, type IssueTrackerProviderType, JiraWikiSanitizer, type LaunchMode, LinearMarkupConverter, type ListOptions, type Logger, type LoggerOptions, type Loom, type LoomAbandonedProperties, type LoomCreatedProperties, type LoomFinishedProperties, type LoomSummary, type MergeOptions, type MergeResult, type MockOptions, type OneShotMode, type OperationResult, PLACEHOLDER_COMMIT_PREFIX, type PRWorktreePattern, type Platform, type PortAssignmentOptions, type ProcessInfo, type ProjectCapability, type PullRequest, type RebaseOutcome, type RebaseResult, type RemoteBranchStatus, type ResourceCleanupOptions, type RgbColor, type SafetyCheck, type SessionStartedProperties, type StartOptions, type StartResult, type SummaryResult, type SwarmChildCompletedProperties, type SwarmCompletedProperties, type SwarmStartedProperties, TableFormatter, type TableFormatterOptions, type TableGenerationOptions, type TelemetryConfig, type TelemetryEventMap, type TelemetryEventName, type UpdateCheckCache, type UpdateCheckResult, UserAbortedCommitError, type ValidationOptions, type ValidationResult, type ValidationStepResult, type Workspace, type WorkspaceInput, WorkspaceManager, type WorkspaceSummary, type Worktree, type WorktreeCleanupOptions, type WorktreeCreateOptions, type WorktreeListOptions, type WorktreeOperationResult, type WorktreeStatus, type WorktreeValidation, branchExists, checkRemoteBranchStatus, createLogger, createStderrLogger, ensureRepositoryHasCommits, executeGitCommand, extractIssueNumber, extractPRNumber, fetchOrigin, findAllBranchesForIssue, findMainWorktreePath, findMainWorktreePathWithSettings, findPlaceholderCommitSha, findWorktreeForBranch, generateWorktreePath, getCurrentBranch, getDefaultBranch, getMergeTargetBranch, getRepoRoot, getThemeMode, getWorktreeRoot, hasUncommittedChanges, isBranchMergedIntoMain, isEmptyRepository, isFileGitignored, isFileTrackedByGit, isPRBranch, isPlaceholderCommit, isRemoteBranchUpToDate, isValidGitRepo, isWorktreePath, logger, parseWorktreeList, pushBranchToRemote, removePlaceholderCommitFromHead, removePlaceholderCommitFromHistory, setThemeMode };
package/dist/index.js CHANGED
@@ -1113,7 +1113,8 @@ var init_SettingsManager = __esm({
1113
1113
  containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
1114
1114
  dockerBuildArgs: z.record(z.string()).optional().describe('Build arguments to pass to docker build (e.g., {"NODE_ENV": "development"})'),
1115
1115
  dockerBuildSecrets: z.record(z.string()).optional().describe('Secret files to mount during docker build via --secret (e.g., {"npmrc": "~/.npmrc"}). Keys are secret IDs, values are source file paths.'),
1116
- dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)')
1116
+ dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)'),
1117
+ dockerRunEnv: z.record(z.string()).optional().describe('Environment variables to pass to docker run (e.g., {"NODE_ENV": "development", "DEBUG": "true"})')
1117
1118
  }).optional().describe('Web dev server settings. To declare a project as a web project, add "web" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),
1118
1119
  database: z.object({
1119
1120
  databaseUrlEnvVarName: z.string().min(1, "Database URL variable name cannot be empty").regex(/^[A-Z_][A-Z0-9_]*$/, "Must be valid env var name (uppercase, underscores)").optional().default("DATABASE_URL").describe("Name of environment variable for database connection URL")
@@ -1128,7 +1129,8 @@ var init_SettingsManager = __esm({
1128
1129
  containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
1129
1130
  dockerBuildArgs: z.record(z.string()).optional().describe('Build arguments to pass to docker build (e.g., {"NODE_ENV": "development"})'),
1130
1131
  dockerBuildSecrets: z.record(z.string()).optional().describe('Secret files to mount during docker build via --secret (e.g., {"npmrc": "~/.npmrc"}). Keys are secret IDs, values are source file paths.'),
1131
- dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)')
1132
+ dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)'),
1133
+ dockerRunEnv: z.record(z.string()).optional().describe('Environment variables to pass to docker run (e.g., {"NODE_ENV": "development", "DEBUG": "true"})')
1132
1134
  }).optional().describe('Web dev server settings. To declare a project as a web project, add "web" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),
1133
1135
  database: z.object({
1134
1136
  databaseUrlEnvVarName: z.string().min(1, "Database URL variable name cannot be empty").regex(/^[A-Z_][A-Z0-9_]*$/, "Must be valid env var name (uppercase, underscores)").optional().describe("Name of environment variable for database connection URL")
@@ -1150,7 +1152,8 @@ var init_SettingsManager = __esm({
1150
1152
  ).describe("Path to Dockerfile relative to worktree root"),
1151
1153
  containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
1152
1154
  buildArgs: z.record(z.string(), z.string()).optional().describe("Build arguments to pass to docker build"),
1153
- runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run")
1155
+ runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run"),
1156
+ runEnv: z.record(z.string(), z.string()).optional().describe("Environment variables to pass to docker run")
1154
1157
  }).optional()
1155
1158
  });
1156
1159
  DevServerSettingsSchemaNoDefaults = z.object({
@@ -1170,7 +1173,8 @@ var init_SettingsManager = __esm({
1170
1173
  ).describe("Path to Dockerfile relative to worktree root"),
1171
1174
  containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
1172
1175
  buildArgs: z.record(z.string(), z.string()).optional().describe("Build arguments to pass to docker build"),
1173
- runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run")
1176
+ runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run"),
1177
+ runEnv: z.record(z.string(), z.string()).optional().describe("Environment variables to pass to docker run")
1174
1178
  }).optional()
1175
1179
  });
1176
1180
  NeonSettingsSchema = z.object({