@afokapu/atdd-flow 0.3.84 → 0.3.85

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afokapu/atdd-flow",
3
- "version": "0.3.84",
3
+ "version": "0.3.85",
4
4
  "description": "Filesystem-first Desk registry for projects, seats, tasks, threads, and handoffs.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/seats.ts CHANGED
@@ -255,7 +255,7 @@ async function taskCoordinatorBase(root: string, config: Project, task: Task, re
255
255
  const head = await runOutput(["git", "-C", coordinator.worktree, "rev-parse", "HEAD"]);
256
256
  if (head !== branchHead) throw new Error(`Coordinator ${coordinator.address} head is stale relative to ${branch}.`);
257
257
  } else {
258
- try { await assertBranchReady(mode, coordinator.worktree, branch); }
258
+ try { await assertBranchReady(mode, coordinator.worktree, branch, coordinator.role === "main"); }
259
259
  catch (error) { throw new Error(`Coordinator ${coordinator.address} is not ready: ${(error as Error).message}`); }
260
260
  }
261
261
  return { coordinator, branch, commit: branchHead };
@@ -331,7 +331,7 @@ async function spawnTaskDriver(root: string, config: Project, role: Role, name:
331
331
  const currentBranch = await branchCommit(mode, base.coordinator.worktree, coordinatorBase.branch);
332
332
  if (currentBranch !== coordinatorBase.commit) throw new Error(`Coordinator ${base.coordinator.address} advanced during driver provisioning.`);
333
333
  if (!baseArgument) {
334
- const current = await assertBranchReady(mode, base.coordinator.worktree, coordinatorBase.branch);
334
+ const current = await assertBranchReady(mode, base.coordinator.worktree, coordinatorBase.branch, base.coordinator.role === "main");
335
335
  if (current !== coordinatorBase.commit) throw new Error(`Coordinator ${base.coordinator.address} advanced during driver provisioning.`);
336
336
  }
337
337
  await atomicYaml(paths(root).seatFile(address), record);
package/src/vcs.ts CHANGED
@@ -103,7 +103,11 @@ export async function isAncestor(cwd: string, ancestor: string, descendant: stri
103
103
  catch { return false; }
104
104
  }
105
105
 
106
- export async function assertBranchReady(mode: VcsMode, cwd: string, branch: string) {
106
+ /**
107
+ * A branch is ready when its checkout is clean and at the branch tip. `allowDirtyParent` additionally accepts a Jujutsu working copy
108
+ * whose parent is exactly the branch tip with uncommitted changes (a migrated dirty primary); conflicts and any other lineage stay refused.
109
+ */
110
+ export async function assertBranchReady(mode: VcsMode, cwd: string, branch: string, allowDirtyParent = false) {
107
111
  if (mode === "git") {
108
112
  if (await runOutput(["git", "-C", cwd, "status", "--porcelain"])) throw new Error(`Worktree ${cwd} is dirty.`);
109
113
  const checkedOut = await runOutput(["git", "-C", cwd, "branch", "--show-current"]);
@@ -120,7 +124,7 @@ export async function assertBranchReady(mode: VcsMode, cwd: string, branch: stri
120
124
  runOutput(["jj", "log", "-r", "@-", "--no-graph", "-T", "commit_id"], cwd),
121
125
  runOutput(["jj", "diff", "-r", "@", "--name-only"], cwd),
122
126
  ]);
123
- if (parent === expected && !changed) return expected;
127
+ if (parent === expected && (!changed || allowDirtyParent)) return expected;
124
128
  }
125
129
  throw new Error(`Worktree ${cwd} is stale relative to ${branch}.`);
126
130
  }