privateer-agent 0.15.5 → 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 (214) 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/privateer-launch.mjs +14 -2
  5. package/bin/privateer-verify.mjs +12 -0
  6. package/dist-boot/boot.mjs +3 -0
  7. package/dist-boot/c-27JKSMWL.mjs +1460 -0
  8. package/dist-boot/c-2BMRFV24.mjs +269 -0
  9. package/dist-boot/c-2CTF6JA3.mjs +166 -0
  10. package/dist-boot/c-2G3BBHRJ.mjs +84 -0
  11. package/dist-boot/c-2IDLKXX6.mjs +250 -0
  12. package/dist-boot/c-2NJD5VYM.mjs +8 -0
  13. package/dist-boot/c-2S5EEQPW.mjs +1602 -0
  14. package/dist-boot/c-2WRDCUVI.mjs +25 -0
  15. package/dist-boot/c-2YN3M256.mjs +14 -0
  16. package/dist-boot/c-37GM3GMU.mjs +187 -0
  17. package/dist-boot/c-3STKRSVO.mjs +2480 -0
  18. package/dist-boot/c-3TPV6TQQ.mjs +2320 -0
  19. package/dist-boot/c-3UVHLQDJ.mjs +225 -0
  20. package/dist-boot/c-42PUUZYC.mjs +697 -0
  21. package/dist-boot/c-4D5UMWVW.mjs +683 -0
  22. package/dist-boot/c-4ETZRMTA.mjs +46 -0
  23. package/dist-boot/c-4QT25BD5.mjs +1482 -0
  24. package/dist-boot/c-4WVR32AP.mjs +2579 -0
  25. package/dist-boot/c-5EMM567G.mjs +152 -0
  26. package/dist-boot/c-5FA4CV63.mjs +145 -0
  27. package/dist-boot/c-5GV3X3RB.mjs +14 -0
  28. package/dist-boot/c-5JCEPRIY.mjs +52 -0
  29. package/dist-boot/c-5NDKIIWT.mjs +16 -0
  30. package/dist-boot/c-5QL3AR26.mjs +4665 -0
  31. package/dist-boot/c-5XY6MFKN.mjs +5142 -0
  32. package/dist-boot/c-65UZIZC7.mjs +2897 -0
  33. package/dist-boot/c-6FUXKHOK.mjs +1969 -0
  34. package/dist-boot/c-6JHWQE4V.mjs +18242 -0
  35. package/dist-boot/c-6LOBR4I6.mjs +5280 -0
  36. package/dist-boot/c-6QHOZXKQ.mjs +14394 -0
  37. package/dist-boot/c-6ZO2SADQ.mjs +178 -0
  38. package/dist-boot/c-6ZORVVZP.mjs +1449 -0
  39. package/dist-boot/c-76QH4UCP.mjs +2441 -0
  40. package/dist-boot/c-77GO5L5Y.mjs +20982 -0
  41. package/dist-boot/c-7M23XFTN.mjs +5052 -0
  42. package/dist-boot/c-7TC367E2.mjs +32 -0
  43. package/dist-boot/c-7UOG7POX.mjs +1524 -0
  44. package/dist-boot/c-7VHP3FLN.mjs +376 -0
  45. package/dist-boot/c-A73JHZP2.mjs +13207 -0
  46. package/dist-boot/c-ABXULAFL.mjs +71 -0
  47. package/dist-boot/c-ANDD2AQO.mjs +74 -0
  48. package/dist-boot/c-AOY77AZL.mjs +1430 -0
  49. package/dist-boot/c-AXEPZ22I.mjs +108 -0
  50. package/dist-boot/c-B2Y7VNHU.mjs +427 -0
  51. package/dist-boot/c-B7VJUH73.mjs +77 -0
  52. package/dist-boot/c-BFW6CDVL.mjs +24 -0
  53. package/dist-boot/c-BHNIF2AR.mjs +188 -0
  54. package/dist-boot/c-BKF2O6BL.mjs +23 -0
  55. package/dist-boot/c-BOZXFTZN.mjs +8 -0
  56. package/dist-boot/c-BRNYJWZL.mjs +28 -0
  57. package/dist-boot/c-C3N4Z2HO.mjs +93 -0
  58. package/dist-boot/c-C4IV7ZFG.mjs +717 -0
  59. package/dist-boot/c-C5NK6UYV.mjs +793 -0
  60. package/dist-boot/c-C67644MB.mjs +1659 -0
  61. package/dist-boot/c-C6S2YB53.mjs +620 -0
  62. package/dist-boot/c-CDBEJSBF.mjs +37 -0
  63. package/dist-boot/c-CG47HBKU.mjs +435 -0
  64. package/dist-boot/c-CKCTWCT5.mjs +51 -0
  65. package/dist-boot/c-CN77DCGF.mjs +60 -0
  66. package/dist-boot/c-CRBXNKFO.mjs +1795 -0
  67. package/dist-boot/c-CRIHASQ6.mjs +973 -0
  68. package/dist-boot/c-CU4NGAUO.mjs +3786 -0
  69. package/dist-boot/c-CWRFLGQU.mjs +1883 -0
  70. package/dist-boot/c-CYQB2USO.mjs +32 -0
  71. package/dist-boot/c-DEE67DJO.mjs +379 -0
  72. package/dist-boot/c-DIFDBYOP.mjs +1258 -0
  73. package/dist-boot/c-DOSGVXDZ.mjs +34879 -0
  74. package/dist-boot/c-DR7XQI32.mjs +381 -0
  75. package/dist-boot/c-DTGPSB46.mjs +14666 -0
  76. package/dist-boot/c-DTHDNA4P.mjs +320 -0
  77. package/dist-boot/c-E4Z3Y5B5.mjs +3864 -0
  78. package/dist-boot/c-E66Z2TI7.mjs +203 -0
  79. package/dist-boot/c-EBU6RLRV.mjs +1527 -0
  80. package/dist-boot/c-EBZZNGSF.mjs +432 -0
  81. package/dist-boot/c-EC3LJ2KF.mjs +1032 -0
  82. package/dist-boot/c-EQBKXWNX.mjs +15829 -0
  83. package/dist-boot/c-EUEPIW4S.mjs +574 -0
  84. package/dist-boot/c-EX4YVWAT.mjs +378 -0
  85. package/dist-boot/c-EYZGSAJU.mjs +98 -0
  86. package/dist-boot/c-F75VRKY4.mjs +172 -0
  87. package/dist-boot/c-FH4NXKHV.mjs +177 -0
  88. package/dist-boot/c-FHNUCTEM.mjs +140 -0
  89. package/dist-boot/c-FJ5T42DS.mjs +5349 -0
  90. package/dist-boot/c-FPCNRL7G.mjs +1728 -0
  91. package/dist-boot/c-G4DLN7Q4.mjs +8 -0
  92. package/dist-boot/c-G56GYQFZ.mjs +2507 -0
  93. package/dist-boot/c-GLIOERDQ.mjs +1200 -0
  94. package/dist-boot/c-GMJ5HUBM.mjs +14 -0
  95. package/dist-boot/c-H3HSGMAQ.mjs +461 -0
  96. package/dist-boot/c-HIKTO6P7.mjs +275 -0
  97. package/dist-boot/c-I2MCJ34O.mjs +464 -0
  98. package/dist-boot/c-I3C6LBW4.mjs +765 -0
  99. package/dist-boot/c-I54OKQHW.mjs +387 -0
  100. package/dist-boot/c-IFSP3R4D.mjs +80 -0
  101. package/dist-boot/c-IZK77VB7.mjs +171 -0
  102. package/dist-boot/c-J3Y25UGE.mjs +54 -0
  103. package/dist-boot/c-J5IESS7W.mjs +27750 -0
  104. package/dist-boot/c-JJWZBY7L.mjs +254 -0
  105. package/dist-boot/c-JKTFXTGF.mjs +463 -0
  106. package/dist-boot/c-JN57AXQ4.mjs +77 -0
  107. package/dist-boot/c-KFIO6LUW.mjs +1096 -0
  108. package/dist-boot/c-KIEMEFWW.mjs +478 -0
  109. package/dist-boot/c-KIVXWBYD.mjs +28 -0
  110. package/dist-boot/c-KP6CRIP4.mjs +580 -0
  111. package/dist-boot/c-L26VOJX4.mjs +11558 -0
  112. package/dist-boot/c-L5GHWG5G.mjs +5988 -0
  113. package/dist-boot/c-M7NSQAKK.mjs +353 -0
  114. package/dist-boot/c-MCEWOPBW.mjs +56 -0
  115. package/dist-boot/c-MGPIEG7I.mjs +20 -0
  116. package/dist-boot/c-NREXJV3M.mjs +393 -0
  117. package/dist-boot/c-O5PP6CTX.mjs +162 -0
  118. package/dist-boot/c-OBQDHSXM.mjs +1774 -0
  119. package/dist-boot/c-OLQHHDD4.mjs +21 -0
  120. package/dist-boot/c-OXW4JQQH.mjs +319 -0
  121. package/dist-boot/c-P3D7ZUWN.mjs +1288 -0
  122. package/dist-boot/c-P4PQZVV5.mjs +948 -0
  123. package/dist-boot/c-P63T3XL2.mjs +26373 -0
  124. package/dist-boot/c-P6N5DQGZ.mjs +194 -0
  125. package/dist-boot/c-P7MLKQFC.mjs +58 -0
  126. package/dist-boot/c-PB3PZJL5.mjs +1276 -0
  127. package/dist-boot/c-PTN4S6G2.mjs +1259 -0
  128. package/dist-boot/c-PYCE5J7U.mjs +1083 -0
  129. package/dist-boot/c-Q4HYCRLB.mjs +19410 -0
  130. package/dist-boot/c-QUXMETGG.mjs +68 -0
  131. package/dist-boot/c-RDMJZCOX.mjs +356 -0
  132. package/dist-boot/c-ROGJK76M.mjs +17 -0
  133. package/dist-boot/c-RQJJ26T4.mjs +708 -0
  134. package/dist-boot/c-RSKCUPJF.mjs +7559 -0
  135. package/dist-boot/c-RVJU4O6P.mjs +37 -0
  136. package/dist-boot/c-S2RVHR3M.mjs +165 -0
  137. package/dist-boot/c-SKMK3PEE.mjs +91120 -0
  138. package/dist-boot/c-TI7SM4EG.mjs +20 -0
  139. package/dist-boot/c-TILJ6GXD.mjs +1235 -0
  140. package/dist-boot/c-TT6BCUJD.mjs +114 -0
  141. package/dist-boot/c-U4ITOXAN.mjs +2107 -0
  142. package/dist-boot/c-UGERXVO2.mjs +7120 -0
  143. package/dist-boot/c-UPBH5AXY.mjs +1363 -0
  144. package/dist-boot/c-US2PUNZL.mjs +597 -0
  145. package/dist-boot/c-UU4WZPPE.mjs +20 -0
  146. package/dist-boot/c-UWVIYPQS.mjs +39 -0
  147. package/dist-boot/c-V4RHQBPQ.mjs +17683 -0
  148. package/dist-boot/c-V5MRVK47.mjs +351 -0
  149. package/dist-boot/c-V6CL266R.mjs +1755 -0
  150. package/dist-boot/c-VJTMFKYE.mjs +14975 -0
  151. package/dist-boot/c-VJTRUKIB.mjs +773 -0
  152. package/dist-boot/c-W4IFSHPW.mjs +43 -0
  153. package/dist-boot/c-WETGB2CF.mjs +113 -0
  154. package/dist-boot/c-WO3QSZUU.mjs +1337 -0
  155. package/dist-boot/c-WQLH73TY.mjs +242 -0
  156. package/dist-boot/c-XL735JW5.mjs +500 -0
  157. package/dist-boot/c-Y7HADL5B.mjs +1107 -0
  158. package/dist-boot/c-YGQHSVSK.mjs +41 -0
  159. package/dist-boot/c-YMP2AMEB.mjs +10350 -0
  160. package/dist-boot/c-YRDO2WEF.mjs +12012 -0
  161. package/dist-boot/c-YUSTRATJ.mjs +8 -0
  162. package/dist-boot/c-Z2262R22.mjs +2697 -0
  163. package/dist-boot/c-Z4ALQMJC.mjs +709 -0
  164. package/dist-boot/c-Z5ZUQVUY.mjs +62 -0
  165. package/dist-boot/c-ZDZUKXF7.mjs +874 -0
  166. package/dist-boot/c-ZJYLGIC3.mjs +32 -0
  167. package/dist-boot/c-ZNA5CDMI.mjs +77 -0
  168. package/dist-boot/c-ZSO6DI3M.mjs +204 -0
  169. package/dist-boot/c-ZWUVHKMK.mjs +100 -0
  170. package/dist-boot/c-ZY4MESEW.mjs +832 -0
  171. package/dist-boot/c-ZZ5REI4L.mjs +329 -0
  172. package/dist-boot/cli.mjs +51 -0
  173. package/dist-boot/ext-anthropic-attribution.mjs +207 -0
  174. package/dist-boot/ext-pi-background-tasks.mjs +7234 -0
  175. package/dist-boot/ext-pi-subagents.mjs +37 -0
  176. package/dist-boot/ext-privateer-account.mjs +4426 -0
  177. package/dist-boot/ext-privateer-brand.mjs +5274 -0
  178. package/dist-boot/ext-privateer-codemode.mjs +37 -0
  179. package/dist-boot/ext-privateer-computer.mjs +626 -0
  180. package/dist-boot/ext-privateer-connect.mjs +1862 -0
  181. package/dist-boot/ext-privateer-context.mjs +323 -0
  182. package/dist-boot/ext-privateer-desktop.mjs +92 -0
  183. package/dist-boot/ext-privateer-final-audit.mjs +48 -0
  184. package/dist-boot/ext-privateer-fresh.mjs +81 -0
  185. package/dist-boot/ext-privateer-gate.mjs +5959 -0
  186. package/dist-boot/ext-privateer-hints.mjs +236 -0
  187. package/dist-boot/ext-privateer-media.mjs +2626 -0
  188. package/dist-boot/ext-privateer-models.mjs +3397 -0
  189. package/dist-boot/ext-privateer-posture.mjs +3006 -0
  190. package/dist-boot/ext-privateer-privacy.mjs +4578 -0
  191. package/dist-boot/ext-privateer-recovery.mjs +287 -0
  192. package/dist-boot/ext-privateer-speak.mjs +4754 -0
  193. package/dist-boot/ext-privateer-terminals.mjs +725 -0
  194. package/dist-boot/ext-privateer-tools.mjs +528 -0
  195. package/dist-boot/ext-privateer-truncation.mjs +74 -0
  196. package/dist-boot/ext-privateer-update.mjs +210 -0
  197. package/dist-boot/ext-privateer-vision.mjs +148 -0
  198. package/dist-boot/ext-privateer-web.mjs +543 -0
  199. package/dist-boot/ext-rpiv-ask-user-question.mjs +710 -0
  200. package/dist-boot/manifest.json +9 -0
  201. package/extensions/privateer-brand.ts +3 -1
  202. package/extensions/privateer-context.ts +4 -2
  203. package/extensions/privateer-final-audit.ts +17 -0
  204. package/extensions/privateer-gate.ts +41 -8
  205. package/extensions/privateer-web.ts +4 -4
  206. package/package.json +3 -1
  207. package/patches/@earendil-works+pi-coding-agent+1.3.0.patch +110 -2
  208. package/patches/pi-background-tasks+2.6.10.patch +91 -7
  209. package/src/config/moatManifest.json +1 -0
  210. package/src/config/whatsNew.json +2 -2
  211. package/src/context.ts +33 -5
  212. package/src/engine/finalAudit.ts +38 -0
  213. package/src/engine/stallWatchdog.ts +8 -1
  214. package/src/providers/account.ts +34 -3
@@ -0,0 +1,287 @@
1
+ import{createRequire as __pvCR}from"node:module";import{fileURLToPath as __pvF}from"node:url";import{dirname as __pvD}from"node:path";const require=__pvCR(import.meta.url);const __pvUrl=(r)=>new URL(r,import.meta.url).href;const __pvFile=(r)=>__pvF(new URL(r,import.meta.url));
2
+ import {
3
+ __name
4
+ } from "./c-CN77DCGF.mjs";
5
+
6
+ // extensions/privateer-recovery.ts?ext=privateer-recovery
7
+ import fs2 from "node:fs";
8
+
9
+ // src/config/paths.ts?ext=privateer-recovery
10
+ import { homedir } from "node:os";
11
+ import { join } from "node:path";
12
+ function globalDir() {
13
+ return process.env.PRIVATEER_HOME ?? join(homedir(), ".privateer");
14
+ }
15
+ __name(globalDir, "globalDir");
16
+
17
+ // bin/session-recovery.mjs?ext=privateer-recovery
18
+ import fs from "node:fs";
19
+ import path from "node:path";
20
+ var RECOVERY_ENV = "PRIVATEER_RECOVERY";
21
+ var MARKER_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
22
+ var RESUME_WINDOW_MS = 3 * 60 * 1e3;
23
+ function liveDir(home) {
24
+ return path.join(home, "run", "live");
25
+ }
26
+ __name(liveDir, "liveDir");
27
+ function markerPath(home, pid) {
28
+ return path.join(liveDir(home), `${pid}.json`);
29
+ }
30
+ __name(markerPath, "markerPath");
31
+ function writeMarker(home, marker) {
32
+ const dir = liveDir(home);
33
+ fs.mkdirSync(dir, { recursive: true, mode: 448 });
34
+ const file = markerPath(home, marker.pid);
35
+ const tmp = `${file}.${process.pid}.tmp`;
36
+ fs.writeFileSync(tmp, JSON.stringify(marker) + "\n", { mode: 384 });
37
+ fs.renameSync(tmp, file);
38
+ }
39
+ __name(writeMarker, "writeMarker");
40
+ function removeMarker(home, pid) {
41
+ try {
42
+ fs.rmSync(markerPath(home, pid), { force: true });
43
+ } catch {
44
+ }
45
+ }
46
+ __name(removeMarker, "removeMarker");
47
+ function safeRead(file) {
48
+ try {
49
+ return fs.readFileSync(file, "utf8");
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+ __name(safeRead, "safeRead");
55
+ function parseMarker(text) {
56
+ if (typeof text !== "string") return null;
57
+ let m;
58
+ try {
59
+ m = JSON.parse(text);
60
+ } catch {
61
+ return null;
62
+ }
63
+ if (!m || m.v !== 1 || !Number.isInteger(m.pid) || typeof m.sessionFile !== "string" || !m.sessionFile) return null;
64
+ return {
65
+ v: 1,
66
+ pid: m.pid,
67
+ sessionFile: m.sessionFile,
68
+ cwd: typeof m.cwd === "string" ? m.cwd : "",
69
+ startedAt: Number(m.startedAt) || 0,
70
+ updatedAt: Number(m.updatedAt) || 0,
71
+ turnOpen: m.turnOpen === true,
72
+ tool: m.tool && typeof m.tool.name === "string" ? { name: m.tool.name, summary: typeof m.tool.summary === "string" ? m.tool.summary : "", startedAt: Number(m.tool.startedAt) || 0 } : null,
73
+ hinted: m.hinted === true
74
+ };
75
+ }
76
+ __name(parseMarker, "parseMarker");
77
+ function isAlive(pid) {
78
+ try {
79
+ process.kill(pid, 0);
80
+ return true;
81
+ } catch (e) {
82
+ return e?.code === "EPERM";
83
+ }
84
+ }
85
+ __name(isAlive, "isAlive");
86
+ function listStale(home, { cwd, now = Date.now(), alive = isAlive } = {}) {
87
+ let names = [];
88
+ try {
89
+ names = fs.readdirSync(liveDir(home)).filter((n) => /^\d+\.json$/.test(n));
90
+ } catch {
91
+ return [];
92
+ }
93
+ const out = [];
94
+ for (const name of names) {
95
+ const file = path.join(liveDir(home), name);
96
+ const m = parseMarker(safeRead(file));
97
+ if (!m) continue;
98
+ if (alive(m.pid)) continue;
99
+ if (!m.turnOpen || now - (m.updatedAt || m.startedAt) > MARKER_MAX_AGE_MS || !fs.existsSync(m.sessionFile)) {
100
+ try {
101
+ fs.rmSync(file, { force: true });
102
+ } catch {
103
+ }
104
+ continue;
105
+ }
106
+ if (cwd && path.resolve(m.cwd) !== path.resolve(cwd)) continue;
107
+ out.push(m);
108
+ }
109
+ return out.sort((a, b) => b.updatedAt - a.updatedAt);
110
+ }
111
+ __name(listStale, "listStale");
112
+ function staleForSession(home, sessionFile, opts = {}) {
113
+ const want = path.resolve(sessionFile);
114
+ return listStale(home, opts).find((m) => path.resolve(m.sessionFile) === want) ?? null;
115
+ }
116
+ __name(staleForSession, "staleForSession");
117
+ function summarizeToolCall(name, args) {
118
+ const flat = /* @__PURE__ */ __name((s) => String(s).replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim(), "flat");
119
+ const clip = /* @__PURE__ */ __name((s, n = 160) => s.length > n ? s.slice(0, n - 1) + "\u2026" : s, "clip");
120
+ if (!args || typeof args !== "object") return clip(flat(name));
121
+ const pick = args.command ?? args.cmd ?? args.path ?? args.file_path ?? args.file ?? args.url ?? args.query;
122
+ if (typeof pick === "string" && pick.trim()) return clip(flat(pick));
123
+ return clip(Object.keys(args).slice(0, 6).join(", "));
124
+ }
125
+ __name(summarizeToolCall, "summarizeToolCall");
126
+ var ago = /* @__PURE__ */ __name((ms) => {
127
+ const m = Math.round(ms / 6e4);
128
+ if (m < 1) return "moments ago";
129
+ if (m < 60) return `${m} min ago`;
130
+ const h = Math.round(m / 60);
131
+ return h < 48 ? `${h} h ago` : `${Math.round(h / 24)} days ago`;
132
+ }, "ago");
133
+ function recoveryNote(marker, { reason = "stopped unexpectedly" } = {}) {
134
+ if (!marker?.turnOpen) return null;
135
+ const during = marker.tool ? `while it was running the \`${marker.tool.name}\` tool${marker.tool.summary ? ` (\`${marker.tool.summary}\`)` : ""}` : "in the middle of a turn, between tool calls";
136
+ return [
137
+ `[Privateer] The previous agent process for this session ${reason} ${during}.`,
138
+ "Its last action may have run fully, partly, or not at all, and anything it started (a server, a build, a migration) may still be running or may have been killed.",
139
+ "Do not repeat that action blindly. Check the current state first (files, git status, running processes, the remote) and tell the user briefly what you found before carrying on."
140
+ ].join(" ");
141
+ }
142
+ __name(recoveryNote, "recoveryNote");
143
+ function recoveryNotice(marker, { now = Date.now() } = {}) {
144
+ const when = ago(now - (marker.updatedAt || marker.startedAt || now));
145
+ if (!marker.turnOpen) return `Resumed your session \u2014 the previous agent stopped ${when}.`;
146
+ const what = marker.tool ? ` during ${marker.tool.name}${marker.tool.summary ? `: ${marker.tool.summary}` : ""}` : "";
147
+ return `Resumed your session \u2014 the previous agent stopped ${when} mid-task${what}. It may have been partly done; the agent will check before continuing.`;
148
+ }
149
+ __name(recoveryNotice, "recoveryNotice");
150
+ function sessionIdFromFile(file) {
151
+ const m = path.basename(file).match(/_([0-9a-f-]{8,})\.jsonl$/i);
152
+ return m ? m[1] : null;
153
+ }
154
+ __name(sessionIdFromFile, "sessionIdFromFile");
155
+ function resumeHint(marker, { cmd = "privateer", now = Date.now() } = {}) {
156
+ const id = sessionIdFromFile(marker.sessionFile);
157
+ const target = id ?? marker.sessionFile;
158
+ const what = marker.tool ? ` (during ${marker.tool.name}${marker.tool.summary ? `: ${marker.tool.summary}` : ""})` : "";
159
+ return `\u2693 Your last session in this folder stopped mid-task ${ago(now - (marker.updatedAt || now))}${what}.
160
+ Resume it: ${cmd} --session ${target}`;
161
+ }
162
+ __name(resumeHint, "resumeHint");
163
+ function decodeRecovery(value) {
164
+ if (typeof value !== "string" || !value) return null;
165
+ try {
166
+ return parseMarker(Buffer.from(value, "base64").toString("utf8"));
167
+ } catch {
168
+ return null;
169
+ }
170
+ }
171
+ __name(decodeRecovery, "decodeRecovery");
172
+
173
+ // extensions/privateer-recovery.ts?ext=privateer-recovery
174
+ var HANDOFF = /* @__PURE__ */ Symbol.for("privateer.recovery.handoff");
175
+ function takeHandoff() {
176
+ const g = globalThis;
177
+ if (!(HANDOFF in g)) {
178
+ g[HANDOFF] = process.env[RECOVERY_ENV];
179
+ delete process.env[RECOVERY_ENV];
180
+ }
181
+ const v = g[HANDOFF];
182
+ g[HANDOFF] = void 0;
183
+ return v;
184
+ }
185
+ __name(takeHandoff, "takeHandoff");
186
+ var sealingWarned = false;
187
+ function sealingNotice(ctx) {
188
+ const g = globalThis;
189
+ const codec = g[/* @__PURE__ */ Symbol.for("privateer.sessionCodec")];
190
+ const error = g[/* @__PURE__ */ Symbol.for("privateer.sessionCodecError")];
191
+ if (!codec) {
192
+ if (sealingWarned || !error) return;
193
+ sealingWarned = true;
194
+ ctx?.ui?.notify?.(`Session encryption is off for this run (${error}). This session is being saved unencrypted. Your key file was left untouched \u2014 sessions sealed with it are unreadable until it's fixed.`, "warning");
195
+ return;
196
+ }
197
+ if (codec.failures > 0) {
198
+ const n = codec.failures;
199
+ codec.failures = 0;
200
+ ctx?.ui?.notify?.(`${n} saved line${n === 1 ? "" : "s"} of this session couldn't be decrypted with this machine's session key and ${n === 1 ? "isn't" : "aren't"} shown. The file itself is unchanged.`, "warning");
201
+ }
202
+ }
203
+ __name(sealingNotice, "sealingNotice");
204
+ function privateerRecovery(pi) {
205
+ const home = globalDir();
206
+ const pid = process.pid;
207
+ let state = null;
208
+ const save = /* @__PURE__ */ __name(() => {
209
+ if (!state) return;
210
+ try {
211
+ writeMarker(home, { v: 1, pid, ...state, updatedAt: Date.now() });
212
+ } catch {
213
+ }
214
+ }, "save");
215
+ pi.on("session_start", (_event, ctx) => {
216
+ if (ctx?.mode !== "tui") return;
217
+ const sessionFile = ctx?.sessionManager?.getSessionFile?.();
218
+ if (!sessionFile) {
219
+ state = null;
220
+ removeMarker(home, pid);
221
+ return;
222
+ }
223
+ state = { sessionFile, cwd: ctx?.cwd ?? process.cwd(), startedAt: Date.now(), turnOpen: false, tool: null };
224
+ save();
225
+ sealingNotice(ctx);
226
+ try {
227
+ if (fs2.existsSync(sessionFile)) fs2.chmodSync(sessionFile, 384);
228
+ } catch {
229
+ }
230
+ const handed = decodeRecovery(takeHandoff());
231
+ const dead = handed && handed.sessionFile === sessionFile ? handed : staleForSession(home, sessionFile);
232
+ if (!dead || dead.pid === pid) {
233
+ if (_event?.reason === "startup") hintInterrupted(ctx, sessionFile);
234
+ return;
235
+ }
236
+ removeMarker(home, dead.pid);
237
+ const note = recoveryNote(dead);
238
+ if (note) {
239
+ pi.sendMessage?.(
240
+ { customType: "privateer-recovery", content: note, display: false },
241
+ { deliverAs: "nextTurn" }
242
+ );
243
+ }
244
+ ctx?.ui?.notify?.(recoveryNotice(dead), dead.turnOpen ? "warning" : "info");
245
+ });
246
+ const hintInterrupted = /* @__PURE__ */ __name((ctx, current) => {
247
+ const cwd = ctx?.cwd ?? process.cwd();
248
+ const m = listStale(home, { cwd }).find((x) => x.turnOpen && !x.hinted && x.sessionFile !== current);
249
+ if (!m) return;
250
+ ctx?.ui?.notify?.(resumeHint(m, { cmd: process.env.PRIVATEER_CMD || "privateer" }), "info");
251
+ try {
252
+ writeMarker(home, { ...m, hinted: true });
253
+ } catch {
254
+ }
255
+ }, "hintInterrupted");
256
+ pi.on("agent_start", () => {
257
+ if (!state) return;
258
+ state.turnOpen = true;
259
+ save();
260
+ });
261
+ pi.on("tool_execution_start", (event) => {
262
+ if (!state || event?.parentToolCallId) return;
263
+ state.tool = { name: String(event?.toolName ?? "tool"), summary: summarizeToolCall(event?.toolName, event?.args), startedAt: Date.now() };
264
+ save();
265
+ });
266
+ pi.on("tool_execution_end", (event) => {
267
+ if (!state || event?.parentToolCallId) return;
268
+ state.tool = null;
269
+ save();
270
+ });
271
+ pi.on("agent_end", () => {
272
+ if (!state) return;
273
+ state.turnOpen = false;
274
+ state.tool = null;
275
+ save();
276
+ });
277
+ pi.on("session_shutdown", () => {
278
+ if (!state) return;
279
+ if (state.turnOpen) save();
280
+ else removeMarker(home, pid);
281
+ state = null;
282
+ });
283
+ }
284
+ __name(privateerRecovery, "privateerRecovery");
285
+ export {
286
+ privateerRecovery as default
287
+ };