feat(mobile): discover and continue external Claude Code/Codex sessions remotely
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 使用场景 / Use case
A user starts Claude Code or Codex in a normal terminal on their desktop, then leaves the computer before importing the task into Cindy or enabling the vendor's remote-control mode.
Later, from Cindy Mobile, they want to find that task on the online desktop and continue it with its existing context.
Concrete flow:
1. Start `claude` or `codex` outside Cindy.
2. Leave home while the desktop and Cindy remain online.
3. Open Cindy Mobile and select the online desktop.
4. See external CLI tasks that have not been imported into Cindy.
5. Choose one and tap **Continue in Cindy**.
This would make cross-device continuity work even when the user did not prepare the session before leaving the computer.
## 当前问题 / Current limitation
Cindy Desktop already has most of the local-session machinery:
- `apps/desktop/src/main/localDb/ipc/session-import.ts` implements scan/import IPC.
- `apps/desktop/src/main/maker-host/claude-local-sessions.ts` scans and imports Claude Code sessions.
- `apps/desktop/src/main/maker-host/codex-local-sessions.ts` provides the analogous Codex flow.
- Imported tasks retain the native SDK session ID, which Cindy can later resume.
However, this flow is desktop-only today:
- `packages/device-link/src/allowlist.ts` explicitly excludes migration/session-import channels from remote invocation.
- `packages/maker-shared/src/deviceLinkContract.ts` has no mobile contract for scanning or adopting external sessions.
- A non-allowlisted remote request is rejected with `CHANNEL_NOT_ALLOWED`.
Therefore, if the user leaves before importing the task, Cindy Mobile cannot discover or continue it.
There is also an important concurrency issue: importing/resuming a native session is not the same as attaching to the already-running terminal process. If both Cindy and the original CLI keep writing to the same native session, transcript state may interleave or conflict.
## 期望方案 / Proposed solution
Add a narrow, validated Device Link capability for external-session handoff. For example:
- `maker:external-session:scan`: return metadata-only candidates from the selected online desktop.
- `maker:external-session:adopt`: explicitly adopt one validated candidate into Cindy.
Suggested mobile experience:
1. On a selected online desktop, show a **Tasks on this computer** entry.
2. List importable Claude Code and Codex sessions with:
- source
- title
- working directory
- last activity time
- possible active/running state, when detectable
3. Let the user tap **Continue in Cindy**.
4. The target desktop revalidates the candidate, imports/adopts it locally, and returns the new Cindy task ID.
5. Mobile refreshes the task list and opens that task.
### Safe concurrency behavior
The feature should never silently create two writers for the same native session.
Recommended safe default:
- If the external CLI may still be active, fork/branch the native session before the first mobile message, so the original terminal can continue independently.
- If reliable live-process detection is available, Cindy may instead block and ask for explicit takeover confirmation.
- PTY-level attachment to an arbitrary existing terminal process can remain out of scope for the first version; native transcript resume/fork already solves the main continuity need.
### Security boundaries
- Require the same account, Device Link enabled, an online non-revoked target, and the existing remote-control permission gates.
- Scanning should return metadata only; do not transmit full transcripts before an explicit adopt action.
- The desktop must revalidate session IDs and ownership. Do not accept an arbitrary path or raw database operation from mobile.
- Expose narrow business handlers rather than generic filesystem, shell, or DB-write channels.
- Preserve graceful behavior for older desktop/mobile versions, such as a clear “desktop version too old” error.
The existing generic Device Link invoke path appears sufficient to carry these narrowly allowlisted client channels, so this may be implementable without adding a new server-side transcript store.
## 已考虑的替代方案 / Alternatives considered
- **Claude Code / Codex vendor remote-control features:** useful, but they must generally be enabled before leaving and are vendor-specific.
- **Desktop Settings → Local Task Import:** already works, but requires physical access to the desktop.
- **Remote shell or command-execution workaround:** poor mobile UX, expands the security surface, and still cannot safely attach to an arbitrary live CLI process.
- **Only sync future Cindy-created tasks:** does not solve the common case where work started in a normal terminal.
## 验收标准 / Acceptance criteria
- [ ] Cindy Mobile can list importable Claude Code and Codex sessions on a selected online desktop.
- [ ] The list shows source, title, working directory, and last activity time without loading the full transcript.
- [ ] **Continue in Cindy** adopts the selected external session, refreshes the task list, and opens the resulting Cindy task.
- [ ] Existing native context/history is preserved to the extent supported by Claude Code or Codex resume/fork semantics.
- [ ] A potentially active external CLI is handled safely by fork, block, or explicit takeover confirmation; Cindy never silently creates concurrent writers to the same native session.
- [ ] Same-account, Device Link enabled, target revocation, and allowlist checks remain enforced.
- [ ] Invalid or stale candidate IDs are rejected on the target desktop.
- [ ] Older client versions receive a clear compatibility error instead of failing silently.
- [ ] Tests cover scan/adopt validation, Device Link allowlisting, mobile transport/contract behavior, and the concurrent-writer guard.
- [ ] Existing Desktop Settings → Local Task Import behavior remains unchanged.
Contributor guide
Research direction
Start by reading apps/desktop/src/main/localDb/ipc/session-import.ts and the Claude and Codex local-session scanners, then inspect packages/device-link/src/allowlist.ts and packages/maker-shared/src/deviceLinkContract.ts. Trace the existing generic Device Link invoke path before defining the narrow scan/adopt behavior. Done means validated metadata-only discovery, safe adoption with stale-candidate and concurrency checks, compatibility errors, and tests for transport, allowlisting, validation, and preserved desktop import behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, react-native, typescript
- Domain
- api, desktop, mobile, security, testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100