feat(panel,service): a head on a fork is named owner:branch, as GitHub names it

Merged
DA
5d ago
+103-6

Built on #4156 (header polish), now merged; this PR targets main.

Summary

The developer asked that a head branch from a fork show owner:branch the way GitHub does. The overview's wire didn't carry the head's owner, so this small PR adds it, split out from #4156 because it changes the hosted service.

  • Wire (@luke/features/coding-agent-wire): the overview's pull request gains an optional headOwner, the account whose fork the head stands on. It's absent for the repository's own head, and absent from a service before this change, so an older service still draws the branch alone.
  • Service (pull-requests.ts): the overview read takes head.repo.owner.login and sets headOwner only when the head's repository differs from the base's. That's the same cross-repository test the stack read already uses.
  • Panel (pull-request-branches.tsx): the head chip names and copies octocat:patch-1, its name "Copy branch octocat:patch-1".

Screenshots

LightDarkHovered
fork head, lightfork head, darkfork head hovered

Evidence

  • vitest: pull-request-overview.test.ts (service), github-people.test.ts, coding-agent-wire.test.ts: 25 tests pass. The fork test in the PR tab passes.
  • tsc for @luke/features, @luke/service, @luke/panel: pass. ./scripts/oxlint.sh: 0 errors. ./scripts/repository-checks.sh: pass.
  • JSON Schema goldens: the two overview pull request answer goldens (coding-agent-wire-…AnswerSchema.json, coding-agent-view-…AnswerViewSchema.json) were re-recorded with LUKE_UPDATE_FIXTURES=1. Each gains only the optional headOwner (a string up to 255) beside head, and nothing joins required. These are HTTP answer schemas, not a model's tools, so no prompt cache is affected.
  • New tests (+2):
    • pull-request-overview.test.ts: a head on a fork names the fork's account; one on the repository itself names none.
    • agent-pull-request-tab.test.ts: a fork's head chip is named, shown and copied as owner:branch.

Notes

  • Hosted service change, so per docs/WORKFLOW.md it needs a ./scripts/run.sh --preview run against this PR's Vercel Preview before it merges. Open a PR from a fork, or any PR, and check that the header's head chip reads owner:branch for a fork and the bare branch otherwise.
  • The field is optional both ways: a new desktop on an old service draws the bare branch, and an old desktop ignores the field.