@geminixiang/mikan 1.0.0-beta.7 → 1.0.0-beta.71

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 (856) hide show
  1. package/CHANGELOG.md +1052 -0
  2. package/README.md +98 -38
  3. package/dist/adapters/commands/admin.d.ts.map +1 -0
  4. package/dist/{commands → adapters/commands}/admin.js +11 -8
  5. package/dist/adapters/commands/admin.js.map +1 -0
  6. package/dist/{commands → adapters/commands}/auto-reply.d.ts +0 -3
  7. package/dist/adapters/commands/auto-reply.d.ts.map +1 -0
  8. package/dist/adapters/commands/auto-reply.js +47 -0
  9. package/dist/adapters/commands/auto-reply.js.map +1 -0
  10. package/dist/adapters/commands/login.d.ts +6 -0
  11. package/dist/adapters/commands/login.d.ts.map +1 -0
  12. package/dist/adapters/commands/login.js +166 -0
  13. package/dist/adapters/commands/login.js.map +1 -0
  14. package/dist/adapters/commands/manifest.d.ts +37 -0
  15. package/dist/adapters/commands/manifest.d.ts.map +1 -0
  16. package/dist/adapters/commands/manifest.js +155 -0
  17. package/dist/adapters/commands/manifest.js.map +1 -0
  18. package/dist/adapters/commands/model.d.ts +15 -0
  19. package/dist/adapters/commands/model.d.ts.map +1 -0
  20. package/dist/adapters/commands/model.js +153 -0
  21. package/dist/adapters/commands/model.js.map +1 -0
  22. package/dist/adapters/commands/new.d.ts.map +1 -0
  23. package/dist/adapters/commands/new.js +41 -0
  24. package/dist/adapters/commands/new.js.map +1 -0
  25. package/dist/adapters/commands/registry.d.ts +5 -0
  26. package/dist/adapters/commands/registry.d.ts.map +1 -0
  27. package/dist/adapters/commands/registry.js +43 -0
  28. package/dist/adapters/commands/registry.js.map +1 -0
  29. package/dist/adapters/commands/sandbox.d.ts.map +1 -0
  30. package/dist/adapters/commands/sandbox.js +125 -0
  31. package/dist/adapters/commands/sandbox.js.map +1 -0
  32. package/dist/adapters/commands/session-view.d.ts.map +1 -0
  33. package/dist/{commands → adapters/commands}/session-view.js +23 -16
  34. package/dist/adapters/commands/session-view.js.map +1 -0
  35. package/dist/adapters/commands/types.d.ts +145 -0
  36. package/dist/adapters/commands/types.d.ts.map +1 -0
  37. package/dist/adapters/commands/types.js.map +1 -0
  38. package/dist/adapters/commands/utils.d.ts +14 -0
  39. package/dist/adapters/commands/utils.d.ts.map +1 -0
  40. package/dist/{commands → adapters/commands}/utils.js +18 -1
  41. package/dist/adapters/commands/utils.js.map +1 -0
  42. package/dist/adapters/discord/bot.d.ts +11 -8
  43. package/dist/adapters/discord/bot.d.ts.map +1 -1
  44. package/dist/adapters/discord/bot.js +223 -256
  45. package/dist/adapters/discord/bot.js.map +1 -1
  46. package/dist/adapters/discord/components.d.ts +28 -0
  47. package/dist/adapters/discord/components.d.ts.map +1 -0
  48. package/dist/adapters/discord/components.js +32 -0
  49. package/dist/adapters/discord/components.js.map +1 -0
  50. package/dist/adapters/discord/context.d.ts +2 -6
  51. package/dist/adapters/discord/context.d.ts.map +1 -1
  52. package/dist/adapters/discord/context.js +64 -218
  53. package/dist/adapters/discord/context.js.map +1 -1
  54. package/dist/adapters/discord/format.d.ts +3 -0
  55. package/dist/adapters/discord/format.d.ts.map +1 -0
  56. package/dist/adapters/discord/format.js +84 -0
  57. package/dist/adapters/discord/format.js.map +1 -0
  58. package/dist/adapters/discord/types.d.ts +8 -1
  59. package/dist/adapters/discord/types.d.ts.map +1 -1
  60. package/dist/adapters/discord/types.js.map +1 -1
  61. package/dist/adapters/github/bot.d.ts +102 -0
  62. package/dist/adapters/github/bot.d.ts.map +1 -0
  63. package/dist/adapters/github/bot.js +720 -0
  64. package/dist/adapters/github/bot.js.map +1 -0
  65. package/dist/adapters/github/client.d.ts +122 -0
  66. package/dist/adapters/github/client.d.ts.map +1 -0
  67. package/dist/adapters/github/client.js +301 -0
  68. package/dist/adapters/github/client.js.map +1 -0
  69. package/dist/adapters/github/context.d.ts +5 -0
  70. package/dist/adapters/github/context.d.ts.map +1 -0
  71. package/dist/adapters/github/context.js +101 -0
  72. package/dist/adapters/github/context.js.map +1 -0
  73. package/dist/adapters/github/github-ops.d.ts +78 -0
  74. package/dist/adapters/github/github-ops.d.ts.map +1 -0
  75. package/dist/adapters/github/github-ops.js +337 -0
  76. package/dist/adapters/github/github-ops.js.map +1 -0
  77. package/dist/adapters/github/ids.d.ts +34 -0
  78. package/dist/adapters/github/ids.d.ts.map +1 -0
  79. package/dist/adapters/github/ids.js +57 -0
  80. package/dist/adapters/github/ids.js.map +1 -0
  81. package/dist/adapters/github/repo.d.ts +33 -0
  82. package/dist/adapters/github/repo.d.ts.map +1 -0
  83. package/dist/adapters/github/repo.js +141 -0
  84. package/dist/adapters/github/repo.js.map +1 -0
  85. package/dist/adapters/github/tool-pack.d.ts +14 -0
  86. package/dist/adapters/github/tool-pack.d.ts.map +1 -0
  87. package/dist/adapters/github/tool-pack.js +55 -0
  88. package/dist/adapters/github/tool-pack.js.map +1 -0
  89. package/dist/adapters/github/tools/checks.d.ts +18 -0
  90. package/dist/adapters/github/tools/checks.d.ts.map +1 -0
  91. package/dist/adapters/github/tools/checks.js +86 -0
  92. package/dist/adapters/github/tools/checks.js.map +1 -0
  93. package/dist/adapters/github/tools/issue.d.ts +21 -0
  94. package/dist/adapters/github/tools/issue.d.ts.map +1 -0
  95. package/dist/adapters/github/tools/issue.js +48 -0
  96. package/dist/adapters/github/tools/issue.js.map +1 -0
  97. package/dist/adapters/github/tools/pr.d.ts +22 -0
  98. package/dist/adapters/github/tools/pr.d.ts.map +1 -0
  99. package/dist/adapters/github/tools/pr.js +48 -0
  100. package/dist/adapters/github/tools/pr.js.map +1 -0
  101. package/dist/adapters/github/tools/read.d.ts +21 -0
  102. package/dist/adapters/github/tools/read.d.ts.map +1 -0
  103. package/dist/adapters/github/tools/read.js +141 -0
  104. package/dist/adapters/github/tools/read.js.map +1 -0
  105. package/dist/adapters/github/tools/review-reply.d.ts +17 -0
  106. package/dist/adapters/github/tools/review-reply.d.ts.map +1 -0
  107. package/dist/adapters/github/tools/review-reply.js +38 -0
  108. package/dist/adapters/github/tools/review-reply.js.map +1 -0
  109. package/dist/adapters/github/tools/sync.d.ts +17 -0
  110. package/dist/adapters/github/tools/sync.d.ts.map +1 -0
  111. package/dist/adapters/github/tools/sync.js +34 -0
  112. package/dist/adapters/github/tools/sync.js.map +1 -0
  113. package/dist/adapters/github/types.d.ts +345 -0
  114. package/dist/adapters/github/types.d.ts.map +1 -0
  115. package/dist/adapters/github/types.js.map +1 -0
  116. package/dist/adapters/github/webhook.d.ts +20 -0
  117. package/dist/adapters/github/webhook.d.ts.map +1 -0
  118. package/dist/adapters/github/webhook.js +78 -0
  119. package/dist/adapters/github/webhook.js.map +1 -0
  120. package/dist/adapters/index.d.ts +12 -0
  121. package/dist/adapters/index.d.ts.map +1 -0
  122. package/dist/adapters/index.js +19 -0
  123. package/dist/adapters/index.js.map +1 -0
  124. package/dist/adapters/intake.d.ts +17 -6
  125. package/dist/adapters/intake.d.ts.map +1 -1
  126. package/dist/adapters/intake.js +96 -27
  127. package/dist/adapters/intake.js.map +1 -1
  128. package/dist/adapters/markdown-tables.d.ts +19 -0
  129. package/dist/adapters/markdown-tables.d.ts.map +1 -0
  130. package/dist/adapters/markdown-tables.js +152 -0
  131. package/dist/adapters/markdown-tables.js.map +1 -0
  132. package/dist/{platform-messages.d.ts → adapters/messages.d.ts} +3 -2
  133. package/dist/adapters/messages.d.ts.map +1 -0
  134. package/dist/{platform-messages.js → adapters/messages.js} +4 -1
  135. package/dist/adapters/messages.js.map +1 -0
  136. package/dist/adapters/progressive-renderer.d.ts +7 -0
  137. package/dist/adapters/progressive-renderer.d.ts.map +1 -0
  138. package/dist/adapters/progressive-renderer.js +443 -0
  139. package/dist/adapters/progressive-renderer.js.map +1 -0
  140. package/dist/adapters/shared.d.ts +37 -11
  141. package/dist/adapters/shared.d.ts.map +1 -1
  142. package/dist/adapters/shared.js +130 -24
  143. package/dist/adapters/shared.js.map +1 -1
  144. package/dist/adapters/slack/assistant.d.ts +73 -0
  145. package/dist/adapters/slack/assistant.d.ts.map +1 -0
  146. package/dist/adapters/slack/assistant.js +205 -0
  147. package/dist/adapters/slack/assistant.js.map +1 -0
  148. package/dist/adapters/slack/auto-reply-context.d.ts +21 -0
  149. package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -0
  150. package/dist/adapters/slack/auto-reply-context.js +28 -0
  151. package/dist/adapters/slack/auto-reply-context.js.map +1 -0
  152. package/dist/adapters/slack/blocks.d.ts +14 -0
  153. package/dist/adapters/slack/blocks.d.ts.map +1 -1
  154. package/dist/adapters/slack/blocks.js +104 -148
  155. package/dist/adapters/slack/blocks.js.map +1 -1
  156. package/dist/adapters/slack/bot.d.ts +154 -21
  157. package/dist/adapters/slack/bot.d.ts.map +1 -1
  158. package/dist/adapters/slack/bot.js +1037 -484
  159. package/dist/adapters/slack/bot.js.map +1 -1
  160. package/dist/adapters/slack/context.d.ts +2 -6
  161. package/dist/adapters/slack/context.d.ts.map +1 -1
  162. package/dist/adapters/slack/context.js +11 -17
  163. package/dist/adapters/slack/context.js.map +1 -1
  164. package/dist/adapters/slack/jev-context.d.ts +30 -0
  165. package/dist/adapters/slack/jev-context.d.ts.map +1 -0
  166. package/dist/adapters/slack/jev-context.js +67 -0
  167. package/dist/adapters/slack/jev-context.js.map +1 -0
  168. package/dist/adapters/slack/markdown.d.ts +3 -0
  169. package/dist/adapters/slack/markdown.d.ts.map +1 -0
  170. package/dist/adapters/slack/markdown.js +48 -0
  171. package/dist/adapters/slack/markdown.js.map +1 -0
  172. package/dist/adapters/slack/persona.d.ts +15 -0
  173. package/dist/adapters/slack/persona.d.ts.map +1 -0
  174. package/dist/adapters/slack/persona.js +22 -0
  175. package/dist/adapters/slack/persona.js.map +1 -0
  176. package/dist/adapters/slack/response-lifecycle.d.ts +1 -1
  177. package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
  178. package/dist/adapters/slack/response-lifecycle.js +261 -345
  179. package/dist/adapters/slack/response-lifecycle.js.map +1 -1
  180. package/dist/adapters/slack/session.d.ts.map +1 -1
  181. package/dist/adapters/slack/session.js +7 -11
  182. package/dist/adapters/slack/session.js.map +1 -1
  183. package/dist/adapters/slack/stream-limits.d.ts +35 -0
  184. package/dist/adapters/slack/stream-limits.d.ts.map +1 -0
  185. package/dist/adapters/slack/stream-limits.js +56 -0
  186. package/dist/adapters/slack/stream-limits.js.map +1 -0
  187. package/dist/adapters/slack/task-intent.d.ts +32 -0
  188. package/dist/adapters/slack/task-intent.d.ts.map +1 -0
  189. package/dist/adapters/slack/task-intent.js +72 -0
  190. package/dist/adapters/slack/task-intent.js.map +1 -0
  191. package/dist/adapters/slack/task-status.d.ts +7 -0
  192. package/dist/adapters/slack/task-status.d.ts.map +1 -0
  193. package/dist/adapters/slack/task-status.js +107 -0
  194. package/dist/adapters/slack/task-status.js.map +1 -0
  195. package/dist/adapters/slack/tool-pack.d.ts +11 -0
  196. package/dist/adapters/slack/tool-pack.d.ts.map +1 -0
  197. package/dist/adapters/slack/tool-pack.js +45 -0
  198. package/dist/adapters/slack/tool-pack.js.map +1 -0
  199. package/dist/adapters/slack/tools/blockkit.d.ts +14 -0
  200. package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -0
  201. package/dist/adapters/slack/tools/blockkit.js +106 -0
  202. package/dist/adapters/slack/tools/blockkit.js.map +1 -0
  203. package/dist/adapters/slack/types.d.ts +73 -2
  204. package/dist/adapters/slack/types.d.ts.map +1 -1
  205. package/dist/adapters/slack/types.js.map +1 -1
  206. package/dist/adapters/slack/update-diagnostics.d.ts +14 -0
  207. package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -0
  208. package/dist/adapters/slack/update-diagnostics.js +134 -0
  209. package/dist/adapters/slack/update-diagnostics.js.map +1 -0
  210. package/dist/adapters/telegram/bot.d.ts +10 -9
  211. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  212. package/dist/adapters/telegram/bot.js +133 -202
  213. package/dist/adapters/telegram/bot.js.map +1 -1
  214. package/dist/adapters/telegram/context.d.ts +2 -6
  215. package/dist/adapters/telegram/context.d.ts.map +1 -1
  216. package/dist/adapters/telegram/context.js +53 -190
  217. package/dist/adapters/telegram/context.js.map +1 -1
  218. package/dist/adapters/telegram/types.d.ts +1 -1
  219. package/dist/adapters/telegram/types.d.ts.map +1 -1
  220. package/dist/adapters/telegram/types.js.map +1 -1
  221. package/dist/adapters/types.d.ts +144 -13
  222. package/dist/adapters/types.d.ts.map +1 -1
  223. package/dist/adapters/types.js.map +1 -1
  224. package/dist/adapters/web/admin/portal.d.ts +44 -0
  225. package/dist/adapters/web/admin/portal.d.ts.map +1 -0
  226. package/dist/adapters/web/admin/portal.js +3207 -0
  227. package/dist/adapters/web/admin/portal.js.map +1 -0
  228. package/dist/{web → adapters/web}/admin/provider-models.d.ts +1 -1
  229. package/dist/adapters/web/admin/provider-models.d.ts.map +1 -0
  230. package/dist/{web → adapters/web}/admin/provider-models.js +1 -1
  231. package/dist/adapters/web/admin/provider-models.js.map +1 -0
  232. package/dist/adapters/web/admin/types.d.ts +53 -0
  233. package/dist/adapters/web/admin/types.d.ts.map +1 -0
  234. package/dist/adapters/web/admin/types.js.map +1 -0
  235. package/dist/adapters/web/login/oauth.d.ts +5 -0
  236. package/dist/adapters/web/login/oauth.d.ts.map +1 -0
  237. package/dist/{web → adapters/web}/login/oauth.js +50 -85
  238. package/dist/adapters/web/login/oauth.js.map +1 -0
  239. package/dist/{web → adapters/web}/login/portal.d.ts +9 -3
  240. package/dist/adapters/web/login/portal.d.ts.map +1 -0
  241. package/dist/{web → adapters/web}/login/portal.js +161 -119
  242. package/dist/adapters/web/login/portal.js.map +1 -0
  243. package/dist/{web → adapters/web}/login/types.d.ts +1 -12
  244. package/dist/adapters/web/login/types.d.ts.map +1 -0
  245. package/dist/adapters/web/login/types.js.map +1 -0
  246. package/dist/adapters/web/portal-shell.d.ts +22 -0
  247. package/dist/adapters/web/portal-shell.d.ts.map +1 -0
  248. package/dist/{portal-shell.js → adapters/web/portal-shell.js} +78 -2
  249. package/dist/adapters/web/portal-shell.js.map +1 -0
  250. package/dist/{web → adapters/web}/server.d.ts +14 -8
  251. package/dist/adapters/web/server.d.ts.map +1 -0
  252. package/dist/{web → adapters/web}/server.js +14 -7
  253. package/dist/adapters/web/server.js.map +1 -0
  254. package/dist/adapters/web/session-view/portal.d.ts +20 -0
  255. package/dist/adapters/web/session-view/portal.d.ts.map +1 -0
  256. package/dist/{web → adapters/web}/session-view/portal.js +633 -162
  257. package/dist/adapters/web/session-view/portal.js.map +1 -0
  258. package/dist/{web → adapters/web}/session-view/types.d.ts +11 -6
  259. package/dist/adapters/web/session-view/types.d.ts.map +1 -0
  260. package/dist/adapters/web/session-view/types.js.map +1 -0
  261. package/dist/adapters/web/token-store.d.ts.map +1 -0
  262. package/dist/{web → adapters/web}/token-store.js +1 -1
  263. package/dist/adapters/web/token-store.js.map +1 -0
  264. package/dist/adapters/web/types.d.ts.map +1 -0
  265. package/dist/adapters/web/types.js.map +1 -0
  266. package/dist/cli/arg-grammar.d.ts +11 -0
  267. package/dist/cli/arg-grammar.d.ts.map +1 -0
  268. package/dist/cli/arg-grammar.js +50 -0
  269. package/dist/cli/arg-grammar.js.map +1 -0
  270. package/dist/cli/boot.d.ts +5 -0
  271. package/dist/cli/boot.d.ts.map +1 -0
  272. package/dist/cli/boot.js +90 -0
  273. package/dist/cli/boot.js.map +1 -0
  274. package/dist/cli/download.d.ts.map +1 -0
  275. package/dist/cli/download.js +88 -0
  276. package/dist/cli/download.js.map +1 -0
  277. package/dist/cli/office.d.ts +2 -0
  278. package/dist/cli/office.d.ts.map +1 -0
  279. package/dist/cli/office.js +181 -0
  280. package/dist/cli/office.js.map +1 -0
  281. package/dist/cli/onboard.d.ts +10 -0
  282. package/dist/cli/onboard.d.ts.map +1 -0
  283. package/dist/cli/onboard.js +225 -0
  284. package/dist/cli/onboard.js.map +1 -0
  285. package/dist/cli/process-lifecycle.d.ts +19 -0
  286. package/dist/cli/process-lifecycle.d.ts.map +1 -0
  287. package/dist/cli/process-lifecycle.js +67 -0
  288. package/dist/cli/process-lifecycle.js.map +1 -0
  289. package/dist/cli/sessions.d.ts +2 -0
  290. package/dist/cli/sessions.d.ts.map +1 -0
  291. package/dist/cli/sessions.js +88 -0
  292. package/dist/cli/sessions.js.map +1 -0
  293. package/dist/cli/types.d.ts +25 -0
  294. package/dist/cli/types.d.ts.map +1 -0
  295. package/dist/cli/types.js.map +1 -0
  296. package/dist/dream/index.d.ts +20 -0
  297. package/dist/dream/index.d.ts.map +1 -0
  298. package/dist/dream/index.js +264 -0
  299. package/dist/dream/index.js.map +1 -0
  300. package/dist/dream/types.d.ts +30 -0
  301. package/dist/dream/types.d.ts.map +1 -0
  302. package/dist/dream/types.js +2 -0
  303. package/dist/dream/types.js.map +1 -0
  304. package/dist/env-manifest.d.ts +38 -0
  305. package/dist/env-manifest.d.ts.map +1 -0
  306. package/dist/env-manifest.js +260 -0
  307. package/dist/env-manifest.js.map +1 -0
  308. package/dist/events/index.d.ts +172 -0
  309. package/dist/events/index.d.ts.map +1 -0
  310. package/dist/events/index.js +340 -0
  311. package/dist/events/index.js.map +1 -0
  312. package/dist/events/scheduler.d.ts +34 -0
  313. package/dist/events/scheduler.d.ts.map +1 -0
  314. package/dist/events/scheduler.js +231 -0
  315. package/dist/events/scheduler.js.map +1 -0
  316. package/dist/file-guards.d.ts +26 -0
  317. package/dist/file-guards.d.ts.map +1 -0
  318. package/dist/file-guards.js +133 -0
  319. package/dist/file-guards.js.map +1 -0
  320. package/dist/harness/execution-env.d.ts +19 -0
  321. package/dist/harness/execution-env.d.ts.map +1 -0
  322. package/dist/harness/execution-env.js +262 -0
  323. package/dist/harness/execution-env.js.map +1 -0
  324. package/dist/harness/execution-resolver.d.ts +25 -0
  325. package/dist/harness/execution-resolver.d.ts.map +1 -0
  326. package/dist/harness/execution-resolver.js +156 -0
  327. package/dist/harness/execution-resolver.js.map +1 -0
  328. package/dist/harness/index.d.ts +18 -13
  329. package/dist/harness/index.d.ts.map +1 -1
  330. package/dist/harness/index.js +11 -11
  331. package/dist/harness/index.js.map +1 -1
  332. package/dist/harness/jev.d.ts +86 -0
  333. package/dist/harness/jev.d.ts.map +1 -0
  334. package/dist/harness/jev.js +167 -0
  335. package/dist/harness/jev.js.map +1 -0
  336. package/dist/harness/mcp.d.ts +38 -0
  337. package/dist/harness/mcp.d.ts.map +1 -0
  338. package/dist/harness/mcp.js +304 -0
  339. package/dist/harness/mcp.js.map +1 -0
  340. package/dist/harness/models.d.ts +7 -4
  341. package/dist/harness/models.d.ts.map +1 -1
  342. package/dist/harness/models.js +54 -55
  343. package/dist/harness/models.js.map +1 -1
  344. package/dist/harness/open-connector.d.ts +25 -0
  345. package/dist/harness/open-connector.d.ts.map +1 -0
  346. package/dist/harness/open-connector.js +178 -0
  347. package/dist/harness/open-connector.js.map +1 -0
  348. package/dist/harness/presenter.d.ts +31 -0
  349. package/dist/harness/presenter.d.ts.map +1 -0
  350. package/dist/harness/presenter.js +859 -0
  351. package/dist/harness/presenter.js.map +1 -0
  352. package/dist/harness/prompt.d.ts +30 -0
  353. package/dist/harness/prompt.d.ts.map +1 -0
  354. package/dist/harness/prompt.js +420 -0
  355. package/dist/harness/prompt.js.map +1 -0
  356. package/dist/harness/runner.d.ts +2 -123
  357. package/dist/harness/runner.d.ts.map +1 -1
  358. package/dist/harness/runner.js +551 -416
  359. package/dist/harness/runner.js.map +1 -1
  360. package/dist/harness/session.d.ts +122 -0
  361. package/dist/harness/session.d.ts.map +1 -0
  362. package/dist/harness/session.js +581 -0
  363. package/dist/harness/session.js.map +1 -0
  364. package/dist/harness/skills.d.ts +17 -28
  365. package/dist/harness/skills.d.ts.map +1 -1
  366. package/dist/harness/skills.js +104 -39
  367. package/dist/harness/skills.js.map +1 -1
  368. package/dist/harness/subagent-profiles.d.ts +8 -0
  369. package/dist/harness/subagent-profiles.d.ts.map +1 -0
  370. package/dist/harness/subagent-profiles.js +293 -0
  371. package/dist/harness/subagent-profiles.js.map +1 -0
  372. package/dist/harness/subagent.d.ts +64 -0
  373. package/dist/harness/subagent.d.ts.map +1 -0
  374. package/dist/harness/subagent.js +687 -0
  375. package/dist/harness/subagent.js.map +1 -0
  376. package/dist/harness/tools/attach.d.ts.map +1 -0
  377. package/dist/{adapters/slack → harness}/tools/attach.js +1 -1
  378. package/dist/harness/tools/attach.js.map +1 -0
  379. package/dist/{tools → harness/tools}/event.d.ts +4 -33
  380. package/dist/harness/tools/event.d.ts.map +1 -0
  381. package/dist/harness/tools/event.js +175 -0
  382. package/dist/harness/tools/event.js.map +1 -0
  383. package/dist/harness/tools/generate-image.d.ts +23 -0
  384. package/dist/harness/tools/generate-image.d.ts.map +1 -0
  385. package/dist/harness/tools/generate-image.js +65 -0
  386. package/dist/harness/tools/generate-image.js.map +1 -0
  387. package/dist/harness/tools/host-fn-tool.d.ts +21 -0
  388. package/dist/harness/tools/host-fn-tool.d.ts.map +1 -0
  389. package/dist/harness/tools/host-fn-tool.js +32 -0
  390. package/dist/harness/tools/host-fn-tool.js.map +1 -0
  391. package/dist/harness/tools/index.d.ts +41 -0
  392. package/dist/harness/tools/index.d.ts.map +1 -0
  393. package/dist/harness/tools/index.js +51 -0
  394. package/dist/harness/tools/index.js.map +1 -0
  395. package/dist/harness/tools/jev.d.ts +21 -0
  396. package/dist/harness/tools/jev.d.ts.map +1 -0
  397. package/dist/harness/tools/jev.js +109 -0
  398. package/dist/harness/tools/jev.js.map +1 -0
  399. package/dist/harness/tools/pi-tools.d.ts +18 -0
  400. package/dist/harness/tools/pi-tools.d.ts.map +1 -0
  401. package/dist/harness/tools/pi-tools.js +84 -0
  402. package/dist/harness/tools/pi-tools.js.map +1 -0
  403. package/dist/harness/tools/react.d.ts.map +1 -0
  404. package/dist/{tools → harness/tools}/react.js +6 -17
  405. package/dist/harness/tools/react.js.map +1 -0
  406. package/dist/{tools → harness/tools}/sandbox.d.ts +4 -4
  407. package/dist/harness/tools/sandbox.d.ts.map +1 -0
  408. package/dist/{tools → harness/tools}/sandbox.js +12 -8
  409. package/dist/harness/tools/sandbox.js.map +1 -0
  410. package/dist/harness/tools/subagent.d.ts +85 -0
  411. package/dist/harness/tools/subagent.d.ts.map +1 -0
  412. package/dist/harness/tools/subagent.js +677 -0
  413. package/dist/harness/tools/subagent.js.map +1 -0
  414. package/dist/harness/tools/task.d.ts +20 -0
  415. package/dist/harness/tools/task.d.ts.map +1 -0
  416. package/dist/harness/tools/task.js +79 -0
  417. package/dist/harness/tools/task.js.map +1 -0
  418. package/dist/harness/tools/types.d.ts +29 -0
  419. package/dist/harness/tools/types.d.ts.map +1 -0
  420. package/dist/harness/tools/types.js +2 -0
  421. package/dist/harness/tools/types.js.map +1 -0
  422. package/dist/harness/types.d.ts +384 -25
  423. package/dist/harness/types.d.ts.map +1 -1
  424. package/dist/harness/types.js +1 -1
  425. package/dist/harness/types.js.map +1 -1
  426. package/dist/index.d.ts +33 -9
  427. package/dist/index.d.ts.map +1 -1
  428. package/dist/index.js +19 -6
  429. package/dist/index.js.map +1 -1
  430. package/dist/log.d.ts.map +1 -1
  431. package/dist/log.js +4 -1
  432. package/dist/log.js.map +1 -1
  433. package/dist/main.js +357 -198
  434. package/dist/main.js.map +1 -1
  435. package/dist/observability/index.d.ts +33 -0
  436. package/dist/observability/index.d.ts.map +1 -0
  437. package/dist/observability/index.js +257 -0
  438. package/dist/observability/index.js.map +1 -0
  439. package/dist/observability/instrument.js +14 -6
  440. package/dist/observability/instrument.js.map +1 -1
  441. package/dist/observability/otel.d.ts +10 -0
  442. package/dist/observability/otel.d.ts.map +1 -0
  443. package/dist/observability/otel.js +183 -0
  444. package/dist/observability/otel.js.map +1 -0
  445. package/dist/observability/sentry.d.ts +40 -7
  446. package/dist/observability/sentry.d.ts.map +1 -1
  447. package/dist/observability/sentry.js +176 -32
  448. package/dist/observability/sentry.js.map +1 -1
  449. package/dist/observability/types.d.ts +24 -3
  450. package/dist/observability/types.d.ts.map +1 -1
  451. package/dist/observability/types.js.map +1 -1
  452. package/dist/office/index.d.ts +139 -0
  453. package/dist/office/index.d.ts.map +1 -0
  454. package/dist/office/index.js +1084 -0
  455. package/dist/office/index.js.map +1 -0
  456. package/dist/office/projection.d.ts +42 -0
  457. package/dist/office/projection.d.ts.map +1 -0
  458. package/dist/office/projection.js +182 -0
  459. package/dist/office/projection.js.map +1 -0
  460. package/dist/office/types.d.ts +116 -0
  461. package/dist/office/types.d.ts.map +1 -0
  462. package/dist/office/types.js +2 -0
  463. package/dist/office/types.js.map +1 -0
  464. package/dist/runtime/conversation-runtime.d.ts +1 -1
  465. package/dist/runtime/conversation-runtime.d.ts.map +1 -1
  466. package/dist/runtime/conversation-runtime.js +423 -152
  467. package/dist/runtime/conversation-runtime.js.map +1 -1
  468. package/dist/runtime/session-lifecycle.d.ts +76 -0
  469. package/dist/runtime/session-lifecycle.d.ts.map +1 -0
  470. package/dist/runtime/session-lifecycle.js +404 -0
  471. package/dist/runtime/session-lifecycle.js.map +1 -0
  472. package/dist/runtime/types.d.ts +63 -15
  473. package/dist/runtime/types.d.ts.map +1 -1
  474. package/dist/runtime/types.js.map +1 -1
  475. package/dist/sandbox/cloudflare.d.ts +4 -0
  476. package/dist/sandbox/cloudflare.d.ts.map +1 -1
  477. package/dist/sandbox/cloudflare.js +54 -52
  478. package/dist/sandbox/cloudflare.js.map +1 -1
  479. package/dist/sandbox/container.d.ts +3 -0
  480. package/dist/sandbox/container.d.ts.map +1 -1
  481. package/dist/sandbox/container.js +19 -7
  482. package/dist/sandbox/container.js.map +1 -1
  483. package/dist/sandbox/host.d.ts +3 -0
  484. package/dist/sandbox/host.d.ts.map +1 -1
  485. package/dist/sandbox/host.js +44 -35
  486. package/dist/sandbox/host.js.map +1 -1
  487. package/dist/sandbox/identity.d.ts +42 -0
  488. package/dist/sandbox/identity.d.ts.map +1 -0
  489. package/dist/sandbox/identity.js +77 -0
  490. package/dist/sandbox/identity.js.map +1 -0
  491. package/dist/sandbox/index.d.ts +24 -6
  492. package/dist/sandbox/index.d.ts.map +1 -1
  493. package/dist/sandbox/index.js +77 -17
  494. package/dist/sandbox/index.js.map +1 -1
  495. package/dist/sandbox/provisioner.d.ts +139 -0
  496. package/dist/sandbox/provisioner.d.ts.map +1 -0
  497. package/dist/{provisioner.js → sandbox/provisioner.js} +378 -24
  498. package/dist/sandbox/provisioner.js.map +1 -0
  499. package/dist/sandbox/types.d.ts +43 -9
  500. package/dist/sandbox/types.d.ts.map +1 -1
  501. package/dist/sandbox/types.js.map +1 -1
  502. package/dist/sandbox/utils.d.ts +24 -0
  503. package/dist/sandbox/utils.d.ts.map +1 -1
  504. package/dist/sandbox/utils.js +92 -1
  505. package/dist/sandbox/utils.js.map +1 -1
  506. package/dist/sessions/chat-history-sync.d.ts +23 -0
  507. package/dist/sessions/chat-history-sync.d.ts.map +1 -0
  508. package/dist/sessions/{agent-memory-file-manager.js → chat-history-sync.js} +239 -175
  509. package/dist/sessions/chat-history-sync.js.map +1 -0
  510. package/dist/sessions/history-line.d.ts +29 -0
  511. package/dist/sessions/history-line.d.ts.map +1 -0
  512. package/dist/sessions/history-line.js +45 -0
  513. package/dist/sessions/history-line.js.map +1 -0
  514. package/dist/sessions/migrate-common.d.ts +43 -0
  515. package/dist/sessions/migrate-common.d.ts.map +1 -0
  516. package/dist/sessions/migrate-common.js +99 -0
  517. package/dist/sessions/migrate-common.js.map +1 -0
  518. package/dist/sessions/migrate-pi-084.d.ts +8 -0
  519. package/dist/sessions/migrate-pi-084.d.ts.map +1 -0
  520. package/dist/sessions/migrate-pi-084.js +302 -0
  521. package/dist/sessions/migrate-pi-084.js.map +1 -0
  522. package/dist/sessions/migrate-v3.d.ts +15 -0
  523. package/dist/sessions/migrate-v3.d.ts.map +1 -0
  524. package/dist/sessions/migrate-v3.js +419 -0
  525. package/dist/sessions/migrate-v3.js.map +1 -0
  526. package/dist/sessions/session-key.d.ts +33 -0
  527. package/dist/sessions/session-key.d.ts.map +1 -0
  528. package/dist/sessions/session-key.js +115 -0
  529. package/dist/sessions/session-key.js.map +1 -0
  530. package/dist/sessions/session-store.d.ts +61 -0
  531. package/dist/sessions/session-store.d.ts.map +1 -0
  532. package/dist/sessions/session-store.js +684 -0
  533. package/dist/sessions/session-store.js.map +1 -0
  534. package/dist/sessions/store.d.ts +17 -10
  535. package/dist/sessions/store.d.ts.map +1 -1
  536. package/dist/sessions/store.js +182 -47
  537. package/dist/sessions/store.js.map +1 -1
  538. package/dist/sessions/types.d.ts +74 -8
  539. package/dist/sessions/types.d.ts.map +1 -1
  540. package/dist/sessions/types.js +1 -1
  541. package/dist/sessions/types.js.map +1 -1
  542. package/dist/settings/apply.d.ts +16 -0
  543. package/dist/settings/apply.d.ts.map +1 -0
  544. package/dist/settings/apply.js +60 -0
  545. package/dist/settings/apply.js.map +1 -0
  546. package/dist/settings/index.d.ts +126 -0
  547. package/dist/settings/index.d.ts.map +1 -0
  548. package/dist/settings/index.js +422 -0
  549. package/dist/settings/index.js.map +1 -0
  550. package/dist/settings/migrate.d.ts +21 -0
  551. package/dist/settings/migrate.d.ts.map +1 -0
  552. package/dist/settings/migrate.js +86 -0
  553. package/dist/settings/migrate.js.map +1 -0
  554. package/dist/types.d.ts +330 -141
  555. package/dist/types.d.ts.map +1 -1
  556. package/dist/types.js +2 -2
  557. package/dist/types.js.map +1 -1
  558. package/dist/vault/index.d.ts +52 -2
  559. package/dist/vault/index.d.ts.map +1 -1
  560. package/dist/vault/index.js +218 -86
  561. package/dist/vault/index.js.map +1 -1
  562. package/dist/vault/types.d.ts +6 -2
  563. package/dist/vault/types.d.ts.map +1 -1
  564. package/dist/vault/types.js.map +1 -1
  565. package/package.json +79 -40
  566. package/dist/adapter.d.ts +0 -2
  567. package/dist/adapter.d.ts.map +0 -1
  568. package/dist/adapter.js +0 -2
  569. package/dist/adapter.js.map +0 -1
  570. package/dist/adapters/slack/tools/attach.d.ts.map +0 -1
  571. package/dist/adapters/slack/tools/attach.js.map +0 -1
  572. package/dist/adapters/streaming.d.ts +0 -18
  573. package/dist/adapters/streaming.d.ts.map +0 -1
  574. package/dist/adapters/streaming.js +0 -44
  575. package/dist/adapters/streaming.js.map +0 -1
  576. package/dist/adapters/telegram/html.d.ts +0 -3
  577. package/dist/adapters/telegram/html.d.ts.map +0 -1
  578. package/dist/adapters/telegram/html.js +0 -98
  579. package/dist/adapters/telegram/html.js.map +0 -1
  580. package/dist/agent-events.d.ts +0 -5
  581. package/dist/agent-events.d.ts.map +0 -1
  582. package/dist/agent-events.js +0 -26
  583. package/dist/agent-events.js.map +0 -1
  584. package/dist/agent.d.ts +0 -39
  585. package/dist/agent.d.ts.map +0 -1
  586. package/dist/agent.js +0 -1291
  587. package/dist/agent.js.map +0 -1
  588. package/dist/cli/ext-git.d.ts +0 -22
  589. package/dist/cli/ext-git.d.ts.map +0 -1
  590. package/dist/cli/ext-git.js +0 -76
  591. package/dist/cli/ext-git.js.map +0 -1
  592. package/dist/cli/ext.d.ts +0 -2
  593. package/dist/cli/ext.d.ts.map +0 -1
  594. package/dist/cli/ext.js +0 -217
  595. package/dist/cli/ext.js.map +0 -1
  596. package/dist/commands/admin.d.ts.map +0 -1
  597. package/dist/commands/admin.js.map +0 -1
  598. package/dist/commands/auto-reply.d.ts.map +0 -1
  599. package/dist/commands/auto-reply.js +0 -76
  600. package/dist/commands/auto-reply.js.map +0 -1
  601. package/dist/commands/extensions.d.ts +0 -14
  602. package/dist/commands/extensions.d.ts.map +0 -1
  603. package/dist/commands/extensions.js +0 -55
  604. package/dist/commands/extensions.js.map +0 -1
  605. package/dist/commands/login.d.ts +0 -5
  606. package/dist/commands/login.d.ts.map +0 -1
  607. package/dist/commands/login.js +0 -115
  608. package/dist/commands/login.js.map +0 -1
  609. package/dist/commands/model.d.ts +0 -10
  610. package/dist/commands/model.d.ts.map +0 -1
  611. package/dist/commands/model.js +0 -102
  612. package/dist/commands/model.js.map +0 -1
  613. package/dist/commands/new.d.ts.map +0 -1
  614. package/dist/commands/new.js +0 -25
  615. package/dist/commands/new.js.map +0 -1
  616. package/dist/commands/parse.d.ts +0 -7
  617. package/dist/commands/parse.d.ts.map +0 -1
  618. package/dist/commands/parse.js +0 -14
  619. package/dist/commands/parse.js.map +0 -1
  620. package/dist/commands/registry.d.ts +0 -5
  621. package/dist/commands/registry.d.ts.map +0 -1
  622. package/dist/commands/registry.js +0 -31
  623. package/dist/commands/registry.js.map +0 -1
  624. package/dist/commands/sandbox.d.ts.map +0 -1
  625. package/dist/commands/sandbox.js +0 -78
  626. package/dist/commands/sandbox.js.map +0 -1
  627. package/dist/commands/session-view.d.ts.map +0 -1
  628. package/dist/commands/session-view.js.map +0 -1
  629. package/dist/commands/types.d.ts +0 -66
  630. package/dist/commands/types.d.ts.map +0 -1
  631. package/dist/commands/types.js.map +0 -1
  632. package/dist/commands/utils.d.ts +0 -11
  633. package/dist/commands/utils.d.ts.map +0 -1
  634. package/dist/commands/utils.js.map +0 -1
  635. package/dist/config.d.ts +0 -78
  636. package/dist/config.d.ts.map +0 -1
  637. package/dist/config.js +0 -450
  638. package/dist/config.js.map +0 -1
  639. package/dist/download.d.ts.map +0 -1
  640. package/dist/download.js +0 -89
  641. package/dist/download.js.map +0 -1
  642. package/dist/events.d.ts +0 -43
  643. package/dist/events.d.ts.map +0 -1
  644. package/dist/events.js +0 -456
  645. package/dist/events.js.map +0 -1
  646. package/dist/execution-resolver.d.ts +0 -21
  647. package/dist/execution-resolver.d.ts.map +0 -1
  648. package/dist/execution-resolver.js +0 -170
  649. package/dist/execution-resolver.js.map +0 -1
  650. package/dist/harness/auth.d.ts +0 -16
  651. package/dist/harness/auth.d.ts.map +0 -1
  652. package/dist/harness/auth.js +0 -86
  653. package/dist/harness/auth.js.map +0 -1
  654. package/dist/harness/extensions/loader.d.ts +0 -86
  655. package/dist/harness/extensions/loader.d.ts.map +0 -1
  656. package/dist/harness/extensions/loader.js +0 -525
  657. package/dist/harness/extensions/loader.js.map +0 -1
  658. package/dist/harness/extensions/registry.d.ts +0 -23
  659. package/dist/harness/extensions/registry.d.ts.map +0 -1
  660. package/dist/harness/extensions/registry.js +0 -45
  661. package/dist/harness/extensions/registry.js.map +0 -1
  662. package/dist/harness/extensions/types.d.ts +0 -248
  663. package/dist/harness/extensions/types.d.ts.map +0 -1
  664. package/dist/harness/extensions/types.js.map +0 -1
  665. package/dist/harness/session-store.d.ts +0 -77
  666. package/dist/harness/session-store.d.ts.map +0 -1
  667. package/dist/harness/session-store.js +0 -248
  668. package/dist/harness/session-store.js.map +0 -1
  669. package/dist/harness/settings.d.ts +0 -47
  670. package/dist/harness/settings.d.ts.map +0 -1
  671. package/dist/harness/settings.js +0 -29
  672. package/dist/harness/settings.js.map +0 -1
  673. package/dist/model-registry.d.ts +0 -4
  674. package/dist/model-registry.d.ts.map +0 -1
  675. package/dist/model-registry.js +0 -7
  676. package/dist/model-registry.js.map +0 -1
  677. package/dist/platform-messages.d.ts.map +0 -1
  678. package/dist/platform-messages.js.map +0 -1
  679. package/dist/portal-shell.d.ts +0 -4
  680. package/dist/portal-shell.d.ts.map +0 -1
  681. package/dist/portal-shell.js.map +0 -1
  682. package/dist/provisioner.d.ts +0 -61
  683. package/dist/provisioner.d.ts.map +0 -1
  684. package/dist/provisioner.js.map +0 -1
  685. package/dist/runtime/agent-run-controller.d.ts +0 -31
  686. package/dist/runtime/agent-run-controller.d.ts.map +0 -1
  687. package/dist/runtime/agent-run-controller.js +0 -195
  688. package/dist/runtime/agent-run-controller.js.map +0 -1
  689. package/dist/sandbox/errors.d.ts +0 -6
  690. package/dist/sandbox/errors.d.ts.map +0 -1
  691. package/dist/sandbox/errors.js +0 -11
  692. package/dist/sandbox/errors.js.map +0 -1
  693. package/dist/sandbox/firecracker.d.ts +0 -15
  694. package/dist/sandbox/firecracker.d.ts.map +0 -1
  695. package/dist/sandbox/firecracker.js +0 -212
  696. package/dist/sandbox/firecracker.js.map +0 -1
  697. package/dist/sandbox/image.d.ts +0 -3
  698. package/dist/sandbox/image.d.ts.map +0 -1
  699. package/dist/sandbox/image.js +0 -27
  700. package/dist/sandbox/image.js.map +0 -1
  701. package/dist/sandbox/path-context.d.ts +0 -3
  702. package/dist/sandbox/path-context.d.ts.map +0 -1
  703. package/dist/sandbox/path-context.js +0 -20
  704. package/dist/sandbox/path-context.js.map +0 -1
  705. package/dist/sessions/agent-memory-file-manager.d.ts +0 -19
  706. package/dist/sessions/agent-memory-file-manager.d.ts.map +0 -1
  707. package/dist/sessions/agent-memory-file-manager.js.map +0 -1
  708. package/dist/sessions/metadata.d.ts +0 -3
  709. package/dist/sessions/metadata.d.ts.map +0 -1
  710. package/dist/sessions/metadata.js +0 -11
  711. package/dist/sessions/metadata.js.map +0 -1
  712. package/dist/sessions/policy.d.ts +0 -6
  713. package/dist/sessions/policy.d.ts.map +0 -1
  714. package/dist/sessions/policy.js +0 -23
  715. package/dist/sessions/policy.js.map +0 -1
  716. package/dist/store.d.ts +0 -46
  717. package/dist/store.d.ts.map +0 -1
  718. package/dist/store.js +0 -177
  719. package/dist/store.js.map +0 -1
  720. package/dist/tools/bash.d.ts +0 -10
  721. package/dist/tools/bash.d.ts.map +0 -1
  722. package/dist/tools/bash.js +0 -80
  723. package/dist/tools/bash.js.map +0 -1
  724. package/dist/tools/edit.d.ts +0 -11
  725. package/dist/tools/edit.d.ts.map +0 -1
  726. package/dist/tools/edit.js +0 -131
  727. package/dist/tools/edit.js.map +0 -1
  728. package/dist/tools/event.d.ts.map +0 -1
  729. package/dist/tools/event.js +0 -252
  730. package/dist/tools/event.js.map +0 -1
  731. package/dist/tools/index.d.ts +0 -24
  732. package/dist/tools/index.d.ts.map +0 -1
  733. package/dist/tools/index.js +0 -31
  734. package/dist/tools/index.js.map +0 -1
  735. package/dist/tools/react.d.ts.map +0 -1
  736. package/dist/tools/react.js.map +0 -1
  737. package/dist/tools/read.d.ts +0 -11
  738. package/dist/tools/read.d.ts.map +0 -1
  739. package/dist/tools/read.js +0 -134
  740. package/dist/tools/read.js.map +0 -1
  741. package/dist/tools/sandbox.d.ts.map +0 -1
  742. package/dist/tools/sandbox.js.map +0 -1
  743. package/dist/tools/truncate.d.ts +0 -33
  744. package/dist/tools/truncate.d.ts.map +0 -1
  745. package/dist/tools/truncate.js +0 -184
  746. package/dist/tools/truncate.js.map +0 -1
  747. package/dist/tools/types.d.ts +0 -54
  748. package/dist/tools/types.d.ts.map +0 -1
  749. package/dist/tools/types.js.map +0 -1
  750. package/dist/tools/write.d.ts +0 -10
  751. package/dist/tools/write.d.ts.map +0 -1
  752. package/dist/tools/write.js +0 -29
  753. package/dist/tools/write.js.map +0 -1
  754. package/dist/trigger.d.ts +0 -22
  755. package/dist/trigger.d.ts.map +0 -1
  756. package/dist/trigger.js +0 -100
  757. package/dist/trigger.js.map +0 -1
  758. package/dist/utils/date.d.ts +0 -10
  759. package/dist/utils/date.d.ts.map +0 -1
  760. package/dist/utils/date.js +0 -23
  761. package/dist/utils/date.js.map +0 -1
  762. package/dist/utils/env.d.ts +0 -3
  763. package/dist/utils/env.d.ts.map +0 -1
  764. package/dist/utils/env.js +0 -12
  765. package/dist/utils/env.js.map +0 -1
  766. package/dist/utils/file-guards.d.ts +0 -9
  767. package/dist/utils/file-guards.d.ts.map +0 -1
  768. package/dist/utils/file-guards.js +0 -59
  769. package/dist/utils/file-guards.js.map +0 -1
  770. package/dist/utils/fs-atomic.d.ts +0 -10
  771. package/dist/utils/fs-atomic.d.ts.map +0 -1
  772. package/dist/utils/fs-atomic.js +0 -45
  773. package/dist/utils/fs-atomic.js.map +0 -1
  774. package/dist/utils/html.d.ts +0 -2
  775. package/dist/utils/html.d.ts.map +0 -1
  776. package/dist/utils/html.js +0 -4
  777. package/dist/utils/html.js.map +0 -1
  778. package/dist/utils/http-body.d.ts +0 -10
  779. package/dist/utils/http-body.d.ts.map +0 -1
  780. package/dist/utils/http-body.js +0 -34
  781. package/dist/utils/http-body.js.map +0 -1
  782. package/dist/vault/routing.d.ts +0 -3
  783. package/dist/vault/routing.d.ts.map +0 -1
  784. package/dist/vault/routing.js +0 -13
  785. package/dist/vault/routing.js.map +0 -1
  786. package/dist/web/admin/portal.d.ts +0 -5
  787. package/dist/web/admin/portal.d.ts.map +0 -1
  788. package/dist/web/admin/portal.js +0 -2572
  789. package/dist/web/admin/portal.js.map +0 -1
  790. package/dist/web/admin/provider-models.d.ts.map +0 -1
  791. package/dist/web/admin/provider-models.js.map +0 -1
  792. package/dist/web/admin/store.d.ts +0 -13
  793. package/dist/web/admin/store.d.ts.map +0 -1
  794. package/dist/web/admin/store.js +0 -14
  795. package/dist/web/admin/store.js.map +0 -1
  796. package/dist/web/admin/types.d.ts +0 -30
  797. package/dist/web/admin/types.d.ts.map +0 -1
  798. package/dist/web/admin/types.js.map +0 -1
  799. package/dist/web/agent-events/portal.d.ts +0 -3
  800. package/dist/web/agent-events/portal.d.ts.map +0 -1
  801. package/dist/web/agent-events/portal.js +0 -18
  802. package/dist/web/agent-events/portal.js.map +0 -1
  803. package/dist/web/login/oauth.d.ts +0 -6
  804. package/dist/web/login/oauth.d.ts.map +0 -1
  805. package/dist/web/login/oauth.js.map +0 -1
  806. package/dist/web/login/portal.d.ts.map +0 -1
  807. package/dist/web/login/portal.js.map +0 -1
  808. package/dist/web/login/store.d.ts +0 -8
  809. package/dist/web/login/store.d.ts.map +0 -1
  810. package/dist/web/login/store.js +0 -15
  811. package/dist/web/login/store.js.map +0 -1
  812. package/dist/web/login/types.d.ts.map +0 -1
  813. package/dist/web/login/types.js.map +0 -1
  814. package/dist/web/request.d.ts +0 -3
  815. package/dist/web/request.d.ts.map +0 -1
  816. package/dist/web/request.js +0 -13
  817. package/dist/web/request.js.map +0 -1
  818. package/dist/web/server.d.ts.map +0 -1
  819. package/dist/web/server.js.map +0 -1
  820. package/dist/web/session-view/command.d.ts +0 -4
  821. package/dist/web/session-view/command.d.ts.map +0 -1
  822. package/dist/web/session-view/command.js +0 -7
  823. package/dist/web/session-view/command.js.map +0 -1
  824. package/dist/web/session-view/portal.d.ts +0 -13
  825. package/dist/web/session-view/portal.d.ts.map +0 -1
  826. package/dist/web/session-view/portal.js.map +0 -1
  827. package/dist/web/session-view/service.d.ts +0 -6
  828. package/dist/web/session-view/service.d.ts.map +0 -1
  829. package/dist/web/session-view/service.js +0 -498
  830. package/dist/web/session-view/service.js.map +0 -1
  831. package/dist/web/session-view/store.d.ts +0 -8
  832. package/dist/web/session-view/store.d.ts.map +0 -1
  833. package/dist/web/session-view/store.js +0 -15
  834. package/dist/web/session-view/store.js.map +0 -1
  835. package/dist/web/session-view/types.d.ts.map +0 -1
  836. package/dist/web/session-view/types.js.map +0 -1
  837. package/dist/web/token-store.d.ts.map +0 -1
  838. package/dist/web/token-store.js.map +0 -1
  839. package/dist/web/types.d.ts.map +0 -1
  840. package/dist/web/types.js.map +0 -1
  841. /package/dist/{commands → adapters/commands}/admin.d.ts +0 -0
  842. /package/dist/{commands → adapters/commands}/new.d.ts +0 -0
  843. /package/dist/{commands → adapters/commands}/sandbox.d.ts +0 -0
  844. /package/dist/{commands → adapters/commands}/session-view.d.ts +0 -0
  845. /package/dist/{commands → adapters/commands}/types.js +0 -0
  846. /package/dist/{harness/extensions → adapters/github}/types.js +0 -0
  847. /package/dist/{tools → adapters/web/admin}/types.js +0 -0
  848. /package/dist/{web/admin → adapters/web/login}/types.js +0 -0
  849. /package/dist/{web/login → adapters/web/session-view}/types.js +0 -0
  850. /package/dist/{web → adapters/web}/token-store.d.ts +0 -0
  851. /package/dist/{web → adapters/web}/types.d.ts +0 -0
  852. /package/dist/{web/session-view → adapters/web}/types.js +0 -0
  853. /package/dist/{download.d.ts → cli/download.d.ts} +0 -0
  854. /package/dist/{web → cli}/types.js +0 -0
  855. /package/dist/{adapters/slack → harness}/tools/attach.d.ts +0 -0
  856. /package/dist/{tools → harness/tools}/react.d.ts +0 -0
@@ -6,12 +6,12 @@
6
6
  * The split/normalize logic itself doesn't differ across platforms — only the
7
7
  * markup wrappers — so it lives here once.
8
8
  */
9
- import { appendFileSync } from "fs";
10
- import { mkdir, writeFile } from "fs/promises";
11
- import { dirname, join } from "path";
12
- import { ensureDirExists } from "../utils/file-guards.js";
9
+ import { appendFileSync } from "node:fs";
10
+ import { mkdir, writeFile } from "node:fs/promises";
11
+ import { dirname, join } from "node:path";
12
+ import { sameOffice } from "../office/index.js";
13
13
  import * as log from "../log.js";
14
- import { reportUserFacingError } from "../observability/sentry.js";
14
+ import { reportUserFacingError } from "../observability/index.js";
15
15
  export function createChatResponseErrorReporter(resolve) {
16
16
  return (err, operation, extra) => {
17
17
  reportChatResponseError(err, { ...resolve(), operation, extra });
@@ -40,19 +40,57 @@ function reportChatResponseError(err, context) {
40
40
  },
41
41
  });
42
42
  }
43
+ export class MessagingIntakeTracker {
44
+ constructor(name) {
45
+ this.name = name;
46
+ this.accepting = true;
47
+ this.active = new Set();
48
+ }
49
+ run(work) {
50
+ if (!this.accepting)
51
+ return Promise.resolve();
52
+ let result;
53
+ try {
54
+ result = work();
55
+ }
56
+ catch (error) {
57
+ result = Promise.reject(error);
58
+ }
59
+ const task = Promise.resolve(result).catch((error) => {
60
+ log.logWarning(`${this.name} intake error`, error instanceof Error ? error.message : String(error));
61
+ });
62
+ this.active.add(task);
63
+ return task.finally(() => this.active.delete(task));
64
+ }
65
+ async close() {
66
+ this.accepting = false;
67
+ await Promise.allSettled(this.active);
68
+ }
69
+ }
43
70
  export class MessagingEventQueue {
44
71
  constructor(name = "") {
45
72
  this.name = name;
46
73
  this.queue = [];
47
74
  this.processing = false;
75
+ this.accepting = true;
76
+ this.drainWaiters = [];
48
77
  }
49
78
  enqueue(work) {
79
+ if (!this.accepting)
80
+ return false;
50
81
  this.queue.push(work);
51
82
  this.processNext();
83
+ return true;
52
84
  }
53
85
  size() {
54
86
  return this.queue.length;
55
87
  }
88
+ close() {
89
+ this.accepting = false;
90
+ if (!this.processing && this.queue.length === 0)
91
+ return Promise.resolve();
92
+ return new Promise((resolve) => this.drainWaiters.push(resolve));
93
+ }
56
94
  async processNext() {
57
95
  if (this.processing || this.queue.length === 0)
58
96
  return;
@@ -65,7 +103,12 @@ export class MessagingEventQueue {
65
103
  log.logWarning(`${this.name ? this.name + " " : ""}queue error`, err instanceof Error ? err.message : String(err));
66
104
  }
67
105
  this.processing = false;
68
- this.processNext();
106
+ if (this.queue.length > 0) {
107
+ this.processNext();
108
+ return;
109
+ }
110
+ for (const resolve of this.drainWaiters.splice(0))
111
+ resolve();
69
112
  }
70
113
  }
71
114
  // RetryOptions is defined in ./types.ts and re-exported from the top of this file.
@@ -120,18 +163,54 @@ export function splitText(text, limit, formatContinuation) {
120
163
  return parts;
121
164
  }
122
165
  /**
123
- * Append a JSON-serializable entry to `${workingDir}/${channel}/log.jsonl`,
124
- * creating the directory on first use. This is the single write path every
166
+ * Append a JSON-serializable entry to the office's `log.jsonl`,
167
+ * materializing the office on first use. This is the single write path every
125
168
  * adapter uses for human-readable message history.
126
169
  */
127
- export function appendChannelLog(workingDir, channel, entry) {
128
- const dir = join(workingDir, channel);
129
- ensureDirExists(dir);
130
- appendFileSync(join(dir, "log.jsonl"), `${JSON.stringify(entry)}\n`);
170
+ export function appendChannelLog(office, entry) {
171
+ office.ensure();
172
+ appendFileSync(office.logPath, `${JSON.stringify(entry)}\n`);
173
+ }
174
+ /**
175
+ * Save incoming platform files under the office's attachments directory.
176
+ *
177
+ * The one owner of the attachment convention: sanitized
178
+ * `<timestamp>_<name>` filenames, the `<office key>/attachments/<file>`
179
+ * workspace-relative localPath the agent reads, and office materialization
180
+ * before the first write. Download mechanics and failure policy stay with
181
+ * the adapter — failures come back in `failed` for the caller to throw or
182
+ * warn about, matching its platform's behavior.
183
+ */
184
+ export async function saveIncomingAttachments(office, items) {
185
+ if (items.length === 0)
186
+ return { saved: [], failed: [] };
187
+ // Attachment downloads can be the office's first write; materialize (and
188
+ // register) it before composing office-relative attachment paths.
189
+ office.ensure();
190
+ await mkdir(office.attachmentsDir, { recursive: true });
191
+ // Results keep the caller's item order regardless of download completion
192
+ // order — platform message logs list attachments as the platform sent them.
193
+ const results = await Promise.all(items.map(async (item) => {
194
+ const sanitized = item.name.replace(/[^a-zA-Z0-9._-]/g, "_");
195
+ const filename = `${item.timestampMs ?? Date.now()}_${sanitized}`;
196
+ try {
197
+ await item.download(join(office.attachmentsDir, filename));
198
+ return {
199
+ saved: { original: item.name, localPath: `${office.key}/attachments/${filename}` },
200
+ };
201
+ }
202
+ catch (error) {
203
+ return { failed: { name: item.name, error } };
204
+ }
205
+ }));
206
+ return {
207
+ saved: results.flatMap((result) => (result.saved ? [result.saved] : [])),
208
+ failed: results.flatMap((result) => (result.failed ? [result.failed] : [])),
209
+ };
131
210
  }
132
211
  /** Convenience for appending the bot's own outbound message. */
133
- export function appendBotResponseLog(workingDir, channel, text, ts, threadTs, extraFields = {}) {
134
- appendChannelLog(workingDir, channel, {
212
+ export function appendBotResponseLog(office, text, ts, threadTs, extraFields = {}) {
213
+ appendChannelLog(office, {
135
214
  date: new Date().toISOString(),
136
215
  ts,
137
216
  ...(threadTs ? { threadTs } : {}),
@@ -150,23 +229,25 @@ export function appendBotResponseLog(workingDir, channel, text, ts, threadTs, ex
150
229
  * 2. The bare conversationId, if running.
151
230
  */
152
231
  export function resolveStopTarget(input) {
153
- const { handler, conversationId, sessionKey } = input;
154
- if (sessionKey && handler.isRunning(sessionKey))
232
+ const { handler, address, sessionKey } = input;
233
+ if (sessionKey && handler.isRunning(address, sessionKey))
155
234
  return sessionKey;
156
- if (handler.isRunning(conversationId))
157
- return conversationId;
235
+ if (handler.isRunning(address, address.conversationId))
236
+ return address.conversationId;
158
237
  return null;
159
238
  }
160
239
  /**
161
- * Return the single running scoped session for this conversation, or null when
162
- * there are zero or multiple matches.
240
+ * Return the single running scoped session for this office, or null when there
241
+ * are zero or multiple matches. Another platform's identically named
242
+ * conversation is a different office and is never a stop target.
163
243
  */
164
- export function resolveOnlyScopedStopTarget(handler, conversationId) {
244
+ export function resolveOnlyScopedStopTarget(handler, address) {
165
245
  const runningScopes = handler
166
246
  .getRunningSessions()
167
- .map((s) => s.sessionKey)
168
- .filter((k) => k.startsWith(`${conversationId}:`));
169
- return runningScopes.length === 1 ? runningScopes[0] : null;
247
+ .filter((session) => sameOffice(session.address, address))
248
+ .map((session) => session.sessionKey)
249
+ .filter((key) => key.startsWith(`${address.conversationId}:`));
250
+ return runningScopes.length === 1 ? (runningScopes[0] ?? null) : null;
170
251
  }
171
252
  /**
172
253
  * Render tool-call args for human display. Drops `label` (already in the
@@ -205,4 +286,29 @@ export async function downloadUrlToFile(url, destPath) {
205
286
  await mkdir(dirname(destPath), { recursive: true });
206
287
  await writeFile(destPath, Buffer.from(buffer));
207
288
  }
289
+ /**
290
+ * Slack-style short names (as the `react` tool and prompt use) to Unicode
291
+ * emoji, for platforms whose reaction API takes a Unicode character rather
292
+ * than a name (Discord, Telegram). Covers what the system prompt actually
293
+ * recommends plus a few other common names; an unmapped name passes through
294
+ * unchanged so an unsupported reaction fails visibly at the platform call
295
+ * instead of silently.
296
+ */
297
+ const SHORT_NAME_TO_UNICODE_EMOJI = {
298
+ saluting_face: "\u{1FAE1}",
299
+ eyes: "\u{1F440}",
300
+ white_check_mark: "\u{2705}",
301
+ "+1": "\u{1F44D}",
302
+ thumbsup: "\u{1F44D}",
303
+ "-1": "\u{1F44E}",
304
+ thumbsdown: "\u{1F44E}",
305
+ heart: "\u{2764}",
306
+ tada: "\u{1F389}",
307
+ rocket: "\u{1F680}",
308
+ };
309
+ /** Translate a Slack-style short name (colons optional) to Unicode; passes through anything else. */
310
+ export function shortNameToUnicodeEmoji(emoji) {
311
+ const name = emoji.replace(/^:|:$/g, "");
312
+ return SHORT_NAME_TO_UNICODE_EMOJI[name] ?? emoji;
313
+ }
208
314
  //# sourceMappingURL=shared.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Helpers shared across platform adapters.\n *\n * The agent runner is platform-agnostic: it hands strings and structured tool\n * results to each adapter, which decides how to split, format, and route them.\n * The split/normalize logic itself doesn't differ across platforms — only the\n * markup wrappers — so it lives here once.\n */\n\nimport { appendFileSync } from \"fs\";\nimport { mkdir, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport type { MessagingEventHandler } from \"../adapter.js\";\nimport { ensureDirExists } from \"../utils/file-guards.js\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/sentry.js\";\nexport type {\n ChatResponseErrorContext,\n ChatResponseErrorOperation,\n ChatResponseErrorReporter,\n ResolveStopTargetInput,\n RetryOptions,\n} from \"./types.js\";\nimport type {\n ChatResponseErrorContext,\n ChatResponseErrorReporter,\n RetryOptions,\n ResolveStopTargetInput,\n} from \"./types.js\";\n\nexport function createChatResponseErrorReporter(\n resolve: () => Omit<ChatResponseErrorContext, \"operation\" | \"extra\">,\n): ChatResponseErrorReporter {\n return (err, operation, extra) => {\n reportChatResponseError(err, { ...resolve(), operation, extra });\n };\n}\n\nfunction reportChatResponseError(err: unknown, context: ChatResponseErrorContext): void {\n reportUserFacingError(err, {\n domain: \"chat_platform\",\n surface: \"chat_response\",\n operation: context.operation,\n severity: context.operation === \"set_working\" ? \"warning\" : \"error\",\n platform: context.platform,\n context: {\n conversationId: context.conversationId,\n channelId: context.channelId,\n chatId: context.chatId,\n messageId: context.messageId,\n sessionKey: context.sessionKey,\n responseMessageId: context.responseMessageId,\n threadTs: context.threadTs,\n replyTargetId: context.replyTargetId,\n replyToId: context.replyToId,\n conversationKind: context.conversationKind,\n isThreaded: context.isThreaded,\n ...context.extra,\n },\n });\n}\n\nexport class MessagingEventQueue {\n private queue: Array<() => Promise<void>> = [];\n private processing = false;\n\n constructor(private readonly name: string = \"\") {}\n\n enqueue(work: () => Promise<void>): void {\n this.queue.push(work);\n this.processNext();\n }\n\n size(): number {\n return this.queue.length;\n }\n\n private async processNext(): Promise<void> {\n if (this.processing || this.queue.length === 0) return;\n this.processing = true;\n const work = this.queue.shift()!;\n try {\n await work();\n } catch (err) {\n log.logWarning(\n `${this.name ? this.name + \" \" : \"\"}queue error`,\n err instanceof Error ? err.message : String(err),\n );\n }\n this.processing = false;\n this.processNext();\n }\n}\n\n// RetryOptions is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Run `fn` and retry with exponential backoff when its error matches\n * `isRateLimited`. Other errors propagate immediately. Each platform supplies\n * its own predicate so we don't have to know every SDK's error shape here.\n */\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T> {\n const maxAttempts = opts.maxAttempts ?? 3;\n const baseDelayMs = opts.baseDelayMs ?? 1000;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n const isLastAttempt = attempt === maxAttempts - 1;\n if (isLastAttempt || !opts.isRateLimited(lastError)) {\n throw lastError;\n }\n\n const delay = baseDelayMs * Math.pow(2, attempt);\n log.logWarning(\n `Retrying after error in ${delay}ms (attempt ${attempt + 1}/${maxAttempts}): ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n throw lastError;\n}\n\n/**\n * Split `text` into chunks no larger than `limit`, appending a continuation\n * marker (e.g. `_(continued 1)_`) at the end of every part except the last.\n *\n * Each adapter passes its own `formatContinuation` so the marker uses the\n * platform's italic / emphasis convention.\n */\nexport function splitText(\n text: string,\n limit: number,\n formatContinuation: (partNum: number) => string,\n): string[] {\n if (text.length <= limit) return [text];\n const parts: string[] = [];\n let remaining = text;\n let partNum = 1;\n while (remaining.length > 0) {\n const suffixReserve = formatContinuation(partNum).length + 8;\n const chunkLimit = Math.max(1, limit - suffixReserve);\n const chunk = remaining.slice(0, chunkLimit);\n remaining = remaining.slice(chunkLimit);\n const suffix = remaining.length > 0 ? `\\n${formatContinuation(partNum)}` : \"\";\n parts.push(chunk + suffix);\n partNum++;\n }\n return parts;\n}\n\n/**\n * Append a JSON-serializable entry to `${workingDir}/${channel}/log.jsonl`,\n * creating the directory on first use. This is the single write path every\n * adapter uses for human-readable message history.\n */\nexport function appendChannelLog(workingDir: string, channel: string, entry: object): void {\n const dir = join(workingDir, channel);\n ensureDirExists(dir);\n appendFileSync(join(dir, \"log.jsonl\"), `${JSON.stringify(entry)}\\n`);\n}\n\n/** Convenience for appending the bot's own outbound message. */\nexport function appendBotResponseLog(\n workingDir: string,\n channel: string,\n text: string,\n ts: string,\n threadTs?: string,\n extraFields: Record<string, unknown> = {},\n): void {\n appendChannelLog(workingDir, channel, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: \"bot\",\n text,\n attachments: [],\n isMessagingBot: true,\n ...extraFields,\n });\n}\n\n// ResolveStopTargetInput is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Pick which session key a `/stop` should target without applying any\n * platform-specific fallback policy. Order:\n * 1. The provided sessionKey, if running.\n * 2. The bare conversationId, if running.\n */\nexport function resolveStopTarget(input: ResolveStopTargetInput): string | null {\n const { handler, conversationId, sessionKey } = input;\n\n if (sessionKey && handler.isRunning(sessionKey)) return sessionKey;\n if (handler.isRunning(conversationId)) return conversationId;\n return null;\n}\n\n/**\n * Return the single running scoped session for this conversation, or null when\n * there are zero or multiple matches.\n */\nexport function resolveOnlyScopedStopTarget(\n handler: MessagingEventHandler,\n conversationId: string,\n): string | null {\n const runningScopes = handler\n .getRunningSessions()\n .map((s) => s.sessionKey)\n .filter((k) => k.startsWith(`${conversationId}:`));\n\n return runningScopes.length === 1 ? runningScopes[0] : null;\n}\n\n/**\n * Render tool-call args for human display. Drops `label` (already in the\n * heading) and folds `path` + `offset`/`limit` into a single `path:start-end`\n * line. Pure data normalization with no platform-specific markup.\n */\nexport function formatToolArgs(args: Record<string, unknown> | undefined): string {\n if (!args) return \"\";\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(args)) {\n if (key === \"label\" || key === \"offset\" || key === \"limit\") continue;\n\n if (key === \"path\" && typeof value === \"string\") {\n const offset = args.offset as number | undefined;\n const limit = args.limit as number | undefined;\n lines.push(\n offset !== undefined && limit !== undefined\n ? `${value}:${offset}-${offset + limit}`\n : value,\n );\n continue;\n }\n\n lines.push(typeof value === \"string\" ? value : JSON.stringify(value));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Fetch `url` and write the response body to `destPath`, creating parent\n * directories as needed. Throws on non-2xx responses or write failures.\n */\nexport async function downloadUrlToFile(url: string, destPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await mkdir(dirname(destPath), { recursive: true });\n await writeFile(destPath, Buffer.from(buffer));\n}\n"]}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/adapters/shared.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Helpers shared across platform adapters.\n *\n * The agent runner is platform-agnostic: it hands strings and structured tool\n * results to each adapter, which decides how to split, format, and route them.\n * The split/normalize logic itself doesn't differ across platforms — only the\n * markup wrappers — so it lives here once.\n */\n\nimport { appendFileSync } from \"node:fs\";\nimport { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport type { MessagingEventHandler, OfficeAddress } from \"./index.js\";\nimport { sameOffice, type Office } from \"../office/index.js\";\nimport * as log from \"../log.js\";\nimport { reportUserFacingError } from \"../observability/index.js\";\nexport type {\n ChatResponseErrorContext,\n ChatResponseErrorOperation,\n ChatResponseErrorReporter,\n IncomingAttachment,\n ResolveStopTargetInput,\n RetryOptions,\n SavedAttachments,\n} from \"./types.js\";\nimport type {\n ChatResponseErrorContext,\n ChatResponseErrorReporter,\n IncomingAttachment,\n RetryOptions,\n ResolveStopTargetInput,\n SavedAttachments,\n} from \"./types.js\";\n\nexport function createChatResponseErrorReporter(\n resolve: () => Omit<ChatResponseErrorContext, \"operation\" | \"extra\">,\n): ChatResponseErrorReporter {\n return (err, operation, extra) => {\n reportChatResponseError(err, { ...resolve(), operation, extra });\n };\n}\n\nfunction reportChatResponseError(err: unknown, context: ChatResponseErrorContext): void {\n reportUserFacingError(err, {\n domain: \"chat_platform\",\n surface: \"chat_response\",\n operation: context.operation,\n severity: context.operation === \"set_working\" ? \"warning\" : \"error\",\n platform: context.platform,\n context: {\n conversationId: context.conversationId,\n channelId: context.channelId,\n chatId: context.chatId,\n messageId: context.messageId,\n sessionKey: context.sessionKey,\n responseMessageId: context.responseMessageId,\n threadTs: context.threadTs,\n replyTargetId: context.replyTargetId,\n replyToId: context.replyToId,\n conversationKind: context.conversationKind,\n isThreaded: context.isThreaded,\n ...context.extra,\n },\n });\n}\n\nexport class MessagingIntakeTracker {\n private accepting = true;\n private active = new Set<Promise<void>>();\n\n constructor(private readonly name: string) {}\n\n run(work: () => Promise<void> | void): Promise<void> {\n if (!this.accepting) return Promise.resolve();\n let result: Promise<void> | void;\n try {\n result = work();\n } catch (error) {\n result = Promise.reject(error);\n }\n const task = Promise.resolve(result).catch((error) => {\n log.logWarning(\n `${this.name} intake error`,\n error instanceof Error ? error.message : String(error),\n );\n });\n this.active.add(task);\n return task.finally(() => this.active.delete(task));\n }\n\n async close(): Promise<void> {\n this.accepting = false;\n await Promise.allSettled(this.active);\n }\n}\n\nexport class MessagingEventQueue {\n private queue: Array<() => Promise<void>> = [];\n private processing = false;\n private accepting = true;\n private drainWaiters: Array<() => void> = [];\n\n constructor(private readonly name: string = \"\") {}\n\n enqueue(work: () => Promise<void>): boolean {\n if (!this.accepting) return false;\n this.queue.push(work);\n this.processNext();\n return true;\n }\n\n size(): number {\n return this.queue.length;\n }\n\n close(): Promise<void> {\n this.accepting = false;\n if (!this.processing && this.queue.length === 0) return Promise.resolve();\n return new Promise((resolve) => this.drainWaiters.push(resolve));\n }\n\n private async processNext(): Promise<void> {\n if (this.processing || this.queue.length === 0) return;\n this.processing = true;\n const work = this.queue.shift()!;\n try {\n await work();\n } catch (err) {\n log.logWarning(\n `${this.name ? this.name + \" \" : \"\"}queue error`,\n err instanceof Error ? err.message : String(err),\n );\n }\n this.processing = false;\n if (this.queue.length > 0) {\n this.processNext();\n return;\n }\n for (const resolve of this.drainWaiters.splice(0)) resolve();\n }\n}\n\n// RetryOptions is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Run `fn` and retry with exponential backoff when its error matches\n * `isRateLimited`. Other errors propagate immediately. Each platform supplies\n * its own predicate so we don't have to know every SDK's error shape here.\n */\nexport async function withRetry<T>(fn: () => Promise<T>, opts: RetryOptions): Promise<T> {\n const maxAttempts = opts.maxAttempts ?? 3;\n const baseDelayMs = opts.baseDelayMs ?? 1000;\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n const isLastAttempt = attempt === maxAttempts - 1;\n if (isLastAttempt || !opts.isRateLimited(lastError)) {\n throw lastError;\n }\n\n const delay = baseDelayMs * Math.pow(2, attempt);\n log.logWarning(\n `Retrying after error in ${delay}ms (attempt ${attempt + 1}/${maxAttempts}): ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n throw lastError;\n}\n\n/**\n * Split `text` into chunks no larger than `limit`, appending a continuation\n * marker (e.g. `_(continued 1)_`) at the end of every part except the last.\n *\n * Each adapter passes its own `formatContinuation` so the marker uses the\n * platform's italic / emphasis convention.\n */\nexport function splitText(\n text: string,\n limit: number,\n formatContinuation: (partNum: number) => string,\n): string[] {\n if (text.length <= limit) return [text];\n const parts: string[] = [];\n let remaining = text;\n let partNum = 1;\n while (remaining.length > 0) {\n const suffixReserve = formatContinuation(partNum).length + 8;\n const chunkLimit = Math.max(1, limit - suffixReserve);\n const chunk = remaining.slice(0, chunkLimit);\n remaining = remaining.slice(chunkLimit);\n const suffix = remaining.length > 0 ? `\\n${formatContinuation(partNum)}` : \"\";\n parts.push(chunk + suffix);\n partNum++;\n }\n return parts;\n}\n\n/**\n * Append a JSON-serializable entry to the office's `log.jsonl`,\n * materializing the office on first use. This is the single write path every\n * adapter uses for human-readable message history.\n */\nexport function appendChannelLog(office: Office, entry: object): void {\n office.ensure();\n appendFileSync(office.logPath, `${JSON.stringify(entry)}\\n`);\n}\n\n/**\n * Save incoming platform files under the office's attachments directory.\n *\n * The one owner of the attachment convention: sanitized\n * `<timestamp>_<name>` filenames, the `<office key>/attachments/<file>`\n * workspace-relative localPath the agent reads, and office materialization\n * before the first write. Download mechanics and failure policy stay with\n * the adapter — failures come back in `failed` for the caller to throw or\n * warn about, matching its platform's behavior.\n */\nexport async function saveIncomingAttachments(\n office: Office,\n items: readonly IncomingAttachment[],\n): Promise<SavedAttachments> {\n if (items.length === 0) return { saved: [], failed: [] };\n // Attachment downloads can be the office's first write; materialize (and\n // register) it before composing office-relative attachment paths.\n office.ensure();\n await mkdir(office.attachmentsDir, { recursive: true });\n\n // Results keep the caller's item order regardless of download completion\n // order — platform message logs list attachments as the platform sent them.\n const results = await Promise.all(\n items.map(async (item) => {\n const sanitized = item.name.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const filename = `${item.timestampMs ?? Date.now()}_${sanitized}`;\n try {\n await item.download(join(office.attachmentsDir, filename));\n return {\n saved: { original: item.name, localPath: `${office.key}/attachments/${filename}` },\n };\n } catch (error) {\n return { failed: { name: item.name, error } };\n }\n }),\n );\n return {\n saved: results.flatMap((result) => (result.saved ? [result.saved] : [])),\n failed: results.flatMap((result) => (result.failed ? [result.failed] : [])),\n };\n}\n\n/** Convenience for appending the bot's own outbound message. */\nexport function appendBotResponseLog(\n office: Office,\n text: string,\n ts: string,\n threadTs?: string,\n extraFields: Record<string, unknown> = {},\n): void {\n appendChannelLog(office, {\n date: new Date().toISOString(),\n ts,\n ...(threadTs ? { threadTs } : {}),\n user: \"bot\",\n text,\n attachments: [],\n isMessagingBot: true,\n ...extraFields,\n });\n}\n\n// ResolveStopTargetInput is defined in ./types.ts and re-exported from the top of this file.\n\n/**\n * Pick which session key a `/stop` should target without applying any\n * platform-specific fallback policy. Order:\n * 1. The provided sessionKey, if running.\n * 2. The bare conversationId, if running.\n */\nexport function resolveStopTarget(input: ResolveStopTargetInput): string | null {\n const { handler, address, sessionKey } = input;\n\n if (sessionKey && handler.isRunning(address, sessionKey)) return sessionKey;\n if (handler.isRunning(address, address.conversationId)) return address.conversationId;\n return null;\n}\n\n/**\n * Return the single running scoped session for this office, or null when there\n * are zero or multiple matches. Another platform's identically named\n * conversation is a different office and is never a stop target.\n */\nexport function resolveOnlyScopedStopTarget(\n handler: MessagingEventHandler,\n address: OfficeAddress,\n): string | null {\n const runningScopes = handler\n .getRunningSessions()\n .filter((session) => sameOffice(session.address, address))\n .map((session) => session.sessionKey)\n .filter((key) => key.startsWith(`${address.conversationId}:`));\n\n return runningScopes.length === 1 ? (runningScopes[0] ?? null) : null;\n}\n\n/**\n * Render tool-call args for human display. Drops `label` (already in the\n * heading) and folds `path` + `offset`/`limit` into a single `path:start-end`\n * line. Pure data normalization with no platform-specific markup.\n */\nexport function formatToolArgs(args: Record<string, unknown> | undefined): string {\n if (!args) return \"\";\n const lines: string[] = [];\n\n for (const [key, value] of Object.entries(args)) {\n if (key === \"label\" || key === \"offset\" || key === \"limit\") continue;\n\n if (key === \"path\" && typeof value === \"string\") {\n const offset = args.offset as number | undefined;\n const limit = args.limit as number | undefined;\n lines.push(\n offset !== undefined && limit !== undefined\n ? `${value}:${offset}-${offset + limit}`\n : value,\n );\n continue;\n }\n\n lines.push(typeof value === \"string\" ? value : JSON.stringify(value));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Fetch `url` and write the response body to `destPath`, creating parent\n * directories as needed. Throws on non-2xx responses or write failures.\n */\nexport async function downloadUrlToFile(url: string, destPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n const buffer = await response.arrayBuffer();\n await mkdir(dirname(destPath), { recursive: true });\n await writeFile(destPath, Buffer.from(buffer));\n}\n\n/**\n * Slack-style short names (as the `react` tool and prompt use) to Unicode\n * emoji, for platforms whose reaction API takes a Unicode character rather\n * than a name (Discord, Telegram). Covers what the system prompt actually\n * recommends plus a few other common names; an unmapped name passes through\n * unchanged so an unsupported reaction fails visibly at the platform call\n * instead of silently.\n */\nconst SHORT_NAME_TO_UNICODE_EMOJI: Record<string, string> = {\n saluting_face: \"\\u{1FAE1}\",\n eyes: \"\\u{1F440}\",\n white_check_mark: \"\\u{2705}\",\n \"+1\": \"\\u{1F44D}\",\n thumbsup: \"\\u{1F44D}\",\n \"-1\": \"\\u{1F44E}\",\n thumbsdown: \"\\u{1F44E}\",\n heart: \"\\u{2764}\",\n tada: \"\\u{1F389}\",\n rocket: \"\\u{1F680}\",\n};\n\n/** Translate a Slack-style short name (colons optional) to Unicode; passes through anything else. */\nexport function shortNameToUnicodeEmoji(emoji: string): string {\n const name = emoji.replace(/^:|:$/g, \"\");\n return SHORT_NAME_TO_UNICODE_EMOJI[name] ?? emoji;\n}\n"]}
@@ -0,0 +1,73 @@
1
+ import type { AgentContext, AssistantSurfaceOps, AssistantThreadPayload } from "./types.js";
2
+ export type { AgentContext, AssistantSurfaceOps, AssistantThreadPayload, SuggestedPrompt, } from "./types.js";
3
+ /**
4
+ * Which conversations belong to this surface, and the context Slack last
5
+ * reported for each.
6
+ *
7
+ * Two levels, because the two manifest keys register at different grains: an
8
+ * `agent_view` DM is known before any thread exists, while an
9
+ * `assistant_view` thread is known individually.
10
+ *
11
+ * In memory on purpose: transient UI state that Slack re-sends on open and on
12
+ * every change, so a restart self-heals on the next interaction. Persisting it
13
+ * would add a store to keep consistent for nothing that survives the trip.
14
+ */
15
+ export declare class AssistantThreadRegistry {
16
+ private threads;
17
+ private channels;
18
+ private titled;
19
+ private key;
20
+ /** An `assistant_view` thread. */
21
+ remember(channelId: string, threadTs: string, context?: AgentContext): void;
22
+ /** An `agent_view` DM, which has no thread yet. */
23
+ rememberChannel(channelId: string, context?: AgentContext): void;
24
+ /** Thread context, falling back to the channel's. */
25
+ contextFor(channelId: string, threadTs: string): AgentContext | undefined;
26
+ channelContext(channelId: string): AgentContext | undefined;
27
+ /**
28
+ * Whether this thread is part of the pane — either registered individually,
29
+ * or living in a DM known to be the agent surface. The second case is what
30
+ * makes titles work under `agent_view`, where Slack opens threads itself and
31
+ * never announces them.
32
+ */
33
+ isAgentSurface(channelId: string, threadTs: string): boolean;
34
+ /** True the first time a thread is seen, so a title is set exactly once. */
35
+ claimTitle(channelId: string, threadTs: string): boolean;
36
+ }
37
+ /**
38
+ * `assistant_view`: a new conversation opened. Greet, and offer prompts for
39
+ * that thread.
40
+ *
41
+ * Failures are logged, never thrown. A greeting that did not post is a worse
42
+ * pane, not a broken conversation, and taking the socket handler down over it
43
+ * would break the surface entirely.
44
+ */
45
+ export declare function handleAssistantThreadStarted(ops: AssistantSurfaceOps, registry: AssistantThreadRegistry, thread: AssistantThreadPayload): Promise<void>;
46
+ /**
47
+ * `agent_view`: the person opened the app's DM. Refresh the prompts pinned to
48
+ * it — and deliberately do not greet, because Slack sends this on *every*
49
+ * open, so a greeting here would arrive again and again.
50
+ */
51
+ export declare function handleAgentDmOpened(ops: AssistantSurfaceOps, registry: AssistantThreadRegistry, channelId: string, context?: AgentContext): Promise<void>;
52
+ /**
53
+ * The person navigated elsewhere. Recorded at both grains so the next turn —
54
+ * and the next prompt refresh — knows where they are, whichever manifest key
55
+ * this app uses.
56
+ */
57
+ export declare function handleAgentContextChanged(registry: AssistantThreadRegistry, payload: {
58
+ channel_id?: string;
59
+ thread_ts?: string;
60
+ context?: AgentContext;
61
+ }): void;
62
+ /**
63
+ * Title a conversation from the first thing the person said, so the pane's
64
+ * sidebar is navigable. Without it every past conversation looks the same.
65
+ */
66
+ export declare function titleAssistantThread(ops: AssistantSurfaceOps, registry: AssistantThreadRegistry, channelId: string, threadTs: string, firstMessage: string): Promise<void>;
67
+ /**
68
+ * First line, trimmed to something a sidebar can show. Deliberately not a
69
+ * model call: a title is worth having immediately and cheaply, and the
70
+ * person's own words label the conversation better than a paraphrase.
71
+ */
72
+ export declare function summarizeTitle(message: string): string;
73
+ //# sourceMappingURL=assistant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC;AA4BpB;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,MAAM,CAAqB;IAEnC,OAAO,CAAC,GAAG;IAIX,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAE1E;IAED,mDAAmD;IACnD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAE/D;IAED,qDAAqD;IACrD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAExE;IAED,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE1D;IAED;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3D;IAED,4EAA4E;IAC5E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKvD;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,GAC3E,IAAI,CAaN;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQtD"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Slack's agent / assistant surface — the app's own pane, separate from
3
+ * channels and ordinary DMs.
4
+ *
5
+ * There are two of these, not one, and they differ in which events signal
6
+ * "someone opened a conversation":
7
+ *
8
+ * | Manifest key | Opened signal | Prompts |
9
+ * | ----------------- | ------------------------------------ | ------------- |
10
+ * | `agent_view` | `app_home_opened` with tab=`messages` | pinned to the DM |
11
+ * | `assistant_view` | `assistant_thread_started` | per thread |
12
+ *
13
+ * Slack's own words for the newer one: "rely on the `app_home_opened` event to
14
+ * know when a user has actively opened a DM with your app", and
15
+ * "the `assistant_thread_started` event no longer indicates this". What the
16
+ * docs do *not* say is whether `assistant_thread_started` still fires for an
17
+ * `agent_view` app — so both paths are handled rather than guessed at, which
18
+ * also means an app on either manifest key works without a migration.
19
+ *
20
+ * The two signals need different behaviour, and conflating them would be a
21
+ * bug: `assistant_thread_started` fires once per new conversation, so greeting
22
+ * is right; `app_home_opened` fires **every time the pane is opened**, so
23
+ * greeting there would nag. The agent path therefore only refreshes the
24
+ * pinned prompts, which is idempotent.
25
+ *
26
+ * Session semantics are deliberately unchanged. Each conversation is a thread
27
+ * and mikan already scopes a thread to its own session — the right shape,
28
+ * because the pane's sidebar is a list of separate conversations rather than
29
+ * one transcript. Continuity across them comes from the office's memory.
30
+ *
31
+ * Suggested prompts are deterministic, varying only with the channel Slack
32
+ * says the person is viewing. Enough to feel aware without spending a model
33
+ * call before they have typed anything.
34
+ */
35
+ import * as log from "../../log.js";
36
+ /** The `assistant_thread` payload on the `assistant_view` lifecycle events. */
37
+ const GREETING = "有什麼我可以幫忙的?";
38
+ const GREETING_WITH_CHANNEL = (channel) => `有什麼我可以幫忙的?我看得到你正在 #${channel}。`;
39
+ /** Prompts offered with no channel context — general-purpose starting points. */
40
+ const DEFAULT_PROMPTS = [
41
+ { title: "看看工作區", message: "這個工作區裡有什麼?先給我一個概覽。" },
42
+ { title: "最近的變更", message: "最近的程式碼變更有哪些?挑重要的說。" },
43
+ { title: "排一個提醒", message: "幫我排一個每天早上的提醒。" },
44
+ ];
45
+ /**
46
+ * Prompts when Slack tells us which channel the person is looking at. Naming
47
+ * the channel is the cheap half of "context-aware": it costs nothing and it is
48
+ * what makes the suggestions feel addressed to the moment.
49
+ */
50
+ function promptsFor(channel) {
51
+ if (!channel)
52
+ return DEFAULT_PROMPTS;
53
+ return [
54
+ { title: `#${channel} 在討論什麼`, message: `幫我摘要 #${channel} 最近的討論。` },
55
+ { title: "有什麼要我接手", message: `#${channel} 裡有沒有需要我處理或追蹤的事?` },
56
+ { title: "看看工作區", message: "這個工作區裡有什麼?先給我一個概覽。" },
57
+ ];
58
+ }
59
+ /**
60
+ * Which conversations belong to this surface, and the context Slack last
61
+ * reported for each.
62
+ *
63
+ * Two levels, because the two manifest keys register at different grains: an
64
+ * `agent_view` DM is known before any thread exists, while an
65
+ * `assistant_view` thread is known individually.
66
+ *
67
+ * In memory on purpose: transient UI state that Slack re-sends on open and on
68
+ * every change, so a restart self-heals on the next interaction. Persisting it
69
+ * would add a store to keep consistent for nothing that survives the trip.
70
+ */
71
+ export class AssistantThreadRegistry {
72
+ constructor() {
73
+ this.threads = new Map();
74
+ this.channels = new Map();
75
+ this.titled = new Set();
76
+ }
77
+ key(channelId, threadTs) {
78
+ return `${channelId}\n${threadTs}`;
79
+ }
80
+ /** An `assistant_view` thread. */
81
+ remember(channelId, threadTs, context) {
82
+ this.threads.set(this.key(channelId, threadTs), context ?? {});
83
+ }
84
+ /** An `agent_view` DM, which has no thread yet. */
85
+ rememberChannel(channelId, context) {
86
+ this.channels.set(channelId, context ?? {});
87
+ }
88
+ /** Thread context, falling back to the channel's. */
89
+ contextFor(channelId, threadTs) {
90
+ return this.threads.get(this.key(channelId, threadTs)) ?? this.channels.get(channelId);
91
+ }
92
+ channelContext(channelId) {
93
+ return this.channels.get(channelId);
94
+ }
95
+ /**
96
+ * Whether this thread is part of the pane — either registered individually,
97
+ * or living in a DM known to be the agent surface. The second case is what
98
+ * makes titles work under `agent_view`, where Slack opens threads itself and
99
+ * never announces them.
100
+ */
101
+ isAgentSurface(channelId, threadTs) {
102
+ return this.threads.has(this.key(channelId, threadTs)) || this.channels.has(channelId);
103
+ }
104
+ /** True the first time a thread is seen, so a title is set exactly once. */
105
+ claimTitle(channelId, threadTs) {
106
+ const key = this.key(channelId, threadTs);
107
+ if (this.titled.has(key))
108
+ return false;
109
+ this.titled.add(key);
110
+ return true;
111
+ }
112
+ }
113
+ /**
114
+ * `assistant_view`: a new conversation opened. Greet, and offer prompts for
115
+ * that thread.
116
+ *
117
+ * Failures are logged, never thrown. A greeting that did not post is a worse
118
+ * pane, not a broken conversation, and taking the socket handler down over it
119
+ * would break the surface entirely.
120
+ */
121
+ export async function handleAssistantThreadStarted(ops, registry, thread) {
122
+ const channelId = thread.channel_id;
123
+ const threadTs = thread.thread_ts;
124
+ if (!channelId || !threadTs)
125
+ return;
126
+ registry.remember(channelId, threadTs, thread.context);
127
+ const channel = thread.context?.channel_id
128
+ ? ops.channelName(thread.context.channel_id)
129
+ : undefined;
130
+ await swallow("greeting", () => ops.postInThread(channelId, threadTs, channel ? GREETING_WITH_CHANNEL(channel) : GREETING));
131
+ await swallow("setSuggestedPrompts", () => ops.setSuggestedPrompts(channelId, threadTs, promptsFor(channel)));
132
+ }
133
+ /**
134
+ * `agent_view`: the person opened the app's DM. Refresh the prompts pinned to
135
+ * it — and deliberately do not greet, because Slack sends this on *every*
136
+ * open, so a greeting here would arrive again and again.
137
+ */
138
+ export async function handleAgentDmOpened(ops, registry, channelId, context) {
139
+ if (!channelId)
140
+ return;
141
+ registry.rememberChannel(channelId, context);
142
+ const channel = context?.channel_id ? ops.channelName(context.channel_id) : undefined;
143
+ // The agent surface is otherwise silent, and its failure mode — no prompts,
144
+ // untitled conversations — looks identical from the outside to Slack simply
145
+ // not sending the event. This line is the difference between the two, and
146
+ // is the first thing to look for when the pane seems inert.
147
+ log.logInfo(`[${channelId}] Slack agent DM opened${channel ? ` (viewing #${channel})` : ""}; refreshing suggested prompts`);
148
+ await swallow("setSuggestedPrompts", () => ops.setSuggestedPrompts(channelId, undefined, promptsFor(channel)));
149
+ }
150
+ /**
151
+ * The person navigated elsewhere. Recorded at both grains so the next turn —
152
+ * and the next prompt refresh — knows where they are, whichever manifest key
153
+ * this app uses.
154
+ */
155
+ export function handleAgentContextChanged(registry, payload) {
156
+ if (!payload.channel_id)
157
+ return;
158
+ // Logged for the same reason as the open event: these two are the whole
159
+ // agent surface, and whether either is subscribed is otherwise invisible
160
+ // from inside mikan.
161
+ log.logInfo(`[${payload.channel_id}] Slack agent context changed${payload.context?.channel_id ? ` (viewing ${payload.context.channel_id})` : ""}`);
162
+ if (payload.thread_ts) {
163
+ registry.remember(payload.channel_id, payload.thread_ts, payload.context);
164
+ return;
165
+ }
166
+ registry.rememberChannel(payload.channel_id, payload.context);
167
+ }
168
+ /**
169
+ * Title a conversation from the first thing the person said, so the pane's
170
+ * sidebar is navigable. Without it every past conversation looks the same.
171
+ */
172
+ export async function titleAssistantThread(ops, registry, channelId, threadTs, firstMessage) {
173
+ if (!registry.isAgentSurface(channelId, threadTs))
174
+ return;
175
+ if (!registry.claimTitle(channelId, threadTs))
176
+ return;
177
+ const title = summarizeTitle(firstMessage);
178
+ if (!title)
179
+ return;
180
+ await swallow("setTitle", () => ops.setTitle(channelId, threadTs, title));
181
+ }
182
+ /**
183
+ * First line, trimmed to something a sidebar can show. Deliberately not a
184
+ * model call: a title is worth having immediately and cheaply, and the
185
+ * person's own words label the conversation better than a paraphrase.
186
+ */
187
+ export function summarizeTitle(message) {
188
+ const firstLine = message
189
+ .replace(/<@[^>]+>/g, "")
190
+ .split("\n")
191
+ .map((line) => line.trim())
192
+ .find((line) => line.length > 0);
193
+ if (!firstLine)
194
+ return "";
195
+ return firstLine.length <= 50 ? firstLine : `${firstLine.slice(0, 49)}…`;
196
+ }
197
+ async function swallow(label, run) {
198
+ try {
199
+ await run();
200
+ }
201
+ catch (err) {
202
+ log.logWarning(`Slack agent surface ${label} failed`, err instanceof Error ? err.message : String(err));
203
+ }
204
+ }
205
+ //# sourceMappingURL=assistant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Slack's agent / assistant surface — the app's own pane, separate from\n * channels and ordinary DMs.\n *\n * There are two of these, not one, and they differ in which events signal\n * \"someone opened a conversation\":\n *\n * | Manifest key | Opened signal | Prompts |\n * | ----------------- | ------------------------------------ | ------------- |\n * | `agent_view` | `app_home_opened` with tab=`messages` | pinned to the DM |\n * | `assistant_view` | `assistant_thread_started` | per thread |\n *\n * Slack's own words for the newer one: \"rely on the `app_home_opened` event to\n * know when a user has actively opened a DM with your app\", and\n * \"the `assistant_thread_started` event no longer indicates this\". What the\n * docs do *not* say is whether `assistant_thread_started` still fires for an\n * `agent_view` app — so both paths are handled rather than guessed at, which\n * also means an app on either manifest key works without a migration.\n *\n * The two signals need different behaviour, and conflating them would be a\n * bug: `assistant_thread_started` fires once per new conversation, so greeting\n * is right; `app_home_opened` fires **every time the pane is opened**, so\n * greeting there would nag. The agent path therefore only refreshes the\n * pinned prompts, which is idempotent.\n *\n * Session semantics are deliberately unchanged. Each conversation is a thread\n * and mikan already scopes a thread to its own session — the right shape,\n * because the pane's sidebar is a list of separate conversations rather than\n * one transcript. Continuity across them comes from the office's memory.\n *\n * Suggested prompts are deterministic, varying only with the channel Slack\n * says the person is viewing. Enough to feel aware without spending a model\n * call before they have typed anything.\n */\nimport * as log from \"../../log.js\";\nimport type {\n AgentContext,\n AssistantSurfaceOps,\n AssistantThreadPayload,\n SuggestedPrompt,\n} from \"./types.js\";\n\nexport type {\n AgentContext,\n AssistantSurfaceOps,\n AssistantThreadPayload,\n SuggestedPrompt,\n} from \"./types.js\";\n\n/** The `assistant_thread` payload on the `assistant_view` lifecycle events. */\nconst GREETING = \"有什麼我可以幫忙的?\";\nconst GREETING_WITH_CHANNEL = (channel: string) =>\n `有什麼我可以幫忙的?我看得到你正在 #${channel}。`;\n\n/** Prompts offered with no channel context — general-purpose starting points. */\nconst DEFAULT_PROMPTS: SuggestedPrompt[] = [\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n { title: \"最近的變更\", message: \"最近的程式碼變更有哪些?挑重要的說。\" },\n { title: \"排一個提醒\", message: \"幫我排一個每天早上的提醒。\" },\n];\n\n/**\n * Prompts when Slack tells us which channel the person is looking at. Naming\n * the channel is the cheap half of \"context-aware\": it costs nothing and it is\n * what makes the suggestions feel addressed to the moment.\n */\nfunction promptsFor(channel: string | undefined): SuggestedPrompt[] {\n if (!channel) return DEFAULT_PROMPTS;\n return [\n { title: `#${channel} 在討論什麼`, message: `幫我摘要 #${channel} 最近的討論。` },\n { title: \"有什麼要我接手\", message: `#${channel} 裡有沒有需要我處理或追蹤的事?` },\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n ];\n}\n\n/**\n * Which conversations belong to this surface, and the context Slack last\n * reported for each.\n *\n * Two levels, because the two manifest keys register at different grains: an\n * `agent_view` DM is known before any thread exists, while an\n * `assistant_view` thread is known individually.\n *\n * In memory on purpose: transient UI state that Slack re-sends on open and on\n * every change, so a restart self-heals on the next interaction. Persisting it\n * would add a store to keep consistent for nothing that survives the trip.\n */\nexport class AssistantThreadRegistry {\n private threads = new Map<string, AgentContext>();\n private channels = new Map<string, AgentContext>();\n private titled = new Set<string>();\n\n private key(channelId: string, threadTs: string): string {\n return `${channelId}\\n${threadTs}`;\n }\n\n /** An `assistant_view` thread. */\n remember(channelId: string, threadTs: string, context?: AgentContext): void {\n this.threads.set(this.key(channelId, threadTs), context ?? {});\n }\n\n /** An `agent_view` DM, which has no thread yet. */\n rememberChannel(channelId: string, context?: AgentContext): void {\n this.channels.set(channelId, context ?? {});\n }\n\n /** Thread context, falling back to the channel's. */\n contextFor(channelId: string, threadTs: string): AgentContext | undefined {\n return this.threads.get(this.key(channelId, threadTs)) ?? this.channels.get(channelId);\n }\n\n channelContext(channelId: string): AgentContext | undefined {\n return this.channels.get(channelId);\n }\n\n /**\n * Whether this thread is part of the pane — either registered individually,\n * or living in a DM known to be the agent surface. The second case is what\n * makes titles work under `agent_view`, where Slack opens threads itself and\n * never announces them.\n */\n isAgentSurface(channelId: string, threadTs: string): boolean {\n return this.threads.has(this.key(channelId, threadTs)) || this.channels.has(channelId);\n }\n\n /** True the first time a thread is seen, so a title is set exactly once. */\n claimTitle(channelId: string, threadTs: string): boolean {\n const key = this.key(channelId, threadTs);\n if (this.titled.has(key)) return false;\n this.titled.add(key);\n return true;\n }\n}\n\n/**\n * `assistant_view`: a new conversation opened. Greet, and offer prompts for\n * that thread.\n *\n * Failures are logged, never thrown. A greeting that did not post is a worse\n * pane, not a broken conversation, and taking the socket handler down over it\n * would break the surface entirely.\n */\nexport async function handleAssistantThreadStarted(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n thread: AssistantThreadPayload,\n): Promise<void> {\n const channelId = thread.channel_id;\n const threadTs = thread.thread_ts;\n if (!channelId || !threadTs) return;\n\n registry.remember(channelId, threadTs, thread.context);\n const channel = thread.context?.channel_id\n ? ops.channelName(thread.context.channel_id)\n : undefined;\n\n await swallow(\"greeting\", () =>\n ops.postInThread(channelId, threadTs, channel ? GREETING_WITH_CHANNEL(channel) : GREETING),\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, threadTs, promptsFor(channel)),\n );\n}\n\n/**\n * `agent_view`: the person opened the app's DM. Refresh the prompts pinned to\n * it — and deliberately do not greet, because Slack sends this on *every*\n * open, so a greeting here would arrive again and again.\n */\nexport async function handleAgentDmOpened(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n context?: AgentContext,\n): Promise<void> {\n if (!channelId) return;\n registry.rememberChannel(channelId, context);\n const channel = context?.channel_id ? ops.channelName(context.channel_id) : undefined;\n // The agent surface is otherwise silent, and its failure mode — no prompts,\n // untitled conversations — looks identical from the outside to Slack simply\n // not sending the event. This line is the difference between the two, and\n // is the first thing to look for when the pane seems inert.\n log.logInfo(\n `[${channelId}] Slack agent DM opened${channel ? ` (viewing #${channel})` : \"\"}; refreshing suggested prompts`,\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, undefined, promptsFor(channel)),\n );\n}\n\n/**\n * The person navigated elsewhere. Recorded at both grains so the next turn —\n * and the next prompt refresh — knows where they are, whichever manifest key\n * this app uses.\n */\nexport function handleAgentContextChanged(\n registry: AssistantThreadRegistry,\n payload: { channel_id?: string; thread_ts?: string; context?: AgentContext },\n): void {\n if (!payload.channel_id) return;\n // Logged for the same reason as the open event: these two are the whole\n // agent surface, and whether either is subscribed is otherwise invisible\n // from inside mikan.\n log.logInfo(\n `[${payload.channel_id}] Slack agent context changed${payload.context?.channel_id ? ` (viewing ${payload.context.channel_id})` : \"\"}`,\n );\n if (payload.thread_ts) {\n registry.remember(payload.channel_id, payload.thread_ts, payload.context);\n return;\n }\n registry.rememberChannel(payload.channel_id, payload.context);\n}\n\n/**\n * Title a conversation from the first thing the person said, so the pane's\n * sidebar is navigable. Without it every past conversation looks the same.\n */\nexport async function titleAssistantThread(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n threadTs: string,\n firstMessage: string,\n): Promise<void> {\n if (!registry.isAgentSurface(channelId, threadTs)) return;\n if (!registry.claimTitle(channelId, threadTs)) return;\n const title = summarizeTitle(firstMessage);\n if (!title) return;\n await swallow(\"setTitle\", () => ops.setTitle(channelId, threadTs, title));\n}\n\n/**\n * First line, trimmed to something a sidebar can show. Deliberately not a\n * model call: a title is worth having immediately and cheaply, and the\n * person's own words label the conversation better than a paraphrase.\n */\nexport function summarizeTitle(message: string): string {\n const firstLine = message\n .replace(/<@[^>]+>/g, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n if (!firstLine) return \"\";\n return firstLine.length <= 50 ? firstLine : `${firstLine.slice(0, 49)}…`;\n}\n\nasync function swallow(label: string, run: () => Promise<unknown>): Promise<void> {\n try {\n await run();\n } catch (err) {\n log.logWarning(\n `Slack agent surface ${label} failed`,\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n"]}