@tokenfactory/acc-runner 0.41.7 → 0.43.0
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/README.md +87 -4
- package/dist/acc.d.ts +3 -0
- package/dist/acc.d.ts.map +1 -0
- package/dist/acc.js +21 -0
- package/dist/acc.js.map +1 -0
- package/dist/cli-name.d.ts +29 -0
- package/dist/cli-name.d.ts.map +1 -0
- package/dist/cli-name.js +17 -0
- package/dist/cli-name.js.map +1 -0
- package/dist/cli.d.ts +20 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +45 -289
- package/dist/cli.js.map +1 -1
- package/dist/engines/account-probe.d.ts +24 -0
- package/dist/engines/account-probe.d.ts.map +1 -1
- package/dist/engines/account-probe.js +18 -1
- package/dist/engines/account-probe.js.map +1 -1
- package/dist/keychain.d.ts +17 -0
- package/dist/keychain.d.ts.map +1 -1
- package/dist/keychain.js +36 -0
- package/dist/keychain.js.map +1 -1
- package/dist/login.d.ts +45 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +91 -4
- package/dist/login.js.map +1 -1
- package/dist/machine-capabilities/index.d.ts +21 -0
- package/dist/machine-capabilities/index.d.ts.map +1 -0
- package/dist/machine-capabilities/index.js +21 -0
- package/dist/machine-capabilities/index.js.map +1 -0
- package/dist/machine-capabilities/probe.d.ts +61 -0
- package/dist/machine-capabilities/probe.d.ts.map +1 -0
- package/dist/machine-capabilities/probe.js +243 -0
- package/dist/machine-capabilities/probe.js.map +1 -0
- package/dist/machine-capabilities/redact.d.ts +42 -0
- package/dist/machine-capabilities/redact.d.ts.map +1 -0
- package/dist/machine-capabilities/redact.js +160 -0
- package/dist/machine-capabilities/redact.js.map +1 -0
- package/dist/machine-capabilities/report.d.ts +107 -0
- package/dist/machine-capabilities/report.d.ts.map +1 -0
- package/dist/machine-capabilities/report.js +211 -0
- package/dist/machine-capabilities/report.js.map +1 -0
- package/dist/machine-capabilities/types.d.ts +115 -0
- package/dist/machine-capabilities/types.d.ts.map +1 -0
- package/dist/machine-capabilities/types.js +11 -0
- package/dist/machine-capabilities/types.js.map +1 -0
- package/dist/migration-seq-guard.d.ts +78 -0
- package/dist/migration-seq-guard.d.ts.map +1 -0
- package/dist/migration-seq-guard.js +304 -0
- package/dist/migration-seq-guard.js.map +1 -0
- package/dist/node-version.d.ts +132 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +318 -0
- package/dist/node-version.js.map +1 -0
- package/dist/prepr-gate.d.ts +120 -0
- package/dist/prepr-gate.d.ts.map +1 -1
- package/dist/prepr-gate.js +202 -3
- package/dist/prepr-gate.js.map +1 -1
- package/dist/program.d.ts +16 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +355 -0
- package/dist/program.js.map +1 -0
- package/dist/runtime/review-chunking.d.ts +101 -0
- package/dist/runtime/review-chunking.d.ts.map +1 -0
- package/dist/runtime/review-chunking.js +192 -0
- package/dist/runtime/review-chunking.js.map +1 -0
- package/dist/runtime/review-diff.d.ts +30 -0
- package/dist/runtime/review-diff.d.ts.map +1 -0
- package/dist/runtime/review-diff.js +59 -0
- package/dist/runtime/review-diff.js.map +1 -0
- package/dist/runtime/reviewer.d.ts +40 -19
- package/dist/runtime/reviewer.d.ts.map +1 -1
- package/dist/runtime/reviewer.js +252 -51
- package/dist/runtime/reviewer.js.map +1 -1
- package/dist/serve-scope/command.d.ts +12 -0
- package/dist/serve-scope/command.d.ts.map +1 -0
- package/dist/serve-scope/command.js +89 -0
- package/dist/serve-scope/command.js.map +1 -0
- package/dist/serve-scope/index.d.ts +130 -0
- package/dist/serve-scope/index.d.ts.map +1 -0
- package/dist/serve-scope/index.js +148 -0
- package/dist/serve-scope/index.js.map +1 -0
- package/dist/task-runner.d.ts +11 -0
- package/dist/task-runner.d.ts.map +1 -1
- package/dist/task-runner.js +69 -0
- package/dist/task-runner.js.map +1 -1
- package/dist/user-auth/device-login.d.ts +47 -0
- package/dist/user-auth/device-login.d.ts.map +1 -0
- package/dist/user-auth/device-login.js +189 -0
- package/dist/user-auth/device-login.js.map +1 -0
- package/dist/user-auth/liveness.d.ts +27 -0
- package/dist/user-auth/liveness.d.ts.map +1 -0
- package/dist/user-auth/liveness.js +128 -0
- package/dist/user-auth/liveness.js.map +1 -0
- package/dist/user-auth/session.d.ts +82 -0
- package/dist/user-auth/session.d.ts.map +1 -0
- package/dist/user-auth/session.js +172 -0
- package/dist/user-auth/session.js.map +1 -0
- package/dist/user-cli/chat.d.ts +44 -0
- package/dist/user-cli/chat.d.ts.map +1 -0
- package/dist/user-cli/chat.js +199 -0
- package/dist/user-cli/chat.js.map +1 -0
- package/dist/user-cli/client.d.ts +20 -0
- package/dist/user-cli/client.d.ts.map +1 -0
- package/dist/user-cli/client.js +60 -0
- package/dist/user-cli/client.js.map +1 -0
- package/dist/user-cli/tasks.d.ts +37 -0
- package/dist/user-cli/tasks.d.ts.map +1 -0
- package/dist/user-cli/tasks.js +131 -0
- package/dist/user-cli/tasks.js.map +1 -0
- package/dist/watch.d.ts +8 -0
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +28 -0
- package/dist/watch.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIG-SEQ-GUARD — re-validate a branch's migration sequence against a FRESHLY
|
|
3
|
+
* FETCHED integration head, immediately before push.
|
|
4
|
+
*
|
|
5
|
+
* The recurring failure it closes (0310 → 0314 → 0315, two collisions in 24h):
|
|
6
|
+
* an agent computes its next-free migration seq at worktree-FORK time — the max
|
|
7
|
+
* of `supabase/migrations/` in the fork snapshot plus the applied ledger. That
|
|
8
|
+
* number is correct when it is chosen and stale by the time the branch pushes,
|
|
9
|
+
* because a sibling migration merged into `acc/integration` in between and took
|
|
10
|
+
* it. `scripts/ci/migration-lint.mjs` catches the collision at PR time, but only
|
|
11
|
+
* after the whole run is spent: the task rework-loops for a rename it could have
|
|
12
|
+
* done itself. Two migration tasks dispatched concurrently hit it every time.
|
|
13
|
+
*
|
|
14
|
+
* MIGFIX-01 (prepr-gate.ts) already auto-renumbers, but it reads the SAME stale
|
|
15
|
+
* worktree snapshot, so it recomputes exactly the seq the sibling took. The fix
|
|
16
|
+
* is not a better computation — it is a fresher input. So right before push:
|
|
17
|
+
*
|
|
18
|
+
* 1. `git fetch <remote> <integration>` — a real network read, not the fork's
|
|
19
|
+
* remote-tracking ref.
|
|
20
|
+
* 2. Read the migration seqs present on that fresh head (`git ls-tree`), and
|
|
21
|
+
* union them with the live `acc.applied_migrations` roster when the caller
|
|
22
|
+
* has one.
|
|
23
|
+
* 3. If this branch's NEW migration no longer holds a free seq (its number is
|
|
24
|
+
* at or below that fresh baseline), hand the roster to
|
|
25
|
+
* `migration-lint.mjs --renumber --baseline-seqs …`, which already rewrites
|
|
26
|
+
* the filename, the `record_migration_applied` self-record, the verify
|
|
27
|
+
* RAISE messages and every sibling test that reads the file by path.
|
|
28
|
+
* 4. Commit the rename so the push carries it, and report the move so the
|
|
29
|
+
* caller can emit an event.
|
|
30
|
+
*
|
|
31
|
+
* FAIL-OPEN by construction. Every step that touches the network or git is
|
|
32
|
+
* best-effort: an unreachable remote, a missing ref, a renumber that changed
|
|
33
|
+
* nothing — each returns a `ran: false` result with a reason, and the push
|
|
34
|
+
* proceeds exactly as it does today. The guard may only ever turn a PR that CI
|
|
35
|
+
* would reject into one it accepts; it must never be the reason a push fails.
|
|
36
|
+
*
|
|
37
|
+
* Two deliberate non-behaviours:
|
|
38
|
+
* • It does NOT act on a forward GAP (a seq ABOVE the fresh baseline + 1).
|
|
39
|
+
* A gap is MIGFIX-01's job at fork time, and after a sibling merges, the
|
|
40
|
+
* local `supabase/migrations/` is legitimately behind the remote — closing
|
|
41
|
+
* "gaps" against a tree that is missing files would renumber healthy
|
|
42
|
+
* branches. Only a seq that is provably TAKEN is moved.
|
|
43
|
+
* • It commits, it never amends. A rework branch's history is already pushed;
|
|
44
|
+
* amending it would force a non-fast-forward push. Same posture as
|
|
45
|
+
* MIGFIX-01's `defaultCommitRenumbered`.
|
|
46
|
+
*/
|
|
47
|
+
import path from "node:path";
|
|
48
|
+
import { execa } from "execa";
|
|
49
|
+
import { buildEnv } from "./bin-resolve.js";
|
|
50
|
+
/** Kill switch. Set to `0`/`false` to skip the pre-push re-validation entirely. */
|
|
51
|
+
export const SEQ_GUARD_ENV = "ACC_MIGRATION_SEQ_GUARD";
|
|
52
|
+
const MIGRATIONS_DIR = "supabase/migrations";
|
|
53
|
+
/**
|
|
54
|
+
* The numeric sequence prefix of a migration path (`…/0315_acc_x.sql` → 315),
|
|
55
|
+
* or null when the filename does not carry one. Mirrors `parseSeq` in
|
|
56
|
+
* scripts/ci/migration-lint.mjs — the two must agree on what counts as a
|
|
57
|
+
* migration, so both accept `_` and `-` after the digits.
|
|
58
|
+
*/
|
|
59
|
+
export function migrationSeq(file) {
|
|
60
|
+
const base = String(file).split(/[\\/]/).pop() ?? "";
|
|
61
|
+
const m = /^(\d+)[_-].+\.sql$/i.exec(base);
|
|
62
|
+
if (!m)
|
|
63
|
+
return null;
|
|
64
|
+
const n = parseInt(m[1], 10);
|
|
65
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
66
|
+
}
|
|
67
|
+
/** Whether the guard is enabled. ON by default; `0`/`false`/`no` turns it off. */
|
|
68
|
+
export function seqGuardEnabled(env = process.env) {
|
|
69
|
+
const raw = env[SEQ_GUARD_ENV]?.trim().toLowerCase();
|
|
70
|
+
if (raw === undefined || raw === "")
|
|
71
|
+
return true;
|
|
72
|
+
return !(raw === "0" || raw === "false" || raw === "no" || raw === "off");
|
|
73
|
+
}
|
|
74
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
75
|
+
// Default I/O (every one is injectable; the unit suite never shells out)
|
|
76
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
77
|
+
async function defaultFetchRef(workdir, remote, branch) {
|
|
78
|
+
// A single-branch fetch, not `--all`: this runs on the push hot path and the
|
|
79
|
+
// only ref whose freshness matters is the integration head.
|
|
80
|
+
const res = await execa("git", ["fetch", "--quiet", remote, branch], {
|
|
81
|
+
cwd: workdir,
|
|
82
|
+
env: buildEnv(),
|
|
83
|
+
reject: false,
|
|
84
|
+
});
|
|
85
|
+
if (res.exitCode !== 0) {
|
|
86
|
+
throw new Error(`git fetch ${remote} ${branch} exited ${res.exitCode ?? "signal"}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function defaultListRemoteMigrations(workdir, ref) {
|
|
90
|
+
const res = await execa("git", ["ls-tree", "-r", "--name-only", ref, "--", MIGRATIONS_DIR], { cwd: workdir, env: buildEnv(), reject: false });
|
|
91
|
+
if (res.exitCode !== 0)
|
|
92
|
+
return null;
|
|
93
|
+
return (res.stdout ?? "")
|
|
94
|
+
.split("\n")
|
|
95
|
+
.map((s) => s.trim())
|
|
96
|
+
.filter((s) => s.toLowerCase().endsWith(".sql"));
|
|
97
|
+
}
|
|
98
|
+
async function defaultListAddedMigrations(workdir, baseRef) {
|
|
99
|
+
if (!baseRef)
|
|
100
|
+
return [];
|
|
101
|
+
// `--diff-filter=A` (added only): a MODIFIED published migration must never be
|
|
102
|
+
// renumbered — that is the forward-only violation the linter already rejects.
|
|
103
|
+
const res = await execa("git", ["diff", "--name-only", "--diff-filter=A", `${baseRef}...HEAD`, "--", MIGRATIONS_DIR], { cwd: workdir, env: buildEnv(), reject: false });
|
|
104
|
+
if (res.exitCode !== 0)
|
|
105
|
+
return [];
|
|
106
|
+
return (res.stdout ?? "")
|
|
107
|
+
.split("\n")
|
|
108
|
+
.map((s) => s.trim())
|
|
109
|
+
.filter((s) => s.toLowerCase().endsWith(".sql"));
|
|
110
|
+
}
|
|
111
|
+
async function defaultRunRenumber(workdir, files, baselineSeqs) {
|
|
112
|
+
const script = path.join(workdir, "scripts", "ci", "migration-lint.mjs");
|
|
113
|
+
const args = ["--renumber"];
|
|
114
|
+
if (baselineSeqs.length > 0)
|
|
115
|
+
args.push("--baseline-seqs", baselineSeqs.join(","));
|
|
116
|
+
// `process.execPath`, not a bare "node": the runner may be launched by
|
|
117
|
+
// launchd with a PATH that has no node at all, and a silently-unspawnable
|
|
118
|
+
// renumber reads exactly like a clean no-op (empty output, clean tree).
|
|
119
|
+
const res = await execa(process.execPath, [script, ...args, ...files], {
|
|
120
|
+
cwd: workdir,
|
|
121
|
+
env: buildEnv(),
|
|
122
|
+
reject: false,
|
|
123
|
+
});
|
|
124
|
+
// `reject: false` resolves with the failure rather than throwing, so a spawn
|
|
125
|
+
// error (no node on PATH) arrives as a result whose exit code is not 0 and
|
|
126
|
+
// whose explanation lives on `shortMessage` — present at runtime on the
|
|
127
|
+
// failure shape, absent from execa's success type.
|
|
128
|
+
const shortMessage = res.shortMessage;
|
|
129
|
+
const spawnFailure = res.exitCode === 0 ? "" : `\n[exit ${res.exitCode ?? "signal"}] ${shortMessage ?? ""}`;
|
|
130
|
+
return { output: `${res.stdout ?? ""}\n${res.stderr ?? ""}${spawnFailure}`.trim() };
|
|
131
|
+
}
|
|
132
|
+
async function defaultIsDirty(workdir) {
|
|
133
|
+
const res = await execa("git", ["status", "--porcelain"], {
|
|
134
|
+
cwd: workdir,
|
|
135
|
+
env: buildEnv(),
|
|
136
|
+
reject: false,
|
|
137
|
+
});
|
|
138
|
+
return (res.stdout ?? "").trim().length > 0;
|
|
139
|
+
}
|
|
140
|
+
async function defaultCommit(workdir, message) {
|
|
141
|
+
await execa("git", ["add", "-A"], { cwd: workdir, env: buildEnv(), reject: false });
|
|
142
|
+
await execa("git", ["commit", "-m", message], {
|
|
143
|
+
cwd: workdir,
|
|
144
|
+
env: buildEnv(),
|
|
145
|
+
reject: false,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
149
|
+
// The guard
|
|
150
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
151
|
+
const OUTPUT_TAIL = 2_000;
|
|
152
|
+
/**
|
|
153
|
+
* Re-validate this branch's NEW migration seq against a freshly-fetched
|
|
154
|
+
* integration head and auto-renumber it when a sibling has since taken the
|
|
155
|
+
* number. Returns what happened; NEVER throws (a crash inside the guard is
|
|
156
|
+
* reported as `renumber-failed` and the push proceeds).
|
|
157
|
+
*/
|
|
158
|
+
export async function revalidateMigrationSeq(workdir, opts, deps = {}) {
|
|
159
|
+
const env = deps.env ?? process.env;
|
|
160
|
+
if (!seqGuardEnabled(env)) {
|
|
161
|
+
return {
|
|
162
|
+
renumbered: false,
|
|
163
|
+
skipped: "disabled",
|
|
164
|
+
detail: `${SEQ_GUARD_ENV} disables the pre-push migration seq re-validation`,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (!opts.baseRef) {
|
|
168
|
+
return {
|
|
169
|
+
renumbered: false,
|
|
170
|
+
skipped: "no-base-ref",
|
|
171
|
+
detail: "no base ref — cannot tell which migrations this branch added",
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const remote = opts.remote ?? "origin";
|
|
175
|
+
const listAdded = deps.listAddedMigrations ?? defaultListAddedMigrations;
|
|
176
|
+
try {
|
|
177
|
+
// Cheapest check first: a task that adds no migration never fetches. This is
|
|
178
|
+
// the overwhelming majority of pushes, and the whole happy path stays a
|
|
179
|
+
// single `git diff`.
|
|
180
|
+
const added = (await listAdded(workdir, opts.baseRef)).filter((f) => migrationSeq(f) !== null);
|
|
181
|
+
if (added.length === 0) {
|
|
182
|
+
return {
|
|
183
|
+
renumbered: false,
|
|
184
|
+
skipped: "no-new-migrations",
|
|
185
|
+
detail: "branch adds no migration — seq re-validation not needed",
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const fetchRef = deps.fetchRef ?? defaultFetchRef;
|
|
189
|
+
const listRemote = deps.listRemoteMigrations ?? defaultListRemoteMigrations;
|
|
190
|
+
// The fetch is the entire point: the fork-time remote-tracking ref is what
|
|
191
|
+
// produced the stale seq in the first place.
|
|
192
|
+
let fetched = true;
|
|
193
|
+
try {
|
|
194
|
+
await fetchRef(workdir, remote, opts.integrationBranch);
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
fetched = false;
|
|
198
|
+
}
|
|
199
|
+
// Prefer FETCH_HEAD (what this fetch just wrote) over the remote-tracking
|
|
200
|
+
// ref, which a fetch refspec may not have updated. Fall back to the
|
|
201
|
+
// tracking ref so a failed fetch can still be checked against whatever the
|
|
202
|
+
// worktree already knows.
|
|
203
|
+
const refs = fetched
|
|
204
|
+
? ["FETCH_HEAD", `${remote}/${opts.integrationBranch}`]
|
|
205
|
+
: [`${remote}/${opts.integrationBranch}`];
|
|
206
|
+
let remoteFiles = null;
|
|
207
|
+
for (const ref of refs) {
|
|
208
|
+
remoteFiles = await listRemote(workdir, ref);
|
|
209
|
+
if (remoteFiles && remoteFiles.length > 0)
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
if (!remoteFiles || remoteFiles.length === 0) {
|
|
213
|
+
return {
|
|
214
|
+
renumbered: false,
|
|
215
|
+
skipped: "no-remote-seqs",
|
|
216
|
+
detail: `could not read ${MIGRATIONS_DIR} on a fresh ${remote}/${opts.integrationBranch} ` +
|
|
217
|
+
`(fetch ${fetched ? "ok" : "failed"}) — seq left as-is`,
|
|
218
|
+
remoteMaxSeq: null,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// The baseline: everything claimed OUTSIDE this worktree. The remote head's
|
|
222
|
+
// seqs, plus the live ledger when the caller could read it (a migration can
|
|
223
|
+
// be applied before its file merges).
|
|
224
|
+
const claimed = new Set();
|
|
225
|
+
for (const f of remoteFiles) {
|
|
226
|
+
const n = migrationSeq(f);
|
|
227
|
+
if (n !== null)
|
|
228
|
+
claimed.add(n);
|
|
229
|
+
}
|
|
230
|
+
for (const n of opts.appliedSeqs ?? []) {
|
|
231
|
+
if (Number.isFinite(n) && n > 0)
|
|
232
|
+
claimed.add(Math.trunc(n));
|
|
233
|
+
}
|
|
234
|
+
const baselineSeqs = [...claimed].sort((a, b) => a - b);
|
|
235
|
+
const remoteMaxSeq = baselineSeqs.length > 0 ? baselineSeqs[baselineSeqs.length - 1] : null;
|
|
236
|
+
// Stale = at or below the fresh baseline: either the exact number a sibling
|
|
237
|
+
// took, or one behind it. A seq ABOVE the baseline is left alone (see the
|
|
238
|
+
// module header — a forward gap is MIGFIX-01's call, not the guard's).
|
|
239
|
+
const stale = added.filter((f) => {
|
|
240
|
+
const n = migrationSeq(f);
|
|
241
|
+
return n !== null && remoteMaxSeq !== null && n <= remoteMaxSeq;
|
|
242
|
+
});
|
|
243
|
+
if (stale.length === 0) {
|
|
244
|
+
return {
|
|
245
|
+
renumbered: false,
|
|
246
|
+
skipped: "seq-free",
|
|
247
|
+
detail: `migration seq still free on a fresh ${remote}/${opts.integrationBranch} ` +
|
|
248
|
+
`(head max ${remoteMaxSeq ?? "n/a"}) — pushing unchanged`,
|
|
249
|
+
remoteMaxSeq,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
const runRenumber = deps.runRenumber ?? defaultRunRenumber;
|
|
253
|
+
const isDirty = deps.isDirty ?? defaultIsDirty;
|
|
254
|
+
const commit = deps.commit ?? defaultCommit;
|
|
255
|
+
const { output } = await runRenumber(workdir, stale, baselineSeqs);
|
|
256
|
+
if (!(await isDirty(workdir))) {
|
|
257
|
+
return {
|
|
258
|
+
renumbered: false,
|
|
259
|
+
skipped: "renumber-noop",
|
|
260
|
+
// Carry the tool's own log: "left unchanged" is either a genuine no-op
|
|
261
|
+
// or a renumber that could not run, and only the log tells them apart.
|
|
262
|
+
detail: `renumber left the worktree unchanged — seq kept: ${stale.join(", ")}; ` +
|
|
263
|
+
`tool said: ${output.slice(-500) || "(no output)"}`,
|
|
264
|
+
remoteMaxSeq,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
// `move` describes the FIRST stale file. A branch adding several colliding
|
|
268
|
+
// migrations at once is vanishingly rare, and the renumber tool chains them
|
|
269
|
+
// correctly anyway (each pass re-reads the directory, so the second lands
|
|
270
|
+
// above the first). The full tool log rides along in `move.output`, so the
|
|
271
|
+
// event is never lossy even then.
|
|
272
|
+
const first = stale[0];
|
|
273
|
+
const fromSeq = migrationSeq(first);
|
|
274
|
+
// The tool's own log names the move (`0315 → 0316`); prefer it, and fall
|
|
275
|
+
// back to the arithmetic the tool would have used so the event is never
|
|
276
|
+
// empty just because the log format shifts.
|
|
277
|
+
const moved = /(\d{2,})\s*→\s*(\d{2,})/.exec(output);
|
|
278
|
+
const toSeq = moved ? Number(moved[2]) : (remoteMaxSeq ?? fromSeq) + 1;
|
|
279
|
+
const newFile = path.join(path.dirname(first), path.basename(first).replace(/^\d+/, String(toSeq).padStart(4, "0")));
|
|
280
|
+
await commit(workdir, `chore(acc): re-validate migration seq against fresh ${opts.integrationBranch} (MIG-SEQ-GUARD)`);
|
|
281
|
+
return {
|
|
282
|
+
renumbered: true,
|
|
283
|
+
detail: `migration seq ${fromSeq} was taken on a fresh ${remote}/${opts.integrationBranch} ` +
|
|
284
|
+
`(head max ${remoteMaxSeq}) — auto-renumbered to ${toSeq} before push`,
|
|
285
|
+
remoteMaxSeq,
|
|
286
|
+
move: {
|
|
287
|
+
file: first,
|
|
288
|
+
newFile,
|
|
289
|
+
fromSeq,
|
|
290
|
+
toSeq,
|
|
291
|
+
output: output.slice(-OUTPUT_TAIL),
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
// Fail-open: the guard may only ever IMPROVE a push's odds.
|
|
297
|
+
return {
|
|
298
|
+
renumbered: false,
|
|
299
|
+
skipped: "renumber-failed",
|
|
300
|
+
detail: `seq re-validation crashed (push proceeds): ${err.message?.slice(0, 300)}`,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
//# sourceMappingURL=migration-seq-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-seq-guard.js","sourceRoot":"","sources":["../src/migration-seq-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/** Worktree-relative path of the file `nvm use` reads. */
|
|
2
|
+
export declare const NVMRC_REL = ".nvmrc";
|
|
3
|
+
/**
|
|
4
|
+
* Explicit escape hatch: a bin dir containing the node the gates must run under.
|
|
5
|
+
* Set it on a host whose node lives outside every layout below. Trusted as
|
|
6
|
+
* declared — the version behind it is not re-verified (that would cost a spawn).
|
|
7
|
+
*/
|
|
8
|
+
export declare const NODE_BIN_DIR_ENV = "ACC_RUNNER_NODE_BIN_DIR";
|
|
9
|
+
/** Where a pin was declared. */
|
|
10
|
+
export type NodePinSource = ".nvmrc" | "package.json engines.node";
|
|
11
|
+
export interface NodePin {
|
|
12
|
+
/** The pin normalised without a leading `v` (`22`, `22.20.0`). */
|
|
13
|
+
spec: string;
|
|
14
|
+
/** Major version — the part that actually has to match. */
|
|
15
|
+
major: number;
|
|
16
|
+
/** Full `x.y.z` when the pin names one; null for a major-only pin. */
|
|
17
|
+
exact: string | null;
|
|
18
|
+
source: NodePinSource;
|
|
19
|
+
}
|
|
20
|
+
/** Version-manager on-disk layouts this module knows how to walk. */
|
|
21
|
+
export type NodeInstallLayout = "nvm" | "fnm" | "volta" | "asdf" | "n";
|
|
22
|
+
/** How `binDir` was arrived at. */
|
|
23
|
+
export type NodeResolutionSource = "current" | "explicit" | NodeInstallLayout | "unresolved" | "unpinned";
|
|
24
|
+
export interface PinnedNodeResolution {
|
|
25
|
+
/** The repo's pin, or null when it declares none. */
|
|
26
|
+
pin: NodePin | null;
|
|
27
|
+
/**
|
|
28
|
+
* The node version the gates will run under, when knowable: the picked
|
|
29
|
+
* install's version, or the current process's. Null only for `explicit`
|
|
30
|
+
* (declared by the operator, deliberately not re-verified).
|
|
31
|
+
*/
|
|
32
|
+
effective: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* True when the node the gates will run under satisfies the pin — and also
|
|
35
|
+
* true when there is no pin to violate. False means "we ran under the wrong
|
|
36
|
+
* node and could not fix it", which is exactly the signal that turns a jsdom
|
|
37
|
+
* failure into an ENVIRONMENT fault rather than a code defect.
|
|
38
|
+
*/
|
|
39
|
+
satisfied: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Dir to prepend to PATH so `node` (and therefore `pnpm`, whose shim shebangs
|
|
42
|
+
* `#!/usr/bin/env node`) resolves to the pinned install. Null when the current
|
|
43
|
+
* node is already right, or when nothing matching was found.
|
|
44
|
+
*/
|
|
45
|
+
binDir: string | null;
|
|
46
|
+
source: NodeResolutionSource;
|
|
47
|
+
/** One-line, log-safe explanation for the runner log. Never contains secrets. */
|
|
48
|
+
note: string;
|
|
49
|
+
}
|
|
50
|
+
export interface NodeVersionDeps {
|
|
51
|
+
/** Env source. Default `process.env`. */
|
|
52
|
+
env?: NodeJS.ProcessEnv;
|
|
53
|
+
/** Home dir the version-manager layouts hang off. Default `os.homedir()`. */
|
|
54
|
+
homedir?: string;
|
|
55
|
+
/** The running node's version (`v22.20.0` or `22.20.0`). Default `process.version`. */
|
|
56
|
+
currentVersion?: string;
|
|
57
|
+
/** Read a text file. Default `fs.readFile(abs, "utf8")`; rejects when absent. */
|
|
58
|
+
readTextFile?: (abs: string) => Promise<string>;
|
|
59
|
+
/** List a directory's entry names. Default `fs.readdir`; rejects when absent. */
|
|
60
|
+
listDir?: (abs: string) => Promise<string[]>;
|
|
61
|
+
/** True when `abs` exists and is executable. Default `fs.access(X_OK)`. */
|
|
62
|
+
isExecutable?: (abs: string) => Promise<boolean>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The version a `.nvmrc` names, normalised without the leading `v`. Comments and
|
|
66
|
+
* blank lines are skipped (nvm allows both). Returns null for an ALIAS
|
|
67
|
+
* (`lts/*`, `node`, `stable`, `iron`) — resolving one needs nvm's alias table,
|
|
68
|
+
* and guessing is worse than reporting "unpinned" and falling back to `engines`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseNvmrc(text: string): string | null;
|
|
71
|
+
/**
|
|
72
|
+
* The major version an `engines.node` RANGE requires, as a major-only pin
|
|
73
|
+
* (`">=22 <23"` → `22`, `"22.x"` → `22`, `"^22.20.0"` → `22`). A range is a
|
|
74
|
+
* range: even when it names a patch we only ever pin the major, so `>=22.20.0
|
|
75
|
+
* <23` is satisfied by 22.21.0. Returns null when no number can be read.
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseEnginesRange(range: string): string | null;
|
|
78
|
+
/** Build a `NodePin` from a normalised spec, or null when it is unusable. */
|
|
79
|
+
export declare function nodePinFrom(spec: string, source: NodePinSource): NodePin | null;
|
|
80
|
+
/** `[major, minor, patch]` of a version string, or null when unparseable. */
|
|
81
|
+
export declare function parseNodeVersion(v: string): [number, number, number] | null;
|
|
82
|
+
/** Ascending comparison; unparseable versions sort first. */
|
|
83
|
+
export declare function compareNodeVersions(a: string, b: string): number;
|
|
84
|
+
/**
|
|
85
|
+
* True when `version` satisfies `pin`: the major must match, and when the pin
|
|
86
|
+
* names an exact `x.y.z` that must match too. An unparseable version satisfies
|
|
87
|
+
* nothing (fail closed — an unknown node is not assumed correct).
|
|
88
|
+
*/
|
|
89
|
+
export declare function satisfiesPin(version: string, pin: NodePin): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* The HIGHEST version in `versions` that satisfies `pin`, or null when none
|
|
92
|
+
* does. Highest, not first: on a host with 22.11.0 and 22.20.0 installed the
|
|
93
|
+
* newer patch is the one CI's `node-version: 22` would resolve to.
|
|
94
|
+
*/
|
|
95
|
+
export declare function pickPinnedInstall(versions: string[], pin: NodePin): string | null;
|
|
96
|
+
export interface NodeInstallRoot {
|
|
97
|
+
layout: NodeInstallLayout;
|
|
98
|
+
/** Directory whose entries are version names (`v22.20.0` or `22.20.0`). */
|
|
99
|
+
dir: string;
|
|
100
|
+
/** The `bin` dir for one entry of `dir`. */
|
|
101
|
+
binDirFor: (entry: string) => string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Version-manager roots to search, in preference order. Honours each manager's
|
|
105
|
+
* own env override so a non-default install location still resolves. Directories
|
|
106
|
+
* that do not exist are simply skipped by the caller — listing them is the probe.
|
|
107
|
+
*/
|
|
108
|
+
export declare function nodeInstallRoots(env: NodeJS.ProcessEnv, homedir: string): NodeInstallRoot[];
|
|
109
|
+
/**
|
|
110
|
+
* Prepend `binDir` to a launchd-safe PATH (see bin-resolve.ts) so the pinned
|
|
111
|
+
* node wins every lookup — including `pnpm`'s own shebang, which is what makes
|
|
112
|
+
* the whole `pnpm run test` subtree inherit it. Idempotent: an already-leading
|
|
113
|
+
* `binDir` is not duplicated.
|
|
114
|
+
*/
|
|
115
|
+
export declare function withPinnedNodePath(env: NodeJS.ProcessEnv, binDir: string | null): NodeJS.ProcessEnv;
|
|
116
|
+
/**
|
|
117
|
+
* The repo's declared node pin: `.nvmrc` first (it is what a human's `nvm use`
|
|
118
|
+
* obeys, so runner and human never disagree), then `package.json`
|
|
119
|
+
* `engines.node`. Null when neither declares a readable version.
|
|
120
|
+
*/
|
|
121
|
+
export declare function readRepoNodePin(workdir: string, deps?: NodeVersionDeps): Promise<NodePin | null>;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve which node the repo's gates must run under, and where it is.
|
|
124
|
+
*
|
|
125
|
+
* Order: no pin → nothing to enforce; current node satisfies → run as-is (the
|
|
126
|
+
* common case, and it costs one file read); `ACC_RUNNER_NODE_BIN_DIR` →
|
|
127
|
+
* trusted as declared; then each version-manager layout, highest matching patch
|
|
128
|
+
* wins; finally `unresolved`, which the caller surfaces rather than papering
|
|
129
|
+
* over.
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolvePinnedNode(workdir: string, deps?: NodeVersionDeps): Promise<PinnedNodeResolution>;
|
|
132
|
+
//# sourceMappingURL=node-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version.d.ts","sourceRoot":"","sources":["../src/node-version.ts"],"names":[],"mappings":"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"}
|