Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .agents/specs/composer.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ instant, so they never move the semantic revision. Elapsed counts the primary's
opens until it ends: it carries through the gaps between steps and stops while an approval or a
question holds the turn on the user. Quiet appears after five seconds with nothing from the
primary's own events, never a child's, and says nothing while the turn waits on the user. A short
row drops effort, then quiet, then elapsed. The row opens with the mark: the Nerd Font's circle,
rounded square and square, outline then filled, in blue for the agent's own work and the
server-tool colour while a provider-run search is the work, standing still in the action-required
colour while approval is required; it moves on the one visible-only clock (MOT-1, MOT-3). The
row drops effort, then quiet, then elapsed. The row opens with the mark, from the Nerd Font's one
Material Design family: a dot grows into a circle, turns into a rounded square and a square, spins
into a diamond and shrinks away through a smaller one, lingering on the whole shapes. It is blue
for the agent's own work and the server-tool colour while a provider-run search is the work, and
stands still as the whole circle in the action-required colour while approval is required; it
moves on the one visible-only clock (MOT-1, MOT-3). The
row's right end holds the selection note (SEL-2) and the attention pill (ATT-1); while its rows are
closed the selection note rides the status row instead (ui-ux §input). Rejected: current work on
the composer's rule, which mixed the agent's doing with the user's typing.
the composer's rule, which mixed the agent's doing with the user's typing; and a mark that changed
shape at one size, or stepped evenly back along its own path, which the user found rigid.

**COM-6 — Input selection names editable source.** A click places the caret; dragging retains a
grapheme-boundary anchor, paints the source range, and release copies it through SEL-4. Typing or
Expand Down
2 changes: 1 addition & 1 deletion .agents/specs/motion.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ clock was doing.

The phase is a count, not a time: renderers derive their frame from it, so two moving things on
screen stay in step. The effort rail's marker and the activity line's mark each complete a cycle every
1.6 s, the mark at three phases a frame over eight frames.
1.6 s, the mark over seven frames holding unequal numbers of its 24 phases.
16 changes: 12 additions & 4 deletions .agents/spikes/conversation-chrome/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
Every decision below was made by the user on a rendered frame, 2026-09-21 and 2026-09-22. The
generators are in [`mockups/`](./mockups/); each writes one HTML page to
`plexmaton-conversation-chrome/` under the system temporary directory, outside this corpus, and
`spin.py`, `logo_term.py` and `cellsize.py` run in a terminal. Regenerate rather than trusting a description of them.
`spin.py`, `mark-lively.py`, `logo_term.py` and `cellsize.py` run in a terminal. Regenerate rather than trusting a description of them.

## What the user chose

| Surface | Chosen | Rejected on sight |
| --- | --- | --- |
| Activity line composition | mark, label, muted `· 32s · high effort`, `· quiet for 31s` once nothing has arrived; no token count | a red stall tell; estimated tokens |
| Activity mark | N2, the Nerd Font's circle, rounded square and square, outline then filled: chosen 2026-09-22 in a kitty window beside the Unicode cycles; the user asked for the filled half to keep it simple yet ever changing | C2′ and C2″, which shook in the user's terminal because mixed-size Unicode shapes centre differently; filled squares; braille; quarter circles; Claude Code's star |
| Activity mark | H: a dot grows into a circle, turns into a rounded square and a square, spins into a diamond and shrinks away through a smaller one, lingering on whole shapes, 1.6 s a cycle; chosen 2026-09-23 in kitty (`mark-lively.py`) after the user found N2 rigid and wanted it to grow from a point | N2, the circle, rounded square and square outline then filled, chosen 2026-09-22 and later found rigid; one size changing shape, and even steps retracing their path, likewise; a slice-by-slice sweep, which reads as progress; C2′ and C2″, which shook because mixed-size Unicode shapes centre differently; filled squares; braille; quarter circles; Claude Code's star |
| User message | band of lifted ground with a blue `›`, continuation indented | the accent bar; a bare prefix; a hairline bar; a band alone |
| Mark placement | centred in the empty conversation, name beneath, gone with the first message | a header or drawer slot, not yet asked for |
| Mark motion | K4 as the base: frame breathes between weights and drifts between palette slots; centre morphs circle, ring, rounded square, square, solid and outline | K1 to K3 as they stood |
Expand All @@ -40,8 +40,16 @@ kitty answers `CSI 16 t` with the cell in pixels; `cellsize.py` shows the reply
Material Design glyphs used, all present at one advance in Sarasa Term SC Nerd and in Symbols Nerd
Font Mono: `circle-small` F09DF, `circle-medium` F09DE, `circle` F0765, `circle-outline` F0766,
`square` F0763, `square-outline` F0764, `square-rounded` F14FB, `square-rounded-outline` F14FC,
`radiobox-marked` F043E, `record-circle` F0FEC, `circle-double` F0E95. The product already draws
its header, tally and copy glyphs from this set.
`radiobox-marked` F043E, `record-circle` F0FEC, `circle-double` F0E95, `rhombus` F070B,
`rhombus-medium` F0A10, `square-small` F0A15, `square-medium` F0A13. The product already draws its
header, tally and copy glyphs from this set.

Measured in Maple Mono NF CN, in units of a 1000-unit em on a 600-unit cell: the family's filled
shapes come at 168, 332 and 461 (the medium diamond), then 750 to 832, with nothing between, so a
mark grows in steps rather than smoothly. Its small and medium sizes and its squares share one
centre; the whole circle and diamond sit 41 units right of it, an offset nobody has seen move.
Maple Mono's own `·`, `•`, `▪`, `●` and `■` centre on the cell instead, 75 to 116 units left of
the family's, so they cannot join its cycle; `▢`, `◼` and `⬤` are not in the font and fall back.

## What the other CLIs do, read from their source

Expand Down
77 changes: 77 additions & 0 deletions .agents/spikes/conversation-chrome/mockups/mark-lively.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""C made lively: growth, a turn and a sweep, from one Material Design family. Ctrl-C to stop.

Every glyph here shares the family's centring, and each frame lasts a whole number of the motion
clock's 67 ms phases; cycles are 24 phases (1.6 s) or 16 (1.07 s), both of which the product's
clock can drive unchanged.
"""
import sys, time

TEXT, BLUE, MUTED, RESET, REV = ("\x1b[38;2;230;233;240m", "\x1b[38;2;130;180;240m",
"\x1b[38;2;142;162;196m", "\x1b[0m", "\x1b[7m")
PHASE_MS = 1000 / 15
G = dict(c_small="\U000F09DF", c_medium="\U000F09DE", circle="\U000F0765",
square="\U000F0763", rounded="\U000F14FB",
rhombus="\U000F070B", r_medium="\U000F0A10")
G.update({f"slice{n}": chr(0xF0A9D + n) for n in range(1, 9)})

SLICES = [(f"slice{n}", 1) for n in range(1, 9)]
CANDIDATES = [
("E liked: C with pace", [("c_small", 3), ("c_medium", 1), ("circle", 5), ("rounded", 2),
("square", 5), ("rounded", 2), ("circle", 5), ("c_medium", 1)]),
("H grow, turn, spin out · 1.6 s", [("c_small", 3), ("c_medium", 1), ("circle", 6), ("rounded", 2),
("square", 5), ("rhombus", 4), ("r_medium", 3)]),
("K spark · 1.6 s", [("c_small", 3), ("c_medium", 1), ("r_medium", 2), ("rhombus", 4),
("square", 4), ("rounded", 2), ("circle", 5), ("c_medium", 3)]),
("I sweep · 1.6 s", [("c_small", 4), ("c_medium", 1), *SLICES, ("circle", 8), ("c_medium", 3)]),
("H' grow, turn, spin out · 1.07 s", [("c_small", 2), ("c_medium", 1), ("circle", 4), ("rounded", 1),
("square", 3), ("rhombus", 3), ("r_medium", 2)]),
("K' spark · 1.07 s", [("c_small", 2), ("c_medium", 1), ("r_medium", 1), ("rhombus", 3),
("square", 3), ("rounded", 1), ("circle", 3), ("c_medium", 2)]),
("I' sweep · 1.07 s", [("c_small", 2), ("c_medium", 1), *SLICES, ("circle", 4), ("c_medium", 1)]),
]


def frame_at(frames, phase):
phase %= sum(hold for _, hold in frames)
for glyph, hold in frames:
if phase < hold:
return glyph
phase -= hold
raise AssertionError("unreachable")


def strip():
print(f"\n{TEXT}Frames in order, each in its own cell; the number is how many 67 ms phases it holds:{RESET}\n")
for name, frames in CANDIDATES:
cells = " ".join(f"{REV}{G[glyph]}{RESET}{MUTED}{hold}{RESET}" for glyph, hold in frames)
print(f" {MUTED}{name:38}{RESET} {cells}")
print(f"\n{TEXT}As the activity line:{RESET}\n")


def animate():
sys.stdout.write("\x1b[?25l")
start = time.time()
try:
while True:
elapsed_ms = (time.time() - start) * 1000
phase = int(elapsed_ms // PHASE_MS)
for name, frames in CANDIDATES:
glyph = G[frame_at(frames, phase)]
seconds = 12 + int(elapsed_ms // 1000)
sys.stdout.write(f" {BLUE}{glyph}{RESET} {TEXT}Thinking…{RESET}"
f"{MUTED} · {seconds}s · max effort{RESET} {MUTED}{name}{RESET}\x1b[K\n\n")
sys.stdout.write(f"\x1b[{2 * len(CANDIDATES)}A")
sys.stdout.flush()
time.sleep(0.01)
except KeyboardInterrupt:
pass
finally:
sys.stdout.write(f"\x1b[{2 * len(CANDIDATES)}B\x1b[?25h{RESET}\n")


if __name__ == "__main__":
for name, frames in CANDIDATES:
assert sum(hold for _, hold in frames) in (16, 24), name
strip()
animate()
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/agents-strip-narrow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
│transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centrali…│
│󰝦 Thinking… ( !2 ) │
│󰧟 Thinking… ( !2 ) │
│ │
── Message ─────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/agents-strip-one-column.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
│independently; this transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centralized and z-ordered. │
│󰝦 Thinking… ( !2 ) │
│󰧟 Thinking… ( !2 ) │
│ │
── Message ────────────────────────────────────────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/agents-strip-tally.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
│independently; this transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centralized and z-ordered. │
│󰝦 Thinking… │
│󰧟 Thinking… │
│ │
── Message ────────────────────────────────────────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/agents-strip-two-columns.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
│interactive. ││ │
│ ││ │
│received from Agent B · UI study · Routing stays centralized and z-…││ │
│󰝦 Thinking… ( !2 ) ││ │
│󰧟 Thinking… ( !2 ) ││ │
│ ││ │
── Message ───────────────────────────────────────────────────────────│ │
Type a message · ⇥ to focus │Controller unavailable · input locked │
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/approval-medium.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
│independently; this transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centralized and z-ordered. │
│󰝦 Thinking… ( !1 ) │
│󰧟 Thinking… ( !1 ) │
│ │
── Approval required · edit ───────────────────────────────────────────────────────────────────

Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/approval-wide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
│transcript remains interactive. ││ │
│ ││ │
│received from Agent B · UI study · Routing stays centrali…││ │
│󰝦 Thinking… ( !1 ) ││ │
│󰧟 Thinking… ( !1 ) ││ │
│ ││ │
── Approval required · edit ────────────────────────────────│ │
│ │
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/canonical-medium.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
│independently; this transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centralized and z-ordered. │
│󰝦 Thinking… ( !1 ) │
│󰧟 Thinking… ( !1 ) │
│ │
── Message ────────────────────────────────────────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/canonical-narrow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
│transcript remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centrali…│
│󰝦 Thinking… ( !1 ) │
│󰧟 Thinking… ( !1 ) │
│ │
── Message ─────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
2 changes: 1 addition & 1 deletion crates/plexmaton-tui/frames/canonical-wide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
│remains interactive. │
│ │
│received from Agent B · UI study · Routing stays centralized and z-ordered. │
│󰝦 Thinking… ( !1 ) │
│󰧟 Thinking… ( !1 ) │
│ │
── Message ─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
│󰝦 Responding… ( !1 ) │
│󰧟 Responding… ( !1 ) │
│ │
── Message ────────────────────────────────────────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
│󰝦 Responding… ( !1 ) │
│󰧟 Responding… ( !1 ) │
│ │
── Message ─────────────────────────────────────────────────
Type a message · ⇥ to focus
Expand Down
Loading
Loading