Commit Graph
17 Commits
Author SHA1 Message Date
Codeman maintainer b98deebafc feat(story-mode): a plain Simple caption on every panel
Story Mode gets a third reading level for someone who has never seen a
terminal (a parent, a manager). Every panel now carries caption.simple:
one short sentence in everyday words, with no file name, command, tool
name, flag or jargon. The sentences are templates only, so nothing from
the transcript (a path, a commit message, a branch) can reach them, and
they are written from the same facts as the story caption: a failed
check never reads as a pass, a failure you asked for says so, and a
check that fails after one passed is a failure again.

The final panel's simple caption is a plain summary: how the turn ended
and roughly how long it took, how many files changed, whether the checks
pass, whether the work is saved (only claimed "not saved" where saving
is in play: you asked for it, or the turn used git), and what the reader
must not miss (a problem left, a note, a question for them).

test/story-plain-words.ts is the guard: the corpus test runs it over
every panel of every page of the eleven sessions, and the unit tests
cover the honest endings (failed check, catch, note, question, stopped,
not done, to be continued, done for now) and the guard itself. The
corpus expectations only gain "simple" lines.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 05:17:31 +02:00
Codeman maintainer dc980d121c fix(story-mode): a new file counts what it ends with, a rewrite is a change, short endings are read (review round 11)
From the fact-checker:
- A script created and then edited in the same panel showed "+95 -3":
  a file created in the span counts what it ends with, never lines
  removed from its own draft (+92), on the badge, the panel and the page.
- "Claude writes 4 files" for files an earlier panel wrote and this one
  rewrote with here-documents: writing a file the turn already touched is
  changing it.
- "Claude says: Compacted": a local command's output is the CLI's own,
  a note, not Claude's words.
- "The CHANGELOG helper is still running" was dropped under "Mission
  complete!": key sentences were read only in endings over 160
  characters; a short ending is read too, and that one is a note.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 17:47:44 +02:00
Codeman maintainer d3c55e04a3 fix(story-mode): what the captions blurred for a reader who skims (review round 11)
From an engineering manager skimming titles and captions:
- "but a check after that fails" under "Mission complete!" where the
  prompt said that step may fail now adds ", as you said it might".
- Saves no prompt of the turn asked for (a project rule, or Claude's own
  idea) were indistinguishable from requested ones: the turn's first such
  save carries a small line, "a save your prompt here did not ask for".
  "save its log with tee" no longer counts as asking to save the work.
- The first save on a branch Claude created says which: "saves the work
  on a new branch (feat/csvstat)".
- "Claude changes 3 files" hid an edit to your CLAUDE.md: a panel that
  wrote some files and patched others says both ("Claude writes
  README.md and .gitignore and changes CLAUDE.md."); a file created and
  then edited in the same panel is written.
- A turn with a problem left and work still out read "Done for now";
  the catch now wins the title.
- A helper's report that is only a path reads "reports back with the
  file it wrote: README.md."

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 17:44:06 +02:00
Codeman maintainer 30b907860d fix(story-mode): whose idea a failure was, new repositories everywhere, honest counts (review round 10)
From the person who asked and a fact-checker, reading fresh pages:
- "as planned" for failing first runs the prompt asked for ("it should
  fail because mode is missing", "run them to watch them fail"): those
  read "The first run fails on purpose, as you asked".
- A repository Claude started was told only on a save panel; the first
  save inside a loop or a test run says it too ("Claude starts a git
  repository and saves the work in 4 commits along the way.").
- `git push && git describe --tags; echo "exit=$?"` exits 0, so a
  failure after the push went unsaid; what it printed after the push
  (`fatal:`, `exit=128`) now counts. The commit subject stays on that
  caption too.
- Tool-call counts no longer include second opinions.
- "a layout check" is "a formatting check"; "Turn over" (a game word)
  is "Not done".
- "the last check finds nothing" told nothing: it now says what came
  back empty ("the last one finds a git setting that is not set, which is
  no error").

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 17:16:03 +02:00
Codeman maintainer f46369a5af fix(story-mode): last words in context, the check after a push, a fresh copy (review round 10)
From the person who asked for the work, reading fresh pages:
- "The result was 4 passed, 1 failed" under "Mission complete!" read as
  a failing end. A test count is no failed step, and Claude's second
  sentence is kept when it is the outcome ("All 5 tests now pass, and the
  change is committed.").
- "Two places where I didn't follow your wording:" showed one. A list
  intro that announces how many brings that many lines.
- "…would fix it for up to 10 files. Want me to add that?" never said
  what "it" was. An offer that points back brings the start of its
  paragraph ("Suffix swap: the two files with the same time would trade
  their _1 suffix. …").
- "Decisions you may want to change" is something for you, like an offer.
- A second opinion whose call failed read as given; it now reads "after
  trying to ask … (no answer came)".
- "but a step after that fails" after a push sounded as if the push
  broke: when everything after it only looks (git log, status), it is "a
  check after that fails".
- Tests run in a fresh clone read "The tests pass in a fresh copy made
  from remote.git."

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 16:59:29 +02:00
Codeman maintainer 70b1ebcc19 fix(story-mode): name the files, say when a repository is new, and when a push stayed on this computer
From review round 9 (a newcomer to the project):
- One or two files are named, not counted: "Claude writes .gitignore and
  saves the work", "Claude changes rename_by_date.sh.", "Claude writes
  the new files mathx.py and test_mathx.py." Three or more are counted.
- The first save in a folder Claude turned into a repository says so:
  "Claude starts a git repository and saves the work: …". A `git init
  --bare` (the push target) does not count, nor a folder that already
  had commits.
- A push to a repository in a folder on this computer (`To ./origin.git`)
  is a copy, not an upload: "then copies it to origin.git, a folder on
  this computer", and the final chip reads "copied to origin.git".
- A tool lookup for plan mode reads "Claude gets ready to plan."

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 16:11:13 +02:00
Codeman maintainer a80638308b fix(story-mode): a second opinion is a line in the next panel, not a panel of its own
From review round 9: "Claude asks a stronger AI model for a second
opinion" stood as a whole panel on almost every page, and the reader
never learns what it said (the answer is encrypted). An advisor call now
rides on the panel of the step after it (or the last one, when nothing
follows), counted in `secondOpinion`: a small line under the caption,
"after asking a stronger AI model for a second opinion" ("then asks…"
when it came last), and "· after 1 second opinion" in the Director's
cut. Pages lose a panel of noise and keep room for the work.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:49:45 +02:00
Codeman maintainer 555efef53d fix(story-mode): name the check that failed, say whose plan a failure was, and when background work finished
From review round 9:
- "another check" was too vague to act on. A check other than the tests
  is named by its tool: a layout check (a formatter), a style check (a
  linter), a type check, the build. "Fix and test, 2 rounds: a test fails
  and Claude fixes it, then a layout check fails and Claude fixes that;
  everything passes."
- A failure the prompt asked for reads "The first run fails on purpose,
  as you asked; the second passes." ("The tests don't even load, as you
  asked."); one Claude planned itself keeps "Test first: … as planned".
- A test run sent to the background that reported in a later turn reads
  "Claude starts the tests in the background; later they pass.", not as
  if they passed in that turn.
- The test board says "1 test" and, when nothing loaded, "1 error".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:45:17 +02:00
Codeman maintainer 59d70caeb3 fix(story-mode): Claude's last words keep the sentences aimed at you (review round 9)
Two fresh cold readers (the person who asked for the work, a newcomer to
the project) found the round-8 balloons still cut exactly where Claude
turns from describing to asking, offering or warning: "Want me to add
that?", "I can fix the number format whenever you want", the
http.server instruction, the fix that followed a reported bug.

Key sentences are now picked by kind, one of each, at most three, and
shown in the order Claude wrote them: a problem left (with the fix right
after it, when there is one, so it never reads as open), a question or
offer, how to use what was built, something not done or checked yet, a
step that failed, a word on what you asked for, a corrected warning. A
list intro is judged on its own words and brings its first items; a
pointer ("described below") is skipped; a short offer brings what
"that" was.

The final panel reads "Done, with a catch" for a problem left, "Done,
with a note" for something pending, and "Done, with a question" when
the next move is yours (`openNote` is now 'catch' | 'note'; `asks`).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:41:57 +02:00
Codeman maintainer e892278abc feat(story-mode): a run panel shows what its command printed
From review round 8: you asked to see a dry run, Claude's balloon said
"Here's the dry run you asked for", and the page showed nothing of it.
A run panel's terminal card now prints, dimmer under the commands, the
first lines its last command printed (the last ones when it failed:
that is where an error is).

The card is drawn on the canvas, so it goes into a saved image someone
may share: a line that looks like a secret (token, password, api key,
credential, inside identifiers too) is left out, addresses and long
token-like strings are masked, and Claude Code's own markers ("(Bash
completed with no output)", tool-error tags) are dropped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:32:36 +02:00
Codeman maintainer 88040c997d fix(story-mode): no celebration when the turn is not a clean finish
From review round 8: "Mission complete!" with confetti and cheering
helpers sat over balloons saying the page will not work as opened, a
helper's tests have not run, or a problem is left. The final panel is now
calm (no confetti, a neutral robot) whenever work was still out at the
turn's end, nothing worked, or Claude's last words name an open problem
(`page.openNote`: a key point about something wrong, not done, not
checked or not fixed); the last of these reads "Done, with a catch".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:23:19 +02:00
Codeman maintainer 6a7d8393dc fix(story-mode): what the cold readers believed that was not so (review round 8)
Two agents read only the comic of the eleven recorded sessions (one who
has never written code, one engineering manager skimming), wrote down
what they believed, then compared with the transcripts. Both were misled
in the same places, and the cause was the same: the final panel kept
Claude's first sentence or two, and what a reader must not lose sat
further into its last message.

- Claude's last words now keep key sentences from anywhere in its final
  message (read in full, past the label's clip): an open problem or a
  quirk, something not yet done, checked or confirmed, work still out,
  what you asked for or expected, a correction of an earlier warning
  (with the sentence it refers to). A bare "I didn't" counts only when
  nothing stronger is there; table rows, list intros and questions never.
  "I built the pomodoro timer. Opening the page: it won't work if you
  double-click index.html…"; "…That note makes the current behaviour
  clear, but it doesn't fix it."; "As you expected, git describe --tags
  then failed because the repo has no tags."
- A turn that ended with helpers or a background command still out says
  so: "Done for now", and "Claude's part is done in 36 seconds. Its 2
  helpers finished later and reported back." (`finishedLater`).
- A failure you asked for, or that Claude said it expected, reads as the
  plan: "Test first: the first run fails as planned, the second
  passes.", "The tests don't even load, as planned." A loop that failed
  once on a test and once on another check says both, and the commits
  made inside a loop are part of its story; the final panel counts the
  turn's commits ("5 commits, uploaded").
- One or two files read are named ("Claude checks README.md." in a
  turn a report started); a tool lookup reads "Claude gets the tools it
  needs ready." again (it was overwritten) without its query; the
  advisor is "a stronger AI model", and one that answered with an error
  "gets no answer"; a commit message loses its `feat:` prefix in the
  plain caption.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 15:17:54 +02:00
Codeman maintainer 76d5c61eda fix(story-mode): a three-row bar on phones, buttons for panels out of view, loop words that match the marks
- The bar on a phone took four rows (216 px of a 664 px screen) with the
  close button alone on the last; it now takes three (170 px): title and
  close, the turn, the view and Save image. The drawer starts exactly
  under it and follows it when the phone turns (the bar is observed).
- A panel below the fold had no buttons until it was scrolled to (only
  drawn panels get click regions), so Tab skipped it. A quiet frame now
  draws one such panel, a band at a time; its entrance still plays when
  it comes into view.
- "Fix and test: the first run fails, the second passes." was chosen by
  rounds, so a loop with three runs (a failing test, then ruff, then a
  pass) said it under ✗ ✗ ✓. It now needs exactly two runs; that loop
  reads "Fix and test, 2 rounds: 2 runs fail, then it passes.", and the
  corpus pins every loop's marks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 12:50:40 +02:00
Codeman maintainer 3f1ecfe83a fix(story-mode): a phone you can use with a thumb, and saves that say what they saved
From review round 5 (a phone with touch):

- Touch screens: every control at least 44 px (prev/next, close, the
  Story/Director's cut toggle, Save image, the final panel's chips, drawer
  buttons and links), and the small type at 13 px.
- The drawer on a phone starts below the bar (it cut through it), closes by
  dragging its head down, and keeps its head small in landscape.
- The turn picker says where you are ("Turn 2 of 5"), learns about new
  turns while you look at an older one, and a turn you picked yourself is
  not announced as news.
- A check whose command also wrote files offers "See the 2 files it wrote".
- Test counts are read from the whole output: a later command's lines had
  pushed pytest's "5 passed" out of the kept tail.
- A save names its commit: "Claude saves the work: "feat: add wrap() for
  modular wrapping into a range"." (from -m, -am, --message or the
  here-document of git commit -F -; a trailer is never the subject).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 12:43:59 +02:00
Codeman maintainer 814bec739d fix(story-mode): what a non-technical reader would believe, from the cold-reader review
Review round 5 had an agent read only the comic of the nine real sessions
(20 turns), write down what it believed happened, and only then compare
with the transcripts. Three panels told it something false, one hid the
failure the user asked to see:

- A push that went through, followed by a check that failed in the same
  command, drew as a failed push; the output (`[new branch]`, `->`) now
  decides: "Claude saves the work in 2 commits and uploads it, but a step
  after that fails."
- A formatter's "would be reformatted" preview, printed before it fixed
  the file, made a clean run a failure: the last verdict wins.
- A blocked command ended in confetti and "Mission complete!": a run panel
  where everything failed says "Claude tries a command, and it is
  blocked.", and a turn where nothing worked ends "Turn over" / "Nothing
  Claude tried worked, so the job is not done." with a neutral robot.
- The loop stamped only the final verdict (POW ×2), so a first run that
  failed on purpose never showed. It now marks every test run red or green,
  and says it: "Fix and test: the first run fails, the second passes." /
  "Build and test, 4 rounds. A check fails once, then everything passes."

Also:
- Files written inside a check or a save reach the plain caption ("Claude
  writes 4 files; the tests pass.").
- Balloons keep the next sentence when the first reports a problem ("…left a
  stray file. I'll remove it…") or is very short ("Not done. The harness
  blocked sleep 65…"); Claude's last words keep a caveat that follows them
  ("Nothing is committed because this folder isn't a git repository.").
- The advisor never shares a panel with helpers that do work; ToolSearch
  reads "Claude gets the tools it needs ready."; Codeman's own case file is
  not drawn as a file Claude read; looking around shows what Claude meant
  (the call's description), not raw commands; a montage at the start of a
  turn reads "Claude gets started".
- Words: boards count tests ("19 tests"), "uploads it" replaces "sends it
  up", and the prompt balloon keeps 400 characters.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 12:32:40 +02:00
Codeman maintainer 0effbb9ce4 perf(story-mode): no long tasks while stepping through turns; the rest of review round 4
Stepping through 40 turns made 46 long tasks of 51 to 286 ms, enough for
the app's guard to drop the terminal's WebGL renderer for the rest of the
page's life. Drawing switched off made none: the cost was canvas raster at
paint time, which the per-frame JS budget never saw. Now:

- Panel backgrounds are shared between panels and turns (kind × size ×
  palette), and a new one is built in four bands, one per frame (a wide
  halftone at 2x was ~35 ms in one go; a band is ~8 ms).
- At most two panels are drawn per frame, the first one served rotating so
  none starves; clocks still run for all.
- Measured on 20 turns stepped 40 times at 2x: 1 long task (52 ms), against
  39; the settled overlay is still ~2% of a core.

Also from round 4:
- The turn picker says when older turns were not loaded (`older` in the
  response: the transcript is longer than the part that was read).
- A compaction after the last turn closes that turn; a local command's
  output is the final panel's balloon ("Compacted"), without its markdown
  ticks, and a turn under a second reads "Done.".
- Exact durations keep their seconds past an hour, so the two captions never
  disagree on the minute ("1 h 10 min." / "1 h 9 min 39 s").
- A turn that arrives already finished is announced as new too.
- Whole files written by here-documents read "Claude writes 3 files."; the
  advisor's caption reads "a second opinion" instead of repeating its name.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 12:11:54 +02:00
Codeman maintainer f464548541 test(story-mode): real sessions as a regression corpus
Nine transcripts from the review rounds, each a real Claude Code worker
building a small program (a Python CLI with a fix loop, a web page with
node:test, a bash script with a background helper, a long turn with a
prompt added mid-turn, teammates then an interrupt, a question then tests
first then a push, a text plan with a scratch dry run, /compact then plan
mode, a test failed on purpose). Each is cut down to the lines and fields
the reducer reads, with every path, user name and email rewritten and the
file contents of Reads left out; replaying them before and after gives
the same pages.

The expected file beside each pins every page (panel kinds, captions,
balloons, counts), so a change that alters a story fails with a diff of
exactly what changed; STORY_CORPUS_UPDATE=1 regenerates them. The beats
the reviews were about are also stated outright.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 11:45:41 +02:00