small gleam coding and persistent agent daemon with a detachable cli and a canvas ui forked from okami.mom/albedo
4.0 kB · 60 lines
Markdown
at acp

ACP frontend #

Read the user-facing guide before changing ACP behavior. This is Zed's Agent Client Protocol, not IBM/BeeAI's unrelated REST protocol.

cli/internal/acp owns stable v1 newline JSON-RPC, bidirectional callback IDs, attachments, capability admission and projection from normalized daemon events. cli/internal/cli/acp.go only registers the command and passes invocation streams. Call named cli/internal/daemon operations through generated OpenAPI HTTP; never add another harness loop, transcript store, ad-hoc HTTP or receipt/SSE recovery.

The reusable client_binding domain owns portable authorization, read and write requests, generations, monitors, bounded pending queues and leases. Only ACP knows session/request_permission and fs/read_text_file method names. The session actor serializes idle installation and native adoption around the existing composition reload lifecycle. Stage before prepare; commit after strict requested MCP discovery. Rollback follows the actual surviving kernel, not the desired one. Unknown release leaves the approval policy sealed.

Only the nonsecret approval-required policy is durable. Ordinary CLI open must never clear it. EOF, restart, extension disable and failed replacement must not turn editor-controlled sessions into unrestricted native execution. Proven missing broker plus explicit idle adoption is different from an unavailable owner or a stale active generation. Transient credentials and catalogues must not enter saved settings, credentials, global MCP tables, snapshots, model context or crash logs.

Approve complete input before every model tool invocation, including Python and direct MCP; nested Python MCP calls have independent nonempty callback call IDs. Denial, malformed/unknown decisions and cancellation never grant execution. Permission waits have no short human timeout. Check the existing run stop latch while waiting and again before invocation: Loop.stopped means true = cancelled. Do not invert that predicate while updating a wrapper; ordinary wrappers use false. This is mediation, not a sandbox inside already-approved Python source.

Normal files helpers route each supported operation to live editor capabilities. Callback failure is not disk fallback. Partial edits require matching read/write authority, including dynamic rebinds, and are explicitly not compare-and-swap. Remote helpers remain remote/local, not this editor's buffers. Read/write deadlines are 20 seconds, beneath synchronous Python host calls; late write outcomes can be unknown. Snapshot/reset processing must not dispatch a side-effecting callback twice.

An ACP prompt stays pending until its captured durable input settles. Cancel that input, not whatever later turn runs. Interruption acknowledgement is not completion. Disconnect never deletes conversations or stops the shared daemon. Transient MCP release must join physical closure before certifying disposal; a timeout is not proof of close. Editor-only MCP activation never starts deselected global servers.

History load replays chronological durable entries, not compacted model context. Resume attaches without replay. Use typed ForwardHistoryPage and opaque Next, not a reverse cursor repurposed as an offset; entries can share a position. Keep identical distinct entries. Match provisional output to committed messages using bounded fingerprints, not unbounded replies. Refuse replaced/reset streams when v1 cannot replace displayed text. Bound frames, queues, cursors and callback IDs.

Real protocol scenarios live in cli/test/e2e/acp_test.go, on the shared hermetic daemon harness with fake providers and real stdio/HTTP peers. Binding ownership, restart/failclosed policy and rollback scenarios live in test/e2e/client_binding_test.py. In-memory tests cover deterministic framing and fault injection. Run codegen checks and the full ./test.sh; an older limited adapter's gate is not evidence for the newly advertised capabilities.