Repository navigation
fix(activity): show what Claude did to the machine, as the design draws it - #22
Merged
Merged
Conversation
The Activity tab showed what Claude Code sends the model, not what a person
can read: a subagent's hand-back headed its turn as raw `<agent-message>`
tags, a heredoc split into one "command" per script line, searches said only
"Searched the code", and tools like ScheduleWakeup read as "Used
ScheduleWakeup".
Each step now keeps a one-line summary: the description Claude already writes
for a command or subagent, or the pattern, query or page a search or fetch was
about. It costs no tokens, since Claude sends it anyway. Steps already in the
log get theirs from the input they recorded.
- A command row is titled by its description, with its commands under it.
Heredoc bodies stay part of their command, each command shows its first
line, long chains show the first three and how many more, and home folders
read as `~`.
- Searches, web calls, subagents and skills say what they were about, and
Claude Code's other tools get plain titles.
- A turn started by a subagent's hand-back or a work report is headed by its
summary ("Agent "pr-scorer" reported back"). Paste markers are taken out of
prompts.
- A main-agent step whose end was never recorded no longer reads "running…"
once its turn has ended.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ws it
The Activity tab exists so a person can see what Claude did: files it made
or changed, what it deleted, where it went online, what it installed. It now
follows design A (side panel timeline):
- What a step did to the machine leads its title: "Installed a package",
"Deleted files", "Touched a secret file", "Read a file outside the
project". Otherwise a command reads as Claude's own description in the past
tense ("Ran the tests").
- A file change shows the lines it added and removed, from Claude Code's own
patch, and a new file reads as "Added". A command that edited files shows
its lines too and counts under the Changes filter.
- A test run shows its result at the row's end ("43 passed", "2 failed"),
read from the whole output by the hook, so a long run can't lose it.
- A step the user approved in a permission dialog says "you approved".
- Web steps say where they went ("Used the internet" over the address,
"Searched the web" over the query), and a search shows what it looked for
and how many files it found. Flag chips read "web" and "outside".
- Reads in a row fold into "Read 9 files" and file changes into "Changed 3
files" with their lines added up. A folded row opens to show each step.
Flagged or failed steps never fold, so they stay in sight.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dev now takes only Claude Code's real paste format (a four-hex-digit id), so the test's made-up id was read as prose. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Testing on a real session showed what the timeline still hid:
- A subagent's steps were mixed in with the main agent's. They now sit
under the step that started the subagent, with their lines added up. A
subagent whose start isn't in view gets a block of its own.
- Claude often reads and writes through Bash. A command that names a file
in the home folder or the system's own (`cat ~/.claude/settings.json`,
`/etc/hosts`) outside the project is now flagged "outside". A command
that changed files names them ("Changed format.js, format.test.js") and is
flagged like a file tool would be.
- The step detail showed a command's result as raw JSON. The hook now
records the output itself, a change's patch or a page's text, keeping the
start and end of a long one. Older JSON results and command inputs are
shown as text too.
- Node's built-in test runner results ("ℹ pass 3") now show as "3 passed".
- A shell loop or `if` reads as one command, not one per piece.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A store already at v6 (from an earlier build of this branch) skipped the column, so the timeline failed to load. It now has a v7 step of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the second smoke run:
- An install's node_modules and git's own files no longer count as files a
command changed, so `npm install` doesn't list a package's LICENSE or add
its lines to the project's.
- A subagent's hand-back heads its turn by the task Claude gave it
("Agent "Review format.js and add test" reported back"), not its type.
- A subagent handing back reads "Reported back", not "Used
SubagentHandback".
- Claude loading its own tools does nothing on the machine, so it is left
out of the timeline and its counts.
- More of Claude's verbs read in the past tense ("Appended", "Reviewed").
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the third smoke run:
- Removing a package (`npm uninstall`, `pnpm remove`, `pip uninstall`,
`brew uninstall`, `cargo remove`, …) takes something off the machine, so
it is flagged like a delete and titled "Removed a package".
- Every verb Claude chains in a description now reads in the past tense
("Installed dayjs and checked its output"), not just the first. Words
that read as nouns after "and" ("…and test files") stay as written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code forks helpers of its own: they carry an agent id but no subagent type, since nobody launched them. One stopping a check-in loop showed up as "Subagent · unknown" with a step that never finished, though it did nothing on the machine. A helper's check-in is now left out like other housekeeping, and anything else a helper does shows under "Claude Code in the background". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A command that removed one package and installed another showed only its most serious flag. Each flag now gets its own chip, most serious first, and "reinstall" and "retry" read in the past tense. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t's launch The hook took any line with "N passed" as a test result, so a run where every test failed showed nothing and `grep passed` output got a green badge. It now reads only the summary lines vitest, jest, pytest, cargo and Node's runner print, and adds up every runner in one command (`pnpm check` counts vitest, node and cargo together). On a subagent's own event, the hook now reads the sidecar Claude Code writes beside its transcript (`subagents/agent-<id>.meta.json`) and records which launch started it, so a subagent can be tied to its launch exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…emovals Matching a subagent to the call that launched it was written three times (the store's SQL, the timeline and the live Agents panel), and the copies already disagreed. kriyon-core now owns it: `exact_launch` (the launch the sidecar names, or a background launch's agent id) before `guessed_launch` (the earliest free launch of its type). The Activity log and the live panel both use it, an exact link never takes a launch from another subagent, and a launch that names no type runs as `DEFAULT_SUBAGENT`. Removing a package is now its own step flag in core, so the frontend no longer keeps a second, already different copy of the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The store read a launch's subagent type from the kept input, which the hook cuts at 2000 characters, so a subagent with a long brief lost its type. It now keeps the type the hook sends on its own (migration v8, filled in from the kept input for older launches), with the launch facts core links by. Each read of a session's turns links its subagents once through core and sends every subagent step its launch and its name; hand-back headings use the same name. The step detail no longer sends `agentId` twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A shell loop or `if` stays one command even when nested, keeping its real separators, and a here-string or `$(( … ))` is no longer read as a heredoc. - Subagent steps nest under the step the store says launched them, and a subagent block, its launch row, its hand-back heading and the step detail all name it the same way. - ", then commit" reads in the past tense; after "then" a word is always a verb. - A background helper's unfinished step keeps "running…" after the turn. - Only the real home folder is shortened to `~`, through one helper the Details rail shares. - The step detail shows only a command step's command; other tools keep all of their input. - Spacing comes from the theme tokens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
Review and fix — pass 1First look at this pull request; reviewed and fixed in one sitting, then re-checked three times. Fixed 24 issues in 3 passes.
Notes
Fixed this pass
Checked by 5 finders (correctness, claude code rules, tests, contract, saved data, frontend rules, react lifecycle, architecture, step 5 re-check of the fixes) · architecture review · scorer: 46 scored, 24 kept. Ready to merge, as far as this review can see. Nothing is open from this pass or any pass before it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Activity tab is there so a person can see what Claude did on their machine: files it made or changed, what it deleted, where it went online, what it installed. It showed Claude Code's internals instead. A subagent's report headed its turn as raw
<agent-message>tags, a heredoc split into one "command" per script line, searches said only "Searched the code", and tools read as "Used ScheduleWakeup".This brings the tab in line with design A (side panel timeline).
What changed
~. This costs no tokens, because Claude sends the description anyway.+12 −3from Claude Code's own patch. A new file reads as "Added". A command that edited files (sed -i) shows its lines too and counts under the Changes filter.cat ~/.claude/settings.json) is flagged "outside", and a command that changed files names them ("Changed format.js, format.test.js").ifreads as one command.How
tool_response, with no extra model calls.activity_log::step_summarypicks each step's one-line summary, andreport_headingwrites the heading for a turn no person started. Both live inkriyon-coreand are unit-tested.Testing
pnpm typecheck,pnpm test,pnpm test:node,cargo fmt,cargo clippyandcargo testall pass.bashEditDiff, Grep, and vitest, cargo and pytest output), the store migration and backfill, the plain-word headings, and the timeline labels, chips, stats and folding.How I tested it
pnpm smoke) against a scratch project: installs and removals, files made and changed through Bash, tests, web lookups, a subagent, and a read outside the project. Each round's screenshot drove the next fix.Checklist
dev.pnpm checkpasses.🤖 Generated with Claude Code