Public: anyone can read this; the crew can change it.

/system groups crew:<name> processes as the crew kind #2814

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/2811-system-groups-crew-name-processes-as-the → main 2 commits fork

  • Merged. scout/2811-system-groups-crew-name-processes-as-the was merged into main as 78de91b.

Review

Sign in to review this change.
3 files changed +19 −4
src/web/pages/system.ts +2 −2
@@ -42,8 +42,8 @@ const meterRow = (name: string, value: number | null, max: number, figure: strin
4242 <meter class="bt-bar" aria-label="${name} ${figure}" min="0" max="${String(max)}" high="${String(max * 0.85)}" value="${String(value ?? 0)}">${figure}</meter>
4343 <span class="bt-val">${figure}</span>${history ? html`<span class="bt-hist" aria-hidden="true">${history}</span>` : null}</div>`;
4444
45 /** Processes grouped forge, check, app, host; the client re-sorts them by CPU or memory (`system-live.ts`). */
46 const KIND_ORDER = ["forge", "check", "app", "host"] as const;
45 /** Processes grouped forge, crew, check, app, host; the client re-sorts them by CPU or memory (`system-live.ts`). */
46 const KIND_ORDER = ["forge", "crew", "check", "app", "host"] as const;
4747 function procTable(v: SystemView): Html {
4848 const groups = KIND_ORDER.flatMap((k) => v.groups.filter((g) => g.kind === k));
4949 return html`<div class="table-wrap"><table class="table bt-procs" aria-label="Processes by what launched them">
src/web/system-live.ts +1 −1
@@ -24,7 +24,7 @@ function rank(items, key, kinds) {
2424 export const systemLiveJs = /* js */ `
2525 (function () {
2626 ${procSortJs}
27 var KINDS = ['forge', 'check', 'app', 'host'], key = 'cpu';
27 var KINDS = ['forge', 'crew', 'check', 'app', 'host'], key = 'cpu';
2828 function read(el) {
2929 return { el: el, kind: el.getAttribute('data-kind'), cpu: Number(el.getAttribute('data-cpu')) || 0, mem: Number(el.getAttribute('data-mem')) || 0 };
3030 }
test/system-btop.test.ts +16 −1
@@ -9,7 +9,7 @@ import { tmpdir } from "node:os";
99 import { join } from "node:path";
1010 import { createLive } from "../src/system/live.ts";
1111 import { parseDiskstats, type Proc, type Raw } from "../src/system/proc.ts";
12 import { buildSystem } from "../src/system/view.ts";
12 import { buildSystem, forAgent } from "../src/system/view.ts";
1313 import { regions } from "../src/web/pages/system.ts";
1414 import { systemLines } from "../src/tui/screens/system.ts";
1515 import { procSortJs, systemLiveJs } from "../src/web/system-live.ts";
@@ -54,6 +54,21 @@ describe("/system as btop", () => {
5454 expect(html).toMatch(/data-cpu="[\d.]+" data-mem="\d+"/);
5555 });
5656
57 test("crew:<name> is its own kind, after forge, and another agent never sees its name", () => {
58 const r = raw(2000, 300);
59 r.procs.push(proc(500, 1, "bwrap", 0, 1 << 20), proc(501, 500, "claude", 10, 80 << 20));
60 const v = buildSystem(undefined, r, [...roots.slice(0, 2), { label: "crew:atlas", root: 500 }], 1);
61 const html = regions(v)["sys-procs"]!;
62 const kinds = [...html.matchAll(/<tbody data-kind="(\w+)"/g)].map((m) => m[1]);
63 expect(kinds).toEqual(["forge", "crew", "check", "app"]);
64 expect(v.groups.find((g) => g.label === "crew:atlas")?.kind).toBe("crew");
65 const hidden = forAgent(v, () => false);
66 expect(JSON.stringify(hidden)).not.toContain("atlas");
67 expect(hidden.groups.find((g) => g.kind === "crew")?.label).toBe("crew:private-1");
68 expect(hidden.groups.find((g) => g.kind === "crew")?.top).toEqual([]);
69 expect(JSON.stringify(forAgent(v, (l) => l === "crew:atlas"))).toContain("crew:atlas");
70 });
71
5772 test("cores, memory, swap, load, disk and network rates are drawn from the sample", () => {
5873 const r = regions(view);
5974 expect(r["cores"]).toContain("cpu0");

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs