feat(desktop): a transcript opens on its origin, sent by the automation, task, or agent it came from
Merged
DA
3d ago+0+0+0123456789-0-0-0123456789
Summary
Chain F, 2 of 3 (items 14–16). Stacked on #2933, which keeps the run on the agent.
What an agent was handed now opens its transcript as a message sent to it. It stands at the right like a sent message, under the sender line every teammate's message has. The card itself stays folded under its title and holds the prompt alone.
| Transcript | Sender line | Pressing the sender |
|---|---|---|
| A task's agent | The task, by its document glyph and name, then "· started by ". The starter is never shown as the reader, matching today's message rule. | Opens the plan (the column's Plan tab). Its hover card is the task's sidebar card (planCardOf). |
| An automation's agent | The automation (ACT_KIND.AUTOMATION tile), then the pull request a GitHub event named, then "· Run by " for Run now. | Opens the automation's page. Its hover card is the existing AutomationCard. The pull request opens on GitHub. |
| A worker's tab | The agent that delegated it. | Opens that agent's tab and centres the delegation's row. |
Special cases:
- Nothing to open. Where the window can't open the automation, the sender is plain text, with no press and no card. That covers a deleted automation ("Flaky test sweep (deleted)", the name F1 keeps), someone else's personal automation, and the Automations experiment being off.
- No Open button. Per Dean's tweak, the sender is the only link.
- Webhook body. It folds inside the card under its own "Webhook body" line. It is never in the sender line.
- Same-agent automations. Later runs still arrive as ordinary messages from the automation. Only the first message becomes the card.
- Nested origins. Only one hop: a worker names its parent agent, not the automation behind it.
- Find and Copy transcript. Both work unchanged. The card folds on the transcript's own
Fold, which ⌘F already opens. Copy transcript still copies the whole brief. - Agent page. The page now stands an
AutomationDirectoryfor its agent's workspace, so the automation can be found and opened from there.
Renders: the real renderer in the show harness on Linux (fonts are SF Pro stand-ins, so ⌘ draws as a box), cropped to the transcript. The composer's lazily loaded editor isn't built in the harness, so it's cut off.
| Light | Dark | |
|---|---|---|
| Code review on a pull request, card open | ![]() | ![]() |
| Run now | ![]() | ![]() |
| Webhook body folded inside the card | ![]() | ![]() |
| Deleted automation, plain | ![]() | ![]() |
| A teammate's task agent | ![]() | ![]() |
CI runs on Linux only and could not verify this on the Mac.
Evidence
pnpm check:affected: exit 0.pnpm exec vitest run --project desktop: 124 files and 944 tests passed, before the two lint-only test fixes.- New tests. Each fails on main, where no
.agent-origincard exists:origin-senders.test.ts:- A task's agent opens on its plan sent by the task, with the teammate who started it; pressing the task opens the Plan tab.
- The reader's own agent shows the task alone.
- A worker's tab is sent by the parent agent; pressing it opens that agent's tab.
desktop-agent-page.test.ts:- An automation's agent shows the prompt alone, without Luke's lines; pressing the sender opens the automation's page.
- A deleted automation is named plainly, and so is one whose experiment is off.
- The GitHub subject link opens the pull request, and Run now reads "Run by you".
- A webhook body stays inside the card's fold and out of the sender line.
- One existing test's selector now skips the origin card, since that card also has a sender line.
Invariants
-
./scripts/check.shgreen. (CI) - JSON Schema goldens unchanged.
- Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
- Gateway envelope goldens unchanged.
- No new
astype assertion. - No
Effect.run*outside the edges. - No new raw async primitives (the worker's seek uses
focusSeek). - No discarded Effect.
- Test count: +8.
- No hand-rolled file replaced.
- No
CLAUDE.md/AGENTS.mdsentence names a changed part. -
PRIVACY.mdunchanged. The webhook body is shown only in the run's transcript, which carve-out D10 allows, and the whole tab is alreadyph-no-capture. - Package deps unchanged.
- Barrel/door rule unaffected.
Notes
- Copy-link workspace: told L12 that the origin card is
PlanCardand that message ids are unchanged.
🤖 Generated with Claude Code









