feat(service,desktop): an automation's agent is named by its pull request or issue, or by the model from its prompt

Merged
DA
3d ago
+269-22

Summary

Chain F, 3 of 3 (item 17, decision 10). Stacked on #2942 (origin messages) and #2933 (the agent keeps its run).

  • Pull request and issue events get a fixed name, with no model. A run fired by a pull request or issue event (opened, labelled, updated) starts its agent already titled by its number and title, #2905 View commands. The name stays the same across pushes and matches what people search for.
  • Every other run is named by the model, from the prompt alone. That covers a schedule, a webhook, Run now, a push, or a failed check.
    • The title model reads the automation's prompt without the "Luke started this run…" lines, which would name every run of one automation alike.
    • Where a GitHub event fired the run, it also reads the event's subject (repository, number, branch, title). The subject comes first, so a long prompt never cuts it off.
  • Placeholder. Until a title lands, the agent is named by its automation (automationName, kept by #2933) rather than by its model's name. This covers the agent page's title, the Inbox's card for a planless agent, and every other place agentTabLabel names an agent.
  • agentTabLabel moves into @luke/features/model-label.ts, beside modelLabel, at chain D's request. The renderer re-exports it, so main (turn-end notices) and @luke/ui (sidebar rows) can name an agent the same way.
  • Review #2905 … for Code review isn't built: the Code review preset (#2781) isn't on main, so nothing marks a run as a review yet. It's a one-line prefix once it lands.

Desktop surface: the agent page's title only. The render below is the show harness on Linux, light and dark. CI runs on Linux only and could not verify this on the Mac.

LightDark

Evidence

  • pnpm check:affected at this stack's tip on main 635c3888: exit 0. After that run: pnpm --filter @luke/desktop typecheck clean, and desktop-inbox and title tests pass.
  • New tests. Each fails without this PR:
    • automation-runs: a run about a pull request starts its agent titled #2905 View commands, and a push's run starts it untitled.
    • title.test.ts (new): an automation's run is named from the prompt alone plus the event's branch, never from Luke's lines; the model's answer becomes the title.
    • desktop-agent-page: an untitled automation's agent is titled by its automation, not its model.
    • desktop-inbox: an untitled automation's agent goes by its automation's name in the Inbox. This is Devin's finding.

Invariants

  • ./scripts/check.sh green. (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 as type assertion.
  • No Effect.run* outside the edges.
  • No new raw async primitives.
  • No discarded Effect.
  • Test count: +4.
  • No hand-rolled file replaced.
  • No CLAUDE.md/AGENTS.md sentence names a changed part.
  • PRIVACY.md unchanged. The title model already reads the agent's first message; it now reads the automation's prompt and the GitHub subject instead.
  • Package deps unchanged.
  • Barrel/door rule unaffected.

Notes

  • Turn-end notices for one-off agents are chain D3's work. They should name an untitled agent the same way (agentTabLabel).

🤖 Generated with Claude Code