Skip to content

feat(remote): session ownership + myagent remote client CLI (M2.2)#12

Merged
wusijian007 merged 1 commit into
mainfrom
feat/m2.2-remote-v2
May 15, 2026
Merged

feat(remote): session ownership + myagent remote client CLI (M2.2)#12
wusijian007 merged 1 commit into
mainfrom
feat/m2.2-remote-v2

Conversation

@wusijian007

Copy link
Copy Markdown
Owner

Builds on M1.3's bearer-token handshake. Two capabilities:

SESSION OWNERSHIP (packages/core/src/remote.ts)

  • New { type: "role", role: "owner" | "follower" } server message, sent right after ready on every connection.
  • The first authenticated connection becomes the owner. Later connections are read-only followers. createRemoteAgentServer now tracks ownerConnectionId plus a connections registry for fan-out.
  • user_message and permission_decision are owner-only — a follower gets { type: "error", message: "read-only follower ..." } and the turn/decision is not processed. resume and ping stay open to any client (read-only / liveness).
  • The owner's turn stream (agent_stdout/stderr, permission_request, terminal_state, session_metadata) is now broadcast to every connection so followers can watch live. ack and input-validation errors stay targeted to the submitter.
  • Owner disconnect releases the slot; the next NEW connection claims it. Existing followers are deliberately NOT auto-promoted — keeps the ownership transition race-free and predictable.

Backward compatible: a lone client (every existing remote test) is the owner, and broadcast-to-one == the old targeted send. protocol version stays 1; role is purely additive (unknown-message-tolerant clients ignore it).

REMOTE CLIENT CLI (packages/cli/src/index.ts)

myagent remote client [--url ws://host:port] [--token ]
[--prompt "

"] [--session ]

  • Parses --url (or --host/--port), resolves the token from --token or falls back to the local .myagent/remote/auth.json.
  • Prints the assigned role, streams agent stdout/stderr to the local terminal, and forwards permission_request to the local TTY via the existing prompt-session + requestPermissionFromPrompt path, sending back permission_decision.
  • With --prompt it submits a turn and exits on terminal_state; without it, it's a pure read-only watcher (Ctrl+C to leave).

Tests: packages/core/test/security/remote-ownership.test.ts (6 cases) — role assignment, follower user_message/permission_decision rejection, broadcast-to-follower, owner-disconnect promotion of a NEW connection, and no-auto-promotion of an existing follower. Updated the cli --help assertion for the new subcommand list. Security catalog + CLAUDE.md updated.

Local: 181 tests, 3/3 green.

Builds on M1.3's bearer-token handshake. Two capabilities:

SESSION OWNERSHIP (packages/core/src/remote.ts)

- New `{ type: "role", role: "owner" | "follower" }` server message,
  sent right after `ready` on every connection.
- The first authenticated connection becomes the owner. Later
  connections are read-only followers. `createRemoteAgentServer` now
  tracks `ownerConnectionId` plus a `connections` registry for fan-out.
- `user_message` and `permission_decision` are owner-only — a
  follower gets `{ type: "error", message: "read-only follower ..." }`
  and the turn/decision is not processed. `resume` and `ping` stay
  open to any client (read-only / liveness).
- The owner's turn stream (agent_stdout/stderr, permission_request,
  terminal_state, session_metadata) is now broadcast to every
  connection so followers can watch live. `ack` and input-validation
  errors stay targeted to the submitter.
- Owner disconnect releases the slot; the next NEW connection claims
  it. Existing followers are deliberately NOT auto-promoted — keeps
  the ownership transition race-free and predictable.

Backward compatible: a lone client (every existing remote test) is
the owner, and broadcast-to-one == the old targeted send. protocol
version stays 1; `role` is purely additive (unknown-message-tolerant
clients ignore it).

REMOTE CLIENT CLI (packages/cli/src/index.ts)

  myagent remote client [--url ws://host:port] [--token <t>]
                        [--prompt "<p>"] [--session <id>]

- Parses --url (or --host/--port), resolves the token from --token or
  falls back to the local .myagent/remote/auth.json.
- Prints the assigned role, streams agent stdout/stderr to the local
  terminal, and forwards permission_request to the local TTY via the
  existing prompt-session + requestPermissionFromPrompt path, sending
  back permission_decision.
- With --prompt it submits a turn and exits on terminal_state; without
  it, it's a pure read-only watcher (Ctrl+C to leave).

Tests: packages/core/test/security/remote-ownership.test.ts (6 cases)
— role assignment, follower user_message/permission_decision
rejection, broadcast-to-follower, owner-disconnect promotion of a
NEW connection, and no-auto-promotion of an existing follower.
Updated the cli --help assertion for the new subcommand list.
Security catalog + CLAUDE.md updated.

Local: 181 tests, 3/3 green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@wusijian007 wusijian007 merged commit afd90ba into main May 15, 2026
3 checks passed
@wusijian007 wusijian007 deleted the feat/m2.2-remote-v2 branch May 15, 2026 06:30
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