Context
Terminal UI audit after the capacity redesign (commit 3c65af7). Audit covered every command that prints; per-command issues are filed separately. This issue tracks the cross-cutting standards they should converge on.
Problem
The CLI has three incompatible status vocabularies, five date/time formats, and naive pluralization, all implemented per-command:
| Command |
Status language |
Time format |
capacity |
OK / LIMITED / EXHAUSTED / UNKNOWN (colored) |
in 4h 40m · 20:25, Sep 25 · 02:52 |
status |
ready / not ready / fail / info |
— |
agent list |
🟢 run / 🟡 wait / ⚪ idle / ❓ unknown |
just now, 5m ago, 2d ago |
channel list |
enabled / stopped |
toLocaleDateString() → 6/4/2026 (machine-locale dependent) |
channel status |
yes / no |
raw ISO → 2026-06-04T19:18:06.962Z |
agent detail |
role colors |
toLocaleTimeString() |
Also recurring:
- Naive pluralization:
1 agent(s) waiting, 5 required check(s) failed, 3 location(s).
- Per-value colors implemented by string-matching rendered text (e.g.
statusStyle in status/render.ts, the text.includes("run") column style in agent.ts), which is fragile and duplicated in each command.
- JSON output emitted via raw
console.log in some commands and ui.text in others.
Expectation
- One shared status model in
packages/cli/src/util/ (e.g. status-styles.ts): a single map of status key → { label, color }, following the STATUS_STYLES pattern introduced in packages/cli/src/commands/capacity/render.ts. All commands map their domain states onto it; nothing colors by parsing rendered strings.
- One shared time util with: relative past (
5m ago), relative future (in 4h 40m · 20:25), absolute (Sep 25 · 02:52), and a now injection parameter for testability (capacity's resetLabel is the reference). No raw ISO and no bare toLocale* in command output.
- One pluralization helper (
pluralize(1, "agent") → "1 agent"), replacing every (s) construction.
- Document the standard (symbols, colors, date formats) in
packages/cli/README.md or docs/, so future commands follow it.
References
- Per-command issues:
status, agent, channel, lint, skill, memory, mutating-flow (init/install/setup/phase/docs).
- Precedent:
capacity redesign — single per-quota table, shared thresholds, humanized resets.
Context
Terminal UI audit after the
capacityredesign (commit 3c65af7). Audit covered every command that prints; per-command issues are filed separately. This issue tracks the cross-cutting standards they should converge on.Problem
The CLI has three incompatible status vocabularies, five date/time formats, and naive pluralization, all implemented per-command:
capacityOK/LIMITED/EXHAUSTED/UNKNOWN(colored)in 4h 40m · 20:25,Sep 25 · 02:52statusready/not ready/fail/infoagent list🟢 run/🟡 wait/⚪ idle/❓ unknownjust now,5m ago,2d agochannel listenabled/stoppedtoLocaleDateString()→6/4/2026(machine-locale dependent)channel statusyes/no2026-06-04T19:18:06.962Zagent detailtoLocaleTimeString()Also recurring:
1 agent(s) waiting,5 required check(s) failed,3 location(s).statusStyleinstatus/render.ts, thetext.includes("run")column style inagent.ts), which is fragile and duplicated in each command.console.login some commands andui.textin others.Expectation
packages/cli/src/util/(e.g.status-styles.ts): a single map of status key →{ label, color }, following theSTATUS_STYLESpattern introduced inpackages/cli/src/commands/capacity/render.ts. All commands map their domain states onto it; nothing colors by parsing rendered strings.5m ago), relative future (in 4h 40m · 20:25), absolute (Sep 25 · 02:52), and anowinjection parameter for testability (capacity'sresetLabelis the reference). No raw ISO and no baretoLocale*in command output.pluralize(1, "agent") → "1 agent"), replacing every(s)construction.packages/cli/README.mdordocs/, so future commands follow it.References
status,agent,channel,lint,skill,memory, mutating-flow (init/install/setup/phase/docs).capacityredesign — single per-quota table, shared thresholds, humanized resets.