@volter/supercode-orchestrator 0.5.57 → 0.5.58

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 (2) hide show
  1. package/board/ci.mjs +18 -11
  2. package/package.json +1 -1
package/board/ci.mjs CHANGED
@@ -4,7 +4,7 @@ import { spawnSync } from 'node:child_process';
4
4
  import { readFileSync, realpathSync, writeFileSync, renameSync, statSync } from 'node:fs';
5
5
  import { dirname, join, relative } from 'node:path';
6
6
  import { createHash } from 'node:crypto';
7
- import { branchCheckouts, checkoutOf, resolveWorkspace } from './workspace.mjs';
7
+ import { branchCheckouts, checkoutOf, isLocalWorkspace, resolveWorkspace } from './workspace.mjs';
8
8
 
9
9
  // GitHub is read through its REST API with Node's own fetch, not the gh binary: Node takes a World's trust bundle and
10
10
  // injector (NODE_EXTRA_CA_CERTS, NODE_OPTIONS), so a review World's GitHub twin answers it, where gh (Go) trusts only
@@ -128,17 +128,23 @@ export const candidatePullRequests = (ci) => ci?.prs ?? (ci?.pr ? [{ repository:
128
128
  // The repository a checkout declares (remote.origin.url), not where a URL rewrite sends its transport.
129
129
  const originOf = (path) => /(?:github\.com[:/])([^/]+\/[^/]+?)(?:\.git)?$/.exec(run('git', ['config', '--get', 'remote.origin.url'], path))?.[1] ?? null;
130
130
 
131
+ /** The card's checkout as its machine answers for it (path, repository, branch), and whether it is on this machine:
132
+ * git runs only in a checkout here, and another machine's is known by what its door said. */
131
133
  function repositoryWorkspace(board, id) {
132
134
  const task = board.db.prepare('SELECT t.*,c.subtask_of,c.workspace_anchor,c.machine FROM tasks t LEFT JOIN supercode_cards c ON c.task_id=t.id WHERE t.id=?').get(id);
133
135
  const parent = task?.subtask_of && board.db.prepare('SELECT t.*,c.workspace_anchor,c.machine FROM tasks t LEFT JOIN supercode_cards c ON c.task_id=t.id WHERE t.id=?').get(task.subtask_of);
134
136
  const workspace = task?.workspace_kind === 'scratch' ? parent : task;
135
- return workspace?.workspace_kind !== 'scratch' && workspace?.workspace_anchor ? resolveWorkspace(workspace, false).path : workspace?.workspace_kind !== 'scratch' ? workspace?.workspace_path : null;
137
+ if (!workspace || workspace.workspace_kind === 'scratch') return null;
138
+ const here = isLocalWorkspace(workspace);
139
+ if (workspace.workspace_anchor) return { ...resolveWorkspace(workspace, false), here };
140
+ return workspace.workspace_path ? { path: workspace.workspace_path, here } : null;
136
141
  }
137
142
 
138
143
  const pullRequestLists = new Map();
139
144
 
140
145
  function branchCheckout(board, id, repository, branch) {
141
146
  const task = board.db.prepare('SELECT c.machine FROM tasks t LEFT JOIN supercode_cards c ON c.task_id=t.id WHERE t.id=?').get(id);
147
+ if (!isLocalWorkspace(task ?? {})) return null;
142
148
  try { return checkoutOf(task?.machine, repository, branch)?.path ?? null; } catch { return null; }
143
149
  }
144
150
 
@@ -179,9 +185,9 @@ export function openReviewPullRequests(board, id) {
179
185
  const own = repositoryWorkspace(board, id);
180
186
  if (!own) return null;
181
187
  const task = board.db.prepare('SELECT branch_name FROM tasks WHERE id=?').get(id);
182
- const ownRepository = originOf(own);
188
+ const ownRepository = own.repository ?? (own.here ? originOf(own.path) : null);
183
189
  if (!ownRepository) return null;
184
- const current = task?.branch_name ? null : run('git', ['branch', '--show-current'], own);
190
+ const current = task?.branch_name ? null : own.branch ?? (own.here ? run('git', ['branch', '--show-current'], own.path) : null);
185
191
  let branch = task?.branch_name ?? (current || null);
186
192
  const registered = registeredBranches(board, id);
187
193
  const mine = (repository, head) => (repository === ownRepository && head === branch) || namedWorkBranch(id, head)
@@ -200,13 +206,13 @@ export function openReviewPullRequests(board, id) {
200
206
  }
201
207
  // The repository's default branch is not a work branch, declared or checked out (a card working in a `dir` on main).
202
208
  if (repository === ownRepository && branch) {
203
- const defaultBranch = list.items.find((pr) => pr.defaultBranch)?.defaultBranch ?? (() => { try { return run('git', ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'], own).replace(/^origin\//, ''); } catch { return null; } })();
209
+ const defaultBranch = list.items.find((pr) => pr.defaultBranch)?.defaultBranch ?? (() => { try { return run('git', ['symbolic-ref', '--quiet', '--short', 'refs/remotes/origin/HEAD'], own.path).replace(/^origin\//, ''); } catch { return null; } })();
204
210
  if (branch === defaultBranch) branch = null;
205
211
  }
206
212
  // a draft is not handed over yet: its review starts when it is marked ready; a PR to another base (main→prod) is a release, not the arc's work
207
213
  for (const pr of list.items) if (!pr.isCrossRepository && !pr.isDraft && pr.baseRefName === pr.defaultBranch && mine(repository, pr.headRefName)) prs.push({ url: pr.url, head: pr.headRefOid });
208
214
  }
209
- if (!prs.length) return branch ? null : { waits: `the card has no work branch (${task?.branch_name ? `it declares ${task.branch_name}, its repository's default` : current ? `its checkout ${own} is on ${current}, its repository's default` : `its checkout ${own} is on no branch`}): give it one with --branch, or open its PR from a wt/${id} branch` };
215
+ if (!prs.length) return branch ? null : { waits: `the card has no work branch (${task?.branch_name ? `it declares ${task.branch_name}, its repository's default` : current ? `its checkout ${own.path} is on ${current}, its repository's default` : `its checkout ${own.path} is on no branch`}): give it one with --branch, or open its PR from a wt/${id} branch` };
210
216
  return { pr: prs.map((p) => p.url), pr_head: prs.map((p) => p.head), branch };
211
217
  }
212
218
 
@@ -214,8 +220,9 @@ export function openReviewPullRequests(board, id) {
214
220
  * beyond its repository's default branch, locally or on origin, its checkout holds no uncommitted work, no PR was
215
221
  * ever opened from it, and it registered no other branch. Answers what its review reads instead of a diff, or null when the arc carries (or may carry) code. */
216
222
  export function noCodeChange(board, id) {
217
- const own = repositoryWorkspace(board, id);
218
- if (!own) return null;
223
+ const checkout = repositoryWorkspace(board, id);
224
+ if (!checkout?.here) return null;
225
+ const own = checkout.path;
219
226
  try {
220
227
  const repository = originOf(own);
221
228
  const task = board.db.prepare('SELECT branch_name FROM tasks WHERE id=?').get(id);
@@ -291,7 +298,7 @@ export function inspectCompletionEvidence(board, id, entry, payload = {}, stage
291
298
  if (stage === 'completion' || stage === 'acceptance') {
292
299
  const supplied = payload.commit ?? payload.metadata?.commit;
293
300
  if (supplied) {
294
- const path = repositoryWorkspace(board, id);
301
+ const path = repositoryWorkspace(board, id)?.path;
295
302
  if (!path) throw new Error('The named commit needs a resolved repository workspace.');
296
303
  Object.assign(state, { repository: originOf(path), commit: run('git', ['rev-parse', '--verify', `${supplied}^{commit}`], path) });
297
304
  }
@@ -351,9 +358,9 @@ function verifyPullRequest(board, id, entry, own, url, supplied, stage) {
351
358
  const repository = new URL(url).pathname.split('/').slice(1, 3).join('/');
352
359
  // An arc may change several repositories. A PR is read from GitHub; its pushed head is the reviewed one. The
353
360
  // card's own checkout, and this machine's checkout of the PR's branch when it keeps one, must also hold that head
354
- // with nothing uncommitted.
361
+ // with nothing uncommitted. A card on another machine is reviewed at its pushed head: its checkout is not read from here.
355
362
  const observed = readPullRequest(url);
356
- const path = originOf(own) === repository && run('git', ['branch', '--show-current'], own) === observed.headRefName ? own : branchCheckout(board, id, repository, observed.headRefName);
363
+ const path = !own.here ? null : originOf(own.path) === repository && run('git', ['branch', '--show-current'], own.path) === observed.headRefName ? own.path : branchCheckout(board, id, repository, observed.headRefName);
357
364
  // A PR merged before its review (an outage fix landed first) is still reviewed: its head is fixed for good, so the
358
365
  // verdict is recorded on that head, and nothing about a worktree or its base can move under it any more.
359
366
  const merged = observed.state === 'MERGED';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-orchestrator",
3
- "version": "0.5.57",
3
+ "version": "0.5.58",
4
4
  "type": "module",
5
5
  "description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
6
6
  "exports": {