Skip to content

feat(acp): add Agent Client Protocol support with daemon relay#625

Open
Wirasm wants to merge 2 commits intomainfrom
acp-experiment
Open

feat(acp): add Agent Client Protocol support with daemon relay#625
Wirasm wants to merge 2 commits intomainfrom
acp-experiment

Conversation

@Wirasm
Copy link
Owner

@Wirasm Wirasm commented Mar 4, 2026

Summary

  • Problem: KILD communicates with AI agents via raw PTY byte streams, limiting structured interaction (no typed tool calls, permission flows, or plan visualization)
  • Why it matters: ACP (JSON-RPC 2.0 over stdio) is an industry standard adopted by 25+ agents — integrating it transforms KILD from a terminal multiplexer into a structured agent orchestration platform
  • What changed: New kild-acp crate, RuntimeMode::Acp variant, ACP daemon relay (transparent byte tunnel), --acp CLI flag, agent backend ACP command declarations, UI awareness
  • What did not change (scope boundary): No rich ACP panel view (Phase 2), no ACP message parsing in daemon (intentionally transparent relay), no changes to existing PTY session flow

Label Snapshot (required)

  • Risk label: risk: medium
  • Size label: size: L
  • Scope labels: core, agent, daemon, runtime
  • Module labels: agent:claude, agent:gemini, agent:opencode
  • Contributor tier label: N/A
  • If any auto-label is incorrect, note requested correction: N/A

Change Metadata

  • Change type: feature
  • Primary scope: runtime

Linked Issue

  • Closes #
  • Related #
  • Depends on #
  • Supersedes #

Validation Evidence (required)

cargo fmt --check              # ✓ clean
cargo clippy --all -- -D warnings  # ✓ clean
cargo test --all               # ✓ 2,493 tests pass, 0 failures
cargo build --all              # ✓ clean
  • Evidence provided: Full build + test + lint pass. E2E manual test: kild create test-acp --acp → daemon spawned claude-code-acp (PID confirmed) → kild list showed runtime_mode: acpkild stop killed process → kild destroy cleaned up.
  • If any command is intentionally skipped, explain why: N/A

Security Impact (required)

  • New permissions/capabilities? No
  • New external network calls? No
  • Secrets/tokens handling changed? No
  • File system access scope changed? No

Privacy and Data Hygiene (required)

  • Data-hygiene status: pass
  • Redaction/anonymization notes: N/A
  • Neutral wording confirmation: Yes

Compatibility / Migration

  • Backward compatible? Yes — ACP is opt-in via --acp flag, all existing PTY sessions unchanged
  • Config/env changes? No
  • Migration needed? No

Human Verification (required)

  • Verified scenarios: Full E2E flow — create ACP session with claude-code-acp, verify process running via ps, check runtime_mode: acp in JSON list output, stop session, destroy session
  • Edge cases checked: --acp conflicts with --daemon/--no-daemon (clap error), attach refused for ACP sessions
  • What was not verified: ACP message-level protocol handshake through kild-acp crate (requires Phase 2 UI integration), opencode/gemini ACP agents

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows: New kild-acp crate (standalone, no internal deps), kild-protocol (new message types — non_exhaustive enums), kild-daemon (new acp/ module), agent backends (new trait method with default None), CLI (new flag), UI (badge + guard)
  • Potential unintended effects: None — ACP is entirely additive, existing PTY path untouched
  • Guardrails/monitoring for early detection: All existing tests pass unchanged, new tests cover all new code paths

Rollback Plan (required)

  • Fast rollback command/path: git revert <commit> — single commit, clean revert
  • Feature flags or config toggles: --acp flag is opt-in, no config changes
  • Observable failure symptoms: kild create --acp would fail to spawn agent process, kild list would not show ACP sessions

Risks and Mitigations

  • Risk: ACP SDK (agent-client-protocol v0.9) is pre-1.0 and API may change
    • Mitigation: kild-acp crate is a standalone wrapper with no internal deps — SDK upgrades are isolated to one crate
  • Risk: Daemon relay doesn't validate ACP message framing (transparent byte tunnel)
    • Mitigation: Intentional design — protocol parsing happens in client (kild-acp), daemon stays simple. Malformed messages fail at the client layer.

Architecture

Client (kild-ui/CLI)                 kild-daemon                    Agent
  CreateAcpSession ────────────────→  spawn agent --acp
  AcpRelay { data } ──────────────→  write to stdin ──────────────→ JSON-RPC
  ← AcpRelay { data } ←────────────  read from stdout ←─────────── JSON-RPC
  ← AcpSessionExited ←─────────────  detect process exit

New crate: kild-acp

Wraps the agent-client-protocol SDK behind a Send+Sync API. The SDK produces !Send futures, so the crate spawns a dedicated OS thread with a single-threaded tokio runtime + LocalSet. External callers communicate via mpsc channels.

Files changed (32 files, +1698/-71)

File list
  • Cargo.lock / Cargo.toml — workspace dependency additions
  • crates/kild-acp/new crate (6 files: lib, errors, types, client_impl, connection, runner)
  • crates/kild-protocol/src/types.rsRuntimeMode::Acp
  • crates/kild-protocol/src/messages.rs — 6 new ACP message types
  • crates/kild-core/src/agents/traits.rsacp_command() method + AcpCommandInfo
  • crates/kild-core/src/agents/backends/mod.rs — 2 new macro arms for ACP agents
  • crates/kild-core/src/agents/registry.rsget_acp_command(), supports_acp()
  • crates/kild-core/src/agents/mod.rs — re-exports
  • crates/kild-core/src/daemon/client.rscreate_acp_session()
  • crates/kild-core/src/sessions/daemon_spawn.rsspawn_acp_agent()
  • crates/kild-core/src/sessions/daemon_helpers.rs — env var builder for ACP
  • crates/kild-core/src/sessions/create.rs — ACP runtime mode dispatch
  • crates/kild-core/src/sessions/open.rs — ACP session reopen
  • crates/kild-daemon/src/acp/new module (mod.rs + relay.rs)
  • crates/kild-daemon/src/server/connection.rs — dispatch 3 ACP message types
  • crates/kild-daemon/src/session/manager.rscreate_acp_session(), write_acp_stdin()
  • crates/kild-daemon/src/lib.rs — acp module declaration
  • crates/kild-ui/src/views/sidebar.rs — ACP badge
  • crates/kild-ui/src/views/main_view/kild_handlers.rs — terminal tab guard
  • crates/kild/src/app/session.rs--acp flag definition
  • crates/kild/src/commands/create.rs — read acp flag
  • crates/kild/src/commands/open.rs[acp] mode label
  • crates/kild/src/commands/attach.rs — refuse attach for ACP
  • crates/kild/src/commands/helpers.rsresolve_runtime_mode() with ACP

Wirasm added 2 commits March 3, 2026 17:18
Integrate ACP (JSON-RPC 2.0 over stdio) as a new runtime mode alongside
PTY-based terminal sessions. The daemon acts as a transparent byte relay,
spawning ACP agent processes and tunneling stdio between clients and agents
without parsing ACP messages.

New kild-acp crate wraps the agent-client-protocol SDK behind a Send+Sync
API using a dedicated single-threaded tokio runtime. Agents declare ACP
support via acp_command() on AgentBackend (claude, gemini, opencode).

CLI: --acp flag on create/open, [acp] badge in list, attach refused.
Daemon: ACP process spawn with stdin/stdout/exit relay tasks.
UI: ACP badge in sidebar, terminal tab guard for ACP sessions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant