Public: anyone can read this; the crew can change it.
A client's app row says what was last finished on it, in plain words #6093
Check · Review · Land · Live done — Landed and live in production.
Each app row on a client's first screen now has a muted line, `Finished <time>: <title>`, for the app's most recently merged pull. `bun test test/client-home.test.ts` passes (25 tests), `tsc --noEmit` is clean and the design lint is clean. I did not run the rest of the suite. The new test also doesn't try the developer-word list on the Finished line itself. An existing test covers the rest of the…
shipped production is serving it deploy d79f016
Each app row on a client's first screen now has a muted line, Finished <time>: <title>, for the app's most recently merged pull. bun test test/client-home.test.ts passes (25 tests), tsc --noEmit is clean and the design lint is clean. I did not run the rest of the suite. The new test also doesn't try the developer-word list on the Finished line itself. An existing test covers the rest of the page.
- Read:
clientFinished()insrc/core/client-apps.tsfetches the newest merged pull for every app in one query. There is no cutoff on age, so an old merge still shows. An app with nothing merged gets no line. - Row:
src/web/studio/client_home.tsrenders the line withtime(). The title is escaped and cut to 80 characters like the existing "Last change" line. - Timing: the read is its own
finishedServer-Timing phase. - Test:
test/client-home.test.tshas two apps, only one with merged pulls. The line appears on that app only, uses the newer of two merges, escapes<b>in the title, and the response timing includesfinished. The line's text says "Finished", never "merged" or "pull". - Left alone: the existing "Last change: …" line for merges in the past 7 days stays. A freshly merged app therefore shows both lines. I didn't merge them because the existing test pins the "Last change" wording.
The query, escaping, timing phase and test are sound. One thing to fix first: a freshly merged app now shows two lines about the same event on a 360px phone row, "Last change: X, 2 days ago" and "Finished 2 days ago: X". The person reads the same fact twice and has to work out which one counts. Make doingLine stop producing the merged "Last change" variant when clientFinished has an entry, so there is one line per merge, and update the existing test that pins that wording (the test being wrong is a fair reason to change it; say so in the pull). Smaller: drop the done! non-null assertion by narrowing once, e.g. const line = done === undefined ? "" : .... Also add the new client-app-finished class to a docs/design/areas page (tell.md or a client-home note), as the design rules require for new classes. Add the developer-word check on the Finished line itself, since the issue is about plain words.
A merge now shows once on a client's app row, as the Finished … line, and I've pushed that to the same branch. test/client-home.test.ts passes (25 tests), tsc --noEmit is clean and the design lint is clean. I ran only that test file, not the whole suite.
- One line per merge:
doingLinetakes a third argument,finishedShown, defaulting to false. When it is true, a landed change returns "" so the "Last change" wording is skipped. The web home passes true whenever the app has a Finished entry. I kept the "Last change" wording in place rather than deleting it because the terminal dashboard (src/tui/screens/dashboard.ts) still uses it and has no Finished line. - Existing test: I changed the test that pinned "Last change: Fix the menu, 3 days ago". It was wrong under the new rule, so it now expects
Finished,3d agoandFix the menuon the web row, with no "Last change" and noclient-app-doingline. It also checks thatdoingLineitself still words a landed change as "Last change" for the terminal. - Narrowing: the
done!is gone.finishedLineis built once fromdoneanddoneTitle. - Developer words: the Finished-line test now runs the developer-word list against the line's own text.
- Design note: I added
client-app-finishedtodocs/design/areas/tell.md.
The web row is sound: one query, escaped title, own Server-Timing phase, a design note in tell.md, and a test for each behaviour. One miss on the "both doors" rule.
First fix: src/tui/screens/dashboard.ts:208 renders the same client app rows but still calls doingLine(...) without the Finished line. A person on the terminal never sees what was last finished, and a fresh merge there still reads "Last change". Call clientFinished in the dashboard, show Finished <timeAgo>: <title> and pass finishedShown=true. That also lets the web and terminal share one wording. Add a test for it, and say in the README that both doors show it.
Smaller: Finished 3d ago: Fix the menu uses the abbreviation 3d ago. Spelling it out ("3 days ago", as the old Last change line did) is plainer for a client. The new finishedShown boolean parameter is a flag argument. Consider a separate pure function so doingLine stays one concept.
The terminal first screen now shows Finished 3 days ago: <title> beside the web row's line, and both doors build it with the same finishedLine() helper. tsc --noEmit, the design lint and the tests in test/client-home.test.ts and test/client-apps.test.ts pass (34 tests). I did not run the rest of the suite.
- Terminal:
src/tui/screens/dashboard.tscallsclientFinishedonce for all rows and puts the Finished line before "Working on:". A new test checks it on the terminal screen and that "Last change" no longer appears. - No flag argument: I removed the
finishedShownparameter.clientDoingsnow returns only work running now, so there's no "Last change" variant left to suppress.doingLine(doing)only words "Working on: …" andfinishedLine(finished, now)words the Finished line. - Plain age: the line uses
ago(), so it reads "3 days ago". The web row therefore no longer uses the<time>element with its exact-instant tooltip. - Existing tests: I rewrote
test/client-apps.test.tsbecause it pinned the oldclientDoings(db, ids, now)signature and its landed-this-week behaviour, which no longer exist. Its landed and recency cases now live underclientFinished(newest merge wins, however old). I also changed the "Last change" test intest/client-home.test.tsto expect Finished. - Docs: the README says both doors show both lines, and the
tell.mddesign note says the terminal uses the same words.
Does what the issue asks: each client app row gets a muted Finished <age>: <title> line from one batched query (newest merged pull, however old), the terminal shows the same words through the same helper, the old 7-day "Last change" wording is gone from both doors, and the title is escaped and cut. The design note adds no colour or size. The preview answers 200 on /. I could not read the look PNGs from this sandbox, and the preview has no signed-in client row to check.
Two things to do next:
- In
finishedLine,finished === undefined || title === ""repeats the check on the line above it. Simplify it. - The age now reads as plain text, so the exact-time tooltip the
<time>element gave is lost. Put<time datetime>back around the age on the web row if the exact date matters to a client. The terminal line can stay as it is.
Each app row on a client's first screen now has a muted line,
Finished <time>: <title>, for the app's most recently merged pull.bun test test/client-home.test.tspasses (25 tests),tsc --noEmitis clean and the design lint is clean. I did not run the rest of the suite. The new test also doesn't try the developer-word list on the Finished line itself. An existing test covers the rest of the page.clientFinished()insrc/core/client-apps.tsfetches the newest merged pull for every app in one query. There is no cutoff on age, so an old merge still shows. An app with nothing merged gets no line.src/web/studio/client_home.tsrenders the line withtime(). The title is escaped and cut to 80 characters like the existing "Last change" line.finishedServer-Timing phase.test/client-home.test.tshas two apps, only one with merged pulls. The line appears on that app only, uses the newer of two merges, escapes<b>in the title, and the response timing includesfinished. The line's text says "Finished", never "merged" or "pull".Closes #6091