borgmcp 0.9.35 → 0.9.37

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/sync.js CHANGED
@@ -1,40 +1,49 @@
1
1
  /**
2
2
  * `borg sync` — worktree lifecycle management subcommand (gh#33).
3
3
  *
4
- * Detects the current state of the operator's git worktree and either
5
- * advances it (fast-forward main, merge origin/main into a feature
6
- * branch, switch to main after a feature branch was merged + deleted
7
- * on origin) or refuses cleanly (dirty tree, network failure).
4
+ * Reconciled to the per-worktree `wt-<suffix>` branch model (PR-B,
5
+ * ruling ea643b33). Replaces the previous main-centric semantics
6
+ * ("idle = on main"; "post-merge = checkout main") under the approved
7
+ * gh#33 model `main` is NEVER a working branch in any worktree; it is
8
+ * purely the integration target. Every worktree works on a named
9
+ * `wt-<suffix>` branch and `borg sync` keeps it current with
10
+ * origin/main, returns to it after a feature branch merges, and absorbs
11
+ * upstream into an in-progress feature branch — never touching `main`
12
+ * as a checkout.
8
13
  *
9
- * Five lifecycle states:
10
- * 1. dirty — uncommitted changes present; refuse + tell
11
- * operator to commit/stash/restore first.
12
- * 2. idle — on main, clean, up-to-date with origin/main
13
- * (or fast-forwarded). Nothing to sync.
14
- * 3. mid-sprint-noop — on a feature branch; origin/main has not
15
- * advanced since the branch's merge base.
16
- * Nothing to do.
17
- * 4. mid-sprint-merge — on a feature branch; origin/main advanced.
18
- * Merge origin/main into the feature branch
19
- * (no rebase, per cube workflow rule (a)).
20
- * 5. post-merge — on a local branch whose remote was deleted
21
- * (typical post-PR-merge state); switch to
22
- * main and pull. Local merged branch is left
23
- * intact for the operator to delete manually.
14
+ * All git mutation/decision logic is delegated to
15
+ * `client/src/worktree-lifecycle.ts` (the seam PR-A added:
16
+ * `adoptWorktree`, `syncWorktree`, `cleanupMerged`, `isMerged`,
17
+ * `localBranchExists`) so the never-discard guards (dirty / unmerged
18
+ * HEAD / unmerged target wt- branch) and the args-array subprocess
19
+ * shape are shared, not duplicated.
24
20
  *
25
- * The subcommand mirrors `borg spawn`'s dependency-injection shape so
26
- * tests can stub every external interaction (git, filesystem, output).
21
+ * Lifecycle states:
22
+ * 1. dirty — uncommitted changes; refuse (never discard).
23
+ * 2. on-wt — on the per-worktree `wt-<suffix>` branch;
24
+ * fast-forward it to origin/main (ff-only).
25
+ * 3. on-main — on `main`/`master` (or detached at a merged
26
+ * point); adopt the `wt-<suffix>` branch
27
+ * (Q4: main is never a working branch).
28
+ * 4. feature-mid-sprint — on a feature branch not yet merged; absorb
29
+ * origin/main into it via `git merge --no-edit`
30
+ * (no rebase — cube workflow rule (a)) when
31
+ * origin/main advanced; else no-op.
32
+ * 5. feature-merged — on a feature branch fully merged into
33
+ * origin/main; return to `wt-<suffix>` and
34
+ * ANNOUNCE the prunable feature branch (prune
35
+ * only with `--prune`, Q3).
27
36
  *
28
- * Anti-features (intentional):
29
- * - No auto-stash, no auto-commit, no auto-discard on dirty tree.
30
- * Fail-loud per cube discipline.
31
- * - No force-push, no rebase, no --force-with-lease (cube rules a, b).
32
- * - No local-branch deletion (operator decides; sync just announces).
33
- * - No remote-branch deletion (Coordinator owns merge actions, not
34
- * this subcommand).
37
+ * Anti-features (intentional, unchanged):
38
+ * - No auto-stash / auto-commit / auto-discard on dirty tree.
39
+ * - No force-push, no rebase, no --force-with-lease.
40
+ * - No remote-branch deletion (Coordinator owns merge actions).
41
+ * - Local feature-branch deletion only on explicit `--prune` (Q3).
35
42
  */
36
43
  import { spawnSync } from 'node:child_process';
44
+ import { basename } from 'node:path';
37
45
  import chalk from 'chalk';
46
+ import { adoptWorktree, syncWorktree, cleanupMerged, isMerged, perWorktreeBranchName, } from './worktree-lifecycle.js';
38
47
  const defaultDeps = {
39
48
  runSync: (cmd, args, cwd) => {
40
49
  const r = spawnSync(cmd, args, { cwd, encoding: 'utf-8' });
@@ -48,111 +57,116 @@ const defaultDeps = {
48
57
  stderr: (line) => process.stderr.write(line),
49
58
  stdout: (line) => process.stdout.write(line),
50
59
  };
60
+ const DEFAULT_BRANCH = 'origin/main';
51
61
  // ------------------------------------------------------------------
52
- // State detection (pure of side effects beyond git reads)
62
+ // wt- branch resolution
53
63
  // ------------------------------------------------------------------
54
64
  /**
55
- * Detect the worktree's current lifecycle state. Read-only performs
56
- * a `git fetch origin` before measuring so origin/main reflects the
57
- * latest remote tip.
65
+ * Resolve the per-worktree `wt-` branch for the current checkout,
66
+ * DETERMINISTICALLY per worktree.
58
67
  *
59
- * Returns an error variant if the worktree is not a git repository
60
- * OR if the remote fetch fails.
68
+ * - current branch is already `wt-*` that is the branch.
69
+ * - otherwise derive `wt-<suffix>` from THIS worktree's directory
70
+ * basename minus the main worktree's (repo) basename prefix — the
71
+ * same `perWorktreeBranchName` derivation the spawn path uses, so
72
+ * the name matches what `borg assimilate --worktree` created.
73
+ *
74
+ * This must NOT list `git branch --list wt-*`: in linked worktrees the
75
+ * local branch namespace is SHARED across all siblings (gh#33 CR-v2
76
+ * blocker 32bc45da), so every drone's `wt-` branch is visible and a
77
+ * "single match" heuristic is never satisfied in a real multi-drone
78
+ * cube. The directory-derivation is unique per worktree and never
79
+ * ambiguous. The first `worktree <path>` line of
80
+ * `git worktree list --porcelain` is the main worktree (the repo dir);
81
+ * its basename is the prefix to strip. For an independent clone the
82
+ * main worktree IS this worktree, so the prefix == basename and the
83
+ * result is `wt-<basename>` (no strip) — consistent with PR-A's
84
+ * in-place adoption.
85
+ */
86
+ export function resolveWtBranch(runSync, cwd, currentBranch) {
87
+ if (currentBranch.startsWith('wt-'))
88
+ return currentBranch;
89
+ const top = runSync('git', ['rev-parse', '--show-toplevel'], cwd);
90
+ const thisDir = top.status === 0 ? top.stdout.trim() : cwd;
91
+ const wtList = runSync('git', ['worktree', 'list', '--porcelain'], cwd);
92
+ let mainDir = thisDir;
93
+ if (wtList.status === 0) {
94
+ const firstWorktreeLine = wtList.stdout
95
+ .split('\n')
96
+ .find((l) => l.startsWith('worktree '));
97
+ if (firstWorktreeLine)
98
+ mainDir = firstWorktreeLine.slice('worktree '.length).trim();
99
+ }
100
+ return perWorktreeBranchName(basename(thisDir), basename(mainDir));
101
+ }
102
+ /**
103
+ * Detect the worktree's lifecycle state. Read-only except for the
104
+ * `git fetch origin --prune` needed to measure against the latest tip.
61
105
  */
62
106
  export function detectState(deps) {
63
107
  const { runSync, cwd } = deps;
64
108
  const cwdValue = cwd();
65
- // (1) Confirm we're in a git repo.
66
- const topLevel = runSync('git', ['rev-parse', '--show-toplevel'], cwdValue);
67
- if (topLevel.status !== 0) {
68
- return {
69
- kind: 'error',
70
- reason: `not in a git repository (cwd: ${cwdValue})`,
71
- };
109
+ // (1) git repo?
110
+ if (runSync('git', ['rev-parse', '--show-toplevel'], cwdValue).status !== 0) {
111
+ return { kind: 'error', reason: `not in a git repository (cwd: ${cwdValue})` };
72
112
  }
73
- // (2) Dirty-tree check FIRST so we never act on a worktree with
74
- // uncommitted changes. `git status --porcelain` returns empty
75
- // string when the worktree is clean; any line is a dirty file.
113
+ // (2) dirty FIRST never act on uncommitted changes.
76
114
  const status = runSync('git', ['status', '--porcelain'], cwdValue);
77
115
  if (status.status !== 0) {
78
- return {
79
- kind: 'error',
80
- reason: `git status failed: ${status.stderr.trim()}`,
81
- };
116
+ return { kind: 'error', reason: `git status failed: ${status.stderr.trim()}` };
82
117
  }
83
- const dirtyLines = status.stdout
84
- .split('\n')
85
- .map((l) => l.trim())
86
- .filter((l) => l.length > 0);
87
- if (dirtyLines.length > 0) {
88
- return { kind: 'dirty', files: dirtyLines };
89
- }
90
- // (3) Current branch.
91
- const branch = runSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], cwdValue);
92
- if (branch.status !== 0) {
93
- return {
94
- kind: 'error',
95
- reason: `cannot resolve current branch: ${branch.stderr.trim()}`,
96
- };
118
+ const dirty = status.stdout.split('\n').map((l) => l.trim()).filter((l) => l.length > 0);
119
+ if (dirty.length > 0)
120
+ return { kind: 'dirty', files: dirty };
121
+ // (3) current branch.
122
+ const branchProbe = runSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], cwdValue);
123
+ if (branchProbe.status !== 0) {
124
+ return { kind: 'error', reason: `cannot resolve current branch: ${branchProbe.stderr.trim()}` };
97
125
  }
98
- const branchName = branch.stdout.trim();
99
- if (branchName === 'HEAD') {
100
- return {
101
- kind: 'error',
102
- reason: 'detached HEAD; cannot sync (checkout a branch first)',
103
- };
126
+ const branch = branchProbe.stdout.trim();
127
+ if (branch === 'HEAD') {
128
+ return { kind: 'error', reason: 'detached HEAD; run `borg assimilate` to adopt a wt- branch first' };
104
129
  }
105
- // (4) Fetch from origin so remote state is current. Failure here is
106
- // fatal — we can't reason about lifecycle without a fresh remote
107
- // view. --prune so the local view of remote-tracking branches
108
- // reflects deletions on origin (load-bearing for post-merge state).
130
+ // (4) fetch fatal on failure (can't reason about lifecycle offline).
109
131
  const fetch = runSync('git', ['fetch', 'origin', '--prune'], cwdValue);
110
132
  if (fetch.status !== 0) {
111
- return {
112
- kind: 'error',
113
- reason: `git fetch origin failed: ${fetch.stderr.trim()}`,
114
- };
133
+ return { kind: 'error', reason: `git fetch origin failed: ${fetch.stderr.trim()}` };
115
134
  }
116
- // (5) Current HEAD short sha.
117
- const head = runSync('git', ['rev-parse', '--short', 'HEAD'], cwdValue);
118
- const headSha = head.stdout.trim();
119
- // (6) Branch-class detection.
120
- if (branchName === 'main') {
121
- return { kind: 'idle', branch: 'main', head: headSha };
122
- }
123
- // (7) Feature-branch sub-states. Check whether origin/<branch>
124
- // still exists; if not, we're in post-merge state.
125
- const remoteBranchProbe = runSync('git', ['rev-parse', '--verify', '--quiet', `refs/remotes/origin/${branchName}`], cwdValue);
126
- if (remoteBranchProbe.status !== 0) {
127
- return { kind: 'post-merge', branch: branchName, mergedSha: headSha };
128
- }
129
- // (8) Remote branch exists — check whether origin/main advanced past
130
- // the merge-base with our feature branch.
131
- const mergeBase = runSync('git', ['merge-base', 'HEAD', 'origin/main'], cwdValue);
132
- if (mergeBase.status !== 0) {
133
- return {
134
- kind: 'error',
135
- reason: `cannot compute merge-base with origin/main: ${mergeBase.stderr.trim()}`,
136
- };
135
+ const wtBranch = resolveWtBranch(runSync, cwdValue, branch);
136
+ // (5) on the per-worktree wt- branch.
137
+ if (branch.startsWith('wt-')) {
138
+ return { kind: 'on-wt', branch, wtBranch: branch };
139
+ }
140
+ // (6) on main/master — Q4: never a working branch; adopt wt-.
141
+ if (branch === 'main' || branch === 'master') {
142
+ return { kind: 'on-main', branch, wtBranch };
137
143
  }
138
- const mergeBaseSha = mergeBase.stdout.trim();
139
- const originMainTip = runSync('git', ['rev-parse', 'origin/main'], cwdValue);
140
- if (mergeBaseSha === originMainTip.stdout.trim()) {
141
- return { kind: 'mid-sprint-noop', branch: branchName, head: headSha };
144
+ // (7) feature branch — merged vs mid-sprint.
145
+ // ASSUMPTION (gh#33 CR NIT 0e19637a): merged-detection keys off commit
146
+ // ancestry (`isMerged` = HEAD is an ancestor of origin/main), which
147
+ // holds for merge-commit / fast-forward integration. A squash- or
148
+ // rebase-merged PR leaves the feature tip a NON-ancestor → it would
149
+ // classify here as mid-sprint, not merged. That degrades safely
150
+ // (merge-back of origin/main, no discard), and this cube integrates
151
+ // via merge commits, so it is not triggered. If squash-merge is ever
152
+ // adopted, switch this to PR-merged-state detection.
153
+ if (isMerged(runSync, cwdValue, 'HEAD', DEFAULT_BRANCH)) {
154
+ return { kind: 'feature-merged', branch, wtBranch };
142
155
  }
143
- const commitCount = runSync('git', ['rev-list', '--count', `${mergeBaseSha}..origin/main`], cwdValue);
144
- const n = parseInt(commitCount.stdout.trim(), 10) || 0;
145
- return { kind: 'mid-sprint-merge', branch: branchName, commits: n };
156
+ // not merged mid-sprint. Count how far origin/main advanced past the
157
+ // merge-base so the message can report it (0 → no-op).
158
+ const mergeBase = runSync('git', ['merge-base', 'HEAD', DEFAULT_BRANCH], cwdValue);
159
+ const base = mergeBase.status === 0 ? mergeBase.stdout.trim() : '';
160
+ const count = runSync('git', ['rev-list', '--count', `${base}..${DEFAULT_BRANCH}`], cwdValue);
161
+ const commits = parseInt(count.stdout.trim(), 10) || 0;
162
+ return { kind: 'feature-mid-sprint', branch, wtBranch, commits };
146
163
  }
147
164
  // ------------------------------------------------------------------
148
- // State-action dispatcher (side-effecting)
165
+ // Orchestrator
149
166
  // ------------------------------------------------------------------
150
- /**
151
- * Run the `borg sync` flow. Returns the desired process exit code.
152
- */
153
- export async function runSync(deps = {}) {
167
+ export async function runSync(deps = {}, opts = { prune: false }) {
154
168
  const merged = { ...defaultDeps, ...deps };
155
- const { runSync: runSyncCmd, cwd, stderr, stdout } = merged;
169
+ const { runSync: run, cwd, stderr, stdout } = merged;
156
170
  const state = detectState(merged);
157
171
  if (state.kind === 'error') {
158
172
  stderr(chalk.red(`◼ borg sync: ${state.reason}\n`));
@@ -160,81 +174,113 @@ export async function runSync(deps = {}) {
160
174
  }
161
175
  if (state.kind === 'dirty') {
162
176
  stderr(chalk.yellow(`◼ Working tree has uncommitted changes.\n`));
163
- const preview = state.files.slice(0, 5);
164
- for (const line of preview) {
177
+ for (const line of state.files.slice(0, 5))
165
178
  stderr(chalk.gray(` ${line}\n`));
166
- }
167
- if (state.files.length > 5) {
179
+ if (state.files.length > 5)
168
180
  stderr(chalk.gray(` ... and ${state.files.length - 5} more\n`));
169
- }
170
- stderr(chalk.yellow(`◼ Commit, stash, or restore before running \`borg sync\`.\n`));
181
+ stderr(chalk.yellow(`◼ Commit, stash, or restore before running \`borg sync\`. Nothing was changed.\n`));
171
182
  return 1;
172
183
  }
173
- if (state.kind === 'idle') {
174
- const ahead = runSyncCmd('git', ['rev-list', '--count', 'HEAD..origin/main'], cwd());
175
- const n = parseInt(ahead.stdout.trim(), 10) || 0;
176
- if (n === 0) {
177
- stdout(chalk.blue(`◼ On main; up to date with origin (@${state.head}).\n`));
184
+ // on-wt: fast-forward the per-worktree branch to origin/main (ff-only,
185
+ // clean-gated, never merge/rebase). Delegates to syncWorktree.
186
+ if (state.kind === 'on-wt') {
187
+ const res = syncWorktree(run, cwd(), state.wtBranch, DEFAULT_BRANCH);
188
+ if (res.action === 'fast-forwarded') {
189
+ stdout(chalk.blue(`◼ On \`${state.wtBranch}\`; fast-forwarded to ${DEFAULT_BRANCH}.\n`));
178
190
  return 0;
179
191
  }
180
- const pull = runSyncCmd('git', ['pull', '--ff-only', 'origin', 'main'], cwd());
181
- if (pull.status !== 0) {
182
- stderr(chalk.red(`◼ borg sync: git pull --ff-only failed:\n${pull.stderr.trim()}\n`));
183
- return 1;
192
+ if (res.action === 'already-current') {
193
+ stdout(chalk.blue(`◼ On \`${state.wtBranch}\`; up to date with ${DEFAULT_BRANCH}.\n`));
194
+ return 0;
184
195
  }
185
- const newHead = runSyncCmd('git', ['rev-parse', '--short', 'HEAD'], cwd());
186
- stdout(chalk.blue(`◼ On main; fast-forwarded ${n} commit${n === 1 ? '' : 's'} → @${newHead.stdout.trim()}.\n`));
187
- return 0;
196
+ // skipped-diverged: the wt- branch has local commits not on origin/main.
197
+ stderr(chalk.yellow(`◼ ${res.message ?? 'sync skipped'}.\n`));
198
+ return 1;
188
199
  }
189
- if (state.kind === 'mid-sprint-noop') {
190
- stdout(chalk.blue(`◼ On \`${state.branch}\` @${state.head}; up to date with origin (no upstream changes).\n`));
191
- stdout(chalk.gray(`◼ Continue your sprint, or post REVIEW-READY when complete.\n`));
192
- return 0;
200
+ // on-main: adopt the wt- branch (Q4 move off main). adoptWorktree
201
+ // applies the dirty / unmerged-HEAD / unmerged-target guards.
202
+ if (state.kind === 'on-main') {
203
+ return adoptAndReport(state.wtBranch, run, cwd, stdout, stderr);
193
204
  }
194
- if (state.kind === 'mid-sprint-merge') {
195
- // Merge origin/main into feature branch. No rebase (cube rule a).
196
- const merge = runSyncCmd('git', ['merge', '--no-edit', 'origin/main'], cwd());
205
+ // feature-mid-sprint: absorb origin/main into the feature branch (no
206
+ // rebase). Leaves the drone on the feature branch to keep working.
207
+ if (state.kind === 'feature-mid-sprint') {
208
+ if (state.commits === 0) {
209
+ stdout(chalk.blue(`◼ On \`${state.branch}\` (feature branch); up to date with ${DEFAULT_BRANCH}.\n`));
210
+ stdout(chalk.gray(`◼ Continue your sprint, or post REVIEW-READY when complete.\n`));
211
+ return 0;
212
+ }
213
+ const merge = run('git', ['merge', '--no-edit', DEFAULT_BRANCH], cwd());
197
214
  if (merge.status !== 0) {
198
- stderr(chalk.red(`◼ borg sync: git merge origin/main failed (likely conflict). Resolve manually:\n${merge.stderr.trim()}\n`));
215
+ stderr(chalk.red(`◼ borg sync: git merge ${DEFAULT_BRANCH} failed (likely conflict). Resolve manually:\n${merge.stderr.trim()}\n`));
199
216
  return 1;
200
217
  }
201
- const newHead = runSyncCmd('git', ['rev-parse', '--short', 'HEAD'], cwd());
202
- stdout(chalk.blue(`◼ On \`${state.branch}\`; merged ${state.commits} commit${state.commits === 1 ? '' : 's'} from origin/main → @${newHead.stdout.trim()}.\n`));
218
+ stdout(chalk.blue(`◼ On \`${state.branch}\`; merged ${state.commits} commit${state.commits === 1 ? '' : 's'} from ${DEFAULT_BRANCH} (no rebase).\n`));
203
219
  stdout(chalk.gray(`◼ Re-run tests; continue your sprint.\n`));
204
220
  return 0;
205
221
  }
206
- if (state.kind === 'post-merge') {
207
- const checkout = runSyncCmd('git', ['checkout', 'main'], cwd());
208
- if (checkout.status !== 0) {
209
- stderr(chalk.red(`◼ borg sync: git checkout main failed:\n${checkout.stderr.trim()}\n`));
210
- return 1;
222
+ // feature-merged: the PR merged. Return to the wt- branch (adopt) and
223
+ // announce the prunable feature branch (prune only with --prune, Q3).
224
+ if (state.kind === 'feature-merged') {
225
+ const feature = state.branch;
226
+ const code = adoptAndReport(state.wtBranch, run, cwd, stdout, stderr, {
227
+ adoptedPrefix: `◼ \`${feature}\` is merged into ${DEFAULT_BRANCH};`,
228
+ });
229
+ if (code !== 0)
230
+ return code; // adoption blocked (dirty/unmerged target) — don't prune
231
+ // Now on the wt- branch — safe to prune/announce the merged feature.
232
+ const cleanup = cleanupMerged(run, cwd(), feature, DEFAULT_BRANCH, { prune: opts.prune });
233
+ if (cleanup.action === 'pruned') {
234
+ stdout(chalk.blue(`◼ Pruned merged branch \`${feature}\`.\n`));
211
235
  }
212
- const pull = runSyncCmd('git', ['pull', '--ff-only', 'origin', 'main'], cwd());
213
- if (pull.status !== 0) {
214
- stderr(chalk.red(`◼ borg sync: git pull --ff-only failed:\n${pull.stderr.trim()}\n`));
215
- return 1;
236
+ else if (cleanup.action === 'announced') {
237
+ stdout(chalk.gray(`◼ ${cleanup.message}\n`));
216
238
  }
217
- const newHead = runSyncCmd('git', ['rev-parse', '--short', 'HEAD'], cwd());
218
- stdout(chalk.blue(`◼ Branch \`${state.branch}\` was merged on origin; switched to main @${newHead.stdout.trim()}.\n`));
219
- stdout(chalk.gray(`◼ Local branch \`${state.branch}\` retained; delete with \`git branch -d ${state.branch}\` when ready.\n`));
220
239
  return 0;
221
240
  }
222
- // Exhaustiveness — unreachable.
241
+ // Exhaustiveness.
223
242
  const _exhaustive = state;
224
243
  stderr(chalk.red(`◼ borg sync: unhandled state\n`));
225
244
  return 1;
226
245
  }
227
246
  /**
228
- * Parse args passed after `borg sync`. No positional args, no flags
229
- * today; reject anything that looks like one to keep room for future
230
- * extensions (e.g., --dry-run).
247
+ * Shared adopt-the-wt-branch path for the on-main + feature-merged
248
+ * states. Surfaces the never-discard outcomes; returns the process exit
249
+ * code (0 adopted, 1 blocked/ambiguous).
250
+ */
251
+ function adoptAndReport(wtBranch, run, cwd, stdout, stderr, opts = {}) {
252
+ const res = adoptWorktree(run, cwd(), wtBranch, DEFAULT_BRANCH);
253
+ if (res.action === 'adopted') {
254
+ if (opts.adoptedPrefix) {
255
+ stdout(chalk.blue(`${opts.adoptedPrefix} switched to \`${wtBranch}\` at ${DEFAULT_BRANCH}.\n`));
256
+ }
257
+ else {
258
+ stdout(chalk.blue(`◼ On \`${wtBranch}\` at ${DEFAULT_BRANCH}.\n`));
259
+ }
260
+ return 0;
261
+ }
262
+ // skipped-dirty handled upstream (dirty state), but defensively surface.
263
+ stderr(chalk.yellow(`◼ borg sync: ${res.message ?? 'not adopted'}. Nothing was changed.\n`));
264
+ return 1;
265
+ }
266
+ /**
267
+ * Parse args after `borg sync`. Supports `--prune` (Q3: delete a merged
268
+ * feature branch after returning to the wt- branch). Rejects anything
269
+ * else to keep room for future flags.
231
270
  */
232
271
  export function parseSyncArgs(rawArgs) {
233
- if (rawArgs.length === 0)
234
- return { ok: true };
235
- return {
236
- ok: false,
237
- error: `unexpected argument: ${rawArgs[0]}. Usage: borg sync (no arguments)`,
238
- };
272
+ let prune = false;
273
+ for (const arg of rawArgs) {
274
+ if (arg === '--prune') {
275
+ prune = true;
276
+ }
277
+ else {
278
+ return {
279
+ ok: false,
280
+ error: `unexpected argument: ${arg}. Usage: borg sync [--prune]`,
281
+ };
282
+ }
283
+ }
284
+ return { ok: true, options: { prune } };
239
285
  }
240
286
  //# sourceMappingURL=sync.js.map
package/dist/sync.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,qBAAqB,GAEtB,MAAM,yBAAyB,CAAC;AA4BjC,MAAM,WAAW,GAAuB;IACtC,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3D,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;YACtB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE;SACvB,CAAC;IACJ,CAAC;IACD,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;IACxB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IAC5C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC,qEAAqE;AACrE,wBAAwB;AACxB,qEAAqE;AAErE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAgB,EAChB,GAAW,EACX,aAAqB;IAErB,IAAI,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,aAAa,CAAC;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,GAAG,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,IAAI,OAAO,GAAG,OAAO,CAAC;IACtB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM;aACpC,KAAK,CAAC,IAAI,CAAC;aACX,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1C,IAAI,iBAAiB;YAAE,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACtF,CAAC;IACD,OAAO,qBAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACrE,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAwB;IAClD,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC9B,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC;IAEvB,gBAAgB;IAChB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,iCAAiC,QAAQ,GAAG,EAAE,CAAC;IACjF,CAAC;IAED,sDAAsD;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,sBAAsB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IACjF,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAE7D,sBAAsB;IACtB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,kCAAkC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IAClG,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,kEAAkE,EAAE,CAAC;IACvG,CAAC;IAED,uEAAuE;IACvE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,4BAA4B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE5D,sCAAsC;IACtC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACrD,CAAC;IAED,8DAA8D;IAC9D,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC/C,CAAC;IAED,6CAA6C;IAC7C,uEAAuE;IACvE,oEAAoE;IACpE,kEAAkE;IAClE,oEAAoE;IACpE,gEAAgE;IAChE,oEAAoE;IACpE,qEAAqE;IACrE,qDAAqD;IACrD,IAAI,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACtD,CAAC;IACD,uEAAuE;IACvE,uDAAuD;IACvD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,KAAK,cAAc,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9F,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACnE,CAAC;AAED,qEAAqE;AACrE,eAAe;AACf,qEAAqE;AAErE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAiB,EAAE,EAAE,OAAoB,EAAE,KAAK,EAAE,KAAK,EAAE;IACrF,MAAM,MAAM,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IACrD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAElC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,2CAA2C,CAAC,CAAC,CAAC;QAClE,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;QAC9E,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7F,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,kFAAkF,CAAC,CAAC,CAAC;QACzG,OAAO,CAAC,CAAC;IACX,CAAC;IAED,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACrE,IAAI,GAAG,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;YACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,yBAAyB,cAAc,KAAK,CAAC,CAAC,CAAC;YACzF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,uBAAuB,cAAc,KAAK,CAAC,CAAC,CAAC;YACvF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,yEAAyE;QACzE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,cAAc,KAAK,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,oEAAoE;IACpE,8DAA8D;IAC9D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,CAAC;IAED,qEAAqE;IACrE,mEAAmE;IACnE,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,MAAM,wCAAwC,cAAc,KAAK,CAAC,CAAC,CAAC;YACtG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC,CAAC;YACpF,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QACxE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,cAAc,iDAAiD,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACpI,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,OAAO,UAAU,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,cAAc,iBAAiB,CAAC,CAAC,CAAC;QACtJ,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,sEAAsE;IACtE,sEAAsE;IACtE,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;QAC7B,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE;YACpE,aAAa,EAAE,OAAO,OAAO,qBAAqB,cAAc,GAAG;SACpE,CAAC,CAAC;QACH,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,yDAAyD;QACtF,qEAAqE;QACrE,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1F,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,4BAA4B,OAAO,OAAO,CAAC,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,kBAAkB;IAClB,MAAM,WAAW,GAAU,KAAK,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACrB,QAAgB,EAChB,GAAY,EACZ,GAAiB,EACjB,MAA2B,EAC3B,MAA2B,EAC3B,OAAmC,EAAE;IAErC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;IAChE,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,kBAAkB,QAAQ,SAAS,cAAc,KAAK,CAAC,CAAC,CAAC;QAClG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,QAAQ,SAAS,cAAc,KAAK,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,yEAAyE;IACzE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,GAAG,CAAC,OAAO,IAAI,aAAa,0BAA0B,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,CAAC;AACX,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAiB;IAC7C,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,wBAAwB,GAAG,8BAA8B;aACjE,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * gh#33 — worktree lifecycle as product behavior.
3
+ *
4
+ * Pure git-decision helpers behind an injected `runSync` seam (matching
5
+ * the `AssimilateDeps.runSync` shape), so every branch is unit-testable
6
+ * without a live repo. This module DECIDES + emits git command sequences;
7
+ * it never launches agents and never touches the cube API.
8
+ *
9
+ * Design spec: docs/superpowers/specs/2026-05-29-worktree-lifecycle-design.md
10
+ * Q-resolutions baked in (SPEC-APPROVED 3a80412d):
11
+ * Q1 branch naming — `wt-<suffix>` prefix-stripped, full-basename fallback.
12
+ * Q2 idle-sync — ff-only, clean-gated; never merge/rebase; never over dirty.
13
+ * Q3 post-merge — auto-return to wt-<basename>; ANNOUNCE the prunable
14
+ * merged branch, prune only when explicitly requested.
15
+ * Q4 uniform — no primary-worktree carve-out; main is never a working branch.
16
+ */
17
+ /** Injected subprocess runner — matches AssimilateDeps.runSync. */
18
+ export type RunSync = (cmd: string, args: string[], cwd?: string) => {
19
+ status: number | null;
20
+ stdout: string;
21
+ stderr: string;
22
+ };
23
+ /**
24
+ * Per-worktree branch name (Q1). Strips the repo basename prefix from the
25
+ * worktree dir basename for readability (`borg-mcp-codex-builder` ->
26
+ * `wt-codex-builder`); falls back to the full dir basename when there is
27
+ * no shared prefix (`myrepo-feature` under repo `otherrepo` ->
28
+ * `wt-myrepo-feature`).
29
+ */
30
+ export declare function perWorktreeBranchName(worktreeBasename: string, repoBasename: string): string;
31
+ /** True iff the working tree is clean (`git status --porcelain` empty). */
32
+ export declare function isCleanTree(runSync: RunSync, cwd: string): boolean;
33
+ export interface DirtyClassification {
34
+ staged: string[];
35
+ unstaged: string[];
36
+ untracked: string[];
37
+ /** Subset that are local-only config (e.g. `.claude/...`) — likely safe to set aside. */
38
+ localConfig: string[];
39
+ }
40
+ /**
41
+ * Classify a dirty tree into staged / unstaged / untracked buckets, and
42
+ * flag local-config files separately. The STAGED bucket is load-bearing:
43
+ * the live UNBLOCK case (b15894be) had a *staged* leftover diff that
44
+ * blocked `pull --ff-only`, which an unstaged-only check would miss.
45
+ */
46
+ export declare function classifyDirty(runSync: RunSync, cwd: string): DirtyClassification;
47
+ /** True iff `branch` is an ancestor of `ref` — i.e. a clean fast-forward target. */
48
+ export declare function isFastForward(runSync: RunSync, cwd: string, branch: string, ref: string): boolean;
49
+ /** True iff `branch`'s tip is an ancestor of `ref` — i.e. fully merged into it. */
50
+ export declare function isMerged(runSync: RunSync, cwd: string, branch: string, ref: string): boolean;
51
+ export interface SyncResult {
52
+ action: 'fast-forwarded' | 'already-current' | 'skipped-dirty' | 'skipped-diverged';
53
+ message?: string;
54
+ }
55
+ /**
56
+ * Idle-sync the current per-worktree branch to `ref` (Q2). NEVER discards
57
+ * work: dirty -> skipped-dirty (no mutation). Only fast-forwards (no
58
+ * merge/rebase): diverged -> skipped-diverged. The caller fetches first.
59
+ *
60
+ * `already-current` when the branch tip already equals `ref` (the common
61
+ * no-op case on every launch).
62
+ */
63
+ export declare function syncWorktree(runSync: RunSync, cwd: string, branch: string, ref: string): SyncResult;
64
+ export interface AdoptResult {
65
+ action: 'adopted' | 'blocked-unmerged' | 'blocked-target-unmerged' | 'skipped-dirty';
66
+ message?: string;
67
+ }
68
+ /** True iff a local branch named `branch` already exists. */
69
+ export declare function localBranchExists(runSync: RunSync, cwd: string, branch: string): boolean;
70
+ /**
71
+ * Migration (Q4/Q5/§4.5): bring a detached/stale worktree onto
72
+ * `wt-<basename>` at `ref`. Idempotent: re-running on an already-adopted
73
+ * clean worktree is a lossless reset to `ref`. Never discards:
74
+ * - dirty work tree -> skipped-dirty (surface)
75
+ * - current HEAD unmerged -> blocked-unmerged (surface)
76
+ * - TARGET `branch` exists with commits not on `ref` -> blocked-target-
77
+ * unmerged (surface). This is load-bearing: the switch uses `-C`
78
+ * (force-create/reset), which would ORPHAN commits on a pre-existing
79
+ * `wt-` branch. The HEAD-merged check alone misses this when the
80
+ * target branch != HEAD (e.g. on `main` while a prior `wt-x` holds
81
+ * committed-but-unmerged work). gh#33 CR-v2 blocker 078d1630.
82
+ */
83
+ export declare function adoptWorktree(runSync: RunSync, cwd: string, branch: string, ref: string): AdoptResult;
84
+ export interface CleanupResult {
85
+ action: 'pruned' | 'announced' | 'not-merged';
86
+ /** The feature branch this result concerns (for the announce message). */
87
+ branch?: string;
88
+ message?: string;
89
+ }
90
+ /**
91
+ * Post-merge cleanup (Q3): when `feature` is fully merged into `ref`,
92
+ * either ANNOUNCE it as prunable (default) or actually prune it with the
93
+ * safe `git branch -d` (which itself refuses to delete an unmerged
94
+ * branch — defense in depth against a stale local ref). Unmerged ->
95
+ * not-merged (never touched).
96
+ */
97
+ export declare function cleanupMerged(runSync: RunSync, cwd: string, feature: string, ref: string, opts?: {
98
+ prune: boolean;
99
+ }): CleanupResult;
100
+ //# sourceMappingURL=worktree-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree-lifecycle.d.ts","sourceRoot":"","sources":["../src/worktree-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,mEAAmE;AACnE,MAAM,MAAM,OAAO,GAAG,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,MAAM,KACT;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAM5F;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,yFAAyF;IACzF,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAkBhF;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEjG;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE5F;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,eAAe,GAAG,kBAAkB,CAAC;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAwBnG;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,SAAS,GAAG,kBAAkB,GAAG,yBAAyB,GAAG,eAAe,CAAC;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAExF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAyBrG;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,YAAY,CAAC;IAC9C,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAqB,GAC1C,aAAa,CAaf"}