Skip to content

Expose session.continueWithReplay on daemon HTTP API for cross-device transfer #133

@lucharo

Description

@lucharo

Summary

The daemon has a session.continueWithReplay RPC handler that enables proper cross-device session transfer — it fetches the encrypted transcript from the relay, decrypts it, builds a replay prompt, and spawns a new session linked to previousSessionId. This is exactly the right primitive for "start a session on machine A, continue it on machine B."

However, this RPC is only accessible via socket.io from the relay cloud. The local HTTP daemon API (/spawn-session, /list, /stop-session) doesn't expose it. There's no way for a local tool (like a TUI or script) to call it.

Use Case

I'm building a TUI session manager that lists all relay sessions across machines and lets you:

  • Enter → chat view via relay stream API (works)
  • R → resume the session locally on a different machine (blocked)

The "resume locally" flow needs continueWithReplay to properly transfer the session. Without it, the only options are:

  1. Bypass happier entirely (claude --resume) — loses relay sync, phone access, session management
  2. Reconstruct the JSONL manually — creates a clone/fork, not a transfer. Happier daemon then auto-registers it as a new session, creating duplicates

Proposed Solution

Any of these would work:

Option A: HTTP endpoint (simplest)

Add /continue-with-replay to the daemon HTTP server with the same schema as the existing RPC handler:

POST /continue-with-replay
{
  "directory": "/home/user/Projects/myapp",
  "agent": "claude",
  "replay": {
    "previousSessionId": "cmmroxg6kk2ods93cm406fy53",
    "strategy": "recent_messages",
    "recentMessagesCount": 16
  }
}

Option B: CLI command

happier session continue <session-id> [--directory <path>] [--agent claude]

Option C: Extend /spawn-session

Add optional replay field to the existing /spawn-session endpoint.

Context

Related: #131 (happier --resume doesn't accept happier session IDs)

The RPC handler already exists and works (line ~24444 in the bundled api-BauLSAv8.mjs). It calls hydrateReplayDialogFromTranscriptbuildHappierReplayPromptFromDialogspawnSession. The plumbing is all there — it just needs an HTTP route or CLI command to expose it.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions