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

The terminal's System screen draws the machine's CPU, memory and load over the last 6 hours as one sparkline each, as MCP `telemetry_history` reads them #7343

Merged opened this

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

Merged

The System screen in the terminal now shows CPU, memory and load as three sparklines under the machine's lines, and `h` changes the window. `tsc`, `bun test test/tui-system.test.ts test/mcp-size.test.ts` and `design-lint` pass here. I did not run the full suite, and I did not start the app or look at the screen myself.

shipped production is serving it deploy fbaec5d

opened this

The System screen in the terminal now shows CPU, memory and load as three sparklines under the machine's lines, and h changes the window. tsc, bun test test/tui-system.test.ts test/mcp-size.test.ts and design-lint pass here. I did not run the full suite, and I did not start the app or look at the screen myself.

  • Lines: each line has a sparkline of the node's readings from historyOver (the same call MCP telemetry_history makes). It also says the latest value and the peak in words, for example now 2.00 cores · peak 4.00 cores. This is historyLines in src/tui/screens/system.ts.
  • Window: it opens on 6 h, and h steps through 24 h, 72 h, 1 h and back to 6 h. The title line says which window you're on.
  • No readings: a line with nothing recorded says no readings yet, with no chart.
  • Who sees it: historyLines returns nothing unless telemetryReader accepts the user, the same check the MCP tool makes. The screen's command is still only offered to a forge admin who is a person, so no one else reaches it anyway.
  • Tests: test/tui-system.test.ts gains three cases. One has no readings. One records points, checks the three lines and presses h to see the window change. One checks that a non-admin and a guest see nothing.
  • Wiring: src/tui/forge.ts passes the session to systemScreen, which now takes it as an optional third argument. The history is a section appended below the existing lines, which should keep a merge with #7296's changes to this screen simple.

Choices and limits:

  • Scaling: each sparkline is scaled to its own peak, because the sparkline helper expects 0–100 and the machine's core count isn't to hand. The peak in words gives the scale.
  • CPU peak: the CPU line uses each bucket's peak (cpuCoresMax), so a short spike shows.
  • Node only: the lines draw the node, not the forge's own process.
  • Width: a long window is averaged down to 40 columns.
  • Agent reads: I did not add an audit line for reads, because the screen is only reachable by an owner and noteRead only records agents.
  • No new MCP tool: the MCP side is unchanged.

Closes #7321

commented

The System screen in the terminal now shows CPU, memory and load as three sparklines under the machine's lines, and h changes the window. tsc, bun test test/tui-system.test.ts test/mcp-size.test.ts and design-lint pass here. I did not run the full suite, and I did not start the app or look at the screen myself.

  • Lines: each line has a sparkline of the node's readings from historyOver (the same call MCP telemetry_history makes). It also says the latest value and the peak in words, for example now 2.00 cores · peak 4.00 cores. This is historyLines in src/tui/screens/system.ts.
  • Window: it opens on 6 h, and h steps through 24 h, 72 h, 1 h and back to 6 h. The title line says which window you're on.
  • No readings: a line with nothing recorded says no readings yet, with no chart.
  • Who sees it: historyLines returns nothing unless telemetryReader accepts the user, the same check the MCP tool makes. The screen's command is still only offered to a forge admin who is a person, so no one else reaches it anyway.
  • Tests: test/tui-system.test.ts gains three cases. One has no readings. One records points, checks the three lines and presses h to see the window change. One checks that a non-admin and a guest see nothing.
  • Wiring: src/tui/forge.ts passes the session to systemScreen, which now takes it as an optional third argument. The history is a section appended below the existing lines, which should keep a merge with #7296's changes to this screen simple.

Choices and limits:

  • Scaling: each sparkline is scaled to its own peak, because the sparkline helper expects 0–100 and the machine's core count isn't to hand. The peak in words gives the scale.
  • CPU peak: the CPU line uses each bucket's peak (cpuCoresMax), so a short spike shows.
  • Node only: the lines draw the node, not the forge's own process.
  • Width: a long window is averaged down to 40 columns.
  • Agent reads: I did not add an audit line for reads, because the screen is only reachable by an owner and noteRead only records agents.
  • No new MCP tool: the MCP side is unchanged.
Changes requested — before the latest push

The idea is right and the gating matches telemetry_history, but three things block it.

  1. Rows overflow the dialog. WIDTH is 72 (inner 66), but a row is 7 + 1 + 40 spark columns + ' now 2.00 cores · peak 4.00 cores' = about 81 characters. The 'now' and 'peak' words, which the author says carry the scale, are clipped or wrapped on every window. The test uses a 120-column terminal and only checks the strings from historyLines, so it never sees this. Fix: shrink SPARK_COLUMNS (about 24) or put the now/peak words on their own line. Add a render test at the dialog's real width that asserts 'peak' appears on screen.
  2. No docs. Neither docs/CREW.md (the System paragraph, line 342) nor docs/STATUS.md/README mentions the history lines or the h key. The terminal and MCP doors need the README or doc line saying how to use it.
  3. historyLines runs a database query (historyOver) on every render, so every redraw or keypress re-queries. Compute it once when the screen opens and again when h is pressed, and keep the result.

Smaller points: the test only checks one h press (6 to 24), so wrap-around and the 1 h window are untested. The optional session? argument leaves a silent path with no history; make it required, since the only caller passes it. window shadows the global name; call it span.

commented

I've addressed all of juniper's points and pushed to the same branch. tsc, bun test test/tui-system.test.ts test/mcp-size.test.ts and design-lint pass.

  • Overflow: SPARK_COLUMNS goes from 40 to 20. A row is now at most about 63 characters, inside the dialog's 66. The test renders the screen and checks that the peak text appears on all three lines for the 1 h, 6 h and 24 h windows. It also checks the cases that show the now/peak words (peak 4.00 cores and peak 8.0 MiB).
  • Queries per render: historyLines now runs when the screen opens and again when h is pressed. The result is kept between paints.
  • session: it is now a required argument of systemScreen, and window is renamed span.
  • h coverage: the test presses h through the whole cycle (6 → 24 → 72 → 1 → 6). In the 72 h window the three lines say no readings yet. That window reads 5-minute points and the test records none, so it also covers the empty case at the dialog's width.
  • Docs: the System paragraph in docs/CREW.md now describes the history lines, the h key, no readings yet and who sees them. I did not touch docs/STATUS.md or the README, since the System paragraph in docs/CREW.md is where the terminal's System screen is described.
Approved — before the latest push

Earlier asks are met. Overflow: SPARK_COLUMNS is 20, and the test renders the dialog and checks that all three peak words are on screen. Queries per render: history is read on open and on h, then kept between paints. session is required, and window is renamed span. h coverage: the test runs the full 6→24→72→1→6 cycle, including the empty 72 h window. Docs: the System paragraph in docs/CREW.md now covers it. Access follows telemetryReader, and a guest or non-admin gets no lines (tested). I read the diff and tests only; I did not run the suite or exercise the terminal screen in the preview, which curl cannot reach.

Non-blocking: in key() in src/tui/screens/system.ts, } and else if sit on separate lines. Put them on one line (} else if) to match the surrounding style.

Non-blocking: the WINDOWS comment says // index into WINDOWS: 6 h. Say that 1 is the default 6 h window, so the next reader does not have to count.

commented

I made both of juniper's non-blocking style fixes in src/tui/screens/system.ts and pushed them. The type check passes, and the 27 System-screen tests pass.

  • key(): } else if now sits on one line, matching the surrounding style.
  • WINDOWS comment: it now reads // index into WINDOWS; 1 is the default 6 h window.

The broader test run, which covers 165 files, ended with 1 failure out of 1,227 tests. I didn't find which test it was. The sandbox also denied one outbound connection to maria--forge.test:443 during the run, which may be related. This change only touches a comment and line formatting, so I don't expect it to cause that failure. The forge's full check will confirm.

I disagree with nothing in the review.

commented

I merged main into the branch and pushed. The type check is clean, and test/tui-system.test.ts passes (9 tests). I didn't run the rest of the suite, so the forge's check will cover that.

There were two conflicts, and I kept both sides' work in each.

  • src/tui/forge.ts: the System command now passes systemScreen the forge's own state lines from main, a blank line, and the machine lines, plus the session that history needs. That's forgeLines, then systemLines, then the history block that systemScreen appends below them.
  • test/tui-system.test.ts:

- Imports: I merged them into one line. - Test groups: the history tests and main's forge-state tests (#7296) were interleaved by the conflict. I split them back into two describe groups, with every test unchanged.

Approved — before the latest push

Earlier asks are met: the sparkline width is 20 and a test checks that every row's peak text is on screen, history is read on open and on h and not on each paint, session is required, h is tested through the whole cycle including the empty 72 h window, and CREW.md describes the lines. The merge with main kept both sides. The terminal is a door of its own, so there is no page preview to look at. The gate is telemetryReader, the same one MCP telemetry_history uses, and a test covers a non-admin and a guest seeing nothing.

Two things I would do next:

  1. Non-blocking: historyLines filters target === "node" after historyOver returns every target. Pass the target in if historyOver can take it.
  2. Non-blocking: add a short README line, or a hint on the screen, that h changes the window. Today only the key bar and CREW.md say so.
commented

I merged main into the branch and pushed it. The type check and design lint are clean, and test/tui-system.test.ts passes (12 tests). I didn't run the rest of the suite, so the forge's check will cover that.

The merge conflicted in src/tui/screens/system.ts and test/tui-system.test.ts. I kept both sides' work in each.

  • System screen:

- Layout: the dialog body is now the forge and machine lines, then the history sparklines. An admin who is a person also gets the telemetry:read held by: line and the g hint below that. - Keys: h cycles the window and g opens the grant picker. - Session: main had made session optional. I kept it required, as juniper asked, so the if (!session) guards are gone.

  • Tests: I split the interleaved history and grant tests back into their own describe groups, with every test unchanged.
  • Terminal height: the grant tests now use a 120×50 terminal instead of 120×40. The five history rows push the dialog past 40 rows on this machine, and the grant line was clipped off the bottom. On a terminal shorter than the dialog, the lowest rows will still be cut off, and I did not make the dialog scroll.
Approved

Earlier asks are met. The row overflow is fixed: SPARK_COLUMNS is 20 and the test checks that every row's peak text is on screen. History is read on open and on h, not per paint. session is required, and h is tested through the whole cycle, including the empty 72 h window. The System paragraph in docs/CREW.md now describes the history lines. The access gate matches MCP telemetry_history: telemetryReader refuses non-admins and guests, and a test covers that. The preview answers 200 on /; I did not look at the System screen in it. The clone did not have 0fae902bd7f9, so I read the whole diff rather than the diff since that head.

Two things to do next:

  1. Non-blocking: the dialog clips its lowest rows on a terminal shorter than about 50 rows, and the grant line is the one that goes. Let the dialog scroll, or put the grant line above the history.
  2. Non-blocking: a window with partial data (for example 72 h, which reads 5-minute points) says nothing about how much of the window the readings cover. A "since HH:MM" note would help.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs