@hydra-acp/cli 0.1.5 → 0.1.6
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 +13 -10
- package/dist/cli.js +50 -18
- package/dist/index.d.ts +1 -0
- package/dist/index.js +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -178,7 +178,7 @@ hydra-acp daemon start
|
|
|
178
178
|
# spawned-by-editor cases where stdio is already piped. The first
|
|
179
179
|
# session/new asks the daemon which agent to spawn (defaults to
|
|
180
180
|
# config.defaultAgent). If you'd rather the editor pin a specific agent,
|
|
181
|
-
# spawn `hydra-acp launch <agent
|
|
181
|
+
# spawn `hydra-acp launch <agent>` (see "Launcher mode" below).
|
|
182
182
|
|
|
183
183
|
# 4. From a terminal, drive a session interactively (TUI).
|
|
184
184
|
hydra-acp # bare invocation in a TTY launches the TUI
|
|
@@ -198,8 +198,8 @@ hydra-acp --session-id hydra_session_abc123
|
|
|
198
198
|
hydra-acp # auto-dispatch: TUI in a TTY, shim when stdio is piped
|
|
199
199
|
hydra-acp shim # explicit shim mode (forces shim regardless of TTY)
|
|
200
200
|
hydra-acp tui # explicit terminal-UI mode
|
|
201
|
-
hydra-acp launch <agent
|
|
202
|
-
# daemon to spawn <agent
|
|
201
|
+
hydra-acp launch <agent> # launcher mode: shim that forces the
|
|
202
|
+
# daemon to spawn <agent> on session/new
|
|
203
203
|
hydra-acp --session-id <id> # attach to existing session
|
|
204
204
|
# (TUI in a TTY, shim otherwise)
|
|
205
205
|
|
|
@@ -234,7 +234,7 @@ A bare invocation (`hydra-acp` with no subcommand) auto-dispatches based on whet
|
|
|
234
234
|
|
|
235
235
|
### Launcher mode
|
|
236
236
|
|
|
237
|
-
`hydra-acp launch <agent
|
|
237
|
+
`hydra-acp launch <agent>` is a convenience for "shim me, and use *this* registry agent." It's the easiest way to wrap an existing ACP-speaking editor configuration whose agent-spawn surface is just a command and arguments:
|
|
238
238
|
|
|
239
239
|
```text
|
|
240
240
|
# Configure your editor's ACP-launch command to:
|
|
@@ -243,9 +243,9 @@ hydra-acp launch claude-code
|
|
|
243
243
|
|
|
244
244
|
When the editor sends `session/new`, the shim rewrites the params to `{ ..., agentId: "claude-code" }` before forwarding to the daemon. 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 sessions` lists the live session and any other client can `session/attach` to it.
|
|
245
245
|
|
|
246
|
-
`<agent
|
|
246
|
+
`<agent>` is the registry ID — e.g. `claude-code`, `gemini-cli`, `codex`. Run `hydra-acp agents` to browse what's available, or fetch the registry CDN URL directly.
|
|
247
247
|
|
|
248
|
-
If both `launch <agent
|
|
248
|
+
If both `launch <agent>` and `--session-id` are given, `--session-id` wins (attach mode); the agent is ignored because the agent process is already running.
|
|
249
249
|
|
|
250
250
|
### Naming sessions from the editor
|
|
251
251
|
|
|
@@ -286,9 +286,9 @@ Each session carries a stable **`lineageId`** that survives every export/import
|
|
|
286
286
|
|
|
287
287
|
The first attach to an imported session is slow: hydra spawns a fresh agent, runs `session/new`, and feeds the imported history back in as a synthesized takeover transcript (same machinery as `/hydra agent`). Subsequent attaches use the normal `session/load` path. This is a text-level handover — the originating agent's internal state (tool-call chains, compacted earlier turns) isn't preserved, so the resumed conversation may be cognitively shallower than the original.
|
|
288
288
|
|
|
289
|
-
### Forwarding agent args (`hydra-acp launch <agent
|
|
289
|
+
### Forwarding agent args (`hydra-acp launch <agent> ...`)
|
|
290
290
|
|
|
291
|
-
Anything you put after `<agent
|
|
291
|
+
Anything you put after `<agent>` in launcher mode is forwarded to the underlying agent's command. Hydra appends the extra args to the registry-provided spawn plan. Example:
|
|
292
292
|
|
|
293
293
|
```text
|
|
294
294
|
hydra-acp launch codex-acp -c sandbox_mode=danger-full-access
|
|
@@ -303,14 +303,17 @@ Every config-knob flag has an `HYDRA_ACP_FOO_BAR` env-var equivalent. Flag wins
|
|
|
303
303
|
| Flag | Env var |
|
|
304
304
|
|---|---|
|
|
305
305
|
| `--name` | `HYDRA_ACP_NAME` |
|
|
306
|
-
| `--agent
|
|
306
|
+
| `--agent` | `HYDRA_ACP_AGENT` |
|
|
307
|
+
| `--model` | `HYDRA_ACP_MODEL` |
|
|
307
308
|
| `--session-id` | `HYDRA_ACP_SESSION_ID` |
|
|
308
309
|
|
|
310
|
+
`--model` is a one-shot override for the per-agent `defaultModels` entry in `~/.hydra-acp/config.json`. It only applies at fresh session creation — resurrect and `/hydra agent` switch ignore it (resurrected sessions stay on whatever model they were last using).
|
|
311
|
+
|
|
309
312
|
Action commands (`init`, `daemon`, `sessions`, `--help`, `--version`, `--rotate-token`) are not config knobs and are flag-only.
|
|
310
313
|
|
|
311
314
|
### Registry id resolution
|
|
312
315
|
|
|
313
|
-
When you ask hydra to spawn an agent (via `launch <
|
|
316
|
+
When you ask hydra to spawn an agent (via `launch <agent>`, `--agent`, or `HYDRA_ACP_AGENT`), the daemon first tries an exact match against the ACP Registry's `id` field. If nothing matches, it falls back to matching against the **npx package basename** (the segment after the last `/` and before the version `@`). That means common binary names work transparently:
|
|
314
317
|
|
|
315
318
|
| You spawn… | Registry `id` | Resolves via |
|
|
316
319
|
|---|---|---|
|
package/dist/cli.js
CHANGED
|
@@ -248,6 +248,9 @@ function extractHydraMeta(meta) {
|
|
|
248
248
|
out.resume = parsed.data;
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
|
+
if (typeof obj.model === "string") {
|
|
252
|
+
out.model = obj.model;
|
|
253
|
+
}
|
|
251
254
|
if (typeof obj.currentModel === "string") {
|
|
252
255
|
out.currentModel = obj.currentModel;
|
|
253
256
|
}
|
|
@@ -5420,8 +5423,17 @@ function formatPlan(event) {
|
|
|
5420
5423
|
}
|
|
5421
5424
|
];
|
|
5422
5425
|
}
|
|
5426
|
+
const allComplete = event.entries.every(
|
|
5427
|
+
(e) => (e.status ?? "pending") === "completed"
|
|
5428
|
+
);
|
|
5429
|
+
const headerStyle = allComplete ? "plan-done" : "plan";
|
|
5423
5430
|
const lines = [
|
|
5424
|
-
{
|
|
5431
|
+
{
|
|
5432
|
+
prefix: "\u25A3 ",
|
|
5433
|
+
prefixStyle: headerStyle,
|
|
5434
|
+
body: "Plan",
|
|
5435
|
+
bodyStyle: headerStyle
|
|
5436
|
+
}
|
|
5425
5437
|
];
|
|
5426
5438
|
for (const entry of event.entries) {
|
|
5427
5439
|
const status = entry.status ?? "pending";
|
|
@@ -5718,10 +5730,17 @@ async function runSession(term, config, opts, exitHint) {
|
|
|
5718
5730
|
let initialCommands;
|
|
5719
5731
|
let initialTurnStartedAt;
|
|
5720
5732
|
if (ctx.sessionId === "__new__") {
|
|
5733
|
+
const hydraNewMeta = {};
|
|
5734
|
+
if (opts.name) {
|
|
5735
|
+
hydraNewMeta.name = opts.name;
|
|
5736
|
+
}
|
|
5737
|
+
if (opts.model) {
|
|
5738
|
+
hydraNewMeta.model = opts.model;
|
|
5739
|
+
}
|
|
5721
5740
|
const created = await conn.request("session/new", {
|
|
5722
5741
|
cwd: ctx.cwd,
|
|
5723
5742
|
...opts.agentId ? { agentId: opts.agentId } : {},
|
|
5724
|
-
...
|
|
5743
|
+
...Object.keys(hydraNewMeta).length > 0 ? { _meta: { [HYDRA_META_KEY]: hydraNewMeta } } : {}
|
|
5725
5744
|
});
|
|
5726
5745
|
resolvedSessionId = created.sessionId;
|
|
5727
5746
|
exitHint.sessionId = resolvedSessionId;
|
|
@@ -7816,7 +7835,8 @@ var SessionManager = class {
|
|
|
7816
7835
|
agentId: params.agentId,
|
|
7817
7836
|
cwd: params.cwd,
|
|
7818
7837
|
agentArgs: params.agentArgs,
|
|
7819
|
-
mcpServers: params.mcpServers
|
|
7838
|
+
mcpServers: params.mcpServers,
|
|
7839
|
+
model: params.model
|
|
7820
7840
|
});
|
|
7821
7841
|
const session = new Session({
|
|
7822
7842
|
cwd: params.cwd,
|
|
@@ -8008,7 +8028,7 @@ var SessionManager = class {
|
|
|
8008
8028
|
);
|
|
8009
8029
|
}
|
|
8010
8030
|
let initialModel = extractInitialModel(newResult);
|
|
8011
|
-
const desired = this.defaultModels[params.agentId];
|
|
8031
|
+
const desired = params.model ?? this.defaultModels[params.agentId];
|
|
8012
8032
|
if (desired && desired !== initialModel) {
|
|
8013
8033
|
try {
|
|
8014
8034
|
await agent.connection.request("session/set_model", {
|
|
@@ -9459,7 +9479,8 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
9459
9479
|
agentId: params.agentId ?? deps.defaultAgent,
|
|
9460
9480
|
mcpServers: params.mcpServers,
|
|
9461
9481
|
title: hydraMeta.name,
|
|
9462
|
-
agentArgs: hydraMeta.agentArgs
|
|
9482
|
+
agentArgs: hydraMeta.agentArgs,
|
|
9483
|
+
model: hydraMeta.model
|
|
9463
9484
|
});
|
|
9464
9485
|
const client = bindClientToSession(connection, session, state);
|
|
9465
9486
|
await session.attach(client, "full");
|
|
@@ -10834,6 +10855,9 @@ function wireShim({
|
|
|
10834
10855
|
outgoing = injectHydraMeta(outgoing, { name: namingState.name });
|
|
10835
10856
|
namingState.used = true;
|
|
10836
10857
|
}
|
|
10858
|
+
if (opts.model) {
|
|
10859
|
+
outgoing = injectHydraMeta(outgoing, { model: opts.model });
|
|
10860
|
+
}
|
|
10837
10861
|
void upstream.send(outgoing);
|
|
10838
10862
|
return;
|
|
10839
10863
|
}
|
|
@@ -10976,10 +11000,10 @@ async function main() {
|
|
|
10976
11000
|
const positionalAgentId = afterLaunch[0];
|
|
10977
11001
|
const agentArgs = afterLaunch.slice(1);
|
|
10978
11002
|
const { flags: flags2 } = parseArgs(beforeLaunch);
|
|
10979
|
-
const agentId = positionalAgentId ?? resolveOption(flags2, "agent
|
|
11003
|
+
const agentId = positionalAgentId ?? resolveOption(flags2, "agent");
|
|
10980
11004
|
if (!agentId) {
|
|
10981
11005
|
process.stderr.write(
|
|
10982
|
-
"Usage: hydra-acp launch <agent
|
|
11006
|
+
"Usage: hydra-acp launch <agent> [agent-args...]\n"
|
|
10983
11007
|
);
|
|
10984
11008
|
process.exit(2);
|
|
10985
11009
|
return;
|
|
@@ -10987,7 +11011,8 @@ async function main() {
|
|
|
10987
11011
|
const launchResume = flags2.resume;
|
|
10988
11012
|
const sessionId2 = typeof launchResume === "string" ? launchResume : resolveOption(flags2, "session-id");
|
|
10989
11013
|
const name2 = resolveOption(flags2, "name");
|
|
10990
|
-
|
|
11014
|
+
const model2 = resolveOption(flags2, "model");
|
|
11015
|
+
await runShim({ sessionId: sessionId2, agentId, agentArgs, name: name2, model: model2 });
|
|
10991
11016
|
return;
|
|
10992
11017
|
}
|
|
10993
11018
|
const { positional, flags } = parseArgs(argv);
|
|
@@ -11004,22 +11029,24 @@ async function main() {
|
|
|
11004
11029
|
const resumeFlag = flags.resume;
|
|
11005
11030
|
const sessionId = typeof resumeFlag === "string" ? resumeFlag : resolveOption(flags, "session-id");
|
|
11006
11031
|
const name = resolveOption(flags, "name");
|
|
11007
|
-
const agentIdFromFlag = resolveOption(flags, "agent
|
|
11032
|
+
const agentIdFromFlag = resolveOption(flags, "agent");
|
|
11033
|
+
const model = resolveOption(flags, "model");
|
|
11008
11034
|
if (!subcommand) {
|
|
11009
11035
|
if (process.stdout.isTTY) {
|
|
11010
11036
|
await dispatchTui(flags, {
|
|
11011
11037
|
sessionId,
|
|
11012
11038
|
agentId: agentIdFromFlag,
|
|
11013
|
-
name
|
|
11039
|
+
name,
|
|
11040
|
+
model
|
|
11014
11041
|
});
|
|
11015
11042
|
return;
|
|
11016
11043
|
}
|
|
11017
|
-
await runShim({ sessionId, name, agentId: agentIdFromFlag });
|
|
11044
|
+
await runShim({ sessionId, name, agentId: agentIdFromFlag, model });
|
|
11018
11045
|
return;
|
|
11019
11046
|
}
|
|
11020
11047
|
switch (subcommand) {
|
|
11021
11048
|
case "shim":
|
|
11022
|
-
await runShim({ sessionId, name, agentId: agentIdFromFlag });
|
|
11049
|
+
await runShim({ sessionId, name, agentId: agentIdFromFlag, model });
|
|
11023
11050
|
return;
|
|
11024
11051
|
case "init":
|
|
11025
11052
|
await runInit(flags);
|
|
@@ -11141,7 +11168,8 @@ async function main() {
|
|
|
11141
11168
|
await dispatchTui(flags, {
|
|
11142
11169
|
sessionId,
|
|
11143
11170
|
agentId: agentIdFromFlag,
|
|
11144
|
-
name
|
|
11171
|
+
name,
|
|
11172
|
+
model
|
|
11145
11173
|
});
|
|
11146
11174
|
return;
|
|
11147
11175
|
default:
|
|
@@ -11169,6 +11197,9 @@ async function dispatchTui(flags, base) {
|
|
|
11169
11197
|
if (base.name !== void 0) {
|
|
11170
11198
|
tuiOpts.name = base.name;
|
|
11171
11199
|
}
|
|
11200
|
+
if (base.model !== void 0) {
|
|
11201
|
+
tuiOpts.model = base.model;
|
|
11202
|
+
}
|
|
11172
11203
|
await runTui(tuiOpts);
|
|
11173
11204
|
}
|
|
11174
11205
|
function readVersion() {
|
|
@@ -11191,9 +11222,9 @@ function printHelp() {
|
|
|
11191
11222
|
" hydra-acp Auto: TUI when stdout is a TTY, shim otherwise (the editor-spawned case)",
|
|
11192
11223
|
" hydra-acp shim Run as ACP shim explicitly (forces shim mode regardless of TTY)",
|
|
11193
11224
|
" hydra-acp tui [opts] Run the terminal UI explicitly (see below for opts)",
|
|
11194
|
-
" hydra-acp launch <agent
|
|
11195
|
-
" Shim mode, force daemon to spawn <agent
|
|
11196
|
-
" from the registry. Args after <agent
|
|
11225
|
+
" hydra-acp launch <agent> [agent-args...]",
|
|
11226
|
+
" Shim mode, force daemon to spawn <agent>",
|
|
11227
|
+
" from the registry. Args after <agent>",
|
|
11197
11228
|
" are forwarded to the agent's command.",
|
|
11198
11229
|
" hydra-acp --resume <id> Attach to an existing session (TUI when in a terminal, shim otherwise)",
|
|
11199
11230
|
" hydra-acp init [--rotate-token] Initialize ~/.hydra-acp/config.json",
|
|
@@ -11214,14 +11245,15 @@ function printHelp() {
|
|
|
11214
11245
|
" hydra-acp extensions logs <name> [-f] [-n N]Tail or follow an extension's log",
|
|
11215
11246
|
" hydra-acp agents [list] List agents in the cached registry",
|
|
11216
11247
|
" hydra-acp agents refresh Force a registry re-fetch",
|
|
11217
|
-
" hydra-acp tui flags: [--resume [<id>]] [--new] [--agent
|
|
11248
|
+
" hydra-acp tui flags: [--resume [<id>]] [--new] [--agent <id>] [--model <id>] [--cwd <path>] [--name <label>]",
|
|
11218
11249
|
" --resume <id> attaches to a specific session; bare --resume picks the most-recent",
|
|
11219
11250
|
" in cwd. Smart default (no flags): picks if any live sessions exist, else new.",
|
|
11220
11251
|
" hydra-acp --version Print version",
|
|
11221
11252
|
" hydra-acp --help Show this help",
|
|
11222
11253
|
"",
|
|
11223
11254
|
"Config knob flags accept env-var equivalents (flag wins):",
|
|
11224
|
-
" --agent
|
|
11255
|
+
" --agent HYDRA_ACP_AGENT",
|
|
11256
|
+
" --model HYDRA_ACP_MODEL (one-shot at session/new; ignored on --resume)",
|
|
11225
11257
|
" --resume / --session-id HYDRA_ACP_SESSION_ID",
|
|
11226
11258
|
" --name HYDRA_ACP_NAME",
|
|
11227
11259
|
""
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -696,6 +696,9 @@ function extractHydraMeta(meta) {
|
|
|
696
696
|
out.resume = parsed.data;
|
|
697
697
|
}
|
|
698
698
|
}
|
|
699
|
+
if (typeof obj.model === "string") {
|
|
700
|
+
out.model = obj.model;
|
|
701
|
+
}
|
|
699
702
|
if (typeof obj.currentModel === "string") {
|
|
700
703
|
out.currentModel = obj.currentModel;
|
|
701
704
|
}
|
|
@@ -2598,7 +2601,8 @@ var SessionManager = class {
|
|
|
2598
2601
|
agentId: params.agentId,
|
|
2599
2602
|
cwd: params.cwd,
|
|
2600
2603
|
agentArgs: params.agentArgs,
|
|
2601
|
-
mcpServers: params.mcpServers
|
|
2604
|
+
mcpServers: params.mcpServers,
|
|
2605
|
+
model: params.model
|
|
2602
2606
|
});
|
|
2603
2607
|
const session = new Session({
|
|
2604
2608
|
cwd: params.cwd,
|
|
@@ -2790,7 +2794,7 @@ var SessionManager = class {
|
|
|
2790
2794
|
);
|
|
2791
2795
|
}
|
|
2792
2796
|
let initialModel = extractInitialModel(newResult);
|
|
2793
|
-
const desired = this.defaultModels[params.agentId];
|
|
2797
|
+
const desired = params.model ?? this.defaultModels[params.agentId];
|
|
2794
2798
|
if (desired && desired !== initialModel) {
|
|
2795
2799
|
try {
|
|
2796
2800
|
await agent.connection.request("session/set_model", {
|
|
@@ -4305,7 +4309,8 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
4305
4309
|
agentId: params.agentId ?? deps.defaultAgent,
|
|
4306
4310
|
mcpServers: params.mcpServers,
|
|
4307
4311
|
title: hydraMeta.name,
|
|
4308
|
-
agentArgs: hydraMeta.agentArgs
|
|
4312
|
+
agentArgs: hydraMeta.agentArgs,
|
|
4313
|
+
model: hydraMeta.model
|
|
4309
4314
|
});
|
|
4310
4315
|
const client = bindClientToSession(connection, session, state);
|
|
4311
4316
|
await session.attach(client, "full");
|