@cleocode/contracts 2026.5.77 → 2026.5.79
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/dist/config.d.ts +66 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/credentials.d.ts +20 -0
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +7 -0
- package/dist/credentials.js.map +1 -1
- package/dist/exit-codes.d.ts +41 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +52 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/operations/worktree.d.ts +251 -0
- package/dist/operations/worktree.d.ts.map +1 -1
- package/dist/release/plan.d.ts +533 -0
- package/dist/release/plan.d.ts.map +1 -0
- package/dist/release/plan.js +393 -0
- package/dist/release/plan.js.map +1 -0
- package/dist/release/plan.test.d.ts +17 -0
- package/dist/release/plan.test.d.ts.map +1 -0
- package/dist/release/plan.test.js +414 -0
- package/dist/release/plan.test.js.map +1 -0
- package/dist/tasks/archive.d.ts +3 -3
- package/package.json +2 -2
- package/src/config.ts +67 -7
- package/src/credentials.ts +29 -0
- package/src/exit-codes.ts +54 -0
- package/src/index.ts +79 -0
- package/src/operations/worktree.ts +274 -0
- package/src/release/plan.test.ts +501 -0
- package/src/release/plan.ts +493 -0
package/src/exit-codes.ts
CHANGED
|
@@ -226,6 +226,60 @@ export enum ExitCode {
|
|
|
226
226
|
LEAD_BYPASS_DETECTED = 107,
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
// Release pipeline v2 error code names (SPEC-T9345 §4.7)
|
|
231
|
+
//
|
|
232
|
+
// String-valued error codes emitted by the new release verbs (plan, open,
|
|
233
|
+
// reconcile, rollback). These are the `code` field of EngineErrorPayload;
|
|
234
|
+
// the numeric exit code is the bucket the verb resolves to (per SPEC §4.7).
|
|
235
|
+
//
|
|
236
|
+
// @task T9525
|
|
237
|
+
// @epic T9492
|
|
238
|
+
// @spec .cleo/rcasd/T9345/research/SPEC-T9345-release-pipeline-v2.md §4.7
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
/** Dirty version files block `cleo release plan` (R-020). Exit code 13. */
|
|
242
|
+
export const E_DIRTY_TREE = 'E_DIRTY_TREE' as const;
|
|
243
|
+
/** Epic referenced by `--epic` has zero children (R-021). Exit code 4. */
|
|
244
|
+
export const E_EPIC_EMPTY = 'E_EPIC_EMPTY' as const;
|
|
245
|
+
/** Epic referenced by `--epic` does not exist (R-021). Exit code 10. */
|
|
246
|
+
export const E_EPIC_NOT_FOUND = 'E_EPIC_NOT_FOUND' as const;
|
|
247
|
+
/** Channel + version scheme are incompatible (R-022). Exit code 6. */
|
|
248
|
+
export const E_CHANNEL_MISMATCH = 'E_CHANNEL_MISMATCH' as const;
|
|
249
|
+
/**
|
|
250
|
+
* One or more tasks in the plan are missing required ADR-051 evidence atoms
|
|
251
|
+
* (R-301 / R-310). Exit code 83. `error.details.tasks[]` lists offenders.
|
|
252
|
+
*/
|
|
253
|
+
export const E_EVIDENCE_INSUFFICIENT = 'E_EVIDENCE_INSUFFICIENT' as const;
|
|
254
|
+
/** Plan file at `.cleo/release/<version>.plan.json` is absent. Exit code 4. */
|
|
255
|
+
export const E_PLAN_NOT_FOUND = 'E_PLAN_NOT_FOUND' as const;
|
|
256
|
+
/** Generic release-plan validation failure (e.g. schema). Exit code 6. */
|
|
257
|
+
export const E_RELEASE_PLAN_INVALID = 'E_RELEASE_PLAN_INVALID' as const;
|
|
258
|
+
/**
|
|
259
|
+
* Release row exists but is not in the status FSM state required by the
|
|
260
|
+
* caller (R-051 — `cleo release open` requires status='planned'). Exit code 6.
|
|
261
|
+
* `error.details.currentStatus` MUST report the actual status; `error.details.expectedStatus`
|
|
262
|
+
* SHOULD list the accepted state(s).
|
|
263
|
+
*
|
|
264
|
+
* @task T9530
|
|
265
|
+
*/
|
|
266
|
+
export const E_INVALID_STATE = 'E_INVALID_STATE' as const;
|
|
267
|
+
/**
|
|
268
|
+
* `gh auth status` exited non-zero (R-052). The GitHub CLI is either not
|
|
269
|
+
* installed or not authenticated for the active hostname. Exit code 5.
|
|
270
|
+
*
|
|
271
|
+
* @task T9530
|
|
272
|
+
*/
|
|
273
|
+
export const E_GH_NOT_AUTHENTICATED = 'E_GH_NOT_AUTHENTICATED' as const;
|
|
274
|
+
/**
|
|
275
|
+
* The expected GitHub Actions workflow file is missing under `.github/workflows/`
|
|
276
|
+
* (R-053). Without it, `gh workflow run` would fail with a non-recoverable error.
|
|
277
|
+
* Exit code 4.
|
|
278
|
+
*
|
|
279
|
+
* @task T9530
|
|
280
|
+
*/
|
|
281
|
+
export const E_WORKFLOW_NOT_FOUND = 'E_WORKFLOW_NOT_FOUND' as const;
|
|
282
|
+
|
|
229
283
|
/** Check if an exit code represents an error (1-99). */
|
|
230
284
|
export function isErrorCode(code: ExitCode): boolean {
|
|
231
285
|
return code >= 1 && code < 100;
|
package/src/index.ts
CHANGED
|
@@ -332,6 +332,18 @@ export {
|
|
|
332
332
|
} from './evidence-record-schema.js';
|
|
333
333
|
// === Exit Codes ===
|
|
334
334
|
export {
|
|
335
|
+
// SPEC-T9345 release pipeline v2 error code names (T9525)
|
|
336
|
+
E_CHANNEL_MISMATCH,
|
|
337
|
+
E_DIRTY_TREE,
|
|
338
|
+
E_EPIC_EMPTY,
|
|
339
|
+
E_EPIC_NOT_FOUND,
|
|
340
|
+
E_EVIDENCE_INSUFFICIENT,
|
|
341
|
+
// SPEC-T9345 release pipeline v2 error code names (T9530)
|
|
342
|
+
E_GH_NOT_AUTHENTICATED,
|
|
343
|
+
E_INVALID_STATE,
|
|
344
|
+
E_PLAN_NOT_FOUND,
|
|
345
|
+
E_RELEASE_PLAN_INVALID,
|
|
346
|
+
E_WORKFLOW_NOT_FOUND,
|
|
335
347
|
ExitCode,
|
|
336
348
|
getExitCodeName,
|
|
337
349
|
isErrorCode,
|
|
@@ -1144,13 +1156,24 @@ export type {
|
|
|
1144
1156
|
CreateWorktreeResult,
|
|
1145
1157
|
DestroyWorktreeOptions,
|
|
1146
1158
|
DestroyWorktreeResult,
|
|
1159
|
+
ForceUnlockWorktreeOpts,
|
|
1160
|
+
ForceUnlockWorktreeResult,
|
|
1147
1161
|
ListWorktreesOptions,
|
|
1162
|
+
ListWorktreesOpts,
|
|
1163
|
+
ListWorktreesResult,
|
|
1164
|
+
PrunedWorktreeOutcome,
|
|
1165
|
+
PruneOrphanedWorktreesOpts,
|
|
1166
|
+
PruneOrphanedWorktreesResult,
|
|
1148
1167
|
PruneWorktreesOptions,
|
|
1149
1168
|
PruneWorktreesResult,
|
|
1150
1169
|
WorktreeHook,
|
|
1151
1170
|
WorktreeHookResult,
|
|
1152
1171
|
WorktreeIncludePattern,
|
|
1172
|
+
WorktreeInfo,
|
|
1173
|
+
WorktreeLifecycleAction,
|
|
1174
|
+
WorktreeLifecycleAuditEntry,
|
|
1153
1175
|
WorktreeListEntry,
|
|
1176
|
+
WorktreeStatusCategory,
|
|
1154
1177
|
} from './operations/worktree.js';
|
|
1155
1178
|
// === Orchestration Roll-up Types (T9082, ADR-070) ===
|
|
1156
1179
|
export type {
|
|
@@ -1235,6 +1258,62 @@ export type {
|
|
|
1235
1258
|
ReleaseVersionScheme,
|
|
1236
1259
|
VerifyResult,
|
|
1237
1260
|
} from './release/pipeline.js';
|
|
1261
|
+
// === Release Plan Envelope (T9527 / SPEC-T9345 §6) ===
|
|
1262
|
+
export type {
|
|
1263
|
+
GateName as ReleaseGateName,
|
|
1264
|
+
GateStatus as ReleaseGateExecutionStatus,
|
|
1265
|
+
Impact as ReleasePlanImpact,
|
|
1266
|
+
PlatformTuple,
|
|
1267
|
+
Publisher,
|
|
1268
|
+
ReleaseChannel as ReleasePlanChannel,
|
|
1269
|
+
ReleaseGate,
|
|
1270
|
+
ReleaseKind,
|
|
1271
|
+
ReleasePlan,
|
|
1272
|
+
ReleasePlanChangelog,
|
|
1273
|
+
ReleasePlanMeta,
|
|
1274
|
+
ReleasePlanTask,
|
|
1275
|
+
ReleasePlatformMatrixEntry,
|
|
1276
|
+
ReleasePreflightSummary,
|
|
1277
|
+
ReleaseScheme,
|
|
1278
|
+
ReleaseStatus as ReleasePlanStatus,
|
|
1279
|
+
ResolvedSource,
|
|
1280
|
+
TaskKind as ReleaseTaskKind,
|
|
1281
|
+
} from './release/plan.js';
|
|
1282
|
+
export {
|
|
1283
|
+
GATE_NAME,
|
|
1284
|
+
GATE_STATUS,
|
|
1285
|
+
GateNameSchema,
|
|
1286
|
+
GateStatusSchema,
|
|
1287
|
+
IMPACT,
|
|
1288
|
+
ImpactSchema,
|
|
1289
|
+
PLATFORM_TUPLE,
|
|
1290
|
+
PlatformTupleSchema,
|
|
1291
|
+
PUBLISHER,
|
|
1292
|
+
PublisherSchema,
|
|
1293
|
+
parseReleasePlan,
|
|
1294
|
+
RELEASE_CHANNEL,
|
|
1295
|
+
RELEASE_KIND,
|
|
1296
|
+
RELEASE_PLAN_SCHEMA_URL,
|
|
1297
|
+
RELEASE_PLAN_SCHEMA_VERSION,
|
|
1298
|
+
RELEASE_SCHEME,
|
|
1299
|
+
RELEASE_STATUS,
|
|
1300
|
+
RESOLVED_SOURCE,
|
|
1301
|
+
ReleaseChannelSchema,
|
|
1302
|
+
ReleaseGateSchema,
|
|
1303
|
+
ReleaseKindSchema,
|
|
1304
|
+
ReleasePlanChangelogSchema,
|
|
1305
|
+
ReleasePlanMetaSchema,
|
|
1306
|
+
ReleasePlanSchema,
|
|
1307
|
+
ReleasePlanTaskSchema,
|
|
1308
|
+
ReleasePlatformMatrixEntrySchema,
|
|
1309
|
+
ReleasePreflightSummarySchema,
|
|
1310
|
+
ReleaseSchemeSchema,
|
|
1311
|
+
ReleaseStatusSchema,
|
|
1312
|
+
ResolvedSourceSchema,
|
|
1313
|
+
safeParseReleasePlan,
|
|
1314
|
+
TASK_KIND,
|
|
1315
|
+
TaskKindSchema,
|
|
1316
|
+
} from './release/plan.js';
|
|
1238
1317
|
// === Release Version Bump ===
|
|
1239
1318
|
export type {
|
|
1240
1319
|
BumpResult,
|
|
@@ -349,3 +349,277 @@ export interface PruneWorktreesResult {
|
|
|
349
349
|
/** Whether `git worktree prune` was run. */
|
|
350
350
|
gitPruneRan: boolean;
|
|
351
351
|
}
|
|
352
|
+
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
// Structured listing (T9546 — worktree-lifecycle 2/5)
|
|
355
|
+
// ---------------------------------------------------------------------------
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Mutually-exclusive worktree status category assigned by orphan-detection
|
|
359
|
+
* heuristics in {@link WorktreeInfo}.
|
|
360
|
+
*
|
|
361
|
+
* Resolution precedence (first match wins):
|
|
362
|
+
* 1. `locked` — git porcelain reports the worktree is locked.
|
|
363
|
+
* 2. `orphan` — owning task is cancelled OR the branch has been deleted.
|
|
364
|
+
* 3. `merged` — the branch is reachable from `main` (already integrated).
|
|
365
|
+
* 4. `stale` — no commits in N days AND (task=done OR no live owner).
|
|
366
|
+
* 5. `active` — everything else (default).
|
|
367
|
+
*
|
|
368
|
+
* @task T9546
|
|
369
|
+
*/
|
|
370
|
+
export type WorktreeStatusCategory = 'active' | 'stale' | 'merged' | 'orphan' | 'locked';
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* A single structured worktree entry with full status classification.
|
|
374
|
+
*
|
|
375
|
+
* Returned by `cleo worktree list` and the `worktree.list` dispatch operation.
|
|
376
|
+
* Each entry combines filesystem state, git state, and owning-task state into
|
|
377
|
+
* a single JSON envelope payload that downstream consumers (prune, dashboard,
|
|
378
|
+
* sentient daemon) can act on without re-querying git.
|
|
379
|
+
*
|
|
380
|
+
* @task T9546
|
|
381
|
+
*/
|
|
382
|
+
export interface WorktreeInfo {
|
|
383
|
+
/** Absolute path to the worktree directory. */
|
|
384
|
+
path: string;
|
|
385
|
+
/** Branch checked out in this worktree. */
|
|
386
|
+
branch: string;
|
|
387
|
+
/** Task ID derived from the branch name (`task/T####`), or null. */
|
|
388
|
+
taskId: string | null;
|
|
389
|
+
/** Agent identifier that owns this worktree (from audit log / metadata), or null. */
|
|
390
|
+
owningAgent: string | null;
|
|
391
|
+
/** ISO-8601 timestamp of last activity (newest commit OR mtime of working tree). */
|
|
392
|
+
lastActivity: string;
|
|
393
|
+
/** Whether `git worktree list --porcelain` reports the worktree as locked. */
|
|
394
|
+
isLocked: boolean;
|
|
395
|
+
/** Whether the worktree is stale: no activity > N days AND (task done/cancelled OR branch merged). */
|
|
396
|
+
isStale: boolean;
|
|
397
|
+
/** Whether the branch is reachable from `main` (already integrated). */
|
|
398
|
+
isMerged: boolean;
|
|
399
|
+
/** Status of the owning task (if {@link taskId} is present and resolvable), or null. */
|
|
400
|
+
owningTaskStatus: string | null;
|
|
401
|
+
/** Mutually-exclusive status category — see {@link WorktreeStatusCategory}. */
|
|
402
|
+
statusCategory: WorktreeStatusCategory;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Options for the structured worktree listing operation.
|
|
407
|
+
*
|
|
408
|
+
* @task T9546
|
|
409
|
+
*/
|
|
410
|
+
export interface ListWorktreesOpts {
|
|
411
|
+
/**
|
|
412
|
+
* Absolute path to the project root (used to compute the project hash
|
|
413
|
+
* and resolve the canonical worktrees directory).
|
|
414
|
+
*/
|
|
415
|
+
projectRoot?: string;
|
|
416
|
+
/**
|
|
417
|
+
* Filter results to entries with one of these status categories.
|
|
418
|
+
* When omitted, all entries are returned.
|
|
419
|
+
*/
|
|
420
|
+
statusFilter?: WorktreeStatusCategory[];
|
|
421
|
+
/**
|
|
422
|
+
* Staleness threshold in days. An entry is marked stale when its last
|
|
423
|
+
* activity is older than this AND either the owning task is done/cancelled
|
|
424
|
+
* or no owning task can be resolved while the branch is merged.
|
|
425
|
+
*
|
|
426
|
+
* @default 7
|
|
427
|
+
*/
|
|
428
|
+
staleDays?: number;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Result of the structured worktree listing operation.
|
|
433
|
+
*
|
|
434
|
+
* @task T9546
|
|
435
|
+
*/
|
|
436
|
+
export interface ListWorktreesResult {
|
|
437
|
+
/** All matched worktree entries (post-filter). */
|
|
438
|
+
worktrees: WorktreeInfo[];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// ---------------------------------------------------------------------------
|
|
442
|
+
// Lifecycle prune + force-unlock (T9547 — worktree-lifecycle 3/5)
|
|
443
|
+
// ---------------------------------------------------------------------------
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Canonical action recorded in `.cleo/audit/worktree-lifecycle.jsonl`.
|
|
447
|
+
*
|
|
448
|
+
* - `prune` — orphaned/merged worktree was removed.
|
|
449
|
+
* - `prune-skip` — orphan was detected but skipped (user said N, or had uncommitted changes).
|
|
450
|
+
* - `force-unlock` — git index.lock removed + `git worktree unlock` ran.
|
|
451
|
+
* - `complete` — worktree was merged (`--no-ff`) into the default branch and pruned (T9548).
|
|
452
|
+
* - `complete-skip` — idempotent no-op (worktree already integrated or branch absent) (T9548).
|
|
453
|
+
* - `complete-manual` — operator marked the worktree as manually-handled via
|
|
454
|
+
* `--resolve manual`; no automatic merge attempted (T9548).
|
|
455
|
+
* - `complete-conflict` — auto-merge attempted but failed (e.g. rebase/merge conflict);
|
|
456
|
+
* worktree was preserved for manual resolution (T9548).
|
|
457
|
+
*
|
|
458
|
+
* @task T9547
|
|
459
|
+
* @task T9548
|
|
460
|
+
*/
|
|
461
|
+
export type WorktreeLifecycleAction =
|
|
462
|
+
| 'prune'
|
|
463
|
+
| 'prune-skip'
|
|
464
|
+
| 'force-unlock'
|
|
465
|
+
| 'complete'
|
|
466
|
+
| 'complete-skip'
|
|
467
|
+
| 'complete-manual'
|
|
468
|
+
| 'complete-conflict';
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* One append-only entry written to `.cleo/audit/worktree-lifecycle.jsonl` by
|
|
472
|
+
* the prune + force-unlock commands.
|
|
473
|
+
*
|
|
474
|
+
* The shape intentionally mirrors the existing audit-jsonl pattern used by
|
|
475
|
+
* `worktree-prune.jsonl` (single-task path) so downstream log shippers can
|
|
476
|
+
* unify both streams. Optional fields are omitted (not null) when absent,
|
|
477
|
+
* keeping the JSONL surface compact and grep-friendly.
|
|
478
|
+
*
|
|
479
|
+
* @task T9547
|
|
480
|
+
*/
|
|
481
|
+
export interface WorktreeLifecycleAuditEntry {
|
|
482
|
+
/** ISO-8601 timestamp when the action was attempted. */
|
|
483
|
+
timestamp: string;
|
|
484
|
+
/** Agent / actor that initiated the action (env `CLEO_AGENT_ID` ?? `'cleo'`). */
|
|
485
|
+
actor: string;
|
|
486
|
+
/** The action performed — see {@link WorktreeLifecycleAction}. */
|
|
487
|
+
action: WorktreeLifecycleAction;
|
|
488
|
+
/** Absolute path to the worktree directory the action targeted. */
|
|
489
|
+
target: string;
|
|
490
|
+
/** Branch name (e.g. `task/T9547`) when known. */
|
|
491
|
+
branch?: string;
|
|
492
|
+
/** Task ID parsed from the branch name when known. */
|
|
493
|
+
taskId?: string;
|
|
494
|
+
/** Free-form reason — e.g. `orphaned-merged`, `dirty-skip`, `index-lock`. */
|
|
495
|
+
reason?: string;
|
|
496
|
+
/** Whether the action completed without error. */
|
|
497
|
+
success: boolean;
|
|
498
|
+
/** Error message when {@link success} is false. */
|
|
499
|
+
error?: string;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Options for {@link pruneOrphanedWorktreesByStatus} — the SDK primitive behind
|
|
504
|
+
* `cleo worktree prune --orphaned`.
|
|
505
|
+
*
|
|
506
|
+
* Per-orphan Y/N confirmation is the responsibility of the CLI layer; the SDK
|
|
507
|
+
* primitive itself is non-interactive and acts on the input set wholesale.
|
|
508
|
+
*
|
|
509
|
+
* @task T9547
|
|
510
|
+
*/
|
|
511
|
+
export interface PruneOrphanedWorktreesOpts {
|
|
512
|
+
/** Absolute path to the project root used for git invocations + audit log. */
|
|
513
|
+
projectRoot: string;
|
|
514
|
+
/**
|
|
515
|
+
* When true, do not actually remove worktrees — return the set that WOULD
|
|
516
|
+
* be pruned with `success: true` and the appropriate `reason`. The audit
|
|
517
|
+
* log is NOT written under `--dry-run`.
|
|
518
|
+
*
|
|
519
|
+
* @default false
|
|
520
|
+
*/
|
|
521
|
+
dryRun?: boolean;
|
|
522
|
+
/**
|
|
523
|
+
* Staleness threshold in days passed through to {@link listWorktrees} when
|
|
524
|
+
* the caller wants a non-default `isStale` window.
|
|
525
|
+
*
|
|
526
|
+
* @default 7
|
|
527
|
+
*/
|
|
528
|
+
staleDays?: number;
|
|
529
|
+
/**
|
|
530
|
+
* Optional subset of paths to prune. When supplied, only worktrees whose
|
|
531
|
+
* absolute `path` matches one of these strings are removed. The CLI passes
|
|
532
|
+
* this set after the user has confirmed per-orphan; in pure SDK use, omit
|
|
533
|
+
* the field to prune every orphan/merged entry the listing surfaces.
|
|
534
|
+
*/
|
|
535
|
+
paths?: readonly string[];
|
|
536
|
+
/**
|
|
537
|
+
* Override actor name written to the audit log. Defaults to
|
|
538
|
+
* `process.env.CLEO_AGENT_ID ?? 'cleo'`.
|
|
539
|
+
*/
|
|
540
|
+
actor?: string;
|
|
541
|
+
/**
|
|
542
|
+
* Optional override for the audit-log file path (testing). When omitted,
|
|
543
|
+
* writes to `<projectRoot>/.cleo/audit/worktree-lifecycle.jsonl`.
|
|
544
|
+
*/
|
|
545
|
+
auditLogPath?: string;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Per-worktree outcome from a prune attempt.
|
|
550
|
+
*
|
|
551
|
+
* @task T9547
|
|
552
|
+
*/
|
|
553
|
+
export interface PrunedWorktreeOutcome {
|
|
554
|
+
/** Absolute path of the worktree. */
|
|
555
|
+
path: string;
|
|
556
|
+
/** Branch name (when known) — used by callers to render audit summaries. */
|
|
557
|
+
branch: string;
|
|
558
|
+
/** Task ID derived from the branch (when known). */
|
|
559
|
+
taskId: string | null;
|
|
560
|
+
/** Why this worktree was selected — e.g. `orphaned-merged`, `orphan-cancelled`. */
|
|
561
|
+
reason: string;
|
|
562
|
+
/** Whether the worktree was actually removed (false under --dry-run or on error). */
|
|
563
|
+
pruned: boolean;
|
|
564
|
+
/** Whether the task branch was deleted (only true when it was safe to do so). */
|
|
565
|
+
branchDeleted: boolean;
|
|
566
|
+
/** Error message when prune failed (set only on `pruned=false` + error path). */
|
|
567
|
+
error?: string;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Result of {@link pruneOrphanedWorktreesByStatus}.
|
|
572
|
+
*
|
|
573
|
+
* @task T9547
|
|
574
|
+
*/
|
|
575
|
+
export interface PruneOrphanedWorktreesResult {
|
|
576
|
+
/** Number of worktrees successfully pruned. */
|
|
577
|
+
prunedCount: number;
|
|
578
|
+
/** Number of orphans detected but NOT pruned (filtered by `paths`, dry-run, or errored). */
|
|
579
|
+
skippedCount: number;
|
|
580
|
+
/** Per-worktree outcomes, one entry per orphan that was considered. */
|
|
581
|
+
outcomes: PrunedWorktreeOutcome[];
|
|
582
|
+
/** Per-worktree errors raised during prune (subset of {@link outcomes} where `error` is set). */
|
|
583
|
+
errors: Array<{ path: string; error: string }>;
|
|
584
|
+
/** Whether {@link PruneOrphanedWorktreesOpts.dryRun} was set. */
|
|
585
|
+
dryRun: boolean;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Options for {@link forceUnlockWorktree} — the SDK primitive behind
|
|
590
|
+
* `cleo worktree force-unlock <taskId>`.
|
|
591
|
+
*
|
|
592
|
+
* @task T9547
|
|
593
|
+
*/
|
|
594
|
+
export interface ForceUnlockWorktreeOpts {
|
|
595
|
+
/** Absolute path to the project root used for git invocations. */
|
|
596
|
+
projectRoot: string;
|
|
597
|
+
/** Task ID whose worktree should be force-unlocked. */
|
|
598
|
+
taskId: string;
|
|
599
|
+
/** Override actor name written to the audit log. */
|
|
600
|
+
actor?: string;
|
|
601
|
+
/** Optional override for the audit-log file path (testing). */
|
|
602
|
+
auditLogPath?: string;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Result of {@link forceUnlockWorktree}.
|
|
607
|
+
*
|
|
608
|
+
* @task T9547
|
|
609
|
+
*/
|
|
610
|
+
export interface ForceUnlockWorktreeResult {
|
|
611
|
+
/** Task ID whose worktree was located. */
|
|
612
|
+
taskId: string;
|
|
613
|
+
/** Absolute path to the worktree (when located). */
|
|
614
|
+
path: string | null;
|
|
615
|
+
/** Whether `.git/index.lock` was present and removed. */
|
|
616
|
+
indexLockRemoved: boolean;
|
|
617
|
+
/** Whether `git worktree unlock` was executed (because porcelain reported `locked`). */
|
|
618
|
+
worktreeUnlocked: boolean;
|
|
619
|
+
/** Whether the worktree had uncommitted changes at the time of unlock (warn-only). */
|
|
620
|
+
hadUncommittedChanges: boolean;
|
|
621
|
+
/** Aggregate success — true when at least one unlock action ran without error. */
|
|
622
|
+
success: boolean;
|
|
623
|
+
/** Error message when no worktree could be located or all actions failed. */
|
|
624
|
+
error?: string;
|
|
625
|
+
}
|