@iloom/cli 0.1.17 → 0.1.18
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.
- package/README.md +14 -0
- package/dist/ClaudeContextManager-LD3VB6EM.js +13 -0
- package/dist/ClaudeService-CFFI7DD5.js +12 -0
- package/dist/{GitHubService-F7Z3XJOS.js → GitHubService-SH4H6VS5.js} +3 -3
- package/dist/{LoomLauncher-MODG2SEM.js → LoomLauncher-FB2MV2ZI.js} +7 -7
- package/dist/{PromptTemplateManager-7FINLRDE.js → PromptTemplateManager-WM5GIPEF.js} +2 -2
- package/dist/{SettingsManager-VAZF26S2.js → SettingsManager-SKLUVE3K.js} +6 -2
- package/dist/{add-issue-22JBNOML.js → add-issue-L5HX6LEV.js} +23 -8
- package/dist/add-issue-L5HX6LEV.js.map +1 -0
- package/dist/{chunk-SSR5AVRJ.js → chunk-6OTVPRXH.js} +21 -8
- package/dist/chunk-6OTVPRXH.js.map +1 -0
- package/dist/{chunk-KQDEK2ZW.js → chunk-DGEKUT7Q.js} +9 -5
- package/dist/chunk-DGEKUT7Q.js.map +1 -0
- package/dist/chunk-FXV24OYZ.js +83 -0
- package/dist/chunk-FXV24OYZ.js.map +1 -0
- package/dist/{chunk-HPJJSYNS.js → chunk-H5LDRGVK.js} +6 -8
- package/dist/{chunk-HPJJSYNS.js.map → chunk-H5LDRGVK.js.map} +1 -1
- package/dist/{chunk-WKEWRSDB.js → chunk-HURVAQRK.js} +3 -3
- package/dist/{chunk-T7QPXANZ.js → chunk-IIPTBZQW.js} +17 -17
- package/dist/chunk-IIPTBZQW.js.map +1 -0
- package/dist/{chunk-QEPVTTHD.js → chunk-IO4WFTL2.js} +17 -11
- package/dist/chunk-IO4WFTL2.js.map +1 -0
- package/dist/{chunk-JQ7VOSTC.js → chunk-KOCQAD2E.js} +3 -3
- package/dist/{chunk-F3XBU2R7.js → chunk-L4QGC27H.js} +68 -2
- package/dist/chunk-L4QGC27H.js.map +1 -0
- package/dist/{chunk-YYSKGAZT.js → chunk-LAPY6NAE.js} +17 -8
- package/dist/chunk-LAPY6NAE.js.map +1 -0
- package/dist/{chunk-O2QWO64Z.js → chunk-PV3GAXQO.js} +56 -3
- package/dist/chunk-PV3GAXQO.js.map +1 -0
- package/dist/{chunk-CP2NU2JC.js → chunk-Q2KYPAH2.js} +7 -7
- package/dist/{chunk-CP2NU2JC.js.map → chunk-Q2KYPAH2.js.map} +1 -1
- package/dist/{chunk-Y7SAGNUT.js → chunk-SLIMABFA.js} +2 -2
- package/dist/{chunk-W3DQTW63.js → chunk-USVVV3FP.js} +4 -4
- package/dist/chunk-VVH3ANF2.js +307 -0
- package/dist/chunk-VVH3ANF2.js.map +1 -0
- package/dist/{chunk-JBH2ZYYZ.js → chunk-VYQLLHZ7.js} +22 -3
- package/dist/chunk-VYQLLHZ7.js.map +1 -0
- package/dist/{chunk-SJUQ2NDR.js → chunk-ZMNQBJUI.js} +24 -19
- package/dist/chunk-ZMNQBJUI.js.map +1 -0
- package/dist/{cleanup-3LUWPSM7.js → cleanup-ZHROIBSQ.js} +12 -16
- package/dist/cleanup-ZHROIBSQ.js.map +1 -0
- package/dist/cli.js +96 -48
- package/dist/cli.js.map +1 -1
- package/dist/{enhance-XJIQHVPD.js → enhance-VVMAKMVZ.js} +18 -8
- package/dist/enhance-VVMAKMVZ.js.map +1 -0
- package/dist/{feedback-23CLXKFT.js → feedback-AKHD7QIM.js} +8 -8
- package/dist/{finish-3CQZIULO.js → finish-WGPISUEH.js} +36 -313
- package/dist/finish-WGPISUEH.js.map +1 -0
- package/dist/{git-LVRZ57GJ.js → git-OUYMVYJX.js} +2 -2
- package/dist/{ignite-WXEF2ID5.js → ignite-JEN3K3OT.js} +7 -7
- package/dist/index.d.ts +791 -712
- package/dist/index.js +126 -32
- package/dist/index.js.map +1 -1
- package/dist/init-EVUT4ZQJ.js +339 -0
- package/dist/init-EVUT4ZQJ.js.map +1 -0
- package/dist/mcp/github-comment-server.js +12 -9
- package/dist/mcp/github-comment-server.js.map +1 -1
- package/dist/neon-helpers-ZVIRPKCI.js +10 -0
- package/dist/{open-X6BTENPV.js → open-ETZUFSE4.js} +15 -17
- package/dist/{open-X6BTENPV.js.map → open-ETZUFSE4.js.map} +1 -1
- package/dist/prompts/init-prompt.txt +746 -0
- package/dist/rebase-KBWFDZCN.js +95 -0
- package/dist/rebase-KBWFDZCN.js.map +1 -0
- package/dist/remote-GJEZWRCC.js +14 -0
- package/dist/{run-2JCPQAX3.js → run-4SVQ3WEU.js} +15 -17
- package/dist/{run-2JCPQAX3.js.map → run-4SVQ3WEU.js.map} +1 -1
- package/dist/schema/settings.schema.json +51 -1
- package/dist/{start-LWVRBJ6S.js → start-2NEZU7SE.js} +54 -53
- package/dist/{start-LWVRBJ6S.js.map → start-2NEZU7SE.js.map} +1 -1
- package/dist/{test-git-XPF4SZXJ.js → test-git-MKZATGZN.js} +3 -3
- package/dist/{test-prefix-XGFXFAYN.js → test-prefix-ZNLWDI3K.js} +3 -3
- package/dist/{update-DN3FSNKY.js → update-4TDDUR5K.js} +10 -4
- package/dist/{update-DN3FSNKY.js.map → update-4TDDUR5K.js.map} +1 -1
- package/package.json +1 -1
- package/dist/ClaudeContextManager-XOSXQ67R.js +0 -13
- package/dist/ClaudeService-YSZ6EXWP.js +0 -12
- package/dist/NeonProvider-PAGPUH7F.js +0 -12
- package/dist/add-issue-22JBNOML.js.map +0 -1
- package/dist/chunk-37DYYFVK.js +0 -29
- package/dist/chunk-37DYYFVK.js.map +0 -1
- package/dist/chunk-F3XBU2R7.js.map +0 -1
- package/dist/chunk-JBH2ZYYZ.js.map +0 -1
- package/dist/chunk-KQDEK2ZW.js.map +0 -1
- package/dist/chunk-O2QWO64Z.js.map +0 -1
- package/dist/chunk-QEPVTTHD.js.map +0 -1
- package/dist/chunk-SJUQ2NDR.js.map +0 -1
- package/dist/chunk-SSR5AVRJ.js.map +0 -1
- package/dist/chunk-T7QPXANZ.js.map +0 -1
- package/dist/chunk-YYSKGAZT.js.map +0 -1
- package/dist/cleanup-3LUWPSM7.js.map +0 -1
- package/dist/enhance-XJIQHVPD.js.map +0 -1
- package/dist/env-MDFL4ZXL.js +0 -23
- package/dist/finish-3CQZIULO.js.map +0 -1
- package/dist/init-RHACUR4E.js +0 -123
- package/dist/init-RHACUR4E.js.map +0 -1
- /package/dist/{ClaudeContextManager-XOSXQ67R.js.map → ClaudeContextManager-LD3VB6EM.js.map} +0 -0
- /package/dist/{ClaudeService-YSZ6EXWP.js.map → ClaudeService-CFFI7DD5.js.map} +0 -0
- /package/dist/{GitHubService-F7Z3XJOS.js.map → GitHubService-SH4H6VS5.js.map} +0 -0
- /package/dist/{LoomLauncher-MODG2SEM.js.map → LoomLauncher-FB2MV2ZI.js.map} +0 -0
- /package/dist/{NeonProvider-PAGPUH7F.js.map → PromptTemplateManager-WM5GIPEF.js.map} +0 -0
- /package/dist/{PromptTemplateManager-7FINLRDE.js.map → SettingsManager-SKLUVE3K.js.map} +0 -0
- /package/dist/{chunk-WKEWRSDB.js.map → chunk-HURVAQRK.js.map} +0 -0
- /package/dist/{chunk-JQ7VOSTC.js.map → chunk-KOCQAD2E.js.map} +0 -0
- /package/dist/{chunk-Y7SAGNUT.js.map → chunk-SLIMABFA.js.map} +0 -0
- /package/dist/{chunk-W3DQTW63.js.map → chunk-USVVV3FP.js.map} +0 -0
- /package/dist/{feedback-23CLXKFT.js.map → feedback-AKHD7QIM.js.map} +0 -0
- /package/dist/{SettingsManager-VAZF26S2.js.map → git-OUYMVYJX.js.map} +0 -0
- /package/dist/{ignite-WXEF2ID5.js.map → ignite-JEN3K3OT.js.map} +0 -0
- /package/dist/{env-MDFL4ZXL.js.map → neon-helpers-ZVIRPKCI.js.map} +0 -0
- /package/dist/{git-LVRZ57GJ.js.map → remote-GJEZWRCC.js.map} +0 -0
- /package/dist/{test-git-XPF4SZXJ.js.map → test-git-MKZATGZN.js.map} +0 -0
- /package/dist/{test-prefix-XGFXFAYN.js.map → test-prefix-ZNLWDI3K.js.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -123,683 +123,6 @@ interface WorktreeCleanupOptions {
|
|
|
123
123
|
dryRun?: boolean;
|
|
124
124
|
}
|
|
125
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
126
|
/**
|
|
804
127
|
* Zod schema for iloom settings
|
|
805
128
|
*/
|
|
@@ -962,6 +285,45 @@ declare const IloomSettingsSchema: z.ZodObject<{
|
|
|
962
285
|
databaseUrlEnvVarName?: string | undefined;
|
|
963
286
|
} | undefined;
|
|
964
287
|
}>>;
|
|
288
|
+
databaseProviders: z.ZodOptional<z.ZodObject<{
|
|
289
|
+
neon: z.ZodOptional<z.ZodObject<{
|
|
290
|
+
projectId: z.ZodString;
|
|
291
|
+
parentBranch: z.ZodString;
|
|
292
|
+
}, "strip", z.ZodTypeAny, {
|
|
293
|
+
projectId: string;
|
|
294
|
+
parentBranch: string;
|
|
295
|
+
}, {
|
|
296
|
+
projectId: string;
|
|
297
|
+
parentBranch: string;
|
|
298
|
+
}>>;
|
|
299
|
+
}, "strip", z.ZodTypeAny, {
|
|
300
|
+
neon?: {
|
|
301
|
+
projectId: string;
|
|
302
|
+
parentBranch: string;
|
|
303
|
+
} | undefined;
|
|
304
|
+
}, {
|
|
305
|
+
neon?: {
|
|
306
|
+
projectId: string;
|
|
307
|
+
parentBranch: string;
|
|
308
|
+
} | undefined;
|
|
309
|
+
}>>;
|
|
310
|
+
issueManagement: z.ZodOptional<z.ZodObject<{
|
|
311
|
+
github: z.ZodOptional<z.ZodObject<{
|
|
312
|
+
remote: z.ZodString;
|
|
313
|
+
}, "strip", z.ZodTypeAny, {
|
|
314
|
+
remote: string;
|
|
315
|
+
}, {
|
|
316
|
+
remote: string;
|
|
317
|
+
}>>;
|
|
318
|
+
}, "strip", z.ZodTypeAny, {
|
|
319
|
+
github?: {
|
|
320
|
+
remote: string;
|
|
321
|
+
} | undefined;
|
|
322
|
+
}, {
|
|
323
|
+
github?: {
|
|
324
|
+
remote: string;
|
|
325
|
+
} | undefined;
|
|
326
|
+
}>>;
|
|
965
327
|
}, "strip", z.ZodTypeAny, {
|
|
966
328
|
mainBranch?: string | undefined;
|
|
967
329
|
worktreePrefix?: string | undefined;
|
|
@@ -1003,6 +365,17 @@ declare const IloomSettingsSchema: z.ZodObject<{
|
|
|
1003
365
|
databaseUrlEnvVarName: string;
|
|
1004
366
|
} | undefined;
|
|
1005
367
|
} | undefined;
|
|
368
|
+
databaseProviders?: {
|
|
369
|
+
neon?: {
|
|
370
|
+
projectId: string;
|
|
371
|
+
parentBranch: string;
|
|
372
|
+
} | undefined;
|
|
373
|
+
} | undefined;
|
|
374
|
+
issueManagement?: {
|
|
375
|
+
github?: {
|
|
376
|
+
remote: string;
|
|
377
|
+
} | undefined;
|
|
378
|
+
} | undefined;
|
|
1006
379
|
}, {
|
|
1007
380
|
mainBranch?: string | undefined;
|
|
1008
381
|
worktreePrefix?: string | undefined;
|
|
@@ -1044,62 +417,756 @@ declare const IloomSettingsSchema: z.ZodObject<{
|
|
|
1044
417
|
databaseUrlEnvVarName?: string | undefined;
|
|
1045
418
|
} | undefined;
|
|
1046
419
|
} | undefined;
|
|
420
|
+
databaseProviders?: {
|
|
421
|
+
neon?: {
|
|
422
|
+
projectId: string;
|
|
423
|
+
parentBranch: string;
|
|
424
|
+
} | undefined;
|
|
425
|
+
} | undefined;
|
|
426
|
+
issueManagement?: {
|
|
427
|
+
github?: {
|
|
428
|
+
remote: string;
|
|
429
|
+
} | undefined;
|
|
430
|
+
} | undefined;
|
|
1047
431
|
}>;
|
|
1048
432
|
/**
|
|
1049
|
-
* TypeScript type for iloom settings derived from Zod schema
|
|
433
|
+
* TypeScript type for iloom settings derived from Zod schema
|
|
434
|
+
*/
|
|
435
|
+
type IloomSettings = z.infer<typeof IloomSettingsSchema>;
|
|
436
|
+
/**
|
|
437
|
+
* Manages project-level settings from .iloom/settings.json
|
|
438
|
+
*/
|
|
439
|
+
declare class SettingsManager {
|
|
440
|
+
/**
|
|
441
|
+
* Load settings from <PROJECT_ROOT>/.iloom/settings.json and settings.local.json
|
|
442
|
+
* Merges settings.local.json over settings.json with priority
|
|
443
|
+
* CLI overrides have highest priority if provided
|
|
444
|
+
* Returns empty object if both files don't exist (not an error)
|
|
445
|
+
*/
|
|
446
|
+
loadSettings(projectRoot?: string, cliOverrides?: Partial<IloomSettings>): Promise<IloomSettings>;
|
|
447
|
+
/**
|
|
448
|
+
* Log the final merged configuration for debugging
|
|
449
|
+
*/
|
|
450
|
+
private logFinalConfiguration;
|
|
451
|
+
/**
|
|
452
|
+
* Load and parse a single settings file
|
|
453
|
+
* Returns empty object if file doesn't exist (not an error)
|
|
454
|
+
*/
|
|
455
|
+
private loadSettingsFile;
|
|
456
|
+
/**
|
|
457
|
+
* Deep merge two settings objects with priority to override
|
|
458
|
+
* Uses deepmerge library with array replacement strategy
|
|
459
|
+
*/
|
|
460
|
+
private mergeSettings;
|
|
461
|
+
/**
|
|
462
|
+
* Format all Zod validation errors into a single error message
|
|
463
|
+
*/
|
|
464
|
+
private formatAllZodErrors;
|
|
465
|
+
/**
|
|
466
|
+
* Validate settings structure and model names using Zod schema
|
|
467
|
+
* This method is kept for testing purposes but uses Zod internally
|
|
468
|
+
* @internal - Only used in tests via bracket notation
|
|
469
|
+
*/
|
|
470
|
+
private validateSettings;
|
|
471
|
+
/**
|
|
472
|
+
* Get project root (defaults to process.cwd())
|
|
473
|
+
*/
|
|
474
|
+
private getProjectRoot;
|
|
475
|
+
/**
|
|
476
|
+
* Get effective protected branches list with mainBranch always included
|
|
477
|
+
*
|
|
478
|
+
* This method provides a single source of truth for protected branches logic:
|
|
479
|
+
* 1. Use configured protectedBranches if provided
|
|
480
|
+
* 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']
|
|
481
|
+
* 3. ALWAYS ensure mainBranch is included even if user configured custom list
|
|
482
|
+
*
|
|
483
|
+
* @param projectRoot - Optional project root directory (defaults to process.cwd())
|
|
484
|
+
* @returns Array of protected branch names with mainBranch guaranteed to be included
|
|
485
|
+
*/
|
|
486
|
+
getProtectedBranches(projectRoot?: string): Promise<string[]>;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Manages Git worktrees for the iloom CLI
|
|
491
|
+
* Ports functionality from bash scripts into TypeScript
|
|
492
|
+
*/
|
|
493
|
+
declare class GitWorktreeManager {
|
|
494
|
+
private readonly _workingDirectory;
|
|
495
|
+
constructor(workingDirectory?: string);
|
|
496
|
+
/**
|
|
497
|
+
* Get the working directory for git operations (main worktree path)
|
|
498
|
+
*/
|
|
499
|
+
get workingDirectory(): string;
|
|
500
|
+
/**
|
|
501
|
+
* List all worktrees in the repository
|
|
502
|
+
* Defaults to porcelain format for reliable machine parsing
|
|
503
|
+
* Equivalent to: git worktree list --porcelain
|
|
504
|
+
*/
|
|
505
|
+
listWorktrees(options?: WorktreeListOptions): Promise<GitWorktree[]>;
|
|
506
|
+
/**
|
|
507
|
+
* Find worktree for a specific branch
|
|
508
|
+
* Ports: find_worktree_for_branch() from find-worktree-for-branch.sh
|
|
509
|
+
*/
|
|
510
|
+
findWorktreeForBranch(branchName: string): Promise<GitWorktree | null>;
|
|
511
|
+
/**
|
|
512
|
+
* Check if a worktree is the main repository worktree
|
|
513
|
+
* Uses findMainWorktreePathWithSettings to determine the main worktree based on settings.
|
|
514
|
+
*
|
|
515
|
+
* @param worktree - The worktree to check
|
|
516
|
+
* @param settingsManager - SettingsManager instance for loading settings
|
|
517
|
+
* @returns true if the worktree is the main worktree
|
|
518
|
+
*/
|
|
519
|
+
isMainWorktree(worktree: GitWorktree, settingsManager: SettingsManager): Promise<boolean>;
|
|
520
|
+
/**
|
|
521
|
+
* Check if a worktree is a PR worktree based on naming patterns
|
|
522
|
+
* Ports: is_pr_worktree() from worktree-utils.sh
|
|
523
|
+
*/
|
|
524
|
+
isPRWorktree(worktree: GitWorktree): boolean;
|
|
525
|
+
/**
|
|
526
|
+
* Get PR number from worktree branch name
|
|
527
|
+
* Ports: get_pr_number_from_worktree() from worktree-utils.sh
|
|
528
|
+
*/
|
|
529
|
+
getPRNumberFromWorktree(worktree: GitWorktree): number | null;
|
|
530
|
+
/**
|
|
531
|
+
* Create a new worktree
|
|
532
|
+
* Ports worktree creation logic from new-branch-workflow.sh
|
|
533
|
+
* @returns The absolute path to the created worktree
|
|
534
|
+
*/
|
|
535
|
+
createWorktree(options: WorktreeCreateOptions): Promise<string>;
|
|
536
|
+
/**
|
|
537
|
+
* Remove a worktree and optionally clean up associated files
|
|
538
|
+
* Ports worktree removal logic from cleanup-worktree.sh
|
|
539
|
+
* @returns A message describing what was done (for dry-run mode)
|
|
540
|
+
*/
|
|
541
|
+
removeWorktree(worktreePath: string, options?: WorktreeCleanupOptions): Promise<string | void>;
|
|
542
|
+
/**
|
|
543
|
+
* Validate worktree state and integrity
|
|
544
|
+
*/
|
|
545
|
+
validateWorktree(worktreePath: string): Promise<WorktreeValidation>;
|
|
546
|
+
/**
|
|
547
|
+
* Get detailed status information for a worktree
|
|
548
|
+
*/
|
|
549
|
+
getWorktreeStatus(worktreePath: string): Promise<WorktreeStatus>;
|
|
550
|
+
/**
|
|
551
|
+
* Generate a suggested worktree path for a branch
|
|
552
|
+
*/
|
|
553
|
+
generateWorktreePath(branchName: string, customRoot?: string, options?: {
|
|
554
|
+
isPR?: boolean;
|
|
555
|
+
prNumber?: number;
|
|
556
|
+
prefix?: string;
|
|
557
|
+
}): string;
|
|
558
|
+
/**
|
|
559
|
+
* Sanitize a branch name for use as a directory name
|
|
560
|
+
* Replaces slashes with dashes and removes invalid filesystem characters
|
|
561
|
+
* Ports logic from bash script line 593: ${BRANCH_NAME//\\//-}
|
|
562
|
+
*/
|
|
563
|
+
sanitizeBranchName(branchName: string): string;
|
|
564
|
+
/**
|
|
565
|
+
* Check if repository is in a valid state for worktree operations
|
|
566
|
+
*/
|
|
567
|
+
isRepoReady(): Promise<boolean>;
|
|
568
|
+
/**
|
|
569
|
+
* Get repository information
|
|
570
|
+
*/
|
|
571
|
+
getRepoInfo(): Promise<{
|
|
572
|
+
root: string | null;
|
|
573
|
+
defaultBranch: string;
|
|
574
|
+
currentBranch: string | null;
|
|
575
|
+
}>;
|
|
576
|
+
/**
|
|
577
|
+
* Prune stale worktree entries (worktrees that no longer exist on disk)
|
|
578
|
+
*/
|
|
579
|
+
pruneWorktrees(): Promise<void>;
|
|
580
|
+
/**
|
|
581
|
+
* Lock a worktree to prevent it from being pruned or moved
|
|
582
|
+
*/
|
|
583
|
+
lockWorktree(worktreePath: string, reason?: string): Promise<void>;
|
|
584
|
+
/**
|
|
585
|
+
* Unlock a previously locked worktree
|
|
586
|
+
*/
|
|
587
|
+
unlockWorktree(worktreePath: string): Promise<void>;
|
|
588
|
+
/**
|
|
589
|
+
* Find worktrees matching an identifier (branch name, path, or PR number)
|
|
590
|
+
*/
|
|
591
|
+
findWorktreesByIdentifier(identifier: string): Promise<GitWorktree[]>;
|
|
592
|
+
/**
|
|
593
|
+
* Find worktree for a specific issue number using exact pattern matching
|
|
594
|
+
* Matches: issue-{N} at start OR after /, -, _ (but NOT issue-{N}X where X is a digit)
|
|
595
|
+
* Supports patterns like: issue-44, feat/issue-44-feature, feat-issue-44, bugfix_issue-44, etc.
|
|
596
|
+
* Avoids false matches like: tissue-44, myissue-44
|
|
597
|
+
* Ports: find_existing_worktree() from bash script lines 131-165
|
|
598
|
+
*/
|
|
599
|
+
findWorktreeForIssue(issueNumber: number): Promise<GitWorktree | null>;
|
|
600
|
+
/**
|
|
601
|
+
* Find worktree for a specific PR by branch name
|
|
602
|
+
* Ports: find_existing_worktree() for PR type from bash script lines 149-160
|
|
603
|
+
*/
|
|
604
|
+
findWorktreeForPR(prNumber: number, branchName: string): Promise<GitWorktree | null>;
|
|
605
|
+
/**
|
|
606
|
+
* Remove multiple worktrees
|
|
607
|
+
* Returns a summary of successes and failures
|
|
608
|
+
* Automatically filters out the main worktree
|
|
609
|
+
*
|
|
610
|
+
* @param worktrees - Array of worktrees to remove
|
|
611
|
+
* @param settingsManager - SettingsManager instance for determining main worktree
|
|
612
|
+
* @param options - Cleanup options
|
|
613
|
+
*/
|
|
614
|
+
removeWorktrees(worktrees: GitWorktree[], settingsManager: SettingsManager, options?: WorktreeCleanupOptions): Promise<{
|
|
615
|
+
successes: Array<{
|
|
616
|
+
worktree: GitWorktree;
|
|
617
|
+
}>;
|
|
618
|
+
failures: Array<{
|
|
619
|
+
worktree: GitWorktree;
|
|
620
|
+
error: string;
|
|
621
|
+
}>;
|
|
622
|
+
skipped: Array<{
|
|
623
|
+
worktree: GitWorktree;
|
|
624
|
+
reason: string;
|
|
625
|
+
}>;
|
|
626
|
+
}>;
|
|
627
|
+
/**
|
|
628
|
+
* Format worktree information for display
|
|
629
|
+
*/
|
|
630
|
+
formatWorktree(worktree: GitWorktree): {
|
|
631
|
+
title: string;
|
|
632
|
+
path: string;
|
|
633
|
+
commit: string;
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
interface EnvVariable {
|
|
638
|
+
key: string;
|
|
639
|
+
value: string;
|
|
640
|
+
}
|
|
641
|
+
interface EnvFileOptions {
|
|
642
|
+
path: string;
|
|
643
|
+
backup?: boolean;
|
|
644
|
+
encoding?: BufferEncoding;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* @deprecated Use exception-based error handling instead
|
|
648
|
+
*/
|
|
649
|
+
interface EnvOperationResult {
|
|
650
|
+
success: boolean;
|
|
651
|
+
backupPath?: string;
|
|
652
|
+
error?: string;
|
|
653
|
+
}
|
|
654
|
+
interface PortAssignmentOptions {
|
|
655
|
+
basePort?: number;
|
|
656
|
+
issueNumber?: number;
|
|
657
|
+
prNumber?: number;
|
|
658
|
+
branchName?: string;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
type ProjectCapability = 'cli' | 'web';
|
|
662
|
+
type Capability = ProjectCapability;
|
|
663
|
+
interface Loom {
|
|
664
|
+
id: string;
|
|
665
|
+
path: string;
|
|
666
|
+
branch: string;
|
|
667
|
+
type: 'issue' | 'pr' | 'branch';
|
|
668
|
+
identifier: string | number;
|
|
669
|
+
port: number;
|
|
670
|
+
databaseBranch?: string;
|
|
671
|
+
createdAt: Date;
|
|
672
|
+
lastAccessed: Date;
|
|
673
|
+
githubData?: {
|
|
674
|
+
title?: string;
|
|
675
|
+
body?: string;
|
|
676
|
+
url?: string;
|
|
677
|
+
state?: string;
|
|
678
|
+
};
|
|
679
|
+
capabilities?: ProjectCapability[];
|
|
680
|
+
binEntries?: Record<string, string>;
|
|
681
|
+
cliSymlinks?: string[];
|
|
682
|
+
}
|
|
683
|
+
interface CreateLoomInput {
|
|
684
|
+
type: 'issue' | 'pr' | 'branch';
|
|
685
|
+
identifier: string | number;
|
|
686
|
+
originalInput: string;
|
|
687
|
+
baseBranch?: string;
|
|
688
|
+
options?: {
|
|
689
|
+
skipDatabase?: boolean;
|
|
690
|
+
skipColorSync?: boolean;
|
|
691
|
+
enableClaude?: boolean;
|
|
692
|
+
enableCode?: boolean;
|
|
693
|
+
enableDevServer?: boolean;
|
|
694
|
+
enableTerminal?: boolean;
|
|
695
|
+
oneShot?: OneShotMode;
|
|
696
|
+
setArguments?: string[];
|
|
697
|
+
executablePath?: string;
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
type LaunchMode = 'editor' | 'terminal' | 'both';
|
|
701
|
+
interface LoomSummary {
|
|
702
|
+
id: string;
|
|
703
|
+
type: 'issue' | 'pr' | 'branch';
|
|
704
|
+
identifier: string | number;
|
|
705
|
+
title?: string;
|
|
706
|
+
branch: string;
|
|
707
|
+
port: number;
|
|
708
|
+
status: 'active' | 'stale' | 'error';
|
|
709
|
+
lastAccessed: string;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Options for ResourceCleanup operations
|
|
1050
714
|
*/
|
|
1051
|
-
|
|
715
|
+
interface ResourceCleanupOptions {
|
|
716
|
+
/** Preview operations without executing */
|
|
717
|
+
dryRun?: boolean;
|
|
718
|
+
/** Skip confirmations and safety checks */
|
|
719
|
+
force?: boolean;
|
|
720
|
+
/** Delete the associated branch */
|
|
721
|
+
deleteBranch?: boolean;
|
|
722
|
+
/** Keep database branch instead of deleting */
|
|
723
|
+
keepDatabase?: boolean;
|
|
724
|
+
/** Prompt for confirmation before operations */
|
|
725
|
+
interactive?: boolean;
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Result of a cleanup operation
|
|
729
|
+
*/
|
|
730
|
+
interface CleanupResult {
|
|
731
|
+
/** Identifier that was cleaned up */
|
|
732
|
+
identifier: string;
|
|
733
|
+
/** Actual branch name that was found (will differ from identifier) */
|
|
734
|
+
branchName?: string;
|
|
735
|
+
/** Overall success status */
|
|
736
|
+
success: boolean;
|
|
737
|
+
/** Individual operation results */
|
|
738
|
+
operations: OperationResult[];
|
|
739
|
+
/** Errors encountered during cleanup */
|
|
740
|
+
errors: Error[];
|
|
741
|
+
/** Whether rollback is required */
|
|
742
|
+
rollbackRequired?: boolean;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Result of an individual cleanup operation
|
|
746
|
+
*/
|
|
747
|
+
interface OperationResult {
|
|
748
|
+
/** Type of operation performed */
|
|
749
|
+
type: 'dev-server' | 'worktree' | 'branch' | 'database' | 'cli-symlinks';
|
|
750
|
+
/** Whether operation succeeded */
|
|
751
|
+
success: boolean;
|
|
752
|
+
/** Human-readable message */
|
|
753
|
+
message: string;
|
|
754
|
+
/** Error message if operation failed */
|
|
755
|
+
error?: string;
|
|
756
|
+
/** For database operations: whether branch was actually deleted (vs not found) */
|
|
757
|
+
deleted?: boolean;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Safety check result
|
|
761
|
+
*/
|
|
762
|
+
interface SafetyCheck {
|
|
763
|
+
/** Whether cleanup is safe to proceed */
|
|
764
|
+
isSafe: boolean;
|
|
765
|
+
/** Non-blocking warnings */
|
|
766
|
+
warnings: string[];
|
|
767
|
+
/** Blocking issues that prevent cleanup */
|
|
768
|
+
blockers: string[];
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Options for branch deletion
|
|
772
|
+
*/
|
|
773
|
+
interface BranchDeleteOptions {
|
|
774
|
+
/** Force delete unmerged branch */
|
|
775
|
+
force?: boolean;
|
|
776
|
+
/** Also delete remote branch */
|
|
777
|
+
remote?: boolean;
|
|
778
|
+
/** Preview without executing */
|
|
779
|
+
dryRun?: boolean;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Target for batch cleanup - represents a branch that may or may not have a worktree
|
|
783
|
+
*/
|
|
784
|
+
interface BranchCleanupTarget {
|
|
785
|
+
/** Branch name */
|
|
786
|
+
branchName: string;
|
|
787
|
+
/** Whether this branch has an associated worktree */
|
|
788
|
+
hasWorktree: boolean;
|
|
789
|
+
/** Path to worktree if it exists */
|
|
790
|
+
worktreePath?: string;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Result of batch cleanup operation for an issue
|
|
794
|
+
*/
|
|
795
|
+
interface BatchCleanupResult {
|
|
796
|
+
/** Issue number that was cleaned up */
|
|
797
|
+
issueNumber: number;
|
|
798
|
+
/** Number of branches found matching the issue */
|
|
799
|
+
targetsFound: number;
|
|
800
|
+
/** Number of worktrees successfully removed */
|
|
801
|
+
worktreesRemoved: number;
|
|
802
|
+
/** Number of branches successfully deleted */
|
|
803
|
+
branchesDeleted: number;
|
|
804
|
+
/** Number of failed operations */
|
|
805
|
+
failed: number;
|
|
806
|
+
/** Individual cleanup results for each branch */
|
|
807
|
+
results: CleanupResult[];
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Information about a running process
|
|
812
|
+
*/
|
|
813
|
+
interface ProcessInfo {
|
|
814
|
+
/** Process ID */
|
|
815
|
+
pid: number;
|
|
816
|
+
/** Process name (e.g., "node", "pnpm") */
|
|
817
|
+
name: string;
|
|
818
|
+
/** Full command line */
|
|
819
|
+
command: string;
|
|
820
|
+
/** Port the process is listening on */
|
|
821
|
+
port: number;
|
|
822
|
+
/** Whether this appears to be a dev server */
|
|
823
|
+
isDevServer: boolean;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
interface Workspace {
|
|
827
|
+
id: string;
|
|
828
|
+
path: string;
|
|
829
|
+
branch: string;
|
|
830
|
+
issueNumber?: number;
|
|
831
|
+
prNumber?: number;
|
|
832
|
+
port: number;
|
|
833
|
+
databaseBranch?: string;
|
|
834
|
+
createdAt: Date;
|
|
835
|
+
lastAccessed: Date;
|
|
836
|
+
}
|
|
837
|
+
interface WorkspaceInput {
|
|
838
|
+
identifier: string;
|
|
839
|
+
type: 'issue' | 'pr' | 'branch';
|
|
840
|
+
skipClaude?: boolean;
|
|
841
|
+
}
|
|
842
|
+
interface WorkspaceSummary {
|
|
843
|
+
id: string;
|
|
844
|
+
issueNumber?: number;
|
|
845
|
+
prNumber?: number;
|
|
846
|
+
title: string;
|
|
847
|
+
branch: string;
|
|
848
|
+
port: number;
|
|
849
|
+
status: 'active' | 'stale' | 'error';
|
|
850
|
+
lastAccessed: string;
|
|
851
|
+
}
|
|
852
|
+
interface Worktree {
|
|
853
|
+
path: string;
|
|
854
|
+
branch: string;
|
|
855
|
+
commit: string;
|
|
856
|
+
isPR: boolean;
|
|
857
|
+
prNumber?: number;
|
|
858
|
+
issueNumber?: number;
|
|
859
|
+
port?: number;
|
|
860
|
+
}
|
|
861
|
+
interface GitStatus {
|
|
862
|
+
hasUncommittedChanges: boolean;
|
|
863
|
+
unstagedFiles: string[];
|
|
864
|
+
stagedFiles: string[];
|
|
865
|
+
currentBranch: string;
|
|
866
|
+
isAheadOfRemote: boolean;
|
|
867
|
+
isBehindRemote: boolean;
|
|
868
|
+
}
|
|
869
|
+
interface Issue {
|
|
870
|
+
number: number;
|
|
871
|
+
title: string;
|
|
872
|
+
body: string;
|
|
873
|
+
state: 'open' | 'closed';
|
|
874
|
+
labels: string[];
|
|
875
|
+
assignees: string[];
|
|
876
|
+
url: string;
|
|
877
|
+
}
|
|
878
|
+
interface PullRequest {
|
|
879
|
+
number: number;
|
|
880
|
+
title: string;
|
|
881
|
+
body: string;
|
|
882
|
+
state: 'open' | 'closed' | 'merged';
|
|
883
|
+
branch: string;
|
|
884
|
+
baseBranch: string;
|
|
885
|
+
url: string;
|
|
886
|
+
isDraft: boolean;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Result of database branch deletion operation
|
|
890
|
+
* Distinguishes between successful deletion, branch not found, and errors
|
|
891
|
+
*/
|
|
892
|
+
interface DatabaseDeletionResult {
|
|
893
|
+
/** Overall operation succeeded (true even if branch didn't exist) */
|
|
894
|
+
success: boolean;
|
|
895
|
+
/** True only if a branch was actually deleted */
|
|
896
|
+
deleted: boolean;
|
|
897
|
+
/** True if branch didn't exist (not an error, just nothing to do) */
|
|
898
|
+
notFound: boolean;
|
|
899
|
+
/** Error message if operation failed */
|
|
900
|
+
error?: string;
|
|
901
|
+
/** User declined deletion (for preview databases) */
|
|
902
|
+
userDeclined?: boolean;
|
|
903
|
+
/** Name of the branch that was processed */
|
|
904
|
+
branchName?: string;
|
|
905
|
+
}
|
|
906
|
+
interface DatabaseProvider {
|
|
907
|
+
createBranch(name: string, fromBranch?: string, cwd?: string): Promise<string>;
|
|
908
|
+
deleteBranch(name: string, isPreview?: boolean, cwd?: string): Promise<DatabaseDeletionResult>;
|
|
909
|
+
getConnectionString(branch: string, cwd?: string): Promise<string>;
|
|
910
|
+
listBranches(cwd?: string): Promise<string[]>;
|
|
911
|
+
branchExists(name: string, cwd?: string): Promise<boolean>;
|
|
912
|
+
findPreviewBranch(branchName: string, cwd?: string): Promise<string | null>;
|
|
913
|
+
getBranchNameFromEndpoint(endpointId: string, cwd?: string): Promise<string | null>;
|
|
914
|
+
sanitizeBranchName(branchName: string): string;
|
|
915
|
+
isAuthenticated(cwd?: string): Promise<boolean>;
|
|
916
|
+
isCliAvailable(): Promise<boolean>;
|
|
917
|
+
isConfigured(): boolean;
|
|
918
|
+
}
|
|
919
|
+
interface Config {
|
|
920
|
+
defaultPort: number;
|
|
921
|
+
databaseProvider?: 'neon' | 'supabase' | 'planetscale';
|
|
922
|
+
claudeModel?: 'opus' | 'sonnet' | 'haiku';
|
|
923
|
+
skipClaude?: boolean;
|
|
924
|
+
customWorkspaceRoot?: string;
|
|
925
|
+
}
|
|
926
|
+
type OneShotMode = 'default' | 'noReview' | 'bypassPermissions';
|
|
927
|
+
interface StartOptions {
|
|
928
|
+
claude?: boolean;
|
|
929
|
+
code?: boolean;
|
|
930
|
+
devServer?: boolean;
|
|
931
|
+
terminal?: boolean;
|
|
932
|
+
oneShot?: OneShotMode;
|
|
933
|
+
}
|
|
934
|
+
interface AddIssueOptions {
|
|
935
|
+
}
|
|
936
|
+
interface FeedbackOptions {
|
|
937
|
+
}
|
|
938
|
+
interface EnhanceOptions {
|
|
939
|
+
noBrowser?: boolean;
|
|
940
|
+
}
|
|
941
|
+
interface FinishOptions {
|
|
942
|
+
force?: boolean;
|
|
943
|
+
dryRun?: boolean;
|
|
944
|
+
pr?: number;
|
|
945
|
+
skipBuild?: boolean;
|
|
946
|
+
}
|
|
1052
947
|
/**
|
|
1053
|
-
*
|
|
948
|
+
* Options for the cleanup command
|
|
949
|
+
* All flags are optional and can be combined (subject to validation)
|
|
1054
950
|
*/
|
|
1055
|
-
|
|
951
|
+
interface CleanupOptions {
|
|
952
|
+
/** List all worktrees without removing anything */
|
|
953
|
+
list?: boolean;
|
|
954
|
+
/** Remove all worktrees (interactive confirmation required unless --force) */
|
|
955
|
+
all?: boolean;
|
|
956
|
+
/** Cleanup by specific issue number */
|
|
957
|
+
issue?: number;
|
|
958
|
+
/** Skip confirmations and force removal */
|
|
959
|
+
force?: boolean;
|
|
960
|
+
/** Show what would be done without actually doing it */
|
|
961
|
+
dryRun?: boolean;
|
|
962
|
+
}
|
|
963
|
+
interface ListOptions {
|
|
964
|
+
json?: boolean;
|
|
965
|
+
}
|
|
966
|
+
interface MockOptions {
|
|
967
|
+
scenario: 'empty' | 'existing' | 'conflicts' | 'error';
|
|
968
|
+
data?: unknown;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
interface RgbColor {
|
|
972
|
+
r: number;
|
|
973
|
+
g: number;
|
|
974
|
+
b: number;
|
|
975
|
+
}
|
|
976
|
+
interface ColorData {
|
|
977
|
+
rgb: RgbColor;
|
|
978
|
+
hex: string;
|
|
979
|
+
index: number;
|
|
980
|
+
}
|
|
981
|
+
type Platform = 'darwin' | 'linux' | 'win32' | 'unsupported';
|
|
982
|
+
interface ValidationOptions {
|
|
983
|
+
dryRun?: boolean;
|
|
984
|
+
skipTypecheck?: boolean;
|
|
985
|
+
skipLint?: boolean;
|
|
986
|
+
skipTests?: boolean;
|
|
987
|
+
}
|
|
988
|
+
interface ValidationStepResult {
|
|
989
|
+
step: 'typecheck' | 'lint' | 'test';
|
|
990
|
+
passed: boolean;
|
|
991
|
+
skipped: boolean;
|
|
992
|
+
output?: string;
|
|
993
|
+
error?: string;
|
|
994
|
+
duration?: number;
|
|
995
|
+
}
|
|
996
|
+
interface ValidationResult {
|
|
997
|
+
success: boolean;
|
|
998
|
+
steps: ValidationStepResult[];
|
|
999
|
+
totalDuration: number;
|
|
1000
|
+
}
|
|
1001
|
+
interface CommitOptions {
|
|
1002
|
+
dryRun?: boolean;
|
|
1003
|
+
issueNumber?: number;
|
|
1004
|
+
message?: string;
|
|
1005
|
+
noReview?: boolean;
|
|
1006
|
+
skipVerify?: boolean;
|
|
1007
|
+
}
|
|
1008
|
+
interface MergeOptions {
|
|
1009
|
+
dryRun?: boolean;
|
|
1010
|
+
force?: boolean;
|
|
1011
|
+
repoRoot?: string;
|
|
1012
|
+
}
|
|
1013
|
+
interface MergeResult {
|
|
1014
|
+
success: boolean;
|
|
1015
|
+
branchName: string;
|
|
1016
|
+
commitsMerged: number;
|
|
1017
|
+
rebaseCompleted: boolean;
|
|
1018
|
+
mergeCompleted: boolean;
|
|
1019
|
+
}
|
|
1020
|
+
interface UpdateCheckCache {
|
|
1021
|
+
lastCheck: number;
|
|
1022
|
+
latestVersion: string;
|
|
1023
|
+
}
|
|
1024
|
+
interface UpdateCheckResult {
|
|
1025
|
+
currentVersion: string;
|
|
1026
|
+
latestVersion: string;
|
|
1027
|
+
updateAvailable: boolean;
|
|
1028
|
+
}
|
|
1029
|
+
type InstallationMethod = 'global' | 'local' | 'linked' | 'unknown';
|
|
1030
|
+
|
|
1031
|
+
interface GitHubInputDetection {
|
|
1032
|
+
type: 'issue' | 'pr' | 'unknown';
|
|
1033
|
+
number: number | null;
|
|
1034
|
+
rawInput: string;
|
|
1035
|
+
}
|
|
1036
|
+
interface BranchNameStrategy {
|
|
1037
|
+
generate(issueNumber: number, title: string): Promise<string>;
|
|
1038
|
+
}
|
|
1039
|
+
interface BranchGenerationOptions {
|
|
1040
|
+
issueNumber: number;
|
|
1041
|
+
title: string;
|
|
1042
|
+
strategy?: BranchNameStrategy;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
declare class GitHubService {
|
|
1046
|
+
private defaultBranchNameStrategy;
|
|
1047
|
+
private prompter;
|
|
1048
|
+
constructor(options?: {
|
|
1049
|
+
branchNameStrategy?: BranchNameStrategy;
|
|
1050
|
+
useClaude?: boolean;
|
|
1051
|
+
claudeModel?: string;
|
|
1052
|
+
prompter?: (message: string) => Promise<boolean>;
|
|
1053
|
+
});
|
|
1054
|
+
detectInputType(input: string, repo?: string): Promise<GitHubInputDetection>;
|
|
1055
|
+
fetchIssue(issueNumber: number, repo?: string): Promise<Issue>;
|
|
1056
|
+
isValidIssue(issueNumber: number, repo?: string): Promise<Issue | false>;
|
|
1057
|
+
private fetchIssueInternal;
|
|
1058
|
+
validateIssueState(issue: Issue): Promise<void>;
|
|
1059
|
+
fetchPR(prNumber: number, repo?: string): Promise<PullRequest>;
|
|
1060
|
+
isValidPR(prNumber: number, repo?: string): Promise<PullRequest | false>;
|
|
1061
|
+
private fetchPRInternal;
|
|
1062
|
+
validatePRState(pr: PullRequest): Promise<void>;
|
|
1063
|
+
generateBranchName(options: BranchGenerationOptions): Promise<string>;
|
|
1064
|
+
createIssue(title: string, body: string, repository?: string, labels?: string[]): Promise<{
|
|
1065
|
+
number: number;
|
|
1066
|
+
url: string;
|
|
1067
|
+
}>;
|
|
1068
|
+
getIssueUrl(issueNumber: number, repo?: string): Promise<string>;
|
|
1069
|
+
moveIssueToInProgress(issueNumber: number): Promise<void>;
|
|
1070
|
+
private updateIssueStatusInProject;
|
|
1071
|
+
extractContext(entity: Issue | PullRequest): string;
|
|
1072
|
+
private mapGitHubIssueToIssue;
|
|
1073
|
+
private mapGitHubPRToPullRequest;
|
|
1074
|
+
private promptUserConfirmation;
|
|
1075
|
+
setDefaultBranchNameStrategy(strategy: BranchNameStrategy): void;
|
|
1076
|
+
getBranchNameStrategy(): BranchNameStrategy;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
declare class EnvironmentManager {
|
|
1080
|
+
private readonly backupSuffix;
|
|
1056
1081
|
/**
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1060
|
-
* Returns empty object if both files don't exist (not an error)
|
|
1082
|
+
* Set or update an environment variable in a .env file
|
|
1083
|
+
* Ports functionality from bash/utils/env-utils.sh:setEnvVar()
|
|
1084
|
+
* @returns The backup path if a backup was created
|
|
1061
1085
|
*/
|
|
1062
|
-
|
|
1086
|
+
setEnvVar(filePath: string, key: string, value: string, backup?: boolean): Promise<string | void>;
|
|
1063
1087
|
/**
|
|
1064
|
-
*
|
|
1088
|
+
* Read and parse a .env file
|
|
1065
1089
|
*/
|
|
1066
|
-
|
|
1090
|
+
readEnvFile(filePath: string): Promise<Map<string, string>>;
|
|
1067
1091
|
/**
|
|
1068
|
-
*
|
|
1069
|
-
*
|
|
1092
|
+
* Generic file copy helper that only copies if source exists
|
|
1093
|
+
* Does not throw if source file doesn't exist - just logs and returns
|
|
1094
|
+
* @private
|
|
1070
1095
|
*/
|
|
1071
|
-
|
|
1096
|
+
copyIfExists(source: string, destination: string): Promise<void>;
|
|
1072
1097
|
/**
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1098
|
+
* Calculate unique port for workspace
|
|
1099
|
+
* Implements:
|
|
1100
|
+
* - Issue/PR: 3000 + issue/PR number
|
|
1101
|
+
* - Branch: 3000 + deterministic hash offset (1-999)
|
|
1075
1102
|
*/
|
|
1076
|
-
|
|
1103
|
+
calculatePort(options: PortAssignmentOptions): number;
|
|
1077
1104
|
/**
|
|
1078
|
-
*
|
|
1105
|
+
* Set port environment variable for workspace
|
|
1079
1106
|
*/
|
|
1080
|
-
|
|
1107
|
+
setPortForWorkspace(envFilePath: string, issueNumber?: number, prNumber?: number, branchName?: string): Promise<number>;
|
|
1081
1108
|
/**
|
|
1082
|
-
* Validate
|
|
1083
|
-
* This method is kept for testing purposes but uses Zod internally
|
|
1084
|
-
* @internal - Only used in tests via bracket notation
|
|
1109
|
+
* Validate environment configuration
|
|
1085
1110
|
*/
|
|
1086
|
-
|
|
1111
|
+
validateEnvFile(filePath: string): Promise<{
|
|
1112
|
+
valid: boolean;
|
|
1113
|
+
errors: string[];
|
|
1114
|
+
}>;
|
|
1087
1115
|
/**
|
|
1088
|
-
*
|
|
1116
|
+
* Create backup of existing file
|
|
1089
1117
|
*/
|
|
1090
|
-
private
|
|
1118
|
+
private createBackup;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Database Manager - orchestrates database operations with conditional execution
|
|
1123
|
+
* Ports functionality from bash scripts with guard conditions:
|
|
1124
|
+
* 1. Database provider must be properly configured (provider.isConfigured())
|
|
1125
|
+
* 2. The worktree's .env file must contain the configured database URL variable (default: DATABASE_URL)
|
|
1126
|
+
*
|
|
1127
|
+
* This ensures database branching only occurs for projects that actually use databases
|
|
1128
|
+
*/
|
|
1129
|
+
declare class DatabaseManager {
|
|
1130
|
+
private provider;
|
|
1131
|
+
private environment;
|
|
1132
|
+
private databaseUrlEnvVarName;
|
|
1133
|
+
constructor(provider: DatabaseProvider, environment: EnvironmentManager, databaseUrlEnvVarName?: string);
|
|
1091
1134
|
/**
|
|
1092
|
-
* Get
|
|
1135
|
+
* Get the configured database URL environment variable name
|
|
1136
|
+
*/
|
|
1137
|
+
getConfiguredVariableName(): string;
|
|
1138
|
+
/**
|
|
1139
|
+
* Check if database branching should be used
|
|
1140
|
+
* Requires BOTH conditions:
|
|
1141
|
+
* 1. Database provider is properly configured (checked via provider.isConfigured())
|
|
1142
|
+
* 2. .env file contains the configured database URL variable
|
|
1143
|
+
*/
|
|
1144
|
+
shouldUseDatabaseBranching(envFilePath: string): Promise<boolean>;
|
|
1145
|
+
/**
|
|
1146
|
+
* Create database branch only if configured
|
|
1147
|
+
* Returns connection string if branch was created, null if skipped
|
|
1093
1148
|
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1097
|
-
|
|
1149
|
+
* @param branchName - Name of the branch to create
|
|
1150
|
+
* @param envFilePath - Path to .env file for configuration checks
|
|
1151
|
+
* @param cwd - Optional working directory to run commands from
|
|
1152
|
+
*/
|
|
1153
|
+
createBranchIfConfigured(branchName: string, envFilePath: string, cwd?: string): Promise<string | null>;
|
|
1154
|
+
/**
|
|
1155
|
+
* Delete database branch only if configured
|
|
1156
|
+
* Returns result object indicating what happened
|
|
1098
1157
|
*
|
|
1099
|
-
* @param
|
|
1100
|
-
* @
|
|
1158
|
+
* @param branchName - Name of the branch to delete
|
|
1159
|
+
* @param shouldCleanup - Boolean indicating if database cleanup should be performed (pre-fetched config)
|
|
1160
|
+
* @param isPreview - Whether this is a preview database branch
|
|
1161
|
+
* @param cwd - Optional working directory to run commands from (prevents issues with deleted directories)
|
|
1101
1162
|
*/
|
|
1102
|
-
|
|
1163
|
+
deleteBranchIfConfigured(branchName: string, shouldCleanup: boolean, isPreview?: boolean, cwd?: string): Promise<DatabaseDeletionResult>;
|
|
1164
|
+
/**
|
|
1165
|
+
* Check if .env has the configured database URL variable
|
|
1166
|
+
* CRITICAL: If user explicitly configured a custom variable name (not default),
|
|
1167
|
+
* throw an error if it's missing from .env
|
|
1168
|
+
*/
|
|
1169
|
+
private hasDatabaseUrlInEnv;
|
|
1103
1170
|
}
|
|
1104
1171
|
|
|
1105
1172
|
interface TemplateVariables {
|
|
@@ -1110,6 +1177,18 @@ interface TemplateVariables {
|
|
|
1110
1177
|
WORKSPACE_PATH?: string;
|
|
1111
1178
|
PORT?: number;
|
|
1112
1179
|
ONE_SHOT_MODE?: boolean;
|
|
1180
|
+
SETTINGS_SCHEMA?: string;
|
|
1181
|
+
SETTINGS_JSON?: string;
|
|
1182
|
+
SETTINGS_LOCAL_JSON?: string;
|
|
1183
|
+
SHELL_TYPE?: string;
|
|
1184
|
+
SHELL_CONFIG_PATH?: string;
|
|
1185
|
+
SHELL_CONFIG_CONTENT?: string;
|
|
1186
|
+
REMOTES_INFO?: string;
|
|
1187
|
+
MULTIPLE_REMOTES?: string;
|
|
1188
|
+
SINGLE_REMOTE?: string;
|
|
1189
|
+
SINGLE_REMOTE_NAME?: string;
|
|
1190
|
+
SINGLE_REMOTE_URL?: string;
|
|
1191
|
+
NO_REMOTES?: string;
|
|
1113
1192
|
}
|
|
1114
1193
|
declare class PromptTemplateManager {
|
|
1115
1194
|
private templateDir;
|
|
@@ -1117,7 +1196,7 @@ declare class PromptTemplateManager {
|
|
|
1117
1196
|
/**
|
|
1118
1197
|
* Load a template file by name
|
|
1119
1198
|
*/
|
|
1120
|
-
loadTemplate(templateName: 'issue' | 'pr' | 'regular'): Promise<string>;
|
|
1199
|
+
loadTemplate(templateName: 'issue' | 'pr' | 'regular' | 'init'): Promise<string>;
|
|
1121
1200
|
/**
|
|
1122
1201
|
* Substitute variables in a template string
|
|
1123
1202
|
*/
|
|
@@ -1132,7 +1211,7 @@ declare class PromptTemplateManager {
|
|
|
1132
1211
|
/**
|
|
1133
1212
|
* Get a fully processed prompt for a workflow type
|
|
1134
1213
|
*/
|
|
1135
|
-
getPrompt(type: 'issue' | 'pr' | 'regular', variables: TemplateVariables): Promise<string>;
|
|
1214
|
+
getPrompt(type: 'issue' | 'pr' | 'regular' | 'init', variables: TemplateVariables): Promise<string>;
|
|
1136
1215
|
}
|
|
1137
1216
|
|
|
1138
1217
|
interface ClaudeWorkflowOptions {
|