llm-relay 0.82.2 → 0.83.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"job-archive.js","sourceRoot":"","sources":["../../src/mcp/job-archive.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"job-archive.js","sourceRoot":"","sources":["../../src/mcp/job-archive.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,23 @@ export interface JournalRow {
5
5
  spec?: string;
6
6
  cwd: string;
7
7
  startedAt: number;
8
+ /** The task's first line, cut short, so another process can list the job recognisably. */
9
+ label?: string;
10
+ /**
11
+ * The process and the journal instance that own the row. Absent on a row written before
12
+ * 2026-09-17, which is read exactly as before: an orphan.
13
+ *
14
+ * ⚠ Why both exist. Two hosts run their own `llm-relay mcp` process at the same time (Claude
15
+ * Desktop and Codex Desktop, measured), and both write this one file. Before the owner was
16
+ * recorded, the second process to start read the first one's LIVE jobs as orphans and reported
17
+ * them killed, and every write by either process erased the other's rows. The pid says whether
18
+ * the owner can still be running; the instance token tells two journals inside one process apart,
19
+ * which is how the suite simulates a restart without a second process.
20
+ */
21
+ owner?: {
22
+ pid: number;
23
+ instance: string;
24
+ };
8
25
  }
9
26
  export interface JournalFile {
10
27
  version: 1;
@@ -26,11 +43,27 @@ export interface JobJournal {
26
43
  note(row: JournalRow): void;
27
44
  /** Remove a job that reached a terminal state, or one that never started. */
28
45
  clear(jobId: string): void;
29
- /** Rows present at STARTUP — i.e. jobs a previous process died holding. */
46
+ /** Rows present at STARTUP whose owner is gone — i.e. jobs a previous process died holding. */
30
47
  orphans(): JournalRow[];
48
+ /**
49
+ * The row for `jobId` if ANOTHER live process owns it right now, read from disk at call time.
50
+ * This is how one host's server answers for a job another host's server is still running.
51
+ */
52
+ foreign(jobId: string): JournalRow | undefined;
53
+ /** Every row another live process owns now. */
54
+ foreignRows(): JournalRow[];
55
+ /** The highest `job-NNNN` sequence any row on disk carries, read at call time; 0 when none. */
56
+ maxSeqOnDisk(): number;
31
57
  }
32
58
  /** A journal that records nothing. The default under vitest, and for an embedder that declines one. */
33
59
  export declare const nullJobJournal: JobJournal;
60
+ /** How a journal decides who owns a row. Injected so the suite can prove both branches. */
61
+ export interface JobJournalOptions {
62
+ /** This process's pid. */
63
+ pid?: number;
64
+ /** Does `pid` still name a running process? `process.kill(pid, 0)` by default. */
65
+ isAlive?: (pid: number) => boolean;
66
+ }
34
67
  /**
35
68
  * The real journal: a small JSON file rewritten on every change, read ONCE at construction.
36
69
  *
@@ -43,4 +76,4 @@ export declare const nullJobJournal: JobJournal;
43
76
  * the strength of an unparseable file would invent deaths, which is the same fail-safe direction
44
77
  * `lane-manifest.ts` takes on a corrupt manifest.
45
78
  */
46
- export declare function createJobJournal(path?: string): JobJournal;
79
+ export declare function createJobJournal(path?: string, options?: JobJournalOptions): JobJournal;
@@ -11,25 +11,55 @@ export const nullJobJournal = {
11
11
  note: () => { },
12
12
  clear: () => { },
13
13
  orphans: () => [],
14
+ foreign: () => undefined,
15
+ foreignRows: () => [],
16
+ maxSeqOnDisk: () => 0,
14
17
  };
15
- export function createJobJournal(path = jobJournalPath()) {
18
+ function defaultIsAlive(pid) {
19
+ try {
20
+ process.kill(pid, 0);
21
+ return true;
22
+ }
23
+ catch (e) {
24
+ return e.code === "EPERM";
25
+ }
26
+ }
27
+ let instanceCounter = 0;
28
+ export function createJobJournal(path = jobJournalPath(), options = {}) {
29
+ const pid = options.pid ?? process.pid;
30
+ const isAlive = options.isAlive ?? defaultIsAlive;
31
+ instanceCounter += 1;
32
+ const instance = `${pid}-${Date.now().toString(36)}-${instanceCounter}`;
16
33
  const rows = new Map();
17
34
  let loaded = false;
18
35
  let startupOrphans = [];
36
+ const readDisk = () => {
37
+ const parsed = safeReadJsonSync(path, {
38
+ validator: (v) => isRecord(v) && v["version"] === JOB_JOURNAL_VERSION && Array.isArray(v["jobs"]),
39
+ });
40
+ return parsed ? parsed.jobs.filter(isJournalRow) : null;
41
+ };
42
+ const ownedElsewhere = (row) => {
43
+ const owner = row.owner;
44
+ if (owner === undefined || owner.instance === instance)
45
+ return false;
46
+ if (owner.pid === pid)
47
+ return false;
48
+ return isAlive(owner.pid);
49
+ };
19
50
  const readOnce = () => {
20
51
  if (loaded)
21
52
  return;
22
53
  loaded = true;
23
- const parsed = safeReadJsonSync(path, {
24
- validator: (v) => isRecord(v) && v["version"] === JOB_JOURNAL_VERSION && Array.isArray(v["jobs"]),
25
- });
26
- if (!parsed)
54
+ const disk = readDisk();
55
+ if (!disk)
27
56
  return;
28
- startupOrphans = parsed.jobs.filter(isJournalRow);
57
+ startupOrphans = disk.filter((row) => row.owner?.instance !== instance && !ownedElsewhere(row));
29
58
  };
30
59
  const flush = () => {
31
60
  try {
32
- atomicWriteJsonSync(path, { version: JOB_JOURNAL_VERSION, jobs: [...rows.values()] });
61
+ const others = (readDisk() ?? []).filter(ownedElsewhere);
62
+ atomicWriteJsonSync(path, { version: JOB_JOURNAL_VERSION, jobs: [...others, ...rows.values()] });
33
63
  }
34
64
  catch {
35
65
  }
@@ -37,7 +67,7 @@ export function createJobJournal(path = jobJournalPath()) {
37
67
  return {
38
68
  note(row) {
39
69
  readOnce();
40
- rows.set(row.jobId, row);
70
+ rows.set(row.jobId, { ...row, owner: { pid, instance } });
41
71
  flush();
42
72
  },
43
73
  clear(jobId) {
@@ -50,6 +80,26 @@ export function createJobJournal(path = jobJournalPath()) {
50
80
  readOnce();
51
81
  return startupOrphans;
52
82
  },
83
+ foreign(jobId) {
84
+ readOnce();
85
+ if (rows.has(jobId))
86
+ return undefined;
87
+ return (readDisk() ?? []).find((row) => row.jobId === jobId && ownedElsewhere(row));
88
+ },
89
+ foreignRows() {
90
+ readOnce();
91
+ return (readDisk() ?? []).filter((row) => !rows.has(row.jobId) && ownedElsewhere(row));
92
+ },
93
+ maxSeqOnDisk() {
94
+ let max = 0;
95
+ for (const row of readDisk() ?? []) {
96
+ const m = /^job-(\d+)$/.exec(row.jobId);
97
+ const n = m ? Number(m[1]) : 0;
98
+ if (Number.isSafeInteger(n) && n > max)
99
+ max = n;
100
+ }
101
+ return max;
102
+ },
53
103
  };
54
104
  }
55
105
  function isRecord(value) {
@@ -62,6 +112,15 @@ function isJournalRow(value) {
62
112
  typeof value["laneId"] === "string" &&
63
113
  typeof value["cwd"] === "string" &&
64
114
  typeof value["startedAt"] === "number" &&
65
- (value["spec"] === undefined || typeof value["spec"] === "string"));
115
+ (value["spec"] === undefined || typeof value["spec"] === "string") &&
116
+ (value["label"] === undefined || typeof value["label"] === "string") &&
117
+ (value["owner"] === undefined || isOwner(value["owner"])));
118
+ }
119
+ function isOwner(value) {
120
+ return (isRecord(value) &&
121
+ typeof value["pid"] === "number" &&
122
+ Number.isSafeInteger(value["pid"]) &&
123
+ value["pid"] > 0 &&
124
+ typeof value["instance"] === "string");
66
125
  }
67
126
  //# sourceMappingURL=job-journal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"job-journal.js","sourceRoot":"","sources":["../../src/mcp/job-journal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"job-journal.js","sourceRoot":"","sources":["../../src/mcp/job-journal.ts"],"names":[],"mappings":"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"}
@@ -212,6 +212,8 @@ export interface LaneJob {
212
212
  * previous process, and its report is exactly what that process wrote (`job-archive.ts`).
213
213
  */
214
214
  restored?: boolean;
215
+ /** The first line of the task, cut short (`taskLabel`), so a job can be recognised in a list. */
216
+ label?: string;
215
217
  /**
216
218
  * The read-only TOOL binding applied to the lane now running (`readonly-boundary.ts`
217
219
  * `readOnlyInvoke`). Replaced per lane, like `expected`; absent for an ordinary dispatch.
@@ -220,6 +222,23 @@ export interface LaneJob {
220
222
  laneId: string;
221
223
  binding: string;
222
224
  };
225
+ /**
226
+ * What the launcher changed before the lane now running started (`prepareLaneLaunch`): an
227
+ * environment value expanded or removed, or the working directory given to AGY. Names only, never
228
+ * a value. Replaced per lane, like `readOnly`; absent when the launcher changed nothing.
229
+ */
230
+ launch?: string[];
231
+ /**
232
+ * What the job changed in its git working tree, rendered (`tree-delta.ts`): set once, when the job
233
+ * ends, for an agent-mode job whose cwd is in a git work tree. Report only.
234
+ */
235
+ treeDelta?: string;
236
+ /**
237
+ * Each lane the walk kept past its attempt budget because it was still working, one line per lane,
238
+ * with the reason. Kept for the whole job — not replaced per lane — because the lane that was kept
239
+ * can still be stopped later, and the record of why it ran long must survive that.
240
+ */
241
+ extended?: string[];
223
242
  }
224
243
  /**
225
244
  * Output progress of the attempt now running. Byte counts and timestamps only — never the bytes.
@@ -288,6 +307,39 @@ export declare function isContentEmpty(text: string): boolean;
288
307
  * literal token, rather than each spelling it out separately.
289
308
  */
290
309
  export declare const EMPTY_OUTPUT_REASON = "empty-output: the lane's output has no usable content after stripping formatting";
310
+ /**
311
+ * Expand the `%NAME%` references a Windows environment value still holds (`docs/backlog.md`: a lane
312
+ * inherited `HOME=%USERPROFILE%` literally, and a child that honours `HOME` wrote into a directory
313
+ * named `%USERPROFILE%`). A reference expands from the SAME environment, looked up without case as
314
+ * Windows does, in one pass. A value that is ONE unresolved reference is removed, because the literal
315
+ * is never a usable value. An unresolved reference inside a longer value (a `PATH` entry) stays: removing
316
+ * the whole value would lose the parts that are real. Windows only — `%` has no meaning to a POSIX
317
+ * shell, and a POSIX value that holds one is data.
318
+ *
319
+ * Returns the notes `LaneJobStore.noteLaunch` records: variable and reference NAMES, never a value.
320
+ */
321
+ export declare function expandEnvReferences(env: NodeJS.ProcessEnv, platform?: NodeJS.Platform): {
322
+ env: NodeJS.ProcessEnv;
323
+ notes: string[];
324
+ };
325
+ type LaneInvoke = {
326
+ command: string;
327
+ args: string[];
328
+ env?: Record<string, string | null>;
329
+ };
330
+ /**
331
+ * Give an AGY lane the caller's working directory (`docs/backlog.md`: AGY works in its own scratch
332
+ * directory whatever `cwd` its process gets, so a lane asked to edit a worktree saw none of its
333
+ * files). AGY reads a directory only through `--add-dir`, so the directory goes on the command line,
334
+ * and the task text names it. Null for every other lane.
335
+ *
336
+ * The prompt is the argument after AGY's own `-p`; a rung with no `-p` gets `--add-dir` alone. An
337
+ * `--add-dir` the rung already declares for the same directory is not repeated.
338
+ */
339
+ export declare function agyWorkingDirInvoke<T extends LaneInvoke>(invoke: T, cwd: string): {
340
+ invoke: T;
341
+ note: string;
342
+ } | null;
291
343
  export interface DispatchedQuotaReport {
292
344
  laneId: string;
293
345
  tier: string | undefined;
@@ -434,6 +486,16 @@ export declare function relayLoopbackUrl(config: {
434
486
  port: number;
435
487
  }, path: string): string;
436
488
  export declare function readRelayAnnouncements(headers: Headers): RelayAnnouncements;
489
+ /** One line of `LaneJobStore.recent`. `elsewhere` marks a job another live process runs. */
490
+ export interface RecentJob {
491
+ id: string;
492
+ status: JobStatus;
493
+ laneId: string;
494
+ startedAt: number;
495
+ endedAt: number | undefined;
496
+ elsewhere: boolean;
497
+ label?: string;
498
+ }
437
499
  /** Raise the counter to at least `seq`; never lowers it. */
438
500
  export declare function seedJobCounter(seq: number): void;
439
501
  /**
@@ -481,7 +543,7 @@ export declare class LaneJobStore {
481
543
  * termination that never happened.
482
544
  */
483
545
  private adoptOrphans;
484
- create(laneId: string, spec: string | undefined, cwd: string, dispatchSource?: "daemon" | "fallback"): LaneJob;
546
+ create(laneId: string, spec: string | undefined, cwd: string, dispatchSource?: "daemon" | "fallback", label?: string): LaneJob;
485
547
  /**
486
548
  * Record the process-handle this dispatcher started for `id`, so the job can be REAPED when it
487
549
  * reaches a terminal state and so what it owned is reportable afterwards.
@@ -534,6 +596,15 @@ export declare class LaneJobStore {
534
596
  noteOutput(id: string, stream: "stdout" | "stderr", bytes: number, now: number): void;
535
597
  /** Record the read-only tool binding the lane now running was given, so the reply can state it. */
536
598
  noteReadOnly(id: string, laneId: string, binding: string): void;
599
+ /** Record what the launcher changed for the lane now running, so the reply can state it. */
600
+ /**
601
+ * Record the job's tree delta. Accepted on a TERMINAL job too — a cancellation ends the job before
602
+ * the second `git status` returns — and the archive row is then written again so it carries it.
603
+ */
604
+ noteTreeDelta(id: string, text: string): void;
605
+ /** Record (or update) why the walk kept `laneId` past its budget. One line per lane. */
606
+ noteExtension(id: string, laneId: string, text: string): void;
607
+ noteLaunch(id: string, notes: readonly string[]): void;
537
608
  /**
538
609
  * Append one tried lane to the walk's record. Appended for EVERY attempt, the winner included,
539
610
  * so the answer can say what it cost to get there — and so an abandoned lane leaves a trace,
@@ -584,7 +655,33 @@ export declare class LaneJobStore {
584
655
  * `docs/reference.md` says so rather than implying a machine-wide guarantee this cannot make.
585
656
  */
586
657
  inFlight(laneId: string, excludeJobId?: string): number;
658
+ /** A job THIS store holds. The walk reads this; it never needs another process's job. */
587
659
  get(id: string): LaneJob | undefined;
660
+ /**
661
+ * A job for a CALLER: one this store holds, else one another `llm-relay mcp` process finished and
662
+ * archived after this store started (kept from then on, marked `restored`), else undefined.
663
+ *
664
+ * ⚠ Why a caller needs more than `get`. Claude Desktop and Codex Desktop each start their own
665
+ * server, and a session can poll through a different connection than the one that dispatched —
666
+ * observed 2026-09-16 as `unknown jobId` for a job that had finished. The archive is shared on
667
+ * disk, so the answer exists; it was read only once, at start.
668
+ */
669
+ find(id: string): LaneJob | undefined;
670
+ /**
671
+ * The newest `limit` jobs this machine knows: this store's, every finished job on disk, and every
672
+ * job another live process is running. Newest start first.
673
+ */
674
+ recent(limit: number): RecentJob[];
675
+ /**
676
+ * The journal row for a job another LIVE `llm-relay mcp` process is running now, or undefined.
677
+ * Nothing about it can be read here except that it runs; its answer reaches `find` once it ends.
678
+ */
679
+ runningElsewhere(id: string): {
680
+ laneId: string;
681
+ spec?: string;
682
+ startedAt: number;
683
+ pid: number;
684
+ } | undefined;
588
685
  list(): LaneJob[];
589
686
  /**
590
687
  * `relay` carries an answer-mode job's captured provenance headers — absent for every
@@ -53,6 +53,62 @@ export function isContentEmpty(text) {
53
53
  return text.replace(/[\s#*_\-|>`~=]/g, "").length === 0;
54
54
  }
55
55
  export const EMPTY_OUTPUT_REASON = "empty-output: the lane's output has no usable content after stripping formatting";
56
+ const ENV_REFERENCE = /%([A-Za-z_][A-Za-z0-9_()]*)%/g;
57
+ const WHOLE_ENV_REFERENCE = /^%[A-Za-z_][A-Za-z0-9_()]*%$/;
58
+ export function expandEnvReferences(env, platform = process.platform) {
59
+ if (platform !== "win32")
60
+ return { env, notes: [] };
61
+ const lookup = new Map();
62
+ for (const [name, value] of Object.entries(env)) {
63
+ if (typeof value === "string")
64
+ lookup.set(name.toUpperCase(), value);
65
+ }
66
+ const out = { ...env };
67
+ const notes = [];
68
+ for (const [name, value] of Object.entries(env)) {
69
+ if (typeof value !== "string" || !value.includes("%"))
70
+ continue;
71
+ if (WHOLE_ENV_REFERENCE.test(value) && !lookup.has(value.slice(1, -1).toUpperCase())) {
72
+ delete out[name];
73
+ notes.push(`${name} removed (${value} does not resolve)`);
74
+ continue;
75
+ }
76
+ const expanded = new Set();
77
+ const next = value.replace(ENV_REFERENCE, (token, ref) => {
78
+ const found = lookup.get(ref.toUpperCase());
79
+ if (found === undefined)
80
+ return token;
81
+ expanded.add(token);
82
+ return found;
83
+ });
84
+ if (expanded.size === 0)
85
+ continue;
86
+ out[name] = next;
87
+ notes.push(`${name} expanded from ${[...expanded].join(", ")}`);
88
+ }
89
+ return { env: out, notes };
90
+ }
91
+ export function agyWorkingDirInvoke(invoke, cwd) {
92
+ const rung = laneOfRung(invoke.command, invoke.args);
93
+ if (rung?.lane !== "agy")
94
+ return null;
95
+ const args = [...invoke.args];
96
+ const start = rung.binary === invoke.command ? 0 : args.indexOf(rung.binary) + 1;
97
+ const prompt = args.indexOf("-p", start);
98
+ if (prompt >= 0 && prompt + 1 < args.length) {
99
+ args[prompt + 1] = `Work in this directory: ${cwd}\n\n${args[prompt + 1]}`;
100
+ }
101
+ const target = samePathKey(cwd);
102
+ const declared = args.some((a, i) => (a === "--add-dir" && args[i + 1] !== undefined && samePathKey(args[i + 1]) === target) ||
103
+ (a.startsWith("--add-dir=") && samePathKey(a.slice("--add-dir=".length)) === target));
104
+ if (!declared)
105
+ args.push("--add-dir", cwd);
106
+ return { invoke: { ...invoke, args }, note: `agy works in ${cwd} (--add-dir)` };
107
+ }
108
+ function samePathKey(path) {
109
+ const resolved = resolvePath(path).replace(/\\/g, "/");
110
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
111
+ }
56
112
  export function classifyDispatchedResult(input) {
57
113
  const { result } = input;
58
114
  if (result.timedOut)
@@ -287,6 +343,20 @@ function readOwnedPids(handle) {
287
343
  }
288
344
  return raw.filter((pid) => Number.isSafeInteger(pid) && pid > 0);
289
345
  }
346
+ function recentOf(job, elsewhere) {
347
+ return {
348
+ id: job.id,
349
+ status: job.status,
350
+ laneId: job.laneId,
351
+ startedAt: job.startedAt,
352
+ endedAt: job.endedAt,
353
+ elsewhere,
354
+ ...(job.label === undefined ? {} : { label: job.label }),
355
+ };
356
+ }
357
+ function newestFirst(a, b) {
358
+ return b.startedAt - a.startedAt || (jobSeqOf(b.id) ?? 0) - (jobSeqOf(a.id) ?? 0);
359
+ }
290
360
  let jobCounter = 0;
291
361
  function nextJobId() {
292
362
  jobCounter += 1;
@@ -361,7 +431,9 @@ export class LaneJobStore {
361
431
  this.archive.record(killed);
362
432
  }
363
433
  }
364
- create(laneId, spec, cwd, dispatchSource) {
434
+ create(laneId, spec, cwd, dispatchSource, label) {
435
+ seedJobCounter(this.archive.lastSeqOnDisk());
436
+ seedJobCounter(this.journal.maxSeqOnDisk());
365
437
  const job = {
366
438
  id: nextJobId(),
367
439
  status: "running",
@@ -377,6 +449,7 @@ export class LaneJobStore {
377
449
  error: undefined,
378
450
  attempts: [],
379
451
  ...(dispatchSource !== undefined ? { dispatchSource } : {}),
452
+ ...(label ? { label } : {}),
380
453
  };
381
454
  this.jobs.set(job.id, job);
382
455
  const seq = jobSeqOf(job.id);
@@ -388,6 +461,7 @@ export class LaneJobStore {
388
461
  ...(job.spec === undefined ? {} : { spec: job.spec }),
389
462
  cwd: job.cwd,
390
463
  startedAt: job.startedAt,
464
+ ...(job.label === undefined ? {} : { label: job.label }),
391
465
  });
392
466
  return job;
393
467
  }
@@ -449,6 +523,7 @@ export class LaneJobStore {
449
523
  job.expected = expected;
450
524
  delete job.activity;
451
525
  delete job.readOnly;
526
+ delete job.launch;
452
527
  }
453
528
  beginAttemptActivity(id, now) {
454
529
  const job = this.jobs.get(id);
@@ -472,6 +547,27 @@ export class LaneJobStore {
472
547
  return;
473
548
  job.readOnly = { laneId, binding };
474
549
  }
550
+ noteTreeDelta(id, text) {
551
+ const job = this.jobs.get(id);
552
+ if (!job)
553
+ return;
554
+ job.treeDelta = text;
555
+ if (job.status !== "running")
556
+ this.archive.record(job);
557
+ }
558
+ noteExtension(id, laneId, text) {
559
+ const job = this.jobs.get(id);
560
+ if (!job || job.status !== "running")
561
+ return;
562
+ const others = (job.extended ?? []).filter((line) => !line.startsWith(`${laneId} `));
563
+ job.extended = [...others, text];
564
+ }
565
+ noteLaunch(id, notes) {
566
+ const job = this.jobs.get(id);
567
+ if (!job || job.status !== "running" || notes.length === 0)
568
+ return;
569
+ job.launch = [...notes];
570
+ }
475
571
  recordAttempt(id, attempt) {
476
572
  this.jobs.get(id)?.attempts.push(attempt);
477
573
  }
@@ -502,8 +598,55 @@ export class LaneJobStore {
502
598
  get(id) {
503
599
  return this.jobs.get(id);
504
600
  }
601
+ find(id) {
602
+ const held = this.jobs.get(id);
603
+ if (held !== undefined)
604
+ return held;
605
+ const archived = this.archive.lookup(id);
606
+ if (archived === undefined)
607
+ return undefined;
608
+ const row = { ...archived, restored: true };
609
+ this.jobs.set(id, row);
610
+ return row;
611
+ }
612
+ recent(limit) {
613
+ const byId = new Map();
614
+ const add = (row) => {
615
+ if (!byId.has(row.id))
616
+ byId.set(row.id, row);
617
+ };
618
+ for (const job of this.jobs.values())
619
+ add(recentOf(job, false));
620
+ for (const job of this.archive.all())
621
+ add(recentOf(job, false));
622
+ for (const row of this.journal.foreignRows()) {
623
+ add({
624
+ id: row.jobId,
625
+ status: "running",
626
+ laneId: row.laneId,
627
+ startedAt: row.startedAt,
628
+ endedAt: undefined,
629
+ elsewhere: true,
630
+ ...(row.label === undefined ? {} : { label: row.label }),
631
+ });
632
+ }
633
+ return [...byId.values()].sort(newestFirst).slice(0, Math.max(0, limit));
634
+ }
635
+ runningElsewhere(id) {
636
+ if (this.jobs.has(id))
637
+ return undefined;
638
+ const row = this.journal.foreign(id);
639
+ if (row?.owner === undefined)
640
+ return undefined;
641
+ return {
642
+ laneId: row.laneId,
643
+ ...(row.spec === undefined ? {} : { spec: row.spec }),
644
+ startedAt: row.startedAt,
645
+ pid: row.owner.pid,
646
+ };
647
+ }
505
648
  list() {
506
- return [...this.jobs.values()].sort((a, b) => b.startedAt - a.startedAt);
649
+ return [...this.jobs.values()].sort(newestFirst);
507
650
  }
508
651
  complete(id, run, semanticFailure, relay) {
509
652
  const job = this.jobs.get(id);