@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,1341 @@
1
+ import { z } from 'zod';
2
+
3
+ declare class WorkspaceManager {
4
+ }
5
+
6
+ /**
7
+ * Represents a Git worktree with all relevant metadata
8
+ */
9
+ interface GitWorktree {
10
+ /** Absolute path to the worktree directory */
11
+ path: string;
12
+ /** Branch name associated with the worktree */
13
+ branch: string;
14
+ /** Current commit SHA */
15
+ commit: string;
16
+ /** Whether this is the main worktree */
17
+ bare: boolean;
18
+ /** Whether this is a detached HEAD state */
19
+ detached: boolean;
20
+ /** Whether this worktree is locked */
21
+ locked: boolean;
22
+ /** Reason for lock if locked */
23
+ lockReason?: string;
24
+ }
25
+ /**
26
+ * Configuration for creating a new worktree
27
+ */
28
+ interface WorktreeCreateOptions {
29
+ /** Path where worktree should be created */
30
+ path: string;
31
+ /** Branch name to checkout/create */
32
+ branch: string;
33
+ /** Base branch to branch from (defaults to current branch) */
34
+ baseBranch?: string;
35
+ /** Whether to create a new branch */
36
+ createBranch?: boolean;
37
+ /** Whether to force creation (overwrite existing) */
38
+ force?: boolean;
39
+ }
40
+ /**
41
+ * Options for listing worktrees
42
+ */
43
+ interface WorktreeListOptions {
44
+ /** Include porcelain output format */
45
+ porcelain?: boolean;
46
+ /** Include verbose information */
47
+ verbose?: boolean;
48
+ }
49
+ /**
50
+ * Result of a worktree operation
51
+ * @deprecated Use exception-based error handling instead
52
+ */
53
+ interface WorktreeOperationResult {
54
+ /** Whether the operation was successful */
55
+ success: boolean;
56
+ /** Output message from Git command */
57
+ message: string;
58
+ /** Error message if operation failed */
59
+ error?: string;
60
+ /** Exit code from Git command */
61
+ exitCode: number;
62
+ }
63
+ /**
64
+ * Pattern matching for PR worktrees based on naming conventions
65
+ */
66
+ interface PRWorktreePattern {
67
+ /** Regex pattern to match PR branch names */
68
+ branchPattern: RegExp;
69
+ /** Regex pattern to match PR worktree paths */
70
+ pathPattern: RegExp;
71
+ /** Function to extract PR number from branch name */
72
+ extractPRNumber: (branchName: string) => number | null;
73
+ }
74
+ /**
75
+ * Worktree validation result
76
+ */
77
+ interface WorktreeValidation {
78
+ /** Whether the worktree is valid */
79
+ isValid: boolean;
80
+ /** List of validation issues found */
81
+ issues: string[];
82
+ /** Whether the worktree exists on disk */
83
+ existsOnDisk: boolean;
84
+ /** Whether the Git repository is valid */
85
+ isValidRepo: boolean;
86
+ /** Whether the branch reference is valid */
87
+ hasValidBranch: boolean;
88
+ }
89
+ /**
90
+ * Git worktree status information
91
+ */
92
+ interface WorktreeStatus {
93
+ /** Number of modified files */
94
+ modified: number;
95
+ /** Number of added/staged files */
96
+ staged: number;
97
+ /** Number of deleted files */
98
+ deleted: number;
99
+ /** Number of untracked files */
100
+ untracked: number;
101
+ /** Whether there are uncommitted changes */
102
+ hasChanges: boolean;
103
+ /** Current branch name */
104
+ branch: string;
105
+ /** Whether in detached HEAD state */
106
+ detached: boolean;
107
+ /** Commits ahead of upstream */
108
+ ahead: number;
109
+ /** Commits behind upstream */
110
+ behind: number;
111
+ }
112
+ /**
113
+ * Worktree cleanup options
114
+ */
115
+ interface WorktreeCleanupOptions {
116
+ /** Remove worktree directory from disk */
117
+ removeDirectory?: boolean;
118
+ /** Force removal even with uncommitted changes */
119
+ force?: boolean;
120
+ /** Remove associated branch if safe */
121
+ removeBranch?: boolean;
122
+ /** Dry run - show what would be done */
123
+ dryRun?: boolean;
124
+ }
125
+
126
+ /**
127
+ * Manages Git worktrees for the iloom CLI
128
+ * Ports functionality from bash scripts into TypeScript
129
+ */
130
+ declare class GitWorktreeManager {
131
+ private readonly _workingDirectory;
132
+ constructor(workingDirectory?: string);
133
+ /**
134
+ * Get the working directory for git operations (main worktree path)
135
+ */
136
+ get workingDirectory(): string;
137
+ /**
138
+ * List all worktrees in the repository
139
+ * Defaults to porcelain format for reliable machine parsing
140
+ * Equivalent to: git worktree list --porcelain
141
+ */
142
+ listWorktrees(options?: WorktreeListOptions): Promise<GitWorktree[]>;
143
+ /**
144
+ * Find worktree for a specific branch
145
+ * Ports: find_worktree_for_branch() from find-worktree-for-branch.sh
146
+ */
147
+ findWorktreeForBranch(branchName: string): Promise<GitWorktree | null>;
148
+ /**
149
+ * Check if a worktree is the main repository worktree
150
+ * The main worktree is the first one listed by git worktree list (Git guarantee)
151
+ * This cannot be determined by path comparison because --show-toplevel returns
152
+ * the same value for all worktrees.
153
+ */
154
+ isMainWorktree(worktree: GitWorktree): Promise<boolean>;
155
+ /**
156
+ * Check if a worktree is a PR worktree based on naming patterns
157
+ * Ports: is_pr_worktree() from worktree-utils.sh
158
+ */
159
+ isPRWorktree(worktree: GitWorktree): boolean;
160
+ /**
161
+ * Get PR number from worktree branch name
162
+ * Ports: get_pr_number_from_worktree() from worktree-utils.sh
163
+ */
164
+ getPRNumberFromWorktree(worktree: GitWorktree): number | null;
165
+ /**
166
+ * Create a new worktree
167
+ * Ports worktree creation logic from new-branch-workflow.sh
168
+ * @returns The absolute path to the created worktree
169
+ */
170
+ createWorktree(options: WorktreeCreateOptions): Promise<string>;
171
+ /**
172
+ * Remove a worktree and optionally clean up associated files
173
+ * Ports worktree removal logic from cleanup-worktree.sh
174
+ * @returns A message describing what was done (for dry-run mode)
175
+ */
176
+ removeWorktree(worktreePath: string, options?: WorktreeCleanupOptions): Promise<string | void>;
177
+ /**
178
+ * Validate worktree state and integrity
179
+ */
180
+ validateWorktree(worktreePath: string): Promise<WorktreeValidation>;
181
+ /**
182
+ * Get detailed status information for a worktree
183
+ */
184
+ getWorktreeStatus(worktreePath: string): Promise<WorktreeStatus>;
185
+ /**
186
+ * Generate a suggested worktree path for a branch
187
+ */
188
+ generateWorktreePath(branchName: string, customRoot?: string, options?: {
189
+ isPR?: boolean;
190
+ prNumber?: number;
191
+ prefix?: string;
192
+ }): string;
193
+ /**
194
+ * Sanitize a branch name for use as a directory name
195
+ * Replaces slashes with dashes and removes invalid filesystem characters
196
+ * Ports logic from bash script line 593: ${BRANCH_NAME//\\//-}
197
+ */
198
+ sanitizeBranchName(branchName: string): string;
199
+ /**
200
+ * Check if repository is in a valid state for worktree operations
201
+ */
202
+ isRepoReady(): Promise<boolean>;
203
+ /**
204
+ * Get repository information
205
+ */
206
+ getRepoInfo(): Promise<{
207
+ root: string | null;
208
+ defaultBranch: string;
209
+ currentBranch: string | null;
210
+ }>;
211
+ /**
212
+ * Prune stale worktree entries (worktrees that no longer exist on disk)
213
+ */
214
+ pruneWorktrees(): Promise<void>;
215
+ /**
216
+ * Lock a worktree to prevent it from being pruned or moved
217
+ */
218
+ lockWorktree(worktreePath: string, reason?: string): Promise<void>;
219
+ /**
220
+ * Unlock a previously locked worktree
221
+ */
222
+ unlockWorktree(worktreePath: string): Promise<void>;
223
+ /**
224
+ * Find worktrees matching an identifier (branch name, path, or PR number)
225
+ */
226
+ findWorktreesByIdentifier(identifier: string): Promise<GitWorktree[]>;
227
+ /**
228
+ * Find worktree for a specific issue number using exact pattern matching
229
+ * Matches: issue-{N} at start OR after /, -, _ (but NOT issue-{N}X where X is a digit)
230
+ * Supports patterns like: issue-44, feat/issue-44-feature, feat-issue-44, bugfix_issue-44, etc.
231
+ * Avoids false matches like: tissue-44, myissue-44
232
+ * Ports: find_existing_worktree() from bash script lines 131-165
233
+ */
234
+ findWorktreeForIssue(issueNumber: number): Promise<GitWorktree | null>;
235
+ /**
236
+ * Find worktree for a specific PR by branch name
237
+ * Ports: find_existing_worktree() for PR type from bash script lines 149-160
238
+ */
239
+ findWorktreeForPR(prNumber: number, branchName: string): Promise<GitWorktree | null>;
240
+ /**
241
+ * Remove multiple worktrees
242
+ * Returns a summary of successes and failures
243
+ * Automatically filters out the main worktree
244
+ */
245
+ removeWorktrees(worktrees: GitWorktree[], options?: WorktreeCleanupOptions): Promise<{
246
+ successes: Array<{
247
+ worktree: GitWorktree;
248
+ }>;
249
+ failures: Array<{
250
+ worktree: GitWorktree;
251
+ error: string;
252
+ }>;
253
+ skipped: Array<{
254
+ worktree: GitWorktree;
255
+ reason: string;
256
+ }>;
257
+ }>;
258
+ /**
259
+ * Format worktree information for display
260
+ */
261
+ formatWorktree(worktree: GitWorktree): {
262
+ title: string;
263
+ path: string;
264
+ commit: string;
265
+ };
266
+ }
267
+
268
+ interface EnvVariable {
269
+ key: string;
270
+ value: string;
271
+ }
272
+ interface EnvFileOptions {
273
+ path: string;
274
+ backup?: boolean;
275
+ encoding?: BufferEncoding;
276
+ }
277
+ /**
278
+ * @deprecated Use exception-based error handling instead
279
+ */
280
+ interface EnvOperationResult {
281
+ success: boolean;
282
+ backupPath?: string;
283
+ error?: string;
284
+ }
285
+ interface PortAssignmentOptions {
286
+ basePort?: number;
287
+ issueNumber?: number;
288
+ prNumber?: number;
289
+ branchName?: string;
290
+ }
291
+
292
+ type ProjectCapability = 'cli' | 'web';
293
+ type Capability = ProjectCapability;
294
+ interface Loom {
295
+ id: string;
296
+ path: string;
297
+ branch: string;
298
+ type: 'issue' | 'pr' | 'branch';
299
+ identifier: string | number;
300
+ port: number;
301
+ databaseBranch?: string;
302
+ createdAt: Date;
303
+ lastAccessed: Date;
304
+ githubData?: {
305
+ title?: string;
306
+ body?: string;
307
+ url?: string;
308
+ state?: string;
309
+ };
310
+ capabilities?: ProjectCapability[];
311
+ binEntries?: Record<string, string>;
312
+ cliSymlinks?: string[];
313
+ }
314
+ interface CreateLoomInput {
315
+ type: 'issue' | 'pr' | 'branch';
316
+ identifier: string | number;
317
+ originalInput: string;
318
+ baseBranch?: string;
319
+ options?: {
320
+ skipDatabase?: boolean;
321
+ skipColorSync?: boolean;
322
+ enableClaude?: boolean;
323
+ enableCode?: boolean;
324
+ enableDevServer?: boolean;
325
+ enableTerminal?: boolean;
326
+ oneShot?: OneShotMode;
327
+ setArguments?: string[];
328
+ executablePath?: string;
329
+ };
330
+ }
331
+ type LaunchMode = 'editor' | 'terminal' | 'both';
332
+ interface LoomSummary {
333
+ id: string;
334
+ type: 'issue' | 'pr' | 'branch';
335
+ identifier: string | number;
336
+ title?: string;
337
+ branch: string;
338
+ port: number;
339
+ status: 'active' | 'stale' | 'error';
340
+ lastAccessed: string;
341
+ }
342
+
343
+ /**
344
+ * Options for ResourceCleanup operations
345
+ */
346
+ interface ResourceCleanupOptions {
347
+ /** Preview operations without executing */
348
+ dryRun?: boolean;
349
+ /** Skip confirmations and safety checks */
350
+ force?: boolean;
351
+ /** Delete the associated branch */
352
+ deleteBranch?: boolean;
353
+ /** Keep database branch instead of deleting */
354
+ keepDatabase?: boolean;
355
+ /** Prompt for confirmation before operations */
356
+ interactive?: boolean;
357
+ }
358
+ /**
359
+ * Result of a cleanup operation
360
+ */
361
+ interface CleanupResult {
362
+ /** Identifier that was cleaned up */
363
+ identifier: string;
364
+ /** Actual branch name that was found (will differ from identifier) */
365
+ branchName?: string;
366
+ /** Overall success status */
367
+ success: boolean;
368
+ /** Individual operation results */
369
+ operations: OperationResult[];
370
+ /** Errors encountered during cleanup */
371
+ errors: Error[];
372
+ /** Whether rollback is required */
373
+ rollbackRequired?: boolean;
374
+ }
375
+ /**
376
+ * Result of an individual cleanup operation
377
+ */
378
+ interface OperationResult {
379
+ /** Type of operation performed */
380
+ type: 'dev-server' | 'worktree' | 'branch' | 'database' | 'cli-symlinks';
381
+ /** Whether operation succeeded */
382
+ success: boolean;
383
+ /** Human-readable message */
384
+ message: string;
385
+ /** Error message if operation failed */
386
+ error?: string;
387
+ /** For database operations: whether branch was actually deleted (vs not found) */
388
+ deleted?: boolean;
389
+ }
390
+ /**
391
+ * Safety check result
392
+ */
393
+ interface SafetyCheck {
394
+ /** Whether cleanup is safe to proceed */
395
+ isSafe: boolean;
396
+ /** Non-blocking warnings */
397
+ warnings: string[];
398
+ /** Blocking issues that prevent cleanup */
399
+ blockers: string[];
400
+ }
401
+ /**
402
+ * Options for branch deletion
403
+ */
404
+ interface BranchDeleteOptions {
405
+ /** Force delete unmerged branch */
406
+ force?: boolean;
407
+ /** Also delete remote branch */
408
+ remote?: boolean;
409
+ /** Preview without executing */
410
+ dryRun?: boolean;
411
+ }
412
+ /**
413
+ * Target for batch cleanup - represents a branch that may or may not have a worktree
414
+ */
415
+ interface BranchCleanupTarget {
416
+ /** Branch name */
417
+ branchName: string;
418
+ /** Whether this branch has an associated worktree */
419
+ hasWorktree: boolean;
420
+ /** Path to worktree if it exists */
421
+ worktreePath?: string;
422
+ }
423
+ /**
424
+ * Result of batch cleanup operation for an issue
425
+ */
426
+ interface BatchCleanupResult {
427
+ /** Issue number that was cleaned up */
428
+ issueNumber: number;
429
+ /** Number of branches found matching the issue */
430
+ targetsFound: number;
431
+ /** Number of worktrees successfully removed */
432
+ worktreesRemoved: number;
433
+ /** Number of branches successfully deleted */
434
+ branchesDeleted: number;
435
+ /** Number of failed operations */
436
+ failed: number;
437
+ /** Individual cleanup results for each branch */
438
+ results: CleanupResult[];
439
+ }
440
+
441
+ /**
442
+ * Information about a running process
443
+ */
444
+ interface ProcessInfo {
445
+ /** Process ID */
446
+ pid: number;
447
+ /** Process name (e.g., "node", "pnpm") */
448
+ name: string;
449
+ /** Full command line */
450
+ command: string;
451
+ /** Port the process is listening on */
452
+ port: number;
453
+ /** Whether this appears to be a dev server */
454
+ isDevServer: boolean;
455
+ }
456
+
457
+ interface Workspace {
458
+ id: string;
459
+ path: string;
460
+ branch: string;
461
+ issueNumber?: number;
462
+ prNumber?: number;
463
+ port: number;
464
+ databaseBranch?: string;
465
+ createdAt: Date;
466
+ lastAccessed: Date;
467
+ }
468
+ interface WorkspaceInput {
469
+ identifier: string;
470
+ type: 'issue' | 'pr' | 'branch';
471
+ skipClaude?: boolean;
472
+ }
473
+ interface WorkspaceSummary {
474
+ id: string;
475
+ issueNumber?: number;
476
+ prNumber?: number;
477
+ title: string;
478
+ branch: string;
479
+ port: number;
480
+ status: 'active' | 'stale' | 'error';
481
+ lastAccessed: string;
482
+ }
483
+ interface Worktree {
484
+ path: string;
485
+ branch: string;
486
+ commit: string;
487
+ isPR: boolean;
488
+ prNumber?: number;
489
+ issueNumber?: number;
490
+ port?: number;
491
+ }
492
+ interface GitStatus {
493
+ hasUncommittedChanges: boolean;
494
+ unstagedFiles: string[];
495
+ stagedFiles: string[];
496
+ currentBranch: string;
497
+ isAheadOfRemote: boolean;
498
+ isBehindRemote: boolean;
499
+ }
500
+ interface Issue {
501
+ number: number;
502
+ title: string;
503
+ body: string;
504
+ state: 'open' | 'closed';
505
+ labels: string[];
506
+ assignees: string[];
507
+ url: string;
508
+ }
509
+ interface PullRequest {
510
+ number: number;
511
+ title: string;
512
+ body: string;
513
+ state: 'open' | 'closed' | 'merged';
514
+ branch: string;
515
+ baseBranch: string;
516
+ url: string;
517
+ isDraft: boolean;
518
+ }
519
+ /**
520
+ * Result of database branch deletion operation
521
+ * Distinguishes between successful deletion, branch not found, and errors
522
+ */
523
+ interface DatabaseDeletionResult {
524
+ /** Overall operation succeeded (true even if branch didn't exist) */
525
+ success: boolean;
526
+ /** True only if a branch was actually deleted */
527
+ deleted: boolean;
528
+ /** True if branch didn't exist (not an error, just nothing to do) */
529
+ notFound: boolean;
530
+ /** Error message if operation failed */
531
+ error?: string;
532
+ /** User declined deletion (for preview databases) */
533
+ userDeclined?: boolean;
534
+ /** Name of the branch that was processed */
535
+ branchName?: string;
536
+ }
537
+ interface DatabaseProvider {
538
+ createBranch(name: string, fromBranch?: string, cwd?: string): Promise<string>;
539
+ deleteBranch(name: string, isPreview?: boolean, cwd?: string): Promise<DatabaseDeletionResult>;
540
+ getConnectionString(branch: string, cwd?: string): Promise<string>;
541
+ listBranches(cwd?: string): Promise<string[]>;
542
+ branchExists(name: string, cwd?: string): Promise<boolean>;
543
+ findPreviewBranch(branchName: string, cwd?: string): Promise<string | null>;
544
+ getBranchNameFromEndpoint(endpointId: string, cwd?: string): Promise<string | null>;
545
+ sanitizeBranchName(branchName: string): string;
546
+ isAuthenticated(cwd?: string): Promise<boolean>;
547
+ isCliAvailable(): Promise<boolean>;
548
+ isConfigured(): boolean;
549
+ }
550
+ interface Config {
551
+ defaultPort: number;
552
+ databaseProvider?: 'neon' | 'supabase' | 'planetscale';
553
+ claudeModel?: 'opus' | 'sonnet' | 'haiku';
554
+ skipClaude?: boolean;
555
+ customWorkspaceRoot?: string;
556
+ }
557
+ type OneShotMode = 'default' | 'noReview' | 'bypassPermissions';
558
+ interface StartOptions {
559
+ claude?: boolean;
560
+ code?: boolean;
561
+ devServer?: boolean;
562
+ terminal?: boolean;
563
+ oneShot?: OneShotMode;
564
+ }
565
+ interface AddIssueOptions {
566
+ }
567
+ interface FeedbackOptions {
568
+ }
569
+ interface EnhanceOptions {
570
+ noBrowser?: boolean;
571
+ }
572
+ interface FinishOptions {
573
+ force?: boolean;
574
+ dryRun?: boolean;
575
+ pr?: number;
576
+ skipBuild?: boolean;
577
+ }
578
+ /**
579
+ * Options for the cleanup command
580
+ * All flags are optional and can be combined (subject to validation)
581
+ */
582
+ interface CleanupOptions {
583
+ /** List all worktrees without removing anything */
584
+ list?: boolean;
585
+ /** Remove all worktrees (interactive confirmation required unless --force) */
586
+ all?: boolean;
587
+ /** Cleanup by specific issue number */
588
+ issue?: number;
589
+ /** Skip confirmations and force removal */
590
+ force?: boolean;
591
+ /** Show what would be done without actually doing it */
592
+ dryRun?: boolean;
593
+ }
594
+ interface ListOptions {
595
+ json?: boolean;
596
+ }
597
+ interface MockOptions {
598
+ scenario: 'empty' | 'existing' | 'conflicts' | 'error';
599
+ data?: unknown;
600
+ }
601
+
602
+ interface RgbColor {
603
+ r: number;
604
+ g: number;
605
+ b: number;
606
+ }
607
+ interface ColorData {
608
+ rgb: RgbColor;
609
+ hex: string;
610
+ index: number;
611
+ }
612
+ type Platform = 'darwin' | 'linux' | 'win32' | 'unsupported';
613
+ interface ValidationOptions {
614
+ dryRun?: boolean;
615
+ skipTypecheck?: boolean;
616
+ skipLint?: boolean;
617
+ skipTests?: boolean;
618
+ }
619
+ interface ValidationStepResult {
620
+ step: 'typecheck' | 'lint' | 'test';
621
+ passed: boolean;
622
+ skipped: boolean;
623
+ output?: string;
624
+ error?: string;
625
+ duration?: number;
626
+ }
627
+ interface ValidationResult {
628
+ success: boolean;
629
+ steps: ValidationStepResult[];
630
+ totalDuration: number;
631
+ }
632
+ interface CommitOptions {
633
+ dryRun?: boolean;
634
+ issueNumber?: number;
635
+ message?: string;
636
+ noReview?: boolean;
637
+ skipVerify?: boolean;
638
+ }
639
+ interface MergeOptions {
640
+ dryRun?: boolean;
641
+ force?: boolean;
642
+ repoRoot?: string;
643
+ }
644
+ interface MergeResult {
645
+ success: boolean;
646
+ branchName: string;
647
+ commitsMerged: number;
648
+ rebaseCompleted: boolean;
649
+ mergeCompleted: boolean;
650
+ }
651
+ interface UpdateCheckCache {
652
+ lastCheck: number;
653
+ latestVersion: string;
654
+ }
655
+ interface UpdateCheckResult {
656
+ currentVersion: string;
657
+ latestVersion: string;
658
+ updateAvailable: boolean;
659
+ }
660
+ type InstallationMethod = 'global' | 'local' | 'linked' | 'unknown';
661
+
662
+ interface GitHubInputDetection {
663
+ type: 'issue' | 'pr' | 'unknown';
664
+ number: number | null;
665
+ rawInput: string;
666
+ }
667
+ interface BranchNameStrategy {
668
+ generate(issueNumber: number, title: string): Promise<string>;
669
+ }
670
+ interface BranchGenerationOptions {
671
+ issueNumber: number;
672
+ title: string;
673
+ strategy?: BranchNameStrategy;
674
+ }
675
+
676
+ declare class GitHubService {
677
+ private defaultBranchNameStrategy;
678
+ private prompter;
679
+ constructor(options?: {
680
+ branchNameStrategy?: BranchNameStrategy;
681
+ useClaude?: boolean;
682
+ claudeModel?: string;
683
+ prompter?: (message: string) => Promise<boolean>;
684
+ });
685
+ detectInputType(input: string): Promise<GitHubInputDetection>;
686
+ fetchIssue(issueNumber: number): Promise<Issue>;
687
+ isValidIssue(issueNumber: number): Promise<Issue | false>;
688
+ private fetchIssueInternal;
689
+ validateIssueState(issue: Issue): Promise<void>;
690
+ fetchPR(prNumber: number): Promise<PullRequest>;
691
+ isValidPR(prNumber: number): Promise<PullRequest | false>;
692
+ private fetchPRInternal;
693
+ validatePRState(pr: PullRequest): Promise<void>;
694
+ generateBranchName(options: BranchGenerationOptions): Promise<string>;
695
+ createIssue(title: string, body: string, repository?: string, labels?: string[]): Promise<{
696
+ number: number;
697
+ url: string;
698
+ }>;
699
+ getIssueUrl(issueNumber: number, repo?: string): Promise<string>;
700
+ moveIssueToInProgress(issueNumber: number): Promise<void>;
701
+ private updateIssueStatusInProject;
702
+ extractContext(entity: Issue | PullRequest): string;
703
+ private mapGitHubIssueToIssue;
704
+ private mapGitHubPRToPullRequest;
705
+ private promptUserConfirmation;
706
+ setDefaultBranchNameStrategy(strategy: BranchNameStrategy): void;
707
+ getBranchNameStrategy(): BranchNameStrategy;
708
+ }
709
+
710
+ declare class EnvironmentManager {
711
+ private readonly backupSuffix;
712
+ /**
713
+ * Set or update an environment variable in a .env file
714
+ * Ports functionality from bash/utils/env-utils.sh:setEnvVar()
715
+ * @returns The backup path if a backup was created
716
+ */
717
+ setEnvVar(filePath: string, key: string, value: string, backup?: boolean): Promise<string | void>;
718
+ /**
719
+ * Read and parse a .env file
720
+ */
721
+ readEnvFile(filePath: string): Promise<Map<string, string>>;
722
+ /**
723
+ * Generic file copy helper that only copies if source exists
724
+ * Does not throw if source file doesn't exist - just logs and returns
725
+ * @private
726
+ */
727
+ copyIfExists(source: string, destination: string): Promise<void>;
728
+ /**
729
+ * Calculate unique port for workspace
730
+ * Implements:
731
+ * - Issue/PR: 3000 + issue/PR number
732
+ * - Branch: 3000 + deterministic hash offset (1-999)
733
+ */
734
+ calculatePort(options: PortAssignmentOptions): number;
735
+ /**
736
+ * Set port environment variable for workspace
737
+ */
738
+ setPortForWorkspace(envFilePath: string, issueNumber?: number, prNumber?: number, branchName?: string): Promise<number>;
739
+ /**
740
+ * Validate environment configuration
741
+ */
742
+ validateEnvFile(filePath: string): Promise<{
743
+ valid: boolean;
744
+ errors: string[];
745
+ }>;
746
+ /**
747
+ * Create backup of existing file
748
+ */
749
+ private createBackup;
750
+ }
751
+
752
+ /**
753
+ * Database Manager - orchestrates database operations with conditional execution
754
+ * Ports functionality from bash scripts with guard conditions:
755
+ * 1. Database provider must be properly configured (provider.isConfigured())
756
+ * 2. The worktree's .env file must contain the configured database URL variable (default: DATABASE_URL)
757
+ *
758
+ * This ensures database branching only occurs for projects that actually use databases
759
+ */
760
+ declare class DatabaseManager {
761
+ private provider;
762
+ private environment;
763
+ private databaseUrlEnvVarName;
764
+ constructor(provider: DatabaseProvider, environment: EnvironmentManager, databaseUrlEnvVarName?: string);
765
+ /**
766
+ * Get the configured database URL environment variable name
767
+ */
768
+ getConfiguredVariableName(): string;
769
+ /**
770
+ * Check if database branching should be used
771
+ * Requires BOTH conditions:
772
+ * 1. Database provider is properly configured (checked via provider.isConfigured())
773
+ * 2. .env file contains the configured database URL variable
774
+ */
775
+ shouldUseDatabaseBranching(envFilePath: string): Promise<boolean>;
776
+ /**
777
+ * Create database branch only if configured
778
+ * Returns connection string if branch was created, null if skipped
779
+ *
780
+ * @param branchName - Name of the branch to create
781
+ * @param envFilePath - Path to .env file for configuration checks
782
+ * @param cwd - Optional working directory to run commands from
783
+ */
784
+ createBranchIfConfigured(branchName: string, envFilePath: string, cwd?: string): Promise<string | null>;
785
+ /**
786
+ * Delete database branch only if configured
787
+ * Returns result object indicating what happened
788
+ *
789
+ * @param branchName - Name of the branch to delete
790
+ * @param shouldCleanup - Boolean indicating if database cleanup should be performed (pre-fetched config)
791
+ * @param isPreview - Whether this is a preview database branch
792
+ * @param cwd - Optional working directory to run commands from (prevents issues with deleted directories)
793
+ */
794
+ deleteBranchIfConfigured(branchName: string, shouldCleanup: boolean, isPreview?: boolean, cwd?: string): Promise<DatabaseDeletionResult>;
795
+ /**
796
+ * Check if .env has the configured database URL variable
797
+ * CRITICAL: If user explicitly configured a custom variable name (not default),
798
+ * throw an error if it's missing from .env
799
+ */
800
+ private hasDatabaseUrlInEnv;
801
+ }
802
+
803
+ /**
804
+ * Zod schema for iloom settings
805
+ */
806
+ declare const IloomSettingsSchema: z.ZodObject<{
807
+ mainBranch: z.ZodOptional<z.ZodString>;
808
+ worktreePrefix: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
809
+ protectedBranches: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
810
+ workflows: z.ZodOptional<z.ZodObject<{
811
+ issue: z.ZodOptional<z.ZodObject<{
812
+ permissionMode: z.ZodOptional<z.ZodEnum<["plan", "acceptEdits", "bypassPermissions", "default"]>>;
813
+ noVerify: z.ZodOptional<z.ZodBoolean>;
814
+ startIde: z.ZodDefault<z.ZodBoolean>;
815
+ startDevServer: z.ZodDefault<z.ZodBoolean>;
816
+ startAiAgent: z.ZodDefault<z.ZodBoolean>;
817
+ startTerminal: z.ZodDefault<z.ZodBoolean>;
818
+ }, "strip", z.ZodTypeAny, {
819
+ startIde: boolean;
820
+ startDevServer: boolean;
821
+ startAiAgent: boolean;
822
+ startTerminal: boolean;
823
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
824
+ noVerify?: boolean | undefined;
825
+ }, {
826
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
827
+ noVerify?: boolean | undefined;
828
+ startIde?: boolean | undefined;
829
+ startDevServer?: boolean | undefined;
830
+ startAiAgent?: boolean | undefined;
831
+ startTerminal?: boolean | undefined;
832
+ }>>;
833
+ pr: z.ZodOptional<z.ZodObject<{
834
+ permissionMode: z.ZodOptional<z.ZodEnum<["plan", "acceptEdits", "bypassPermissions", "default"]>>;
835
+ noVerify: z.ZodOptional<z.ZodBoolean>;
836
+ startIde: z.ZodDefault<z.ZodBoolean>;
837
+ startDevServer: z.ZodDefault<z.ZodBoolean>;
838
+ startAiAgent: z.ZodDefault<z.ZodBoolean>;
839
+ startTerminal: z.ZodDefault<z.ZodBoolean>;
840
+ }, "strip", z.ZodTypeAny, {
841
+ startIde: boolean;
842
+ startDevServer: boolean;
843
+ startAiAgent: boolean;
844
+ startTerminal: boolean;
845
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
846
+ noVerify?: boolean | undefined;
847
+ }, {
848
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
849
+ noVerify?: boolean | undefined;
850
+ startIde?: boolean | undefined;
851
+ startDevServer?: boolean | undefined;
852
+ startAiAgent?: boolean | undefined;
853
+ startTerminal?: boolean | undefined;
854
+ }>>;
855
+ regular: z.ZodOptional<z.ZodObject<{
856
+ permissionMode: z.ZodOptional<z.ZodEnum<["plan", "acceptEdits", "bypassPermissions", "default"]>>;
857
+ noVerify: z.ZodOptional<z.ZodBoolean>;
858
+ startIde: z.ZodDefault<z.ZodBoolean>;
859
+ startDevServer: z.ZodDefault<z.ZodBoolean>;
860
+ startAiAgent: z.ZodDefault<z.ZodBoolean>;
861
+ startTerminal: z.ZodDefault<z.ZodBoolean>;
862
+ }, "strip", z.ZodTypeAny, {
863
+ startIde: boolean;
864
+ startDevServer: boolean;
865
+ startAiAgent: boolean;
866
+ startTerminal: boolean;
867
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
868
+ noVerify?: boolean | undefined;
869
+ }, {
870
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
871
+ noVerify?: boolean | undefined;
872
+ startIde?: boolean | undefined;
873
+ startDevServer?: boolean | undefined;
874
+ startAiAgent?: boolean | undefined;
875
+ startTerminal?: boolean | undefined;
876
+ }>>;
877
+ }, "strip", z.ZodTypeAny, {
878
+ issue?: {
879
+ startIde: boolean;
880
+ startDevServer: boolean;
881
+ startAiAgent: boolean;
882
+ startTerminal: boolean;
883
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
884
+ noVerify?: boolean | undefined;
885
+ } | undefined;
886
+ pr?: {
887
+ startIde: boolean;
888
+ startDevServer: boolean;
889
+ startAiAgent: boolean;
890
+ startTerminal: boolean;
891
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
892
+ noVerify?: boolean | undefined;
893
+ } | undefined;
894
+ regular?: {
895
+ startIde: boolean;
896
+ startDevServer: boolean;
897
+ startAiAgent: boolean;
898
+ startTerminal: boolean;
899
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
900
+ noVerify?: boolean | undefined;
901
+ } | undefined;
902
+ }, {
903
+ issue?: {
904
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
905
+ noVerify?: boolean | undefined;
906
+ startIde?: boolean | undefined;
907
+ startDevServer?: boolean | undefined;
908
+ startAiAgent?: boolean | undefined;
909
+ startTerminal?: boolean | undefined;
910
+ } | undefined;
911
+ pr?: {
912
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
913
+ noVerify?: boolean | undefined;
914
+ startIde?: boolean | undefined;
915
+ startDevServer?: boolean | undefined;
916
+ startAiAgent?: boolean | undefined;
917
+ startTerminal?: boolean | undefined;
918
+ } | undefined;
919
+ regular?: {
920
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
921
+ noVerify?: boolean | undefined;
922
+ startIde?: boolean | undefined;
923
+ startDevServer?: boolean | undefined;
924
+ startAiAgent?: boolean | undefined;
925
+ startTerminal?: boolean | undefined;
926
+ } | undefined;
927
+ }>>;
928
+ agents: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
929
+ model: z.ZodOptional<z.ZodEnum<["sonnet", "opus", "haiku"]>>;
930
+ }, "strip", z.ZodTypeAny, {
931
+ model?: "sonnet" | "opus" | "haiku" | undefined;
932
+ }, {
933
+ model?: "sonnet" | "opus" | "haiku" | undefined;
934
+ }>>>>;
935
+ capabilities: z.ZodOptional<z.ZodObject<{
936
+ web: z.ZodOptional<z.ZodObject<{
937
+ basePort: z.ZodOptional<z.ZodNumber>;
938
+ }, "strip", z.ZodTypeAny, {
939
+ basePort?: number | undefined;
940
+ }, {
941
+ basePort?: number | undefined;
942
+ }>>;
943
+ database: z.ZodOptional<z.ZodObject<{
944
+ databaseUrlEnvVarName: z.ZodDefault<z.ZodOptional<z.ZodString>>;
945
+ }, "strip", z.ZodTypeAny, {
946
+ databaseUrlEnvVarName: string;
947
+ }, {
948
+ databaseUrlEnvVarName?: string | undefined;
949
+ }>>;
950
+ }, "strip", z.ZodTypeAny, {
951
+ web?: {
952
+ basePort?: number | undefined;
953
+ } | undefined;
954
+ database?: {
955
+ databaseUrlEnvVarName: string;
956
+ } | undefined;
957
+ }, {
958
+ web?: {
959
+ basePort?: number | undefined;
960
+ } | undefined;
961
+ database?: {
962
+ databaseUrlEnvVarName?: string | undefined;
963
+ } | undefined;
964
+ }>>;
965
+ }, "strip", z.ZodTypeAny, {
966
+ mainBranch?: string | undefined;
967
+ worktreePrefix?: string | undefined;
968
+ protectedBranches?: string[] | undefined;
969
+ workflows?: {
970
+ issue?: {
971
+ startIde: boolean;
972
+ startDevServer: boolean;
973
+ startAiAgent: boolean;
974
+ startTerminal: boolean;
975
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
976
+ noVerify?: boolean | undefined;
977
+ } | undefined;
978
+ pr?: {
979
+ startIde: boolean;
980
+ startDevServer: boolean;
981
+ startAiAgent: boolean;
982
+ startTerminal: boolean;
983
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
984
+ noVerify?: boolean | undefined;
985
+ } | undefined;
986
+ regular?: {
987
+ startIde: boolean;
988
+ startDevServer: boolean;
989
+ startAiAgent: boolean;
990
+ startTerminal: boolean;
991
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
992
+ noVerify?: boolean | undefined;
993
+ } | undefined;
994
+ } | undefined;
995
+ agents?: Record<string, {
996
+ model?: "sonnet" | "opus" | "haiku" | undefined;
997
+ }> | null | undefined;
998
+ capabilities?: {
999
+ web?: {
1000
+ basePort?: number | undefined;
1001
+ } | undefined;
1002
+ database?: {
1003
+ databaseUrlEnvVarName: string;
1004
+ } | undefined;
1005
+ } | undefined;
1006
+ }, {
1007
+ mainBranch?: string | undefined;
1008
+ worktreePrefix?: string | undefined;
1009
+ protectedBranches?: string[] | undefined;
1010
+ workflows?: {
1011
+ issue?: {
1012
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
1013
+ noVerify?: boolean | undefined;
1014
+ startIde?: boolean | undefined;
1015
+ startDevServer?: boolean | undefined;
1016
+ startAiAgent?: boolean | undefined;
1017
+ startTerminal?: boolean | undefined;
1018
+ } | undefined;
1019
+ pr?: {
1020
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
1021
+ noVerify?: boolean | undefined;
1022
+ startIde?: boolean | undefined;
1023
+ startDevServer?: boolean | undefined;
1024
+ startAiAgent?: boolean | undefined;
1025
+ startTerminal?: boolean | undefined;
1026
+ } | undefined;
1027
+ regular?: {
1028
+ permissionMode?: "plan" | "acceptEdits" | "bypassPermissions" | "default" | undefined;
1029
+ noVerify?: boolean | undefined;
1030
+ startIde?: boolean | undefined;
1031
+ startDevServer?: boolean | undefined;
1032
+ startAiAgent?: boolean | undefined;
1033
+ startTerminal?: boolean | undefined;
1034
+ } | undefined;
1035
+ } | undefined;
1036
+ agents?: Record<string, {
1037
+ model?: "sonnet" | "opus" | "haiku" | undefined;
1038
+ }> | null | undefined;
1039
+ capabilities?: {
1040
+ web?: {
1041
+ basePort?: number | undefined;
1042
+ } | undefined;
1043
+ database?: {
1044
+ databaseUrlEnvVarName?: string | undefined;
1045
+ } | undefined;
1046
+ } | undefined;
1047
+ }>;
1048
+ /**
1049
+ * TypeScript type for iloom settings derived from Zod schema
1050
+ */
1051
+ type IloomSettings = z.infer<typeof IloomSettingsSchema>;
1052
+ /**
1053
+ * Manages project-level settings from .iloom/settings.json
1054
+ */
1055
+ declare class SettingsManager {
1056
+ /**
1057
+ * Load settings from <PROJECT_ROOT>/.iloom/settings.json and settings.local.json
1058
+ * Merges settings.local.json over settings.json with priority
1059
+ * CLI overrides have highest priority if provided
1060
+ * Returns empty object if both files don't exist (not an error)
1061
+ */
1062
+ loadSettings(projectRoot?: string, cliOverrides?: Partial<IloomSettings>): Promise<IloomSettings>;
1063
+ /**
1064
+ * Log the final merged configuration for debugging
1065
+ */
1066
+ private logFinalConfiguration;
1067
+ /**
1068
+ * Load and parse a single settings file
1069
+ * Returns empty object if file doesn't exist (not an error)
1070
+ */
1071
+ private loadSettingsFile;
1072
+ /**
1073
+ * Deep merge two settings objects with priority to override
1074
+ * Uses deepmerge library with array replacement strategy
1075
+ */
1076
+ private mergeSettings;
1077
+ /**
1078
+ * Format all Zod validation errors into a single error message
1079
+ */
1080
+ private formatAllZodErrors;
1081
+ /**
1082
+ * Validate settings structure and model names using Zod schema
1083
+ * This method is kept for testing purposes but uses Zod internally
1084
+ * @internal - Only used in tests via bracket notation
1085
+ */
1086
+ private validateSettings;
1087
+ /**
1088
+ * Get project root (defaults to process.cwd())
1089
+ */
1090
+ private getProjectRoot;
1091
+ /**
1092
+ * Get effective protected branches list with mainBranch always included
1093
+ *
1094
+ * This method provides a single source of truth for protected branches logic:
1095
+ * 1. Use configured protectedBranches if provided
1096
+ * 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']
1097
+ * 3. ALWAYS ensure mainBranch is included even if user configured custom list
1098
+ *
1099
+ * @param projectRoot - Optional project root directory (defaults to process.cwd())
1100
+ * @returns Array of protected branch names with mainBranch guaranteed to be included
1101
+ */
1102
+ getProtectedBranches(projectRoot?: string): Promise<string[]>;
1103
+ }
1104
+
1105
+ interface TemplateVariables {
1106
+ ISSUE_NUMBER?: number;
1107
+ PR_NUMBER?: number;
1108
+ ISSUE_TITLE?: string;
1109
+ PR_TITLE?: string;
1110
+ WORKSPACE_PATH?: string;
1111
+ PORT?: number;
1112
+ ONE_SHOT_MODE?: boolean;
1113
+ }
1114
+ declare class PromptTemplateManager {
1115
+ private templateDir;
1116
+ constructor(templateDir?: string);
1117
+ /**
1118
+ * Load a template file by name
1119
+ */
1120
+ loadTemplate(templateName: 'issue' | 'pr' | 'regular'): Promise<string>;
1121
+ /**
1122
+ * Substitute variables in a template string
1123
+ */
1124
+ substituteVariables(template: string, variables: TemplateVariables): string;
1125
+ /**
1126
+ * Process conditional sections in template
1127
+ * Format: {{#IF ONE_SHOT_MODE}}content{{/IF ONE_SHOT_MODE}}
1128
+ *
1129
+ * Note: /s flag allows . to match newlines
1130
+ */
1131
+ private processConditionalSections;
1132
+ /**
1133
+ * Get a fully processed prompt for a workflow type
1134
+ */
1135
+ getPrompt(type: 'issue' | 'pr' | 'regular', variables: TemplateVariables): Promise<string>;
1136
+ }
1137
+
1138
+ interface ClaudeWorkflowOptions {
1139
+ type: 'issue' | 'pr' | 'regular';
1140
+ issueNumber?: number;
1141
+ prNumber?: number;
1142
+ title?: string;
1143
+ workspacePath: string;
1144
+ port?: number;
1145
+ headless?: boolean;
1146
+ branchName?: string;
1147
+ oneShot?: OneShotMode;
1148
+ setArguments?: string[];
1149
+ executablePath?: string;
1150
+ }
1151
+ declare class ClaudeService {
1152
+ private templateManager;
1153
+ private settingsManager;
1154
+ private settings?;
1155
+ constructor(templateManager?: PromptTemplateManager, settingsManager?: SettingsManager);
1156
+ /**
1157
+ * Check if Claude CLI is available
1158
+ */
1159
+ isAvailable(): Promise<boolean>;
1160
+ /**
1161
+ * Get the appropriate model for a workflow type
1162
+ */
1163
+ private getModelForWorkflow;
1164
+ /**
1165
+ * Get the appropriate permission mode for a workflow type
1166
+ */
1167
+ private getPermissionModeForWorkflow;
1168
+ /**
1169
+ * Launch Claude for a specific workflow
1170
+ */
1171
+ launchForWorkflow(options: ClaudeWorkflowOptions): Promise<string | void>;
1172
+ /**
1173
+ * Generate branch name with Claude, with fallback on failure
1174
+ */
1175
+ generateBranchNameWithFallback(issueTitle: string, issueNumber: number): Promise<string>;
1176
+ }
1177
+
1178
+ interface ClaudeContext {
1179
+ type: 'issue' | 'pr' | 'regular';
1180
+ identifier: number | string;
1181
+ title?: string;
1182
+ workspacePath: string;
1183
+ port?: number;
1184
+ branchName?: string;
1185
+ oneShot?: OneShotMode;
1186
+ setArguments?: string[];
1187
+ executablePath?: string;
1188
+ }
1189
+ declare class ClaudeContextManager {
1190
+ private claudeService;
1191
+ constructor(claudeService?: ClaudeService, _promptTemplateManager?: PromptTemplateManager, settingsManager?: SettingsManager);
1192
+ /**
1193
+ * Prepare context for Claude launch
1194
+ * Placeholder for future .claude-context.md generation (Issue #11)
1195
+ */
1196
+ prepareContext(context: ClaudeContext): Promise<void>;
1197
+ /**
1198
+ * Launch Claude with the prepared context
1199
+ */
1200
+ launchWithContext(context: ClaudeContext, headless?: boolean): Promise<string | void>;
1201
+ }
1202
+
1203
+ /**
1204
+ * Execute a Git command and return the stdout result
1205
+ * Throws an error if the command fails
1206
+ */
1207
+ declare function executeGitCommand(args: string[], options?: {
1208
+ cwd?: string;
1209
+ timeout?: number;
1210
+ stdio?: 'inherit' | 'pipe';
1211
+ }): Promise<string>;
1212
+ /**
1213
+ * Parse git worktree list output into structured data
1214
+ * @param output - The output from git worktree list --porcelain
1215
+ * @param defaultBranch - Default branch name to use for bare repositories (defaults to 'main')
1216
+ */
1217
+ declare function parseWorktreeList(output: string, defaultBranch?: string): GitWorktree[];
1218
+ /**
1219
+ * Check if a branch name follows PR naming patterns
1220
+ */
1221
+ declare function isPRBranch(branchName: string): boolean;
1222
+ /**
1223
+ * Extract PR number from branch name
1224
+ */
1225
+ declare function extractPRNumber(branchName: string): number | null;
1226
+ /**
1227
+ * Check if a path follows worktree naming patterns
1228
+ */
1229
+ declare function isWorktreePath(path: string): boolean;
1230
+ /**
1231
+ * Generate a worktree path based on branch name and root directory
1232
+ * For PRs, adds _pr_<PR_NUM> suffix to distinguish from issue branches
1233
+ */
1234
+ declare function generateWorktreePath(branchName: string, rootDir?: string, options?: {
1235
+ isPR?: boolean;
1236
+ prNumber?: number;
1237
+ prefix?: string;
1238
+ }): string;
1239
+ /**
1240
+ * Validate that a directory is a valid Git repository
1241
+ */
1242
+ declare function isValidGitRepo(path: string): Promise<boolean>;
1243
+ /**
1244
+ * Get the current branch name for a repository
1245
+ */
1246
+ declare function getCurrentBranch(path?: string): Promise<string | null>;
1247
+ /**
1248
+ * Check if a branch exists (local or remote)
1249
+ */
1250
+ declare function branchExists(branchName: string, path?: string, includeRemote?: boolean): Promise<boolean>;
1251
+ /**
1252
+ * Get repository root directory
1253
+ */
1254
+ declare function getRepoRoot(path?: string): Promise<string | null>;
1255
+ /**
1256
+ * Find the worktree path where main branch is checked out
1257
+ * Copies bash script approach: parse git worktree list to find main
1258
+ */
1259
+ declare function findMainWorktreePath(path?: string, options?: {
1260
+ mainBranch?: string;
1261
+ }): Promise<string>;
1262
+ /**
1263
+ * Find main worktree path with automatic settings loading
1264
+ *
1265
+ * This is a convenience wrapper that:
1266
+ * 1. Loads project settings from .iloom/settings.json
1267
+ * 2. Extracts mainBranch configuration if present
1268
+ * 3. Calls findMainWorktreePath with appropriate options
1269
+ *
1270
+ * @param path - Path to search from (defaults to process.cwd())
1271
+ * @param settingsManager - Optional SettingsManager instance (for DI/testing)
1272
+ * @returns Path to main worktree
1273
+ * @throws Error if main worktree cannot be found
1274
+ */
1275
+ declare function findMainWorktreePathWithSettings(path?: string, settingsManager?: SettingsManager): Promise<string>;
1276
+ /**
1277
+ * Check if there are uncommitted changes in a repository
1278
+ */
1279
+ declare function hasUncommittedChanges(path?: string): Promise<boolean>;
1280
+ /**
1281
+ * Get the default branch name for a repository
1282
+ */
1283
+ declare function getDefaultBranch(path?: string): Promise<string>;
1284
+ /**
1285
+ * Find all branches related to a GitHub issue or PR number
1286
+ * Matches patterns like:
1287
+ * - Issue patterns: issue-25, issue/25, 25-feature, feat-25, feat/issue-25
1288
+ * - PR patterns: pr/25, pull/25, pr-25, feature/pr-25
1289
+ *
1290
+ * Based on bash cleanup-worktree.sh find_issue_branches() (lines 133-154)
1291
+ *
1292
+ * @param issueNumber - The issue or PR number to search for
1293
+ * @param path - Working directory to search from (defaults to process.cwd())
1294
+ * @param settingsManager - Optional SettingsManager instance (for DI/testing)
1295
+ */
1296
+ declare function findAllBranchesForIssue(issueNumber: number, path?: string, settingsManager?: SettingsManager): Promise<string[]>;
1297
+ /**
1298
+ * Check if a repository is empty (has no commits yet)
1299
+ * @param path - Repository path to check (defaults to process.cwd())
1300
+ * @returns true if repository has no commits, false otherwise
1301
+ */
1302
+ declare function isEmptyRepository(path?: string): Promise<boolean>;
1303
+ /**
1304
+ * Ensure repository has at least one commit
1305
+ * Creates an initial empty commit if repository is empty
1306
+ * @param path - Repository path (defaults to process.cwd())
1307
+ */
1308
+ declare function ensureRepositoryHasCommits(path?: string): Promise<void>;
1309
+ /**
1310
+ * Push a branch to remote repository
1311
+ * Used for PR workflow to push changes to remote without merging locally
1312
+ *
1313
+ * @param branchName - The branch name to push
1314
+ * @param worktreePath - The worktree path where the branch is checked out
1315
+ * @param options - Push options
1316
+ * @throws Error if push fails
1317
+ */
1318
+ declare function pushBranchToRemote(branchName: string, worktreePath: string, options?: {
1319
+ dryRun?: boolean;
1320
+ }): Promise<void>;
1321
+
1322
+ interface LoggerOptions {
1323
+ prefix?: string;
1324
+ timestamp?: boolean;
1325
+ silent?: boolean;
1326
+ forceColor?: boolean | undefined | null;
1327
+ debug?: boolean;
1328
+ }
1329
+ interface Logger {
1330
+ info: (message: string, ...args: unknown[]) => void;
1331
+ success: (message: string, ...args: unknown[]) => void;
1332
+ warn: (message: string, ...args: unknown[]) => void;
1333
+ error: (message: string, ...args: unknown[]) => void;
1334
+ debug: (message: string, ...args: unknown[]) => void;
1335
+ setDebug: (enabled: boolean) => void;
1336
+ isDebugEnabled: () => boolean;
1337
+ }
1338
+ declare const logger: Logger;
1339
+ declare function createLogger(options?: LoggerOptions): Logger;
1340
+
1341
+ export { type AddIssueOptions, type BatchCleanupResult, type BranchCleanupTarget, type BranchDeleteOptions, type Capability, type ClaudeContext, ClaudeContextManager, type CleanupOptions, type CleanupResult, type ColorData, type CommitOptions, type Config, type CreateLoomInput, type DatabaseDeletionResult, DatabaseManager, type DatabaseProvider, type EnhanceOptions, type EnvFileOptions, type EnvOperationResult, type EnvVariable, EnvironmentManager, type FeedbackOptions, type FinishOptions, GitHubService, type GitStatus, type GitWorktree, GitWorktreeManager, type InstallationMethod, type Issue, type LaunchMode, type ListOptions, type Logger, type LoggerOptions, type Loom, type LoomSummary, type MergeOptions, type MergeResult, type MockOptions, type OneShotMode, type OperationResult, type PRWorktreePattern, type Platform, type PortAssignmentOptions, type ProcessInfo, type ProjectCapability, type PullRequest, type ResourceCleanupOptions, type RgbColor, type SafetyCheck, type StartOptions, type UpdateCheckCache, type UpdateCheckResult, type ValidationOptions, type ValidationResult, type ValidationStepResult, type Workspace, type WorkspaceInput, WorkspaceManager, type WorkspaceSummary, type Worktree, type WorktreeCleanupOptions, type WorktreeCreateOptions, type WorktreeListOptions, type WorktreeOperationResult, type WorktreeStatus, type WorktreeValidation, branchExists, createLogger, ensureRepositoryHasCommits, executeGitCommand, extractPRNumber, findAllBranchesForIssue, findMainWorktreePath, findMainWorktreePathWithSettings, generateWorktreePath, getCurrentBranch, getDefaultBranch, getRepoRoot, hasUncommittedChanges, isEmptyRepository, isPRBranch, isValidGitRepo, isWorktreePath, logger, parseWorktreeList, pushBranchToRemote };