@openagt/skill-branches 0.0.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/SKILL.md +70 -0
  3. package/bin/branches +11 -0
  4. package/dist/bin-dir.d.ts +7 -0
  5. package/dist/bin-dir.d.ts.map +1 -0
  6. package/dist/bin-dir.js +8 -0
  7. package/dist/bin-dir.js.map +1 -0
  8. package/dist/branch-links.d.ts +37 -0
  9. package/dist/branch-links.d.ts.map +1 -0
  10. package/dist/branch-links.js +67 -0
  11. package/dist/branch-links.js.map +1 -0
  12. package/dist/branch-names.d.ts +41 -0
  13. package/dist/branch-names.d.ts.map +1 -0
  14. package/dist/branch-names.js +54 -0
  15. package/dist/branch-names.js.map +1 -0
  16. package/dist/branch-state.d.ts +68 -0
  17. package/dist/branch-state.d.ts.map +1 -0
  18. package/dist/branch-state.js +146 -0
  19. package/dist/branch-state.js.map +1 -0
  20. package/dist/checkout.d.ts +25 -0
  21. package/dist/checkout.d.ts.map +1 -0
  22. package/dist/checkout.js +37 -0
  23. package/dist/checkout.js.map +1 -0
  24. package/dist/cli.d.ts +36 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +310 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/command-link.d.ts +20 -0
  29. package/dist/command-link.d.ts.map +1 -0
  30. package/dist/command-link.js +37 -0
  31. package/dist/command-link.js.map +1 -0
  32. package/dist/file-branch.d.ts +150 -0
  33. package/dist/file-branch.d.ts.map +1 -0
  34. package/dist/file-branch.js +371 -0
  35. package/dist/file-branch.js.map +1 -0
  36. package/dist/git-exclude.d.ts +17 -0
  37. package/dist/git-exclude.d.ts.map +1 -0
  38. package/dist/git-exclude.js +30 -0
  39. package/dist/git-exclude.js.map +1 -0
  40. package/dist/git.d.ts +73 -0
  41. package/dist/git.d.ts.map +1 -0
  42. package/dist/git.js +164 -0
  43. package/dist/git.js.map +1 -0
  44. package/dist/index.d.ts +15 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +15 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/merge-hold.d.ts +20 -0
  49. package/dist/merge-hold.d.ts.map +1 -0
  50. package/dist/merge-hold.js +64 -0
  51. package/dist/merge-hold.js.map +1 -0
  52. package/dist/merge-watch.d.ts +68 -0
  53. package/dist/merge-watch.d.ts.map +1 -0
  54. package/dist/merge-watch.js +97 -0
  55. package/dist/merge-watch.js.map +1 -0
  56. package/dist/merge.d.ts +70 -0
  57. package/dist/merge.d.ts.map +1 -0
  58. package/dist/merge.js +55 -0
  59. package/dist/merge.js.map +1 -0
  60. package/dist/publish.d.ts +138 -0
  61. package/dist/publish.d.ts.map +1 -0
  62. package/dist/publish.js +215 -0
  63. package/dist/publish.js.map +1 -0
  64. package/dist/push.d.ts +53 -0
  65. package/dist/push.d.ts.map +1 -0
  66. package/dist/push.js +41 -0
  67. package/dist/push.js.map +1 -0
  68. package/dist/reclaim.d.ts +74 -0
  69. package/dist/reclaim.d.ts.map +1 -0
  70. package/dist/reclaim.js +87 -0
  71. package/dist/reclaim.js.map +1 -0
  72. package/dist/skill-links.d.ts +43 -0
  73. package/dist/skill-links.d.ts.map +1 -0
  74. package/dist/skill-links.js +50 -0
  75. package/dist/skill-links.js.map +1 -0
  76. package/dist/worktree-deps.d.ts +30 -0
  77. package/dist/worktree-deps.d.ts.map +1 -0
  78. package/dist/worktree-deps.js +128 -0
  79. package/dist/worktree-deps.js.map +1 -0
  80. package/dist/worktree.d.ts +220 -0
  81. package/dist/worktree.d.ts.map +1 -0
  82. package/dist/worktree.js +397 -0
  83. package/dist/worktree.js.map +1 -0
  84. package/package.json +53 -0
@@ -0,0 +1,397 @@
1
+ import { basename, dirname, join } from 'node:path';
2
+ import { realpath, stat } from 'node:fs/promises';
3
+ import { nodeGitRunner, checkoutRoot, originDefaultBranch, BRANCHES_DIR } from '@openagt/agent-data';
4
+ import { AGENT_BRANCH_PREFIX, isSafeAgentId, isAgentBranch, agentBranchName, agentIdFromWorktreeDir } from './branch-names.js';
5
+ import { DATA_BRANCH } from '@openagt/agent-data/names';
6
+ /**
7
+ * Git-worktree lifecycle for concurrent agents (#453/#735): give each agent its own
8
+ * checkout so N agents on one repo never fight over the working tree. Pure plumbing
9
+ * over the {@link GitRunner} seam: this module only knows how to add, list, name,
10
+ * remove, and prune worktrees, and to read what a retention decision needs.
11
+ */
12
+ /** The path an agent's worktree gets (#1580): `<repo>/.branches/<agent branch>`. */
13
+ export function worktreePath(repo, agentId) {
14
+ return join(repo, BRANCHES_DIR, agentBranchName(agentId));
15
+ }
16
+ async function nodeReaddir(path) {
17
+ const { readdir } = await import('node:fs/promises');
18
+ const entries = await readdir(path, { withFileTypes: true }).catch(() => []);
19
+ return entries.filter(entry => entry.isDirectory()).map(entry => entry.name);
20
+ }
21
+ /**
22
+ * Every checkout directory on disk (#1580): a directory under `.branches/` named as an agent
23
+ * branch. Only directories count — the same place holds the rename links (#1589), symlinks named
24
+ * as agent branches too, which are views, not checkouts. Forgiving: a missing root yields nothing.
25
+ */
26
+ export async function worktreeDirEntries(repo, readdir = nodeReaddir) {
27
+ const root = join(repo, BRANCHES_DIR);
28
+ const entries = [];
29
+ for (const name of await readdir(root).catch(() => [])) {
30
+ const agentId = agentIdFromWorktreeDir(name);
31
+ if (isAgentBranch(name) && isSafeAgentId(agentId))
32
+ entries.push({ path: join(root, name), agentId });
33
+ }
34
+ return entries;
35
+ }
36
+ /**
37
+ * The agent ids that have a worktree directory (#737/#1580). Forgiving — a project that never ran
38
+ * concurrently has no such dir and yields `[]`.
39
+ */
40
+ export async function listWorktreeDirs(repo, readdir = nodeReaddir) {
41
+ return [...new Set((await worktreeDirEntries(repo, readdir)).map(entry => entry.agentId))];
42
+ }
43
+ /** How long a new agent branch waits for origin's default branch to be fetched: Claude Code's own cap. */
44
+ export const FRESH_START_FETCH_MS = 5_000;
45
+ /**
46
+ * Where a new agent branch starts: origin's default branch, fetched first so it is current. Never
47
+ * the project's HEAD: that is whatever the user has checked out, unpushed work included, and a
48
+ * branch started there publishes that work when the agent's branch is pushed. The fetch is waited
49
+ * for {@link FRESH_START_FETCH_MS} at most, and one that fails (offline) or runs longer leaves the
50
+ * copy this clone already has; a fetch still running finishes on its own. A repository with no
51
+ * remote has no such branch: undefined, and git starts from HEAD, the only commit there is.
52
+ */
53
+ async function freshStart(repo, git) {
54
+ const start = await originDefaultBranch(repo, git);
55
+ if (!start)
56
+ return undefined;
57
+ const fetched = git(['fetch', '--quiet', '--no-write-fetch-head', 'origin', start.slice('origin/'.length)], repo).catch(() => { });
58
+ let timer;
59
+ const capped = new Promise(resolve => {
60
+ timer = setTimeout(resolve, FRESH_START_FETCH_MS);
61
+ timer.unref();
62
+ });
63
+ await Promise.race([fetched, capped]);
64
+ clearTimeout(timer);
65
+ return start;
66
+ }
67
+ /**
68
+ * Create a worktree for an agent on a fresh branch: `git worktree add --no-track -b <branch>
69
+ * <path> <base>`, the base origin's default branch unless the caller names one. No upstream:
70
+ * tracking writes the repository's shared `.git/config`, whose lock a running agent's own git
71
+ * command in another checkout may hold. Git makes the leaf dir (and any missing parents) itself. The
72
+ * `agentId` is validated as path-safe first so a caller can never traverse out of
73
+ * `.branches/`. Rejects on any git failure (a caller that wants a
74
+ * run needs its checkout, so failure must surface, not be swallowed).
75
+ */
76
+ export async function addWorktree(repo, opts, git = nodeGitRunner()) {
77
+ if (!isSafeAgentId(opts.agentId))
78
+ throw new Error(`unsafe agent id: ${opts.agentId}`);
79
+ const path = worktreePath(repo, opts.agentId);
80
+ const base = opts.base ?? (await freshStart(repo, git));
81
+ await git(['worktree', 'add', '--no-track', '-b', opts.branch, path, ...(base ? [base] : [])], repo);
82
+ return { path, branch: opts.branch };
83
+ }
84
+ /**
85
+ * Check an *existing* branch out into an agent's worktree (#762). Continuing an agent puts it back
86
+ * on the branch its work is already on, rather than branching again and stranding what it did
87
+ * last time. The branch as this clone has it; else origin's copy, as a new local branch with no
88
+ * upstream set, as in {@link addWorktree}; else, gone everywhere, a new branch where the agent's
89
+ * first one started: the base the caller names, as this clone has it or else as origin does, and
90
+ * with none, or one that is gone too, where a new agent branch starts ({@link freshStart}); the
91
+ * answer then says the branch was made again. The
92
+ * only branch the package deletes is one that held nothing past a commit the remote already had,
93
+ * so nothing of the agent's is lost. Anything git refuses — the branch checked out elsewhere, say —
94
+ * rejects, like {@link addWorktree}: a continued agent needs its checkout.
95
+ */
96
+ export async function attachWorktree(repo, opts, git = nodeGitRunner()) {
97
+ if (!isSafeAgentId(opts.agentId))
98
+ throw new Error(`unsafe agent id: ${opts.agentId}`);
99
+ const path = worktreePath(repo, opts.agentId);
100
+ const has = (ref) => git(['rev-parse', '--verify', '--quiet', `${ref}^{commit}`], repo).then(out => out.trim() !== '', () => false);
101
+ if (await has(`refs/heads/${opts.branch}`)) {
102
+ await git(['worktree', 'add', path, opts.branch], repo);
103
+ return { path, branch: opts.branch };
104
+ }
105
+ const theirs = `refs/remotes/origin/${opts.branch}`;
106
+ const starts = [theirs, ...(opts.base !== undefined ? [opts.base, `refs/remotes/origin/${opts.base}`] : [])];
107
+ let start;
108
+ for (const ref of starts)
109
+ if (start === undefined && (await has(ref)))
110
+ start = ref;
111
+ const again = start !== theirs;
112
+ start ??= await freshStart(repo, git);
113
+ await git(['worktree', 'add', '--no-track', '-b', opts.branch, path, ...(start ? [start] : [])], repo);
114
+ return { path, branch: opts.branch, ...(again ? { again: true } : {}) };
115
+ }
116
+ /**
117
+ * Every worktree registered for the repo (the main checkout included). Forgiving:
118
+ * a non-repo / git failure yields `[]` so a reconcile scan never throws.
119
+ */
120
+ export async function listWorktrees(repo, git = nodeGitRunner()) {
121
+ try {
122
+ return parseWorktreeList(await git(['worktree', 'list', '--porcelain'], repo));
123
+ }
124
+ catch {
125
+ return [];
126
+ }
127
+ }
128
+ /**
129
+ * Parse `git worktree list --porcelain`: blank-line-separated records, each with
130
+ * a `worktree <path>` line, a `HEAD <sha>` line, and either `branch refs/heads/...`
131
+ * or `detached`. Extra attributes (bare/locked/prunable) are ignored. Exported so
132
+ * the parsing is unit-testable without a real repo.
133
+ */
134
+ export function parseWorktreeList(porcelain) {
135
+ const entries = [];
136
+ for (const block of porcelain.split(/\n\s*\n/)) {
137
+ let path;
138
+ let head = '';
139
+ let branch;
140
+ for (const line of block.split('\n')) {
141
+ if (line.startsWith('worktree '))
142
+ path = line.slice('worktree '.length).trim();
143
+ else if (line.startsWith('HEAD '))
144
+ head = line.slice('HEAD '.length).trim();
145
+ else if (line.startsWith('branch '))
146
+ branch = line.slice('branch '.length).trim().replace(/^refs\/heads\//, '');
147
+ }
148
+ if (path)
149
+ entries.push({ path, head, ...(branch ? { branch } : {}) });
150
+ }
151
+ return entries;
152
+ }
153
+ /**
154
+ * Remove an agent's worktree. Tolerant of an already-gone / never-registered path so
155
+ * teardown stays idempotent (a caller may run it twice).
156
+ *
157
+ * Plain removal first: it refuses a checkout git considers unclean, which after the
158
+ * caller's {@link worktreeClean} check means a state we did not anticipate. Falling back to
159
+ * `--force` keeps teardown working (an ignored build artifact must not strand a
160
+ * worktree forever), but it says so, because forcing past unknown state is exactly
161
+ * how uncommitted work got deleted in the first place.
162
+ */
163
+ export async function removeWorktree(repo, path, git = nodeGitRunner()) {
164
+ try {
165
+ await git(['worktree', 'remove', path], repo);
166
+ return;
167
+ }
168
+ catch {
169
+ // Unclean by git's reckoning, already removed, or never registered: try forcing.
170
+ }
171
+ try {
172
+ await git(['worktree', 'remove', '--force', path], repo);
173
+ // stderr: on a CLI run stdout carries the JSON result, and this line would corrupt it.
174
+ console.error(`[branches] forced removal of worktree ${path} (git called it unclean)`);
175
+ }
176
+ catch (err) {
177
+ // Already removed, or never registered: nothing to do. A checkout still on disk is another
178
+ // matter (#1757): a caller told "removed" while it stands would drop its branch next.
179
+ if (await stat(path).then(() => true, () => false))
180
+ throw err;
181
+ }
182
+ }
183
+ /**
184
+ * Delete a branch that holds nothing (#1650). `-D`, because "merged" in git's eyes is the wrong
185
+ * test: the caller proved the tip is a commit the remote already has, which is the stronger fact.
186
+ * Forgiving: the checkout is already gone by the time this runs, and a branch that would not
187
+ * delete is a leftover name, not lost work. Says whether it went, so a caller names only the
188
+ * branches that are actually gone (#1757).
189
+ */
190
+ export async function deleteBranch(repo, branch, git = nodeGitRunner()) {
191
+ return git(['branch', '-D', branch], repo).then(() => true, () => false);
192
+ }
193
+ /**
194
+ * Whether `path` is the root of a git worktree — the main checkout's or a linked one (#1654).
195
+ *
196
+ * Git answers for any directory *inside* a repository, so a `.branches/<agent>` directory that is
197
+ * no longer a worktree (a checkout removed by hand, a marker written after teardown) makes every
198
+ * git command run in it act on the enclosing repo: the user's own checkout, on the user's own
199
+ * branch. The one question that tells the two apart is whether git's top level is this very
200
+ * directory. False on any failure, and the caller leaves the directory alone.
201
+ */
202
+ export async function isWorktreeRoot(path, git = nodeGitRunner()) {
203
+ try {
204
+ const top = (await git(['rev-parse', '--show-toplevel'], path)).trim();
205
+ if (!top)
206
+ return false;
207
+ // Both sides resolved: macOS's tmpdir sits behind the /var -> /private/var link, and git
208
+ // reports the resolved path.
209
+ return (await realpath(top)) === (await realpath(path));
210
+ }
211
+ catch {
212
+ return false;
213
+ }
214
+ }
215
+ /**
216
+ * The branch checked out at `path` when `path` is a worktree root (#1654), else `undefined` —
217
+ * the read every consumer of a `.branches/<agent>` directory wants, so none of them can take the
218
+ * enclosing repo's branch for the run's.
219
+ */
220
+ export async function worktreeBranch(path, git = nodeGitRunner()) {
221
+ return (await isWorktreeRoot(path, git)) ? currentBranch(path, git) : undefined;
222
+ }
223
+ /**
224
+ * The branch checked out at `path`, or `undefined` when detached / not a repo.
225
+ * Forgiving, like {@link listWorktrees}: callers use it to decide, not to fail.
226
+ */
227
+ export async function currentBranch(path, git = nodeGitRunner()) {
228
+ try {
229
+ const name = (await git(['rev-parse', '--abbrev-ref', 'HEAD'], path)).trim();
230
+ return name && name !== 'HEAD' ? name : undefined;
231
+ }
232
+ catch {
233
+ return undefined;
234
+ }
235
+ }
236
+ /**
237
+ * The project a directory belongs to (#1725): the checkout whose `.branches/` holds the agent
238
+ * checkouts. From inside an agent's checkout that is two levels up, by the layout every checkout
239
+ * is created with; from anywhere else it is the checkout itself. Read from the layout rather than
240
+ * from git's common dir, so a project that is itself a linked worktree, or a submodule, answers
241
+ * with the directory the caller registered. Rejects outside a repo.
242
+ */
243
+ export async function projectRoot(cwd, git = nodeGitRunner()) {
244
+ const checkout = await checkoutRoot(cwd, git);
245
+ const parent = dirname(checkout);
246
+ return basename(parent) === BRANCHES_DIR ? dirname(parent) : checkout;
247
+ }
248
+ /** A session name as the agent picks it: the charset the skill asks for. */
249
+ export function isSessionName(name) {
250
+ return /^[a-z0-9-]+$/.test(name);
251
+ }
252
+ /** How often a rename lost to a sibling naming the same thing at the same moment is retried. */
253
+ const NAME_ATTEMPTS = 3;
254
+ /**
255
+ * Name the session (#1725): rename the checkout's branch to `agent-<name>`. A rename, not a new
256
+ * branch, so the branch the checkout was born on is the branch it ends on and nothing is left
257
+ * behind to clean up. Only a branch the package minted is ever renamed: an agent that somehow
258
+ * runs in the user's own checkout must not rename `main`.
259
+ *
260
+ * A taken name gets a numeric suffix (`agent-<name>-2`, `-3`, …) rather than a refusal: the agent
261
+ * asked for a name, and the caller reads back the one it got. Taken means any local branch or
262
+ * any remote-tracking branch, so the later push does not land on someone else's branch — except
263
+ * the checkout's own branch, pushed or not, which is why asking again for the name the checkout
264
+ * already carries (suffixed or not) changes nothing. Two checkouts naming the same thing at the
265
+ * same moment race on the rename itself; the loser reads the branches again and takes the next
266
+ * free suffix.
267
+ */
268
+ export async function nameBranch(path, name, git = nodeGitRunner()) {
269
+ if (!isSessionName(name))
270
+ return { ok: false, reason: 'invalid-name' };
271
+ const wanted = `${AGENT_BRANCH_PREFIX}${name}`;
272
+ if (!(await isWorktreeRoot(path, git)))
273
+ return { ok: false, reason: 'not-a-worktree' };
274
+ const current = await currentBranch(path, git);
275
+ if (!current)
276
+ return { ok: false, reason: 'no-branch' };
277
+ if (!isAgentBranch(current))
278
+ return { ok: false, reason: 'not-an-agent-branch' };
279
+ for (let attempt = 1;; attempt++) {
280
+ const taken = await branchNames(path, git);
281
+ taken.delete(current);
282
+ // The data branch is nobody's session, whether or not this repo has it yet: `name data` gets `-2`.
283
+ taken.add(DATA_BRANCH);
284
+ let branch = wanted;
285
+ for (let n = 2; taken.has(branch); n++)
286
+ branch = `${wanted}-${n}`;
287
+ if (branch === current)
288
+ return { ok: true, branch };
289
+ try {
290
+ await git(['branch', '-m', current, branch], path);
291
+ return { ok: true, branch };
292
+ }
293
+ catch (err) {
294
+ if (attempt >= NAME_ATTEMPTS || !/already exists/.test(err instanceof Error ? err.message : String(err)))
295
+ throw err;
296
+ }
297
+ }
298
+ }
299
+ /** Every branch name the repo knows, local and remote-tracking, without the remote's prefix. */
300
+ async function branchNames(path, git) {
301
+ const out = await git(['for-each-ref', '--format=%(refname)', 'refs/heads/', 'refs/remotes/'], path);
302
+ const names = new Set();
303
+ for (const ref of out.split('\n')) {
304
+ const heads = ref.match(/^refs\/heads\/(.+)$/);
305
+ if (heads?.[1])
306
+ names.add(heads[1]);
307
+ const remotes = ref.match(/^refs\/remotes\/[^/]+\/(.+)$/);
308
+ if (remotes?.[1])
309
+ names.add(remotes[1]);
310
+ }
311
+ return names;
312
+ }
313
+ /**
314
+ * `git worktree prune`: drop administrative entries for worktree dirs a crash left
315
+ * behind. Never removes a live worktree, so it is always safe. Forgiving.
316
+ */
317
+ export async function pruneWorktrees(repo, git = nodeGitRunner()) {
318
+ try {
319
+ await git(['worktree', 'prune'], repo);
320
+ }
321
+ catch {
322
+ // Not a repo / nothing to prune: no-op.
323
+ }
324
+ }
325
+ /** A {@link SizeRunner} over `du -sk`: one process, and it does not follow the symlinked deps (#736). */
326
+ export function nodeSizeRunner() {
327
+ return path => new Promise((resolvePromise, rejectPromise) => {
328
+ void import('node:child_process').then(({ execFile }) => {
329
+ execFile('du', ['-sk', path], { timeout: 5_000 }, (err, stdout) => err ? rejectPromise(err) : resolvePromise(stdout));
330
+ });
331
+ });
332
+ }
333
+ /**
334
+ * A worktree's size on disk in bytes, or undefined when it cannot be read (#798). Best-effort by
335
+ * design: this only ever labels a "remove this" button, so a missing number costs nothing while a
336
+ * throw or a hang would cost the listing it sits in. `du` is absent on Windows, which reads as
337
+ * unknown like any other failure.
338
+ */
339
+ export async function worktreeSize(path, size = nodeSizeRunner()) {
340
+ try {
341
+ const kb = Number.parseInt((await size(path)).trim().split(/\s+/)[0] ?? '', 10);
342
+ return Number.isFinite(kb) ? kb * 1024 : undefined;
343
+ }
344
+ catch {
345
+ return undefined;
346
+ }
347
+ }
348
+ /**
349
+ * Whether a branch is on the remote, with the local tip already there.
350
+ *
351
+ * What a caller asks to say whether a branch's work is published yet.
352
+ *
353
+ * `git rev-parse` of the remote-tracking ref, then a merge-base check: the ref existing is not
354
+ * enough, because a branch pushed and then committed to again has a tip the remote has never seen.
355
+ * Reads only local refs (no fetch), so it is cheap enough to ask on every poll — the remote ref
356
+ * is written by the push this is checking for, which is what makes that sound.
357
+ *
358
+ * Anything unreadable answers `false`, and so does a repo with no remote configured.
359
+ */
360
+ export async function branchPushed(repo, branch, git = nodeGitRunner()) {
361
+ try {
362
+ const local = (await git(['rev-parse', '--verify', `refs/heads/${branch}`], repo)).trim();
363
+ const remote = (await git(['rev-parse', '--verify', `refs/remotes/origin/${branch}`], repo)).trim();
364
+ if (!local || !remote)
365
+ return false;
366
+ if (local === remote)
367
+ return true;
368
+ // The remote may be ahead (someone pushed on top): what matters is that our tip is in it.
369
+ await git(['merge-base', '--is-ancestor', local, remote], repo);
370
+ return true;
371
+ }
372
+ catch {
373
+ return false;
374
+ }
375
+ }
376
+ /**
377
+ * Whether the checkout has nothing uncommitted. A read, never a commit (#1638): the package
378
+ * commits nothing on an agent's behalf, so a checkout holding uncommitted work is one the caller
379
+ * keeps. Throws when git cannot answer, so the caller keeps the checkout rather than guessing.
380
+ */
381
+ export async function worktreeClean(path, git = nodeGitRunner()) {
382
+ return !(await git(['status', '--porcelain'], path)).trim();
383
+ }
384
+ /**
385
+ * Whether the repo has any remote configured at all: with none there is nowhere to publish a
386
+ * branch to, and a caller offers no push. Anything unreadable answers `false`, like
387
+ * {@link branchPushed}.
388
+ */
389
+ export async function repoHasRemote(repo, git = nodeGitRunner()) {
390
+ try {
391
+ return (await git(['remote'], repo)).trim().length > 0;
392
+ }
393
+ catch {
394
+ return false;
395
+ }
396
+ }
397
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../src/worktree.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@openagt/skill-branches",
3
+ "version": "0.0.1",
4
+ "description": "Branch management for coding agents: one git checkout per agent under .branches/, named as its branch, reclaimed once its work is on the remote.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/framework/the-framework.git",
9
+ "directory": "packages/skill-branches"
10
+ },
11
+ "type": "module",
12
+ "engines": {
13
+ "node": ">=22.12.0"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "bin/branches",
21
+ "SKILL.md"
22
+ ],
23
+ "bin": {
24
+ "branches": "bin/branches"
25
+ },
26
+ "framework": {
27
+ "branches": "branches"
28
+ },
29
+ "exports": {
30
+ "./package.json": "./package.json",
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./branch-names": {
36
+ "types": "./dist/branch-names.d.ts",
37
+ "default": "./dist/branch-names.js"
38
+ }
39
+ },
40
+ "dependencies": {
41
+ "@openagt/agent-data": "0.0.1"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.0.0",
45
+ "typescript": "^7.0.2"
46
+ },
47
+ "scripts": {
48
+ "build": "tsc -p tsconfig.build.json",
49
+ "typecheck": "tsc --noEmit",
50
+ "test": "tsc -p tsconfig.test.json && node --test --test-timeout=60000 'dist-test/**/*.test.js'",
51
+ "clean": "rm -rf dist dist-test"
52
+ }
53
+ }