@hydra-acp/cli 0.1.55 → 0.1.57
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/dist/cli.js +106 -29
- package/dist/index.js +54 -29
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2102,12 +2102,6 @@ var init_stream_buffer = __esm({
|
|
|
2102
2102
|
});
|
|
2103
2103
|
|
|
2104
2104
|
// src/core/hydra-commands.ts
|
|
2105
|
-
function hydraCommandsAsAdvertised() {
|
|
2106
|
-
return HYDRA_COMMANDS.map((c) => ({
|
|
2107
|
-
name: c.argsHint ? `${c.name} ${c.argsHint}` : c.name,
|
|
2108
|
-
description: c.description
|
|
2109
|
-
}));
|
|
2110
|
-
}
|
|
2111
2105
|
var HYDRA_COMMANDS, VERB_INDEX;
|
|
2112
2106
|
var init_hydra_commands = __esm({
|
|
2113
2107
|
"src/core/hydra-commands.ts"() {
|
|
@@ -4283,19 +4277,30 @@ var init_session = __esm({
|
|
|
4283
4277
|
// emits a non-spec shape (e.g. config_option_update). Fires modelHandlers
|
|
4284
4278
|
// (persistence) and broadcasts a synthetic current_model_update so all
|
|
4285
4279
|
// attached clients — including the originator — repaint immediately.
|
|
4280
|
+
//
|
|
4281
|
+
// The broadcast fires even when `modelId` already equals currentModel.
|
|
4282
|
+
// claude-acp emits a stale current_model_update (with the pre-change
|
|
4283
|
+
// value) during set_model processing and a separate config_option_update
|
|
4284
|
+
// with the new value; the configOption path updates currentModel here
|
|
4285
|
+
// before our synthetic broadcast would run, so a value-equality guard
|
|
4286
|
+
// would suppress the corrective broadcast and leave attached clients
|
|
4287
|
+
// (notably the TUI, which doesn't render config_option_update) showing
|
|
4288
|
+
// the stale model from the agent's earlier notification.
|
|
4286
4289
|
applyModelChange(modelId) {
|
|
4287
4290
|
const trimmed = modelId.trim();
|
|
4288
|
-
if (!trimmed
|
|
4291
|
+
if (!trimmed) {
|
|
4289
4292
|
return;
|
|
4290
4293
|
}
|
|
4291
|
-
this.
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4294
|
+
if (trimmed !== this.currentModel) {
|
|
4295
|
+
this.logger?.info(
|
|
4296
|
+
`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(trimmed)}`
|
|
4297
|
+
);
|
|
4298
|
+
this.currentModel = trimmed;
|
|
4299
|
+
for (const handler of this.modelHandlers) {
|
|
4300
|
+
try {
|
|
4301
|
+
handler(trimmed);
|
|
4302
|
+
} catch {
|
|
4303
|
+
}
|
|
4299
4304
|
}
|
|
4300
4305
|
}
|
|
4301
4306
|
const update = {
|
|
@@ -4312,23 +4317,39 @@ var init_session = __esm({
|
|
|
4312
4317
|
}
|
|
4313
4318
|
// Apply a mode change initiated by a client request (session/set_mode)
|
|
4314
4319
|
// when the agent doesn't emit a current_mode_update notification on its
|
|
4315
|
-
// own. Fires modeHandlers
|
|
4316
|
-
//
|
|
4320
|
+
// own. Fires modeHandlers (persistence) and broadcasts a synthetic
|
|
4321
|
+
// current_mode_update so all attached clients — including the originator
|
|
4322
|
+
// — repaint immediately, mirroring applyModelChange. Without the
|
|
4323
|
+
// broadcast, peer clients (e.g. the TUI when set_mode was issued by Zed
|
|
4324
|
+
// through the shim) would stay on the prior mode.
|
|
4317
4325
|
applyModeChange(modeId) {
|
|
4318
4326
|
const trimmed = modeId.trim();
|
|
4319
|
-
if (!trimmed
|
|
4327
|
+
if (!trimmed) {
|
|
4320
4328
|
return;
|
|
4321
4329
|
}
|
|
4322
|
-
this.
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
+
if (trimmed !== this.currentMode) {
|
|
4331
|
+
this.logger?.info(
|
|
4332
|
+
`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(trimmed)}`
|
|
4333
|
+
);
|
|
4334
|
+
this.currentMode = trimmed;
|
|
4335
|
+
for (const handler of this.modeHandlers) {
|
|
4336
|
+
try {
|
|
4337
|
+
handler(trimmed);
|
|
4338
|
+
} catch {
|
|
4339
|
+
}
|
|
4330
4340
|
}
|
|
4331
4341
|
}
|
|
4342
|
+
const update = {
|
|
4343
|
+
sessionUpdate: "current_mode_update",
|
|
4344
|
+
currentModeId: trimmed
|
|
4345
|
+
};
|
|
4346
|
+
if (this.agentAdvertisedModes.length > 0) {
|
|
4347
|
+
update.availableModes = [...this.agentAdvertisedModes];
|
|
4348
|
+
}
|
|
4349
|
+
this.recordAndBroadcast("session/update", {
|
|
4350
|
+
sessionId: this.upstreamSessionId,
|
|
4351
|
+
update
|
|
4352
|
+
});
|
|
4332
4353
|
}
|
|
4333
4354
|
onUsageChange(handler) {
|
|
4334
4355
|
this.usageHandlers.push(handler);
|
|
@@ -4340,8 +4361,8 @@ var init_session = __esm({
|
|
|
4340
4361
|
// entries, then whatever the agent advertised.
|
|
4341
4362
|
mergedAvailableCommands() {
|
|
4342
4363
|
const out = [
|
|
4343
|
-
|
|
4344
|
-
{ name: "model
|
|
4364
|
+
{ name: "hydra", description: "Hydra session command (kill, restart, title, agent <agent>)" },
|
|
4365
|
+
{ name: "model", description: "Switch model; omit arg to list available models" },
|
|
4345
4366
|
{ name: "sessions", description: "List all sessions" },
|
|
4346
4367
|
{ name: "help", description: "Show available commands" }
|
|
4347
4368
|
];
|
|
@@ -24638,8 +24659,11 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
24638
24659
|
connection.onRequest("session/list", async (raw) => {
|
|
24639
24660
|
const params = SessionListParams.parse(raw ?? {});
|
|
24640
24661
|
const entries = await deps.manager.list({ cwd: params.cwd });
|
|
24662
|
+
const visible = entries.filter(
|
|
24663
|
+
(e) => e.originatingClient?.name !== HYDRA_CAT_CLIENT_NAME
|
|
24664
|
+
);
|
|
24641
24665
|
const result = {
|
|
24642
|
-
sessions:
|
|
24666
|
+
sessions: visible.map(sessionListEntryToWire)
|
|
24643
24667
|
};
|
|
24644
24668
|
return result;
|
|
24645
24669
|
});
|
|
@@ -28377,6 +28401,7 @@ function maxLen3(headerCell, values) {
|
|
|
28377
28401
|
init_config();
|
|
28378
28402
|
init_service_token();
|
|
28379
28403
|
init_paths();
|
|
28404
|
+
import * as fsp12 from "fs/promises";
|
|
28380
28405
|
async function runAgentsList() {
|
|
28381
28406
|
const config = await loadConfig();
|
|
28382
28407
|
const serviceToken = await loadServiceToken();
|
|
@@ -28606,6 +28631,53 @@ async function runAgentsLogs(agentId, rest) {
|
|
|
28606
28631
|
const logPath = paths.agentLogFile(agentId);
|
|
28607
28632
|
await runLogTail(logPath, rest, "No log file (agent never ran?)");
|
|
28608
28633
|
}
|
|
28634
|
+
async function runAgentsSetDefault(agentId) {
|
|
28635
|
+
if (!agentId) {
|
|
28636
|
+
process.stderr.write("Usage: hydra-acp agent set <agent-id>\n");
|
|
28637
|
+
process.exit(2);
|
|
28638
|
+
return;
|
|
28639
|
+
}
|
|
28640
|
+
const config = await loadConfig();
|
|
28641
|
+
const serviceToken = await loadServiceToken();
|
|
28642
|
+
const baseUrl = httpBase(config.daemon.host, config.daemon.port, !!config.daemon.tls);
|
|
28643
|
+
let known;
|
|
28644
|
+
try {
|
|
28645
|
+
const r = await fetch(`${baseUrl}/v1/agents`, {
|
|
28646
|
+
headers: { Authorization: `Bearer ${serviceToken}` }
|
|
28647
|
+
});
|
|
28648
|
+
if (r.ok) {
|
|
28649
|
+
const body = await r.json();
|
|
28650
|
+
known = body.agents.map((a) => a.id);
|
|
28651
|
+
}
|
|
28652
|
+
} catch {
|
|
28653
|
+
}
|
|
28654
|
+
if (known !== void 0 && !known.includes(agentId)) {
|
|
28655
|
+
process.stderr.write(
|
|
28656
|
+
`hydra agent set: '${agentId}' is not in the registry. Known ids: ${known.join(", ")}
|
|
28657
|
+
`
|
|
28658
|
+
);
|
|
28659
|
+
process.exit(1);
|
|
28660
|
+
return;
|
|
28661
|
+
}
|
|
28662
|
+
const raw = await readRawConfig3();
|
|
28663
|
+
raw.defaultAgent = agentId;
|
|
28664
|
+
await writeRawConfig3(raw);
|
|
28665
|
+
process.stdout.write(
|
|
28666
|
+
`Set defaultAgent to '${agentId}' in ${paths.config()}
|
|
28667
|
+
`
|
|
28668
|
+
);
|
|
28669
|
+
}
|
|
28670
|
+
async function readRawConfig3() {
|
|
28671
|
+
const raw = await fsp12.readFile(paths.config(), "utf8");
|
|
28672
|
+
return JSON.parse(raw);
|
|
28673
|
+
}
|
|
28674
|
+
async function writeRawConfig3(raw) {
|
|
28675
|
+
await fsp12.writeFile(
|
|
28676
|
+
paths.config(),
|
|
28677
|
+
JSON.stringify(raw, null, 2) + "\n",
|
|
28678
|
+
{ encoding: "utf8", mode: 384 }
|
|
28679
|
+
);
|
|
28680
|
+
}
|
|
28609
28681
|
async function runAgentsRefresh() {
|
|
28610
28682
|
const config = await loadConfig();
|
|
28611
28683
|
const serviceToken = await loadServiceToken();
|
|
@@ -30259,6 +30331,10 @@ async function main() {
|
|
|
30259
30331
|
await runAgentsSync(positional[2]);
|
|
30260
30332
|
return;
|
|
30261
30333
|
}
|
|
30334
|
+
if (sub === "set") {
|
|
30335
|
+
await runAgentsSetDefault(positional[2]);
|
|
30336
|
+
return;
|
|
30337
|
+
}
|
|
30262
30338
|
if (sub === "log" || sub === "logs") {
|
|
30263
30339
|
const agIdx = argv.indexOf(subcommand);
|
|
30264
30340
|
const tail = argv.slice(agIdx + 2);
|
|
@@ -30495,6 +30571,7 @@ function printHelp() {
|
|
|
30495
30571
|
" hydra-acp agent [list] List agents in the cached registry",
|
|
30496
30572
|
" hydra-acp agent refresh Force a registry re-fetch",
|
|
30497
30573
|
" hydra-acp agent install <id> Pre-install <id> from the registry (else lazy on first session)",
|
|
30574
|
+
" hydra-acp agent set <id> Set <id> as the default agent (config.defaultAgent)",
|
|
30498
30575
|
" hydra-acp agent sync <id> Spawn <id> just long enough to ACP session/list it, then persist any sessions it remembers (across every cwd) as cold rows in `session list`",
|
|
30499
30576
|
" hydra-acp agent log <id> [-f] [-n N] Tail or follow an agent's spawn/stderr log",
|
|
30500
30577
|
" hydra-acp auth password [--force] Set the daemon's master password",
|
package/dist/index.js
CHANGED
|
@@ -2672,12 +2672,6 @@ var HYDRA_COMMANDS = [
|
|
|
2672
2672
|
}
|
|
2673
2673
|
];
|
|
2674
2674
|
var VERB_INDEX = new Map(HYDRA_COMMANDS.map((c) => [c.verb, c]));
|
|
2675
|
-
function hydraCommandsAsAdvertised() {
|
|
2676
|
-
return HYDRA_COMMANDS.map((c) => ({
|
|
2677
|
-
name: c.argsHint ? `${c.name} ${c.argsHint}` : c.name,
|
|
2678
|
-
description: c.description
|
|
2679
|
-
}));
|
|
2680
|
-
}
|
|
2681
2675
|
|
|
2682
2676
|
// src/core/coalesce-replay.ts
|
|
2683
2677
|
function coalesceReplay(entries) {
|
|
@@ -4543,19 +4537,30 @@ var Session = class {
|
|
|
4543
4537
|
// emits a non-spec shape (e.g. config_option_update). Fires modelHandlers
|
|
4544
4538
|
// (persistence) and broadcasts a synthetic current_model_update so all
|
|
4545
4539
|
// attached clients — including the originator — repaint immediately.
|
|
4540
|
+
//
|
|
4541
|
+
// The broadcast fires even when `modelId` already equals currentModel.
|
|
4542
|
+
// claude-acp emits a stale current_model_update (with the pre-change
|
|
4543
|
+
// value) during set_model processing and a separate config_option_update
|
|
4544
|
+
// with the new value; the configOption path updates currentModel here
|
|
4545
|
+
// before our synthetic broadcast would run, so a value-equality guard
|
|
4546
|
+
// would suppress the corrective broadcast and leave attached clients
|
|
4547
|
+
// (notably the TUI, which doesn't render config_option_update) showing
|
|
4548
|
+
// the stale model from the agent's earlier notification.
|
|
4546
4549
|
applyModelChange(modelId) {
|
|
4547
4550
|
const trimmed = modelId.trim();
|
|
4548
|
-
if (!trimmed
|
|
4551
|
+
if (!trimmed) {
|
|
4549
4552
|
return;
|
|
4550
4553
|
}
|
|
4551
|
-
this.
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4554
|
+
if (trimmed !== this.currentModel) {
|
|
4555
|
+
this.logger?.info(
|
|
4556
|
+
`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(trimmed)}`
|
|
4557
|
+
);
|
|
4558
|
+
this.currentModel = trimmed;
|
|
4559
|
+
for (const handler of this.modelHandlers) {
|
|
4560
|
+
try {
|
|
4561
|
+
handler(trimmed);
|
|
4562
|
+
} catch {
|
|
4563
|
+
}
|
|
4559
4564
|
}
|
|
4560
4565
|
}
|
|
4561
4566
|
const update = {
|
|
@@ -4572,23 +4577,39 @@ var Session = class {
|
|
|
4572
4577
|
}
|
|
4573
4578
|
// Apply a mode change initiated by a client request (session/set_mode)
|
|
4574
4579
|
// when the agent doesn't emit a current_mode_update notification on its
|
|
4575
|
-
// own. Fires modeHandlers
|
|
4576
|
-
//
|
|
4580
|
+
// own. Fires modeHandlers (persistence) and broadcasts a synthetic
|
|
4581
|
+
// current_mode_update so all attached clients — including the originator
|
|
4582
|
+
// — repaint immediately, mirroring applyModelChange. Without the
|
|
4583
|
+
// broadcast, peer clients (e.g. the TUI when set_mode was issued by Zed
|
|
4584
|
+
// through the shim) would stay on the prior mode.
|
|
4577
4585
|
applyModeChange(modeId) {
|
|
4578
4586
|
const trimmed = modeId.trim();
|
|
4579
|
-
if (!trimmed
|
|
4587
|
+
if (!trimmed) {
|
|
4580
4588
|
return;
|
|
4581
4589
|
}
|
|
4582
|
-
this.
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
+
if (trimmed !== this.currentMode) {
|
|
4591
|
+
this.logger?.info(
|
|
4592
|
+
`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(trimmed)}`
|
|
4593
|
+
);
|
|
4594
|
+
this.currentMode = trimmed;
|
|
4595
|
+
for (const handler of this.modeHandlers) {
|
|
4596
|
+
try {
|
|
4597
|
+
handler(trimmed);
|
|
4598
|
+
} catch {
|
|
4599
|
+
}
|
|
4590
4600
|
}
|
|
4591
4601
|
}
|
|
4602
|
+
const update = {
|
|
4603
|
+
sessionUpdate: "current_mode_update",
|
|
4604
|
+
currentModeId: trimmed
|
|
4605
|
+
};
|
|
4606
|
+
if (this.agentAdvertisedModes.length > 0) {
|
|
4607
|
+
update.availableModes = [...this.agentAdvertisedModes];
|
|
4608
|
+
}
|
|
4609
|
+
this.recordAndBroadcast("session/update", {
|
|
4610
|
+
sessionId: this.upstreamSessionId,
|
|
4611
|
+
update
|
|
4612
|
+
});
|
|
4592
4613
|
}
|
|
4593
4614
|
onUsageChange(handler) {
|
|
4594
4615
|
this.usageHandlers.push(handler);
|
|
@@ -4600,8 +4621,8 @@ var Session = class {
|
|
|
4600
4621
|
// entries, then whatever the agent advertised.
|
|
4601
4622
|
mergedAvailableCommands() {
|
|
4602
4623
|
const out = [
|
|
4603
|
-
|
|
4604
|
-
{ name: "model
|
|
4624
|
+
{ name: "hydra", description: "Hydra session command (kill, restart, title, agent <agent>)" },
|
|
4625
|
+
{ name: "model", description: "Switch model; omit arg to list available models" },
|
|
4605
4626
|
{ name: "sessions", description: "List all sessions" },
|
|
4606
4627
|
{ name: "help", description: "Show available commands" }
|
|
4607
4628
|
];
|
|
@@ -6372,6 +6393,7 @@ function resolveVersion() {
|
|
|
6372
6393
|
return "0.0.0";
|
|
6373
6394
|
}
|
|
6374
6395
|
var HYDRA_VERSION = resolveVersion();
|
|
6396
|
+
var HYDRA_CAT_CLIENT_NAME = "hydra-acp-cat";
|
|
6375
6397
|
|
|
6376
6398
|
// src/core/history-transcript.ts
|
|
6377
6399
|
var DEFAULT_MAX_CHARS = 4e5;
|
|
@@ -12532,8 +12554,11 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
12532
12554
|
connection.onRequest("session/list", async (raw) => {
|
|
12533
12555
|
const params = SessionListParams.parse(raw ?? {});
|
|
12534
12556
|
const entries = await deps.manager.list({ cwd: params.cwd });
|
|
12557
|
+
const visible = entries.filter(
|
|
12558
|
+
(e) => e.originatingClient?.name !== HYDRA_CAT_CLIENT_NAME
|
|
12559
|
+
);
|
|
12535
12560
|
const result = {
|
|
12536
|
-
sessions:
|
|
12561
|
+
sessions: visible.map(sessionListEntryToWire)
|
|
12537
12562
|
};
|
|
12538
12563
|
return result;
|
|
12539
12564
|
});
|