privateer-agent 0.15.4 → 0.15.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.
Files changed (229) hide show
  1. package/README.md +11 -0
  2. package/bin/boot-bundle.d.mts +2 -0
  3. package/bin/boot-bundle.mjs +44 -0
  4. package/bin/fresh-supervisor.d.mts +5 -1
  5. package/bin/fresh-supervisor.mjs +47 -10
  6. package/bin/privateer-launch.mjs +27 -3
  7. package/bin/privateer-subagent.mjs +5 -2
  8. package/bin/privateer-verify.mjs +12 -0
  9. package/bin/session-recovery.d.mts +53 -0
  10. package/bin/session-recovery.mjs +240 -0
  11. package/bin/session-seal-preload.mjs +17 -0
  12. package/bin/session-seal.d.mts +25 -0
  13. package/bin/session-seal.mjs +242 -0
  14. package/dist-boot/boot.mjs +3 -0
  15. package/dist-boot/c-27JKSMWL.mjs +1460 -0
  16. package/dist-boot/c-2BMRFV24.mjs +269 -0
  17. package/dist-boot/c-2CTF6JA3.mjs +166 -0
  18. package/dist-boot/c-2G3BBHRJ.mjs +84 -0
  19. package/dist-boot/c-2IDLKXX6.mjs +250 -0
  20. package/dist-boot/c-2NJD5VYM.mjs +8 -0
  21. package/dist-boot/c-2S5EEQPW.mjs +1602 -0
  22. package/dist-boot/c-2WRDCUVI.mjs +25 -0
  23. package/dist-boot/c-2YN3M256.mjs +14 -0
  24. package/dist-boot/c-37GM3GMU.mjs +187 -0
  25. package/dist-boot/c-3STKRSVO.mjs +2480 -0
  26. package/dist-boot/c-3TPV6TQQ.mjs +2320 -0
  27. package/dist-boot/c-3UVHLQDJ.mjs +225 -0
  28. package/dist-boot/c-42PUUZYC.mjs +697 -0
  29. package/dist-boot/c-4D5UMWVW.mjs +683 -0
  30. package/dist-boot/c-4ETZRMTA.mjs +46 -0
  31. package/dist-boot/c-4QT25BD5.mjs +1482 -0
  32. package/dist-boot/c-4WVR32AP.mjs +2579 -0
  33. package/dist-boot/c-5EMM567G.mjs +152 -0
  34. package/dist-boot/c-5FA4CV63.mjs +145 -0
  35. package/dist-boot/c-5GV3X3RB.mjs +14 -0
  36. package/dist-boot/c-5JCEPRIY.mjs +52 -0
  37. package/dist-boot/c-5NDKIIWT.mjs +16 -0
  38. package/dist-boot/c-5QL3AR26.mjs +4665 -0
  39. package/dist-boot/c-5XY6MFKN.mjs +5142 -0
  40. package/dist-boot/c-65UZIZC7.mjs +2897 -0
  41. package/dist-boot/c-6FUXKHOK.mjs +1969 -0
  42. package/dist-boot/c-6JHWQE4V.mjs +18242 -0
  43. package/dist-boot/c-6LOBR4I6.mjs +5280 -0
  44. package/dist-boot/c-6QHOZXKQ.mjs +14394 -0
  45. package/dist-boot/c-6ZO2SADQ.mjs +178 -0
  46. package/dist-boot/c-6ZORVVZP.mjs +1449 -0
  47. package/dist-boot/c-76QH4UCP.mjs +2441 -0
  48. package/dist-boot/c-77GO5L5Y.mjs +20982 -0
  49. package/dist-boot/c-7M23XFTN.mjs +5052 -0
  50. package/dist-boot/c-7TC367E2.mjs +32 -0
  51. package/dist-boot/c-7UOG7POX.mjs +1524 -0
  52. package/dist-boot/c-7VHP3FLN.mjs +376 -0
  53. package/dist-boot/c-A73JHZP2.mjs +13207 -0
  54. package/dist-boot/c-ABXULAFL.mjs +71 -0
  55. package/dist-boot/c-ANDD2AQO.mjs +74 -0
  56. package/dist-boot/c-AOY77AZL.mjs +1430 -0
  57. package/dist-boot/c-AXEPZ22I.mjs +108 -0
  58. package/dist-boot/c-B2Y7VNHU.mjs +427 -0
  59. package/dist-boot/c-B7VJUH73.mjs +77 -0
  60. package/dist-boot/c-BFW6CDVL.mjs +24 -0
  61. package/dist-boot/c-BHNIF2AR.mjs +188 -0
  62. package/dist-boot/c-BKF2O6BL.mjs +23 -0
  63. package/dist-boot/c-BOZXFTZN.mjs +8 -0
  64. package/dist-boot/c-BRNYJWZL.mjs +28 -0
  65. package/dist-boot/c-C3N4Z2HO.mjs +93 -0
  66. package/dist-boot/c-C4IV7ZFG.mjs +717 -0
  67. package/dist-boot/c-C5NK6UYV.mjs +793 -0
  68. package/dist-boot/c-C67644MB.mjs +1659 -0
  69. package/dist-boot/c-C6S2YB53.mjs +620 -0
  70. package/dist-boot/c-CDBEJSBF.mjs +37 -0
  71. package/dist-boot/c-CG47HBKU.mjs +435 -0
  72. package/dist-boot/c-CKCTWCT5.mjs +51 -0
  73. package/dist-boot/c-CN77DCGF.mjs +60 -0
  74. package/dist-boot/c-CRBXNKFO.mjs +1795 -0
  75. package/dist-boot/c-CRIHASQ6.mjs +973 -0
  76. package/dist-boot/c-CU4NGAUO.mjs +3786 -0
  77. package/dist-boot/c-CWRFLGQU.mjs +1883 -0
  78. package/dist-boot/c-CYQB2USO.mjs +32 -0
  79. package/dist-boot/c-DEE67DJO.mjs +379 -0
  80. package/dist-boot/c-DIFDBYOP.mjs +1258 -0
  81. package/dist-boot/c-DOSGVXDZ.mjs +34879 -0
  82. package/dist-boot/c-DR7XQI32.mjs +381 -0
  83. package/dist-boot/c-DTGPSB46.mjs +14666 -0
  84. package/dist-boot/c-DTHDNA4P.mjs +320 -0
  85. package/dist-boot/c-E4Z3Y5B5.mjs +3864 -0
  86. package/dist-boot/c-E66Z2TI7.mjs +203 -0
  87. package/dist-boot/c-EBU6RLRV.mjs +1527 -0
  88. package/dist-boot/c-EBZZNGSF.mjs +432 -0
  89. package/dist-boot/c-EC3LJ2KF.mjs +1032 -0
  90. package/dist-boot/c-EQBKXWNX.mjs +15829 -0
  91. package/dist-boot/c-EUEPIW4S.mjs +574 -0
  92. package/dist-boot/c-EX4YVWAT.mjs +378 -0
  93. package/dist-boot/c-EYZGSAJU.mjs +98 -0
  94. package/dist-boot/c-F75VRKY4.mjs +172 -0
  95. package/dist-boot/c-FH4NXKHV.mjs +177 -0
  96. package/dist-boot/c-FHNUCTEM.mjs +140 -0
  97. package/dist-boot/c-FJ5T42DS.mjs +5349 -0
  98. package/dist-boot/c-FPCNRL7G.mjs +1728 -0
  99. package/dist-boot/c-G4DLN7Q4.mjs +8 -0
  100. package/dist-boot/c-G56GYQFZ.mjs +2507 -0
  101. package/dist-boot/c-GLIOERDQ.mjs +1200 -0
  102. package/dist-boot/c-GMJ5HUBM.mjs +14 -0
  103. package/dist-boot/c-H3HSGMAQ.mjs +461 -0
  104. package/dist-boot/c-HIKTO6P7.mjs +275 -0
  105. package/dist-boot/c-I2MCJ34O.mjs +464 -0
  106. package/dist-boot/c-I3C6LBW4.mjs +765 -0
  107. package/dist-boot/c-I54OKQHW.mjs +387 -0
  108. package/dist-boot/c-IFSP3R4D.mjs +80 -0
  109. package/dist-boot/c-IZK77VB7.mjs +171 -0
  110. package/dist-boot/c-J3Y25UGE.mjs +54 -0
  111. package/dist-boot/c-J5IESS7W.mjs +27750 -0
  112. package/dist-boot/c-JJWZBY7L.mjs +254 -0
  113. package/dist-boot/c-JKTFXTGF.mjs +463 -0
  114. package/dist-boot/c-JN57AXQ4.mjs +77 -0
  115. package/dist-boot/c-KFIO6LUW.mjs +1096 -0
  116. package/dist-boot/c-KIEMEFWW.mjs +478 -0
  117. package/dist-boot/c-KIVXWBYD.mjs +28 -0
  118. package/dist-boot/c-KP6CRIP4.mjs +580 -0
  119. package/dist-boot/c-L26VOJX4.mjs +11558 -0
  120. package/dist-boot/c-L5GHWG5G.mjs +5988 -0
  121. package/dist-boot/c-M7NSQAKK.mjs +353 -0
  122. package/dist-boot/c-MCEWOPBW.mjs +56 -0
  123. package/dist-boot/c-MGPIEG7I.mjs +20 -0
  124. package/dist-boot/c-NREXJV3M.mjs +393 -0
  125. package/dist-boot/c-O5PP6CTX.mjs +162 -0
  126. package/dist-boot/c-OBQDHSXM.mjs +1774 -0
  127. package/dist-boot/c-OLQHHDD4.mjs +21 -0
  128. package/dist-boot/c-OXW4JQQH.mjs +319 -0
  129. package/dist-boot/c-P3D7ZUWN.mjs +1288 -0
  130. package/dist-boot/c-P4PQZVV5.mjs +948 -0
  131. package/dist-boot/c-P63T3XL2.mjs +26373 -0
  132. package/dist-boot/c-P6N5DQGZ.mjs +194 -0
  133. package/dist-boot/c-P7MLKQFC.mjs +58 -0
  134. package/dist-boot/c-PB3PZJL5.mjs +1276 -0
  135. package/dist-boot/c-PTN4S6G2.mjs +1259 -0
  136. package/dist-boot/c-PYCE5J7U.mjs +1083 -0
  137. package/dist-boot/c-Q4HYCRLB.mjs +19410 -0
  138. package/dist-boot/c-QUXMETGG.mjs +68 -0
  139. package/dist-boot/c-RDMJZCOX.mjs +356 -0
  140. package/dist-boot/c-ROGJK76M.mjs +17 -0
  141. package/dist-boot/c-RQJJ26T4.mjs +708 -0
  142. package/dist-boot/c-RSKCUPJF.mjs +7559 -0
  143. package/dist-boot/c-RVJU4O6P.mjs +37 -0
  144. package/dist-boot/c-S2RVHR3M.mjs +165 -0
  145. package/dist-boot/c-SKMK3PEE.mjs +91120 -0
  146. package/dist-boot/c-TI7SM4EG.mjs +20 -0
  147. package/dist-boot/c-TILJ6GXD.mjs +1235 -0
  148. package/dist-boot/c-TT6BCUJD.mjs +114 -0
  149. package/dist-boot/c-U4ITOXAN.mjs +2107 -0
  150. package/dist-boot/c-UGERXVO2.mjs +7120 -0
  151. package/dist-boot/c-UPBH5AXY.mjs +1363 -0
  152. package/dist-boot/c-US2PUNZL.mjs +597 -0
  153. package/dist-boot/c-UU4WZPPE.mjs +20 -0
  154. package/dist-boot/c-UWVIYPQS.mjs +39 -0
  155. package/dist-boot/c-V4RHQBPQ.mjs +17683 -0
  156. package/dist-boot/c-V5MRVK47.mjs +351 -0
  157. package/dist-boot/c-V6CL266R.mjs +1755 -0
  158. package/dist-boot/c-VJTMFKYE.mjs +14975 -0
  159. package/dist-boot/c-VJTRUKIB.mjs +773 -0
  160. package/dist-boot/c-W4IFSHPW.mjs +43 -0
  161. package/dist-boot/c-WETGB2CF.mjs +113 -0
  162. package/dist-boot/c-WO3QSZUU.mjs +1337 -0
  163. package/dist-boot/c-WQLH73TY.mjs +242 -0
  164. package/dist-boot/c-XL735JW5.mjs +500 -0
  165. package/dist-boot/c-Y7HADL5B.mjs +1107 -0
  166. package/dist-boot/c-YGQHSVSK.mjs +41 -0
  167. package/dist-boot/c-YMP2AMEB.mjs +10350 -0
  168. package/dist-boot/c-YRDO2WEF.mjs +12012 -0
  169. package/dist-boot/c-YUSTRATJ.mjs +8 -0
  170. package/dist-boot/c-Z2262R22.mjs +2697 -0
  171. package/dist-boot/c-Z4ALQMJC.mjs +709 -0
  172. package/dist-boot/c-Z5ZUQVUY.mjs +62 -0
  173. package/dist-boot/c-ZDZUKXF7.mjs +874 -0
  174. package/dist-boot/c-ZJYLGIC3.mjs +32 -0
  175. package/dist-boot/c-ZNA5CDMI.mjs +77 -0
  176. package/dist-boot/c-ZSO6DI3M.mjs +204 -0
  177. package/dist-boot/c-ZWUVHKMK.mjs +100 -0
  178. package/dist-boot/c-ZY4MESEW.mjs +832 -0
  179. package/dist-boot/c-ZZ5REI4L.mjs +329 -0
  180. package/dist-boot/cli.mjs +51 -0
  181. package/dist-boot/ext-anthropic-attribution.mjs +207 -0
  182. package/dist-boot/ext-pi-background-tasks.mjs +7234 -0
  183. package/dist-boot/ext-pi-subagents.mjs +37 -0
  184. package/dist-boot/ext-privateer-account.mjs +4426 -0
  185. package/dist-boot/ext-privateer-brand.mjs +5274 -0
  186. package/dist-boot/ext-privateer-codemode.mjs +37 -0
  187. package/dist-boot/ext-privateer-computer.mjs +626 -0
  188. package/dist-boot/ext-privateer-connect.mjs +1862 -0
  189. package/dist-boot/ext-privateer-context.mjs +323 -0
  190. package/dist-boot/ext-privateer-desktop.mjs +92 -0
  191. package/dist-boot/ext-privateer-final-audit.mjs +48 -0
  192. package/dist-boot/ext-privateer-fresh.mjs +81 -0
  193. package/dist-boot/ext-privateer-gate.mjs +5959 -0
  194. package/dist-boot/ext-privateer-hints.mjs +236 -0
  195. package/dist-boot/ext-privateer-media.mjs +2626 -0
  196. package/dist-boot/ext-privateer-models.mjs +3397 -0
  197. package/dist-boot/ext-privateer-posture.mjs +3006 -0
  198. package/dist-boot/ext-privateer-privacy.mjs +4578 -0
  199. package/dist-boot/ext-privateer-recovery.mjs +287 -0
  200. package/dist-boot/ext-privateer-speak.mjs +4754 -0
  201. package/dist-boot/ext-privateer-terminals.mjs +725 -0
  202. package/dist-boot/ext-privateer-tools.mjs +528 -0
  203. package/dist-boot/ext-privateer-truncation.mjs +74 -0
  204. package/dist-boot/ext-privateer-update.mjs +210 -0
  205. package/dist-boot/ext-privateer-vision.mjs +148 -0
  206. package/dist-boot/ext-privateer-web.mjs +543 -0
  207. package/dist-boot/ext-rpiv-ask-user-question.mjs +710 -0
  208. package/dist-boot/manifest.json +9 -0
  209. package/extensions/privateer-brand.ts +3 -1
  210. package/extensions/privateer-context.ts +4 -2
  211. package/extensions/privateer-final-audit.ts +17 -0
  212. package/extensions/privateer-gate.ts +55 -9
  213. package/extensions/privateer-recovery.ts +175 -0
  214. package/extensions/privateer-web.ts +4 -4
  215. package/package.json +3 -1
  216. package/patches/@earendil-works+pi-coding-agent+1.3.0.patch +199 -2
  217. package/patches/pi-background-tasks+2.6.10.patch +91 -7
  218. package/src/cli/chat.ts +7 -1
  219. package/src/config/moatManifest.json +2 -0
  220. package/src/config/whatsNew.json +4 -4
  221. package/src/context.ts +33 -5
  222. package/src/engine/finalAudit.ts +38 -0
  223. package/src/engine/stallWatchdog.ts +8 -1
  224. package/src/providers/account.ts +34 -3
  225. package/src/remote/attentionPush.ts +40 -0
  226. package/src/remote/liveTaskSession.ts +7 -1
  227. package/src/remote/relayClient.ts +38 -4
  228. package/src/remote/remoteBridge.ts +17 -0
  229. package/src/remote/transcriptSnapshot.ts +104 -0
@@ -0,0 +1,376 @@
1
+ import{createRequire as __pvCR}from"node:module";import{fileURLToPath as __pvF}from"node:url";import{dirname as __pvD}from"node:path";const require=__pvCR(import.meta.url);const __pvUrl=(r)=>new URL(r,import.meta.url).href;const __pvFile=(r)=>__pvF(new URL(r,import.meta.url));
2
+ import {
3
+ __name
4
+ } from "./c-CN77DCGF.mjs";
5
+
6
+ // node_modules/pi-subagents/src/runs/shared/herdr-connection.js?ext=pi-subagents
7
+ import { spawn, spawnSync } from "node:child_process";
8
+ import * as fs from "node:fs";
9
+ import * as net from "node:net";
10
+ import * as os from "node:os";
11
+ import * as path from "node:path";
12
+ var MAX_DISCOVERY_BYTES = 256 * 1024;
13
+ var MAX_RPC_BYTES = 4 * 1024 * 1024;
14
+ var SUBSCRIPTION_ACK_TIMEOUT_MS = 15e3;
15
+ var HERDR_REMOTE_PATH = "$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";
16
+ var HERDR_SSH_BASE = ["-T", "-o", "BatchMode=yes", "-o", "NumberOfPasswordPrompts=0", "-o", "StrictHostKeyChecking=yes", "-o", "ConnectTimeout=10", "-o", "ConnectionAttempts=1", "-o", "ForwardAgent=no", "-o", "ExitOnForwardFailure=yes", "-o", "ServerAliveInterval=15", "-o", "ServerAliveCountMax=4", "-o", "SendEnv=-*", "-o", "SetEnv=PI_SUBAGENTS_SSH_GUARD="];
17
+ function hardenedSshEnv(source = process.env) {
18
+ return { PATH: process.platform === "win32" ? source.PATH : "/usr/bin:/bin:/usr/sbin:/sbin", ...source.SystemRoot ? { SystemRoot: source.SystemRoot } : {}, ...source.WINDIR ? { WINDIR: source.WINDIR } : {} };
19
+ }
20
+ __name(hardenedSshEnv, "hardenedSshEnv");
21
+ function herdrSshArgs(source = process.env) {
22
+ return [...HERDR_SSH_BASE, ...source.SSH_AUTH_SOCK ? ["-o", `IdentityAgent=${source.SSH_AUTH_SOCK}`] : []];
23
+ }
24
+ __name(herdrSshArgs, "herdrSshArgs");
25
+ var HerdrRpcError = class extends Error {
26
+ static {
27
+ __name(this, "HerdrRpcError");
28
+ }
29
+ code;
30
+ requestId;
31
+ constructor(message, requestId, code) {
32
+ super(message);
33
+ this.name = "HerdrRpcError";
34
+ this.requestId = requestId;
35
+ this.code = code;
36
+ }
37
+ };
38
+ var HerdrTransportError = class extends Error {
39
+ static {
40
+ __name(this, "HerdrTransportError");
41
+ }
42
+ constructor(message, options) {
43
+ super(message, options);
44
+ this.name = "HerdrTransportError";
45
+ }
46
+ };
47
+ function decodeHerdrJsonLine(line) {
48
+ try {
49
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(line));
50
+ } catch {
51
+ throw new Error("Herdr emitted malformed JSON or UTF-8.");
52
+ }
53
+ }
54
+ __name(decodeHerdrJsonLine, "decodeHerdrJsonLine");
55
+ function shellQuoteRemote(value) {
56
+ return `'${value.replaceAll("'", "'\\''")}'`;
57
+ }
58
+ __name(shellQuoteRemote, "shellQuoteRemote");
59
+ function remoteShellCommand(script, args = []) {
60
+ return `sh -c ${shellQuoteRemote(`PATH="${HERDR_REMOTE_PATH}"; export PATH; ${script}`)} sh${args.map((arg) => ` ${shellQuoteRemote(arg)}`).join("")}`;
61
+ }
62
+ __name(remoteShellCommand, "remoteShellCommand");
63
+ function canonicalHerdrSession(session) {
64
+ return session && session !== "default" ? session : null;
65
+ }
66
+ __name(canonicalHerdrSession, "canonicalHerdrSession");
67
+ function sshEnvCommand(session, command) {
68
+ const selected = canonicalHerdrSession(session), assignment = selected ? ` HERDR_SESSION=${shellQuoteRemote(selected)}` : "";
69
+ return `/usr/bin/env -u HERDR_SOCKET_PATH -u HERDR_SESSION${assignment} ${remoteShellCommand(command)}`;
70
+ }
71
+ __name(sshEnvCommand, "sshEnvCommand");
72
+ function runHerdrRemoteCommand(machine, command, options = {}) {
73
+ return spawnSync(options.sshBin ?? "ssh", [...herdrSshArgs(options.env), machine.target, command], { encoding: "utf8", env: hardenedSshEnv(options.env), timeout: options.timeout ?? 15e3, maxBuffer: options.maxBuffer ?? MAX_DISCOVERY_BYTES, windowsHide: true });
74
+ }
75
+ __name(runHerdrRemoteCommand, "runHerdrRemoteCommand");
76
+ function runHerdrRemoteCommandAsync(machine, command, options = {}) {
77
+ return new Promise((resolve) => {
78
+ const child = spawn(options.sshBin ?? "ssh", [...herdrSshArgs(options.env), machine.target, command], { env: hardenedSshEnv(options.env), stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
79
+ const stdout = [], stderr = [], maxBuffer = options.maxBuffer ?? MAX_DISCOVERY_BYTES;
80
+ let stdoutBytes = 0, stderrBytes = 0, error, settled = false, escalation;
81
+ const finish = /* @__PURE__ */ __name((status, spawnError = error) => {
82
+ if (settled)
83
+ return;
84
+ settled = true;
85
+ clearTimeout(timer);
86
+ if (escalation)
87
+ clearTimeout(escalation);
88
+ resolve({ status, stdout: Buffer.concat(stdout).toString("utf8"), stderr: Buffer.concat(stderr).toString("utf8"), ...spawnError ? { error: spawnError } : {} });
89
+ }, "finish");
90
+ const terminate = /* @__PURE__ */ __name(() => {
91
+ child.kill("SIGTERM");
92
+ escalation ??= setTimeout(() => {
93
+ if (!settled) {
94
+ child.kill("SIGKILL");
95
+ finish(child.exitCode ?? null);
96
+ }
97
+ }, 1e3);
98
+ escalation.unref?.();
99
+ }, "terminate");
100
+ const collect = /* @__PURE__ */ __name((target, stream) => (chunk) => {
101
+ const bytes = stream === "stdout" ? stdoutBytes += chunk.byteLength : stderrBytes += chunk.byteLength;
102
+ if (bytes > maxBuffer) {
103
+ error ??= new Error(`${stream} maxBuffer length exceeded`);
104
+ terminate();
105
+ } else
106
+ target.push(chunk);
107
+ }, "collect");
108
+ child.stdout.on("data", collect(stdout, "stdout"));
109
+ child.stderr.on("data", collect(stderr, "stderr"));
110
+ child.once("error", (spawnError) => finish(null, spawnError));
111
+ child.once("close", (status) => finish(status));
112
+ const timer = setTimeout(terminate, options.timeout ?? 15e3);
113
+ timer.unref?.();
114
+ });
115
+ }
116
+ __name(runHerdrRemoteCommandAsync, "runHerdrRemoteCommandAsync");
117
+ function parseHerdrEndpoint(value, expectedSession) {
118
+ let parsed;
119
+ try {
120
+ parsed = JSON.parse(value);
121
+ } catch {
122
+ throw new Error("Remote Herdr endpoint discovery returned malformed JSON.");
123
+ }
124
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
125
+ throw new Error("Remote Herdr endpoint discovery returned no endpoint.");
126
+ const p = parsed;
127
+ if (typeof p.socket !== "string" || !path.posix.isAbsolute(p.socket) || typeof p.version !== "string" || typeof p.protocol !== "number")
128
+ throw new Error("Remote Herdr endpoint discovery returned incomplete identity.");
129
+ const session = canonicalHerdrSession(typeof p.session === "string" ? p.session : null), expected = canonicalHerdrSession(expectedSession);
130
+ if (expected !== session)
131
+ throw new Error(`Remote Herdr session identity mismatch: expected ${expected ?? "default"}, received ${session ?? "default"}.`);
132
+ if (p.running !== true || p.compatible !== true || p.endpoint_compatible === false)
133
+ throw new Error("The selected remote Herdr session is stopped or incompatible.");
134
+ return { socket: p.socket, session, version: p.version, protocol: p.protocol, compatible: true, running: true };
135
+ }
136
+ __name(parseHerdrEndpoint, "parseHerdrEndpoint");
137
+ async function discoverHerdrEndpoint(machine, options = {}) {
138
+ const discovery = 'herdr_path=$(command -v herdr) || exit 127; case "$herdr_path" in /*/herdr) ;; *) exit 126;; esac; exec "$herdr_path" status server --json';
139
+ const result = await runHerdrRemoteCommandAsync(machine, sshEnvCommand(machine.session, discovery), { ...options, timeout: 15e3, maxBuffer: MAX_DISCOVERY_BYTES });
140
+ if (result.error)
141
+ throw new Error(`Remote Herdr discovery failed: ${result.error.message}`);
142
+ if (result.status !== 0)
143
+ throw new Error(`Remote Herdr discovery failed with code ${result.status}: ${(result.stderr || result.stdout).trim()}`);
144
+ return parseHerdrEndpoint(result.stdout, machine.session);
145
+ }
146
+ __name(discoverHerdrEndpoint, "discoverHerdrEndpoint");
147
+ var SocketRpcClient = class {
148
+ static {
149
+ __name(this, "SocketRpcClient");
150
+ }
151
+ #socketPath;
152
+ #subscriptionAckTimeoutMs;
153
+ #next = 0;
154
+ constructor(socketPath, subscriptionAckTimeoutMs = SUBSCRIPTION_ACK_TIMEOUT_MS) {
155
+ this.#socketPath = socketPath;
156
+ this.#subscriptionAckTimeoutMs = subscriptionAckTimeoutMs;
157
+ }
158
+ call(method, params = {}, timeoutMs = 15e3) {
159
+ return new Promise((resolve, reject) => {
160
+ const socket = net.createConnection(this.#socketPath);
161
+ let bytes = 0;
162
+ let data = Buffer.alloc(0);
163
+ let finished = false;
164
+ const id = String(++this.#next);
165
+ const timer = setTimeout(() => finish(new HerdrTransportError(`Herdr RPC '${method}' timed out.`)), timeoutMs);
166
+ timer.unref?.();
167
+ const finish = /* @__PURE__ */ __name((error, value) => {
168
+ if (finished)
169
+ return;
170
+ finished = true;
171
+ clearTimeout(timer);
172
+ socket.destroy();
173
+ error ? reject(error) : resolve(value);
174
+ }, "finish");
175
+ socket.on("connect", () => socket.write(`${JSON.stringify({ id, method, params })}
176
+ `));
177
+ socket.on("data", (chunk) => {
178
+ bytes += chunk.byteLength;
179
+ if (bytes > MAX_RPC_BYTES) {
180
+ finish(new Error("Herdr RPC response exceeded its byte bound."));
181
+ return;
182
+ }
183
+ data = Buffer.concat([data, chunk]);
184
+ const newline = data.indexOf(10);
185
+ if (newline < 0)
186
+ return;
187
+ let frame;
188
+ try {
189
+ frame = decodeHerdrJsonLine(data.subarray(0, newline));
190
+ } catch {
191
+ finish(new Error("Herdr RPC returned malformed JSON or UTF-8."));
192
+ return;
193
+ }
194
+ const record = frame;
195
+ if (record.id !== id) {
196
+ finish(new Error("Herdr RPC response identity mismatch."));
197
+ return;
198
+ }
199
+ if (record.error)
200
+ finish(new HerdrRpcError(String(record.error.message ?? "Herdr RPC failed."), id, typeof record.error.code === "string" ? record.error.code : void 0));
201
+ else
202
+ finish(void 0, record.result);
203
+ });
204
+ socket.on("error", (error) => finish(new HerdrTransportError(error.message, { cause: error })));
205
+ socket.on("close", () => finish(new HerdrTransportError(`Herdr RPC '${method}' ended before a response.`)));
206
+ });
207
+ }
208
+ async subscribe(subscriptions, listener, onDisconnect) {
209
+ const socket = net.createConnection(this.#socketPath);
210
+ const id = String(++this.#next);
211
+ let buffer = Buffer.alloc(0), bytes = 0, acknowledged = false, intentional = false, notified = false, settled = false;
212
+ let resolveAck, rejectAck;
213
+ const acknowledgement = new Promise((resolve, reject) => {
214
+ resolveAck = resolve;
215
+ rejectAck = reject;
216
+ });
217
+ const failHandshake = /* @__PURE__ */ __name((error) => {
218
+ if (settled)
219
+ return;
220
+ settled = true;
221
+ clearTimeout(timer);
222
+ socket.destroy();
223
+ rejectAck(error);
224
+ }, "failHandshake");
225
+ const disconnect = /* @__PURE__ */ __name((error) => {
226
+ if (intentional || notified)
227
+ return;
228
+ notified = true;
229
+ if (!acknowledged)
230
+ failHandshake(error);
231
+ else
232
+ onDisconnect?.(error);
233
+ }, "disconnect");
234
+ const timer = setTimeout(() => failHandshake(new Error("Herdr subscription acknowledgement timed out.")), this.#subscriptionAckTimeoutMs);
235
+ timer.unref?.();
236
+ socket.on("data", (chunk) => {
237
+ bytes += chunk.byteLength;
238
+ if (bytes > (acknowledged ? MAX_RPC_BYTES * 32 : MAX_RPC_BYTES)) {
239
+ disconnect(new Error("Herdr subscription exceeded its byte bound."));
240
+ socket.destroy();
241
+ return;
242
+ }
243
+ buffer = Buffer.concat([buffer, chunk]);
244
+ for (; ; ) {
245
+ const i = buffer.indexOf(10);
246
+ if (i < 0)
247
+ break;
248
+ const line = buffer.subarray(0, i);
249
+ buffer = buffer.subarray(i + 1);
250
+ let value;
251
+ try {
252
+ value = decodeHerdrJsonLine(line);
253
+ } catch {
254
+ disconnect(new Error("Herdr subscription emitted malformed JSON or UTF-8."));
255
+ socket.destroy();
256
+ return;
257
+ }
258
+ const record = value;
259
+ if (!acknowledged) {
260
+ if (record.id === id) {
261
+ if (record.error) {
262
+ failHandshake(new HerdrRpcError(String(record.error.message ?? "Herdr subscription failed."), id, typeof record.error.code === "string" ? record.error.code : void 0));
263
+ return;
264
+ }
265
+ if (record.result?.type !== "subscription_started") {
266
+ failHandshake(new Error("Herdr subscription returned an invalid acknowledgement."));
267
+ return;
268
+ }
269
+ acknowledged = true;
270
+ settled = true;
271
+ clearTimeout(timer);
272
+ resolveAck();
273
+ continue;
274
+ }
275
+ if (record.id === "" && record.error && record.error.code === "invalid_request") {
276
+ failHandshake(new HerdrRpcError(String(record.error.message ?? "Herdr subscription request was invalid."), "", "invalid_request"));
277
+ return;
278
+ }
279
+ failHandshake(new Error("Herdr subscription emitted an event before acknowledgement."));
280
+ return;
281
+ }
282
+ if (record.error) {
283
+ disconnect(new HerdrRpcError(String(record.error.message ?? "Herdr subscription failed."), typeof record.id === "string" ? record.id : "", typeof record.error.code === "string" ? record.error.code : void 0));
284
+ socket.destroy();
285
+ return;
286
+ }
287
+ listener(value);
288
+ }
289
+ });
290
+ socket.on("error", (error) => disconnect(error));
291
+ socket.on("close", () => disconnect(new Error("Herdr subscription connection was lost.")));
292
+ socket.on("connect", () => socket.write(`${JSON.stringify({ id, method: "events.subscribe", params: { subscriptions } })}
293
+ `));
294
+ await acknowledgement;
295
+ return () => {
296
+ intentional = true;
297
+ clearTimeout(timer);
298
+ socket.destroy();
299
+ };
300
+ }
301
+ };
302
+ async function waitForSocket(socketPath, child) {
303
+ for (let attempt = 0; attempt < 100; attempt++) {
304
+ if (child.exitCode !== null)
305
+ throw new Error(`SSH StreamLocal forwarding exited with code ${child.exitCode}.`);
306
+ try {
307
+ const stat = fs.lstatSync(socketPath);
308
+ if (stat.isSocket()) {
309
+ fs.chmodSync(socketPath, 384);
310
+ return;
311
+ }
312
+ } catch {
313
+ }
314
+ await new Promise((resolve) => setTimeout(resolve, 25));
315
+ }
316
+ throw new Error("SSH StreamLocal forwarding did not create its local socket.");
317
+ }
318
+ __name(waitForSocket, "waitForSocket");
319
+ async function terminateChild(child) {
320
+ const wait = /* @__PURE__ */ __name((ms) => child.exitCode !== null || child.signalCode !== null ? Promise.resolve() : Promise.race([new Promise((resolve) => child.once("exit", () => resolve())), new Promise((resolve) => setTimeout(resolve, ms))]), "wait");
321
+ if (child.exitCode === null && child.signalCode === null)
322
+ child.kill("SIGTERM");
323
+ await wait(1e3);
324
+ if (child.exitCode === null && child.signalCode === null) {
325
+ child.kill("SIGKILL");
326
+ await wait(1e3);
327
+ }
328
+ }
329
+ __name(terminateChild, "terminateChild");
330
+ async function connectHerdrMachine(machine, options = {}) {
331
+ if (process.platform === "win32")
332
+ throw new Error("Pane-native Herdr placement requires OpenSSH StreamLocal forwarding and is not supported on Windows.");
333
+ const endpoint = await discoverHerdrEndpoint(machine, options);
334
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-herdr-"));
335
+ fs.chmodSync(dir, 448);
336
+ const children = /* @__PURE__ */ new Set();
337
+ const forward = /* @__PURE__ */ __name(async (remotePath, name) => {
338
+ if (!path.posix.isAbsolute(remotePath))
339
+ throw new Error("Remote socket path must be absolute.");
340
+ const local = path.join(dir, `${name}.sock`);
341
+ const child = spawn(options.sshBin ?? "ssh", [...herdrSshArgs(options.env), "-N", "-o", "StreamLocalBindUnlink=yes", "-L", `${local}:${remotePath}`, machine.target], { env: hardenedSshEnv(options.env), stdio: "ignore", windowsHide: true });
342
+ children.add(child);
343
+ const stop = /* @__PURE__ */ __name(async () => {
344
+ await terminateChild(child);
345
+ children.delete(child);
346
+ try {
347
+ fs.rmSync(local, { force: true });
348
+ } catch {
349
+ }
350
+ }, "stop");
351
+ try {
352
+ await waitForSocket(local, child);
353
+ } catch (error) {
354
+ await stop();
355
+ throw error;
356
+ }
357
+ return { socketPath: local, close: stop };
358
+ }, "forward");
359
+ const primary = await forward(endpoint.socket, "herdr").catch((error) => {
360
+ fs.rmSync(dir, { recursive: true, force: true });
361
+ throw error;
362
+ });
363
+ return { endpoint, socketPath: primary.socketPath, client: new SocketRpcClient(primary.socketPath), forwardRemoteSocket: forward, close: /* @__PURE__ */ __name(async () => {
364
+ await Promise.all([...children].map(terminateChild));
365
+ children.clear();
366
+ fs.rmSync(dir, { recursive: true, force: true });
367
+ }, "close") };
368
+ }
369
+ __name(connectHerdrMachine, "connectHerdrMachine");
370
+
371
+ export {
372
+ remoteShellCommand,
373
+ runHerdrRemoteCommand,
374
+ runHerdrRemoteCommandAsync,
375
+ connectHerdrMachine
376
+ };