@hydra-acp/cli 0.1.50 → 0.1.52
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 +46 -50
- package/dist/cli.js +7562 -6908
- package/dist/index.d.ts +51 -0
- package/dist/index.js +668 -172
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,62 +93,58 @@ Existing ACP clients are stdio-based: they `spawn(command)` a process and exchan
|
|
|
93
93
|
|
|
94
94
|
Clients that adopt the streamable-http-websocket-transport RFD natively can connect to the daemon's `/acp` endpoint directly without the shim.
|
|
95
95
|
|
|
96
|
-
###
|
|
96
|
+
### Cat mode
|
|
97
|
+
|
|
98
|
+
`hydra-acp cat` is a pipe-friendly headless verb: it feeds stdin to a fresh
|
|
99
|
+
session as the user prompt and streams the agent's text reply to stdout. No
|
|
100
|
+
TUI, no JSON-RPC for the caller, no terminal control sequences in the
|
|
101
|
+
output — just text in, text out, exit code 0 on a clean turn. Hydra ends up
|
|
102
|
+
usable as a unix filter, with the agent as the program in the middle of the
|
|
103
|
+
pipeline.
|
|
104
|
+
|
|
105
|
+
A few properties keep it well-behaved:
|
|
106
|
+
|
|
107
|
+
- **Sandboxed cwd by default.** Piped invocations get a fresh empty tempdir as
|
|
108
|
+
the agent's `cwd`, and the permission handler rejects every tool call that
|
|
109
|
+
isn't one of the `hydra-acp-stdin` MCP tools (head / tail / grep / read on
|
|
110
|
+
the piped bytes). The agent has nothing to look at except the data you
|
|
111
|
+
piped in. Override with `--cwd <path>` when you want it poking at the
|
|
112
|
+
project (e.g. "find docs in the codebase that mention this error").
|
|
113
|
+
- **Smart about size.** Small inputs are inlined into the prompt. Large inputs
|
|
114
|
+
(default >1 MiB) get the daemon's in-memory `hydra-acp-stdin` MCP server:
|
|
115
|
+
bytes flow into a ring buffer and the agent pulls them on demand via
|
|
116
|
+
`head`, `tail`, `grep`, `read`, and `info`. A multi-gigabyte log isn't a
|
|
117
|
+
context-window problem; it's a fixed-size buffer the agent samples.
|
|
118
|
+
- **`--follow` for live streams.** Pipe `tail -f` into `--follow` and each quiet
|
|
119
|
+
burst on stdin is sent as a new turn. The standing prompt (`-p`) is sent
|
|
120
|
+
only on the first turn; later turns carry just the new bytes.
|
|
121
|
+
- **`--detach` to share the session.** By default the session lives as long as
|
|
122
|
+
the cat process; on stdin EOF it dies. With `--detach` it stays in the
|
|
123
|
+
daemon, `hydra-acp session` lists it, and the slack / browser / notifier
|
|
124
|
+
extensions can ride on it. Useful for kicking off a long-running watch
|
|
125
|
+
from a shell script and following it on your phone.
|
|
126
|
+
|
|
127
|
+
A few examples:
|
|
97
128
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
2. **The shim caches that namespaced data in a `SessionTracker`** as messages flow through, keyed by the hydra sessionId the editor knows.
|
|
102
|
-
3. **The shim's WS connection is wrapped in a `ResilientWsStream`** that reconnects with exponential backoff (200ms → 5s, capped, max 60 attempts) and buffers outbound messages from the editor while disconnected.
|
|
103
|
-
4. **After each successful reconnect, the shim replays a `session/attach`** for every cached session, including the resume hints under `_meta["hydra-acp"].resume`.
|
|
104
|
-
5. **If the daemon already knows the session** (e.g., the daemon never died, just a network blip), it ignores the resume hint and does a normal attach.
|
|
105
|
-
6. **If the daemon doesn't know the session**, it resurrects: spawns a fresh agent of `agentId` in `cwd`, runs `initialize`, calls ACP `session/load { sessionId: upstreamSessionId }` against the agent, and registers a new hydra `Session` *with the same hydra sessionId the shim claimed*. The editor sees nothing.
|
|
106
|
-
|
|
107
|
-
The resurrection is serialized per hydra sessionId, so two shims racing to reattach to the same session don't both spawn fresh agents.
|
|
108
|
-
|
|
109
|
-
**What this requires:** the underlying agent must support `loadSession` and persist its own session state to disk between processes (e.g., claude-code-acp does, in `~/.claude/sessions/`). For agents that don't support load, resurrection fails on the daemon side and the shim surfaces an error to the editor.
|
|
110
|
-
|
|
111
|
-
**What gets lost across restart:** the daemon's in-memory streaming history and in-flight tool calls. The agent's persisted state — past completed turns, conversation context — is recovered via `session/load`. The agent will need to re-issue any tool call that was mid-stream when the daemon died.
|
|
112
|
-
|
|
113
|
-
**In-flight permission prompts:** the shim tracks open `session/request_permission` requests it has forwarded to the editor. On any reconnect (which always implies the previous daemon-side promise is gone), the shim emits a `session/update` notification with `sessionUpdate: "permission_resolved"` toward the editor for each pending request, carrying the original `toolCallId` plus `outcome: { kind: "cancelled", reason: "daemon-disconnected" }` and `resolvedBy: { clientId: "hydra-acp" }`. Editors that handle `permission_resolved` per [RFD #533](https://github.com/agentclientprotocol/agent-client-protocol/pull/533) will dismiss their in-flight permission UI. Any response the editor still sends afterward is silently dropped by the new daemon (unknown request id).
|
|
129
|
+
```sh
|
|
130
|
+
# One-shot question, no stdin.
|
|
131
|
+
hydra-acp -p "tools to convert a HEIC photo to JPEG on linux?"
|
|
114
132
|
|
|
115
|
-
|
|
133
|
+
# Analyze a big log without copy-pasting it into a chat window.
|
|
134
|
+
journalctl -u nginx --since "1 hour ago" | hydra-acp cat -p "anything alarming?"
|
|
116
135
|
|
|
117
|
-
|
|
136
|
+
# Treat hydra as the filter in a unix pipeline — output is plain text,
|
|
137
|
+
# so tee / grep / jq downstream just work.
|
|
138
|
+
git log --since="last monday" --pretty=full | hydra-acp cat -p "draft release notes, one bullet per user-visible change, grouped by version" | tee RELEASE_NOTES.md
|
|
118
139
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"agent-vendor": { "sequence": 7 },
|
|
124
|
-
"hydra-acp": {
|
|
125
|
-
"upstreamSessionId": "u_xyz",
|
|
126
|
-
"agentId": "claude-code",
|
|
127
|
-
"cwd": "/path/to/project"
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
140
|
+
# Watch a live log and only speak up when something's wrong. --detach
|
|
141
|
+
# keeps the session in the daemon, so you can follow it on your phone
|
|
142
|
+
# via the slack extension after closing the shell.
|
|
143
|
+
tail -F /var/log/app.log | hydra-acp cat --follow --detach -p "if a line looks like an error or stack trace, summarize it. otherwise stay silent."
|
|
131
144
|
```
|
|
132
145
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
For resurrection, the shim sends `session/attach` with a resume hint nested in the same namespace:
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"sessionId": "hydra_session_abc123",
|
|
140
|
-
"historyPolicy": "pending_only",
|
|
141
|
-
"_meta": {
|
|
142
|
-
"hydra-acp": {
|
|
143
|
-
"resume": {
|
|
144
|
-
"upstreamSessionId": "u_xyz",
|
|
145
|
-
"agentId": "claude-code",
|
|
146
|
-
"cwd": "/path/to/project"
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
```
|
|
146
|
+
Sessions created by `cat` are normal hydra sessions, so `hydra-acp session`,
|
|
147
|
+
`session export`, `/hydra title`, and the rest of the surface all work on them.
|
|
152
148
|
|
|
153
149
|
## Install
|
|
154
150
|
|