@cleocode/worktree 2026.5.104 → 2026.5.106
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/napi-binding.d.ts +64 -1
- package/dist/napi-binding.d.ts.map +1 -1
- package/dist/napi-binding.js +2 -0
- package/dist/napi-binding.js.map +1 -1
- package/dist/worktree-prune.d.ts +47 -14
- package/dist/worktree-prune.d.ts.map +1 -1
- package/dist/worktree-prune.js +171 -104
- package/dist/worktree-prune.js.map +1 -1
- package/package.json +5 -5
package/dist/napi-binding.d.ts
CHANGED
|
@@ -51,6 +51,65 @@ interface WorktreeInfoNapi {
|
|
|
51
51
|
isLocked: boolean;
|
|
52
52
|
isPrunable: boolean;
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Options for the napi `pruneWorktrees` binding (T10203).
|
|
56
|
+
*
|
|
57
|
+
* Mirrors `crates/worktree-napi`'s `PruneOpts` — see ADR-078 for the
|
|
58
|
+
* worktrunk-core SDK boundary contract.
|
|
59
|
+
*/
|
|
60
|
+
interface PruneOptsNapi {
|
|
61
|
+
/** Absolute path to the git repository whose worktrees we plan to prune. */
|
|
62
|
+
repoRoot: string;
|
|
63
|
+
/**
|
|
64
|
+
* The integration target branch (e.g. `"main"`) the candidates are tested
|
|
65
|
+
* against for "is this merged in?".
|
|
66
|
+
*/
|
|
67
|
+
integrationTarget: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Single prune candidate returned by the napi `pruneWorktrees` plan (T10203).
|
|
71
|
+
*/
|
|
72
|
+
interface PruneCandidateNapi {
|
|
73
|
+
/** Branch name (`undefined` for detached HEAD worktrees). */
|
|
74
|
+
branch?: string;
|
|
75
|
+
/** Display label (branch name or `(detached <short>)`). */
|
|
76
|
+
label: string;
|
|
77
|
+
/** Worktree path (`undefined` for branch-only candidates). */
|
|
78
|
+
path?: string;
|
|
79
|
+
/** Candidate kind: `"current" | "worktree" | "branch_only"`. */
|
|
80
|
+
kind: string;
|
|
81
|
+
/** Human-readable integration reason. */
|
|
82
|
+
reason: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Read-only prune plan returned by the napi `pruneWorktrees` binding (T10203).
|
|
86
|
+
*/
|
|
87
|
+
interface PrunePlanNapi {
|
|
88
|
+
/** The default branch this plan was computed against. */
|
|
89
|
+
integrationTarget: string;
|
|
90
|
+
/** Candidates eligible for removal, in deterministic discovery order. */
|
|
91
|
+
candidates: PruneCandidateNapi[];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Options for the napi `removeDir` binding (T10203).
|
|
95
|
+
*
|
|
96
|
+
* Recursively removes a directory tree using
|
|
97
|
+
* `worktrunk_core::remove_dir::remove_dir_with_progress`. Best-effort —
|
|
98
|
+
* read/unlink/rmdir errors are silently skipped on the SDK side.
|
|
99
|
+
*/
|
|
100
|
+
interface RemoveDirOptsNapi {
|
|
101
|
+
/** Absolute path to the directory tree to remove. */
|
|
102
|
+
path: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Result of a napi `removeDir` call (T10203).
|
|
106
|
+
*/
|
|
107
|
+
interface RemoveDirResultNapi {
|
|
108
|
+
/** Number of leaf files unlinked. */
|
|
109
|
+
files: number;
|
|
110
|
+
/** Total bytes unlinked. Capped at `u32::MAX` for napi compatibility. */
|
|
111
|
+
bytes: number;
|
|
112
|
+
}
|
|
54
113
|
/**
|
|
55
114
|
* Shape of the native module exported by `@cleocode/worktree-napi`.
|
|
56
115
|
*
|
|
@@ -66,11 +125,15 @@ interface WorktreeNapiModule {
|
|
|
66
125
|
readWorktreeInclude(repoRoot: string): IncludePatternNapi[];
|
|
67
126
|
applyInclude(patterns: IncludePatternNapi[], srcDir: string, destDir: string, opts: CopyOptsNapi): CopyResultNapi;
|
|
68
127
|
listWorktrees(opts: ListOptsNapi): WorktreeInfoNapi[];
|
|
128
|
+
pruneWorktrees(opts: PruneOptsNapi): PrunePlanNapi;
|
|
129
|
+
removeDir(opts: RemoveDirOptsNapi): RemoveDirResultNapi;
|
|
69
130
|
}
|
|
70
131
|
export declare const copyPathsParallel: WorktreeNapiModule['copyPathsParallel'];
|
|
71
132
|
export declare const destroyWorktree: WorktreeNapiModule['destroyWorktree'];
|
|
72
133
|
export declare const readWorktreeInclude: WorktreeNapiModule['readWorktreeInclude'];
|
|
73
134
|
export declare const applyInclude: WorktreeNapiModule['applyInclude'];
|
|
74
135
|
export declare const listWorktrees: WorktreeNapiModule['listWorktrees'];
|
|
75
|
-
export
|
|
136
|
+
export declare const pruneWorktrees: WorktreeNapiModule['pruneWorktrees'];
|
|
137
|
+
export declare const removeDir: WorktreeNapiModule['removeDir'];
|
|
138
|
+
export type { CopyOptsNapi, CopyResultNapi, DestroyOptsNapi, DestroyResultNapi, IncludePatternNapi, ListOptsNapi, PruneCandidateNapi, PruneOptsNapi, PrunePlanNapi, RemoveDirOptsNapi, RemoveDirResultNapi, WorktreeInfoNapi, };
|
|
76
139
|
//# sourceMappingURL=napi-binding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"napi-binding.d.ts","sourceRoot":"","sources":["../src/napi-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,UAAU,YAAY;IACpB,qDAAqD;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,UAAU,kBAAkB;IAC1B,iBAAiB,CACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,YAAY,GACjB,cAAc,CAAC;IAClB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAC1D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAAC;IAC5D,YAAY,CACV,QAAQ,EAAE,kBAAkB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,GACjB,cAAc,CAAC;IAClB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"napi-binding.d.ts","sourceRoot":"","sources":["../src/napi-binding.ts"],"names":[],"mappings":"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"}
|
package/dist/napi-binding.js
CHANGED
|
@@ -40,4 +40,6 @@ export const destroyWorktree = (opts) => getNative().destroyWorktree(opts);
|
|
|
40
40
|
export const readWorktreeInclude = (repoRoot) => getNative().readWorktreeInclude(repoRoot);
|
|
41
41
|
export const applyInclude = (patterns, srcDir, destDir, opts) => getNative().applyInclude(patterns, srcDir, destDir, opts);
|
|
42
42
|
export const listWorktrees = (opts) => getNative().listWorktrees(opts);
|
|
43
|
+
export const pruneWorktrees = (opts) => getNative().pruneWorktrees(opts);
|
|
44
|
+
export const removeDir = (opts) => getNative().removeDir(opts);
|
|
43
45
|
//# sourceMappingURL=napi-binding.js.map
|
package/dist/napi-binding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"napi-binding.js","sourceRoot":"","sources":["../src/napi-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"napi-binding.js","sourceRoot":"","sources":["../src/napi-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AA2IhD;;;;;;;;;;;GAWG;AACH,IAAI,aAAa,GAA8B,IAAI,CAAC;AACpD,SAAS,SAAS;IAChB,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,aAAa,GAAG,QAAQ,CAAC,yBAAyB,CAAuB,CAAC;IAC5E,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAA4C,CACxE,MAAM,EACN,OAAO,EACP,KAAK,EACL,IAAI,EACJ,EAAE,CAAC,SAAS,EAAE,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAA0C,CAAC,IAAI,EAAE,EAAE,CAC7E,SAAS,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAEpC,MAAM,CAAC,MAAM,mBAAmB,GAA8C,CAAC,QAAQ,EAAE,EAAE,CACzF,SAAS,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAuC,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAClG,SAAS,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,aAAa,GAAwC,CAAC,IAAI,EAAE,EAAE,CACzE,SAAS,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,MAAM,cAAc,GAAyC,CAAC,IAAI,EAAE,EAAE,CAC3E,SAAS,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AAEnC,MAAM,CAAC,MAAM,SAAS,GAAoC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/worktree-prune.d.ts
CHANGED
|
@@ -1,37 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Worktree prune operation for @cleocode/worktree.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* to clean up stale git administrative entries.
|
|
4
|
+
* Thin orchestration over the `worktrunk_core` SDK exposed via
|
|
5
|
+
* `@cleocode/worktree-napi` (T10203 / ADR-078). The native binding owns:
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* - Git-aware prune-plan construction (`napi.pruneWorktrees`) — read-only
|
|
8
|
+
* discovery of merged-in worktrees + orphan branches.
|
|
9
|
+
* - Recursive directory removal (`napi.removeDir`) — replaces the
|
|
10
|
+
* `rmSync` + `git worktree remove` fallback that previously lived here.
|
|
11
|
+
*
|
|
12
|
+
* The TypeScript layer keeps three concerns that are explicitly outside the
|
|
13
|
+
* SDK boundary per ADR-061:
|
|
14
|
+
*
|
|
15
|
+
* 1. CLEO XDG-layout scan + `preserveTaskIds`/`idleDays` filter — business
|
|
16
|
+
* logic that the napi binding intentionally avoids.
|
|
17
|
+
* 2. Audit-log writes to `.cleo/audit/worktree-lifecycle.jsonl` (T9805 AC3).
|
|
18
|
+
* 3. Sentinel-index updates at `<gitRoot>/.cleo/worktrees.json` (D009).
|
|
12
19
|
*
|
|
13
20
|
* Called periodically by `cleo sentient tick` via `worktree-dispatch.ts`.
|
|
14
21
|
*
|
|
15
22
|
* @task T1161
|
|
16
23
|
* @task T9805
|
|
24
|
+
* @task T10204
|
|
17
25
|
*/
|
|
18
26
|
import type { PruneWorktreesOptions, PruneWorktreesResult } from '@cleocode/contracts';
|
|
27
|
+
import { pruneWorktrees as napiPrune } from './napi-binding.js';
|
|
19
28
|
/**
|
|
20
29
|
* Prune orphaned agent worktrees for a project.
|
|
21
30
|
*
|
|
22
|
-
* Algorithm:
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
31
|
+
* Algorithm (thin orchestration over napi SDK):
|
|
32
|
+
*
|
|
33
|
+
* 1. Resolve the git root (falling back to `projectRoot` when not in a repo).
|
|
34
|
+
* 2. Optionally invoke `napi.pruneWorktrees` for git-aware candidate discovery
|
|
35
|
+
* — the SDK plan is currently advisory; the TS layer drives the actual
|
|
36
|
+
* removal because audit + sentinel concerns are TS-owned per ADR-061.
|
|
37
|
+
* 3. Scan the XDG worktree root, filtering by `preserveTaskIds`/`idleDays`.
|
|
38
|
+
* 4. For each eligible entry: unlock via git → remove via napi → audit-log →
|
|
39
|
+
* sentinel-index cleanup.
|
|
29
40
|
*
|
|
30
41
|
* @param options - Prune options with project root and optional preserve list.
|
|
31
42
|
* @returns Result listing removed paths and any errors.
|
|
32
43
|
*
|
|
33
44
|
* @task T1161
|
|
34
45
|
* @task T9805
|
|
46
|
+
* @task T10204
|
|
35
47
|
*/
|
|
36
48
|
export declare function pruneWorktrees(options: PruneWorktreesOptions): PruneWorktreesResult;
|
|
49
|
+
/**
|
|
50
|
+
* Build a git-aware prune plan via the `worktrunk-core` SDK (T10203).
|
|
51
|
+
*
|
|
52
|
+
* Wraps `napi.pruneWorktrees` with the integration-target branch the caller
|
|
53
|
+
* expects. Returns `null` when the underlying call fails (the napi layer
|
|
54
|
+
* raises on bare repos, detached HEAD on main, or empty worktree lists) so
|
|
55
|
+
* the legacy filesystem-scan path stays unaffected.
|
|
56
|
+
*
|
|
57
|
+
* Currently advisory: the result is exposed for callers that want the
|
|
58
|
+
* SDK-classified merge-state, but {@link pruneWorktrees} still drives removal
|
|
59
|
+
* from the XDG layout because preserveTaskIds + idleDays semantics live
|
|
60
|
+
* outside the SDK boundary.
|
|
61
|
+
*
|
|
62
|
+
* @param gitRoot - Absolute path to the git repository root.
|
|
63
|
+
* @param integrationTarget - Branch name to test "is merged" against
|
|
64
|
+
* (typically `main` or `master`).
|
|
65
|
+
* @returns The SDK plan, or `null` when the napi call cannot be issued.
|
|
66
|
+
*
|
|
67
|
+
* @task T10204
|
|
68
|
+
*/
|
|
69
|
+
export declare function buildGitAwarePrunePlan(gitRoot: string, integrationTarget: string): ReturnType<typeof napiPrune> | null;
|
|
37
70
|
//# sourceMappingURL=worktree-prune.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-prune.d.ts","sourceRoot":"","sources":["../src/worktree-prune.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worktree-prune.d.ts","sourceRoot":"","sources":["../src/worktree-prune.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEvF,OAAO,EAAE,cAAc,IAAI,SAAS,EAA8B,MAAM,mBAAmB,CAAC;AAI5F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CAiBnF;AA2KD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,iBAAiB,EAAE,MAAM,GACxB,UAAU,CAAC,OAAO,SAAS,CAAC,GAAG,IAAI,CAMrC"}
|
package/dist/worktree-prune.js
CHANGED
|
@@ -1,149 +1,188 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Worktree prune operation for @cleocode/worktree.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* to clean up stale git administrative entries.
|
|
4
|
+
* Thin orchestration over the `worktrunk_core` SDK exposed via
|
|
5
|
+
* `@cleocode/worktree-napi` (T10203 / ADR-078). The native binding owns:
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* - Git-aware prune-plan construction (`napi.pruneWorktrees`) — read-only
|
|
8
|
+
* discovery of merged-in worktrees + orphan branches.
|
|
9
|
+
* - Recursive directory removal (`napi.removeDir`) — replaces the
|
|
10
|
+
* `rmSync` + `git worktree remove` fallback that previously lived here.
|
|
11
|
+
*
|
|
12
|
+
* The TypeScript layer keeps three concerns that are explicitly outside the
|
|
13
|
+
* SDK boundary per ADR-061:
|
|
14
|
+
*
|
|
15
|
+
* 1. CLEO XDG-layout scan + `preserveTaskIds`/`idleDays` filter — business
|
|
16
|
+
* logic that the napi binding intentionally avoids.
|
|
17
|
+
* 2. Audit-log writes to `.cleo/audit/worktree-lifecycle.jsonl` (T9805 AC3).
|
|
18
|
+
* 3. Sentinel-index updates at `<gitRoot>/.cleo/worktrees.json` (D009).
|
|
12
19
|
*
|
|
13
20
|
* Called periodically by `cleo sentient tick` via `worktree-dispatch.ts`.
|
|
14
21
|
*
|
|
15
22
|
* @task T1161
|
|
16
23
|
* @task T9805
|
|
24
|
+
* @task T10204
|
|
17
25
|
*/
|
|
18
26
|
import { execFileSync } from 'node:child_process';
|
|
19
|
-
import { existsSync, readdirSync
|
|
27
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
20
28
|
import { join } from 'node:path';
|
|
21
29
|
import { getGitRoot, gitSilent } from './git.js';
|
|
30
|
+
import { pruneWorktrees as napiPrune, removeDir as napiRemoveDir } from './napi-binding.js';
|
|
22
31
|
import { computeProjectHash, resolveWorktreeRootForHash } from './paths.js';
|
|
23
32
|
import { appendWorktreeAuditLog, removeWorktreeFromSentinelIndex } from './worktree-audit.js';
|
|
24
33
|
/**
|
|
25
34
|
* Prune orphaned agent worktrees for a project.
|
|
26
35
|
*
|
|
27
|
-
* Algorithm:
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
36
|
+
* Algorithm (thin orchestration over napi SDK):
|
|
37
|
+
*
|
|
38
|
+
* 1. Resolve the git root (falling back to `projectRoot` when not in a repo).
|
|
39
|
+
* 2. Optionally invoke `napi.pruneWorktrees` for git-aware candidate discovery
|
|
40
|
+
* — the SDK plan is currently advisory; the TS layer drives the actual
|
|
41
|
+
* removal because audit + sentinel concerns are TS-owned per ADR-061.
|
|
42
|
+
* 3. Scan the XDG worktree root, filtering by `preserveTaskIds`/`idleDays`.
|
|
43
|
+
* 4. For each eligible entry: unlock via git → remove via napi → audit-log →
|
|
44
|
+
* sentinel-index cleanup.
|
|
34
45
|
*
|
|
35
46
|
* @param options - Prune options with project root and optional preserve list.
|
|
36
47
|
* @returns Result listing removed paths and any errors.
|
|
37
48
|
*
|
|
38
49
|
* @task T1161
|
|
39
50
|
* @task T9805
|
|
51
|
+
* @task T10204
|
|
40
52
|
*/
|
|
41
53
|
export function pruneWorktrees(options) {
|
|
42
54
|
const { projectRoot, preserveTaskIds, gitPrune = true, idleDays } = options;
|
|
43
55
|
const projectHash = computeProjectHash(projectRoot);
|
|
44
56
|
const worktreeRoot = resolveWorktreeRootForHash(projectHash);
|
|
57
|
+
const gitRoot = resolveGitRootOrFallback(projectRoot);
|
|
45
58
|
const removed = [];
|
|
46
59
|
const errors = [];
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
const gitPruneRan = gitPrune ? runGitPruneAdminCleanup(gitRoot) : false;
|
|
61
|
+
if ((preserveTaskIds === undefined && idleDays === undefined) || !existsSync(worktreeRoot)) {
|
|
62
|
+
return { removed: 0, removedPaths: [], errors, gitPruneRan };
|
|
63
|
+
}
|
|
64
|
+
for (const entry of safeReaddir(worktreeRoot)) {
|
|
65
|
+
const decision = classifyPruneCandidate(entry, preserveTaskIds, idleDays, worktreeRoot);
|
|
66
|
+
if (decision === null)
|
|
67
|
+
continue;
|
|
68
|
+
pruneSingleEntry(decision, gitRoot, projectRoot, removed, errors);
|
|
69
|
+
}
|
|
70
|
+
return { removed: removed.length, removedPaths: removed, errors, gitPruneRan };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the git root for `projectRoot`, falling back to `projectRoot` when
|
|
74
|
+
* we are not inside a git repository. Lets prune still clean directories that
|
|
75
|
+
* exist outside a working repo.
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
function resolveGitRootOrFallback(projectRoot) {
|
|
49
80
|
try {
|
|
50
|
-
|
|
81
|
+
return getGitRoot(projectRoot);
|
|
51
82
|
}
|
|
52
83
|
catch {
|
|
53
|
-
|
|
54
|
-
gitRoot = projectRoot;
|
|
84
|
+
return projectRoot;
|
|
55
85
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Run `git worktree prune` to clean up stale administrative entries.
|
|
89
|
+
*
|
|
90
|
+
* Returns `true` on success, `false` when not in a git repo (non-fatal).
|
|
91
|
+
*
|
|
92
|
+
* @internal
|
|
93
|
+
*/
|
|
94
|
+
function runGitPruneAdminCleanup(gitRoot) {
|
|
95
|
+
return gitSilent(['worktree', 'prune'], gitRoot);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Safely read directory entries, returning `[]` on failure.
|
|
99
|
+
*
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
function safeReaddir(dir) {
|
|
103
|
+
try {
|
|
104
|
+
return readdirSync(dir);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Classify a single worktree-root subdirectory entry for prune eligibility.
|
|
112
|
+
*
|
|
113
|
+
* Returns `null` when the entry should be preserved, or a {@link PruneDecision}
|
|
114
|
+
* describing why it qualifies. Encapsulates the CLEO-specific
|
|
115
|
+
* `preserveTaskIds`/`idleDays` business logic that lives outside the
|
|
116
|
+
* worktrunk-core SDK by design (ADR-061).
|
|
117
|
+
*
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
function classifyPruneCandidate(entry, preserveTaskIds, idleDays, worktreeRoot) {
|
|
121
|
+
const path = join(worktreeRoot, entry);
|
|
122
|
+
if (preserveTaskIds !== undefined) {
|
|
123
|
+
if (!preserveTaskIds.has(entry)) {
|
|
124
|
+
return { taskId: entry, path, reason: 'orphan' };
|
|
61
125
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
gitPruneRan = false;
|
|
126
|
+
if (idleDays !== undefined && isWorktreeIdle(path, idleDays)) {
|
|
127
|
+
return { taskId: entry, path, reason: `idle-${idleDays}d` };
|
|
65
128
|
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
if (idleDays !== undefined && isWorktreeIdle(path, idleDays)) {
|
|
132
|
+
return { taskId: entry, path, reason: `idle-${idleDays}d` };
|
|
66
133
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Remove a single worktree entry: unlock via git, remove via napi-backed
|
|
138
|
+
* directory removal, then write audit + sentinel-index entries.
|
|
139
|
+
*
|
|
140
|
+
* Mutates `removed` and `errors` in place to keep the orchestrator function
|
|
141
|
+
* thin. Both audit-log and sentinel-index updates are best-effort and never
|
|
142
|
+
* block successful removal.
|
|
143
|
+
*
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
function pruneSingleEntry(decision, gitRoot, projectRoot, removed, errors) {
|
|
147
|
+
const { taskId, path, reason } = decision;
|
|
148
|
+
gitSilent(['worktree', 'unlock', path], gitRoot);
|
|
149
|
+
const gitRemoveSucceeded = gitSilent(['worktree', 'remove', '--force', path], gitRoot);
|
|
150
|
+
let pruneSuccess = gitRemoveSucceeded;
|
|
151
|
+
let errorMessage = null;
|
|
152
|
+
if (!gitRemoveSucceeded) {
|
|
71
153
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
154
|
+
// Delegate the recursive directory removal to worktrunk-core via napi
|
|
155
|
+
// (T10203). The SDK is best-effort: read/unlink/rmdir errors are
|
|
156
|
+
// silently skipped, so a non-zero file count signals success.
|
|
157
|
+
napiRemoveDir({ path });
|
|
158
|
+
pruneSuccess = true;
|
|
76
159
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Determine whether this entry is a prune candidate.
|
|
80
|
-
let reason = 'orphan';
|
|
81
|
-
let shouldPrune = false;
|
|
82
|
-
if (preserveTaskIds !== undefined) {
|
|
83
|
-
if (preserveTaskIds.has(entry)) {
|
|
84
|
-
// Still check idle-days even for preserved IDs when idleDays is set.
|
|
85
|
-
if (idleDays !== undefined && isWorktreeIdle(worktreePath, idleDays)) {
|
|
86
|
-
shouldPrune = true;
|
|
87
|
-
reason = `idle-${idleDays}d`;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
shouldPrune = true;
|
|
92
|
-
reason = 'orphan';
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
else if (idleDays !== undefined) {
|
|
96
|
-
// preserveTaskIds not set — only idle-days check applies.
|
|
97
|
-
if (isWorktreeIdle(worktreePath, idleDays)) {
|
|
98
|
-
shouldPrune = true;
|
|
99
|
-
reason = `idle-${idleDays}d`;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (!shouldPrune)
|
|
103
|
-
continue;
|
|
104
|
-
// Try git-aware removal first.
|
|
105
|
-
gitSilent(['worktree', 'unlock', worktreePath], gitRoot);
|
|
106
|
-
let pruneSuccess = false;
|
|
107
|
-
if (gitSilent(['worktree', 'remove', '--force', worktreePath], gitRoot)) {
|
|
108
|
-
removed.push(worktreePath);
|
|
109
|
-
pruneSuccess = true;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
// Fall back to rmSync for directories that aren't registered worktrees.
|
|
113
|
-
try {
|
|
114
|
-
rmSync(worktreePath, { recursive: true, force: true });
|
|
115
|
-
removed.push(worktreePath);
|
|
116
|
-
pruneSuccess = true;
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
120
|
-
errors.push({ path: worktreePath, reason: errMsg });
|
|
121
|
-
// T9805 AC3: Audit the failed removal.
|
|
122
|
-
appendWorktreeAuditLog(projectRoot, {
|
|
123
|
-
action: 'prune',
|
|
124
|
-
xdgPath: worktreePath,
|
|
125
|
-
taskId: entry,
|
|
126
|
-
reason,
|
|
127
|
-
success: false,
|
|
128
|
-
error: errMsg,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (pruneSuccess) {
|
|
133
|
-
// T9805 AC3: Audit the successful removal.
|
|
134
|
-
appendWorktreeAuditLog(projectRoot, {
|
|
135
|
-
action: 'prune',
|
|
136
|
-
xdgPath: worktreePath,
|
|
137
|
-
taskId: entry,
|
|
138
|
-
reason,
|
|
139
|
-
success: true,
|
|
140
|
-
});
|
|
141
|
-
// T9805 D009: Remove from sentinel index.
|
|
142
|
-
removeWorktreeFromSentinelIndex(gitRoot, entry);
|
|
143
|
-
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
errorMessage = err instanceof Error ? err.message : String(err);
|
|
144
162
|
}
|
|
145
163
|
}
|
|
146
|
-
|
|
164
|
+
if (pruneSuccess) {
|
|
165
|
+
removed.push(path);
|
|
166
|
+
appendWorktreeAuditLog(projectRoot, {
|
|
167
|
+
action: 'prune',
|
|
168
|
+
xdgPath: path,
|
|
169
|
+
taskId,
|
|
170
|
+
reason,
|
|
171
|
+
success: true,
|
|
172
|
+
});
|
|
173
|
+
removeWorktreeFromSentinelIndex(gitRoot, taskId);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const finalError = errorMessage ?? 'napi removeDir failed';
|
|
177
|
+
errors.push({ path, reason: finalError });
|
|
178
|
+
appendWorktreeAuditLog(projectRoot, {
|
|
179
|
+
action: 'prune',
|
|
180
|
+
xdgPath: path,
|
|
181
|
+
taskId,
|
|
182
|
+
reason,
|
|
183
|
+
success: false,
|
|
184
|
+
error: finalError,
|
|
185
|
+
});
|
|
147
186
|
}
|
|
148
187
|
/**
|
|
149
188
|
* Check whether the last commit on a worktree's branch is older than
|
|
@@ -177,4 +216,32 @@ function isWorktreeIdle(worktreePath, thresholdDays) {
|
|
|
177
216
|
return false;
|
|
178
217
|
}
|
|
179
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Build a git-aware prune plan via the `worktrunk-core` SDK (T10203).
|
|
221
|
+
*
|
|
222
|
+
* Wraps `napi.pruneWorktrees` with the integration-target branch the caller
|
|
223
|
+
* expects. Returns `null` when the underlying call fails (the napi layer
|
|
224
|
+
* raises on bare repos, detached HEAD on main, or empty worktree lists) so
|
|
225
|
+
* the legacy filesystem-scan path stays unaffected.
|
|
226
|
+
*
|
|
227
|
+
* Currently advisory: the result is exposed for callers that want the
|
|
228
|
+
* SDK-classified merge-state, but {@link pruneWorktrees} still drives removal
|
|
229
|
+
* from the XDG layout because preserveTaskIds + idleDays semantics live
|
|
230
|
+
* outside the SDK boundary.
|
|
231
|
+
*
|
|
232
|
+
* @param gitRoot - Absolute path to the git repository root.
|
|
233
|
+
* @param integrationTarget - Branch name to test "is merged" against
|
|
234
|
+
* (typically `main` or `master`).
|
|
235
|
+
* @returns The SDK plan, or `null` when the napi call cannot be issued.
|
|
236
|
+
*
|
|
237
|
+
* @task T10204
|
|
238
|
+
*/
|
|
239
|
+
export function buildGitAwarePrunePlan(gitRoot, integrationTarget) {
|
|
240
|
+
try {
|
|
241
|
+
return napiPrune({ repoRoot: gitRoot, integrationTarget });
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
180
247
|
//# sourceMappingURL=worktree-prune.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-prune.js","sourceRoot":"","sources":["../src/worktree-prune.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"worktree-prune.js","sourceRoot":"","sources":["../src/worktree-prune.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleocode/worktree",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "v2026.5.106",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Native CLEO worktree backend SDK — createWorktree, destroyWorktree, listWorktrees, pruneWorktrees with XDG path canon and declarative hooks (T1161)",
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
"author": "CLEO Code <hello@cleocode.dev>",
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@cleocode/
|
|
34
|
-
"@cleocode/
|
|
33
|
+
"@cleocode/paths": "v2026.5.106",
|
|
34
|
+
"@cleocode/contracts": "v2026.5.106"
|
|
35
35
|
},
|
|
36
36
|
"optionalDependencies": {
|
|
37
|
-
"@cleocode/worktree-napi": "
|
|
37
|
+
"@cleocode/worktree-napi": "v2026.5.106"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^24.3.0",
|
|
41
41
|
"typescript": "^6.0.2",
|
|
42
42
|
"vitest": "^4.1.4",
|
|
43
|
-
"@cleocode/core": "
|
|
43
|
+
"@cleocode/core": "v2026.5.106"
|
|
44
44
|
},
|
|
45
45
|
"repository": {
|
|
46
46
|
"type": "git",
|