Skip to content

v0.2.0 — local session parity

Choose a tag to compare

@jkrandom-sudo jkrandom-sudo released this 10 Aug 02:04
· 7 commits to main since this release
3b94f28

opencode-plugin-peers 0.2.0 — local session parity

Brings the plugin to local-session parity with Claude Code's cross-session messaging. Protocol v2 makes every OpenCode session (including child sessions) individually addressable, delivery is immediate even while the target is busy, and message state is durable across restarts.

Features

  • Per-session endpoints (protocol v2): one registry record per OpenCode session instead of one per process; exact endpoint-ID targeting with unique-name fallback; v1 peers keep working through a compatibility record + loopback listener
  • Immediate busy-session delivery: one promptAsync per message, deterministic msg_* IDs, structured metadata.peerMessage provenance — no more waiting for idle
  • Durable per-endpoint spool: queued/held/inflight/done state machine, atomic writes, idempotency by sender+messageId, restart recovery, workspace-spool migration
  • Durable outbox + final ACKs: delivered / refused / expired / dropped / duplicate outcomes are retried into the sender's outbox; new peer_message_status tool and /peers-outbox command
  • UDS transport on macOS/Linux (loopback TCP on Windows)
  • inboundPolicy: "auto": same-directory sessions accept, cross-directory hold; held messages expire after 5 minutes (configurable) with final ACKs to the sender
  • Permission guardrails: in allow mode, requests touching permission config / AGENTS.md / credentials / shell startup files stay under native OpenCode policy (best-effort — see README security section)
  • TUI controls: palette actions for peers / inbox / outbox / rename use explicit host dialogs with confirmations; single-Enter slash commands unchanged
  • Slash commands self-register: /peers, /list-agents, /peers-name, /peers-inbox, /peers-outbox are injected via the plugin config hook — fresh installs get them without any manual config (opencode does not scan plugin packages for commands/*.md)

Fixes (review round on top of the parity branch)

  • Fire-and-forget ACK dispatch no longer rejects unhandled — a slow spool lock cannot crash the host opencode process
  • Prompt injection is bounded by injectTimeoutMs (default 30s) — a hung promptAsync no longer wedges delivery and dispose() forever
  • Startup routing window closed: inbound messages arriving before deferred session discovery wait (bounded) instead of getting a terminal 404
  • Transient "message not visible yet" permission verdicts are no longer cached as local turns
  • Protected-permission denylist extended (shell rc, .gitconfig, .netrc, .kube, .docker, LaunchAgents, crontab); README documents it as best-effort, not a boundary

Tests

  • npm test: 168/168 pass — including real OpenCode 1.18.15 process coverage: two OS processes, same-name sessions in one process, exact routing, concurrent busy injection, restart recovery, v1↔v2 interop, hold accept/drop/expiry ACKs
  • Node 18.20.8 focused protocol coverage: pass
  • npm run typecheck, npm pack --dry-run: pass
  • Real TUI E2E: /peers and /peers-outbox execute on a single Enter from the home route

Docs

  • README rewritten: v2 architecture, migration behavior, security model (incl. honest limits of the allow guardrail), Claude Code comparison, new options (heldExpiryMs, maxMessageAgeMs, inboundPolicy: "auto", injectTimeoutMs)

Full Changelog: v0.1.7...v0.2.0