@spacebar_ai/moldclaw-core 2026.3.41 → 2026.3.44

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 (1144) hide show
  1. package/dist/accounts-5qY-dKca.d.ts +103 -0
  2. package/dist/accounts-SqdHz2ZP.js +114 -0
  3. package/dist/acp-cli-E6bcNqiE.js +2093 -0
  4. package/dist/actions.runtime-BU_XMuLk.js +119 -0
  5. package/dist/actions.runtime-CY5h8lqH.js +133 -0
  6. package/dist/agent-scope-lZlwP1At.js +208 -0
  7. package/dist/agents-C4SkadR1.js +853 -0
  8. package/dist/agents-RfwqGCzE.js +222 -0
  9. package/dist/agents.config-CX9CPNfP.js +17 -0
  10. package/dist/agents.config-DF9Zwn9n.js +121 -0
  11. package/dist/allow-list-3WSjz1zl.js +81 -0
  12. package/dist/allowlist-DNbDjFjw.js +142 -0
  13. package/dist/api-BEOpJ7dR.js +117 -0
  14. package/dist/audit-CpJz_eu6.js +787 -0
  15. package/dist/audit-CpfSjvyo.js +54 -0
  16. package/dist/audit-channel.collect.runtime-BeGotloZ.js +605 -0
  17. package/dist/audit-channel.runtime-BJDZ7ETt.js +121 -0
  18. package/dist/audit-extra.async-C2G0mqmk.js +813 -0
  19. package/dist/audit-membership-runtime-B1FqJsPV.js +162 -0
  20. package/dist/audit.deep.runtime-DyL9O_sU.js +25 -0
  21. package/dist/audit.nondeep.runtime-C6jFgJfH.js +832 -0
  22. package/dist/audit.runtime-Dnlsn23e.js +118 -0
  23. package/dist/auth-Ch3Rchm4.js +101 -0
  24. package/dist/auth-choice-CEFSlnLT.js +122 -0
  25. package/dist/auth-choice-CVCef-eU.js +268 -0
  26. package/dist/auth-choice-Cez-pXrg.js +507 -0
  27. package/dist/auth-choice-options-DO78mvPe.js +123 -0
  28. package/dist/auth-choice-prompt-CUkC7Mmb.js +36 -0
  29. package/dist/auth-choice-prompt-DCuQRiVl.js +115 -0
  30. package/dist/auth-choice.apply-helpers-BhbNIV8X.js +66 -0
  31. package/dist/auth-choice.plugin-providers.runtime-4BhqvEw_.js +119 -0
  32. package/dist/auth-profiles-smABVXzp.js +128040 -0
  33. package/dist/auth-profiles.runtime-Cr-ojtTc.js +116 -0
  34. package/dist/banner-CojBHPWr.js +342 -0
  35. package/dist/bluebubbles-BnLsj2Fy.d.ts +6 -0
  36. package/dist/bluebubbles-CVk7M3Bl.js +64 -0
  37. package/dist/bot-DdyrB2z9.d.ts +478 -0
  38. package/dist/brave-w4Fo8WZ3.js +24 -0
  39. package/dist/browser-cli-DWFs3P_i.js +1494 -0
  40. package/dist/build-info.json +3 -3
  41. package/dist/bundled/boot-md/handler.d.ts +1 -1
  42. package/dist/bundled/boot-md/handler.js +35 -35
  43. package/dist/bundled/bootstrap-extra-files/handler.d.ts +1 -1
  44. package/dist/bundled/bootstrap-extra-files/handler.js +1 -1
  45. package/dist/bundled/command-logger/handler.d.ts +1 -1
  46. package/dist/bundled/session-memory/handler.d.ts +1 -1
  47. package/dist/bundled/session-memory/handler.js +36 -36
  48. package/dist/call-Do7wTSr7.js +39 -0
  49. package/dist/call-gdDAt07d.js +640 -0
  50. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  51. package/dist/channel-B26pkce0.js +214 -0
  52. package/dist/channel-BJHp0AQC.js +352 -0
  53. package/dist/channel-BKFOv51P.js +4681 -0
  54. package/dist/channel-BNgpOY8v.js +538 -0
  55. package/dist/channel-BcQAAo2P.js +226 -0
  56. package/dist/channel-BvNdnhbx.js +1598 -0
  57. package/dist/channel-C1Rda3Jd.js +306 -0
  58. package/dist/channel-C87DG-F7.js +803 -0
  59. package/dist/channel-CIip0kvZ.js +619 -0
  60. package/dist/channel-CTPxoT_E2.js +316 -0
  61. package/dist/channel-CklaCzUG.js +562 -0
  62. package/dist/channel-CoJnAdLs.js +920 -0
  63. package/dist/channel-D3tafL1_.js +949 -0
  64. package/dist/channel-DFMrP2uu.js +542 -0
  65. package/dist/channel-DMd5cJQe.js +397 -0
  66. package/dist/channel-Dm34kxAJ.js +207 -0
  67. package/dist/channel-DmwF9udn.js +1321 -0
  68. package/dist/channel-account-context-Bjur9nlh.js +103 -0
  69. package/dist/channel-bGnST659.js +943 -0
  70. package/dist/channel-hIgbkTZf.js +575 -0
  71. package/dist/channel-m_TGrDKo.js +497 -0
  72. package/dist/channel-options-DoUPBMa8.js +50 -0
  73. package/dist/channel-plugin-ids-TZIY4hFs.js +26 -0
  74. package/dist/channel-summary-qD54bOBO.js +111 -0
  75. package/dist/channel.runtime-B0H04Dkk.js +199 -0
  76. package/dist/channel.runtime-BU1f3NkV.js +418 -0
  77. package/dist/channel.runtime-Bj1sfLep.js +4011 -0
  78. package/dist/channel.runtime-BtPAAJc3.js +870 -0
  79. package/dist/channel.runtime-Bx-10m_j.js +171 -0
  80. package/dist/channel.runtime-CI_TBywQ.js +179 -0
  81. package/dist/channel.runtime-CSLj14-Z.js +182 -0
  82. package/dist/channel.runtime-D-lTSYAd.js +404 -0
  83. package/dist/channel.runtime-DJqIOSji.js +127 -0
  84. package/dist/channel.runtime-Ec8aQ9V2.js +241 -0
  85. package/dist/channel.runtime-ax5a1jBm.js +218 -0
  86. package/dist/channel.setup-B-ncdYLT.js +9 -0
  87. package/dist/channel.setup-BY4bh5dm.js +9 -0
  88. package/dist/channel.setup-BovsdMnL.js +57 -0
  89. package/dist/channel.setup-CXzXA25h.js +6 -0
  90. package/dist/channel.setup-DcZUEufN.js +8 -0
  91. package/dist/channel.setup-E6zceRsE.js +8 -0
  92. package/dist/channel.setup-Pc7nGbdX.js +11 -0
  93. package/dist/channels/plugins/actions/discord.d.ts +2 -2
  94. package/dist/channels/plugins/actions/discord.js +35 -35
  95. package/dist/channels/plugins/actions/signal.d.ts +1 -1
  96. package/dist/channels/plugins/actions/signal.js +35 -35
  97. package/dist/channels/plugins/actions/telegram.d.ts +2 -2
  98. package/dist/channels/plugins/actions/telegram.js +35 -35
  99. package/dist/channels/plugins/agent-tools/whatsapp-login.d.ts +3 -3
  100. package/dist/channels/plugins/agent-tools/whatsapp-login.js +35 -35
  101. package/dist/channels-CPtE5ND6.js +404 -0
  102. package/dist/channels-Cj8ZolHI.js +1118 -0
  103. package/dist/channels-cli-D2sKrntt.js +291 -0
  104. package/dist/channels-status-issues-CzIHODg2.js +16 -0
  105. package/dist/clawbot-cli-BcwEDmUn.js +118 -0
  106. package/dist/cleanup-utils-D0L17RsX.js +96 -0
  107. package/dist/cli/daemon-cli.js +1 -1
  108. package/dist/cli-BvGVPKnD.js +154 -0
  109. package/dist/command-registry-CADQzTAg.js +14 -0
  110. package/dist/command-registry-ktiJNAJd.js +242 -0
  111. package/dist/command-secret-gateway-CXp10RTM.js +111 -0
  112. package/dist/compact.runtime-DyKL-Iar.js +116 -0
  113. package/dist/completion-cli-Bz4STrpt.js +17 -0
  114. package/dist/completion-cli-pVda2OFb.js +445 -0
  115. package/dist/config-BbvDRSYp.js +31 -0
  116. package/dist/config-CwBv71QC.js +44 -0
  117. package/dist/config-cli-Y0uXHbOw.js +678 -0
  118. package/dist/config-guard-BpW5g7JE.js +118 -0
  119. package/dist/config-validation-B-vLIsbo.js +262 -0
  120. package/dist/config-value-DT3-5958.js +132 -0
  121. package/dist/configure-B9U-jCqP.js +1100 -0
  122. package/dist/configure-BJ3Wrs5b.js +243 -0
  123. package/dist/control-ui-assets-C1YDYi82.js +232 -0
  124. package/dist/control-ui-shared-Dm5Dh0Lo.js +29 -0
  125. package/dist/core-BwKq3krw.js +150 -0
  126. package/dist/core-hjBwfDsW.d.ts +87 -0
  127. package/dist/cron-cli-DTDgfoMh.js +639 -0
  128. package/dist/daemon-cli-C-dkAXR1.js +339 -0
  129. package/dist/daemon-install-Oy0Q5pMF.js +180 -0
  130. package/dist/deliver-DNGnDqF9.js +111 -0
  131. package/dist/deliver-runtime-CCNZIhET.js +111 -0
  132. package/dist/device-id-cli-XvwZbIyC.js +52 -0
  133. package/dist/device-identity-IG5DngWM.js +365 -0
  134. package/dist/devices-cli-DIsxj4xp.js +342 -0
  135. package/dist/diagnostic-DTPopFvh.js +310 -0
  136. package/dist/directory-cli-DTSY3Ktr.js +311 -0
  137. package/dist/directory-config-helpers-DpFcAbmo.d.ts +38 -0
  138. package/dist/directory.static-CBRAUwUW.js +44 -0
  139. package/dist/discord-CrgxhEWw.js +114 -0
  140. package/dist/discovery-DrG7wmAR.js +48 -0
  141. package/dist/dm-policy-shared-DKoGdUpY.d.ts +95 -0
  142. package/dist/dns-cli-BJiz6CLK.js +217 -0
  143. package/dist/docs-cli-Dq2Yi5qO.js +174 -0
  144. package/dist/doctor-completion-D3GeVcFP.js +90 -0
  145. package/dist/doctor-config-flow-B1cMjr8h.js +112 -0
  146. package/dist/doctor-config-flow-BUe7JpV3.js +2437 -0
  147. package/dist/enable-Bc8bCuVe.js +24 -0
  148. package/dist/entry.js +4 -4
  149. package/dist/exec-approvals-cli-kLAev6bP.js +421 -0
  150. package/dist/extensions/acpx/index.d.ts +1 -1
  151. package/dist/extensions/amazon-bedrock/index.d.ts +1 -1
  152. package/dist/extensions/amazon-bedrock/index.js +4 -4
  153. package/dist/extensions/anthropic/index.d.ts +1 -1
  154. package/dist/extensions/anthropic/index.js +35 -35
  155. package/dist/extensions/bluebubbles/index.d.ts +1 -1
  156. package/dist/extensions/bluebubbles/index.js +39 -39
  157. package/dist/extensions/bluebubbles/setup-entry.d.ts +2 -2
  158. package/dist/extensions/bluebubbles/setup-entry.js +39 -39
  159. package/dist/extensions/brave/index.d.ts +1 -1
  160. package/dist/extensions/brave/index.js +5 -5
  161. package/dist/extensions/byteplus/index.d.ts +1 -1
  162. package/dist/extensions/byteplus/index.js +35 -35
  163. package/dist/extensions/cloudflare-ai-gateway/index.d.ts +1 -1
  164. package/dist/extensions/cloudflare-ai-gateway/index.js +36 -36
  165. package/dist/extensions/copilot-proxy/index.d.ts +1 -1
  166. package/dist/extensions/copilot-proxy/index.js +4 -4
  167. package/dist/extensions/device-pair/index.d.ts +1 -1
  168. package/dist/extensions/device-pair/index.js +4 -4
  169. package/dist/extensions/diagnostics-otel/index.d.ts +1 -1
  170. package/dist/extensions/diagnostics-otel/index.js +4 -4
  171. package/dist/extensions/diffs/index.d.ts +1 -1
  172. package/dist/extensions/discord/index.d.ts +1 -1
  173. package/dist/extensions/discord/index.js +40 -40
  174. package/dist/extensions/discord/setup-entry.d.ts +1 -1
  175. package/dist/extensions/discord/setup-entry.js +38 -38
  176. package/dist/extensions/elevenlabs/index.d.ts +1 -1
  177. package/dist/extensions/elevenlabs/index.js +35 -35
  178. package/dist/extensions/feishu/index.d.ts +2 -2
  179. package/dist/extensions/feishu/index.js +40 -40
  180. package/dist/extensions/feishu/setup-entry.d.ts +2 -2
  181. package/dist/extensions/feishu/setup-entry.js +37 -37
  182. package/dist/extensions/firecrawl/index.d.ts +1 -1
  183. package/dist/extensions/firecrawl/index.js +35 -35
  184. package/dist/extensions/github-copilot/index.d.ts +1 -1
  185. package/dist/extensions/github-copilot/index.js +35 -35
  186. package/dist/extensions/google/index.d.ts +1 -1
  187. package/dist/extensions/google/index.js +35 -35
  188. package/dist/extensions/googlechat/index.d.ts +1 -1
  189. package/dist/extensions/googlechat/index.js +38 -38
  190. package/dist/extensions/googlechat/setup-entry.d.ts +1 -1
  191. package/dist/extensions/googlechat/setup-entry.js +38 -38
  192. package/dist/extensions/huggingface/index.d.ts +1 -1
  193. package/dist/extensions/huggingface/index.js +35 -35
  194. package/dist/extensions/imessage/index.d.ts +1 -1
  195. package/dist/extensions/imessage/index.js +39 -39
  196. package/dist/extensions/imessage/setup-entry.d.ts +1 -1
  197. package/dist/extensions/imessage/setup-entry.js +39 -39
  198. package/dist/extensions/irc/index.d.ts +1 -1
  199. package/dist/extensions/irc/index.js +38 -38
  200. package/dist/extensions/irc/setup-entry.d.ts +2 -2
  201. package/dist/extensions/irc/setup-entry.js +38 -38
  202. package/dist/extensions/kakao-talkchannel/index.d.ts +1 -1
  203. package/dist/extensions/kakao-talkchannel/index.js +4 -4
  204. package/dist/extensions/kilocode/index.d.ts +1 -1
  205. package/dist/extensions/kilocode/index.js +35 -35
  206. package/dist/extensions/kimi-coding/index.d.ts +1 -1
  207. package/dist/extensions/kimi-coding/index.js +35 -35
  208. package/dist/extensions/line/index.d.ts +1 -1
  209. package/dist/extensions/line/index.js +37 -37
  210. package/dist/extensions/line/setup-entry.d.ts +1 -1
  211. package/dist/extensions/line/setup-entry.js +37 -37
  212. package/dist/extensions/llm-task/index.d.ts +1 -1
  213. package/dist/extensions/llm-task/index.js +35 -35
  214. package/dist/extensions/lobster/index.d.ts +1 -1
  215. package/dist/extensions/lobster/index.js +4 -4
  216. package/dist/extensions/matrix/index.d.ts +1 -1
  217. package/dist/extensions/matrix/index.js +40 -40
  218. package/dist/extensions/matrix/setup-entry.d.ts +2 -2
  219. package/dist/extensions/matrix/setup-entry.js +40 -40
  220. package/dist/extensions/mattermost/index.d.ts +1 -1
  221. package/dist/extensions/mattermost/index.js +37 -37
  222. package/dist/extensions/mattermost/setup-entry.d.ts +2 -2
  223. package/dist/extensions/mattermost/setup-entry.js +37 -37
  224. package/dist/extensions/memory-core/index.d.ts +1 -1
  225. package/dist/extensions/memory-core/index.js +4 -4
  226. package/dist/extensions/memory-lancedb/index.d.ts +1 -1
  227. package/dist/extensions/memory-lancedb/index.js +4 -4
  228. package/dist/extensions/microsoft/index.d.ts +1 -1
  229. package/dist/extensions/microsoft/index.js +35 -35
  230. package/dist/extensions/minimax/index.d.ts +1 -1
  231. package/dist/extensions/minimax/index.js +35 -35
  232. package/dist/extensions/mistral/index.d.ts +1 -1
  233. package/dist/extensions/mistral/index.js +35 -35
  234. package/dist/extensions/modelstudio/index.d.ts +1 -1
  235. package/dist/extensions/modelstudio/index.js +35 -35
  236. package/dist/extensions/moonshot/index.d.ts +1 -1
  237. package/dist/extensions/moonshot/index.js +35 -35
  238. package/dist/extensions/msteams/index.d.ts +1 -1
  239. package/dist/extensions/msteams/index.js +40 -40
  240. package/dist/extensions/msteams/setup-entry.d.ts +1 -1
  241. package/dist/extensions/msteams/setup-entry.js +40 -40
  242. package/dist/extensions/nextcloud-talk/index.d.ts +1 -1
  243. package/dist/extensions/nextcloud-talk/index.js +37 -37
  244. package/dist/extensions/nextcloud-talk/setup-entry.d.ts +2 -2
  245. package/dist/extensions/nextcloud-talk/setup-entry.js +37 -37
  246. package/dist/extensions/nostr/index.d.ts +1 -1
  247. package/dist/extensions/nostr/index.js +37 -37
  248. package/dist/extensions/nostr/setup-entry.d.ts +1 -1
  249. package/dist/extensions/nostr/setup-entry.js +37 -37
  250. package/dist/extensions/nvidia/index.d.ts +1 -1
  251. package/dist/extensions/nvidia/index.js +4 -4
  252. package/dist/extensions/ollama/index.d.ts +1 -1
  253. package/dist/extensions/ollama/index.js +7 -7
  254. package/dist/extensions/open-prose/index.d.ts +1 -1
  255. package/dist/extensions/open-prose/index.js +4 -4
  256. package/dist/extensions/openai/index.d.ts +1 -1
  257. package/dist/extensions/openai/index.js +35 -35
  258. package/dist/extensions/opencode/index.d.ts +1 -1
  259. package/dist/extensions/opencode/index.js +35 -35
  260. package/dist/extensions/opencode-go/index.d.ts +1 -1
  261. package/dist/extensions/opencode-go/index.js +35 -35
  262. package/dist/extensions/openrouter/index.d.ts +1 -1
  263. package/dist/extensions/openrouter/index.js +35 -35
  264. package/dist/extensions/openshell/index.d.ts +1 -1
  265. package/dist/extensions/openshell/index.js +35 -35
  266. package/dist/extensions/perplexity/index.d.ts +1 -1
  267. package/dist/extensions/perplexity/index.js +5 -5
  268. package/dist/extensions/phone-control/index.d.ts +1 -1
  269. package/dist/extensions/phone-control/index.js +4 -4
  270. package/dist/extensions/qianfan/index.d.ts +1 -1
  271. package/dist/extensions/qianfan/index.js +35 -35
  272. package/dist/extensions/qwen-portal-auth/index.d.ts +1 -1
  273. package/dist/extensions/qwen-portal-auth/index.js +35 -35
  274. package/dist/extensions/sglang/index.d.ts +1 -1
  275. package/dist/extensions/sglang/index.js +35 -35
  276. package/dist/extensions/signal/index.d.ts +1 -1
  277. package/dist/extensions/signal/index.js +38 -38
  278. package/dist/extensions/signal/setup-entry.d.ts +1 -1
  279. package/dist/extensions/signal/setup-entry.js +38 -38
  280. package/dist/extensions/slack/index.d.ts +1 -1
  281. package/dist/extensions/slack/index.js +39 -39
  282. package/dist/extensions/slack/setup-entry.d.ts +1 -1
  283. package/dist/extensions/slack/setup-entry.js +38 -38
  284. package/dist/extensions/synology-chat/index.d.ts +1 -1
  285. package/dist/extensions/synology-chat/index.js +37 -37
  286. package/dist/extensions/synology-chat/setup-entry.d.ts +1 -1
  287. package/dist/extensions/synology-chat/setup-entry.js +37 -37
  288. package/dist/extensions/synthetic/index.d.ts +1 -1
  289. package/dist/extensions/synthetic/index.js +35 -35
  290. package/dist/extensions/talk-voice/index.d.ts +1 -1
  291. package/dist/extensions/talk-voice/index.js +35 -35
  292. package/dist/extensions/telegram/index.d.ts +1 -1
  293. package/dist/extensions/telegram/index.js +38 -38
  294. package/dist/extensions/telegram/setup-entry.d.ts +1 -1
  295. package/dist/extensions/telegram/setup-entry.js +37 -37
  296. package/dist/extensions/thread-ownership/index.d.ts +1 -1
  297. package/dist/extensions/thread-ownership/index.js +4 -4
  298. package/dist/extensions/tlon/index.d.ts +1 -1
  299. package/dist/extensions/tlon/index.js +37 -37
  300. package/dist/extensions/tlon/setup-entry.d.ts +1 -1
  301. package/dist/extensions/tlon/setup-entry.js +37 -37
  302. package/dist/extensions/together/index.d.ts +1 -1
  303. package/dist/extensions/together/index.js +35 -35
  304. package/dist/extensions/twitch/index.d.ts +2 -2
  305. package/dist/extensions/twitch/index.js +37 -37
  306. package/dist/extensions/venice/index.d.ts +1 -1
  307. package/dist/extensions/venice/index.js +35 -35
  308. package/dist/extensions/vercel-ai-gateway/index.d.ts +1 -1
  309. package/dist/extensions/vercel-ai-gateway/index.js +36 -36
  310. package/dist/extensions/vllm/index.d.ts +1 -1
  311. package/dist/extensions/vllm/index.js +35 -35
  312. package/dist/extensions/voice-call/index.d.ts +1 -1
  313. package/dist/extensions/voice-call/index.js +35 -35
  314. package/dist/extensions/volcengine/index.d.ts +1 -1
  315. package/dist/extensions/volcengine/index.js +35 -35
  316. package/dist/extensions/whatsapp/index.d.ts +1 -1
  317. package/dist/extensions/whatsapp/index.js +38 -38
  318. package/dist/extensions/whatsapp/setup-entry.d.ts +1 -1
  319. package/dist/extensions/whatsapp/setup-entry.js +38 -38
  320. package/dist/extensions/xai/index.d.ts +1 -1
  321. package/dist/extensions/xai/index.js +35 -35
  322. package/dist/extensions/xiaomi/index.d.ts +1 -1
  323. package/dist/extensions/xiaomi/index.js +35 -35
  324. package/dist/extensions/zai/index.d.ts +1 -1
  325. package/dist/extensions/zai/index.js +35 -35
  326. package/dist/extensions/zalo/index.d.ts +1 -1
  327. package/dist/extensions/zalo/index.js +39 -39
  328. package/dist/extensions/zalo/setup-entry.d.ts +1 -1
  329. package/dist/extensions/zalo/setup-entry.js +39 -39
  330. package/dist/extensions/zalouser/index.d.ts +1 -1
  331. package/dist/extensions/zalouser/index.js +40 -40
  332. package/dist/extensions/zalouser/setup-entry.d.ts +1 -1
  333. package/dist/extensions/zalouser/setup-entry.js +40 -40
  334. package/dist/feishu-fIcnHDTd.d.ts +36 -0
  335. package/dist/gateway-cli-0c-8h93_.js +26437 -0
  336. package/dist/gateway-install-token-1PwJvrBY.js +163 -0
  337. package/dist/gateway-rpc-C0Vk51W7.js +26 -0
  338. package/dist/gateway-runtime-CBm3CCoA.js +69 -0
  339. package/dist/git-commit-BTWXFY41.js +177 -0
  340. package/dist/git-commit-D6GTN5Yt.js +2 -0
  341. package/dist/googlechat-BQr4xgoZ.js +307 -0
  342. package/dist/googlechat-BvwsCVKl.d.ts +12 -0
  343. package/dist/group-access-DpiQnd-G.d.ts +61 -0
  344. package/dist/health-6yZQGADY.js +113 -0
  345. package/dist/health-C9DYGyRe.js +570 -0
  346. package/dist/heartbeat-summary-Dct2lqJj.js +57 -0
  347. package/dist/help-CtwSApfq.js +81 -0
  348. package/dist/hooks-9gokOxZ5.d.ts +6 -0
  349. package/dist/hooks-cli-BegKzHZT.js +1000 -0
  350. package/dist/hooks-status-Bm_pGORf.js +78 -0
  351. package/dist/http-registry-D-S6a1Na.d.ts +20 -0
  352. package/dist/identity-file-Diub2a0t.js +60 -0
  353. package/dist/image-generation-CbIVzmAR.d.ts +9 -0
  354. package/dist/imessage-Bgok9kfl.js +31 -0
  355. package/dist/imessage-VIHePprL.js +115 -0
  356. package/dist/inbound-reply-dispatch-B53GAGWq.js +71 -0
  357. package/dist/inbound-reply-dispatch-n7U3qg15.d.ts +72 -0
  358. package/dist/index.js +2 -2
  359. package/dist/install-target-oz1pjfHH.js +574 -0
  360. package/dist/installs-CUFm5V8a.js +532 -0
  361. package/dist/io-BaBxjB1v.js +9739 -0
  362. package/dist/io-CgHb1Jld.js +29 -0
  363. package/dist/irc-CaRKzGvW.js +672 -0
  364. package/dist/library-C5SNBCMb.js +112 -0
  365. package/dist/lifecycle-core-Dn8PK6nk.js +382 -0
  366. package/dist/line/accounts.d.ts +2 -2
  367. package/dist/line/send.d.ts +1 -1
  368. package/dist/line/send.js +7 -7
  369. package/dist/line/template-messages.d.ts +1 -1
  370. package/dist/line-B5QFpgN_.d.ts +75 -0
  371. package/dist/line-fePrrQOD.js +530 -0
  372. package/dist/llm-slug-generator-hKae3XDA.js +67 -0
  373. package/dist/llm-slug-generator.d.ts +1 -1
  374. package/dist/llm-slug-generator.js +36 -36
  375. package/dist/logging-CdisccbY.js +13 -0
  376. package/dist/logging-LKQSgX1d.js +30 -0
  377. package/dist/login-qr-C1YWh4nE.js +233 -0
  378. package/dist/login-qr-WFluMDMb.js +112 -0
  379. package/dist/logs-cli-CNzOvZ2d.js +256 -0
  380. package/dist/manager-runtime-DgMhLTkR.js +111 -0
  381. package/dist/manager.runtime-hUWgpPt2.js +715 -0
  382. package/dist/manifest-registry-CS_p1OBQ.js +1329 -0
  383. package/dist/matrix-43_RGLZN.d.ts +68 -0
  384. package/dist/matrix-CCFxHfxa.js +1269 -0
  385. package/dist/matrix-DWs_qIkJ.js +1495 -0
  386. package/dist/mcp-cli-Ci2jvv3s.js +87 -0
  387. package/dist/media-understanding.runtime-Cdr6iTW6.js +116 -0
  388. package/dist/memory-cli-LZbyF0Iu.js +111 -0
  389. package/dist/memory-search-BHhETk6u.js +17 -0
  390. package/dist/memory-search-tTD5o_rU.js +204 -0
  391. package/dist/method-scopes-B2ZKSsxQ.js +2452 -0
  392. package/dist/model-auth-markers-LqZ4qhrZ.d.ts +20 -0
  393. package/dist/model-picker-CTR5mo4v.js +112 -0
  394. package/dist/model-picker-DG4z_dBs.js +390 -0
  395. package/dist/model-picker.runtime-DMQ9Pj9_.js +125 -0
  396. package/dist/model-selection-bBBxfXdb.js +653 -0
  397. package/dist/model-suppression.runtime-BVG75tZ7.js +116 -0
  398. package/dist/models-BjkVLfgw.js +2514 -0
  399. package/dist/models-ZO01Q4cx.js +118 -0
  400. package/dist/models-cli-DemdF-bm.js +309 -0
  401. package/dist/models-config-B2Jja8ua.js +111 -0
  402. package/dist/models-config.providers.discovery-puxTsH39.d.ts +18 -0
  403. package/dist/moldclaw-root-Cb6HRlUO.js +92 -0
  404. package/dist/monitor-BP4idxJD.js +782 -0
  405. package/dist/monitor-B_eP8Eim.js +772 -0
  406. package/dist/monitor-CRHYNl5J.js +3468 -0
  407. package/dist/monitor-Ci1Xg4g3.js +113 -0
  408. package/dist/monitor-DEodDl3z.js +6823 -0
  409. package/dist/monitor-DJlNKuMz.js +115 -0
  410. package/dist/monitor-DvFwDS9w.js +3076 -0
  411. package/dist/monitor-shared--cEjSf8s.js +444 -0
  412. package/dist/msteams-CV2a8uE8.js +852 -0
  413. package/dist/node-cli-Of2g7DSd.js +2503 -0
  414. package/dist/node-resolve-BYC2FbO2.js +835 -0
  415. package/dist/nodes-cli-CPHM6Upj.js +1380 -0
  416. package/dist/nostr-BFKRoOlz.d.ts +7 -0
  417. package/dist/nostr-lHpcBzz4.js +8744 -0
  418. package/dist/npm-resolution-kqHN85wB.js +60 -0
  419. package/dist/oauth-env-CLG8KOrz.js +10 -0
  420. package/dist/onboard-BON0C360.js +48 -0
  421. package/dist/onboard-CRkIBgOI.js +589 -0
  422. package/dist/onboard-DsKI17iq.js +25 -0
  423. package/dist/onboard-channels-BY3IbBBf.js +1241 -0
  424. package/dist/onboard-channels-CLKdRxvW.js +205 -0
  425. package/dist/onboard-custom-BjPrMo_R.js +571 -0
  426. package/dist/onboard-custom-DqcPiZBN.js +114 -0
  427. package/dist/onboard-helpers-BkrOY5OE.js +113 -0
  428. package/dist/onboard-helpers-DiSRTpZC.js +335 -0
  429. package/dist/onboard-hooks-pzEPZAvl.js +72 -0
  430. package/dist/onboard-remote-ChyLC6Dk.js +181 -0
  431. package/dist/onboard-remote-DHmK9ntl.js +117 -0
  432. package/dist/onboard-search-BgA3jEMW.js +302 -0
  433. package/dist/onboard-skills-BMo_NvnW.js +133 -0
  434. package/dist/onboard-skills-Bba-Z2p8.js +117 -0
  435. package/dist/outbound-media-BHD4aJEX.d.ts +11 -0
  436. package/dist/outbound-media-DSno0N82.js +11 -0
  437. package/dist/pairing-access-CzHpaM0R.d.ts +21 -0
  438. package/dist/pairing-cli-CmklqK0q.js +217 -0
  439. package/dist/perplexity-CXwMDD3u.js +24 -0
  440. package/dist/persistent-dedupe-B9vrAf8t.d.ts +26 -0
  441. package/dist/pi-model-discovery-runtime-BrK7tcaO.js +111 -0
  442. package/dist/pi-tools.before-tool-call.runtime-C5yLUogH.js +381 -0
  443. package/dist/plugin-install-C4AWJIFP.js +117 -0
  444. package/dist/plugin-install-CB3J1hfV.js +184 -0
  445. package/dist/plugin-install-plan-7itZiegi.js +49 -0
  446. package/dist/plugin-registry-DX_GFoiz.js +113 -0
  447. package/dist/plugin-registry-e3cxTtvb.js +49 -0
  448. package/dist/plugin-sdk/account-resolution.js +35 -35
  449. package/dist/plugin-sdk/acp-runtime.js +35 -35
  450. package/dist/plugin-sdk/agent-runtime.js +35 -35
  451. package/dist/plugin-sdk/bluebubbles.js +37 -37
  452. package/dist/plugin-sdk/channel-config-helpers.js +35 -35
  453. package/dist/plugin-sdk/channel-policy.js +35 -35
  454. package/dist/plugin-sdk/channel-runtime.js +35 -35
  455. package/dist/plugin-sdk/compat.js +36 -36
  456. package/dist/plugin-sdk/config-runtime.js +35 -35
  457. package/dist/plugin-sdk/conversation-runtime.js +35 -35
  458. package/dist/plugin-sdk/copilot-proxy.js +4 -4
  459. package/dist/plugin-sdk/core.js +4 -4
  460. package/dist/plugin-sdk/device-pair.js +4 -4
  461. package/dist/plugin-sdk/discord.js +35 -35
  462. package/dist/plugin-sdk/feishu.js +35 -35
  463. package/dist/plugin-sdk/gateway-runtime.js +10 -10
  464. package/dist/plugin-sdk/googlechat.js +37 -37
  465. package/dist/plugin-sdk/image-generation-runtime.js +35 -35
  466. package/dist/plugin-sdk/image-generation.js +35 -35
  467. package/dist/plugin-sdk/imessage.js +36 -36
  468. package/dist/plugin-sdk/index.js +35 -35
  469. package/dist/plugin-sdk/infra-runtime.js +35 -35
  470. package/dist/plugin-sdk/irc.js +37 -37
  471. package/dist/plugin-sdk/line.js +36 -36
  472. package/dist/plugin-sdk/llm-task.js +35 -35
  473. package/dist/plugin-sdk/lobster.js +4 -4
  474. package/dist/plugin-sdk/matrix.js +37 -37
  475. package/dist/plugin-sdk/mattermost.js +36 -36
  476. package/dist/plugin-sdk/media-runtime.js +35 -35
  477. package/dist/plugin-sdk/media-understanding-runtime.js +35 -35
  478. package/dist/plugin-sdk/media-understanding.js +35 -35
  479. package/dist/plugin-sdk/memory-lancedb.js +4 -4
  480. package/dist/plugin-sdk/minimax-portal-auth.js +4 -4
  481. package/dist/plugin-sdk/msteams.js +38 -38
  482. package/dist/plugin-sdk/nextcloud-talk.js +36 -36
  483. package/dist/plugin-sdk/nostr.js +36 -36
  484. package/dist/plugin-sdk/ollama-setup.js +9 -9
  485. package/dist/plugin-sdk/open-prose.js +4 -4
  486. package/dist/plugin-sdk/phone-control.js +4 -4
  487. package/dist/plugin-sdk/plugin-runtime.js +35 -35
  488. package/dist/plugin-sdk/provider-auth.js +35 -35
  489. package/dist/plugin-sdk/provider-models.js +5 -5
  490. package/dist/plugin-sdk/provider-onboard.js +4 -4
  491. package/dist/plugin-sdk/provider-setup.js +39 -39
  492. package/dist/plugin-sdk/provider-stream.js +4 -4
  493. package/dist/plugin-sdk/provider-usage.js +4 -4
  494. package/dist/plugin-sdk/qwen-portal-auth.js +35 -35
  495. package/dist/plugin-sdk/reply-history.js +35 -35
  496. package/dist/plugin-sdk/reply-runtime.js +35 -35
  497. package/dist/plugin-sdk/routing.js +3 -3
  498. package/dist/plugin-sdk/sandbox.js +35 -35
  499. package/dist/plugin-sdk/security-runtime.js +35 -35
  500. package/dist/plugin-sdk/self-hosted-provider-setup.js +37 -37
  501. package/dist/plugin-sdk/setup.js +35 -35
  502. package/dist/plugin-sdk/signal.js +35 -35
  503. package/dist/plugin-sdk/slack.js +35 -35
  504. package/dist/plugin-sdk/speech-runtime.js +35 -35
  505. package/dist/plugin-sdk/speech.js +35 -35
  506. package/dist/plugin-sdk/src/secrets/secure-file-store.d.ts +26 -0
  507. package/dist/plugin-sdk/src/subscription/provider.d.ts +5 -3
  508. package/dist/plugin-sdk/synology-chat.js +36 -36
  509. package/dist/plugin-sdk/talk-voice.js +4 -4
  510. package/dist/plugin-sdk/telegram.js +35 -35
  511. package/dist/plugin-sdk/text-runtime.js +7 -7
  512. package/dist/plugin-sdk/thread-ownership.js +4 -4
  513. package/dist/plugin-sdk/tlon.js +36 -36
  514. package/dist/plugin-sdk/twitch.js +35 -35
  515. package/dist/plugin-sdk/voice-call.js +35 -35
  516. package/dist/plugin-sdk/whatsapp.js +35 -35
  517. package/dist/plugin-sdk/zalo.js +38 -38
  518. package/dist/plugin-sdk/zalouser.js +38 -38
  519. package/dist/plugins/runtime/index.d.ts +1 -1
  520. package/dist/plugins/runtime/index.js +35 -35
  521. package/dist/plugins-DF5FaTO0.js +111 -0
  522. package/dist/plugins-cli-CvTJemqC.js +917 -0
  523. package/dist/policy-CNXISK_a.js +143 -0
  524. package/dist/preflight-audio.runtime-RP000oxo.js +116 -0
  525. package/dist/probe-BkM5pykD.js +21 -0
  526. package/dist/probe-DKbRTJv5.js +1793 -0
  527. package/dist/probe-DkrfRsjU.js +47 -0
  528. package/dist/probe-DpcJ0WeP.js +129 -0
  529. package/dist/probe-auth-BcNjX8hy.js +40 -0
  530. package/dist/probe-auth-DhuAb8ls.js +48 -0
  531. package/dist/probe-wciBj-aL.js +6329 -0
  532. package/dist/program-C8-p0mW5.js +253 -0
  533. package/dist/prompt-select-styled-DH0pVoc0.js +2673 -0
  534. package/dist/provider-api-key-auth.runtime-CAFeIQ1u.js +121 -0
  535. package/dist/provider-auth-choice-CB_HzdTl.js +126 -0
  536. package/dist/provider-auth-choice-helpers-hzDkh3f1.js +48 -0
  537. package/dist/provider-auth-choice-preference-BHCXvNSE.js +189 -0
  538. package/dist/provider-auth-choice.runtime-Dx4ms2C5.js +123 -0
  539. package/dist/provider-auth-choices-0KaDNPBQ.js +57 -0
  540. package/dist/provider-auth-guidance-BaAUiNr_.js +34 -0
  541. package/dist/provider-auth-result-Bto1bYtS.d.ts +18 -0
  542. package/dist/provider-models-DxOmeToO.d.ts +867 -0
  543. package/dist/provider-models-xnyxy6mO.js +2113 -0
  544. package/dist/provider-ollama-setup-DBYK__ov.d.ts +32 -0
  545. package/dist/provider-ollama-setup-QzgCxj44.js +314 -0
  546. package/dist/provider-onboard-B9ionepI.js +139 -0
  547. package/dist/provider-onboard-CURxJ_UX.d.ts +40 -0
  548. package/dist/provider-runtime.runtime-4xwmsl5L.js +111 -0
  549. package/dist/provider-self-hosted-setup-BHd24EDG.js +182 -0
  550. package/dist/provider-self-hosted-setup-qeY8BYSy.d.ts +61 -0
  551. package/dist/provider-stream-Chz_EFw3.js +512 -0
  552. package/dist/provider-usage-C11Q7UwS.js +111 -0
  553. package/dist/provider-usage-kxemdMp2.js +633 -0
  554. package/dist/provider-wizard-CanJoxNC.js +152 -0
  555. package/dist/push-apns-Dsajnm8C.js +1038 -0
  556. package/dist/pw-ai-DUe4BbH2.js +1867 -0
  557. package/dist/qmd-manager-CAAFp7qK.js +1570 -0
  558. package/dist/qr-cli-Bu2jqTPY.js +113 -0
  559. package/dist/qr-cli-Bu9Z-X48.js +369 -0
  560. package/dist/reactions-Cpfum4iU.js +281 -0
  561. package/dist/read-only-account-inspect.discord.runtime-BK0LaMgC.js +116 -0
  562. package/dist/read-only-account-inspect.slack.runtime-DgKiC5wT.js +116 -0
  563. package/dist/read-only-account-inspect.telegram.runtime-mxfgFVOU.js +116 -0
  564. package/dist/redact-snapshot-DD8A4tdd.js +2663 -0
  565. package/dist/register.agent-DU4FtrU2.js +439 -0
  566. package/dist/register.backup-8nOYtJqg.js +625 -0
  567. package/dist/register.configure-DmtecqIH.js +252 -0
  568. package/dist/register.maintenance-Dir3ulKP.js +574 -0
  569. package/dist/register.message-Cfl-f3Ju.js +709 -0
  570. package/dist/register.onboard-Bv7WVzEi.js +192 -0
  571. package/dist/register.setup-BIyeI8RY.js +212 -0
  572. package/dist/register.status-health-sessions-C69WQcF4.js +498 -0
  573. package/dist/register.subclis-B_4KCgTd.js +315 -0
  574. package/dist/register.subclis-BeXsmgBL.js +13 -0
  575. package/dist/replies-DdcFUmki.js +110 -0
  576. package/dist/resolve-channels-DRZqPV5o.js +226 -0
  577. package/dist/resolve-channels-DxW1kqxA.js +262 -0
  578. package/dist/resolve-route-DdX-HBVt.js +538 -0
  579. package/dist/resolve-users-rgCQvkLs.js +143 -0
  580. package/dist/root-help-QAkoA7GD.js +32 -0
  581. package/dist/routes-CcJNnwTF.js +7097 -0
  582. package/dist/rpc-DDUAlBbH.js +67 -0
  583. package/dist/run-main-D9ci5pn7.js +424 -0
  584. package/dist/runtime-Bitmi8Er.d.ts +26 -0
  585. package/dist/runtime-discord-ops.runtime-T4sf7aRB.js +9078 -0
  586. package/dist/runtime-slack-ops.runtime-BQpP48mC.js +4556 -0
  587. package/dist/runtime-telegram-ops.runtime-cVO5dqOp.js +133 -0
  588. package/dist/runtime-whatsapp-login.runtime-DtNx0dSY.js +114 -0
  589. package/dist/runtime-whatsapp-outbound.runtime-Bw47QbFK.js +117 -0
  590. package/dist/sandbox-cli-DsFwjbjC.js +535 -0
  591. package/dist/search-manager-BRAK8fEe.js +16 -0
  592. package/dist/search-manager-BS5Db0A6.js +386 -0
  593. package/dist/secrets-cli-D3J46TJp.js +2070 -0
  594. package/dist/security-cli-B866M9cB.js +575 -0
  595. package/dist/send-B1pX9_Oc.js +283 -0
  596. package/dist/send-B2RrLg83.js +100 -0
  597. package/dist/send-DFnV__Aq.js +1025 -0
  598. package/dist/send-DZIH6CJt.js +629 -0
  599. package/dist/send-sl9WnKbW.js +631 -0
  600. package/dist/server-node-events-BT6egg20.js +506 -0
  601. package/dist/server-zI_K-D05.js +107 -0
  602. package/dist/sessions-C8kiAcoJ.js +112 -0
  603. package/dist/sessions-DLBpp52_.js +218 -0
  604. package/dist/setup-C7eOzMiC.js +387 -0
  605. package/dist/setup-CFIMq-Pz.d.ts +37 -0
  606. package/dist/setup-binary-CcAv8NXz.js +406 -0
  607. package/dist/setup-browser-C4eRV3h6.js +70 -0
  608. package/dist/setup-core-BnR486P-.js +143 -0
  609. package/dist/setup-core-CIswIiu5.js +166 -0
  610. package/dist/setup-core-CcbcrXXg.js +47 -0
  611. package/dist/setup-core-nZSw5BSv.js +205 -0
  612. package/dist/setup-surface-C5iSpT4M.js +490 -0
  613. package/dist/setup-wizard-helpers-r0J6l8ST.d.ts +203 -0
  614. package/dist/setup.finalize-adiRfo0U.js +522 -0
  615. package/dist/setup.gateway-config-BwFWKDfT.js +343 -0
  616. package/dist/shared-12TimyeF.js +182 -0
  617. package/dist/shared-9EWO34-k.js +298 -0
  618. package/dist/shared-B4vUbaRR.js +75 -0
  619. package/dist/shared-bNWpW3Dd.js +96 -0
  620. package/dist/shared-lU1y5dvS.js +102 -0
  621. package/dist/signal-DBlETRu9.js +114 -0
  622. package/dist/skills-Bio8GwTE.js +20 -0
  623. package/dist/skills-DE_MXFSN.js +853 -0
  624. package/dist/skills-cli-BGuW-tKw.js +292 -0
  625. package/dist/skills-install--rnorIoJ.js +763 -0
  626. package/dist/skills-status-B08PtBc_.js +21 -0
  627. package/dist/skills-status-CzM008aB.js +169 -0
  628. package/dist/slack-C4T53Nc-.js +114 -0
  629. package/dist/slash-commands.runtime-B7fsD8Be.js +128 -0
  630. package/dist/slash-dispatch.runtime-t0PAX4vQ.js +141 -0
  631. package/dist/slash-skill-commands.runtime-DIhPnEfR.js +116 -0
  632. package/dist/src-DrDirlvw.js +1701 -0
  633. package/dist/status-Bld14WSA.js +131 -0
  634. package/dist/status-CgeO4RuH.js +43 -0
  635. package/dist/status-HlvixAOq.js +606 -0
  636. package/dist/status-Rom_Lf3c.js +1599 -0
  637. package/dist/status-TwbMH6Am.js +126 -0
  638. package/dist/status-json-DMW7cmuK.js +288 -0
  639. package/dist/status.link-channel-V4LkB6Gq.js +143 -0
  640. package/dist/status.scan.deps.runtime-BE3X-dcP.js +126 -0
  641. package/dist/status.scan.runtime-BxVY4mty.js +119 -0
  642. package/dist/status.summary-CzLM0vVr.js +592 -0
  643. package/dist/status.summary.runtime-BSBnHZ1Q.js +118 -0
  644. package/dist/status.update-BxblMS7P.js +77 -0
  645. package/dist/subagent-orphan-recovery-BpRPryEj.js +307 -0
  646. package/dist/subagent-registry-runtime-DYYU5p3X.js +111 -0
  647. package/dist/subscription-CpFdxuFS.js +33 -0
  648. package/dist/subscription-DaA1urx-.js +102 -0
  649. package/dist/subscription-cli-Bvto9EmO.js +134 -0
  650. package/dist/synology-chat-3nwk-Nj0.js +297 -0
  651. package/dist/system-cli-BvNps8sl.js +94 -0
  652. package/dist/telegram/audit.d.ts +1 -1
  653. package/dist/telegram/audit.js +1 -1
  654. package/dist/telegram/token.d.ts +1 -1
  655. package/dist/telegram/token.js +35 -35
  656. package/dist/telegram-RtKXoEsF.js +114 -0
  657. package/dist/text-chunking-BD5mQe2R.js +84 -0
  658. package/dist/text-chunking-DDUU_vAF.d.ts +79 -0
  659. package/dist/tlon-z-kYmJE-.js +433 -0
  660. package/dist/tui-cli-CzSK08Rh.js +137 -0
  661. package/dist/tui-wV7R1Tlc.js +3834 -0
  662. package/dist/types-2H_e7eWT.d.ts +45 -0
  663. package/dist/types-ZKnGUchG.d.ts +22692 -0
  664. package/dist/types.base-BFiQZ4J9.d.ts +188 -0
  665. package/dist/ui-BWVHreeR.js +31 -0
  666. package/dist/update-D1Wgh1Tj.js +1036 -0
  667. package/dist/update-cli-CZh99uyY.js +1503 -0
  668. package/dist/update-offset-store-D5xTdUr0.js +112 -0
  669. package/dist/update-runner-GbKfoCHs.js +1496 -0
  670. package/dist/upsert-with-lock-BZU7Le8n.js +33 -0
  671. package/dist/usage-Czgwvg0h.js +115 -0
  672. package/dist/web-CMczmL90.js +112 -0
  673. package/dist/web-shared-B5Q0mIJq.d.ts +45 -0
  674. package/dist/webhook-request-guards-CsKDhZJr.d.ts +76 -0
  675. package/dist/webhook-targets-BSmFtesN.js +181 -0
  676. package/dist/webhook-targets-CjxuEE9C.d.ts +106 -0
  677. package/dist/webhooks-cli-Wl9y6AWW.js +350 -0
  678. package/dist/whatsapp-VzRW8MdR.js +114 -0
  679. package/dist/whatsapp-actions-Cg1Wxv8W.js +167 -0
  680. package/dist/workspace-DJ_S272u.js +484 -0
  681. package/dist/workspace-DbZSqjw0.js +289 -0
  682. package/dist/workspace-cli-D93DLmAh.js +154 -0
  683. package/dist/workspace-dirs-CGeIPpGN.js +2003 -0
  684. package/dist/zalo-CK2dlGmu.d.ts +9 -0
  685. package/dist/zalo-Db7s2boL.js +415 -0
  686. package/dist/zalouser-Jh5YTJX3.js +30911 -0
  687. package/docs/reference/templates/AGENTS.dev.md +83 -0
  688. package/docs/reference/templates/AGENTS.md +219 -0
  689. package/docs/reference/templates/BOOT.md +11 -0
  690. package/docs/reference/templates/BOOTSTRAP.md +62 -0
  691. package/docs/reference/templates/HEARTBEAT.md +12 -0
  692. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  693. package/docs/reference/templates/IDENTITY.md +29 -0
  694. package/docs/reference/templates/SOUL.dev.md +76 -0
  695. package/docs/reference/templates/SOUL.md +43 -0
  696. package/docs/reference/templates/TOOLS.dev.md +24 -0
  697. package/docs/reference/templates/TOOLS.md +47 -0
  698. package/docs/reference/templates/USER.dev.md +18 -0
  699. package/docs/reference/templates/USER.md +23 -0
  700. package/extensions/discord/src/monitor/allow-list.ts +8 -1
  701. package/extensions/discord/src/monitor/message-handler.preflight.ts +4 -1
  702. package/package.json +2 -1
  703. package/dist/accounts-CDr-lDaV.d.ts +0 -103
  704. package/dist/accounts-CS8U4v8C.js +0 -114
  705. package/dist/acp-cli-BGT0jXcC.js +0 -2093
  706. package/dist/actions.runtime-BfckTw6c.js +0 -119
  707. package/dist/actions.runtime-Cl9mBfqH.js +0 -133
  708. package/dist/agent-scope-C-YmLnnb.js +0 -208
  709. package/dist/agents-CydD54p8.js +0 -222
  710. package/dist/agents-DpQsZO6O.js +0 -853
  711. package/dist/agents.config-XU7IsYE-.js +0 -121
  712. package/dist/agents.config-ssoQXuvF.js +0 -17
  713. package/dist/allow-list-Cfn6lmMK.js +0 -81
  714. package/dist/allowlist-CCYXVpM9.js +0 -142
  715. package/dist/api-BoXoFKxy.js +0 -117
  716. package/dist/audit-Bv05N5o9.js +0 -787
  717. package/dist/audit-CIWW1Aqm.js +0 -54
  718. package/dist/audit-channel.collect.runtime-Bi7yrdcO.js +0 -605
  719. package/dist/audit-channel.runtime-C_NDweiW.js +0 -121
  720. package/dist/audit-extra.async-Dp7OKSXg.js +0 -813
  721. package/dist/audit-membership-runtime-B8FQ6VtN.js +0 -162
  722. package/dist/audit.deep.runtime-CXhobL6b.js +0 -25
  723. package/dist/audit.nondeep.runtime-CrEm3T16.js +0 -832
  724. package/dist/audit.runtime-CJPKj1Zg.js +0 -118
  725. package/dist/auth-Byfp0flq.js +0 -101
  726. package/dist/auth-choice-BgOjdeXN.js +0 -507
  727. package/dist/auth-choice-CD1Heq0M.js +0 -122
  728. package/dist/auth-choice-ePNfg0iQ.js +0 -268
  729. package/dist/auth-choice-options-BlewQWI0.js +0 -123
  730. package/dist/auth-choice-prompt-BP2b6aXz.js +0 -36
  731. package/dist/auth-choice-prompt-Cmwl4n97.js +0 -115
  732. package/dist/auth-choice.apply-helpers-Dq-nxuuX.js +0 -66
  733. package/dist/auth-choice.plugin-providers.runtime-B23kOUzQ.js +0 -119
  734. package/dist/auth-profiles-1kPLbBwI.js +0 -127823
  735. package/dist/auth-profiles.runtime-DAfSjku1.js +0 -116
  736. package/dist/banner-DeOsobLO.js +0 -342
  737. package/dist/bluebubbles-BsLGedBM.js +0 -64
  738. package/dist/bluebubbles-CnT9wiS4.d.ts +0 -6
  739. package/dist/bot-CuzVYwa_.d.ts +0 -478
  740. package/dist/brave-BoWimrLe.js +0 -24
  741. package/dist/browser-cli-D_S3wEYE.js +0 -1494
  742. package/dist/call-ByEzDJ1_.js +0 -640
  743. package/dist/call-CHCWVg-O.js +0 -39
  744. package/dist/channel-3VC0oOMu.js +0 -214
  745. package/dist/channel-B9fCBPiS.js +0 -207
  746. package/dist/channel-B9q775cM.js +0 -562
  747. package/dist/channel-BG3UK54j.js +0 -803
  748. package/dist/channel-BRQAdMML.js +0 -352
  749. package/dist/channel-BmlLp933.js +0 -1321
  750. package/dist/channel-By6KvdTG.js +0 -920
  751. package/dist/channel-C8rRsdf6.js +0 -226
  752. package/dist/channel-CLEDBbXE.js +0 -943
  753. package/dist/channel-CMvBAG7o.js +0 -306
  754. package/dist/channel-CmlxxjHY.js +0 -1598
  755. package/dist/channel-CqG6_xN0.js +0 -949
  756. package/dist/channel-DNueHKs92.js +0 -316
  757. package/dist/channel-DUtyN7BX.js +0 -4681
  758. package/dist/channel-DWD6GrfZ.js +0 -538
  759. package/dist/channel-DaRYMYzj.js +0 -619
  760. package/dist/channel-Dj6BgLp8.js +0 -575
  761. package/dist/channel-account-context-Ba3u5D21.js +0 -103
  762. package/dist/channel-crabk6Em.js +0 -542
  763. package/dist/channel-i8uqQaK2.js +0 -497
  764. package/dist/channel-options-xljvwHS2.js +0 -50
  765. package/dist/channel-plugin-ids-DAgknSG4.js +0 -26
  766. package/dist/channel-summary-dHTMCG75.js +0 -111
  767. package/dist/channel-xVWQ96Ni.js +0 -397
  768. package/dist/channel.runtime-B6PoZ4BV.js +0 -182
  769. package/dist/channel.runtime-BPZmo57e.js +0 -404
  770. package/dist/channel.runtime-B_1uGR-U.js +0 -199
  771. package/dist/channel.runtime-BiXnPU0d.js +0 -218
  772. package/dist/channel.runtime-BpvDc9sv.js +0 -870
  773. package/dist/channel.runtime-CUua3W80.js +0 -418
  774. package/dist/channel.runtime-CaCBTd0A.js +0 -179
  775. package/dist/channel.runtime-D0FfYvUj.js +0 -4011
  776. package/dist/channel.runtime-DhoJtpvJ.js +0 -241
  777. package/dist/channel.runtime-Kj9EXNE0.js +0 -127
  778. package/dist/channel.runtime-r4tPuPyh.js +0 -171
  779. package/dist/channel.setup-B7d_grfe.js +0 -6
  780. package/dist/channel.setup-C0vu1fhi.js +0 -9
  781. package/dist/channel.setup-CAI0FNHj.js +0 -11
  782. package/dist/channel.setup-CkDVwv5R.js +0 -57
  783. package/dist/channel.setup-Cpd00YqQ.js +0 -8
  784. package/dist/channel.setup-DbBz1-WT.js +0 -9
  785. package/dist/channel.setup-GZnAvD9g.js +0 -8
  786. package/dist/channels-5H484RSw.js +0 -1118
  787. package/dist/channels-BnPudfyx.js +0 -404
  788. package/dist/channels-cli-WIC-QeH_.js +0 -291
  789. package/dist/channels-status-issues-RDmzovJU.js +0 -16
  790. package/dist/clawbot-cli-BgutNwf8.js +0 -118
  791. package/dist/cleanup-utils-DBl1Aij1.js +0 -96
  792. package/dist/cli-1P7u6zqu.js +0 -154
  793. package/dist/command-registry-B8jovrws.js +0 -232
  794. package/dist/command-registry-DtDl1FVm.js +0 -14
  795. package/dist/command-secret-gateway-BgUo3FxJ.js +0 -111
  796. package/dist/compact.runtime-CXbXM0AU.js +0 -116
  797. package/dist/completion-cli-Cik_owAE.js +0 -17
  798. package/dist/completion-cli-RU3P2RSl.js +0 -445
  799. package/dist/config-5HUpB1L1.js +0 -31
  800. package/dist/config-cli-QHaUHoZI.js +0 -433
  801. package/dist/config-guard-C9Sn3pE-.js +0 -118
  802. package/dist/config-sW57gztj.js +0 -44
  803. package/dist/config-validation-5LkjIKNt.js +0 -262
  804. package/dist/config-value-CtTWALxG.js +0 -132
  805. package/dist/configure-BmR2TPLf.js +0 -243
  806. package/dist/configure-DaLN-5xM.js +0 -1100
  807. package/dist/control-ui-assets-CH3MYmAo.js +0 -232
  808. package/dist/control-ui-shared-CA77PTml.js +0 -29
  809. package/dist/core-CvDzLs7B.js +0 -150
  810. package/dist/core-jm751KJ9.d.ts +0 -87
  811. package/dist/cron-cli-tguLpzyq.js +0 -639
  812. package/dist/daemon-cli-ptosOkL8.js +0 -339
  813. package/dist/daemon-install-DzU4EnVa.js +0 -180
  814. package/dist/deliver-DwxFoHM3.js +0 -111
  815. package/dist/deliver-runtime-DOdDyaPI.js +0 -111
  816. package/dist/device-id-cli-GopvlxxZ.js +0 -52
  817. package/dist/device-identity-CRfhC3_s.js +0 -365
  818. package/dist/devices-cli-ain7ESqU.js +0 -342
  819. package/dist/diagnostic-D96Xaqrj.js +0 -310
  820. package/dist/directory-cli-fh1UxGgY.js +0 -311
  821. package/dist/directory-config-helpers-Coivm0Mt.d.ts +0 -38
  822. package/dist/directory.static-CKjJUNGl.js +0 -44
  823. package/dist/discord-CflhwDEM.js +0 -114
  824. package/dist/discovery-x0ZqY4AB.js +0 -48
  825. package/dist/dm-policy-shared-DKzsSLlO.d.ts +0 -95
  826. package/dist/dns-cli-DCHyKjGf.js +0 -217
  827. package/dist/docs-cli-D3OoqYSP.js +0 -174
  828. package/dist/doctor-completion-Bq2eP87s.js +0 -90
  829. package/dist/doctor-config-flow-D8XRG9Ku.js +0 -2437
  830. package/dist/doctor-config-flow-DGiF1HGc.js +0 -112
  831. package/dist/enable-0QSF4YGH.js +0 -24
  832. package/dist/exec-approvals-cli-Bncym0Gd.js +0 -421
  833. package/dist/feishu-C1dM8pl2.d.ts +0 -36
  834. package/dist/gateway-cli-DYscsmA-.js +0 -26437
  835. package/dist/gateway-install-token-CNv17ac9.js +0 -163
  836. package/dist/gateway-rpc-BGC1Rxvg.js +0 -26
  837. package/dist/gateway-runtime-D89mSQPB.js +0 -69
  838. package/dist/git-commit-CeLH5Ozm.js +0 -2
  839. package/dist/git-commit-DUKRiCP-.js +0 -177
  840. package/dist/googlechat-BgXeXjd1.js +0 -307
  841. package/dist/googlechat-CNZQb1jd.d.ts +0 -12
  842. package/dist/group-access-Deh1tVNr.d.ts +0 -61
  843. package/dist/health-BEjzWwaB.js +0 -570
  844. package/dist/health-FjqrWQL6.js +0 -113
  845. package/dist/heartbeat-summary-CfdSA9M1.js +0 -57
  846. package/dist/help-BZeVprq1.js +0 -81
  847. package/dist/hooks-06OUQvAV.d.ts +0 -6
  848. package/dist/hooks-cli-B7uGJs2O.js +0 -1000
  849. package/dist/hooks-status-CfceaUSg.js +0 -78
  850. package/dist/http-registry-DYskWhOr.d.ts +0 -20
  851. package/dist/identity-file-sshkKKIr.js +0 -60
  852. package/dist/image-generation-D4o3j8o6.d.ts +0 -9
  853. package/dist/imessage-BcV3WGx_.js +0 -31
  854. package/dist/imessage-Dhje7Ty-.js +0 -115
  855. package/dist/inbound-reply-dispatch-C73_7SOl.js +0 -71
  856. package/dist/inbound-reply-dispatch-D6_HNqH8.d.ts +0 -72
  857. package/dist/install-target-D7NRhfzc.js +0 -574
  858. package/dist/installs-Bj6jblqc.js +0 -532
  859. package/dist/io-CMfWWPXQ.js +0 -9738
  860. package/dist/io-CV844hAM.js +0 -29
  861. package/dist/irc-DKi1fDYI.js +0 -672
  862. package/dist/library-rygTG3oA.js +0 -112
  863. package/dist/lifecycle-core-BPlvShWY.js +0 -382
  864. package/dist/line-B8gTtl3Y.d.ts +0 -75
  865. package/dist/line-CGsemKWJ.js +0 -530
  866. package/dist/llm-slug-generator-DlhVyMqT.js +0 -67
  867. package/dist/logging-5wu9k6w4.js +0 -30
  868. package/dist/logging-CxP9suT8.js +0 -13
  869. package/dist/login-qr-BcDsiwHs.js +0 -233
  870. package/dist/login-qr-Y8pJ5yV4.js +0 -112
  871. package/dist/logs-cli-XI9oVXpH.js +0 -256
  872. package/dist/manager-runtime-DkIlXBhD.js +0 -111
  873. package/dist/manager.runtime-Q0q2rJCC.js +0 -715
  874. package/dist/manifest-registry-DAd0SRAP.js +0 -1329
  875. package/dist/matrix-BI0DBBrG.js +0 -1495
  876. package/dist/matrix-D2JoHzb4.d.ts +0 -68
  877. package/dist/matrix-DiABGjJR.js +0 -1269
  878. package/dist/mcp-cli-BOyn_DLL.js +0 -87
  879. package/dist/media-understanding.runtime-DjUa7Dka.js +0 -116
  880. package/dist/memory-cli-CJd_vl-Y.js +0 -111
  881. package/dist/memory-search-CEEItIFR.js +0 -17
  882. package/dist/memory-search-Cv1SBrn7.js +0 -204
  883. package/dist/method-scopes-CQE7-bZ-.js +0 -2452
  884. package/dist/model-auth-markers-BFoM4IPf.d.ts +0 -20
  885. package/dist/model-picker-D6_89XHg.js +0 -112
  886. package/dist/model-picker-Svaw-APs.js +0 -390
  887. package/dist/model-picker.runtime-Chi9nV7A.js +0 -125
  888. package/dist/model-selection-hL8i1Jbs.js +0 -653
  889. package/dist/model-suppression.runtime-DjWJZ0X-.js +0 -116
  890. package/dist/models-7qj1dG_W.js +0 -118
  891. package/dist/models-BPOB_xJF.js +0 -2514
  892. package/dist/models-cli-DdlOVUjS.js +0 -309
  893. package/dist/models-config-CBqUS-jX.js +0 -111
  894. package/dist/models-config.providers.discovery-Dc905FWG.d.ts +0 -18
  895. package/dist/moldclaw-root-D6PbhbZk.js +0 -88
  896. package/dist/monitor-BPYhkEqF.js +0 -782
  897. package/dist/monitor-BuTcQ24j.js +0 -3468
  898. package/dist/monitor-CuXvNhFh.js +0 -113
  899. package/dist/monitor-D-TqSIHF.js +0 -6823
  900. package/dist/monitor-DRSgo9u2.js +0 -3076
  901. package/dist/monitor-DcHch39z.js +0 -772
  902. package/dist/monitor-DsHBMrXp.js +0 -115
  903. package/dist/monitor-shared-CL8T4gt1.js +0 -444
  904. package/dist/msteams-7FMwTvQG.js +0 -852
  905. package/dist/node-cli-BCjaSCZM.js +0 -2503
  906. package/dist/node-resolve-D5Hvcgyx.js +0 -835
  907. package/dist/nodes-cli-Dd_SNbkt.js +0 -1380
  908. package/dist/nostr-DBTFTxKs.js +0 -8744
  909. package/dist/nostr-DLqaIuZx.d.ts +0 -7
  910. package/dist/npm-resolution-CYfb3MHG.js +0 -60
  911. package/dist/oauth-env-zPt5RywA.js +0 -10
  912. package/dist/onboard-BEFQQeig.js +0 -25
  913. package/dist/onboard-CJHNyxJh.js +0 -48
  914. package/dist/onboard-D_3UeLEN.js +0 -589
  915. package/dist/onboard-channels-B_JL0Djc.js +0 -1241
  916. package/dist/onboard-channels-CqZzHt2C.js +0 -205
  917. package/dist/onboard-custom-CER3Ggbq.js +0 -571
  918. package/dist/onboard-custom-bNRdGECb.js +0 -114
  919. package/dist/onboard-helpers-BK0Hsb7Y.js +0 -335
  920. package/dist/onboard-helpers-CXZ5RPoR.js +0 -113
  921. package/dist/onboard-hooks-1NsxEDjH.js +0 -72
  922. package/dist/onboard-remote-DuKhC_7W.js +0 -117
  923. package/dist/onboard-remote-OwRcDuB3.js +0 -181
  924. package/dist/onboard-search-Cy8dOq2W.js +0 -302
  925. package/dist/onboard-skills-D5phRa6r.js +0 -117
  926. package/dist/onboard-skills-c9qWCNe9.js +0 -133
  927. package/dist/outbound-media-CXKqTh2X.d.ts +0 -11
  928. package/dist/outbound-media-DYRO2vTD.js +0 -11
  929. package/dist/pairing-access-BwJu1mkk.d.ts +0 -21
  930. package/dist/pairing-cli-BOnv0TYn.js +0 -217
  931. package/dist/perplexity-EZwC3y2b.js +0 -24
  932. package/dist/persistent-dedupe-hNES5tS1.d.ts +0 -26
  933. package/dist/pi-model-discovery-runtime-BToY3A6K.js +0 -111
  934. package/dist/pi-tools.before-tool-call.runtime-D_acPtld.js +0 -381
  935. package/dist/plugin-install-CgJpSjYd.js +0 -184
  936. package/dist/plugin-install-Cl1A4EF6.js +0 -117
  937. package/dist/plugin-install-plan-Dc2Z4DeU.js +0 -49
  938. package/dist/plugin-registry-B1UaWrQD.js +0 -49
  939. package/dist/plugin-registry-Cy8biwnn.js +0 -113
  940. package/dist/plugins-CXwvg50F.js +0 -111
  941. package/dist/plugins-cli-Uvzp2aYV.js +0 -917
  942. package/dist/policy-DsMBbEe7.js +0 -143
  943. package/dist/preflight-audio.runtime-hWsZIYvc.js +0 -116
  944. package/dist/probe-CNsSf1Uf.js +0 -6329
  945. package/dist/probe-CqOIrPhb.js +0 -47
  946. package/dist/probe-DH6gDw-h.js +0 -129
  947. package/dist/probe-DM16PLf4.js +0 -21
  948. package/dist/probe-DvAEEWYr.js +0 -1793
  949. package/dist/probe-auth-COfgCble.js +0 -48
  950. package/dist/probe-auth-I_5TX1Eh.js +0 -40
  951. package/dist/program-Dz80sgTU.js +0 -253
  952. package/dist/prompt-select-styled-wQehwFxK.js +0 -2673
  953. package/dist/provider-api-key-auth.runtime-BR9GU4ya.js +0 -121
  954. package/dist/provider-auth-choice-CdhA84kr.js +0 -126
  955. package/dist/provider-auth-choice-helpers-kabp_0zA.js +0 -48
  956. package/dist/provider-auth-choice-preference-se3zAM_2.js +0 -189
  957. package/dist/provider-auth-choice.runtime-BMc8-xNQ.js +0 -123
  958. package/dist/provider-auth-choices-CYsCViGi.js +0 -57
  959. package/dist/provider-auth-guidance-CMjUWlNf.js +0 -34
  960. package/dist/provider-auth-result-5xgWoVGi.d.ts +0 -18
  961. package/dist/provider-models-BCId_Lfu.js +0 -2113
  962. package/dist/provider-models-D-eFl9oH.d.ts +0 -867
  963. package/dist/provider-ollama-setup-B6XJZ0So.js +0 -314
  964. package/dist/provider-ollama-setup-BF1vhob8.d.ts +0 -32
  965. package/dist/provider-onboard-BjXHP3IZ.d.ts +0 -40
  966. package/dist/provider-onboard-Ca0TaNud.js +0 -139
  967. package/dist/provider-runtime.runtime-DwwkHw_7.js +0 -111
  968. package/dist/provider-self-hosted-setup-BEKLVGpj.js +0 -182
  969. package/dist/provider-self-hosted-setup-BQ5BIlpi.d.ts +0 -61
  970. package/dist/provider-stream-DrUD69ai.js +0 -512
  971. package/dist/provider-usage-BgKHCnjr.js +0 -111
  972. package/dist/provider-usage-D8EZpFz9.js +0 -633
  973. package/dist/provider-wizard-DMdb-zj_.js +0 -152
  974. package/dist/push-apns-BPH6d4VV.js +0 -1038
  975. package/dist/pw-ai-DttfldtL.js +0 -1867
  976. package/dist/qmd-manager-CybcDUfk.js +0 -1570
  977. package/dist/qr-cli-8NcmJ8Ft.js +0 -369
  978. package/dist/qr-cli-DWe0Our3.js +0 -113
  979. package/dist/reactions-D6N0LR16.js +0 -281
  980. package/dist/read-only-account-inspect.discord.runtime-CqUWTRfl.js +0 -116
  981. package/dist/read-only-account-inspect.slack.runtime-9-jpln3q.js +0 -116
  982. package/dist/read-only-account-inspect.telegram.runtime-EKPI1D7n.js +0 -116
  983. package/dist/redact-snapshot-DwJEIVk9.js +0 -2663
  984. package/dist/register.agent-D3YdDirP.js +0 -439
  985. package/dist/register.backup-dR27qCuo.js +0 -625
  986. package/dist/register.configure-BjFhkkka.js +0 -252
  987. package/dist/register.maintenance-DiMQJIOa.js +0 -574
  988. package/dist/register.message-CdZsKYH1.js +0 -709
  989. package/dist/register.onboard-B0rV1eaO.js +0 -192
  990. package/dist/register.setup-wKMvohzo.js +0 -212
  991. package/dist/register.status-health-sessions-BJ68m6pt.js +0 -498
  992. package/dist/register.subclis-CnnrWt2a.js +0 -315
  993. package/dist/register.subclis-lSvTkC6z.js +0 -13
  994. package/dist/replies-BABt9b48.js +0 -110
  995. package/dist/resolve-channels-BqZFl2Ux.js +0 -262
  996. package/dist/resolve-channels-DjQLXb7B.js +0 -226
  997. package/dist/resolve-route-CSHDsa_m.js +0 -538
  998. package/dist/resolve-users-BG6HaSR5.js +0 -143
  999. package/dist/root-help-ohmaCyC_.js +0 -32
  1000. package/dist/routes-4k2kpvoT.js +0 -7097
  1001. package/dist/rpc-Cnwn4Q6L.js +0 -67
  1002. package/dist/run-main-VYlacKA0.js +0 -424
  1003. package/dist/runtime-Cy8pqYUB.d.ts +0 -26
  1004. package/dist/runtime-discord-ops.runtime-DafrU-rI.js +0 -9078
  1005. package/dist/runtime-slack-ops.runtime-CdXBKXwd.js +0 -4556
  1006. package/dist/runtime-telegram-ops.runtime-B12sF7gE.js +0 -133
  1007. package/dist/runtime-whatsapp-login.runtime-CqEudH37.js +0 -114
  1008. package/dist/runtime-whatsapp-outbound.runtime-D5m2qyn-.js +0 -117
  1009. package/dist/sandbox-cli-CHJiEWXB.js +0 -535
  1010. package/dist/search-manager-BtNC3-i_.js +0 -16
  1011. package/dist/search-manager-C7J7B3_a.js +0 -386
  1012. package/dist/secrets-cli-C6yIWBbN.js +0 -2070
  1013. package/dist/security-cli-BVu9BkjD.js +0 -575
  1014. package/dist/send-BSreC7rr.js +0 -631
  1015. package/dist/send-BsLHQG_B.js +0 -1025
  1016. package/dist/send-BuNhp8PH.js +0 -283
  1017. package/dist/send-DOCswVar.js +0 -100
  1018. package/dist/send-Dl0LLErk.js +0 -629
  1019. package/dist/server-node-events-Bq2067EG.js +0 -506
  1020. package/dist/server-y38L7N5H.js +0 -107
  1021. package/dist/sessions-BV8gXURR.js +0 -112
  1022. package/dist/sessions-dl1Kc-Ci.js +0 -218
  1023. package/dist/setup-DGszQH0_.js +0 -387
  1024. package/dist/setup-DR5rRw9y.d.ts +0 -37
  1025. package/dist/setup-binary-C17YnmA8.js +0 -406
  1026. package/dist/setup-browser-CPx-nEsr.js +0 -70
  1027. package/dist/setup-core-BByHN1ME.js +0 -143
  1028. package/dist/setup-core-C0KPlBmL.js +0 -47
  1029. package/dist/setup-core-Cq37G6of.js +0 -166
  1030. package/dist/setup-core-uO84_Y75.js +0 -205
  1031. package/dist/setup-surface-BEMi7Rmb.js +0 -490
  1032. package/dist/setup-wizard-helpers-BtuGx_gN.d.ts +0 -203
  1033. package/dist/setup.finalize-BzPBa8zW.js +0 -522
  1034. package/dist/setup.gateway-config-DdwkF-8e.js +0 -343
  1035. package/dist/shared-BCw4SKjB.js +0 -96
  1036. package/dist/shared-CjNzsULP.js +0 -75
  1037. package/dist/shared-Cu1BE7ZE.js +0 -298
  1038. package/dist/shared-DSClmyUn.js +0 -182
  1039. package/dist/shared-DyJdGH6y.js +0 -102
  1040. package/dist/signal-Dyv4NZsB.js +0 -114
  1041. package/dist/skills-CbB5b27M.js +0 -853
  1042. package/dist/skills-CnfI7Szw.js +0 -20
  1043. package/dist/skills-cli-CavB1f_3.js +0 -292
  1044. package/dist/skills-install-B1OBdgd0.js +0 -763
  1045. package/dist/skills-status-B3gAmIbW.js +0 -169
  1046. package/dist/skills-status-DrHhFgU9.js +0 -21
  1047. package/dist/slack-BRzqnoAz.js +0 -114
  1048. package/dist/slash-commands.runtime-BK88kgds.js +0 -128
  1049. package/dist/slash-dispatch.runtime-COGywwJE.js +0 -141
  1050. package/dist/slash-skill-commands.runtime-Ti4brxgh.js +0 -116
  1051. package/dist/src-DUR6OQxI.js +0 -1701
  1052. package/dist/status-C6dgQY9a.js +0 -131
  1053. package/dist/status-CNK0Q7QH.js +0 -606
  1054. package/dist/status-DBcX0DSC.js +0 -43
  1055. package/dist/status-DKgFgbwv.js +0 -1599
  1056. package/dist/status-Wn5lhNAc.js +0 -126
  1057. package/dist/status-json-D2EkWqAl.js +0 -288
  1058. package/dist/status.link-channel-D3ULIdEa.js +0 -143
  1059. package/dist/status.scan.deps.runtime-BsjWTAm4.js +0 -126
  1060. package/dist/status.scan.runtime-D4HbzROD.js +0 -119
  1061. package/dist/status.summary-C3YxPrDK.js +0 -592
  1062. package/dist/status.summary.runtime-DAkXPSaK.js +0 -118
  1063. package/dist/status.update-B4NnN9P1.js +0 -77
  1064. package/dist/subagent-orphan-recovery-QiQEBv36.js +0 -307
  1065. package/dist/subagent-registry-runtime-BJatPQFK.js +0 -111
  1066. package/dist/subscription-BhZORXN9.js +0 -100
  1067. package/dist/subscription-QEUjQRMv.js +0 -33
  1068. package/dist/subscription-cli-HrULlAgc.js +0 -134
  1069. package/dist/synology-chat-DB76GWMN.js +0 -297
  1070. package/dist/system-cli-D8jDwWuL.js +0 -94
  1071. package/dist/telegram-BHiiqKkQ.js +0 -114
  1072. package/dist/text-chunking-Baonm9Lu.js +0 -84
  1073. package/dist/text-chunking-Y3dPBOuZ.d.ts +0 -79
  1074. package/dist/tlon-DLESxNgD.js +0 -433
  1075. package/dist/tui-C75zi2Cl.js +0 -3834
  1076. package/dist/tui-cli-DFwx5e6i.js +0 -137
  1077. package/dist/types-BBJ3Qz7j.d.ts +0 -45
  1078. package/dist/types-Ckufs_BY.d.ts +0 -22692
  1079. package/dist/types.base-Cw0-zIvE.d.ts +0 -188
  1080. package/dist/ui-B55NOIB6.js +0 -31
  1081. package/dist/update--ojavYQ4.js +0 -1036
  1082. package/dist/update-cli-Cvj5aWYM.js +0 -1503
  1083. package/dist/update-offset-store-upatuWwX.js +0 -112
  1084. package/dist/update-runner-DHkY_-76.js +0 -1496
  1085. package/dist/upsert-with-lock-C171GLaR.js +0 -33
  1086. package/dist/usage-N3bxnbmt.js +0 -115
  1087. package/dist/web-RdvT7gKa.js +0 -112
  1088. package/dist/web-shared-HSGD3yGt.d.ts +0 -45
  1089. package/dist/webhook-request-guards-CosLyl01.d.ts +0 -76
  1090. package/dist/webhook-targets-Bfnag-du.js +0 -181
  1091. package/dist/webhook-targets-Di17rt8e.d.ts +0 -106
  1092. package/dist/webhooks-cli-ZpnXrq7G.js +0 -350
  1093. package/dist/whatsapp-DNTAyZHt.js +0 -114
  1094. package/dist/whatsapp-actions-o1zKQzKZ.js +0 -167
  1095. package/dist/workspace-CpWi5wPr.js +0 -479
  1096. package/dist/workspace-Ii7aRS7c.js +0 -289
  1097. package/dist/workspace-dirs-x10McA9t.js +0 -2003
  1098. package/dist/zalo-BN3VCrRY.d.ts +0 -9
  1099. package/dist/zalo-zm_bYCKg.js +0 -415
  1100. package/dist/zalouser-CvVEUvc5.js +0 -30911
  1101. /package/dist/{account-id-B3YSn4hl.d.ts → account-id-B8ce6G_4.d.ts} +0 -0
  1102. /package/dist/{acpx-CnNv70m2.d.ts → acpx-Ci50I9T2.d.ts} +0 -0
  1103. /package/dist/{agent-media-payload-DE2pEcsz.d.ts → agent-media-payload-en-gS5p6.d.ts} +0 -0
  1104. /package/dist/{allow-from-DPpHnT2A.d.ts → allow-from-cMeQ47Ot.d.ts} +0 -0
  1105. /package/dist/{allowlist-resolution-CLFiZ6nE.d.ts → allowlist-resolution-DoAWbfXV.d.ts} +0 -0
  1106. /package/dist/{bluebubbles-Duhu-Jer.d.ts → bluebubbles-C6yYmUl0.d.ts} +0 -0
  1107. /package/dist/{boolean-param-BhFjB3gp.d.ts → boolean-param-CdO2TFTk.d.ts} +0 -0
  1108. /package/dist/{channel-config-schema-DnnVMdjR.d.ts → channel-config-schema-Chp38wel.d.ts} +0 -0
  1109. /package/dist/{channel-policy-Baq-Z06b.d.ts → channel-policy-g2h6AbYQ.d.ts} +0 -0
  1110. /package/dist/{chat-type-DpiBgwuG.d.ts → chat-type-BLt59pPT.d.ts} +0 -0
  1111. /package/dist/{command-format-vi4xq8e8.d.ts → command-format-BDJC05Jp.d.ts} +0 -0
  1112. /package/dist/{diffs-DK7fVSDo.d.ts → diffs-D_iNKCyn.d.ts} +0 -0
  1113. /package/dist/{directory-runtime-BTLPaysA.d.ts → directory-runtime-DhMex6HY.d.ts} +0 -0
  1114. /package/dist/{exec-C01wtBHu.d.ts → exec-pjfUY4KM.d.ts} +0 -0
  1115. /package/dist/{gaxios-fetch-compat-wZ38b3w3.js → gaxios-fetch-compat-B_vtINdV.js} +0 -0
  1116. /package/dist/{history-CwXuP2TW.d.ts → history-aqSS5VGQ.d.ts} +0 -0
  1117. /package/dist/{inbound-envelope-SggrBs9m.d.ts → inbound-envelope-C5hWuZod.d.ts} +0 -0
  1118. /package/dist/{index-apAZHsDo.d.ts → index-DXVQFYGX.d.ts} +0 -0
  1119. /package/dist/{json-store-r75IZGk9.d.ts → json-store-UnqQ5aV3.d.ts} +0 -0
  1120. /package/dist/{keyed-async-queue-DHIr7yNe.d.ts → keyed-async-queue-guucpLw3.d.ts} +0 -0
  1121. /package/dist/{links-HeQ3r_L0.d.ts → links-Bar0meEK.d.ts} +0 -0
  1122. /package/dist/{markdown-to-line-CDb4Jy3V.d.ts → markdown-to-line-D8uH_KOj.d.ts} +0 -0
  1123. /package/dist/{mattermost-DtCsxpgg.d.ts → mattermost-xl7jAFJL.d.ts} +0 -0
  1124. /package/dist/{net-BATPDwdQ.d.ts → net-rGOKGds6.d.ts} +0 -0
  1125. /package/dist/{nextcloud-talk-Bb2wHOwp.d.ts → nextcloud-talk-De2CZ9dV.d.ts} +0 -0
  1126. /package/dist/{oauth-utils-u567CLT0.d.ts → oauth-utils-DzN1AlEH.d.ts} +0 -0
  1127. /package/dist/{parse-finite-number-l3tNlrZh.d.ts → parse-finite-number-odgyqhi0.d.ts} +0 -0
  1128. /package/dist/{provider-usage.types-C6061OVN.d.ts → provider-usage.types-EDE9o-H_.d.ts} +0 -0
  1129. /package/dist/{reply-history-BDsFnZFl.d.ts → reply-history-CVuU31xe.d.ts} +0 -0
  1130. /package/dist/{reply-payload-CCvM4W9u.d.ts → reply-payload-CHkpBYwL.d.ts} +0 -0
  1131. /package/dist/{request-url-C54l4-xC.d.ts → request-url-DHisbiHY.d.ts} +0 -0
  1132. /package/dist/{run-command-D3RqWcHu.d.ts → run-command-y0Cndsb1.d.ts} +0 -0
  1133. /package/dist/{secret-input-schema-BLBt-NAP.d.ts → secret-input-schema-b1vpYDQN.d.ts} +0 -0
  1134. /package/dist/{session-key-BQ2-bR-9.d.ts → session-key-DTHQl57f.d.ts} +0 -0
  1135. /package/dist/{ssh-config-C4mcH9Ly.js → ssh-config-hEHBfU2_.js} +0 -0
  1136. /package/dist/{testing-DLkhGsoz.d.ts → testing-DszuZXgK.d.ts} +0 -0
  1137. /package/dist/{thinking-DRkjX18p.d.ts → thinking-IwXTGSeT.d.ts} +0 -0
  1138. /package/dist/{tool-send-CMMD1uDu.d.ts → tool-send-DWHRmKpz.d.ts} +0 -0
  1139. /package/dist/{vllm-defaults-CcGuf4hL.d.ts → vllm-defaults-CrxZgE6-.d.ts} +0 -0
  1140. /package/dist/{wait-Daog8bxM.d.ts → wait-wDWw_MTI.d.ts} +0 -0
  1141. /package/dist/{webhook-memory-guards-C5MrExwT.d.ts → webhook-memory-guards-DreORuJy.d.ts} +0 -0
  1142. /package/dist/{windows-spawn-j2l-dqu8.d.ts → windows-spawn-BIzH92x2.d.ts} +0 -0
  1143. /package/dist/{zod-schema.agent-runtime-krMrBnIn.d.ts → zod-schema.agent-runtime-CP2rmis3.d.ts} +0 -0
  1144. /package/dist/{zod-schema.core-BNDieZDZ.d.ts → zod-schema.core-Foi1tYwi.d.ts} +0 -0
@@ -1,4011 +0,0 @@
1
- import { t as __commonJSMin } from "./chunk-DORXReHP.js";
2
- import "./redact-fatrROh9.js";
3
- import "./errors-DOJWZqNo.js";
4
- import "./unhandled-rejections-CTvNvnT0.js";
5
- import "./logger-BFfIIIKH.js";
6
- import "./paths-D6AgsMTU.js";
7
- import "./tmp-moldclaw-dir-DWF-d8qD.js";
8
- import "./theme-BSXzMzAA.js";
9
- import "./globals-DESrFYmC.js";
10
- import "./runtime-_tQz41uA.js";
11
- import "./ansi-BPhP6LBZ.js";
12
- import "./subsystem-CPmDTJ2P.js";
13
- import "./boolean-B6zcAynR.js";
14
- import "./env-D42cffog.js";
15
- import "./warning-filter-B1UOeM0G.js";
16
- import "./utils-C7ykRPCQ.js";
17
- import "./links-BcahUP5U.js";
18
- import "./setup-binary-C17YnmA8.js";
19
- import { WS as createDedupeCache } from "./auth-profiles-1kPLbBwI.js";
20
- import "./model-selection-hL8i1Jbs.js";
21
- import "./agent-scope-C-YmLnnb.js";
22
- import "./boundary-file-read-tPYh_8fH.js";
23
- import "./logger-BGzLUitz.js";
24
- import "./exec-CvEtXqTZ.js";
25
- import "./workspace-CpWi5wPr.js";
26
- import "./io-CMfWWPXQ.js";
27
- import "./host-env-security-DQ2i_W12.js";
28
- import "./safe-text-Cnulee_z.js";
29
- import "./version-T8nMYUnU.js";
30
- import "./env-substitution-68cyvF5h.js";
31
- import "./config-state-h5jUoHya.js";
32
- import "./network-mode-BtWXzwYn.js";
33
- import "./registry-C1pRrsQl.js";
34
- import "./manifest-registry-DAd0SRAP.js";
35
- import "./ip-C4YAIpr4.js";
36
- import "./zod-schema.core-DvwgNmpd.js";
37
- import "./config-sW57gztj.js";
38
- import "./audit-fs-CMb-YUHX.js";
39
- import "./resolve-PSlwZjg3.js";
40
- import { J as fetchWithSsrFGuard } from "./provider-web-search-CcUC9ktE.js";
41
- import "./text-runtime-Cfq-Uyx0.js";
42
- import "./workspace-dirs-x10McA9t.js";
43
- import "./config-BwkGZjD5.js";
44
- import "./tailnet-fFTz5Twr.js";
45
- import "./net-K181nxTH.js";
46
- import "./credentials-D-5Pb-aZ.js";
47
- import "./routes-4k2kpvoT.js";
48
- import "./frontmatter-Cgg0ICvh.js";
49
- import "./env-overrides-DBQl3LRc.js";
50
- import "./path-alias-guards-BtSO7sk7.js";
51
- import "./skills-CbB5b27M.js";
52
- import "./ports-Ca74cFb2.js";
53
- import "./ports-lsof-CoiADo0p.js";
54
- import "./ssh-tunnel-DsY-9yao.js";
55
- import "./image-ops-Ck_D_vpe.js";
56
- import "./fs-safe-CRXFoBmh.js";
57
- import "./mime-DGFQe4XX.js";
58
- import "./server-middleware-Djfoa1s0.js";
59
- import "./message-channel-DFE4FuE_.js";
60
- import "./resolve-route-CSHDsa_m.js";
61
- import "./internal-hooks-83AcmxP3.js";
62
- import "./lazy-runtime-BoGB4usD.js";
63
- import "./config-schema-BNU4GQh_.js";
64
- import "./method-scopes-CQE7-bZ-.js";
65
- import "./session-cost-usage-DWgQk6XT.js";
66
- import "./paths-ApLcu1Uu.js";
67
- import "./routing-DQ-fpTaA.js";
68
- import "./send-BuNhp8PH.js";
69
- import "./node-resolve-D5Hvcgyx.js";
70
- import "./provider-stream-DrUD69ai.js";
71
- import "./identity-file-sshkKKIr.js";
72
- import "./provider-models-BCId_Lfu.js";
73
- import "./secret-file-p1IhQzwJ.js";
74
- import "./logging-Dy7UYzIN.js";
75
- import "./runtime-env-BlEtPF6b.js";
76
- import "./registry-BFMbkmgR.js";
77
- import "./provider-onboard-Ca0TaNud.js";
78
- import "./model-definitions-Cyyzm6Kr.js";
79
- import "./usage-N3bxnbmt.js";
80
- import "./device-identity-CRfhC3_s.js";
81
- import "./auth-Byfp0flq.js";
82
- import "./subscription-BhZORXN9.js";
83
- import "./diagnostic-D96Xaqrj.js";
84
- import "./message-hook-mappers-CeiHXgSQ.js";
85
- import "./json-store--7cBPxTG.js";
86
- import "./call-ByEzDJ1_.js";
87
- import "./multimodal-BJBBn_4F.js";
88
- import "./memory-search-Cv1SBrn7.js";
89
- import "./query-expansion-D_Mm5Hhi.js";
90
- import "./search-manager-C7J7B3_a.js";
91
- import "./core-CvDzLs7B.js";
92
- import "./issue-format-B0SI57Es.js";
93
- import "./logging-CxP9suT8.js";
94
- import "./note-dOl5kPAy.js";
95
- import "./state-paths-DsMoTg25.js";
96
- import "./config-value-CtTWALxG.js";
97
- import "./command-secret-targets-BFF4x_RB.js";
98
- import "./brave-BoWimrLe.js";
99
- import "./provider-usage-D8EZpFz9.js";
100
- import "./perplexity-EZwC3y2b.js";
101
- import "./restart-stale-pids-CPF1_61W.js";
102
- import "./delivery-queue-BOf5wYIc.js";
103
- import "./pairing-token-bu1e6z6X.js";
104
- import "./accounts-J2OhhhQi.js";
105
- import "./process-runtime-D27SftX_.js";
106
- import "./audit-CIWW1Aqm.js";
107
- import "./cli-runtime-DTCHPjCi.js";
108
- import "./cli-utils-BCuSS4l6.js";
109
- import "./help-format-BFzPm_8V.js";
110
- import "./progress-Cwq59vgZ.js";
111
- import "./gateway-runtime-D89mSQPB.js";
112
- import { t as createLoggerBackedRuntime } from "./runtime-DP4WaDXD.js";
113
- import { c as normalizeShip, d as resolveTlonOutboundTarget, i as validateUrbitBaseUrl, l as parseChannelNest, o as resolveTlonAccount, s as formatTargetHint, t as tlonSetupWizard, u as parseTlonTarget } from "./tlon-DLESxNgD.js";
114
- import { t as getTlonRuntime } from "./runtime-BJXL2IIY.js";
115
- import { createWriteStream } from "node:fs";
116
- import * as path$1 from "node:path";
117
- import { homedir } from "node:os";
118
- import { mkdir } from "node:fs/promises";
119
- import crypto, { randomUUID } from "node:crypto";
120
- import { pipeline } from "node:stream/promises";
121
- import { Readable } from "node:stream";
122
- import { configureClient, uploadFile } from "@tloncorp/api";
123
- //#region extensions/tlon/src/settings.ts
124
- const SETTINGS_DESK = "moltbot";
125
- const SETTINGS_BUCKET = "tlon";
126
- /**
127
- * Parse channelRules - handles both JSON string and object formats.
128
- * Settings-store doesn't support nested objects, so we store as JSON string.
129
- */
130
- function parseChannelRules(value) {
131
- if (!value) return;
132
- if (typeof value === "string") try {
133
- const parsed = JSON.parse(value);
134
- if (isChannelRulesObject(parsed)) return parsed;
135
- } catch {
136
- return;
137
- }
138
- if (isChannelRulesObject(value)) return value;
139
- }
140
- /**
141
- * Parse settings from the raw Urbit settings-store response.
142
- * The response shape is: { [bucket]: { [key]: value } }
143
- */
144
- function parseSettingsResponse(raw) {
145
- if (!raw || typeof raw !== "object") return {};
146
- const bucket = raw[SETTINGS_BUCKET];
147
- if (!bucket || typeof bucket !== "object") return {};
148
- const settings = bucket;
149
- return {
150
- groupChannels: Array.isArray(settings.groupChannels) ? settings.groupChannels.filter((x) => typeof x === "string") : void 0,
151
- dmAllowlist: Array.isArray(settings.dmAllowlist) ? settings.dmAllowlist.filter((x) => typeof x === "string") : void 0,
152
- autoDiscover: typeof settings.autoDiscover === "boolean" ? settings.autoDiscover : void 0,
153
- showModelSig: typeof settings.showModelSig === "boolean" ? settings.showModelSig : void 0,
154
- autoAcceptDmInvites: typeof settings.autoAcceptDmInvites === "boolean" ? settings.autoAcceptDmInvites : void 0,
155
- autoAcceptGroupInvites: typeof settings.autoAcceptGroupInvites === "boolean" ? settings.autoAcceptGroupInvites : void 0,
156
- groupInviteAllowlist: Array.isArray(settings.groupInviteAllowlist) ? settings.groupInviteAllowlist.filter((x) => typeof x === "string") : void 0,
157
- channelRules: parseChannelRules(settings.channelRules),
158
- defaultAuthorizedShips: Array.isArray(settings.defaultAuthorizedShips) ? settings.defaultAuthorizedShips.filter((x) => typeof x === "string") : void 0,
159
- ownerShip: typeof settings.ownerShip === "string" ? settings.ownerShip : void 0,
160
- pendingApprovals: parsePendingApprovals(settings.pendingApprovals)
161
- };
162
- }
163
- function isChannelRulesObject(val) {
164
- if (!val || typeof val !== "object" || Array.isArray(val)) return false;
165
- for (const [, rule] of Object.entries(val)) if (!rule || typeof rule !== "object") return false;
166
- return true;
167
- }
168
- /**
169
- * Parse pendingApprovals - handles both JSON string and array formats.
170
- * Settings-store stores complex objects as JSON strings.
171
- */
172
- function parsePendingApprovals(value) {
173
- if (!value) return;
174
- let parsed = value;
175
- if (typeof value === "string") try {
176
- parsed = JSON.parse(value);
177
- } catch {
178
- return;
179
- }
180
- if (!Array.isArray(parsed)) return;
181
- return parsed.filter((item) => {
182
- if (!item || typeof item !== "object") return false;
183
- const obj = item;
184
- return typeof obj.id === "string" && (obj.type === "dm" || obj.type === "channel" || obj.type === "group") && typeof obj.requestingShip === "string" && typeof obj.timestamp === "number";
185
- });
186
- }
187
- /**
188
- * Parse a single settings entry update event.
189
- */
190
- function parseSettingsEvent(event) {
191
- if (!event || typeof event !== "object") return null;
192
- const evt = event;
193
- if (evt["put-entry"]) {
194
- const put = evt["put-entry"];
195
- if (put.desk !== SETTINGS_DESK || put["bucket-key"] !== SETTINGS_BUCKET) return null;
196
- return {
197
- key: String(put["entry-key"] ?? ""),
198
- value: put.value
199
- };
200
- }
201
- if (evt["del-entry"]) {
202
- const del = evt["del-entry"];
203
- if (del.desk !== SETTINGS_DESK || del["bucket-key"] !== SETTINGS_BUCKET) return null;
204
- return {
205
- key: String(del["entry-key"] ?? ""),
206
- value: void 0
207
- };
208
- }
209
- return null;
210
- }
211
- /**
212
- * Apply a single settings update to the current state.
213
- */
214
- function applySettingsUpdate(current, key, value) {
215
- const next = { ...current };
216
- switch (key) {
217
- case "groupChannels":
218
- next.groupChannels = Array.isArray(value) ? value.filter((x) => typeof x === "string") : void 0;
219
- break;
220
- case "dmAllowlist":
221
- next.dmAllowlist = Array.isArray(value) ? value.filter((x) => typeof x === "string") : void 0;
222
- break;
223
- case "autoDiscover":
224
- next.autoDiscover = typeof value === "boolean" ? value : void 0;
225
- break;
226
- case "showModelSig":
227
- next.showModelSig = typeof value === "boolean" ? value : void 0;
228
- break;
229
- case "autoAcceptDmInvites":
230
- next.autoAcceptDmInvites = typeof value === "boolean" ? value : void 0;
231
- break;
232
- case "autoAcceptGroupInvites":
233
- next.autoAcceptGroupInvites = typeof value === "boolean" ? value : void 0;
234
- break;
235
- case "groupInviteAllowlist":
236
- next.groupInviteAllowlist = Array.isArray(value) ? value.filter((x) => typeof x === "string") : void 0;
237
- break;
238
- case "channelRules":
239
- next.channelRules = parseChannelRules(value);
240
- break;
241
- case "defaultAuthorizedShips":
242
- next.defaultAuthorizedShips = Array.isArray(value) ? value.filter((x) => typeof x === "string") : void 0;
243
- break;
244
- case "ownerShip":
245
- next.ownerShip = typeof value === "string" ? value : void 0;
246
- break;
247
- case "pendingApprovals":
248
- next.pendingApprovals = parsePendingApprovals(value);
249
- break;
250
- }
251
- return next;
252
- }
253
- /**
254
- * Create a settings store subscription manager.
255
- *
256
- * Usage:
257
- * const settings = createSettingsManager(api, logger);
258
- * await settings.load();
259
- * settings.subscribe((newSettings) => { ... });
260
- */
261
- function createSettingsManager(api, logger) {
262
- let state = {
263
- current: {},
264
- loaded: false
265
- };
266
- const listeners = /* @__PURE__ */ new Set();
267
- const notify = () => {
268
- for (const listener of listeners) try {
269
- listener(state.current);
270
- } catch (err) {
271
- logger?.error?.(`[settings] Listener error: ${String(err)}`);
272
- }
273
- };
274
- return {
275
- get current() {
276
- return state.current;
277
- },
278
- get loaded() {
279
- return state.loaded;
280
- },
281
- async load() {
282
- try {
283
- const deskData = (await api.scry("/settings/all.json"))?.all?.[SETTINGS_DESK];
284
- state.current = parseSettingsResponse(deskData ?? {});
285
- state.loaded = true;
286
- logger?.log?.(`[settings] Loaded: ${JSON.stringify(state.current)}`);
287
- return state.current;
288
- } catch (err) {
289
- logger?.log?.(`[settings] No settings found (using defaults): ${String(err)}`);
290
- state.current = {};
291
- state.loaded = true;
292
- return state.current;
293
- }
294
- },
295
- async startSubscription() {
296
- await api.subscribe({
297
- app: "settings",
298
- path: "/desk/" + SETTINGS_DESK,
299
- event: (event) => {
300
- const update = parseSettingsEvent(event);
301
- if (!update) return;
302
- logger?.log?.(`[settings] Update: ${update.key} = ${JSON.stringify(update.value)}`);
303
- state.current = applySettingsUpdate(state.current, update.key, update.value);
304
- notify();
305
- },
306
- err: (error) => {
307
- logger?.error?.(`[settings] Subscription error: ${String(error)}`);
308
- },
309
- quit: () => {
310
- logger?.log?.("[settings] Subscription ended");
311
- }
312
- });
313
- logger?.log?.("[settings] Subscribed to settings updates");
314
- },
315
- onChange(listener) {
316
- listeners.add(listener);
317
- return () => listeners.delete(listener);
318
- }
319
- };
320
- }
321
- //#endregion
322
- //#region extensions/tlon/src/urbit/errors.ts
323
- var UrbitError = class extends Error {
324
- constructor(code, message, options) {
325
- super(message, options);
326
- this.name = "UrbitError";
327
- this.code = code;
328
- }
329
- };
330
- var UrbitUrlError = class extends UrbitError {
331
- constructor(message, options) {
332
- super("invalid_url", message, options);
333
- this.name = "UrbitUrlError";
334
- }
335
- };
336
- var UrbitHttpError = class extends UrbitError {
337
- constructor(params) {
338
- const suffix = params.bodyText ? ` - ${params.bodyText}` : "";
339
- super("http_error", `${params.operation} failed: ${params.status}${suffix}`, { cause: params.cause });
340
- this.name = "UrbitHttpError";
341
- this.status = params.status;
342
- this.operation = params.operation;
343
- this.bodyText = params.bodyText;
344
- }
345
- };
346
- var UrbitAuthError = class extends UrbitError {
347
- constructor(code, message, options) {
348
- super(code, message, options);
349
- this.name = "UrbitAuthError";
350
- }
351
- };
352
- //#endregion
353
- //#region extensions/tlon/src/urbit/fetch.ts
354
- async function urbitFetch(params) {
355
- const validated = validateUrbitBaseUrl(params.baseUrl);
356
- if (!validated.ok) throw new UrbitUrlError(validated.error);
357
- return await fetchWithSsrFGuard({
358
- url: new URL(params.path, validated.baseUrl).toString(),
359
- fetchImpl: params.fetchImpl,
360
- init: params.init,
361
- timeoutMs: params.timeoutMs,
362
- maxRedirects: params.maxRedirects,
363
- signal: params.signal,
364
- policy: params.ssrfPolicy,
365
- lookupFn: params.lookupFn,
366
- auditContext: params.auditContext,
367
- pinDns: params.pinDns
368
- });
369
- }
370
- //#endregion
371
- //#region extensions/tlon/src/urbit/auth.ts
372
- async function authenticate(url, code, options = {}) {
373
- const { response, release } = await urbitFetch({
374
- baseUrl: url,
375
- path: "/~/login",
376
- init: {
377
- method: "POST",
378
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
379
- body: new URLSearchParams({ password: code }).toString()
380
- },
381
- ssrfPolicy: options.ssrfPolicy,
382
- lookupFn: options.lookupFn,
383
- fetchImpl: options.fetchImpl,
384
- timeoutMs: options.timeoutMs ?? 15e3,
385
- maxRedirects: 3,
386
- auditContext: "tlon-urbit-login"
387
- });
388
- try {
389
- if (!response.ok) throw new UrbitAuthError("auth_failed", `Login failed with status ${response.status}`);
390
- await response.text().catch(() => {});
391
- const cookie = response.headers.get("set-cookie");
392
- if (!cookie) throw new UrbitAuthError("missing_cookie", "No authentication cookie received");
393
- return cookie;
394
- } finally {
395
- await release();
396
- }
397
- }
398
- //#endregion
399
- //#region extensions/tlon/src/urbit/context.ts
400
- function resolveShipFromHostname(hostname) {
401
- const trimmed = hostname.trim().toLowerCase().replace(/\.$/, "");
402
- if (!trimmed) return "";
403
- if (trimmed.includes(".")) return trimmed.split(".")[0] ?? trimmed;
404
- return trimmed;
405
- }
406
- function normalizeUrbitShip(ship, hostname) {
407
- return (ship?.replace(/^~/, "") ?? resolveShipFromHostname(hostname)).trim();
408
- }
409
- function normalizeUrbitCookie(cookie) {
410
- return cookie.split(";")[0] ?? cookie;
411
- }
412
- function getUrbitContext(url, ship) {
413
- const validated = validateUrbitBaseUrl(url);
414
- if (!validated.ok) throw new UrbitUrlError(validated.error);
415
- return {
416
- baseUrl: validated.baseUrl,
417
- hostname: validated.hostname,
418
- ship: normalizeUrbitShip(ship, validated.hostname)
419
- };
420
- }
421
- function ssrfPolicyFromAllowPrivateNetwork(allowPrivateNetwork) {
422
- return allowPrivateNetwork ? { allowPrivateNetwork: true } : void 0;
423
- }
424
- /**
425
- * Get the default SSRF policy for image uploads.
426
- * Uses a restrictive policy that blocks private networks by default.
427
- */
428
- function getDefaultSsrFPolicy() {}
429
- //#endregion
430
- //#region node_modules/.pnpm/@urbit+aura@3.0.0/node_modules/@urbit/aura/dist/aura.cjs.production.min.js
431
- var require_aura_cjs_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
432
- function n(n) {
433
- let t = !0, [e, r, u] = n.split("..");
434
- r = r || "0.0.0", u = u || "0000";
435
- let [s, c, l] = e.slice(1).split(".");
436
- "-" === s.at(-1) && (s = s.slice(0, -1), t = !1);
437
- const [d, p, g] = r.split("."), h = u.split(".").map(((n) => BigInt("0x" + n)));
438
- return function(n) {
439
- const t = n.pos ? a + BigInt(n.year) : a - (BigInt(n.year) - 1n), e = (() => {
440
- let e = i(t) ? f : o, r = n.time.day - 1n, a = n.month - 1n;
441
- for (; 0n !== a;) {
442
- const [n, ...t] = e;
443
- r += BigInt(n), a -= 1n, e = t;
444
- }
445
- let u = !0, s = t;
446
- for (; 1 == u;) s % 4n !== 0n ? (s -= 1n, r += i(s) ? 366n : 365n) : s % 100n !== 0n ? (s -= 4n, r += i(s) ? 1461n : 1460n) : s % 400n !== 0n ? (s -= 100n, r += i(s) ? 36525n : 36524n) : (r += s / 400n * (4n * 36524n + 1n), u = !1);
447
- return r;
448
- })();
449
- return n.time.day = e, m(n.time);
450
- }({
451
- pos: t,
452
- year: BigInt(s),
453
- month: BigInt(c),
454
- time: {
455
- day: BigInt(l),
456
- hour: BigInt(d),
457
- minute: BigInt(p),
458
- second: BigInt(g),
459
- ms: h
460
- }
461
- });
462
- }
463
- function t(n) {
464
- const t = {
465
- day: 0n,
466
- hour: 0n,
467
- minute: 0n,
468
- second: 0n,
469
- ms: []
470
- };
471
- n = n.slice(1);
472
- let [e, r] = n.split("..");
473
- return r = r || "0000", t.ms = r.split(".").map(((n) => BigInt("0x" + n))), e.split(".").forEach(((e) => {
474
- switch (e[0]) {
475
- case "d":
476
- t.day += BigInt(e.slice(1));
477
- break;
478
- case "h":
479
- t.hour += BigInt(e.slice(1));
480
- break;
481
- case "m":
482
- t.minute += BigInt(e.slice(1));
483
- break;
484
- case "s":
485
- t.second += BigInt(e.slice(1));
486
- break;
487
- default: throw new Error("bad dr: " + n);
488
- }
489
- })), r = r || "0000", m(t);
490
- }
491
- Object.defineProperty(exports, "__esModule", { value: !0 });
492
- const e = BigInt("170141184475152167957503069145530368000"), r = BigInt("18446744073709551616"), a = BigInt("292277024400");
493
- function i(n) {
494
- return n % 4n === 0n && n % 100n !== 0n || n % 400n === 0n;
495
- }
496
- const o = [
497
- 31,
498
- 28,
499
- 31,
500
- 30,
501
- 31,
502
- 30,
503
- 31,
504
- 31,
505
- 30,
506
- 31,
507
- 30,
508
- 31
509
- ], f = [
510
- 31,
511
- 29,
512
- 31,
513
- 30,
514
- 31,
515
- 30,
516
- 31,
517
- 31,
518
- 30,
519
- 31,
520
- 30,
521
- 31
522
- ], u = 86400n, s = 3600n, c = 60n, l = 146097n, d = 36524n;
523
- function m(n) {
524
- let t = n.second + u * n.day + s * n.hour + c * n.minute, e = n.ms, r = 0n, a = 3n;
525
- for (; 0 !== e.length;) {
526
- const [n, ...t] = e;
527
- r += n << 16n * a, e = t, a -= 1n;
528
- }
529
- return r | t << 64n;
530
- }
531
- function p(n) {
532
- let t = n >> 64n;
533
- const e = (BigInt("0xffffffffffffffff") & n).toString(16).padStart(16, "0").match(/.{4}/g).map(((n) => BigInt("0x" + n)));
534
- for (; 0n === e.at(-1);) e.pop();
535
- let r = t / u;
536
- t %= u;
537
- let a = t / s;
538
- t %= s;
539
- let i = t / c;
540
- return t %= c, {
541
- ms: e,
542
- day: r,
543
- minute: i,
544
- hour: a,
545
- second: t
546
- };
547
- }
548
- const g = (n, t) => ((n, t) => {
549
- const e = Number(255n & t), r = Number((65280n & t) / 256n), a = String.fromCharCode(e) + String.fromCharCode(r);
550
- return BigInt(((n, t) => {
551
- let e, r, a, i, o, f, u, s;
552
- for (e = 3 & n.length, r = n.length - e, a = t, o = 3432918353, f = 461845907, s = 0; s < r;) u = 255 & n.charCodeAt(s) | (255 & n.charCodeAt(++s)) << 8 | (255 & n.charCodeAt(++s)) << 16 | (255 & n.charCodeAt(++s)) << 24, ++s, u = (65535 & u) * o + (((u >>> 16) * o & 65535) << 16) & 4294967295, u = u << 15 | u >>> 17, u = (65535 & u) * f + (((u >>> 16) * f & 65535) << 16) & 4294967295, a ^= u, a = a << 13 | a >>> 19, i = 5 * (65535 & a) + ((5 * (a >>> 16) & 65535) << 16) & 4294967295, a = 27492 + (65535 & i) + ((58964 + (i >>> 16) & 65535) << 16);
553
- switch (u = 0, e) {
554
- case 3: u ^= (255 & n.charCodeAt(s + 2)) << 16;
555
- case 2: u ^= (255 & n.charCodeAt(s + 1)) << 8;
556
- case 1: u ^= 255 & n.charCodeAt(s), u = (65535 & u) * o + (((u >>> 16) * o & 65535) << 16) & 4294967295, u = u << 15 | u >>> 17, u = (65535 & u) * f + (((u >>> 16) * f & 65535) << 16) & 4294967295, a ^= u;
557
- }
558
- return a ^= n.length, a ^= a >>> 16, a = 2246822507 * (65535 & a) + ((2246822507 * (a >>> 16) & 65535) << 16) & 4294967295, a ^= a >>> 13, a = 3266489909 * (65535 & a) + ((3266489909 * (a >>> 16) & 65535) << 16) & 4294967295, a ^= a >>> 16, a >>> 0;
559
- })(a, n));
560
- })([
561
- 3077398253,
562
- 3995603712,
563
- 2243735041,
564
- 1261992695
565
- ][n], t), h = (n) => y(4, 65535n, 65536n, 4294967295n, g, n), y = (n, t, e, r, a, i) => {
566
- const o = b(n, t, e, a, i);
567
- return o < r ? o : b(n, t, e, a, o);
568
- }, b = (n, t, e, r, a) => {
569
- const i = (a, o, f) => {
570
- if (a > n) return n % 2 != 0 || f === t ? t * f + o : t * o + f;
571
- {
572
- const n = BigInt(r(a - 1, f).toString());
573
- return i(a + 1, f, a % 2 != 0 ? (o + n) % t : (o + n) % e);
574
- }
575
- };
576
- return i(1, a % t, a / t);
577
- }, x = (n) => w(4, 65535n, 65536n, 4294967295n, g, n), w = (n, t, e, r, a, i) => {
578
- const o = B(n, t, e, a, i);
579
- return o < r ? o : B(n, t, e, a, o);
580
- }, B = (n, t, e, r, a) => {
581
- const i = (n, a, o) => {
582
- if (n < 1) return t * o + a;
583
- {
584
- const f = r(n - 1, a);
585
- return i(n - 1, n % 2 != 0 ? (o + t - f % t) % t : (o + e - f % e) % e, a);
586
- }
587
- }, o = n % 2 != 0 ? a / t : a % t, f = n % 2 != 0 ? a % t : a / t;
588
- return i(n, f === t ? o : f, f === t ? f : o);
589
- };
590
- var I = {
591
- F: g,
592
- fe: b,
593
- Fe: y,
594
- feis: h,
595
- fein: (n) => {
596
- const t = (n) => {
597
- const e = 4294967295n & n, r = 18446744069414584320n & n;
598
- return n >= 65536n && n <= 4294967295n ? 65536n + h(n - 65536n) : n >= 4294967296n && n <= 18446744073709551615n ? r | t(e) : n;
599
- };
600
- return t(n);
601
- },
602
- fen: B,
603
- Fen: w,
604
- tail: x,
605
- fynd: (n) => {
606
- const t = (n) => {
607
- const e = 4294967295n & n, r = 18446744069414584320n & n;
608
- return n >= 65536n && n <= 4294967295n ? 65536n + x(n - 65536n) : n >= 4294967296n && n <= 18446744073709551615n ? r | t(e) : n;
609
- };
610
- return t(BigInt(n));
611
- }
612
- };
613
- const v = /^~([a-z]{3}|([a-z]{6}(\-[a-z]{6}){0,3}(\-(\-[a-z]{6}){4})*))$/;
614
- function S(n) {
615
- const t = N(n), e = (n) => n.toString(2).padStart(8, "0"), r = t.reduce(((n, r, a) => a % 2 != 0 || 1 === t.length ? n + e(E.indexOf(r)) : n + e(C.indexOf(r))), ""), a = BigInt("0b" + r);
616
- return I.fynd(a);
617
- }
618
- function $(n) {
619
- const t = I.fein(n), e = Math.ceil(t.toString(16).length / 2), r = Math.ceil(t.toString(16).length / 4);
620
- return "~" + (e <= 1 ? E[Number(t)] : function n(t, e, a) {
621
- const i = 65535n & t, o = C[Number(i >> 8n)], f = E[Number(255n & i)];
622
- return e === r ? a : n(t >> 16n, e + 1, o + f + (3 & e ? "-" : 0 === e ? "" : "--") + a);
623
- }(t, 0, ""));
624
- }
625
- function A(n) {
626
- let t;
627
- return t = "bigint" == typeof n ? n : z(n), t <= 255n ? "czar" : t <= 65535n ? "king" : t <= 4294967295n ? "duke" : t <= 18446744073709551615n ? "earl" : "pawn";
628
- }
629
- function k(n) {
630
- switch (n) {
631
- case "czar": return "galaxy";
632
- case "king": return "star";
633
- case "duke": return "planet";
634
- case "earl": return "moon";
635
- case "pawn": return "comet";
636
- }
637
- }
638
- function z(n) {
639
- if (!function(n) {
640
- return v.test(n) && j(n) && n === $(S(n));
641
- }(n)) throw new Error("invalid @p literal: " + n);
642
- return S(n);
643
- }
644
- const C = "\ndozmarbinwansamlitsighidfidlissogdirwacsabwissibrigsoldopmodfoglidhopdardorlorhodfolrintogsilmirholpaslacrovlivdalsatlibtabhanticpidtorbolfosdotlosdilforpilramtirwintadbicdifrocwidbisdasmidloprilnardapmolsanlocnovsitnidtipsicropwitnatpanminritpodmottamtolsavposnapnopsomfinfonbanmorworsipronnorbotwicsocwatdolmagpicdavbidbaltimtasmalligsivtagpadsaldivdactansidfabtarmonranniswolmispallasdismaprabtobrollatlonnodnavfignomnibpagsopralbilhaddocridmocpacravripfaltodtiltinhapmicfanpattaclabmogsimsonpinlomrictapfirhasbosbatpochactidhavsaplindibhosdabbitbarracparloddosbortochilmactomdigfilfasmithobharmighinradmashalraglagfadtopmophabnilnosmilfopfamdatnoldinhatnacrisfotribhocnimlarfitwalrapsarnalmoslandondanladdovrivbacpollaptalpitnambonrostonfodponsovnocsorlavmatmipfip".match(/.{1,3}/g), E = "\nzodnecbudwessevpersutletfulpensytdurwepserwylsunrypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnexlunmeplutseppesdelsulpedtemledtulmetwenbynhexfebpyldulhetmevruttylwydtepbesdexsefwycburderneppurrysrebdennutsubpetrulsynregtydsupsemwynrecmegnetsecmulnymtevwebsummutnyxrextebfushepbenmuswyxsymselrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpelsyptermebsetdutdegtexsurfeltudnuxruxrenwytnubmedlytdusnebrumtynseglyxpunresredfunrevrefmectedrusbexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermertenlusnussyltecmexpubrymtucfyllepdebbermughuttunbylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmylwedducfurfexnulluclennerlexrupnedlecrydlydfenwelnydhusrelrudneshesfetdesretdunlernyrsebhulrylludremlysfynwerrycsugnysnyllyndyndemluxfedsedbecmunlyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes".match(/.{1,3}/g);
645
- function N(n) {
646
- return n.replace(/[\^~-]/g, "").match(/.{1,3}/g) || [];
647
- }
648
- function j(n) {
649
- const t = N(n);
650
- return !(t.length % 2 != 0 && 1 !== t.length) && t.every(((n, e) => e % 2 != 0 || 1 === t.length ? E.includes(n) : C.includes(n)));
651
- }
652
- function _(n, t) {
653
- let e = [], r = [e];
654
- for (let a = 0; a < n.length; a++) e.length < t ? e.push(n[a]) : (e = [n[a]], r.push(e));
655
- return r;
656
- }
657
- function q(n, t) {
658
- return n = M(n), function(n, t, e) {
659
- if ("nan" === n) return function(n, t) {
660
- return O(BigInt(n + 1)) << BigInt(t - 1);
661
- }(t, e);
662
- if ("inf" === n) return U(!0, t, e);
663
- if ("-inf" === n) return U(!1, t, e);
664
- let r = 0, a = !0;
665
- "-" === n[r] && (a = !1, r++);
666
- let i = "";
667
- for (; "." !== n[r] && "e" !== n[r] && void 0 !== n[r];) i += n[r++];
668
- "." === n[r] && r++;
669
- let o = "";
670
- for (; "e" !== n[r] && void 0 !== n[r];) o += n[r++];
671
- "e" === n[r] && r++;
672
- let f = !0;
673
- "-" === n[r] && (f = !1, r++);
674
- let u = "";
675
- for (; void 0 !== n[r];) u += n[r++];
676
- return BigInt("0b" + function(n, t, e, r, a, i, o) {
677
- return 0 !== o && (i ? (r += a.padEnd(o, "0").slice(0, o), a = a.slice(o)) : (a = r.padStart(o, "0").slice(-o) + a, r = r.slice(0, -o))), function(n, t, e, r, a, i) {
678
- function o(n) {
679
- return console.warn(n), 1;
680
- }
681
- const f = 2 ** (t - 1) - 1, u = 1 - f, s = f, c = u - n, l = 2 * f + 1 + n + 3, d = new Array(l), m = 10n ** a;
682
- var p, g, h, y, b, x, w = 0, B = !e;
683
- for (p = l; p; d[--p] = 0);
684
- for (p = f + 2; r && p; d[--p] = 1n & r, r >>= 1n);
685
- for (p = f + 1; i > 0n && p < l; (d[++p] = (i *= 2n) >= m ? 1 : 0) && (i -= m));
686
- for (p = -1; ++p < l && !d[p];);
687
- if (d[(g = n - 1 + (p = (w = f + 1 - p) >= u && w <= s ? p + 1 : f + 1 - (w = u - 1))) + 1]) {
688
- if (!(h = d[g])) for (y = g + 2; !h && y < l; h = d[y++]);
689
- for (y = g + 1; h && --y >= 0; (d[y] = (d[y] ? 0 : 1) - 0) && (h = 0));
690
- }
691
- for (p = p - 2 < 0 ? -1 : p - 3; ++p < l && !d[p];);
692
- for ((w = f + 1 - p) >= u && w <= s ? ++p : w < u && (w != f + 1 - l && w < c && o("r.construct underflow"), p = f + 1 - (w = u - 1)), r && (o(r ? "r.construct overflow" : "r.construct"), w = s + 1, p = f + 2), x = Math.abs(w + f), y = t + 1, b = ""; --y; b = (1 & x) + b, x = x >>= 1);
693
- return (B ? "1" : "0") + b + d.slice(p, p + n).join("");
694
- }(t, n, e, BigInt(r), BigInt(a.length), BigInt(a));
695
- }(t, e, a, i, o, f, Number(u)));
696
- }(t.slice(n.l.length), n.w, n.p);
697
- }
698
- function F(n, t) {
699
- return (n = M(n)).l + function(n) {
700
- if ("n" === n.t) return "nan";
701
- if ("i" === n.t) return n.s ? "inf" : "-inf";
702
- let t;
703
- return n.e - 4 > 0 || n.e + 2 < 0 ? t = 1 : (t = n.e + 1, n.e = 0), (n.s ? "" : "-") + function(n, t) {
704
- const e = Math.abs(n);
705
- if (n <= 0) return "0." + "".padEnd(e, "0") + t;
706
- {
707
- const n = t.length;
708
- return e >= n ? t + "".padEnd(e - n, "0") : t.slice(0, e) + "." + t.slice(e);
709
- }
710
- }(t, n.a) + (0 === n.e ? "" : "e" + n.e.toString());
711
- }(function(n, t, e) {
712
- const r = O(e), a = O(t), i = n & r, o = n >> BigInt(e) & a, f = 0n === (n >> BigInt(t + e) & 1n);
713
- let u, s, c, l;
714
- if (o === a) return 0n === i ? {
715
- t: "i",
716
- s: f
717
- } : { t: "n" };
718
- 0n !== o ? (u = 1n << BigInt(e) | i, s = o - (2n ** (t - 1n) - 1n) - e, c = Number(e), l = 1n !== o && 0n === i) : (u = i, s = 1n - (2n ** (t - 1n) - 1n) - e, c = u.toString(2).length - 1, l = !1);
719
- const d = (2n ** e).toString(10).length + 1, m = function(n, t, e, r, a, i, o) {
720
- const f = BigInt(t);
721
- let u, s, c, l, d = 0, m = new Array(o).fill("0"), p = 0;
722
- if (0n === n) return m[0] = "0", p = 0, {
723
- digits: m.slice(0, 1).join(""),
724
- outExponent: p
725
- };
726
- r ? t > 0 ? (s = 4n * n, s <<= f, u = 4n, c = 1n << f, l = 1n << f + 1n) : (s = 4n * n, u = 1n << -f + 2n, c = 1n, l = 2n) : t > 0 ? (s = 2n * n, s <<= f, u = 2n, c = 1n << f, l = c) : (s = 2n * n, u = 1n << BigInt(1 - t), c = 1n, l = c);
727
- let g = Math.ceil(.3010299956639812 * (e + t) - .69);
728
- if (g > 0) u *= BigInt(10) ** BigInt(g);
729
- else if (g < 0) {
730
- const n = BigInt(10) ** BigInt(-g);
731
- s *= n, c *= n, l !== c && (l *= c);
732
- }
733
- s >= u ? g += 1 : (s *= 10n, c *= 10n, l !== c && (l *= 10n));
734
- let h = g - o;
735
- p = g - 1;
736
- let y = !1, b = !1, x = 0;
737
- for (; g -= 1, x = Number(s / u), s %= u, y = s < c, b = s + l > u, !y && !b && g !== h;) m[d] = String.fromCharCode("0".charCodeAt(0) + x), d += 1, s *= 10n, c *= 10n, l !== c && (l *= 10n);
738
- let w = y;
739
- if (y === b) {
740
- s *= 2n;
741
- let n = s < u ? -1 : s > u ? 1 : 0;
742
- w = n < 0, 0 === n && (w = 0 == (1 & x));
743
- }
744
- if (w) m[d] = String.fromCharCode("0".charCodeAt(0) + x), d += 1;
745
- else if (9 === x) for (;;) {
746
- if (0 === d) {
747
- m[d] = "1", d += 1, p += 1;
748
- break;
749
- }
750
- if (d -= 1, "9" !== m[d]) {
751
- m[d] = String.fromCharCode(m[d].charCodeAt(0) + 1), d += 1;
752
- break;
753
- }
754
- }
755
- else m[d] = String.fromCharCode("0".charCodeAt(0) + x + 1), d += 1;
756
- return {
757
- digits: m.slice(0, d).join(""),
758
- outExponent: p
759
- };
760
- }(u, Number(s), c, l, 0, 0, d);
761
- return {
762
- t: "d",
763
- s: f,
764
- e: m.outExponent,
765
- a: m.digits
766
- };
767
- }(t, BigInt(n.w), BigInt(n.p)));
768
- }
769
- function M(n) {
770
- return "h" === n ? {
771
- w: 5,
772
- p: 10,
773
- l: ".~~"
774
- } : "s" === n ? {
775
- w: 8,
776
- p: 23,
777
- l: "."
778
- } : "d" === n ? {
779
- w: 11,
780
- p: 52,
781
- l: ".~"
782
- } : "q" === n ? {
783
- w: 15,
784
- p: 112,
785
- l: ".~~~"
786
- } : n;
787
- }
788
- function O(n) {
789
- return 2n ** n - 1n;
790
- }
791
- function U(n, t, e) {
792
- return O(BigInt(n ? t : t + 1)) << BigInt(e);
793
- }
794
- function Z(n, t, e, r, a) {
795
- return void 0 === a && (a = !1), new RegExp(`^${a ? "\\-\\-?" : ""}${n}(0|${0 === r ? t : `${t}${e}{0,${r - 1}}`}${0 === r ? `${e}*` : `(\\.${e}{${r}})*`})$`);
796
- }
797
- function P(n) {
798
- return new RegExp(`^\\.~{${n}}(nan|\\-?(inf|(0|[1-9][0-9]*)(\\.[0-9]+)?(e\\-?(0|[1-9][0-9]*))?))$`);
799
- }
800
- const R = {
801
- c: /^~\-((~[0-9a-fA-F]+\.)|(~[~\.])|[0-9a-z\-\._])*$/,
802
- da: /^~(0|[1-9][0-9]*)\-?\.0*([1-9]|1[0-2])\.0*[1-9][0-9]*(\.\.([0-9]+)\.([0-9]+)\.([0-9]+)(\.(\.[0-9a-f]{4})+)?)?$/,
803
- dr: /^~((d|h|m|s)(0|[1-9][0-9]*))(\.(d|h|m|s)(0|[1-9][0-9]*))*(\.(\.[0-9a-f]{4})+)?$/,
804
- f: /^\.(y|n)$/,
805
- if: /^(\.(0|[1-9][0-9]{0,2})){4}$/,
806
- is: /^(\.(0|[1-9a-fA-F][0-9a-fA-F]{0,3})){8}$/,
807
- n: /^~$/,
808
- p: v,
809
- q: /^\.~(([a-z]{3}|[a-z]{6})(\-[a-z]{6})*)$/,
810
- rd: P(1),
811
- rh: P(2),
812
- rq: P(3),
813
- rs: P(0),
814
- sb: Z("0b", "1", "[01]", 4, !0),
815
- sd: Z("", "[1-9]", "[0-9]", 3, !0),
816
- si: Z("0i", "[1-9]", "[0-9]", 0, !0),
817
- sv: Z("0v", "[1-9a-v]", "[0-9a-v]", 5, !0),
818
- sw: Z("0w", "[1-9a-zA-Z~-]", "[0-9a-zA-Z~-]", 5, !0),
819
- sx: Z("0x", "[1-9a-f]", "[0-9a-f]", 4, !0),
820
- t: /^~~((~[0-9a-fA-F]+\.)|(~[~\.])|[0-9a-z\-\._])*$/,
821
- ta: /^~\.[0-9a-z\-\.~_]*$/,
822
- tas: /^[a-z][a-z0-9\-]*$/,
823
- ub: Z("0b", "1", "[01]", 4),
824
- ud: Z("", "[1-9]", "[0-9]", 3),
825
- ui: Z("0i", "[1-9]", "[0-9]", 0),
826
- uv: Z("0v", "[1-9a-v]", "[0-9a-v]", 5),
827
- uw: Z("0w", "[1-9a-zA-Z~-]", "[0-9a-zA-Z~-]", 5),
828
- ux: Z("0x", "[1-9a-f]", "[0-9a-f]", 4)
829
- }, T = D;
830
- function D(n, t) {
831
- const e = H(n, t);
832
- if (!e) throw new Error("slav: failed to parse @" + n + " from string: " + t);
833
- return e;
834
- }
835
- const G = H;
836
- function H(n, t) {
837
- if (n in R && !R[n].test(t)) return null;
838
- const e = J(t);
839
- return e && "dime" === e.type && e.aura === n ? e.atom : null;
840
- }
841
- function J(e) {
842
- if ("" === e) return null;
843
- const r = e[0];
844
- if (r >= "a" && r <= "z") return R.tas.test(e) ? {
845
- type: "dime",
846
- aura: "tas",
847
- atom: Q(e)
848
- } : null;
849
- if (r >= "0" && r <= "9") {
850
- const n = K(e);
851
- return n ? {
852
- type: "dime",
853
- ...n
854
- } : null;
855
- }
856
- if ("-" === r) {
857
- let n = !0;
858
- "-" == e[1] ? e = e.slice(2) : (e = e.slice(1), n = !1);
859
- const t = K(e);
860
- return t ? (n ? t.atom = 2n * t.atom : 0n !== t.atom && (t.atom = 1n + 2n * (t.atom - 1n)), {
861
- type: "dime",
862
- aura: t.aura.replace("u", "s"),
863
- atom: t.atom
864
- }) : null;
865
- }
866
- if ("." === r) {
867
- if (".y" === e) return {
868
- type: "dime",
869
- aura: "f",
870
- atom: 0n
871
- };
872
- if (".n" === e) return {
873
- type: "dime",
874
- aura: "f",
875
- atom: 1n
876
- };
877
- if (R.is.test(e)) {
878
- const n = e.slice(1).split(".").reduce(((n, t) => n + t.padStart(4, "0")), "");
879
- return {
880
- type: "dime",
881
- aura: "is",
882
- atom: BigInt("0x" + n)
883
- };
884
- }
885
- if (R.if.test(e)) return {
886
- type: "dime",
887
- aura: "if",
888
- atom: e.slice(1).split(".").reduce(((n, t, e) => n + (BigInt(t) << BigInt(8 * (3 - e)))), 0n)
889
- };
890
- if ("~" === e[1] && (R.rd.test(e) || R.rh.test(e) || R.rq.test(e)) || R.rs.test(e)) {
891
- let n, t = 0;
892
- for (; "~" === e[t + 1];) t++;
893
- switch (t) {
894
- case 0:
895
- n = "rs";
896
- break;
897
- case 1:
898
- n = "rd";
899
- break;
900
- case 2:
901
- n = "rh";
902
- break;
903
- case 3:
904
- n = "rq";
905
- break;
906
- default: throw new Error("parsing invalid @r*");
907
- }
908
- return {
909
- type: "dime",
910
- aura: n,
911
- atom: q(n[1], e)
912
- };
913
- }
914
- if ("~" === e[1] && R.q.test(e)) {
915
- const n = function(n) {
916
- try {
917
- return function(n) {
918
- const t = n.slice(2).split("-"), e = (n) => {
919
- if (n < 0) throw new Error("malformed @q");
920
- return n.toString(16).padStart(2, "0");
921
- }, r = t.map(((n, t) => {
922
- let r = function(n, t) {
923
- return [t.slice(0, 3), t.slice(3)];
924
- }(0, n);
925
- return "" === r[1] && 0 === t ? e(E.indexOf(r[0])) : e(C.indexOf(r[0])) + e(E.indexOf(r[1]));
926
- }));
927
- return BigInt("0x" + (0 === n.length ? "00" : r.join("")));
928
- }(n);
929
- } catch (n) {
930
- return null;
931
- }
932
- }(e);
933
- return null === n ? null : {
934
- type: "dime",
935
- aura: "q",
936
- atom: n
937
- };
938
- }
939
- if ("_" === e[1] && /^\.(_([0-9a-zA-Z\-\.]|~\-|~~)+)*__$/.test(e)) {
940
- const n = e.slice(1, -2).split("_").slice(1).map(((n) => J(n = n.replaceAll("~-", "_").replaceAll("~~", "~"))));
941
- return n.some(((n) => null === n)) ? null : {
942
- type: "many",
943
- list: n
944
- };
945
- }
946
- return null;
947
- }
948
- if ("~" === r) {
949
- if ("~" === e) return {
950
- type: "dime",
951
- aura: "n",
952
- atom: 0n
953
- };
954
- if (R.da.test(e)) return {
955
- type: "dime",
956
- aura: "da",
957
- atom: n(e)
958
- };
959
- if (R.dr.test(e)) return {
960
- type: "dime",
961
- aura: "dr",
962
- atom: t(e)
963
- };
964
- if (R.p.test(e)) {
965
- const n = function(n) {
966
- if (!v.test(n) || !j(n)) return null;
967
- const t = S(n);
968
- return n === $(t) ? t : null;
969
- }(e);
970
- return null === n ? null : {
971
- type: "dime",
972
- aura: "p",
973
- atom: n
974
- };
975
- }
976
- return "." === e[1] && R.ta.test(e) ? {
977
- type: "dime",
978
- aura: "ta",
979
- atom: Q(e.slice(2))
980
- } : "~" === e[1] && R.t.test(e) ? {
981
- type: "dime",
982
- aura: "t",
983
- atom: Q(L(e.slice(2)))
984
- } : "-" === e[1] && R.c.test(e) ? /^~\-~[0-9a-f]+\.$/.test(e) ? {
985
- type: "dime",
986
- aura: "c",
987
- atom: BigInt("0x" + e.slice(3, -1))
988
- } : {
989
- type: "dime",
990
- aura: "c",
991
- atom: Q(L(e.slice(2)))
992
- } : "0" === e[1] && /^~0[0-9a-v]+$/.test(e) ? {
993
- type: "blob",
994
- jam: X(5, W, e.slice(2))
995
- } : null;
996
- }
997
- return null;
998
- }
999
- function K(n) {
1000
- switch (n.slice(0, 2)) {
1001
- case "0b": return R.ub.test(n) ? {
1002
- aura: "ub",
1003
- atom: BigInt(n.replaceAll(".", ""))
1004
- } : null;
1005
- case "0c": return console.log("aura-js: @uc parsing unsupported (bisk)"), null;
1006
- case "0i": return R.ui.test(n) ? {
1007
- aura: "ui",
1008
- atom: BigInt(n.slice(2))
1009
- } : null;
1010
- case "0x": return R.ux.test(n) ? {
1011
- aura: "ux",
1012
- atom: BigInt(n.replaceAll(".", ""))
1013
- } : null;
1014
- case "0v": return R.uv.test(n) ? {
1015
- aura: "uv",
1016
- atom: X(5, W, n.slice(2))
1017
- } : null;
1018
- case "0w": return R.uw.test(n) ? {
1019
- aura: "uw",
1020
- atom: X(6, V, n.slice(2))
1021
- } : null;
1022
- default: return R.ud.test(n) ? {
1023
- aura: "ud",
1024
- atom: BigInt(n.replaceAll(".", ""))
1025
- } : null;
1026
- }
1027
- }
1028
- function L(n) {
1029
- let t = "", e = 0;
1030
- for (; e < n.length;) switch (n[e]) {
1031
- case ".":
1032
- t += " ", e++;
1033
- continue;
1034
- case "~": switch (n[++e]) {
1035
- case "~":
1036
- t += "~", e++;
1037
- continue;
1038
- case ".":
1039
- t += ".", e++;
1040
- continue;
1041
- default:
1042
- let r = 0;
1043
- do
1044
- r = r << 4 | Number.parseInt(n[e++], 16);
1045
- while ("." !== n[e]);
1046
- t += String.fromCodePoint(r), e++;
1047
- continue;
1048
- }
1049
- default:
1050
- t += n[e++];
1051
- continue;
1052
- }
1053
- return t;
1054
- }
1055
- function Q(n) {
1056
- return function(n) {
1057
- if (0 === n.length) return 0n;
1058
- if ("undefined" != typeof Buffer) return BigInt("0x" + Buffer.from(n.reverse()).toString("hex"));
1059
- let t, e = [];
1060
- for (var r = n.length - 1; r >= 0; --r) t = n[r], e.push(t < 16 ? "0" + t.toString(16) : t.toString(16));
1061
- return BigInt("0x" + e.join(""));
1062
- }(new TextEncoder().encode(n));
1063
- }
1064
- const V = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~", W = "0123456789abcdefghijklmnopqrstuv";
1065
- function X(n, t, e) {
1066
- let r = 0n;
1067
- const a = BigInt(n);
1068
- for (; "" !== e;) "." !== e[0] && (r = (r << a) + BigInt(t.indexOf(e[0]))), e = e.slice(1);
1069
- return r;
1070
- }
1071
- const Y = nn;
1072
- function nn(n, t) {
1073
- return tn({
1074
- type: "dime",
1075
- aura: n,
1076
- atom: t
1077
- });
1078
- }
1079
- function tn(n) {
1080
- switch (n.type) {
1081
- case "blob": return "~0" + n.jam.toString(32);
1082
- case "many": return "." + n.list.reduce(((n, t) => n + "_" + tn(t).replaceAll("~", "~~").replaceAll("_", "~-")), "") + "__";
1083
- case "dime": switch (n.aura[0]) {
1084
- case "c": return n.atom < 127n ? "~-" + rn(String.fromCharCode(Number(n.atom))) : "~-~" + n.atom.toString(16) + ".";
1085
- case "d": switch (n.aura[1]) {
1086
- case "a": return function(n) {
1087
- const { pos: t, year: e, month: r, time: i } = function(n) {
1088
- const t = p(n), [e, r, i] = function(n) {
1089
- let t = 0n, e = 0n, r = !1;
1090
- t = n / l, (n %= l) < d + 1n ? r = !0 : (r = !1, e = 1n, e += (n -= d + 1n) / d, n %= d);
1091
- let a = 400n * t + 100n * e, i = !0;
1092
- for (; 1 == i;) {
1093
- let t = r ? 366n : 365n;
1094
- if (n < t) {
1095
- i = !1;
1096
- let e = 0n;
1097
- for (;;) {
1098
- let t = BigInt((r ? f : o)[Number(e)]);
1099
- if (n < t) return [
1100
- a,
1101
- e + 1n,
1102
- n + 1n
1103
- ];
1104
- e += 1n, n -= t;
1105
- }
1106
- } else a += 1n, n -= t, r = a % 4n === 0n;
1107
- }
1108
- return [
1109
- 0n,
1110
- 0n,
1111
- 0n
1112
- ];
1113
- }(t.day);
1114
- t.day = i;
1115
- const u = e > a;
1116
- return {
1117
- pos: u,
1118
- year: u ? e - a : a + 1n - e,
1119
- month: r,
1120
- time: t
1121
- };
1122
- }(n);
1123
- let u = `~${e}${t ? "" : "-"}.${r}.${i.day}`;
1124
- return 0n === i.hour && 0n === i.minute && 0n === i.second && 0 === i.ms.length || (u += `..${i.hour.toString().padStart(2, "0")}.${i.minute.toString().padStart(2, "0")}.${i.second.toString().padStart(2, "0")}`, 0 !== i.ms.length && (u += `..${i.ms.map(((n) => n.toString(16).padStart(4, "0"))).join(".")}`)), u;
1125
- }(n.atom);
1126
- case "r": return function(n) {
1127
- if (0n === n) return "~s0";
1128
- const { day: t, hour: e, minute: r, second: a, ms: i } = p(n);
1129
- let o = [];
1130
- return 0n !== t && o.push("d" + t.toString()), 0n !== e && o.push("h" + e.toString()), 0n !== r && o.push("m" + r.toString()), 0n !== a && o.push("s" + a.toString()), 0 !== i.length && (0 === o.length && o.push("s0"), o.push("." + i.map(((n) => n.toString(16).padStart(4, "0"))).join("."))), "~" + o.join(".");
1131
- }(n.atom);
1132
- default: return en(n.atom);
1133
- }
1134
- case "f": switch (n.atom) {
1135
- case 0n: return ".y";
1136
- case 1n: return ".n";
1137
- default: return en(n.atom);
1138
- }
1139
- case "n": return "~";
1140
- case "i": switch (n.aura[1]) {
1141
- case "f": return "." + fn(n.atom, 1, 4, 10);
1142
- case "s": return "." + fn(n.atom, 2, 8, 16);
1143
- default: return en(n.atom);
1144
- }
1145
- case "p": return $(n.atom);
1146
- case "q": return function(n) {
1147
- const t = n.toString(16), e = t.length, r = Buffer.from(t.padStart(e + e % 2, "0"), "hex"), a = r.length % 2 != 0 && r.length > 1 ? [[r[0]]].concat(_(Array.from(r.slice(1)), 2)) : _(Array.from(r), 2);
1148
- return a.reduce(((n, t) => {
1149
- return n + (".~" === n ? "" : "-") + ((e = t).length % 2 != 0 && a.length > 1 ? void 0 === (r = e)[1] ? E[r[0]] : C[r[0]] + E[r[1]] : ((n) => void 0 === n[1] ? E[n[0]] : C[n[0]] + E[n[1]])(e));
1150
- var e, r;
1151
- }), ".~");
1152
- }(n.atom);
1153
- case "r": switch (n.aura[1]) {
1154
- case "d": return F("d", n.atom);
1155
- case "h": return F("h", n.atom);
1156
- case "q": return F("q", n.atom);
1157
- case "s": return F("s", n.atom);
1158
- default: return en(n.atom);
1159
- }
1160
- case "u": switch (n.aura[1]) {
1161
- case "c": throw new Error("aura-js: @uc rendering unsupported");
1162
- case "b": return "0b" + on(n.atom.toString(2), 4);
1163
- case "i": return "0i" + n.atom.toString(10).padStart(1, "0");
1164
- case "x": return "0x" + on(n.atom.toString(16), 4);
1165
- case "v": return "0v" + on(n.atom.toString(32), 5);
1166
- case "w": return "0w" + on(function(n, t, e) {
1167
- if (0n === e) return t[0];
1168
- let r = "";
1169
- const a = BigInt(6);
1170
- for (; 0n !== e;) r = t[Number(BigInt.asUintN(6, e))] + r, e >>= a;
1171
- return r;
1172
- }(0, an, n.atom), 5);
1173
- default: return on(n.atom.toString(10), 3);
1174
- }
1175
- case "s":
1176
- const t = 1n & n.atom;
1177
- return n.atom = t + (n.atom >> 1n), n.aura = n.aura.replace("s", "u"), (0n === t ? "--" : "-") + tn(n);
1178
- case "t": return "a" === n.aura[1] ? "s" === n.aura[2] ? un(n.atom) : "~." + un(n.atom) : "~~" + rn(un(n.atom));
1179
- default: return en(n.atom);
1180
- }
1181
- }
1182
- }
1183
- function en(n) {
1184
- return "0x" + function(n, t) {
1185
- return t.toString(16).padStart(1, "0");
1186
- }(0, n);
1187
- }
1188
- function rn(n) {
1189
- let t = "";
1190
- for (let e = 0; e < n.length; e += 1) {
1191
- const r = n[e];
1192
- let a = "";
1193
- switch (r) {
1194
- case " ":
1195
- a = ".";
1196
- break;
1197
- case ".":
1198
- a = "~.";
1199
- break;
1200
- case "~":
1201
- a = "~~";
1202
- break;
1203
- default: {
1204
- const t = n.codePointAt(e);
1205
- if (!t) break;
1206
- t > 65535 && (e += 1), a = t >= 97 && t <= 122 || t >= 48 && t <= 57 || "-" === r ? r : `~${t.toString(16)}.`;
1207
- }
1208
- }
1209
- t += a;
1210
- }
1211
- return t;
1212
- }
1213
- const an = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~";
1214
- function on(n, t) {
1215
- return n.replace(new RegExp(`(?=(?:.{${t}})+$)(?!^)`, "g"), ".");
1216
- }
1217
- function fn(n, t, e, r) {
1218
- void 0 === r && (r = 10);
1219
- let a = "";
1220
- const i = 8n * BigInt(t), o = (1n << i) - 1n;
1221
- for (; e-- > 0;) "" !== a && (a = "." + a), a = (n & o).toString(r) + a, n >>= i;
1222
- return a;
1223
- }
1224
- function un(n) {
1225
- return new TextDecoder("utf-8").decode(function(n) {
1226
- if (0n === n) return new Uint8Array(0);
1227
- const t = n.toString(16), e = t.length % 2 == 0 ? t : "0" + t, r = new Uint8Array(e.length / 2);
1228
- for (let n = 0; n < e.length; n += 2) {
1229
- const t = e.slice(n, n + 2), a = parseInt(t, 16) << 24 >> 24;
1230
- r[n / 2] = a;
1231
- }
1232
- return r;
1233
- }(n).reverse());
1234
- }
1235
- const sn = {
1236
- toSeconds: function(n) {
1237
- const { day: t, hour: e, minute: r, second: a } = p(n);
1238
- return 60n * (60n * (24n * t + e) + r) + a;
1239
- },
1240
- fromSeconds: function(n) {
1241
- return m({
1242
- day: 0n,
1243
- hour: 0n,
1244
- minute: 0n,
1245
- second: n,
1246
- ms: []
1247
- });
1248
- }
1249
- }, cn = {
1250
- cite: function(n) {
1251
- let t;
1252
- return t = "bigint" == typeof n ? n : z(n), t <= 4294967295n ? $(t) : t <= 18446744073709551615n ? $(4294967295n & t).replace("-", "^") : $(BigInt("0x" + t.toString(16).slice(0, 4))) + "_" + $(65535n & t).slice(1);
1253
- },
1254
- sein: function(n) {
1255
- let t;
1256
- t = "bigint" == typeof n ? n : z(n);
1257
- let e = A(t);
1258
- const r = "czar" === e ? t : "king" === e ? 255n & t : "duke" === e ? 65535n & t : "earl" === e ? 4294967295n & t : 65535n & t;
1259
- return "bigint" == typeof n ? r : $(r);
1260
- },
1261
- clan: A,
1262
- kind: function(n) {
1263
- return k(A(n));
1264
- },
1265
- rankToSize: k,
1266
- sizeToRank: function(n) {
1267
- switch (n) {
1268
- case "galaxy": return "czar";
1269
- case "star": return "king";
1270
- case "planet": return "duke";
1271
- case "moon": return "earl";
1272
- case "comet": return "pawn";
1273
- }
1274
- }
1275
- };
1276
- exports.da = {
1277
- toUnix: function(n) {
1278
- return Math.round(Number(1000n * (r / 2000n + (n - e)) / r));
1279
- },
1280
- fromUnix: function(n) {
1281
- return e + BigInt(n) * r / 1000n;
1282
- }
1283
- }, exports.dr = sn, exports.nuck = J, exports.p = cn, exports.parse = T, exports.rend = tn, exports.render = Y, exports.scot = nn, exports.slav = D, exports.slaw = H, exports.tryParse = G, exports.valid = function(n, t) {
1284
- return null !== H(n, t);
1285
- };
1286
- }));
1287
- //#endregion
1288
- //#region extensions/tlon/src/urbit/story.ts
1289
- var import_dist = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
1290
- module.exports = require_aura_cjs_production_min();
1291
- })))();
1292
- /**
1293
- * Parse inline markdown formatting (bold, italic, code, links, mentions)
1294
- */
1295
- function parseInlineMarkdown(text) {
1296
- const result = [];
1297
- let remaining = text;
1298
- while (remaining.length > 0) {
1299
- const shipMatch = remaining.match(/^(~[a-z][-a-z0-9]*)/);
1300
- if (shipMatch) {
1301
- result.push({ ship: shipMatch[1] });
1302
- remaining = remaining.slice(shipMatch[0].length);
1303
- continue;
1304
- }
1305
- const boldMatch = remaining.match(/^\*\*(.+?)\*\*|^__(.+?)__/);
1306
- if (boldMatch) {
1307
- const content = boldMatch[1] || boldMatch[2];
1308
- result.push({ bold: parseInlineMarkdown(content) });
1309
- remaining = remaining.slice(boldMatch[0].length);
1310
- continue;
1311
- }
1312
- const italicsMatch = remaining.match(/^\*([^*]+?)\*|^_([^_]+?)_(?![a-zA-Z0-9])/);
1313
- if (italicsMatch) {
1314
- const content = italicsMatch[1] || italicsMatch[2];
1315
- result.push({ italics: parseInlineMarkdown(content) });
1316
- remaining = remaining.slice(italicsMatch[0].length);
1317
- continue;
1318
- }
1319
- const strikeMatch = remaining.match(/^~~(.+?)~~/);
1320
- if (strikeMatch) {
1321
- result.push({ strike: parseInlineMarkdown(strikeMatch[1]) });
1322
- remaining = remaining.slice(strikeMatch[0].length);
1323
- continue;
1324
- }
1325
- const codeMatch = remaining.match(/^`([^`]+)`/);
1326
- if (codeMatch) {
1327
- result.push({ "inline-code": codeMatch[1] });
1328
- remaining = remaining.slice(codeMatch[0].length);
1329
- continue;
1330
- }
1331
- const linkMatch = remaining.match(/^\[([^\]]+)\]\(([^)]+)\)/);
1332
- if (linkMatch) {
1333
- result.push({ link: {
1334
- href: linkMatch[2],
1335
- content: linkMatch[1]
1336
- } });
1337
- remaining = remaining.slice(linkMatch[0].length);
1338
- continue;
1339
- }
1340
- const imageMatch = remaining.match(/^!\[([^\]]*)\]\(([^)]+)\)/);
1341
- if (imageMatch) {
1342
- result.push({ __image: {
1343
- src: imageMatch[2],
1344
- alt: imageMatch[1]
1345
- } });
1346
- remaining = remaining.slice(imageMatch[0].length);
1347
- continue;
1348
- }
1349
- const urlMatch = remaining.match(/^(https?:\/\/[^\s<>"\]]+)/);
1350
- if (urlMatch) {
1351
- result.push({ link: {
1352
- href: urlMatch[1],
1353
- content: urlMatch[1]
1354
- } });
1355
- remaining = remaining.slice(urlMatch[0].length);
1356
- continue;
1357
- }
1358
- const plainMatch = remaining.match(/^[^*_`~[#~\n:/]+/);
1359
- if (plainMatch) {
1360
- result.push(plainMatch[0]);
1361
- remaining = remaining.slice(plainMatch[0].length);
1362
- continue;
1363
- }
1364
- result.push(remaining[0]);
1365
- remaining = remaining.slice(1);
1366
- }
1367
- return mergeAdjacentStrings(result);
1368
- }
1369
- /**
1370
- * Merge adjacent string elements in an inline array
1371
- */
1372
- function mergeAdjacentStrings(inlines) {
1373
- const result = [];
1374
- for (const item of inlines) if (typeof item === "string" && typeof result[result.length - 1] === "string") result[result.length - 1] = result[result.length - 1] + item;
1375
- else result.push(item);
1376
- return result;
1377
- }
1378
- /**
1379
- * Create an image block
1380
- */
1381
- function createImageBlock(src, alt = "", height = 0, width = 0) {
1382
- return { block: { image: {
1383
- src,
1384
- height,
1385
- width,
1386
- alt
1387
- } } };
1388
- }
1389
- /**
1390
- * Check if URL looks like an image
1391
- */
1392
- function isImageUrl(url) {
1393
- return /\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)(\?.*)?$/i.test(url);
1394
- }
1395
- /**
1396
- * Process inlines and extract any image markers into blocks
1397
- */
1398
- function processInlinesForImages(inlines) {
1399
- const cleanInlines = [];
1400
- const imageBlocks = [];
1401
- for (const inline of inlines) if (typeof inline === "object" && "__image" in inline) {
1402
- const img = inline.__image;
1403
- imageBlocks.push(createImageBlock(img.src, img.alt));
1404
- } else cleanInlines.push(inline);
1405
- return {
1406
- inlines: cleanInlines,
1407
- imageBlocks
1408
- };
1409
- }
1410
- /**
1411
- * Convert markdown text to Tlon story format
1412
- */
1413
- function markdownToStory(markdown) {
1414
- const story = [];
1415
- const lines = markdown.split("\n");
1416
- let i = 0;
1417
- while (i < lines.length) {
1418
- const line = lines[i];
1419
- if (line.startsWith("```")) {
1420
- const lang = line.slice(3).trim() || "plaintext";
1421
- const codeLines = [];
1422
- i++;
1423
- while (i < lines.length && !lines[i].startsWith("```")) {
1424
- codeLines.push(lines[i]);
1425
- i++;
1426
- }
1427
- story.push({ block: { code: {
1428
- code: codeLines.join("\n"),
1429
- lang
1430
- } } });
1431
- i++;
1432
- continue;
1433
- }
1434
- const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
1435
- if (headerMatch) {
1436
- const tag = `h${headerMatch[1].length}`;
1437
- story.push({ block: { header: {
1438
- tag,
1439
- content: parseInlineMarkdown(headerMatch[2])
1440
- } } });
1441
- i++;
1442
- continue;
1443
- }
1444
- if (/^(-{3,}|\*{3,})$/.test(line.trim())) {
1445
- story.push({ block: { rule: null } });
1446
- i++;
1447
- continue;
1448
- }
1449
- if (line.startsWith("> ")) {
1450
- const quoteLines = [];
1451
- while (i < lines.length && lines[i].startsWith("> ")) {
1452
- quoteLines.push(lines[i].slice(2));
1453
- i++;
1454
- }
1455
- const quoteText = quoteLines.join("\n");
1456
- story.push({ inline: [{ blockquote: parseInlineMarkdown(quoteText) }] });
1457
- continue;
1458
- }
1459
- if (line.trim() === "") {
1460
- i++;
1461
- continue;
1462
- }
1463
- const paragraphLines = [];
1464
- while (i < lines.length && lines[i].trim() !== "" && !lines[i].startsWith("#") && !lines[i].startsWith("```") && !lines[i].startsWith("> ") && !/^(-{3,}|\*{3,})$/.test(lines[i].trim())) {
1465
- paragraphLines.push(lines[i]);
1466
- i++;
1467
- }
1468
- if (paragraphLines.length > 0) {
1469
- const inlines = parseInlineMarkdown(paragraphLines.join("\n"));
1470
- const withBreaks = [];
1471
- for (const inline of inlines) if (typeof inline === "string" && inline.includes("\n")) {
1472
- const parts = inline.split("\n");
1473
- for (let j = 0; j < parts.length; j++) {
1474
- if (parts[j]) withBreaks.push(parts[j]);
1475
- if (j < parts.length - 1) withBreaks.push({ break: null });
1476
- }
1477
- } else withBreaks.push(inline);
1478
- const { inlines: cleanInlines, imageBlocks } = processInlinesForImages(withBreaks);
1479
- if (cleanInlines.length > 0) story.push({ inline: cleanInlines });
1480
- story.push(...imageBlocks);
1481
- }
1482
- }
1483
- return story;
1484
- }
1485
- //#endregion
1486
- //#region extensions/tlon/src/urbit/send.ts
1487
- async function sendDm({ api, fromShip, toShip, text }) {
1488
- return sendDmWithStory({
1489
- api,
1490
- fromShip,
1491
- toShip,
1492
- story: markdownToStory(text)
1493
- });
1494
- }
1495
- async function sendDmWithStory({ api, fromShip, toShip, story }) {
1496
- const sentAt = Date.now();
1497
- const id = `${fromShip}/${(0, import_dist.scot)("ud", import_dist.da.fromUnix(sentAt))}`;
1498
- const action = {
1499
- ship: toShip,
1500
- diff: {
1501
- id,
1502
- delta: { add: {
1503
- memo: {
1504
- content: story,
1505
- author: fromShip,
1506
- sent: sentAt
1507
- },
1508
- kind: null,
1509
- time: null
1510
- } }
1511
- }
1512
- };
1513
- await api.poke({
1514
- app: "chat",
1515
- mark: "chat-dm-action",
1516
- json: action
1517
- });
1518
- return {
1519
- channel: "tlon",
1520
- messageId: id
1521
- };
1522
- }
1523
- async function sendGroupMessage({ api, fromShip, hostShip, channelName, text, replyToId }) {
1524
- return sendGroupMessageWithStory({
1525
- api,
1526
- fromShip,
1527
- hostShip,
1528
- channelName,
1529
- story: markdownToStory(text),
1530
- replyToId
1531
- });
1532
- }
1533
- async function sendGroupMessageWithStory({ api, fromShip, hostShip, channelName, story, replyToId }) {
1534
- const sentAt = Date.now();
1535
- let formattedReplyId = replyToId;
1536
- if (replyToId && /^\d+$/.test(replyToId)) try {
1537
- formattedReplyId = (0, import_dist.scot)("ud", BigInt(replyToId));
1538
- } catch {}
1539
- const action = { channel: {
1540
- nest: `chat/${hostShip}/${channelName}`,
1541
- action: formattedReplyId ? { post: { reply: {
1542
- id: formattedReplyId,
1543
- action: { add: {
1544
- content: story,
1545
- author: fromShip,
1546
- sent: sentAt
1547
- } }
1548
- } } } : { post: { add: {
1549
- content: story,
1550
- author: fromShip,
1551
- sent: sentAt,
1552
- kind: "/chat",
1553
- blob: null,
1554
- meta: null
1555
- } } }
1556
- } };
1557
- await api.poke({
1558
- app: "channels",
1559
- mark: "channel-action-1",
1560
- json: action
1561
- });
1562
- return {
1563
- channel: "tlon",
1564
- messageId: `${fromShip}/${sentAt}`
1565
- };
1566
- }
1567
- /**
1568
- * Build a story with text and optional media (image)
1569
- */
1570
- function buildMediaStory(text, mediaUrl) {
1571
- const story = [];
1572
- const cleanText = text?.trim() ?? "";
1573
- const cleanUrl = mediaUrl?.trim() ?? "";
1574
- if (cleanText) story.push(...markdownToStory(cleanText));
1575
- if (cleanUrl && isImageUrl(cleanUrl)) story.push(createImageBlock(cleanUrl, ""));
1576
- else if (cleanUrl) story.push({ inline: [{ link: {
1577
- href: cleanUrl,
1578
- content: cleanUrl
1579
- } }] });
1580
- return story.length > 0 ? story : [{ inline: [""] }];
1581
- }
1582
- //#endregion
1583
- //#region extensions/tlon/src/urbit/channel-ops.ts
1584
- async function putUrbitChannel(deps, params) {
1585
- return await urbitFetch({
1586
- baseUrl: deps.baseUrl,
1587
- path: `/~/channel/${deps.channelId}`,
1588
- init: {
1589
- method: "PUT",
1590
- headers: {
1591
- "Content-Type": "application/json",
1592
- Cookie: deps.cookie
1593
- },
1594
- body: JSON.stringify(params.body)
1595
- },
1596
- ssrfPolicy: deps.ssrfPolicy,
1597
- lookupFn: deps.lookupFn,
1598
- fetchImpl: deps.fetchImpl,
1599
- timeoutMs: 3e4,
1600
- auditContext: params.auditContext
1601
- });
1602
- }
1603
- async function pokeUrbitChannel(deps, params) {
1604
- const pokeId = Date.now();
1605
- const { response, release } = await putUrbitChannel(deps, {
1606
- body: [{
1607
- id: pokeId,
1608
- action: "poke",
1609
- ship: deps.ship,
1610
- app: params.app,
1611
- mark: params.mark,
1612
- json: params.json
1613
- }],
1614
- auditContext: params.auditContext
1615
- });
1616
- try {
1617
- if (!response.ok && response.status !== 204) {
1618
- const errorText = await response.text().catch(() => "");
1619
- throw new Error(`Poke failed: ${response.status}${errorText ? ` - ${errorText}` : ""}`);
1620
- }
1621
- return pokeId;
1622
- } finally {
1623
- await release();
1624
- }
1625
- }
1626
- async function scryUrbitPath(deps, params) {
1627
- const scryPath = `/~/scry${params.path}`;
1628
- const { response, release } = await urbitFetch({
1629
- baseUrl: deps.baseUrl,
1630
- path: scryPath,
1631
- init: {
1632
- method: "GET",
1633
- headers: { Cookie: deps.cookie }
1634
- },
1635
- ssrfPolicy: deps.ssrfPolicy,
1636
- lookupFn: deps.lookupFn,
1637
- fetchImpl: deps.fetchImpl,
1638
- timeoutMs: 3e4,
1639
- auditContext: params.auditContext
1640
- });
1641
- try {
1642
- if (!response.ok) throw new Error(`Scry failed: ${response.status} for path ${params.path}`);
1643
- return await response.json();
1644
- } finally {
1645
- await release();
1646
- }
1647
- }
1648
- async function createUrbitChannel(deps, params) {
1649
- const { response, release } = await putUrbitChannel(deps, params);
1650
- try {
1651
- if (!response.ok && response.status !== 204) throw new UrbitHttpError({
1652
- operation: "Channel creation",
1653
- status: response.status
1654
- });
1655
- } finally {
1656
- await release();
1657
- }
1658
- }
1659
- async function wakeUrbitChannel(deps) {
1660
- const { response, release } = await putUrbitChannel(deps, {
1661
- body: [{
1662
- id: Date.now(),
1663
- action: "poke",
1664
- ship: deps.ship,
1665
- app: "hood",
1666
- mark: "helm-hi",
1667
- json: "Opening API channel"
1668
- }],
1669
- auditContext: "tlon-urbit-channel-wake"
1670
- });
1671
- try {
1672
- if (!response.ok && response.status !== 204) throw new UrbitHttpError({
1673
- operation: "Channel activation",
1674
- status: response.status
1675
- });
1676
- } finally {
1677
- await release();
1678
- }
1679
- }
1680
- async function ensureUrbitChannelOpen(deps, params) {
1681
- await createUrbitChannel(deps, {
1682
- body: params.createBody,
1683
- auditContext: params.createAuditContext
1684
- });
1685
- await wakeUrbitChannel(deps);
1686
- }
1687
- //#endregion
1688
- //#region extensions/tlon/src/urbit/sse-client.ts
1689
- var UrbitSSEClient = class {
1690
- constructor(url, cookie, options = {}) {
1691
- this.subscriptions = [];
1692
- this.eventHandlers = /* @__PURE__ */ new Map();
1693
- this.aborted = false;
1694
- this.streamController = null;
1695
- this.reconnectAttempts = 0;
1696
- this.isConnected = false;
1697
- this.streamRelease = null;
1698
- this.lastHeardEventId = -1;
1699
- this.lastAcknowledgedEventId = -1;
1700
- this.ackThreshold = 20;
1701
- const ctx = getUrbitContext(url, options.ship);
1702
- this.url = ctx.baseUrl;
1703
- this.cookie = normalizeUrbitCookie(cookie);
1704
- this.ship = ctx.ship;
1705
- this.channelId = `${Math.floor(Date.now() / 1e3)}-${randomUUID()}`;
1706
- this.channelUrl = new URL(`/~/channel/${this.channelId}`, this.url).toString();
1707
- this.onReconnect = options.onReconnect ?? null;
1708
- this.autoReconnect = options.autoReconnect !== false;
1709
- this.maxReconnectAttempts = options.maxReconnectAttempts ?? 10;
1710
- this.reconnectDelay = options.reconnectDelay ?? 1e3;
1711
- this.maxReconnectDelay = options.maxReconnectDelay ?? 3e4;
1712
- this.logger = options.logger ?? {};
1713
- this.ssrfPolicy = options.ssrfPolicy;
1714
- this.lookupFn = options.lookupFn;
1715
- this.fetchImpl = options.fetchImpl;
1716
- }
1717
- async subscribe(params) {
1718
- const subId = this.subscriptions.length + 1;
1719
- const subscription = {
1720
- id: subId,
1721
- action: "subscribe",
1722
- ship: this.ship,
1723
- app: params.app,
1724
- path: params.path
1725
- };
1726
- this.subscriptions.push(subscription);
1727
- this.eventHandlers.set(subId, {
1728
- event: params.event,
1729
- err: params.err,
1730
- quit: params.quit
1731
- });
1732
- if (this.isConnected) try {
1733
- await this.sendSubscription(subscription);
1734
- } catch (error) {
1735
- this.eventHandlers.get(subId)?.err?.(error);
1736
- }
1737
- return subId;
1738
- }
1739
- async sendSubscription(subscription) {
1740
- const { response, release } = await this.putChannelPayload([subscription], {
1741
- timeoutMs: 3e4,
1742
- auditContext: "tlon-urbit-subscribe"
1743
- });
1744
- try {
1745
- if (!response.ok && response.status !== 204) {
1746
- const errorText = await response.text().catch(() => "");
1747
- throw new Error(`Subscribe failed: ${response.status}${errorText ? ` - ${errorText}` : ""}`);
1748
- }
1749
- } finally {
1750
- await release();
1751
- }
1752
- }
1753
- async connect() {
1754
- await ensureUrbitChannelOpen({
1755
- baseUrl: this.url,
1756
- cookie: this.cookie,
1757
- ship: this.ship,
1758
- channelId: this.channelId,
1759
- ssrfPolicy: this.ssrfPolicy,
1760
- lookupFn: this.lookupFn,
1761
- fetchImpl: this.fetchImpl
1762
- }, {
1763
- createBody: this.subscriptions,
1764
- createAuditContext: "tlon-urbit-channel-create"
1765
- });
1766
- await this.openStream();
1767
- this.isConnected = true;
1768
- this.reconnectAttempts = 0;
1769
- }
1770
- async openStream() {
1771
- const controller = new AbortController();
1772
- const timeoutId = setTimeout(() => controller.abort(), 6e4);
1773
- this.streamController = controller;
1774
- const { response, release } = await urbitFetch({
1775
- baseUrl: this.url,
1776
- path: `/~/channel/${this.channelId}`,
1777
- init: {
1778
- method: "GET",
1779
- headers: {
1780
- Accept: "text/event-stream",
1781
- Cookie: this.cookie
1782
- }
1783
- },
1784
- ssrfPolicy: this.ssrfPolicy,
1785
- lookupFn: this.lookupFn,
1786
- fetchImpl: this.fetchImpl,
1787
- signal: controller.signal,
1788
- auditContext: "tlon-urbit-sse-stream"
1789
- });
1790
- this.streamRelease = release;
1791
- clearTimeout(timeoutId);
1792
- if (!response.ok) {
1793
- await release();
1794
- this.streamRelease = null;
1795
- throw new Error(`Stream connection failed: ${response.status}`);
1796
- }
1797
- this.processStream(response.body).catch((error) => {
1798
- if (!this.aborted) {
1799
- this.logger.error?.(`Stream error: ${String(error)}`);
1800
- for (const { err } of this.eventHandlers.values()) if (err) err(error);
1801
- }
1802
- });
1803
- }
1804
- async processStream(body) {
1805
- if (!body) return;
1806
- const stream = body instanceof ReadableStream ? Readable.fromWeb(body) : body;
1807
- let buffer = "";
1808
- try {
1809
- for await (const chunk of stream) {
1810
- if (this.aborted) break;
1811
- buffer += chunk.toString();
1812
- let eventEnd;
1813
- while ((eventEnd = buffer.indexOf("\n\n")) !== -1) {
1814
- const eventData = buffer.substring(0, eventEnd);
1815
- buffer = buffer.substring(eventEnd + 2);
1816
- this.processEvent(eventData);
1817
- }
1818
- }
1819
- } finally {
1820
- if (this.streamRelease) {
1821
- const release = this.streamRelease;
1822
- this.streamRelease = null;
1823
- await release();
1824
- }
1825
- this.streamController = null;
1826
- if (!this.aborted && this.autoReconnect) {
1827
- this.isConnected = false;
1828
- this.logger.log?.("[SSE] Stream ended, attempting reconnection...");
1829
- await this.attemptReconnect();
1830
- }
1831
- }
1832
- }
1833
- processEvent(eventData) {
1834
- const lines = eventData.split("\n");
1835
- let data = null;
1836
- let eventId = null;
1837
- for (const line of lines) {
1838
- if (line.startsWith("id: ")) eventId = parseInt(line.substring(4), 10);
1839
- if (line.startsWith("data: ")) data = line.substring(6);
1840
- }
1841
- if (!data) return;
1842
- if (eventId !== null && !isNaN(eventId)) {
1843
- if (eventId > this.lastHeardEventId) {
1844
- this.lastHeardEventId = eventId;
1845
- if (eventId - this.lastAcknowledgedEventId > this.ackThreshold) {
1846
- this.logger.log?.(`[SSE] Acking event ${eventId} (last acked: ${this.lastAcknowledgedEventId})`);
1847
- this.ack(eventId).catch((err) => {
1848
- this.logger.error?.(`Failed to ack event ${eventId}: ${String(err)}`);
1849
- });
1850
- }
1851
- }
1852
- }
1853
- try {
1854
- const parsed = JSON.parse(data);
1855
- if (parsed.response === "quit") {
1856
- if (parsed.id) {
1857
- const handlers = this.eventHandlers.get(parsed.id);
1858
- if (handlers?.quit) handlers.quit();
1859
- }
1860
- return;
1861
- }
1862
- if (parsed.id && this.eventHandlers.has(parsed.id)) {
1863
- const { event } = this.eventHandlers.get(parsed.id) ?? {};
1864
- if (event && parsed.json) event(parsed.json);
1865
- } else if (parsed.json) {
1866
- for (const { event } of this.eventHandlers.values()) if (event) event(parsed.json);
1867
- }
1868
- } catch (error) {
1869
- this.logger.error?.(`Error parsing SSE event: ${String(error)}`);
1870
- }
1871
- }
1872
- async poke(params) {
1873
- return await pokeUrbitChannel({
1874
- baseUrl: this.url,
1875
- cookie: this.cookie,
1876
- ship: this.ship,
1877
- channelId: this.channelId,
1878
- ssrfPolicy: this.ssrfPolicy,
1879
- lookupFn: this.lookupFn,
1880
- fetchImpl: this.fetchImpl
1881
- }, {
1882
- ...params,
1883
- auditContext: "tlon-urbit-poke"
1884
- });
1885
- }
1886
- async scry(path) {
1887
- return await scryUrbitPath({
1888
- baseUrl: this.url,
1889
- cookie: this.cookie,
1890
- ssrfPolicy: this.ssrfPolicy,
1891
- lookupFn: this.lookupFn,
1892
- fetchImpl: this.fetchImpl
1893
- }, {
1894
- path,
1895
- auditContext: "tlon-urbit-scry"
1896
- });
1897
- }
1898
- /**
1899
- * Update the cookie used for authentication.
1900
- * Call this when re-authenticating after session expiry.
1901
- */
1902
- updateCookie(newCookie) {
1903
- this.cookie = normalizeUrbitCookie(newCookie);
1904
- }
1905
- async ack(eventId) {
1906
- this.lastAcknowledgedEventId = eventId;
1907
- const ackData = {
1908
- id: Date.now(),
1909
- action: "ack",
1910
- "event-id": eventId
1911
- };
1912
- const { response, release } = await this.putChannelPayload([ackData], {
1913
- timeoutMs: 1e4,
1914
- auditContext: "tlon-urbit-ack"
1915
- });
1916
- try {
1917
- if (!response.ok) throw new Error(`Ack failed with status ${response.status}`);
1918
- } finally {
1919
- await release();
1920
- }
1921
- }
1922
- async attemptReconnect() {
1923
- if (this.aborted || !this.autoReconnect) {
1924
- this.logger.log?.("[SSE] Reconnection aborted or disabled");
1925
- return;
1926
- }
1927
- if (this.reconnectAttempts >= this.maxReconnectAttempts) {
1928
- this.logger.log?.(`[SSE] Max reconnection attempts (${this.maxReconnectAttempts}) reached. Waiting 10s before resetting...`);
1929
- const extendedBackoff = 1e4;
1930
- await new Promise((resolve) => setTimeout(resolve, extendedBackoff));
1931
- this.reconnectAttempts = 0;
1932
- this.logger.log?.("[SSE] Reconnection attempts reset, resuming reconnection...");
1933
- }
1934
- this.reconnectAttempts += 1;
1935
- const delay = Math.min(this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1), this.maxReconnectDelay);
1936
- this.logger.log?.(`[SSE] Reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms...`);
1937
- await new Promise((resolve) => setTimeout(resolve, delay));
1938
- try {
1939
- this.channelId = `${Math.floor(Date.now() / 1e3)}-${randomUUID()}`;
1940
- this.channelUrl = new URL(`/~/channel/${this.channelId}`, this.url).toString();
1941
- if (this.onReconnect) await this.onReconnect(this);
1942
- await this.connect();
1943
- this.logger.log?.("[SSE] Reconnection successful!");
1944
- } catch (error) {
1945
- this.logger.error?.(`[SSE] Reconnection failed: ${String(error)}`);
1946
- await this.attemptReconnect();
1947
- }
1948
- }
1949
- async close() {
1950
- this.aborted = true;
1951
- this.isConnected = false;
1952
- this.streamController?.abort();
1953
- try {
1954
- const unsubscribes = this.subscriptions.map((sub) => ({
1955
- id: sub.id,
1956
- action: "unsubscribe",
1957
- subscription: sub.id
1958
- }));
1959
- {
1960
- const { response, release } = await this.putChannelPayload(unsubscribes, {
1961
- timeoutMs: 3e4,
1962
- auditContext: "tlon-urbit-unsubscribe"
1963
- });
1964
- try {
1965
- response.body?.cancel();
1966
- } finally {
1967
- await release();
1968
- }
1969
- }
1970
- {
1971
- const { response, release } = await urbitFetch({
1972
- baseUrl: this.url,
1973
- path: `/~/channel/${this.channelId}`,
1974
- init: {
1975
- method: "DELETE",
1976
- headers: { Cookie: this.cookie }
1977
- },
1978
- ssrfPolicy: this.ssrfPolicy,
1979
- lookupFn: this.lookupFn,
1980
- fetchImpl: this.fetchImpl,
1981
- timeoutMs: 3e4,
1982
- auditContext: "tlon-urbit-channel-close"
1983
- });
1984
- try {
1985
- response.body?.cancel();
1986
- } finally {
1987
- await release();
1988
- }
1989
- }
1990
- } catch (error) {
1991
- this.logger.error?.(`Error closing channel: ${String(error)}`);
1992
- }
1993
- if (this.streamRelease) {
1994
- const release = this.streamRelease;
1995
- this.streamRelease = null;
1996
- await release();
1997
- }
1998
- }
1999
- async putChannelPayload(payload, params) {
2000
- return await urbitFetch({
2001
- baseUrl: this.url,
2002
- path: `/~/channel/${this.channelId}`,
2003
- init: {
2004
- method: "PUT",
2005
- headers: {
2006
- "Content-Type": "application/json",
2007
- Cookie: this.cookie
2008
- },
2009
- body: JSON.stringify(payload)
2010
- },
2011
- ssrfPolicy: this.ssrfPolicy,
2012
- lookupFn: this.lookupFn,
2013
- fetchImpl: this.fetchImpl,
2014
- timeoutMs: params.timeoutMs,
2015
- auditContext: params.auditContext
2016
- });
2017
- }
2018
- };
2019
- //#endregion
2020
- //#region extensions/tlon/src/monitor/approval.ts
2021
- /**
2022
- * Generate a unique approval ID in the format: {type}-{timestamp}-{shortHash}
2023
- */
2024
- function generateApprovalId(type) {
2025
- return `${type}-${Date.now()}-${Math.random().toString(36).substring(2, 6)}`;
2026
- }
2027
- /**
2028
- * Create a pending approval object.
2029
- */
2030
- function createPendingApproval(params) {
2031
- return {
2032
- id: generateApprovalId(params.type),
2033
- type: params.type,
2034
- requestingShip: params.requestingShip,
2035
- channelNest: params.channelNest,
2036
- groupFlag: params.groupFlag,
2037
- messagePreview: params.messagePreview,
2038
- originalMessage: params.originalMessage,
2039
- timestamp: Date.now()
2040
- };
2041
- }
2042
- /**
2043
- * Truncate text to a maximum length with ellipsis.
2044
- */
2045
- function truncate(text, maxLength) {
2046
- if (text.length <= maxLength) return text;
2047
- return text.substring(0, maxLength - 3) + "...";
2048
- }
2049
- /**
2050
- * Format a notification message for the owner about a pending approval.
2051
- */
2052
- function formatApprovalRequest(approval) {
2053
- const preview = approval.messagePreview ? `\n"${truncate(approval.messagePreview, 100)}"` : "";
2054
- switch (approval.type) {
2055
- case "dm": return `New DM request from ${approval.requestingShip}:${preview}\n\nReply "approve", "deny", or "block" (ID: ${approval.id})`;
2056
- case "channel": return `${approval.requestingShip} mentioned you in ${approval.channelNest}:${preview}\n\nReply "approve", "deny", or "block"\n(ID: ${approval.id})`;
2057
- case "group": return `Group invite from ${approval.requestingShip} to join ${approval.groupFlag}\n\nReply "approve", "deny", or "block"\n(ID: ${approval.id})`;
2058
- }
2059
- }
2060
- /**
2061
- * Parse an owner's response to an approval request.
2062
- * Supports formats:
2063
- * - "approve" / "deny" / "block" (applies to most recent pending)
2064
- * - "approve dm-1234567890-abc" / "deny dm-1234567890-abc" (specific ID)
2065
- * - "block" permanently blocks the ship via Tlon's native blocking
2066
- */
2067
- function parseApprovalResponse(text) {
2068
- const match = text.trim().toLowerCase().match(/^(approve|deny|block)(?:\s+(.+))?$/);
2069
- if (!match) return null;
2070
- return {
2071
- action: match[1],
2072
- id: match[2]?.trim()
2073
- };
2074
- }
2075
- /**
2076
- * Check if a message text looks like an approval response.
2077
- * Used to determine if we should intercept the message before normal processing.
2078
- */
2079
- function isApprovalResponse(text) {
2080
- const trimmed = text.trim().toLowerCase();
2081
- return trimmed.startsWith("approve") || trimmed.startsWith("deny") || trimmed.startsWith("block");
2082
- }
2083
- /**
2084
- * Find a pending approval by ID, or return the most recent if no ID specified.
2085
- */
2086
- function findPendingApproval(pendingApprovals, id) {
2087
- if (id) return pendingApprovals.find((a) => a.id === id);
2088
- return pendingApprovals[pendingApprovals.length - 1];
2089
- }
2090
- /**
2091
- * Remove a pending approval from the list by ID.
2092
- */
2093
- function removePendingApproval(pendingApprovals, id) {
2094
- return pendingApprovals.filter((a) => a.id !== id);
2095
- }
2096
- /**
2097
- * Format a confirmation message after an approval action.
2098
- */
2099
- function formatApprovalConfirmation(approval, action) {
2100
- if (action === "block") return `Blocked ${approval.requestingShip}. They will no longer be able to contact the bot.`;
2101
- const actionText = action === "approve" ? "Approved" : "Denied";
2102
- switch (approval.type) {
2103
- case "dm":
2104
- if (action === "approve") return `${actionText} DM access for ${approval.requestingShip}. They can now message the bot.`;
2105
- return `${actionText} DM request from ${approval.requestingShip}.`;
2106
- case "channel":
2107
- if (action === "approve") return `${actionText} ${approval.requestingShip} for ${approval.channelNest}. They can now interact in this channel.`;
2108
- return `${actionText} ${approval.requestingShip} for ${approval.channelNest}.`;
2109
- case "group":
2110
- if (action === "approve") return `${actionText} group invite from ${approval.requestingShip} to ${approval.groupFlag}. Joining group...`;
2111
- return `${actionText} group invite from ${approval.requestingShip} to ${approval.groupFlag}.`;
2112
- }
2113
- }
2114
- /**
2115
- * Parse an admin command from owner message.
2116
- * Supports:
2117
- * - "unblock ~ship" - unblock a specific ship
2118
- * - "blocked" - list all blocked ships
2119
- * - "pending" - list all pending approvals
2120
- */
2121
- function parseAdminCommand(text) {
2122
- const trimmed = text.trim().toLowerCase();
2123
- if (trimmed === "blocked") return { type: "blocked" };
2124
- if (trimmed === "pending") return { type: "pending" };
2125
- const unblockMatch = trimmed.match(/^unblock\s+(~[\w-]+)$/);
2126
- if (unblockMatch) return {
2127
- type: "unblock",
2128
- ship: unblockMatch[1]
2129
- };
2130
- return null;
2131
- }
2132
- /**
2133
- * Check if a message text looks like an admin command.
2134
- */
2135
- function isAdminCommand(text) {
2136
- return parseAdminCommand(text) !== null;
2137
- }
2138
- /**
2139
- * Format the list of blocked ships for display to owner.
2140
- */
2141
- function formatBlockedList(ships) {
2142
- if (ships.length === 0) return "No ships are currently blocked.";
2143
- return `Blocked ships (${ships.length}):\n${ships.map((s) => `• ${s}`).join("\n")}`;
2144
- }
2145
- /**
2146
- * Format the list of pending approvals for display to owner.
2147
- */
2148
- function formatPendingList(approvals) {
2149
- if (approvals.length === 0) return "No pending approval requests.";
2150
- return `Pending approvals (${approvals.length}):\n${approvals.map((a) => `• ${a.id}: ${a.type} from ${a.requestingShip}`).join("\n")}`;
2151
- }
2152
- //#endregion
2153
- //#region extensions/tlon/src/monitor/utils.ts
2154
- function extractCites(content) {
2155
- if (!content || !Array.isArray(content)) return [];
2156
- const cites = [];
2157
- for (const verse of content) if (verse?.block?.cite && typeof verse.block.cite === "object") {
2158
- const cite = verse.block.cite;
2159
- if (cite.chan && typeof cite.chan === "object") {
2160
- const { nest, where } = cite.chan;
2161
- const whereMatch = where?.match(/\/msg\/(~[a-z-]+)\/(.+)/);
2162
- cites.push({
2163
- type: "chan",
2164
- nest,
2165
- where,
2166
- author: whereMatch?.[1],
2167
- postId: whereMatch?.[2]
2168
- });
2169
- } else if (cite.group && typeof cite.group === "string") cites.push({
2170
- type: "group",
2171
- group: cite.group
2172
- });
2173
- else if (cite.desk && typeof cite.desk === "object") cites.push({
2174
- type: "desk",
2175
- flag: cite.desk.flag,
2176
- where: cite.desk.where
2177
- });
2178
- else if (cite.bait && typeof cite.bait === "object") cites.push({
2179
- type: "bait",
2180
- group: cite.bait.group,
2181
- nest: cite.bait.graph,
2182
- where: cite.bait.where
2183
- });
2184
- }
2185
- return cites;
2186
- }
2187
- function formatModelName(modelString) {
2188
- if (!modelString) return "AI";
2189
- const modelName = modelString.includes("/") ? modelString.split("/")[1] : modelString;
2190
- const modelMappings = {
2191
- "claude-opus-4-5": "Claude Opus 4.5",
2192
- "claude-sonnet-4-5": "Claude Sonnet 4.5",
2193
- "claude-sonnet-3-5": "Claude Sonnet 3.5",
2194
- "gpt-4o": "GPT-4o",
2195
- "gpt-4-turbo": "GPT-4 Turbo",
2196
- "gpt-4": "GPT-4",
2197
- "gemini-2.0-flash": "Gemini 2.0 Flash",
2198
- "gemini-pro": "Gemini Pro"
2199
- };
2200
- if (modelMappings[modelName]) return modelMappings[modelName];
2201
- return modelName.replace(/-/g, " ").split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
2202
- }
2203
- function isBotMentioned(messageText, botShipName, nickname) {
2204
- if (!messageText || !botShipName) return false;
2205
- if (/@all\b/i.test(messageText)) return true;
2206
- const escapedShip = normalizeShip(botShipName).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2207
- if (new RegExp(`(^|\\s)${escapedShip}(?=\\s|$)`, "i").test(messageText)) return true;
2208
- if (nickname) {
2209
- const escapedNickname = nickname.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2210
- if (new RegExp(`(^|\\s)${escapedNickname}(?=\\s|$|[,!?.])`, "i").test(messageText)) return true;
2211
- }
2212
- return false;
2213
- }
2214
- /**
2215
- * Strip bot ship mention from message text for command detection.
2216
- * "~bot-ship /status" → "/status"
2217
- */
2218
- function stripBotMention(messageText, botShipName) {
2219
- if (!messageText || !botShipName) return messageText;
2220
- return messageText.replace(normalizeShip(botShipName), "").trim();
2221
- }
2222
- function isDmAllowed(senderShip, allowlist) {
2223
- if (!allowlist || allowlist.length === 0) return false;
2224
- const normalizedSender = normalizeShip(senderShip);
2225
- return allowlist.map((ship) => normalizeShip(ship)).some((ship) => ship === normalizedSender);
2226
- }
2227
- function renderInlineItem(item, options) {
2228
- if (typeof item === "string") return item;
2229
- if (!item || typeof item !== "object") return "";
2230
- if (item.ship) return item.ship;
2231
- if ("sect" in item) return `@${item.sect || "all"}`;
2232
- if (options?.allowBreak && item.break !== void 0) return "\n";
2233
- if (item["inline-code"]) return `\`${item["inline-code"]}\``;
2234
- if (item.code) return `\`${item.code}\``;
2235
- if (item.link && item.link.href) return options?.linkMode === "href" ? item.link.href : item.link.content || item.link.href;
2236
- if (item.bold && Array.isArray(item.bold)) return `**${extractInlineText(item.bold)}**`;
2237
- if (item.italics && Array.isArray(item.italics)) return `*${extractInlineText(item.italics)}*`;
2238
- if (item.strike && Array.isArray(item.strike)) return `~~${extractInlineText(item.strike)}~~`;
2239
- if (options?.allowBlockquote && item.blockquote && Array.isArray(item.blockquote)) return `> ${extractInlineText(item.blockquote)}`;
2240
- return "";
2241
- }
2242
- function extractInlineText(items) {
2243
- return items.map((item) => renderInlineItem(item)).join("");
2244
- }
2245
- function extractMessageText(content) {
2246
- if (!content || !Array.isArray(content)) return "";
2247
- return content.map((verse) => {
2248
- if (verse.inline && Array.isArray(verse.inline)) return verse.inline.map((item) => renderInlineItem(item, {
2249
- linkMode: "href",
2250
- allowBreak: true,
2251
- allowBlockquote: true
2252
- })).join("");
2253
- if (verse.block && typeof verse.block === "object") {
2254
- const block = verse.block;
2255
- if (block.image && block.image.src) {
2256
- const alt = block.image.alt ? ` (${block.image.alt})` : "";
2257
- return `\n${block.image.src}${alt}\n`;
2258
- }
2259
- if (block.code && typeof block.code === "object") return `\n\`\`\`${block.code.lang || ""}\n${block.code.code || ""}\n\`\`\`\n`;
2260
- if (block.header && typeof block.header === "object") return `\n## ${block.header.content?.map((item) => typeof item === "string" ? item : "").join("") || ""}\n`;
2261
- if (block.cite && typeof block.cite === "object") {
2262
- const cite = block.cite;
2263
- if (cite.chan && typeof cite.chan === "object") {
2264
- const { nest, where } = cite.chan;
2265
- const whereMatch = where?.match(/\/msg\/(~[a-z-]+)\/(.+)/);
2266
- if (whereMatch) {
2267
- const [, author, _postId] = whereMatch;
2268
- return `\n> [quoted: ${author} in ${nest}]\n`;
2269
- }
2270
- return `\n> [quoted from ${nest}]\n`;
2271
- }
2272
- if (cite.group && typeof cite.group === "string") return `\n> [ref: group ${cite.group}]\n`;
2273
- if (cite.desk && typeof cite.desk === "object") return `\n> [ref: ${cite.desk.flag}]\n`;
2274
- if (cite.bait && typeof cite.bait === "object") return `\n> [ref: ${cite.bait.graph} in ${cite.bait.group}]\n`;
2275
- return `\n> [quoted message]\n`;
2276
- }
2277
- }
2278
- return "";
2279
- }).join("\n").trim();
2280
- }
2281
- function isSummarizationRequest(messageText) {
2282
- return [
2283
- /summarize\s+(this\s+)?(channel|chat|conversation)/i,
2284
- /what\s+did\s+i\s+miss/i,
2285
- /catch\s+me\s+up/i,
2286
- /channel\s+summary/i,
2287
- /tldr/i
2288
- ].some((pattern) => pattern.test(messageText));
2289
- }
2290
- //#endregion
2291
- //#region extensions/tlon/src/monitor/discovery.ts
2292
- /**
2293
- * Fetch groups-ui init data, returning channels and foreigns.
2294
- * This is a single scry that provides both channel discovery and pending invites.
2295
- */
2296
- async function fetchInitData(api, runtime) {
2297
- try {
2298
- runtime.log?.("[tlon] Fetching groups-ui init data...");
2299
- const initData = await api.scry("/groups-ui/v6/init.json");
2300
- const channels = [];
2301
- if (initData?.groups) {
2302
- for (const groupData of Object.values(initData.groups)) if (groupData && typeof groupData === "object" && groupData.channels) {
2303
- for (const channelNest of Object.keys(groupData.channels)) if (channelNest.startsWith("chat/")) channels.push(channelNest);
2304
- }
2305
- }
2306
- if (channels.length > 0) runtime.log?.(`[tlon] Auto-discovered ${channels.length} chat channel(s)`);
2307
- else runtime.log?.("[tlon] No chat channels found via auto-discovery");
2308
- const foreigns = initData?.foreigns || null;
2309
- if (foreigns) {
2310
- const pendingCount = Object.values(foreigns).filter((f) => f.invites?.some((i) => i.valid)).length;
2311
- if (pendingCount > 0) runtime.log?.(`[tlon] Found ${pendingCount} pending group invite(s)`);
2312
- }
2313
- return {
2314
- channels,
2315
- foreigns
2316
- };
2317
- } catch (error) {
2318
- runtime.log?.(`[tlon] Init data fetch failed: ${error?.message ?? String(error)}`);
2319
- return {
2320
- channels: [],
2321
- foreigns: null
2322
- };
2323
- }
2324
- }
2325
- async function fetchAllChannels(api, runtime) {
2326
- const { channels } = await fetchInitData(api, runtime);
2327
- return channels;
2328
- }
2329
- //#endregion
2330
- //#region extensions/tlon/src/monitor/history.ts
2331
- /**
2332
- * Format a number as @ud (with dots every 3 digits from the right)
2333
- * e.g., 170141184507799509469114119040828178432 -> 170.141.184.507.799.509.469.114.119.040.828.178.432
2334
- */
2335
- function formatUd(id) {
2336
- const reversed = String(id).replace(/\./g, "").split("").toReversed();
2337
- const chunks = [];
2338
- for (let i = 0; i < reversed.length; i += 3) chunks.push(reversed.slice(i, i + 3).toReversed().join(""));
2339
- return chunks.toReversed().join(".");
2340
- }
2341
- const messageCache = /* @__PURE__ */ new Map();
2342
- const MAX_CACHED_MESSAGES = 100;
2343
- function cacheMessage(channelNest, message) {
2344
- if (!messageCache.has(channelNest)) messageCache.set(channelNest, []);
2345
- const cache = messageCache.get(channelNest);
2346
- if (!cache) return;
2347
- cache.unshift(message);
2348
- if (cache.length > MAX_CACHED_MESSAGES) cache.pop();
2349
- }
2350
- async function fetchChannelHistory(api, channelNest, count = 50, runtime) {
2351
- try {
2352
- const scryPath = `/channels/v4/${channelNest}/posts/newest/${count}/outline.json`;
2353
- runtime?.log?.(`[tlon] Fetching history: ${scryPath}`);
2354
- const data = await api.scry(scryPath);
2355
- if (!data) return [];
2356
- let posts = [];
2357
- if (Array.isArray(data)) posts = data;
2358
- else if (data.posts && typeof data.posts === "object") posts = Object.values(data.posts);
2359
- else if (typeof data === "object") posts = Object.values(data);
2360
- const messages = posts.map((item) => {
2361
- const essay = item.essay || item["r-post"]?.set?.essay;
2362
- const seal = item.seal || item["r-post"]?.set?.seal;
2363
- return {
2364
- author: essay?.author || "unknown",
2365
- content: extractMessageText(essay?.content || []),
2366
- timestamp: essay?.sent || Date.now(),
2367
- id: seal?.id
2368
- };
2369
- }).filter((msg) => msg.content);
2370
- runtime?.log?.(`[tlon] Extracted ${messages.length} messages from history`);
2371
- return messages;
2372
- } catch (error) {
2373
- runtime?.log?.(`[tlon] Error fetching channel history: ${error?.message ?? String(error)}`);
2374
- return [];
2375
- }
2376
- }
2377
- async function getChannelHistory(api, channelNest, count = 50, runtime) {
2378
- const cache = messageCache.get(channelNest) ?? [];
2379
- if (cache.length >= count) {
2380
- runtime?.log?.(`[tlon] Using cached messages (${cache.length} available)`);
2381
- return cache.slice(0, count);
2382
- }
2383
- runtime?.log?.(`[tlon] Cache has ${cache.length} messages, need ${count}, fetching from scry...`);
2384
- return await fetchChannelHistory(api, channelNest, count, runtime);
2385
- }
2386
- /**
2387
- * Fetch thread/reply history for a specific parent post.
2388
- * Used to get context when entering a thread conversation.
2389
- */
2390
- async function fetchThreadHistory(api, channelNest, parentId, count = 50, runtime) {
2391
- try {
2392
- const formattedParentId = formatUd(parentId);
2393
- runtime?.log?.(`[tlon] Thread history - parentId: ${parentId} -> formatted: ${formattedParentId}`);
2394
- const scryPath = `/channels/v4/${channelNest}/posts/post/id/${formattedParentId}/replies/newest/${count}.json`;
2395
- runtime?.log?.(`[tlon] Fetching thread history: ${scryPath}`);
2396
- const data = await api.scry(scryPath);
2397
- if (!data) {
2398
- runtime?.log?.(`[tlon] No thread history data returned`);
2399
- return [];
2400
- }
2401
- let replies = [];
2402
- if (Array.isArray(data)) replies = data;
2403
- else if (data.replies && Array.isArray(data.replies)) replies = data.replies;
2404
- else if (typeof data === "object") replies = Object.values(data);
2405
- const messages = replies.map((item) => {
2406
- const memo = item.memo || item["r-reply"]?.set?.memo || item;
2407
- const seal = item.seal || item["r-reply"]?.set?.seal;
2408
- return {
2409
- author: memo?.author || "unknown",
2410
- content: extractMessageText(memo?.content || []),
2411
- timestamp: memo?.sent || Date.now(),
2412
- id: seal?.id || item.id
2413
- };
2414
- }).filter((msg) => msg.content);
2415
- runtime?.log?.(`[tlon] Extracted ${messages.length} thread replies from history`);
2416
- return messages;
2417
- } catch (error) {
2418
- runtime?.log?.(`[tlon] Error fetching thread history: ${error?.message ?? String(error)}`);
2419
- try {
2420
- const altPath = `/channels/v4/${channelNest}/posts/post/id/${formatUd(parentId)}.json`;
2421
- runtime?.log?.(`[tlon] Trying alternate path: ${altPath}`);
2422
- const data = await api.scry(altPath);
2423
- if (data?.seal?.meta?.replyCount > 0 && data?.replies) {
2424
- const messages = (Array.isArray(data.replies) ? data.replies : Object.values(data.replies)).map((reply) => ({
2425
- author: reply.memo?.author || "unknown",
2426
- content: extractMessageText(reply.memo?.content || []),
2427
- timestamp: reply.memo?.sent || Date.now(),
2428
- id: reply.seal?.id
2429
- })).filter((msg) => msg.content);
2430
- runtime?.log?.(`[tlon] Extracted ${messages.length} replies from post data`);
2431
- return messages;
2432
- }
2433
- } catch (altError) {
2434
- runtime?.log?.(`[tlon] Alternate path also failed: ${altError?.message ?? String(altError)}`);
2435
- }
2436
- return [];
2437
- }
2438
- }
2439
- //#endregion
2440
- //#region extensions/tlon/src/monitor/media.ts
2441
- const DEFAULT_MEDIA_DIR = path$1.join(homedir(), ".moldclaw", "workspace", "media", "inbound");
2442
- /**
2443
- * Extract image blocks from Tlon message content.
2444
- * Returns array of image URLs found in the message.
2445
- */
2446
- function extractImageBlocks(content) {
2447
- if (!content || !Array.isArray(content)) return [];
2448
- const images = [];
2449
- for (const verse of content) if (verse?.block?.image?.src) images.push({
2450
- url: verse.block.image.src,
2451
- alt: verse.block.image.alt
2452
- });
2453
- return images;
2454
- }
2455
- /**
2456
- * Download a media file from URL to local storage.
2457
- * Returns the local path where the file was saved.
2458
- */
2459
- async function downloadMedia(url, mediaDir = DEFAULT_MEDIA_DIR) {
2460
- try {
2461
- const parsedUrl = new URL(url);
2462
- if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
2463
- console.warn(`[tlon-media] Rejected non-http(s) URL: ${url}`);
2464
- return null;
2465
- }
2466
- await mkdir(mediaDir, { recursive: true });
2467
- const { response, release } = await fetchWithSsrFGuard({
2468
- url,
2469
- init: { method: "GET" },
2470
- policy: /* @__PURE__ */ getDefaultSsrFPolicy(),
2471
- auditContext: "tlon-media-download"
2472
- });
2473
- try {
2474
- if (!response.ok) {
2475
- console.error(`[tlon-media] Failed to fetch ${url}: ${response.status}`);
2476
- return null;
2477
- }
2478
- const contentType = response.headers.get("content-type") || "application/octet-stream";
2479
- const ext = getExtensionFromContentType(contentType) || getExtensionFromUrl(url) || "bin";
2480
- const filename = `${randomUUID()}.${ext}`;
2481
- const localPath = path$1.join(mediaDir, filename);
2482
- const body = response.body;
2483
- if (!body) {
2484
- console.error(`[tlon-media] No response body for ${url}`);
2485
- return null;
2486
- }
2487
- const writeStream = createWriteStream(localPath);
2488
- await pipeline(Readable.fromWeb(body), writeStream);
2489
- return {
2490
- localPath,
2491
- contentType,
2492
- originalUrl: url
2493
- };
2494
- } finally {
2495
- await release();
2496
- }
2497
- } catch (error) {
2498
- console.error(`[tlon-media] Error downloading ${url}: ${error?.message ?? String(error)}`);
2499
- return null;
2500
- }
2501
- }
2502
- function getExtensionFromContentType(contentType) {
2503
- return {
2504
- "image/jpeg": "jpg",
2505
- "image/jpg": "jpg",
2506
- "image/png": "png",
2507
- "image/gif": "gif",
2508
- "image/webp": "webp",
2509
- "image/svg+xml": "svg",
2510
- "video/mp4": "mp4",
2511
- "video/webm": "webm",
2512
- "audio/mpeg": "mp3",
2513
- "audio/ogg": "ogg"
2514
- }[contentType.split(";")[0].trim()] ?? null;
2515
- }
2516
- function getExtensionFromUrl(url) {
2517
- try {
2518
- const match = new URL(url).pathname.match(/\.([a-z0-9]+)$/i);
2519
- return match ? match[1].toLowerCase() : null;
2520
- } catch {
2521
- return null;
2522
- }
2523
- }
2524
- /**
2525
- * Download all images from a message and return attachment metadata.
2526
- * Format matches MoldClaw's expected attachment structure.
2527
- */
2528
- async function downloadMessageImages(content, mediaDir) {
2529
- const images = extractImageBlocks(content);
2530
- if (images.length === 0) return [];
2531
- const attachments = [];
2532
- for (const image of images) {
2533
- const downloaded = await downloadMedia(image.url, mediaDir);
2534
- if (downloaded) attachments.push({
2535
- path: downloaded.localPath,
2536
- contentType: downloaded.contentType
2537
- });
2538
- }
2539
- return attachments;
2540
- }
2541
- //#endregion
2542
- //#region extensions/tlon/src/monitor/processed-messages.ts
2543
- function createProcessedMessageTracker(limit = 2e3) {
2544
- const dedupe = createDedupeCache({
2545
- ttlMs: 0,
2546
- maxSize: limit
2547
- });
2548
- const mark = (id) => {
2549
- const trimmed = id?.trim();
2550
- if (!trimmed) return true;
2551
- return !dedupe.check(trimmed);
2552
- };
2553
- const has = (id) => {
2554
- const trimmed = id?.trim();
2555
- if (!trimmed) return false;
2556
- return dedupe.peek(trimmed);
2557
- };
2558
- return {
2559
- mark,
2560
- has,
2561
- size: () => dedupe.size()
2562
- };
2563
- }
2564
- //#endregion
2565
- //#region extensions/tlon/src/monitor/index.ts
2566
- /**
2567
- * Resolve channel authorization by merging file config with settings store.
2568
- * Settings store takes precedence for fields it defines.
2569
- */
2570
- function resolveChannelAuthorization(cfg, channelNest, settings) {
2571
- const tlonConfig = cfg.channels?.tlon;
2572
- const fileRules = tlonConfig?.authorization?.channelRules ?? {};
2573
- const rule = (settings?.channelRules ?? {})[channelNest] ?? fileRules[channelNest];
2574
- const defaultShips = settings?.defaultAuthorizedShips ?? tlonConfig?.defaultAuthorizedShips ?? [];
2575
- const allowedShips = rule?.allowedShips ?? defaultShips;
2576
- return {
2577
- mode: rule?.mode ?? "restricted",
2578
- allowedShips
2579
- };
2580
- }
2581
- async function monitorTlonProvider(opts = {}) {
2582
- const core = getTlonRuntime();
2583
- const cfg = core.config.loadConfig();
2584
- if (cfg.channels?.tlon?.enabled === false) return;
2585
- const logger = core.logging.getChildLogger({ module: "tlon-auto-reply" });
2586
- const runtime = opts.runtime ?? createLoggerBackedRuntime({ logger });
2587
- const account = resolveTlonAccount(cfg, opts.accountId ?? void 0);
2588
- if (!account.enabled) return;
2589
- if (!account.configured || !account.ship || !account.url || !account.code) throw new Error("Tlon account not configured (ship/url/code required)");
2590
- const botShipName = normalizeShip(account.ship);
2591
- runtime.log?.(`[tlon] Starting monitor for ${botShipName}`);
2592
- const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(account.allowPrivateNetwork);
2593
- const accountUrl = account.url;
2594
- const accountCode = account.code;
2595
- async function authenticateWithRetry(maxAttempts = 10) {
2596
- for (let attempt = 1;; attempt++) {
2597
- if (opts.abortSignal?.aborted) throw new Error("Aborted while waiting to authenticate");
2598
- try {
2599
- runtime.log?.(`[tlon] Attempting authentication to ${accountUrl}...`);
2600
- return await authenticate(accountUrl, accountCode, { ssrfPolicy });
2601
- } catch (error) {
2602
- runtime.error?.(`[tlon] Failed to authenticate (attempt ${attempt}): ${error?.message ?? String(error)}`);
2603
- if (attempt >= maxAttempts) throw error;
2604
- const delay = Math.min(3e4, 1e3 * Math.pow(2, attempt - 1));
2605
- runtime.log?.(`[tlon] Retrying authentication in ${delay}ms...`);
2606
- await new Promise((resolve, reject) => {
2607
- const timer = setTimeout(resolve, delay);
2608
- if (opts.abortSignal) {
2609
- const onAbort = () => {
2610
- clearTimeout(timer);
2611
- reject(/* @__PURE__ */ new Error("Aborted"));
2612
- };
2613
- opts.abortSignal.addEventListener("abort", onAbort, { once: true });
2614
- }
2615
- });
2616
- }
2617
- }
2618
- }
2619
- let api = null;
2620
- const cookie = await authenticateWithRetry();
2621
- api = new UrbitSSEClient(account.url, cookie, {
2622
- ship: botShipName,
2623
- ssrfPolicy,
2624
- logger: {
2625
- log: (message) => runtime.log?.(message),
2626
- error: (message) => runtime.error?.(message)
2627
- },
2628
- onReconnect: async (client) => {
2629
- runtime.log?.("[tlon] Re-authenticating on SSE reconnect...");
2630
- const newCookie = await authenticateWithRetry(5);
2631
- client.updateCookie(newCookie);
2632
- runtime.log?.("[tlon] Re-authentication successful");
2633
- }
2634
- });
2635
- const processedTracker = createProcessedMessageTracker(2e3);
2636
- let groupChannels = [];
2637
- let botNickname = null;
2638
- const settingsManager = createSettingsManager(api, {
2639
- log: (msg) => runtime.log?.(msg),
2640
- error: (msg) => runtime.error?.(msg)
2641
- });
2642
- let effectiveDmAllowlist = account.dmAllowlist;
2643
- let effectiveShowModelSig = account.showModelSignature ?? false;
2644
- let effectiveAutoAcceptDmInvites = account.autoAcceptDmInvites ?? false;
2645
- let effectiveAutoAcceptGroupInvites = account.autoAcceptGroupInvites ?? false;
2646
- let effectiveGroupInviteAllowlist = account.groupInviteAllowlist;
2647
- let effectiveAutoDiscoverChannels = account.autoDiscoverChannels ?? false;
2648
- let effectiveOwnerShip = account.ownerShip ? normalizeShip(account.ownerShip) : null;
2649
- let pendingApprovals = [];
2650
- let currentSettings = {};
2651
- const participatedThreads = /* @__PURE__ */ new Set();
2652
- const dmSendersBySession = /* @__PURE__ */ new Map();
2653
- let sharedSessionWarningSent = false;
2654
- try {
2655
- const selfProfile = await api.scry("/contacts/v1/self.json");
2656
- if (selfProfile && typeof selfProfile === "object") {
2657
- botNickname = selfProfile.nickname?.value || null;
2658
- if (botNickname) runtime.log?.(`[tlon] Bot nickname: ${botNickname}`);
2659
- }
2660
- } catch (error) {
2661
- runtime.log?.(`[tlon] Could not fetch nickname: ${error?.message ?? String(error)}`);
2662
- }
2663
- let initForeigns = null;
2664
- async function migrateConfigToSettings() {
2665
- const migrations = [
2666
- {
2667
- key: "dmAllowlist",
2668
- fileValue: account.dmAllowlist,
2669
- settingsValue: currentSettings.dmAllowlist
2670
- },
2671
- {
2672
- key: "groupInviteAllowlist",
2673
- fileValue: account.groupInviteAllowlist,
2674
- settingsValue: currentSettings.groupInviteAllowlist
2675
- },
2676
- {
2677
- key: "groupChannels",
2678
- fileValue: account.groupChannels,
2679
- settingsValue: currentSettings.groupChannels
2680
- },
2681
- {
2682
- key: "defaultAuthorizedShips",
2683
- fileValue: account.defaultAuthorizedShips,
2684
- settingsValue: currentSettings.defaultAuthorizedShips
2685
- },
2686
- {
2687
- key: "autoDiscoverChannels",
2688
- fileValue: account.autoDiscoverChannels,
2689
- settingsValue: currentSettings.autoDiscoverChannels
2690
- },
2691
- {
2692
- key: "autoAcceptDmInvites",
2693
- fileValue: account.autoAcceptDmInvites,
2694
- settingsValue: currentSettings.autoAcceptDmInvites
2695
- },
2696
- {
2697
- key: "autoAcceptGroupInvites",
2698
- fileValue: account.autoAcceptGroupInvites,
2699
- settingsValue: currentSettings.autoAcceptGroupInvites
2700
- },
2701
- {
2702
- key: "showModelSig",
2703
- fileValue: account.showModelSignature,
2704
- settingsValue: currentSettings.showModelSig
2705
- }
2706
- ];
2707
- for (const { key, fileValue, settingsValue } of migrations) {
2708
- const hasFileValue = Array.isArray(fileValue) ? fileValue.length > 0 : fileValue != null;
2709
- const hasSettingsValue = Array.isArray(settingsValue) ? settingsValue.length > 0 : settingsValue != null;
2710
- if (hasFileValue && !hasSettingsValue) try {
2711
- await api.poke({
2712
- app: "settings",
2713
- mark: "settings-event",
2714
- json: { "put-entry": {
2715
- "bucket-key": "tlon",
2716
- "entry-key": key,
2717
- value: fileValue,
2718
- desk: "moltbot"
2719
- } }
2720
- });
2721
- runtime.log?.(`[tlon] Migrated ${key} from config to settings store`);
2722
- } catch (err) {
2723
- runtime.log?.(`[tlon] Failed to migrate ${key}: ${String(err)}`);
2724
- }
2725
- }
2726
- }
2727
- try {
2728
- currentSettings = await settingsManager.load();
2729
- await migrateConfigToSettings();
2730
- if (currentSettings.defaultAuthorizedShips?.length) runtime.log?.(`[tlon] Using defaultAuthorizedShips from settings store: ${currentSettings.defaultAuthorizedShips.join(", ")}`);
2731
- if (currentSettings.autoDiscoverChannels !== void 0) {
2732
- effectiveAutoDiscoverChannels = currentSettings.autoDiscoverChannels;
2733
- runtime.log?.(`[tlon] Using autoDiscoverChannels from settings store: ${effectiveAutoDiscoverChannels}`);
2734
- }
2735
- if (currentSettings.dmAllowlist !== void 0) {
2736
- effectiveDmAllowlist = currentSettings.dmAllowlist;
2737
- runtime.log?.(`[tlon] Using dmAllowlist from settings store: ${effectiveDmAllowlist.join(", ")}`);
2738
- }
2739
- if (currentSettings.showModelSig !== void 0) effectiveShowModelSig = currentSettings.showModelSig;
2740
- if (currentSettings.autoAcceptDmInvites !== void 0) {
2741
- effectiveAutoAcceptDmInvites = currentSettings.autoAcceptDmInvites;
2742
- runtime.log?.(`[tlon] Using autoAcceptDmInvites from settings store: ${effectiveAutoAcceptDmInvites}`);
2743
- }
2744
- if (currentSettings.autoAcceptGroupInvites !== void 0) {
2745
- effectiveAutoAcceptGroupInvites = currentSettings.autoAcceptGroupInvites;
2746
- runtime.log?.(`[tlon] Using autoAcceptGroupInvites from settings store: ${effectiveAutoAcceptGroupInvites}`);
2747
- }
2748
- if (currentSettings.groupInviteAllowlist !== void 0) {
2749
- effectiveGroupInviteAllowlist = currentSettings.groupInviteAllowlist;
2750
- runtime.log?.(`[tlon] Using groupInviteAllowlist from settings store: ${effectiveGroupInviteAllowlist.join(", ")}`);
2751
- }
2752
- if (currentSettings.ownerShip) {
2753
- effectiveOwnerShip = normalizeShip(currentSettings.ownerShip);
2754
- runtime.log?.(`[tlon] Using ownerShip from settings store: ${effectiveOwnerShip}`);
2755
- }
2756
- if (currentSettings.pendingApprovals?.length) {
2757
- pendingApprovals = currentSettings.pendingApprovals;
2758
- runtime.log?.(`[tlon] Loaded ${pendingApprovals.length} pending approval(s) from settings`);
2759
- }
2760
- } catch (err) {
2761
- runtime.log?.(`[tlon] Settings store not available, using file config: ${String(err)}`);
2762
- }
2763
- if (effectiveAutoDiscoverChannels) try {
2764
- const initData = await fetchInitData(api, runtime);
2765
- if (initData.channels.length > 0) groupChannels = initData.channels;
2766
- initForeigns = initData.foreigns;
2767
- } catch (error) {
2768
- runtime.error?.(`[tlon] Auto-discovery failed: ${error?.message ?? String(error)}`);
2769
- }
2770
- if (account.groupChannels.length > 0) {
2771
- for (const ch of account.groupChannels) if (!groupChannels.includes(ch)) groupChannels.push(ch);
2772
- runtime.log?.(`[tlon] Added ${account.groupChannels.length} manual groupChannels to monitoring`);
2773
- }
2774
- if (currentSettings.groupChannels?.length) {
2775
- for (const ch of currentSettings.groupChannels) if (!groupChannels.includes(ch)) groupChannels.push(ch);
2776
- }
2777
- if (groupChannels.length > 0) runtime.log?.(`[tlon] Monitoring ${groupChannels.length} group channel(s): ${groupChannels.join(", ")}`);
2778
- else runtime.log?.("[tlon] No group channels to monitor (DMs only)");
2779
- async function resolveCiteContent(cite) {
2780
- if (cite.type !== "chan" || !cite.nest || !cite.postId) return null;
2781
- try {
2782
- const scryPath = `/channels/v4/${cite.nest}/posts/post/${cite.postId}.json`;
2783
- runtime.log?.(`[tlon] Fetching cited post: ${scryPath}`);
2784
- const data = await api.scry(scryPath);
2785
- if (data?.essay?.content) return extractMessageText(data.essay.content) || null;
2786
- return null;
2787
- } catch (err) {
2788
- runtime.log?.(`[tlon] Failed to fetch cited post: ${String(err)}`);
2789
- return null;
2790
- }
2791
- }
2792
- async function resolveAllCites(content) {
2793
- const cites = extractCites(content);
2794
- if (cites.length === 0) return "";
2795
- const resolved = [];
2796
- for (const cite of cites) {
2797
- const text = await resolveCiteContent(cite);
2798
- if (text) {
2799
- const author = cite.author || "unknown";
2800
- resolved.push(`> ${author} wrote: ${text}`);
2801
- }
2802
- }
2803
- return resolved.length > 0 ? resolved.join("\n") + "\n\n" : "";
2804
- }
2805
- async function savePendingApprovals() {
2806
- try {
2807
- await api.poke({
2808
- app: "settings",
2809
- mark: "settings-event",
2810
- json: { "put-entry": {
2811
- desk: "moltbot",
2812
- "bucket-key": "tlon",
2813
- "entry-key": "pendingApprovals",
2814
- value: JSON.stringify(pendingApprovals)
2815
- } }
2816
- });
2817
- } catch (err) {
2818
- runtime.error?.(`[tlon] Failed to save pending approvals: ${String(err)}`);
2819
- }
2820
- }
2821
- async function addToDmAllowlist(ship) {
2822
- const normalizedShip = normalizeShip(ship);
2823
- if (!effectiveDmAllowlist.includes(normalizedShip)) effectiveDmAllowlist = [...effectiveDmAllowlist, normalizedShip];
2824
- try {
2825
- await api.poke({
2826
- app: "settings",
2827
- mark: "settings-event",
2828
- json: { "put-entry": {
2829
- desk: "moltbot",
2830
- "bucket-key": "tlon",
2831
- "entry-key": "dmAllowlist",
2832
- value: effectiveDmAllowlist
2833
- } }
2834
- });
2835
- runtime.log?.(`[tlon] Added ${normalizedShip} to dmAllowlist`);
2836
- } catch (err) {
2837
- runtime.error?.(`[tlon] Failed to update dmAllowlist: ${String(err)}`);
2838
- }
2839
- }
2840
- async function addToChannelAllowlist(ship, channelNest) {
2841
- const normalizedShip = normalizeShip(ship);
2842
- const channelRules = currentSettings.channelRules ?? {};
2843
- const rule = channelRules[channelNest] ?? {
2844
- mode: "restricted",
2845
- allowedShips: []
2846
- };
2847
- const allowedShips = [...rule.allowedShips ?? []];
2848
- if (!allowedShips.includes(normalizedShip)) allowedShips.push(normalizedShip);
2849
- const updatedRules = {
2850
- ...channelRules,
2851
- [channelNest]: {
2852
- ...rule,
2853
- allowedShips
2854
- }
2855
- };
2856
- currentSettings = {
2857
- ...currentSettings,
2858
- channelRules: updatedRules
2859
- };
2860
- try {
2861
- await api.poke({
2862
- app: "settings",
2863
- mark: "settings-event",
2864
- json: { "put-entry": {
2865
- desk: "moltbot",
2866
- "bucket-key": "tlon",
2867
- "entry-key": "channelRules",
2868
- value: JSON.stringify(updatedRules)
2869
- } }
2870
- });
2871
- runtime.log?.(`[tlon] Added ${normalizedShip} to ${channelNest} allowlist`);
2872
- } catch (err) {
2873
- runtime.error?.(`[tlon] Failed to update channelRules: ${String(err)}`);
2874
- }
2875
- }
2876
- async function blockShip(ship) {
2877
- const normalizedShip = normalizeShip(ship);
2878
- try {
2879
- await api.poke({
2880
- app: "chat",
2881
- mark: "chat-block-ship",
2882
- json: { ship: normalizedShip }
2883
- });
2884
- runtime.log?.(`[tlon] Blocked ship ${normalizedShip}`);
2885
- } catch (err) {
2886
- runtime.error?.(`[tlon] Failed to block ship ${normalizedShip}: ${String(err)}`);
2887
- }
2888
- }
2889
- async function isShipBlocked(ship) {
2890
- const normalizedShip = normalizeShip(ship);
2891
- try {
2892
- const blocked = await api.scry("/chat/blocked.json");
2893
- return Array.isArray(blocked) && blocked.some((s) => normalizeShip(s) === normalizedShip);
2894
- } catch (err) {
2895
- runtime.log?.(`[tlon] Failed to check blocked list: ${String(err)}`);
2896
- return false;
2897
- }
2898
- }
2899
- async function getBlockedShips() {
2900
- try {
2901
- const blocked = await api.scry("/chat/blocked.json");
2902
- return Array.isArray(blocked) ? blocked : [];
2903
- } catch (err) {
2904
- runtime.log?.(`[tlon] Failed to get blocked list: ${String(err)}`);
2905
- return [];
2906
- }
2907
- }
2908
- async function unblockShip(ship) {
2909
- const normalizedShip = normalizeShip(ship);
2910
- try {
2911
- await api.poke({
2912
- app: "chat",
2913
- mark: "chat-unblock-ship",
2914
- json: { ship: normalizedShip }
2915
- });
2916
- runtime.log?.(`[tlon] Unblocked ship ${normalizedShip}`);
2917
- return true;
2918
- } catch (err) {
2919
- runtime.error?.(`[tlon] Failed to unblock ship ${normalizedShip}: ${String(err)}`);
2920
- return false;
2921
- }
2922
- }
2923
- async function sendOwnerNotification(message) {
2924
- if (!effectiveOwnerShip) {
2925
- runtime.log?.("[tlon] No ownerShip configured, cannot send notification");
2926
- return;
2927
- }
2928
- try {
2929
- await sendDm({
2930
- api,
2931
- fromShip: botShipName,
2932
- toShip: effectiveOwnerShip,
2933
- text: message
2934
- });
2935
- runtime.log?.(`[tlon] Sent notification to owner ${effectiveOwnerShip}`);
2936
- } catch (err) {
2937
- runtime.error?.(`[tlon] Failed to send notification to owner: ${String(err)}`);
2938
- }
2939
- }
2940
- async function queueApprovalRequest(approval) {
2941
- if (await isShipBlocked(approval.requestingShip)) {
2942
- runtime.log?.(`[tlon] Ignoring request from blocked ship ${approval.requestingShip}`);
2943
- return;
2944
- }
2945
- const existingIndex = pendingApprovals.findIndex((a) => a.type === approval.type && a.requestingShip === approval.requestingShip && (approval.type !== "channel" || a.channelNest === approval.channelNest) && (approval.type !== "group" || a.groupFlag === approval.groupFlag));
2946
- if (existingIndex !== -1) {
2947
- const existing = pendingApprovals[existingIndex];
2948
- if (approval.originalMessage) {
2949
- existing.originalMessage = approval.originalMessage;
2950
- existing.messagePreview = approval.messagePreview;
2951
- }
2952
- runtime.log?.(`[tlon] Updated existing approval for ${approval.requestingShip} (${approval.type}) - re-sending notification`);
2953
- await savePendingApprovals();
2954
- await sendOwnerNotification(formatApprovalRequest(existing));
2955
- return;
2956
- }
2957
- pendingApprovals.push(approval);
2958
- await savePendingApprovals();
2959
- await sendOwnerNotification(formatApprovalRequest(approval));
2960
- runtime.log?.(`[tlon] Queued approval request: ${approval.id} (${approval.type} from ${approval.requestingShip})`);
2961
- }
2962
- async function handleApprovalResponse(text) {
2963
- const parsed = parseApprovalResponse(text);
2964
- if (!parsed) return false;
2965
- const approval = findPendingApproval(pendingApprovals, parsed.id);
2966
- if (!approval) {
2967
- await sendOwnerNotification("No pending approval found" + (parsed.id ? ` for ID: ${parsed.id}` : ""));
2968
- return true;
2969
- }
2970
- if (parsed.action === "approve") {
2971
- switch (approval.type) {
2972
- case "dm":
2973
- await addToDmAllowlist(approval.requestingShip);
2974
- if (approval.originalMessage) {
2975
- runtime.log?.(`[tlon] Processing original message from ${approval.requestingShip} after approval`);
2976
- await processMessage({
2977
- messageId: approval.originalMessage.messageId,
2978
- senderShip: approval.requestingShip,
2979
- messageText: approval.originalMessage.messageText,
2980
- messageContent: approval.originalMessage.messageContent,
2981
- isGroup: false,
2982
- timestamp: approval.originalMessage.timestamp
2983
- });
2984
- }
2985
- break;
2986
- case "channel":
2987
- if (approval.channelNest) {
2988
- await addToChannelAllowlist(approval.requestingShip, approval.channelNest);
2989
- if (approval.originalMessage) {
2990
- const parsed = parseChannelNest(approval.channelNest);
2991
- runtime.log?.(`[tlon] Processing original message from ${approval.requestingShip} in ${approval.channelNest} after approval`);
2992
- await processMessage({
2993
- messageId: approval.originalMessage.messageId,
2994
- senderShip: approval.requestingShip,
2995
- messageText: approval.originalMessage.messageText,
2996
- messageContent: approval.originalMessage.messageContent,
2997
- isGroup: true,
2998
- channelNest: approval.channelNest,
2999
- hostShip: parsed?.hostShip,
3000
- channelName: parsed?.channelName,
3001
- timestamp: approval.originalMessage.timestamp,
3002
- parentId: approval.originalMessage.parentId,
3003
- isThreadReply: approval.originalMessage.isThreadReply
3004
- });
3005
- }
3006
- }
3007
- break;
3008
- case "group":
3009
- if (approval.groupFlag) try {
3010
- await api.poke({
3011
- app: "groups",
3012
- mark: "group-join",
3013
- json: {
3014
- flag: approval.groupFlag,
3015
- "join-all": true
3016
- }
3017
- });
3018
- runtime.log?.(`[tlon] Joined group ${approval.groupFlag} after approval`);
3019
- setTimeout(async () => {
3020
- try {
3021
- const discoveredChannels = await fetchAllChannels(api, runtime);
3022
- let newCount = 0;
3023
- for (const channelNest of discoveredChannels) if (!watchedChannels.has(channelNest)) {
3024
- watchedChannels.add(channelNest);
3025
- newCount++;
3026
- }
3027
- if (newCount > 0) runtime.log?.(`[tlon] Discovered ${newCount} new channel(s) after joining group`);
3028
- } catch (err) {
3029
- runtime.log?.(`[tlon] Channel discovery after group join failed: ${String(err)}`);
3030
- }
3031
- }, 2e3);
3032
- } catch (err) {
3033
- runtime.error?.(`[tlon] Failed to join group ${approval.groupFlag}: ${String(err)}`);
3034
- }
3035
- break;
3036
- }
3037
- await sendOwnerNotification(formatApprovalConfirmation(approval, "approve"));
3038
- } else if (parsed.action === "block") {
3039
- await blockShip(approval.requestingShip);
3040
- await sendOwnerNotification(formatApprovalConfirmation(approval, "block"));
3041
- } else await sendOwnerNotification(formatApprovalConfirmation(approval, "deny"));
3042
- pendingApprovals = removePendingApproval(pendingApprovals, approval.id);
3043
- await savePendingApprovals();
3044
- return true;
3045
- }
3046
- async function handleAdminCommand(text) {
3047
- const command = parseAdminCommand(text);
3048
- if (!command) return false;
3049
- switch (command.type) {
3050
- case "blocked": {
3051
- const blockedShips = await getBlockedShips();
3052
- await sendOwnerNotification(formatBlockedList(blockedShips));
3053
- runtime.log?.(`[tlon] Owner requested blocked ships list (${blockedShips.length} ships)`);
3054
- return true;
3055
- }
3056
- case "pending":
3057
- await sendOwnerNotification(formatPendingList(pendingApprovals));
3058
- runtime.log?.(`[tlon] Owner requested pending approvals list (${pendingApprovals.length} pending)`);
3059
- return true;
3060
- case "unblock": {
3061
- const shipToUnblock = command.ship;
3062
- if (!await isShipBlocked(shipToUnblock)) {
3063
- await sendOwnerNotification(`${shipToUnblock} is not blocked.`);
3064
- return true;
3065
- }
3066
- if (await unblockShip(shipToUnblock)) await sendOwnerNotification(`Unblocked ${shipToUnblock}.`);
3067
- else await sendOwnerNotification(`Failed to unblock ${shipToUnblock}.`);
3068
- return true;
3069
- }
3070
- }
3071
- }
3072
- function isOwner(ship) {
3073
- if (!effectiveOwnerShip) return false;
3074
- return normalizeShip(ship) === effectiveOwnerShip;
3075
- }
3076
- /**
3077
- * Extract the DM partner ship from the 'whom' field.
3078
- * This is the canonical source for DM routing (more reliable than essay.author).
3079
- * Returns empty string if whom doesn't contain a valid patp-like value.
3080
- */
3081
- function extractDmPartnerShip(whom) {
3082
- const normalized = normalizeShip(typeof whom === "string" ? whom : whom && typeof whom === "object" && "ship" in whom && typeof whom.ship === "string" ? whom.ship : "");
3083
- return /^~?[a-z-]+$/i.test(normalized) ? normalized : "";
3084
- }
3085
- const processMessage = async (params) => {
3086
- const { messageId, senderShip, isGroup, channelNest, hostShip, channelName, timestamp, parentId, isThreadReply, messageContent } = params;
3087
- const groupChannel = channelNest;
3088
- let messageText = params.messageText;
3089
- let attachments = [];
3090
- if (messageContent) try {
3091
- attachments = await downloadMessageImages(messageContent);
3092
- if (attachments.length > 0) runtime.log?.(`[tlon] Downloaded ${attachments.length} image(s) from message`);
3093
- } catch (error) {
3094
- runtime.log?.(`[tlon] Failed to download images: ${error?.message ?? String(error)}`);
3095
- }
3096
- if (isThreadReply && parentId && groupChannel) try {
3097
- const threadHistory = await fetchThreadHistory(api, groupChannel, parentId, 20, runtime);
3098
- if (threadHistory.length > 0) {
3099
- const threadContext = threadHistory.slice(-10).map((msg) => `${msg.author}: ${msg.content}`).join("\n");
3100
- messageText = `${`[Thread conversation - ${threadHistory.length} previous replies. You are participating in this thread. Only respond if relevant or helpful - you don't need to reply to every message.]`}\n\n[Previous messages]\n${threadContext}\n\n[Current message]\n${messageText}`;
3101
- runtime?.log?.(`[tlon] Added thread context (${threadHistory.length} replies) to message`);
3102
- }
3103
- } catch (error) {
3104
- runtime?.log?.(`[tlon] Could not fetch thread context: ${error?.message ?? String(error)}`);
3105
- }
3106
- if (isGroup && groupChannel && isSummarizationRequest(messageText)) try {
3107
- const history = await getChannelHistory(api, groupChannel, 50, runtime);
3108
- if (history.length === 0) {
3109
- const noHistoryMsg = "I couldn't fetch any messages for this channel. It might be empty or there might be a permissions issue.";
3110
- if (isGroup) {
3111
- const parsed = parseChannelNest(groupChannel);
3112
- if (parsed) await sendGroupMessage({
3113
- api,
3114
- fromShip: botShipName,
3115
- hostShip: parsed.hostShip,
3116
- channelName: parsed.channelName,
3117
- text: noHistoryMsg
3118
- });
3119
- } else await sendDm({
3120
- api,
3121
- fromShip: botShipName,
3122
- toShip: senderShip,
3123
- text: noHistoryMsg
3124
- });
3125
- return;
3126
- }
3127
- const historyText = history.map((msg) => `[${new Date(msg.timestamp).toLocaleString()}] ${msg.author}: ${msg.content}`).join("\n");
3128
- messageText = `Please summarize this channel conversation (${history.length} recent messages):\n\n${historyText}\n\nProvide a concise summary highlighting:
3129
- 1. Main topics discussed
3130
- 2. Key decisions or conclusions
3131
- 3. Action items if any
3132
- 4. Notable participants`;
3133
- } catch (error) {
3134
- const errorMsg = `Sorry, I encountered an error while fetching the channel history: ${error?.message ?? String(error)}`;
3135
- if (isGroup && groupChannel) {
3136
- const parsed = parseChannelNest(groupChannel);
3137
- if (parsed) await sendGroupMessage({
3138
- api,
3139
- fromShip: botShipName,
3140
- hostShip: parsed.hostShip,
3141
- channelName: parsed.channelName,
3142
- text: errorMsg
3143
- });
3144
- } else await sendDm({
3145
- api,
3146
- fromShip: botShipName,
3147
- toShip: senderShip,
3148
- text: errorMsg
3149
- });
3150
- return;
3151
- }
3152
- const route = core.channel.routing.resolveAgentRoute({
3153
- cfg,
3154
- channel: "tlon",
3155
- accountId: opts.accountId ?? void 0,
3156
- peer: {
3157
- kind: isGroup ? "group" : "direct",
3158
- id: isGroup ? groupChannel ?? senderShip : senderShip
3159
- }
3160
- });
3161
- if (!isGroup) {
3162
- const sessionKey = route.sessionKey;
3163
- if (!dmSendersBySession.has(sessionKey)) dmSendersBySession.set(sessionKey, /* @__PURE__ */ new Set());
3164
- const senders = dmSendersBySession.get(sessionKey);
3165
- if (senders.size > 0 && !senders.has(senderShip)) {
3166
- runtime.log?.("[tlon] ⚠️ SECURITY: Multiple users sharing DM session. Configure \"session.dmScope: per-channel-peer\" in MoldClaw config.");
3167
- if (!sharedSessionWarningSent && effectiveOwnerShip) {
3168
- sharedSessionWarningSent = true;
3169
- sendDm({
3170
- api,
3171
- fromShip: botShipName,
3172
- toShip: effectiveOwnerShip,
3173
- text: "⚠️ Security Warning: Multiple users are sharing a DM session with this bot. This can leak conversation context between users.\n\nFix: Add to your MoldClaw config:\nsession:\n dmScope: \"per-channel-peer\"\n\nDocs: https://docs.moldclaw.ai/concepts/session#secure-dm-mode"
3174
- }).catch((err) => runtime.error?.(`[tlon] Failed to send security warning to owner: ${err}`));
3175
- }
3176
- }
3177
- senders.add(senderShip);
3178
- }
3179
- const senderRole = isOwner(senderShip) ? "owner" : "user";
3180
- const fromLabel = isGroup ? `${senderShip} [${senderRole}] in ${channelNest}` : `${senderShip} [${senderRole}]`;
3181
- const shouldComputeAuth = core.channel.commands.shouldComputeCommandAuthorized(messageText, cfg);
3182
- let commandAuthorized = false;
3183
- if (shouldComputeAuth) {
3184
- const useAccessGroups = cfg.commands?.useAccessGroups !== false;
3185
- const senderIsOwner = isOwner(senderShip);
3186
- commandAuthorized = core.channel.commands.resolveCommandAuthorizedFromAuthorizers({
3187
- useAccessGroups,
3188
- authorizers: [{
3189
- configured: Boolean(effectiveOwnerShip),
3190
- allowed: senderIsOwner
3191
- }]
3192
- });
3193
- if (!commandAuthorized) console.log(`[tlon] Command attempt denied: ${senderShip} is not owner (owner=${effectiveOwnerShip ?? "not configured"})`);
3194
- }
3195
- let bodyWithAttachments = messageText;
3196
- if (attachments.length > 0) bodyWithAttachments = attachments.map((a) => `[media attached: ${a.path} (${a.contentType}) | ${a.path}]`).join("\n") + "\n" + messageText;
3197
- const body = core.channel.reply.formatAgentEnvelope({
3198
- channel: "Tlon",
3199
- from: fromLabel,
3200
- timestamp,
3201
- body: bodyWithAttachments
3202
- });
3203
- const commandBody = isGroup ? stripBotMention(messageText, botShipName) : messageText;
3204
- const ctxPayload = core.channel.reply.finalizeInboundContext({
3205
- Body: body,
3206
- RawBody: messageText,
3207
- CommandBody: commandBody,
3208
- From: isGroup ? `tlon:group:${groupChannel}` : `tlon:${senderShip}`,
3209
- To: `tlon:${botShipName}`,
3210
- SessionKey: route.sessionKey,
3211
- AccountId: route.accountId,
3212
- ChatType: isGroup ? "group" : "direct",
3213
- ConversationLabel: fromLabel,
3214
- SenderName: senderShip,
3215
- SenderId: senderShip,
3216
- SenderRole: senderRole,
3217
- CommandAuthorized: commandAuthorized,
3218
- CommandSource: "text",
3219
- Provider: "tlon",
3220
- Surface: "tlon",
3221
- MessageSid: messageId,
3222
- ...attachments.length > 0 && { Attachments: attachments },
3223
- OriginatingChannel: "tlon",
3224
- OriginatingTo: `tlon:${isGroup ? groupChannel : botShipName}`,
3225
- ...parentId && {
3226
- ThreadId: String(parentId),
3227
- ReplyToId: String(parentId)
3228
- }
3229
- });
3230
- const dispatchStartTime = Date.now();
3231
- const responsePrefix = core.channel.reply.resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix;
3232
- const humanDelay = core.channel.reply.resolveHumanDelayConfig(cfg, route.agentId);
3233
- await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
3234
- ctx: ctxPayload,
3235
- cfg,
3236
- dispatcherOptions: {
3237
- responsePrefix,
3238
- humanDelay,
3239
- deliver: async (payload) => {
3240
- let replyText = payload.text;
3241
- if (!replyText) return;
3242
- if (effectiveShowModelSig) {
3243
- const extPayload = payload;
3244
- const extRoute = route;
3245
- const defaultModel = cfg.agents?.defaults?.model;
3246
- const modelInfo = extPayload.metadata?.model || extPayload.model || extRoute.model || (typeof defaultModel === "string" ? defaultModel : defaultModel?.primary);
3247
- extPayload.metadata?.model || extPayload.model || extRoute.model || typeof defaultModel === "string" || defaultModel?.primary;
3248
- replyText = `${replyText}\n\n_[Generated by ${formatModelName(modelInfo)}]_`;
3249
- }
3250
- if (isGroup && groupChannel) {
3251
- const parsed = parseChannelNest(groupChannel);
3252
- if (!parsed) return;
3253
- await sendGroupMessage({
3254
- api,
3255
- fromShip: botShipName,
3256
- hostShip: parsed.hostShip,
3257
- channelName: parsed.channelName,
3258
- text: replyText,
3259
- replyToId: parentId ?? void 0
3260
- });
3261
- if (parentId) {
3262
- participatedThreads.add(String(parentId));
3263
- runtime.log?.(`[tlon] Now tracking thread for future replies: ${parentId}`);
3264
- }
3265
- } else await sendDm({
3266
- api,
3267
- fromShip: botShipName,
3268
- toShip: senderShip,
3269
- text: replyText
3270
- });
3271
- },
3272
- onError: (err, info) => {
3273
- const dispatchDuration = Date.now() - dispatchStartTime;
3274
- runtime.error?.(`[tlon] ${info.kind} reply failed after ${dispatchDuration}ms: ${String(err)}`);
3275
- }
3276
- }
3277
- });
3278
- };
3279
- const watchedChannels = new Set(groupChannels);
3280
- const handleChannelsFirehose = async (event) => {
3281
- try {
3282
- const nest = event?.nest;
3283
- if (!nest) return;
3284
- if (!watchedChannels.has(nest)) return;
3285
- const response = event?.response;
3286
- if (!response) return;
3287
- const essay = response?.post?.["r-post"]?.set?.essay;
3288
- const memo = response?.post?.["r-post"]?.reply?.["r-reply"]?.set?.memo;
3289
- if (!essay && !memo) return;
3290
- const content = memo || essay;
3291
- const isThreadReply = Boolean(memo);
3292
- const messageId = isThreadReply ? response?.post?.["r-post"]?.reply?.id : response?.post?.id;
3293
- if (!processedTracker.mark(messageId)) return;
3294
- const senderShip = normalizeShip(content.author ?? "");
3295
- if (!senderShip || senderShip === botShipName) return;
3296
- const rawText = extractMessageText(content.content);
3297
- if (!rawText.trim()) return;
3298
- cacheMessage(nest, {
3299
- author: senderShip,
3300
- content: rawText,
3301
- timestamp: content.sent || Date.now(),
3302
- id: messageId
3303
- });
3304
- const seal = isThreadReply ? response?.post?.["r-post"]?.reply?.["r-reply"]?.set?.seal : response?.post?.["r-post"]?.set?.seal;
3305
- const parentId = seal?.["parent-id"] || seal?.parent || null;
3306
- const mentioned = isBotMentioned(rawText, botShipName, botNickname ?? void 0);
3307
- const inParticipatedThread = isThreadReply && parentId && participatedThreads.has(String(parentId));
3308
- if (!mentioned && !inParticipatedThread) return;
3309
- if (inParticipatedThread && !mentioned) runtime.log?.(`[tlon] Responding to thread we participated in (no mention): ${parentId}`);
3310
- if (isOwner(senderShip)) runtime.log?.(`[tlon] Owner ${senderShip} is always allowed in channels`);
3311
- else {
3312
- const { mode, allowedShips } = resolveChannelAuthorization(cfg, nest, currentSettings);
3313
- if (mode === "restricted") {
3314
- if (!allowedShips.map(normalizeShip).includes(senderShip)) {
3315
- if (effectiveOwnerShip) await queueApprovalRequest(createPendingApproval({
3316
- type: "channel",
3317
- requestingShip: senderShip,
3318
- channelNest: nest,
3319
- messagePreview: rawText.substring(0, 100),
3320
- originalMessage: {
3321
- messageId: messageId ?? "",
3322
- messageText: rawText,
3323
- messageContent: content.content,
3324
- timestamp: content.sent || Date.now(),
3325
- parentId: parentId ?? void 0,
3326
- isThreadReply
3327
- }
3328
- }));
3329
- else runtime.log?.(`[tlon] Access denied: ${senderShip} in ${nest} (allowed: ${allowedShips.join(", ")})`);
3330
- return;
3331
- }
3332
- }
3333
- }
3334
- const messageText = await resolveAllCites(content.content) + rawText;
3335
- const parsed = parseChannelNest(nest);
3336
- await processMessage({
3337
- messageId: messageId ?? "",
3338
- senderShip,
3339
- messageText,
3340
- messageContent: content.content,
3341
- isGroup: true,
3342
- channelNest: nest,
3343
- hostShip: parsed?.hostShip,
3344
- channelName: parsed?.channelName,
3345
- timestamp: content.sent || Date.now(),
3346
- parentId,
3347
- isThreadReply
3348
- });
3349
- } catch (error) {
3350
- runtime.error?.(`[tlon] Error handling channel firehose event: ${error?.message ?? String(error)}`);
3351
- }
3352
- };
3353
- const processedDmInvites = /* @__PURE__ */ new Set();
3354
- const handleChatFirehose = async (event) => {
3355
- try {
3356
- if (Array.isArray(event)) {
3357
- for (const invite of event) {
3358
- const ship = normalizeShip(invite.ship || "");
3359
- if (!ship || processedDmInvites.has(ship)) continue;
3360
- if (isOwner(ship)) {
3361
- try {
3362
- await api.poke({
3363
- app: "chat",
3364
- mark: "chat-dm-rsvp",
3365
- json: {
3366
- ship,
3367
- ok: true
3368
- }
3369
- });
3370
- processedDmInvites.add(ship);
3371
- runtime.log?.(`[tlon] Auto-accepted DM invite from owner ${ship}`);
3372
- } catch (err) {
3373
- runtime.error?.(`[tlon] Failed to auto-accept DM from owner: ${String(err)}`);
3374
- }
3375
- continue;
3376
- }
3377
- if (effectiveAutoAcceptDmInvites && isDmAllowed(ship, effectiveDmAllowlist)) {
3378
- try {
3379
- await api.poke({
3380
- app: "chat",
3381
- mark: "chat-dm-rsvp",
3382
- json: {
3383
- ship,
3384
- ok: true
3385
- }
3386
- });
3387
- processedDmInvites.add(ship);
3388
- runtime.log?.(`[tlon] Auto-accepted DM invite from ${ship}`);
3389
- } catch (err) {
3390
- runtime.error?.(`[tlon] Failed to auto-accept DM from ${ship}: ${String(err)}`);
3391
- }
3392
- continue;
3393
- }
3394
- if (effectiveOwnerShip && !isDmAllowed(ship, effectiveDmAllowlist)) {
3395
- await queueApprovalRequest(createPendingApproval({
3396
- type: "dm",
3397
- requestingShip: ship,
3398
- messagePreview: "(DM invite - no message yet)"
3399
- }));
3400
- processedDmInvites.add(ship);
3401
- }
3402
- }
3403
- return;
3404
- }
3405
- if (!("whom" in event) || !("response" in event)) return;
3406
- const whom = event.whom;
3407
- const messageId = event.id;
3408
- const essay = event.response?.add?.essay;
3409
- if (!essay) return;
3410
- if (!processedTracker.mark(messageId)) return;
3411
- const authorShip = normalizeShip(essay.author ?? "");
3412
- const partnerShip = extractDmPartnerShip(whom);
3413
- const senderShip = partnerShip || authorShip;
3414
- if (authorShip === botShipName) return;
3415
- if (!senderShip || senderShip === botShipName) return;
3416
- if (authorShip && partnerShip && authorShip !== partnerShip) runtime.log?.(`[tlon] DM ship mismatch (author=${authorShip}, partner=${partnerShip}) - routing to partner`);
3417
- const rawText = extractMessageText(essay.content);
3418
- if (!rawText.trim()) return;
3419
- const resolvedMessageText = await resolveAllCites(essay.content) + rawText;
3420
- const messageText = rawText;
3421
- if (isOwner(senderShip) && isApprovalResponse(messageText)) {
3422
- if (await handleApprovalResponse(messageText)) {
3423
- runtime.log?.(`[tlon] Processed approval response from owner: ${messageText}`);
3424
- return;
3425
- }
3426
- }
3427
- if (isOwner(senderShip) && isAdminCommand(messageText)) {
3428
- if (await handleAdminCommand(messageText)) {
3429
- runtime.log?.(`[tlon] Processed admin command from owner: ${messageText}`);
3430
- return;
3431
- }
3432
- }
3433
- if (isOwner(senderShip)) {
3434
- runtime.log?.(`[tlon] Processing DM from owner ${senderShip}`);
3435
- await processMessage({
3436
- messageId: messageId ?? "",
3437
- senderShip,
3438
- messageText: resolvedMessageText,
3439
- messageContent: essay.content,
3440
- isGroup: false,
3441
- timestamp: essay.sent || Date.now()
3442
- });
3443
- return;
3444
- }
3445
- if (!isDmAllowed(senderShip, effectiveDmAllowlist)) {
3446
- if (effectiveOwnerShip) await queueApprovalRequest(createPendingApproval({
3447
- type: "dm",
3448
- requestingShip: senderShip,
3449
- messagePreview: messageText.substring(0, 100),
3450
- originalMessage: {
3451
- messageId: messageId ?? "",
3452
- messageText,
3453
- messageContent: essay.content,
3454
- timestamp: essay.sent || Date.now()
3455
- }
3456
- }));
3457
- else runtime.log?.(`[tlon] Blocked DM from ${senderShip}: not in allowlist`);
3458
- return;
3459
- }
3460
- await processMessage({
3461
- messageId: messageId ?? "",
3462
- senderShip,
3463
- messageText: resolvedMessageText,
3464
- messageContent: essay.content,
3465
- isGroup: false,
3466
- timestamp: essay.sent || Date.now()
3467
- });
3468
- } catch (error) {
3469
- runtime.error?.(`[tlon] Error handling chat firehose event: ${error?.message ?? String(error)}`);
3470
- }
3471
- };
3472
- try {
3473
- runtime.log?.("[tlon] Subscribing to firehose updates...");
3474
- await api.subscribe({
3475
- app: "channels",
3476
- path: "/v2",
3477
- event: handleChannelsFirehose,
3478
- err: (error) => {
3479
- runtime.error?.(`[tlon] Channels firehose error: ${String(error)}`);
3480
- },
3481
- quit: () => {
3482
- runtime.log?.("[tlon] Channels firehose subscription ended");
3483
- }
3484
- });
3485
- runtime.log?.("[tlon] Subscribed to channels firehose (/v2)");
3486
- await api.subscribe({
3487
- app: "chat",
3488
- path: "/v3",
3489
- event: handleChatFirehose,
3490
- err: (error) => {
3491
- runtime.error?.(`[tlon] Chat firehose error: ${String(error)}`);
3492
- },
3493
- quit: () => {
3494
- runtime.log?.("[tlon] Chat firehose subscription ended");
3495
- }
3496
- });
3497
- runtime.log?.("[tlon] Subscribed to chat firehose (/v3)");
3498
- await api.subscribe({
3499
- app: "contacts",
3500
- path: "/v1/news",
3501
- event: (event) => {
3502
- try {
3503
- if (event?.self) {
3504
- const selfUpdate = event.self;
3505
- if (selfUpdate?.contact?.nickname?.value !== void 0) {
3506
- const newNickname = selfUpdate.contact.nickname.value || null;
3507
- if (newNickname !== botNickname) {
3508
- botNickname = newNickname;
3509
- runtime.log?.(`[tlon] Nickname updated: ${botNickname}`);
3510
- }
3511
- }
3512
- }
3513
- } catch (error) {
3514
- runtime.error?.(`[tlon] Error handling contacts event: ${error?.message ?? String(error)}`);
3515
- }
3516
- },
3517
- err: (error) => {
3518
- runtime.error?.(`[tlon] Contacts subscription error: ${String(error)}`);
3519
- },
3520
- quit: () => {
3521
- runtime.log?.("[tlon] Contacts subscription ended");
3522
- }
3523
- });
3524
- runtime.log?.("[tlon] Subscribed to contacts updates (/v1/news)");
3525
- settingsManager.onChange((newSettings) => {
3526
- currentSettings = newSettings;
3527
- if (newSettings.groupChannels?.length) {
3528
- const newChannels = newSettings.groupChannels;
3529
- for (const ch of newChannels) if (!watchedChannels.has(ch)) {
3530
- watchedChannels.add(ch);
3531
- runtime.log?.(`[tlon] Settings: now watching channel ${ch}`);
3532
- }
3533
- }
3534
- if (newSettings.dmAllowlist !== void 0) {
3535
- effectiveDmAllowlist = newSettings.dmAllowlist;
3536
- runtime.log?.(`[tlon] Settings: dmAllowlist updated to ${effectiveDmAllowlist.join(", ")}`);
3537
- }
3538
- if (newSettings.showModelSig !== void 0) {
3539
- effectiveShowModelSig = newSettings.showModelSig;
3540
- runtime.log?.(`[tlon] Settings: showModelSig = ${effectiveShowModelSig}`);
3541
- }
3542
- if (newSettings.autoAcceptDmInvites !== void 0) {
3543
- effectiveAutoAcceptDmInvites = newSettings.autoAcceptDmInvites;
3544
- runtime.log?.(`[tlon] Settings: autoAcceptDmInvites = ${effectiveAutoAcceptDmInvites}`);
3545
- }
3546
- if (newSettings.autoAcceptGroupInvites !== void 0) {
3547
- effectiveAutoAcceptGroupInvites = newSettings.autoAcceptGroupInvites;
3548
- runtime.log?.(`[tlon] Settings: autoAcceptGroupInvites = ${effectiveAutoAcceptGroupInvites}`);
3549
- }
3550
- if (newSettings.groupInviteAllowlist !== void 0) {
3551
- effectiveGroupInviteAllowlist = newSettings.groupInviteAllowlist;
3552
- runtime.log?.(`[tlon] Settings: groupInviteAllowlist updated to ${effectiveGroupInviteAllowlist.join(", ")}`);
3553
- }
3554
- if (newSettings.defaultAuthorizedShips !== void 0) runtime.log?.(`[tlon] Settings: defaultAuthorizedShips updated to ${(newSettings.defaultAuthorizedShips || []).join(", ")}`);
3555
- if (newSettings.autoDiscoverChannels !== void 0) {
3556
- effectiveAutoDiscoverChannels = newSettings.autoDiscoverChannels;
3557
- runtime.log?.(`[tlon] Settings: autoDiscoverChannels = ${effectiveAutoDiscoverChannels}`);
3558
- }
3559
- if (newSettings.ownerShip !== void 0) {
3560
- effectiveOwnerShip = newSettings.ownerShip ? normalizeShip(newSettings.ownerShip) : account.ownerShip ? normalizeShip(account.ownerShip) : null;
3561
- runtime.log?.(`[tlon] Settings: ownerShip = ${effectiveOwnerShip}`);
3562
- }
3563
- if (newSettings.pendingApprovals !== void 0) {
3564
- pendingApprovals = newSettings.pendingApprovals;
3565
- runtime.log?.(`[tlon] Settings: pendingApprovals updated (${pendingApprovals.length} items)`);
3566
- }
3567
- });
3568
- try {
3569
- await settingsManager.startSubscription();
3570
- } catch (err) {
3571
- runtime.log?.(`[tlon] Settings subscription not available: ${String(err)}`);
3572
- }
3573
- try {
3574
- await api.subscribe({
3575
- app: "groups",
3576
- path: "/groups/ui",
3577
- event: async (event) => {
3578
- try {
3579
- if (event && typeof event === "object") {
3580
- if (event.channels && typeof event.channels === "object") {
3581
- const channels = event.channels;
3582
- for (const [channelNest, _channelData] of Object.entries(channels)) {
3583
- if (!channelNest.startsWith("chat/")) continue;
3584
- if (!watchedChannels.has(channelNest)) {
3585
- watchedChannels.add(channelNest);
3586
- runtime.log?.(`[tlon] Auto-detected new channel (invite accepted): ${channelNest}`);
3587
- if (effectiveAutoAcceptGroupInvites) try {
3588
- const currentChannels = currentSettings.groupChannels || [];
3589
- if (!currentChannels.includes(channelNest)) {
3590
- const updatedChannels = [...currentChannels, channelNest];
3591
- await api.poke({
3592
- app: "settings",
3593
- mark: "settings-event",
3594
- json: { "put-entry": {
3595
- "bucket-key": "tlon",
3596
- "entry-key": "groupChannels",
3597
- value: updatedChannels,
3598
- desk: "moltbot"
3599
- } }
3600
- });
3601
- runtime.log?.(`[tlon] Persisted ${channelNest} to settings store`);
3602
- }
3603
- } catch (err) {
3604
- runtime.error?.(`[tlon] Failed to persist channel to settings: ${String(err)}`);
3605
- }
3606
- }
3607
- }
3608
- }
3609
- if (event.join && typeof event.join === "object") {
3610
- const join = event.join;
3611
- if (join.channels) for (const channelNest of join.channels) {
3612
- if (!channelNest.startsWith("chat/")) continue;
3613
- if (!watchedChannels.has(channelNest)) {
3614
- watchedChannels.add(channelNest);
3615
- runtime.log?.(`[tlon] Auto-detected joined channel: ${channelNest}`);
3616
- if (effectiveAutoAcceptGroupInvites) try {
3617
- const currentChannels = currentSettings.groupChannels || [];
3618
- if (!currentChannels.includes(channelNest)) {
3619
- const updatedChannels = [...currentChannels, channelNest];
3620
- await api.poke({
3621
- app: "settings",
3622
- mark: "settings-event",
3623
- json: { "put-entry": {
3624
- "bucket-key": "tlon",
3625
- "entry-key": "groupChannels",
3626
- value: updatedChannels,
3627
- desk: "moltbot"
3628
- } }
3629
- });
3630
- runtime.log?.(`[tlon] Persisted ${channelNest} to settings store`);
3631
- }
3632
- } catch (err) {
3633
- runtime.error?.(`[tlon] Failed to persist channel to settings: ${String(err)}`);
3634
- }
3635
- }
3636
- }
3637
- }
3638
- }
3639
- } catch (error) {
3640
- runtime.error?.(`[tlon] Error handling groups-ui event: ${error?.message ?? String(error)}`);
3641
- }
3642
- },
3643
- err: (error) => {
3644
- runtime.error?.(`[tlon] Groups-ui subscription error: ${String(error)}`);
3645
- },
3646
- quit: () => {
3647
- runtime.log?.("[tlon] Groups-ui subscription ended");
3648
- }
3649
- });
3650
- runtime.log?.("[tlon] Subscribed to groups-ui for real-time channel detection");
3651
- } catch (err) {
3652
- runtime.log?.(`[tlon] Groups-ui subscription failed (will rely on polling): ${String(err)}`);
3653
- }
3654
- {
3655
- const processedGroupInvites = /* @__PURE__ */ new Set();
3656
- const processPendingInvites = async (foreigns) => {
3657
- if (!foreigns || typeof foreigns !== "object") return;
3658
- for (const [groupFlag, foreign] of Object.entries(foreigns)) {
3659
- if (processedGroupInvites.has(groupFlag)) continue;
3660
- if (!foreign.invites || foreign.invites.length === 0) continue;
3661
- const validInvite = foreign.invites.find((inv) => inv.valid);
3662
- if (!validInvite) continue;
3663
- const inviterShip = validInvite.from;
3664
- const normalizedInviter = normalizeShip(inviterShip);
3665
- if (isOwner(inviterShip)) {
3666
- try {
3667
- await api.poke({
3668
- app: "groups",
3669
- mark: "group-join",
3670
- json: {
3671
- flag: groupFlag,
3672
- "join-all": true
3673
- }
3674
- });
3675
- processedGroupInvites.add(groupFlag);
3676
- runtime.log?.(`[tlon] Auto-accepted group invite from owner: ${groupFlag}`);
3677
- } catch (err) {
3678
- runtime.error?.(`[tlon] Failed to accept group invite from owner: ${String(err)}`);
3679
- }
3680
- continue;
3681
- }
3682
- if (!effectiveAutoAcceptGroupInvites) {
3683
- if (effectiveOwnerShip) {
3684
- await queueApprovalRequest(createPendingApproval({
3685
- type: "group",
3686
- requestingShip: inviterShip,
3687
- groupFlag
3688
- }));
3689
- processedGroupInvites.add(groupFlag);
3690
- }
3691
- continue;
3692
- }
3693
- if (!(effectiveGroupInviteAllowlist.length > 0 ? effectiveGroupInviteAllowlist.map((s) => normalizeShip(s)).some((s) => s === normalizedInviter) : false)) {
3694
- if (effectiveOwnerShip) {
3695
- await queueApprovalRequest(createPendingApproval({
3696
- type: "group",
3697
- requestingShip: inviterShip,
3698
- groupFlag
3699
- }));
3700
- processedGroupInvites.add(groupFlag);
3701
- } else {
3702
- runtime.log?.(`[tlon] Rejected group invite from ${inviterShip} (not in groupInviteAllowlist): ${groupFlag}`);
3703
- processedGroupInvites.add(groupFlag);
3704
- }
3705
- continue;
3706
- }
3707
- try {
3708
- await api.poke({
3709
- app: "groups",
3710
- mark: "group-join",
3711
- json: {
3712
- flag: groupFlag,
3713
- "join-all": true
3714
- }
3715
- });
3716
- processedGroupInvites.add(groupFlag);
3717
- runtime.log?.(`[tlon] Auto-accepted group invite: ${groupFlag} (from ${validInvite.from})`);
3718
- } catch (err) {
3719
- runtime.error?.(`[tlon] Failed to auto-accept group ${groupFlag}: ${String(err)}`);
3720
- }
3721
- }
3722
- };
3723
- if (initForeigns) await processPendingInvites(initForeigns);
3724
- try {
3725
- await api.subscribe({
3726
- app: "groups",
3727
- path: "/v1/foreigns",
3728
- event: (data) => {
3729
- (async () => {
3730
- try {
3731
- await processPendingInvites(data);
3732
- } catch (error) {
3733
- runtime.error?.(`[tlon] Error handling foreigns event: ${error?.message ?? String(error)}`);
3734
- }
3735
- })();
3736
- },
3737
- err: (error) => {
3738
- runtime.error?.(`[tlon] Foreigns subscription error: ${String(error)}`);
3739
- },
3740
- quit: () => {
3741
- runtime.log?.("[tlon] Foreigns subscription ended");
3742
- }
3743
- });
3744
- runtime.log?.("[tlon] Subscribed to foreigns (/v1/foreigns) for auto-accepting group invites");
3745
- } catch (err) {
3746
- runtime.log?.(`[tlon] Foreigns subscription failed: ${String(err)}`);
3747
- }
3748
- }
3749
- if (effectiveAutoDiscoverChannels) {
3750
- const discoveredChannels = await fetchAllChannels(api, runtime);
3751
- for (const channelNest of discoveredChannels) watchedChannels.add(channelNest);
3752
- runtime.log?.(`[tlon] Watching ${watchedChannels.size} channel(s)`);
3753
- }
3754
- for (const channelNest of watchedChannels) runtime.log?.(`[tlon] Watching channel: ${channelNest}`);
3755
- runtime.log?.("[tlon] All subscriptions registered, connecting to SSE stream...");
3756
- await api.connect();
3757
- runtime.log?.("[tlon] Connected! Firehose subscriptions active");
3758
- const pollInterval = setInterval(async () => {
3759
- if (!opts.abortSignal?.aborted) try {
3760
- if (effectiveAutoDiscoverChannels) {
3761
- const discoveredChannels = await fetchAllChannels(api, runtime);
3762
- for (const channelNest of discoveredChannels) if (!watchedChannels.has(channelNest)) {
3763
- watchedChannels.add(channelNest);
3764
- runtime.log?.(`[tlon] Now watching new channel: ${channelNest}`);
3765
- }
3766
- }
3767
- } catch (error) {
3768
- runtime.error?.(`[tlon] Channel refresh error: ${error?.message ?? String(error)}`);
3769
- }
3770
- }, 120 * 1e3);
3771
- if (opts.abortSignal) {
3772
- const signal = opts.abortSignal;
3773
- await new Promise((resolve) => {
3774
- signal.addEventListener("abort", () => {
3775
- clearInterval(pollInterval);
3776
- resolve(null);
3777
- }, { once: true });
3778
- });
3779
- } else await new Promise(() => {});
3780
- } finally {
3781
- try {
3782
- await api?.close();
3783
- } catch (error) {
3784
- runtime.error?.(`[tlon] Cleanup error: ${error?.message ?? String(error)}`);
3785
- }
3786
- }
3787
- }
3788
- //#endregion
3789
- //#region extensions/tlon/src/urbit/upload.ts
3790
- /**
3791
- * Upload an image from a URL to Tlon storage.
3792
- */
3793
- /**
3794
- * Fetch an image from a URL and upload it to Tlon storage.
3795
- * Returns the uploaded URL, or falls back to the original URL on error.
3796
- *
3797
- * Note: configureClient must be called before using this function.
3798
- */
3799
- async function uploadImageFromUrl(imageUrl) {
3800
- try {
3801
- const url = new URL(imageUrl);
3802
- if (url.protocol !== "http:" && url.protocol !== "https:") {
3803
- console.warn(`[tlon] Rejected non-http(s) URL: ${imageUrl}`);
3804
- return imageUrl;
3805
- }
3806
- const { response, release } = await fetchWithSsrFGuard({
3807
- url: imageUrl,
3808
- init: { method: "GET" },
3809
- policy: /* @__PURE__ */ getDefaultSsrFPolicy(),
3810
- auditContext: "tlon-upload-image"
3811
- });
3812
- try {
3813
- if (!response.ok) {
3814
- console.warn(`[tlon] Failed to fetch image from ${imageUrl}: ${response.status}`);
3815
- return imageUrl;
3816
- }
3817
- const contentType = response.headers.get("content-type") || "image/png";
3818
- return (await uploadFile({
3819
- blob: await response.blob(),
3820
- fileName: new URL(imageUrl).pathname.split("/").pop() || `upload-${Date.now()}.png`,
3821
- contentType
3822
- })).url;
3823
- } finally {
3824
- await release();
3825
- }
3826
- } catch (err) {
3827
- console.warn(`[tlon] Failed to upload image, using original URL: ${err}`);
3828
- return imageUrl;
3829
- }
3830
- }
3831
- //#endregion
3832
- //#region extensions/tlon/src/channel.runtime.ts
3833
- async function createHttpPokeApi(params) {
3834
- const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(params.allowPrivateNetwork);
3835
- const cookie = await authenticate(params.url, params.code, { ssrfPolicy });
3836
- const channelPath = `/~/channel/${`${Math.floor(Date.now() / 1e3)}-${crypto.randomUUID()}`}`;
3837
- const shipName = params.ship.replace(/^~/, "");
3838
- return {
3839
- poke: async (pokeParams) => {
3840
- const pokeId = Date.now();
3841
- const pokeData = {
3842
- id: pokeId,
3843
- action: "poke",
3844
- ship: shipName,
3845
- app: pokeParams.app,
3846
- mark: pokeParams.mark,
3847
- json: pokeParams.json
3848
- };
3849
- const { response, release } = await urbitFetch({
3850
- baseUrl: params.url,
3851
- path: channelPath,
3852
- init: {
3853
- method: "PUT",
3854
- headers: {
3855
- "Content-Type": "application/json",
3856
- Cookie: cookie.split(";")[0]
3857
- },
3858
- body: JSON.stringify([pokeData])
3859
- },
3860
- ssrfPolicy,
3861
- auditContext: "tlon-poke"
3862
- });
3863
- try {
3864
- if (!response.ok && response.status !== 204) {
3865
- const errorText = await response.text();
3866
- throw new Error(`Poke failed: ${response.status} - ${errorText}`);
3867
- }
3868
- return pokeId;
3869
- } finally {
3870
- await release();
3871
- }
3872
- },
3873
- delete: async () => {}
3874
- };
3875
- }
3876
- function resolveOutboundContext(params) {
3877
- const account = resolveTlonAccount(params.cfg, params.accountId ?? void 0);
3878
- if (!account.configured || !account.ship || !account.url || !account.code) throw new Error("Tlon account not configured");
3879
- const parsed = parseTlonTarget(params.to);
3880
- if (!parsed) throw new Error(`Invalid Tlon target. Use ${formatTargetHint()}`);
3881
- return {
3882
- account,
3883
- parsed
3884
- };
3885
- }
3886
- function resolveReplyId(replyToId, threadId) {
3887
- return replyToId ?? threadId ? String(replyToId ?? threadId) : void 0;
3888
- }
3889
- async function withHttpPokeAccountApi(account, run) {
3890
- const api = await createHttpPokeApi({
3891
- url: account.url,
3892
- ship: account.ship,
3893
- code: account.code,
3894
- allowPrivateNetwork: account.allowPrivateNetwork ?? void 0
3895
- });
3896
- try {
3897
- return await run(api);
3898
- } finally {
3899
- try {
3900
- await api.delete();
3901
- } catch {}
3902
- }
3903
- }
3904
- const tlonRuntimeOutbound = {
3905
- deliveryMode: "direct",
3906
- textChunkLimit: 1e4,
3907
- resolveTarget: ({ to }) => resolveTlonOutboundTarget(to),
3908
- sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
3909
- const { account, parsed } = resolveOutboundContext({
3910
- cfg,
3911
- accountId,
3912
- to
3913
- });
3914
- return withHttpPokeAccountApi(account, async (api) => {
3915
- const fromShip = normalizeShip(account.ship);
3916
- if (parsed.kind === "dm") return await sendDm({
3917
- api,
3918
- fromShip,
3919
- toShip: parsed.ship,
3920
- text
3921
- });
3922
- return await sendGroupMessage({
3923
- api,
3924
- fromShip,
3925
- hostShip: parsed.hostShip,
3926
- channelName: parsed.channelName,
3927
- text,
3928
- replyToId: resolveReplyId(replyToId, threadId)
3929
- });
3930
- });
3931
- },
3932
- sendMedia: async ({ cfg, to, text, mediaUrl, accountId, replyToId, threadId }) => {
3933
- const { account, parsed } = resolveOutboundContext({
3934
- cfg,
3935
- accountId,
3936
- to
3937
- });
3938
- configureClient({
3939
- shipUrl: account.url,
3940
- shipName: account.ship.replace(/^~/, ""),
3941
- verbose: false,
3942
- getCode: async () => account.code
3943
- });
3944
- const uploadedUrl = mediaUrl ? await uploadImageFromUrl(mediaUrl) : void 0;
3945
- return withHttpPokeAccountApi(account, async (api) => {
3946
- const fromShip = normalizeShip(account.ship);
3947
- const story = buildMediaStory(text, uploadedUrl);
3948
- if (parsed.kind === "dm") return await sendDmWithStory({
3949
- api,
3950
- fromShip,
3951
- toShip: parsed.ship,
3952
- story
3953
- });
3954
- return await sendGroupMessageWithStory({
3955
- api,
3956
- fromShip,
3957
- hostShip: parsed.hostShip,
3958
- channelName: parsed.channelName,
3959
- story,
3960
- replyToId: resolveReplyId(replyToId, threadId)
3961
- });
3962
- });
3963
- }
3964
- };
3965
- async function probeTlonAccount(account) {
3966
- try {
3967
- const ssrfPolicy = ssrfPolicyFromAllowPrivateNetwork(account.allowPrivateNetwork);
3968
- const cookie = await authenticate(account.url, account.code, { ssrfPolicy });
3969
- const { response, release } = await urbitFetch({
3970
- baseUrl: account.url,
3971
- path: "/~/name",
3972
- init: {
3973
- method: "GET",
3974
- headers: { Cookie: cookie }
3975
- },
3976
- ssrfPolicy,
3977
- timeoutMs: 3e4,
3978
- auditContext: "tlon-probe-account"
3979
- });
3980
- try {
3981
- if (!response.ok) return {
3982
- ok: false,
3983
- error: `Name request failed: ${response.status}`
3984
- };
3985
- return { ok: true };
3986
- } finally {
3987
- await release();
3988
- }
3989
- } catch (error) {
3990
- return {
3991
- ok: false,
3992
- error: error?.message ?? String(error)
3993
- };
3994
- }
3995
- }
3996
- async function startTlonGatewayAccount(ctx) {
3997
- const account = ctx.account;
3998
- ctx.setStatus({
3999
- accountId: account.accountId,
4000
- ship: account.ship,
4001
- url: account.url
4002
- });
4003
- ctx.log?.info(`[${account.accountId}] starting Tlon provider for ${account.ship ?? "tlon"}`);
4004
- return monitorTlonProvider({
4005
- runtime: ctx.runtime,
4006
- abortSignal: ctx.abortSignal,
4007
- accountId: account.accountId
4008
- });
4009
- }
4010
- //#endregion
4011
- export { probeTlonAccount, startTlonGatewayAccount, tlonRuntimeOutbound, tlonSetupWizard };