@agentproto/cli 0.1.0-alpha.5 → 0.1.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @agentproto/cli
2
2
 
3
- The `agentproto` binary — install, run, and serve [AIP-45 agent CLIs](https://agentproto.sh/docs/aip-45).
3
+ The `agentproto` binary — host for [AIP-45 agent CLIs](https://agentproto.sh/docs/aip-45). Install adapters, run one-shot turns, spawn long-lived sessions, expose them over a tunnel, and drive an interactive PTY from your terminal or a web client.
4
4
 
5
5
  ```bash
6
6
  npm install -g @agentproto/cli
@@ -11,50 +11,313 @@ This installs the `agentproto` executable on your `PATH`.
11
11
  ## Verbs
12
12
 
13
13
  ```text
14
- agentproto install <slug> install an adapter's underlying CLI
15
- agentproto run <slug> [opts] spawn the adapter, dispatch a turn, stream events
16
- agentproto serve --connect <url> long-running daemon (relays spawns over a tunnel)
14
+ agentproto auth <login|status|logout> authenticate against a remote host (Guilde, …)
15
+ agentproto config <show|get|set|unset|edit> read/write ~/.agentproto/config.json
16
+ agentproto daemon <install|uninstall|…> manage agentproto as a background service (launchd)
17
+ agentproto install <slug> install an adapter's underlying CLI
18
+ agentproto setup <slug> re-run an adapter's setup steps (idempotent)
19
+ agentproto run <slug> spawn the adapter, dispatch one turn, exit
20
+ agentproto serve [--connect <wss>] long-running local daemon (HTTP + MCP + sessions)
21
+ agentproto workspace <add|list|remove|use> register workspaces the daemon can spawn into
22
+ agentproto sessions [...] browse + control live sessions on the daemon
17
23
  ```
18
24
 
19
- ### `run`
25
+ `agentproto --help` prints the full usage; `--version` prints the package version.
26
+
27
+ ## Quick start
20
28
 
21
29
  ```bash
22
- # install an adapter package once
30
+ # 1. Install an adapter (one-time, per slug).
23
31
  npm i -g @agentproto/adapter-claude-code
24
32
 
25
- # run a one-shot turn against the current directory
33
+ # 2. One-shot: get a single turn back and exit.
34
+ agentproto run claude-code --cwd . --prompt "summarise this repo"
35
+
36
+ # 3. Daemon: keep the gateway alive so you can drive sessions over HTTP / MCP / WS.
37
+ agentproto serve &
38
+
39
+ # 4. Spawn a real terminal under PTY and attach to it.
40
+ agentproto sessions terminal --name claude-tui --attach -- claude
41
+ ```
42
+
43
+ ## `run` — one-shot
44
+
45
+ Spawns the adapter, sends a single prompt, streams events to stdout, exits.
46
+
47
+ ```bash
48
+ # Prompt via flag
26
49
  agentproto run claude-code --cwd . --prompt "what does this repo do?"
27
50
 
28
- # pipe a prompt over stdin
51
+ # Prompt piped over stdin
29
52
  echo "summarise CHANGELOG.md" | agentproto run claude-code
30
53
 
31
- # resume an existing protocol session
54
+ # Resume an existing adapter-side protocol session (claude-code session id)
32
55
  agentproto run claude-code --resume <session-id>
56
+
57
+ # Machine-readable: one event per line as NDJSON
58
+ agentproto run claude-code --prompt "hi" --json
33
59
  ```
34
60
 
35
- Output is human-readable by default; pass `--json` for one-event-per-line NDJSON.
61
+ For multi-turn or interactive use, see [`serve`](#serve--the-local-daemon) + [`sessions`](#sessions--browse--control-the-daemon) below.
36
62
 
37
- ### `install`
63
+ ## `install` / `setup`
38
64
 
39
65
  ```bash
40
- agentproto install claude-code # idempotent, skips if version_check passes
66
+ agentproto install claude-code # idempotent skips if version_check passes
41
67
  agentproto install claude-code --force # reinstall regardless
42
68
  agentproto install claude-code --dry-run # print steps, don't execute
69
+
70
+ agentproto setup openclaw # re-run adapter setup (env keys, login, …)
71
+ agentproto setup openclaw --only login # only specific steps
43
72
  ```
44
73
 
45
74
  v0.1 implements the `npm` install method; other package managers print a clear "not yet" message and exit non-zero.
46
75
 
47
- ### `serve` *(coming soon)*
76
+ ## `config` defaults at `~/.agentproto/config.json`
77
+
78
+ Hand-editable JSON the daemon reads at boot. CLI flags on `agentproto serve` still override anything in here; the file is the place to remember choices so you don't re-type them every restart.
79
+
80
+ ```bash
81
+ agentproto config show # dump full config
82
+ agentproto config path # print the file path
83
+ agentproto config get daemon.port # read one key
84
+ agentproto config set daemon.port 18791 # number auto-detected
85
+ agentproto config set daemon.workspace ~/code/agentik-studio
86
+ agentproto config set daemon.allowedOrigins https://guilde.work,https://app.example.com
87
+ agentproto config set tunnel.host wss://guilde.work/api/v1/agentproto/tunnel
88
+ agentproto config set tunnel.autoconnect true # --connect implied at next serve
89
+ agentproto config unset tunnel.host # forget
90
+ agentproto config edit # open in $EDITOR
91
+ ```
92
+
93
+ Schema (all fields optional):
94
+
95
+ ```jsonc
96
+ {
97
+ "daemon": {
98
+ "workspace": "/abs/path", // default cwd when not passed
99
+ "port": 18790,
100
+ "bind": "127.0.0.1",
101
+ "allowedOrigins": ["https://guilde.work"], // extends localhost defaults
102
+ "strictOrigins": false, // when true, drops localhost defaults — only allowedOrigins is honoured
103
+ "label": "jeremy@mbp"
104
+ },
105
+ "tunnel": {
106
+ "host": "wss://guilde.work/api/v1/agentproto/tunnel",
107
+ "autoconnect": false // bootstrap with --connect at serve
108
+ },
109
+ "features": { "pty": true }
110
+ }
111
+ ```
112
+
113
+ **About `strictOrigins`:** by default any browser on `localhost` (any port) is allowed to drive mutating routes — that's what makes Guilde dev / Vite / Storybook all "just work" without per-port config. Set `strictOrigins: true` if you want to lock the daemon down to a literal list (shared host, hardened setup). Note: any local user with shell access can read `runtime.json`'s token regardless of this setting; strict mode only narrows the browser-Origin surface.
114
+
115
+ ## `daemon` — run as a background service
48
116
 
49
- Long-running daemon that exposes locally-installed adapters to a remote host over a WebSocket tunnel. Wire protocol still being designed; the verb is parsed but currently exits 64 with a tracking message.
117
+ Wraps the host's init system so you don't keep a terminal open. macOS `launchd` ships today; Linux `systemd --user` and Windows are on the follow-up list (the verb prints a clear "not yet" until then).
118
+
119
+ ```bash
120
+ agentproto config set daemon.workspace ~/code/my-project # one-time
121
+ agentproto config set daemon.allowedOrigins https://guilde.work
122
+ agentproto daemon install # write plist + bootstrap
123
+ agentproto daemon status # plist? loaded? /health probe?
124
+ agentproto daemon logs --lines 30 # tail ~/.agentproto/daemon.log
125
+ agentproto daemon stop # SIGTERM
126
+ agentproto daemon start # kickstart again
127
+ agentproto daemon uninstall # bootout + delete plist
128
+ ```
129
+
130
+ `install` reads the current `config.json` and bakes its `daemon.*` keys into the plist's `ProgramArguments`. Re-run `install` after any config change to refresh. Logs land in `~/.agentproto/daemon.log` (stdout + stderr merged).
131
+
132
+ ## `auth` — talk to a remote host
133
+
134
+ ```bash
135
+ agentproto auth login --host wss://guilde.work # device-flow login → ~/.agentproto/credentials.json
136
+ agentproto auth status --host wss://guilde.work # show expiry
137
+ agentproto auth logout --host wss://guilde.work # forget the token
138
+ ```
139
+
140
+ The credential is used automatically by `agentproto serve --connect <host>` to establish the tunnel.
141
+
142
+ ## `workspace` — register spawn targets
143
+
144
+ Workspaces are slug→path bindings stored in `~/.agentproto/workspaces.json`. The daemon resolves a `workspaceSlug` field to an absolute cwd for `/sessions/agent` and `/sessions/terminal`.
145
+
146
+ ```bash
147
+ agentproto workspace add ~/code/my-project --slug my-project
148
+ agentproto workspace add ~/code/secret --slug secret --label "Skunkworks"
149
+ agentproto workspace list
150
+ agentproto workspace use my-project # mark active
151
+ agentproto workspace remove secret
152
+ ```
153
+
154
+ The active workspace is what `serve` defaults to when launched with no `--workspace`, and what the daemon falls back to when an HTTP call omits both `cwd` and `workspaceSlug`.
155
+
156
+ ## `serve` — the local daemon
157
+
158
+ ```bash
159
+ # Plain local daemon (loopback only). Reads / writes the active workspace.
160
+ agentproto serve
161
+
162
+ # Bind to a specific port + workspace
163
+ agentproto serve --port 18790 --workspace ~/code/my-project
164
+
165
+ # Local + tunnel: cloud host can dispatch spawns through the daemon.
166
+ agentproto serve --connect wss://guilde.work/api/v1/agentproto/tunnel
167
+
168
+ # Light banner + chain into the interactive dashboard (same terminal).
169
+ # Quitting the TUI shuts the daemon down too.
170
+ agentproto serve --interactive # alias: -i
171
+ ```
172
+
173
+ The dashboard looks roughly like:
174
+
175
+ ```
176
+ ─ agentproto monitor · http://127.0.0.1:18790 ──── workspace ~/code/proj · uptime 12m ─
177
+ SESSIONS (3) │ DETAIL
178
+ ▸ PTY claude-tui running 12m │ id sess_a3f8c1b2
179
+ PTY shell-main running 4m │ name claude-tui
180
+ hermes-bg exited 1h │ kind terminal (pty)
181
+ │ status running
182
+ │ workspace agentik-studio
183
+ │ command claude
184
+ │ pid 12345
185
+ │ started 12m ago
186
+ │ last out 3s ago
187
+
188
+ │ Enter to attach
189
+ ─ events 20:42:01 boot · agentik-studio · 20:43:11 spawn sess_a3f8c1b2 ──────────────
190
+ ↑/↓ select · Enter attach · K kill · d forget · r refresh · q quit
191
+ ```
192
+
193
+ What `serve` exposes:
194
+
195
+ | Surface | URL | Notes |
196
+ |-------------------|-------------------------------------------|--------------------------------------------------------|
197
+ | Health | `GET /health` | Workspace + uptime — always public |
198
+ | Events (SSE) | `GET /events` | RuntimeEvents stream |
199
+ | MCP | `POST /mcp` (Streamable HTTP) | Adapter spawn, terminal sessions, fs/exec, … |
200
+ | Adapter discovery | `GET /adapters` | Globally-installed `@agentproto/adapter-*` packages |
201
+ | Sessions (list) | `GET /sessions` / `GET /sessions/:id` | id-or-name in `:id` |
202
+ | Agent spawn | `POST /sessions/agent` | Long-lived ACP agent (multi-turn) |
203
+ | **PTY spawn** | **`POST /sessions/terminal`** | Real PTY under node-pty (alt-screen, ANSI, raw input) |
204
+ | **PTY attach** | **`WS /sessions/:id/pty`** | JSON-framed duplex; multi-subscriber |
205
+ | SSE attach | `GET /sessions/:id/stream` | Line-by-line text events |
206
+ | Kill | `POST /sessions/:id/kill` | SIGTERM the underlying child |
207
+
208
+ ### Discovery + token
209
+
210
+ At boot the daemon writes `<workspace>/.agentproto/runtime.json` (mode `0600`) with:
211
+
212
+ ```json
213
+ {
214
+ "workspace": "/abs/path",
215
+ "port": 18790,
216
+ "bind": "127.0.0.1",
217
+ "pid": 12345,
218
+ "startedAt": "2026-05-13T…",
219
+ "name": "agentproto-serve",
220
+ "registered": [],
221
+ "token": "<random-uuid>"
222
+ }
223
+ ```
224
+
225
+ - The CLI reads this file to find the daemon URL and the bearer token.
226
+ - The token is required on **mutating** `/sessions/*` routes and the `/sessions/:id/pty` WebSocket upgrade. There is **no loopback bypass** — the threat we're defending against (a browser fetch from a localhost-loaded page) is itself on loopback. A browser can't read `runtime.json` (mode 0600); a same-user CLI can.
227
+ - Override via env: `AGENTPROTO_DAEMON_URL=http://… AGENTPROTO_DAEMON_TOKEN=…`.
228
+ - Read routes (`GET /sessions`, SSE `/stream`) stay open so existing read-only tooling keeps working.
229
+
230
+ ## `sessions` — browse + control the daemon
231
+
232
+ ```bash
233
+ # One-shot table of live + recent sessions
234
+ agentproto sessions
235
+
236
+ # Interactive dashboard — 3 panes + live events ticker
237
+ agentproto sessions --watch
238
+ # ↑/↓ or j/k move selection in the sidebar
239
+ # Enter attach to selected (PTY-aware)
240
+ # K SIGTERM selected session
241
+ # d forget selected (must be exited)
242
+ # r refresh now
243
+ # q or Ctrl-C quit
244
+ #
245
+ # Flat-table version for piping into a pager or grep:
246
+ agentproto sessions --watch --simple
247
+
248
+ # Attach to a specific session (id or name) — full duplex
249
+ agentproto sessions --attach claude-tui
250
+
251
+ # Mirror — read-only tail, never takes stdin, Ctrl-C exits cleanly
252
+ # (great when your terminal emulator eats the Ctrl-] q detach chord)
253
+ agentproto sessions mirror claude-tui
254
+
255
+ # Spawn an agent CLI (ACP, structured events)
256
+ agentproto sessions start claude-code --workspace agentik-studio --attach
257
+ agentproto sessions start hermes --label "ops on-call"
258
+
259
+ # Spawn a real PTY (raw bytes, ANSI escapes, alt-screen apps)
260
+ agentproto sessions terminal --name claude-tui --attach -- claude
261
+ agentproto sessions terminal --name shell --cwd /tmp -- bash -l
262
+ agentproto sessions terminal --name htop --workspace my-project -- htop
263
+
264
+ # Stop by id or name
265
+ agentproto sessions stop claude-tui
266
+ ```
267
+
268
+ **Flag conventions for `sessions terminal`:** verb flags come **before** `--`; everything after `--` is argv passed verbatim to the spawned binary. So `--name my-shell -- bash --login` sets the session name and runs `bash --login`. The leading `--` is optional when no argv flag collides with verb flags.
269
+
270
+ ### Attach modes
271
+
272
+ `agentproto sessions --attach <id-or-name>` fetches the descriptor first and switches transport based on `desc.pty`:
273
+
274
+ | Verb / kind | Transport | Stdin → child | Resize | Detach |
275
+ |-----------------------------|----------------------|---------------|--------|------------------|
276
+ | `--attach` to PTY | WebSocket `/pty` | raw bytes ✓ | ✓ | `Ctrl-] q` chord |
277
+ | `mirror` to PTY | WebSocket `/pty` | **no** (read-only) | no | `Ctrl-C` |
278
+ | `--attach` to agent-cli | SSE `/stream` | n/a (use `prompt_agent_session` MCP tool) | n/a | `Ctrl-C` |
279
+ | `--attach` to command/piped | SSE `/stream` | n/a | n/a | `Ctrl-C` |
280
+
281
+ **When to pick which:**
282
+ - **`--attach`** — you want to TYPE into the session (drive claude, run bash commands, etc.). Duplex, takes over stdin, you detach with the `Ctrl-] q` chord.
283
+ - **`mirror`** — you want to WATCH without interfering, OR your terminal swallows `Ctrl-] q`. Read-only, `Ctrl-C` exits cleanly. The session keeps running on the daemon.
284
+
285
+ **Detach chord (PTY only):** `Ctrl-]` then `q` closes the WebSocket and exits the CLI; the session keeps running on the daemon. Re-attach later with `agentproto sessions --attach <id-or-name>`. Multiple clients (CLI + xterm.js web panel + another CLI) can attach to the same session simultaneously — the daemon fans bytes out and merges input.
286
+
287
+ ## MCP tools
288
+
289
+ When `agentproto serve` is up, the gateway's `/mcp` endpoint exposes these tools (call from a Mastra agent, Claude Code as sub-agent, Cursor MCP client, …):
290
+
291
+ | Tool | Purpose |
292
+ |-------------------------------|-----------------------------------------------------------|
293
+ | **`list_sessions`** | List sessions with `kind` / `status` / `onlyAlive` filters (canonical lister) |
294
+ | `list_agent_sessions` | Deprecated alias for `list_sessions` (no filters) |
295
+ | `start_agent_session` | Spawn a long-lived ACP adapter (claude-code/hermes/…) |
296
+ | `prompt_agent_session` | Send a follow-up turn to a live agent session |
297
+ | `get_agent_session_output` | Tail the recent ring buffer (lines) |
298
+ | `kill_agent_session` | SIGTERM an agent session |
299
+ | **`start_terminal_session`** | Spawn a PTY-backed process (any argv) |
300
+ | **`write_terminal_input`** | Send keystrokes to a PTY's stdin |
301
+ | **`read_terminal_output`** | Snapshot the recent byte buffer (base64) |
302
+ | **`kill_terminal_session`** | SIGTERM a PTY session |
303
+ | `list_adapters` | Enumerate installed `@agentproto/adapter-*` packages |
304
+ | `list_discovered_mcps` | MCP servers configured in claude / cursor / goose |
305
+ | `list_imported_mcps` | The user's curated MCP set |
306
+ | `import_mcp` / `remove_imported_mcp` | Curate the set |
307
+ | `mcp_imported_status` | Connection status of every imported MCP |
308
+ | `mcp_imported_list_tools` / `mcp_imported_call` | Proxy the imported MCP's tools |
309
+
310
+ The terminal tools let one agent **orchestrate** other sessions: an agent in a structured ACP session can call `start_terminal_session({argv: ["bash"]})`, then drive it turn-by-turn with `write_terminal_input` + `read_terminal_output`. Same surface backs the future `wire`/`tee` primitive for cross-session piping.
50
311
 
51
312
  ## Adapter resolution
52
313
 
53
314
  `<slug>` resolves to the npm package `@agentproto/adapter-<slug>`. Install adapters globally so `agentproto` can find them on its `NODE_PATH`. Built-in adapters as of v0.1:
54
315
 
55
- - `@agentproto/adapter-claude-code` — Anthropic Claude Code via [@agentclientprotocol/claude-agent-acp](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp)
56
- - `@agentproto/adapter-hermes` — generic Hermes-flavoured agents
57
- - `@agentproto/adapter-mastra` — Mastra agents
316
+ - `@agentproto/adapter-claude-code` — Anthropic Claude Code via [@agentclientprotocol/claude-agent-acp](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp) (protocol: ACP, structured events)
317
+ - `@agentproto/adapter-hermes` — Hermes (protocol: ACP)
318
+ - `@agentproto/adapter-openclaw` / `opencode` / `codex` / `mastra` — others discoverable via `GET /adapters` on a live daemon
319
+
320
+ Use `agentproto sessions terminal -- claude` (or `-- hermes`, `-- aider`, …) when you want the **raw interactive TUI** instead of the structured ACP event stream.
58
321
 
59
322
  ## License
60
323