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,1602 @@
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
+ DEFAULT_WATCHDOG_CONFIG,
4
+ MainWatchdogRuntime,
5
+ WATCHDOG_DIFF_TOOL_NAME,
6
+ captureWatchdogDiffBaseline,
7
+ childSupervisorMetadata,
8
+ createMainWatchdogReview,
9
+ createWatchdogDiffTool,
10
+ createWatchdogWarningMessage,
11
+ drainOutstandingWork,
12
+ evaluateChildToolDiagnostic,
13
+ formatWatchdogCwdSection,
14
+ registerNativeSupervisorClient,
15
+ registerWaitTool,
16
+ resolveCurrentSessionId,
17
+ resolveWatchdogReviewModel,
18
+ startWatchdogDiffBaselineCapture
19
+ } from "./c-UGERXVO2.mjs";
20
+ import {
21
+ MODEL_ONLY_TOOL,
22
+ agentStreamOptions,
23
+ getProjectSubagentsDir,
24
+ inheritedNestedRouteOf,
25
+ opencodeSessionHeaders
26
+ } from "./c-DTGPSB46.mjs";
27
+ import {
28
+ CHILD_WATCHDOG_STATUS_EVENT,
29
+ INTERCOM_SESSION_IDENTITY_EVENT,
30
+ MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR,
31
+ SUBAGENT_WATCHDOG_WARNING_TYPE,
32
+ appendPermissionAudit,
33
+ createStructuredOutputToolParameters,
34
+ decodeChildWatchdogConfig,
35
+ discoverAgents,
36
+ formatUnknownAgentError,
37
+ getAgentDir,
38
+ permissionArgsPreview,
39
+ permissionDecision,
40
+ resolveAgentName,
41
+ shouldBlockToolForBudget,
42
+ toolBudgetBlockedMessage,
43
+ toolBudgetSoftNudge,
44
+ unknownAgentDiagnosticContext,
45
+ validateAcceptanceReport,
46
+ validateStructuredOutputValue
47
+ } from "./c-V4RHQBPQ.mjs";
48
+ import {
49
+ convertToLlm
50
+ } from "./c-SKMK3PEE.mjs";
51
+ import {
52
+ Agent
53
+ } from "./c-UPBH5AXY.mjs";
54
+ import {
55
+ typebox_exports
56
+ } from "./c-RQJJ26T4.mjs";
57
+ import {
58
+ __name
59
+ } from "./c-CN77DCGF.mjs";
60
+
61
+ // node_modules/pi-subagents/src/agents/agent-refinements.js?ext=pi-subagents
62
+ import { createHash, randomUUID } from "node:crypto";
63
+ import * as fs from "node:fs";
64
+ import * as path from "node:path";
65
+ var REFINEMENT_FORMAT_VERSION = 1;
66
+ var REFINEMENT_DIR = "refinements";
67
+ var CURRENT_FENCE = "pi-subagents-refinement-current";
68
+ var SNAPSHOTS_FENCE = "pi-subagents-refinement-snapshots-json";
69
+ var MAX_EVIDENCE_ITEMS = 8;
70
+ var MAX_AGE_DAYS = 14;
71
+ var MAX_ITEM_BYTES = 2048;
72
+ var MAX_PACKET_BYTES = 16384;
73
+ var PROPOSAL_AGENT = "reviewer";
74
+ function result(text2, isError = false) {
75
+ return {
76
+ content: [{ type: "text", text: text2 }],
77
+ ...isError ? { isError: true } : {},
78
+ details: { mode: "management", results: [] }
79
+ };
80
+ }
81
+ __name(result, "result");
82
+ function record(value) {
83
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
84
+ }
85
+ __name(record, "record");
86
+ function text(value) {
87
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
88
+ }
89
+ __name(text, "text");
90
+ function textArray(value) {
91
+ if (!Array.isArray(value))
92
+ return [];
93
+ return value.map(text).filter((entry) => entry !== null);
94
+ }
95
+ __name(textArray, "textArray");
96
+ function isoTime(value) {
97
+ const numberValue = typeof value === "number" && Number.isFinite(value) ? value : void 0;
98
+ if (numberValue !== void 0)
99
+ return new Date(numberValue).toISOString();
100
+ const stringValue = text(value);
101
+ if (!stringValue)
102
+ return void 0;
103
+ const parsed = Date.parse(stringValue);
104
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : void 0;
105
+ }
106
+ __name(isoTime, "isoTime");
107
+ function hashPrompt(systemPrompt) {
108
+ return createHash("sha256").update(systemPrompt).digest("hex");
109
+ }
110
+ __name(hashPrompt, "hashPrompt");
111
+ function safeAgentFileName(agentName) {
112
+ const trimmed = agentName.trim();
113
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(trimmed) || trimmed.includes("..")) {
114
+ throw new Error(`Agent name '${agentName}' cannot be used as a refinement file name.`);
115
+ }
116
+ return `${trimmed}.md`;
117
+ }
118
+ __name(safeAgentFileName, "safeAgentFileName");
119
+ function getAgentRefinementPath(cwd, agentName) {
120
+ const refinementRoot = path.join(getProjectSubagentsDir(cwd), REFINEMENT_DIR);
121
+ const resolvedRoot = path.resolve(refinementRoot);
122
+ const resolvedPath = path.resolve(refinementRoot, safeAgentFileName(agentName));
123
+ if (resolvedPath !== path.join(resolvedRoot, path.basename(resolvedPath))) {
124
+ throw new Error(`Agent name '${agentName}' cannot be used as a refinement file name.`);
125
+ }
126
+ return resolvedPath;
127
+ }
128
+ __name(getAgentRefinementPath, "getAgentRefinementPath");
129
+ function readExisting(cwd, agentName) {
130
+ const filePath = getAgentRefinementPath(cwd, agentName);
131
+ if (!fs.existsSync(filePath))
132
+ return { path: filePath };
133
+ return { path: filePath, parsed: parseRefinementFile(fs.readFileSync(filePath, "utf-8"), filePath) };
134
+ }
135
+ __name(readExisting, "readExisting");
136
+ function extractFence(markdown, fence) {
137
+ const escaped = fence.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
138
+ const match = markdown.match(new RegExp("\\n```" + escaped + "\\n([\\s\\S]*?)\\n```", "m"));
139
+ return match?.[1] ?? null;
140
+ }
141
+ __name(extractFence, "extractFence");
142
+ function parseRefinementFile(markdown, label = "refinement file") {
143
+ const metadataMatch = markdown.match(/^<!-- pi-subagents-refinement:v1\n([\s\S]*?)\n-->\n/);
144
+ if (!metadataMatch?.[1])
145
+ throw new Error(`${label} is missing refinement metadata.`);
146
+ const metadataValue = JSON.parse(metadataMatch[1]);
147
+ const metadataRecord = record(metadataValue);
148
+ if (!metadataRecord)
149
+ throw new Error(`${label} metadata must be an object.`);
150
+ const agent = text(metadataRecord.agent);
151
+ const revision = metadataRecord.revision;
152
+ const updatedAt = text(metadataRecord.updatedAt);
153
+ const base = record(metadataRecord.base);
154
+ const evidence = record(metadataRecord.evidence);
155
+ if (!agent || typeof revision !== "number" || !Number.isInteger(revision) || !updatedAt || !base || !evidence) {
156
+ throw new Error(`${label} metadata is invalid.`);
157
+ }
158
+ const source = text(base.source);
159
+ const filePath = text(base.filePath);
160
+ const systemPromptSha256 = text(base.systemPromptSha256);
161
+ if (source !== "builtin" && source !== "package" && source !== "user" && source !== "project")
162
+ throw new Error(`${label} base source is invalid.`);
163
+ if (!filePath || !systemPromptSha256)
164
+ throw new Error(`${label} base metadata is invalid.`);
165
+ const current = extractFence(markdown, CURRENT_FENCE);
166
+ if (current === null)
167
+ throw new Error(`${label} is missing current refinement block.`);
168
+ const snapshotsRaw = extractFence(markdown, SNAPSHOTS_FENCE) ?? "[]";
169
+ const snapshotsValue = JSON.parse(snapshotsRaw);
170
+ if (!Array.isArray(snapshotsValue))
171
+ throw new Error(`${label} snapshots must be an array.`);
172
+ const snapshots = snapshotsValue.map((entry, index) => {
173
+ const item = record(entry);
174
+ if (!item)
175
+ throw new Error(`${label} snapshot ${index} must be an object.`);
176
+ const action = text(item.action);
177
+ const before = typeof item.before === "string" ? item.before : null;
178
+ const after = typeof item.after === "string" ? item.after : null;
179
+ const at = text(item.at);
180
+ if (typeof item.revision !== "number" || !Number.isInteger(item.revision) || !at || action !== "refine" && action !== "rollback" || before === null || after === null) {
181
+ throw new Error(`${label} snapshot ${index} is invalid.`);
182
+ }
183
+ return {
184
+ revision: item.revision,
185
+ at,
186
+ action,
187
+ before,
188
+ after,
189
+ evidenceIds: textArray(item.evidenceIds),
190
+ ...text(item.proposalAgent) ? { proposalAgent: text(item.proposalAgent) } : {}
191
+ };
192
+ });
193
+ return {
194
+ metadata: {
195
+ agent,
196
+ revision,
197
+ updatedAt,
198
+ base: { source, filePath, systemPromptSha256 },
199
+ evidence: {
200
+ maxItems: typeof evidence.maxItems === "number" ? evidence.maxItems : MAX_EVIDENCE_ITEMS,
201
+ maxAgeDays: typeof evidence.maxAgeDays === "number" ? evidence.maxAgeDays : MAX_AGE_DAYS,
202
+ itemBytes: typeof evidence.itemBytes === "number" ? evidence.itemBytes : MAX_ITEM_BYTES,
203
+ totalBytes: typeof evidence.totalBytes === "number" ? evidence.totalBytes : MAX_PACKET_BYTES
204
+ }
205
+ },
206
+ current,
207
+ snapshots
208
+ };
209
+ }
210
+ __name(parseRefinementFile, "parseRefinementFile");
211
+ function serializeRefinementFile(parsed) {
212
+ const metadata = JSON.stringify(parsed.metadata, null, 2);
213
+ const snapshots = JSON.stringify(parsed.snapshots, null, 2);
214
+ return [
215
+ `<!-- pi-subagents-refinement:v${REFINEMENT_FORMAT_VERSION}`,
216
+ metadata,
217
+ "-->",
218
+ "",
219
+ `# Current refinement for \`${parsed.metadata.agent}\``,
220
+ "",
221
+ `\`\`\`${CURRENT_FENCE}`,
222
+ parsed.current,
223
+ "```",
224
+ "",
225
+ "# Snapshots",
226
+ "",
227
+ `\`\`\`${SNAPSHOTS_FENCE}`,
228
+ snapshots,
229
+ "```",
230
+ ""
231
+ ].join("\n");
232
+ }
233
+ __name(serializeRefinementFile, "serializeRefinementFile");
234
+ function writeRefinementFile(filePath, parsed) {
235
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
236
+ const tmp = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
237
+ fs.writeFileSync(tmp, serializeRefinementFile(parsed), "utf-8");
238
+ fs.renameSync(tmp, filePath);
239
+ }
240
+ __name(writeRefinementFile, "writeRefinementFile");
241
+ function baseMetadata(agent) {
242
+ return {
243
+ source: agent.source,
244
+ filePath: agent.filePath,
245
+ systemPromptSha256: hashPrompt(agent.systemPrompt)
246
+ };
247
+ }
248
+ __name(baseMetadata, "baseMetadata");
249
+ function metadataFor(agent, revision, now) {
250
+ return {
251
+ agent: agent.name,
252
+ revision,
253
+ updatedAt: now,
254
+ base: baseMetadata(agent),
255
+ evidence: {
256
+ maxItems: MAX_EVIDENCE_ITEMS,
257
+ maxAgeDays: MAX_AGE_DAYS,
258
+ itemBytes: MAX_ITEM_BYTES,
259
+ totalBytes: MAX_PACKET_BYTES
260
+ }
261
+ };
262
+ }
263
+ __name(metadataFor, "metadataFor");
264
+ function withinAge(at, now = Date.now()) {
265
+ if (!at)
266
+ return true;
267
+ const parsed = Date.parse(at);
268
+ return Number.isFinite(parsed) && now - parsed <= MAX_AGE_DAYS * 24 * 60 * 60 * 1e3;
269
+ }
270
+ __name(withinAge, "withinAge");
271
+ function tailBytes(value, maxBytes) {
272
+ const buffer = Buffer.from(value, "utf-8");
273
+ if (buffer.byteLength <= maxBytes)
274
+ return value;
275
+ return buffer.subarray(buffer.byteLength - maxBytes).toString("utf-8");
276
+ }
277
+ __name(tailBytes, "tailBytes");
278
+ function pushCapped(items, item) {
279
+ if (items.length >= MAX_EVIDENCE_ITEMS)
280
+ return;
281
+ items.push({ ...item, outputTail: item.outputTail ? tailBytes(item.outputTail, MAX_ITEM_BYTES) : void 0 });
282
+ }
283
+ __name(pushCapped, "pushCapped");
284
+ function acceptanceFields(value) {
285
+ const ledger = record(value);
286
+ if (!ledger)
287
+ return {};
288
+ const childReport = record(ledger.childReport);
289
+ const reviewResult = record(ledger.reviewResult);
290
+ const reviewFindings = [
291
+ ...textArray(childReport?.reviewFindings),
292
+ ...Array.isArray(reviewResult?.findings) ? reviewResult.findings.map((finding) => text(record(finding)?.issue)).filter((entry) => entry !== null) : []
293
+ ];
294
+ const residualRisks = textArray(childReport?.residualRisks);
295
+ return {
296
+ ...text(ledger.status) ? { acceptanceStatus: text(ledger.status) } : {},
297
+ ...reviewFindings.length > 0 ? { reviewFindings } : {},
298
+ ...residualRisks.length > 0 ? { residualRisks } : {}
299
+ };
300
+ }
301
+ __name(acceptanceFields, "acceptanceFields");
302
+ function controlSignals(value) {
303
+ if (!Array.isArray(value))
304
+ return [];
305
+ return value.map((entry) => {
306
+ const item = record(entry);
307
+ if (!item)
308
+ return null;
309
+ const message = text(item.message);
310
+ const reason = text(item.reason);
311
+ return message ? reason ? `${reason}: ${message}` : message : null;
312
+ }).filter((entry) => entry !== null);
313
+ }
314
+ __name(controlSignals, "controlSignals");
315
+ function evidencePacket(items) {
316
+ const packet = [];
317
+ let bytes = 2;
318
+ for (const item of items) {
319
+ const encoded = Buffer.byteLength(JSON.stringify(item), "utf-8") + 1;
320
+ if (bytes + encoded > MAX_PACKET_BYTES)
321
+ break;
322
+ packet.push(item);
323
+ bytes += encoded;
324
+ }
325
+ return packet;
326
+ }
327
+ __name(evidencePacket, "evidencePacket");
328
+ function collectBoundedRefinementEvidence(cwd, agentName, state) {
329
+ const items = [];
330
+ const jobs = [...state.asyncJobs.values()].filter((job) => !job.cwd || path.resolve(job.cwd) === path.resolve(cwd)).filter((job) => job.agents?.includes(agentName) || job.steps?.some((step) => step.agent === agentName)).sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
331
+ for (const job of jobs) {
332
+ const at = isoTime(job.updatedAt ?? job.startedAt);
333
+ if (!withinAge(at))
334
+ continue;
335
+ const matchingSteps = job.steps?.filter((step) => step.agent === agentName) ?? [];
336
+ if (matchingSteps.length === 0) {
337
+ pushCapped(items, {
338
+ id: `live:${job.asyncId}`,
339
+ source: "live-state",
340
+ runId: job.asyncId,
341
+ agent: agentName,
342
+ ...at ? { at } : {},
343
+ status: job.status,
344
+ refs: [job.asyncDir]
345
+ });
346
+ continue;
347
+ }
348
+ for (const [index, step] of matchingSteps.entries()) {
349
+ const stepRecord = step;
350
+ pushCapped(items, {
351
+ id: `live:${job.asyncId}:${index}`,
352
+ source: "live-state",
353
+ runId: job.asyncId,
354
+ agent: agentName,
355
+ ...at ? { at } : {},
356
+ status: step.status,
357
+ ...text(stepRecord.model) ? { model: text(stepRecord.model) } : {},
358
+ ...text(stepRecord.thinking) ? { thinking: text(stepRecord.thinking) } : {},
359
+ ...acceptanceFields(stepRecord.acceptance),
360
+ ...text(step.error) ? { errors: [text(step.error)] } : {},
361
+ ...text(stepRecord.recentOutput) ? { outputTail: text(stepRecord.recentOutput) } : {},
362
+ refs: [job.asyncDir]
363
+ });
364
+ }
365
+ }
366
+ const artifactsDir = path.join(getProjectSubagentsDir(cwd), "artifacts");
367
+ if (fs.existsSync(artifactsDir)) {
368
+ const files = fs.readdirSync(artifactsDir).filter((file) => file.endsWith("_meta.json")).map((file) => path.join(artifactsDir, file)).sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
369
+ for (const file of files) {
370
+ if (items.length >= MAX_EVIDENCE_ITEMS)
371
+ break;
372
+ let metadata = null;
373
+ try {
374
+ metadata = record(JSON.parse(fs.readFileSync(file, "utf-8")));
375
+ } catch {
376
+ metadata = null;
377
+ }
378
+ if (!metadata || text(metadata.agent) !== agentName)
379
+ continue;
380
+ const stat = fs.statSync(file);
381
+ const at = isoTime(metadata.timestamp ?? stat.mtimeMs);
382
+ if (!withinAge(at))
383
+ continue;
384
+ const outputPath = file.replace(/_meta\.json$/, "_output.md");
385
+ const outputTail = fs.existsSync(outputPath) ? tailBytes(fs.readFileSync(outputPath, "utf-8"), MAX_ITEM_BYTES) : void 0;
386
+ pushCapped(items, {
387
+ id: `artifact:${path.basename(file, "_meta.json")}`,
388
+ source: outputTail ? "artifact-output" : "artifact-metadata",
389
+ ...text(metadata.runId) ? { runId: text(metadata.runId) } : {},
390
+ agent: agentName,
391
+ ...at ? { at } : {},
392
+ status: typeof metadata.exitCode === "number" ? metadata.exitCode === 0 ? "completed" : "failed" : void 0,
393
+ ...text(metadata.model) ? { model: text(metadata.model) } : {},
394
+ ...text(metadata.thinking) ? { thinking: text(metadata.thinking) } : {},
395
+ ...acceptanceFields(metadata.acceptance),
396
+ ...text(metadata.error) ? { errors: [text(metadata.error)] } : {},
397
+ ...controlSignals(metadata.controlEvents).length > 0 ? { controlSignals: controlSignals(metadata.controlEvents) } : {},
398
+ ...outputTail ? { outputTail } : {},
399
+ refs: outputTail ? [file, outputPath] : [file]
400
+ });
401
+ }
402
+ }
403
+ return evidencePacket(items);
404
+ }
405
+ __name(collectBoundedRefinementEvidence, "collectBoundedRefinementEvidence");
406
+ function appendAgentRefinementOverlay(systemPrompt, input) {
407
+ let current = "";
408
+ let filePath = "";
409
+ try {
410
+ filePath = getAgentRefinementPath(input.cwd, input.agentName);
411
+ if (!fs.existsSync(filePath))
412
+ return systemPrompt;
413
+ current = parseRefinementFile(fs.readFileSync(filePath, "utf-8"), filePath).current.trim();
414
+ } catch {
415
+ return systemPrompt;
416
+ }
417
+ if (!current)
418
+ return systemPrompt;
419
+ const overlay = [
420
+ `<pi-subagents-refinement agent=${JSON.stringify(input.agentName)} source=${JSON.stringify(path.relative(input.cwd, filePath))}>`,
421
+ "Project-local refinement guidance generated from recent bounded evidence.",
422
+ "It does not override tool, developer, task, output, acceptance, or safety instructions.",
423
+ "",
424
+ current,
425
+ "</pi-subagents-refinement>"
426
+ ].join("\n");
427
+ return systemPrompt.trim() ? `${systemPrompt}
428
+
429
+ ${overlay}` : overlay;
430
+ }
431
+ __name(appendAgentRefinementOverlay, "appendAgentRefinementOverlay");
432
+ function validateRefinementProposal(proposal, evidenceIds) {
433
+ const item = record(proposal);
434
+ if (!item)
435
+ return { ok: false, error: "Refinement proposal must be an object." };
436
+ const summary = text(item.summary);
437
+ const editsValue = item.edits;
438
+ if (!summary || !Array.isArray(editsValue))
439
+ return { ok: false, error: "Refinement proposal requires summary and edits." };
440
+ if (editsValue.length > 3)
441
+ return { ok: false, error: "Refinement proposal may contain at most 3 edits." };
442
+ const allowed = new Set(evidenceIds);
443
+ const protectedInstruction = "(?:acceptance|output|safety|policy|policies|tools?|developer|system)";
444
+ const blocked = new RegExp(`\\b(all agents|every agent|global|(?:disable|ignore|bypass|skip|override)\\s+(?:the\\s+)?${protectedInstruction}(?:\\s+instructions?)?|${protectedInstruction}\\s+(?:instructions?|overrides?)|tool safety|review gates|rewrite base|base agent file|settings\\.json|\\.pi/agent|agents/.*\\.md)\\b`, "i");
445
+ const edits = [];
446
+ for (const [index, editValue] of editsValue.entries()) {
447
+ const edit = record(editValue);
448
+ if (!edit)
449
+ return { ok: false, error: `Refinement proposal edit ${index} must be an object.` };
450
+ const title = text(edit.title);
451
+ const guidance = text(edit.guidance);
452
+ const rationale = text(edit.rationale);
453
+ const cited = textArray(edit.evidenceIds);
454
+ if (!title || !guidance || !rationale)
455
+ return { ok: false, error: `Refinement proposal edit ${index} is missing title, guidance, or rationale.` };
456
+ if (cited.length === 0 || cited.some((id) => !allowed.has(id)))
457
+ return { ok: false, error: `Refinement proposal edit ${index} must cite known evidence ids.` };
458
+ if (guidance.includes("```") || guidance.includes("</pi-subagents-refinement>") || blocked.test(guidance))
459
+ return { ok: false, error: `Refinement proposal edit ${index} contains disallowed guidance.` };
460
+ edits.push({ title, guidance, rationale, evidenceIds: cited });
461
+ }
462
+ return { ok: true, proposal: { summary, edits, rejectedIdeas: textArray(item.rejectedIdeas), residualRisks: textArray(item.residualRisks) } };
463
+ }
464
+ __name(validateRefinementProposal, "validateRefinementProposal");
465
+ function proposalSchema() {
466
+ return {
467
+ type: "object",
468
+ additionalProperties: false,
469
+ required: ["summary", "edits", "residualRisks"],
470
+ properties: {
471
+ summary: { type: "string" },
472
+ edits: {
473
+ type: "array",
474
+ maxItems: 3,
475
+ items: {
476
+ type: "object",
477
+ additionalProperties: false,
478
+ required: ["title", "guidance", "evidenceIds", "rationale"],
479
+ properties: {
480
+ title: { type: "string" },
481
+ guidance: { type: "string" },
482
+ evidenceIds: { type: "array", items: { type: "string" }, minItems: 1 },
483
+ rationale: { type: "string" }
484
+ }
485
+ }
486
+ },
487
+ rejectedIdeas: { type: "array", items: { type: "string" } },
488
+ residualRisks: { type: "array", items: { type: "string" } }
489
+ }
490
+ };
491
+ }
492
+ __name(proposalSchema, "proposalSchema");
493
+ function proposalFromChild(child) {
494
+ for (const entry of child.details?.results ?? []) {
495
+ if (entry.structuredOutput !== void 0)
496
+ return entry.structuredOutput;
497
+ }
498
+ const output = child.details?.results?.map((entry) => entry.finalOutput ?? "").find((entry) => entry.trim().length > 0) ?? child.content?.map((entry) => entry.text ?? "").find((entry) => entry.trim().length > 0) ?? "";
499
+ const jsonMatch = output.match(/```(?:json)?\n([\s\S]*?)\n```/) ?? output.match(/({[\s\S]*})/);
500
+ if (!jsonMatch?.[1])
501
+ return null;
502
+ try {
503
+ return JSON.parse(jsonMatch[1]);
504
+ } catch {
505
+ return null;
506
+ }
507
+ }
508
+ __name(proposalFromChild, "proposalFromChild");
509
+ function proposalTask(agent, current, evidence) {
510
+ return [
511
+ `You are a fresh read-only proposal child for project-local refinement of one subagent: ${agent.name}.`,
512
+ "Do not read files. Do not use write, edit, or shell tools. Use only the evidence packet below.",
513
+ "Propose at most 2-3 minimal overlay guidance edits.",
514
+ "Each edit must cite one or more evidence ids from the packet.",
515
+ "Do not propose base agent file, settings, global, automatic, tool, safety, output, acceptance, developer, or system instruction changes.",
516
+ "Return only structured output that matches the schema.",
517
+ "",
518
+ "Agent metadata:",
519
+ JSON.stringify({ name: agent.name, source: agent.source, filePath: agent.filePath, basePromptSha256: hashPrompt(agent.systemPrompt) }, null, 2),
520
+ "",
521
+ "Current overlay:",
522
+ current.trim() || "(none)",
523
+ "",
524
+ "Evidence packet:",
525
+ JSON.stringify(evidence, null, 2)
526
+ ].join("\n");
527
+ }
528
+ __name(proposalTask, "proposalTask");
529
+ function guidanceFromProposal(proposal) {
530
+ return proposal.edits.map((edit) => `- ${edit.guidance.trim()}`).join("\n");
531
+ }
532
+ __name(guidanceFromProposal, "guidanceFromProposal");
533
+ function resolveOneAgent(cwd, agentName) {
534
+ const discovered = discoverAgents(cwd, "both");
535
+ const resolved = resolveAgentName(agentName, discovered.agents);
536
+ if (resolved.error)
537
+ return { ok: false, error: resolved.error };
538
+ if (!resolved.agent)
539
+ return { ok: false, error: formatUnknownAgentError(agentName, unknownAgentDiagnosticContext(discovered)) };
540
+ return { ok: true, agent: resolved.agent };
541
+ }
542
+ __name(resolveOneAgent, "resolveOneAgent");
543
+ async function handleRefinementAction(action, params, ctx) {
544
+ const requestedAgent = params.agent?.trim();
545
+ if (!requestedAgent)
546
+ return result(`${action} requires agent. Use /subagents-refine <agent> or subagent({ action: "${action}", agent: "<agent>" }).`, true);
547
+ let resolved;
548
+ try {
549
+ resolved = resolveOneAgent(ctx.cwd, requestedAgent);
550
+ } catch (error) {
551
+ return result(error instanceof Error ? error.message : String(error), true);
552
+ }
553
+ if (!resolved.ok)
554
+ return result(resolved.error, true);
555
+ const agent = resolved.agent;
556
+ let existing;
557
+ try {
558
+ existing = readExisting(ctx.cwd, agent.name);
559
+ } catch (error) {
560
+ return result(error instanceof Error ? error.message : String(error), true);
561
+ }
562
+ if (action === "refine.show") {
563
+ if (!existing.parsed)
564
+ return result(`No refinement overlay exists for '${agent.name}'.`);
565
+ const currentDigest = hashPrompt(agent.systemPrompt);
566
+ const drift = existing.parsed.metadata.base.systemPromptSha256 === currentDigest ? "no" : "yes";
567
+ const history = existing.parsed.snapshots.slice(-5).map((snapshot2) => `- r${snapshot2.revision} ${snapshot2.action} at ${snapshot2.at} (${snapshot2.evidenceIds.length} evidence id${snapshot2.evidenceIds.length === 1 ? "" : "s"})`).join("\n") || "- none";
568
+ return result([
569
+ `Refinement overlay for '${agent.name}'`,
570
+ `Path: ${existing.path}`,
571
+ `Revision: ${existing.parsed.metadata.revision}`,
572
+ `Updated: ${existing.parsed.metadata.updatedAt}`,
573
+ `Base: ${existing.parsed.metadata.base.source} ${existing.parsed.metadata.base.filePath}`,
574
+ `Base prompt changed since overlay: ${drift}`,
575
+ "",
576
+ "Current guidance:",
577
+ existing.parsed.current.trim() || "(empty)",
578
+ "",
579
+ "Recent history:",
580
+ history
581
+ ].join("\n"));
582
+ }
583
+ if (action === "refine.rollback") {
584
+ if (!existing.parsed)
585
+ return result(`No refinement overlay exists for '${agent.name}'.`, true);
586
+ const latest = existing.parsed.snapshots.at(-1);
587
+ if (!latest)
588
+ return result(`No refinement snapshot exists for '${agent.name}'.`, true);
589
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
590
+ const nextRevision2 = existing.parsed.metadata.revision + 1;
591
+ const next2 = {
592
+ metadata: metadataFor(agent, nextRevision2, now2),
593
+ current: latest.before,
594
+ snapshots: [...existing.parsed.snapshots, { revision: nextRevision2, at: now2, action: "rollback", before: existing.parsed.current, after: latest.before, evidenceIds: latest.evidenceIds }]
595
+ };
596
+ try {
597
+ writeRefinementFile(existing.path, next2);
598
+ } catch (error) {
599
+ return result(error instanceof Error ? error.message : String(error), true);
600
+ }
601
+ return result(`Rolled back refinement overlay for '${agent.name}' to revision ${nextRevision2}.
602
+ Path: ${existing.path}`);
603
+ }
604
+ const evidence = collectBoundedRefinementEvidence(ctx.cwd, agent.name, ctx.state);
605
+ if (evidence.length === 0)
606
+ return result(`No bounded recent evidence was found for '${agent.name}'. No proposal child was launched and no overlay was written.`);
607
+ const current = existing.parsed?.current ?? "";
608
+ const child = await ctx.launchProposalChild(proposalTask(agent, current, evidence), proposalSchema(), ctx.signal);
609
+ if (child.isError)
610
+ return result(`Refinement proposal child failed. No overlay was written.`, true);
611
+ const validation = validateRefinementProposal(proposalFromChild(child), evidence.map((item) => item.id));
612
+ if (!validation.ok)
613
+ return result(`${validation.error} No overlay was written.`, true);
614
+ if (validation.proposal.edits.length === 0)
615
+ return result(`The proposal child returned no edits for '${agent.name}'. No overlay was written.`);
616
+ const now = (/* @__PURE__ */ new Date()).toISOString();
617
+ const nextRevision = (existing.parsed?.metadata.revision ?? 0) + 1;
618
+ const after = guidanceFromProposal(validation.proposal);
619
+ const snapshot = {
620
+ revision: nextRevision,
621
+ at: now,
622
+ action: "refine",
623
+ before: current,
624
+ after,
625
+ evidenceIds: [...new Set(validation.proposal.edits.flatMap((edit) => edit.evidenceIds))],
626
+ proposalAgent: PROPOSAL_AGENT
627
+ };
628
+ const next = {
629
+ metadata: metadataFor(agent, nextRevision, now),
630
+ current: after,
631
+ snapshots: [...existing.parsed?.snapshots ?? [], snapshot]
632
+ };
633
+ try {
634
+ writeRefinementFile(existing.path, next);
635
+ } catch (error) {
636
+ return result(error instanceof Error ? error.message : String(error), true);
637
+ }
638
+ return result([
639
+ `Wrote refinement overlay for '${agent.name}' at revision ${nextRevision}.`,
640
+ `Path: ${existing.path}`,
641
+ `Evidence items: ${evidence.length}`,
642
+ `Edits: ${validation.proposal.edits.length}`
643
+ ].join("\n"));
644
+ }
645
+ __name(handleRefinementAction, "handleRefinementAction");
646
+
647
+ // node_modules/pi-subagents/src/runs/shared/subagent-prompt-runtime.js?ext=pi-subagents
648
+ import { createHash as createHash2 } from "node:crypto";
649
+ import * as fs2 from "node:fs";
650
+ import * as path2 from "node:path";
651
+
652
+ // node_modules/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.js?ext=pi-subagents
653
+ var RUNTIME_EXTENSION_ACK_EVENT = "subagent:acknowledge-extension";
654
+ var MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_IDS = 32;
655
+ var MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_ID_LENGTH = 128;
656
+ function isRuntimeAcknowledgedExtensionId(value) {
657
+ return typeof value === "string" && value.length > 0 && value.length <= MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_ID_LENGTH && /^[A-Za-z0-9._:@+-]+$/.test(value) && !value.includes("..") && !value.includes("/") && !value.includes("\\");
658
+ }
659
+ __name(isRuntimeAcknowledgedExtensionId, "isRuntimeAcknowledgedExtensionId");
660
+ function projectRuntimeAcknowledgedExtensions(ids) {
661
+ const unique = [];
662
+ const seen = /* @__PURE__ */ new Set();
663
+ for (const id of ids) {
664
+ if (!isRuntimeAcknowledgedExtensionId(id) || seen.has(id))
665
+ continue;
666
+ seen.add(id);
667
+ unique.push(id);
668
+ }
669
+ if (unique.length === 0)
670
+ return void 0;
671
+ return {
672
+ version: 1,
673
+ source: "child-runtime",
674
+ ids: unique.slice(0, MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_IDS),
675
+ omitted: Math.max(0, unique.length - MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_IDS)
676
+ };
677
+ }
678
+ __name(projectRuntimeAcknowledgedExtensions, "projectRuntimeAcknowledgedExtensions");
679
+
680
+ // node_modules/pi-subagents/src/runs/shared/tool-availability.js?ext=pi-subagents
681
+ function formatChildToolDiagnostic(diagnostic, options = {}) {
682
+ const subject = diagnostic.agent ? `Agent '${diagnostic.agent}'` : "Subagent";
683
+ if (options.host === "parent") {
684
+ return [
685
+ `${subject} ran as a foreground child, which never loads the parent's ambient extensions, and these child tools were unavailable: ${diagnostic.missing.join(", ")}.`,
686
+ "The `tools` field is a strict allowlist; it does not load extension code.",
687
+ ...diagnostic.missingMcpDirectTools?.length ? [`MCP direct tools missing from the child registry: ${diagnostic.missingMcpDirectTools.join(", ")}.`] : [],
688
+ "MCP tools require background children (`async: true`) because only they load ambient extensions.",
689
+ "For extension tools a foreground child can load, add the provider path to `subagentOnlyExtensions` (child-only), `extensions`, or as a path-like entry in `tools`, while keeping each registered tool name in `tools`."
690
+ ].join("\n");
691
+ }
692
+ return [
693
+ `${subject} requested unavailable child tools: ${diagnostic.missing.join(", ")}.`,
694
+ "The `tools` field is a strict allowlist; it does not load extension code.",
695
+ ...diagnostic.missingMcpDirectTools?.length ? [`Resolved MCP direct tools missing from the child registry: ${diagnostic.missingMcpDirectTools.join(", ")}. Resolved names must match what the host or pi-mcp-adapter registers; check the MCP direct-tool registration before treating this as a tool-call failure.`] : [],
696
+ "For extension tools, add the provider path to `subagentOnlyExtensions` (child-only), `extensions`, or as a path-like entry in `tools`, while keeping each registered tool name in `tools`.",
697
+ "For MCP tools, verify the MCP adapter configuration and selected tool names. For builtin tools, verify the name against the installed Pi version."
698
+ ].join("\n");
699
+ }
700
+ __name(formatChildToolDiagnostic, "formatChildToolDiagnostic");
701
+
702
+ // node_modules/pi-subagents/src/watchdog/register-child.js?ext=pi-subagents
703
+ function childResolvedConfig(config) {
704
+ return {
705
+ ...DEFAULT_WATCHDOG_CONFIG,
706
+ enabled: true,
707
+ agentEndTimeoutMs: config.agentEndTimeoutMs,
708
+ maxWarnings: config.maxWarnings,
709
+ main: {
710
+ enabled: true,
711
+ ...config.model ? { model: config.model } : {},
712
+ ...config.thinking !== void 0 ? { thinking: config.thinking } : {}
713
+ },
714
+ stalemateRepeats: config.stalemateRepeats,
715
+ cadence: { ...config.cadence },
716
+ children: {
717
+ ...DEFAULT_WATCHDOG_CONFIG.children,
718
+ watchdogTailTimeoutMs: config.watchdogTailTimeoutMs
719
+ },
720
+ lsp: { ...config.lsp }
721
+ };
722
+ }
723
+ __name(childResolvedConfig, "childResolvedConfig");
724
+ function childWarningDetails(details, config) {
725
+ return {
726
+ ...details,
727
+ source: details.source === "lsp" ? "lsp" : "child",
728
+ ...config.agent ? { agent: config.agent } : {},
729
+ ...config.runId ? { runId: config.runId } : {}
730
+ };
731
+ }
732
+ __name(childWarningDetails, "childWarningDetails");
733
+ function registerChildWatchdog(pi, childConfig, writeStatus, structuredTerminal) {
734
+ if (!childConfig)
735
+ return void 0;
736
+ if (!writeStatus)
737
+ throw new Error("Child watchdog status sink is missing; the host must pass ChildRuntimeConfig.watchdogStatus.");
738
+ let currentContext;
739
+ let diffBaseline;
740
+ let agentSettled = false;
741
+ let seq = 0;
742
+ const emitStatus = /* @__PURE__ */ __name((phase, reason, warning) => {
743
+ writeStatus({
744
+ type: CHILD_WATCHDOG_STATUS_EVENT,
745
+ ...childConfig.runId ? { runId: childConfig.runId } : {},
746
+ ...childConfig.agent ? { agent: childConfig.agent } : {},
747
+ ...childConfig.childIndex !== void 0 ? { childIndex: childConfig.childIndex, stepIndex: childConfig.childIndex } : {},
748
+ seq: ++seq,
749
+ phase,
750
+ ts: Date.now(),
751
+ ...reason ? { reason } : {},
752
+ ...warning ? { warning } : {}
753
+ });
754
+ }, "emitStatus");
755
+ const resolved = childResolvedConfig(childConfig);
756
+ const runtime = new MainWatchdogRuntime({
757
+ resolveConfig: /* @__PURE__ */ __name(() => ({ ok: true, config: resolved, errors: [], sources: [{ scope: "session", exists: true }] }), "resolveConfig"),
758
+ review: createMainWatchdogReview(() => currentContext, { getThinkingLevel: /* @__PURE__ */ __name(() => pi.getThinkingLevel(), "getThinkingLevel"), diffBaseline: /* @__PURE__ */ __name(() => diffBaseline, "diffBaseline") }),
759
+ reviewDescription: "child model review",
760
+ reviewChangesOnly: true,
761
+ displayWarning: /* @__PURE__ */ __name((details, options) => {
762
+ const childDetails = childWarningDetails(details, childConfig);
763
+ emitStatus("reviewing", void 0, { severity: childDetails.severity, importance: childDetails.importance, category: childDetails.category, summary: childDetails.summary, evidence: childDetails.evidence, recommendedAction: childDetails.recommendedAction, ...childDetails.displayedAt ? { displayedAt: childDetails.displayedAt } : {}, addressed: false, stalemate: childDetails.state === "stalemate" });
764
+ const message = createWatchdogWarningMessage(childDetails, { display: true, details: childDetails });
765
+ if (agentSettled)
766
+ pi.appendEntry(SUBAGENT_WATCHDOG_WARNING_TYPE, childDetails);
767
+ else
768
+ pi.sendMessage(message, options);
769
+ }, "displayWarning"),
770
+ displayUserWarning: /* @__PURE__ */ __name((details) => {
771
+ const childDetails = childWarningDetails(details, childConfig);
772
+ emitStatus("reviewing", void 0, { severity: childDetails.severity, importance: childDetails.importance, category: childDetails.category, summary: childDetails.summary, evidence: childDetails.evidence, recommendedAction: childDetails.recommendedAction, ...childDetails.displayedAt ? { displayedAt: childDetails.displayedAt } : {}, addressed: false, stalemate: childDetails.state === "stalemate" });
773
+ pi.appendEntry(SUBAGENT_WATCHDOG_WARNING_TYPE, childDetails);
774
+ }, "displayUserWarning")
775
+ });
776
+ const rememberContext = /* @__PURE__ */ __name((ctx) => {
777
+ currentContext = ctx;
778
+ }, "rememberContext");
779
+ const onRuntimeEvent = pi.on;
780
+ onRuntimeEvent("session_start", (_event, ctx) => {
781
+ rememberContext(ctx);
782
+ diffBaseline = startWatchdogDiffBaselineCapture(ctx.cwd);
783
+ runtime.bindSession(ctx);
784
+ emitStatus("idle");
785
+ });
786
+ onRuntimeEvent("before_agent_start", (event, ctx) => {
787
+ agentSettled = false;
788
+ rememberContext(ctx);
789
+ runtime.handleBeforeAgentStart(event, ctx);
790
+ });
791
+ onRuntimeEvent("turn_end", (event, ctx) => {
792
+ rememberContext(ctx);
793
+ runtime.handleTurnEnd(event, ctx, structuredTerminal?.captured === true);
794
+ });
795
+ onRuntimeEvent("tool_result", (_event, ctx) => {
796
+ rememberContext(ctx);
797
+ runtime.handleToolResult(ctx);
798
+ });
799
+ onRuntimeEvent("agent_end", async (event, ctx) => {
800
+ rememberContext(ctx);
801
+ emitStatus("reviewing");
802
+ await runtime.handleAgentEnd(event, ctx);
803
+ const snapshot = runtime.getSnapshot(ctx.cwd);
804
+ if (snapshot.status === "failed")
805
+ emitStatus("failed", snapshot.lastError);
806
+ else if (snapshot.status === "stale")
807
+ emitStatus("stale", "review stale");
808
+ else
809
+ emitStatus("idle");
810
+ });
811
+ onRuntimeEvent("agent_settled", () => {
812
+ agentSettled = true;
813
+ });
814
+ onRuntimeEvent("session_shutdown", () => {
815
+ currentContext = void 0;
816
+ runtime.dispose();
817
+ emitStatus("idle");
818
+ });
819
+ return runtime;
820
+ }
821
+ __name(registerChildWatchdog, "registerChildWatchdog");
822
+
823
+ // node_modules/pi-subagents/src/watchdog/permission-arbiter.js?ext=pi-subagents
824
+ var PermissionDecisionParams = typebox_exports.Object({
825
+ decision: typebox_exports.String({ enum: ["approve", "deny"] }),
826
+ reason: typebox_exports.String({ description: "One concise reason for this exact decision." })
827
+ }, { additionalProperties: false });
828
+ function conciseReason(value) {
829
+ const trimmed = value.trim();
830
+ return trimmed ? trimmed.slice(0, 500) : "Watchdog returned an empty reason.";
831
+ }
832
+ __name(conciseReason, "conciseReason");
833
+ function createWatchdogPermissionArbiter(options = {}) {
834
+ return async (request) => {
835
+ const preview = permissionArgsPreview(request.args);
836
+ const createdAt = Date.now();
837
+ const auditBase = { type: "permission.request", createdAt, toolName: request.toolName, preview, matchedRule: "ask", decisionSource: "watchdog" };
838
+ appendPermissionAudit(request.auditPath, auditBase);
839
+ let completed = false;
840
+ const finish = /* @__PURE__ */ __name((approved, reason, decision2) => {
841
+ const concise = conciseReason(reason);
842
+ if (completed)
843
+ return { approved, reason: concise, source: "watchdog" };
844
+ completed = true;
845
+ appendPermissionAudit(request.auditPath, {
846
+ type: "permission.decision",
847
+ createdAt: Date.now(),
848
+ requestCreatedAt: createdAt,
849
+ toolName: request.toolName,
850
+ decision: decision2,
851
+ approved,
852
+ decisionSource: "watchdog",
853
+ reason: concise
854
+ });
855
+ return { approved, reason: concise, source: "watchdog" };
856
+ }, "finish");
857
+ let childConfig;
858
+ try {
859
+ childConfig = decodeChildWatchdogConfig(request.rawWatchdogConfig);
860
+ } catch (error) {
861
+ const reason = error instanceof Error ? error.message : String(error);
862
+ return finish(false, `Watchdog permission arbiter configuration is invalid: ${reason}`, "unavailable");
863
+ }
864
+ if (!childConfig)
865
+ return finish(false, "Watchdog permission arbiter is unavailable because the child watchdog is disabled.", "unavailable");
866
+ if (request.signal?.aborted || request.ctx.signal?.aborted)
867
+ return finish(false, "Watchdog permission decision was cancelled.", "cancelled");
868
+ let decision;
869
+ const tool = {
870
+ name: "watchdog_permission_decision",
871
+ label: "Watchdog permission decision",
872
+ description: "Approve or deny this exact child tool call. Call exactly once.",
873
+ parameters: PermissionDecisionParams,
874
+ executionMode: "sequential",
875
+ async execute(_toolCallId, params) {
876
+ if (!decision)
877
+ decision = params;
878
+ return { content: [{ type: "text", text: "Permission decision recorded." }], details: { recorded: true } };
879
+ }
880
+ };
881
+ let timeout;
882
+ let agent;
883
+ let abort;
884
+ try {
885
+ const run = /* @__PURE__ */ __name(async () => {
886
+ const config = childResolvedConfig(childConfig);
887
+ const selection = await resolveWatchdogReviewModel(request.ctx, config);
888
+ const auth = selection.auth;
889
+ const sessionId = request.ctx.sessionManager.getSessionId();
890
+ const baseStreamFn = options.streamFn ?? ((model, context, streamOptions) => request.ctx.modelRegistry.streamSimple(model, context, streamOptions));
891
+ const streamFn = /* @__PURE__ */ __name((model, context, streamOptions) => baseStreamFn(model, context, {
892
+ ...streamOptions,
893
+ ...auth.apiKey ? { apiKey: auth.apiKey } : {},
894
+ env: auth.env || streamOptions?.env ? { ...auth.env ?? {}, ...streamOptions?.env ?? {} } : void 0,
895
+ headers: { ...opencodeSessionHeaders(model, sessionId), ...streamOptions?.headers ?? {}, ...auth.headers ?? {} }
896
+ }), "streamFn");
897
+ const systemPrompt = [
898
+ "You are the pi-subagents watchdog permission arbiter.",
899
+ "Decide only whether this exact non-bash child tool call should proceed.",
900
+ "Call watchdog_permission_decision exactly once with approve or deny and a concise reason.",
901
+ "Deny when uncertain. Do not produce freeform advice or ask the parent orchestrator.",
902
+ "",
903
+ formatWatchdogCwdSection(request.ctx.cwd)
904
+ ].join("\n");
905
+ const tools = [tool];
906
+ agent = new Agent({
907
+ initialState: {
908
+ systemPrompt,
909
+ model: selection.model,
910
+ thinkingLevel: selection.thinkingLevel,
911
+ tools
912
+ },
913
+ convertToLlm,
914
+ ...agentStreamOptions(streamFn),
915
+ getApiKey: /* @__PURE__ */ __name((providerName) => providerName === selection.model.provider ? auth.apiKey : void 0, "getApiKey"),
916
+ beforeToolCall: /* @__PURE__ */ __name(async ({ toolCall }) => toolCall.name === tool.name ? void 0 : { block: true, reason: `Permission arbiter tool '${toolCall.name}' is not allowed.` }, "beforeToolCall"),
917
+ toolExecution: "sequential"
918
+ });
919
+ await agent.prompt(`Tool: ${request.toolName}
920
+ Redacted arguments: ${preview}`);
921
+ if (!decision)
922
+ return finish(false, "Watchdog permission arbiter returned no decision.", "malformed");
923
+ const approved = decision.decision === "approve";
924
+ return finish(approved, decision.reason, decision.decision);
925
+ }, "run");
926
+ return await Promise.race([
927
+ run(),
928
+ new Promise((resolve3) => {
929
+ timeout = setTimeout(() => {
930
+ agent?.abort();
931
+ resolve3(finish(false, "Watchdog permission decision timed out.", "timeout"));
932
+ }, childConfig.agentEndTimeoutMs);
933
+ }),
934
+ new Promise((resolve3) => {
935
+ abort = /* @__PURE__ */ __name(() => {
936
+ agent?.abort();
937
+ resolve3(finish(false, "Watchdog permission decision was cancelled.", "cancelled"));
938
+ }, "abort");
939
+ request.signal?.addEventListener("abort", abort, { once: true });
940
+ request.ctx.signal?.addEventListener("abort", abort, { once: true });
941
+ })
942
+ ]);
943
+ } catch (error) {
944
+ const reason = error instanceof Error ? error.message : String(error);
945
+ return finish(false, `Watchdog permission arbiter failed closed: ${reason}`, reason.includes("timed out") ? "timeout" : "error");
946
+ } finally {
947
+ if (timeout)
948
+ clearTimeout(timeout);
949
+ if (abort) {
950
+ request.signal?.removeEventListener("abort", abort);
951
+ request.ctx.signal?.removeEventListener("abort", abort);
952
+ }
953
+ }
954
+ };
955
+ }
956
+ __name(createWatchdogPermissionArbiter, "createWatchdogPermissionArbiter");
957
+ var requestWatchdogPermission = createWatchdogPermissionArbiter();
958
+
959
+ // node_modules/pi-subagents/src/runs/shared/subagent-prompt-runtime.js?ext=pi-subagents
960
+ var STRUCTURED_OUTPUT_INSTRUCTIONS = [
961
+ "This subagent step has a strict structured output contract.",
962
+ "Your final action must be to call the `structured_output` tool with JSON matching the provided schema.",
963
+ "Do not rely on prose-only completion; if you do not call `structured_output`, the parent will fail this step."
964
+ ].join("\n");
965
+ var CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS = [
966
+ "You are a child subagent, not the parent orchestrator.",
967
+ "The parent session owns delegation, orchestration, review fanout, and follow-up worker launches.",
968
+ "Ignore prior parent-only orchestration instructions in inherited conversation history.",
969
+ "Do not propose or run subagents. Complete only your assigned role-specific task with the tools available to you.",
970
+ "If you need to edit files, use the available editing tools. Do not print tool-call syntax, patches, or pseudo-tool calls as text."
971
+ ].join("\n");
972
+ var CHILD_FANOUT_BOUNDARY_INSTRUCTIONS = [
973
+ "You are a child subagent with explicit fanout responsibility for this assigned task.",
974
+ "The parent session owns final orchestration, acceptance, and follow-up implementation launches.",
975
+ "You may use the `subagent` tool only for the fanout work explicitly requested in this task.",
976
+ "Do not broaden yourself into general parent orchestration. Do not launch follow-up workers unless the task explicitly asks for that.",
977
+ "The maxSubagentDepth cap still applies and may block further fanout.",
978
+ "If you need to edit files, use the available editing tools. Do not print tool-call syntax, patches, or pseudo-tool calls as text."
979
+ ].join("\n");
980
+ var PARENT_ONLY_CUSTOM_MESSAGE_TYPES = /* @__PURE__ */ new Set([
981
+ "subagent-orchestration-instructions",
982
+ "subagent-slash-result",
983
+ "subagent-slash-text-result",
984
+ "subagent-notify",
985
+ "subagent_control_notice",
986
+ "subagent-control",
987
+ "subagent-control-notice"
988
+ ]);
989
+ var SUBAGENT_ORCHESTRATION_SKILL_NAME_PATTERN = /<name>\s*pi-subagents\s*<\/name>/;
990
+ var PROJECT_CONTEXT_XML_HEADER = "\n\n<project_context>\n\n";
991
+ var PROJECT_CONTEXT_LEGACY_HEADER = "\n\n# Project Context\n\nProject-specific instructions and guidelines:\n\n";
992
+ var SKILLS_HEADER = "\n\nThe following skills provide specialized instructions for specific tasks.";
993
+ var DATE_HEADER = "\nCurrent date:";
994
+ function registerRuntimeExtensionAcknowledgements(pi, sink) {
995
+ if (!sink)
996
+ return;
997
+ const ids = [];
998
+ let finalized = false;
999
+ const acknowledge = /* @__PURE__ */ __name((payload) => {
1000
+ if (finalized || !payload || typeof payload !== "object")
1001
+ return void 0;
1002
+ const id = payload.id;
1003
+ if (isRuntimeAcknowledgedExtensionId(id))
1004
+ ids.push(id);
1005
+ return void 0;
1006
+ }, "acknowledge");
1007
+ const finalize = /* @__PURE__ */ __name(() => {
1008
+ if (finalized)
1009
+ return void 0;
1010
+ finalized = true;
1011
+ sink(ids);
1012
+ return void 0;
1013
+ }, "finalize");
1014
+ try {
1015
+ const events = pi.events;
1016
+ events?.on?.(RUNTIME_EXTENSION_ACK_EVENT, acknowledge);
1017
+ const onRuntimeEvent = pi.on;
1018
+ onRuntimeEvent("agent_end", finalize);
1019
+ onRuntimeEvent("session_shutdown", finalize);
1020
+ } catch {
1021
+ }
1022
+ }
1023
+ __name(registerRuntimeExtensionAcknowledgements, "registerRuntimeExtensionAcknowledgements");
1024
+ function findSectionEnd(prompt, startIndex, nextHeaders) {
1025
+ let endIndex = prompt.length;
1026
+ for (const header of nextHeaders) {
1027
+ const index = prompt.indexOf(header, startIndex);
1028
+ if (index !== -1 && index < endIndex) {
1029
+ endIndex = index;
1030
+ }
1031
+ }
1032
+ return endIndex;
1033
+ }
1034
+ __name(findSectionEnd, "findSectionEnd");
1035
+ function stripProjectContext(prompt) {
1036
+ const xmlStartIndex = prompt.indexOf(PROJECT_CONTEXT_XML_HEADER);
1037
+ if (xmlStartIndex !== -1) {
1038
+ const closingTag = "</project_context>";
1039
+ const closingIndex = prompt.indexOf(closingTag, xmlStartIndex + PROJECT_CONTEXT_XML_HEADER.length);
1040
+ if (closingIndex !== -1) {
1041
+ return `${prompt.slice(0, xmlStartIndex)}${prompt.slice(closingIndex + closingTag.length)}`;
1042
+ }
1043
+ }
1044
+ const legacyStartIndex = prompt.indexOf(PROJECT_CONTEXT_LEGACY_HEADER);
1045
+ if (legacyStartIndex === -1)
1046
+ return prompt;
1047
+ const endIndex = findSectionEnd(prompt, legacyStartIndex + PROJECT_CONTEXT_LEGACY_HEADER.length, [SKILLS_HEADER, DATE_HEADER]);
1048
+ return `${prompt.slice(0, legacyStartIndex)}${prompt.slice(endIndex)}`;
1049
+ }
1050
+ __name(stripProjectContext, "stripProjectContext");
1051
+ var GLOBAL_CONTEXT_FILE_NAMES = /* @__PURE__ */ new Set(["agents.md", "agents.override.md", "claude.md"]);
1052
+ function canonicalDirectory(dir) {
1053
+ try {
1054
+ return fs2.realpathSync(dir);
1055
+ } catch {
1056
+ return path2.resolve(dir);
1057
+ }
1058
+ }
1059
+ __name(canonicalDirectory, "canonicalDirectory");
1060
+ function expandContextPath(filePath) {
1061
+ const home = process.env.HOME ?? process.env.USERPROFILE;
1062
+ return filePath === "~" ? home ?? filePath : /^~[\\/]/.test(filePath) ? path2.join(home ?? "~", filePath.slice(2)) : filePath;
1063
+ }
1064
+ __name(expandContextPath, "expandContextPath");
1065
+ function isContextFilePath(filePath) {
1066
+ return GLOBAL_CONTEXT_FILE_NAMES.has(path2.basename(expandContextPath(filePath)).toLowerCase());
1067
+ }
1068
+ __name(isContextFilePath, "isContextFilePath");
1069
+ function isGlobalContextFile(filePath) {
1070
+ const expanded = expandContextPath(filePath);
1071
+ if (!isContextFilePath(filePath))
1072
+ return false;
1073
+ return canonicalDirectory(path2.dirname(expanded)) === canonicalDirectory(getAgentDir());
1074
+ }
1075
+ __name(isGlobalContextFile, "isGlobalContextFile");
1076
+ function stripGlobalInstructionsFromXmlContext(context) {
1077
+ const block = /<project_instructions\s+path=(["'])(.*?)\1\s*>[\s\S]*?<\/project_instructions>\s*/gi;
1078
+ return context.replace(block, (match, _quote, filePath) => isGlobalContextFile(filePath) ? "" : match);
1079
+ }
1080
+ __name(stripGlobalInstructionsFromXmlContext, "stripGlobalInstructionsFromXmlContext");
1081
+ function stripGlobalInstructionsFromLegacyContext(context) {
1082
+ const sections = [...context.matchAll(/^## ([^\r\n]+)(?:\r?\n|$)/gm)].filter((match) => isContextFilePath(match[1].trim()));
1083
+ let rewritten = "";
1084
+ let cursor = 0;
1085
+ for (let index = 0; index < sections.length; index++) {
1086
+ const section = sections[index];
1087
+ const start = section.index;
1088
+ const end = sections[index + 1]?.index ?? context.length;
1089
+ rewritten += context.slice(cursor, start);
1090
+ if (!isGlobalContextFile(section[1].trim()))
1091
+ rewritten += context.slice(start, end);
1092
+ cursor = end;
1093
+ }
1094
+ return `${rewritten}${context.slice(cursor)}`;
1095
+ }
1096
+ __name(stripGlobalInstructionsFromLegacyContext, "stripGlobalInstructionsFromLegacyContext");
1097
+ function stripGlobalContext(prompt) {
1098
+ const rewrittenXml = prompt.replace(/<project_context>[\s\S]*?<\/project_context>/gi, (context) => {
1099
+ const rewritten = stripGlobalInstructionsFromXmlContext(context);
1100
+ return /<project_instructions\b/i.test(rewritten) ? rewritten : "";
1101
+ });
1102
+ const legacyStartIndex = rewrittenXml.indexOf(PROJECT_CONTEXT_LEGACY_HEADER);
1103
+ if (legacyStartIndex === -1)
1104
+ return rewrittenXml;
1105
+ const legacyEndIndex = findSectionEnd(rewrittenXml, legacyStartIndex + PROJECT_CONTEXT_LEGACY_HEADER.length, [SKILLS_HEADER, DATE_HEADER]);
1106
+ const legacyContext = rewrittenXml.slice(legacyStartIndex, legacyEndIndex);
1107
+ return `${rewrittenXml.slice(0, legacyStartIndex)}${stripGlobalInstructionsFromLegacyContext(legacyContext)}${rewrittenXml.slice(legacyEndIndex)}`;
1108
+ }
1109
+ __name(stripGlobalContext, "stripGlobalContext");
1110
+ function stripInheritedSkills(prompt) {
1111
+ const startIndex = prompt.indexOf(SKILLS_HEADER);
1112
+ if (startIndex === -1)
1113
+ return prompt;
1114
+ const endIndex = findSectionEnd(prompt, startIndex + SKILLS_HEADER.length, [DATE_HEADER]);
1115
+ return `${prompt.slice(0, startIndex)}${prompt.slice(endIndex)}`;
1116
+ }
1117
+ __name(stripInheritedSkills, "stripInheritedSkills");
1118
+ function stripSubagentOrchestrationSkill(prompt) {
1119
+ return prompt.replace(/\n{0,2}<skill\s+name=["']pi-subagents["'][^>]*>[\s\S]*?<\/skill>\n{0,2}/g, "\n\n").replace(/[ \t]*<skill>\s*[\s\S]*?<\/skill>\s*/g, (block) => SUBAGENT_ORCHESTRATION_SKILL_NAME_PATTERN.test(block) ? "" : block);
1120
+ }
1121
+ __name(stripSubagentOrchestrationSkill, "stripSubagentOrchestrationSkill");
1122
+ function stripChildBoundaryInstructions(prompt) {
1123
+ let rewritten = prompt;
1124
+ for (const instructions of [CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS, CHILD_FANOUT_BOUNDARY_INSTRUCTIONS, STRUCTURED_OUTPUT_INSTRUCTIONS]) {
1125
+ rewritten = rewritten.split(`
1126
+
1127
+ ${instructions}`).join("").split(instructions).join("");
1128
+ }
1129
+ return rewritten.replace(/^(?:[ \t]*\r?\n)+/, "");
1130
+ }
1131
+ __name(stripChildBoundaryInstructions, "stripChildBoundaryInstructions");
1132
+ function stripInheritedPromptText(prompt, options) {
1133
+ let rewritten = prompt;
1134
+ if (!options.inheritProjectContext) {
1135
+ rewritten = stripProjectContext(rewritten);
1136
+ }
1137
+ if (!options.inheritGlobalContext) {
1138
+ rewritten = stripGlobalContext(rewritten);
1139
+ }
1140
+ if (!options.inheritSkills) {
1141
+ rewritten = stripInheritedSkills(rewritten);
1142
+ }
1143
+ return stripChildBoundaryInstructions(stripSubagentOrchestrationSkill(rewritten));
1144
+ }
1145
+ __name(stripInheritedPromptText, "stripInheritedPromptText");
1146
+ function appendChildBoundary(prompt, options) {
1147
+ const boundary = options.fanoutChild ? CHILD_FANOUT_BOUNDARY_INSTRUCTIONS : CHILD_SUBAGENT_BOUNDARY_INSTRUCTIONS;
1148
+ const structured = options.structuredOutput ? `
1149
+
1150
+ ${STRUCTURED_OUTPUT_INSTRUCTIONS}` : "";
1151
+ return `${stripChildBoundaryInstructions(prompt)}
1152
+
1153
+ ${boundary}${structured}`;
1154
+ }
1155
+ __name(appendChildBoundary, "appendChildBoundary");
1156
+ function rewriteSubagentPrompt(prompt, options) {
1157
+ return appendChildBoundary(stripInheritedPromptText(prompt, options), options);
1158
+ }
1159
+ __name(rewriteSubagentPrompt, "rewriteSubagentPrompt");
1160
+ function filterChildPromptOptions(options, inherited) {
1161
+ if (!inherited.inheritProjectContext)
1162
+ options.contextFiles = [];
1163
+ else if (!inherited.inheritGlobalContext)
1164
+ options.contextFiles = options.contextFiles.filter((file) => !isGlobalContextFile(file.path));
1165
+ options.skills = inherited.inheritSkills ? options.skills.filter((skill) => skill.name !== "pi-subagents") : [];
1166
+ if (options.customPrompt)
1167
+ options.customPrompt = stripInheritedPromptText(options.customPrompt, inherited);
1168
+ if (options.appendSystemPrompt)
1169
+ options.appendSystemPrompt = stripInheritedPromptText(options.appendSystemPrompt, inherited);
1170
+ }
1171
+ __name(filterChildPromptOptions, "filterChildPromptOptions");
1172
+ function rewritesChildPrompt(config) {
1173
+ return config.inheritProjectContext !== void 0 || config.inheritGlobalContext !== void 0 || config.inheritSkills !== void 0 || Boolean(config.fanoutChild);
1174
+ }
1175
+ __name(rewritesChildPrompt, "rewritesChildPrompt");
1176
+ function registerSubagentPromptBoundary(pi, config) {
1177
+ if (!rewritesChildPrompt(config))
1178
+ return;
1179
+ pi.on("before_agent_start", (event) => {
1180
+ const finalized = appendChildBoundary(event.systemPrompt, { fanoutChild: config.fanoutChild, structuredOutput: Boolean(config.structuredOutput) });
1181
+ return finalized === event.systemPrompt ? void 0 : { systemPrompt: finalized };
1182
+ });
1183
+ }
1184
+ __name(registerSubagentPromptBoundary, "registerSubagentPromptBoundary");
1185
+ function isParentOnlySubagentMessage(message) {
1186
+ const m = message;
1187
+ if (m?.role !== "custom" || typeof m.customType !== "string")
1188
+ return false;
1189
+ if (m.customType === SUBAGENT_WATCHDOG_WARNING_TYPE)
1190
+ return true;
1191
+ return PARENT_ONLY_CUSTOM_MESSAGE_TYPES.has(m.customType);
1192
+ }
1193
+ __name(isParentOnlySubagentMessage, "isParentOnlySubagentMessage");
1194
+ function isSubagentToolResultMessage(message) {
1195
+ const m = message;
1196
+ return m?.role === "toolResult" && m.toolName === "subagent";
1197
+ }
1198
+ __name(isSubagentToolResultMessage, "isSubagentToolResultMessage");
1199
+ function isSubagentToolCallBlock(block) {
1200
+ const b = block;
1201
+ return b?.type === "toolCall" && b.name === "subagent";
1202
+ }
1203
+ __name(isSubagentToolCallBlock, "isSubagentToolCallBlock");
1204
+ var PORTABLE_TOOL_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
1205
+ var MAX_PORTABLE_TOOL_ID_LENGTH = 64;
1206
+ var COMPOSITE_TOOL_ID_APIS = /* @__PURE__ */ new Set([
1207
+ "azure-openai-responses",
1208
+ "cursor-native",
1209
+ "openai-completions",
1210
+ "openai-responses"
1211
+ ]);
1212
+ var PROMPT_CACHE_KEY_APIS = /* @__PURE__ */ new Set([
1213
+ "azure-openai-responses",
1214
+ "openai-codex-responses",
1215
+ "openai-completions",
1216
+ "openai-responses"
1217
+ ]);
1218
+ var isSystemMessage = /* @__PURE__ */ __name((message) => message.role === "system", "isSystemMessage");
1219
+ var writtenSince = /* @__PURE__ */ __name((message, forkedAt) => typeof message.timestamp === "number" && message.timestamp >= forkedAt, "writtenSince");
1220
+ function toolsDeclaredBefore(messages, forkedAt) {
1221
+ const tools = /* @__PURE__ */ new Map();
1222
+ for (const message of messages) {
1223
+ if (!isSystemMessage(message) || writtenSince(message, forkedAt))
1224
+ continue;
1225
+ for (const tool of message.toolsRemoved ?? [])
1226
+ tools.delete(tool.name);
1227
+ for (const tool of message.toolsAdded ?? [])
1228
+ tools.set(tool.name, tool);
1229
+ }
1230
+ return [...tools.values()];
1231
+ }
1232
+ __name(toolsDeclaredBefore, "toolsDeclaredBefore");
1233
+ function keepInheritedToolDeclarations(messages, inherited, forkedAt) {
1234
+ const older = /* @__PURE__ */ __name((message) => typeof message.timestamp === "number" && message.timestamp < forkedAt, "older");
1235
+ if (inherited.length === 0 || !messages.some(older))
1236
+ return messages;
1237
+ const names = new Set(inherited.map((tool) => tool.name));
1238
+ let changed = false;
1239
+ let next = messages.map((message) => {
1240
+ if (!isSystemMessage(message) || !writtenSince(message, forkedAt) || !message.toolsRemoved?.some((tool) => names.has(tool.name)))
1241
+ return message;
1242
+ changed = true;
1243
+ const { toolsRemoved, ...rest } = message;
1244
+ const kept = toolsRemoved.filter((tool) => !names.has(tool.name));
1245
+ return kept.length > 0 ? { ...rest, toolsRemoved: kept } : rest;
1246
+ });
1247
+ const declared = new Map(toolsDeclaredBefore(next, Number.POSITIVE_INFINITY).map((tool) => [tool.name, tool]));
1248
+ const wanted = [...inherited.map((tool) => declared.get(tool.name) ?? tool), ...[...declared.values()].filter((tool) => !names.has(tool.name))];
1249
+ const order = [...declared.keys()];
1250
+ const head = next[0];
1251
+ if (head && isSystemMessage(head) && wanted.some((tool, index) => order[index] !== tool.name)) {
1252
+ changed = true;
1253
+ const { toolsRemoved: _removed, ...rest } = head;
1254
+ next = [{ ...rest, toolsAdded: wanted }, ...next.slice(1)];
1255
+ }
1256
+ return changed ? next : messages;
1257
+ }
1258
+ __name(keepInheritedToolDeclarations, "keepInheritedToolDeclarations");
1259
+ function rewriteForkCacheProviderRequest(event, ctx, forkCacheKey) {
1260
+ const key = forkCacheKey?.trim();
1261
+ if (!key || !PROMPT_CACHE_KEY_APIS.has(ctx?.model?.api ?? ""))
1262
+ return void 0;
1263
+ if (!event || typeof event !== "object")
1264
+ return void 0;
1265
+ const payload = event.payload;
1266
+ if (!payload || typeof payload !== "object" || Array.isArray(payload))
1267
+ return void 0;
1268
+ if (typeof payload.prompt_cache_key !== "string")
1269
+ return void 0;
1270
+ return { ...payload, prompt_cache_key: key };
1271
+ }
1272
+ __name(rewriteForkCacheProviderRequest, "rewriteForkCacheProviderRequest");
1273
+ function portableToolId(id, preserveBoundedCompositeToolIds = false) {
1274
+ if (PORTABLE_TOOL_ID_PATTERN.test(id) && id.length <= MAX_PORTABLE_TOOL_ID_LENGTH)
1275
+ return id;
1276
+ if (preserveBoundedCompositeToolIds) {
1277
+ const parts = id.split("|");
1278
+ if (parts.length === 2 && parts.every((part) => PORTABLE_TOOL_ID_PATTERN.test(part) && part.length <= MAX_PORTABLE_TOOL_ID_LENGTH))
1279
+ return id;
1280
+ }
1281
+ const encoded = `tool_${Buffer.from(id).toString("base64url") || "empty"}`;
1282
+ if (encoded.length <= MAX_PORTABLE_TOOL_ID_LENGTH)
1283
+ return encoded;
1284
+ return `tool_${createHash2("sha256").update(id).digest("base64url")}`;
1285
+ }
1286
+ __name(portableToolId, "portableToolId");
1287
+ function sanitizeToolHistoryMessage(message, preserveBoundedCompositeToolIds = false) {
1288
+ const m = message;
1289
+ if (m?.role === "toolResult" && typeof m.toolCallId === "string") {
1290
+ const toolCallId = portableToolId(m.toolCallId, preserveBoundedCompositeToolIds);
1291
+ return toolCallId === m.toolCallId ? message : { ...m, toolCallId };
1292
+ }
1293
+ if (m?.role !== "assistant" || !Array.isArray(m.content))
1294
+ return message;
1295
+ let changed = false;
1296
+ const content = m.content.map((block) => {
1297
+ const b = block;
1298
+ if (b?.type !== "toolCall" || typeof b.id !== "string")
1299
+ return block;
1300
+ const id = portableToolId(b.id, preserveBoundedCompositeToolIds);
1301
+ if (id === b.id)
1302
+ return block;
1303
+ changed = true;
1304
+ return { ...b, id };
1305
+ });
1306
+ return changed ? { ...m, content } : message;
1307
+ }
1308
+ __name(sanitizeToolHistoryMessage, "sanitizeToolHistoryMessage");
1309
+ function stripAssistantSubagentToolCallBlocks(message) {
1310
+ const m = message;
1311
+ if (m?.role !== "assistant" || !Array.isArray(m.content))
1312
+ return message;
1313
+ const filteredContent = m.content.filter((block) => !isSubagentToolCallBlock(block));
1314
+ if (filteredContent.length === m.content.length)
1315
+ return message;
1316
+ if (filteredContent.length === 0)
1317
+ return void 0;
1318
+ return { ...m, content: filteredContent };
1319
+ }
1320
+ __name(stripAssistantSubagentToolCallBlocks, "stripAssistantSubagentToolCallBlocks");
1321
+ function stripParentOnlySubagentMessages(messages, options = {}) {
1322
+ const preserveCurrentFanoutToolHistory = options.preserveFanoutToolHistory === true;
1323
+ const sanitizeToolIds = options.sanitizeToolIds ?? true;
1324
+ const inheritedBefore = options.inheritedBefore;
1325
+ const inherited = /* @__PURE__ */ __name((message) => inheritedBefore !== void 0 && typeof message?.timestamp === "number" && message.timestamp < inheritedBefore, "inherited");
1326
+ let changed = false;
1327
+ const filtered = [];
1328
+ for (const message of messages) {
1329
+ const keep = inherited(message);
1330
+ if (!keep && (isParentOnlySubagentMessage(message) || !preserveCurrentFanoutToolHistory && isSubagentToolResultMessage(message))) {
1331
+ changed = true;
1332
+ continue;
1333
+ }
1334
+ const stripped = keep || preserveCurrentFanoutToolHistory ? message : stripAssistantSubagentToolCallBlocks(message);
1335
+ if (stripped === void 0) {
1336
+ changed = true;
1337
+ continue;
1338
+ }
1339
+ const sanitized = sanitizeToolIds ? sanitizeToolHistoryMessage(stripped, options.preserveBoundedCompositeToolIds === true) : stripped;
1340
+ if (stripped !== message || sanitized !== stripped)
1341
+ changed = true;
1342
+ filtered.push(sanitized);
1343
+ }
1344
+ return changed ? filtered : messages;
1345
+ }
1346
+ __name(stripParentOnlySubagentMessages, "stripParentOnlySubagentMessages");
1347
+ function registerPermissionGate(pi, permissions, childWatchdog, requestPermission = requestWatchdogPermission) {
1348
+ const rules = permissions?.rules;
1349
+ if (!rules || Object.keys(rules).length === 0)
1350
+ return;
1351
+ const rawWatchdogConfig = childWatchdog ? JSON.stringify(childWatchdog) : void 0;
1352
+ const timeoutMs = childWatchdog?.agentEndTimeoutMs ?? 3e4;
1353
+ const onRuntimeEvent = pi.on;
1354
+ onRuntimeEvent("tool_call", async (event, ctx) => {
1355
+ const toolName = typeof event.toolName === "string" ? event.toolName : "tool";
1356
+ const decision = permissionDecision(rules, toolName);
1357
+ if (decision === "allow")
1358
+ return void 0;
1359
+ if (decision === "deny")
1360
+ return { block: true, reason: `Blocked by pi-subagents permission rule: '${toolName}' is denied.` };
1361
+ if (ctx.signal?.aborted)
1362
+ return { block: true, reason: "Blocked by pi-subagents permission rule: Watchdog permission decision was cancelled." };
1363
+ let timeout;
1364
+ let abort;
1365
+ let result2;
1366
+ try {
1367
+ result2 = await Promise.race([
1368
+ requestPermission({
1369
+ ctx,
1370
+ toolName,
1371
+ args: event.input ?? {},
1372
+ rawWatchdogConfig,
1373
+ auditPath: permissions.auditPath,
1374
+ ...ctx.signal ? { signal: ctx.signal } : {}
1375
+ }),
1376
+ new Promise((resolve3) => {
1377
+ if (!ctx.signal)
1378
+ return;
1379
+ abort = /* @__PURE__ */ __name(() => resolve3({ approved: false, reason: "Watchdog permission decision was cancelled.", source: "watchdog" }), "abort");
1380
+ ctx.signal.addEventListener("abort", abort, { once: true });
1381
+ }),
1382
+ new Promise((_, reject) => {
1383
+ timeout = setTimeout(() => reject(new Error(`Watchdog permission decision timed out after ${timeoutMs}ms.`)), timeoutMs);
1384
+ })
1385
+ ]);
1386
+ } catch (error) {
1387
+ const reason = error instanceof Error ? error.message : String(error);
1388
+ return { block: true, reason: `Blocked by pi-subagents permission rule: Watchdog permission arbiter failed closed: ${reason}` };
1389
+ } finally {
1390
+ if (timeout)
1391
+ clearTimeout(timeout);
1392
+ if (abort)
1393
+ ctx.signal?.removeEventListener("abort", abort);
1394
+ }
1395
+ if (result2.approved)
1396
+ return void 0;
1397
+ return { block: true, reason: `Blocked by pi-subagents permission rule: ${result2.reason}` };
1398
+ });
1399
+ }
1400
+ __name(registerPermissionGate, "registerPermissionGate");
1401
+ function registerToolBudget(pi, budget) {
1402
+ if (!budget)
1403
+ return;
1404
+ let toolCount = 0;
1405
+ let softNudged = false;
1406
+ const sendUserMessage = pi.sendUserMessage;
1407
+ const onRuntimeEvent = pi.on;
1408
+ onRuntimeEvent("tool_call", (event) => {
1409
+ const toolName = typeof event.toolName === "string" ? event.toolName : "tool";
1410
+ toolCount++;
1411
+ if (budget.soft !== void 0 && toolCount >= budget.soft && !softNudged) {
1412
+ softNudged = true;
1413
+ try {
1414
+ sendUserMessage?.(toolBudgetSoftNudge(budget, toolCount), { deliverAs: "steer" });
1415
+ } catch {
1416
+ }
1417
+ }
1418
+ if (!shouldBlockToolForBudget(budget, toolName, toolCount))
1419
+ return void 0;
1420
+ return { block: true, reason: toolBudgetBlockedMessage(budget, toolName, toolCount) };
1421
+ });
1422
+ }
1423
+ __name(registerToolBudget, "registerToolBudget");
1424
+ function registerStructuredOutputTool(pi, structured) {
1425
+ const terminalState = structured.terminalState ??= { captured: false };
1426
+ const required = structured.acceptanceReport === "required";
1427
+ const parameters = createStructuredOutputToolParameters(structured.schema, { acceptanceReport: structured.acceptanceReport });
1428
+ const registerTool = pi.registerTool;
1429
+ registerTool({
1430
+ name: "structured_output",
1431
+ ...MODEL_ONLY_TOOL,
1432
+ label: "Structured Output",
1433
+ description: "Submit the required final structured output for this subagent step. This terminates the step.",
1434
+ parameters,
1435
+ async execute(_id, params) {
1436
+ const validation = await validateStructuredOutputValue(structured.schema, params.value);
1437
+ if (validation.status === "invalid") {
1438
+ throw new Error(`Structured output validation failed: ${validation.message}`);
1439
+ }
1440
+ if (required && params.acceptanceReport === void 0) {
1441
+ throw new Error(MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR);
1442
+ }
1443
+ if (required && params.acceptanceReport !== void 0) {
1444
+ const acceptanceValidation = validateAcceptanceReport(params.acceptanceReport, "acceptanceReport");
1445
+ if (!acceptanceValidation.report) {
1446
+ throw new Error(`Invalid structured output acceptance report: ${acceptanceValidation.errors.join("; ")}`);
1447
+ }
1448
+ }
1449
+ structured.capture(params.value, structured.acceptanceReport ? params.acceptanceReport : void 0);
1450
+ terminalState.captured = true;
1451
+ return {
1452
+ content: [{ type: "text", text: "Structured output captured." }],
1453
+ details: {},
1454
+ terminate: true
1455
+ };
1456
+ }
1457
+ });
1458
+ }
1459
+ __name(registerStructuredOutputTool, "registerStructuredOutputTool");
1460
+ function registerSubagentPromptRuntime(pi, config, drainObservation) {
1461
+ if (!config)
1462
+ return;
1463
+ registerRuntimeExtensionAcknowledgements(pi, config.runtimeAcknowledgements);
1464
+ registerPermissionGate(pi, config.permissions, config.childWatchdog);
1465
+ registerToolBudget(pi, config.toolBudget);
1466
+ if (config.structuredOutput && !config.structuredOutput.terminalState)
1467
+ config.structuredOutput.terminalState = { captured: false };
1468
+ registerChildWatchdog(pi, config.childWatchdog, config.watchdogStatus, config.structuredOutput?.terminalState);
1469
+ const requestedWatchdogDiff = config.requiredTools?.includes(WATCHDOG_DIFF_TOOL_NAME);
1470
+ const reviewerLaunchBaseline = requestedWatchdogDiff && config.cwd ? captureWatchdogDiffBaseline(config.cwd) : void 0;
1471
+ if (requestedWatchdogDiff && typeof pi.registerTool === "function") {
1472
+ pi.registerTool(createWatchdogDiffTool(reviewerLaunchBaseline, { workingTreeAtLaunch: true }));
1473
+ }
1474
+ const waitState = config.runtimeState ?? {
1475
+ baseCwd: "",
1476
+ currentSessionId: null,
1477
+ asyncJobs: /* @__PURE__ */ new Map(),
1478
+ foregroundRuns: /* @__PURE__ */ new Map(),
1479
+ foregroundControls: /* @__PURE__ */ new Map(),
1480
+ lastForegroundControlId: null,
1481
+ cleanupTimers: /* @__PURE__ */ new Map(),
1482
+ lastUiContext: null,
1483
+ poller: null,
1484
+ completionSeen: /* @__PURE__ */ new Map(),
1485
+ watcher: null,
1486
+ watcherRestartTimer: null,
1487
+ resultFileCoalescer: { schedule: /* @__PURE__ */ __name(() => false, "schedule"), clear: /* @__PURE__ */ __name(() => {
1488
+ }, "clear") }
1489
+ };
1490
+ const nestedRootRunId = inheritedNestedRouteOf(config)?.rootRunId;
1491
+ if (typeof pi.registerTool === "function")
1492
+ registerWaitTool(pi, waitState, config.waitTool.enabled, void 0, config.waitTool.defaultTimeoutMs, { nestedRootRunId });
1493
+ const supervisorMetadata = childSupervisorMetadata(config);
1494
+ let nativeSupervisorClientRegistered = false;
1495
+ const registerNativeSupervisorClientOnce = /* @__PURE__ */ __name(() => {
1496
+ if (nativeSupervisorClientRegistered)
1497
+ return;
1498
+ nativeSupervisorClientRegistered = true;
1499
+ registerNativeSupervisorClient(pi, supervisorMetadata);
1500
+ }, "registerNativeSupervisorClientOnce");
1501
+ const onRuntimeEvent = pi.on;
1502
+ onRuntimeEvent("session_start", (_event, ctx) => {
1503
+ const sessionManager = ctx?.sessionManager;
1504
+ waitState.currentSessionId = sessionManager ? resolveCurrentSessionId(sessionManager) : null;
1505
+ registerNativeSupervisorClientOnce();
1506
+ });
1507
+ onRuntimeEvent("agent_start", () => {
1508
+ if (!config.requiredTools)
1509
+ return;
1510
+ const diagnostic = evaluateChildToolDiagnostic(config, pi.getAllTools().map((tool) => tool.name));
1511
+ config.toolDiagnostic?.(diagnostic);
1512
+ if (diagnostic)
1513
+ throw new Error(formatChildToolDiagnostic(diagnostic));
1514
+ });
1515
+ onRuntimeEvent("agent_end", async (_event, ctx) => {
1516
+ if (ctx?.hasUI === true)
1517
+ drainObservation?.deny();
1518
+ if (drainObservation) {
1519
+ try {
1520
+ if (ctx?.sessionManager?.getSessionFile() !== waitState.currentSessionId)
1521
+ drainObservation.deny();
1522
+ } catch {
1523
+ drainObservation.deny();
1524
+ }
1525
+ }
1526
+ config.holdFinalDrain?.(true);
1527
+ try {
1528
+ await drainOutstandingWork({ state: waitState, events: pi.events, nestedRootRunId, hasPendingSupervisorRequest: config.hasPendingSupervisorRequest }, drainObservation);
1529
+ } finally {
1530
+ config.holdFinalDrain?.(false);
1531
+ }
1532
+ });
1533
+ if (config.structuredOutput)
1534
+ registerStructuredOutputTool(pi, config.structuredOutput);
1535
+ onRuntimeEvent("before_provider_request", (event, ctx) => rewriteForkCacheProviderRequest(event, ctx, config.forkCacheKey));
1536
+ let inheritedTools;
1537
+ if (config.forkCacheKey)
1538
+ onRuntimeEvent("context_with_system", (event, ctx) => {
1539
+ if (!event || typeof event !== "object" || !("messages" in event) || !Array.isArray(event.messages))
1540
+ return void 0;
1541
+ const header = ctx?.sessionManager?.getHeader();
1542
+ if (!header)
1543
+ return void 0;
1544
+ if (inheritedTools?.session !== header.id) {
1545
+ const forkedAt = Date.parse(header.timestamp);
1546
+ inheritedTools = { session: header.id, forkedAt, tools: Number.isFinite(forkedAt) ? toolsDeclaredBefore(ctx.sessionManager.buildSessionProjection().messages, forkedAt) : [] };
1547
+ }
1548
+ const messages = keepInheritedToolDeclarations(event.messages, inheritedTools.tools, inheritedTools.forkedAt);
1549
+ return messages === event.messages ? void 0 : { messages };
1550
+ });
1551
+ onRuntimeEvent("context", (event, ctx) => {
1552
+ if (!event || typeof event !== "object" || !("messages" in event) || !Array.isArray(event.messages))
1553
+ return void 0;
1554
+ const forkedAt = config.forkCacheKey ? Date.parse(ctx?.sessionManager?.getHeader()?.timestamp ?? "") : Number.NaN;
1555
+ const messages = stripParentOnlySubagentMessages(event.messages, {
1556
+ sanitizeToolIds: !COMPOSITE_TOOL_ID_APIS.has(ctx?.model?.api ?? ""),
1557
+ preserveBoundedCompositeToolIds: ctx?.model?.api === "openai-codex-responses",
1558
+ preserveFanoutToolHistory: config.fanoutChild,
1559
+ ...Number.isFinite(forkedAt) ? { inheritedBefore: forkedAt } : {}
1560
+ });
1561
+ if (messages === event.messages)
1562
+ return void 0;
1563
+ return { messages };
1564
+ });
1565
+ const routingName = config.intercomSessionName;
1566
+ let intercomIdClaimed = false;
1567
+ if (routingName) {
1568
+ pi.events.on(INTERCOM_SESSION_IDENTITY_EVENT, (request) => {
1569
+ if (!request || typeof request !== "object" || !("version" in request) || request.version !== 1 || !("claim" in request) || typeof request.claim !== "function")
1570
+ return;
1571
+ request.claim(routingName);
1572
+ intercomIdClaimed = true;
1573
+ });
1574
+ }
1575
+ onRuntimeEvent("before_agent_start", async (event) => {
1576
+ if (!event || typeof event !== "object" || !("systemPrompt" in event) || typeof event.systemPrompt !== "string")
1577
+ return void 0;
1578
+ registerNativeSupervisorClientOnce();
1579
+ const childSessionName = intercomIdClaimed ? config.sessionName || routingName : routingName || config.sessionName;
1580
+ if (childSessionName && typeof pi.setSessionName === "function") {
1581
+ pi.setSessionName(childSessionName);
1582
+ }
1583
+ if (!rewritesChildPrompt(config))
1584
+ return;
1585
+ filterChildPromptOptions(event.systemPromptOptions, {
1586
+ inheritProjectContext: config.inheritProjectContext ?? true,
1587
+ inheritGlobalContext: config.inheritGlobalContext ?? true,
1588
+ inheritSkills: config.inheritSkills ?? true
1589
+ });
1590
+ });
1591
+ }
1592
+ __name(registerSubagentPromptRuntime, "registerSubagentPromptRuntime");
1593
+
1594
+ export {
1595
+ appendAgentRefinementOverlay,
1596
+ handleRefinementAction,
1597
+ projectRuntimeAcknowledgedExtensions,
1598
+ formatChildToolDiagnostic,
1599
+ rewriteSubagentPrompt,
1600
+ registerSubagentPromptBoundary,
1601
+ registerSubagentPromptRuntime
1602
+ };