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,1096 @@
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
+ buildDelegateChildArgv,
4
+ delegateChildEnv,
5
+ ensureDelegateChildSessionDir,
6
+ preflightDelegateLaunch,
7
+ resolveDelegateChildExtensionPath
8
+ } from "./c-C5NK6UYV.mjs";
9
+ import {
10
+ DELEGATE_INLINE_ANSWER_BYTES,
11
+ DELEGATE_MANIFEST_SCHEMA_VERSION,
12
+ DELEGATE_RECEIPT_SCHEMA_VERSION,
13
+ DELEGATE_RESULT_PACKAGE_SCHEMA_VERSION,
14
+ DelegateError
15
+ } from "./c-IFSP3R4D.mjs";
16
+ import {
17
+ canonicalJson
18
+ } from "./c-KIVXWBYD.mjs";
19
+ import {
20
+ resolveAnthropicAttributionExtensionPath
21
+ } from "./c-BFW6CDVL.mjs";
22
+ import {
23
+ replaceFileDurable
24
+ } from "./c-DR7XQI32.mjs";
25
+ import {
26
+ sanitizePathSegment
27
+ } from "./c-I3C6LBW4.mjs";
28
+ import {
29
+ __name
30
+ } from "./c-CN77DCGF.mjs";
31
+
32
+ // node_modules/pi-background-tasks/src/core/delegate/runner.ts?ext=pi-background-tasks
33
+ import { existsSync as existsSync2 } from "node:fs";
34
+ import { readFile as readFile2, rmdir } from "node:fs/promises";
35
+ import { dirname, join as join2 } from "node:path";
36
+
37
+ // node_modules/pi-background-tasks/src/core/delegate/artifacts.ts?ext=pi-background-tasks
38
+ import { createHash as createHash2 } from "node:crypto";
39
+ import { existsSync } from "node:fs";
40
+ import { chmod, mkdir, open, readFile, rename, rm } from "node:fs/promises";
41
+ import { basename, isAbsolute, join, relative, sep } from "node:path";
42
+
43
+ // node_modules/pi-background-tasks/src/core/delegate/result-package.ts?ext=pi-background-tasks
44
+ import { createHash } from "node:crypto";
45
+ var DELEGATE_RESULT_PACKAGE_FILENAME = "result.json";
46
+ function sha256Bytes(bytes) {
47
+ return createHash("sha256").update(bytes).digest("hex");
48
+ }
49
+ __name(sha256Bytes, "sha256Bytes");
50
+ function isRecord(value) {
51
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52
+ }
53
+ __name(isRecord, "isRecord");
54
+ function fail(message, code, taskId) {
55
+ const details = { code, childCreated: true };
56
+ if (taskId !== void 0) details.taskId = taskId;
57
+ throw new DelegateError(message, details);
58
+ }
59
+ __name(fail, "fail");
60
+ function serializeDelegateResultPackage(pkg) {
61
+ return `${canonicalJson(pkg)}
62
+ `;
63
+ }
64
+ __name(serializeDelegateResultPackage, "serializeDelegateResultPackage");
65
+ function requireString(record, key, taskId) {
66
+ const value = record[key];
67
+ if (typeof value !== "string")
68
+ fail(`delegate result package field ${key} must be a string`, "child_result_invalid", taskId);
69
+ return value;
70
+ }
71
+ __name(requireString, "requireString");
72
+ function requireInteger(record, key, taskId) {
73
+ const value = record[key];
74
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
75
+ fail(
76
+ `delegate result package field ${key} must be a non-negative safe integer`,
77
+ "child_result_invalid",
78
+ taskId
79
+ );
80
+ return value;
81
+ }
82
+ __name(requireInteger, "requireInteger");
83
+ var SHA256_PATTERN = /^[0-9a-f]{64}$/;
84
+ function requireSha256(record, key, taskId) {
85
+ const value = requireString(record, key, taskId);
86
+ if (!SHA256_PATTERN.test(value))
87
+ fail(
88
+ `delegate result package field ${key} must be a lowercase SHA-256 digest`,
89
+ "child_result_invalid",
90
+ taskId
91
+ );
92
+ return value;
93
+ }
94
+ __name(requireSha256, "requireSha256");
95
+ function parseUsage(value, taskId) {
96
+ if (!isRecord(value))
97
+ fail("delegate result package usage must be an object", "child_result_invalid", taskId);
98
+ const status = value["status"];
99
+ if (status === "unavailable") {
100
+ const reason = value["reason"];
101
+ if (typeof reason !== "string")
102
+ fail(
103
+ "delegate result package unavailable usage must state a reason",
104
+ "child_result_invalid",
105
+ taskId
106
+ );
107
+ return { status: "unavailable", reason };
108
+ }
109
+ if (status !== "observed")
110
+ fail(
111
+ "delegate result package usage status must be observed or unavailable",
112
+ "child_result_invalid",
113
+ taskId
114
+ );
115
+ const usage = value["usage"];
116
+ if (!isRecord(usage))
117
+ fail(
118
+ "delegate result package observed usage must be an object",
119
+ "child_result_invalid",
120
+ taskId
121
+ );
122
+ const cost = usage["cost"];
123
+ if (!isRecord(cost))
124
+ fail(
125
+ "delegate result package observed usage must carry a complete cost breakdown",
126
+ "child_result_invalid",
127
+ taskId
128
+ );
129
+ const number = /* @__PURE__ */ __name((record, key) => {
130
+ const raw = record[key];
131
+ if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0)
132
+ fail(
133
+ `delegate result package usage.${key} must be a non-negative finite number`,
134
+ "child_result_invalid",
135
+ taskId
136
+ );
137
+ return raw;
138
+ }, "number");
139
+ return {
140
+ status: "observed",
141
+ usage: {
142
+ input: number(usage, "input"),
143
+ output: number(usage, "output"),
144
+ cacheRead: number(usage, "cacheRead"),
145
+ cacheWrite: number(usage, "cacheWrite"),
146
+ totalTokens: number(usage, "totalTokens"),
147
+ cost: {
148
+ input: number(cost, "input"),
149
+ output: number(cost, "output"),
150
+ cacheRead: number(cost, "cacheRead"),
151
+ cacheWrite: number(cost, "cacheWrite"),
152
+ total: number(cost, "total")
153
+ }
154
+ }
155
+ };
156
+ }
157
+ __name(parseUsage, "parseUsage");
158
+ function parseAttestations(value, taskId) {
159
+ if (!Array.isArray(value))
160
+ fail(
161
+ "delegate result package route_attestations must be an array",
162
+ "route_attestation_missing",
163
+ taskId
164
+ );
165
+ if (value.length === 0)
166
+ fail(
167
+ "delegate result package carries no route attestation, so the route the child actually used cannot be proven",
168
+ "route_attestation_missing",
169
+ taskId
170
+ );
171
+ return value.map((entry) => {
172
+ if (!isRecord(entry))
173
+ fail("delegate route attestation must be an object", "route_attestation_missing", taskId);
174
+ return {
175
+ provider: requireString(entry, "provider", taskId),
176
+ model: requireString(entry, "model", taskId),
177
+ stop_reason: requireString(entry, "stop_reason", taskId)
178
+ };
179
+ });
180
+ }
181
+ __name(parseAttestations, "parseAttestations");
182
+ function parseSpillContentFormat(value, taskId) {
183
+ if (value === void 0) return void 0;
184
+ if (value !== "single_text_utf8" && value !== "tool_result_content_json_v1" && value !== "opaque_bytes") {
185
+ fail("delegate spill receipt content_format is invalid", "child_result_invalid", taskId);
186
+ }
187
+ return value;
188
+ }
189
+ __name(parseSpillContentFormat, "parseSpillContentFormat");
190
+ function parseSpillReceipts(value, taskId) {
191
+ if (!Array.isArray(value))
192
+ fail(
193
+ "delegate result package spilled_artifacts must be an array",
194
+ "child_result_invalid",
195
+ taskId
196
+ );
197
+ return value.map((entry) => {
198
+ if (!isRecord(entry))
199
+ fail("delegate spill receipt must be an object", "child_result_invalid", taskId);
200
+ if (entry["schema_version"] !== DELEGATE_RECEIPT_SCHEMA_VERSION)
201
+ fail("delegate spill receipt schema_version mismatch", "child_result_invalid", taskId);
202
+ return {
203
+ schema_version: DELEGATE_RECEIPT_SCHEMA_VERSION,
204
+ artifact: requireString(entry, "artifact", taskId),
205
+ tool_name: requireString(entry, "tool_name", taskId),
206
+ tool_call_id: requireString(entry, "tool_call_id", taskId),
207
+ turn_sequence: requireInteger(entry, "turn_sequence", taskId),
208
+ source_call_index: requireInteger(entry, "source_call_index", taskId),
209
+ byte_length: requireInteger(entry, "byte_length", taskId),
210
+ sha256: requireSha256(entry, "sha256", taskId),
211
+ content_format: parseSpillContentFormat(entry["content_format"], taskId)
212
+ };
213
+ });
214
+ }
215
+ __name(parseSpillReceipts, "parseSpillReceipts");
216
+ function verifyDelegateResultPackage(raw, expected) {
217
+ let parsed;
218
+ try {
219
+ parsed = JSON.parse(raw);
220
+ } catch (error) {
221
+ fail(
222
+ `delegate result package is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
223
+ "child_result_invalid",
224
+ expected.taskId
225
+ );
226
+ }
227
+ if (!isRecord(parsed))
228
+ fail("delegate result package must be a JSON object", "child_result_invalid", expected.taskId);
229
+ if (parsed["schema_version"] !== DELEGATE_RESULT_PACKAGE_SCHEMA_VERSION)
230
+ fail(
231
+ `delegate result package schema_version must be ${DELEGATE_RESULT_PACKAGE_SCHEMA_VERSION}`,
232
+ "child_result_invalid",
233
+ expected.taskId
234
+ );
235
+ const taskId = requireString(parsed, "task_id", expected.taskId);
236
+ const launchNonce = requireString(parsed, "launch_nonce", expected.taskId);
237
+ if (taskId !== expected.taskId || launchNonce !== expected.launchNonce)
238
+ fail(
239
+ "delegate result package identity does not match the launched task; a stale or foreign package is never accepted",
240
+ "child_result_invalid",
241
+ expected.taskId
242
+ );
243
+ const seedSha256 = requireSha256(parsed, "seed_sha256", expected.taskId);
244
+ if (seedSha256 !== expected.seedSha256)
245
+ fail(
246
+ `delegate result package was produced from a different seed: expected ${expected.seedSha256}, package declares ${seedSha256}`,
247
+ "seed_hash_mismatch",
248
+ expected.taskId
249
+ );
250
+ const routeRecord = parsed["route"];
251
+ if (!isRecord(routeRecord))
252
+ fail(
253
+ "delegate result package route must be an object",
254
+ "child_result_invalid",
255
+ expected.taskId
256
+ );
257
+ const provider = requireString(routeRecord, "provider", expected.taskId);
258
+ const model = requireString(routeRecord, "model", expected.taskId);
259
+ if (provider !== expected.route.provider || model !== expected.route.model)
260
+ fail(
261
+ `delegate result package route ${provider}/${model} does not match the pinned route ${expected.route.provider}/${expected.route.model}`,
262
+ "route_mismatch",
263
+ expected.taskId
264
+ );
265
+ const attestations = parseAttestations(parsed["route_attestations"], expected.taskId);
266
+ for (const attestation of attestations) {
267
+ if (attestation.provider !== expected.route.provider || attestation.model !== expected.route.model)
268
+ fail(
269
+ `delegate child produced an assistant message on ${attestation.provider}/${attestation.model}, but the pinned route is ${expected.route.provider}/${expected.route.model}`,
270
+ "route_mismatch",
271
+ expected.taskId
272
+ );
273
+ }
274
+ const answerRecord = parsed["answer"];
275
+ if (!isRecord(answerRecord))
276
+ fail(
277
+ "delegate result package answer must be an object",
278
+ "child_result_invalid",
279
+ expected.taskId
280
+ );
281
+ if (answerRecord["encoding"] !== "utf-8")
282
+ fail(
283
+ "delegate result package answer encoding must be utf-8",
284
+ "child_result_encoding_invalid",
285
+ expected.taskId
286
+ );
287
+ const declaredLength = requireInteger(answerRecord, "byte_length", expected.taskId);
288
+ const declaredSha = requireSha256(answerRecord, "sha256", expected.taskId);
289
+ const blocksValue = answerRecord["blocks"];
290
+ if (!Array.isArray(blocksValue))
291
+ fail(
292
+ "delegate result package answer blocks must be an array",
293
+ "child_result_invalid",
294
+ expected.taskId
295
+ );
296
+ const blocks = [];
297
+ const buffers = [];
298
+ for (const [index, entry] of blocksValue.entries()) {
299
+ if (!isRecord(entry))
300
+ fail(
301
+ `delegate answer block ${String(index)} must be an object`,
302
+ "child_result_invalid",
303
+ expected.taskId
304
+ );
305
+ if (entry["kind"] !== "text")
306
+ fail(
307
+ `delegate answer block ${String(index)} kind must be text`,
308
+ "child_result_invalid",
309
+ expected.taskId
310
+ );
311
+ const byteLength = requireInteger(entry, "byte_length", expected.taskId);
312
+ const sha = requireSha256(entry, "sha256", expected.taskId);
313
+ const dataBase64 = requireString(entry, "data_base64", expected.taskId);
314
+ const bytes = Buffer.from(dataBase64, "base64");
315
+ if (bytes.toString("base64") !== dataBase64)
316
+ fail(
317
+ `delegate answer block ${String(index)} is not strict base64`,
318
+ "child_result_invalid",
319
+ expected.taskId
320
+ );
321
+ if (bytes.length !== byteLength)
322
+ fail(
323
+ `delegate answer block ${String(index)} declares ${String(byteLength)} bytes but carries ${String(bytes.length)}`,
324
+ "answer_hash_mismatch",
325
+ expected.taskId
326
+ );
327
+ const actual = sha256Bytes(bytes);
328
+ if (actual !== sha)
329
+ fail(
330
+ `delegate answer block ${String(index)} hash mismatch: declared ${sha}, computed ${actual}`,
331
+ "answer_hash_mismatch",
332
+ expected.taskId
333
+ );
334
+ blocks.push({ kind: "text", byte_length: byteLength, sha256: sha, data_base64: dataBase64 });
335
+ buffers.push(bytes);
336
+ }
337
+ const aggregate = Buffer.concat(buffers);
338
+ if (aggregate.length !== declaredLength)
339
+ fail(
340
+ `delegate answer declares ${String(declaredLength)} bytes but its blocks total ${String(aggregate.length)}`,
341
+ "answer_hash_mismatch",
342
+ expected.taskId
343
+ );
344
+ const aggregateSha = sha256Bytes(aggregate);
345
+ if (aggregateSha !== declaredSha)
346
+ fail(
347
+ `delegate answer aggregate hash mismatch: declared ${declaredSha}, computed ${aggregateSha}`,
348
+ "answer_hash_mismatch",
349
+ expected.taskId
350
+ );
351
+ const answer = aggregate.toString("utf8");
352
+ if (!Buffer.from(answer, "utf8").equals(aggregate))
353
+ fail(
354
+ "delegate answer bytes are not well-formed UTF-8; they are preserved on disk and never returned with substitution characters",
355
+ "child_result_encoding_invalid",
356
+ expected.taskId
357
+ );
358
+ return {
359
+ package: {
360
+ schema_version: DELEGATE_RESULT_PACKAGE_SCHEMA_VERSION,
361
+ task_id: taskId,
362
+ launch_nonce: launchNonce,
363
+ seed_sha256: seedSha256,
364
+ directive_sha256: requireSha256(parsed, "directive_sha256", expected.taskId),
365
+ route: { provider, model },
366
+ route_attestations: attestations,
367
+ stop_reason: requireString(parsed, "stop_reason", expected.taskId),
368
+ turns: requireInteger(parsed, "turns", expected.taskId),
369
+ tool_calls: requireInteger(parsed, "tool_calls", expected.taskId),
370
+ usage: parseUsage(parsed["usage"], expected.taskId),
371
+ answer: {
372
+ encoding: "utf-8",
373
+ byte_length: declaredLength,
374
+ sha256: declaredSha,
375
+ blocks
376
+ },
377
+ spilled_artifacts: parseSpillReceipts(parsed["spilled_artifacts"], expected.taskId)
378
+ },
379
+ answer,
380
+ answerBytes: aggregate
381
+ };
382
+ }
383
+ __name(verifyDelegateResultPackage, "verifyDelegateResultPackage");
384
+
385
+ // node_modules/pi-background-tasks/src/core/delegate/artifacts.ts?ext=pi-background-tasks
386
+ var DELEGATE_ARTIFACT_NAMES = {
387
+ seed: "seed.json",
388
+ ledger: "context-omission-ledger.json",
389
+ budgetPlan: "budget-plan.json",
390
+ manifest: "manifest.json",
391
+ outcome: "outcome.json",
392
+ result: DELEGATE_RESULT_PACKAGE_FILENAME,
393
+ childPrompt: "child-prompt.txt",
394
+ runtimeBudget: "runtime-budget.json",
395
+ error: "error.json"
396
+ };
397
+ var DELEGATE_SPILL_DIRNAME = "spill";
398
+ function sha256Bytes2(bytes) {
399
+ return createHash2("sha256").update(bytes).digest("hex");
400
+ }
401
+ __name(sha256Bytes2, "sha256Bytes");
402
+ function pathInside(parent, child) {
403
+ const rel = relative(parent, child);
404
+ return rel === "" || !rel.startsWith("..") && !isAbsolute(rel) && !rel.split(sep).includes("..");
405
+ }
406
+ __name(pathInside, "pathInside");
407
+ function artifactError(message, cause) {
408
+ const suffix = cause === void 0 ? "" : `: ${cause instanceof Error ? cause.message : String(cause)}`;
409
+ return new DelegateError(`${message}${suffix}`, {
410
+ code: "artifact_error",
411
+ childCreated: true,
412
+ remediation: [
413
+ "The delegate artifact directory could not be written. Check free disk space and directory permissions."
414
+ ]
415
+ });
416
+ }
417
+ __name(artifactError, "artifactError");
418
+ var DelegateArtifactStore = class _DelegateArtifactStore {
419
+ static {
420
+ __name(this, "DelegateArtifactStore");
421
+ }
422
+ rootAbs;
423
+ rootDisplay;
424
+ spillAbs;
425
+ now;
426
+ manifest;
427
+ writeChain = Promise.resolve();
428
+ totalSpilledBytes = 0;
429
+ constructor(rootAbs, rootDisplay, now, manifest) {
430
+ this.rootAbs = rootAbs;
431
+ this.rootDisplay = rootDisplay;
432
+ this.spillAbs = join(rootAbs, DELEGATE_SPILL_DIRNAME);
433
+ this.now = now;
434
+ this.manifest = manifest;
435
+ }
436
+ /**
437
+ * Create the artifact root with exclusive semantics.
438
+ *
439
+ * The directory name embeds the task id, which is cryptographically random, so
440
+ * two delegates launched in the same assistant message cannot collide. The
441
+ * directory is created with `recursive: false` so a pre-existing directory is
442
+ * a loud failure rather than a silent reuse.
443
+ */
444
+ static async create(options) {
445
+ const sessionSegment = sanitizePathSegment(
446
+ options.sessionId ?? `session-${String(process.pid)}`
447
+ );
448
+ const runDirName = `${sessionSegment}-${String(process.pid)}`;
449
+ const parentAbs = join(options.cwd, ".pi", "delegate", runDirName);
450
+ const rootAbs = join(parentAbs, options.taskId);
451
+ const rootDisplay = join(".pi", "delegate", runDirName, options.taskId);
452
+ try {
453
+ await mkdir(parentAbs, { recursive: true, mode: 448 });
454
+ await mkdir(rootAbs, { recursive: false, mode: 448 });
455
+ await chmod(rootAbs, 448);
456
+ await mkdir(join(rootAbs, DELEGATE_SPILL_DIRNAME), { recursive: false, mode: 448 });
457
+ } catch (error) {
458
+ throw artifactError(`could not create delegate artifact directory ${rootDisplay}`, error);
459
+ }
460
+ const timestamp = (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
461
+ const manifest = {
462
+ schema_version: DELEGATE_MANIFEST_SCHEMA_VERSION,
463
+ task_id: options.taskId,
464
+ launch_nonce: options.launchNonce,
465
+ created_at: timestamp,
466
+ updated_at: timestamp,
467
+ cwd: options.cwd,
468
+ child_session_id: options.childSessionId,
469
+ child_session_dir: options.childSessionDir,
470
+ extension_mode: options.extensionMode,
471
+ route: options.route,
472
+ limits: options.limits,
473
+ seed_sha256: options.seedSha256,
474
+ state: "launched",
475
+ artifacts: {}
476
+ };
477
+ const store = new _DelegateArtifactStore(
478
+ rootAbs,
479
+ rootDisplay,
480
+ options.now ?? (() => /* @__PURE__ */ new Date()),
481
+ manifest
482
+ );
483
+ await store.persistManifest();
484
+ return store;
485
+ }
486
+ get artifactDir() {
487
+ return this.rootDisplay;
488
+ }
489
+ get artifactDirAbs() {
490
+ return this.rootAbs;
491
+ }
492
+ get spillDirAbs() {
493
+ return this.spillAbs;
494
+ }
495
+ get resultPathAbs() {
496
+ return join(this.rootAbs, DELEGATE_ARTIFACT_NAMES.result);
497
+ }
498
+ snapshot() {
499
+ return { ...this.manifest, artifacts: { ...this.manifest.artifacts } };
500
+ }
501
+ async writeSeed(serialized) {
502
+ return this.write(DELEGATE_ARTIFACT_NAMES.seed, serialized);
503
+ }
504
+ /** Persist the exact prompt bytes handed to the child over stdin. */
505
+ async writeChildPrompt(bytes) {
506
+ return this.write(DELEGATE_ARTIFACT_NAMES.childPrompt, bytes);
507
+ }
508
+ async writeLedger(ledger) {
509
+ return this.write(DELEGATE_ARTIFACT_NAMES.ledger, `${canonicalJson(ledger)}
510
+ `);
511
+ }
512
+ async writeBudgetPlan(plan) {
513
+ return this.write(DELEGATE_ARTIFACT_NAMES.budgetPlan, `${canonicalJson(plan)}
514
+ `);
515
+ }
516
+ /** Commit the run. The rename performed here is the single success point. */
517
+ async commitResult(pkg) {
518
+ const ref = await this.write(
519
+ DELEGATE_ARTIFACT_NAMES.result,
520
+ serializeDelegateResultPackage(pkg)
521
+ );
522
+ await this.setState("committed");
523
+ return ref;
524
+ }
525
+ async readCommittedResult() {
526
+ try {
527
+ return await readFile(this.resultPathAbs, "utf8");
528
+ } catch (error) {
529
+ const diagnosticNames = [
530
+ DELEGATE_ARTIFACT_NAMES.error,
531
+ DELEGATE_ARTIFACT_NAMES.outcome,
532
+ DELEGATE_ARTIFACT_NAMES.runtimeBudget,
533
+ DELEGATE_ARTIFACT_NAMES.manifest
534
+ ].filter((name) => existsSync(join(this.rootAbs, name)));
535
+ throw new DelegateError(
536
+ `delegate result package could not be read at ${join(this.rootDisplay, DELEGATE_ARTIFACT_NAMES.result)}; no committed answer is available (${error instanceof Error ? error.message : String(error)})`,
537
+ {
538
+ code: "result_unavailable",
539
+ childCreated: true,
540
+ taskId: this.manifest.task_id,
541
+ artifactDir: this.rootDisplay,
542
+ preserved: diagnosticNames,
543
+ remediation: diagnosticNames.length === 0 ? [
544
+ "No diagnostic control artifact exists; inspect the background task merged output if one was created."
545
+ ] : [`Inspect the existing delegate control artifacts: ${diagnosticNames.join(", ")}.`]
546
+ }
547
+ );
548
+ }
549
+ }
550
+ async writeError(state, message) {
551
+ await this.write(
552
+ DELEGATE_ARTIFACT_NAMES.error,
553
+ `${canonicalJson({ state, error: message })}
554
+ `
555
+ );
556
+ await this.setState(state, message);
557
+ }
558
+ async setState(state, error) {
559
+ await this.update((manifest) => {
560
+ manifest.state = state;
561
+ if (error !== void 0) manifest.error = error;
562
+ });
563
+ }
564
+ /**
565
+ * Spill one oversized tool payload.
566
+ *
567
+ * The filename encodes `(turnSequence, sourceCallIndex, toolCallId)` assigned
568
+ * before the tool executed, so a receipt can never be associated with the
569
+ * wrong call when parallel results complete out of order.
570
+ *
571
+ * A spill that cannot be committed is a terminal failure. The original payload
572
+ * is never returned as a fallback and no receipt is emitted for a file that
573
+ * was not committed.
574
+ */
575
+ async spillToolPayload(input) {
576
+ const nextTotal = this.totalSpilledBytes + input.payload.length;
577
+ if (nextTotal > input.maxTotalBytes) {
578
+ throw new DelegateError(
579
+ `delegate aggregate tool output would reach ${String(nextTotal)} bytes, exceeding the ${String(input.maxTotalBytes)}-byte cap for one run`,
580
+ {
581
+ code: "aggregate_tool_output_cap",
582
+ childCreated: true,
583
+ taskId: this.manifest.task_id,
584
+ artifactDir: this.rootDisplay,
585
+ preserved: [this.rootDisplay],
586
+ remediation: [
587
+ "The delegate read more tool output than one run is allowed to accumulate. Narrow the investigation prompt or raise the cap deliberately."
588
+ ]
589
+ }
590
+ );
591
+ }
592
+ const safeCallId = sanitizePathSegment(input.toolCallId).slice(0, 64);
593
+ const name = `t${String(input.turnSequence).padStart(4, "0")}-c${String(
594
+ input.sourceCallIndex
595
+ ).padStart(4, "0")}-${safeCallId}.bin`;
596
+ const absPath = join(this.spillAbs, name);
597
+ if (!pathInside(this.spillAbs, absPath)) {
598
+ throw artifactError(`delegate spill path escapes the artifact directory: ${name}`);
599
+ }
600
+ try {
601
+ await this.durableReplace(absPath, input.payload);
602
+ } catch (error) {
603
+ throw new DelegateError(
604
+ `delegate could not durably spill a ${String(input.payload.length)}-byte tool result; the payload is not forwarded and no receipt is emitted`,
605
+ {
606
+ code: "artifact_spill_failed",
607
+ childCreated: true,
608
+ taskId: this.manifest.task_id,
609
+ artifactDir: this.rootDisplay,
610
+ preserved: [this.rootDisplay],
611
+ remediation: [
612
+ `Underlying cause: ${error instanceof Error ? error.message : String(error)}`,
613
+ "Check free disk space and permissions on the delegate artifact directory."
614
+ ]
615
+ }
616
+ );
617
+ }
618
+ this.totalSpilledBytes = nextTotal;
619
+ return {
620
+ schema_version: DELEGATE_RECEIPT_SCHEMA_VERSION,
621
+ artifact: join(DELEGATE_SPILL_DIRNAME, name),
622
+ tool_name: input.toolName,
623
+ tool_call_id: input.toolCallId,
624
+ turn_sequence: input.turnSequence,
625
+ source_call_index: input.sourceCallIndex,
626
+ byte_length: input.payload.length,
627
+ sha256: sha256Bytes2(input.payload),
628
+ content_format: "opaque_bytes"
629
+ };
630
+ }
631
+ /**
632
+ * Read an exact byte range from a spilled artifact.
633
+ *
634
+ * Returns exactly the requested range or fails. It never returns a shorter
635
+ * range than requested, and it never clamps the request to what happens to be
636
+ * available: a request past end-of-file is a loud error naming the real size.
637
+ */
638
+ async readSpillRange(relativePath, offset, length) {
639
+ if (!Number.isSafeInteger(offset) || offset < 0)
640
+ throw this.readFailure(relativePath, "offset must be a non-negative integer");
641
+ if (!Number.isSafeInteger(length) || length <= 0)
642
+ throw this.readFailure(relativePath, "length must be a positive integer");
643
+ const absPath = join(this.rootAbs, relativePath);
644
+ if (!pathInside(this.rootAbs, absPath))
645
+ throw this.readFailure(relativePath, "path escapes the delegate artifact directory");
646
+ let handle;
647
+ try {
648
+ handle = await open(absPath, "r");
649
+ } catch (error) {
650
+ throw this.readFailure(
651
+ relativePath,
652
+ `cannot open artifact: ${error instanceof Error ? error.message : String(error)}`
653
+ );
654
+ }
655
+ try {
656
+ const stats = await handle.stat();
657
+ const totalBytes = stats.size;
658
+ if (offset + length > totalBytes) {
659
+ throw this.readFailure(
660
+ relativePath,
661
+ `requested bytes ${String(offset)}..${String(offset + length)} exceed the artifact size of ${String(totalBytes)} bytes; the read is refused rather than silently shortened`
662
+ );
663
+ }
664
+ const buffer = Buffer.alloc(length);
665
+ const { bytesRead } = await handle.read(buffer, 0, length, offset);
666
+ if (bytesRead !== length) {
667
+ throw this.readFailure(
668
+ relativePath,
669
+ `read returned ${String(bytesRead)} of ${String(length)} requested bytes`
670
+ );
671
+ }
672
+ return { bytes: buffer, totalBytes };
673
+ } finally {
674
+ await handle.close();
675
+ }
676
+ }
677
+ readFailure(relativePath, reason) {
678
+ return new DelegateError(`delegate artifact read failed for ${relativePath}: ${reason}`, {
679
+ code: "artifact_read_failed",
680
+ childCreated: true,
681
+ taskId: this.manifest.task_id,
682
+ artifactDir: this.rootDisplay
683
+ });
684
+ }
685
+ async durableReplace(absPath, data) {
686
+ await replaceFileDurable(absPath, data);
687
+ }
688
+ async write(name, data) {
689
+ const absPath = join(this.rootAbs, name);
690
+ if (name.length === 0 || name.includes("/") || name.includes("\\"))
691
+ throw artifactError(`invalid delegate artifact name: ${name}`);
692
+ if (!pathInside(this.rootAbs, absPath))
693
+ throw artifactError(`delegate artifact path escapes the run directory: ${name}`);
694
+ const bytes = Buffer.isBuffer(data) ? data : Buffer.from(data, "utf8");
695
+ try {
696
+ await this.durableReplace(absPath, data);
697
+ } catch (error) {
698
+ throw artifactError(`could not durably write delegate artifact ${name}`, error);
699
+ }
700
+ const ref = {
701
+ path: basename(absPath),
702
+ byte_length: bytes.length,
703
+ sha256: sha256Bytes2(bytes)
704
+ };
705
+ await this.update((manifest) => {
706
+ manifest.artifacts = { ...manifest.artifacts, [name]: ref };
707
+ });
708
+ return ref;
709
+ }
710
+ async persistManifest() {
711
+ const absPath = join(this.rootAbs, DELEGATE_ARTIFACT_NAMES.manifest);
712
+ try {
713
+ await this.durableReplace(absPath, `${canonicalJson(this.snapshot())}
714
+ `);
715
+ } catch (error) {
716
+ throw artifactError("could not durably write the delegate manifest", error);
717
+ }
718
+ }
719
+ async update(mutator) {
720
+ const apply = /* @__PURE__ */ __name(async () => {
721
+ mutator(this.manifest);
722
+ this.manifest.updated_at = this.now().toISOString();
723
+ await this.persistManifest();
724
+ }, "apply");
725
+ const next = this.writeChain.then(apply, apply);
726
+ this.writeChain = next.catch(() => void 0);
727
+ await next;
728
+ }
729
+ };
730
+ async function discardDelegateArtifactRoot(rootAbs) {
731
+ await rm(rootAbs, { recursive: true, force: true });
732
+ }
733
+ __name(discardDelegateArtifactRoot, "discardDelegateArtifactRoot");
734
+
735
+ // node_modules/pi-background-tasks/src/core/delegate/runner.ts?ext=pi-background-tasks
736
+ var PREPARATION_CLEANUP_ERROR_MAX_CHARS = 320;
737
+ function boundedPreparationError(error) {
738
+ const text = (error instanceof Error ? error.message : String(error)).replace(/\s+/gu, " ").trim();
739
+ if (text.length <= PREPARATION_CLEANUP_ERROR_MAX_CHARS) return text;
740
+ return `${text.slice(0, PREPARATION_CLEANUP_ERROR_MAX_CHARS)}\u2026`;
741
+ }
742
+ __name(boundedPreparationError, "boundedPreparationError");
743
+ function filesystemErrorCode(error) {
744
+ if (typeof error !== "object" || error === null) return void 0;
745
+ const code = Reflect.get(error, "code");
746
+ return typeof code === "string" ? code : void 0;
747
+ }
748
+ __name(filesystemErrorCode, "filesystemErrorCode");
749
+ async function removeEmptyDirectory(path) {
750
+ try {
751
+ await rmdir(path);
752
+ return true;
753
+ } catch (error) {
754
+ const code = filesystemErrorCode(error);
755
+ if (code === "ENOENT") return true;
756
+ if (code === "ENOTEMPTY" || code === "EEXIST") return false;
757
+ throw error;
758
+ }
759
+ }
760
+ __name(removeEmptyDirectory, "removeEmptyDirectory");
761
+ async function discardUnownedDelegatePreparation(rootAbs) {
762
+ await discardDelegateArtifactRoot(rootAbs);
763
+ const runParent = dirname(rootAbs);
764
+ if (!await removeEmptyDirectory(runParent)) return;
765
+ await removeEmptyDirectory(dirname(runParent));
766
+ }
767
+ __name(discardUnownedDelegatePreparation, "discardUnownedDelegatePreparation");
768
+ function throwIfPreparationAborted(signal) {
769
+ if (signal?.aborted !== true) return;
770
+ const reason = signal.reason;
771
+ if (reason instanceof Error) throw reason;
772
+ throw new Error("delegate launch preparation was cancelled before task registration");
773
+ }
774
+ __name(throwIfPreparationAborted, "throwIfPreparationAborted");
775
+ function preparationCleanupFailure(original, cleanup) {
776
+ return new AggregateError(
777
+ [original, cleanup],
778
+ `delegate launch preparation failed and rollback also failed: ${boundedPreparationError(cleanup)}`
779
+ );
780
+ }
781
+ __name(preparationCleanupFailure, "preparationCleanupFailure");
782
+ async function prepareDelegateLaunch(input) {
783
+ throwIfPreparationAborted(input.signal);
784
+ const childExtensionPath = input.childExtensionPath ?? resolveDelegateChildExtensionPath();
785
+ let attributionExtensionPath;
786
+ if (input.route.provider === "anthropic") {
787
+ try {
788
+ attributionExtensionPath = input.attributionExtensionPath ?? resolveAnthropicAttributionExtensionPath();
789
+ } catch (error) {
790
+ throw new DelegateError(
791
+ `Anthropic delegate attribution extension could not be resolved: ${error instanceof Error ? error.message : String(error)}`,
792
+ {
793
+ code: "delegate_isolation_unsupported",
794
+ childCreated: false,
795
+ remediation: ["Reinstall the package; Anthropic delegates require attribution."]
796
+ }
797
+ );
798
+ }
799
+ }
800
+ throwIfPreparationAborted(input.signal);
801
+ const preflight = preflightDelegateLaunch(input);
802
+ throwIfPreparationAborted(input.signal);
803
+ let store;
804
+ try {
805
+ store = await DelegateArtifactStore.create({
806
+ cwd: input.cwd,
807
+ taskId: preflight.taskId,
808
+ launchNonce: preflight.launchNonce,
809
+ sessionId: input.sessionId,
810
+ childSessionId: preflight.childSessionId,
811
+ childSessionDir: "",
812
+ extensionMode: input.extensionMode,
813
+ route: input.route,
814
+ limits: preflight.limits,
815
+ seedSha256: preflight.seed.sha256,
816
+ ...input.now === void 0 ? {} : { now: input.now }
817
+ });
818
+ throwIfPreparationAborted(input.signal);
819
+ const seedRef = await store.writeSeed(preflight.seed.serialized);
820
+ throwIfPreparationAborted(input.signal);
821
+ if (seedRef.sha256 !== preflight.seed.sha256) {
822
+ throw new DelegateError("delegate seed hash changed between construction and persistence", {
823
+ code: "seed_persist_failed",
824
+ childCreated: false,
825
+ taskId: preflight.taskId,
826
+ artifactDir: store.artifactDir
827
+ });
828
+ }
829
+ await store.writeLedger(preflight.seed.ledger);
830
+ throwIfPreparationAborted(input.signal);
831
+ await store.writeBudgetPlan(preflight.plan);
832
+ throwIfPreparationAborted(input.signal);
833
+ const childSessionDirAbs = await ensureDelegateChildSessionDir(store.artifactDirAbs);
834
+ throwIfPreparationAborted(input.signal);
835
+ const seedPathAbs = join2(store.artifactDirAbs, "seed.json");
836
+ const argv = buildDelegateChildArgv({
837
+ route: input.route,
838
+ capability: input.capability,
839
+ extensionMode: input.extensionMode,
840
+ childSessionId: preflight.childSessionId,
841
+ childSessionDir: childSessionDirAbs,
842
+ childExtensionPath,
843
+ attributionExtensionPath,
844
+ systemPrompt: preflight.childSystemPrompt
845
+ });
846
+ const env = delegateChildEnv(
847
+ {
848
+ artifactDirAbs: store.artifactDirAbs,
849
+ seedPathAbs,
850
+ seedSha256: preflight.seed.sha256,
851
+ taskId: preflight.taskId,
852
+ launchNonce: preflight.launchNonce
853
+ },
854
+ input.env ?? process.env
855
+ );
856
+ const facts = {
857
+ taskId: preflight.taskId,
858
+ launchNonce: preflight.launchNonce,
859
+ artifactDir: store.artifactDir,
860
+ artifactDirAbs: store.artifactDirAbs,
861
+ seedSha256: preflight.seed.sha256,
862
+ childSessionId: preflight.childSessionId,
863
+ route: {
864
+ provider: input.route.provider,
865
+ model: input.route.model,
866
+ qualifiedId: input.route.qualified_id
867
+ },
868
+ budget: {
869
+ family: preflight.plan.route.family,
870
+ rate_source: preflight.plan.route.rate_source,
871
+ conservative_rate_source: preflight.plan.conservative_estimate.rateSource
872
+ },
873
+ extensionMode: input.extensionMode,
874
+ autoDeliver: input.autoDeliver
875
+ };
876
+ const stdinBytes = Buffer.from(preflight.childPrompt, "utf8");
877
+ await store.writeChildPrompt(stdinBytes);
878
+ throwIfPreparationAborted(input.signal);
879
+ const artifactDirAbs = store.artifactDirAbs;
880
+ let rollbackPromise;
881
+ const rollback = /* @__PURE__ */ __name(() => {
882
+ rollbackPromise ??= discardUnownedDelegatePreparation(artifactDirAbs);
883
+ return rollbackPromise;
884
+ }, "rollback");
885
+ return {
886
+ preflight,
887
+ store,
888
+ argv,
889
+ env,
890
+ facts,
891
+ childSessionDirAbs,
892
+ seedPathAbs,
893
+ stdinBytes,
894
+ rollback
895
+ };
896
+ } catch (error) {
897
+ if (store === void 0) throw error;
898
+ try {
899
+ await discardUnownedDelegatePreparation(store.artifactDirAbs);
900
+ } catch (cleanupError) {
901
+ throw preparationCleanupFailure(error, cleanupError);
902
+ }
903
+ throw error;
904
+ }
905
+ }
906
+ __name(prepareDelegateLaunch, "prepareDelegateLaunch");
907
+ async function evaluateDelegateTerminal(input) {
908
+ const evaluation = await adjudicateDelegateTerminal(input);
909
+ try {
910
+ await replaceFileDurable(
911
+ join2(input.artifactDirAbs, "outcome.json"),
912
+ `${canonicalJson({
913
+ schema_version: "pi-background-tasks.delegate-outcome.v1",
914
+ task_id: input.taskId,
915
+ launch_nonce: input.launchNonce,
916
+ observed_task_status: input.taskStatus,
917
+ outcome: evaluation.outcome,
918
+ error_code: evaluation.error?.code ?? null
919
+ })}
920
+ `
921
+ );
922
+ } catch {
923
+ }
924
+ return evaluation;
925
+ }
926
+ __name(evaluateDelegateTerminal, "evaluateDelegateTerminal");
927
+ async function adjudicateDelegateTerminal(input) {
928
+ const resultPath = join2(input.artifactDirAbs, "result.json");
929
+ const terminalPath = join2(input.artifactDirAbs, "child-terminal.json");
930
+ if (!existsSync2(resultPath)) {
931
+ const recorded = existsSync2(terminalPath) ? await readChildTerminal(terminalPath) : void 0;
932
+ const cancelled = input.taskStatus === "killed";
933
+ const code = recorded?.code ?? (cancelled ? "child_cancelled" : "child_exited_without_commit");
934
+ const detail = recorded?.message ?? input.taskError ?? "the delegate child exited without committing a result package";
935
+ const preserved = [
936
+ "seed.json",
937
+ "budget-plan.json",
938
+ "child-terminal.json",
939
+ "runtime-budget.json"
940
+ ].filter((name) => existsSync2(join2(input.artifactDirAbs, name)));
941
+ if (input.taskOutputPath !== void 0 && input.taskOutputAbsPath !== void 0 && existsSync2(input.taskOutputAbsPath)) {
942
+ preserved.push(input.taskOutputPath);
943
+ }
944
+ const diagnosticTargets = preserved.filter(
945
+ (name) => name === "child-terminal.json" || name === "runtime-budget.json" || name === input.taskOutputPath
946
+ );
947
+ const diagnostic = diagnosticTargets.length === 0 ? "No child terminal record or merged task output exists; inspect the preserved launch artifacts listed above." : `Inspect the preserved diagnostic evidence: ${diagnosticTargets.join(", ")}.`;
948
+ const error = new DelegateError(`bg_delegate produced no committed answer: ${detail}`, {
949
+ code: isDelegateErrorCode(code) ? code : "child_exited_without_commit",
950
+ childCreated: true,
951
+ taskId: input.taskId,
952
+ artifactDir: input.artifactDirAbs,
953
+ preserved,
954
+ remediation: [
955
+ diagnostic,
956
+ "No partial answer is returned; nothing was truncated to look like success."
957
+ ]
958
+ });
959
+ const outcome = {
960
+ status: cancelled ? "cancelled" : "failed",
961
+ errorCode: error.code
962
+ };
963
+ return { outcome, error };
964
+ }
965
+ let raw;
966
+ try {
967
+ raw = await readFile2(resultPath, "utf8");
968
+ } catch (error) {
969
+ const failure = new DelegateError(
970
+ `bg_delegate could not read its committed result package: ${error instanceof Error ? error.message : String(error)}`,
971
+ {
972
+ code: "artifact_read_failed",
973
+ childCreated: true,
974
+ taskId: input.taskId,
975
+ artifactDir: input.artifactDirAbs
976
+ }
977
+ );
978
+ return { outcome: { status: "failed", errorCode: failure.code }, error: failure };
979
+ }
980
+ try {
981
+ const verified = verifyDelegateResultPackage(raw, {
982
+ taskId: input.taskId,
983
+ launchNonce: input.launchNonce,
984
+ seedSha256: input.seedSha256,
985
+ route: input.route
986
+ });
987
+ return {
988
+ outcome: {
989
+ status: "committed",
990
+ answerBytes: verified.package.answer.byte_length,
991
+ answerSha256: verified.package.answer.sha256,
992
+ turns: verified.package.turns,
993
+ toolCalls: verified.package.tool_calls
994
+ },
995
+ result: verified
996
+ };
997
+ } catch (error) {
998
+ if (error instanceof DelegateError) {
999
+ return { outcome: { status: "failed", errorCode: error.code }, error };
1000
+ }
1001
+ throw error;
1002
+ }
1003
+ }
1004
+ __name(adjudicateDelegateTerminal, "adjudicateDelegateTerminal");
1005
+ async function readChildTerminal(path) {
1006
+ try {
1007
+ const parsed = JSON.parse(await readFile2(path, "utf8"));
1008
+ if (typeof parsed !== "object" || parsed === null) return void 0;
1009
+ const code = Reflect.get(parsed, "code");
1010
+ const message = Reflect.get(parsed, "message");
1011
+ if (typeof code !== "string" || typeof message !== "string") return void 0;
1012
+ return { code, message };
1013
+ } catch {
1014
+ return void 0;
1015
+ }
1016
+ }
1017
+ __name(readChildTerminal, "readChildTerminal");
1018
+ var DELEGATE_ERROR_CODE_SET = /* @__PURE__ */ new Set([
1019
+ "delegate_hook_contract_unsupported",
1020
+ "delegate_isolation_unsupported",
1021
+ "route_unresolved",
1022
+ "route_capacity_unknown",
1023
+ "seed_projection_failed",
1024
+ "seed_budget_exceeded",
1025
+ "seed_persist_failed",
1026
+ "invalid_arguments",
1027
+ "child_spawn_failed",
1028
+ "child_startup_failed",
1029
+ "child_timeout",
1030
+ "child_cancelled",
1031
+ "child_turn_limit",
1032
+ "child_tool_call_limit",
1033
+ "child_exited_without_commit",
1034
+ "provider_context_budget_exhausted",
1035
+ "aggregate_tool_output_cap",
1036
+ "child_model_output_limit",
1037
+ "child_capture_limit",
1038
+ "child_result_invalid",
1039
+ "child_result_encoding_invalid",
1040
+ "route_attestation_missing",
1041
+ "route_mismatch",
1042
+ "seed_hash_mismatch",
1043
+ "answer_hash_mismatch",
1044
+ "artifact_spill_failed",
1045
+ "artifact_read_failed",
1046
+ "artifact_error",
1047
+ "result_not_ready",
1048
+ "result_unavailable",
1049
+ "result_too_large_for_inline",
1050
+ "task_unknown"
1051
+ ]);
1052
+ function isDelegateErrorCode(value) {
1053
+ return DELEGATE_ERROR_CODE_SET.has(value);
1054
+ }
1055
+ __name(isDelegateErrorCode, "isDelegateErrorCode");
1056
+ function decideDelegateDelivery(answerBytes, requested, cap = DELEGATE_INLINE_ANSWER_BYTES) {
1057
+ if (requested === "artifact") {
1058
+ return { mode: "artifact", reason: "artifact delivery was requested explicitly" };
1059
+ }
1060
+ if (answerBytes <= cap) {
1061
+ return {
1062
+ mode: "inline",
1063
+ reason: `the answer is ${String(answerBytes)} bytes, within the ${String(cap)}-byte inline cap`
1064
+ };
1065
+ }
1066
+ return {
1067
+ mode: "artifact",
1068
+ reason: `the answer is ${String(answerBytes)} bytes, over the ${String(cap)}-byte inline cap`
1069
+ };
1070
+ }
1071
+ __name(decideDelegateDelivery, "decideDelegateDelivery");
1072
+ function inlineTooLarge(taskId, artifactDir, answerBytes, cap = DELEGATE_INLINE_ANSWER_BYTES) {
1073
+ return new DelegateError(
1074
+ `bg_result cannot return this answer inline: it is ${String(answerBytes)} bytes, over the ${String(cap)}-byte inline cap. The complete verified answer is preserved at ${join2(artifactDir, "result.json")}. It is not truncated to fit.`,
1075
+ {
1076
+ code: "result_too_large_for_inline",
1077
+ childCreated: true,
1078
+ taskId,
1079
+ artifactDir,
1080
+ preserved: [join2(artifactDir, "result.json")],
1081
+ remediation: [
1082
+ 'Call bg_result with delivery:"artifact" to receive the verified metadata plus the artifact reference.',
1083
+ "Read the answer from the artifact path directly if the full text is required."
1084
+ ]
1085
+ }
1086
+ );
1087
+ }
1088
+ __name(inlineTooLarge, "inlineTooLarge");
1089
+
1090
+ export {
1091
+ prepareDelegateLaunch,
1092
+ evaluateDelegateTerminal,
1093
+ adjudicateDelegateTerminal,
1094
+ decideDelegateDelivery,
1095
+ inlineTooLarge
1096
+ };