Skip to content

Upgrade Agent Relay dependencies to v10.6.3#398

Merged
khaliqgant merged 3 commits into
mainfrom
chore/relay-10-bump
Jul 17, 2026
Merged

Upgrade Agent Relay dependencies to v10.6.3#398
khaliqgant merged 3 commits into
mainfrom
chore/relay-10-bump

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

  • upgrade every directly consumed Agent Relay package to 10.6.3 and factory to 0.1.19 so its embedded Relay stack is also v10
  • migrate the Pear local fleet capability provider from the removed broker-local WebSocket handshake to the v10 startServeNode engine handshake
  • bound fleet credential reads by both the registration deadline and sidecar stop signal
  • thread v10 raw-PTY offsets plus Pear event-stream generations through IPC for snapshot-safe terminal replay
  • add renderer replay suppression only for generation + offset + content matches; identity-less or uncertain traffic still delivers
  • drain the predictive-echo ordering chain before engine/model/terminal teardown so Relay v10 reset cannot discard already-accepted authoritative bytes
  • regenerate packaged MCP resources for the new nested Relaycast and ai-hist-native dependency layout

Compatibility audit

  • Relay protocol version remains 2.
  • Fleet v10 removes nodeManifest and the register_node/register_handlers/deregister_node/handler_result client flow. Pear now waits for the broker-minted node id and token, then attaches its provider to that same node.
  • Worker stream and snapshots now expose cumulative raw-PTY offsets. Pear scopes those resettable counters to its event-stream listener generation.
  • Relay 10.6.3 does not fix the harness-driver predictive-echo erasePredictionRegion early-return strand vector: prediction state can still be cleared before the cursor-row mismatch return leaves optimistic glyphs unerased. This PR does not claim that vector is fixed.
  • A full Pear teardown audit found one additional v10 hazard: the engine's reset() drops onServerOutput work still waiting in its async tail. The runtime now seals the router, releases capture-held chunks, awaits its accepted ordering chain, then resets/disposes the engine and terminal. Direct↔engine route changes, remounts, resizes, and rollbacks reuse the same engine and do not dispose it.
  • Harness, integration-prompts, SDK, cloud, and factory changes consumed by Pear compile without further breaking changes.

Isolated live fleet gate

  • launched the Relay 10.6.3 broker binary directly with isolated instance pear-relay10-persist-gate, state directory, and port 63136; no agent-relay local up/down command was used
  • Pear sidecar registered all 9 capabilities on node node_f1b6ed06639b0d71a9536bf79b30f59e; broker query reported online/live, handlersLive: true, and relay-broker/10.6.3
  • targeted Codex spawn invocation inv_203841067181731840 completed through that node; the isolated broker exposed the spawned PTY worker and its snapshot showed the deterministic task executing
  • released the worker, shut down the isolated broker, verified its connection disappeared, and removed both isolated temporary state directories

Validation

  • npm run build
  • npm run verify:mcp-resources-drift
  • npm run typecheck
  • focused Vitest: 8 files, 175 tests (required broker/buffer/size/echo gates plus fleet, PTY dedupe, runtime registry, and hook coverage)
  • deterministic real-v10 regression: accepted engine output is painted before router disposal allows engine reset
  • npm run test:fidelity: 8 passed
  • npm run test:redraw: 1 passed, drained=true, finalRenderedSeq=1920, consoleErrorCount=0
  • scoped ESLint and git diff --check

The live pear broker on port 3889 was not touched.

@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 142c9ea3-53bd-41f2-9bb0-6d0ca66581e6

📥 Commits

Reviewing files that changed from the base of the PR and between 0ac19bf and 66b7aef.

📒 Files selected for processing (14)
  • src/main/broker.test.ts
  • src/main/broker.ts
  • src/main/pear-fleet-node.test.ts
  • src/main/pear-fleet-node.ts
  • src/preload/index.ts
  • src/renderer/src/hooks/use-broker-events.ts
  • src/renderer/src/lib/echo-router.test.ts
  • src/renderer/src/lib/echo-router.ts
  • src/renderer/src/lib/ipc-mock.ts
  • src/renderer/src/lib/terminal-runtime-registry.dom.test.ts
  • src/renderer/src/lib/terminal-runtime-registry.ts
  • src/renderer/src/stores/pty-buffer-store.test.ts
  • src/renderer/src/stores/pty-buffer-store.ts
  • src/shared/types/ipc.ts

📝 Walkthrough

Walkthrough

Relay v10 dependencies and packaging filters are updated. PTY offsets and generations now flow through broker, IPC, and renderer buffering for snapshot-aware replay. The local fleet sidecar polls broker sessions and starts nodes through startServeNode. Router shutdown now drains accepted output asynchronously.

Changes

PTY offset propagation and replay

Layer / File(s) Summary
PTY offset contracts and transport
src/shared/types/ipc.ts, src/main/broker.ts, src/preload/index.ts, src/renderer/src/hooks/*, src/renderer/src/lib/ipc-mock.ts, src/main/broker.test.ts
Optional offsets and generations are propagated with terminal snapshots and PTY chunks across broker, IPC, renderer, and mock paths.
Offset-aware buffer and terminal attach
src/renderer/src/stores/pty-buffer-store.ts, src/renderer/src/lib/terminal-runtime-registry.ts
Buffered chunks retain replay metadata, and terminal attach writes only chunks beyond the snapshot baseline before live subscription.
Terminal shutdown and replay validation
src/renderer/src/lib/echo-router.ts, src/renderer/src/lib/terminal-runtime-registry.ts, src/renderer/src/**/*test.ts
Router disposal drains accepted output asynchronously, runtime cleanup waits for the drain, and tests cover offset filtering, generation handling, deduplication, and attach ordering.

Relay v10 fleet sidecar migration

Layer / File(s) Summary
Relay v10 dependencies and packaged resources
package.json, electron-builder.mcp-resources.yml
Agent Relay packages are upgraded to v10.6.3, and nested dependencies plus platform-specific ai-hist-native binaries are added to packaging filters.
Broker session resolution and node serving
src/main/pear-fleet-node.ts, src/main/broker.ts
The sidecar reads broker sessions, waits for node credentials, constructs a node connection, and starts the node through startServeNode.
Fleet registration and connection tests
src/main/pear-fleet-node.test.ts, src/main/broker.test.ts
Tests validate local capability metadata, credential resolution, timeout and abort handling, and session callback wiring.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Broker
  participant PreloadIPC
  participant PtyBufferStore
  participant TerminalRuntimeRegistry
  Broker->>PreloadIPC: send PTY chunks with offset and generation
  PreloadIPC->>PtyBufferStore: append chunk metadata
  TerminalRuntimeRegistry->>PtyBufferStore: select chunks after snapshot offset
  PtyBufferStore-->>TerminalRuntimeRegistry: post-snapshot chunks
  TerminalRuntimeRegistry->>TerminalRuntimeRegistry: write before live subscription
Loading
sequenceDiagram
  participant BrokerSession
  participant resolvePearFleetConnection
  participant startPearFleetSidecar
  participant startServeNode
  BrokerSession->>resolvePearFleetConnection: provide node credentials
  resolvePearFleetConnection-->>startPearFleetSidecar: resolved connection and node name
  startPearFleetSidecar->>startServeNode: start serving node
  startServeNode-->>startPearFleetSidecar: registered FleetNodeInfo
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers: miyaontherelay

Poem

A rabbit hops with offsets bright,
PTY trails fall into line just right.
Fleet tokens guide nodes through the gate,
While drained bytes wait before shutdown’s fate.
Relay v10 makes the burrow glow—
Hop, hop, ship the change! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: upgrading Agent Relay dependencies to v10.6.3.
Description check ✅ Passed The description is directly related and accurately covers the dependency upgrade, fleet handshake migration, PTY offset threading, and resource updates.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/relay-10-bump

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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.

@khaliqgant
khaliqgant marked this pull request as draft July 17, 2026 11:23
@khaliqgant khaliqgant added the no-agent-relay-review Disable agent-relay automated PR review/fixes label Jul 17, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request upgrades various @agent-relay dependencies to version 10.6.3 and refactors the local fleet node connection logic to use the standard @agent-relay/fleet node server instead of a custom WebSocket loop. It also introduces cumulative raw-PTY byte offsets to terminal snapshots and PTY chunks to prevent duplicate output rendering when attaching to terminals. The review feedback suggests two improvements for robustness: using optional chaining when checking the resolved broker session to prevent potential TypeErrors during polling, and strictly validating that the snapshot offset is a number before filtering PTY chunks.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/main/pear-fleet-node.ts Outdated
try {
lastSession = await readBrokerSession()
lastError = undefined
if (lastSession.node_id && lastSession.node_token) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

If readBrokerSession() resolves to null or undefined (for example, if the session is not yet initialized), accessing lastSession.node_id will throw a TypeError. While this error is caught by the try-catch block, it is cleaner and more robust to use optional chaining to avoid throwing exceptions during normal polling.

Suggested change
if (lastSession.node_id && lastSession.node_token) {
if (lastSession?.node_id && lastSession?.node_token) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in d713f34. Broker session reads now accept null/undefined during normal polling and use optional chaining before credential access.

// snapshot instead of treating the entire roundtrip window as covered
// (which could drop output emitted after snapshot capture).
flushPtyChunksNow(key)
if (result.snapshot.offset !== undefined) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To ensure type safety and prevent passing non-numeric values (like null if present in the JSON response) to getPtyChunksAfterOffset, it is safer to explicitly check if result.snapshot.offset is a number.

Suggested change
if (result.snapshot.offset !== undefined) {
if (typeof result.snapshot.offset === 'number') {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in d713f34. Snapshot offset correlation now requires a numeric offset; main also rejects non-finite snapshot offsets.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ac19bf07e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 198 to 200
} else {
pending.set(key, [chunk])
pending.set(key, [entry])
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Dedupe repeated offset-tagged chunks before queuing

When the same broker:pty-chunk delivery reaches the renderer twice—for example through IPC replay or duplicate renderer listeners—this blindly queues both entries even though the new offset metadata can identify an exact replay. Both copies are then written to xterm, which can duplicate control sequences and recreate stacked-screen corruption. AGENTS.md explicitly requires the renderer buffer to guard PTY delivery and to dedupe by identity plus content, so suppress the same offset-and-chunk within the current broker generation while retaining identical content at different offsets.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in d713f34. The renderer final guard now suppresses only when event-stream generation, PTY offset, and content hash all match. Tests retain identical content at different offsets/generations and identity-less repeats.

Comment on lines +140 to +143
const bufferOffsets = offsets.get(key) ?? []
return buffer.filter((_, index) => {
const offset = bufferOffsets[index]
return offset === undefined || offset > snapshotOffset

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Scope snapshot offsets to a broker generation

If the broker daemon restarts while this key's lazy buffer still contains old output, its cumulative PTY offset resets but getPtyChunksAfterOffset compares the new snapshot against every retained offset without a generation check. Old-generation chunks with numerically higher offsets are therefore replayed over the fresh snapshot when the terminal is first attached, corrupting the screen. This is the counter-reset case warned about in AGENTS.md; clear or generation-tag offsets across reconnects and deliver uncertain chunks rather than treating the raw number as globally comparable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed in d713f34. PTY IPC and attach snapshots now carry the main event-stream generation. Attach filtering drops known older-generation chunks, compares offsets only within the same generation, and delivers future/unknown generations.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/pear-fleet-node.ts`:
- Around line 221-224: Update the broker-session polling loop around
readBrokerSession() so each read is raced or cancelled against both the
remaining deadline and signal, allowing hung reads to terminate promptly. Apply
the same change to the corresponding polling path around the additionally
referenced section, preserve existing retry behavior for completed reads, and
add coverage using a never-resolving reader to verify timeout and stop()
completion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e344254-b739-483d-9e2b-0b45f99a5f7f

📥 Commits

Reviewing files that changed from the base of the PR and between ce9f2c1 and 0ac19bf.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • electron-builder.mcp-resources.yml
  • package.json
  • src/main/broker.test.ts
  • src/main/broker.ts
  • src/main/pear-fleet-node.test.ts
  • src/main/pear-fleet-node.ts
  • src/preload/index.ts
  • src/renderer/src/hooks/use-broker-events.ts
  • src/renderer/src/lib/ipc-mock.ts
  • src/renderer/src/lib/terminal-runtime-registry.dom.test.ts
  • src/renderer/src/lib/terminal-runtime-registry.ts
  • src/renderer/src/stores/pty-buffer-store.test.ts
  • src/renderer/src/stores/pty-buffer-store.ts
  • src/shared/types/ipc.ts

Comment thread src/main/pear-fleet-node.ts Outdated
@khaliqgant
khaliqgant marked this pull request as ready for review July 17, 2026 13:15
@khaliqgant
khaliqgant merged commit 87dde0c into main Jul 17, 2026
4 checks passed
@khaliqgant
khaliqgant deleted the chore/relay-10-bump branch July 17, 2026 13:15

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66b7aef6b5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// of the generation comparison, the numeric offset is not globally safe;
// deliver the uncertain chunk instead of risking dropped terminal bytes.
if (snapshotGeneration === undefined || generation === undefined) return true
if (generation < snapshotGeneration) return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not discard chunks from an earlier listener generation

When an event-stream refresh races with terminal attachment, this drops every buffered chunk tagged with the previous listener generation even if its offset is greater than the snapshot offset. The checked refresh path in src/main/broker.ts:2388-2395 increments eventStreamGeneration for ordinary focus/visibility rebinds without restarting the PTY, while attachTerminal stamps the snapshot with the generation current after its asynchronous snapshot request; therefore output emitted after snapshot capture but before a concurrent rebind can be tagged with the older generation and be lost here, corrupting the terminal stream. Listener generations should not be treated as PTY/daemon generations, or older-generation chunks should only be discarded when a real PTY restart is established.

Useful? React with 👍 / 👎.

khaliqgant added a commit that referenced this pull request Jul 17, 2026
…402)

Clicking any issue in the Issues control center (Attention Inbox) threw
"Integration remote directory is outside this project integration scope"
from IntegrationsManager.listRemoteDirectory.

The Issues tab lists /linear/issues (issues-store.ts) and reads/writes the
issue records beneath it for status writeback and comments. But Linear
integrations mount at the team level — /linear/teams or /linear/teams/AR
(integrations.catalog.ts defaultMountPaths, unchanged since #9) — and the
adapter materializes /linear/issues as a SIBLING of that mount, not inside
it. So canListRemoteDirectoryForMountPaths rejected every /linear/issues
listing. This was latent since the Attention Inbox shipped; #226 added an
identical carve-out for /linear/states but its commit message wrongly
assumed "integrations configure mounts like /linear/issues", so it never
noticed /linear/issues had the same problem. Not a regression from
#398/#399/#384 (none touch scope logic) and not the .integrations symlink
pattern (this guard is a remote relayfile-path check, never touches disk).

Add isLinearIssuesListablePath mirroring the states carve-out, gated on a
visible Linear integration, wired into listRemoteDirectory (guard + entry
filter) and readRemoteFile. Unlike states, the carve-out is also wired into
writeRemoteFile: issue status changes and comments are the Issues control
center's whole purpose. Rename the private gate
linearStatesListingEnabledForProject -> linearListingEnabledForProject since
it now backs both Linear reference subtrees.

Tests: integrations.test.ts exercises list+read+write against the operator's
real team-scoped mount (/linear/teams/AR); predicate unit tests cover the
subtree boundary and states/issues disjointness. Full integrations suite
(70) + predicate suite (10) green; typecheck:node + eslint clean.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-agent-relay-review Disable agent-relay automated PR review/fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant