cyber-agentkit 0.0.0-stage → 0.7.1
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/.claude-plugin/plugin.json +19 -0
- package/.codex-plugin/plugin.json +19 -0
- package/.cursor-plugin/plugin.json +19 -0
- package/LICENSE +21 -0
- package/bin/cyber-agentkit.mjs +10 -0
- package/dist/cli.js +14307 -0
- package/dist/commands.d.ts +149 -0
- package/dist/commands.js +984 -0
- package/dist/harness-id-BgKL-x6C.d.ts +11 -0
- package/dist/index.d.ts +724 -0
- package/dist/index.js +652 -0
- package/dist/reference-where-BhymfNgA.js +10195 -0
- package/dist/resolve-reference-Cis-Ye6T.d.ts +232 -0
- package/dist/worktrees.d.ts +690 -0
- package/dist/worktrees.js +1456 -0
- package/package.json +92 -5
- package/plugin.json +27 -0
- package/readme.md +423 -0
- package/references/plugin-dependencies.md +31 -0
- package/skills/reference/README.md +63 -0
- package/skills/reference/SKILL.md +109 -0
- package/skills/reference/references/create.md +71 -0
- package/skills/reference/references/load.md +80 -0
- package/skills/reference/scripts/reference.mjs +199 -0
- package/README.md +0 -3
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
import { t as HarnessId } from "./harness-id-BgKL-x6C.js";
|
|
2
|
+
//#region src/worktrees/exec.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Runs a command and resolves its trimmed stdout, or `null` on any failure. Every git and forge call
|
|
5
|
+
* in this folder goes through it, so a caller can drive the whole worktree layer with a fake or with
|
|
6
|
+
* its own environment (a pinned `GIT_CONFIG_GLOBAL`, a different `PATH`).
|
|
7
|
+
*/
|
|
8
|
+
type Exec = (cmd: string, args: readonly string[]) => Promise<string | null>;
|
|
9
|
+
/** The default `Exec`: `execFile` with stderr captured, never inherited, because routine failures
|
|
10
|
+
* (no `origin/HEAD`, a branch with no upstream) would otherwise spam the caller's terminal. */
|
|
11
|
+
export declare const nodeExec: Exec;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/worktrees/landed.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Which signal established that a branch's work has landed on the default branch, in the cost order
|
|
16
|
+
* the signals run. Each is positive-only: a signal that cannot match never contributes a `false`, so
|
|
17
|
+
* two signals can never contradict each other.
|
|
18
|
+
*
|
|
19
|
+
* - `ancestor`: the branch tip is an ancestor of the default branch (`git branch --merged`).
|
|
20
|
+
* - `upstream-gone`: the branch's remote-tracking ref has disappeared (`[gone]`), meaning the forge
|
|
21
|
+
* merged the pull request and deleted its head branch. Only as fresh as the caller's last
|
|
22
|
+
* `git fetch --prune`; this module never fetches.
|
|
23
|
+
* - `squash-patch`: the branch, collapsed to one commit, is already applied on the default branch
|
|
24
|
+
* (`git cherry`). Matches a clean squash or rebase merge, not a hand-edited one.
|
|
25
|
+
* - `forge`: the forge reports a merged pull request for the branch. Needs network and auth, so it
|
|
26
|
+
* runs only when the caller passes a `ForgeMergedProbe`.
|
|
27
|
+
*/
|
|
28
|
+
type LandedSignal = 'ancestor' | 'upstream-gone' | 'squash-patch' | 'forge';
|
|
29
|
+
/** Asks the forge whether `branch` is the head of a merged pull request. `undefined` means the forge
|
|
30
|
+
* could not say, which, like `false`, clears nothing. */
|
|
31
|
+
type ForgeMergedProbe = (branch: string) => Promise<boolean | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* A `ForgeMergedProbe` backed by the GitHub CLI: `gh pr list --head <branch> --state merged`. Every
|
|
34
|
+
* way it can fail (no `gh`, no auth, no network, a non-GitHub origin) resolves `undefined`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function ghForgeMergedProbe(exec: Exec, primaryRoot: string): ForgeMergedProbe;
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/worktrees/lease.d.ts
|
|
39
|
+
/** A held worktree: what `acquire` hands out and `release` takes back. */
|
|
40
|
+
interface Lease {
|
|
41
|
+
/** The worktree root, as `WorktreeEntry.root` gives it. */
|
|
42
|
+
worktree: string;
|
|
43
|
+
leaseId: string;
|
|
44
|
+
holder: string;
|
|
45
|
+
/**
|
|
46
|
+
* The repo's git common dir, recorded at claim so `release` can still clear the lock after the
|
|
47
|
+
* worktree's directory is gone. Absent on a hand-built lease; then the checkout must exist.
|
|
48
|
+
*/
|
|
49
|
+
commonDir?: string | undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The file operations the lease store performs on git's `locked` file, injected so a caller can
|
|
53
|
+
* sandbox them or a test can stage the race with `git worktree lock` (E-GIT-L5). Paths are absolute.
|
|
54
|
+
*/
|
|
55
|
+
interface LeaseFs {
|
|
56
|
+
/** Create the file only if nothing is there; `false` when something already is. */
|
|
57
|
+
createExclusive(path: string, text: string): Promise<boolean>;
|
|
58
|
+
/** The file's text, or `undefined` when it does not exist. */
|
|
59
|
+
readText(path: string): Promise<string | undefined>;
|
|
60
|
+
/** Delete the file; a no-op when it is already gone. */
|
|
61
|
+
remove(path: string): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
/** The default `LeaseFs`, on `node:fs/promises`. */
|
|
64
|
+
export declare const nodeLeaseFs: LeaseFs;
|
|
65
|
+
interface LeaseStoreOptions {
|
|
66
|
+
exec?: Exec | undefined;
|
|
67
|
+
/** Defaults to `nodeLeaseFs`. */
|
|
68
|
+
fs?: LeaseFs | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `$GIT_COMMON_DIR/worktrees/<id>/locked` for a linked worktree, or `undefined` when git cannot say.
|
|
72
|
+
* The `<id>` is git's admin folder name, which need not match the basename, so it is read from
|
|
73
|
+
* `--git-dir` rather than built. When the checkout is gone, `commonDir` finds the admin folder by the
|
|
74
|
+
* `gitdir` pointer it keeps, so a lease on a vanished worktree can still be cleared.
|
|
75
|
+
*/
|
|
76
|
+
export declare function leaseFile(worktreeRoot: string, exec?: Exec, commonDir?: string | undefined): Promise<string | undefined>;
|
|
77
|
+
/**
|
|
78
|
+
* Claim a worktree: exclusive-create its `locked` file with the lease as a one-line JSON reason, which
|
|
79
|
+
* git then honours as a lock (E-GIT-L1, E-GIT-L2, E-GIT-L3), and read it back. `git worktree lock`
|
|
80
|
+
* checks then truncates, so it can overwrite a lease created inside its window (E-GIT-L5); the read
|
|
81
|
+
* back catches that. `undefined` when the worktree is already locked or the claim was lost.
|
|
82
|
+
*/
|
|
83
|
+
export declare function claimLease(worktreeRoot: string, holder: string, options?: LeaseStoreOptions & {
|
|
84
|
+
leaseId?: string | undefined;
|
|
85
|
+
}): Promise<Lease | undefined>;
|
|
86
|
+
/** Whether the worktree's `locked` file still records this lease. Checked again before a destructive
|
|
87
|
+
* step, since a manual `git worktree unlock` or a racing `lock` can take it away (E-GIT-L4, E-GIT-L5). */
|
|
88
|
+
export declare function holdsLease(lease: Lease, options?: LeaseStoreOptions): Promise<boolean>;
|
|
89
|
+
type ReleaseResult = {
|
|
90
|
+
released: true;
|
|
91
|
+
} |
|
|
92
|
+
/** The `locked` file no longer records this lease: someone unlocked it, broke it with
|
|
93
|
+
* `remove -f -f` (E-GIT-L4), or locked over it. Reported, not thrown: that is the user's override. */
|
|
94
|
+
{
|
|
95
|
+
released: false;
|
|
96
|
+
reason: 'lost';
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Give a lease back by deleting the `locked` file, only when it still records this `leaseId`. It does
|
|
100
|
+
* not recycle: an occupant such as a judge may still be working there, so the next `acquire` recycles
|
|
101
|
+
* after probing.
|
|
102
|
+
*/
|
|
103
|
+
export declare function release(lease: Lease, options?: LeaseStoreOptions): Promise<ReleaseResult>;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/worktrees/list-worktrees.d.ts
|
|
106
|
+
/** A worktree as git reports it, plus the landed and dirty facts the reuse and cleanup checks read. */
|
|
107
|
+
interface WorktreeEntry {
|
|
108
|
+
/** Absolute checkout path, symlinks resolved. */
|
|
109
|
+
root: string;
|
|
110
|
+
/** The checked-out commit; absent for a bare entry. */
|
|
111
|
+
head?: string | undefined;
|
|
112
|
+
/** The checked-out branch, without `refs/heads/`; absent when detached or bare. */
|
|
113
|
+
branch?: string | undefined;
|
|
114
|
+
/** HEAD is detached. */
|
|
115
|
+
detached: boolean;
|
|
116
|
+
/** `false` for the primary checkout, `true` for a linked worktree. */
|
|
117
|
+
linked: boolean;
|
|
118
|
+
/** git considers the entry stale: its checkout is gone from disk. */
|
|
119
|
+
prunable: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* The lock reason when the worktree is locked (`''` for a lock with no reason), absent when it is
|
|
122
|
+
* not. A lock may be a lease, a harness's own hold, or a user's.
|
|
123
|
+
*/
|
|
124
|
+
locked?: string | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* The branch's work has landed on the default branch. Absent when undeterminable (no branch, or no
|
|
127
|
+
* default branch to compare against), never `false` as a stand-in.
|
|
128
|
+
*/
|
|
129
|
+
merged?: boolean | undefined;
|
|
130
|
+
/** Which signal established `merged: true`. */
|
|
131
|
+
mergedSignal?: LandedSignal | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* The checkout has uncommitted changes, tracked or untracked. Absent for a prunable entry or when
|
|
134
|
+
* git could not answer.
|
|
135
|
+
*/
|
|
136
|
+
dirty?: boolean | undefined;
|
|
137
|
+
}
|
|
138
|
+
interface PrimaryRootOptions {
|
|
139
|
+
/** Any directory inside the repository, the primary checkout or a linked worktree. Defaults to `.`. */
|
|
140
|
+
from?: string | undefined;
|
|
141
|
+
exec?: Exec | undefined;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* The primary checkout's root, from the primary checkout or any linked worktree:
|
|
145
|
+
* `--git-common-dir` always points at the primary's `.git`.
|
|
146
|
+
*/
|
|
147
|
+
export declare function primaryRoot(options?: PrimaryRootOptions): Promise<string>;
|
|
148
|
+
/**
|
|
149
|
+
* The single normalization for every path matched against another, so a symlinked repo or macOS's
|
|
150
|
+
* `/tmp` → `/private/tmp` still matches. Falls back to `resolve` for a path not on disk.
|
|
151
|
+
*/
|
|
152
|
+
export declare function normalizeWorktreePath(path: string): Promise<string>;
|
|
153
|
+
interface ListWorktreesOptions {
|
|
154
|
+
/** The primary checkout's root; see `primaryRoot`. */
|
|
155
|
+
primaryRoot: string;
|
|
156
|
+
exec?: Exec | undefined;
|
|
157
|
+
/** Paths whose changes do not make a worktree dirty; see `DirtyOptions.ignore`. */
|
|
158
|
+
ignore?: readonly string[] | undefined;
|
|
159
|
+
/** The opt-in forge signal; the offline signals run either way. */
|
|
160
|
+
forge?: ForgeMergedProbe | undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Every worktree of the repo, from `git worktree list --porcelain`, with landed and dirty facts. */
|
|
163
|
+
export declare function listWorktrees(options: ListWorktreesOptions): Promise<WorktreeEntry[]>;
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/worktrees/process-source.d.ts
|
|
166
|
+
/**
|
|
167
|
+
* One process as the probe sees it. Every field but `pid` may be missing: a process can exit
|
|
168
|
+
* mid-read, and another user's process hides its `exe`, `cwd`, and `environ`.
|
|
169
|
+
*/
|
|
170
|
+
interface ProcessInfo {
|
|
171
|
+
pid: number;
|
|
172
|
+
/** Parent pid; absent when unreadable. */
|
|
173
|
+
ppid?: number | undefined;
|
|
174
|
+
/** Resolved executable path, with any ` (deleted)` suffix removed. */
|
|
175
|
+
exe?: string | undefined;
|
|
176
|
+
/** The command line; empty for a kernel thread or an unreadable process. */
|
|
177
|
+
argv: readonly string[];
|
|
178
|
+
/** Resolved working directory, with any ` (deleted)` suffix removed. */
|
|
179
|
+
cwd?: string | undefined;
|
|
180
|
+
/** The process's environment; absent when unreadable. */
|
|
181
|
+
env?: Readonly<Record<string, string>> | undefined;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Lists every process the caller can see, or `null` when this platform has no supported way to read
|
|
185
|
+
* another process's executable and working directory. Inject one to run the probe on fixtures, or on
|
|
186
|
+
* a platform the default does not cover.
|
|
187
|
+
*/
|
|
188
|
+
type ProcessSource = () => Promise<readonly ProcessInfo[] | null>;
|
|
189
|
+
/**
|
|
190
|
+
* Reads processes from a Linux `/proc` (or a mounted copy at `procRoot`). On any other platform the
|
|
191
|
+
* default root returns `null`: macOS would need `proc_pidinfo` (E-PROC-OS2), and Windows has no
|
|
192
|
+
* documented way to read another process's cwd (E-PROC-OS3).
|
|
193
|
+
*/
|
|
194
|
+
export declare function procfsProcessSource(procRoot?: string): ProcessSource;
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/worktrees/session-signatures.d.ts
|
|
197
|
+
/** A harness the process probe recognises: the detected harnesses plus two seen only as processes. */
|
|
198
|
+
type SessionHarnessId = HarnessId | 'goose' | 'antigravity-cli';
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/worktrees/occupancy.d.ts
|
|
201
|
+
/** A live agent session working inside a worktree. A wrapper and its native or relaunched child are
|
|
202
|
+
* one session (E-PROC-KILO1, E-PROC-GEM1). */
|
|
203
|
+
interface Session {
|
|
204
|
+
harness: SessionHarnessId;
|
|
205
|
+
/** The session's top process: the wrapper when there is one. */
|
|
206
|
+
pid: number;
|
|
207
|
+
/** Every process of the session, the wrapper and its child; any one inside the worktree counts. */
|
|
208
|
+
pids: readonly number[];
|
|
209
|
+
/** The session id, when one of its tool processes carries it in the harness's link variable. */
|
|
210
|
+
sessionId?: string | undefined;
|
|
211
|
+
/** Evidence IDs the match rests on. */
|
|
212
|
+
research: readonly string[];
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Why a process left in a worktree was reported:
|
|
216
|
+
* - `session-gone`: its link variable names no live session (E-PROC-CC2, E-PROC-CX2).
|
|
217
|
+
* - `helper-orphaned`: a per-session helper, such as Cursor's worker, outlived its session
|
|
218
|
+
* (E-PROC-CUR3).
|
|
219
|
+
* - `harness-idle`: a helper shared by every session of a harness, such as Cline's hub, with no
|
|
220
|
+
* session of that harness alive (E-PROC-CLINE1).
|
|
221
|
+
* - `no-link`: no live session above it and no link variable, so orphaned and user-started look the
|
|
222
|
+
* same (cline, OpenHands, crush tool processes, or a user's own terminal).
|
|
223
|
+
* - `unresolved-link`: its session id matches none known, but a live session of that harness has not
|
|
224
|
+
* revealed its id, so the process may still be that session's.
|
|
225
|
+
* - `env-unreadable`: no live session above it and its environment could not be read.
|
|
226
|
+
*/
|
|
227
|
+
type LeftoverReason = 'session-gone' | 'helper-orphaned' | 'harness-idle' | 'no-link' | 'unresolved-link' | 'env-unreadable';
|
|
228
|
+
/** A non-session process inside a worktree with no live session above it. Reported, never killed. */
|
|
229
|
+
interface LeftoverProcess {
|
|
230
|
+
pid: number;
|
|
231
|
+
ppid?: number | undefined;
|
|
232
|
+
argv: readonly string[];
|
|
233
|
+
cwd: string;
|
|
234
|
+
/** The harness its link variable or helper signature names, when known. */
|
|
235
|
+
harness?: SessionHarnessId | undefined;
|
|
236
|
+
reason: LeftoverReason;
|
|
237
|
+
}
|
|
238
|
+
interface WorktreeOccupancy {
|
|
239
|
+
/**
|
|
240
|
+
* A live agent session works here, so the worktree must not be recycled or removed. Dev services
|
|
241
|
+
* do not count. When the probe is unverified this is `strict`.
|
|
242
|
+
*/
|
|
243
|
+
busy: boolean;
|
|
244
|
+
/** `false` when the platform's processes could not be read; `occupants` is then empty, not proof. */
|
|
245
|
+
verified: boolean;
|
|
246
|
+
/** Every live session found inside; never limited in number or role. */
|
|
247
|
+
occupants: Session[];
|
|
248
|
+
/** Processes no live session launched, provably: safe for a caller to reclaim. */
|
|
249
|
+
lingering: LeftoverProcess[];
|
|
250
|
+
/** Processes with no live session above them whose launcher cannot be told; reported, not lingering. */
|
|
251
|
+
unlinked: LeftoverProcess[];
|
|
252
|
+
}
|
|
253
|
+
interface ProbeOptions {
|
|
254
|
+
/** Where processes come from; defaults to Linux `/proc`. */
|
|
255
|
+
source?: ProcessSource | undefined;
|
|
256
|
+
}
|
|
257
|
+
interface OccupancyOptions {
|
|
258
|
+
/** Treat an unverified probe as busy. Off by default: reuse proceeds, reported as unverified. */
|
|
259
|
+
strict?: boolean | undefined;
|
|
260
|
+
/**
|
|
261
|
+
* Roots of worktrees nested inside this one (Claude Code puts its worktrees under
|
|
262
|
+
* `<repo>/.claude/worktrees/`, E-PROC-CC5); processes there belong to them, not to this one.
|
|
263
|
+
*/
|
|
264
|
+
nested?: readonly string[] | undefined;
|
|
265
|
+
}
|
|
266
|
+
/** One snapshot of the process table, answering for any number of worktrees. */
|
|
267
|
+
interface ProcessProbe {
|
|
268
|
+
verified: boolean;
|
|
269
|
+
/** @param worktreeRoot absolute, symlinks resolved, as `WorktreeEntry.root` gives it. */
|
|
270
|
+
occupancy(worktreeRoot: string, options?: OccupancyOptions): WorktreeOccupancy;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Snapshots processes once and classifies each against the session signature table. Read-only: the
|
|
274
|
+
* probe never signals or kills a process. A harness missing from the table is invisible to it.
|
|
275
|
+
*/
|
|
276
|
+
export declare function probeProcesses(options?: ProbeOptions): Promise<ProcessProbe>;
|
|
277
|
+
/**
|
|
278
|
+
* The live agent sessions inside a worktree, or `undefined` when the probe could not read this
|
|
279
|
+
* platform's processes.
|
|
280
|
+
*/
|
|
281
|
+
export declare function occupants(worktreeRoot: string, options?: ProbeOptions & Pick<OccupancyOptions, 'nested'>): Promise<Session[] | undefined>;
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/worktrees/owner.d.ts
|
|
284
|
+
/**
|
|
285
|
+
* Who a worktree belongs to. Only `self`, a worktree this library leased, may be reused or removed;
|
|
286
|
+
* every other owner is foreign and left alone.
|
|
287
|
+
*
|
|
288
|
+
* - `self`: locked with this library's lease, or an idle slot the library created: unlocked, at a
|
|
289
|
+
* library-assigned path (`slotPath`). A lease is a lock that release deletes (E-GIT-L1), so the
|
|
290
|
+
* slot path is what still marks a released worktree as ours.
|
|
291
|
+
* - `claude-code`, `codex`: recognised by a researched marker.
|
|
292
|
+
* - `cursor`: not produced yet. Its worktree root rests on a forum post only (E-CUR-W1, Low), so a
|
|
293
|
+
* Cursor worktree reports `unknown` until that is verified.
|
|
294
|
+
* - `user`: the primary checkout.
|
|
295
|
+
* - `unknown`: anything else, including Copilot CLI and herdr worktrees, whose layouts are not
|
|
296
|
+
* documented (E-COP-W1, E-HERDR-W1), and a lock whose reason names no one we recognise.
|
|
297
|
+
*/
|
|
298
|
+
type WorktreeOwnerKind = 'self' | 'claude-code' | 'cursor' | 'codex' | 'user' | 'unknown';
|
|
299
|
+
interface WorktreeOwner {
|
|
300
|
+
owner: WorktreeOwnerKind;
|
|
301
|
+
/** The `.research/worktree-management` evidence IDs the classification rests on; empty when none. */
|
|
302
|
+
research: readonly string[];
|
|
303
|
+
}
|
|
304
|
+
/** The `library` value a lease reason carries. */
|
|
305
|
+
export declare const LEASE_LIBRARY = "cyber-agentkit";
|
|
306
|
+
/** A lease as recorded in the `locked` file: one line of JSON (E-GIT-L1, E-GIT-L2). */
|
|
307
|
+
interface LeaseReason {
|
|
308
|
+
library: typeof LEASE_LIBRARY;
|
|
309
|
+
leaseId: string;
|
|
310
|
+
holder: string;
|
|
311
|
+
}
|
|
312
|
+
/** The lease a lock reason records, or `undefined` when the lock is not this library's. */
|
|
313
|
+
export declare function parseLeaseReason(reason: string | undefined): LeaseReason | undefined;
|
|
314
|
+
interface ClassifyOwnerOptions {
|
|
315
|
+
/** The primary checkout's root, normalized as `WorktreeEntry.root` is (`normalizeWorktreePath`). */
|
|
316
|
+
primaryRoot: string;
|
|
317
|
+
/**
|
|
318
|
+
* Codex's home (`$CODEX_HOME`), normalized. Without it no worktree is recognised as Codex's: the
|
|
319
|
+
* research records the `$CODEX_HOME/worktrees` root but not its default.
|
|
320
|
+
*/
|
|
321
|
+
codexHome?: string | undefined;
|
|
322
|
+
}
|
|
323
|
+
/** Classify a worktree's owner from its lock reason and path. Pure: reads nothing from disk. */
|
|
324
|
+
export declare function classifyOwner(entry: WorktreeEntry, options: ClassifyOwnerOptions): WorktreeOwner;
|
|
325
|
+
//#endregion
|
|
326
|
+
//#region src/worktrees/acquire.d.ts
|
|
327
|
+
/**
|
|
328
|
+
* Why a worktree cannot be reused, in the order the checks run (E-TH-2). The first that applies wins.
|
|
329
|
+
*
|
|
330
|
+
* - `primary`: the primary checkout, never reused.
|
|
331
|
+
* - `foreign`: another tool or the user owns it; see `owner`.
|
|
332
|
+
* - `leased`: a holder has it; see `holder`. The lease protects it whatever the probe sees.
|
|
333
|
+
* - `prunable`: its checkout is gone from disk.
|
|
334
|
+
* - `busy`: a live agent session works inside.
|
|
335
|
+
* - `unverified`: the probe could not read processes and the caller asked for `strict`.
|
|
336
|
+
* - `dirty`: uncommitted changes, or git could not say (fail closed).
|
|
337
|
+
* - `unmerged`: HEAD has not landed on the reset target, or that could not be told.
|
|
338
|
+
* - `rejected`: the caller's `available` predicate said no.
|
|
339
|
+
*/
|
|
340
|
+
type SkipReason = 'primary' | 'foreign' | 'leased' | 'prunable' | 'busy' | 'unverified' | 'dirty' | 'unmerged' | 'rejected';
|
|
341
|
+
/** One worktree's standing for reuse. */
|
|
342
|
+
interface WorktreeVerdict {
|
|
343
|
+
worktree: WorktreeEntry;
|
|
344
|
+
owner: WorktreeOwner;
|
|
345
|
+
/** Absent when the worktree can be reused. */
|
|
346
|
+
skip?: SkipReason | undefined;
|
|
347
|
+
/** The lease holder, when `skip` is `leased`. */
|
|
348
|
+
holder?: string | undefined;
|
|
349
|
+
/** What the probe saw, when the checks reached it. */
|
|
350
|
+
occupancy?: WorktreeOccupancy | undefined;
|
|
351
|
+
/**
|
|
352
|
+
* `false` when the probe could not read processes, so a reusable verdict is not proof that no
|
|
353
|
+
* session works there. `true` when the probe answered or was never needed.
|
|
354
|
+
*/
|
|
355
|
+
verified: boolean;
|
|
356
|
+
}
|
|
357
|
+
interface ExplainOptions {
|
|
358
|
+
/** Any directory inside the repository; ignored when `primaryRoot` is given. Defaults to `.`. */
|
|
359
|
+
from?: string | undefined;
|
|
360
|
+
/** The primary checkout's root; resolved from `from` when absent. */
|
|
361
|
+
primaryRoot?: string | undefined;
|
|
362
|
+
/** The ref a recycle resets to. Defaults to `origin/HEAD`, then the primary checkout's branch. */
|
|
363
|
+
base?: string | undefined;
|
|
364
|
+
exec?: Exec | undefined;
|
|
365
|
+
/** Paths whose changes do not make a worktree dirty; see `DirtyOptions.ignore`. */
|
|
366
|
+
ignore?: readonly string[] | undefined;
|
|
367
|
+
/** The opt-in forge signal for "landed"; see `ListWorktreesOptions.forge`. */
|
|
368
|
+
forge?: ForgeMergedProbe | undefined;
|
|
369
|
+
/** A process snapshot; one is taken when absent. */
|
|
370
|
+
probe?: ProcessProbe | undefined;
|
|
371
|
+
/** Treat a probe that could not read processes as busy. Off by default: reuse proceeds, unverified. */
|
|
372
|
+
strict?: boolean | undefined;
|
|
373
|
+
/** `$CODEX_HOME`, so Codex worktrees classify as `codex`; see `ClassifyOwnerOptions`. */
|
|
374
|
+
codexHome?: string | undefined;
|
|
375
|
+
/** An extra condition, checked after every safety check; it cannot make a skipped worktree reusable. */
|
|
376
|
+
available?: ((worktree: WorktreeEntry) => boolean | Promise<boolean>) | undefined;
|
|
377
|
+
}
|
|
378
|
+
/** Every worktree of the repo with the reason it cannot be reused, or none when it can. */
|
|
379
|
+
export declare function explain(options?: ExplainOptions): Promise<WorktreeVerdict[]>;
|
|
380
|
+
/** What a `WorktreeCreator` is asked to make. */
|
|
381
|
+
interface CreateWorktreeRequest {
|
|
382
|
+
primaryRoot: string;
|
|
383
|
+
/** The library-chosen path, `<parent>/<repo>.worktrees/<repo>-<n>`; the creator must use it. */
|
|
384
|
+
path: string;
|
|
385
|
+
/** The ref to start from. */
|
|
386
|
+
base: string;
|
|
387
|
+
/** The branch to check out: an existing one, or a new one at `base`. Detached at `base` when absent. */
|
|
388
|
+
branch?: string | undefined;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Makes the worktree at the library-chosen path, so a caller can create it through another tool,
|
|
392
|
+
* such as herdr, which binds only worktrees it created itself (E-MUX-7). Throw on failure.
|
|
393
|
+
*/
|
|
394
|
+
type WorktreeCreator = (request: CreateWorktreeRequest) => Promise<void>;
|
|
395
|
+
/**
|
|
396
|
+
* Undoes what a `WorktreeCreator` did besides the checkout itself, such as a herdr workspace bound to
|
|
397
|
+
* the path. `acquire` calls it when the slot it just created lost its lease claim: the checkout may
|
|
398
|
+
* now belong to whoever won the claim (E-GIT-L5), so this must leave the worktree and its directory
|
|
399
|
+
* alone. Failures are swallowed so the retry still runs.
|
|
400
|
+
*/
|
|
401
|
+
type WorktreeCreatorUndo = (request: CreateWorktreeRequest) => Promise<void>;
|
|
402
|
+
/** The default `WorktreeCreator`: `git worktree add`. */
|
|
403
|
+
export declare function gitWorktreeCreator(exec?: Exec): WorktreeCreator;
|
|
404
|
+
interface AcquireOptions extends ExplainOptions {
|
|
405
|
+
/** Who holds the lease, such as a Captain or Pod; recorded in the lock reason. */
|
|
406
|
+
holder: string;
|
|
407
|
+
/** The branch to work on: an existing one, or a new one at `base`. Detached at `base` when absent. */
|
|
408
|
+
branch?: string | undefined;
|
|
409
|
+
/** The most slots the repo may have; a new one is created only below it. Unlimited when absent. */
|
|
410
|
+
max?: number | undefined;
|
|
411
|
+
/** Defaults to `gitWorktreeCreator(exec)`. */
|
|
412
|
+
create?: WorktreeCreator | undefined;
|
|
413
|
+
/** Called when a slot `create` made lost its lease claim; see `WorktreeCreatorUndo`. */
|
|
414
|
+
undoCreate?: WorktreeCreatorUndo | undefined;
|
|
415
|
+
/** The lease store's file operations; see `LeaseFs`. */
|
|
416
|
+
fs?: LeaseFs | undefined;
|
|
417
|
+
/** Makes lease ids; defaults to a random UUID. */
|
|
418
|
+
newLeaseId?: (() => string) | undefined;
|
|
419
|
+
}
|
|
420
|
+
interface AcquireResult extends Lease {
|
|
421
|
+
/** `true` when an idle worktree was recycled, `false` when a new one was created. A reused path
|
|
422
|
+
* carries path-keyed harness state, so a "continue" there resumes the previous task (E-PROC-CC6). */
|
|
423
|
+
reused: boolean;
|
|
424
|
+
/** The branch now checked out; absent when detached. */
|
|
425
|
+
branch?: string | undefined;
|
|
426
|
+
/** The branch a reused worktree had before the recycle. */
|
|
427
|
+
previousBranch?: string | undefined;
|
|
428
|
+
/** That branch was merged and has been deleted. */
|
|
429
|
+
previousBranchDeleted?: boolean | undefined;
|
|
430
|
+
/** `false` when the reused worktree was not checked for live sessions because the probe could not
|
|
431
|
+
* read processes. */
|
|
432
|
+
verified: boolean;
|
|
433
|
+
/** Dev services left running in a reused worktree with no live session behind them. Never killed. */
|
|
434
|
+
lingering: LeftoverProcess[];
|
|
435
|
+
}
|
|
436
|
+
type AcquireErrorCode = 'pool-full' | 'no-base' | 'contended';
|
|
437
|
+
export declare class AcquireError extends Error {
|
|
438
|
+
readonly code: AcquireErrorCode;
|
|
439
|
+
/** The skip reason for every worktree, from the last look. */
|
|
440
|
+
readonly verdicts: readonly WorktreeVerdict[];
|
|
441
|
+
constructor(code: AcquireErrorCode, message: string,
|
|
442
|
+
/** The skip reason for every worktree, from the last look. */
|
|
443
|
+
verdicts: readonly WorktreeVerdict[]);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Lease a worktree: recycle an idle one of ours when there is one, otherwise create one at the next
|
|
447
|
+
* free slot if under `max`. Never fetches and never kills a process.
|
|
448
|
+
*/
|
|
449
|
+
export declare function acquire(options: AcquireOptions): Promise<AcquireResult>;
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/worktrees/dirty.d.ts
|
|
452
|
+
interface DirtyOptions {
|
|
453
|
+
exec: Exec;
|
|
454
|
+
/**
|
|
455
|
+
* Paths, relative to the worktree root, whose changes do not count — a tool's own marker file, such
|
|
456
|
+
* as cyberlegion's `.agents/cyberlegion/config.json`. Passed to git as `:(exclude)` pathspecs.
|
|
457
|
+
*/
|
|
458
|
+
ignore?: readonly string[] | undefined;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Whether a checkout has uncommitted changes, tracked or untracked, or `undefined` when git could not
|
|
462
|
+
* say. `undefined` is not `false`: a caller deciding whether a worktree is safe to reuse must not read
|
|
463
|
+
* an unanswered question as a clean tree.
|
|
464
|
+
*
|
|
465
|
+
* `--untracked-files=all` is explicit because a repo's `status.showUntrackedFiles=no` would otherwise
|
|
466
|
+
* hide untracked work.
|
|
467
|
+
*/
|
|
468
|
+
export declare function readDirty(worktreeRoot: string, options: DirtyOptions): Promise<boolean | undefined>;
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/worktrees/naming.d.ts
|
|
471
|
+
/**
|
|
472
|
+
* Where the library puts a repo's worktrees: `<parent>/<repo>.worktrees`, a sibling of the primary
|
|
473
|
+
* checkout (E-MUX-2, E-LEG-1). Every worktree the library creates is a slot in this folder.
|
|
474
|
+
*/
|
|
475
|
+
export declare function worktreesDir(primaryRoot: string): string;
|
|
476
|
+
/**
|
|
477
|
+
* The path of slot `n`: `<parent>/<repo>.worktrees/<repo>-<n>`. The library assigns `n` and the
|
|
478
|
+
* caller cannot, so the name stays meaningless and true for the worktree's whole life; what it is
|
|
479
|
+
* for lives in its branch and lease holder, which change on reuse (decision 2026-10-05, E-TH-7).
|
|
480
|
+
*/
|
|
481
|
+
export declare function slotPath(primaryRoot: string, n: number): string;
|
|
482
|
+
/**
|
|
483
|
+
* The slot number of a worktree root, or `undefined` when the root is not one of the library's slots.
|
|
484
|
+
* Both paths are normalized (`normalizeWorktreePath`). `n` is a positive integer with no leading
|
|
485
|
+
* zero, so `repo-01` is not slot 1.
|
|
486
|
+
*/
|
|
487
|
+
export declare function slotNumber(primaryRoot: string, worktreeRoot: string): number | undefined;
|
|
488
|
+
//#endregion
|
|
489
|
+
//#region src/worktrees/prune-worktrees.d.ts
|
|
490
|
+
/**
|
|
491
|
+
* Why a worktree was left in place, in the fail-closed order the checks run (E-MUX-5, E-TH-2):
|
|
492
|
+
*
|
|
493
|
+
* - `primary`: the primary checkout. Never removed, with no override.
|
|
494
|
+
* - `foreign`: owned by another tool or person (`classifyOwner`), including a worktree off this library's slot paths.
|
|
495
|
+
* - `leased`: held by this library's lease. git itself refuses to remove it (E-GIT-L3); `release`
|
|
496
|
+
* it first.
|
|
497
|
+
* - `prunable`: its checkout is already gone; `git worktree prune` collects the entry.
|
|
498
|
+
* - `busy`: a live agent session works inside.
|
|
499
|
+
* - `unverified`: the process probe could not read this platform, and the caller kept the strict
|
|
500
|
+
* rule.
|
|
501
|
+
* - `dirty`: uncommitted changes, tracked or untracked.
|
|
502
|
+
* - `dirty-unknown`: git could not say whether it is clean.
|
|
503
|
+
* - `unmerged`: its branch has not landed on the default branch.
|
|
504
|
+
* - `merge-unknown`: whether it landed cannot be told (detached HEAD, or no default branch).
|
|
505
|
+
* - `unlisted`: only `removeWorktree` reports it: the named path is no worktree of this repository.
|
|
506
|
+
*/
|
|
507
|
+
type PruneSkipReason = 'primary' | 'foreign' | 'leased' | 'prunable' | 'busy' | 'unverified' | 'dirty' | 'dirty-unknown' | 'unmerged' | 'merge-unknown' | 'unlisted';
|
|
508
|
+
interface PruneOutcome {
|
|
509
|
+
root: string;
|
|
510
|
+
branch?: string | undefined;
|
|
511
|
+
owner: WorktreeOwnerKind;
|
|
512
|
+
/**
|
|
513
|
+
* - `candidate`: passed every check; a dry run stops here.
|
|
514
|
+
* - `removed`: `git worktree remove` succeeded.
|
|
515
|
+
* - `failed`: passed every check, but git refused, or the tree changed before removal.
|
|
516
|
+
* - `skipped`: see `reason`.
|
|
517
|
+
*/
|
|
518
|
+
status: 'candidate' | 'removed' | 'failed' | 'skipped';
|
|
519
|
+
reason?: PruneSkipReason | undefined;
|
|
520
|
+
/** The probe could not read this platform, and the caller opted out of the strict rule. */
|
|
521
|
+
unverified?: true | undefined;
|
|
522
|
+
/** Live agent sessions found inside. */
|
|
523
|
+
occupants: Session[];
|
|
524
|
+
/** Dev services no live session launched: the caller may reclaim them. Never killed. */
|
|
525
|
+
lingering: LeftoverProcess[];
|
|
526
|
+
/** Processes whose launcher cannot be told. Reported, never killed. */
|
|
527
|
+
unlinked: LeftoverProcess[];
|
|
528
|
+
}
|
|
529
|
+
interface PruneReport {
|
|
530
|
+
/** `false` for a dry run. */
|
|
531
|
+
applied: boolean;
|
|
532
|
+
/** One outcome per considered worktree, in `git worktree list` order. */
|
|
533
|
+
worktrees: PruneOutcome[];
|
|
534
|
+
/** `git worktree prune` succeeded; absent on a dry run. */
|
|
535
|
+
pruned?: boolean | undefined;
|
|
536
|
+
}
|
|
537
|
+
interface PruneWorktreesOptions {
|
|
538
|
+
/** The primary checkout's root; see `primaryRoot`. */
|
|
539
|
+
primaryRoot: string;
|
|
540
|
+
/** Remove the candidates and run `git worktree prune`. Off by default: a dry run. */
|
|
541
|
+
apply?: boolean | undefined;
|
|
542
|
+
/** Consider only these worktree roots; every worktree when absent. */
|
|
543
|
+
roots?: readonly string[] | undefined;
|
|
544
|
+
/**
|
|
545
|
+
* Skip every worktree when the process probe cannot read this platform. On by default, since
|
|
546
|
+
* removal cannot be undone; `false` proceeds and marks each outcome `unverified`.
|
|
547
|
+
*/
|
|
548
|
+
strict?: boolean | undefined;
|
|
549
|
+
exec?: Exec | undefined;
|
|
550
|
+
/** Paths whose changes do not make a worktree dirty; see `DirtyOptions.ignore`. */
|
|
551
|
+
ignore?: readonly string[] | undefined;
|
|
552
|
+
/** The opt-in forge signal for landed detection. */
|
|
553
|
+
forge?: ForgeMergedProbe | undefined;
|
|
554
|
+
/** Where processes come from; defaults to Linux `/proc`. */
|
|
555
|
+
source?: ProcessSource | undefined;
|
|
556
|
+
/** Codex's home, normalized; see `ClassifyOwnerOptions.codexHome`. */
|
|
557
|
+
codexHome?: string | undefined;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Removes the worktrees this library owns that nothing needs any more: unleased, idle, clean, and
|
|
561
|
+
* landed. A dry run unless `apply` is set. Never touches the primary checkout, a foreign worktree, a
|
|
562
|
+
* leased one, or a busy one, and never kills a process: lingering services are reported so the caller
|
|
563
|
+
* can reclaim them (E-TH-5 is the counterexample).
|
|
564
|
+
*
|
|
565
|
+
* An unleased worktree carries no record of its owner, since the lease is the only one this library
|
|
566
|
+
* writes; `classifyOwner` recognises it as this library's by its slot path (`slotPath`).
|
|
567
|
+
*/
|
|
568
|
+
export declare function pruneWorktrees(options: PruneWorktreesOptions): Promise<PruneReport>;
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/worktrees/remove-worktree.d.ts
|
|
571
|
+
interface RemoveWorktreeOptions {
|
|
572
|
+
/** The primary checkout's root; see `primaryRoot`. */
|
|
573
|
+
primaryRoot: string;
|
|
574
|
+
/** The worktree to remove, by path. Symlinks and trailing separators are normalized. */
|
|
575
|
+
root: string;
|
|
576
|
+
/**
|
|
577
|
+
* Remove it with `git worktree remove --force`. `true` waives foreign, `prunable`, dirty, and unmerged,
|
|
578
|
+
* but still skips a busy or `unverified` worktree. `'in-use'` waives those two as well, reporting the
|
|
579
|
+
* occupants and never killing them. Off by default: the same fail-closed checks `pruneWorktrees` runs.
|
|
580
|
+
* The primary checkout and a leased worktree are never removed, in any mode.
|
|
581
|
+
*/
|
|
582
|
+
force?: boolean | 'in-use' | undefined;
|
|
583
|
+
/**
|
|
584
|
+
* Skip a busy worktree when the process probe cannot read this platform. On by default; `false`
|
|
585
|
+
* proceeds and marks the outcome `unverified`. Moot under `force: 'in-use'`, which does not consult it.
|
|
586
|
+
*/
|
|
587
|
+
strict?: boolean | undefined;
|
|
588
|
+
exec?: Exec | undefined;
|
|
589
|
+
/** Paths whose changes do not make a worktree dirty; see `DirtyOptions.ignore`. */
|
|
590
|
+
ignore?: readonly string[] | undefined;
|
|
591
|
+
/** The opt-in forge signal for landed detection. */
|
|
592
|
+
forge?: ForgeMergedProbe | undefined;
|
|
593
|
+
/** Where processes come from; defaults to Linux `/proc`. */
|
|
594
|
+
source?: ProcessSource | undefined;
|
|
595
|
+
/** Codex's home, normalized; see `ClassifyOwnerOptions.codexHome`. */
|
|
596
|
+
codexHome?: string | undefined;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Removes one worktree the caller names, the single-target counterpart of `pruneWorktrees`, and
|
|
600
|
+
* reports the same `PruneOutcome` with a skip `reason`. The caller naming it is what a prune lacks, so
|
|
601
|
+
* the landed check can be waived with `force`, and the idle check with `force: 'in-use'`; ownership cannot:
|
|
602
|
+
*
|
|
603
|
+
* | worktree | without `force` | `force: true` | `force: 'in-use'` |
|
|
604
|
+
* | --- | --- | --- | --- |
|
|
605
|
+
* | the primary checkout | `primary` | `primary` | `primary` |
|
|
606
|
+
* | held by this library's lease | `leased`; `release` it first | `leased` | `leased`; the lease is never broken |
|
|
607
|
+
* | foreign (another tool, person, or lock) | `foreign` | removed, unless git refuses a locked one: `failed` | same |
|
|
608
|
+
* | a live agent session inside | `busy` (or `unverified`) | `busy` (or `unverified`) | removed; the sessions are reported, never killed |
|
|
609
|
+
* | checkout already gone | `prunable` | `git worktree remove --force` is tried | same |
|
|
610
|
+
* | dirty or unmerged | the matching reason | removed | removed |
|
|
611
|
+
* | a path that is no worktree of this repository | `unlisted` | `unlisted` | `unlisted` |
|
|
612
|
+
*
|
|
613
|
+
* `--force` is passed once and `-f -f` never: one refuses a locked worktree, so a lease taken after the
|
|
614
|
+
* listing holds (E-GIT-L3, E-GIT-L4). Never kills a process; lingering services are reported so the
|
|
615
|
+
* caller can reclaim them. Always applies: there is no dry run, since the caller named the target.
|
|
616
|
+
*/
|
|
617
|
+
export declare function removeWorktree(options: RemoveWorktreeOptions): Promise<PruneOutcome>;
|
|
618
|
+
//#endregion
|
|
619
|
+
//#region src/worktrees/seed-worktree.d.ts
|
|
620
|
+
/**
|
|
621
|
+
* The file operations `seedWorktree` performs, injected so a caller can dry-run, sandbox, or log
|
|
622
|
+
* them. Paths are absolute. Nothing here runs a command: the include file is data, never a script
|
|
623
|
+
* (research: 'E-TH-4').
|
|
624
|
+
*/
|
|
625
|
+
interface SeedFs {
|
|
626
|
+
/** The file's text, or `undefined` when it does not exist. */
|
|
627
|
+
readText(path: string): Promise<string | undefined>;
|
|
628
|
+
/** Whether anything — file, directory, or link — is at the path. */
|
|
629
|
+
exists(path: string): Promise<boolean>;
|
|
630
|
+
/** Create a directory and its parents; a no-op when it exists. */
|
|
631
|
+
mkdirp(path: string): Promise<void>;
|
|
632
|
+
copyFile(from: string, to: string): Promise<void>;
|
|
633
|
+
}
|
|
634
|
+
/** The default `SeedFs`, on `node:fs/promises`. */
|
|
635
|
+
export declare const nodeSeedFs: SeedFs;
|
|
636
|
+
interface SeedWorktreeOptions {
|
|
637
|
+
exec: Exec;
|
|
638
|
+
/** Defaults to `nodeSeedFs`. */
|
|
639
|
+
fs?: SeedFs | undefined;
|
|
640
|
+
/**
|
|
641
|
+
* Replace a file the worktree already has. Off by default: a recycled worktree keeps its ignored
|
|
642
|
+
* files (a recycle runs `clean -fd` without `-x`, research: 'E-TH-3'), and its own `.env` may have
|
|
643
|
+
* been edited on purpose.
|
|
644
|
+
*/
|
|
645
|
+
overwrite?: boolean | undefined;
|
|
646
|
+
}
|
|
647
|
+
type SeedSkipReason =
|
|
648
|
+
/** Matches the include file but is not gitignored, so a checkout already carries it or it is
|
|
649
|
+
* untracked work that belongs to the source checkout (research: 'E-CC-W2'). */
|
|
650
|
+
'not-ignored' |
|
|
651
|
+
/** The worktree already has something at that path, and `overwrite` is off. */
|
|
652
|
+
'exists' |
|
|
653
|
+
/** The copy threw; `error` holds the message. */
|
|
654
|
+
'failed';
|
|
655
|
+
interface SeedSkip {
|
|
656
|
+
/** Relative to the checkout root, with `/` separators, as git prints it. */
|
|
657
|
+
path: string;
|
|
658
|
+
reason: SeedSkipReason;
|
|
659
|
+
error?: string | undefined;
|
|
660
|
+
}
|
|
661
|
+
interface SeedInventory {
|
|
662
|
+
/**
|
|
663
|
+
* `absent` when the source has no `.worktreeinclude`, so nothing was attempted; `unknown` when git
|
|
664
|
+
* could not list the candidates, so nothing was copied and nothing is known to be missing.
|
|
665
|
+
*/
|
|
666
|
+
include: 'present' | 'absent' | 'unknown';
|
|
667
|
+
/** Paths copied, relative to the checkout root. */
|
|
668
|
+
copied: string[];
|
|
669
|
+
skipped: SeedSkip[];
|
|
670
|
+
}
|
|
671
|
+
/** The include file's name and place: the project root, `.gitignore` syntax (research: 'E-CC-W2'). */
|
|
672
|
+
export declare const WORKTREE_INCLUDE = ".worktreeinclude";
|
|
673
|
+
/**
|
|
674
|
+
* Copies the gitignored files a `.worktreeinclude` names from a source checkout (normally the primary)
|
|
675
|
+
* into a new or recycled worktree, and reports what it copied and what it skipped.
|
|
676
|
+
*
|
|
677
|
+
* Claude Code's semantics (research: 'E-CC-W2'): the file sits at the project root and uses
|
|
678
|
+
* `.gitignore` syntax, and only a file that matches a pattern *and* is gitignored is copied, so
|
|
679
|
+
* tracked files are never duplicated. Git does the matching here, so negation, anchoring, and
|
|
680
|
+
* directory patterns behave exactly as they do in `.gitignore`. Inside a wholly ignored directory, a
|
|
681
|
+
* pattern that starts with `**` and a slash matches every file below it here, while Claude Code reaches
|
|
682
|
+
* in only when the directory's path holds the pattern's first name (research: 'E-CC-W6'), so this can
|
|
683
|
+
* copy a superset of what Claude Code would.
|
|
684
|
+
*
|
|
685
|
+
* The include file is read from the source's working tree, as Claude Code does, not from its
|
|
686
|
+
* committed HEAD as Treehouse does (research: 'E-TH-4'), so an uncommitted edit takes effect.
|
|
687
|
+
*/
|
|
688
|
+
export declare function seedWorktree(sourceRoot: string, worktreeRoot: string, options: SeedWorktreeOptions): Promise<SeedInventory>;
|
|
689
|
+
//#endregion
|
|
690
|
+
export type { AcquireErrorCode, AcquireOptions, AcquireResult, ClassifyOwnerOptions, CreateWorktreeRequest, DirtyOptions, Exec, ExplainOptions, ForgeMergedProbe, LandedSignal, Lease, LeaseFs, LeaseReason, LeaseStoreOptions, LeftoverProcess, LeftoverReason, ListWorktreesOptions, OccupancyOptions, PrimaryRootOptions, ProbeOptions, ProcessInfo, ProcessProbe, ProcessSource, PruneOutcome, PruneReport, PruneSkipReason, PruneWorktreesOptions, ReleaseResult, RemoveWorktreeOptions, SeedFs, SeedInventory, SeedSkip, SeedSkipReason, SeedWorktreeOptions, Session, SessionHarnessId, SkipReason, WorktreeCreator, WorktreeCreatorUndo, WorktreeEntry, WorktreeOccupancy, WorktreeOwner, WorktreeOwnerKind, WorktreeVerdict };
|