feat(cli): ping-peer CLI + MCP ping_peer for peer messaging (#1195)

* feat(cli): add ping-peer CLI and MCP ping_peer for peer messaging

Promote resume-if-inactive + wait-active + POST message into a first-class
CLI command and session MCP tool so agents stop reinventing JWT+curl.

Fixes #1194

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): do not auto-approve MCP ping_peer

Cross-session messaging can resume a peer and inject a prompt, so keep
permission-mode gating (Codex PR review Major on #1195).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): require approval for ping_peer in read-only mode

Read-only auto-approve treated non-write names as safe; ping_peer can still
resume a peer and inject prompts, so gate it like a write tool.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): keep ping_peer out of Claude --allowedTools

toolNames still registers the MCP tool, but Claude auto-allow must not
pre-approve cross-session resume+inject without a permission prompt.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cli): re-check session active before ping-peer send

List/get can race; POST /messages still 409s if the target flips inactive
before send. Resume+wait again (and re-gate pi) immediately before POST.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
HeavyGee
2026-07-28 08:36:56 +08:00
committed by GitHub
co-authored by Cursor
parent 84cd9aa3b1
commit e2631a553a
20 changed files with 1241 additions and 21 deletions
+2 -1
View File
@@ -34,6 +34,7 @@ Run Claude Code, Codex, Cursor Agent, Grok Build, or OpenCode sessions from your
- `hapi opencode` - Start OpenCode mode via ACP. See `src/opencode/runOpencode.ts`.
Note: OpenCode supports local and remote modes; local mode streams via OpenCode plugins.
- `hapi resume [sessionId]` - List resumable sessions for this machine or resume one locally.
- `hapi ping-peer <session-id-prefix> <message>` - Resume (if needed) and message another session. Prefer this or MCP `ping_peer` over reinventing JWT+curl. Also `--message-file` / `--list`.
### Resume a remote session locally
@@ -116,7 +117,7 @@ See `src/configuration.ts` for all options.
### Set for the wrapped agent
- `HAPI_SESSION_ID` - The hub session id for the current run, exported into the wrapped agent/CLI child environment at spawn for every flavor (claude / codex / cursor / gemini / opencode / kimi / grok / pi), both runner-spawned and locally started sessions. Agents can read it to self-target "this chat" over the hub REST API or shell helpers without listing `/api/sessions`. Prefer the MCP `display_image` tool for inline media when it is available; use `HAPI_SESSION_ID` for hub REST / shell tooling where MCP is not.
- `HAPI_SESSION_ID` - The hub session id for the current run, exported into the wrapped agent/CLI child environment at spawn for every flavor (claude / codex / cursor / gemini / opencode / kimi / grok / pi), both runner-spawned and locally started sessions. Agents can read it to self-target "this chat" over the hub REST API or shell helpers without listing `/api/sessions`. Prefer the MCP `display_image` tool for inline media when it is available; use `HAPI_SESSION_ID` for hub REST / shell tooling where MCP is not. To message **another** session, prefer MCP `ping_peer` or `hapi ping-peer` — do not reinvent JWT+curl.
Lazy Codex (terminal) sessions export the id only after the hub row is materialized, which happens when the MCP bridge starts — before the agent process is spawned — so path-only self-targeting does not race a missing hub row.