Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,70 @@

## Unreleased

### Breaking

- **Collaboration layer renamed `amux` → `rooms`.** The crate, library, and
binary are now `rooms`, and the wire namespace changed accordingly:
- `amux/*` notification/control methods → `rooms/*` (e.g. `amux/turn_started`
→ `rooms/turn_started`, `amux/queue_prompt` → `rooms/queue_prompt`).
- `_meta.amux` → `_meta.rooms` (on `session/attach` results and propagated
request metadata); the `session/list` decoration key moved likewise.
- The `amuxTurnId` field is now `roomsTurnId`.
Clients written against the previous `amux/*` releases must update method
names and `_meta` keys. The lower-level core crate/binary stays `acp-mux`.

### Added

- **Two-crate workspace: core mux vs Rooms layer.** The repo is now a Cargo
workspace with a hard, compiler-enforced boundary:
- `acp-mux` (lib `acp_mux`, binary `acp-mux`) — the standalone generic 1→N
ACP multiplexer. Id translation, response routing, first-writer-wins
agent-request fan-in, `initialize`/`session/new` caching, `fs/*`/`terminal/*`
safety, plain replay/late-join, and an RFD-#533-baseline
`session/attach`/`session/detach`. It contains zero `rooms/*` knowledge and
does not depend on the `rooms` crate. The standalone binary attaches on
`?mux=<id>`.
- `rooms` (lib `rooms`, binary `rooms`) — the Rooms collaboration protocol,
implemented as a `MuxExtension` plugged into the core mux actor. Owns turns,
queue/steer/cancel, presence, segments, `_meta.rooms` attach
enrichment, and all `rooms/*` frames. Depends on `acp-mux`. The `rooms`
binary attaches on `?room=<id>`.
- The boundary is realized through a `MuxExtension` trait + `MuxCtx`
capability surface in core (core ships a no-op extension; `rooms` provides
the real one). There is now a single multiplexer implementation.
- **Standalone `acp-mux` binary.** A pure one-agent-to-many-clients mux with no
collaboration layer, for clients that only need raw ACP mirroring.
- **Optional persistent replay store.** `--replay-store <DIR>` persists
broadcast-tier room history as append-only JSONL and rehydrates replay
frames/segment bookends on restart. The upstream agent still owns actual
conversation state.
broadcast-tier room history as append-only JSONL and rehydrates the broadcast
replay log on restart so late joiners can recover the transcript via
`historyPolicy: full_lineage`. Segment lineage and current-segment (`full`)
scoping are not reconstructed across restart yet — see the "cross-restart
segment fidelity" limitation in `docs/design/rooms.md`. The upstream agent
still owns actual conversation state.
- **Client contract fixtures.** `docs/examples/client-contract/` contains
copyable request/response/notification JSON fixtures for `session/attach`,
turn lifecycle, queue lifecycle, agent-request lifecycle, replay markers,
and segment lineage.

### Changed

- **Library reorganized into two crates.** Core multiplexing moved from
`src/room/state.rs` (`RoomInner`) into `crates/acp-mux/src/mux/` (`MuxCore` +
actor) with no `rooms/*` concerns; the collaboration behavior moved into
`crates/rooms/src/extension/` (`RoomsExtension: MuxExtension`). The `rooms`
crate's `RoomRegistry`/`server` are now thin wrappers over the core
`MuxRegistry::with_extension(...)`. Aside from the `amux/*` → `rooms/*`
namespace rename above, the `rooms` binary's behavior is otherwise unchanged;
the integration suite and `docs/examples/client-contract/` fixtures were
updated to the new namespace and still pass.
- **Provider-neutral core contract.** The mainline mux is now documented and
implemented as a generic ACP multiplexer / agent mirror rather than a
provider-specific adapter. Provider metadata is passed through opaquely;
mux-owned lifecycle state is driven only by JSON-RPC envelopes, ACP method
names, `session/load`, and observable ACP `params.sessionId` changes.
- **Docs reframed around rooms, mirrors, and generic ACP clients.** README,
roadmap, and design docs now describe `acp-mux` as a reusable ACP room
server with provider-neutral safety defaults and an explicit `amux/*`
server with provider-neutral safety defaults and an explicit `rooms/*`
side channel.

### Removed
Expand Down
21 changes: 20 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 3 additions & 31 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,31 +1,3 @@
[package]
name = "acp-mux"
version = "0.1.3"
edition = "2024"

# The crate (and GitHub repo) is "acp-mux" but the installed binary is
# the shorter "amux". `src/bin/mock_acp.rs` is still auto-detected.
# The library exists so integration tests under `tests/` can use the
# server/registry/protocol modules without spawning the binary.
[lib]
name = "amux"
path = "src/lib.rs"

[[bin]]
name = "amux"
path = "src/main.rs"

[dependencies]
anyhow = "1.0.102"
axum = { version = "0.8.9", features = ["ws", "macros"] }
bytes = "1.11.1"
clap = { version = "4.6.1", features = ["derive"] }
futures = "0.3.32"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"
thiserror = "2.0.18"
tokio = { version = "1.52.3", features = ["full"] }
tokio-tungstenite = "0.29.0"
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter", "fmt"] }
url = "2.5.8"
[workspace]
members = ["crates/acp-mux", "crates/rooms"]
resolver = "3"
Loading
Loading