Skip to content

⛔ DO NOT MERGE — feat: upgrade @agent-relay to 8.3.0, wire headless spawn routing and runtime tracking#139

Draft
khaliqgant wants to merge 5 commits into
mainfrom
claude/relay-8.3-headless-runtime
Draft

⛔ DO NOT MERGE — feat: upgrade @agent-relay to 8.3.0, wire headless spawn routing and runtime tracking#139
khaliqgant wants to merge 5 commits into
mainfrom
claude/relay-8.3-headless-runtime

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

@khaliqgant khaliqgant commented Jun 7, 2026

What this PR does

  • Bumps all @agent-relay/* packages to ^8.3.0 which ships SpawnCliInput and the headless runtime discriminator ('pty' | 'headless')
  • Routes Claude and Codex spawns through spawnCli({ transport: 'headless' }) instead of spawnPty() — no PTY process is created for these agents
  • Tracks each agent's runtime ('pty' | 'headless') per session in BrokerManager.agentRuntimes; attachTerminal skips PTY snapshot/resize for headless agents
  • Tightens BrokerListAgent and BrokerAttachTerminalResult types to 'pty' | 'headless'; propagates runtime through agent-store
  • Terminal config improvements: lineHeight: 1.2, letterSpacing: 0.5, bar cursor, 10k scrollback, alt fast-scroll, macOptionIsMeta
  • Tab switching changed from instant display:none to 150ms opacity fade

Critical gap — structured output rendering is NOT in this PR

Changing from spawnPty to spawnCli stops creating a PTY process, but the output pipeline is unchanged: relay still emits worker_stream events → broker forwards raw chunks to renderer via broker:pty-chunk → xterm renders them verbatim.

For Claude headless agents, those chunks are raw NDJSON from --output-format stream-json. xterm currently displays the raw JSON, not formatted text. This is not the intended end state.

Blocker: relay 8.3.0 not installed

package.json has been bumped to ^8.3.0 but the lockfile still pins @agent-relay/harness-driver at 8.1.2. spawnCli() does not exist at runtime until npm install is run and committed. This must be done before this PR is mergeable.

V1 plan (next PR after this merges)

Intercept broker:pty-chunk events in the renderer for headless agents and parse the structured format before sending to xterm:

  • Claude: parse NDJSON stream-json events; extract content_block_delta.text from { event: { type: 'content_block_delta', delta: { type: 'text_delta', text: '...' } } }; emit clean text only
  • Codex: parse app-server protocol events (AgentMessageDelta, FileChangePatchUpdated, ApplyPatchApprovalParams)

Result: xterm shows nicely formatted human-readable output with no raw JSON visible.

V2 plan

No xterm at all for headless agents. Replace the terminal pane with custom React components — message bubbles, file-diff cards, approval dialogs — rendering the same structured events as native Pear UI.

Deferred

  • Install relay 8.3.0 (npm install) — required before merge
  • V1 structured rendering (Claude stream-json + Codex app-server → formatted xterm text)
  • V2 native Pear UI (custom React components, no xterm for headless agents)
  • Native approval cards: intercept y/n? prompts and render as Pear dialog cards
  • Grok headless: tracked in issue feat: enable headless spawn for Grok once relay confirms streaming-json support #141, pending relay confirmation

Generated by Claude Code

Bumps all @agent-relay/* packages to ^8.3.0 which ships Codex
app-server adapter, headless agent runtime, and SpawnCliInput.

Pear now tracks each agent's runtime (pty | headless) from the
agent_spawned event and skips PTY snapshot/resize in attachTerminal
for headless agents. The terminal pane shows a placeholder for
headless agents instead of an xterm instance.

Also improves the xterm.js config: lineHeight 1.2, letterSpacing 0.5,
bar cursor, 10k scrollback, alt fast-scroll, macOptionIsMeta, and
replaces instant display:none tab switching with a 150ms opacity fade.

Deferred (noted for follow-up):
- Structured output rendering for Claude (--output-format stream-json)
- Structured output rendering for Codex (app-server events)
- Native approval-prompt UI cards (vs y/n in terminal)
- Bundled monospace font (Geist Mono / Berkeley Mono)

https://claude.ai/code/session_01KXU1uAUwx3L82TMLnAmU4z
@gemini-code-assist
Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Jun 7, 2026

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 7, 2026

Warning

Review limit reached

@khaliqgant, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 10 minutes and 15 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7f058862-ab72-4690-8be6-407d54f1182c

📥 Commits

Reviewing files that changed from the base of the PR and between 89eec3a and 87df5df.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • electron-builder.mcp-resources.yml
  • package.json
  • src/main/broker.test.ts
  • src/main/broker.ts
  • src/renderer/src/components/terminal/TerminalPane.tsx
  • src/renderer/src/hooks/use-terminal.ts
  • src/renderer/src/stores/agent-store.ts
  • src/shared/types/ipc.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/relay-8.3-headless-runtime

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 6 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/main/broker.ts Outdated
Comment thread src/renderer/src/stores/agent-store.ts Outdated
Comment thread src/renderer/src/components/terminal/TerminalPane.tsx Outdated
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Jun 7, 2026

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@agent-relay-code
Copy link
Copy Markdown
Contributor

pr-reviewer applied fixes — committed and pushed 746acf0 to this PR. The notes below describe what changed.

Reviewed and fixed the PR checkout.

Changes made:

  • Updated package-lock.json to match the Relay 8.3.0 dependency bumps in package.json.
  • Fixed headless runtime tracking in src/main/broker.ts:
    • runtime cache is now session-scoped, avoiding local/cloud agent-name collisions
    • runtime is learned from listAgents, so attach does not depend on seeing an agent_spawned event first
    • stale runtime entries are cleaned up with session/input-stream teardown
  • Added a focused regression in src/main/broker.test.ts proving headless attach skips resizePty and snapshot.

Verification run locally:

  • npx vitest run src/main/broker.test.ts passed: 35 tests
  • npm test passed: 88 tests
  • npm run build passed

I did not print READY because I cannot verify GitHub-side CI status, mergeability, or pending checks from this sandbox.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Jun 7, 2026

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@agent-relay-code
Copy link
Copy Markdown
Contributor

pr-reviewer applied fixes — committed and pushed d4f2f07 to this PR. The notes below describe what changed.

Fixed the two live unresolved cubic findings:

  • agent-store.ts: added runtime validation before storing event.runtime, so invalid discriminator values are ignored instead of cast into state.
  • TerminalPane.tsx: removed immediate visibility: hidden so inactive panes can actually fade out while remaining non-interactive.

Also removed local ignored install artifacts created during dependency setup: bin/relayfile-mount and bin/.relayfile-mount-version.

Verification run:

  • npx vitest run src/main/broker.test.ts passed: 35 tests
  • npm run build passed
  • npm test passed: 88 tests
  • npm run verify:mcp-resources-drift passed

I’m not printing READY because I cannot verify GitHub-side required check status or mergeability from the available tools.

…red-output CLIs

Claude uses --output-format stream-json and Codex has its own app-server; neither
needs an interactive PTY. spawnAgentOnce now routes these two CLIs through
spawnCli({ transport: 'headless' }) (relay 8.3.0) while shells and unknown
executables continue to use spawnPty.

The resolved runtime is set on agentRuntimes immediately after spawn so
attachTerminal skips PTY-only operations (resize, snapshot) without a race
against the async agent_spawned event.

worker_stream chunks still flow through broker:pty-chunk → xterm, so the
headless placeholder that hid the terminal entirely is removed — V1 rendering
is unaffected.

https://claude.ai/code/session_01KXU1uAUwx3L82TMLnAmU4z
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Jun 7, 2026

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread src/main/broker.ts Outdated
Three bugs caught in review:

1. SpawnCliInput was missing from the @agent-relay/harness-driver import block,
   causing a TypeScript compile error wherever it was referenced.

2. The immediate agentRuntimes.set() after spawnCli used a bare agent name,
   while every other read/write in the map (agent_spawned event, syncAgents,
   attachTerminal) used the composite "sessionKey:name" key from
   getAgentRuntimeKey(). The cache miss meant the early-set optimization —
   intended to prevent a race between spawnAgent returning and attachTerminal
   reading before agent_spawned fires — was always a no-op.

3. The broker test mock's listAgents/getStatus always returned runtime:'pty'
   for every agent, including those spawned via spawnCli. This would overwrite
   the correct headless runtime in agentRuntimes on the next listAgents poll.
   The mock now tracks runtimes per agent in a local Map, consistent with how
   spawnPty/spawnCli register them.

https://claude.ai/code/session_01KXU1uAUwx3L82TMLnAmU4z
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Jun 7, 2026

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@khaliqgant khaliqgant changed the title feat: upgrade @agent-relay to 8.3.0, wire headless runtime support feat: upgrade @agent-relay to 8.3.0, wire headless spawn routing and runtime tracking Jun 7, 2026
@khaliqgant khaliqgant changed the title feat: upgrade @agent-relay to 8.3.0, wire headless spawn routing and runtime tracking ⛔ DO NOT MERGE — feat: upgrade @agent-relay to 8.3.0, wire headless spawn routing and runtime tracking Jun 7, 2026
@khaliqgant khaliqgant marked this pull request as draft June 7, 2026 07:27
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.

2 participants