@hydra-acp/cli 0.1.32 → 0.1.34
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 +15 -18
- package/dist/cli.js +4605 -3555
- package/dist/index.d.ts +43 -115
- package/dist/index.js +160 -32
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
41
41
|
sessionIdleTimeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
42
42
|
sessionHistoryMaxEntries: z.ZodDefault<z.ZodNumber>;
|
|
43
43
|
agentStderrTailBytes: z.ZodDefault<z.ZodNumber>;
|
|
44
|
+
publicHost: z.ZodOptional<z.ZodString>;
|
|
44
45
|
}, "strip", z.ZodTypeAny, {
|
|
45
46
|
host: string;
|
|
46
47
|
port: number;
|
|
@@ -52,6 +53,7 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
52
53
|
cert: string;
|
|
53
54
|
key: string;
|
|
54
55
|
} | undefined;
|
|
56
|
+
publicHost?: string | undefined;
|
|
55
57
|
}, {
|
|
56
58
|
host?: string | undefined;
|
|
57
59
|
port?: number | undefined;
|
|
@@ -63,6 +65,7 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
63
65
|
sessionIdleTimeoutSeconds?: number | undefined;
|
|
64
66
|
sessionHistoryMaxEntries?: number | undefined;
|
|
65
67
|
agentStderrTailBytes?: number | undefined;
|
|
68
|
+
publicHost?: string | undefined;
|
|
66
69
|
}>>;
|
|
67
70
|
registry: z.ZodDefault<z.ZodObject<{
|
|
68
71
|
url: z.ZodDefault<z.ZodString>;
|
|
@@ -121,6 +124,15 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
121
124
|
defaultEnterAction?: "enqueue" | "amend" | undefined;
|
|
122
125
|
}>>;
|
|
123
126
|
}, "strip", z.ZodTypeAny, {
|
|
127
|
+
tui: {
|
|
128
|
+
repaintThrottleMs: number;
|
|
129
|
+
maxScrollbackLines: number;
|
|
130
|
+
mouse: boolean;
|
|
131
|
+
logMaxBytes: number;
|
|
132
|
+
cwdColumnMaxWidth: number;
|
|
133
|
+
progressIndicator: boolean;
|
|
134
|
+
defaultEnterAction: "enqueue" | "amend";
|
|
135
|
+
};
|
|
124
136
|
daemon: {
|
|
125
137
|
host: string;
|
|
126
138
|
port: number;
|
|
@@ -132,6 +144,7 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
132
144
|
cert: string;
|
|
133
145
|
key: string;
|
|
134
146
|
} | undefined;
|
|
147
|
+
publicHost?: string | undefined;
|
|
135
148
|
};
|
|
136
149
|
extensions: Record<string, {
|
|
137
150
|
command: string[];
|
|
@@ -139,15 +152,6 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
139
152
|
env: Record<string, string>;
|
|
140
153
|
enabled: boolean;
|
|
141
154
|
}>;
|
|
142
|
-
tui: {
|
|
143
|
-
repaintThrottleMs: number;
|
|
144
|
-
maxScrollbackLines: number;
|
|
145
|
-
mouse: boolean;
|
|
146
|
-
logMaxBytes: number;
|
|
147
|
-
cwdColumnMaxWidth: number;
|
|
148
|
-
progressIndicator: boolean;
|
|
149
|
-
defaultEnterAction: "enqueue" | "amend";
|
|
150
|
-
};
|
|
151
155
|
registry: {
|
|
152
156
|
url: string;
|
|
153
157
|
ttlHours: number;
|
|
@@ -158,6 +162,15 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
158
162
|
sessionListColdLimit: number;
|
|
159
163
|
npmRegistry?: string | undefined;
|
|
160
164
|
}, {
|
|
165
|
+
tui?: {
|
|
166
|
+
repaintThrottleMs?: number | undefined;
|
|
167
|
+
maxScrollbackLines?: number | undefined;
|
|
168
|
+
mouse?: boolean | undefined;
|
|
169
|
+
logMaxBytes?: number | undefined;
|
|
170
|
+
cwdColumnMaxWidth?: number | undefined;
|
|
171
|
+
progressIndicator?: boolean | undefined;
|
|
172
|
+
defaultEnterAction?: "enqueue" | "amend" | undefined;
|
|
173
|
+
} | undefined;
|
|
161
174
|
daemon?: {
|
|
162
175
|
host?: string | undefined;
|
|
163
176
|
port?: number | undefined;
|
|
@@ -169,6 +182,7 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
169
182
|
sessionIdleTimeoutSeconds?: number | undefined;
|
|
170
183
|
sessionHistoryMaxEntries?: number | undefined;
|
|
171
184
|
agentStderrTailBytes?: number | undefined;
|
|
185
|
+
publicHost?: string | undefined;
|
|
172
186
|
} | undefined;
|
|
173
187
|
extensions?: Record<string, {
|
|
174
188
|
command?: string[] | undefined;
|
|
@@ -176,15 +190,6 @@ declare const HydraConfig: z.ZodObject<{
|
|
|
176
190
|
env?: Record<string, string> | undefined;
|
|
177
191
|
enabled?: boolean | undefined;
|
|
178
192
|
}> | undefined;
|
|
179
|
-
tui?: {
|
|
180
|
-
repaintThrottleMs?: number | undefined;
|
|
181
|
-
maxScrollbackLines?: number | undefined;
|
|
182
|
-
mouse?: boolean | undefined;
|
|
183
|
-
logMaxBytes?: number | undefined;
|
|
184
|
-
cwdColumnMaxWidth?: number | undefined;
|
|
185
|
-
progressIndicator?: boolean | undefined;
|
|
186
|
-
defaultEnterAction?: "enqueue" | "amend" | undefined;
|
|
187
|
-
} | undefined;
|
|
188
193
|
registry?: {
|
|
189
194
|
url?: string | undefined;
|
|
190
195
|
ttlHours?: number | undefined;
|
|
@@ -1369,15 +1374,12 @@ type SessionDetachParams = z.infer<typeof SessionDetachParams>;
|
|
|
1369
1374
|
declare const SessionListParams: z.ZodObject<{
|
|
1370
1375
|
cwd: z.ZodOptional<z.ZodString>;
|
|
1371
1376
|
cursor: z.ZodOptional<z.ZodString>;
|
|
1372
|
-
limit: z.ZodOptional<z.ZodNumber>;
|
|
1373
1377
|
}, "strip", z.ZodTypeAny, {
|
|
1374
1378
|
cwd?: string | undefined;
|
|
1375
1379
|
cursor?: string | undefined;
|
|
1376
|
-
limit?: number | undefined;
|
|
1377
1380
|
}, {
|
|
1378
1381
|
cwd?: string | undefined;
|
|
1379
1382
|
cursor?: string | undefined;
|
|
1380
|
-
limit?: number | undefined;
|
|
1381
1383
|
}>;
|
|
1382
1384
|
type SessionListParams = z.infer<typeof SessionListParams>;
|
|
1383
1385
|
declare const SessionListEntry: z.ZodObject<{
|
|
@@ -1410,9 +1412,9 @@ declare const SessionListEntry: z.ZodObject<{
|
|
|
1410
1412
|
status: z.ZodDefault<z.ZodEnum<["live", "cold"]>>;
|
|
1411
1413
|
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1412
1414
|
}, "strip", z.ZodTypeAny, {
|
|
1413
|
-
status: "live" | "cold";
|
|
1414
|
-
cwd: string;
|
|
1415
1415
|
sessionId: string;
|
|
1416
|
+
cwd: string;
|
|
1417
|
+
status: "live" | "cold";
|
|
1416
1418
|
updatedAt: string;
|
|
1417
1419
|
attachedClients: number;
|
|
1418
1420
|
agentId?: string | undefined;
|
|
@@ -1429,8 +1431,8 @@ declare const SessionListEntry: z.ZodObject<{
|
|
|
1429
1431
|
importedFromMachine?: string | undefined;
|
|
1430
1432
|
importedFromUpstreamSessionId?: string | undefined;
|
|
1431
1433
|
}, {
|
|
1432
|
-
cwd: string;
|
|
1433
1434
|
sessionId: string;
|
|
1435
|
+
cwd: string;
|
|
1434
1436
|
updatedAt: string;
|
|
1435
1437
|
attachedClients: number;
|
|
1436
1438
|
status?: "live" | "cold" | undefined;
|
|
@@ -1452,115 +1454,40 @@ type SessionListEntry = z.infer<typeof SessionListEntry>;
|
|
|
1452
1454
|
declare const SessionListResult: z.ZodObject<{
|
|
1453
1455
|
sessions: z.ZodArray<z.ZodObject<{
|
|
1454
1456
|
sessionId: z.ZodString;
|
|
1455
|
-
upstreamSessionId: z.ZodOptional<z.ZodString>;
|
|
1456
1457
|
cwd: z.ZodString;
|
|
1457
1458
|
title: z.ZodOptional<z.ZodString>;
|
|
1458
|
-
|
|
1459
|
-
currentModel: z.ZodOptional<z.ZodString>;
|
|
1460
|
-
currentUsage: z.ZodOptional<z.ZodObject<{
|
|
1461
|
-
used: z.ZodOptional<z.ZodNumber>;
|
|
1462
|
-
size: z.ZodOptional<z.ZodNumber>;
|
|
1463
|
-
costAmount: z.ZodOptional<z.ZodNumber>;
|
|
1464
|
-
costCurrency: z.ZodOptional<z.ZodString>;
|
|
1465
|
-
}, "strip", z.ZodTypeAny, {
|
|
1466
|
-
used?: number | undefined;
|
|
1467
|
-
size?: number | undefined;
|
|
1468
|
-
costAmount?: number | undefined;
|
|
1469
|
-
costCurrency?: string | undefined;
|
|
1470
|
-
}, {
|
|
1471
|
-
used?: number | undefined;
|
|
1472
|
-
size?: number | undefined;
|
|
1473
|
-
costAmount?: number | undefined;
|
|
1474
|
-
costCurrency?: string | undefined;
|
|
1475
|
-
}>>;
|
|
1476
|
-
importedFromMachine: z.ZodOptional<z.ZodString>;
|
|
1477
|
-
importedFromUpstreamSessionId: z.ZodOptional<z.ZodString>;
|
|
1478
|
-
updatedAt: z.ZodString;
|
|
1479
|
-
attachedClients: z.ZodNumber;
|
|
1480
|
-
status: z.ZodDefault<z.ZodEnum<["live", "cold"]>>;
|
|
1459
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
1481
1460
|
_meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1482
1461
|
}, "strip", z.ZodTypeAny, {
|
|
1483
|
-
status: "live" | "cold";
|
|
1484
|
-
cwd: string;
|
|
1485
1462
|
sessionId: string;
|
|
1486
|
-
|
|
1487
|
-
attachedClients: number;
|
|
1488
|
-
agentId?: string | undefined;
|
|
1489
|
-
upstreamSessionId?: string | undefined;
|
|
1463
|
+
cwd: string;
|
|
1490
1464
|
title?: string | undefined;
|
|
1491
1465
|
_meta?: Record<string, unknown> | undefined;
|
|
1492
|
-
|
|
1493
|
-
currentUsage?: {
|
|
1494
|
-
used?: number | undefined;
|
|
1495
|
-
size?: number | undefined;
|
|
1496
|
-
costAmount?: number | undefined;
|
|
1497
|
-
costCurrency?: string | undefined;
|
|
1498
|
-
} | undefined;
|
|
1499
|
-
importedFromMachine?: string | undefined;
|
|
1500
|
-
importedFromUpstreamSessionId?: string | undefined;
|
|
1466
|
+
updatedAt?: string | undefined;
|
|
1501
1467
|
}, {
|
|
1502
|
-
cwd: string;
|
|
1503
1468
|
sessionId: string;
|
|
1504
|
-
|
|
1505
|
-
attachedClients: number;
|
|
1506
|
-
status?: "live" | "cold" | undefined;
|
|
1507
|
-
agentId?: string | undefined;
|
|
1508
|
-
upstreamSessionId?: string | undefined;
|
|
1469
|
+
cwd: string;
|
|
1509
1470
|
title?: string | undefined;
|
|
1510
1471
|
_meta?: Record<string, unknown> | undefined;
|
|
1511
|
-
|
|
1512
|
-
currentUsage?: {
|
|
1513
|
-
used?: number | undefined;
|
|
1514
|
-
size?: number | undefined;
|
|
1515
|
-
costAmount?: number | undefined;
|
|
1516
|
-
costCurrency?: string | undefined;
|
|
1517
|
-
} | undefined;
|
|
1518
|
-
importedFromMachine?: string | undefined;
|
|
1519
|
-
importedFromUpstreamSessionId?: string | undefined;
|
|
1472
|
+
updatedAt?: string | undefined;
|
|
1520
1473
|
}>, "many">;
|
|
1521
1474
|
nextCursor: z.ZodOptional<z.ZodString>;
|
|
1522
1475
|
}, "strip", z.ZodTypeAny, {
|
|
1523
1476
|
sessions: {
|
|
1524
|
-
status: "live" | "cold";
|
|
1525
|
-
cwd: string;
|
|
1526
1477
|
sessionId: string;
|
|
1527
|
-
|
|
1528
|
-
attachedClients: number;
|
|
1529
|
-
agentId?: string | undefined;
|
|
1530
|
-
upstreamSessionId?: string | undefined;
|
|
1478
|
+
cwd: string;
|
|
1531
1479
|
title?: string | undefined;
|
|
1532
1480
|
_meta?: Record<string, unknown> | undefined;
|
|
1533
|
-
|
|
1534
|
-
currentUsage?: {
|
|
1535
|
-
used?: number | undefined;
|
|
1536
|
-
size?: number | undefined;
|
|
1537
|
-
costAmount?: number | undefined;
|
|
1538
|
-
costCurrency?: string | undefined;
|
|
1539
|
-
} | undefined;
|
|
1540
|
-
importedFromMachine?: string | undefined;
|
|
1541
|
-
importedFromUpstreamSessionId?: string | undefined;
|
|
1481
|
+
updatedAt?: string | undefined;
|
|
1542
1482
|
}[];
|
|
1543
1483
|
nextCursor?: string | undefined;
|
|
1544
1484
|
}, {
|
|
1545
1485
|
sessions: {
|
|
1546
|
-
cwd: string;
|
|
1547
1486
|
sessionId: string;
|
|
1548
|
-
|
|
1549
|
-
attachedClients: number;
|
|
1550
|
-
status?: "live" | "cold" | undefined;
|
|
1551
|
-
agentId?: string | undefined;
|
|
1552
|
-
upstreamSessionId?: string | undefined;
|
|
1487
|
+
cwd: string;
|
|
1553
1488
|
title?: string | undefined;
|
|
1554
1489
|
_meta?: Record<string, unknown> | undefined;
|
|
1555
|
-
|
|
1556
|
-
currentUsage?: {
|
|
1557
|
-
used?: number | undefined;
|
|
1558
|
-
size?: number | undefined;
|
|
1559
|
-
costAmount?: number | undefined;
|
|
1560
|
-
costCurrency?: string | undefined;
|
|
1561
|
-
} | undefined;
|
|
1562
|
-
importedFromMachine?: string | undefined;
|
|
1563
|
-
importedFromUpstreamSessionId?: string | undefined;
|
|
1490
|
+
updatedAt?: string | undefined;
|
|
1564
1491
|
}[];
|
|
1565
1492
|
nextCursor?: string | undefined;
|
|
1566
1493
|
}>;
|
|
@@ -1623,7 +1550,7 @@ declare const AmendPromptResult: z.ZodObject<{
|
|
|
1623
1550
|
type AmendPromptResult = z.infer<typeof AmendPromptResult>;
|
|
1624
1551
|
interface SessionCapabilities {
|
|
1625
1552
|
attach?: Record<string, never>;
|
|
1626
|
-
list?:
|
|
1553
|
+
list?: Record<string, never>;
|
|
1627
1554
|
}
|
|
1628
1555
|
interface PromptCapabilities {
|
|
1629
1556
|
image?: boolean;
|
|
@@ -2055,11 +1982,11 @@ declare const SessionRecord: z.ZodObject<{
|
|
|
2055
1982
|
createdAt: z.ZodString;
|
|
2056
1983
|
updatedAt: z.ZodString;
|
|
2057
1984
|
}, "strip", z.ZodTypeAny, {
|
|
1985
|
+
sessionId: string;
|
|
2058
1986
|
version: 1;
|
|
2059
1987
|
cwd: string;
|
|
2060
1988
|
agentId: string;
|
|
2061
1989
|
upstreamSessionId: string;
|
|
2062
|
-
sessionId: string;
|
|
2063
1990
|
updatedAt: string;
|
|
2064
1991
|
createdAt: string;
|
|
2065
1992
|
title?: string | undefined;
|
|
@@ -2091,11 +2018,11 @@ declare const SessionRecord: z.ZodObject<{
|
|
|
2091
2018
|
description?: string | undefined;
|
|
2092
2019
|
}[] | undefined;
|
|
2093
2020
|
}, {
|
|
2021
|
+
sessionId: string;
|
|
2094
2022
|
version: 1;
|
|
2095
2023
|
cwd: string;
|
|
2096
2024
|
agentId: string;
|
|
2097
2025
|
upstreamSessionId: string;
|
|
2098
|
-
sessionId: string;
|
|
2099
2026
|
updatedAt: string;
|
|
2100
2027
|
createdAt: string;
|
|
2101
2028
|
title?: string | undefined;
|
|
@@ -2200,9 +2127,9 @@ declare const Bundle: z.ZodObject<{
|
|
|
2200
2127
|
createdAt: z.ZodString;
|
|
2201
2128
|
updatedAt: z.ZodString;
|
|
2202
2129
|
}, "strip", z.ZodTypeAny, {
|
|
2130
|
+
sessionId: string;
|
|
2203
2131
|
cwd: string;
|
|
2204
2132
|
agentId: string;
|
|
2205
|
-
sessionId: string;
|
|
2206
2133
|
updatedAt: string;
|
|
2207
2134
|
lineageId: string;
|
|
2208
2135
|
createdAt: string;
|
|
@@ -2226,9 +2153,9 @@ declare const Bundle: z.ZodObject<{
|
|
|
2226
2153
|
description?: string | undefined;
|
|
2227
2154
|
}[] | undefined;
|
|
2228
2155
|
}, {
|
|
2156
|
+
sessionId: string;
|
|
2229
2157
|
cwd: string;
|
|
2230
2158
|
agentId: string;
|
|
2231
|
-
sessionId: string;
|
|
2232
2159
|
updatedAt: string;
|
|
2233
2160
|
lineageId: string;
|
|
2234
2161
|
createdAt: string;
|
|
@@ -2269,9 +2196,9 @@ declare const Bundle: z.ZodObject<{
|
|
|
2269
2196
|
}, "strip", z.ZodTypeAny, {
|
|
2270
2197
|
version: 1;
|
|
2271
2198
|
session: {
|
|
2199
|
+
sessionId: string;
|
|
2272
2200
|
cwd: string;
|
|
2273
2201
|
agentId: string;
|
|
2274
|
-
sessionId: string;
|
|
2275
2202
|
updatedAt: string;
|
|
2276
2203
|
lineageId: string;
|
|
2277
2204
|
createdAt: string;
|
|
@@ -2309,9 +2236,9 @@ declare const Bundle: z.ZodObject<{
|
|
|
2309
2236
|
}, {
|
|
2310
2237
|
version: 1;
|
|
2311
2238
|
session: {
|
|
2239
|
+
sessionId: string;
|
|
2312
2240
|
cwd: string;
|
|
2313
2241
|
agentId: string;
|
|
2314
|
-
sessionId: string;
|
|
2315
2242
|
updatedAt: string;
|
|
2316
2243
|
lineageId: string;
|
|
2317
2244
|
createdAt: string;
|
|
@@ -2510,6 +2437,7 @@ declare const paths: {
|
|
|
2510
2437
|
home: typeof hydraHome;
|
|
2511
2438
|
config: () => string;
|
|
2512
2439
|
authToken: () => string;
|
|
2440
|
+
remotes: () => string;
|
|
2513
2441
|
pidFile: () => string;
|
|
2514
2442
|
logFile: () => string;
|
|
2515
2443
|
currentLogFile: () => string;
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,17 @@ import * as fs14 from "fs";
|
|
|
3
3
|
import * as fsp5 from "fs/promises";
|
|
4
4
|
import Fastify from "fastify";
|
|
5
5
|
import websocketPlugin from "@fastify/websocket";
|
|
6
|
+
|
|
7
|
+
// src/daemon/ws-protocol.ts
|
|
8
|
+
var ACP_WS_PROTOCOL_VERSION = "acp.v1";
|
|
9
|
+
function selectAcpSubprotocol(protocols, _req) {
|
|
10
|
+
if (protocols.has(ACP_WS_PROTOCOL_VERSION)) {
|
|
11
|
+
return ACP_WS_PROTOCOL_VERSION;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/daemon/server.ts
|
|
6
17
|
import pino from "pino";
|
|
7
18
|
import createPinoRoll from "pino-roll";
|
|
8
19
|
|
|
@@ -33,6 +44,10 @@ var paths = {
|
|
|
33
44
|
// Auth token lives in its own file so config.json can be version-
|
|
34
45
|
// controlled without leaking the secret. Raw string contents, mode 0600.
|
|
35
46
|
authToken: () => path.join(hydraHome(), "auth-token"),
|
|
47
|
+
// Per-host cache of password-issued session tokens used by
|
|
48
|
+
// `hydra session attach hydra://<host>/...`. JSON object keyed by
|
|
49
|
+
// "<host>:<port>" → { token, expiresAt, label? }. Mode 0600.
|
|
50
|
+
remotes: () => path.join(hydraHome(), "remotes.json"),
|
|
36
51
|
pidFile: () => path.join(hydraHome(), "daemon.pid"),
|
|
37
52
|
logFile: () => path.join(hydraHome(), "daemon.log"),
|
|
38
53
|
currentLogFile: () => path.join(hydraHome(), "current.log"),
|
|
@@ -150,7 +165,14 @@ var DaemonConfig = z.object({
|
|
|
150
165
|
// Bytes of trailing agent stderr buffered per AgentInstance so the
|
|
151
166
|
// daemon can include it in the diagnostic message when a spawn fails.
|
|
152
167
|
// Bump if your agents emit large tracebacks you want surfaced.
|
|
153
|
-
agentStderrTailBytes: z.number().int().positive().default(4096)
|
|
168
|
+
agentStderrTailBytes: z.number().int().positive().default(4096),
|
|
169
|
+
// Externally-reachable hostname for this daemon, used when `hydra
|
|
170
|
+
// session share` constructs a URL to advertise. Useful when the
|
|
171
|
+
// daemon binds to loopback (the normal case) but is exposed via a
|
|
172
|
+
// tunnel (ngrok) or VPN (Tailscale) under a different name. The
|
|
173
|
+
// `--host` flag on `share` overrides this; omitting both falls
|
|
174
|
+
// back to `daemon.host`, then to "127.0.0.1" with a stderr warning.
|
|
175
|
+
publicHost: z.string().optional()
|
|
154
176
|
});
|
|
155
177
|
var RegistryConfig = z.object({
|
|
156
178
|
url: z.string().url().default(REGISTRY_URL_DEFAULT),
|
|
@@ -605,9 +627,16 @@ async function ensureNpmPackage(args) {
|
|
|
605
627
|
platformKey,
|
|
606
628
|
args.version
|
|
607
629
|
);
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
630
|
+
const packageName = packageNameFromSpec(args.packageSpec);
|
|
631
|
+
const basename = packageBasename(packageName);
|
|
632
|
+
const resolveArgs = { installDir, packageName, hint: args.bin, basename };
|
|
633
|
+
const hintPath = path3.join(installDir, "node_modules", ".bin", args.bin);
|
|
634
|
+
if (await fileExists2(hintPath))
|
|
635
|
+
return hintPath;
|
|
636
|
+
if (await fileExists2(installDir)) {
|
|
637
|
+
const slowResolved = await resolveBin(resolveArgs);
|
|
638
|
+
if (slowResolved)
|
|
639
|
+
return slowResolved.binPath;
|
|
611
640
|
}
|
|
612
641
|
await installInto({
|
|
613
642
|
agentId: args.agentId,
|
|
@@ -617,12 +646,15 @@ async function ensureNpmPackage(args) {
|
|
|
617
646
|
registry: args.registry,
|
|
618
647
|
onProgress: args.onProgress
|
|
619
648
|
});
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
649
|
+
const resolved = await resolveBin(resolveArgs);
|
|
650
|
+
if (resolved)
|
|
651
|
+
return resolved.binPath;
|
|
652
|
+
const binField = await readPackageJsonBin(installDir, packageName);
|
|
653
|
+
const declared = typeof binField === "object" && binField !== null ? Object.keys(binField) : typeof binField === "string" ? [basename] : [];
|
|
654
|
+
const suffix = declared.length > 0 ? ` (package declares bins: ${declared.join(", ")})` : "";
|
|
655
|
+
throw new Error(
|
|
656
|
+
`Agent ${args.agentId}: npm install of ${args.packageSpec} did not produce bin ${args.bin} (looked in ${installDir}/node_modules/.bin/)${suffix}`
|
|
657
|
+
);
|
|
626
658
|
}
|
|
627
659
|
async function installInto(args) {
|
|
628
660
|
await fsp2.mkdir(path3.dirname(args.installDir), { recursive: true });
|
|
@@ -754,6 +786,73 @@ stderr: ${tail}` : `npm install ${args.packageSpec} failed (${reason})`
|
|
|
754
786
|
throw err;
|
|
755
787
|
}
|
|
756
788
|
}
|
|
789
|
+
function packageNameFromSpec(spec) {
|
|
790
|
+
if (spec.startsWith("@")) {
|
|
791
|
+
const slashIdx = spec.indexOf("/");
|
|
792
|
+
if (slashIdx === -1)
|
|
793
|
+
return spec;
|
|
794
|
+
const rest = spec.slice(slashIdx + 1);
|
|
795
|
+
const atIdx2 = rest.indexOf("@");
|
|
796
|
+
if (atIdx2 === -1)
|
|
797
|
+
return spec;
|
|
798
|
+
return spec.slice(0, slashIdx + 1 + atIdx2);
|
|
799
|
+
}
|
|
800
|
+
const atIdx = spec.indexOf("@");
|
|
801
|
+
if (atIdx <= 0)
|
|
802
|
+
return spec;
|
|
803
|
+
return spec.slice(0, atIdx);
|
|
804
|
+
}
|
|
805
|
+
function packageBasename(packageName) {
|
|
806
|
+
const lastSlash = packageName.lastIndexOf("/");
|
|
807
|
+
return lastSlash === -1 ? packageName : packageName.slice(lastSlash + 1);
|
|
808
|
+
}
|
|
809
|
+
async function readPackageJsonBin(installDir, packageName) {
|
|
810
|
+
const pkgPath = path3.join(
|
|
811
|
+
installDir,
|
|
812
|
+
"node_modules",
|
|
813
|
+
packageName,
|
|
814
|
+
"package.json"
|
|
815
|
+
);
|
|
816
|
+
try {
|
|
817
|
+
const text = await fsp2.readFile(pkgPath, "utf8");
|
|
818
|
+
const pkg = JSON.parse(text);
|
|
819
|
+
if (typeof pkg.bin === "string" || typeof pkg.bin === "object" && pkg.bin !== null && !Array.isArray(pkg.bin))
|
|
820
|
+
return pkg.bin;
|
|
821
|
+
return void 0;
|
|
822
|
+
} catch {
|
|
823
|
+
return void 0;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
async function resolveBin(args) {
|
|
827
|
+
const binDir = path3.join(args.installDir, "node_modules", ".bin");
|
|
828
|
+
const hintPath = path3.join(binDir, args.hint);
|
|
829
|
+
if (await fileExists2(hintPath))
|
|
830
|
+
return { binName: args.hint, binPath: hintPath };
|
|
831
|
+
const binField = await readPackageJsonBin(args.installDir, args.packageName);
|
|
832
|
+
if (typeof binField === "object" && binField !== null) {
|
|
833
|
+
const keys = Object.keys(binField);
|
|
834
|
+
if (keys.length === 1) {
|
|
835
|
+
const key = keys[0];
|
|
836
|
+
const p = path3.join(binDir, key);
|
|
837
|
+
if (await fileExists2(p))
|
|
838
|
+
return { binName: key, binPath: p };
|
|
839
|
+
} else if (keys.length > 1) {
|
|
840
|
+
for (const candidate of [args.hint, args.basename]) {
|
|
841
|
+
if (keys.includes(candidate)) {
|
|
842
|
+
const p = path3.join(binDir, candidate);
|
|
843
|
+
if (await fileExists2(p))
|
|
844
|
+
return { binName: candidate, binPath: p };
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
if (args.basename !== args.hint) {
|
|
850
|
+
const p = path3.join(binDir, args.basename);
|
|
851
|
+
if (await fileExists2(p))
|
|
852
|
+
return { binName: args.basename, binPath: p };
|
|
853
|
+
}
|
|
854
|
+
return void 0;
|
|
855
|
+
}
|
|
757
856
|
async function fileExists2(p) {
|
|
758
857
|
try {
|
|
759
858
|
await fsp2.access(p);
|
|
@@ -1250,8 +1349,7 @@ var SessionDetachParams = z3.object({
|
|
|
1250
1349
|
});
|
|
1251
1350
|
var SessionListParams = z3.object({
|
|
1252
1351
|
cwd: z3.string().optional(),
|
|
1253
|
-
cursor: z3.string().optional()
|
|
1254
|
-
limit: z3.number().int().positive().max(200).optional()
|
|
1352
|
+
cursor: z3.string().optional()
|
|
1255
1353
|
});
|
|
1256
1354
|
var SessionListUsage = z3.object({
|
|
1257
1355
|
used: z3.number().optional(),
|
|
@@ -1281,10 +1379,51 @@ var SessionListEntry = z3.object({
|
|
|
1281
1379
|
status: z3.enum(["live", "cold"]).default("live"),
|
|
1282
1380
|
_meta: z3.record(z3.unknown()).optional()
|
|
1283
1381
|
});
|
|
1382
|
+
var SessionListEntryWire = z3.object({
|
|
1383
|
+
sessionId: z3.string(),
|
|
1384
|
+
cwd: z3.string(),
|
|
1385
|
+
title: z3.string().optional(),
|
|
1386
|
+
updatedAt: z3.string().optional(),
|
|
1387
|
+
_meta: z3.record(z3.unknown()).optional()
|
|
1388
|
+
});
|
|
1284
1389
|
var SessionListResult = z3.object({
|
|
1285
|
-
sessions: z3.array(
|
|
1390
|
+
sessions: z3.array(SessionListEntryWire),
|
|
1286
1391
|
nextCursor: z3.string().optional()
|
|
1287
1392
|
});
|
|
1393
|
+
function sessionListEntryToWire(entry) {
|
|
1394
|
+
const hydraMeta = {
|
|
1395
|
+
attachedClients: entry.attachedClients,
|
|
1396
|
+
status: entry.status
|
|
1397
|
+
};
|
|
1398
|
+
if (entry.agentId !== void 0) {
|
|
1399
|
+
hydraMeta.agentId = entry.agentId;
|
|
1400
|
+
}
|
|
1401
|
+
if (entry.upstreamSessionId !== void 0) {
|
|
1402
|
+
hydraMeta.upstreamSessionId = entry.upstreamSessionId;
|
|
1403
|
+
}
|
|
1404
|
+
if (entry.currentModel !== void 0) {
|
|
1405
|
+
hydraMeta.currentModel = entry.currentModel;
|
|
1406
|
+
}
|
|
1407
|
+
if (entry.currentUsage !== void 0) {
|
|
1408
|
+
hydraMeta.currentUsage = entry.currentUsage;
|
|
1409
|
+
}
|
|
1410
|
+
if (entry.importedFromMachine !== void 0) {
|
|
1411
|
+
hydraMeta.importedFromMachine = entry.importedFromMachine;
|
|
1412
|
+
}
|
|
1413
|
+
if (entry.importedFromUpstreamSessionId !== void 0) {
|
|
1414
|
+
hydraMeta.importedFromUpstreamSessionId = entry.importedFromUpstreamSessionId;
|
|
1415
|
+
}
|
|
1416
|
+
const wire = {
|
|
1417
|
+
sessionId: entry.sessionId,
|
|
1418
|
+
cwd: entry.cwd,
|
|
1419
|
+
updatedAt: entry.updatedAt,
|
|
1420
|
+
_meta: mergeMeta(entry._meta, hydraMeta)
|
|
1421
|
+
};
|
|
1422
|
+
if (entry.title !== void 0) {
|
|
1423
|
+
wire.title = entry.title;
|
|
1424
|
+
}
|
|
1425
|
+
return wire;
|
|
1426
|
+
}
|
|
1288
1427
|
var SessionPromptParams = z3.object({
|
|
1289
1428
|
sessionId: z3.string(),
|
|
1290
1429
|
prompt: z3.array(z3.unknown())
|
|
@@ -1380,17 +1519,6 @@ var AgentInstallProgressParams = z3.object({
|
|
|
1380
1519
|
packageSpec: z3.string().optional()
|
|
1381
1520
|
});
|
|
1382
1521
|
var AGENT_INSTALL_PROGRESS_METHOD = "hydra-acp/agent_install_progress";
|
|
1383
|
-
var ProxyInitializeParams = z3.object({
|
|
1384
|
-
protocolVersion: z3.number().optional(),
|
|
1385
|
-
proxyInfo: z3.object({
|
|
1386
|
-
name: z3.string(),
|
|
1387
|
-
version: z3.string().optional()
|
|
1388
|
-
}).optional(),
|
|
1389
|
-
successor: z3.object({
|
|
1390
|
-
command: z3.array(z3.string()),
|
|
1391
|
-
env: z3.record(z3.string()).optional()
|
|
1392
|
-
}).optional()
|
|
1393
|
-
});
|
|
1394
1522
|
|
|
1395
1523
|
// src/acp/framing.ts
|
|
1396
1524
|
function ndjsonStreamFromStdio(stdout, stdin) {
|
|
@@ -7744,10 +7872,6 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
7744
7872
|
InitializeParams.parse(raw ?? {});
|
|
7745
7873
|
return buildInitializeResult();
|
|
7746
7874
|
});
|
|
7747
|
-
connection.onRequest("proxy/initialize", async (raw) => {
|
|
7748
|
-
ProxyInitializeParams.parse(raw ?? {});
|
|
7749
|
-
return buildInitializeResult();
|
|
7750
|
-
});
|
|
7751
7875
|
connection.onRequest("session/new", async (raw) => {
|
|
7752
7876
|
const params = SessionNewParams.parse(raw);
|
|
7753
7877
|
const hydraMeta = extractHydraMeta(
|
|
@@ -7918,8 +8042,10 @@ function registerAcpWsEndpoint(app, deps) {
|
|
|
7918
8042
|
});
|
|
7919
8043
|
connection.onRequest("session/list", async (raw) => {
|
|
7920
8044
|
const params = SessionListParams.parse(raw ?? {});
|
|
7921
|
-
const
|
|
7922
|
-
const result = {
|
|
8045
|
+
const entries = await deps.manager.list({ cwd: params.cwd });
|
|
8046
|
+
const result = {
|
|
8047
|
+
sessions: entries.map(sessionListEntryToWire)
|
|
8048
|
+
};
|
|
7923
8049
|
return result;
|
|
7924
8050
|
});
|
|
7925
8051
|
connection.onRequest("session/prompt", async (raw) => {
|
|
@@ -8350,7 +8476,7 @@ function buildInitializeResult() {
|
|
|
8350
8476
|
loadSession: true,
|
|
8351
8477
|
sessionCapabilities: {
|
|
8352
8478
|
attach: {},
|
|
8353
|
-
list:
|
|
8479
|
+
list: {}
|
|
8354
8480
|
}
|
|
8355
8481
|
},
|
|
8356
8482
|
authMethods: [
|
|
@@ -8405,7 +8531,9 @@ async function startDaemon(config, serviceToken) {
|
|
|
8405
8531
|
// the 1MB Fastify default rejects ordinary imports.
|
|
8406
8532
|
bodyLimit: 256 * 1024 * 1024
|
|
8407
8533
|
});
|
|
8408
|
-
await app.register(websocketPlugin
|
|
8534
|
+
await app.register(websocketPlugin, {
|
|
8535
|
+
options: { handleProtocols: selectAcpSubprotocol }
|
|
8536
|
+
});
|
|
8409
8537
|
setBinaryInstallLogger((msg) => {
|
|
8410
8538
|
app.log.info(msg);
|
|
8411
8539
|
});
|