@iloom/cli 0.5.1 → 0.5.2

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 (169) hide show
  1. package/dist/{BranchNamingService-GCCWB3LK.js → BranchNamingService-B5PVRR7F.js} +4 -4
  2. package/dist/ClaudeContextManager-PQ46VILL.js +14 -0
  3. package/dist/ClaudeService-6OMO552H.js +13 -0
  4. package/dist/GitHubService-S2OGUTDR.js +12 -0
  5. package/dist/{LoomLauncher-JNWBMHES.js → LoomLauncher-ZHDTPKED.js} +13 -16
  6. package/dist/{LoomLauncher-JNWBMHES.js.map → LoomLauncher-ZHDTPKED.js.map} +1 -1
  7. package/dist/MetadataManager-DFI73J3G.js +10 -0
  8. package/dist/PRManager-OCSB2HPT.js +14 -0
  9. package/dist/PromptTemplateManager-5GNF7FCP.js +9 -0
  10. package/dist/{SettingsManager-XPR4TEQL.js → SettingsManager-CNYBGXDT.js} +3 -3
  11. package/dist/SettingsMigrationManager-KZKDG66H.js +10 -0
  12. package/dist/{chunk-OEGECBFS.js → chunk-3PT7RKL5.js} +4 -4
  13. package/dist/{chunk-WUQQNE63.js → chunk-433MOLAU.js} +44 -7
  14. package/dist/chunk-433MOLAU.js.map +1 -0
  15. package/dist/{chunk-LN4H3A6A.js → chunk-53OMUNUN.js} +5 -5
  16. package/dist/{chunk-THF25ICZ.js → chunk-5F6IWWRS.js} +2 -2
  17. package/dist/{chunk-P2ZQ5LKB.js → chunk-5IWU3HXE.js} +5 -5
  18. package/dist/{chunk-QIUJPPJQ.js → chunk-5TXLVEXT.js} +3 -3
  19. package/dist/{chunk-TSLKDFAF.js → chunk-66BMJ25W.js} +7 -7
  20. package/dist/{chunk-6UIGZD2N.js → chunk-6MLEBAYZ.js} +2 -2
  21. package/dist/{chunk-BVIK2P6P.js → chunk-7HIRPCKU.js} +4 -4
  22. package/dist/{chunk-UNXRACJ7.js → chunk-7LSSNB7Y.js} +3 -3
  23. package/dist/{chunk-QHA67Q7A.js → chunk-7Q66W4OH.js} +2 -2
  24. package/dist/{chunk-RUC7OULH.js → chunk-AEIMYF4P.js} +6 -8
  25. package/dist/{chunk-RUC7OULH.js.map → chunk-AEIMYF4P.js.map} +1 -1
  26. package/dist/{chunk-MD6HA5IK.js → chunk-B2UO6EYE.js} +2 -2
  27. package/dist/{chunk-YZTDGPFB.js → chunk-CFUWQHCJ.js} +2 -2
  28. package/dist/{chunk-UYWAESOT.js → chunk-F2PWIRV4.js} +3 -3
  29. package/dist/{chunk-PSFVTBM7.js → chunk-FXDYIV3K.js} +2 -2
  30. package/dist/{chunk-CDQEK2WD.js → chunk-FXJKNVZW.js} +5 -5
  31. package/dist/{chunk-3CMGCRB5.js → chunk-HMMO2LDS.js} +3 -3
  32. package/dist/{chunk-OOU3DKNT.js → chunk-IDUICCZY.js} +2 -2
  33. package/dist/{chunk-HABINPX2.js → chunk-J7GHNTYK.js} +67 -11
  34. package/dist/chunk-J7GHNTYK.js.map +1 -0
  35. package/dist/{chunk-DKQ4SUII.js → chunk-K5G5SFWY.js} +2 -2
  36. package/dist/chunk-K5G5SFWY.js.map +1 -0
  37. package/dist/{chunk-KO2FOMHL.js → chunk-LT3SGBR7.js} +2 -2
  38. package/dist/{chunk-VBFDVGAE.js → chunk-LVLRMP7V.js} +2 -2
  39. package/dist/{chunk-RNZMHJK7.js → chunk-N4ZJVATC.js} +3 -3
  40. package/dist/chunk-NXMDEL3F.js +54 -0
  41. package/dist/chunk-NXMDEL3F.js.map +1 -0
  42. package/dist/{chunk-CDF7ZX2B.js → chunk-O7VL5N6S.js} +2 -2
  43. package/dist/{chunk-S65T4O6I.js → chunk-QPS6TZUW.js} +3 -3
  44. package/dist/{chunk-RJKMF6BC.js → chunk-SHVB3EFE.js} +3 -3
  45. package/dist/chunk-VT4PDUYT.js +578 -0
  46. package/dist/chunk-VT4PDUYT.js.map +1 -0
  47. package/dist/{chunk-4YTILIIH.js → chunk-VV66DH6T.js} +8 -8
  48. package/dist/{chunk-GVRO4PWE.js → chunk-XNNXAAZT.js} +6 -6
  49. package/dist/{chunk-AS2IRKLU.js → chunk-YU5HVI6B.js} +2 -2
  50. package/dist/{chunk-6KB7R22U.js → chunk-Z5BM4JWB.js} +25 -24
  51. package/dist/chunk-Z5BM4JWB.js.map +1 -0
  52. package/dist/{chunk-SJ2GZ6RF.js → chunk-ZX3GTM7O.js} +2 -2
  53. package/dist/{claude-ACVXNB6N.js → claude-H33OQMXO.js} +4 -6
  54. package/dist/{cleanup-LU6NU2NZ.js → cleanup-Y5W3CNUV.js} +20 -22
  55. package/dist/{cleanup-LU6NU2NZ.js.map → cleanup-Y5W3CNUV.js.map} +1 -1
  56. package/dist/cli.js +71 -73
  57. package/dist/cli.js.map +1 -1
  58. package/dist/{color-ZPIIUADB.js → color-4TJ4P5EY.js} +5 -3
  59. package/dist/{contribute-RS3DO3WP.js → contribute-K7UXBOML.js} +8 -8
  60. package/dist/{dev-server-ASH7HJVI.js → dev-server-HNBRWGCD.js} +11 -13
  61. package/dist/{dev-server-ASH7HJVI.js.map → dev-server-HNBRWGCD.js.map} +1 -1
  62. package/dist/{feedback-OFVW22UW.js → feedback-567ZH2O7.js} +11 -13
  63. package/dist/{feedback-OFVW22UW.js.map → feedback-567ZH2O7.js.map} +1 -1
  64. package/dist/{git-OQAPUPLP.js → git-OV6ADVO7.js} +6 -6
  65. package/dist/{ignite-NREQ3JRM.js → ignite-3HB3ZBEW.js} +15 -17
  66. package/dist/{ignite-NREQ3JRM.js.map → ignite-3HB3ZBEW.js.map} +1 -1
  67. package/dist/index.d.ts +54 -35
  68. package/dist/index.js +371 -276
  69. package/dist/index.js.map +1 -1
  70. package/dist/init-CMIRHFSR.js +19 -0
  71. package/dist/{installation-detector-6R6YOFVZ.js → installation-detector-VXZOCL6P.js} +3 -3
  72. package/dist/mcp/issue-management-server.js +62 -7
  73. package/dist/mcp/issue-management-server.js.map +1 -1
  74. package/dist/neon-helpers-3KBC4A3Y.js +11 -0
  75. package/dist/{open-KW4NTLXH.js → open-AXE225Z5.js} +11 -13
  76. package/dist/{open-KW4NTLXH.js.map → open-AXE225Z5.js.map} +1 -1
  77. package/dist/{projects-QEAEBAT2.js → projects-GVEMCN5R.js} +4 -4
  78. package/dist/{prompt-A7GGRHSY.js → prompt-3SAZYRUN.js} +3 -3
  79. package/dist/prompts/session-summary-prompt.txt +58 -4
  80. package/dist/{rebase-WZHHE5LU.js → rebase-6UIHMUWS.js} +9 -11
  81. package/dist/{rebase-WZHHE5LU.js.map → rebase-6UIHMUWS.js.map} +1 -1
  82. package/dist/{recap-33NPZ3ZO.js → recap-XTBNMEMO.js} +12 -19
  83. package/dist/recap-XTBNMEMO.js.map +1 -0
  84. package/dist/{remote-73TZ2ADI.js → remote-IJAMOEAP.js} +3 -3
  85. package/dist/{run-HRYQ7TR7.js → run-H375EYRB.js} +11 -13
  86. package/dist/{run-HRYQ7TR7.js.map → run-H375EYRB.js.map} +1 -1
  87. package/dist/{shell-JMU5XTHW.js → shell-33FJCWJQ.js} +9 -11
  88. package/dist/{shell-JMU5XTHW.js.map → shell-33FJCWJQ.js.map} +1 -1
  89. package/dist/{summary-4SSGGH7N.js → summary-JUMOCNLR.js} +14 -15
  90. package/dist/{summary-4SSGGH7N.js.map → summary-JUMOCNLR.js.map} +1 -1
  91. package/dist/{test-git-6SAIRBUD.js → test-git-CO3BA4BV.js} +6 -6
  92. package/dist/{test-prefix-RLVRK5ZD.js → test-prefix-HZYSDQYT.js} +6 -6
  93. package/dist/{test-tabs-3SCJWRKT.js → test-tabs-D3POYOJ5.js} +3 -6
  94. package/dist/{test-tabs-3SCJWRKT.js.map → test-tabs-D3POYOJ5.js.map} +1 -1
  95. package/dist/{test-webserver-VPNLAFZ3.js → test-webserver-YVQD42W6.js} +2 -2
  96. package/dist/{update-LETF5ASC.js → update-5NOHT4SG.js} +4 -4
  97. package/dist/{update-notifier-H55ZK7NU.js → update-notifier-ARA5SPUW.js} +3 -3
  98. package/package.json +1 -1
  99. package/dist/ClaudeContextManager-DQFKIMEP.js +0 -16
  100. package/dist/ClaudeService-CJS32WG2.js +0 -15
  101. package/dist/GitHubService-RPM27GWD.js +0 -12
  102. package/dist/MetadataManager-WXUVXKUS.js +0 -10
  103. package/dist/PRManager-7DSIMCAD.js +0 -16
  104. package/dist/PromptTemplateManager-72FEOGT6.js +0 -9
  105. package/dist/SettingsMigrationManager-EH3J2TCN.js +0 -10
  106. package/dist/chunk-6KB7R22U.js.map +0 -1
  107. package/dist/chunk-DKQ4SUII.js.map +0 -1
  108. package/dist/chunk-HABINPX2.js.map +0 -1
  109. package/dist/chunk-UYVWLISQ.js +0 -113
  110. package/dist/chunk-UYVWLISQ.js.map +0 -1
  111. package/dist/chunk-VAYGNQTE.js +0 -234
  112. package/dist/chunk-VAYGNQTE.js.map +0 -1
  113. package/dist/chunk-WUQQNE63.js.map +0 -1
  114. package/dist/chunk-Z5NXYJIG.js +0 -207
  115. package/dist/chunk-Z5NXYJIG.js.map +0 -1
  116. package/dist/init-F6PFMSU5.js +0 -21
  117. package/dist/neon-helpers-L5CXQ5CT.js +0 -11
  118. package/dist/recap-33NPZ3ZO.js.map +0 -1
  119. /package/dist/{BranchNamingService-GCCWB3LK.js.map → BranchNamingService-B5PVRR7F.js.map} +0 -0
  120. /package/dist/{ClaudeContextManager-DQFKIMEP.js.map → ClaudeContextManager-PQ46VILL.js.map} +0 -0
  121. /package/dist/{ClaudeService-CJS32WG2.js.map → ClaudeService-6OMO552H.js.map} +0 -0
  122. /package/dist/{GitHubService-RPM27GWD.js.map → GitHubService-S2OGUTDR.js.map} +0 -0
  123. /package/dist/{MetadataManager-WXUVXKUS.js.map → MetadataManager-DFI73J3G.js.map} +0 -0
  124. /package/dist/{PRManager-7DSIMCAD.js.map → PRManager-OCSB2HPT.js.map} +0 -0
  125. /package/dist/{PromptTemplateManager-72FEOGT6.js.map → PromptTemplateManager-5GNF7FCP.js.map} +0 -0
  126. /package/dist/{SettingsManager-XPR4TEQL.js.map → SettingsManager-CNYBGXDT.js.map} +0 -0
  127. /package/dist/{SettingsMigrationManager-EH3J2TCN.js.map → SettingsMigrationManager-KZKDG66H.js.map} +0 -0
  128. /package/dist/{chunk-OEGECBFS.js.map → chunk-3PT7RKL5.js.map} +0 -0
  129. /package/dist/{chunk-LN4H3A6A.js.map → chunk-53OMUNUN.js.map} +0 -0
  130. /package/dist/{chunk-THF25ICZ.js.map → chunk-5F6IWWRS.js.map} +0 -0
  131. /package/dist/{chunk-P2ZQ5LKB.js.map → chunk-5IWU3HXE.js.map} +0 -0
  132. /package/dist/{chunk-QIUJPPJQ.js.map → chunk-5TXLVEXT.js.map} +0 -0
  133. /package/dist/{chunk-TSLKDFAF.js.map → chunk-66BMJ25W.js.map} +0 -0
  134. /package/dist/{chunk-6UIGZD2N.js.map → chunk-6MLEBAYZ.js.map} +0 -0
  135. /package/dist/{chunk-BVIK2P6P.js.map → chunk-7HIRPCKU.js.map} +0 -0
  136. /package/dist/{chunk-UNXRACJ7.js.map → chunk-7LSSNB7Y.js.map} +0 -0
  137. /package/dist/{chunk-QHA67Q7A.js.map → chunk-7Q66W4OH.js.map} +0 -0
  138. /package/dist/{chunk-MD6HA5IK.js.map → chunk-B2UO6EYE.js.map} +0 -0
  139. /package/dist/{chunk-YZTDGPFB.js.map → chunk-CFUWQHCJ.js.map} +0 -0
  140. /package/dist/{chunk-UYWAESOT.js.map → chunk-F2PWIRV4.js.map} +0 -0
  141. /package/dist/{chunk-PSFVTBM7.js.map → chunk-FXDYIV3K.js.map} +0 -0
  142. /package/dist/{chunk-CDQEK2WD.js.map → chunk-FXJKNVZW.js.map} +0 -0
  143. /package/dist/{chunk-3CMGCRB5.js.map → chunk-HMMO2LDS.js.map} +0 -0
  144. /package/dist/{chunk-OOU3DKNT.js.map → chunk-IDUICCZY.js.map} +0 -0
  145. /package/dist/{chunk-KO2FOMHL.js.map → chunk-LT3SGBR7.js.map} +0 -0
  146. /package/dist/{chunk-VBFDVGAE.js.map → chunk-LVLRMP7V.js.map} +0 -0
  147. /package/dist/{chunk-RNZMHJK7.js.map → chunk-N4ZJVATC.js.map} +0 -0
  148. /package/dist/{chunk-CDF7ZX2B.js.map → chunk-O7VL5N6S.js.map} +0 -0
  149. /package/dist/{chunk-S65T4O6I.js.map → chunk-QPS6TZUW.js.map} +0 -0
  150. /package/dist/{chunk-RJKMF6BC.js.map → chunk-SHVB3EFE.js.map} +0 -0
  151. /package/dist/{chunk-4YTILIIH.js.map → chunk-VV66DH6T.js.map} +0 -0
  152. /package/dist/{chunk-GVRO4PWE.js.map → chunk-XNNXAAZT.js.map} +0 -0
  153. /package/dist/{chunk-AS2IRKLU.js.map → chunk-YU5HVI6B.js.map} +0 -0
  154. /package/dist/{chunk-SJ2GZ6RF.js.map → chunk-ZX3GTM7O.js.map} +0 -0
  155. /package/dist/{claude-ACVXNB6N.js.map → claude-H33OQMXO.js.map} +0 -0
  156. /package/dist/{color-ZPIIUADB.js.map → color-4TJ4P5EY.js.map} +0 -0
  157. /package/dist/{contribute-RS3DO3WP.js.map → contribute-K7UXBOML.js.map} +0 -0
  158. /package/dist/{git-OQAPUPLP.js.map → git-OV6ADVO7.js.map} +0 -0
  159. /package/dist/{init-F6PFMSU5.js.map → init-CMIRHFSR.js.map} +0 -0
  160. /package/dist/{installation-detector-6R6YOFVZ.js.map → installation-detector-VXZOCL6P.js.map} +0 -0
  161. /package/dist/{neon-helpers-L5CXQ5CT.js.map → neon-helpers-3KBC4A3Y.js.map} +0 -0
  162. /package/dist/{projects-QEAEBAT2.js.map → projects-GVEMCN5R.js.map} +0 -0
  163. /package/dist/{prompt-A7GGRHSY.js.map → prompt-3SAZYRUN.js.map} +0 -0
  164. /package/dist/{remote-73TZ2ADI.js.map → remote-IJAMOEAP.js.map} +0 -0
  165. /package/dist/{test-git-6SAIRBUD.js.map → test-git-CO3BA4BV.js.map} +0 -0
  166. /package/dist/{test-prefix-RLVRK5ZD.js.map → test-prefix-HZYSDQYT.js.map} +0 -0
  167. /package/dist/{test-webserver-VPNLAFZ3.js.map → test-webserver-YVQD42W6.js.map} +0 -0
  168. /package/dist/{update-LETF5ASC.js.map → update-5NOHT4SG.js.map} +0 -0
  169. /package/dist/{update-notifier-H55ZK7NU.js.map → update-notifier-ARA5SPUW.js.map} +0 -0
package/dist/index.js CHANGED
@@ -8,8 +8,282 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/utils/env.ts
12
+ import path from "path";
13
+ import dotenvFlow from "dotenv-flow";
14
+ function parseEnvFile(content) {
15
+ const envMap = /* @__PURE__ */ new Map();
16
+ const lines = content.split("\n");
17
+ for (const line of lines) {
18
+ const trimmedLine = line.trim();
19
+ if (!trimmedLine || trimmedLine.startsWith("#")) {
20
+ continue;
21
+ }
22
+ const cleanLine = trimmedLine.startsWith("export ") ? trimmedLine.substring(7) : trimmedLine;
23
+ const equalsIndex = cleanLine.indexOf("=");
24
+ if (equalsIndex === -1) {
25
+ continue;
26
+ }
27
+ const key = cleanLine.substring(0, equalsIndex).trim();
28
+ let value = cleanLine.substring(equalsIndex + 1);
29
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
30
+ value = value.substring(1, value.length - 1);
31
+ value = value.replace(/\\"/g, '"').replace(/\\'/g, "'");
32
+ value = value.replace(/\\n/g, "\n");
33
+ }
34
+ if (key) {
35
+ envMap.set(key, value);
36
+ }
37
+ }
38
+ return envMap;
39
+ }
40
+ function formatEnvLine(key, value) {
41
+ const escapedValue = value.replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
42
+ return `${key}="${escapedValue}"`;
43
+ }
44
+ function validateEnvVariable(key, _value) {
45
+ if (!key || key.length === 0) {
46
+ return {
47
+ valid: false,
48
+ error: "Environment variable key cannot be empty"
49
+ };
50
+ }
51
+ if (!isValidEnvKey(key)) {
52
+ return {
53
+ valid: false,
54
+ error: `Invalid environment variable name: ${key}. Must start with a letter or underscore and contain only letters, numbers, and underscores.`
55
+ };
56
+ }
57
+ return { valid: true };
58
+ }
59
+ function isValidEnvKey(key) {
60
+ if (!key || key.length === 0) {
61
+ return false;
62
+ }
63
+ const validKeyRegex = /^[A-Za-z_][A-Za-z0-9_]*$/;
64
+ return validKeyRegex.test(key);
65
+ }
66
+ function getDotenvFlowFiles() {
67
+ return [
68
+ ".env",
69
+ ".env.local",
70
+ `.env.${DOTENV_FLOW_NODE_ENV}`,
71
+ `.env.${DOTENV_FLOW_NODE_ENV}.local`
72
+ ];
73
+ }
74
+ async function buildEnvSourceCommands(workspacePath, fileExists) {
75
+ const files = getDotenvFlowFiles();
76
+ const commands = [];
77
+ for (const file of files) {
78
+ const fullPath = path.join(workspacePath, file);
79
+ const exists = await fileExists(fullPath);
80
+ if (exists) {
81
+ commands.push(`source ${file}`);
82
+ }
83
+ }
84
+ return commands;
85
+ }
86
+ async function findEnvFileContainingVariable(workspacePath, variableName, fileExists, getEnvVariable) {
87
+ const files = getDotenvFlowFiles().reverse();
88
+ for (const file of files) {
89
+ const fullPath = path.join(workspacePath, file);
90
+ if (!await fileExists(fullPath)) {
91
+ continue;
92
+ }
93
+ const value = await getEnvVariable(fullPath, variableName);
94
+ if (value !== null) {
95
+ return file;
96
+ }
97
+ }
98
+ return null;
99
+ }
100
+ async function hasVariableInAnyEnvFile(workspacePath, variableName, fileExists, getEnvVariable) {
101
+ const file = await findEnvFileContainingVariable(workspacePath, variableName, fileExists, getEnvVariable);
102
+ return file !== null;
103
+ }
104
+ var DOTENV_FLOW_NODE_ENV;
105
+ var init_env = __esm({
106
+ "src/utils/env.ts"() {
107
+ "use strict";
108
+ init_logger();
109
+ DOTENV_FLOW_NODE_ENV = process.env.DOTENV_FLOW_NODE_ENV ?? "development";
110
+ }
111
+ });
112
+
113
+ // src/utils/terminal.ts
114
+ import { execa } from "execa";
115
+ import { existsSync } from "fs";
116
+ function detectPlatform() {
117
+ const platform = process.platform;
118
+ if (platform === "darwin") return "darwin";
119
+ if (platform === "linux") return "linux";
120
+ if (platform === "win32") return "win32";
121
+ return "unsupported";
122
+ }
123
+ async function detectDarkMode() {
124
+ const platform = detectPlatform();
125
+ if (platform !== "darwin") {
126
+ return "light";
127
+ }
128
+ try {
129
+ const result = await execa("defaults", ["read", "-g", "AppleInterfaceStyle"]);
130
+ return result.stdout.trim().toLowerCase() === "dark" ? "dark" : "light";
131
+ } catch {
132
+ return "light";
133
+ }
134
+ }
135
+ async function detectITerm2() {
136
+ const platform = detectPlatform();
137
+ if (platform !== "darwin") return false;
138
+ return existsSync("/Applications/iTerm.app");
139
+ }
140
+ async function openTerminalWindow(options) {
141
+ const platform = detectPlatform();
142
+ if (platform !== "darwin") {
143
+ throw new Error(
144
+ `Terminal window launching not yet supported on ${platform}. Currently only macOS is supported.`
145
+ );
146
+ }
147
+ const hasITerm2 = await detectITerm2();
148
+ const applescript = hasITerm2 ? await buildITerm2SingleTabScript(options) : await buildAppleScript(options);
149
+ try {
150
+ await execa("osascript", ["-e", applescript]);
151
+ if (!hasITerm2) {
152
+ await execa("osascript", ["-e", 'tell application "Terminal" to activate']);
153
+ }
154
+ } catch (error) {
155
+ throw new Error(
156
+ `Failed to open terminal window: ${error instanceof Error ? error.message : "Unknown error"}`
157
+ );
158
+ }
159
+ }
160
+ async function buildAppleScript(options) {
161
+ const {
162
+ workspacePath,
163
+ command,
164
+ backgroundColor,
165
+ port,
166
+ includeEnvSetup,
167
+ includePortExport
168
+ } = options;
169
+ const commands = [];
170
+ if (workspacePath) {
171
+ commands.push(`cd '${escapePathForAppleScript(workspacePath)}'`);
172
+ }
173
+ if (includeEnvSetup && workspacePath) {
174
+ const sourceCommands = await buildEnvSourceCommands(
175
+ workspacePath,
176
+ async (p) => existsSync(p)
177
+ );
178
+ commands.push(...sourceCommands);
179
+ }
180
+ if (includePortExport && port !== void 0) {
181
+ commands.push(`export PORT=${port}`);
182
+ }
183
+ if (command) {
184
+ commands.push(command);
185
+ }
186
+ const fullCommand = commands.join(" && ");
187
+ const historyFreeCommand = ` ${fullCommand}`;
188
+ let script = `tell application "Terminal"
189
+ `;
190
+ script += ` set newTab to do script "${escapeForAppleScript(historyFreeCommand)}"
191
+ `;
192
+ if (backgroundColor) {
193
+ const { r, g, b } = backgroundColor;
194
+ script += ` set background color of newTab to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
195
+ `;
196
+ }
197
+ script += `end tell`;
198
+ return script;
199
+ }
200
+ function escapePathForAppleScript(path7) {
201
+ return path7.replace(/'/g, "'\\''");
202
+ }
203
+ function escapeForAppleScript(command) {
204
+ return command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
205
+ }
206
+ async function buildITerm2SingleTabScript(options) {
207
+ const command = await buildCommandSequence(options);
208
+ let script = 'tell application id "com.googlecode.iterm2"\n';
209
+ script += " create window with default profile\n";
210
+ script += " set s1 to current session of current window\n\n";
211
+ if (options.backgroundColor) {
212
+ const { r, g, b } = options.backgroundColor;
213
+ script += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
214
+ `;
215
+ }
216
+ script += ` tell s1 to write text "${escapeForAppleScript(command)}"
217
+
218
+ `;
219
+ if (options.title) {
220
+ script += ` set name of s1 to "${escapeForAppleScript(options.title)}"
221
+
222
+ `;
223
+ }
224
+ script += " activate\n";
225
+ script += "end tell";
226
+ return script;
227
+ }
228
+ async function buildCommandSequence(options) {
229
+ const {
230
+ workspacePath,
231
+ command,
232
+ port,
233
+ includeEnvSetup,
234
+ includePortExport
235
+ } = options;
236
+ const commands = [];
237
+ if (workspacePath) {
238
+ commands.push(`cd '${escapePathForAppleScript(workspacePath)}'`);
239
+ }
240
+ if (includeEnvSetup && workspacePath) {
241
+ const sourceCommands = await buildEnvSourceCommands(
242
+ workspacePath,
243
+ async (p) => existsSync(p)
244
+ );
245
+ commands.push(...sourceCommands);
246
+ }
247
+ if (includePortExport && port !== void 0) {
248
+ commands.push(`export PORT=${port}`);
249
+ }
250
+ if (command) {
251
+ commands.push(command);
252
+ }
253
+ const fullCommand = commands.join(" && ");
254
+ return ` ${fullCommand}`;
255
+ }
256
+ var init_terminal = __esm({
257
+ "src/utils/terminal.ts"() {
258
+ "use strict";
259
+ init_env();
260
+ }
261
+ });
262
+
11
263
  // src/utils/logger.ts
12
264
  import chalk, { Chalk } from "chalk";
265
+ async function initializeThemeMode() {
266
+ try {
267
+ currentThemeMode = await detectDarkMode();
268
+ } catch {
269
+ currentThemeMode = "light";
270
+ }
271
+ }
272
+ function getInfoColor(chalkInstance) {
273
+ return currentThemeMode === "dark" ? chalkInstance.cyan : chalkInstance.blue;
274
+ }
275
+ function getSuccessColor(chalkInstance) {
276
+ return currentThemeMode === "dark" ? chalkInstance.greenBright : chalkInstance.green;
277
+ }
278
+ function getWarnColor(chalkInstance) {
279
+ return currentThemeMode === "dark" ? chalkInstance.yellowBright : chalkInstance.yellow;
280
+ }
281
+ function getErrorColor(chalkInstance) {
282
+ return currentThemeMode === "dark" ? chalkInstance.redBright : chalkInstance.red;
283
+ }
284
+ function getDebugColor(chalkInstance) {
285
+ return currentThemeMode === "dark" ? chalkInstance.gray : chalkInstance.gray;
286
+ }
13
287
  function formatMessage(message, ...args) {
14
288
  const formattedArgs = args.map(
15
289
  (arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)
@@ -54,32 +328,32 @@ function createLogger(options = {}) {
54
328
  info: (message, ...args) => {
55
329
  const formatted = formatMessage(message, ...args);
56
330
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
57
- const output = formatWithEmoji(fullMessage, "\u{1F5C2}\uFE0F ", customStdoutChalk.blue);
331
+ const output = formatWithEmoji(fullMessage, "\u{1F5C2}\uFE0F ", getInfoColor(customStdoutChalk));
58
332
  console.log(output);
59
333
  },
60
334
  success: (message, ...args) => {
61
335
  const formatted = formatMessage(message, ...args);
62
336
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
63
- const output = formatWithEmoji(fullMessage, "\u2705", customStdoutChalk.green);
337
+ const output = formatWithEmoji(fullMessage, "\u2705", getSuccessColor(customStdoutChalk));
64
338
  console.log(output);
65
339
  },
66
340
  warn: (message, ...args) => {
67
341
  const formatted = formatMessage(message, ...args);
68
342
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
69
- const output = formatWithEmoji(fullMessage, "\u26A0\uFE0F ", customStderrChalk.yellow);
343
+ const output = formatWithEmoji(fullMessage, "\u26A0\uFE0F ", getWarnColor(customStderrChalk));
70
344
  console.error(output);
71
345
  },
72
346
  error: (message, ...args) => {
73
347
  const formatted = formatMessage(message, ...args);
74
348
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
75
- const output = formatWithEmoji(fullMessage, "\u274C", customStderrChalk.red);
349
+ const output = formatWithEmoji(fullMessage, "\u274C", getErrorColor(customStderrChalk));
76
350
  console.error(output);
77
351
  },
78
352
  debug: (message, ...args) => {
79
353
  if (localDebugEnabled) {
80
354
  const formatted = formatMessage(message, ...args);
81
355
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
82
- const output = formatWithEmoji(fullMessage, "\u{1F50D}", customStdoutChalk.gray);
356
+ const output = formatWithEmoji(fullMessage, "\u{1F50D}", getDebugColor(customStdoutChalk));
83
357
  console.log(output);
84
358
  }
85
359
  },
@@ -102,32 +376,32 @@ function createStderrLogger(options = {}) {
102
376
  info: (message, ...args) => {
103
377
  const formatted = formatMessage(message, ...args);
104
378
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
105
- const output = formatWithEmoji(fullMessage, "\u{1F5C2}\uFE0F ", customChalk.blue);
379
+ const output = formatWithEmoji(fullMessage, "\u{1F5C2}\uFE0F ", getInfoColor(customChalk));
106
380
  console.error(output);
107
381
  },
108
382
  success: (message, ...args) => {
109
383
  const formatted = formatMessage(message, ...args);
110
384
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
111
- const output = formatWithEmoji(fullMessage, "\u2705", customChalk.green);
385
+ const output = formatWithEmoji(fullMessage, "\u2705", getSuccessColor(customChalk));
112
386
  console.error(output);
113
387
  },
114
388
  warn: (message, ...args) => {
115
389
  const formatted = formatMessage(message, ...args);
116
390
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
117
- const output = formatWithEmoji(fullMessage, "\u26A0\uFE0F ", customChalk.yellow);
391
+ const output = formatWithEmoji(fullMessage, "\u26A0\uFE0F ", getWarnColor(customChalk));
118
392
  console.error(output);
119
393
  },
120
394
  error: (message, ...args) => {
121
395
  const formatted = formatMessage(message, ...args);
122
396
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
123
- const output = formatWithEmoji(fullMessage, "\u274C", customChalk.red);
397
+ const output = formatWithEmoji(fullMessage, "\u274C", getErrorColor(customChalk));
124
398
  console.error(output);
125
399
  },
126
400
  debug: (message, ...args) => {
127
401
  if (localDebugEnabled) {
128
402
  const formatted = formatMessage(message, ...args);
129
403
  const fullMessage = `${getTimestamp()}${prefixStr}${formatted}`;
130
- const output = formatWithEmoji(fullMessage, "\u{1F50D}", customChalk.gray);
404
+ const output = formatWithEmoji(fullMessage, "\u{1F50D}", getDebugColor(customChalk));
131
405
  console.error(output);
132
406
  }
133
407
  },
@@ -141,38 +415,47 @@ function createStderrLogger(options = {}) {
141
415
  // Use stderr for progress output in JSON mode
142
416
  };
143
417
  }
144
- var stdoutChalk, stderrChalk, globalDebugEnabled, logger, logger_default;
418
+ function setThemeMode(mode) {
419
+ currentThemeMode = mode;
420
+ }
421
+ function getThemeMode() {
422
+ return currentThemeMode;
423
+ }
424
+ var stdoutChalk, stderrChalk, currentThemeMode, globalDebugEnabled, logger, logger_default;
145
425
  var init_logger = __esm({
146
426
  "src/utils/logger.ts"() {
147
427
  "use strict";
428
+ init_terminal();
148
429
  stdoutChalk = new Chalk({ level: chalk.level });
149
430
  stderrChalk = new Chalk({ level: chalk.level });
431
+ currentThemeMode = "light";
432
+ void initializeThemeMode();
150
433
  globalDebugEnabled = false;
151
434
  logger = {
152
435
  info: (message, ...args) => {
153
436
  const formatted = formatMessage(message, ...args);
154
- const output = formatWithEmoji(formatted, "\u{1F5C2}\uFE0F ", stdoutChalk.blue);
437
+ const output = formatWithEmoji(formatted, "\u{1F5C2}\uFE0F ", getInfoColor(stdoutChalk));
155
438
  console.log(output);
156
439
  },
157
440
  success: (message, ...args) => {
158
441
  const formatted = formatMessage(message, ...args);
159
- const output = formatWithEmoji(formatted, "\u2705", stdoutChalk.green);
442
+ const output = formatWithEmoji(formatted, "\u2705", getSuccessColor(stdoutChalk));
160
443
  console.log(output);
161
444
  },
162
445
  warn: (message, ...args) => {
163
446
  const formatted = formatMessage(message, ...args);
164
- const output = formatWithEmoji(formatted, "\u26A0\uFE0F ", stderrChalk.yellow);
447
+ const output = formatWithEmoji(formatted, "\u26A0\uFE0F ", getWarnColor(stderrChalk));
165
448
  console.error(output);
166
449
  },
167
450
  error: (message, ...args) => {
168
451
  const formatted = formatMessage(message, ...args);
169
- const output = formatWithEmoji(formatted, "\u274C", stderrChalk.red);
452
+ const output = formatWithEmoji(formatted, "\u274C", getErrorColor(stderrChalk));
170
453
  console.error(output);
171
454
  },
172
455
  debug: (message, ...args) => {
173
456
  if (globalDebugEnabled) {
174
457
  const formatted = formatMessage(message, ...args);
175
- const output = formatWithEmoji(formatted, "\u{1F50D}", stdoutChalk.gray);
458
+ const output = formatWithEmoji(formatted, "\u{1F50D}", getDebugColor(stdoutChalk));
176
459
  console.log(output);
177
460
  }
178
461
  },
@@ -207,7 +490,7 @@ __export(SettingsManager_exports, {
207
490
  WorkflowsSettingsSchemaNoDefaults: () => WorkflowsSettingsSchemaNoDefaults
208
491
  });
209
492
  import { readFile } from "fs/promises";
210
- import path from "path";
493
+ import path2 from "path";
211
494
  import os from "os";
212
495
  import { z } from "zod";
213
496
  import deepmerge from "deepmerge";
@@ -437,10 +720,10 @@ var init_SettingsManager = __esm({
437
720
  const globalSettingsPath = this.getGlobalSettingsPath();
438
721
  logger.debug(`\u{1F30D} Global settings from ${globalSettingsPath}:`, JSON.stringify(globalSettings, null, 2));
439
722
  const baseSettings = await this.loadSettingsFile(root, "settings.json");
440
- const baseSettingsPath = path.join(root, ".iloom", "settings.json");
723
+ const baseSettingsPath = path2.join(root, ".iloom", "settings.json");
441
724
  logger.debug(`\u{1F4C4} Base settings from ${baseSettingsPath}:`, JSON.stringify(baseSettings, null, 2));
442
725
  const localSettings = await this.loadSettingsFile(root, "settings.local.json");
443
- const localSettingsPath = path.join(root, ".iloom", "settings.local.json");
726
+ const localSettingsPath = path2.join(root, ".iloom", "settings.local.json");
444
727
  logger.debug(`\u{1F4C4} Local settings from ${localSettingsPath}:`, JSON.stringify(localSettings, null, 2));
445
728
  let merged = this.mergeSettings(this.mergeSettings(globalSettings, baseSettings), localSettings);
446
729
  logger.debug("\u{1F504} After merging global + base + local settings:", JSON.stringify(merged, null, 2));
@@ -478,7 +761,7 @@ Note: CLI overrides were applied. Check your --set arguments.`);
478
761
  * Uses non-defaulting schema to prevent polluting partial settings with defaults before merge
479
762
  */
480
763
  async loadSettingsFile(projectRoot, filename) {
481
- const settingsPath = path.join(projectRoot, ".iloom", filename);
764
+ const settingsPath = path2.join(projectRoot, ".iloom", filename);
482
765
  try {
483
766
  const content = await readFile(settingsPath, "utf-8");
484
767
  let parsed;
@@ -553,13 +836,13 @@ ${errorMessages.join("\n")}`
553
836
  * Get global config directory path (~/.config/iloom-ai)
554
837
  */
555
838
  getGlobalConfigDir() {
556
- return path.join(os.homedir(), ".config", "iloom-ai");
839
+ return path2.join(os.homedir(), ".config", "iloom-ai");
557
840
  }
558
841
  /**
559
842
  * Get global settings file path (~/.config/iloom-ai/settings.json)
560
843
  */
561
844
  getGlobalSettingsPath() {
562
- return path.join(this.getGlobalConfigDir(), "settings.json");
845
+ return path2.join(this.getGlobalConfigDir(), "settings.json");
563
846
  }
564
847
  /**
565
848
  * Load and parse global settings file
@@ -656,6 +939,7 @@ __export(color_exports, {
656
939
  colorDistance: () => colorDistance,
657
940
  generateColorFromBranchName: () => generateColorFromBranchName,
658
941
  getColorPalette: () => getColorPalette,
942
+ getDarkColorPalette: () => getDarkColorPalette,
659
943
  hexToRgb: () => hexToRgb,
660
944
  lightenColor: () => lightenColor,
661
945
  rgbToHex: () => rgbToHex,
@@ -699,6 +983,42 @@ function getColorPalette() {
699
983
  // 15: Soft salmon
700
984
  ];
701
985
  }
986
+ function getDarkColorPalette() {
987
+ return [
988
+ { r: 30, g: 45, b: 85 },
989
+ // 0: Dark blue
990
+ { r: 85, g: 30, b: 50 },
991
+ // 1: Dark rose
992
+ { r: 30, g: 75, b: 40 },
993
+ // 2: Dark green
994
+ { r: 75, g: 65, b: 30 },
995
+ // 3: Dark olive
996
+ { r: 60, g: 35, b: 85 },
997
+ // 4: Dark lavender
998
+ { r: 30, g: 65, b: 75 },
999
+ // 5: Dark cyan
1000
+ { r: 55, g: 55, b: 55 },
1001
+ // 6: Dark grey
1002
+ { r: 85, g: 40, b: 40 },
1003
+ // 7: Dark coral
1004
+ { r: 35, g: 80, b: 50 },
1005
+ // 8: Dark mint
1006
+ { r: 70, g: 50, b: 30 },
1007
+ // 9: Dark brown
1008
+ { r: 30, g: 75, b: 75 },
1009
+ // 10: Dark aqua
1010
+ { r: 75, g: 30, b: 75 },
1011
+ // 11: Dark magenta
1012
+ { r: 75, g: 75, b: 30 },
1013
+ // 12: Dark yellow
1014
+ { r: 50, g: 35, b: 85 },
1015
+ // 13: Dark violet
1016
+ { r: 30, g: 80, b: 65 },
1017
+ // 14: Dark sea green
1018
+ { r: 85, g: 40, b: 30 }
1019
+ // 15: Dark rust
1020
+ ];
1021
+ }
702
1022
  function rgbToHex(r, g, b) {
703
1023
  if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
704
1024
  throw new Error("RGB values must be between 0 and 255");
@@ -718,10 +1038,10 @@ function hexToRgb(hex) {
718
1038
  const b = parseInt(cleanHex.slice(4, 6), 16);
719
1039
  return { r, g, b };
720
1040
  }
721
- function generateColorFromBranchName(branchName) {
1041
+ function generateColorFromBranchName(branchName, themeMode = "light") {
722
1042
  const hash = createHash2("sha256").update(branchName).digest("hex");
723
1043
  const hashPrefix = hash.slice(0, 8);
724
- const palette = getColorPalette();
1044
+ const palette = themeMode === "dark" ? getDarkColorPalette() : getColorPalette();
725
1045
  const hashAsInt = parseInt(hashPrefix, 16);
726
1046
  const index = hashAsInt % palette.length;
727
1047
  logger_default.debug(`[generateColorFromBranchName] Branch name: ${branchName}, Hash: ${hash}, Hash prefix: ${hashPrefix}, Hash as int: ${hashAsInt}, Index: ${index}`);
@@ -741,9 +1061,9 @@ function colorDistance(a, b) {
741
1061
  Math.pow(a.r - b.r, 2) + Math.pow(a.g - b.g, 2) + Math.pow(a.b - b.b, 2)
742
1062
  );
743
1063
  }
744
- function selectDistinctColor(branchName, usedHexColors) {
745
- const palette = getColorPalette();
746
- const hashBasedColor = generateColorFromBranchName(branchName);
1064
+ function selectDistinctColor(branchName, usedHexColors, themeMode = "light") {
1065
+ const palette = themeMode === "dark" ? getDarkColorPalette() : getColorPalette();
1066
+ const hashBasedColor = generateColorFromBranchName(branchName, themeMode);
747
1067
  if (usedHexColors.length === 0) {
748
1068
  return hashBasedColor;
749
1069
  }
@@ -824,16 +1144,16 @@ var WorkspaceManager = class {
824
1144
  };
825
1145
 
826
1146
  // src/lib/GitWorktreeManager.ts
827
- import path4 from "path";
1147
+ import path5 from "path";
828
1148
  import fs2 from "fs-extra";
829
1149
 
830
1150
  // src/utils/git.ts
831
1151
  init_SettingsManager();
832
- import path3 from "path";
833
- import { execa } from "execa";
1152
+ import path4 from "path";
1153
+ import { execa as execa2 } from "execa";
834
1154
 
835
1155
  // src/lib/MetadataManager.ts
836
- import path2 from "path";
1156
+ import path3 from "path";
837
1157
  import os2 from "os";
838
1158
  import fs from "fs-extra";
839
1159
 
@@ -848,7 +1168,7 @@ function getLogger() {
848
1168
  // src/lib/MetadataManager.ts
849
1169
  var MetadataManager = class {
850
1170
  constructor() {
851
- this.loomsDir = path2.join(os2.homedir(), ".config", "iloom-ai", "looms");
1171
+ this.loomsDir = path3.join(os2.homedir(), ".config", "iloom-ai", "looms");
852
1172
  }
853
1173
  /**
854
1174
  * Convert worktree path to filename slug per spec section 2.2
@@ -874,7 +1194,7 @@ var MetadataManager = class {
874
1194
  */
875
1195
  getFilePath(worktreePath) {
876
1196
  const filename = this.slugifyPath(worktreePath);
877
- return path2.join(this.loomsDir, filename);
1197
+ return path3.join(this.loomsDir, filename);
878
1198
  }
879
1199
  /**
880
1200
  * Get the full path to the metadata file for a worktree (public API)
@@ -981,7 +1301,7 @@ var MetadataManager = class {
981
1301
  continue;
982
1302
  }
983
1303
  try {
984
- const filePath = path2.join(this.loomsDir, file);
1304
+ const filePath = path3.join(this.loomsDir, file);
985
1305
  const content = await fs.readFile(filePath, "utf8");
986
1306
  const data = JSON.parse(content);
987
1307
  if (!data.description) {
@@ -1046,7 +1366,7 @@ var MetadataManager = class {
1046
1366
  init_logger();
1047
1367
  async function executeGitCommand(args, options) {
1048
1368
  try {
1049
- const result = await execa("git", args, {
1369
+ const result = await execa2("git", args, {
1050
1370
  cwd: (options == null ? void 0 : options.cwd) ?? process.cwd(),
1051
1371
  timeout: (options == null ? void 0 : options.timeout) ?? 3e4,
1052
1372
  encoding: "utf8",
@@ -1211,10 +1531,10 @@ function generateWorktreePath(branchName, rootDir = process.cwd(), options) {
1211
1531
  if ((options == null ? void 0 : options.isPR) && (options == null ? void 0 : options.prNumber)) {
1212
1532
  sanitized = `${sanitized}_pr_${options.prNumber}`;
1213
1533
  }
1214
- const parentDir = path3.dirname(rootDir);
1534
+ const parentDir = path4.dirname(rootDir);
1215
1535
  let prefix;
1216
1536
  if ((options == null ? void 0 : options.prefix) === void 0) {
1217
- const mainFolderName = path3.basename(rootDir);
1537
+ const mainFolderName = path4.basename(rootDir);
1218
1538
  prefix = mainFolderName ? `${mainFolderName}-looms/` : "looms/";
1219
1539
  } else if (options.prefix === "") {
1220
1540
  prefix = "";
@@ -1234,16 +1554,16 @@ function generateWorktreePath(branchName, rootDir = process.cwd(), options) {
1234
1554
  }
1235
1555
  }
1236
1556
  if (prefix === "") {
1237
- return path3.join(parentDir, sanitized);
1557
+ return path4.join(parentDir, sanitized);
1238
1558
  } else if (prefix.endsWith("/")) {
1239
- return path3.join(parentDir, prefix, sanitized);
1559
+ return path4.join(parentDir, prefix, sanitized);
1240
1560
  } else if (prefix.includes("/")) {
1241
1561
  const lastSlashIndex = prefix.lastIndexOf("/");
1242
1562
  const dirPath = prefix.substring(0, lastSlashIndex);
1243
1563
  const prefixWithSeparator = prefix.substring(lastSlashIndex + 1);
1244
- return path3.join(parentDir, dirPath, `${prefixWithSeparator}${sanitized}`);
1564
+ return path4.join(parentDir, dirPath, `${prefixWithSeparator}${sanitized}`);
1245
1565
  } else {
1246
- return path3.join(parentDir, `${prefix}${sanitized}`);
1566
+ return path4.join(parentDir, `${prefix}${sanitized}`);
1247
1567
  }
1248
1568
  }
1249
1569
  async function isValidGitRepo(path7) {
@@ -1767,7 +2087,7 @@ var GitWorktreeManager = class {
1767
2087
  if (!options.branch) {
1768
2088
  throw new Error("Branch name is required");
1769
2089
  }
1770
- const absolutePath = path4.resolve(options.path);
2090
+ const absolutePath = path5.resolve(options.path);
1771
2091
  if (await fs2.pathExists(absolutePath)) {
1772
2092
  if (!options.force) {
1773
2093
  throw new Error(`Path already exists: ${absolutePath}`);
@@ -2083,9 +2403,9 @@ var GitHubError = class extends Error {
2083
2403
 
2084
2404
  // src/utils/github.ts
2085
2405
  init_logger();
2086
- import { execa as execa2 } from "execa";
2406
+ import { execa as execa3 } from "execa";
2087
2407
  async function executeGhCommand(args, options) {
2088
- const result = await execa2("gh", args, {
2408
+ const result = await execa3("gh", args, {
2089
2409
  cwd: (options == null ? void 0 : options.cwd) ?? process.cwd(),
2090
2410
  timeout: (options == null ? void 0 : options.timeout) ?? 3e4,
2091
2411
  encoding: "utf8"
@@ -2251,7 +2571,7 @@ async function createIssue(title, body, options) {
2251
2571
  if (!repo) {
2252
2572
  execaOptions.cwd = process.cwd();
2253
2573
  }
2254
- const result = await execa2("gh", args, execaOptions);
2574
+ const result = await execa3("gh", args, execaOptions);
2255
2575
  const urlMatch = result.stdout.trim().match(/https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/);
2256
2576
  if (!(urlMatch == null ? void 0 : urlMatch[1])) {
2257
2577
  throw new Error(`Failed to parse issue URL from gh output: ${result.stdout}`);
@@ -2936,102 +3256,7 @@ var IssueTrackerFactory = class {
2936
3256
 
2937
3257
  // src/lib/EnvironmentManager.ts
2938
3258
  import fs3 from "fs-extra";
2939
-
2940
- // src/utils/env.ts
2941
- init_logger();
2942
- import path5 from "path";
2943
- import dotenvFlow from "dotenv-flow";
2944
- function parseEnvFile(content) {
2945
- const envMap = /* @__PURE__ */ new Map();
2946
- const lines = content.split("\n");
2947
- for (const line of lines) {
2948
- const trimmedLine = line.trim();
2949
- if (!trimmedLine || trimmedLine.startsWith("#")) {
2950
- continue;
2951
- }
2952
- const cleanLine = trimmedLine.startsWith("export ") ? trimmedLine.substring(7) : trimmedLine;
2953
- const equalsIndex = cleanLine.indexOf("=");
2954
- if (equalsIndex === -1) {
2955
- continue;
2956
- }
2957
- const key = cleanLine.substring(0, equalsIndex).trim();
2958
- let value = cleanLine.substring(equalsIndex + 1);
2959
- if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
2960
- value = value.substring(1, value.length - 1);
2961
- value = value.replace(/\\"/g, '"').replace(/\\'/g, "'");
2962
- value = value.replace(/\\n/g, "\n");
2963
- }
2964
- if (key) {
2965
- envMap.set(key, value);
2966
- }
2967
- }
2968
- return envMap;
2969
- }
2970
- function formatEnvLine(key, value) {
2971
- const escapedValue = value.replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
2972
- return `${key}="${escapedValue}"`;
2973
- }
2974
- function validateEnvVariable(key, _value) {
2975
- if (!key || key.length === 0) {
2976
- return {
2977
- valid: false,
2978
- error: "Environment variable key cannot be empty"
2979
- };
2980
- }
2981
- if (!isValidEnvKey(key)) {
2982
- return {
2983
- valid: false,
2984
- error: `Invalid environment variable name: ${key}. Must start with a letter or underscore and contain only letters, numbers, and underscores.`
2985
- };
2986
- }
2987
- return { valid: true };
2988
- }
2989
- function isValidEnvKey(key) {
2990
- if (!key || key.length === 0) {
2991
- return false;
2992
- }
2993
- const validKeyRegex = /^[A-Za-z_][A-Za-z0-9_]*$/;
2994
- return validKeyRegex.test(key);
2995
- }
2996
- var DOTENV_FLOW_NODE_ENV = process.env.DOTENV_FLOW_NODE_ENV ?? "development";
2997
- function getDotenvFlowFiles() {
2998
- return [
2999
- ".env",
3000
- ".env.local",
3001
- `.env.${DOTENV_FLOW_NODE_ENV}`,
3002
- `.env.${DOTENV_FLOW_NODE_ENV}.local`
3003
- ];
3004
- }
3005
- async function buildEnvSourceCommands(workspacePath, fileExists) {
3006
- const files = getDotenvFlowFiles();
3007
- const commands = [];
3008
- for (const file of files) {
3009
- const fullPath = path5.join(workspacePath, file);
3010
- const exists = await fileExists(fullPath);
3011
- if (exists) {
3012
- commands.push(`source ${file}`);
3013
- }
3014
- }
3015
- return commands;
3016
- }
3017
- async function findEnvFileContainingVariable(workspacePath, variableName, fileExists, getEnvVariable) {
3018
- const files = getDotenvFlowFiles().reverse();
3019
- for (const file of files) {
3020
- const fullPath = path5.join(workspacePath, file);
3021
- if (!await fileExists(fullPath)) {
3022
- continue;
3023
- }
3024
- const value = await getEnvVariable(fullPath, variableName);
3025
- if (value !== null) {
3026
- return file;
3027
- }
3028
- }
3029
- return null;
3030
- }
3031
- async function hasVariableInAnyEnvFile(workspacePath, variableName, fileExists, getEnvVariable) {
3032
- const file = await findEnvFileContainingVariable(workspacePath, variableName, fileExists, getEnvVariable);
3033
- return file !== null;
3034
- }
3259
+ init_env();
3035
3260
 
3036
3261
  // src/utils/port.ts
3037
3262
  import { createHash } from "crypto";
@@ -3248,6 +3473,7 @@ var EnvironmentManager = class {
3248
3473
  };
3249
3474
 
3250
3475
  // src/lib/DatabaseManager.ts
3476
+ init_env();
3251
3477
  import fs4 from "fs-extra";
3252
3478
  var DatabaseManager = class {
3253
3479
  constructor(provider, environment, databaseUrlEnvVarName = "DATABASE_URL") {
@@ -3481,140 +3707,7 @@ import { execa as execa4 } from "execa";
3481
3707
  import { existsSync as existsSync2 } from "fs";
3482
3708
  import { join } from "path";
3483
3709
  import { createHash as createHash3 } from "crypto";
3484
-
3485
- // src/utils/terminal.ts
3486
- import { execa as execa3 } from "execa";
3487
- import { existsSync } from "fs";
3488
- function detectPlatform() {
3489
- const platform = process.platform;
3490
- if (platform === "darwin") return "darwin";
3491
- if (platform === "linux") return "linux";
3492
- if (platform === "win32") return "win32";
3493
- return "unsupported";
3494
- }
3495
- async function detectITerm2() {
3496
- const platform = detectPlatform();
3497
- if (platform !== "darwin") return false;
3498
- return existsSync("/Applications/iTerm.app");
3499
- }
3500
- async function openTerminalWindow(options) {
3501
- const platform = detectPlatform();
3502
- if (platform !== "darwin") {
3503
- throw new Error(
3504
- `Terminal window launching not yet supported on ${platform}. Currently only macOS is supported.`
3505
- );
3506
- }
3507
- const hasITerm2 = await detectITerm2();
3508
- const applescript = hasITerm2 ? await buildITerm2SingleTabScript(options) : await buildAppleScript(options);
3509
- try {
3510
- await execa3("osascript", ["-e", applescript]);
3511
- if (!hasITerm2) {
3512
- await execa3("osascript", ["-e", 'tell application "Terminal" to activate']);
3513
- }
3514
- } catch (error) {
3515
- throw new Error(
3516
- `Failed to open terminal window: ${error instanceof Error ? error.message : "Unknown error"}`
3517
- );
3518
- }
3519
- }
3520
- async function buildAppleScript(options) {
3521
- const {
3522
- workspacePath,
3523
- command,
3524
- backgroundColor,
3525
- port,
3526
- includeEnvSetup,
3527
- includePortExport
3528
- } = options;
3529
- const commands = [];
3530
- if (workspacePath) {
3531
- commands.push(`cd '${escapePathForAppleScript(workspacePath)}'`);
3532
- }
3533
- if (includeEnvSetup && workspacePath) {
3534
- const sourceCommands = await buildEnvSourceCommands(
3535
- workspacePath,
3536
- async (p) => existsSync(p)
3537
- );
3538
- commands.push(...sourceCommands);
3539
- }
3540
- if (includePortExport && port !== void 0) {
3541
- commands.push(`export PORT=${port}`);
3542
- }
3543
- if (command) {
3544
- commands.push(command);
3545
- }
3546
- const fullCommand = commands.join(" && ");
3547
- const historyFreeCommand = ` ${fullCommand}`;
3548
- let script = `tell application "Terminal"
3549
- `;
3550
- script += ` set newTab to do script "${escapeForAppleScript(historyFreeCommand)}"
3551
- `;
3552
- if (backgroundColor) {
3553
- const { r, g, b } = backgroundColor;
3554
- script += ` set background color of newTab to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
3555
- `;
3556
- }
3557
- script += `end tell`;
3558
- return script;
3559
- }
3560
- function escapePathForAppleScript(path7) {
3561
- return path7.replace(/'/g, "'\\''");
3562
- }
3563
- function escapeForAppleScript(command) {
3564
- return command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
3565
- }
3566
- async function buildITerm2SingleTabScript(options) {
3567
- const command = await buildCommandSequence(options);
3568
- let script = 'tell application id "com.googlecode.iterm2"\n';
3569
- script += " create window with default profile\n";
3570
- script += " set s1 to current session of current window\n\n";
3571
- if (options.backgroundColor) {
3572
- const { r, g, b } = options.backgroundColor;
3573
- script += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
3574
- `;
3575
- }
3576
- script += ` tell s1 to write text "${escapeForAppleScript(command)}"
3577
-
3578
- `;
3579
- if (options.title) {
3580
- script += ` set name of s1 to "${escapeForAppleScript(options.title)}"
3581
-
3582
- `;
3583
- }
3584
- script += " activate\n";
3585
- script += "end tell";
3586
- return script;
3587
- }
3588
- async function buildCommandSequence(options) {
3589
- const {
3590
- workspacePath,
3591
- command,
3592
- port,
3593
- includeEnvSetup,
3594
- includePortExport
3595
- } = options;
3596
- const commands = [];
3597
- if (workspacePath) {
3598
- commands.push(`cd '${escapePathForAppleScript(workspacePath)}'`);
3599
- }
3600
- if (includeEnvSetup && workspacePath) {
3601
- const sourceCommands = await buildEnvSourceCommands(
3602
- workspacePath,
3603
- async (p) => existsSync(p)
3604
- );
3605
- commands.push(...sourceCommands);
3606
- }
3607
- if (includePortExport && port !== void 0) {
3608
- commands.push(`export PORT=${port}`);
3609
- }
3610
- if (command) {
3611
- commands.push(command);
3612
- }
3613
- const fullCommand = commands.join(" && ");
3614
- return ` ${fullCommand}`;
3615
- }
3616
-
3617
- // src/utils/claude.ts
3710
+ init_terminal();
3618
3711
  async function detectClaudeCli() {
3619
3712
  try {
3620
3713
  await execa4("command", ["-v", "claude"], {
@@ -4630,6 +4723,7 @@ export {
4630
4723
  getDefaultBranch,
4631
4724
  getMergeTargetBranch,
4632
4725
  getRepoRoot,
4726
+ getThemeMode,
4633
4727
  getWorktreeRoot,
4634
4728
  hasUncommittedChanges,
4635
4729
  isBranchMergedIntoMain,
@@ -4645,6 +4739,7 @@ export {
4645
4739
  parseWorktreeList,
4646
4740
  pushBranchToRemote,
4647
4741
  removePlaceholderCommitFromHead,
4648
- removePlaceholderCommitFromHistory
4742
+ removePlaceholderCommitFromHistory,
4743
+ setThemeMode
4649
4744
  };
4650
4745
  //# sourceMappingURL=index.js.map