@hraness/ghostget 0.17.2

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 (500) hide show
  1. package/CHANGELOG.md +458 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1359 -0
  4. package/bunfig.toml +2 -0
  5. package/dist/apple-photos-client.js +704 -0
  6. package/dist/beeper-client.js +4602 -0
  7. package/dist/client.js +1605 -0
  8. package/dist/index-26yq8q16.js +31 -0
  9. package/dist/index-9t13b4k7.js +508 -0
  10. package/dist/index-axwm9b3v.js +5 -0
  11. package/dist/index-gwk7rbyj.js +30 -0
  12. package/dist/index.js +701 -0
  13. package/dist/messaging.js +1130 -0
  14. package/dist/omni-client.js +1406 -0
  15. package/dist/whatsapp-client.js +355 -0
  16. package/docs/imessage-direct-provider.md +106 -0
  17. package/docs/rental-listings.md +94 -0
  18. package/package.json +600 -0
  19. package/skills/ghostget/SKILL.md +251 -0
  20. package/skills/ghostget/agents/openai.yaml +4 -0
  21. package/skills/ghostget/references/adapter-contract.md +181 -0
  22. package/skills/ghostget/references/apple-photos.md +115 -0
  23. package/skills/ghostget/references/article-drafts.md +235 -0
  24. package/skills/ghostget/references/code-owned-provider-scaffold.md +134 -0
  25. package/skills/ghostget/references/cross-posting-video.md +139 -0
  26. package/skills/ghostget/references/cross-posting.md +82 -0
  27. package/skills/ghostget/references/derivation.md +390 -0
  28. package/skills/ghostget/references/hraness-social-profile-stats.json +269 -0
  29. package/skills/ghostget/references/install.md +66 -0
  30. package/skills/ghostget/references/linkedin-adapter.md +442 -0
  31. package/skills/ghostget/references/messaging.md +168 -0
  32. package/skills/ghostget/references/meta-comet-contract.md +153 -0
  33. package/skills/ghostget/references/platform-patterns.md +122 -0
  34. package/skills/ghostget/references/provider-plugins.md +496 -0
  35. package/skills/ghostget/references/reddit-flair.md +78 -0
  36. package/skills/ghostget/references/safety-and-state.md +214 -0
  37. package/skills/ghostget/references/settlement-and-duplicate-cleanup.md +79 -0
  38. package/skills/ghostget/references/social-platform-routing.md +66 -0
  39. package/skills/ghostget/references/social-profile-stats.md +195 -0
  40. package/skills/ghostget/references/social-video-platform-routing.md +89 -0
  41. package/skills/ghostget/references/whatsapp-adapter.md +101 -0
  42. package/skills/ghostget/references/x-adapter.md +332 -0
  43. package/skills/ghostget/references/x-ai-disclosure.md +71 -0
  44. package/src/apple-photos-cli.ts +639 -0
  45. package/src/apple-photos-client-types.ts +168 -0
  46. package/src/apple-photos-client.ts +201 -0
  47. package/src/apple-photos-contact-evidence.ts +838 -0
  48. package/src/apple-photos-local-source.ts +1131 -0
  49. package/src/args.ts +2053 -0
  50. package/src/article-draft-document.ts +417 -0
  51. package/src/article-draft-embeds.ts +123 -0
  52. package/src/article-draft-images.ts +214 -0
  53. package/src/assets/adapter-template/wrench-adapter.json +40 -0
  54. package/src/assets/adapters/beeper/wrench-web-adapter.json +1500 -0
  55. package/src/assets/adapters/beeper/wrench-web-adapter.v1.0.0.json +129 -0
  56. package/src/assets/adapters/beeper/wrench-web-adapter.v1.1.0.json +207 -0
  57. package/src/assets/adapters/beeper/wrench-web-adapter.v2.0.0.json +1463 -0
  58. package/src/assets/adapters/beeper/wrench-web-adapter.v2.1.0.json +1463 -0
  59. package/src/assets/adapters/beeper/wrench-web-adapter.v2.2.0.json +1475 -0
  60. package/src/assets/adapters/beeper/wrench-web-adapter.v2.3.0.json +1488 -0
  61. package/src/assets/adapters/bluesky/wrench-web-adapter.json +684 -0
  62. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.0.0.json +581 -0
  63. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.1.0.json +581 -0
  64. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.2.0.json +581 -0
  65. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.3.0.json +615 -0
  66. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.4.0.json +684 -0
  67. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.5.0.json +684 -0
  68. package/src/assets/adapters/bluesky/wrench-web-adapter.v1.6.0.json +684 -0
  69. package/src/assets/adapters/clasificados/wrench-web-adapter.json +54 -0
  70. package/src/assets/adapters/facebook/wrench-web-adapter.json +750 -0
  71. package/src/assets/adapters/facebook/wrench-web-adapter.v1.0.0.json +706 -0
  72. package/src/assets/adapters/facebook/wrench-web-adapter.v1.1.0.json +703 -0
  73. package/src/assets/adapters/facebook/wrench-web-adapter.v1.2.0.json +750 -0
  74. package/src/assets/adapters/facebook-group/wrench-web-adapter.json +682 -0
  75. package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.0.0.json +583 -0
  76. package/src/assets/adapters/facebook-group/wrench-web-adapter.v1.1.0.json +682 -0
  77. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.json +437 -0
  78. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.0.0.json +383 -0
  79. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.0.json +437 -0
  80. package/src/assets/adapters/facebook-marketplace/wrench-web-adapter.v1.1.1.json +437 -0
  81. package/src/assets/adapters/facebook-page/wrench-web-adapter.json +880 -0
  82. package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.0.0.json +740 -0
  83. package/src/assets/adapters/facebook-page/wrench-web-adapter.v1.1.0.json +880 -0
  84. package/src/assets/adapters/github/wrench-web-adapter.json +69 -0
  85. package/src/assets/adapters/github/wrench-web-adapter.v1.0.0.json +42 -0
  86. package/src/assets/adapters/github/wrench-web-adapter.v1.1.0.json +69 -0
  87. package/src/assets/adapters/gmail/wrench-adapter.json +161 -0
  88. package/src/assets/adapters/gmail/wrench-adapter.v1.2.0.json +157 -0
  89. package/src/assets/adapters/hacker-news/wrench-web-adapter.json +315 -0
  90. package/src/assets/adapters/hacker-news/wrench-web-adapter.v1.0.0.json +315 -0
  91. package/src/assets/adapters/imessage/wrench-web-adapter.json +236 -0
  92. package/src/assets/adapters/instagram/wrench-web-adapter.json +719 -0
  93. package/src/assets/adapters/instagram/wrench-web-adapter.v1.0.0.json +627 -0
  94. package/src/assets/adapters/instagram/wrench-web-adapter.v1.1.0.json +609 -0
  95. package/src/assets/adapters/instagram/wrench-web-adapter.v1.2.0.json +640 -0
  96. package/src/assets/adapters/instagram/wrench-web-adapter.v1.3.0.json +671 -0
  97. package/src/assets/adapters/instagram/wrench-web-adapter.v1.4.0.json +710 -0
  98. package/src/assets/adapters/instagram/wrench-web-adapter.v1.5.0.json +710 -0
  99. package/src/assets/adapters/instagram/wrench-web-adapter.v1.6.0.json +719 -0
  100. package/src/assets/adapters/instagram/wrench-web-adapter.v1.7.0.json +719 -0
  101. package/src/assets/adapters/linkedin/wrench-adapter.json +442 -0
  102. package/src/assets/adapters/linkedin/wrench-adapter.v0.4.0.json +124 -0
  103. package/src/assets/adapters/linkedin/wrench-adapter.v1.0.0.json +411 -0
  104. package/src/assets/adapters/linkedin/wrench-web-adapter.json +914 -0
  105. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.0.0.json +604 -0
  106. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.1.0.json +604 -0
  107. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.10.0.json +809 -0
  108. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.11.0.json +809 -0
  109. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.12.0.json +820 -0
  110. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.13.0.json +819 -0
  111. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.14.0.json +819 -0
  112. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.15.0.json +819 -0
  113. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.16.0.json +874 -0
  114. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.17.0.json +874 -0
  115. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.18.0.json +874 -0
  116. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.19.0.json +874 -0
  117. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.2.0.json +731 -0
  118. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.3.0.json +768 -0
  119. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.4.0.json +808 -0
  120. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.5.0.json +808 -0
  121. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.6.0.json +808 -0
  122. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.7.0.json +825 -0
  123. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.8.0.json +792 -0
  124. package/src/assets/adapters/linkedin/wrench-web-adapter.v1.9.0.json +809 -0
  125. package/src/assets/adapters/reddit/wrench-web-adapter.json +855 -0
  126. package/src/assets/adapters/reddit/wrench-web-adapter.v1.0.0.json +577 -0
  127. package/src/assets/adapters/reddit/wrench-web-adapter.v1.1.0.json +604 -0
  128. package/src/assets/adapters/reddit/wrench-web-adapter.v1.10.0.json +712 -0
  129. package/src/assets/adapters/reddit/wrench-web-adapter.v1.11.0.json +712 -0
  130. package/src/assets/adapters/reddit/wrench-web-adapter.v1.12.0.json +712 -0
  131. package/src/assets/adapters/reddit/wrench-web-adapter.v1.2.0.json +653 -0
  132. package/src/assets/adapters/reddit/wrench-web-adapter.v1.3.0.json +712 -0
  133. package/src/assets/adapters/reddit/wrench-web-adapter.v1.4.0.json +713 -0
  134. package/src/assets/adapters/reddit/wrench-web-adapter.v1.5.0.json +712 -0
  135. package/src/assets/adapters/reddit/wrench-web-adapter.v1.6.0.json +713 -0
  136. package/src/assets/adapters/reddit/wrench-web-adapter.v1.7.0.json +713 -0
  137. package/src/assets/adapters/reddit/wrench-web-adapter.v1.8.0.json +713 -0
  138. package/src/assets/adapters/reddit/wrench-web-adapter.v1.9.0.json +713 -0
  139. package/src/assets/adapters/substack/wrench-web-adapter.json +936 -0
  140. package/src/assets/adapters/substack/wrench-web-adapter.v1.0.0.json +817 -0
  141. package/src/assets/adapters/substack/wrench-web-adapter.v1.1.0.json +812 -0
  142. package/src/assets/adapters/substack/wrench-web-adapter.v1.2.0.json +812 -0
  143. package/src/assets/adapters/substack/wrench-web-adapter.v1.3.0.json +902 -0
  144. package/src/assets/adapters/substack/wrench-web-adapter.v1.4.0.json +936 -0
  145. package/src/assets/adapters/substack/wrench-web-adapter.v1.5.0.json +936 -0
  146. package/src/assets/adapters/substack/wrench-web-adapter.v1.6.0.json +936 -0
  147. package/src/assets/adapters/threads/wrench-web-adapter.json +692 -0
  148. package/src/assets/adapters/threads/wrench-web-adapter.v1.0.0.json +629 -0
  149. package/src/assets/adapters/threads/wrench-web-adapter.v1.1.0.json +623 -0
  150. package/src/assets/adapters/threads/wrench-web-adapter.v1.2.0.json +622 -0
  151. package/src/assets/adapters/threads/wrench-web-adapter.v1.3.0.json +622 -0
  152. package/src/assets/adapters/threads/wrench-web-adapter.v1.4.0.json +622 -0
  153. package/src/assets/adapters/threads/wrench-web-adapter.v1.5.0.json +699 -0
  154. package/src/assets/adapters/threads/wrench-web-adapter.v1.6.0.json +693 -0
  155. package/src/assets/adapters/threads/wrench-web-adapter.v1.7.0.json +692 -0
  156. package/src/assets/adapters/tiktok/wrench-web-adapter.json +762 -0
  157. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.0.0.json +681 -0
  158. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.1.0.json +708 -0
  159. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.2.0.json +762 -0
  160. package/src/assets/adapters/tiktok/wrench-web-adapter.v1.3.0.json +762 -0
  161. package/src/assets/adapters/twitch/wrench-web-adapter.json +42 -0
  162. package/src/assets/adapters/twitch/wrench-web-adapter.v1.0.0.json +42 -0
  163. package/src/assets/adapters/whatsapp/wrench-web-adapter.json +400 -0
  164. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.0.0.json +355 -0
  165. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.1.0.json +386 -0
  166. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.2.0.json +386 -0
  167. package/src/assets/adapters/whatsapp/wrench-web-adapter.v1.3.0.json +400 -0
  168. package/src/assets/adapters/x/wrench-adapter.json +749 -0
  169. package/src/assets/adapters/x/wrench-adapter.v1.0.0.json +700 -0
  170. package/src/assets/adapters/x/wrench-adapter.v1.1.0.json +707 -0
  171. package/src/assets/adapters/x/wrench-web-adapter.json +712 -0
  172. package/src/assets/adapters/x/wrench-web-adapter.v1.1.0.json +579 -0
  173. package/src/assets/adapters/x/wrench-web-adapter.v1.10.0.json +685 -0
  174. package/src/assets/adapters/x/wrench-web-adapter.v1.11.0.json +712 -0
  175. package/src/assets/adapters/x/wrench-web-adapter.v1.12.0.json +712 -0
  176. package/src/assets/adapters/x/wrench-web-adapter.v1.13.0.json +712 -0
  177. package/src/assets/adapters/x/wrench-web-adapter.v1.2.0.json +578 -0
  178. package/src/assets/adapters/x/wrench-web-adapter.v1.3.0.json +610 -0
  179. package/src/assets/adapters/x/wrench-web-adapter.v1.4.0.json +617 -0
  180. package/src/assets/adapters/x/wrench-web-adapter.v1.5.0.json +634 -0
  181. package/src/assets/adapters/x/wrench-web-adapter.v1.6.0.json +632 -0
  182. package/src/assets/adapters/x/wrench-web-adapter.v1.7.0.json +649 -0
  183. package/src/assets/adapters/x/wrench-web-adapter.v1.8.0.json +649 -0
  184. package/src/assets/adapters/x/wrench-web-adapter.v1.9.0.json +683 -0
  185. package/src/assets/adapters/youtube/wrench-web-adapter.json +561 -0
  186. package/src/assets/adapters/youtube/wrench-web-adapter.v1.0.0.json +465 -0
  187. package/src/assets/adapters/youtube/wrench-web-adapter.v1.1.0.json +519 -0
  188. package/src/assets/adapters/youtube/wrench-web-adapter.v1.2.0.json +561 -0
  189. package/src/assets/adapters/youtube/wrench-web-adapter.v1.3.0.json +561 -0
  190. package/src/assets/code-owned-provider-template/plugin.test.ts.template +54 -0
  191. package/src/assets/code-owned-provider-template/plugin.ts.template +102 -0
  192. package/src/assets/code-owned-provider-template/runtime.internal.test.ts.template +44 -0
  193. package/src/assets/code-owned-provider-template/runtime.ts.template +59 -0
  194. package/src/assets/code-owned-provider-template/wrench-adapter.json.template +33 -0
  195. package/src/assets/fonts/nebula-sans/LICENSE.txt +96 -0
  196. package/src/assets/fonts/nebula-sans/NebulaSans-Book.woff2 +0 -0
  197. package/src/assets/fonts/nebula-sans/PROVENANCE.md +14 -0
  198. package/src/assets.d.ts +4 -0
  199. package/src/auth.ts +1157 -0
  200. package/src/beeper-client-types.ts +169 -0
  201. package/src/beeper-client.ts +250 -0
  202. package/src/beeper-contact-interactions-cli.ts +180 -0
  203. package/src/beeper-contact-interactions.ts +1612 -0
  204. package/src/beeper-message-bundle-v1.ts +257 -0
  205. package/src/beeper-message-like-me-cli.ts +84 -0
  206. package/src/beeper-message-like-me-export.ts +2274 -0
  207. package/src/beeper-message-like-me-recovery.ts +931 -0
  208. package/src/beeper-message-like-me-source.ts +4034 -0
  209. package/src/browser-admission.ts +928 -0
  210. package/src/browser-snapshots.ts +260 -0
  211. package/src/browser.ts +3873 -0
  212. package/src/canonical-json.ts +60 -0
  213. package/src/catalog-cli.ts +638 -0
  214. package/src/cli.ts +208 -0
  215. package/src/client-types.ts +301 -0
  216. package/src/client.ts +2726 -0
  217. package/src/confirmed-write-failure.ts +44 -0
  218. package/src/confirmed-write-model.ts +72 -0
  219. package/src/confirmed-write-platform.ts +1055 -0
  220. package/src/confirmed-write-program.ts +224 -0
  221. package/src/confirmed-write-runtime.ts +16 -0
  222. package/src/cursor-token.ts +228 -0
  223. package/src/derivation-dnr-readiness.ts +367 -0
  224. package/src/derivation-file-chooser.ts +384 -0
  225. package/src/derivation-network-boundary.ts +835 -0
  226. package/src/derivation-network-guard.ts +782 -0
  227. package/src/derivation-network-proxy-helper.ts +440 -0
  228. package/src/derivation-network-proxy.ts +385 -0
  229. package/src/derive-command-helper.ts +693 -0
  230. package/src/derive-fixtures.ts +343 -0
  231. package/src/derive-review.ts +980 -0
  232. package/src/derive.ts +4754 -0
  233. package/src/fixtures/beeper-message-like-me-v1/accounts.ndjson +2 -0
  234. package/src/fixtures/beeper-message-like-me-v1/conversations.ndjson +1 -0
  235. package/src/fixtures/beeper-message-like-me-v1/manifest.json +1 -0
  236. package/src/fixtures/beeper-message-like-me-v1/messages.ndjson +2 -0
  237. package/src/fixtures/beeper-message-like-me-v1/participants.ndjson +3 -0
  238. package/src/fixtures/beeper-message-like-me-v1/reactions.ndjson +1 -0
  239. package/src/fixtures/beeper-message-like-me-v1/tombstones.ndjson +1 -0
  240. package/src/ghostget.ts +3672 -0
  241. package/src/gmail-capture.ts +1244 -0
  242. package/src/har-internal.ts +1242 -0
  243. package/src/har.ts +743 -0
  244. package/src/index.ts +218 -0
  245. package/src/invocation-read-platform.ts +55 -0
  246. package/src/invocation-read-program.ts +93 -0
  247. package/src/invocation-read-runtime.ts +11 -0
  248. package/src/linked-device-lifecycle-admission.ts +450 -0
  249. package/src/linked-device-lifecycle-journal.ts +1560 -0
  250. package/src/linked-device-lifecycle-runtime.ts +1602 -0
  251. package/src/local-cli-admission.ts +135 -0
  252. package/src/local-cli-contracts.ts +271 -0
  253. package/src/local-cli-execution.ts +98 -0
  254. package/src/local-cli-surface-contract.ts +1510 -0
  255. package/src/local-cli-tool-identity.ts +336 -0
  256. package/src/media/archive.ts +2325 -0
  257. package/src/media/args.ts +303 -0
  258. package/src/media/cli.ts +287 -0
  259. package/src/media/doctor.ts +475 -0
  260. package/src/media/ffmpeg.ts +1330 -0
  261. package/src/media/http-capture.ts +711 -0
  262. package/src/media/http-probe.ts +593 -0
  263. package/src/media/http.ts +387 -0
  264. package/src/media/index.ts +10 -0
  265. package/src/media/local-transcription.ts +613 -0
  266. package/src/media/lock.ts +321 -0
  267. package/src/media/manifest.ts +1712 -0
  268. package/src/media/metadata.ts +906 -0
  269. package/src/media/process.ts +723 -0
  270. package/src/media/revision.ts +166 -0
  271. package/src/media/runtime-closure.ts +1063 -0
  272. package/src/media/source-router.ts +187 -0
  273. package/src/media/transcriber-config.ts +1122 -0
  274. package/src/media/transcript-persistence-model.ts +15 -0
  275. package/src/media/transcript-persistence-platform.ts +89 -0
  276. package/src/media/transcript-persistence-program.ts +39 -0
  277. package/src/media/transcript-persistence-runtime.ts +24 -0
  278. package/src/media/transcript.ts +616 -0
  279. package/src/media/utf8-order.ts +30 -0
  280. package/src/media/whisper-cpp.ts +464 -0
  281. package/src/media/whisper-language.ts +58 -0
  282. package/src/media/yt-dlp.ts +439 -0
  283. package/src/message-like-me-agentic-messaging.ts +882 -0
  284. package/src/messaging-action-store.ts +793 -0
  285. package/src/messaging-runtime.ts +2136 -0
  286. package/src/messaging-store.ts +539 -0
  287. package/src/messaging-types.ts +1663 -0
  288. package/src/messaging.ts +334 -0
  289. package/src/model.ts +2671 -0
  290. package/src/oauth-google.ts +888 -0
  291. package/src/omni-client-types.ts +306 -0
  292. package/src/omni-client.ts +2225 -0
  293. package/src/omni-limits.ts +34 -0
  294. package/src/omni-model.ts +1614 -0
  295. package/src/omni-request.ts +379 -0
  296. package/src/omni-runtime.ts +1632 -0
  297. package/src/operation-deadline.ts +189 -0
  298. package/src/path-helper.ts +1656 -0
  299. package/src/pinned-https.ts +194 -0
  300. package/src/plan-assets.ts +832 -0
  301. package/src/platform-catalog.ts +1832 -0
  302. package/src/plugins/beeper-linked-device/plugin.ts +310 -0
  303. package/src/plugins/bluesky-web/plugin.ts +178 -0
  304. package/src/plugins/clasificados-web/plugin.ts +66 -0
  305. package/src/plugins/github-web/plugin.ts +80 -0
  306. package/src/plugins/gmail-official/plugin.ts +110 -0
  307. package/src/plugins/hacker-news-web/plugin.ts +52 -0
  308. package/src/plugins/imessage-direct/plugin.ts +195 -0
  309. package/src/plugins/imessage-direct/vendor/0001-fix-keep-AppleScript-send-payloads-out-of-child-argv.patch +1430 -0
  310. package/src/plugins/imessage-direct/vendor/0002-feat-rpc-add-exact-chat-lookup.patch +225 -0
  311. package/src/plugins/imessage-direct/vendor/provenance.json +80 -0
  312. package/src/plugins/linkedin-official/plugin.ts +84 -0
  313. package/src/plugins/linkedin-web/plugin.ts +412 -0
  314. package/src/plugins/meta-web/plugin.ts +317 -0
  315. package/src/plugins/reddit-web/flair.ts +492 -0
  316. package/src/plugins/reddit-web/plugin.ts +477 -0
  317. package/src/plugins/substack-web/plugin.ts +124 -0
  318. package/src/plugins/tiktok-web/plugin.ts +67 -0
  319. package/src/plugins/twitch-web/plugin.ts +54 -0
  320. package/src/plugins/whatsapp-linked-device/plugin.ts +105 -0
  321. package/src/plugins/x-official/plugin.ts +64 -0
  322. package/src/plugins/x-web/plugin.ts +488 -0
  323. package/src/plugins/youtube-web/plugin.ts +101 -0
  324. package/src/portable-run-recovery.ts +466 -0
  325. package/src/process-identity.ts +501 -0
  326. package/src/profile-clone-helper.ts +104 -0
  327. package/src/provider-catalog-views.ts +51 -0
  328. package/src/provider-context.ts +69 -0
  329. package/src/provider-contract-definitions-x.ts +45 -0
  330. package/src/provider-contract-definitions.ts +948 -0
  331. package/src/provider-contract-input-gmail.ts +176 -0
  332. package/src/provider-contract-input-linkedin.ts +77 -0
  333. package/src/provider-contract-input-x.ts +304 -0
  334. package/src/provider-contract-planning.ts +23 -0
  335. package/src/provider-contract-semantic-identity.ts +54 -0
  336. package/src/provider-contracts.ts +251 -0
  337. package/src/provider-http.ts +723 -0
  338. package/src/provider-plugin-auth.ts +36 -0
  339. package/src/provider-plugin-builtins.ts +229 -0
  340. package/src/provider-plugin-cleanup-barrier.ts +229 -0
  341. package/src/provider-plugin-cleanup-execution.ts +79 -0
  342. package/src/provider-plugin-cleanup-resource.ts +470 -0
  343. package/src/provider-plugin-contract-identity.ts +707 -0
  344. package/src/provider-plugin-host.ts +1972 -0
  345. package/src/provider-plugin-identifiers.ts +60 -0
  346. package/src/provider-plugin-invocation-lease.ts +889 -0
  347. package/src/provider-plugin-lifecycle-kernel.ts +566 -0
  348. package/src/provider-plugin-lifecycle.ts +1455 -0
  349. package/src/provider-plugin-module-analysis.ts +336 -0
  350. package/src/provider-plugin-package.ts +2530 -0
  351. package/src/provider-plugin-portable-authority.ts +106 -0
  352. package/src/provider-plugin-portable-catalog.ts +94 -0
  353. package/src/provider-plugin-portable-identity.ts +315 -0
  354. package/src/provider-plugin-portable-runtime.ts +2057 -0
  355. package/src/provider-plugin-protocol.ts +1625 -0
  356. package/src/provider-plugin-registry.ts +3342 -0
  357. package/src/provider-plugin-store.ts +2155 -0
  358. package/src/provider-plugin-test-fixture.ts +5 -0
  359. package/src/provider-plugin.ts +4907 -0
  360. package/src/provider-plugins.generated.ts +43 -0
  361. package/src/provider-plugins.ts +8 -0
  362. package/src/provider-subject.ts +41 -0
  363. package/src/provider.ts +315 -0
  364. package/src/providers/beeper-local-runtime.ts +5426 -0
  365. package/src/providers/beeper-local.ts +2739 -0
  366. package/src/providers/beeper-messaging.ts +462 -0
  367. package/src/providers/beeper-omni.ts +1159 -0
  368. package/src/providers/bluesky-web-runtime.ts +2895 -0
  369. package/src/providers/bluesky-web.ts +1614 -0
  370. package/src/providers/clasificados-web-runtime.ts +255 -0
  371. package/src/providers/clasificados-web.ts +503 -0
  372. package/src/providers/contact-projection.ts +301 -0
  373. package/src/providers/github-read-model.ts +94 -0
  374. package/src/providers/github-read-platform.ts +165 -0
  375. package/src/providers/github-read-program.ts +97 -0
  376. package/src/providers/github-web-runtime.ts +320 -0
  377. package/src/providers/github-web.ts +403 -0
  378. package/src/providers/gmail-api.ts +2834 -0
  379. package/src/providers/gmail-omni.ts +830 -0
  380. package/src/providers/gmail.ts +1130 -0
  381. package/src/providers/hacker-news-web-runtime.ts +220 -0
  382. package/src/providers/hacker-news-web.ts +809 -0
  383. package/src/providers/imessage-direct-install.ts +354 -0
  384. package/src/providers/imessage-direct-messaging.ts +532 -0
  385. package/src/providers/imessage-direct-omni.ts +400 -0
  386. package/src/providers/imessage-direct-runtime.ts +1498 -0
  387. package/src/providers/imessage-direct.ts +351 -0
  388. package/src/providers/instagram-video-foundations.ts +913 -0
  389. package/src/providers/instagram-web-profile-browser.ts +600 -0
  390. package/src/providers/iso-bmff.ts +338 -0
  391. package/src/providers/linkedin-company-platform.ts +42 -0
  392. package/src/providers/linkedin-company-program.ts +88 -0
  393. package/src/providers/linkedin-contact-failure.ts +84 -0
  394. package/src/providers/linkedin-contact-platform.ts +45 -0
  395. package/src/providers/linkedin-contact-program.ts +91 -0
  396. package/src/providers/linkedin-profile-activity-failure.ts +76 -0
  397. package/src/providers/linkedin-profile-activity-platform.ts +41 -0
  398. package/src/providers/linkedin-profile-activity-program.ts +67 -0
  399. package/src/providers/linkedin-read-failure.ts +52 -0
  400. package/src/providers/linkedin-self-platform.ts +53 -0
  401. package/src/providers/linkedin-self-program.ts +122 -0
  402. package/src/providers/linkedin-web-article-browser.ts +794 -0
  403. package/src/providers/linkedin-web-bootstrap.ts +146 -0
  404. package/src/providers/linkedin-web-contact.ts +830 -0
  405. package/src/providers/linkedin-web-feed-browser.ts +832 -0
  406. package/src/providers/linkedin-web-feed.ts +864 -0
  407. package/src/providers/linkedin-web-post-browser.ts +653 -0
  408. package/src/providers/linkedin-web-profile-browser.ts +683 -0
  409. package/src/providers/linkedin-web-runtime.ts +2388 -0
  410. package/src/providers/linkedin-web.ts +3305 -0
  411. package/src/providers/linkedin.ts +1885 -0
  412. package/src/providers/meta-bootstrap.ts +1043 -0
  413. package/src/providers/meta-facebook-group.ts +690 -0
  414. package/src/providers/meta-marketplace-relay.ts +747 -0
  415. package/src/providers/meta-omni.ts +373 -0
  416. package/src/providers/meta-relay-bundle.ts +1049 -0
  417. package/src/providers/meta-web-descriptors.ts +1740 -0
  418. package/src/providers/meta-web-runtime.ts +3388 -0
  419. package/src/providers/meta-web.ts +2931 -0
  420. package/src/providers/read-failure.ts +139 -0
  421. package/src/providers/reddit-omni.ts +462 -0
  422. package/src/providers/reddit-web-runtime.ts +1929 -0
  423. package/src/providers/reddit-web.ts +1611 -0
  424. package/src/providers/rental-listings.ts +460 -0
  425. package/src/providers/substack-omni.ts +406 -0
  426. package/src/providers/substack-video-mp4.ts +33 -0
  427. package/src/providers/substack-web-runtime.ts +2812 -0
  428. package/src/providers/substack-web.ts +1502 -0
  429. package/src/providers/tiktok-video-mp4.ts +33 -0
  430. package/src/providers/tiktok-web-runtime.ts +770 -0
  431. package/src/providers/tiktok-web.ts +2786 -0
  432. package/src/providers/twitch-web-runtime.ts +226 -0
  433. package/src/providers/twitch-web.ts +274 -0
  434. package/src/providers/whatsapp-account-identity.ts +55 -0
  435. package/src/providers/whatsapp-contact-projection-helper.ts +874 -0
  436. package/src/providers/whatsapp-contact-projection-protocol.ts +403 -0
  437. package/src/providers/whatsapp-interaction-projection-helper.ts +1452 -0
  438. package/src/providers/whatsapp-interaction-projection-protocol.ts +462 -0
  439. package/src/providers/whatsapp-message-export-projection-protocol.ts +532 -0
  440. package/src/providers/whatsapp-messaging.ts +132 -0
  441. package/src/providers/whatsapp-omni.ts +586 -0
  442. package/src/providers/whatsapp-web-runtime.ts +3108 -0
  443. package/src/providers/whatsapp-web.ts +1037 -0
  444. package/src/providers/x-image-provenance.ts +523 -0
  445. package/src/providers/x-made-with-ai.ts +106 -0
  446. package/src/providers/x-transaction-id.ts +413 -0
  447. package/src/providers/x-web-runtime.ts +3485 -0
  448. package/src/providers/x-web.ts +2332 -0
  449. package/src/providers/x.ts +1889 -0
  450. package/src/providers/youtube-web-runtime.ts +1400 -0
  451. package/src/providers/youtube-web.ts +1221 -0
  452. package/src/read-admission-runtime.ts +91 -0
  453. package/src/read-client.ts +521 -0
  454. package/src/read-effect-platform.ts +7 -0
  455. package/src/read-effect-runtime.ts +14 -0
  456. package/src/read-effect.ts +52 -0
  457. package/src/read-projection-admission.ts +866 -0
  458. package/src/read-projections.ts +3151 -0
  459. package/src/recovery.ts +1492 -0
  460. package/src/reviewed-template.ts +146 -0
  461. package/src/run-journal.ts +1272 -0
  462. package/src/runtime.ts +5116 -0
  463. package/src/scripts/generate-provider-plugin-catalog.ts +121 -0
  464. package/src/scripts/install-whatsapp-protocol.sh +232 -0
  465. package/src/scripts/recover-install-stages.ts +1491 -0
  466. package/src/scripts/resolve-state-home.ts +30 -0
  467. package/src/scripts/scaffold-web-provider.ts +973 -0
  468. package/src/scripts/sync-bundled-adapters.ts +695 -0
  469. package/src/session-secrets.ts +1183 -0
  470. package/src/state-helper.bunfig.toml +2 -0
  471. package/src/state-helper.ts +2914 -0
  472. package/src/storage.ts +3842 -0
  473. package/src/transport-policy.ts +2 -0
  474. package/src/usage.ts +182 -0
  475. package/src/version.ts +2 -0
  476. package/src/web-session-authentication-policy.ts +136 -0
  477. package/src/web-session-cleanup-admission.ts +2344 -0
  478. package/src/web-session-cleanup-join.ts +99 -0
  479. package/src/web-session-client.ts +996 -0
  480. package/src/web-session-contract-definitions.ts +820 -0
  481. package/src/web-session-contract-planning.ts +42 -0
  482. package/src/web-session-contracts.ts +228 -0
  483. package/src/web-session-cookies.ts +500 -0
  484. package/src/web-session-execution.ts +385 -0
  485. package/src/web-session-http.ts +373 -0
  486. package/src/web-session-read-errors.ts +19 -0
  487. package/src/web-session-read-runtime.ts +124 -0
  488. package/src/web-session-recovery.ts +818 -0
  489. package/src/web-session-sites.ts +58 -0
  490. package/src/web-session-template.ts +994 -0
  491. package/src/web-session.ts +93 -0
  492. package/src/whatsapp-client-binding.ts +21 -0
  493. package/src/whatsapp-client-types.ts +75 -0
  494. package/src/whatsapp-client.ts +395 -0
  495. package/src/whatsapp-export-coordinate.ts +17 -0
  496. package/src/whatsapp-message-bundle-v2.ts +195 -0
  497. package/src/whatsapp-message-like-me-cli.ts +195 -0
  498. package/src/whatsapp-message-like-me-export.ts +1072 -0
  499. package/src/whatsapp-message-like-me-source.ts +1012 -0
  500. package/tsconfig.json +67 -0
@@ -0,0 +1,169 @@
1
+ /** Self-contained DTO types for the side-effect-free public Beeper client. */
2
+
3
+ export type BeeperContactInteractionAccount = Readonly<{
4
+ accountId: string;
5
+ accountProviderId: string;
6
+ network: string;
7
+ selfParticipantId: string;
8
+ selfParticipantProviderId: string;
9
+ observedAt: string;
10
+ }>;
11
+
12
+ export type BeeperContactInteraction = Readonly<{
13
+ accountId: string;
14
+ accountProviderId: string;
15
+ contactId: string;
16
+ contactProviderId: string;
17
+ network: string;
18
+ sentCount: number;
19
+ receivedCount: number;
20
+ interactionCount: number;
21
+ conversationCount: number;
22
+ firstInteractionAt: string;
23
+ lastInteractionAt: string;
24
+ reciprocal: boolean;
25
+ completeness: "lower-bound";
26
+ provenance: Readonly<{
27
+ sourceId: "beeper-local";
28
+ sourceVersion: "1.1.0";
29
+ providerId: "beeper";
30
+ providerVersion: string;
31
+ observedAt: string;
32
+ }>;
33
+ }>;
34
+
35
+ export type BeeperContactInteractionSummary = Readonly<{
36
+ schemaVersion: 1;
37
+ format: "wrench.contact-interaction-summary";
38
+ transform: Readonly<{
39
+ id: "beeper-direct-contact-interactions";
40
+ version: 1;
41
+ sourceVersion: "1.1.0";
42
+ }>;
43
+ source: Readonly<{ id: "beeper-local"; version: "1.1.0" }>;
44
+ provider: Readonly<{ id: "beeper"; version: string }>;
45
+ observedAt: string | null;
46
+ scope: Readonly<{
47
+ conversations: "complete-direct-only";
48
+ messages: "current-direction-known-only";
49
+ }>;
50
+ completeness: Readonly<{
51
+ kind: "lower-bound";
52
+ sourceKind: "bounded-local" | "truncated" | "unknown";
53
+ reason: string | null;
54
+ observedFrom: string | null;
55
+ observedThrough: string | null;
56
+ }>;
57
+ warnings: readonly string[];
58
+ privacy: Readonly<{
59
+ messageBodies: "excluded";
60
+ attachments: "excluded";
61
+ reactions: "excluded";
62
+ media: "excluded";
63
+ groupMessages: "excluded";
64
+ localPaths: "excluded";
65
+ credentials: "excluded";
66
+ }>;
67
+ counts: Readonly<{
68
+ accounts: number;
69
+ directRelationships: number;
70
+ directConversations: number;
71
+ interactions: number;
72
+ sent: number;
73
+ received: number;
74
+ }>;
75
+ accounts: readonly BeeperContactInteractionAccount[];
76
+ interactions: readonly BeeperContactInteraction[];
77
+ integrity: Readonly<{
78
+ algorithm: "sha256";
79
+ summarySha256: string;
80
+ }>;
81
+ }>;
82
+
83
+ export type BeeperContactInteractionExportBounds = Readonly<{
84
+ limitChats: number | null;
85
+ limitMessages: number | null;
86
+ maxParticipants: number | null;
87
+ }>;
88
+
89
+ export type BeeperContactInteractionExportReceipt = Readonly<{
90
+ schemaVersion: 1;
91
+ format: "wrench.beeper-contact-interaction-export-receipt";
92
+ runId: string;
93
+ operation: "beeper.export-contact-interactions";
94
+ status: "succeeded";
95
+ transport: "linked-device";
96
+ implementation: Readonly<{
97
+ producer: Readonly<{
98
+ package: "@hraness/ghostget";
99
+ version: "0.17.2";
100
+ }>;
101
+ officialCli: Readonly<{
102
+ implementation: "github.com/beeper/cli";
103
+ version: "0.6.2";
104
+ commit: "a416af06023449a87312dc11e54643fd9dc94b8c";
105
+ platform: "darwin-arm64";
106
+ binarySha256: "48aa895449129c793a212ea19f69a534adc34a8adc4037ca1d7da9e648716425";
107
+ }>;
108
+ }>;
109
+ startedAt: string;
110
+ finishedAt: string;
111
+ auth: Readonly<{
112
+ id: string;
113
+ kind: "linked-device-store";
114
+ provider: "beeper";
115
+ identitySha256: string;
116
+ }>;
117
+ bounds: BeeperContactInteractionExportBounds;
118
+ source: BeeperContactInteractionSummary["source"];
119
+ provider: BeeperContactInteractionSummary["provider"];
120
+ transform: BeeperContactInteractionSummary["transform"];
121
+ completeness: BeeperContactInteractionSummary["completeness"];
122
+ counts: BeeperContactInteractionSummary["counts"];
123
+ output: Readonly<{
124
+ schemaVersion: 1;
125
+ format: "wrench.contact-interaction-summary";
126
+ summarySha256: string;
127
+ }>;
128
+ privacy: Readonly<{
129
+ messageBodies: "excluded";
130
+ attachments: "excluded";
131
+ reactions: "excluded";
132
+ media: "excluded";
133
+ localPaths: "excluded";
134
+ credentials: "excluded";
135
+ }>;
136
+ integrity: Readonly<{
137
+ algorithm: "sha256";
138
+ receiptSha256: string;
139
+ }>;
140
+ }>;
141
+
142
+ export type BeeperContactInteractionExportResult = Readonly<{
143
+ receipt: BeeperContactInteractionExportReceipt;
144
+ output: BeeperContactInteractionSummary;
145
+ }>;
146
+
147
+ export type BeeperContactInteractionClientRequest = Readonly<{
148
+ authId: string;
149
+ limitChats?: number;
150
+ limitMessages?: number;
151
+ maxParticipants?: number;
152
+ }>;
153
+
154
+ export type BeeperContactInteractionClientOptions = Readonly<{
155
+ environment?: Readonly<Record<string, string | undefined>>;
156
+ }>;
157
+
158
+ export declare function exportBeeperContactInteractionsSync(
159
+ request: BeeperContactInteractionClientRequest,
160
+ options?: BeeperContactInteractionClientOptions,
161
+ ): BeeperContactInteractionExportResult;
162
+
163
+ export declare function parseBeeperContactInteractionExportResult(
164
+ value: unknown,
165
+ ): BeeperContactInteractionExportResult;
166
+
167
+ export declare function parseBeeperContactInteractionSummary(
168
+ value: unknown,
169
+ ): BeeperContactInteractionSummary;
@@ -0,0 +1,250 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { types as nodeTypes } from "node:util";
5
+
6
+ import {
7
+ BEEPER_CONTACT_INTERACTION_WIRE_MAX_BYTES,
8
+ parseBeeperContactInteractionExportResult,
9
+ } from "./beeper-contact-interactions";
10
+ import type {
11
+ BeeperContactInteractionClientOptions,
12
+ BeeperContactInteractionClientRequest,
13
+ BeeperContactInteractionExportResult,
14
+ } from "./beeper-client-types";
15
+
16
+ const MAX_STDERR_BYTES = 8 * 1024;
17
+ const PROCESS_TIMEOUT_MS = 6 * 60 * 60 * 1_000 + 60_000;
18
+
19
+ function fail(message: string): never {
20
+ throw new Error(`Ghostget Beeper client: ${message}`);
21
+ }
22
+
23
+ function cliSourcePath(): string {
24
+ const besideSource = fileURLToPath(new URL("./cli.ts", import.meta.url));
25
+ if (existsSync(besideSource)) return besideSource;
26
+ const packagedSource = fileURLToPath(new URL("../src/cli.ts", import.meta.url));
27
+ if (existsSync(packagedSource)) return packagedSource;
28
+ return fail("the installed Ghostget CLI source is unavailable");
29
+ }
30
+
31
+ function requireBunRuntime(): void {
32
+ if (typeof process.versions.bun !== "string") {
33
+ fail("@hraness/ghostget/beeper requires Bun to run the installed Ghostget CLI");
34
+ }
35
+ }
36
+
37
+ function plainDataObject(
38
+ value: unknown,
39
+ label: string,
40
+ ): Readonly<Record<string, PropertyDescriptor>> {
41
+ if (
42
+ typeof value !== "object"
43
+ || value === null
44
+ || Array.isArray(value)
45
+ || nodeTypes.isProxy(value)
46
+ || (
47
+ Object.getPrototypeOf(value) !== Object.prototype
48
+ && Object.getPrototypeOf(value) !== null
49
+ )
50
+ ) return fail(`${label} must use a plain, non-proxy object`);
51
+ const descriptors = Object.getOwnPropertyDescriptors(value);
52
+ const keys = Reflect.ownKeys(descriptors);
53
+ if (keys.some((key) => typeof key !== "string")) {
54
+ return fail(`${label} has unsupported symbol fields`);
55
+ }
56
+ for (const key of keys as string[]) {
57
+ const descriptor = descriptors[key];
58
+ if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor)) {
59
+ return fail(`${label} must contain only enumerable data properties`);
60
+ }
61
+ }
62
+ return descriptors;
63
+ }
64
+
65
+ function positiveInteger(
66
+ value: unknown,
67
+ label: string,
68
+ maximum: number,
69
+ ): number | undefined {
70
+ if (value === undefined) return undefined;
71
+ if (
72
+ typeof value !== "number"
73
+ || !Number.isSafeInteger(value)
74
+ || value < 1
75
+ || value > maximum
76
+ ) return fail(`${label} must be an integer from 1 through ${String(maximum)}`);
77
+ return value;
78
+ }
79
+
80
+ function prepareRequest(
81
+ value: BeeperContactInteractionClientRequest,
82
+ ): Required<Pick<BeeperContactInteractionClientRequest, "authId">>
83
+ & Omit<BeeperContactInteractionClientRequest, "authId"> {
84
+ const descriptors = plainDataObject(value, "request");
85
+ const keys = Object.keys(descriptors);
86
+ const allowed = new Set([
87
+ "authId", "limitChats", "limitMessages", "maxParticipants",
88
+ ]);
89
+ if (!keys.includes("authId") || keys.some((key) => !allowed.has(key))) {
90
+ return fail("request contains unsupported or missing fields");
91
+ }
92
+ const authId = descriptors.authId?.value as unknown;
93
+ if (
94
+ typeof authId !== "string"
95
+ || !/^[a-z][a-z0-9-]{0,127}$/u.test(authId)
96
+ ) return fail("authId must be lowercase kebab text");
97
+ const limitChats = positiveInteger(
98
+ descriptors.limitChats?.value,
99
+ "limitChats",
100
+ 100_000,
101
+ );
102
+ const limitMessages = positiveInteger(
103
+ descriptors.limitMessages?.value,
104
+ "limitMessages",
105
+ 1_000_000,
106
+ );
107
+ const maxParticipants = positiveInteger(
108
+ descriptors.maxParticipants?.value,
109
+ "maxParticipants",
110
+ 2_000,
111
+ );
112
+ return Object.freeze({
113
+ authId,
114
+ ...(limitChats === undefined ? {} : { limitChats }),
115
+ ...(limitMessages === undefined ? {} : { limitMessages }),
116
+ ...(maxParticipants === undefined ? {} : { maxParticipants }),
117
+ });
118
+ }
119
+
120
+ function environmentName(value: string): string {
121
+ if (value.length < 1 || value.includes("=") || value.includes("\0")) {
122
+ return fail("environment name is malformed");
123
+ }
124
+ return value;
125
+ }
126
+
127
+ function prepareEnvironment(
128
+ value: BeeperContactInteractionClientOptions["environment"],
129
+ ): Readonly<Record<string, string>> {
130
+ const environment = Object.create(null) as Record<string, string>;
131
+ for (const [key, item] of Object.entries(process.env)) {
132
+ if (typeof item === "string") environment[key] = item;
133
+ }
134
+ if (value === undefined) return Object.freeze(environment);
135
+ const descriptors = plainDataObject(value, "environment");
136
+ for (const key of Object.keys(descriptors).sort()) {
137
+ const name = environmentName(key);
138
+ const item = descriptors[key]!.value as unknown;
139
+ if (item === undefined) delete environment[name];
140
+ else if (typeof item !== "string" || item.includes("\0")) {
141
+ return fail("environment value is malformed");
142
+ } else environment[name] = item;
143
+ }
144
+ return Object.freeze(environment);
145
+ }
146
+
147
+ function prepareOptions(
148
+ value: BeeperContactInteractionClientOptions,
149
+ ): Readonly<Record<string, string>> {
150
+ const descriptors = plainDataObject(value, "options");
151
+ const keys = Object.keys(descriptors);
152
+ if (keys.some((key) => key !== "environment")) {
153
+ return fail("options contain an unsupported field");
154
+ }
155
+ return prepareEnvironment(descriptors.environment?.value as
156
+ BeeperContactInteractionClientOptions["environment"]);
157
+ }
158
+
159
+ function boundedError(value: unknown): string {
160
+ const text = typeof value === "string" ? value.trim() : "";
161
+ const bytes = Buffer.from(text, "utf8");
162
+ if (bytes.byteLength <= MAX_STDERR_BYTES) return text;
163
+ return `${bytes.subarray(0, MAX_STDERR_BYTES).toString("utf8").trim()}…`;
164
+ }
165
+
166
+ /**
167
+ * Execute Ghostget's installed, reviewed body-free Beeper export synchronously.
168
+ * The executable is package-owned, not caller-selected. Progress is inherited
169
+ * on stderr and the returned value has passed the exact public artifact parser.
170
+ */
171
+ export function exportBeeperContactInteractionsSync(
172
+ requestValue: BeeperContactInteractionClientRequest,
173
+ optionsValue: BeeperContactInteractionClientOptions = {},
174
+ ): BeeperContactInteractionExportResult {
175
+ requireBunRuntime();
176
+ const request = prepareRequest(requestValue);
177
+ const environment = prepareOptions(optionsValue);
178
+ const result = spawnSync(process.execPath, [
179
+ cliSourcePath(),
180
+ "beeper",
181
+ "export-contact-interactions",
182
+ "--auth",
183
+ request.authId,
184
+ ...(request.limitChats === undefined
185
+ ? []
186
+ : ["--limit-chats", String(request.limitChats)]),
187
+ ...(request.limitMessages === undefined
188
+ ? []
189
+ : ["--limit-messages", String(request.limitMessages)]),
190
+ ...(request.maxParticipants === undefined
191
+ ? []
192
+ : ["--max-participants", String(request.maxParticipants)]),
193
+ "--json",
194
+ ], {
195
+ cwd: process.cwd(),
196
+ env: environment,
197
+ encoding: "utf8",
198
+ maxBuffer: BEEPER_CONTACT_INTERACTION_WIRE_MAX_BYTES,
199
+ timeout: PROCESS_TIMEOUT_MS,
200
+ stdio: ["ignore", "pipe", "inherit"],
201
+ });
202
+ if (result.error !== undefined) return fail("summary process could not complete");
203
+ if (result.status !== 0 || typeof result.stdout !== "string") {
204
+ const stderr = boundedError(result.stderr);
205
+ return fail(stderr.length === 0 ? "summary process failed" : stderr);
206
+ }
207
+ if (
208
+ Buffer.byteLength(result.stdout, "utf8")
209
+ > BEEPER_CONTACT_INTERACTION_WIRE_MAX_BYTES
210
+ ) {
211
+ return fail("summary response exceeded its byte bound");
212
+ }
213
+ let parsed: unknown;
214
+ try {
215
+ parsed = JSON.parse(result.stdout) as unknown;
216
+ } catch {
217
+ return fail("summary response was not JSON");
218
+ }
219
+ const resultValue = parseBeeperContactInteractionExportResult(parsed);
220
+ if (resultValue.receipt.auth.id !== request.authId) {
221
+ return fail("summary receipt auth does not match its request");
222
+ }
223
+ const expectedBounds = Object.freeze({
224
+ limitChats: request.limitChats ?? null,
225
+ limitMessages: request.limitMessages ?? null,
226
+ maxParticipants: request.maxParticipants ?? null,
227
+ });
228
+ if (
229
+ resultValue.receipt.bounds.limitChats !== expectedBounds.limitChats
230
+ || resultValue.receipt.bounds.limitMessages !== expectedBounds.limitMessages
231
+ || resultValue.receipt.bounds.maxParticipants !== expectedBounds.maxParticipants
232
+ ) return fail("summary receipt bounds do not match its request");
233
+ return resultValue;
234
+ }
235
+
236
+ export {
237
+ parseBeeperContactInteractionExportResult,
238
+ parseBeeperContactInteractionSummary,
239
+ } from "./beeper-contact-interactions";
240
+
241
+ export type {
242
+ BeeperContactInteraction,
243
+ BeeperContactInteractionAccount,
244
+ BeeperContactInteractionClientOptions,
245
+ BeeperContactInteractionClientRequest,
246
+ BeeperContactInteractionExportBounds,
247
+ BeeperContactInteractionExportReceipt,
248
+ BeeperContactInteractionExportResult,
249
+ BeeperContactInteractionSummary,
250
+ } from "./beeper-client-types";
@@ -0,0 +1,180 @@
1
+ import { randomUUID } from "node:crypto";
2
+
3
+ import type { GhostgetAuth } from "./auth";
4
+ import { canonicalJson, sha256 } from "./canonical-json";
5
+ import {
6
+ createBeeperContactInteractionExportResult,
7
+ encodeBeeperContactInteractionExportResult,
8
+ summarizeBeeperContactInteractions,
9
+ type BeeperContactInteractionExportResult,
10
+ type BeeperContactInteractionProgress,
11
+ type BeeperContactInteractionSummary,
12
+ } from "./beeper-contact-interactions";
13
+
14
+ export { encodeBeeperContactInteractionExportResult };
15
+ import {
16
+ acquireBeeperMessageLikeMeExportAdmission,
17
+ recoverBeeperMessageLikeMeDirectoryLeases,
18
+ releaseBeeperMessageLikeMeExportAdmission,
19
+ } from "./beeper-message-like-me-recovery";
20
+ import {
21
+ createBeeperMessageLikeMeSource,
22
+ type BeeperMessageLikeMeProgress,
23
+ type BeeperMessageLikeMeSourceCoordinate,
24
+ type BeeperMessageLikeMeSourceLimits,
25
+ } from "./beeper-message-like-me-source";
26
+
27
+ const CLEANUP_HEARTBEAT_MS = 30_000;
28
+
29
+ export type BeeperContactInteractionCliProgress =
30
+ | BeeperMessageLikeMeProgress
31
+ | BeeperContactInteractionProgress;
32
+
33
+ export type BeeperContactInteractionCliRequest = Readonly<{
34
+ auth: GhostgetAuth;
35
+ limits?: BeeperMessageLikeMeSourceLimits;
36
+ environment?: Readonly<Record<string, string | undefined>>;
37
+ signal?: AbortSignal;
38
+ onProgress?: (progress: BeeperContactInteractionCliProgress) => void;
39
+ }>;
40
+
41
+ /** Preserve the exact platform identity published by the schema-1 receipt. */
42
+ export function assertBeeperContactInteractionExportRuntime(
43
+ platform: NodeJS.Platform = process.platform,
44
+ arch: string = process.arch,
45
+ ): void {
46
+ if (platform !== "darwin" || arch !== "arm64") {
47
+ throw new Error(
48
+ "Beeper contact interaction summary: schema-1 export requires the pinned darwin/arm64 Beeper CLI artifact",
49
+ );
50
+ }
51
+ }
52
+
53
+ async function disposeSource(
54
+ dispose: (() => Promise<void>) | undefined,
55
+ onProgress: BeeperContactInteractionCliRequest["onProgress"],
56
+ ): Promise<void> {
57
+ if (dispose === undefined) return;
58
+ const startedAt = Date.now();
59
+ const report = (): void => onProgress?.(Object.freeze({
60
+ phase: "private-cleanup",
61
+ elapsedSeconds: Math.max(0, Math.floor((Date.now() - startedAt) / 1_000)),
62
+ }));
63
+ report();
64
+ const heartbeat = onProgress === undefined
65
+ ? undefined
66
+ : setInterval(report, CLEANUP_HEARTBEAT_MS);
67
+ try {
68
+ await dispose();
69
+ } finally {
70
+ if (heartbeat !== undefined) clearInterval(heartbeat);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Run the admitted sequential Beeper history source and return only its
76
+ * content-free direct-contact interaction summary. Raw private shards are
77
+ * operation-owned and removed before this function resolves.
78
+ */
79
+ export async function exportBeeperContactInteractionsFromAuth(
80
+ request: BeeperContactInteractionCliRequest,
81
+ ): Promise<BeeperContactInteractionExportResult> {
82
+ assertBeeperContactInteractionExportRuntime();
83
+ const startedAt = new Date().toISOString();
84
+ try {
85
+ const environment = request.environment ?? process.env;
86
+ request.onProgress?.(Object.freeze({ phase: "recovery-started" }));
87
+ const admission = acquireBeeperMessageLikeMeExportAdmission({ environment });
88
+ try {
89
+ const recovery = await recoverBeeperMessageLikeMeDirectoryLeases({
90
+ environment,
91
+ });
92
+ if (recovery.active > 0 || recovery.indeterminate > 0) {
93
+ throw new Error(
94
+ "Beeper contact interaction summary: another export is active or prior private export recovery is indeterminate",
95
+ );
96
+ }
97
+ request.onProgress?.(Object.freeze({
98
+ phase: "recovery-completed",
99
+ recovered: recovery.recovered,
100
+ published: recovery.published,
101
+ }));
102
+ const coordinates = new WeakMap<object, BeeperMessageLikeMeSourceCoordinate>();
103
+ const source = createBeeperMessageLikeMeSource({
104
+ auth: request.auth,
105
+ ...(request.limits === undefined ? {} : { limits: request.limits }),
106
+ ...(request.environment === undefined
107
+ ? {}
108
+ : { environment: request.environment }),
109
+ ...(request.signal === undefined ? {} : { signal: request.signal }),
110
+ ...(request.onProgress === undefined
111
+ ? {}
112
+ : { onProgress: request.onProgress }),
113
+ onRecordCoordinate: (record, coordinate) => {
114
+ coordinates.set(record, coordinate);
115
+ },
116
+ });
117
+ let summary: BeeperContactInteractionSummary | undefined;
118
+ let operationError: unknown;
119
+ try {
120
+ summary = await summarizeBeeperContactInteractions({
121
+ source,
122
+ coordinateForRecord: (record) => (
123
+ typeof record === "object" && record !== null
124
+ ? coordinates.get(record)
125
+ : undefined
126
+ ),
127
+ ...(request.onProgress === undefined
128
+ ? {}
129
+ : { onProgress: request.onProgress }),
130
+ ...(request.signal === undefined ? {} : { signal: request.signal }),
131
+ });
132
+ } catch (error) {
133
+ operationError = error;
134
+ }
135
+ try {
136
+ await disposeSource(
137
+ source.dispose === undefined
138
+ ? undefined
139
+ : () => source.dispose!(false),
140
+ request.onProgress,
141
+ );
142
+ } catch (cleanupError) {
143
+ if (operationError !== undefined) {
144
+ throw new AggregateError(
145
+ [operationError, cleanupError],
146
+ "Beeper contact interaction summary and private cleanup both failed",
147
+ );
148
+ }
149
+ throw cleanupError;
150
+ }
151
+ if (operationError !== undefined) throw operationError;
152
+ if (summary === undefined) {
153
+ throw new Error("Beeper contact interaction summary: result disappeared");
154
+ }
155
+ return createBeeperContactInteractionExportResult({
156
+ runId: randomUUID(),
157
+ startedAt,
158
+ finishedAt: new Date().toISOString(),
159
+ authId: request.auth.id,
160
+ authIdentitySha256: sha256(canonicalJson(request.auth)),
161
+ bounds: Object.freeze({
162
+ limitChats: request.limits?.limitChats ?? null,
163
+ limitMessages: request.limits?.limitMessages ?? null,
164
+ maxParticipants: request.limits?.maxParticipants ?? null,
165
+ }),
166
+ output: summary,
167
+ });
168
+ } finally {
169
+ releaseBeeperMessageLikeMeExportAdmission(admission);
170
+ }
171
+ } catch (error) {
172
+ if (
173
+ error instanceof Error
174
+ && /^(?:Beeper |Message Like Me |pinned Beeper CLI )/u.test(error.message)
175
+ ) throw error;
176
+ throw new Error(
177
+ "Beeper contact interaction summary: private local operation failed",
178
+ );
179
+ }
180
+ }