@hydra-acp/cli 0.1.60 → 0.1.62
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 +123 -107
- package/dist/cli.js +2324 -764
- package/dist/index.d.ts +231 -22
- package/dist/index.js +1372 -541
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,25 @@
|
|
|
27
27
|
|
|
28
28
|
## What it is
|
|
29
29
|
|
|
30
|
-
`hydra-acp` is a daemon
|
|
30
|
+
`hydra-acp` is a **session manager, multiplexer, and TUI** for AI coding agents. One daemon manages your agent processes and the sessions running inside them; many clients — a terminal TUI, your editor, a browser, Slack — attach to the same live session at once and see it update in real time. Start a session at your desk, follow it from your phone, hand it off to a teammate.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g @hydra-acp/cli
|
|
34
|
+
hydra-acp # launch the TUI and start a session
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
That's the whole getting-started path: install, run, talk to an agent. The TUI is the front door — it picks an agent, drives the conversation, lists your sessions, and lets you attach to one that's already running. From there you can wire up your editor, add a browser or Slack bridge, or pipe data through it on the command line.
|
|
38
|
+
|
|
39
|
+
### What it gives you
|
|
40
|
+
|
|
41
|
+
- **A session manager.** Every session is tracked, named, listable (`hydra-acp session`), exportable, and resurrectable. Close your terminal and the session keeps running in the daemon; reattach later from anywhere.
|
|
42
|
+
- **A multiplexer.** Many clients share one live session. Events broadcast to all attached clients; prompts serialize through a per-session queue; permission requests race (first response wins). Editor, TUI, browser, and Slack all watch the same agent at once.
|
|
43
|
+
- **A TUI.** A full terminal UI for driving sessions interactively — picking agents, prompting, approving tool calls, scrolling transcripts, and switching between live sessions.
|
|
44
|
+
- **Extensions.** Optional companion processes — Slack bridge, web UI, desktop notifier, auto-approver, cross-machine sync — that the daemon spawns and manages for you. See [Extensions](#extensions) below.
|
|
45
|
+
|
|
46
|
+
### How it's built
|
|
47
|
+
|
|
48
|
+
Under the hood, `hydra-acp` is a daemon + CLI shim that implements two open ACP RFDs as a single coherent surface, on top of the standard ACP protocol (including `session/list` for session discovery), plus the official ACP Registry as its agent-distribution mechanism. The rest of this section is the protocol detail; skip to [Quick start](#quick-start) if you just want to use it.
|
|
31
49
|
|
|
32
50
|
### The standards it stitches together
|
|
33
51
|
|
|
@@ -194,6 +212,105 @@ hydra-acp session
|
|
|
194
212
|
hydra-acp --session hydra_session_abc123
|
|
195
213
|
```
|
|
196
214
|
|
|
215
|
+
## Extensions
|
|
216
|
+
|
|
217
|
+
Hydra can spawn user-configured extension processes when the daemon starts. Extensions are arbitrary commands — written in any language — that talk to the daemon over its existing REST or WSS endpoints. Hydra handles their lifecycle (spawn on start, kill on stop, auto-restart on crash with exponential backoff up to ~60s) and injects daemon connection info via env vars.
|
|
218
|
+
|
|
219
|
+
Various ready-made extensions ship under the same `@hydra-acp` npm scope. All are optional and can be installed independently.
|
|
220
|
+
|
|
221
|
+
**[`@hydra-acp/slack`](https://github.com/smagnuso/hydra-acp-slack) — Slack thread bridge.** Each hydra session gets its own Slack thread; the agent's prose, tool cards, plans, and permission prompts stream in, and replies typed in the thread come back to the agent as user prompts. Useful for non-developer collaborators, or for driving an agent from your phone while you're away from the keyboard. Respects RFD #533's `prompt_received` and survives daemon restarts via session resurrection.
|
|
222
|
+
|
|
223
|
+
```sh
|
|
224
|
+
npm install -g @hydra-acp/slack
|
|
225
|
+
hydra-acp extension add hydra-acp-slack
|
|
226
|
+
hydra-acp extension restart hydra-acp-slack
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
You'll also need a Slack app and a config at `~/.hydra-acp-slack.conf` — see the [package's setup section](https://github.com/smagnuso/hydra-acp-slack#setup) for scopes, tokens, and authorized users.
|
|
230
|
+
|
|
231
|
+
**[`@hydra-acp/browser`](https://github.com/smagnuso/hydra-acp-browser) — local web UI.** Single-page app that lists live sessions, attaches to each one, and renders the transcript (agent messages, tool calls, plans, mode/model changes) with a composer for prompting and permission widgets for approving tool use. Cheap to bring up when you want to spot-check an agent without firing up the editor.
|
|
232
|
+
|
|
233
|
+
```sh
|
|
234
|
+
npm install -g @hydra-acp/browser
|
|
235
|
+
hydra-acp extension add hydra-acp-browser
|
|
236
|
+
hydra-acp extension restart hydra-acp-browser
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The first launch generates `~/.hydra-acp-browser/authkey` and writes the open URL (with `?authkey=…`) to `~/.hydra-acp-browser/link`. Defaults to localhost-only; see the [package's HTTPS section](https://github.com/smagnuso/hydra-acp-browser#https) for binding to a LAN address with TLS.
|
|
240
|
+
|
|
241
|
+
**[`@hydra-acp/notifier`](https://github.com/smagnuso/hydra-acp-notifier) — desktop notifications.** Always-on companion that fires `notify-send` (Linux) or `osascript` (macOS) when sessions emit notable events — by default, `turn_complete`. The default title is `🐉 <agentId> · <short-session-id> · <session-title-or-cwd>` and the body renders the agent's stop reason as friendly text (`Finished`, `Max token limit reached`, etc.). Drop a JS rule at `~/.hydra-acp/notifier.config.js` to customize per-event, or set `HYDRA_ACP_NOTIFY_CMD` to route everything to ntfy/Pushover/your phone.
|
|
242
|
+
|
|
243
|
+
```sh
|
|
244
|
+
npm install -g @hydra-acp/notifier
|
|
245
|
+
hydra-acp extension add hydra-acp-notifier
|
|
246
|
+
hydra-acp extension start hydra-acp-notifier
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**[`@hydra-acp/approver`](https://github.com/smagnuso/hydra-acp-approver) — headless permission auto-responder.** Attaches to every live session and answers `session/request_permission` based on a JS rule at `~/.hydra-acp/approver.config.js`. When the rule returns an `optionId` it wins the race and dismisses the prompt before any human client sees it; when it abstains (returns `null`), the prompt stays open for your interactive clients. Useful for centralizing approval policy in one place so per-client approval can go away.
|
|
250
|
+
|
|
251
|
+
```sh
|
|
252
|
+
npm install -g @hydra-acp/approver
|
|
253
|
+
hydra-acp extension add hydra-acp-approver
|
|
254
|
+
hydra-acp extension start hydra-acp-approver
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Without a config file the approver abstains on everything — installing it has no behavioral effect until you write a rule.
|
|
258
|
+
|
|
259
|
+
**[`@hydra-acp/archiver`](https://github.com/smagnuso/hydra-acp-archiver) — cross-machine session sync.** Uploads session bundles to a shared backend (Google Drive, plain filesystem) after every turn and imports peers' bundles in the background, so a session started on machine A shows up on machine B without manual export/import. Imported sessions carry an `importedFromMachine` breadcrumb that the picker, browser, slack, and `sessions list` honor for host filtering.
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
npm install -g @hydra-acp/archiver
|
|
263
|
+
hydra-acp extension add hydra-acp-archiver
|
|
264
|
+
hydra-acp extension start hydra-acp-archiver
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
See the [package README](https://github.com/smagnuso/hydra-acp-archiver#readme) for backend setup (Drive OAuth, filesystem path).
|
|
268
|
+
|
|
269
|
+
### Configuring extensions
|
|
270
|
+
|
|
271
|
+
Configure in `~/.hydra-acp/config.json`:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"extensions": {
|
|
276
|
+
"hydra-acp-slack": {},
|
|
277
|
+
"hydra-acp-browser": {
|
|
278
|
+
"command": ["hydra-acp-browser"],
|
|
279
|
+
"args": ["--port", "9999"],
|
|
280
|
+
"env": { "UI_THEME": "dark" }
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
If `command` is omitted, it defaults to `[<name>]` — useful when the package's `bin` matches its key (e.g. `npm install -g @hydra-acp/slack` exposes `hydra-acp-slack` on PATH, so `"hydra-acp-slack": {}` is enough).
|
|
287
|
+
|
|
288
|
+
Each extension is launched with these env vars set:
|
|
289
|
+
|
|
290
|
+
| Env var | Example |
|
|
291
|
+
|---|---|
|
|
292
|
+
| `HYDRA_ACP_DAEMON_URL` | `http://127.0.0.1:55514` |
|
|
293
|
+
| `HYDRA_ACP_DAEMON_HOST` | `127.0.0.1` |
|
|
294
|
+
| `HYDRA_ACP_DAEMON_PORT` | `55514` |
|
|
295
|
+
| `HYDRA_ACP_TOKEN` | `hydra_token_<hex>` |
|
|
296
|
+
| `HYDRA_ACP_WS_URL` | `ws://127.0.0.1:55514/acp` |
|
|
297
|
+
| `HYDRA_ACP_HOME` | `~/.hydra-acp` |
|
|
298
|
+
| `HYDRA_ACP_EXTENSION_NAME` | the `name` from config |
|
|
299
|
+
|
|
300
|
+
Extension stdout/stderr are appended to `~/.hydra-acp/extensions/<name>.log`.
|
|
301
|
+
|
|
302
|
+
While the daemon is running you can manage extensions without bouncing it:
|
|
303
|
+
|
|
304
|
+
```text
|
|
305
|
+
hydra-acp extension list
|
|
306
|
+
hydra-acp extension restart hydra-acp-slack
|
|
307
|
+
hydra-acp extension log hydra-acp-slack --follow
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`stop` suppresses the auto-restart backoff; the extension stays down until the next `start`, `restart`, or daemon bounce. `add`/`remove` are config-only — restart the daemon to apply. Per-extension config (env vars, args, custom command paths) goes in the same `extensions` block. `hydra-acp extension log <name> -f` tails an extension's stdout/stderr if you need to debug.
|
|
311
|
+
|
|
312
|
+
**Trust model**: each extension receives its own per-process token scoped to that process's lifetime. The token grants the same read/write access to the daemon's REST and WSS surfaces as a logged-in client. Treat extensions as part of your trusted compute base — review extensions before installing and don't run untrusted code through this mechanism. See `cli/examples/client-observe.mjs` for an annotated reference implementation.
|
|
313
|
+
|
|
197
314
|
## CLI
|
|
198
315
|
|
|
199
316
|
```
|
|
@@ -288,7 +405,7 @@ A bare invocation (`hydra-acp` with no subcommand) auto-dispatches based on whet
|
|
|
288
405
|
hydra-acp launch claude-code
|
|
289
406
|
```
|
|
290
407
|
|
|
291
|
-
When the editor sends `session/new`, the shim
|
|
408
|
+
When the editor sends `session/new`, the shim injects the agent id under `_meta["hydra-acp"].agentId` (e.g. `"claude-code"`) before forwarding to the daemon — the spec `session/new` params stay clean. The daemon resolves `claude-code` against the cached ACP Registry, downloads/installs the agent on first use under `~/.hydra-acp/agents/`, and spawns the subprocess. The editor sees a normal ACP agent. From then on, `hydra-acp session` lists the live session and any other client can `session/attach` to it.
|
|
292
409
|
|
|
293
410
|
`<agent>` is the registry ID — e.g. `claude-code`, `gemini-cli`, `codex`. Run `hydra-acp agent` to browse what's available, or fetch the registry CDN URL directly.
|
|
294
411
|
|
|
@@ -296,7 +413,7 @@ If both `launch <agent>` and `--session-id` are given, `--session-id` wins (atta
|
|
|
296
413
|
|
|
297
414
|
### Naming sessions from the editor
|
|
298
415
|
|
|
299
|
-
Pass `--name <label>` or set `HYDRA_ACP_NAME` and the first `session/new` from that shim is labeled accordingly. The label flows through `_meta["hydra-acp"].
|
|
416
|
+
Pass `--name <label>` or set `HYDRA_ACP_NAME` and the first `session/new` from that shim is labeled accordingly. The label flows through `_meta["hydra-acp"].title` on the wire, lands in `Session.title`, and shows up in `session/list` and `hydra-acp session`. Subsequent `session/new` calls from the same shim are not labeled — first one wins. The label survives daemon restart (it's carried in the resume hints).
|
|
300
417
|
|
|
301
418
|
```text
|
|
302
419
|
HYDRA_ACP_NAME="$BUFFER_NAME" hydra-acp launch claude-acp
|
|
@@ -314,7 +431,7 @@ Sometimes you want to scroll through a session's transcript — usually one impo
|
|
|
314
431
|
hydra-acp tui --resume <id> --readonly
|
|
315
432
|
```
|
|
316
433
|
|
|
317
|
-
The daemon enforces the contract: a
|
|
434
|
+
The daemon enforces the contract: a read-only attach to a *cold* session takes a viewer path that streams history straight from disk — no `manager.resurrect`, no agent process. Any mutating method sent from a read-only connection is refused. History replay and live updates are unchanged, so the existing scrollback search (`^R` when scrolled back) works over the full transcript. (Wire details — including how the read-only flag is carried — live in PROTOCOL.md.)
|
|
318
435
|
|
|
319
436
|
The TUI suppresses the composer entirely — those rows go to scrollback so you see more of the conversation. The window title is suffixed `[VIEW ONLY]` so the mode is unambiguous. Prompt-shaped keys (Enter, Shift+Enter, Shift+Tab) are inert; `^P`, `^G`, `^L`, `^R`, `PgUp/PgDn`, `^C`, `^D` work as usual.
|
|
320
437
|
|
|
@@ -413,107 +530,6 @@ The service token lives in its own file (`~/.hydra-acp/auth-token`, mode 0600) a
|
|
|
413
530
|
|
|
414
531
|
`tui.defaultEnterAction` (default `"amend"`) controls what the unmodified Enter key does in the prompt composer. With `"amend"` (the default), Enter amends the in-flight turn and `Shift+Enter` enqueues a new prompt; with no turn in flight either key just enqueues, since there's nothing to amend. Set to `"enqueue"` to flip the two: Enter enqueues (sends immediately when idle, queues behind an in-flight turn) and `Shift+Enter` amends.
|
|
415
532
|
|
|
416
|
-
### Extensions
|
|
417
|
-
|
|
418
|
-
Hydra can spawn user-configured extension processes when the daemon starts. Extensions are arbitrary commands — written in any language — that talk to the daemon over its existing REST or WSS endpoints. Hydra handles their lifecycle (spawn on start, kill on stop, auto-restart on crash with exponential backoff up to ~60s) and injects daemon connection info via env vars.
|
|
419
|
-
|
|
420
|
-
Configure in `~/.hydra-acp/config.json`:
|
|
421
|
-
|
|
422
|
-
```json
|
|
423
|
-
{
|
|
424
|
-
"extensions": {
|
|
425
|
-
"hydra-acp-slack": {},
|
|
426
|
-
"hydra-acp-browser": {
|
|
427
|
-
"command": ["hydra-acp-browser"],
|
|
428
|
-
"args": ["--port", "9999"],
|
|
429
|
-
"env": { "UI_THEME": "dark" }
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
If `command` is omitted, it defaults to `[<name>]` — useful when the package's `bin` matches its key (e.g. `npm install -g @hydra-acp/slack` exposes `hydra-acp-slack` on PATH, so `"hydra-acp-slack": {}` is enough).
|
|
436
|
-
|
|
437
|
-
Each extension is launched with these env vars set:
|
|
438
|
-
|
|
439
|
-
| Env var | Example |
|
|
440
|
-
|---|---|
|
|
441
|
-
| `HYDRA_ACP_DAEMON_URL` | `http://127.0.0.1:55514` |
|
|
442
|
-
| `HYDRA_ACP_DAEMON_HOST` | `127.0.0.1` |
|
|
443
|
-
| `HYDRA_ACP_DAEMON_PORT` | `55514` |
|
|
444
|
-
| `HYDRA_ACP_TOKEN` | `hydra_token_<hex>` |
|
|
445
|
-
| `HYDRA_ACP_WS_URL` | `ws://127.0.0.1:55514/acp` |
|
|
446
|
-
| `HYDRA_ACP_HOME` | `~/.hydra-acp` |
|
|
447
|
-
| `HYDRA_ACP_EXTENSION_NAME` | the `name` from config |
|
|
448
|
-
|
|
449
|
-
Extension stdout/stderr are appended to `~/.hydra-acp/extensions/<name>.log`.
|
|
450
|
-
|
|
451
|
-
While the daemon is running you can manage extensions without bouncing it:
|
|
452
|
-
|
|
453
|
-
```text
|
|
454
|
-
hydra-acp extension list
|
|
455
|
-
hydra-acp extension restart hydra-acp-slack
|
|
456
|
-
hydra-acp extension log hydra-acp-slack --follow
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
`stop` suppresses the auto-restart backoff; the extension stays down until the next `start`, `restart`, or daemon bounce. `add`/`remove` are config-only — restart the daemon to apply.
|
|
460
|
-
|
|
461
|
-
**Trust model**: each extension receives its own per-process token scoped to that process's lifetime. The token grants the same read/write access to the daemon's REST and WSS surfaces as a logged-in client. Treat extensions as part of your trusted compute base — review extensions before installing and don't run untrusted code through this mechanism. See `cli/examples/client-observe.mjs` for an annotated reference implementation.
|
|
462
|
-
|
|
463
|
-
#### Optional extensions
|
|
464
|
-
|
|
465
|
-
Various ready-made extensions ship under the same `@hydra-acp` npm scope. All are optional and can be installed independently.
|
|
466
|
-
|
|
467
|
-
**[`@hydra-acp/slack`](https://github.com/smagnuso/hydra-acp-slack) — Slack thread bridge.** Each hydra session gets its own Slack thread; the agent's prose, tool cards, plans, and permission prompts stream in, and replies typed in the thread come back to the agent as user prompts. Useful for non-developer collaborators, or for driving an agent from your phone while you're away from the keyboard. Respects RFD #533's `prompt_received` and survives daemon restarts via session resurrection.
|
|
468
|
-
|
|
469
|
-
```sh
|
|
470
|
-
npm install -g @hydra-acp/slack
|
|
471
|
-
hydra-acp extension add hydra-acp-slack
|
|
472
|
-
hydra-acp extension restart hydra-acp-slack
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
You'll also need a Slack app and a config at `~/.hydra-acp-slack.conf` — see the [package's setup section](https://github.com/smagnuso/hydra-acp-slack#setup) for scopes, tokens, and authorized users.
|
|
476
|
-
|
|
477
|
-
**[`@hydra-acp/browser`](https://github.com/smagnuso/hydra-acp-browser) — local web UI.** Single-page app that lists live sessions, attaches to each one, and renders the transcript (agent messages, tool calls, plans, mode/model changes) with a composer for prompting and permission widgets for approving tool use. Cheap to bring up when you want to spot-check an agent without firing up the editor.
|
|
478
|
-
|
|
479
|
-
```sh
|
|
480
|
-
npm install -g @hydra-acp/browser
|
|
481
|
-
hydra-acp extension add hydra-acp-browser
|
|
482
|
-
hydra-acp extension restart hydra-acp-browser
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
The first launch generates `~/.hydra-acp-browser/authkey` and writes the open URL (with `?authkey=…`) to `~/.hydra-acp-browser/link`. Defaults to localhost-only; see the [package's HTTPS section](https://github.com/smagnuso/hydra-acp-browser#https) for binding to a LAN address with TLS.
|
|
486
|
-
|
|
487
|
-
**[`@hydra-acp/notifier`](https://github.com/smagnuso/hydra-acp-notifier) — desktop notifications.** Always-on companion that fires `notify-send` (Linux) or `osascript` (macOS) when sessions emit notable events — by default, `turn_complete`. The default title is `🐉 <agentId> · <short-session-id> · <session-title-or-cwd>` and the body renders the agent's stop reason as friendly text (`Finished`, `Max token limit reached`, etc.). Drop a JS rule at `~/.hydra-acp/notifier.config.js` to customize per-event, or set `HYDRA_ACP_NOTIFY_CMD` to route everything to ntfy/Pushover/your phone.
|
|
488
|
-
|
|
489
|
-
```sh
|
|
490
|
-
npm install -g @hydra-acp/notifier
|
|
491
|
-
hydra-acp extension add hydra-acp-notifier
|
|
492
|
-
hydra-acp extension start hydra-acp-notifier
|
|
493
|
-
```
|
|
494
|
-
|
|
495
|
-
**[`@hydra-acp/approver`](https://github.com/smagnuso/hydra-acp-approver) — headless permission auto-responder.** Attaches to every live session and answers `session/request_permission` based on a JS rule at `~/.hydra-acp/approver.config.js`. When the rule returns an `optionId` it wins the race and dismisses the prompt before any human client sees it; when it abstains (returns `null`), the prompt stays open for your interactive clients. Useful for centralizing approval policy in one place so per-client approval can go away.
|
|
496
|
-
|
|
497
|
-
```sh
|
|
498
|
-
npm install -g @hydra-acp/approver
|
|
499
|
-
hydra-acp extension add hydra-acp-approver
|
|
500
|
-
hydra-acp extension start hydra-acp-approver
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
Without a config file the approver abstains on everything — installing it has no behavioral effect until you write a rule.
|
|
504
|
-
|
|
505
|
-
**[`@hydra-acp/archiver`](https://github.com/smagnuso/hydra-acp-archiver) — cross-machine session sync.** Uploads session bundles to a shared backend (Google Drive, plain filesystem) after every turn and imports peers' bundles in the background, so a session started on machine A shows up on machine B without manual export/import. Imported sessions carry an `importedFromMachine` breadcrumb that the picker, browser, slack, and `sessions list` honor for host filtering.
|
|
506
|
-
|
|
507
|
-
```sh
|
|
508
|
-
npm install -g @hydra-acp/archiver
|
|
509
|
-
hydra-acp extension add hydra-acp-archiver
|
|
510
|
-
hydra-acp extension start hydra-acp-archiver
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
See the [package README](https://github.com/smagnuso/hydra-acp-archiver#readme) for backend setup (Drive OAuth, filesystem path).
|
|
514
|
-
|
|
515
|
-
Per-extension config (env vars, args, custom command paths) goes in the same `extensions` block in `~/.hydra-acp/config.json` — see the snippet above. `hydra-acp extension log <name> -f` tails an extension's stdout/stderr if you need to debug.
|
|
516
|
-
|
|
517
533
|
### Transformers
|
|
518
534
|
|
|
519
535
|
Transformers are a second kind of daemon-managed process. Where an extension is a *client* — it observes broadcast events and sends prompts — a transformer is *middleware*: it sits inside the daemon's message pipeline and sees every in-flight ACP message before the daemon acts on it, in both directions.
|
|
@@ -544,11 +560,11 @@ Each transformer receives:
|
|
|
544
560
|
- the same env vars as extensions (`HYDRA_ACP_TOKEN`, `HYDRA_ACP_WS_URL`, etc.)
|
|
545
561
|
- a `HYDRA_ACP_TRANSFORMER_NAME` env var with its config key
|
|
546
562
|
|
|
547
|
-
A transformer process connects using its own token (same mechanism as extensions) and then
|
|
563
|
+
A transformer process connects using its own token (same mechanism as extensions) and then registers the message kinds it wants to intercept. For each intercepted message the daemon hands it to the transformer and waits for a continue/stop/processing decision. (The exact JSON-RPC methods and payloads live in PROTOCOL.md.)
|
|
548
564
|
|
|
549
565
|
See `cli/examples/transformer-observe.mjs` for a working reference that logs all traffic and always continues, `cli/examples/transformer-edit.mjs` for one that modifies prompts before they reach the agent, and `cli/examples/transformer-lifecycle.mjs` for one that reacts to session lifecycle events (`session.opened`, `session.idle`, `session.closed`) and optionally emits a follow-up prompt when a session goes quiet.
|
|
550
566
|
|
|
551
|
-
**Trust model**: transformers receive the same per-process scoped token as extensions, but have structurally more access — they intercept traffic that no client ever sees.
|
|
567
|
+
**Trust model**: transformers receive the same per-process scoped token as extensions, but have structurally more access — they intercept traffic that no client ever sees. The transformer-specific methods are only callable with a transformer-kind token; an extension process that tries to call them receives `MethodNotFound`. Treat every entry in `transformers` as a higher-trust boundary than `extensions`.
|
|
552
568
|
|
|
553
569
|
The service token (stored at `~/.hydra-acp/auth-token`, mode 0600) is generated on `hydra-acp init` and required as `Authorization: Bearer <token>` for every REST call and as a WebSocket subprotocol or query parameter for `wss://.../acp`. The token never leaves `~/.hydra-acp/`.
|
|
554
570
|
|