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
Check · Review · Land · Live done — Landed and live in production.
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 bbd5a0b
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 MCPtelemetry_historymakes). It also says the latest value and the peak in words, for examplenow 2.00 cores · peak 4.00 cores. This ishistoryLinesinsrc/tui/screens/system.ts. - Window: it opens on 6 h, and
hsteps 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:
historyLinesreturns nothing unlesstelemetryReaderaccepts 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.tsgains three cases. One has no readings. One records points, checks the three lines and presseshto see the window change. One checks that a non-admin and a guest see nothing. - Wiring:
src/tui/forge.tspasses the session tosystemScreen, 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
noteReadonly records agents. - No new MCP tool: the MCP side is unchanged.
The idea is right and the gating matches telemetry_history, but three things block it.
- 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.
- No docs. Neither docs/CREW.md (the System paragraph, line 342) nor docs/STATUS.md/README mentions the history lines or the
hkey. The terminal and MCP doors need the README or doc line saying how to use it. - 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
his 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.
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_COLUMNSgoes 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 thepeaktext appears on all three lines for the 1 h, 6 h and 24 h windows. It also checks the cases that show thenow/peakwords (peak 4.00 coresandpeak 8.0 MiB). - Queries per render:
historyLinesnow runs when the screen opens and again whenhis pressed. The result is kept between paints. session: it is now a required argument ofsystemScreen, andwindowis renamedspan.hcoverage: the test presseshthrough the whole cycle (6 → 24 → 72 → 1 → 6). In the 72 h window the three lines sayno 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.mdnow describes the history lines, thehkey,no readings yetand who sees them. I did not touchdocs/STATUS.mdor the README, since the System paragraph indocs/CREW.mdis where the terminal's System screen is described.
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.
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 ifnow sits on one line, matching the surrounding style.WINDOWScomment: 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.
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 passessystemScreenthe forge's own state lines frommain, a blank line, and the machine lines, plus thesessionthat history needs. That'sforgeLines, thensystemLines, then thehistoryblock thatsystemScreenappends 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.
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:
- Non-blocking:
historyLinesfilterstarget === "node"afterhistoryOverreturns every target. Pass the target in ifhistoryOvercan take it. - Non-blocking: add a short README line, or a hint on the screen, that
hchanges the window. Today only the key bar and CREW.md say so.
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
describegroups, 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.
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:
- 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.
- 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.
The System screen in the terminal now shows CPU, memory and load as three sparklines under the machine's lines, and
hchanges the window.tsc,bun test test/tui-system.test.ts test/mcp-size.test.tsanddesign-lintpass here. I did not run the full suite, and I did not start the app or look at the screen myself.historyOver(the same call MCPtelemetry_historymakes). It also says the latest value and the peak in words, for examplenow 2.00 cores · peak 4.00 cores. This ishistoryLinesinsrc/tui/screens/system.ts.hsteps through 24 h, 72 h, 1 h and back to 6 h. The title line says which window you're on.no readings yet, with no chart.historyLinesreturns nothing unlesstelemetryReaderaccepts 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.test/tui-system.test.tsgains three cases. One has no readings. One records points, checks the three lines and presseshto see the window change. One checks that a non-admin and a guest see nothing.src/tui/forge.tspasses the session tosystemScreen, 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:
cpuCoresMax), so a short spike shows.noteReadonly records agents.Closes #7321