Skip to content

ADE-116: Add cross-machine session handoff#779

Merged
arul28 merged 8 commits into
mainfrom
ade-116-design-and-implement-cross-machine-session-handoff
Jul 10, 2026
Merged

ADE-116: Add cross-machine session handoff#779
arul28 merged 8 commits into
mainfrom
ade-116-design-and-implement-cross-machine-session-handoff

Conversation

@arul28

@arul28 arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Fixes ADE-116

Linked Linear issues

ADE   Open in ADE  ·  ade-116-design-and-implement-cross-machine-session-handoff branch  ·  PR #779

Greptile Summary

This PR adds cross-machine chat handoff for ADE sessions. The main changes are:

  • Sanitized handoff capsule creation from the source chat and lane.
  • Source validation for clean, published branches before transfer.
  • Destination storage, Git, model, and lane preflight checks.
  • Remote runtime actions for clone, accept, and source completion marking.
  • Renderer modal flow for choosing a machine, cloning when needed, and confirming route security.
  • Shared types, IPC/preload bindings, tests, and documentation for the new flow.

Confidence Score: 5/5

This PR appears safe to merge based on the reviewed paths.

No blocking correctness or security issues were identified in the changed handoff flow. Previously reported issues around Git token command arguments, unvalidated remote payload spreading, and skipped completion callback are addressed in the current diff.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex generated the capture scripts used for the attempted validation.
  • T-Rex started the Vite dev server with npm run dev:vite and observed the process being killed shortly after.
  • T-Rex attempted validation with Playwright against the harness route and encountered a navigation timeout.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
apps/desktop/src/main/services/chat/agentChatService.ts Implements capsule preparation, source validation, destination preflight, acceptance, idempotency, and source marking; no issues found.
apps/desktop/src/renderer/components/chat/CrossMachineHandoffModal.tsx Adds the cross-machine handoff UI flow, including source validation, destination clone, route approval, and completion handling; no issues found.
apps/ade-cli/src/multiProjectRpcServer.ts Adds destination storage and Git auth preflight for handoff cloning, using env-based Git headers; no issues found.
apps/ade-cli/src/services/sync/syncRemoteCommandService.ts Registers and validates cross-machine chat handoff remote commands; no issues found.
apps/desktop/src/main/services/remoteRuntime/remoteConnectionPool.ts Adds handoff action timeouts, storage capability gating, and route-change enforcement; no issues found.
apps/desktop/src/main/services/ipc/runtimeBridge.ts Exposes remote handoff preflight and clone flows while preserving destination-only credential mode; no issues found.
apps/desktop/src/shared/crossMachineHandoff.ts Adds shared normalization and response decoding helpers for handoff runtime calls; no issues found.
apps/desktop/src/shared/types/chat.ts Adds cross-machine handoff capsule, target, preflight, accept, and marker types; no issues found.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as Source Renderer
participant Source as Source ADE Runtime
participant Remote as Remote Runtime Bridge
participant Dest as Destination ADE Runtime
participant Git as Git Origin

UI->>Source: prepareCrossMachineHandoff(sourceSessionId, target config)
Source->>Git: verify clean published branch/head
Source-->>UI: sanitized capsule + fingerprint
UI->>Remote: listProjects / getHandoffStoragePreflight
Remote->>Dest: projects preflight / clone if needed
Dest->>Git: verify destination credentials and branch head
Dest-->>UI: destination project + preflight result
UI->>Source: validateCrossMachineSource(capsule, fingerprint)
Source->>Git: revalidate branch/head and chat activity
UI->>Remote: callAction(chat.acceptCrossMachineHandoff)
Remote->>Dest: accept capsule under required route kind
Dest->>Git: fetch source branch commit
Dest->>Dest: import/reuse lane and create handoff chat
Dest-->>UI: destination lane/session result
UI->>Source: markCrossMachineHandoff(destination details)
Source-->>UI: source chat marked complete
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as Source Renderer
participant Source as Source ADE Runtime
participant Remote as Remote Runtime Bridge
participant Dest as Destination ADE Runtime
participant Git as Git Origin

UI->>Source: prepareCrossMachineHandoff(sourceSessionId, target config)
Source->>Git: verify clean published branch/head
Source-->>UI: sanitized capsule + fingerprint
UI->>Remote: listProjects / getHandoffStoragePreflight
Remote->>Dest: projects preflight / clone if needed
Dest->>Git: verify destination credentials and branch head
Dest-->>UI: destination project + preflight result
UI->>Source: validateCrossMachineSource(capsule, fingerprint)
Source->>Git: revalidate branch/head and chat activity
UI->>Remote: callAction(chat.acceptCrossMachineHandoff)
Remote->>Dest: accept capsule under required route kind
Dest->>Git: fetch source branch commit
Dest->>Dest: import/reuse lane and create handoff chat
Dest-->>UI: destination lane/session result
UI->>Source: markCrossMachineHandoff(destination details)
Source-->>UI: source chat marked complete
Loading

Reviews (6): Last reviewed commit: "ci: refresh handoff secret-scan fingerpr..." | Re-trigger Greptile

@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jul 10, 2026 9:23pm

@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

ADE-116

@arul28

arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@copilot review but do not make fixes

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@arul28, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aafd20cb-ccdf-4584-9caa-c04e810851ee

📥 Commits

Reviewing files that changed from the base of the PR and between 734797c and 280a66f.

⛔ Files ignored due to path filters (9)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/PRD.md is excluded by !docs/**
  • docs/README.md is excluded by !docs/**
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/features/chat/composer-and-ui.md is excluded by !docs/**
  • docs/features/remote-runtime/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/cross-machine-session-handoff.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/remote-commands.md is excluded by !docs/**
📒 Files selected for processing (34)
  • .gitleaksignore
  • apps/ade-cli/README.md
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/multiProjectRpcServer.test.ts
  • apps/ade-cli/src/multiProjectRpcServer.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.test.ts
  • apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/chat/agentChatService.test.ts
  • apps/desktop/src/main/services/chat/agentChatService.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/ipc/runtimeBridge.test.ts
  • apps/desktop/src/main/services/ipc/runtimeBridge.ts
  • apps/desktop/src/main/services/remoteRuntime/remoteBootstrap.test.ts
  • apps/desktop/src/main/services/remoteRuntime/remoteBootstrap.ts
  • apps/desktop/src/main/services/remoteRuntime/remoteConnectionPool.test.ts
  • apps/desktop/src/main/services/remoteRuntime/remoteConnectionPool.ts
  • apps/desktop/src/main/services/remoteRuntime/remoteConnectionService.ts
  • apps/desktop/src/main/services/remoteRuntime/retryableRemoteActions.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/chat/CrossMachineHandoffModal.test.tsx
  • apps/desktop/src/renderer/components/chat/CrossMachineHandoffModal.tsx
  • apps/desktop/src/renderer/components/terminals/useWorkSessions.test.ts
  • apps/desktop/src/shared/crossMachineHandoff.test.ts
  • apps/desktop/src/shared/crossMachineHandoff.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/types/chat.ts
  • apps/desktop/src/shared/types/remoteRuntime.ts
  • apps/desktop/src/shared/types/sync.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade-116-design-and-implement-cross-machine-session-handoff

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.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
Connect Timeout Error (attempted address: api.github.com:443, timeout: 10000ms)

@arul28

arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: a6652cd5ae

ℹ️ 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".

providerSlashCommand,
forceClaudeUserMessage,
onDispatched,
onDispatched: onBackendDispatched ?? onDispatched,

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 Wait for Claude prompt acceptance before completing handoff

In the Claude path this maps awaitBackendDispatch onto the normal onDispatched callback; runClaudeTurn fires that callback when it appends the local user_message, before the Claude SDK has accepted the prompt. When a cross-machine handoff targets Claude and the SDK/query fails immediately afterwards (for example expired auth or startup failure), sendMessage({ awaitBackendDispatch: true }) still resolves and acceptCrossMachineHandoff marks the handoff complete even though the destination turn failed. Please resolve the backend ack only after the provider has accepted the prompt, as the Cursor/Droid paths do.

Useful? React with 👍 / 👎.

@arul28

arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: 0a01e75c9e

ℹ️ 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 thread apps/desktop/src/main/services/chat/agentChatService.ts
Comment thread apps/desktop/src/shared/crossMachineHandoff.ts
Comment thread apps/ade-cli/src/services/sync/syncRemoteCommandService.ts
@arul28

arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@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: 5d276bef4e

ℹ️ 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".

const capsule: AgentChatCrossMachineHandoffCapsule = {
version: 1,
handoffId,
createdAt: nowIso(),

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 Capture handoff snapshot time before building the brief

If the source chat receives any event while prepareCrossMachineHandoff is awaiting the brief generation, the capsule is built from the older transcript/artifact snapshot but createdAt is set after that activity. validateCrossMachineSource only rejects transcript entries with timestamp > capsule.createdAt, so final send can approve a stale capsule and continue on another machine without the latest user/assistant turn. Capture the snapshot timestamp before reading the transcript/generating the brief, or compare against the last included event, so mid-prepare activity forces a fresh handoff.

Useful? React with 👍 / 👎.

Comment on lines +24413 to +24415
}, { awaitBackendDispatch: true });

record = { ...record, state: "dispatched", updatedAt: nowIso(), lastError: null };

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 Make handoff prompt dispatch idempotent across retries

When the destination process dies after the backend has accepted the first handoff prompt but before the dispatched state is persisted, the record remains chat_ready with the deterministic session id. Retrying the same handoff then reuses that session and executes this send again, creating a duplicate first turn even though the UI presents retries as safe. Persist an idempotent prompt marker before dispatch, or skip dispatch when the transcript already contains this crossMachineHandoffId.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

Comment thread apps/ade-cli/src/multiProjectRpcServer.ts
@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/arul28s-projects?upgradeToPro=build-rate-limit

@arul28

arul28 commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@arul28 arul28 force-pushed the ade-116-design-and-implement-cross-machine-session-handoff branch from 21c25d4 to 34c54fb Compare July 10, 2026 22:10
@arul28 arul28 merged commit 1c19d59 into main Jul 10, 2026
31 of 32 checks passed
@arul28 arul28 deleted the ade-116-design-and-implement-cross-machine-session-handoff branch July 10, 2026 22:42
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