19. Companion messaging

"Companion messaging" lets you remotely drive the desktop assistant, receive approvals and collaborate as a team from your phone.

19.1 Channels

  • WeChat channel: scan-to-login, no developer account needed.
  • Reserved for Feishu / DingTalk and others.

19.2 Pairing

  1. Settings → Companion Messaging.
  2. Scan the QR code with WeChat to log into the channel.
  3. Generate a 6-digit pairing code on the desktop for the target workspace (10-minute TTL).
  4. Send /bind 123456 in a WeChat DM or group.

Once paired, desktop and WeChat sessions share state and survive restarts.

19.3 Routing strategy

Inbound messages match in priority order; first hit wins:

  1. The session named by /new [text].
  2. The session named by /s <short-id> (the inline [s:<short-id>] prefix is equivalent).
  3. The session most recently active for this peer.
  4. A stable fallback session auto-assigned on first inbound.

On the workspace axis: inline [ws:<name>] override > the peer's bound workspace > the global default workspace.

19.4 Built-in commands

Command Purpose
/bind <code> Bind to workspace
/ws <name> Persistently switch this peer's bound workspace (survives restarts; the next message starts a fresh session; unknown names get a reply listing available workspaces; use the [ws:<name>] prefix for a one-message switch)
/sessions List recent sessions
/new [text] New session
/s <short-id> Switch session (≥4-char prefix)
/approve / /always / /deny <id> Approval
/stop / /resume Pause the peer and terminate running tasks (persists across restarts) / resume
/help Help

19.5 Behaviour notes

  • Typing indicator: the assistant uses the channel's native "typing" affordance during processing instead of a placeholder text — no spam.
  • Auto-chunking: long replies are split (default min 200 / idle 3 s / max 3800 chars) to avoid hitting WeChat's per-message cap.
  • Cross-device handoff: /s <short-id> on the phone resumes an in-progress desktop session.
  • Push initiation: the assistant can push intermediate results to a group or DM during a run, e.g. progress on a long-running task.

19.6 Group collaboration

Once bound to a group:

  • Multiple people can talk to the assistant; replies are visible to everyone in the group.
  • Approval cards are visible to all; whoever taps first decides.
  • /sessions lists every active session in the group, handy for team leads.

19.7 Two-way pending badges + inbound parking queue

Settings → Companion Messaging → Workspace Bindings shows a two-way badge per row (only when count > 0):

Badge Meaning
↑ N to send Outbound chunks that failed or are backed up by channel cool-down
↓ N to handle Inbound messages parked while the workspace is closed

Inbound parking: previously if the workspace was closed when a peer sent a message, it bounced back "workspace not running, please resend". Now it's parked + acknowledged "received; will auto-process when open; no need to resend". When the workspace is back up, parked messages auto-deliver (or you can toggle auto-delivery off in routing policy and use a manual "Deliver" button on the binding row; or "Discard"). The parking queue hard-expires after 24 hours, on par with the outbox; expired entries are recorded as a visible session message.

19.8 Manage bindings for closed workspaces

If a workspace is currently closed (removed from the main UI / not opened), its companion-messaging bindings aren't dropped — they show with an "Unopened" badge for at-a-glance distinction:

  • "Reopen" button — one click brings the workspace back to the main UI and restores conversation capability.
  • "Unbind" button — pops a confirmation dialog (in-app ConfirmDialog, rendered above Settings cleanly). Confirm to unbind immediately.

Earlier versions used native confirm() and these buttons silently no-op'd inside the WebView; fixed in this release.

19.9 Safety

  • All IM messages travel only within sessions and workspaces you've bound; never leaked into random groups.
  • The pairing code expires after 10 minutes; a screenshot after expiry can't be used to re-bind.
  • You can unbind a peer at any time from Settings → Companion Messaging with immediate effect.