diff --git a/docs/channels/matrix.md b/docs/channels/matrix.md index 14d934654c5..a2dafba6742 100644 --- a/docs/channels/matrix.md +++ b/docs/channels/matrix.md @@ -470,6 +470,23 @@ Matrix supports native Matrix threads for both automatic replies and message-too - Top-level Matrix room/DM `/focus` creates a new Matrix thread and binds it to the target session when `threadBindings.spawnSubagentSessions=true`. - Running `/focus` or `/acp spawn --thread here` inside an existing Matrix thread binds that current thread instead. +## ACP conversation bindings + +Matrix rooms, DMs, and existing Matrix threads can be turned into durable ACP workspaces without changing the chat surface. + +Fast operator flow: + +- Run `/acp spawn codex --bind here` inside the Matrix DM, room, or existing thread you want to keep using. +- In a top-level Matrix DM or room, the current DM/room stays the chat surface and future messages route to the spawned ACP session. +- Inside an existing Matrix thread, `--bind here` binds that current thread in place. +- `/new` and `/reset` reset the same bound ACP session in place. +- `/acp close` closes the ACP session and removes the binding. + +Notes: + +- `--bind here` does not create a child Matrix thread. +- `threadBindings.spawnAcpSessions` is only required for `/acp spawn --thread auto|here`, where OpenClaw needs to create or bind a child Matrix thread. + ### Thread Binding Config Matrix inherits global defaults from `session.threadBindings`, and also supports per-channel overrides: diff --git a/src/auto-reply/reply/commands-acp.test.ts b/src/auto-reply/reply/commands-acp.test.ts index 769819d0897..22c622b1737 100644 --- a/src/auto-reply/reply/commands-acp.test.ts +++ b/src/auto-reply/reply/commands-acp.test.ts @@ -920,6 +920,34 @@ describe("/acp command", () => { ); }); + it("binds Matrix rooms with --bind here without requiring thread spawn", async () => { + const cfg = { + ...baseCfg, + channels: { + matrix: { + threadBindings: { + enabled: true, + spawnAcpSessions: false, + }, + }, + }, + } satisfies OpenClawConfig; + + const result = await runMatrixAcpCommand("/acp spawn codex --bind here", cfg); + + expect(result?.reply?.text).toContain("Bound this conversation to"); + expect(hoisted.sessionBindingBindMock).toHaveBeenCalledWith( + expect.objectContaining({ + placement: "current", + conversation: expect.objectContaining({ + channel: "matrix", + accountId: "default", + conversationId: "!room:example.org", + }), + }), + ); + }); + it("creates Matrix thread-bound ACP spawns from top-level rooms when enabled", async () => { const cfg = { ...baseCfg,