Skip to content

GitHub/Vercel notch panel and actions, terminal Claude Code sessions, reply from the notch - #280

Closed
guerraOrzc wants to merge 7 commits into
Louis-CFM:mainfrom
guerraOrzc:contrib/github-vercel-notch
Closed

guerraOrzc wants to merge 7 commits into
Louis-CFM:mainfrom
guerraOrzc:contrib/github-vercel-notch

Conversation

@guerraOrzc

Copy link
Copy Markdown
Contributor

This draft PR adds three features to the Mac app (NotchBuddy/):

  1. GitHub and Vercel: watch lists, a right-side detail panel, and actions from the notch.
  2. Claude Code sessions started in a terminal (Warp, Terminal, iTerm…) now show in the notch.
  3. Replying to a Claude Code session from the notch.

It bundles three topics, which goes against "one topic per PR". They share code: the right-side panel is used by all three, and the shared runner is used by the reply and the iPhone instructions. Splitting them means stacked PRs. Happy to do that if you prefer, along with anything else that should change. Screenshots/GIFs are still to come; they'll be added before this leaves draft.

The iPhone app, the widgets and the Windows/Linux app are untouched; the CoucouPhone scheme still builds. Pill IDs, the bundle ID and ~/.claude/settings.json handling are unchanged.


1. GitHub and Vercel in the notch

Settings

  • GitHub → Repositories.
    • Choose up to 20 repos to watch from a list loaded from /user/repos (owner, collaborator and organization member, archived repos excluded, up to 500 repos).
    • Watched repos are fetched by name in the pulse GraphQL query as aliases r0…rN, each checked against [A-Za-z0-9._-].
    • With none selected, the pulse works as before (your 10 most recently pushed repos).
    • Behavior change: with a watch list, My PRs, To review and default-branch CI only show those repos.
  • Vercel → Scope.
    • Personal account or a team, loaded from /v2/teams.
    • Every Vercel call (poller, project list, actions) gets ?teamId= through a new VercelAPI.url(_:).
    • Changing the scope clears the project filter and polls the new scope without an alert.

In the notch

  • Quick switch. The GitHub and Vercel card titles become a button (title + chevron) when there is more than one repo/project. It opens a chip picker in the right card, styled like the agent pills, with "All" plus the watched repos/projects. The choice is saved.
  • Right-side panel (SidePanelView.swift).
    • The right card can temporarily replace the agent pills with details:
      • a GitHub section (My PRs, To review, default-branch CI);
      • one Vercel deployment;
      • the PR/CI of a session's branch;
      • the reply box.
    • It closes with ✕ or Esc. It also closes on its own when the focused pill changes, the island collapses, or another view takes over (approval, question, chat), so approval and question cards are never hidden.
    • While other pills have a badge, the ✕ shows a small amber dot.
  • Actions. Every action needs two clicks: the first turns the button into "Confirm?" for 3 s.
    • GitHub: Merge (non-draft My PRs, squash), Approve (To review), Re-run failed jobs (failing default-branch CI, or a session's failing branch; it finds the latest failed run via actions/runs).
    • Vercel: Redeploy (Ready/Error), Cancel build (in progress), Promote (Ready, non-production).
    • The result shows in the panel header. They reuse the iPhone actions, moved from the iPhone-only PhoneLink/ServiceDetailRunner.swift into a shared ServiceAPI.swift, unchanged apart from the team scope.
  • Vercel deployments.
    • Builds in progress (BUILDING / QUEUED / INITIALIZING) are now kept and shown as "building…" with an amber dot. Before, only finished deployments were listed. The poller fetches 20 deployments instead of 5.
    • A failed deployment shows why it failed: its errorMessage, else the most specific error line of its build log (v3/deployments/{id}/events, terminal color codes stripped).
    • Alerts still fire once per finished deployment of a watched project.
    • The iPhone snapshot shows builds in progress as a warning.
  • Session → PR and CI.
    • Next to a workspace session's name (Claude Code, Cursor), a chip shows the open PR of the session's branch (#12 + CI dot), or the branch name.
    • The branch comes from the session folder's .git, read as files (GitRepoInfo.swift, no git process); worktrees and gitdir: files are followed.
    • The PR lookup (SessionGitHubLinker.swift) passes the repo and branch as GraphQL variables. It keeps only PRs whose head repo is the origin repo, so a fork's same-named branch doesn't match.
    • It runs only while the island is open on that session: at most once a minute, every 30 s while CI is running.
    • The chip opens a panel with: the PR + Merge; or "No open pull request" + an "Open PR" compare link; the branch checks + Re-run; and the branch's Vercel deployment.
  • PR → Vercel preview. In My PRs, a small Vercel mark opens the preview deployment built from the PR's branch.

Behavior changes to existing views (CLAUDE.md asks not to restyle shipped views without being asked, so flagging them here):

  • The Vercel card's left-side detail (VercelDetailView) is replaced by the right-side panel, and every deployment row can be tapped.
  • The GitHub and Vercel card titles can show the focused repo/project.
  • Vercel polling now runs only while the Vercel pill is active (or iPhone sync is on), instead of whenever a token is saved.

2. Claude Code sessions started in a terminal

Until now, hook events not coming from VS Code or Cursor were dropped ("Ignored … from WarpTerminal" in nb.log). Sessions in Warp, Terminal, iTerm, Ghostty, kitty, Alacritty, WezTerm, Hyper and Zed (ClaudeHost.swift, matched on __CFBundleIdentifier, else TERM_PROGRAM) now route to the existing integration_claude pill:

  • The pill shows steps, diffs, finished state, and the branch chip.
  • The pill reads "Claude Code" (VS Code sessions keep "VS Code").
  • Its open button brings the terminal forward ("Open Warp").
  • Notes say "Handled in Warp."

Questions and permission requests from terminal sessions stay in the terminal by default. The --ask and PermissionRequest hooks hold the request until the notch answers, so showing them in the notch would make the terminal wait. A new setting under the Claude Code hooks, "Answer questions and permissions from terminal sessions in the notch" (off by default), lets terminal users opt into the VS Code behavior. When it is off, the request is answered with ask at once.

Like VS Code today, the pill follows the most recently active session.

3. Replying to a session from the notch (GitHub build)

  • A ↰ chip next to the session name opens a reply box in the right card.
  • Return sends the message with claude -p --resume <session id> -- <text> in the session's folder, in the background, through a new SessionResumer.
  • InstructionRunner (iPhone instructions) now uses the same runner, so it gains terminal support, and the -- fix: a message starting with - is never read as an option.
  • The session ID, folder and terminal come from the hooks (AppState.claudeSessions), never from the UI.
  • The environment is set so the run's hooks land on the same pill. Hooks keep working, so the turn shows in the notch like any other, and permission prompts still need a click.
  • Sending is blocked while the session is working or waiting for an answer.
  • While the box is open, the island doesn't auto-collapse, and ⌘ + arrows move the cursor instead of switching pills.
  • A failed run shows "⚠ Reply failed: …" as the session's last line.
  • Limitation: the turn runs in a separate process, so the terminal or editor the session was started in doesn't show it. The reply box says so.

Not in the App Store build: it can't start claude and can't read .git in the sandbox, so it has neither the reply box nor the session chip.


Not done / known limits

  • Localization: new strings are English only. They are plain SwiftUI literals, so they can be added to Localizable.xcstrings, but no translations are included.
  • Session PR lookup: it queries the origin repo only, so PRs opened from a fork into upstream aren't found.
  • Preview matching: it looks at the 20 most recent Vercel deployments.

Testing

  • Builds: NotchBuddy (Debug, and Debug with PHONE_LINK), CoucouAppStore (CODE_SIGNING_ALLOWED=NO) and CoucouPhone (iOS Simulator) build on Xcode 27.
    • A clean build has no warnings on any line this PR adds or changes. The 44 warnings it prints are already on main.
  • Tests: all 13 scripts/test-*.sh pass, including these new ones:
    • test-claude-host.sh (terminal detection, labels, the setting is off by default);
    • test-git-repo-info.sh (remote URLs, HEAD, config, worktrees);
    • additions to test-github-pulse.sh (alias parsing, repo filtering, SessionBranchInfo including the fork case).
  • Checked live:
    • The pulse query with aliases and the session-branch query, against the GitHub API (read-only).
    • The session lookup finds the right PR, and skips a fork PR with the same branch name.
    • Warp hook events reach the Claude Code pill.
    • With the setting off, a permission request from Warp gets ask immediately.
    • claude -p --resume <id> -- "--…" continues a session, including a message that starts with --.
  • Not tested yet: the Vercel failure reason on a real failed deployment.

🤖 Generated with Claude Code

guerraOrzc and others added 7 commits October 6, 2026 00:39
…ide panel

- Settings: pick the GitHub repos to watch (up to 20; none = the 10 most
  recently pushed) and the Vercel scope (personal account or a team).
  Vercel calls, iPhone actions included, now pass teamId.
- Notch: the GitHub / Vercel card title picks the repo or project in focus,
  as chips in the right card. Alerts still cover every watched item.
- Right card: PR lists, default-branch CI and deployment details open in
  place of the agent pills, which come back on ✕, Esc, a focus change, the
  island collapsing, or an approval/question.
- Vercel list honours the project filter; Vercel stops polling while its
  pill is off (unless iPhone sync is on); a scope change doesn't alert.
- Pulse query moved to GitHubPulse.query(watched:), with tests.
- project.pbxproj regenerated with XcodeGen 2.46 (adds SidePanelView.swift).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…right panel

- GitHub panel rows: Merge (my non-draft PRs), Approve (reviews asked of
  me), Re-run failed jobs (failing default-branch CI, latest failed run).
- Vercel deployment panel: Open, Redeploy (ready or failed), Promote
  (ready, not already production).
- Every action needs a second "Confirm?" click; the result shows in the
  panel header and the data refreshes.
- ServiceAPI moved out of the PHONE_LINK-only ServiceDetailRunner into
  ServiceAPI.swift so the notch and the iPhone share one implementation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… → preview

- Vercel: builds in progress are kept (amber, "building…"), with Cancel
  build in their panel; the finished alert fires once per finished
  deployment, including one that was building. A failed deployment's panel
  shows Vercel's errorMessage, else the most relevant build-log line.
- Claude Code sessions: GitRepoInfo reads the repo and branch from the
  session's .git (worktrees included); SessionGitHubLinker looks up that
  branch's open PR and CI while the island is open on the session (GraphQL
  variables, fork PRs with the same branch name ignored). A chip next to
  the session name opens a panel with the PR (Merge), the checks (Re-run)
  and the Vercel preview.
- My PRs: a ▲ opens the PR's Vercel preview when one matches its branch.
- iPhone: builds in progress read as "Building", not as failures.
- Tests: GitRepoInfoTests (+ scripts/test-git-repo-info.sh), SessionBranchInfo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Claude Code sessions run in a terminal (Warp, Terminal, iTerm, Ghostty,
  kitty, Alacritty, WezTerm, Hyper, Zed) now route to the Claude Code pill,
  including approval and question cards. The pill says "Claude Code" and its
  open button brings the terminal forward (ClaudeHost).
- Reply panel: continue the focused Claude Code session from the notch with
  `claude -p --resume` in the background. SessionResumer is shared with the
  iPhone instructions and keeps the hooks on the same pill and host.
- The session branch/PR chip now also shows on the Claude Code pill's card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Session → PR/CI never ran: the linker skipped integration tasks, and every
  Claude Code pill is one. The branch chip, its panel and the preview row now
  work on the Claude Code pill.
- Vercel panel: the failure reason is looked up again when a build fails
  while the panel is open.
- Reply panel: the island no longer auto-collapses while it is open, ⌘ +
  arrows move the text cursor instead of switching pills, and the message
  goes after "--" so text starting with "-" isn't read as an option.
- "No failed run to re-run" shows as a grey notice instead of a success.
- A production deployment on the session's branch is labelled Production.
- Vercel: a poll answer from the previous team scope is dropped.
- Settings: the repository list loads up to 500 repos (5 pages).
- Cleanup: unused TurnRecorder.lastSession removed, doc comments fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- New setting (off by default): "Answer questions and permissions from
  terminal sessions in the notch". Off: terminal sessions still show in the
  notch, but their questions and permission requests go straight back to the
  terminal. On: the notch shows them first, as for VS Code.
- Approvals and questions from a terminal no longer flip the Claude Code
  pill back to "VS Code" (the host was dropped on those paths).
- A failed reply from the notch shows "⚠ Reply failed: …" as the session's
  last line instead of only an error sound.
- The branch/PR chip now works for every workspace session with a folder,
  Cursor included.
- ClaudeHost no longer depends on AgentTask; new tests
  (scripts/test-claude-host.sh); deprecated activation call replaced;
  misplaced doc comment fixed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts: HookServer notes and approval routing (kept Copilot CLI and Muse
Code alongside terminal sessions), the localized "Watching %lld of %lld"
label (kept with the repo limit), project.pbxproj regenerated with XcodeGen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@guerraOrzc

Copy link
Copy Markdown
Contributor Author

Split into three PRs, one topic each as CONTRIBUTING asks:

The code is the same as here; #283's branch has exactly this PR's files.

@guerraOrzc guerraOrzc closed this Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant