Skip to content

feat(drive): /openremote-control drives THIS coding session (resume by id) - #91

Merged
Pher217 merged 2 commits into
mainfrom
claude/2026-06-28-drive-this-session
Jul 1, 2026
Merged

feat(drive): /openremote-control drives THIS coding session (resume by id)#91
Pher217 merged 2 commits into
mainfrom
claude/2026-06-28-drive-this-session

Conversation

@Pher217

@Pher217 Pher217 commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Goal

Make /openremote-control put this coding session on Telegram — driveable (write+stream) — instead of spinning up a separate fresh Claude. This is the "drive this chat from my phone, like June" ask.

The unlock

  • Claude Code exposes CLAUDE_CODE_SESSION_ID to MCP-server subprocesses (verified live: it's this session's id).
  • claude -p --resume <id> "..." appends to the same JSONL transcript in place — verified empirically (resume on a closed session: 24→35 lines, response returned, no new session file). So resuming continues the conversation and the reply streams back via the existing session.headless_reply path.

This is exactly the decided mechanism in the vault spec [2026-06-25 headless-default-drive] — headless claude -p --resume, no tmux, cross-platform. The only change is binding to the caller's session id instead of a fresh one.

Changes

  • orc-mcp openremote_control: read CLAUDE_CODE_SESSION_ID + cwd, forward to the backend.
  • orc-mcp client start_remote_control: send claude_session_id + workspace_root (omitted when absent → unchanged behaviour).
  • backend start_session(claude_session_id=...): bind the driveable thread to that id and mark claude_session_started=True so the first Telegram reply --resumes this conversation (run_headless's resume-or-create continues in place). No id → mint fresh (standalone session, unchanged).
  • command doc: documents the bind + the handoff caveat.

Caveat (documented)

Phone-driven turns won't appear live in the editor panel — a separate claude -p process appends the shared transcript; the extension doesn't hot-reload it. It's a handoff, not a two-way live mirror. Don't type in both at once.

Security

Unchanged posture: a driveable thread already ran claude -p --permission-mode bypassPermissions in cwd, gated by the Telegram allowlist (handle_forum_reply). This resumes the existing session instead of a new one — same gate, no new surface.

Test summary

  • backend: 522 passed (+2: bind-to-id, mint-fresh). Ruff clean on changed files.
  • orc-mcp: 11 passed (+2: session-id forwarded / omitted).
  • Mechanism proof: resume-append (PINGOK) + the pre-existing headless drive E2E (host-agent/tests/test_drive_e2e.py).

Verify (after merge + deploy)

  1. Merge, git pull, restart stack (launchctl kickstart -k gui/$(id -u)/com.openremote.daphne).
  2. Reinstall/restart the orc MCP so it runs the new code, then start a new Claude Code session.
  3. Run /openremote-control → reply in the Telegram topic → the reply resumes that session and streams back.

🤖 Generated with Claude Code

…y id)

Until now /openremote-control dispatched a driveable chat bound to a FRESH
headless session — so the Telegram topic was a separate Claude, not the
conversation you ran the command from. This binds the chat to the caller's own
session id so a Telegram reply runs `claude -p --resume <this-session>` and
continues THIS exact conversation, streaming the reply back. Write + stream,
this chat, no read-only mirror.

How: Claude Code exposes CLAUDE_CODE_SESSION_ID to MCP-server subprocesses.
- orc-mcp `openremote_control` reads it (+ cwd) and forwards both to the backend.
- `start_session(claude_session_id=...)` binds the driveable thread to that id and
  marks it already-started, so the first reply `--resume`s (run_headless's
  resume-or-create then continues in place). Omitted id → fresh session (unchanged).

Mechanism verified: `claude -p --resume <id> "..."` appends to the same JSONL
transcript in place (no new session file) — so the resumed turns continue the
conversation and stream back via the existing session.headless_reply path. No
observe/mirror needed; fully consistent with #90.

Caveat (documented in the command): phone-driven turns don't appear live in the
editor panel (separate process appending the shared transcript) — it's a handoff,
not a two-way live mirror.

Tests: bind-to-id + mint-fresh (backend), session-id forwarding (orc-mcp client).
Backend 522 passed; orc-mcp 11 passed.
…dispatch

Conflict in start_session: keep the caller-session bind (bound_id +
claude_session_started) from this branch AND the tail.start dispatch
from PR #93, with tail.start sending bound_id so fresh-minted sessions
tail the correct transcript without waiting for the reconnect resync.

Backend suite: 536 passed, 3 skipped. orc-mcp: 34 passed.
@Pher217
Pher217 merged commit 8738df8 into main Jul 1, 2026
@Pher217
Pher217 deleted the claude/2026-06-28-drive-this-session branch July 1, 2026 21:12
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