@iloom/cli 0.1.14

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 (161) hide show
  1. package/LICENSE +33 -0
  2. package/README.md +711 -0
  3. package/dist/ClaudeContextManager-XOSXQ67R.js +13 -0
  4. package/dist/ClaudeContextManager-XOSXQ67R.js.map +1 -0
  5. package/dist/ClaudeService-YSZ6EXWP.js +12 -0
  6. package/dist/ClaudeService-YSZ6EXWP.js.map +1 -0
  7. package/dist/GitHubService-F7Z3XJOS.js +11 -0
  8. package/dist/GitHubService-F7Z3XJOS.js.map +1 -0
  9. package/dist/LoomLauncher-MODG2SEM.js +263 -0
  10. package/dist/LoomLauncher-MODG2SEM.js.map +1 -0
  11. package/dist/NeonProvider-PAGPUH7F.js +12 -0
  12. package/dist/NeonProvider-PAGPUH7F.js.map +1 -0
  13. package/dist/PromptTemplateManager-7FINLRDE.js +9 -0
  14. package/dist/PromptTemplateManager-7FINLRDE.js.map +1 -0
  15. package/dist/SettingsManager-VAZF26S2.js +19 -0
  16. package/dist/SettingsManager-VAZF26S2.js.map +1 -0
  17. package/dist/SettingsMigrationManager-MTQIMI54.js +146 -0
  18. package/dist/SettingsMigrationManager-MTQIMI54.js.map +1 -0
  19. package/dist/add-issue-22JBNOML.js +54 -0
  20. package/dist/add-issue-22JBNOML.js.map +1 -0
  21. package/dist/agents/iloom-issue-analyze-and-plan.md +580 -0
  22. package/dist/agents/iloom-issue-analyzer.md +290 -0
  23. package/dist/agents/iloom-issue-complexity-evaluator.md +224 -0
  24. package/dist/agents/iloom-issue-enhancer.md +266 -0
  25. package/dist/agents/iloom-issue-implementer.md +262 -0
  26. package/dist/agents/iloom-issue-planner.md +358 -0
  27. package/dist/agents/iloom-issue-reviewer.md +63 -0
  28. package/dist/chunk-2ZPFJQ3B.js +63 -0
  29. package/dist/chunk-2ZPFJQ3B.js.map +1 -0
  30. package/dist/chunk-37DYYFVK.js +29 -0
  31. package/dist/chunk-37DYYFVK.js.map +1 -0
  32. package/dist/chunk-BLCTGFZN.js +121 -0
  33. package/dist/chunk-BLCTGFZN.js.map +1 -0
  34. package/dist/chunk-CP2NU2JC.js +545 -0
  35. package/dist/chunk-CP2NU2JC.js.map +1 -0
  36. package/dist/chunk-CWR2SANQ.js +39 -0
  37. package/dist/chunk-CWR2SANQ.js.map +1 -0
  38. package/dist/chunk-F3XBU2R7.js +110 -0
  39. package/dist/chunk-F3XBU2R7.js.map +1 -0
  40. package/dist/chunk-GEHQXLEI.js +130 -0
  41. package/dist/chunk-GEHQXLEI.js.map +1 -0
  42. package/dist/chunk-GYCR2LOU.js +143 -0
  43. package/dist/chunk-GYCR2LOU.js.map +1 -0
  44. package/dist/chunk-GZP4UGGM.js +48 -0
  45. package/dist/chunk-GZP4UGGM.js.map +1 -0
  46. package/dist/chunk-H4E4THUZ.js +55 -0
  47. package/dist/chunk-H4E4THUZ.js.map +1 -0
  48. package/dist/chunk-HPJJSYNS.js +644 -0
  49. package/dist/chunk-HPJJSYNS.js.map +1 -0
  50. package/dist/chunk-JBH2ZYYZ.js +220 -0
  51. package/dist/chunk-JBH2ZYYZ.js.map +1 -0
  52. package/dist/chunk-JNKJ7NJV.js +78 -0
  53. package/dist/chunk-JNKJ7NJV.js.map +1 -0
  54. package/dist/chunk-JQ7VOSTC.js +437 -0
  55. package/dist/chunk-JQ7VOSTC.js.map +1 -0
  56. package/dist/chunk-KQDEK2ZW.js +199 -0
  57. package/dist/chunk-KQDEK2ZW.js.map +1 -0
  58. package/dist/chunk-O2QWO64Z.js +179 -0
  59. package/dist/chunk-O2QWO64Z.js.map +1 -0
  60. package/dist/chunk-OC4H6HJD.js +248 -0
  61. package/dist/chunk-OC4H6HJD.js.map +1 -0
  62. package/dist/chunk-PR7FKQBG.js +120 -0
  63. package/dist/chunk-PR7FKQBG.js.map +1 -0
  64. package/dist/chunk-PXZBAC2M.js +250 -0
  65. package/dist/chunk-PXZBAC2M.js.map +1 -0
  66. package/dist/chunk-QEPVTTHD.js +383 -0
  67. package/dist/chunk-QEPVTTHD.js.map +1 -0
  68. package/dist/chunk-RSRO7564.js +203 -0
  69. package/dist/chunk-RSRO7564.js.map +1 -0
  70. package/dist/chunk-SJUQ2NDR.js +146 -0
  71. package/dist/chunk-SJUQ2NDR.js.map +1 -0
  72. package/dist/chunk-SPYPLHMK.js +177 -0
  73. package/dist/chunk-SPYPLHMK.js.map +1 -0
  74. package/dist/chunk-SSCQCCJ7.js +75 -0
  75. package/dist/chunk-SSCQCCJ7.js.map +1 -0
  76. package/dist/chunk-SSR5AVRJ.js +41 -0
  77. package/dist/chunk-SSR5AVRJ.js.map +1 -0
  78. package/dist/chunk-T7QPXANZ.js +315 -0
  79. package/dist/chunk-T7QPXANZ.js.map +1 -0
  80. package/dist/chunk-U3WU5OWO.js +203 -0
  81. package/dist/chunk-U3WU5OWO.js.map +1 -0
  82. package/dist/chunk-W3DQTW63.js +124 -0
  83. package/dist/chunk-W3DQTW63.js.map +1 -0
  84. package/dist/chunk-WKEWRSDB.js +151 -0
  85. package/dist/chunk-WKEWRSDB.js.map +1 -0
  86. package/dist/chunk-Y7SAGNUT.js +66 -0
  87. package/dist/chunk-Y7SAGNUT.js.map +1 -0
  88. package/dist/chunk-YETJNRQM.js +39 -0
  89. package/dist/chunk-YETJNRQM.js.map +1 -0
  90. package/dist/chunk-YYSKGAZT.js +384 -0
  91. package/dist/chunk-YYSKGAZT.js.map +1 -0
  92. package/dist/chunk-ZZZWQGTS.js +169 -0
  93. package/dist/chunk-ZZZWQGTS.js.map +1 -0
  94. package/dist/claude-7LUVDZZ4.js +17 -0
  95. package/dist/claude-7LUVDZZ4.js.map +1 -0
  96. package/dist/cleanup-3LUWPSM7.js +412 -0
  97. package/dist/cleanup-3LUWPSM7.js.map +1 -0
  98. package/dist/cli-overrides-XFZWY7CM.js +16 -0
  99. package/dist/cli-overrides-XFZWY7CM.js.map +1 -0
  100. package/dist/cli.js +603 -0
  101. package/dist/cli.js.map +1 -0
  102. package/dist/color-ZVALX37U.js +21 -0
  103. package/dist/color-ZVALX37U.js.map +1 -0
  104. package/dist/enhance-XJIQHVPD.js +166 -0
  105. package/dist/enhance-XJIQHVPD.js.map +1 -0
  106. package/dist/env-MDFL4ZXL.js +23 -0
  107. package/dist/env-MDFL4ZXL.js.map +1 -0
  108. package/dist/feedback-23CLXKFT.js +158 -0
  109. package/dist/feedback-23CLXKFT.js.map +1 -0
  110. package/dist/finish-CY4CIH6O.js +1608 -0
  111. package/dist/finish-CY4CIH6O.js.map +1 -0
  112. package/dist/git-LVRZ57GJ.js +43 -0
  113. package/dist/git-LVRZ57GJ.js.map +1 -0
  114. package/dist/ignite-WXEF2ID5.js +359 -0
  115. package/dist/ignite-WXEF2ID5.js.map +1 -0
  116. package/dist/index.d.ts +1341 -0
  117. package/dist/index.js +3058 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/init-RHACUR4E.js +123 -0
  120. package/dist/init-RHACUR4E.js.map +1 -0
  121. package/dist/installation-detector-VARGFFRZ.js +11 -0
  122. package/dist/installation-detector-VARGFFRZ.js.map +1 -0
  123. package/dist/logger-MKYH4UDV.js +12 -0
  124. package/dist/logger-MKYH4UDV.js.map +1 -0
  125. package/dist/mcp/chunk-6SDFJ42P.js +62 -0
  126. package/dist/mcp/chunk-6SDFJ42P.js.map +1 -0
  127. package/dist/mcp/claude-YHHHLSXH.js +249 -0
  128. package/dist/mcp/claude-YHHHLSXH.js.map +1 -0
  129. package/dist/mcp/color-QS5BFCNN.js +168 -0
  130. package/dist/mcp/color-QS5BFCNN.js.map +1 -0
  131. package/dist/mcp/github-comment-server.js +165 -0
  132. package/dist/mcp/github-comment-server.js.map +1 -0
  133. package/dist/mcp/terminal-SDCMDVD7.js +202 -0
  134. package/dist/mcp/terminal-SDCMDVD7.js.map +1 -0
  135. package/dist/open-X6BTENPV.js +278 -0
  136. package/dist/open-X6BTENPV.js.map +1 -0
  137. package/dist/prompt-ANTQWHUF.js +13 -0
  138. package/dist/prompt-ANTQWHUF.js.map +1 -0
  139. package/dist/prompts/issue-prompt.txt +230 -0
  140. package/dist/prompts/pr-prompt.txt +35 -0
  141. package/dist/prompts/regular-prompt.txt +14 -0
  142. package/dist/run-2JCPQAX3.js +278 -0
  143. package/dist/run-2JCPQAX3.js.map +1 -0
  144. package/dist/schema/settings.schema.json +221 -0
  145. package/dist/start-LWVRBJ6S.js +982 -0
  146. package/dist/start-LWVRBJ6S.js.map +1 -0
  147. package/dist/terminal-3D6TUAKJ.js +16 -0
  148. package/dist/terminal-3D6TUAKJ.js.map +1 -0
  149. package/dist/test-git-XPF4SZXJ.js +52 -0
  150. package/dist/test-git-XPF4SZXJ.js.map +1 -0
  151. package/dist/test-prefix-XGFXFAYN.js +68 -0
  152. package/dist/test-prefix-XGFXFAYN.js.map +1 -0
  153. package/dist/test-tabs-JRKY3QMM.js +69 -0
  154. package/dist/test-tabs-JRKY3QMM.js.map +1 -0
  155. package/dist/test-webserver-M2I3EV4J.js +62 -0
  156. package/dist/test-webserver-M2I3EV4J.js.map +1 -0
  157. package/dist/update-3ZT2XX2G.js +79 -0
  158. package/dist/update-3ZT2XX2G.js.map +1 -0
  159. package/dist/update-notifier-QSSEB5KC.js +11 -0
  160. package/dist/update-notifier-QSSEB5KC.js.map +1 -0
  161. package/package.json +113 -0
@@ -0,0 +1,384 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ promptConfirmation
4
+ } from "./chunk-JNKJ7NJV.js";
5
+ import {
6
+ createLogger
7
+ } from "./chunk-GEHQXLEI.js";
8
+
9
+ // src/lib/providers/NeonProvider.ts
10
+ import { execa } from "execa";
11
+ var logger = createLogger({ prefix: "\u{1F5C2}\uFE0F" });
12
+ function validateNeonConfig(config) {
13
+ if (!config.projectId) {
14
+ return {
15
+ valid: false,
16
+ error: "NEON_PROJECT_ID is required"
17
+ };
18
+ }
19
+ if (!config.parentBranch) {
20
+ return {
21
+ valid: false,
22
+ error: "NEON_PARENT_BRANCH is required"
23
+ };
24
+ }
25
+ if (!/^[a-zA-Z0-9-]+$/.test(config.projectId)) {
26
+ return {
27
+ valid: false,
28
+ error: "NEON_PROJECT_ID contains invalid characters"
29
+ };
30
+ }
31
+ return { valid: true };
32
+ }
33
+ var NeonProvider = class {
34
+ constructor(config) {
35
+ this.config = config;
36
+ this._isConfigured = false;
37
+ logger.debug("NeonProvider initialized with config:", {
38
+ projectId: config.projectId,
39
+ parentBranch: config.parentBranch,
40
+ hasProjectId: !!config.projectId,
41
+ hasParentBranch: !!config.parentBranch
42
+ });
43
+ const validation = validateNeonConfig(config);
44
+ if (!validation.valid) {
45
+ logger.debug(`NeonProvider not configured: ${validation.error}`);
46
+ logger.debug("Neon database branching will not be used");
47
+ this._isConfigured = false;
48
+ } else {
49
+ this._isConfigured = true;
50
+ }
51
+ }
52
+ /**
53
+ * Check if provider is properly configured
54
+ * Returns true if NEON_PROJECT_ID and NEON_PARENT_BRANCH are set
55
+ */
56
+ isConfigured() {
57
+ return this._isConfigured;
58
+ }
59
+ /**
60
+ * Execute a Neon CLI command and return stdout
61
+ * Throws an error if the command fails
62
+ *
63
+ * @param args - Command arguments to pass to neon CLI
64
+ * @param cwd - Optional working directory to run the command from (defaults to current directory)
65
+ */
66
+ async executeNeonCommand(args, cwd) {
67
+ if (!this._isConfigured) {
68
+ throw new Error("NeonProvider is not configured. Check NEON_PROJECT_ID and NEON_PARENT_BRANCH environment variables.");
69
+ }
70
+ const command = `neon ${args.join(" ")}`;
71
+ logger.debug(`Executing Neon CLI command: ${command}`);
72
+ logger.debug(`Project ID being used: ${this.config.projectId}`);
73
+ if (cwd) {
74
+ logger.debug(`Working directory: ${cwd}`);
75
+ }
76
+ const result = await execa("neon", args, {
77
+ timeout: 3e4,
78
+ encoding: "utf8",
79
+ stdio: "pipe",
80
+ ...cwd && { cwd }
81
+ });
82
+ return result.stdout;
83
+ }
84
+ /**
85
+ * Check if neon CLI is available
86
+ * Ports: check_neon_cli() from bash/utils/neon-utils.sh:18-23
87
+ */
88
+ async isCliAvailable() {
89
+ try {
90
+ await execa("command", ["-v", "neon"], {
91
+ timeout: 5e3,
92
+ shell: true
93
+ });
94
+ return true;
95
+ } catch {
96
+ return false;
97
+ }
98
+ }
99
+ /**
100
+ * Check if user is authenticated with Neon CLI
101
+ * Ports: check_neon_auth() from bash/utils/neon-utils.sh:25-36
102
+ *
103
+ * @param cwd - Optional working directory to run the command from (prevents issues with deleted directories)
104
+ * @throws Error if authentication check fails for reasons other than not being authenticated
105
+ */
106
+ async isAuthenticated(cwd) {
107
+ var _a;
108
+ const cliAvailable = await this.isCliAvailable();
109
+ if (!cliAvailable) {
110
+ return false;
111
+ }
112
+ try {
113
+ await execa("neon", ["me"], {
114
+ timeout: 1e4,
115
+ stdio: "pipe",
116
+ ...cwd && { cwd }
117
+ });
118
+ return true;
119
+ } catch (error) {
120
+ const execaError = error;
121
+ const stderr = ((_a = execaError.stderr) == null ? void 0 : _a.trim()) ?? "";
122
+ const isAuthError = stderr.toLowerCase().includes("not authenticated") || stderr.toLowerCase().includes("not logged in") || stderr.toLowerCase().includes("authentication required") || stderr.toLowerCase().includes("login required");
123
+ if (isAuthError) {
124
+ return false;
125
+ }
126
+ throw error;
127
+ }
128
+ }
129
+ /**
130
+ * Sanitize branch name for Neon (replace slashes with underscores)
131
+ * Ports: sanitize_neon_branch_name() from bash/utils/neon-utils.sh:11-15
132
+ */
133
+ sanitizeBranchName(branchName) {
134
+ return branchName.replace(/\//g, "_");
135
+ }
136
+ /**
137
+ * Extract endpoint ID from Neon connection string
138
+ * Pattern matches: ep-abc-123 or ep-abc-123-pooler
139
+ * Returns: ep-abc-123 (without -pooler suffix)
140
+ * Used by: get_neon_branch_name() from bash/utils/neon-utils.sh:294
141
+ */
142
+ extractEndpointId(connectionString) {
143
+ const hostMatch = connectionString.match(/@(ep-[a-z0-9-]+)\./);
144
+ if (!(hostMatch == null ? void 0 : hostMatch[1])) {
145
+ return null;
146
+ }
147
+ const fullEndpoint = hostMatch[1];
148
+ return fullEndpoint.replace(/-pooler$/, "");
149
+ }
150
+ /**
151
+ * List all branches in the Neon project
152
+ * Ports: list_neon_branches() from bash/utils/neon-utils.sh:63-74
153
+ *
154
+ * @param cwd - Optional working directory to run commands from
155
+ */
156
+ async listBranches(cwd) {
157
+ const output = await this.executeNeonCommand([
158
+ "branches",
159
+ "list",
160
+ "--project-id",
161
+ this.config.projectId,
162
+ "--output",
163
+ "json"
164
+ ], cwd);
165
+ const branches = JSON.parse(output);
166
+ return branches.map((branch) => branch.name);
167
+ }
168
+ /**
169
+ * Check if a branch exists
170
+ * Ports: check_neon_branch_exists() from bash/utils/neon-utils.sh:38-61
171
+ *
172
+ * @param name - Branch name to check
173
+ * @param cwd - Optional working directory to run commands from
174
+ */
175
+ async branchExists(name, cwd) {
176
+ const branches = await this.listBranches(cwd);
177
+ return branches.includes(name);
178
+ }
179
+ /**
180
+ * Get connection string for a specific branch
181
+ * Ports: get_neon_connection_string() from bash/utils/neon-utils.sh:76-90
182
+ *
183
+ * @param branch - Branch name to get connection string for
184
+ * @param cwd - Optional working directory to run commands from
185
+ */
186
+ async getConnectionString(branch, cwd) {
187
+ const connectionString = await this.executeNeonCommand([
188
+ "connection-string",
189
+ "--branch",
190
+ branch,
191
+ "--project-id",
192
+ this.config.projectId
193
+ ], cwd);
194
+ return connectionString.trim();
195
+ }
196
+ /**
197
+ * Find Vercel preview database branch
198
+ * Checks for both patterns: preview/<branch> and preview_<sanitized-branch>
199
+ * Ports: find_preview_database_branch() from bash/utils/neon-utils.sh:92-124
200
+ *
201
+ * @param branchName - Branch name to find preview for
202
+ * @param cwd - Optional working directory to run commands from
203
+ */
204
+ async findPreviewBranch(branchName, cwd) {
205
+ const slashPattern = `preview/${branchName}`;
206
+ if (await this.branchExists(slashPattern, cwd)) {
207
+ logger.info(`Found Vercel preview database: ${slashPattern}`);
208
+ return slashPattern;
209
+ }
210
+ const sanitized = this.sanitizeBranchName(branchName);
211
+ const underscorePattern = `preview_${sanitized}`;
212
+ if (await this.branchExists(underscorePattern, cwd)) {
213
+ logger.info(`Found Vercel preview database: ${underscorePattern}`);
214
+ return underscorePattern;
215
+ }
216
+ return null;
217
+ }
218
+ /**
219
+ * Create a new database branch
220
+ * ALWAYS checks for Vercel preview database first
221
+ * Returns connection string for the branch
222
+ * Ports: create_neon_database_branch() from bash/utils/neon-utils.sh:126-187
223
+ *
224
+ * @param name - Name for the new branch
225
+ * @param fromBranch - Parent branch to create from (defaults to config.parentBranch)
226
+ * @param cwd - Optional working directory to run commands from
227
+ */
228
+ async createBranch(name, fromBranch, cwd) {
229
+ const previewBranch = await this.findPreviewBranch(name, cwd);
230
+ if (previewBranch) {
231
+ const connectionString2 = await this.getConnectionString(previewBranch, cwd);
232
+ logger.success(`Using existing Vercel preview database: ${previewBranch}`);
233
+ return connectionString2;
234
+ }
235
+ const sanitizedName = this.sanitizeBranchName(name);
236
+ const parentBranch = fromBranch ?? this.config.parentBranch;
237
+ logger.info("Creating Neon database branch...");
238
+ logger.info(` Source branch: ${parentBranch}`);
239
+ logger.info(` New branch: ${sanitizedName}`);
240
+ await this.executeNeonCommand([
241
+ "branches",
242
+ "create",
243
+ "--name",
244
+ sanitizedName,
245
+ "--parent",
246
+ parentBranch,
247
+ "--project-id",
248
+ this.config.projectId
249
+ ], cwd);
250
+ logger.success("Database branch created successfully");
251
+ logger.info("Getting connection string for new database branch...");
252
+ const connectionString = await this.getConnectionString(sanitizedName, cwd);
253
+ return connectionString;
254
+ }
255
+ /**
256
+ * Delete a database branch
257
+ * Includes preview database protection with user confirmation
258
+ * Ports: delete_neon_database_branch() from bash/utils/neon-utils.sh:204-259
259
+ *
260
+ * @param name - Name of the branch to delete
261
+ * @param isPreview - Whether this is a preview database branch
262
+ * @param cwd - Optional working directory to run commands from (prevents issues with deleted directories)
263
+ */
264
+ async deleteBranch(name, isPreview = false, cwd) {
265
+ const sanitizedName = this.sanitizeBranchName(name);
266
+ if (isPreview) {
267
+ const previewBranch = await this.findPreviewBranch(name, cwd);
268
+ if (previewBranch) {
269
+ logger.warn(`Found Vercel preview database: ${previewBranch}`);
270
+ logger.warn("Preview databases are managed by Vercel and will be cleaned up automatically");
271
+ logger.warn("Manual deletion may interfere with Vercel's preview deployments");
272
+ const confirmed = await promptConfirmation(
273
+ "Delete preview database anyway?",
274
+ false
275
+ );
276
+ if (confirmed) {
277
+ try {
278
+ logger.info(`Deleting Vercel preview database: ${previewBranch}`);
279
+ await this.executeNeonCommand([
280
+ "branches",
281
+ "delete",
282
+ previewBranch,
283
+ "--project-id",
284
+ this.config.projectId
285
+ ], cwd);
286
+ logger.success("Preview database deleted successfully");
287
+ return {
288
+ success: true,
289
+ deleted: true,
290
+ notFound: false,
291
+ branchName: previewBranch
292
+ };
293
+ } catch (error) {
294
+ const errorMessage = error instanceof Error ? error.message : String(error);
295
+ logger.error(`Failed to delete preview database: ${errorMessage}`);
296
+ return {
297
+ success: false,
298
+ deleted: false,
299
+ notFound: false,
300
+ error: errorMessage,
301
+ branchName: previewBranch
302
+ };
303
+ }
304
+ } else {
305
+ logger.info("Skipping preview database deletion");
306
+ return {
307
+ success: true,
308
+ deleted: false,
309
+ notFound: false,
310
+ userDeclined: true,
311
+ branchName: previewBranch
312
+ };
313
+ }
314
+ }
315
+ }
316
+ logger.info(`Checking for Neon database branch: ${sanitizedName}`);
317
+ try {
318
+ const exists = await this.branchExists(sanitizedName, cwd);
319
+ if (!exists) {
320
+ logger.info(`No database branch found for '${name}'`);
321
+ return {
322
+ success: true,
323
+ deleted: false,
324
+ notFound: true,
325
+ branchName: sanitizedName
326
+ };
327
+ }
328
+ logger.info(`Deleting Neon database branch: ${sanitizedName}`);
329
+ await this.executeNeonCommand([
330
+ "branches",
331
+ "delete",
332
+ sanitizedName,
333
+ "--project-id",
334
+ this.config.projectId
335
+ ], cwd);
336
+ logger.success("Database branch deleted successfully");
337
+ return {
338
+ success: true,
339
+ deleted: true,
340
+ notFound: false,
341
+ branchName: sanitizedName
342
+ };
343
+ } catch (error) {
344
+ const errorMessage = error instanceof Error ? error.message : String(error);
345
+ logger.error(`Failed to delete database branch: ${errorMessage}`);
346
+ return {
347
+ success: false,
348
+ deleted: false,
349
+ notFound: false,
350
+ error: errorMessage,
351
+ branchName: sanitizedName
352
+ };
353
+ }
354
+ }
355
+ /**
356
+ * Get branch name from endpoint ID (reverse lookup)
357
+ * Searches all branches to find one with matching endpoint
358
+ * Ports: get_neon_branch_name() from bash/utils/neon-utils.sh:262-308
359
+ *
360
+ * @param endpointId - Endpoint ID to search for
361
+ * @param cwd - Optional working directory to run commands from
362
+ */
363
+ async getBranchNameFromEndpoint(endpointId, cwd) {
364
+ const branches = await this.listBranches(cwd);
365
+ for (const branch of branches) {
366
+ try {
367
+ const connectionString = await this.getConnectionString(branch, cwd);
368
+ const branchEndpointId = this.extractEndpointId(connectionString);
369
+ if (branchEndpointId === endpointId) {
370
+ return branch;
371
+ }
372
+ } catch {
373
+ continue;
374
+ }
375
+ }
376
+ return null;
377
+ }
378
+ };
379
+
380
+ export {
381
+ validateNeonConfig,
382
+ NeonProvider
383
+ };
384
+ //# sourceMappingURL=chunk-YYSKGAZT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/providers/NeonProvider.ts"],"sourcesContent":["import { execa, type ExecaError } from 'execa'\nimport type { DatabaseProvider } from '../../types/index.js'\nimport { createLogger } from '../../utils/logger.js'\nimport { promptConfirmation } from '../../utils/prompt.js'\n\nconst logger = createLogger({ prefix: '🗂️' })\n\ninterface NeonBranch {\n name: string\n id: string\n [key: string]: unknown\n}\n\nexport interface NeonConfig {\n projectId: string\n parentBranch: string\n}\n\n/**\n * Validate Neon configuration\n * Checks that required configuration values are present\n */\nexport function validateNeonConfig(config: {\n projectId?: string\n parentBranch?: string\n}): { valid: boolean; error?: string } {\n if (!config.projectId) {\n return {\n valid: false,\n error: 'NEON_PROJECT_ID is required',\n }\n }\n\n if (!config.parentBranch) {\n return {\n valid: false,\n error: 'NEON_PARENT_BRANCH is required',\n }\n }\n\n // Basic validation for project ID format (should start with appropriate prefix)\n if (!/^[a-zA-Z0-9-]+$/.test(config.projectId)) {\n return {\n valid: false,\n error: 'NEON_PROJECT_ID contains invalid characters',\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Neon database provider implementation\n * Ports functionality from bash/utils/neon-utils.sh\n */\nexport class NeonProvider implements DatabaseProvider {\n private _isConfigured: boolean = false\n\n constructor(private config: NeonConfig) {\n logger.debug('NeonProvider initialized with config:', {\n projectId: config.projectId,\n parentBranch: config.parentBranch,\n hasProjectId: !!config.projectId,\n hasParentBranch: !!config.parentBranch,\n })\n\n // Validate config but don't throw - just mark as not configured\n // This allows the provider to be instantiated even when Neon is not being used\n const validation = validateNeonConfig(config)\n if (!validation.valid) {\n logger.debug(`NeonProvider not configured: ${validation.error}`)\n logger.debug('Neon database branching will not be used')\n this._isConfigured = false\n } else {\n this._isConfigured = true\n }\n }\n\n /**\n * Check if provider is properly configured\n * Returns true if NEON_PROJECT_ID and NEON_PARENT_BRANCH are set\n */\n isConfigured(): boolean {\n return this._isConfigured\n }\n\n /**\n * Execute a Neon CLI command and return stdout\n * Throws an error if the command fails\n *\n * @param args - Command arguments to pass to neon CLI\n * @param cwd - Optional working directory to run the command from (defaults to current directory)\n */\n private async executeNeonCommand(args: string[], cwd?: string): Promise<string> {\n // Check if provider is properly configured\n if (!this._isConfigured) {\n throw new Error('NeonProvider is not configured. Check NEON_PROJECT_ID and NEON_PARENT_BRANCH environment variables.')\n }\n\n // Log the exact command being executed for debugging\n const command = `neon ${args.join(' ')}`\n logger.debug(`Executing Neon CLI command: ${command}`)\n logger.debug(`Project ID being used: ${this.config.projectId}`)\n if (cwd) {\n logger.debug(`Working directory: ${cwd}`)\n }\n\n const result = await execa('neon', args, {\n timeout: 30000,\n encoding: 'utf8',\n stdio: 'pipe',\n ...(cwd && { cwd }),\n })\n return result.stdout\n }\n\n /**\n * Check if neon CLI is available\n * Ports: check_neon_cli() from bash/utils/neon-utils.sh:18-23\n */\n async isCliAvailable(): Promise<boolean> {\n try {\n await execa('command', ['-v', 'neon'], {\n timeout: 5000,\n shell: true,\n })\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Check if user is authenticated with Neon CLI\n * Ports: check_neon_auth() from bash/utils/neon-utils.sh:25-36\n *\n * @param cwd - Optional working directory to run the command from (prevents issues with deleted directories)\n * @throws Error if authentication check fails for reasons other than not being authenticated\n */\n async isAuthenticated(cwd?: string): Promise<boolean> {\n const cliAvailable = await this.isCliAvailable()\n if (!cliAvailable) {\n return false\n }\n\n try {\n await execa('neon', ['me'], {\n timeout: 10000,\n stdio: 'pipe',\n ...(cwd && { cwd }),\n })\n return true\n } catch (error) {\n const execaError = error as ExecaError\n const stderr = execaError.stderr?.trim() ?? ''\n\n // Check for authentication failure patterns (should return false, not throw)\n const isAuthError =\n stderr.toLowerCase().includes('not authenticated') ||\n stderr.toLowerCase().includes('not logged in') ||\n stderr.toLowerCase().includes('authentication required') ||\n stderr.toLowerCase().includes('login required')\n\n if (isAuthError) {\n return false\n }\n\n // For any other error, let it bubble up\n throw error\n }\n }\n\n /**\n * Sanitize branch name for Neon (replace slashes with underscores)\n * Ports: sanitize_neon_branch_name() from bash/utils/neon-utils.sh:11-15\n */\n sanitizeBranchName(branchName: string): string {\n return branchName.replace(/\\//g, '_')\n }\n\n /**\n * Extract endpoint ID from Neon connection string\n * Pattern matches: ep-abc-123 or ep-abc-123-pooler\n * Returns: ep-abc-123 (without -pooler suffix)\n * Used by: get_neon_branch_name() from bash/utils/neon-utils.sh:294\n */\n private extractEndpointId(connectionString: string): string | null {\n // First, extract the full host part between @ and first dot\n // Examples:\n // @ep-abc123.us-east-1.neon.tech -> ep-abc123\n // @ep-abc123-pooler.us-east-1.neon.tech -> ep-abc123-pooler\n const hostMatch = connectionString.match(/@(ep-[a-z0-9-]+)\\./)\n if (!hostMatch?.[1]) {\n return null\n }\n\n const fullEndpoint = hostMatch[1]\n // Remove -pooler suffix if present\n return fullEndpoint.replace(/-pooler$/, '')\n }\n\n /**\n * List all branches in the Neon project\n * Ports: list_neon_branches() from bash/utils/neon-utils.sh:63-74\n *\n * @param cwd - Optional working directory to run commands from\n */\n async listBranches(cwd?: string): Promise<string[]> {\n const output = await this.executeNeonCommand([\n 'branches',\n 'list',\n '--project-id',\n this.config.projectId,\n '--output',\n 'json',\n ], cwd)\n\n const branches: NeonBranch[] = JSON.parse(output)\n return branches.map(branch => branch.name)\n }\n\n /**\n * Check if a branch exists\n * Ports: check_neon_branch_exists() from bash/utils/neon-utils.sh:38-61\n *\n * @param name - Branch name to check\n * @param cwd - Optional working directory to run commands from\n */\n async branchExists(name: string, cwd?: string): Promise<boolean> {\n const branches = await this.listBranches(cwd)\n return branches.includes(name)\n }\n\n /**\n * Get connection string for a specific branch\n * Ports: get_neon_connection_string() from bash/utils/neon-utils.sh:76-90\n *\n * @param branch - Branch name to get connection string for\n * @param cwd - Optional working directory to run commands from\n */\n async getConnectionString(branch: string, cwd?: string): Promise<string> {\n const connectionString = await this.executeNeonCommand([\n 'connection-string',\n '--branch',\n branch,\n '--project-id',\n this.config.projectId,\n ], cwd)\n return connectionString.trim()\n }\n\n /**\n * Find Vercel preview database branch\n * Checks for both patterns: preview/<branch> and preview_<sanitized-branch>\n * Ports: find_preview_database_branch() from bash/utils/neon-utils.sh:92-124\n *\n * @param branchName - Branch name to find preview for\n * @param cwd - Optional working directory to run commands from\n */\n async findPreviewBranch(branchName: string, cwd?: string): Promise<string | null> {\n // Check for exact preview branch match with slash pattern\n const slashPattern = `preview/${branchName}`\n if (await this.branchExists(slashPattern, cwd)) {\n logger.info(`Found Vercel preview database: ${slashPattern}`)\n return slashPattern\n }\n\n // Check for underscore pattern variation\n const sanitized = this.sanitizeBranchName(branchName)\n const underscorePattern = `preview_${sanitized}`\n if (await this.branchExists(underscorePattern, cwd)) {\n logger.info(`Found Vercel preview database: ${underscorePattern}`)\n return underscorePattern\n }\n\n return null\n }\n\n /**\n * Create a new database branch\n * ALWAYS checks for Vercel preview database first\n * Returns connection string for the branch\n * Ports: create_neon_database_branch() from bash/utils/neon-utils.sh:126-187\n *\n * @param name - Name for the new branch\n * @param fromBranch - Parent branch to create from (defaults to config.parentBranch)\n * @param cwd - Optional working directory to run commands from\n */\n async createBranch(name: string, fromBranch?: string, cwd?: string): Promise<string> {\n // Always check for existing Vercel preview database first (lines 149-158)\n const previewBranch = await this.findPreviewBranch(name, cwd)\n if (previewBranch) {\n const connectionString = await this.getConnectionString(previewBranch, cwd)\n logger.success(`Using existing Vercel preview database: ${previewBranch}`)\n return connectionString\n }\n\n // Sanitize branch name for Neon (replace slashes with underscores)\n const sanitizedName = this.sanitizeBranchName(name)\n const parentBranch = fromBranch ?? this.config.parentBranch\n\n logger.info('Creating Neon database branch...')\n logger.info(` Source branch: ${parentBranch}`)\n logger.info(` New branch: ${sanitizedName}`)\n\n // Create the database branch\n await this.executeNeonCommand([\n 'branches',\n 'create',\n '--name',\n sanitizedName,\n '--parent',\n parentBranch,\n '--project-id',\n this.config.projectId,\n ], cwd)\n\n logger.success('Database branch created successfully')\n\n // Get the connection string for the new branch\n logger.info('Getting connection string for new database branch...')\n const connectionString = await this.getConnectionString(sanitizedName, cwd)\n\n return connectionString\n }\n\n /**\n * Delete a database branch\n * Includes preview database protection with user confirmation\n * Ports: delete_neon_database_branch() from bash/utils/neon-utils.sh:204-259\n *\n * @param name - Name of the branch to delete\n * @param isPreview - Whether this is a preview database branch\n * @param cwd - Optional working directory to run commands from (prevents issues with deleted directories)\n */\n async deleteBranch(name: string, isPreview: boolean = false, cwd?: string): Promise<import('../../types/index.js').DatabaseDeletionResult> {\n // Sanitize branch name for Neon\n const sanitizedName = this.sanitizeBranchName(name)\n\n // For preview contexts, check for preview databases first\n if (isPreview) {\n const previewBranch = await this.findPreviewBranch(name, cwd)\n if (previewBranch) {\n logger.warn(`Found Vercel preview database: ${previewBranch}`)\n logger.warn('Preview databases are managed by Vercel and will be cleaned up automatically')\n logger.warn('Manual deletion may interfere with Vercel\\'s preview deployments')\n\n const confirmed = await promptConfirmation(\n 'Delete preview database anyway?',\n false\n )\n\n if (confirmed) {\n // User confirmed - delete preview branch\n try {\n logger.info(`Deleting Vercel preview database: ${previewBranch}`)\n await this.executeNeonCommand([\n 'branches',\n 'delete',\n previewBranch,\n '--project-id',\n this.config.projectId,\n ], cwd)\n logger.success('Preview database deleted successfully')\n return {\n success: true,\n deleted: true,\n notFound: false,\n branchName: previewBranch\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error(`Failed to delete preview database: ${errorMessage}`)\n return {\n success: false,\n deleted: false,\n notFound: false,\n error: errorMessage,\n branchName: previewBranch\n }\n }\n } else {\n // User declined deletion\n logger.info('Skipping preview database deletion')\n return {\n success: true,\n deleted: false,\n notFound: false,\n userDeclined: true,\n branchName: previewBranch\n }\n }\n }\n // If no preview database found, fall through to check regular branch\n }\n\n // Check for regular branch\n logger.info(`Checking for Neon database branch: ${sanitizedName}`)\n\n try {\n const exists = await this.branchExists(sanitizedName, cwd)\n\n if (!exists) {\n logger.info(`No database branch found for '${name}'`)\n return {\n success: true,\n deleted: false,\n notFound: true,\n branchName: sanitizedName\n }\n }\n\n // Branch exists - delete it\n logger.info(`Deleting Neon database branch: ${sanitizedName}`)\n await this.executeNeonCommand([\n 'branches',\n 'delete',\n sanitizedName,\n '--project-id',\n this.config.projectId,\n ], cwd)\n logger.success('Database branch deleted successfully')\n\n return {\n success: true,\n deleted: true,\n notFound: false,\n branchName: sanitizedName\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n logger.error(`Failed to delete database branch: ${errorMessage}`)\n return {\n success: false,\n deleted: false,\n notFound: false,\n error: errorMessage,\n branchName: sanitizedName\n }\n }\n }\n\n /**\n * Get branch name from endpoint ID (reverse lookup)\n * Searches all branches to find one with matching endpoint\n * Ports: get_neon_branch_name() from bash/utils/neon-utils.sh:262-308\n *\n * @param endpointId - Endpoint ID to search for\n * @param cwd - Optional working directory to run commands from\n */\n async getBranchNameFromEndpoint(endpointId: string, cwd?: string): Promise<string | null> {\n const branches = await this.listBranches(cwd)\n\n for (const branch of branches) {\n try {\n const connectionString = await this.getConnectionString(branch, cwd)\n const branchEndpointId = this.extractEndpointId(connectionString)\n\n if (branchEndpointId === endpointId) {\n return branch\n }\n } catch {\n // Skip branches that fail to get connection string\n continue\n }\n }\n\n return null\n }\n}\n"],"mappings":"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","names":["connectionString"]}
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ logger_default
4
+ } from "./chunk-GEHQXLEI.js";
5
+
6
+ // src/utils/color.ts
7
+ import { createHash } from "crypto";
8
+ function getColorPalette() {
9
+ return [
10
+ // First 10 colors preserved for backward compatibility
11
+ { r: 220, g: 235, b: 248 },
12
+ // 0: Soft blue
13
+ { r: 248, g: 220, b: 235 },
14
+ // 1: Soft pink
15
+ { r: 220, g: 248, b: 235 },
16
+ // 2: Soft green
17
+ { r: 248, g: 240, b: 220 },
18
+ // 3: Soft cream
19
+ { r: 240, g: 220, b: 248 },
20
+ // 4: Soft lavender
21
+ { r: 220, g: 240, b: 248 },
22
+ // 5: Soft cyan
23
+ { r: 235, g: 235, b: 235 },
24
+ // 6: Soft grey
25
+ { r: 228, g: 238, b: 248 },
26
+ // 7: Soft ice blue
27
+ { r: 248, g: 228, b: 238 },
28
+ // 8: Soft rose
29
+ { r: 228, g: 248, b: 238 },
30
+ // 9: Soft mint
31
+ // 30 new colors (indices 10-39)
32
+ { r: 235, g: 245, b: 250 },
33
+ // 10: Pale sky blue
34
+ { r: 250, g: 235, b: 245 },
35
+ // 11: Pale orchid
36
+ { r: 235, g: 250, b: 245 },
37
+ // 12: Pale seafoam
38
+ { r: 250, g: 245, b: 235 },
39
+ // 13: Pale peach
40
+ { r: 245, g: 235, b: 250 },
41
+ // 14: Pale periwinkle
42
+ { r: 235, g: 245, b: 235 },
43
+ // 15: Pale sage
44
+ { r: 245, g: 250, b: 235 },
45
+ // 16: Pale lemon
46
+ { r: 245, g: 235, b: 235 },
47
+ // 17: Pale blush
48
+ { r: 235, g: 235, b: 250 },
49
+ // 18: Pale lavender blue
50
+ { r: 250, g: 235, b: 235 },
51
+ // 19: Pale coral
52
+ { r: 235, g: 250, b: 250 },
53
+ // 20: Pale aqua
54
+ { r: 240, g: 248, b: 255 },
55
+ // 21: Alice blue
56
+ { r: 255, g: 240, b: 248 },
57
+ // 22: Lavender blush
58
+ { r: 240, g: 255, b: 248 },
59
+ // 23: Honeydew tint
60
+ { r: 255, g: 248, b: 240 },
61
+ // 24: Antique white
62
+ { r: 248, g: 240, b: 255 },
63
+ // 25: Magnolia
64
+ { r: 240, g: 248, b: 240 },
65
+ // 26: Mint cream tint
66
+ { r: 248, g: 255, b: 240 },
67
+ // 27: Ivory tint
68
+ { r: 248, g: 240, b: 240 },
69
+ // 28: Misty rose tint
70
+ { r: 240, g: 240, b: 255 },
71
+ // 29: Ghost white tint
72
+ { r: 255, g: 245, b: 238 },
73
+ // 30: Seashell
74
+ { r: 245, g: 255, b: 250 },
75
+ // 31: Azure mist
76
+ { r: 250, g: 245, b: 255 },
77
+ // 32: Lilac mist
78
+ { r: 255, g: 250, b: 245 },
79
+ // 33: Snow peach
80
+ { r: 238, g: 245, b: 255 },
81
+ // 34: Powder blue
82
+ { r: 255, g: 238, b: 245 },
83
+ // 35: Pink lace
84
+ { r: 245, g: 255, b: 238 },
85
+ // 36: Pale lime
86
+ { r: 238, g: 255, b: 245 },
87
+ // 37: Pale turquoise
88
+ { r: 245, g: 238, b: 255 },
89
+ // 38: Pale violet
90
+ { r: 255, g: 245, b: 255 }
91
+ // 39: Pale magenta
92
+ ];
93
+ }
94
+ function rgbToHex(r, g, b) {
95
+ if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
96
+ throw new Error("RGB values must be between 0 and 255");
97
+ }
98
+ const rHex = r.toString(16).padStart(2, "0");
99
+ const gHex = g.toString(16).padStart(2, "0");
100
+ const bHex = b.toString(16).padStart(2, "0");
101
+ return `#${rHex}${gHex}${bHex}`;
102
+ }
103
+ function hexToRgb(hex) {
104
+ const cleanHex = hex.startsWith("#") ? hex.slice(1) : hex;
105
+ if (cleanHex.length !== 6 || !/^[0-9a-fA-F]{6}$/.test(cleanHex)) {
106
+ throw new Error("Invalid hex color format. Expected format: #RRGGBB or RRGGBB");
107
+ }
108
+ const r = parseInt(cleanHex.slice(0, 2), 16);
109
+ const g = parseInt(cleanHex.slice(2, 4), 16);
110
+ const b = parseInt(cleanHex.slice(4, 6), 16);
111
+ return { r, g, b };
112
+ }
113
+ function generateColorFromBranchName(branchName) {
114
+ const hash = createHash("sha256").update(branchName).digest("hex");
115
+ const hashPrefix = hash.slice(0, 8);
116
+ const palette = getColorPalette();
117
+ const hashAsInt = parseInt(hashPrefix, 16);
118
+ const index = hashAsInt % palette.length;
119
+ logger_default.debug(`[generateColorFromBranchName] Branch name: ${branchName}, Hash: ${hash}, Hash prefix: ${hashPrefix}, Hash as int: ${hashAsInt}, Index: ${index}`);
120
+ const rgb = palette[index];
121
+ if (!rgb) {
122
+ throw new Error(`Invalid color index: ${index}`);
123
+ }
124
+ const hex = rgbToHex(rgb.r, rgb.g, rgb.b);
125
+ return {
126
+ rgb,
127
+ hex,
128
+ index
129
+ };
130
+ }
131
+ function lightenColor(rgb, amount) {
132
+ const clamp = (value) => Math.min(255, Math.max(0, Math.round(value)));
133
+ return {
134
+ r: clamp(rgb.r + (255 - rgb.r) * amount),
135
+ g: clamp(rgb.g + (255 - rgb.g) * amount),
136
+ b: clamp(rgb.b + (255 - rgb.b) * amount)
137
+ };
138
+ }
139
+ function saturateColor(rgb, amount) {
140
+ const clamp = (value) => Math.min(255, Math.max(0, Math.round(value)));
141
+ const avg = (rgb.r + rgb.g + rgb.b) / 3;
142
+ return {
143
+ r: clamp(rgb.r + (rgb.r - avg) * amount),
144
+ g: clamp(rgb.g + (rgb.g - avg) * amount),
145
+ b: clamp(rgb.b + (rgb.b - avg) * amount)
146
+ };
147
+ }
148
+ function calculateForegroundColor(rgb) {
149
+ const toLinear = (channel) => {
150
+ const c = channel / 255;
151
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
152
+ };
153
+ const r = toLinear(rgb.r);
154
+ const g = toLinear(rgb.g);
155
+ const b = toLinear(rgb.b);
156
+ const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
157
+ return luminance > 0.5 ? "#000000" : "#ffffff";
158
+ }
159
+
160
+ export {
161
+ getColorPalette,
162
+ rgbToHex,
163
+ hexToRgb,
164
+ generateColorFromBranchName,
165
+ lightenColor,
166
+ saturateColor,
167
+ calculateForegroundColor
168
+ };
169
+ //# sourceMappingURL=chunk-ZZZWQGTS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/color.ts"],"sourcesContent":["import { createHash } from 'crypto'\nimport logger from './logger'\n\n/**\n * RGB color representation\n */\nexport interface RgbColor {\n\tr: number\n\tg: number\n\tb: number\n}\n\n/**\n * Complete color data with RGB, hex, and palette index\n */\nexport interface ColorData {\n\trgb: RgbColor\n\thex: string\n\tindex: number\n}\n\n/**\n * Get the predefined color palette (40 subtle, professional colors)\n * Matches the terminal color palette from bash/new-branch-workflow.sh\n *\n * @returns Array of 40 RGB colors\n */\nexport function getColorPalette(): RgbColor[] {\n\treturn [\n\t\t// First 10 colors preserved for backward compatibility\n\t\t{ r: 220, g: 235, b: 248 }, // 0: Soft blue\n\t\t{ r: 248, g: 220, b: 235 }, // 1: Soft pink\n\t\t{ r: 220, g: 248, b: 235 }, // 2: Soft green\n\t\t{ r: 248, g: 240, b: 220 }, // 3: Soft cream\n\t\t{ r: 240, g: 220, b: 248 }, // 4: Soft lavender\n\t\t{ r: 220, g: 240, b: 248 }, // 5: Soft cyan\n\t\t{ r: 235, g: 235, b: 235 }, // 6: Soft grey\n\t\t{ r: 228, g: 238, b: 248 }, // 7: Soft ice blue\n\t\t{ r: 248, g: 228, b: 238 }, // 8: Soft rose\n\t\t{ r: 228, g: 248, b: 238 }, // 9: Soft mint\n\t\t// 30 new colors (indices 10-39)\n\t\t{ r: 235, g: 245, b: 250 }, // 10: Pale sky blue\n\t\t{ r: 250, g: 235, b: 245 }, // 11: Pale orchid\n\t\t{ r: 235, g: 250, b: 245 }, // 12: Pale seafoam\n\t\t{ r: 250, g: 245, b: 235 }, // 13: Pale peach\n\t\t{ r: 245, g: 235, b: 250 }, // 14: Pale periwinkle\n\t\t{ r: 235, g: 245, b: 235 }, // 15: Pale sage\n\t\t{ r: 245, g: 250, b: 235 }, // 16: Pale lemon\n\t\t{ r: 245, g: 235, b: 235 }, // 17: Pale blush\n\t\t{ r: 235, g: 235, b: 250 }, // 18: Pale lavender blue\n\t\t{ r: 250, g: 235, b: 235 }, // 19: Pale coral\n\t\t{ r: 235, g: 250, b: 250 }, // 20: Pale aqua\n\t\t{ r: 240, g: 248, b: 255 }, // 21: Alice blue\n\t\t{ r: 255, g: 240, b: 248 }, // 22: Lavender blush\n\t\t{ r: 240, g: 255, b: 248 }, // 23: Honeydew tint\n\t\t{ r: 255, g: 248, b: 240 }, // 24: Antique white\n\t\t{ r: 248, g: 240, b: 255 }, // 25: Magnolia\n\t\t{ r: 240, g: 248, b: 240 }, // 26: Mint cream tint\n\t\t{ r: 248, g: 255, b: 240 }, // 27: Ivory tint\n\t\t{ r: 248, g: 240, b: 240 }, // 28: Misty rose tint\n\t\t{ r: 240, g: 240, b: 255 }, // 29: Ghost white tint\n\t\t{ r: 255, g: 245, b: 238 }, // 30: Seashell\n\t\t{ r: 245, g: 255, b: 250 }, // 31: Azure mist\n\t\t{ r: 250, g: 245, b: 255 }, // 32: Lilac mist\n\t\t{ r: 255, g: 250, b: 245 }, // 33: Snow peach\n\t\t{ r: 238, g: 245, b: 255 }, // 34: Powder blue\n\t\t{ r: 255, g: 238, b: 245 }, // 35: Pink lace\n\t\t{ r: 245, g: 255, b: 238 }, // 36: Pale lime\n\t\t{ r: 238, g: 255, b: 245 }, // 37: Pale turquoise\n\t\t{ r: 245, g: 238, b: 255 }, // 38: Pale violet\n\t\t{ r: 255, g: 245, b: 255 }, // 39: Pale magenta\n\t]\n}\n\n/**\n * Convert RGB values to hex color format\n *\n * @param r - Red value (0-255)\n * @param g - Green value (0-255)\n * @param b - Blue value (0-255)\n * @returns Hex color string (e.g., \"#dcebf8\")\n * @throws Error if RGB values are out of range\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n\t// Validate RGB values\n\tif (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {\n\t\tthrow new Error('RGB values must be between 0 and 255')\n\t}\n\n\t// Convert to hex and pad with zeros\n\tconst rHex = r.toString(16).padStart(2, '0')\n\tconst gHex = g.toString(16).padStart(2, '0')\n\tconst bHex = b.toString(16).padStart(2, '0')\n\n\treturn `#${rHex}${gHex}${bHex}`\n}\n\n/**\n * Convert hex color format to RGB values\n *\n * @param hex - Hex color string (with or without # prefix)\n * @returns RGB color object\n * @throws Error if hex format is invalid\n */\nexport function hexToRgb(hex: string): RgbColor {\n\t// Remove # prefix if present\n\tconst cleanHex = hex.startsWith('#') ? hex.slice(1) : hex\n\n\t// Validate format (must be exactly 6 hex characters)\n\tif (cleanHex.length !== 6 || !/^[0-9a-fA-F]{6}$/.test(cleanHex)) {\n\t\tthrow new Error('Invalid hex color format. Expected format: #RRGGBB or RRGGBB')\n\t}\n\n\t// Parse hex values\n\tconst r = parseInt(cleanHex.slice(0, 2), 16)\n\tconst g = parseInt(cleanHex.slice(2, 4), 16)\n\tconst b = parseInt(cleanHex.slice(4, 6), 16)\n\n\treturn { r, g, b }\n}\n\n/**\n * Generate deterministic color from branch name using SHA256 hash\n * Matches the bash implementation in bash/new-branch-workflow.sh\n *\n * @param branchName - Branch name to generate color from\n * @returns ColorData with RGB, hex, and palette index\n */\nexport function generateColorFromBranchName(branchName: string): ColorData {\n\t// Generate SHA256 hash of branch name\n\tconst hash = createHash('sha256').update(branchName).digest('hex')\n\n\t// Take first 8 hex characters and convert to index (0-39)\n\t// Matches bash: local index=$(( 0x$hash % ${#colors[@]} ))\n\tconst hashPrefix = hash.slice(0, 8)\n\tconst palette = getColorPalette()\n\tconst hashAsInt = parseInt(hashPrefix, 16)\n\tconst index = hashAsInt % palette.length\n\tlogger.debug(`[generateColorFromBranchName] Branch name: ${branchName}, Hash: ${hash}, Hash prefix: ${hashPrefix}, Hash as int: ${hashAsInt}, Index: ${index}`)\n\n\t// Get color from palette\n\tconst rgb = palette[index]\n\n\t// This should never happen as index is always in range [0, palette.length)\n\tif (!rgb) {\n\t\tthrow new Error(`Invalid color index: ${index}`)\n\t}\n\n\t// Convert to hex format\n\tconst hex = rgbToHex(rgb.r, rgb.g, rgb.b)\n\n\treturn {\n\t\trgb,\n\t\thex,\n\t\tindex,\n\t}\n}\n\n/**\n * Lighten a color by a given amount\n * Useful for creating slightly lighter variants for hover states\n *\n * @param rgb - RGB color to lighten\n * @param amount - Amount to lighten (0-1, where 0.1 = 10% lighter)\n * @returns Lightened RGB color\n */\nexport function lightenColor(rgb: RgbColor, amount: number): RgbColor {\n\tconst clamp = (value: number): number => Math.min(255, Math.max(0, Math.round(value)))\n\n\treturn {\n\t\tr: clamp(rgb.r + (255 - rgb.r) * amount),\n\t\tg: clamp(rgb.g + (255 - rgb.g) * amount),\n\t\tb: clamp(rgb.b + (255 - rgb.b) * amount),\n\t}\n}\n\n/**\n * Saturate a color by pushing it away from grey towards its dominant hue\n * Makes subtle colors more vivid while maintaining their hue\n *\n * @param rgb - RGB color to saturate\n * @param amount - Amount to saturate (0-1, where 0.4 = 40% more saturated)\n * @returns Saturated RGB color\n */\nexport function saturateColor(rgb: RgbColor, amount: number): RgbColor {\n\tconst clamp = (value: number): number => Math.min(255, Math.max(0, Math.round(value)))\n\n\t// Calculate average (grey point)\n\tconst avg = (rgb.r + rgb.g + rgb.b) / 3\n\n\t// Push each channel away from grey\n\treturn {\n\t\tr: clamp(rgb.r + (rgb.r - avg) * amount),\n\t\tg: clamp(rgb.g + (rgb.g - avg) * amount),\n\t\tb: clamp(rgb.b + (rgb.b - avg) * amount),\n\t}\n}\n\n/**\n * Calculate appropriate foreground color (black or white) for a given background\n * Uses relative luminance formula from WCAG 2.0\n *\n * @param rgb - Background RGB color\n * @returns '#000000' for light backgrounds, '#ffffff' for dark backgrounds\n */\nexport function calculateForegroundColor(rgb: RgbColor): string {\n\t// Convert RGB to relative luminance (WCAG 2.0 formula)\n\tconst toLinear = (channel: number): number => {\n\t\tconst c = channel / 255\n\t\treturn c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)\n\t}\n\n\tconst r = toLinear(rgb.r)\n\tconst g = toLinear(rgb.g)\n\tconst b = toLinear(rgb.b)\n\n\tconst luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b\n\n\t// Use black text for light backgrounds (luminance > 0.5)\n\t// Use white text for dark backgrounds\n\treturn luminance > 0.5 ? '#000000' : '#ffffff'\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ detectClaudeCli,
4
+ generateBranchName,
5
+ getClaudeVersion,
6
+ launchClaude,
7
+ launchClaudeInNewTerminalWindow
8
+ } from "./chunk-PXZBAC2M.js";
9
+ import "./chunk-GEHQXLEI.js";
10
+ export {
11
+ detectClaudeCli,
12
+ generateBranchName,
13
+ getClaudeVersion,
14
+ launchClaude,
15
+ launchClaudeInNewTerminalWindow
16
+ };
17
+ //# sourceMappingURL=claude-7LUVDZZ4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}