@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.
Files changed (114) hide show
  1. package/README.md +87 -4
  2. package/dist/acc.d.ts +3 -0
  3. package/dist/acc.d.ts.map +1 -0
  4. package/dist/acc.js +21 -0
  5. package/dist/acc.js.map +1 -0
  6. package/dist/cli-name.d.ts +29 -0
  7. package/dist/cli-name.d.ts.map +1 -0
  8. package/dist/cli-name.js +17 -0
  9. package/dist/cli-name.js.map +1 -0
  10. package/dist/cli.d.ts +20 -2
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +45 -289
  13. package/dist/cli.js.map +1 -1
  14. package/dist/engines/account-probe.d.ts +24 -0
  15. package/dist/engines/account-probe.d.ts.map +1 -1
  16. package/dist/engines/account-probe.js +18 -1
  17. package/dist/engines/account-probe.js.map +1 -1
  18. package/dist/keychain.d.ts +17 -0
  19. package/dist/keychain.d.ts.map +1 -1
  20. package/dist/keychain.js +36 -0
  21. package/dist/keychain.js.map +1 -1
  22. package/dist/login.d.ts +45 -1
  23. package/dist/login.d.ts.map +1 -1
  24. package/dist/login.js +91 -4
  25. package/dist/login.js.map +1 -1
  26. package/dist/machine-capabilities/index.d.ts +21 -0
  27. package/dist/machine-capabilities/index.d.ts.map +1 -0
  28. package/dist/machine-capabilities/index.js +21 -0
  29. package/dist/machine-capabilities/index.js.map +1 -0
  30. package/dist/machine-capabilities/probe.d.ts +61 -0
  31. package/dist/machine-capabilities/probe.d.ts.map +1 -0
  32. package/dist/machine-capabilities/probe.js +243 -0
  33. package/dist/machine-capabilities/probe.js.map +1 -0
  34. package/dist/machine-capabilities/redact.d.ts +42 -0
  35. package/dist/machine-capabilities/redact.d.ts.map +1 -0
  36. package/dist/machine-capabilities/redact.js +160 -0
  37. package/dist/machine-capabilities/redact.js.map +1 -0
  38. package/dist/machine-capabilities/report.d.ts +107 -0
  39. package/dist/machine-capabilities/report.d.ts.map +1 -0
  40. package/dist/machine-capabilities/report.js +211 -0
  41. package/dist/machine-capabilities/report.js.map +1 -0
  42. package/dist/machine-capabilities/types.d.ts +115 -0
  43. package/dist/machine-capabilities/types.d.ts.map +1 -0
  44. package/dist/machine-capabilities/types.js +11 -0
  45. package/dist/machine-capabilities/types.js.map +1 -0
  46. package/dist/migration-seq-guard.d.ts +78 -0
  47. package/dist/migration-seq-guard.d.ts.map +1 -0
  48. package/dist/migration-seq-guard.js +304 -0
  49. package/dist/migration-seq-guard.js.map +1 -0
  50. package/dist/node-version.d.ts +132 -0
  51. package/dist/node-version.d.ts.map +1 -0
  52. package/dist/node-version.js +318 -0
  53. package/dist/node-version.js.map +1 -0
  54. package/dist/prepr-gate.d.ts +120 -0
  55. package/dist/prepr-gate.d.ts.map +1 -1
  56. package/dist/prepr-gate.js +202 -3
  57. package/dist/prepr-gate.js.map +1 -1
  58. package/dist/program.d.ts +16 -0
  59. package/dist/program.d.ts.map +1 -0
  60. package/dist/program.js +355 -0
  61. package/dist/program.js.map +1 -0
  62. package/dist/runtime/review-chunking.d.ts +101 -0
  63. package/dist/runtime/review-chunking.d.ts.map +1 -0
  64. package/dist/runtime/review-chunking.js +192 -0
  65. package/dist/runtime/review-chunking.js.map +1 -0
  66. package/dist/runtime/review-diff.d.ts +30 -0
  67. package/dist/runtime/review-diff.d.ts.map +1 -0
  68. package/dist/runtime/review-diff.js +59 -0
  69. package/dist/runtime/review-diff.js.map +1 -0
  70. package/dist/runtime/reviewer.d.ts +40 -19
  71. package/dist/runtime/reviewer.d.ts.map +1 -1
  72. package/dist/runtime/reviewer.js +252 -51
  73. package/dist/runtime/reviewer.js.map +1 -1
  74. package/dist/serve-scope/command.d.ts +12 -0
  75. package/dist/serve-scope/command.d.ts.map +1 -0
  76. package/dist/serve-scope/command.js +89 -0
  77. package/dist/serve-scope/command.js.map +1 -0
  78. package/dist/serve-scope/index.d.ts +130 -0
  79. package/dist/serve-scope/index.d.ts.map +1 -0
  80. package/dist/serve-scope/index.js +148 -0
  81. package/dist/serve-scope/index.js.map +1 -0
  82. package/dist/task-runner.d.ts +11 -0
  83. package/dist/task-runner.d.ts.map +1 -1
  84. package/dist/task-runner.js +69 -0
  85. package/dist/task-runner.js.map +1 -1
  86. package/dist/user-auth/device-login.d.ts +47 -0
  87. package/dist/user-auth/device-login.d.ts.map +1 -0
  88. package/dist/user-auth/device-login.js +189 -0
  89. package/dist/user-auth/device-login.js.map +1 -0
  90. package/dist/user-auth/liveness.d.ts +27 -0
  91. package/dist/user-auth/liveness.d.ts.map +1 -0
  92. package/dist/user-auth/liveness.js +128 -0
  93. package/dist/user-auth/liveness.js.map +1 -0
  94. package/dist/user-auth/session.d.ts +82 -0
  95. package/dist/user-auth/session.d.ts.map +1 -0
  96. package/dist/user-auth/session.js +172 -0
  97. package/dist/user-auth/session.js.map +1 -0
  98. package/dist/user-cli/chat.d.ts +44 -0
  99. package/dist/user-cli/chat.d.ts.map +1 -0
  100. package/dist/user-cli/chat.js +199 -0
  101. package/dist/user-cli/chat.js.map +1 -0
  102. package/dist/user-cli/client.d.ts +20 -0
  103. package/dist/user-cli/client.d.ts.map +1 -0
  104. package/dist/user-cli/client.js +60 -0
  105. package/dist/user-cli/client.js.map +1 -0
  106. package/dist/user-cli/tasks.d.ts +37 -0
  107. package/dist/user-cli/tasks.d.ts.map +1 -0
  108. package/dist/user-cli/tasks.js +131 -0
  109. package/dist/user-cli/tasks.js.map +1 -0
  110. package/dist/watch.d.ts +8 -0
  111. package/dist/watch.d.ts.map +1 -1
  112. package/dist/watch.js +28 -0
  113. package/dist/watch.js.map +1 -1
  114. 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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"}