@spinabot/brigade 1.6.1 → 1.8.0

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 (339) hide show
  1. package/dist/agents/agent-loop.d.ts +13 -0
  2. package/dist/agents/agent-loop.d.ts.map +1 -1
  3. package/dist/agents/agent-loop.js +5 -0
  4. package/dist/agents/agent-loop.js.map +1 -1
  5. package/dist/agents/channels/access-control/group-tool-policy.d.ts +73 -0
  6. package/dist/agents/channels/access-control/group-tool-policy.d.ts.map +1 -0
  7. package/dist/agents/channels/access-control/group-tool-policy.js +193 -0
  8. package/dist/agents/channels/access-control/group-tool-policy.js.map +1 -0
  9. package/dist/agents/channels/access-control/index.d.ts +1 -0
  10. package/dist/agents/channels/access-control/index.d.ts.map +1 -1
  11. package/dist/agents/channels/access-control/index.js +1 -0
  12. package/dist/agents/channels/access-control/index.js.map +1 -1
  13. package/dist/agents/channels/bluebubbles/account-config.d.ts +253 -0
  14. package/dist/agents/channels/bluebubbles/account-config.d.ts.map +1 -0
  15. package/dist/agents/channels/bluebubbles/account-config.js +486 -0
  16. package/dist/agents/channels/bluebubbles/account-config.js.map +1 -0
  17. package/dist/agents/channels/bluebubbles/account-registry.d.ts +33 -0
  18. package/dist/agents/channels/bluebubbles/account-registry.d.ts.map +1 -0
  19. package/dist/agents/channels/bluebubbles/account-registry.js +46 -0
  20. package/dist/agents/channels/bluebubbles/account-registry.js.map +1 -0
  21. package/dist/agents/channels/bluebubbles/adapter.d.ts +45 -0
  22. package/dist/agents/channels/bluebubbles/adapter.d.ts.map +1 -0
  23. package/dist/agents/channels/bluebubbles/adapter.js +366 -0
  24. package/dist/agents/channels/bluebubbles/adapter.js.map +1 -0
  25. package/dist/agents/channels/bluebubbles/catchup-cursor.d.ts +52 -0
  26. package/dist/agents/channels/bluebubbles/catchup-cursor.d.ts.map +1 -0
  27. package/dist/agents/channels/bluebubbles/catchup-cursor.js +118 -0
  28. package/dist/agents/channels/bluebubbles/catchup-cursor.js.map +1 -0
  29. package/dist/agents/channels/bluebubbles/catchup.d.ts +114 -0
  30. package/dist/agents/channels/bluebubbles/catchup.d.ts.map +1 -0
  31. package/dist/agents/channels/bluebubbles/catchup.js +220 -0
  32. package/dist/agents/channels/bluebubbles/catchup.js.map +1 -0
  33. package/dist/agents/channels/bluebubbles/chat.d.ts +75 -0
  34. package/dist/agents/channels/bluebubbles/chat.d.ts.map +1 -0
  35. package/dist/agents/channels/bluebubbles/chat.js +182 -0
  36. package/dist/agents/channels/bluebubbles/chat.js.map +1 -0
  37. package/dist/agents/channels/bluebubbles/connection.d.ts +95 -0
  38. package/dist/agents/channels/bluebubbles/connection.d.ts.map +1 -0
  39. package/dist/agents/channels/bluebubbles/connection.js +413 -0
  40. package/dist/agents/channels/bluebubbles/connection.js.map +1 -0
  41. package/dist/agents/channels/bluebubbles/contact-names.d.ts +79 -0
  42. package/dist/agents/channels/bluebubbles/contact-names.d.ts.map +1 -0
  43. package/dist/agents/channels/bluebubbles/contact-names.js +188 -0
  44. package/dist/agents/channels/bluebubbles/contact-names.js.map +1 -0
  45. package/dist/agents/channels/bluebubbles/debounce.d.ts +78 -0
  46. package/dist/agents/channels/bluebubbles/debounce.d.ts.map +1 -0
  47. package/dist/agents/channels/bluebubbles/debounce.js +173 -0
  48. package/dist/agents/channels/bluebubbles/debounce.js.map +1 -0
  49. package/dist/agents/channels/bluebubbles/dedupe.d.ts +25 -0
  50. package/dist/agents/channels/bluebubbles/dedupe.d.ts.map +1 -0
  51. package/dist/agents/channels/bluebubbles/dedupe.js +35 -0
  52. package/dist/agents/channels/bluebubbles/dedupe.js.map +1 -0
  53. package/dist/agents/channels/bluebubbles/effects.d.ts +17 -0
  54. package/dist/agents/channels/bluebubbles/effects.d.ts.map +1 -0
  55. package/dist/agents/channels/bluebubbles/effects.js +57 -0
  56. package/dist/agents/channels/bluebubbles/effects.js.map +1 -0
  57. package/dist/agents/channels/bluebubbles/history.d.ts +56 -0
  58. package/dist/agents/channels/bluebubbles/history.d.ts.map +1 -0
  59. package/dist/agents/channels/bluebubbles/history.js +140 -0
  60. package/dist/agents/channels/bluebubbles/history.js.map +1 -0
  61. package/dist/agents/channels/bluebubbles/index.d.ts +18 -0
  62. package/dist/agents/channels/bluebubbles/index.d.ts.map +1 -0
  63. package/dist/agents/channels/bluebubbles/index.js +18 -0
  64. package/dist/agents/channels/bluebubbles/index.js.map +1 -0
  65. package/dist/agents/channels/bluebubbles/media.d.ts +104 -0
  66. package/dist/agents/channels/bluebubbles/media.d.ts.map +1 -0
  67. package/dist/agents/channels/bluebubbles/media.js +222 -0
  68. package/dist/agents/channels/bluebubbles/media.js.map +1 -0
  69. package/dist/agents/channels/bluebubbles/messaging.d.ts +13 -0
  70. package/dist/agents/channels/bluebubbles/messaging.d.ts.map +1 -0
  71. package/dist/agents/channels/bluebubbles/messaging.js +36 -0
  72. package/dist/agents/channels/bluebubbles/messaging.js.map +1 -0
  73. package/dist/agents/channels/bluebubbles/module.d.ts +24 -0
  74. package/dist/agents/channels/bluebubbles/module.d.ts.map +1 -0
  75. package/dist/agents/channels/bluebubbles/module.js +52 -0
  76. package/dist/agents/channels/bluebubbles/module.js.map +1 -0
  77. package/dist/agents/channels/bluebubbles/normalize.d.ts +111 -0
  78. package/dist/agents/channels/bluebubbles/normalize.d.ts.map +1 -0
  79. package/dist/agents/channels/bluebubbles/normalize.js +239 -0
  80. package/dist/agents/channels/bluebubbles/normalize.js.map +1 -0
  81. package/dist/agents/channels/bluebubbles/plugin.d.ts +46 -0
  82. package/dist/agents/channels/bluebubbles/plugin.d.ts.map +1 -0
  83. package/dist/agents/channels/bluebubbles/plugin.js +242 -0
  84. package/dist/agents/channels/bluebubbles/plugin.js.map +1 -0
  85. package/dist/agents/channels/bluebubbles/probe.d.ts +79 -0
  86. package/dist/agents/channels/bluebubbles/probe.d.ts.map +1 -0
  87. package/dist/agents/channels/bluebubbles/probe.js +138 -0
  88. package/dist/agents/channels/bluebubbles/probe.js.map +1 -0
  89. package/dist/agents/channels/bluebubbles/reactions.d.ts +46 -0
  90. package/dist/agents/channels/bluebubbles/reactions.d.ts.map +1 -0
  91. package/dist/agents/channels/bluebubbles/reactions.js +207 -0
  92. package/dist/agents/channels/bluebubbles/reactions.js.map +1 -0
  93. package/dist/agents/channels/bluebubbles/send.d.ts +132 -0
  94. package/dist/agents/channels/bluebubbles/send.d.ts.map +1 -0
  95. package/dist/agents/channels/bluebubbles/send.js +327 -0
  96. package/dist/agents/channels/bluebubbles/send.js.map +1 -0
  97. package/dist/agents/channels/bluebubbles/status-issues.d.ts +57 -0
  98. package/dist/agents/channels/bluebubbles/status-issues.d.ts.map +1 -0
  99. package/dist/agents/channels/bluebubbles/status-issues.js +93 -0
  100. package/dist/agents/channels/bluebubbles/status-issues.js.map +1 -0
  101. package/dist/agents/channels/bluebubbles/types.d.ts +69 -0
  102. package/dist/agents/channels/bluebubbles/types.d.ts.map +1 -0
  103. package/dist/agents/channels/bluebubbles/types.js +118 -0
  104. package/dist/agents/channels/bluebubbles/types.js.map +1 -0
  105. package/dist/agents/channels/bluebubbles/webhook.d.ts +97 -0
  106. package/dist/agents/channels/bluebubbles/webhook.d.ts.map +1 -0
  107. package/dist/agents/channels/bluebubbles/webhook.js +249 -0
  108. package/dist/agents/channels/bluebubbles/webhook.js.map +1 -0
  109. package/dist/agents/channels/bundled-channel-metas.d.ts +13 -0
  110. package/dist/agents/channels/bundled-channel-metas.d.ts.map +1 -1
  111. package/dist/agents/channels/bundled-channel-metas.js +33 -0
  112. package/dist/agents/channels/bundled-channel-metas.js.map +1 -1
  113. package/dist/agents/channels/discord/account-config.d.ts +60 -0
  114. package/dist/agents/channels/discord/account-config.d.ts.map +1 -1
  115. package/dist/agents/channels/discord/account-config.js +89 -0
  116. package/dist/agents/channels/discord/account-config.js.map +1 -1
  117. package/dist/agents/channels/discord/adapter.d.ts +24 -1
  118. package/dist/agents/channels/discord/adapter.d.ts.map +1 -1
  119. package/dist/agents/channels/discord/adapter.js +208 -41
  120. package/dist/agents/channels/discord/adapter.js.map +1 -1
  121. package/dist/agents/channels/discord/component-blocks.d.ts +108 -0
  122. package/dist/agents/channels/discord/component-blocks.d.ts.map +1 -0
  123. package/dist/agents/channels/discord/component-blocks.js +113 -0
  124. package/dist/agents/channels/discord/component-blocks.js.map +1 -0
  125. package/dist/agents/channels/discord/components.d.ts +78 -0
  126. package/dist/agents/channels/discord/components.d.ts.map +1 -1
  127. package/dist/agents/channels/discord/components.js +89 -0
  128. package/dist/agents/channels/discord/components.js.map +1 -1
  129. package/dist/agents/channels/discord/connection.d.ts +195 -12
  130. package/dist/agents/channels/discord/connection.d.ts.map +1 -1
  131. package/dist/agents/channels/discord/connection.js +852 -38
  132. package/dist/agents/channels/discord/connection.js.map +1 -1
  133. package/dist/agents/channels/discord/directory-cache.d.ts +47 -0
  134. package/dist/agents/channels/discord/directory-cache.d.ts.map +1 -0
  135. package/dist/agents/channels/discord/directory-cache.js +131 -0
  136. package/dist/agents/channels/discord/directory-cache.js.map +1 -0
  137. package/dist/agents/channels/discord/directory-live.d.ts +61 -0
  138. package/dist/agents/channels/discord/directory-live.d.ts.map +1 -0
  139. package/dist/agents/channels/discord/directory-live.js +140 -0
  140. package/dist/agents/channels/discord/directory-live.js.map +1 -0
  141. package/dist/agents/channels/discord/format.d.ts +15 -0
  142. package/dist/agents/channels/discord/format.d.ts.map +1 -1
  143. package/dist/agents/channels/discord/format.js +56 -0
  144. package/dist/agents/channels/discord/format.js.map +1 -1
  145. package/dist/agents/channels/discord/guilds.d.ts +25 -0
  146. package/dist/agents/channels/discord/guilds.d.ts.map +1 -0
  147. package/dist/agents/channels/discord/guilds.js +46 -0
  148. package/dist/agents/channels/discord/guilds.js.map +1 -0
  149. package/dist/agents/channels/discord/inbound-extras.d.ts +166 -9
  150. package/dist/agents/channels/discord/inbound-extras.d.ts.map +1 -1
  151. package/dist/agents/channels/discord/inbound-extras.js +246 -8
  152. package/dist/agents/channels/discord/inbound-extras.js.map +1 -1
  153. package/dist/agents/channels/discord/index.d.ts +10 -3
  154. package/dist/agents/channels/discord/index.d.ts.map +1 -1
  155. package/dist/agents/channels/discord/index.js +10 -3
  156. package/dist/agents/channels/discord/index.js.map +1 -1
  157. package/dist/agents/channels/discord/modal-registry.d.ts +89 -0
  158. package/dist/agents/channels/discord/modal-registry.d.ts.map +1 -0
  159. package/dist/agents/channels/discord/modal-registry.js +104 -0
  160. package/dist/agents/channels/discord/modal-registry.js.map +1 -0
  161. package/dist/agents/channels/discord/modals.d.ts +100 -0
  162. package/dist/agents/channels/discord/modals.d.ts.map +1 -0
  163. package/dist/agents/channels/discord/modals.js +124 -0
  164. package/dist/agents/channels/discord/modals.js.map +1 -0
  165. package/dist/agents/channels/discord/permission-audit.d.ts +43 -0
  166. package/dist/agents/channels/discord/permission-audit.d.ts.map +1 -0
  167. package/dist/agents/channels/discord/permission-audit.js +192 -0
  168. package/dist/agents/channels/discord/permission-audit.js.map +1 -0
  169. package/dist/agents/channels/discord/plugin.d.ts +18 -2
  170. package/dist/agents/channels/discord/plugin.d.ts.map +1 -1
  171. package/dist/agents/channels/discord/plugin.js +73 -4
  172. package/dist/agents/channels/discord/plugin.js.map +1 -1
  173. package/dist/agents/channels/discord/probe.d.ts +23 -1
  174. package/dist/agents/channels/discord/probe.d.ts.map +1 -1
  175. package/dist/agents/channels/discord/probe.js +40 -5
  176. package/dist/agents/channels/discord/probe.js.map +1 -1
  177. package/dist/agents/channels/discord/rest-actions.d.ts +346 -0
  178. package/dist/agents/channels/discord/rest-actions.d.ts.map +1 -0
  179. package/dist/agents/channels/discord/rest-actions.js +559 -0
  180. package/dist/agents/channels/discord/rest-actions.js.map +1 -0
  181. package/dist/agents/channels/discord/rest-components.d.ts +122 -0
  182. package/dist/agents/channels/discord/rest-components.d.ts.map +1 -0
  183. package/dist/agents/channels/discord/rest-components.js +243 -0
  184. package/dist/agents/channels/discord/rest-components.js.map +1 -0
  185. package/dist/agents/channels/discord/security-audit.d.ts +29 -0
  186. package/dist/agents/channels/discord/security-audit.d.ts.map +1 -0
  187. package/dist/agents/channels/discord/security-audit.js +94 -0
  188. package/dist/agents/channels/discord/security-audit.js.map +1 -0
  189. package/dist/agents/channels/discord/security-doctor.d.ts +43 -0
  190. package/dist/agents/channels/discord/security-doctor.d.ts.map +1 -0
  191. package/dist/agents/channels/discord/security-doctor.js +83 -0
  192. package/dist/agents/channels/discord/security-doctor.js.map +1 -0
  193. package/dist/agents/channels/discord/status-issues.d.ts +37 -0
  194. package/dist/agents/channels/discord/status-issues.d.ts.map +1 -0
  195. package/dist/agents/channels/discord/status-issues.js +66 -0
  196. package/dist/agents/channels/discord/status-issues.js.map +1 -0
  197. package/dist/agents/channels/discord/subagent-thread-binding-store.d.ts +57 -0
  198. package/dist/agents/channels/discord/subagent-thread-binding-store.d.ts.map +1 -0
  199. package/dist/agents/channels/discord/subagent-thread-binding-store.js +98 -0
  200. package/dist/agents/channels/discord/subagent-thread-binding-store.js.map +1 -0
  201. package/dist/agents/channels/discord/subagent-thread-binding.d.ts +95 -0
  202. package/dist/agents/channels/discord/subagent-thread-binding.d.ts.map +1 -0
  203. package/dist/agents/channels/discord/subagent-thread-binding.js +208 -0
  204. package/dist/agents/channels/discord/subagent-thread-binding.js.map +1 -0
  205. package/dist/agents/channels/discord/system-events.d.ts +31 -0
  206. package/dist/agents/channels/discord/system-events.d.ts.map +1 -0
  207. package/dist/agents/channels/discord/system-events.js +74 -0
  208. package/dist/agents/channels/discord/system-events.js.map +1 -0
  209. package/dist/agents/channels/general-callback.d.ts +12 -0
  210. package/dist/agents/channels/general-callback.d.ts.map +1 -1
  211. package/dist/agents/channels/general-callback.js +18 -0
  212. package/dist/agents/channels/general-callback.js.map +1 -1
  213. package/dist/agents/channels/imessage/account-config.d.ts +178 -0
  214. package/dist/agents/channels/imessage/account-config.d.ts.map +1 -0
  215. package/dist/agents/channels/imessage/account-config.js +371 -0
  216. package/dist/agents/channels/imessage/account-config.js.map +1 -0
  217. package/dist/agents/channels/imessage/adapter.d.ts +36 -0
  218. package/dist/agents/channels/imessage/adapter.d.ts.map +1 -0
  219. package/dist/agents/channels/imessage/adapter.js +286 -0
  220. package/dist/agents/channels/imessage/adapter.js.map +1 -0
  221. package/dist/agents/channels/imessage/client.d.ts +99 -0
  222. package/dist/agents/channels/imessage/client.d.ts.map +1 -0
  223. package/dist/agents/channels/imessage/client.js +231 -0
  224. package/dist/agents/channels/imessage/client.js.map +1 -0
  225. package/dist/agents/channels/imessage/connection.d.ts +101 -0
  226. package/dist/agents/channels/imessage/connection.d.ts.map +1 -0
  227. package/dist/agents/channels/imessage/connection.js +367 -0
  228. package/dist/agents/channels/imessage/connection.js.map +1 -0
  229. package/dist/agents/channels/imessage/format.d.ts +45 -0
  230. package/dist/agents/channels/imessage/format.d.ts.map +1 -0
  231. package/dist/agents/channels/imessage/format.js +170 -0
  232. package/dist/agents/channels/imessage/format.js.map +1 -0
  233. package/dist/agents/channels/imessage/history.d.ts +49 -0
  234. package/dist/agents/channels/imessage/history.d.ts.map +1 -0
  235. package/dist/agents/channels/imessage/history.js +74 -0
  236. package/dist/agents/channels/imessage/history.js.map +1 -0
  237. package/dist/agents/channels/imessage/index.d.ts +25 -0
  238. package/dist/agents/channels/imessage/index.d.ts.map +1 -0
  239. package/dist/agents/channels/imessage/index.js +25 -0
  240. package/dist/agents/channels/imessage/index.js.map +1 -0
  241. package/dist/agents/channels/imessage/media.d.ts +92 -0
  242. package/dist/agents/channels/imessage/media.d.ts.map +1 -0
  243. package/dist/agents/channels/imessage/media.js +196 -0
  244. package/dist/agents/channels/imessage/media.js.map +1 -0
  245. package/dist/agents/channels/imessage/messaging.d.ts +14 -0
  246. package/dist/agents/channels/imessage/messaging.d.ts.map +1 -0
  247. package/dist/agents/channels/imessage/messaging.js +37 -0
  248. package/dist/agents/channels/imessage/messaging.js.map +1 -0
  249. package/dist/agents/channels/imessage/module.d.ts +16 -0
  250. package/dist/agents/channels/imessage/module.d.ts.map +1 -0
  251. package/dist/agents/channels/imessage/module.js +23 -0
  252. package/dist/agents/channels/imessage/module.js.map +1 -0
  253. package/dist/agents/channels/imessage/monitor.d.ts +207 -0
  254. package/dist/agents/channels/imessage/monitor.d.ts.map +1 -0
  255. package/dist/agents/channels/imessage/monitor.js +504 -0
  256. package/dist/agents/channels/imessage/monitor.js.map +1 -0
  257. package/dist/agents/channels/imessage/plugin.d.ts +53 -0
  258. package/dist/agents/channels/imessage/plugin.d.ts.map +1 -0
  259. package/dist/agents/channels/imessage/plugin.js +215 -0
  260. package/dist/agents/channels/imessage/plugin.js.map +1 -0
  261. package/dist/agents/channels/imessage/probe.d.ts +68 -0
  262. package/dist/agents/channels/imessage/probe.d.ts.map +1 -0
  263. package/dist/agents/channels/imessage/probe.js +134 -0
  264. package/dist/agents/channels/imessage/probe.js.map +1 -0
  265. package/dist/agents/channels/imessage/remote-attachments.d.ts +61 -0
  266. package/dist/agents/channels/imessage/remote-attachments.d.ts.map +1 -0
  267. package/dist/agents/channels/imessage/remote-attachments.js +131 -0
  268. package/dist/agents/channels/imessage/remote-attachments.js.map +1 -0
  269. package/dist/agents/channels/imessage/send.d.ts +61 -0
  270. package/dist/agents/channels/imessage/send.d.ts.map +1 -0
  271. package/dist/agents/channels/imessage/send.js +108 -0
  272. package/dist/agents/channels/imessage/send.js.map +1 -0
  273. package/dist/agents/channels/imessage/targets.d.ts +91 -0
  274. package/dist/agents/channels/imessage/targets.d.ts.map +1 -0
  275. package/dist/agents/channels/imessage/targets.js +245 -0
  276. package/dist/agents/channels/imessage/targets.js.map +1 -0
  277. package/dist/agents/channels/imessage/watch-error.d.ts +23 -0
  278. package/dist/agents/channels/imessage/watch-error.d.ts.map +1 -0
  279. package/dist/agents/channels/imessage/watch-error.js +69 -0
  280. package/dist/agents/channels/imessage/watch-error.js.map +1 -0
  281. package/dist/agents/channels/inbound-pipeline.d.ts +11 -0
  282. package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
  283. package/dist/agents/channels/inbound-pipeline.js +25 -4
  284. package/dist/agents/channels/inbound-pipeline.js.map +1 -1
  285. package/dist/agents/channels/manager.d.ts +9 -0
  286. package/dist/agents/channels/manager.d.ts.map +1 -1
  287. package/dist/agents/channels/manager.js.map +1 -1
  288. package/dist/agents/channels/sdk.d.ts +4 -0
  289. package/dist/agents/channels/sdk.d.ts.map +1 -1
  290. package/dist/agents/channels/sdk.js +4 -0
  291. package/dist/agents/channels/sdk.js.map +1 -1
  292. package/dist/agents/extensions/modules/index.d.ts.map +1 -1
  293. package/dist/agents/extensions/modules/index.js +12 -0
  294. package/dist/agents/extensions/modules/index.js.map +1 -1
  295. package/dist/agents/extensions/types.d.ts +7 -0
  296. package/dist/agents/extensions/types.d.ts.map +1 -1
  297. package/dist/agents/extensions/types.js.map +1 -1
  298. package/dist/agents/session-wiring.d.ts +31 -0
  299. package/dist/agents/session-wiring.d.ts.map +1 -1
  300. package/dist/agents/session-wiring.js +45 -2
  301. package/dist/agents/session-wiring.js.map +1 -1
  302. package/dist/agents/subagent-announce-delivery.d.ts +10 -0
  303. package/dist/agents/subagent-announce-delivery.d.ts.map +1 -1
  304. package/dist/agents/subagent-announce-delivery.js +1 -0
  305. package/dist/agents/subagent-announce-delivery.js.map +1 -1
  306. package/dist/agents/subagent-completion-bridge.d.ts.map +1 -1
  307. package/dist/agents/subagent-completion-bridge.js +81 -0
  308. package/dist/agents/subagent-completion-bridge.js.map +1 -1
  309. package/dist/agents/subagent-spawn.d.ts.map +1 -1
  310. package/dist/agents/subagent-spawn.js +57 -4
  311. package/dist/agents/subagent-spawn.js.map +1 -1
  312. package/dist/agents/tools/bluebubbles-action-tool.d.ts +66 -0
  313. package/dist/agents/tools/bluebubbles-action-tool.d.ts.map +1 -0
  314. package/dist/agents/tools/bluebubbles-action-tool.js +234 -0
  315. package/dist/agents/tools/bluebubbles-action-tool.js.map +1 -0
  316. package/dist/agents/tools/discord-action-tool.d.ts +224 -0
  317. package/dist/agents/tools/discord-action-tool.d.ts.map +1 -0
  318. package/dist/agents/tools/discord-action-tool.js +848 -0
  319. package/dist/agents/tools/discord-action-tool.js.map +1 -0
  320. package/dist/agents/tools/registry.d.ts.map +1 -1
  321. package/dist/agents/tools/registry.js +39 -0
  322. package/dist/agents/tools/registry.js.map +1 -1
  323. package/dist/agents/tools/sessions/index.d.ts +8 -0
  324. package/dist/agents/tools/sessions/index.d.ts.map +1 -1
  325. package/dist/agents/tools/sessions/index.js +15 -3
  326. package/dist/agents/tools/sessions/index.js.map +1 -1
  327. package/dist/buildstamp.json +1 -1
  328. package/dist/cli/commands/channels.d.ts +2 -0
  329. package/dist/cli/commands/channels.d.ts.map +1 -1
  330. package/dist/cli/commands/channels.js +58 -1
  331. package/dist/cli/commands/channels.js.map +1 -1
  332. package/dist/core/server.d.ts.map +1 -1
  333. package/dist/core/server.js +48 -2
  334. package/dist/core/server.js.map +1 -1
  335. package/dist/infra/net/fetch-guard.d.ts +24 -2
  336. package/dist/infra/net/fetch-guard.d.ts.map +1 -1
  337. package/dist/infra/net/fetch-guard.js +78 -31
  338. package/dist/infra/net/fetch-guard.js.map +1 -1
  339. package/package.json +1 -1
@@ -0,0 +1,286 @@
1
+ /**
2
+ * iMessage channel adapter.
3
+ *
4
+ * Implements the Brigade `ChannelAdapter` contract on top of the `imsg` CLI
5
+ * driven as a JSON-RPC subprocess (`connection.ts`). iMessage authenticates via
6
+ * the local Messages.app session — there is NO bot token, so enablement is just
7
+ * `channels.imessage.enabled: true` plus a runnable `imsg` binary. The adapter
8
+ * declares a `setup` wizard for the binary path (so `brigade channels add` can
9
+ * configure a non-PATH install) and has no QR/link flow.
10
+ *
11
+ * Modeled on `discord/adapter.ts`: same `isConfigured`→`start` config capture,
12
+ * same health-flag mirroring, same deferred-media passthrough on inbound, same
13
+ * chunk-then-send outbound (chunk the markdown, plain-text-ify each chunk, send).
14
+ *
15
+ * TEST SEAM: `connectImpl` overrides how the connection is built — production
16
+ * leaves it undefined and `connectIMessage` lazy-spawns the subprocess (which
17
+ * itself refuses in tests); a unit test injects a fake connection so send /
18
+ * health / inbound dispatch run with no real binary.
19
+ */
20
+ import { loadConfig } from "../../../core/config.js";
21
+ // Channel SDK barrel — the single import surface for the channel-authoring
22
+ // contract + shared helpers.
23
+ import { chunkText, } from "../sdk.js";
24
+ import { imessageChannelEnabled, listIMessageAccountIds, resolveIMessageAccount, resolveIMessageCliPath, DEFAULT_IMESSAGE_TEXT_CHUNK_LIMIT, IMESSAGE_CHANNEL_ID, IMESSAGE_DEFAULT_ACCOUNT_ID, } from "./account-config.js";
25
+ import { connectIMessage, } from "./connection.js";
26
+ import { markdownToIMessageText } from "./format.js";
27
+ /** iMessage's practical per-message text limit for chunked sends (default; config can override). */
28
+ const IMESSAGE_TEXT_LIMIT = DEFAULT_IMESSAGE_TEXT_CHUNK_LIMIT;
29
+ /** iMessage capabilities — DMs + groups, media + reply; no edit/unsend/reactions via the bridge. */
30
+ export const IMESSAGE_CAPABILITIES = {
31
+ chatTypes: ["direct", "group"],
32
+ media: true,
33
+ reply: true,
34
+ };
35
+ async function loadStartConfig() {
36
+ return loadConfig();
37
+ }
38
+ /**
39
+ * For `chunkMode: "newline"`, break an already-limit-bounded chunk into one piece
40
+ * per line (dropping blank lines), so each non-empty line is delivered as its own
41
+ * message. A line longer than `limit` is left intact (the caller already bounded
42
+ * the chunk to `limit`, so this only ever sub-divides). Returns the original
43
+ * chunk in a single-element array when it has no internal line breaks.
44
+ */
45
+ function splitChunkByNewline(chunk, limit) {
46
+ void limit;
47
+ const lines = chunk.split("\n").map((l) => l.trimEnd());
48
+ const out = lines.filter((l) => l.trim().length > 0);
49
+ return out.length > 0 ? out : [chunk];
50
+ }
51
+ export function createIMessageAdapter(opts = {}) {
52
+ const accountId = opts.accountId?.trim() || IMESSAGE_DEFAULT_ACCOUNT_ID;
53
+ const connectImpl = opts.connectImpl ?? connectIMessage;
54
+ let connection = null;
55
+ // The manager calls isConfigured(cfg, env) right before start(ctx); capture
56
+ // them so start() reads the resolved account without a second config load.
57
+ let lastConfig = null;
58
+ let lastEnv = process.env;
59
+ // Health flags mirrored from the connection lifecycle so health() never has to
60
+ // round-trip the subprocess.
61
+ let connected = false;
62
+ let closedReason = null;
63
+ // Captured from the resolved account at start() so the inbound/outbound paths
64
+ // don't re-resolve config per message.
65
+ let selfHandle = "";
66
+ let textChunkLimit = IMESSAGE_TEXT_LIMIT;
67
+ let chunkMode = "length";
68
+ const adapter = {
69
+ id: IMESSAGE_CHANNEL_ID,
70
+ label: "iMessage",
71
+ isConfigured(cfg, env) {
72
+ lastConfig = cfg;
73
+ lastEnv = env ?? process.env;
74
+ if (!imessageChannelEnabled(cfg))
75
+ return false;
76
+ // Need a resolvable `imsg` binary path (always resolves to at least the
77
+ // default "imsg"); enablement is the real gate.
78
+ if (!resolveIMessageCliPath(cfg, accountId, env ?? process.env))
79
+ return false;
80
+ // Multi-account: the plugin path owns lifecycle when >1 account; the
81
+ // legacy single adapter steps aside.
82
+ const isLegacyAdapter = accountId === IMESSAGE_DEFAULT_ACCOUNT_ID;
83
+ if (isLegacyAdapter && listIMessageAccountIds(cfg).length > 1)
84
+ return false;
85
+ return true;
86
+ },
87
+ async start(ctx) {
88
+ const cfg = lastConfig ?? (await loadStartConfig());
89
+ const account = resolveIMessageAccount(cfg, accountId, lastEnv);
90
+ selfHandle = account.selfHandle;
91
+ textChunkLimit = account.textChunkLimit;
92
+ chunkMode = account.chunkMode;
93
+ try {
94
+ const conn = await connectImpl({
95
+ account,
96
+ loadConfig: () => (lastConfig ?? cfg),
97
+ log: ctx.log,
98
+ ...(ctx.signal ? { signal: ctx.signal } : {}),
99
+ onConnected: () => {
100
+ connected = true;
101
+ closedReason = null;
102
+ ctx.log("iMessage connected");
103
+ ctx.onConnected?.();
104
+ },
105
+ onClosed: (reason) => {
106
+ connected = false;
107
+ closedReason = reason;
108
+ ctx.log(`iMessage transport closed: ${reason}`);
109
+ ctx.onLoggedOut?.();
110
+ },
111
+ onMessage: (msg) => {
112
+ // Prepend the rolling-history context block (untagged group msg) to
113
+ // the body so the agent replies INTO the conversation.
114
+ const body = msg.historyContext ? `${msg.historyContext}\n\n${msg.text}` : msg.text;
115
+ void ctx.onInbound({
116
+ channel: IMESSAGE_CHANNEL_ID,
117
+ accountId,
118
+ conversationId: msg.conversationId,
119
+ ...(msg.messageId ? { messageId: msg.messageId } : {}),
120
+ ...(msg.createdAtMs !== undefined ? { messageTimestampMs: msg.createdAtMs } : {}),
121
+ from: msg.from,
122
+ ...(msg.fromName !== undefined ? { fromName: msg.fromName } : {}),
123
+ text: body,
124
+ chatType: msg.isGroup ? "group" : "direct",
125
+ isGroup: msg.isGroup,
126
+ // Bot-handle mentions (group requireMention gate fires on these).
127
+ ...(msg.mentions && msg.mentions.length > 0 ? { mentions: msg.mentions } : {}),
128
+ ...(msg.replyTo ? { replyTo: msg.replyTo } : {}),
129
+ // Deferred media thunk rides through untouched — the pipeline
130
+ // resolves it only after the access gate admits the sender.
131
+ ...(msg.resolveMedia ? { resolveMedia: msg.resolveMedia } : {}),
132
+ raw: msg.raw,
133
+ });
134
+ },
135
+ });
136
+ connection = conn;
137
+ }
138
+ catch (err) {
139
+ connected = false;
140
+ closedReason = err instanceof Error ? err.message : String(err);
141
+ ctx.log(`iMessage failed to start: ${closedReason}`);
142
+ }
143
+ },
144
+ async stop() {
145
+ await connection?.close();
146
+ connection = null;
147
+ connected = false;
148
+ },
149
+ health() {
150
+ if (!connection) {
151
+ return { ok: false, kind: "starting", reason: "iMessage adapter is not started yet." };
152
+ }
153
+ if (!connected || !connection.isConnected()) {
154
+ return {
155
+ ok: false,
156
+ kind: "disconnected",
157
+ reason: closedReason
158
+ ? `iMessage is not connected — ${closedReason}.`
159
+ : "iMessage is reconnecting — sends will fail until the imsg bridge resumes.",
160
+ remediation: "Ensure the imsg CLI is installed and Messages.app is signed in.",
161
+ };
162
+ }
163
+ return { ok: true };
164
+ },
165
+ async sendText(conversationId, text, opts) {
166
+ if (!connection)
167
+ throw new Error("iMessage channel is not started");
168
+ // Chunk on the raw markdown (so fences/paragraphs aren't shredded), then
169
+ // plain-text-ify each chunk and send. The chunk size is config-driven
170
+ // (`textChunkLimit`); `chunkMode: "newline"` additionally breaks each chunk
171
+ // on single line boundaries (one message per line), where `length` (default)
172
+ // packs lines to the limit.
173
+ const limit = textChunkLimit > 0 ? textChunkLimit : IMESSAGE_TEXT_LIMIT;
174
+ let chunks = chunkText(text, { limit });
175
+ if (chunkMode === "newline") {
176
+ chunks = chunks.flatMap((chunk) => splitChunkByNewline(chunk, limit));
177
+ }
178
+ let first = true;
179
+ let lastMessageId;
180
+ for (const chunk of chunks) {
181
+ const body = markdownToIMessageText(chunk);
182
+ if (body.trim().length === 0)
183
+ continue;
184
+ // Native reply target applies to the FIRST chunk only.
185
+ const replyOpt = first && opts?.replyToId ? { replyToId: opts.replyToId } : {};
186
+ const sent = await connection.sendText(conversationId, body, { ...replyOpt });
187
+ if (sent.messageId)
188
+ lastMessageId = sent.messageId;
189
+ first = false;
190
+ }
191
+ return lastMessageId ? { messageId: lastMessageId } : undefined;
192
+ },
193
+ async sendMedia(conversationId, media) {
194
+ if (!connection)
195
+ throw new Error("iMessage channel is not started");
196
+ const sent = await connection.sendMedia(conversationId, media);
197
+ return sent.messageId ? { messageId: sent.messageId } : undefined;
198
+ },
199
+ // The bot's own iMessage handle (when the operator configured
200
+ // `channels.imessage.selfHandle`) — lets the central pipeline's group
201
+ // mention-gating match `msg.mentions` against the bot. Undefined when unset.
202
+ selfId() {
203
+ return selfHandle || undefined;
204
+ },
205
+ connectedAt() {
206
+ return connection?.connectedAt() ?? null;
207
+ },
208
+ // iMessage senders are phone numbers / emails on the operator's own device;
209
+ // the bot runs AS the operator (Messages.app), so the pairing card uses the
210
+ // "account" label and ownership is NOT bootstrapped from a separate bot.
211
+ pairing: { idLabel: "account" },
212
+ // iMessage has no bot token — the `imsg` binary path + Messages.app sign-in
213
+ // are the auth. `brigade channels add imessage` walks: cliPath → dmPolicy →
214
+ // allowFrom → selfHandle. The first prompt carries the macOS-permissions
215
+ // completion note (Full Disk Access + Automation) since the central setup
216
+ // surface has no separate "completion note" hook.
217
+ setup: {
218
+ credentialKeys: [
219
+ {
220
+ key: "cliPath",
221
+ prompt: "Path to the `imsg` CLI binary (leave blank to use `imsg` on PATH). " +
222
+ "Requires Messages.app signed in on this Mac, and the terminal/app running `imsg` must be granted " +
223
+ "macOS Full Disk Access (to read the Messages chat.db) + Automation permission for Messages " +
224
+ "(System Settings → Privacy & Security). Tip: list chats with `imsg chats --limit 20`.",
225
+ secret: false,
226
+ envVar: "IMSG_CLI_PATH",
227
+ },
228
+ {
229
+ key: "dmPolicy",
230
+ prompt: "Who may DM this account? pairing (owner + approved; strangers challenged — default) / " +
231
+ "allowlist (only allowFrom) / open (anyone) / disabled (drop all DMs). Leave blank for pairing.",
232
+ secret: false,
233
+ },
234
+ {
235
+ key: "allowFrom",
236
+ prompt: "Allowlist of senders for allowlist mode — handles or chat targets, comma-separated " +
237
+ "(e.g. +15555550123, user@example.com, chat_id:123). Leave blank for none.",
238
+ secret: false,
239
+ },
240
+ {
241
+ key: "selfHandle",
242
+ prompt: "This bot's OWN iMessage handle (phone or email) — used so a group message naming the bot " +
243
+ "counts as a mention for the group requireMention gate. Leave blank to skip.",
244
+ secret: false,
245
+ },
246
+ ],
247
+ validateInput(key, value) {
248
+ const v = value.trim();
249
+ if (key === "cliPath" && v && /\s$/.test(value))
250
+ return "Path must not end with whitespace.";
251
+ if (key === "dmPolicy" && v && !["pairing", "allowlist", "open", "disabled"].includes(v.toLowerCase())) {
252
+ return "dmPolicy must be one of: pairing, allowlist, open, disabled.";
253
+ }
254
+ return null;
255
+ },
256
+ buildAccountConfig(values) {
257
+ const out = { enabled: true };
258
+ const cliPath = (values.cliPath ?? "").trim();
259
+ if (cliPath)
260
+ out.cliPath = cliPath;
261
+ const dmPolicy = (values.dmPolicy ?? "").trim().toLowerCase();
262
+ if (dmPolicy && dmPolicy !== "pairing")
263
+ out.dmPolicy = dmPolicy;
264
+ const allowFrom = (values.allowFrom ?? "")
265
+ .split(/[\n,]+/g)
266
+ .map((s) => s.trim())
267
+ .filter(Boolean);
268
+ if (allowFrom.length > 0)
269
+ out.allowFrom = allowFrom;
270
+ const selfHandleVal = (values.selfHandle ?? "").trim();
271
+ if (selfHandleVal)
272
+ out.selfHandle = selfHandleVal;
273
+ return out;
274
+ },
275
+ },
276
+ capabilities: IMESSAGE_CAPABILITIES,
277
+ // iMessage has no edit/delete/react/pin via the bridge; the central
278
+ // message_action tool pre-checks `capabilities` (none advertised beyond
279
+ // reply), so this reports anything else unsupported cleanly.
280
+ async handleAction() {
281
+ return { ok: false, error: "iMessage does not support message actions" };
282
+ },
283
+ };
284
+ return adapter;
285
+ }
286
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../../src/agents/channels/imessage/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * iMessage RPC client — newline-delimited JSON-RPC 2.0 over a child process's
3
+ * stdin/stdout.
4
+ *
5
+ * The transport spawns the third-party `imsg` CLI as `imsg rpc [--db <path>]`
6
+ * and speaks JSON-RPC 2.0 framed ONE object per `\n`:
7
+ * - a request is `{ jsonrpc:"2.0", id, method, params }\n` written to stdin;
8
+ * - a line with a non-null `id` is a RESPONSE matched against the pending map;
9
+ * - a line with a `method` and NO `id` is an inbound NOTIFICATION dispatched to
10
+ * `onNotification` (the monitor subscribes to these for new messages).
11
+ *
12
+ * This is the iMessage analogue of a token-channel's transport SDK. There is a
13
+ * hard TEST SEAM: the real client REFUSES to spawn a subprocess in tests (see
14
+ * {@link isTestEnv}). Unit tests inject a {@link IMessageRpcLike} fake on the
15
+ * adapter/connection seam instead, so send / normalize / probe / dedupe are all
16
+ * exercised with NO real `imsg` binary and NO live subprocess.
17
+ */
18
+ /** A JSON-RPC error object. */
19
+ export type IMessageRpcError = {
20
+ code?: number;
21
+ message?: string;
22
+ data?: unknown;
23
+ };
24
+ /** A parsed inbound notification (a line with a `method` and no `id`). */
25
+ export type IMessageRpcNotification = {
26
+ method: string;
27
+ params?: unknown;
28
+ };
29
+ /** Cross-cutting runtime hooks the client surfaces (logging only). */
30
+ export interface IMessageRpcRuntime {
31
+ error?: (message: string) => void;
32
+ info?: (message: string) => void;
33
+ }
34
+ /** Construction options for {@link IMessageRpcClient}. */
35
+ export interface IMessageRpcClientOptions {
36
+ /** Path to the `imsg` binary. Defaults to `"imsg"` (found on PATH). */
37
+ cliPath?: string;
38
+ /** Optional chat.db override (`~`-expanded here). */
39
+ dbPath?: string;
40
+ /** Logging hooks (stderr lines, parse failures). */
41
+ runtime?: IMessageRpcRuntime;
42
+ /** Called for every inbound notification (`{ method, params }`). */
43
+ onNotification?: (msg: IMessageRpcNotification) => void;
44
+ }
45
+ /**
46
+ * The minimal transport surface the adapter / send path depend on. The real
47
+ * {@link IMessageRpcClient} implements it; tests inject a fake satisfying it.
48
+ * Keeping the dependency on this interface (NOT the concrete class) is the test
49
+ * seam — a unit test never touches a child process.
50
+ */
51
+ export interface IMessageRpcLike {
52
+ start(): Promise<void>;
53
+ stop(): Promise<void>;
54
+ request<T = unknown>(method: string, params?: unknown, opts?: {
55
+ timeoutMs?: number;
56
+ }): Promise<T>;
57
+ waitForClose(): Promise<void>;
58
+ }
59
+ /**
60
+ * True in a test environment. The real client REFUSES to spawn `imsg rpc` here
61
+ * so a stray unit test can never shell out to the binary — tests must inject a
62
+ * mock {@link IMessageRpcLike} on the seam instead.
63
+ */
64
+ export declare function isTestEnv(): boolean;
65
+ /**
66
+ * Long-lived JSON-RPC 2.0 client over an `imsg rpc` child process. A pending-id
67
+ * map matches responses; an `onNotification` callback fans out inbound events;
68
+ * `failAll` rejects every in-flight request when the child errors or closes.
69
+ */
70
+ export declare class IMessageRpcClient implements IMessageRpcLike {
71
+ private readonly cliPath;
72
+ private readonly dbPath;
73
+ private readonly runtime;
74
+ private readonly onNotification;
75
+ private readonly pending;
76
+ private readonly closed;
77
+ private closedResolve;
78
+ private child;
79
+ private reader;
80
+ private nextId;
81
+ constructor(opts?: IMessageRpcClientOptions);
82
+ /** Spawn the child + wire stdout (responses/notifications) and stderr (logs). Idempotent. */
83
+ start(): Promise<void>;
84
+ /** Gracefully end stdin, then SIGTERM after a 500ms grace if still alive. */
85
+ stop(): Promise<void>;
86
+ /** Resolves when the child has errored or closed. */
87
+ waitForClose(): Promise<void>;
88
+ /** Issue a JSON-RPC request and await its matching response (10s default timeout). */
89
+ request<T = unknown>(method: string, params?: unknown, opts?: {
90
+ timeoutMs?: number;
91
+ }): Promise<T>;
92
+ /** Parse one stdout line: a non-null `id` is a response, a bare `method` is a notification. */
93
+ private handleLine;
94
+ /** Reject every in-flight request with `err` and clear their timers. */
95
+ private failAll;
96
+ }
97
+ /** Construct + start a real RPC client. */
98
+ export declare function createIMessageRpcClient(opts?: IMessageRpcClientOptions): Promise<IMessageRpcClient>;
99
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/agents/channels/imessage/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,+BAA+B;AAC/B,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnF,0EAA0E;AAC1E,MAAM,MAAM,uBAAuB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE3E,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IAClC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,0DAA0D;AAC1D,MAAM,WAAW,wBAAwB;IACxC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,oEAAoE;IACpE,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACxD;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AASD;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAInC;AAgBD;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuD;IACtF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,MAAM,CAAK;gBAEP,IAAI,GAAE,wBAA6B;IAU/C,6FAA6F;IACvF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC5B,6EAA6E;IACvE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B3B,qDAAqD;IAC/C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC,sFAAsF;IAChF,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC;IAwBvG,+FAA+F;IAC/F,OAAO,CAAC,UAAU;IA0ClB,wEAAwE;IACxE,OAAO,CAAC,OAAO;CAOf;AAED,2CAA2C;AAC3C,wBAAsB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAI7G"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * iMessage RPC client — newline-delimited JSON-RPC 2.0 over a child process's
3
+ * stdin/stdout.
4
+ *
5
+ * The transport spawns the third-party `imsg` CLI as `imsg rpc [--db <path>]`
6
+ * and speaks JSON-RPC 2.0 framed ONE object per `\n`:
7
+ * - a request is `{ jsonrpc:"2.0", id, method, params }\n` written to stdin;
8
+ * - a line with a non-null `id` is a RESPONSE matched against the pending map;
9
+ * - a line with a `method` and NO `id` is an inbound NOTIFICATION dispatched to
10
+ * `onNotification` (the monitor subscribes to these for new messages).
11
+ *
12
+ * This is the iMessage analogue of a token-channel's transport SDK. There is a
13
+ * hard TEST SEAM: the real client REFUSES to spawn a subprocess in tests (see
14
+ * {@link isTestEnv}). Unit tests inject a {@link IMessageRpcLike} fake on the
15
+ * adapter/connection seam instead, so send / normalize / probe / dedupe are all
16
+ * exercised with NO real `imsg` binary and NO live subprocess.
17
+ */
18
+ import { spawn } from "node:child_process";
19
+ import os from "node:os";
20
+ import path from "node:path";
21
+ import { createInterface } from "node:readline";
22
+ import { DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS } from "./account-config.js";
23
+ /**
24
+ * True in a test environment. The real client REFUSES to spawn `imsg rpc` here
25
+ * so a stray unit test can never shell out to the binary — tests must inject a
26
+ * mock {@link IMessageRpcLike} on the seam instead.
27
+ */
28
+ export function isTestEnv() {
29
+ if (process.env.NODE_ENV === "test")
30
+ return true;
31
+ const vitest = (process.env.VITEST ?? "").trim().toLowerCase();
32
+ return Boolean(vitest);
33
+ }
34
+ /** Expand a leading `~` to the user's home dir. */
35
+ function expandUserPath(p) {
36
+ const trimmed = p.trim();
37
+ if (trimmed === "~")
38
+ return os.homedir();
39
+ if (trimmed.startsWith("~/") || trimmed.startsWith("~\\")) {
40
+ return path.join(os.homedir(), trimmed.slice(2));
41
+ }
42
+ return trimmed;
43
+ }
44
+ function formatErr(err) {
45
+ return err instanceof Error ? err.message : String(err);
46
+ }
47
+ /**
48
+ * Long-lived JSON-RPC 2.0 client over an `imsg rpc` child process. A pending-id
49
+ * map matches responses; an `onNotification` callback fans out inbound events;
50
+ * `failAll` rejects every in-flight request when the child errors or closes.
51
+ */
52
+ export class IMessageRpcClient {
53
+ cliPath;
54
+ dbPath;
55
+ runtime;
56
+ onNotification;
57
+ pending = new Map();
58
+ closed;
59
+ closedResolve = null;
60
+ child = null;
61
+ reader = null;
62
+ nextId = 1;
63
+ constructor(opts = {}) {
64
+ this.cliPath = opts.cliPath?.trim() || "imsg";
65
+ this.dbPath = opts.dbPath?.trim() ? expandUserPath(opts.dbPath) : undefined;
66
+ this.runtime = opts.runtime;
67
+ this.onNotification = opts.onNotification;
68
+ this.closed = new Promise((resolve) => {
69
+ this.closedResolve = resolve;
70
+ });
71
+ }
72
+ /** Spawn the child + wire stdout (responses/notifications) and stderr (logs). Idempotent. */
73
+ async start() {
74
+ if (this.child)
75
+ return;
76
+ if (isTestEnv()) {
77
+ throw new Error("Refusing to start imsg rpc in test environment; inject a mock iMessage RPC client");
78
+ }
79
+ const args = ["rpc"];
80
+ if (this.dbPath)
81
+ args.push("--db", this.dbPath);
82
+ const child = spawn(this.cliPath, args, { stdio: ["pipe", "pipe", "pipe"] });
83
+ this.child = child;
84
+ this.reader = createInterface({ input: child.stdout });
85
+ this.reader.on("line", (line) => {
86
+ const trimmed = line.trim();
87
+ if (!trimmed)
88
+ return;
89
+ this.handleLine(trimmed);
90
+ });
91
+ child.stderr.on("data", (chunk) => {
92
+ for (const line of chunk.toString("utf8").split(/\r?\n/)) {
93
+ const t = line.trim();
94
+ if (t)
95
+ this.runtime?.error?.(`imsg rpc: ${t}`);
96
+ }
97
+ });
98
+ child.on("error", (err) => {
99
+ this.failAll(err instanceof Error ? err : new Error(formatErr(err)));
100
+ this.closedResolve?.();
101
+ });
102
+ child.on("close", (code, signal) => {
103
+ if (code !== 0 && code !== null) {
104
+ const reason = signal ? `signal ${signal}` : `code ${code}`;
105
+ this.failAll(new Error(`imsg rpc exited (${reason})`));
106
+ }
107
+ else {
108
+ this.failAll(new Error("imsg rpc closed"));
109
+ }
110
+ this.closedResolve?.();
111
+ });
112
+ }
113
+ /** Gracefully end stdin, then SIGTERM after a 500ms grace if still alive. */
114
+ async stop() {
115
+ const child = this.child;
116
+ if (!child)
117
+ return;
118
+ this.reader?.close();
119
+ this.reader = null;
120
+ try {
121
+ child.stdin?.end();
122
+ }
123
+ catch {
124
+ /* best-effort */
125
+ }
126
+ this.child = null;
127
+ await Promise.race([
128
+ this.closed,
129
+ new Promise((resolve) => {
130
+ const t = setTimeout(() => {
131
+ if (!child.killed) {
132
+ try {
133
+ child.kill("SIGTERM");
134
+ }
135
+ catch {
136
+ /* best-effort */
137
+ }
138
+ }
139
+ resolve();
140
+ }, 500);
141
+ if (typeof t.unref === "function")
142
+ t.unref();
143
+ }),
144
+ ]);
145
+ }
146
+ /** Resolves when the child has errored or closed. */
147
+ async waitForClose() {
148
+ await this.closed;
149
+ }
150
+ /** Issue a JSON-RPC request and await its matching response (10s default timeout). */
151
+ async request(method, params, opts) {
152
+ if (!this.child || !this.child.stdin)
153
+ throw new Error("imsg rpc not running");
154
+ const id = this.nextId++;
155
+ const payload = { jsonrpc: "2.0", id, method, params: params ?? {} };
156
+ const line = `${JSON.stringify(payload)}\n`;
157
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS;
158
+ const response = new Promise((resolve, reject) => {
159
+ const key = String(id);
160
+ const timer = timeoutMs > 0
161
+ ? setTimeout(() => {
162
+ this.pending.delete(key);
163
+ reject(new Error(`imsg rpc timeout (${method})`));
164
+ }, timeoutMs)
165
+ : undefined;
166
+ if (timer && typeof timer.unref === "function") {
167
+ timer.unref();
168
+ }
169
+ this.pending.set(key, { resolve: (v) => resolve(v), reject, timer });
170
+ });
171
+ this.child.stdin.write(line);
172
+ return await response;
173
+ }
174
+ /** Parse one stdout line: a non-null `id` is a response, a bare `method` is a notification. */
175
+ handleLine(line) {
176
+ let parsed;
177
+ try {
178
+ parsed = JSON.parse(line);
179
+ }
180
+ catch (err) {
181
+ this.runtime?.error?.(`imsg rpc: failed to parse ${line}: ${formatErr(err)}`);
182
+ return;
183
+ }
184
+ if (parsed.id !== undefined && parsed.id !== null) {
185
+ const key = String(parsed.id);
186
+ const pending = this.pending.get(key);
187
+ if (!pending)
188
+ return;
189
+ if (pending.timer)
190
+ clearTimeout(pending.timer);
191
+ this.pending.delete(key);
192
+ if (parsed.error) {
193
+ const baseMessage = parsed.error.message ?? "imsg rpc error";
194
+ const details = parsed.error.data;
195
+ const code = parsed.error.code;
196
+ const suffixes = [];
197
+ if (typeof code === "number")
198
+ suffixes.push(`code=${code}`);
199
+ if (details !== undefined) {
200
+ const detailText = typeof details === "string" ? details : JSON.stringify(details);
201
+ if (detailText)
202
+ suffixes.push(detailText);
203
+ }
204
+ const msg = suffixes.length > 0 ? `${baseMessage}: ${suffixes.join(" ")}` : baseMessage;
205
+ pending.reject(new Error(msg));
206
+ return;
207
+ }
208
+ pending.resolve(parsed.result);
209
+ return;
210
+ }
211
+ if (parsed.method) {
212
+ this.onNotification?.({ method: parsed.method, params: parsed.params });
213
+ }
214
+ }
215
+ /** Reject every in-flight request with `err` and clear their timers. */
216
+ failAll(err) {
217
+ for (const [, pending] of this.pending) {
218
+ if (pending.timer)
219
+ clearTimeout(pending.timer);
220
+ pending.reject(err);
221
+ }
222
+ this.pending.clear();
223
+ }
224
+ }
225
+ /** Construct + start a real RPC client. */
226
+ export async function createIMessageRpcClient(opts = {}) {
227
+ const client = new IMessageRpcClient(opts);
228
+ await client.start();
229
+ return client;
230
+ }
231
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/agents/channels/imessage/client.ts"],"names":[],"mappings":"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"}