|
| 1 | +--- |
| 2 | +name: acpremote |
| 3 | +description: Use for `acpremote` tasks: exposing ACP agents or stdio ACP commands over WebSocket, mirroring remote ACP endpoints locally, host ownership semantics, metadata/auth routes, and remote transport examples. |
| 4 | +--- |
| 5 | + |
| 6 | +# acpremote Skill |
| 7 | + |
| 8 | +Use this skill when the task is about the `acpremote` transport package. |
| 9 | + |
| 10 | +This package is the repo's ACP transport/helper layer. It assumes the runtime already speaks ACP |
| 11 | +and focuses on moving that ACP boundary across WebSocket transport or back into a local ACP proxy. |
| 12 | + |
| 13 | +It is not an adapter. |
| 14 | + |
| 15 | +That distinction matters: |
| 16 | + |
| 17 | +- adapters turn framework runtimes into ACP |
| 18 | +- `acpremote` transports or mirrors an ACP boundary that already exists |
| 19 | + |
| 20 | +## Start Here |
| 21 | + |
| 22 | +If you only need the shortest high-signal path: |
| 23 | + |
| 24 | +1. read `Quick Routing` |
| 25 | +2. open `server.py` for exposure-path questions |
| 26 | +3. open `client.py` and `proxy_agent.py` for mirror-path questions |
| 27 | +4. open `command.py` only when the upstream runtime is ACP-over-stdio |
| 28 | + |
| 29 | +## Quick Routing |
| 30 | + |
| 31 | +| If the task is about... | Use this skill? | Open first | |
| 32 | +| --- | --- | --- | |
| 33 | +| expose an existing ACP agent over WebSocket | Yes | `server.py`, `config.py` | |
| 34 | +| expose a stdio ACP command over WebSocket | Yes | `command.py`, `server.py` | |
| 35 | +| mirror a remote ACP endpoint locally | Yes | `client.py`, `proxy_agent.py` | |
| 36 | +| bearer auth or metadata routes | Yes | `auth.py`, `metadata.py`, `server.py` | |
| 37 | +| remote host ownership or `remote_cwd` | Yes | `proxy_agent.py`, `client.py`, `metadata.py` | |
| 38 | +| line buffering / frame relay issues | Yes | `stream.py` | |
| 39 | +| adapting a Pydantic or LangChain runtime to ACP | No, pair with adapter skill | adapter packages | |
| 40 | + |
| 41 | +## Package Boundary |
| 42 | + |
| 43 | +`acpremote` owns: |
| 44 | + |
| 45 | +- WebSocket transport |
| 46 | +- stdio-to-WebSocket ACP relaying |
| 47 | +- remote mirror proxy behavior |
| 48 | +- `/acp` metadata |
| 49 | +- `/healthz` |
| 50 | +- bearer-token protection |
| 51 | +- transport latency metadata/projection |
| 52 | +- host-ownership policy for mirrored clients |
| 53 | + |
| 54 | +It does not own: |
| 55 | + |
| 56 | +- adapting `pydantic_ai.Agent` |
| 57 | +- adapting LangGraph/LangChain graphs |
| 58 | +- root CLI target loading |
| 59 | +- Codex auth parsing |
| 60 | + |
| 61 | +## Do Not Confuse With |
| 62 | + |
| 63 | +- `acpremote` vs `acpkit-sdk` |
| 64 | + `acpremote` is transport; `acpkit` is the root CLI/runtime package |
| 65 | +- `acpremote` vs `pydantic-acp` |
| 66 | + `acpremote` exposes or mirrors ACP; `pydantic-acp` creates ACP from a Pydantic runtime |
| 67 | +- `acpremote` vs `langchain-acp` |
| 68 | + `acpremote` transports ACP; `langchain-acp` adapts graph runtimes into ACP |
| 69 | + |
| 70 | +## Primary References |
| 71 | + |
| 72 | +Package references: |
| 73 | + |
| 74 | +- Raw skill: |
| 75 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/.agents/skills/acpremote/SKILL.md` |
| 76 | +- Raw transport docs: |
| 77 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/docs/acpremote.md` |
| 78 | +- Raw remote-host docs: |
| 79 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/docs/examples/remote-hosting.md` |
| 80 | +- Rendered docs: |
| 81 | + `https://vcoderun.github.io/acpkit/acpremote/` |
| 82 | +- Source tree: |
| 83 | + `https://github.com/vcoderun/acpkit/tree/main/packages/transports/acpremote` |
| 84 | + |
| 85 | +Cross-skill references: |
| 86 | + |
| 87 | +- Root package skill: |
| 88 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/.agents/skills/acpkit-sdk/SKILL.md` |
| 89 | +- Pydantic adapter skill: |
| 90 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/.agents/skills/pydantic-acp/SKILL.md` |
| 91 | +- LangChain adapter skill: |
| 92 | + `https://raw.githubusercontent.com/vcoderun/acpkit/main/.agents/skills/langchain-acp/SKILL.md` |
| 93 | + |
| 94 | +## Public Surface |
| 95 | + |
| 96 | +Server-side seams: |
| 97 | + |
| 98 | +- `serve_acp(...)` |
| 99 | +- `serve_command(...)` |
| 100 | +- `serve_stdio_command(...)` |
| 101 | + |
| 102 | +Client-side seam: |
| 103 | + |
| 104 | +- `connect_acp(...)` |
| 105 | + |
| 106 | +Support types: |
| 107 | + |
| 108 | +- `TransportOptions` |
| 109 | +- `CommandOptions` |
| 110 | +- `ServerOptions` |
| 111 | + |
| 112 | +Package entrypoint: |
| 113 | + |
| 114 | +- `https://github.com/vcoderun/acpkit/blob/main/packages/transports/acpremote/src/acpremote/__init__.py` |
| 115 | + |
| 116 | +## Module Guide |
| 117 | + |
| 118 | +| Subsystem | Key files | Use them for | |
| 119 | +| --- | --- | --- | |
| 120 | +| server and routing | `server.py`, `auth.py`, `metadata.py`, `config.py`, `limits.py` | server startup, mount paths, metadata, health, auth, limits | |
| 121 | +| remote client and proxy behavior | `client.py`, `proxy_agent.py` | remote connection setup, metadata fetch, local mirroring, host ownership | |
| 122 | +| command-backed transport | `command.py` | stdio ACP commands that need WebSocket exposure | |
| 123 | +| stream plumbing | `stream.py` | line buffering, text/binary frame handling, sender/receiver lifecycle | |
| 124 | + |
| 125 | +## Core Transport Shapes |
| 126 | + |
| 127 | +### Shape 1: Existing ACP agent object |
| 128 | + |
| 129 | +Use: |
| 130 | + |
| 131 | +- `serve_acp(...)` |
| 132 | + |
| 133 | +Meaning: |
| 134 | + |
| 135 | +1. some runtime already produced an `acp.interfaces.Agent` |
| 136 | +2. `acpremote` exposes that ACP boundary over WebSocket |
| 137 | + |
| 138 | +### Shape 2: Existing stdio ACP command |
| 139 | + |
| 140 | +Use: |
| 141 | + |
| 142 | +- `serve_command(...)` |
| 143 | +- `serve_stdio_command(...)` |
| 144 | + |
| 145 | +Meaning: |
| 146 | + |
| 147 | +1. the upstream runtime only exposes ACP on stdin/stdout |
| 148 | +2. `acpremote` spawns that command |
| 149 | +3. stdin/stdout ACP frames are bridged onto WebSocket |
| 150 | + |
| 151 | +### Shape 3: Remote ACP mirrored locally |
| 152 | + |
| 153 | +Use: |
| 154 | + |
| 155 | +- `connect_acp(...)` |
| 156 | + |
| 157 | +Meaning: |
| 158 | + |
| 159 | +1. there is an existing remote ACP WebSocket endpoint |
| 160 | +2. `acpremote` opens a remote connection |
| 161 | +3. the local machine gets a proxy ACP agent that mirrors the remote endpoint |
| 162 | + |
| 163 | +## Remote Host Ownership |
| 164 | + |
| 165 | +This is one of the most important rules in the package. |
| 166 | + |
| 167 | +The default should keep the remote host authoritative for: |
| 168 | + |
| 169 | +- `cwd` |
| 170 | +- host-backed filesystem ownership |
| 171 | +- host-backed terminal ownership |
| 172 | + |
| 173 | +That is why the proxy layer: |
| 174 | + |
| 175 | +- prefers remote metadata like `remote_cwd` |
| 176 | +- strips local host-backed capabilities before forwarding `initialize(...)` |
| 177 | + |
| 178 | +Use client passthrough only when the product explicitly wants the local machine to become host |
| 179 | +owner. |
| 180 | + |
| 181 | +If a user reports: |
| 182 | + |
| 183 | +- remote command executed in local cwd |
| 184 | +- local filesystem used instead of remote filesystem |
| 185 | +- remote agent owning the wrong host |
| 186 | + |
| 187 | +inspect `proxy_agent.py` and metadata flow first. |
| 188 | + |
| 189 | +## Metadata and Health Surface |
| 190 | + |
| 191 | +The transport package also owns the lightweight HTTP surface around the WebSocket endpoint: |
| 192 | + |
| 193 | +- `/acp` |
| 194 | +- `/healthz` |
| 195 | + |
| 196 | +Typical uses: |
| 197 | + |
| 198 | +- health checks |
| 199 | +- transport metadata inspection |
| 200 | +- remote `cwd` discovery |
| 201 | +- debugging auth and route configuration |
| 202 | + |
| 203 | +This is transport-level behavior. Do not push it into adapter code. |
| 204 | + |
| 205 | +## Latency and Transport Visibility |
| 206 | + |
| 207 | +`acpremote` can emit transport-observed latency through: |
| 208 | + |
| 209 | +- metadata fields |
| 210 | +- optional visible latency projection |
| 211 | + |
| 212 | +Keep the distinction explicit: |
| 213 | + |
| 214 | +- this is proxy-observed timing |
| 215 | +- it is not a claim of clock-synchronized one-way network truth |
| 216 | + |
| 217 | +## Skill-Bundled Examples |
| 218 | + |
| 219 | +Skill-local examples: |
| 220 | + |
| 221 | +- `https://github.com/vcoderun/acpkit/blob/main/.agents/skills/acpremote/examples/serve_command.py` |
| 222 | +- `https://github.com/vcoderun/acpkit/blob/main/.agents/skills/acpremote/examples/mirror_remote.py` |
| 223 | +- `https://github.com/vcoderun/acpkit/blob/main/.agents/skills/acpremote/examples/README.md` |
| 224 | + |
| 225 | +These demonstrate: |
| 226 | + |
| 227 | +- exposing a stdio ACP command remotely |
| 228 | +- mirroring a remote ACP endpoint locally |
| 229 | +- using `TransportOptions` intentionally |
| 230 | + |
| 231 | +## Handoff Rules |
| 232 | + |
| 233 | +Pair or switch to: |
| 234 | + |
| 235 | +- `acpkit-sdk` |
| 236 | + when the remote host is reached through `acpkit serve ...` or the local mirror is |
| 237 | + `acpkit run --addr ...` |
| 238 | +- `pydantic-acp` |
| 239 | + when a Pydantic agent is adapted first, then exposed remotely |
| 240 | +- `langchain-acp` |
| 241 | + when a LangGraph or DeepAgents graph is adapted first, then exposed remotely |
| 242 | + |
| 243 | +Common end-to-end references: |
| 244 | + |
| 245 | +- root recipe index: |
| 246 | + `https://github.com/vcoderun/acpkit/blob/main/.agents/skills/acpkit-sdk/examples/README.md` |
| 247 | +- public Pydantic example: |
| 248 | + `https://github.com/vcoderun/acpkit/blob/main/examples/pydantic/finance_agent.py` |
| 249 | +- public LangChain example: |
| 250 | + `https://github.com/vcoderun/acpkit/blob/main/examples/langchain/workspace_graph.py` |
| 251 | + |
| 252 | +## Guardrails |
| 253 | + |
| 254 | +- Do not call `acpremote` an adapter. |
| 255 | +- Do not claim it can adapt a framework runtime by itself. |
| 256 | +- Do not blur ACP adaptation with ACP transport. |
| 257 | +- If the task is really about `acpkit run ...` or `acpkit serve ...`, pair this skill with |
| 258 | + `acpkit-sdk`. |
0 commit comments