Skip to content

Feature: register custom/third-party ACP runtimes (e.g. Hermes, self-hosted, SSH-bridged agents) #16

@rexamus

Description

@rexamus

Summary

Today the ACP runtime registry is hard-coded to four entries — codex-acp, claude-acp, gemini-acp, kilo-acp — in apps/desktop/src/features/ai/utils/runtimeMetadata.ts (RUNTIME_METADATA). The customBinaryPath setting in AIProvidersSettings.tsx only overrides the binary path for those four IDs; it doesn't allow registering a new runtime.

This means users with their own ACP-speaking agents (Hermes, internal tooling, fine-tuned wrappers, SSH-bridged remote agents, etc.) can't connect them to NeverWrite — even though Zed and other ACP clients let you do this with a few lines of config.

Use cases

  • Custom memory/indexing wrappers — agents that wrap an LLM with their own persistent memory store. Routing prompts through them via ACP captures the conversation + file context into that memory; routing through the built-in Claude/Codex runtimes does not.
  • Remote agents over SSH — running an ACP server on a workstation/cluster and tunneling stdio over SSH from the laptop running NeverWrite.
  • Fine-tuned or self-hosted models — anything that speaks ACP/JSON-RPC over stdio.
  • OSS ACP runtimes that ship later — avoids needing a NeverWrite release every time a new ACP agent appears.

Proposed shape

A user-defined runtime entry, configured in Settings → AI Providers, with at minimum:

Field Notes
id user-chosen, must be unique
name display name
command program to launch (absolute path or PATH-resolved)
args array of arguments
env optional environment variables
cwd optional working directory
capabilities optional override; default to a conservative set

Persisted in the same settings store the existing runtime overrides use. Spawned the same way the built-in ACP sidecars are spawned (stdio JSON-RPC).

Why this is low-risk

  • ACP is already the transport for the four built-ins, so the spawn/lifecycle/IPC code paths exist.
  • The change is essentially: turn RUNTIME_METADATA from a const array into [...builtIns, ...userRuntimes], and add a small CRUD UI in AIProvidersSettings.tsx.
  • Capability discovery already happens at runtime via the ACP handshake, so the hard-coded capabilities arrays in runtimeMetadata.ts are nice-to-have hints rather than load-bearing.

Workaround until then

Users can sacrifice one of the built-in slots (e.g. Kilo) by pointing its customBinaryPath at a wrapper script that exec's their own ACP server. This works but mislabels the runtime in the UI and inherits Kilo's hard-coded capability list.

Happy to contribute

If a maintainer signals this is in scope, I'm willing to take a stab at a PR. Wanted to file the issue first so the design isn't wasted effort.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions