feat(drive): /openremote-control drives THIS coding session (resume by id) - #91
Merged
Merged
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goal
Make
/openremote-controlput 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_SESSION_IDto 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 existingsession.headless_replypath.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
openremote_control: readCLAUDE_CODE_SESSION_ID+ cwd, forward to the backend.start_remote_control: sendclaude_session_id+workspace_root(omitted when absent → unchanged behaviour).start_session(claude_session_id=...): bind the driveable thread to that id and markclaude_session_started=Trueso the first Telegram reply--resumes this conversation (run_headless's resume-or-create continues in place). No id → mint fresh (standalone session, unchanged).Caveat (documented)
Phone-driven turns won't appear live in the editor panel — a separate
claude -pprocess 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 bypassPermissionsin 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
host-agent/tests/test_drive_e2e.py).Verify (after merge + deploy)
git pull, restart stack (launchctl kickstart -k gui/$(id -u)/com.openremote.daphne)./openremote-control→ reply in the Telegram topic → the reply resumes that session and streams back.🤖 Generated with Claude Code