@seqyuan/annovibe 0.8.40 → 0.8.53

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 (236) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +15 -8
  3. package/.next/build-manifest.json +2 -2
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.js +1 -1
  6. package/.next/required-server-files.json +1 -1
  7. package/.next/routes-manifest.json +48 -8
  8. package/.next/server/app/_global-error/page.js +2 -2
  9. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/server/app/_global-error.html +1 -1
  11. package/.next/server/app/_global-error.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  17. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/server/app/_not-found/page.js +2 -2
  19. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/server/app/_not-found.html +1 -1
  21. package/.next/server/app/_not-found.rsc +1 -1
  22. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  23. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  24. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  25. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  26. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  27. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  28. package/.next/server/app/api/agent/[id]/events/route.js +1 -1
  29. package/.next/server/app/api/agent/[id]/route.js +1 -1
  30. package/.next/server/app/api/agent/new/route.js +1 -1
  31. package/.next/server/app/api/agent/runtime/route.js +1 -1
  32. package/.next/server/app/api/apps/[id]/[[...path]]/route.js +1 -1
  33. package/.next/server/app/api/apps/route.js +2 -2
  34. package/.next/server/app/api/auth/all-providers/route.js +1 -1
  35. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
  36. package/.next/server/app/api/auth/login/[provider]/route.js +2 -2
  37. package/.next/server/app/api/auth/login/route.js +1 -1
  38. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
  39. package/.next/server/app/api/auth/providers/route.js +1 -1
  40. package/.next/server/app/api/auth/status/route.js +1 -1
  41. package/.next/server/app/api/default-cwd/route.js +1 -1
  42. package/.next/server/app/api/files/[...path]/route.js +3 -3
  43. package/.next/server/app/api/harness/route.js +1 -1
  44. package/.next/server/app/api/home/route.js +1 -1
  45. package/.next/server/app/api/im/cancel/route.js +1 -0
  46. package/.next/server/app/api/im/cancel/route_client-reference-manifest.js +1 -0
  47. package/.next/server/app/api/im/gateway-status/route.js +1 -0
  48. package/.next/server/app/api/im/gateway-status/route_client-reference-manifest.js +1 -0
  49. package/.next/server/app/api/im/gateway-token/route.js +1 -0
  50. package/.next/server/app/api/im/gateway-token/route_client-reference-manifest.js +1 -0
  51. package/.next/server/app/api/im/project/route.js +1 -0
  52. package/.next/server/app/api/im/project/route_client-reference-manifest.js +1 -0
  53. package/.next/server/app/api/im/projects/route.js +1 -0
  54. package/.next/server/app/api/im/projects/route_client-reference-manifest.js +1 -0
  55. package/.next/server/app/api/im/session-ids/route.js +1 -0
  56. package/.next/server/app/api/im/session-ids/route_client-reference-manifest.js +1 -0
  57. package/.next/server/app/api/im/turn/route.js +3 -0
  58. package/.next/server/app/api/im/turn/route_client-reference-manifest.js +1 -0
  59. package/.next/server/app/api/internal/runtime/route.js +1 -1
  60. package/.next/server/app/api/memory/promote/route.js +2 -2
  61. package/.next/server/app/api/models/route.js +1 -1
  62. package/.next/server/app/api/models-config/discover/route.js +1 -1
  63. package/.next/server/app/api/models-config/route.js +1 -1
  64. package/.next/server/app/api/models-config/test/route.js +1 -1
  65. package/.next/server/app/api/plot-kernels/route.js +1 -1
  66. package/.next/server/app/api/plot-kernels/save/route.js +1 -0
  67. package/.next/server/app/api/plot-kernels/save/route_client-reference-manifest.js +1 -0
  68. package/.next/server/app/api/plot-kernels/status/route.js +1 -1
  69. package/.next/server/app/api/plot-kernels/stop/route.js +1 -1
  70. package/.next/server/app/api/projects/browse/route.js +1 -1
  71. package/.next/server/app/api/projects/route.js +2 -2
  72. package/.next/server/app/api/search/route.js +2 -2
  73. package/.next/server/app/api/sessions/[id]/context/route.js +2 -2
  74. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  75. package/.next/server/app/api/sessions/new/route.js +1 -1
  76. package/.next/server/app/api/sessions/route.js +2 -2
  77. package/.next/server/app/api/settings/route.js +1 -1
  78. package/.next/server/app/api/skills/install/route.js +2 -2
  79. package/.next/server/app/api/skills/route.js +2 -2
  80. package/.next/server/app/api/skills/search/route.js +1 -1
  81. package/.next/server/app/api/soul/route.js +1 -1
  82. package/.next/server/app/api/subagents/status/route.js +1 -1
  83. package/.next/server/app/api/version/route.js +1 -1
  84. package/.next/server/app/favicon.ico/route.js +1 -1
  85. package/.next/server/app/icon.svg/route.js +1 -1
  86. package/.next/server/app/index.html +1 -1
  87. package/.next/server/app/index.rsc +2 -2
  88. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  89. package/.next/server/app/index.segments/_full.segment.rsc +2 -2
  90. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  91. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  92. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  93. package/.next/server/app/login/page.js +2 -2
  94. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  95. package/.next/server/app/login.html +1 -1
  96. package/.next/server/app/login.rsc +1 -1
  97. package/.next/server/app/login.segments/_full.segment.rsc +1 -1
  98. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  99. package/.next/server/app/login.segments/_index.segment.rsc +1 -1
  100. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  101. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  102. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  103. package/.next/server/app/page.js +10 -10
  104. package/.next/server/app/page_client-reference-manifest.js +1 -1
  105. package/.next/server/app/smoke/page.js +3 -3
  106. package/.next/server/app/smoke/page_client-reference-manifest.js +1 -1
  107. package/.next/server/app/smoke.html +78 -23
  108. package/.next/server/app/smoke.rsc +2 -2
  109. package/.next/server/app/smoke.segments/_full.segment.rsc +2 -2
  110. package/.next/server/app/smoke.segments/_head.segment.rsc +1 -1
  111. package/.next/server/app/smoke.segments/_index.segment.rsc +1 -1
  112. package/.next/server/app/smoke.segments/_tree.segment.rsc +1 -1
  113. package/.next/server/app/smoke.segments/smoke/__PAGE__.segment.rsc +2 -2
  114. package/.next/server/app/smoke.segments/smoke.segment.rsc +1 -1
  115. package/.next/server/app-paths-manifest.json +15 -8
  116. package/.next/server/chunks/1494.js +278 -0
  117. package/.next/server/chunks/7601.js +44 -75
  118. package/.next/server/functions-config-manifest.json +3 -0
  119. package/.next/server/middleware-build-manifest.js +1 -1
  120. package/.next/server/pages/404.html +1 -1
  121. package/.next/server/pages/500.html +1 -1
  122. package/.next/server/server-reference-manifest.json +1 -1
  123. package/.next/static/chunks/9901-7e044d778f6622ea.js +278 -0
  124. package/.next/static/chunks/app/_global-error/page-b23e767fd4cc8cb6.js +1 -0
  125. package/.next/static/chunks/app/api/agent/[id]/events/route-b23e767fd4cc8cb6.js +1 -0
  126. package/.next/static/chunks/app/api/agent/[id]/route-b23e767fd4cc8cb6.js +1 -0
  127. package/.next/static/chunks/app/api/agent/new/route-b23e767fd4cc8cb6.js +1 -0
  128. package/.next/static/chunks/app/api/agent/runtime/route-b23e767fd4cc8cb6.js +1 -0
  129. package/.next/static/chunks/app/api/apps/[id]/[[...path]]/route-b23e767fd4cc8cb6.js +1 -0
  130. package/.next/static/chunks/app/api/apps/route-b23e767fd4cc8cb6.js +1 -0
  131. package/.next/static/chunks/app/api/auth/all-providers/route-b23e767fd4cc8cb6.js +1 -0
  132. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-b23e767fd4cc8cb6.js +1 -0
  133. package/.next/static/chunks/app/api/auth/login/[provider]/route-b23e767fd4cc8cb6.js +1 -0
  134. package/.next/static/chunks/app/api/auth/login/route-b23e767fd4cc8cb6.js +1 -0
  135. package/.next/static/chunks/app/api/auth/logout/[provider]/route-b23e767fd4cc8cb6.js +1 -0
  136. package/.next/static/chunks/app/api/auth/providers/route-b23e767fd4cc8cb6.js +1 -0
  137. package/.next/static/chunks/app/api/auth/status/route-b23e767fd4cc8cb6.js +1 -0
  138. package/.next/static/chunks/app/api/default-cwd/route-b23e767fd4cc8cb6.js +1 -0
  139. package/.next/static/chunks/app/api/files/[...path]/route-b23e767fd4cc8cb6.js +1 -0
  140. package/.next/static/chunks/app/api/harness/route-b23e767fd4cc8cb6.js +1 -0
  141. package/.next/static/chunks/app/api/home/route-b23e767fd4cc8cb6.js +1 -0
  142. package/.next/static/chunks/app/api/im/cancel/route-b23e767fd4cc8cb6.js +1 -0
  143. package/.next/static/chunks/app/api/im/gateway-status/route-b23e767fd4cc8cb6.js +1 -0
  144. package/.next/static/chunks/app/api/im/gateway-token/route-b23e767fd4cc8cb6.js +1 -0
  145. package/.next/static/chunks/app/api/im/project/route-b23e767fd4cc8cb6.js +1 -0
  146. package/.next/static/chunks/app/api/im/projects/route-b23e767fd4cc8cb6.js +1 -0
  147. package/.next/static/chunks/app/api/im/session-ids/route-b23e767fd4cc8cb6.js +1 -0
  148. package/.next/static/chunks/app/api/im/turn/route-b23e767fd4cc8cb6.js +1 -0
  149. package/.next/static/chunks/app/api/internal/runtime/route-b23e767fd4cc8cb6.js +1 -0
  150. package/.next/static/chunks/app/api/memory/promote/route-b23e767fd4cc8cb6.js +1 -0
  151. package/.next/static/chunks/app/api/models/route-b23e767fd4cc8cb6.js +1 -0
  152. package/.next/static/chunks/app/api/models-config/discover/route-b23e767fd4cc8cb6.js +1 -0
  153. package/.next/static/chunks/app/api/models-config/route-b23e767fd4cc8cb6.js +1 -0
  154. package/.next/static/chunks/app/api/models-config/test/route-b23e767fd4cc8cb6.js +1 -0
  155. package/.next/static/chunks/app/api/plot-kernels/route-b23e767fd4cc8cb6.js +1 -0
  156. package/.next/static/chunks/app/api/plot-kernels/save/route-b23e767fd4cc8cb6.js +1 -0
  157. package/.next/static/chunks/app/api/plot-kernels/status/route-b23e767fd4cc8cb6.js +1 -0
  158. package/.next/static/chunks/app/api/plot-kernels/stop/route-b23e767fd4cc8cb6.js +1 -0
  159. package/.next/static/chunks/app/api/projects/browse/route-b23e767fd4cc8cb6.js +1 -0
  160. package/.next/static/chunks/app/api/projects/route-b23e767fd4cc8cb6.js +1 -0
  161. package/.next/static/chunks/app/api/search/route-b23e767fd4cc8cb6.js +1 -0
  162. package/.next/static/chunks/app/api/sessions/[id]/context/route-b23e767fd4cc8cb6.js +1 -0
  163. package/.next/static/chunks/app/api/sessions/[id]/route-b23e767fd4cc8cb6.js +1 -0
  164. package/.next/static/chunks/app/api/sessions/new/route-b23e767fd4cc8cb6.js +1 -0
  165. package/.next/static/chunks/app/api/sessions/route-b23e767fd4cc8cb6.js +1 -0
  166. package/.next/static/chunks/app/api/settings/route-b23e767fd4cc8cb6.js +1 -0
  167. package/.next/static/chunks/app/api/skills/install/route-b23e767fd4cc8cb6.js +1 -0
  168. package/.next/static/chunks/app/api/skills/route-b23e767fd4cc8cb6.js +1 -0
  169. package/.next/static/chunks/app/api/skills/search/route-b23e767fd4cc8cb6.js +1 -0
  170. package/.next/static/chunks/app/api/soul/route-b23e767fd4cc8cb6.js +1 -0
  171. package/.next/static/chunks/app/api/subagents/status/route-b23e767fd4cc8cb6.js +1 -0
  172. package/.next/static/chunks/app/api/version/route-b23e767fd4cc8cb6.js +1 -0
  173. package/.next/static/chunks/app/favicon.ico/route-b23e767fd4cc8cb6.js +1 -0
  174. package/.next/static/chunks/app/page-e88a9417235fcde7.js +27 -0
  175. package/.next/static/chunks/app/smoke/{page-431310549b820f3b.js → page-d1be0dc9ec4396ba.js} +2 -2
  176. package/.next/static/chunks/next/dist/client/components/builtin/app-error-b23e767fd4cc8cb6.js +1 -0
  177. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-b23e767fd4cc8cb6.js +1 -0
  178. package/.next/static/chunks/next/dist/client/components/builtin/not-found-b23e767fd4cc8cb6.js +1 -0
  179. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b23e767fd4cc8cb6.js +1 -0
  180. package/.next/static/dxpkIGb5tQfNQD77g3dwV/_buildManifest.js +1 -0
  181. package/bin/annovibe-im-gateway.js +566 -0
  182. package/package.json +3 -2
  183. package/.next/server/app/api/reports/[id]/route.js +0 -12
  184. package/.next/server/app/api/reports/[id]/route_client-reference-manifest.js +0 -1
  185. package/.next/server/chunks/1210.js +0 -246
  186. package/.next/static/_cg-NeIs7evKmS6N4eYHl/_buildManifest.js +0 -1
  187. package/.next/static/chunks/9595-64b81f0fd7a50dc4.js +0 -246
  188. package/.next/static/chunks/app/_global-error/page-412387d4b52026c9.js +0 -1
  189. package/.next/static/chunks/app/api/agent/[id]/events/route-412387d4b52026c9.js +0 -1
  190. package/.next/static/chunks/app/api/agent/[id]/route-412387d4b52026c9.js +0 -1
  191. package/.next/static/chunks/app/api/agent/new/route-412387d4b52026c9.js +0 -1
  192. package/.next/static/chunks/app/api/agent/runtime/route-412387d4b52026c9.js +0 -1
  193. package/.next/static/chunks/app/api/apps/[id]/[[...path]]/route-412387d4b52026c9.js +0 -1
  194. package/.next/static/chunks/app/api/apps/route-412387d4b52026c9.js +0 -1
  195. package/.next/static/chunks/app/api/auth/all-providers/route-412387d4b52026c9.js +0 -1
  196. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-412387d4b52026c9.js +0 -1
  197. package/.next/static/chunks/app/api/auth/login/[provider]/route-412387d4b52026c9.js +0 -1
  198. package/.next/static/chunks/app/api/auth/login/route-412387d4b52026c9.js +0 -1
  199. package/.next/static/chunks/app/api/auth/logout/[provider]/route-412387d4b52026c9.js +0 -1
  200. package/.next/static/chunks/app/api/auth/providers/route-412387d4b52026c9.js +0 -1
  201. package/.next/static/chunks/app/api/auth/status/route-412387d4b52026c9.js +0 -1
  202. package/.next/static/chunks/app/api/default-cwd/route-412387d4b52026c9.js +0 -1
  203. package/.next/static/chunks/app/api/files/[...path]/route-412387d4b52026c9.js +0 -1
  204. package/.next/static/chunks/app/api/harness/route-412387d4b52026c9.js +0 -1
  205. package/.next/static/chunks/app/api/home/route-412387d4b52026c9.js +0 -1
  206. package/.next/static/chunks/app/api/internal/runtime/route-412387d4b52026c9.js +0 -1
  207. package/.next/static/chunks/app/api/memory/promote/route-412387d4b52026c9.js +0 -1
  208. package/.next/static/chunks/app/api/models/route-412387d4b52026c9.js +0 -1
  209. package/.next/static/chunks/app/api/models-config/discover/route-412387d4b52026c9.js +0 -1
  210. package/.next/static/chunks/app/api/models-config/route-412387d4b52026c9.js +0 -1
  211. package/.next/static/chunks/app/api/models-config/test/route-412387d4b52026c9.js +0 -1
  212. package/.next/static/chunks/app/api/plot-kernels/route-412387d4b52026c9.js +0 -1
  213. package/.next/static/chunks/app/api/plot-kernels/status/route-412387d4b52026c9.js +0 -1
  214. package/.next/static/chunks/app/api/plot-kernels/stop/route-412387d4b52026c9.js +0 -1
  215. package/.next/static/chunks/app/api/projects/browse/route-412387d4b52026c9.js +0 -1
  216. package/.next/static/chunks/app/api/projects/route-412387d4b52026c9.js +0 -1
  217. package/.next/static/chunks/app/api/reports/[id]/route-412387d4b52026c9.js +0 -1
  218. package/.next/static/chunks/app/api/search/route-412387d4b52026c9.js +0 -1
  219. package/.next/static/chunks/app/api/sessions/[id]/context/route-412387d4b52026c9.js +0 -1
  220. package/.next/static/chunks/app/api/sessions/[id]/route-412387d4b52026c9.js +0 -1
  221. package/.next/static/chunks/app/api/sessions/new/route-412387d4b52026c9.js +0 -1
  222. package/.next/static/chunks/app/api/sessions/route-412387d4b52026c9.js +0 -1
  223. package/.next/static/chunks/app/api/settings/route-412387d4b52026c9.js +0 -1
  224. package/.next/static/chunks/app/api/skills/install/route-412387d4b52026c9.js +0 -1
  225. package/.next/static/chunks/app/api/skills/route-412387d4b52026c9.js +0 -1
  226. package/.next/static/chunks/app/api/skills/search/route-412387d4b52026c9.js +0 -1
  227. package/.next/static/chunks/app/api/soul/route-412387d4b52026c9.js +0 -1
  228. package/.next/static/chunks/app/api/subagents/status/route-412387d4b52026c9.js +0 -1
  229. package/.next/static/chunks/app/api/version/route-412387d4b52026c9.js +0 -1
  230. package/.next/static/chunks/app/favicon.ico/route-412387d4b52026c9.js +0 -1
  231. package/.next/static/chunks/app/page-3291f6a1f268c41d.js +0 -27
  232. package/.next/static/chunks/next/dist/client/components/builtin/app-error-412387d4b52026c9.js +0 -1
  233. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-412387d4b52026c9.js +0 -1
  234. package/.next/static/chunks/next/dist/client/components/builtin/not-found-412387d4b52026c9.js +0 -1
  235. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-412387d4b52026c9.js +0 -1
  236. /package/.next/static/{_cg-NeIs7evKmS6N4eYHl → dxpkIGb5tQfNQD77g3dwV}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2444],{54833:(e,t,o)=>{"use strict";o.r(t),o.d(t,{default:()=>Y});var i=o(95155),r=o(12115),s=o(52496),n=o(76577),a=o(44667),d=o(94456),l=o(99670),c=o(31775),m=o(56264),p=o(49006),x=o(18678),u=o(99947),g=o(28093),h=o(17689),f=o(63161),k=o(53308),v=o(6750),w=o(96793);let b="/tmp/annovibe-smoke",y=`${b}/README.smoke.md`,j="/Volumes/data/github/seqyuan/annovibe",D=`${j}/smoke/report.md`,S=Date.UTC(2026,5,6,6,26,0);function C(e=0){return S+6e4*e}let E="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%20viewBox%3D%220%200%20640%20360%22%3E%3Crect%20width%3D%22640%22%20height%3D%22360%22%20rx%3D%2224%22%20fill%3D%22%23f3f4f6%22%2F%3E%3Crect%20x%3D%2232%22%20y%3D%2232%22%20width%3D%22576%22%20height%3D%22296%22%20rx%3D%2220%22%20fill%3D%22%23ffffff%22%20stroke%3D%22%23d1d5db%22%2F%3E%3Ccircle%20cx%3D%22132%22%20cy%3D%22140%22%20r%3D%2256%22%20fill%3D%22%2360a5fa%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%2296%22%20width%3D%22272%22%20height%3D%2220%22%20rx%3D%2210%22%20fill%3D%22%23111827%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22132%22%20width%3D%22208%22%20height%3D%2216%22%20rx%3D%228%22%20fill%3D%22%236b7280%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22162%22%20width%3D%22168%22%20height%3D%2216%22%20rx%3D%228%22%20fill%3D%22%239ca3af%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22214%22%20width%3D%22128%22%20height%3D%2236%22%20rx%3D%2210%22%20fill%3D%22%232563eb%22%2F%3E%3Ctext%20x%3D%22280%22%20y%3D%22237%22%20font-family%3D%22Arial%2C%20sans-serif%22%20font-size%3D%2216%22%20text-anchor%3D%22middle%22%20fill%3D%22%23ffffff%22%3EAlpha%3C%2Ftext%3E%3C%2Fsvg%3E",T=`
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2444],{54833:(e,t,o)=>{"use strict";o.r(t),o.d(t,{default:()=>Y});var i=o(95155),r=o(12115),s=o(25618),n=o(76577),a=o(44667),d=o(94456),l=o(99670),c=o(31775),m=o(30259),p=o(49006),x=o(18678),u=o(99947),g=o(28093),h=o(17689),f=o(63161),k=o(53308),v=o(6750),w=o(96793);let b="/tmp/annovibe-smoke",y=`${b}/README.smoke.md`,j="/Volumes/data/github/seqyuan/annovibe",D=`${j}/smoke/report.md`,S=Date.UTC(2026,5,6,6,26,0);function C(e=0){return S+6e4*e}let E="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22640%22%20height%3D%22360%22%20viewBox%3D%220%200%20640%20360%22%3E%3Crect%20width%3D%22640%22%20height%3D%22360%22%20rx%3D%2224%22%20fill%3D%22%23f3f4f6%22%2F%3E%3Crect%20x%3D%2232%22%20y%3D%2232%22%20width%3D%22576%22%20height%3D%22296%22%20rx%3D%2220%22%20fill%3D%22%23ffffff%22%20stroke%3D%22%23d1d5db%22%2F%3E%3Ccircle%20cx%3D%22132%22%20cy%3D%22140%22%20r%3D%2256%22%20fill%3D%22%2360a5fa%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%2296%22%20width%3D%22272%22%20height%3D%2220%22%20rx%3D%2210%22%20fill%3D%22%23111827%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22132%22%20width%3D%22208%22%20height%3D%2216%22%20rx%3D%228%22%20fill%3D%22%236b7280%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22162%22%20width%3D%22168%22%20height%3D%2216%22%20rx%3D%228%22%20fill%3D%22%239ca3af%22%2F%3E%3Crect%20x%3D%22216%22%20y%3D%22214%22%20width%3D%22128%22%20height%3D%2236%22%20rx%3D%2210%22%20fill%3D%22%232563eb%22%2F%3E%3Ctext%20x%3D%22280%22%20y%3D%22237%22%20font-family%3D%22Arial%2C%20sans-serif%22%20font-size%3D%2216%22%20text-anchor%3D%22middle%22%20fill%3D%22%23ffffff%22%3EAlpha%3C%2Ftext%3E%3C%2Fsvg%3E",T=`
2
2
  # Generative UI Smoke
3
3
 
4
4
  Inline code: \`const answer = 42\`
@@ -96,4 +96,4 @@ ${P}
96
96
  ${R}
97
97
  \`\`\``,renderer:"react-markdown"})}),(0,i.jsx)(ee,{title:"Short Code Block",dataSmoke:"short-code-block",children:(0,i.jsx)(a.T,{content:"```ts\nconst shortValue = 7;\nconsole.log(shortValue);\n```",renderer:"react-markdown"})}),(0,i.jsx)(ee,{title:"Shiki Cache",dataSmoke:"shiki-cache",children:(0,i.jsx)(K,{})}),(0,i.jsx)(ee,{title:"Shiki Async",dataSmoke:"shiki-async",children:(0,i.jsx)(Q,{})}),(0,i.jsx)(ee,{title:"Unknown Language Fallback",dataSmoke:"shiki-fallback",children:(0,i.jsx)(a.T,{content:'```mysterydsl\nfoo: alpha\nbar -> beta\nemit "plain text fallback"\n```\n',renderer:"react-markdown"})}),(0,i.jsx)(ee,{title:"Clipboard Mock",dataSmoke:"clipboard-mock",children:(0,i.jsx)(Z,{})}),(0,i.jsx)(ee,{title:"Local Paths",dataSmoke:"local-paths",children:(0,i.jsx)(X,{})}),(0,i.jsx)(ee,{title:"Local Preview Paths",dataSmoke:"local-preview-paths",children:(0,i.jsx)(d.D,{message:V,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:j})}),(0,i.jsx)(ee,{title:"SVG Visual Code",dataSmoke:"svg-visual-code",children:(0,i.jsx)(d.D,{message:B,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b,renderVisualCodeBlocks:!0})}),(0,i.jsx)(ee,{title:"Compound Components",dataSmoke:"compound-components",children:(0,i.jsx)(H,{})}),(0,i.jsx)(ee,{title:"Process Panel",dataSmoke:"process-panel",children:(0,i.jsx)(l.kD,{tools:g,results:h,thinkingBlocks:[{content:"Reviewing assistant markdown renderer and tool result layout.",duration:8}],isStreaming:o,cwd:b})}),(0,i.jsx)(ee,{title:"MessageView Integration",dataSmoke:"message-view",children:(0,i.jsx)(d.D,{message:O,isStreaming:!0,toolResults:f,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b,renderVisualCodeBlocks:!0})}),(0,i.jsx)(ee,{title:"User Image Message",dataSmoke:"user-image-message",children:(0,i.jsx)(d.D,{message:G,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b})}),(0,i.jsx)(ee,{title:"Custom MessageView",dataSmoke:"custom-message-view",children:(0,i.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:12},children:[(0,i.jsx)(d.D,{message:U,showTimestamp:!0,modelNames:{"smoke:gpt-5":"Smoke GPT-5"}}),(0,i.jsx)(d.D,{message:z,showTimestamp:!0,modelNames:{"smoke:gpt-5":"Smoke GPT-5"}})]})}),(0,i.jsx)(ee,{title:"Widget Streaming Placeholder",dataSmoke:"widget-streaming",children:(0,i.jsx)(d.D,{message:I,isStreaming:!0,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b})}),(0,i.jsx)(ee,{title:"Non-CDN Widget",dataSmoke:"widget-no-shimmer",children:(0,i.jsx)(d.D,{message:W,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b})}),(0,i.jsx)(ee,{title:"Report Update Placeholder",dataSmoke:"report-update",children:(0,i.jsx)(d.D,{message:$,modelNames:{"smoke:gpt-5":"Smoke GPT-5"},cwd:b})}),(0,i.jsx)(ee,{title:"FileViewer Integration",dataSmoke:"file-viewer",children:(0,i.jsx)(q,{})}),(0,i.jsxs)("section",{style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(320px, 1fr))",gap:16},children:[(0,i.jsx)(ee,{title:"TerminalOutput ANSI",dataSmoke:"terminal-output",children:(0,i.jsx)(c.m,{text:`${L}
98
98
  ${R}`,background:"var(--bg-panel)"})}),(0,i.jsx)(ee,{title:"ToolResultPreview",dataSmoke:"tool-result-preview",children:(0,i.jsx)(m.qb,{text:`${L}
99
- ${R}`,isEmpty:!1,isError:!1,images:[],imagePaths:[]})})]})]})})}function ee({title:e,children:t,dataSmoke:o}){return(0,i.jsxs)("section",{"data-smoke":o,style:{border:"1px solid var(--border)",borderRadius:8,background:"var(--assistant-bg)",overflow:"hidden"},children:[(0,i.jsx)("div",{style:{padding:"10px 12px",borderBottom:"1px solid var(--border)",background:"var(--bg-panel)",fontSize:12,color:"var(--text-muted)",fontWeight:600},children:e}),(0,i.jsx)("div",{style:{padding:14},children:t})]})}function et({title:e,children:t,dataSmoke:o}){return(0,i.jsxs)("div",{"data-smoke":o,style:{border:"1px solid var(--border)",borderRadius:8,background:"var(--assistant-bg)",padding:12,display:"flex",flexDirection:"column",gap:10,minHeight:92},children:[(0,i.jsx)("div",{style:{fontSize:12,color:"var(--text-muted)",fontWeight:600},children:e}),(0,i.jsx)("div",{children:t})]})}},74e3:(e,t,o)=>{Promise.resolve().then(o.bind(o,54833))}},e=>{e.O(0,[7330,6079,2941,2995,8194,9595,8441,3794,7358],()=>e(e.s=74e3)),_N_E=e.O()}]);
99
+ ${R}`,isEmpty:!1,isError:!1,images:[],imagePaths:[]})})]})]})})}function ee({title:e,children:t,dataSmoke:o}){return(0,i.jsxs)("section",{"data-smoke":o,style:{border:"1px solid var(--border)",borderRadius:8,background:"var(--assistant-bg)",overflow:"hidden"},children:[(0,i.jsx)("div",{style:{padding:"10px 12px",borderBottom:"1px solid var(--border)",background:"var(--bg-panel)",fontSize:12,color:"var(--text-muted)",fontWeight:600},children:e}),(0,i.jsx)("div",{style:{padding:14},children:t})]})}function et({title:e,children:t,dataSmoke:o}){return(0,i.jsxs)("div",{"data-smoke":o,style:{border:"1px solid var(--border)",borderRadius:8,background:"var(--assistant-bg)",padding:12,display:"flex",flexDirection:"column",gap:10,minHeight:92},children:[(0,i.jsx)("div",{style:{fontSize:12,color:"var(--text-muted)",fontWeight:600},children:e}),(0,i.jsx)("div",{children:t})]})}},74e3:(e,t,o)=>{Promise.resolve().then(o.bind(o,54833))}},e=>{e.O(0,[7330,6079,2941,2995,8194,9901,8441,3794,7358],()=>e(e.s=74e3)),_N_E=e.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[21,64,186,222,552,976,1004,1097,1327,1541,1921,2007,2234,2314,2752,2922,3230,3374,3679,3785,3851,3955,4037,4368,4896,5177,5221,5907,6202,6442,6450,6709,6710,6780,6819,6849,6919,6988,7070,7253,7473,7483,7758,7778,7812,7851,8167,8658,8743,8933,9626,9787,9815,9968],{84441:()=>{}},_=>{_.O(0,[8441,3794,7358],()=>_(_.s=84441)),_N_E=_.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[21,64,186,222,552,976,1004,1097,1327,1541,1921,2007,2234,2314,2752,2922,3230,3374,3679,3785,3851,3955,4037,4368,4896,5177,5221,5907,6202,6442,6450,6709,6710,6780,6819,6849,6919,6988,7070,7253,7473,7483,7758,7778,7812,7851,8167,8658,8743,8933,9626,9787,9815,9968],{84441:()=>{}},_=>{_.O(0,[8441,3794,7358],()=>_(_.s=84441)),_N_E=_.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[21,64,186,222,552,976,1004,1097,1327,1541,1921,2007,2234,2314,2752,2922,3230,3374,3679,3785,3851,3955,4037,4368,4896,5177,5221,5907,6202,6442,6450,6709,6710,6780,6819,6849,6919,6988,7070,7253,7473,7483,7758,7778,7812,7851,8167,8658,8743,8933,9626,9787,9815,9968],{84441:()=>{}},_=>{_.O(0,[8441,3794,7358],()=>_(_.s=84441)),_N_E=_.O()}]);
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[21,64,186,222,552,976,1004,1097,1327,1541,1921,2007,2234,2314,2752,2922,3230,3374,3679,3785,3851,3955,4037,4368,4896,5177,5221,5907,6202,6442,6450,6709,6710,6780,6819,6849,6919,6988,7070,7253,7473,7483,7758,7778,7812,7851,8167,8658,8743,8933,9626,9787,9815,9968],{84441:()=>{}},_=>{_.O(0,[8441,3794,7358],()=>_(_.s=84441)),_N_E=_.O()}]);
@@ -0,0 +1 @@
1
+ self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:46,errorRate:1e-4,numBits:882,numHashes:14,bitArray:[1,1,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,0,1,1,0,1,1,1,1,1,0,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,0,1,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,1,1,1,1,0,0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,1,1,1,1,1,0,1,1,0,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1,1,1,1,1,1,0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,1,0,1,0,1,1,0,1,1,1,0,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,1,0,0,0,1,1,1,0,1,1,0,1,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,1,0,1,1,1,1,1,0,0,1,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,1,0,0,0,1,0,1,1,1,1,0,0,0,1,0,1,0,1,0,0,0,1,1,0,0,1,1,0,1,0,0,1,0,1,0,1,0,1,1,1,1,1,0,0,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,0,1,1,0,1,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,0,0,0,0,1,1,1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,0,0,1,0,1,1,0,0,1,0,0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,0,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,0,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1,1,0,0,1,0,1,0,1,1,1,0,0,1,0,0,1,1,0,1,1,0,0,0,1,1,1,0,0,1,1,0,1,1,0]},__routerFilterDynamic:{numItems:7,errorRate:1e-4,numBits:135,numHashes:14,bitArray:[0,1,1,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,1,1,0,0,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,0,0,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,0,0,1,0,1,0,1,0,1,1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,0,1,0,1]},sortedPages:["/_app"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
@@ -0,0 +1,566 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Annovibe IM Gateway — Standalone process that bridges WeCom bots to the
4
+ * Annovibe Next.js server.
5
+ *
6
+ * Usage: node bin/annovibe-im-gateway.js
7
+ *
8
+ * Reads project IM configs from localhost:PORT/api/im/projects,
9
+ * connects each enabled bot to WeCom WebSocket, and routes
10
+ * incoming messages through /api/im/turn (SSE streaming).
11
+ */
12
+ "use strict";
13
+
14
+ const fs = require("fs");
15
+ const http = require("http");
16
+ const https = require("https");
17
+ const os = require("os");
18
+ const path = require("path");
19
+ const WebSocket = require("ws");
20
+
21
+ const REVISION_DIGITS = ["\u200b", "\u200c", "\u200d", "\u2060", "\ufeff"];
22
+ const REVISION_SUFFIX_PATTERN = /[\u200b\u200c\u200d\u2060\ufeff]+$/u;
23
+
24
+ // ── Config ──────────────────────────────────────────────────────────
25
+
26
+ function envFirst(...names) {
27
+ for (const name of names) {
28
+ const value = process.env[name];
29
+ if (value !== undefined && value !== "") return value;
30
+ }
31
+ return undefined;
32
+ }
33
+
34
+ const ANNOvibe_PORT = envFirst("ANNOVIBE_PORT", "PORT") ?? "30141";
35
+ const BASE_URL = `http://127.0.0.1:${ANNOvibe_PORT}`;
36
+ const GATEWAY_TOKEN = process.env.ANNOVIBE_GATEWAY_TOKEN?.trim() || "";
37
+
38
+ function getAgentDir() {
39
+ return envFirst("PI_AGENT_DIR") ?? path.join(os.homedir(), ".pi", "agent");
40
+ }
41
+
42
+ function readGatewayToken() {
43
+ const statePath = path.join(getAgentDir(), "im", "gateway.json");
44
+ try {
45
+ const state = JSON.parse(fs.readFileSync(statePath, "utf8"));
46
+ return typeof state.token === "string" ? state.token.trim() : "";
47
+ } catch {
48
+ return "";
49
+ }
50
+ }
51
+
52
+ // ── HTTP helpers ────────────────────────────────────────────────────
53
+
54
+ function requestJson(method, pathname, body) {
55
+ const url = new URL(pathname, BASE_URL);
56
+ const payload = body === undefined ? undefined : JSON.stringify(body);
57
+ const lib = url.protocol === "https:" ? https : http;
58
+ const token = GATEWAY_TOKEN || readGatewayToken();
59
+
60
+ return new Promise((resolve, reject) => {
61
+ const req = lib.request(
62
+ url,
63
+ {
64
+ method,
65
+ headers: {
66
+ ...(payload ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(payload) } : {}),
67
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
68
+ },
69
+ },
70
+ (res) => {
71
+ let data = "";
72
+ res.setEncoding("utf8");
73
+ res.on("data", (chunk) => { data += chunk; });
74
+ res.on("end", () => {
75
+ let parsed;
76
+ try { parsed = data ? JSON.parse(data) : {}; } catch (e) {
77
+ reject(new Error(`Invalid JSON: ${String(e)}`));
78
+ return;
79
+ }
80
+ if (res.statusCode >= 400) {
81
+ reject(new Error(parsed.error || parsed.reply || `HTTP ${res.statusCode}`));
82
+ return;
83
+ }
84
+ resolve(parsed);
85
+ });
86
+ },
87
+ );
88
+ req.on("error", reject);
89
+ if (payload) req.write(payload);
90
+ req.end();
91
+ });
92
+ }
93
+
94
+ function requestImTurnStream(body) {
95
+ const url = new URL("/api/im/turn", BASE_URL);
96
+ const payload = JSON.stringify(body);
97
+ const lib = url.protocol === "https:" ? https : http;
98
+ const token = GATEWAY_TOKEN || readGatewayToken();
99
+
100
+ return new Promise((resolve, reject) => {
101
+ const req = lib.request(
102
+ url,
103
+ {
104
+ method: "POST",
105
+ headers: {
106
+ "Content-Type": "application/json",
107
+ "Content-Length": Buffer.byteLength(payload),
108
+ Accept: "text/event-stream",
109
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
110
+ },
111
+ },
112
+ (res) => {
113
+ if (res.statusCode >= 400) {
114
+ let data = "";
115
+ res.setEncoding("utf8");
116
+ res.on("data", (chunk) => { data += chunk; });
117
+ res.on("end", () => {
118
+ let parsed;
119
+ try { parsed = data ? JSON.parse(data) : {}; } catch { parsed = { error: data }; }
120
+ reject(new Error(parsed.error || parsed.reply || `HTTP ${res.statusCode}`));
121
+ });
122
+ return;
123
+ }
124
+
125
+ let buffer = "";
126
+ let doneEvent = null;
127
+
128
+ res.on("data", (chunk) => {
129
+ buffer += chunk;
130
+ const parts = buffer.split("\n\n");
131
+ buffer = parts.pop() || "";
132
+ for (const part of parts) {
133
+ for (const line of part.split("\n")) {
134
+ if (!line.startsWith("data: ")) continue;
135
+ try {
136
+ const event = JSON.parse(line.slice(6));
137
+ if (event && event.type === "done") doneEvent = event;
138
+ } catch { /* ignore */ }
139
+ }
140
+ }
141
+ });
142
+
143
+ res.on("end", () => {
144
+ if (doneEvent) {
145
+ resolve(doneEvent);
146
+ } else {
147
+ resolve({ type: "done", ok: false, reply: "No response from agent" });
148
+ }
149
+ });
150
+
151
+ res.on("error", reject);
152
+ },
153
+ );
154
+ req.on("error", reject);
155
+ req.write(payload);
156
+ req.end();
157
+ });
158
+ }
159
+
160
+ // ── WeCom helpers ───────────────────────────────────────────────────
161
+
162
+ function encodeRevision(revision) {
163
+ const base = REVISION_DIGITS.length;
164
+ let remaining = Math.max(1, revision);
165
+ let encoded = "";
166
+ while (remaining > 0) {
167
+ const digit = remaining % base;
168
+ encoded += REVISION_DIGITS[digit];
169
+ remaining = Math.floor(remaining / base);
170
+ }
171
+ return encoded;
172
+ }
173
+
174
+ function applyRevisionSuffix(text, revision) {
175
+ return text + encodeRevision(revision);
176
+ }
177
+
178
+ function stripRevisionSuffix(text) {
179
+ return text.replace(REVISION_SUFFIX_PATTERN, "");
180
+ }
181
+
182
+ // ── WeCom WebSocket client ──────────────────────────────────────────
183
+
184
+ class WeComWsClient {
185
+ constructor(options) {
186
+ this.options = options;
187
+ this.ws = null;
188
+ this.heartbeatTimer = null;
189
+ this.pendingAcks = new Map();
190
+ this.authenticated = createDeferred();
191
+ }
192
+
193
+ get isConnected() {
194
+ return this.ws?.readyState === WebSocket.OPEN;
195
+ }
196
+
197
+ async connect() {
198
+ if (this.isConnected) return;
199
+
200
+ await new Promise((resolve, reject) => {
201
+ const ws = new WebSocket(this.options.wsUrl || "wss://openws.work.weixin.qq.com");
202
+ this.ws = ws;
203
+ ws.once("open", () => resolve());
204
+ ws.once("error", (err) => reject(err));
205
+ ws.on("error", () => undefined);
206
+ ws.on("message", (raw) => { void this.handleFrame(String(raw)); });
207
+ ws.on("close", () => {
208
+ this.stopHeartbeat();
209
+ this.rejectPendingAcks(new Error("wecom websocket closed"));
210
+ });
211
+ });
212
+
213
+ await this.sendFrame({
214
+ cmd: "aibot_subscribe",
215
+ headers: { req_id: `aibot_subscribe_${Date.now()}` },
216
+ body: { bot_id: this.options.botId, secret: this.options.botSecret },
217
+ });
218
+ }
219
+
220
+ async waitAuthenticated(timeoutMs = 10000) {
221
+ const timer = setTimeout(() => {
222
+ this.authenticated.reject(new Error("wecom authentication timeout"));
223
+ }, timeoutMs);
224
+ try {
225
+ await this.authenticated.promise;
226
+ return true;
227
+ } catch { return false; }
228
+ finally { clearTimeout(timer); }
229
+ }
230
+
231
+ async replyStream(reqId, streamId, content, finish) {
232
+ await this.sendFrame({
233
+ cmd: "aibot_respond_msg",
234
+ headers: { req_id: reqId },
235
+ body: { msgtype: "stream", stream: { id: streamId, content, finish } },
236
+ });
237
+ if (!finish) return;
238
+ await new Promise((resolve, reject) => {
239
+ const timeout = setTimeout(() => {
240
+ this.pendingAcks.delete(reqId);
241
+ reject(new Error(`wecom reply ack timeout for ${reqId}`));
242
+ }, 5000);
243
+ this.pendingAcks.set(reqId, { resolve, reject, timeout });
244
+ }).catch(() => undefined);
245
+ }
246
+
247
+ async disconnect() {
248
+ this.stopHeartbeat();
249
+ this.rejectPendingAcks(new Error("wecom websocket disconnected"));
250
+ if (!this.ws) return;
251
+ const ws = this.ws;
252
+ this.ws = null;
253
+ await new Promise((resolve) => {
254
+ ws.once("close", () => resolve());
255
+ ws.close();
256
+ });
257
+ }
258
+
259
+ async handleFrame(frameText) {
260
+ const frame = JSON.parse(frameText);
261
+ const reqId = frame.headers?.req_id?.trim();
262
+
263
+ if (reqId && this.pendingAcks.has(reqId)) {
264
+ const pending = this.pendingAcks.get(reqId);
265
+ if (pending) {
266
+ this.pendingAcks.delete(reqId);
267
+ clearTimeout(pending.timeout);
268
+ if ((frame.errcode ?? 0) !== 0) {
269
+ pending.reject(new Error(frame.errmsg || "wecom reply ack failed"));
270
+ } else {
271
+ pending.resolve();
272
+ }
273
+ }
274
+ return;
275
+ }
276
+
277
+ if (reqId?.startsWith("aibot_subscribe_")) {
278
+ if ((frame.errcode ?? 0) !== 0) {
279
+ this.authenticated.reject(new Error(frame.errmsg || "wecom authentication failed"));
280
+ return;
281
+ }
282
+ this.authenticated.resolve();
283
+ this.startHeartbeat();
284
+ return;
285
+ }
286
+
287
+ if (reqId?.startsWith("ping_")) return;
288
+
289
+ if (frame.cmd === "aibot_msg_callback" || frame.cmd === "aibot_event_callback") {
290
+ await this.options.onMessage(frame);
291
+ }
292
+ }
293
+
294
+ startHeartbeat() {
295
+ this.stopHeartbeat();
296
+ const intervalMs = this.options.heartbeatIntervalMs ?? 30000;
297
+ this.heartbeatTimer = setInterval(() => {
298
+ void this.sendFrame({
299
+ cmd: "ping",
300
+ headers: { req_id: `ping_${Date.now()}` },
301
+ }).catch(() => undefined);
302
+ }, intervalMs);
303
+ }
304
+
305
+ stopHeartbeat() {
306
+ if (!this.heartbeatTimer) return;
307
+ clearInterval(this.heartbeatTimer);
308
+ this.heartbeatTimer = null;
309
+ }
310
+
311
+ async sendFrame(frame) {
312
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
313
+ throw new Error("wecom websocket not connected");
314
+ }
315
+ this.ws.send(JSON.stringify(frame));
316
+ }
317
+
318
+ rejectPendingAcks(error) {
319
+ for (const [reqId, pending] of this.pendingAcks) {
320
+ this.pendingAcks.delete(reqId);
321
+ clearTimeout(pending.timeout);
322
+ pending.reject(error);
323
+ }
324
+ }
325
+ }
326
+
327
+ function createDeferred() {
328
+ let resolve, reject;
329
+ const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
330
+ return { promise, resolve, reject };
331
+ }
332
+
333
+ // ── Inbound message extraction ──────────────────────────────────────
334
+
335
+ function extractInboundMessage(frame) {
336
+ const reqId = frame.headers?.req_id?.trim();
337
+ const body = frame.body;
338
+ if (!reqId || !body || body.msgtype !== "text") return null;
339
+
340
+ const from = body.from;
341
+ const rawUserId = typeof from?.userid === "string" ? from.userid.trim() : "";
342
+ const textBody = body.text;
343
+ let content = typeof textBody?.content === "string" ? textBody.content.trim() : "";
344
+ if (!rawUserId || !content) return null;
345
+
346
+ const chatId = (typeof body.chat_id === "string" ? body.chat_id : null) ||
347
+ (typeof body.room_id === "string" ? body.room_id : null) || null;
348
+
349
+ let mentionedBot = false;
350
+ if (chatId) {
351
+ const mentions = content.match(/<@[^>]+>\s*/g);
352
+ if (mentions && mentions.length > 0) {
353
+ mentionedBot = true;
354
+ content = content.replace(/<@[^>]+>\s*/g, "").trim();
355
+ }
356
+ if (!content) return null;
357
+ }
358
+
359
+ return { reqId, userId: rawUserId, chatId, content, mentionedBot };
360
+ }
361
+
362
+ // ── Project bridge ──────────────────────────────────────────────────
363
+
364
+ class ProjectWeComBridge {
365
+ constructor(project) {
366
+ this.project = project;
367
+ this.client = null;
368
+ this.stopped = false;
369
+ this.reconnectTimer = null;
370
+ }
371
+
372
+ async start() {
373
+ if (this.stopped) return;
374
+ const secret = this.project.botSecret;
375
+ if (!secret) {
376
+ console.error(`[im] missing bot secret for ${this.project.cwd}`);
377
+ this.scheduleReconnect(30000);
378
+ return;
379
+ }
380
+
381
+ this.client = new WeComWsClient({
382
+ botId: this.project.botId,
383
+ botSecret: secret,
384
+ onMessage: (frame) => this.handleFrame(frame),
385
+ });
386
+
387
+ try {
388
+ await this.client.connect();
389
+ const ok = await this.client.waitAuthenticated();
390
+ if (!ok) throw new Error("wecom authentication failed");
391
+ console.error(`[im] connected project ${this.project.cwd} bot ${this.project.botId}`);
392
+ } catch (error) {
393
+ console.error(`[im] connect failed for ${this.project.cwd}: ${String(error)}`);
394
+ await this.client?.disconnect().catch(() => undefined);
395
+ this.client = null;
396
+ this.scheduleReconnect(10000);
397
+ }
398
+ }
399
+
400
+ scheduleReconnect(delayMs) {
401
+ if (this.stopped || this.reconnectTimer) return;
402
+ this.reconnectTimer = setTimeout(() => {
403
+ this.reconnectTimer = null;
404
+ void this.start();
405
+ }, delayMs);
406
+ }
407
+
408
+ async stop() {
409
+ this.stopped = true;
410
+ if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
411
+ await this.client?.disconnect().catch(() => undefined);
412
+ this.client = null;
413
+ }
414
+
415
+ async handleFrame(frame) {
416
+ const message = extractInboundMessage(frame);
417
+ if (!message) return;
418
+
419
+ // Skip group messages if requireMention and not mentioned
420
+ if (message.chatId && this.project.requireMentionInGroup && !message.mentionedBot) {
421
+ return;
422
+ }
423
+
424
+ // For group chats, skip if not mentioned at all
425
+ if (message.chatId && !message.mentionedBot) {
426
+ return;
427
+ }
428
+
429
+ const reqId = message.reqId;
430
+ const streamId = `${reqId}-stream`;
431
+ let revision = 0;
432
+
433
+ const pushText = async (text) => {
434
+ revision += 1;
435
+ if (this.client?.isConnected) {
436
+ await this.client.replyStream(reqId, streamId, applyRevisionSuffix(text, revision), false);
437
+ }
438
+ };
439
+
440
+ const finishText = async (text) => {
441
+ revision += 1;
442
+ if (this.client?.isConnected) {
443
+ await this.client.replyStream(reqId, streamId, applyRevisionSuffix(text, revision), true);
444
+ }
445
+ };
446
+
447
+ try {
448
+ // Start processing placeholder
449
+ await pushText(`(working 1s)`);
450
+
451
+ const elapsedInterval = setInterval(async () => {
452
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
453
+ await pushText(`(working ${elapsed}s)`);
454
+ }, 3000);
455
+
456
+ const startTime = Date.now();
457
+
458
+ const result = await requestImTurnStream({
459
+ cwd: this.project.cwd,
460
+ userId: message.userId,
461
+ message: message.content,
462
+ chatId: message.chatId,
463
+ });
464
+
465
+ clearInterval(elapsedInterval);
466
+
467
+ const reply = stripRevisionSuffix(result.reply || "");
468
+ await finishText(reply || "(no response)");
469
+ } catch (error) {
470
+ await finishText(`Error: ${error.message}`);
471
+ }
472
+ }
473
+ }
474
+
475
+ class ImGateway {
476
+ constructor() {
477
+ this.bridges = new Map();
478
+ this.pollTimer = null;
479
+ this.stopped = false;
480
+ }
481
+
482
+ async start() {
483
+ console.error("[im] Annovibe IM Gateway starting...");
484
+
485
+ // Write gateway state
486
+ const imDir = path.join(getAgentDir(), "im");
487
+ try { fs.mkdirSync(imDir, { recursive: true }); } catch {}
488
+ const token = require("crypto").randomBytes(32).toString("hex");
489
+ fs.writeFileSync(
490
+ path.join(imDir, "gateway.json"),
491
+ JSON.stringify({
492
+ token,
493
+ startedAt: new Date().toISOString(),
494
+ pid: process.pid,
495
+ }, null, 2),
496
+ );
497
+
498
+ console.error(`[im] Gateway token: ${token.slice(0, 8)}...`);
499
+
500
+ // Start config poll
501
+ await this.pollProjects();
502
+ this.pollTimer = setInterval(() => this.pollProjects(), 30000);
503
+ }
504
+
505
+ async pollProjects() {
506
+ if (this.stopped) return;
507
+ try {
508
+ const data = await requestJson("GET", "/api/im/projects");
509
+ const projects = data.projects || [];
510
+ const activeCwds = new Set();
511
+
512
+ for (const project of projects) {
513
+ if (!project.cwd || !project.botId) continue;
514
+ activeCwds.add(project.cwd);
515
+
516
+ const key = project.cwd;
517
+ let bridge = this.bridges.get(key);
518
+ if (bridge) {
519
+ // Update project info
520
+ bridge.project = project;
521
+ } else {
522
+ bridge = new ProjectWeComBridge(project);
523
+ this.bridges.set(key, bridge);
524
+ void bridge.start();
525
+ }
526
+ }
527
+
528
+ // Stop bridges for removed projects
529
+ for (const [cwd, bridge] of this.bridges) {
530
+ if (!activeCwds.has(cwd)) {
531
+ await bridge.stop();
532
+ this.bridges.delete(cwd);
533
+ }
534
+ }
535
+ } catch (error) {
536
+ console.error(`[im] Failed to poll projects: ${error.message}`);
537
+ }
538
+ }
539
+
540
+ async stop() {
541
+ this.stopped = true;
542
+ if (this.pollTimer) clearInterval(this.pollTimer);
543
+ for (const bridge of this.bridges.values()) {
544
+ await bridge.stop();
545
+ }
546
+ this.bridges.clear();
547
+
548
+ // Clear gateway state
549
+ try {
550
+ const statePath = path.join(getAgentDir(), "im", "gateway.json");
551
+ fs.writeFileSync(statePath, JSON.stringify({ token: "" }, null, 2));
552
+ } catch {}
553
+ }
554
+ }
555
+
556
+ // ── Main ────────────────────────────────────────────────────────────
557
+
558
+ const gateway = new ImGateway();
559
+
560
+ process.on("SIGINT", () => { void gateway.stop().then(() => process.exit(0)); });
561
+ process.on("SIGTERM", () => { void gateway.stop().then(() => process.exit(0)); });
562
+
563
+ void gateway.start();
564
+
565
+ // Keep process alive
566
+ setInterval(() => {}, 60000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seqyuan/annovibe",
3
- "version": "0.8.40",
3
+ "version": "0.8.53",
4
4
  "description": "AI-native bioinformatics workspace by Annoroad",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -70,6 +70,7 @@
70
70
  "@types/node": "^25",
71
71
  "@types/react": "19.2.17",
72
72
  "@types/react-dom": "^19",
73
+ "@types/ws": "^8.18.1",
73
74
  "ansi-to-react": "^6.2.6",
74
75
  "codemirror": "^6.0.2",
75
76
  "docx-preview": "^0.3.7",
@@ -84,7 +85,7 @@
84
85
  "shiki": "^4.2.0",
85
86
  "streamdown": "^2.5.0",
86
87
  "tailwindcss": "^4.2.2",
87
- "typescript": "5.9.3",
88
+ "typescript": "^5.9.3",
88
89
  "xlsx": "^0.18.5"
89
90
  }
90
91
  }