botmux 2.46.1 → 2.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) hide show
  1. package/README.en.md +5 -10
  2. package/README.md +5 -10
  3. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  4. package/dist/adapters/backend/tmux-backend.js +0 -11
  5. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  6. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  7. package/dist/adapters/cli/claude-code.js +9 -36
  8. package/dist/adapters/cli/claude-code.js.map +1 -1
  9. package/dist/adapters/cli/coco.d.ts.map +1 -1
  10. package/dist/adapters/cli/coco.js +1 -26
  11. package/dist/adapters/cli/coco.js.map +1 -1
  12. package/dist/adapters/cli/codex.d.ts.map +1 -1
  13. package/dist/adapters/cli/codex.js +1 -6
  14. package/dist/adapters/cli/codex.js.map +1 -1
  15. package/dist/adapters/cli/cursor.d.ts.map +1 -1
  16. package/dist/adapters/cli/cursor.js +12 -58
  17. package/dist/adapters/cli/cursor.js.map +1 -1
  18. package/dist/adapters/cli/gemini.d.ts.map +1 -1
  19. package/dist/adapters/cli/gemini.js +1 -5
  20. package/dist/adapters/cli/gemini.js.map +1 -1
  21. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  22. package/dist/adapters/cli/opencode.js +1 -19
  23. package/dist/adapters/cli/opencode.js.map +1 -1
  24. package/dist/adapters/cli/registry.d.ts +1 -5
  25. package/dist/adapters/cli/registry.d.ts.map +1 -1
  26. package/dist/adapters/cli/registry.js +2 -22
  27. package/dist/adapters/cli/registry.js.map +1 -1
  28. package/dist/adapters/cli/shared-hints.d.ts +1 -1
  29. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  30. package/dist/adapters/cli/shared-hints.js +1 -2
  31. package/dist/adapters/cli/shared-hints.js.map +1 -1
  32. package/dist/adapters/cli/types.d.ts +2 -35
  33. package/dist/adapters/cli/types.d.ts.map +1 -1
  34. package/dist/bot-registry.d.ts +0 -59
  35. package/dist/bot-registry.d.ts.map +1 -1
  36. package/dist/bot-registry.js +0 -67
  37. package/dist/bot-registry.js.map +1 -1
  38. package/dist/cli/bots-list-output.d.ts +0 -8
  39. package/dist/cli/bots-list-output.d.ts.map +1 -1
  40. package/dist/cli/bots-list-output.js +0 -9
  41. package/dist/cli/bots-list-output.js.map +1 -1
  42. package/dist/cli.d.ts +1 -15
  43. package/dist/cli.d.ts.map +1 -1
  44. package/dist/cli.js +106 -603
  45. package/dist/cli.js.map +1 -1
  46. package/dist/config.d.ts +2 -11
  47. package/dist/config.d.ts.map +1 -1
  48. package/dist/config.js +4 -17
  49. package/dist/config.js.map +1 -1
  50. package/dist/core/command-handler.d.ts +0 -20
  51. package/dist/core/command-handler.d.ts.map +1 -1
  52. package/dist/core/command-handler.js +313 -762
  53. package/dist/core/command-handler.js.map +1 -1
  54. package/dist/core/dashboard-ipc-server.d.ts +0 -2
  55. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  56. package/dist/core/dashboard-ipc-server.js +2 -222
  57. package/dist/core/dashboard-ipc-server.js.map +1 -1
  58. package/dist/core/role-resolver.d.ts +1 -17
  59. package/dist/core/role-resolver.d.ts.map +1 -1
  60. package/dist/core/role-resolver.js +10 -64
  61. package/dist/core/role-resolver.js.map +1 -1
  62. package/dist/core/session-discovery.d.ts.map +1 -1
  63. package/dist/core/session-discovery.js +5 -19
  64. package/dist/core/session-discovery.js.map +1 -1
  65. package/dist/core/session-manager.d.ts +1 -1
  66. package/dist/core/session-manager.d.ts.map +1 -1
  67. package/dist/core/session-manager.js +20 -37
  68. package/dist/core/session-manager.js.map +1 -1
  69. package/dist/core/types.d.ts +0 -5
  70. package/dist/core/types.d.ts.map +1 -1
  71. package/dist/core/types.js.map +1 -1
  72. package/dist/core/worker-pool.d.ts +0 -141
  73. package/dist/core/worker-pool.d.ts.map +1 -1
  74. package/dist/core/worker-pool.js +24 -543
  75. package/dist/core/worker-pool.js.map +1 -1
  76. package/dist/daemon.d.ts.map +1 -1
  77. package/dist/daemon.js +58 -213
  78. package/dist/daemon.js.map +1 -1
  79. package/dist/dashboard/auth.d.ts +1 -6
  80. package/dist/dashboard/auth.d.ts.map +1 -1
  81. package/dist/dashboard/auth.js +1 -9
  82. package/dist/dashboard/auth.js.map +1 -1
  83. package/dist/dashboard/web/app.js +0 -8
  84. package/dist/dashboard/web/app.js.map +1 -1
  85. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  86. package/dist/dashboard/web/bot-defaults.js +21 -205
  87. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  88. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  89. package/dist/dashboard/web/i18n.js +5 -43
  90. package/dist/dashboard/web/i18n.js.map +1 -1
  91. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  92. package/dist/dashboard/web/sessions.js +0 -4
  93. package/dist/dashboard/web/sessions.js.map +1 -1
  94. package/dist/dashboard/web/workflows.js +3 -3
  95. package/dist/dashboard/web/workflows.js.map +1 -1
  96. package/dist/dashboard/workflow-api.d.ts +1 -8
  97. package/dist/dashboard/workflow-api.d.ts.map +1 -1
  98. package/dist/dashboard/workflow-api.js +4 -19
  99. package/dist/dashboard/workflow-api.js.map +1 -1
  100. package/dist/dashboard-web/app.js +375 -539
  101. package/dist/dashboard-web/index.html +1 -3
  102. package/dist/dashboard-web/style.css +0 -22
  103. package/dist/dashboard.js +2 -199
  104. package/dist/dashboard.js.map +1 -1
  105. package/dist/i18n/en.d.ts.map +1 -1
  106. package/dist/i18n/en.js +11 -104
  107. package/dist/i18n/en.js.map +1 -1
  108. package/dist/i18n/zh.d.ts.map +1 -1
  109. package/dist/i18n/zh.js +11 -104
  110. package/dist/i18n/zh.js.map +1 -1
  111. package/dist/im/lark/card-builder.d.ts +3 -108
  112. package/dist/im/lark/card-builder.d.ts.map +1 -1
  113. package/dist/im/lark/card-builder.js +50 -480
  114. package/dist/im/lark/card-builder.js.map +1 -1
  115. package/dist/im/lark/card-handler.d.ts.map +1 -1
  116. package/dist/im/lark/card-handler.js +18 -241
  117. package/dist/im/lark/card-handler.js.map +1 -1
  118. package/dist/im/lark/client.d.ts +0 -83
  119. package/dist/im/lark/client.d.ts.map +1 -1
  120. package/dist/im/lark/client.js +70 -286
  121. package/dist/im/lark/client.js.map +1 -1
  122. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  123. package/dist/im/lark/event-dispatcher.js +4 -29
  124. package/dist/im/lark/event-dispatcher.js.map +1 -1
  125. package/dist/im/lark/grant-command.d.ts +1 -2
  126. package/dist/im/lark/grant-command.d.ts.map +1 -1
  127. package/dist/im/lark/grant-command.js +2 -3
  128. package/dist/im/lark/grant-command.js.map +1 -1
  129. package/dist/im/lark/identity-cache.d.ts.map +1 -1
  130. package/dist/im/lark/identity-cache.js +3 -3
  131. package/dist/im/lark/identity-cache.js.map +1 -1
  132. package/dist/im/lark/md-card.d.ts +2 -20
  133. package/dist/im/lark/md-card.d.ts.map +1 -1
  134. package/dist/im/lark/md-card.js +17 -49
  135. package/dist/im/lark/md-card.js.map +1 -1
  136. package/dist/im/lark/message-parser.d.ts.map +1 -1
  137. package/dist/im/lark/message-parser.js +31 -87
  138. package/dist/im/lark/message-parser.js.map +1 -1
  139. package/dist/im/lark/workflow-card-handler.d.ts +2 -2
  140. package/dist/im/lark/workflow-card-handler.d.ts.map +1 -1
  141. package/dist/im/lark/workflow-card-handler.js +1 -12
  142. package/dist/im/lark/workflow-card-handler.js.map +1 -1
  143. package/dist/im/lark/workflow-progress-card.d.ts.map +1 -1
  144. package/dist/im/lark/workflow-progress-card.js +0 -53
  145. package/dist/im/lark/workflow-progress-card.js.map +1 -1
  146. package/dist/services/codex-bridge-queue.d.ts +0 -1
  147. package/dist/services/codex-bridge-queue.d.ts.map +1 -1
  148. package/dist/services/codex-bridge-queue.js +0 -23
  149. package/dist/services/codex-bridge-queue.js.map +1 -1
  150. package/dist/services/codex-transcript.d.ts +0 -1
  151. package/dist/services/codex-transcript.d.ts.map +1 -1
  152. package/dist/services/codex-transcript.js.map +1 -1
  153. package/dist/services/feishu-task-client.d.ts +28 -0
  154. package/dist/services/feishu-task-client.d.ts.map +1 -0
  155. package/dist/services/feishu-task-client.js +123 -0
  156. package/dist/services/feishu-task-client.js.map +1 -0
  157. package/dist/services/grant-store.d.ts +2 -12
  158. package/dist/services/grant-store.d.ts.map +1 -1
  159. package/dist/services/grant-store.js +4 -51
  160. package/dist/services/grant-store.js.map +1 -1
  161. package/dist/services/group-creator.d.ts +0 -10
  162. package/dist/services/group-creator.d.ts.map +1 -1
  163. package/dist/services/group-creator.js +1 -26
  164. package/dist/services/group-creator.js.map +1 -1
  165. package/dist/services/groups-store.d.ts +0 -30
  166. package/dist/services/groups-store.d.ts.map +1 -1
  167. package/dist/services/groups-store.js +12 -85
  168. package/dist/services/groups-store.js.map +1 -1
  169. package/dist/services/project-scanner.d.ts +0 -10
  170. package/dist/services/project-scanner.d.ts.map +1 -1
  171. package/dist/services/project-scanner.js +0 -11
  172. package/dist/services/project-scanner.js.map +1 -1
  173. package/dist/services/session-store.js +1 -1
  174. package/dist/services/session-store.js.map +1 -1
  175. package/dist/services/task-store.d.ts +37 -0
  176. package/dist/services/task-store.d.ts.map +1 -0
  177. package/dist/services/task-store.js +115 -0
  178. package/dist/services/task-store.js.map +1 -0
  179. package/dist/setup/bot-config-editor.d.ts +1 -8
  180. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  181. package/dist/setup/bot-config-editor.js +2 -20
  182. package/dist/setup/bot-config-editor.js.map +1 -1
  183. package/dist/setup/ensure-tmux.d.ts +22 -0
  184. package/dist/setup/ensure-tmux.d.ts.map +1 -1
  185. package/dist/setup/ensure-tmux.js +1 -25
  186. package/dist/setup/ensure-tmux.js.map +1 -1
  187. package/dist/setup/verify-permissions.d.ts.map +1 -1
  188. package/dist/setup/verify-permissions.js +1 -15
  189. package/dist/setup/verify-permissions.js.map +1 -1
  190. package/dist/skills/definitions.d.ts +0 -2
  191. package/dist/skills/definitions.d.ts.map +1 -1
  192. package/dist/skills/definitions.js +12 -178
  193. package/dist/skills/definitions.js.map +1 -1
  194. package/dist/skills/installer.d.ts +0 -34
  195. package/dist/skills/installer.d.ts.map +1 -1
  196. package/dist/skills/installer.js +2 -119
  197. package/dist/skills/installer.js.map +1 -1
  198. package/dist/types.d.ts +0 -25
  199. package/dist/types.d.ts.map +1 -1
  200. package/dist/utils/bot-routing.d.ts +0 -50
  201. package/dist/utils/bot-routing.d.ts.map +1 -1
  202. package/dist/utils/bot-routing.js +0 -83
  203. package/dist/utils/bot-routing.js.map +1 -1
  204. package/dist/utils/user-token.d.ts.map +1 -1
  205. package/dist/utils/user-token.js +2 -0
  206. package/dist/utils/user-token.js.map +1 -1
  207. package/dist/worker.js +27 -198
  208. package/dist/worker.js.map +1 -1
  209. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  210. package/dist/workflows/attempt-resume.js +2 -2
  211. package/dist/workflows/attempt-resume.js.map +1 -1
  212. package/dist/workflows/definition.d.ts +9 -412
  213. package/dist/workflows/definition.d.ts.map +1 -1
  214. package/dist/workflows/definition.js +3 -238
  215. package/dist/workflows/definition.js.map +1 -1
  216. package/dist/workflows/events/payloads.d.ts +11 -114
  217. package/dist/workflows/events/payloads.d.ts.map +1 -1
  218. package/dist/workflows/events/payloads.js +0 -46
  219. package/dist/workflows/events/payloads.js.map +1 -1
  220. package/dist/workflows/events/replay.d.ts +0 -21
  221. package/dist/workflows/events/replay.d.ts.map +1 -1
  222. package/dist/workflows/events/replay.js +0 -103
  223. package/dist/workflows/events/replay.js.map +1 -1
  224. package/dist/workflows/events/schema.d.ts +1017 -1712
  225. package/dist/workflows/events/schema.d.ts.map +1 -1
  226. package/dist/workflows/events/schema.js +1 -37
  227. package/dist/workflows/events/schema.js.map +1 -1
  228. package/dist/workflows/events/types.d.ts +1 -5
  229. package/dist/workflows/events/types.d.ts.map +1 -1
  230. package/dist/workflows/loader.d.ts +0 -14
  231. package/dist/workflows/loader.d.ts.map +1 -1
  232. package/dist/workflows/loader.js +0 -27
  233. package/dist/workflows/loader.js.map +1 -1
  234. package/dist/workflows/loop.js +0 -58
  235. package/dist/workflows/loop.js.map +1 -1
  236. package/dist/workflows/ops-projection.d.ts +0 -58
  237. package/dist/workflows/ops-projection.d.ts.map +1 -1
  238. package/dist/workflows/ops-projection.js +0 -74
  239. package/dist/workflows/ops-projection.js.map +1 -1
  240. package/dist/workflows/orchestrator.d.ts +1 -65
  241. package/dist/workflows/orchestrator.d.ts.map +1 -1
  242. package/dist/workflows/orchestrator.js +74 -486
  243. package/dist/workflows/orchestrator.js.map +1 -1
  244. package/dist/workflows/output-binding.d.ts +1 -8
  245. package/dist/workflows/output-binding.d.ts.map +1 -1
  246. package/dist/workflows/output-binding.js +11 -75
  247. package/dist/workflows/output-binding.js.map +1 -1
  248. package/dist/workflows/runtime.d.ts +1 -1
  249. package/dist/workflows/runtime.d.ts.map +1 -1
  250. package/dist/workflows/runtime.js +4 -39
  251. package/dist/workflows/runtime.js.map +1 -1
  252. package/dist/workflows/wait.d.ts +2 -23
  253. package/dist/workflows/wait.d.ts.map +1 -1
  254. package/dist/workflows/wait.js +17 -39
  255. package/dist/workflows/wait.js.map +1 -1
  256. package/package.json +1 -1
  257. package/dist/adapters/adopt-route.d.ts +0 -63
  258. package/dist/adapters/adopt-route.d.ts.map +0 -1
  259. package/dist/adapters/adopt-route.js +0 -195
  260. package/dist/adapters/adopt-route.js.map +0 -1
  261. package/dist/adapters/cli/codex-app.d.ts +0 -4
  262. package/dist/adapters/cli/codex-app.d.ts.map +0 -1
  263. package/dist/adapters/cli/codex-app.js +0 -72
  264. package/dist/adapters/cli/codex-app.js.map +0 -1
  265. package/dist/adapters/cli/hermes.d.ts +0 -4
  266. package/dist/adapters/cli/hermes.d.ts.map +0 -1
  267. package/dist/adapters/cli/hermes.js +0 -40
  268. package/dist/adapters/cli/hermes.js.map +0 -1
  269. package/dist/adapters/cli/mira.d.ts +0 -4
  270. package/dist/adapters/cli/mira.d.ts.map +0 -1
  271. package/dist/adapters/cli/mira.js +0 -67
  272. package/dist/adapters/cli/mira.js.map +0 -1
  273. package/dist/adapters/cli/mtr.d.ts +0 -5
  274. package/dist/adapters/cli/mtr.d.ts.map +0 -1
  275. package/dist/adapters/cli/mtr.js +0 -62
  276. package/dist/adapters/cli/mtr.js.map +0 -1
  277. package/dist/adapters/hook-command.d.ts +0 -18
  278. package/dist/adapters/hook-command.d.ts.map +0 -1
  279. package/dist/adapters/hook-command.js +0 -38
  280. package/dist/adapters/hook-command.js.map +0 -1
  281. package/dist/adapters/hook-installer.d.ts +0 -14
  282. package/dist/adapters/hook-installer.d.ts.map +0 -1
  283. package/dist/adapters/hook-installer.js +0 -192
  284. package/dist/adapters/hook-installer.js.map +0 -1
  285. package/dist/codex-app-runner.d.ts +0 -3
  286. package/dist/codex-app-runner.d.ts.map +0 -1
  287. package/dist/codex-app-runner.js +0 -512
  288. package/dist/codex-app-runner.js.map +0 -1
  289. package/dist/core/ask-api.d.ts +0 -47
  290. package/dist/core/ask-api.d.ts.map +0 -1
  291. package/dist/core/ask-api.js +0 -139
  292. package/dist/core/ask-api.js.map +0 -1
  293. package/dist/core/ask-args.d.ts +0 -53
  294. package/dist/core/ask-args.d.ts.map +0 -1
  295. package/dist/core/ask-args.js +0 -122
  296. package/dist/core/ask-args.js.map +0 -1
  297. package/dist/core/ask-broker.d.ts +0 -98
  298. package/dist/core/ask-broker.d.ts.map +0 -1
  299. package/dist/core/ask-broker.js +0 -329
  300. package/dist/core/ask-broker.js.map +0 -1
  301. package/dist/core/ask-hook/claude-code.d.ts +0 -50
  302. package/dist/core/ask-hook/claude-code.d.ts.map +0 -1
  303. package/dist/core/ask-hook/claude-code.js +0 -145
  304. package/dist/core/ask-hook/claude-code.js.map +0 -1
  305. package/dist/core/ask-hook/codex.d.ts +0 -43
  306. package/dist/core/ask-hook/codex.d.ts.map +0 -1
  307. package/dist/core/ask-hook/codex.js +0 -69
  308. package/dist/core/ask-hook/codex.js.map +0 -1
  309. package/dist/core/ask-hook/opencode.d.ts +0 -41
  310. package/dist/core/ask-hook/opencode.d.ts.map +0 -1
  311. package/dist/core/ask-hook/opencode.js +0 -108
  312. package/dist/core/ask-hook/opencode.js.map +0 -1
  313. package/dist/core/ask-hook/registry.d.ts +0 -3
  314. package/dist/core/ask-hook/registry.d.ts.map +0 -1
  315. package/dist/core/ask-hook/registry.js +0 -12
  316. package/dist/core/ask-hook/registry.js.map +0 -1
  317. package/dist/core/ask-hook/types.d.ts +0 -26
  318. package/dist/core/ask-hook/types.d.ts.map +0 -1
  319. package/dist/core/ask-hook/types.js +0 -2
  320. package/dist/core/ask-hook/types.js.map +0 -1
  321. package/dist/core/ask-types.d.ts +0 -146
  322. package/dist/core/ask-types.d.ts.map +0 -1
  323. package/dist/core/ask-types.js +0 -18
  324. package/dist/core/ask-types.js.map +0 -1
  325. package/dist/core/trigger-session.d.ts +0 -9
  326. package/dist/core/trigger-session.d.ts.map +0 -1
  327. package/dist/core/trigger-session.js +0 -158
  328. package/dist/core/trigger-session.js.map +0 -1
  329. package/dist/dashboard/connector-api.d.ts +0 -3
  330. package/dist/dashboard/connector-api.d.ts.map +0 -1
  331. package/dist/dashboard/connector-api.js +0 -351
  332. package/dist/dashboard/connector-api.js.map +0 -1
  333. package/dist/dashboard/federated-group-core.d.ts +0 -54
  334. package/dist/dashboard/federated-group-core.d.ts.map +0 -1
  335. package/dist/dashboard/federated-group-core.js +0 -165
  336. package/dist/dashboard/federated-group-core.js.map +0 -1
  337. package/dist/dashboard/federation-api.d.ts +0 -42
  338. package/dist/dashboard/federation-api.d.ts.map +0 -1
  339. package/dist/dashboard/federation-api.js +0 -408
  340. package/dist/dashboard/federation-api.js.map +0 -1
  341. package/dist/dashboard/federation-spoke-api.d.ts +0 -76
  342. package/dist/dashboard/federation-spoke-api.d.ts.map +0 -1
  343. package/dist/dashboard/federation-spoke-api.js +0 -618
  344. package/dist/dashboard/federation-spoke-api.js.map +0 -1
  345. package/dist/dashboard/team-group.d.ts +0 -18
  346. package/dist/dashboard/team-group.d.ts.map +0 -1
  347. package/dist/dashboard/team-group.js +0 -7
  348. package/dist/dashboard/team-group.js.map +0 -1
  349. package/dist/dashboard/trigger-api.d.ts +0 -13
  350. package/dist/dashboard/trigger-api.d.ts.map +0 -1
  351. package/dist/dashboard/trigger-api.js +0 -77
  352. package/dist/dashboard/trigger-api.js.map +0 -1
  353. package/dist/dashboard/web/connectors.d.ts +0 -2
  354. package/dist/dashboard/web/connectors.d.ts.map +0 -1
  355. package/dist/dashboard/web/connectors.js +0 -187
  356. package/dist/dashboard/web/connectors.js.map +0 -1
  357. package/dist/dashboard/web/team-federation.d.ts +0 -3
  358. package/dist/dashboard/web/team-federation.d.ts.map +0 -1
  359. package/dist/dashboard/web/team-federation.js +0 -487
  360. package/dist/dashboard/web/team-federation.js.map +0 -1
  361. package/dist/dashboard/webhook-routes.d.ts +0 -19
  362. package/dist/dashboard/webhook-routes.d.ts.map +0 -1
  363. package/dist/dashboard/webhook-routes.js +0 -321
  364. package/dist/dashboard/webhook-routes.js.map +0 -1
  365. package/dist/im/lark/ask-card.d.ts +0 -55
  366. package/dist/im/lark/ask-card.d.ts.map +0 -1
  367. package/dist/im/lark/ask-card.js +0 -328
  368. package/dist/im/lark/ask-card.js.map +0 -1
  369. package/dist/mira-output.d.ts +0 -3
  370. package/dist/mira-output.d.ts.map +0 -1
  371. package/dist/mira-output.js +0 -136
  372. package/dist/mira-output.js.map +0 -1
  373. package/dist/mira-runner.d.ts +0 -3
  374. package/dist/mira-runner.d.ts.map +0 -1
  375. package/dist/mira-runner.js +0 -534
  376. package/dist/mira-runner.js.map +0 -1
  377. package/dist/services/bot-owner-store.d.ts +0 -28
  378. package/dist/services/bot-owner-store.d.ts.map +0 -1
  379. package/dist/services/bot-owner-store.js +0 -82
  380. package/dist/services/bot-owner-store.js.map +0 -1
  381. package/dist/services/bot-profile-store.d.ts +0 -16
  382. package/dist/services/bot-profile-store.d.ts.map +0 -1
  383. package/dist/services/bot-profile-store.js +0 -98
  384. package/dist/services/bot-profile-store.js.map +0 -1
  385. package/dist/services/brand-store.d.ts +0 -15
  386. package/dist/services/brand-store.d.ts.map +0 -1
  387. package/dist/services/brand-store.js +0 -47
  388. package/dist/services/brand-store.js.map +0 -1
  389. package/dist/services/card-prefs-store.d.ts +0 -20
  390. package/dist/services/card-prefs-store.d.ts.map +0 -1
  391. package/dist/services/card-prefs-store.js +0 -82
  392. package/dist/services/card-prefs-store.js.map +0 -1
  393. package/dist/services/connector-store.d.ts +0 -58
  394. package/dist/services/connector-store.d.ts.map +0 -1
  395. package/dist/services/connector-store.js +0 -79
  396. package/dist/services/connector-store.js.map +0 -1
  397. package/dist/services/deployment-identity.d.ts +0 -22
  398. package/dist/services/deployment-identity.d.ts.map +0 -1
  399. package/dist/services/deployment-identity.js +0 -67
  400. package/dist/services/deployment-identity.js.map +0 -1
  401. package/dist/services/federation-membership-store.d.ts +0 -23
  402. package/dist/services/federation-membership-store.d.ts.map +0 -1
  403. package/dist/services/federation-membership-store.js +0 -66
  404. package/dist/services/federation-membership-store.js.map +0 -1
  405. package/dist/services/federation-roster.d.ts +0 -54
  406. package/dist/services/federation-roster.d.ts.map +0 -1
  407. package/dist/services/federation-roster.js +0 -51
  408. package/dist/services/federation-roster.js.map +0 -1
  409. package/dist/services/federation-store.d.ts +0 -76
  410. package/dist/services/federation-store.d.ts.map +0 -1
  411. package/dist/services/federation-store.js +0 -133
  412. package/dist/services/federation-store.js.map +0 -1
  413. package/dist/services/hermes-transcript.d.ts +0 -7
  414. package/dist/services/hermes-transcript.d.ts.map +0 -1
  415. package/dist/services/hermes-transcript.js +0 -117
  416. package/dist/services/hermes-transcript.js.map +0 -1
  417. package/dist/services/invite-store.d.ts +0 -28
  418. package/dist/services/invite-store.d.ts.map +0 -1
  419. package/dist/services/invite-store.js +0 -85
  420. package/dist/services/invite-store.js.map +0 -1
  421. package/dist/services/pairing-store.d.ts +0 -47
  422. package/dist/services/pairing-store.d.ts.map +0 -1
  423. package/dist/services/pairing-store.js +0 -132
  424. package/dist/services/pairing-store.js.map +0 -1
  425. package/dist/services/relay-picker.d.ts +0 -22
  426. package/dist/services/relay-picker.d.ts.map +0 -1
  427. package/dist/services/relay-picker.js +0 -62
  428. package/dist/services/relay-picker.js.map +0 -1
  429. package/dist/services/send-policy.d.ts +0 -55
  430. package/dist/services/send-policy.d.ts.map +0 -1
  431. package/dist/services/send-policy.js +0 -47
  432. package/dist/services/send-policy.js.map +0 -1
  433. package/dist/services/team-roster.d.ts +0 -38
  434. package/dist/services/team-roster.d.ts.map +0 -1
  435. package/dist/services/team-roster.js +0 -82
  436. package/dist/services/team-roster.js.map +0 -1
  437. package/dist/services/team-store.d.ts +0 -54
  438. package/dist/services/team-store.d.ts.map +0 -1
  439. package/dist/services/team-store.js +0 -156
  440. package/dist/services/team-store.js.map +0 -1
  441. package/dist/services/trigger-log-store.d.ts +0 -46
  442. package/dist/services/trigger-log-store.d.ts.map +0 -1
  443. package/dist/services/trigger-log-store.js +0 -132
  444. package/dist/services/trigger-log-store.js.map +0 -1
  445. package/dist/services/trigger-types.d.ts +0 -57
  446. package/dist/services/trigger-types.d.ts.map +0 -1
  447. package/dist/services/trigger-types.js +0 -28
  448. package/dist/services/trigger-types.js.map +0 -1
  449. package/dist/services/webhook-key.d.ts +0 -16
  450. package/dist/services/webhook-key.d.ts.map +0 -1
  451. package/dist/services/webhook-key.js +0 -123
  452. package/dist/services/webhook-key.js.map +0 -1
  453. package/dist/services/webhook-lifecycle-extractors.d.ts +0 -15
  454. package/dist/services/webhook-lifecycle-extractors.d.ts.map +0 -1
  455. package/dist/services/webhook-lifecycle-extractors.js +0 -59
  456. package/dist/services/webhook-lifecycle-extractors.js.map +0 -1
  457. package/dist/services/webhook-lifecycle-store.d.ts +0 -45
  458. package/dist/services/webhook-lifecycle-store.d.ts.map +0 -1
  459. package/dist/services/webhook-lifecycle-store.js +0 -159
  460. package/dist/services/webhook-lifecycle-store.js.map +0 -1
  461. package/dist/utils/daemon-discovery.d.ts +0 -11
  462. package/dist/utils/daemon-discovery.d.ts.map +0 -1
  463. package/dist/utils/daemon-discovery.js +0 -59
  464. package/dist/utils/daemon-discovery.js.map +0 -1
  465. package/dist/workflows/trigger-from-envelope.d.ts +0 -13
  466. package/dist/workflows/trigger-from-envelope.d.ts.map +0 -1
  467. package/dist/workflows/trigger-from-envelope.js +0 -67
  468. package/dist/workflows/trigger-from-envelope.js.map +0 -1
@@ -1,85 +0,0 @@
1
- /**
2
- * Team invite store: an existing member mints a single-use, short-TTL invite
3
- * code; the invitee pairs (pairing-login) and presents the code on consume,
4
- * which authorizes joining the team (team-store.addMember). This sidesteps
5
- * email→open_id resolution (the dashboard process has no Lark client) — the
6
- * invitee self-authenticates via the bot, the invite only grants admission.
7
- *
8
- * Storage: `{dataDir}/team-invites.json`, atomic writes; expired/used pruned.
9
- *
10
- * Concurrency: consume is a read-modify-write. This assumes a SINGLE dashboard
11
- * writer process (the current deployment model). If multiple dashboard processes
12
- * ever write concurrently, a single-use code would need a file lock here.
13
- */
14
- import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync } from 'node:fs';
15
- import { join } from 'node:path';
16
- import { randomBytes, randomUUID } from 'node:crypto';
17
- const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000; // 24h
18
- function filePath(dataDir) { return join(dataDir, 'team-invites.json'); }
19
- function readFile(dataDir) {
20
- const fp = filePath(dataDir);
21
- if (!existsSync(fp))
22
- return {};
23
- try {
24
- const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
25
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
26
- return parsed;
27
- }
28
- catch { /* corrupt */ }
29
- return {};
30
- }
31
- function writeFileAtomic(dataDir, data) {
32
- if (!existsSync(dataDir))
33
- mkdirSync(dataDir, { recursive: true });
34
- const fp = filePath(dataDir);
35
- const tmp = `${fp}.${process.pid}.${randomUUID()}.tmp`;
36
- writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf-8');
37
- renameSync(tmp, fp);
38
- }
39
- /** Drop expired or used-and-old entries. */
40
- function prune(data, now) {
41
- for (const [code, inv] of Object.entries(data)) {
42
- if (inv.expiresAt <= now || (inv.usedAt && now - inv.usedAt > DEFAULT_TTL_MS))
43
- delete data[code];
44
- }
45
- return data;
46
- }
47
- /** Mint a single-use invite for a team. */
48
- export function createInvite(dataDir, teamId, createdBy, ttlMs = DEFAULT_TTL_MS, now = Date.now()) {
49
- const data = prune(readFile(dataDir), now);
50
- const code = randomBytes(9).toString('base64url'); // ~12 chars, high entropy
51
- data[code] = { code, teamId, createdBy, createdAt: now, expiresAt: now + ttlMs };
52
- writeFileAtomic(dataDir, data);
53
- return { code, expiresAt: now + ttlMs };
54
- }
55
- /** Drop every invite for a team (e.g. when the team is deleted), so stale codes
56
- * can't later be consumed to join/switch into a non-existent team. Returns count. */
57
- export function deleteInvitesForTeam(dataDir, teamId) {
58
- const data = readFile(dataDir);
59
- let removed = 0;
60
- for (const [code, inv] of Object.entries(data)) {
61
- if (inv.teamId === teamId) {
62
- delete data[code];
63
- removed++;
64
- }
65
- }
66
- if (removed)
67
- writeFileAtomic(dataDir, data);
68
- return removed;
69
- }
70
- /** Validate + burn an invite (single-use). Determines the precise failure
71
- * reason BEFORE pruning, so an expired code reports `expired` (not `not_found`). */
72
- export function consumeInvite(dataDir, code, now = Date.now()) {
73
- const data = readFile(dataDir);
74
- const inv = data[code?.trim()];
75
- if (!inv)
76
- return { ok: false, reason: 'not_found' };
77
- if (inv.expiresAt <= now)
78
- return { ok: false, reason: 'expired' };
79
- if (inv.usedAt)
80
- return { ok: false, reason: 'used' };
81
- inv.usedAt = now;
82
- writeFileAtomic(dataDir, prune(data, now)); // burn this one; prune other stale entries
83
- return { ok: true, teamId: inv.teamId };
84
- }
85
- //# sourceMappingURL=invite-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"invite-store.js","sourceRoot":"","sources":["../../src/services/invite-store.ts"],"names":[],"mappings":"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"}
@@ -1,47 +0,0 @@
1
- export type PairingStatus = 'pending' | 'claimed' | 'consumed';
2
- export interface PairingClaimer {
3
- openId: string;
4
- unionId?: string;
5
- name?: string;
6
- /** The bot app the user ran `/pair` with — open_id is scoped to THIS app. */
7
- larkAppId?: string;
8
- }
9
- export interface StartedPairing {
10
- pairingId: string;
11
- code: string;
12
- browserToken: string;
13
- expiresAt: number;
14
- }
15
- /** Begin a pairing. Returns the code to show the user + a private browserToken. */
16
- export declare function createPairing(dataDir: string, ttlMs?: number, now?: number): StartedPairing;
17
- export type ClaimResult = {
18
- ok: true;
19
- pairingId: string;
20
- } | {
21
- ok: false;
22
- reason: 'not_found' | 'expired' | 'already_claimed';
23
- };
24
- /** Claim a pending pairing for a Feishu identity (called by the daemon on the bot side). */
25
- export declare function claimPairing(dataDir: string, code: string, claimer: PairingClaimer, now?: number): ClaimResult;
26
- export type PairingView = {
27
- status: 'pending';
28
- } | {
29
- status: 'claimed';
30
- claimedBy: PairingClaimer;
31
- } | {
32
- status: 'consumed';
33
- } | {
34
- status: 'not_found';
35
- };
36
- /** Browser-side status poll; requires the matching browserToken. */
37
- export declare function getPairingStatus(dataDir: string, pairingId: string, browserToken: string, now?: number): PairingView;
38
- export type ConsumeResult = {
39
- ok: true;
40
- claimedBy: PairingClaimer;
41
- } | {
42
- ok: false;
43
- reason: 'not_found' | 'not_claimed' | 'already_consumed';
44
- };
45
- /** Single-use: turn a claimed pairing into a session. Requires the browserToken. */
46
- export declare function consumePairing(dataDir: string, pairingId: string, browserToken: string, now?: number): ConsumeResult;
47
- //# sourceMappingURL=pairing-store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pairing-store.d.ts","sourceRoot":"","sources":["../../src/services/pairing-store.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAmDD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAuB,EAAE,GAAG,GAAE,MAAmB,GAAG,cAAc,CAavH;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEvE,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,WAAW,CAe1H;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5B,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,WAAW,CAOhI;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GACvC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,kBAAkB,CAAA;CAAE,CAAC;AAE5E,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,aAAa,CAUhI"}
@@ -1,132 +0,0 @@
1
- /**
2
- * Pairing-login store: binds a browser session to a Feishu user without a web
3
- * OAuth redirect (which is unfriendly to ip:port self-host — see
4
- * docs/platform-design.md). Device-code style:
5
- *
6
- * 1. Browser (unauthenticated) calls start → gets a short human `code` to show
7
- * the user, plus a high-entropy `browserToken` it keeps privately.
8
- * 2. User sends the `code` to the bot in Feishu. The daemon (which already
9
- * knows the sender's open_id) claims the pairing for that identity.
10
- * 3. Browser polls/consumes with its `browserToken`; on a claimed pairing it
11
- * learns the Feishu identity and the web endpoint issues a session.
12
- *
13
- * Identity is established INSIDE Feishu, so only a short-lived code crosses to
14
- * the web — independent of domain/IP/port. Team-membership gating is the
15
- * caller's job (via team-store); this store only pairs browser ↔ identity.
16
- *
17
- * Security: code is high-entropy + short TTL + single-use; browserToken gates
18
- * status/consume so a guessed code alone can't hijack a browser session.
19
- * (Brute-forcing codes is further bounded by endpoint rate limiting at the wiring
20
- * layer.) Codes/tokens are never logged.
21
- *
22
- * Storage: `{dataDir}/pairings.json` (shared across the web + daemon processes),
23
- * atomic writes.
24
- */
25
- import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync } from 'node:fs';
26
- import { join } from 'node:path';
27
- import { randomBytes, randomUUID } from 'node:crypto';
28
- const DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes
29
- /** Unambiguous alphabet (no 0/O/1/I) for the human-entered code. */
30
- const CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
31
- const CODE_LEN = 8;
32
- function filePath(dataDir) {
33
- return join(dataDir, 'pairings.json');
34
- }
35
- function readFile(dataDir) {
36
- const fp = filePath(dataDir);
37
- if (!existsSync(fp))
38
- return {};
39
- try {
40
- const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
41
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
42
- return parsed;
43
- }
44
- catch { /* corrupt — fall through */ }
45
- return {};
46
- }
47
- function writeFileAtomic(dataDir, data) {
48
- if (!existsSync(dataDir))
49
- mkdirSync(dataDir, { recursive: true });
50
- const fp = filePath(dataDir);
51
- const tmp = `${fp}.${process.pid}.${randomUUID()}.tmp`;
52
- writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf-8');
53
- renameSync(tmp, fp);
54
- }
55
- /** Drop expired entries; returns the live map. */
56
- function prune(data, now) {
57
- for (const [id, e] of Object.entries(data)) {
58
- if (e.expiresAt <= now)
59
- delete data[id];
60
- }
61
- return data;
62
- }
63
- function genCode() {
64
- const bytes = randomBytes(CODE_LEN);
65
- let out = '';
66
- for (let i = 0; i < CODE_LEN; i++)
67
- out += CODE_ALPHABET[bytes[i] % CODE_ALPHABET.length];
68
- return out;
69
- }
70
- /** Begin a pairing. Returns the code to show the user + a private browserToken. */
71
- export function createPairing(dataDir, ttlMs = DEFAULT_TTL_MS, now = Date.now()) {
72
- const data = prune(readFile(dataDir), now);
73
- const entry = {
74
- pairingId: randomUUID(),
75
- code: genCode(),
76
- browserToken: randomBytes(24).toString('base64url'),
77
- status: 'pending',
78
- createdAt: now,
79
- expiresAt: now + ttlMs,
80
- };
81
- data[entry.pairingId] = entry;
82
- writeFileAtomic(dataDir, data);
83
- return { pairingId: entry.pairingId, code: entry.code, browserToken: entry.browserToken, expiresAt: entry.expiresAt };
84
- }
85
- /** Claim a pending pairing for a Feishu identity (called by the daemon on the bot side). */
86
- export function claimPairing(dataDir, code, claimer, now = Date.now()) {
87
- const data = prune(readFile(dataDir), now);
88
- const entry = Object.values(data).find(e => e.code === code.trim().toUpperCase());
89
- if (!entry)
90
- return { ok: false, reason: 'not_found' };
91
- if (entry.expiresAt <= now)
92
- return { ok: false, reason: 'expired' };
93
- if (entry.status !== 'pending')
94
- return { ok: false, reason: 'already_claimed' };
95
- entry.status = 'claimed';
96
- entry.claimedBy = {
97
- openId: claimer.openId,
98
- ...(claimer.unionId ? { unionId: claimer.unionId } : {}),
99
- ...(claimer.name ? { name: claimer.name } : {}),
100
- ...(claimer.larkAppId ? { larkAppId: claimer.larkAppId } : {}),
101
- };
102
- writeFileAtomic(dataDir, data);
103
- return { ok: true, pairingId: entry.pairingId };
104
- }
105
- /** Browser-side status poll; requires the matching browserToken. */
106
- export function getPairingStatus(dataDir, pairingId, browserToken, now = Date.now()) {
107
- const data = prune(readFile(dataDir), now);
108
- const entry = data[pairingId];
109
- if (!entry || entry.browserToken !== browserToken)
110
- return { status: 'not_found' };
111
- if (entry.status === 'claimed' && entry.claimedBy)
112
- return { status: 'claimed', claimedBy: entry.claimedBy };
113
- if (entry.status === 'consumed')
114
- return { status: 'consumed' };
115
- return { status: 'pending' };
116
- }
117
- /** Single-use: turn a claimed pairing into a session. Requires the browserToken. */
118
- export function consumePairing(dataDir, pairingId, browserToken, now = Date.now()) {
119
- const data = prune(readFile(dataDir), now);
120
- const entry = data[pairingId];
121
- if (!entry || entry.browserToken !== browserToken)
122
- return { ok: false, reason: 'not_found' };
123
- if (entry.status === 'consumed')
124
- return { ok: false, reason: 'already_consumed' };
125
- if (entry.status !== 'claimed' || !entry.claimedBy)
126
- return { ok: false, reason: 'not_claimed' };
127
- entry.status = 'consumed';
128
- const claimedBy = entry.claimedBy;
129
- writeFileAtomic(dataDir, data);
130
- return { ok: true, claimedBy };
131
- }
132
- //# sourceMappingURL=pairing-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pairing-store.js","sourceRoot":"","sources":["../../src/services/pairing-store.ts"],"names":[],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- /**
2
- * Shared helper for collecting the operator's relayable sessions used by the
3
- * /relay picker. Same selection criteria used both at first render
4
- * (command-handler) and on each card-update click (card-handler re-render),
5
- * so factor it out to keep both paths in sync.
6
- *
7
- * Selection rules:
8
- * • same bot (this larkAppId — only this daemon's sessions are visible)
9
- * • NOT in the current chat (can't relay into the chat it already lives in)
10
- * • operator is the session owner (owner-only access)
11
- * • not an adopt session (those wrap a user-attached tmux pane, refused
12
- * by transferSession anyway)
13
- *
14
- * Resolves friendly chat names and modes via getChatNameAndMode in parallel
15
- * (1 API call per unique source chatId). Failure modes are tolerant:
16
- * unresolved chats fall back to the raw chatId for chatLabel and the
17
- * session's own chatType for mode.
18
- */
19
- import type { DaemonSession } from '../core/types.js';
20
- import type { RelayPickerEntry } from '../im/lark/card-builder.js';
21
- export declare function collectRelayPickerEntries(activeSessions: Map<string, DaemonSession>, myAppId: string, currentChatId: string, operatorOpenId: string): Promise<RelayPickerEntry[]>;
22
- //# sourceMappingURL=relay-picker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"relay-picker.d.ts","sourceRoot":"","sources":["../../src/services/relay-picker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAInE,wBAAsB,yBAAyB,CAC7C,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAC1C,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAwD7B"}
@@ -1,62 +0,0 @@
1
- import { getChatNameAndMode } from '../im/lark/client.js';
2
- import { isRelayableRealSession } from '../core/worker-pool.js';
3
- export async function collectRelayPickerEntries(activeSessions, myAppId, currentChatId, operatorOpenId) {
4
- const candidates = [];
5
- for (const c of activeSessions.values()) {
6
- if (c.larkAppId !== myAppId)
7
- continue;
8
- if (c.chatId === currentChatId)
9
- continue;
10
- if (c.session.ownerOpenId !== operatorOpenId)
11
- continue;
12
- if (c.session.adoptedFrom)
13
- continue;
14
- // Daemon-command scratches (worker:null + no persisted CLI markers)
15
- // are placeholder records for /help / unfinished /relay etc. — they
16
- // have no real conversation to bring along. Don't surface them in
17
- // anyone's picker.
18
- if (!isRelayableRealSession(c))
19
- continue;
20
- candidates.push(c);
21
- }
22
- // Skip the API call entirely for p2p chats. session.chatType is recorded
23
- // at session creation from the Lark event payload and is authoritative —
24
- // it doesn't drift. The earlier design used `info?.mode ?? fallbackMode`,
25
- // but `getChatNameAndMode` swallows API errors and returns the SAFE
26
- // DEFAULT `{ name: null, mode: 'group' }` — which then mis-classified
27
- // every p2p session as 普通群 whenever the chat.get call failed
28
- // (permissions / network / etc.). 王皓 caught this. Authoritative path:
29
- // p2p → session.chatType; non-p2p → Lark API (for group/topic split).
30
- const groupChatIds = [...new Set(candidates.filter(c => c.chatType !== 'p2p').map(c => c.chatId))];
31
- const resolved = await Promise.all(groupChatIds.map(async (cid) => [cid, await getChatNameAndMode(myAppId, cid)]));
32
- const chatInfo = new Map();
33
- for (const [cid, info] of resolved)
34
- chatInfo.set(cid, info);
35
- return candidates.map(c => {
36
- if (c.chatType === 'p2p') {
37
- return {
38
- sessionId: c.session.sessionId,
39
- // chatLabel is unused for p2p in the rendered output (location
40
- // field always renders the locale-aware "单聊" literal), but we
41
- // still set it to chatId for completeness / downstream debug.
42
- chatLabel: c.chatId,
43
- title: c.session.title || c.currentTurnTitle || '(no title)',
44
- workingDir: c.session.workingDir,
45
- cliId: c.session.cliId,
46
- lastMessageAt: c.lastMessageAt,
47
- chatMode: 'p2p',
48
- };
49
- }
50
- const info = chatInfo.get(c.chatId);
51
- return {
52
- sessionId: c.session.sessionId,
53
- chatLabel: info?.name ?? c.chatId,
54
- title: c.session.title || c.currentTurnTitle || '(no title)',
55
- workingDir: c.session.workingDir,
56
- cliId: c.session.cliId,
57
- lastMessageAt: c.lastMessageAt,
58
- chatMode: info?.mode ?? 'group',
59
- };
60
- });
61
- }
62
- //# sourceMappingURL=relay-picker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"relay-picker.js","sourceRoot":"","sources":["../../src/services/relay-picker.ts"],"names":[],"mappings":"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"}
@@ -1,55 +0,0 @@
1
- /**
2
- * Pure decision helpers for `botmux send` (extracted from cmdSend so they can
3
- * be unit-tested without process.exit / Lark I/O).
4
- *
5
- * Two policies live here:
6
- * - resolveQuoteTarget: which message a chat-scope send should quote (reply
7
- * to), so 普通群 messages render Lark's 引用 chain. Thread-scope and
8
- * --top-level never quote.
9
- * - validateMentionDecision: the @ hard-gate — every model-initiated reply
10
- * must explicitly choose --mention / --mention-back / --no-mention.
11
- */
12
- export interface QuoteTargetArgs {
13
- /** session.scope === 'chat' */
14
- isChatScope: boolean;
15
- /** --top-level publish mode */
16
- sendTopLevel: boolean;
17
- /** --no-quote: force a plain (un-quoted) send */
18
- noQuote: boolean;
19
- /** --quote <message_id> explicit override */
20
- explicitQuote?: string;
21
- /** session.quoteTargetId — the latest inbound message this turn responds to */
22
- sessionQuoteTargetId?: string;
23
- }
24
- /**
25
- * Resolve the message id a send should quote, or null for a plain send.
26
- * Priority: --quote > session.quoteTargetId. Only chat-scope, non-top-level,
27
- * non-`--no-quote` sends quote.
28
- */
29
- export declare function resolveQuoteTarget(args: QuoteTargetArgs): string | null;
30
- export interface MentionDecisionArgs {
31
- /** config.send.requireMentionDecision */
32
- enabled: boolean;
33
- /** --top-level publish is exempt from the gate */
34
- sendTopLevel: boolean;
35
- /** at least one --mention <ou:Name> given */
36
- hasMentionArgs: boolean;
37
- /** --mention-back given */
38
- mentionBack: boolean;
39
- /** --no-mention given */
40
- noMention: boolean;
41
- /** whether the session knows who sent the message being replied to */
42
- hasQuoteTargetSender: boolean;
43
- }
44
- export interface MentionDecisionResult {
45
- ok: boolean;
46
- /** present when !ok — the message to print before exit(2) */
47
- error?: string;
48
- }
49
- /**
50
- * Enforce that the model made an explicit @ decision before sending.
51
- * Returns ok:false with a context-aware error when no decision was made or
52
- * the flags contradict each other.
53
- */
54
- export declare function validateMentionDecision(args: MentionDecisionArgs): MentionDecisionResult;
55
- //# sourceMappingURL=send-policy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-policy.d.ts","sourceRoot":"","sources":["../../src/services/send-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,WAAW,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAIvE;AAED,MAAM,WAAW,mBAAmB;IAClC,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,YAAY,EAAE,OAAO,CAAC;IACtB,6CAA6C;IAC7C,cAAc,EAAE,OAAO,CAAC;IACxB,2BAA2B;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,yBAAyB;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,sEAAsE;IACtE,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,mBAAmB,GAAG,qBAAqB,CAoBxF"}
@@ -1,47 +0,0 @@
1
- /**
2
- * Pure decision helpers for `botmux send` (extracted from cmdSend so they can
3
- * be unit-tested without process.exit / Lark I/O).
4
- *
5
- * Two policies live here:
6
- * - resolveQuoteTarget: which message a chat-scope send should quote (reply
7
- * to), so 普通群 messages render Lark's 引用 chain. Thread-scope and
8
- * --top-level never quote.
9
- * - validateMentionDecision: the @ hard-gate — every model-initiated reply
10
- * must explicitly choose --mention / --mention-back / --no-mention.
11
- */
12
- /**
13
- * Resolve the message id a send should quote, or null for a plain send.
14
- * Priority: --quote > session.quoteTargetId. Only chat-scope, non-top-level,
15
- * non-`--no-quote` sends quote.
16
- */
17
- export function resolveQuoteTarget(args) {
18
- if (!args.isChatScope || args.sendTopLevel || args.noQuote)
19
- return null;
20
- const target = args.explicitQuote ?? args.sessionQuoteTargetId;
21
- return target && target.trim() ? target.trim() : null;
22
- }
23
- /**
24
- * Enforce that the model made an explicit @ decision before sending.
25
- * Returns ok:false with a context-aware error when no decision was made or
26
- * the flags contradict each other.
27
- */
28
- export function validateMentionDecision(args) {
29
- if (!args.enabled || args.sendTopLevel)
30
- return { ok: true };
31
- if (args.noMention && (args.hasMentionArgs || args.mentionBack)) {
32
- return { ok: false, error: '--no-mention 不能与 --mention / --mention-back 同时使用。' };
33
- }
34
- if (args.mentionBack && !args.hasQuoteTargetSender) {
35
- return { ok: false, error: '--mention-back 无可 @ 对象:本轮没有可识别的触发消息发送者。请改用 --mention <ou:Name> 或 --no-mention。' };
36
- }
37
- const decided = args.hasMentionArgs || args.mentionBack || args.noMention;
38
- if (decided)
39
- return { ok: true };
40
- // No decision made — guide by message VALUE (not by human-vs-bot). Avoid
41
- // letting --no-mention become the lazy default, and avoid meaningless @.
42
- return {
43
- ok: false,
44
- error: '本条需显式 @ 决策(别把 --no-mention 当默认):有实质结论、要对方继续看/确认/决策 → --mention-back(或 --mention <ou:Name> 点名);纯记录/低优先级进度/简短确认 → --no-mention;若只是没信息量的"收到",不如不发,等有内容再回。',
45
- };
46
- }
47
- //# sourceMappingURL=send-policy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-policy.js","sourceRoot":"","sources":["../../src/services/send-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAeH;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,oBAAoB,CAAC;IAC/D,OAAO,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AAuBD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAyB;IAC/D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAE5D,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAC;IACnF,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gFAAgF,EAAE,CAAC;IAChH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,SAAS,CAAC;IAC1E,IAAI,OAAO;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAEjC,yEAAyE;IACzE,yEAAyE;IACzE,OAAO;QACL,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,wJAAwJ;KAChK,CAAC;AACJ,CAAC"}
@@ -1,38 +0,0 @@
1
- export interface TeamRosterBot {
2
- larkAppId: string;
3
- name: string;
4
- cliId: string;
5
- capability: string | null;
6
- hasTeamRole: boolean;
7
- /** Owner for grouping by person; null if unassigned. unionId is the key, name for display. */
8
- owner: {
9
- unionId?: string;
10
- openId?: string;
11
- name?: string;
12
- } | null;
13
- }
14
- export interface TeamRoster {
15
- team: {
16
- id: string;
17
- name: string;
18
- memberCount: number;
19
- };
20
- bots: TeamRosterBot[];
21
- }
22
- /** A currently-running bot from the live daemon registry (authoritative for
23
- * "what's running" — unlike bots-info.json which is a racy, probe-lagged file). */
24
- export interface LiveBot {
25
- larkAppId: string;
26
- botName?: string | null;
27
- cliId?: string;
28
- }
29
- /**
30
- * @param configOrder optional list of larkAppIds in bots.json (config) order;
31
- * when given, the roster is sorted to match it (and the personal dashboard).
32
- * @param liveBots optional live daemon-registry bots. When given, the roster's
33
- * bot set is THESE (authoritative — fixes an empty/stale bots-info.json
34
- * showing no bots even though daemons are running), enriched with cliId from
35
- * bots-info.json by larkAppId. When omitted, falls back to bots-info.json.
36
- */
37
- export declare function buildTeamRoster(dataDir: string, teamId?: string, configOrder?: string[], liveBots?: LiveBot[]): TeamRoster;
38
- //# sourceMappingURL=team-roster.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"team-roster.d.ts","sourceRoot":"","sources":["../../src/services/team-roster.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,8FAA8F;IAC9F,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACpE;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,IAAI,EAAE,aAAa,EAAE,CAAC;CACvB;AAkBD;oFACoF;AACpF,MAAM,WAAW,OAAO;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAEvF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAwB,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,UAAU,CAyC3I"}
@@ -1,82 +0,0 @@
1
- /**
2
- * Team-level collaboration roster for the platform UI: every bot the deployment
3
- * runs (from bots-info.json) enriched with its team capability label and whether
4
- * it has a team-level role, plus the team's member count.
5
- *
6
- * This is the TEAM view (who's on the team), distinct from the per-chat roster
7
- * in listChatBotMembers (who's in a given group + reliably @-mentionable).
8
- * Pure read from `{dataDir}` files — no Lark API, no config coupling — so it is
9
- * trivially testable and cheap for the UI to poll.
10
- */
11
- import { readFileSync, existsSync } from 'node:fs';
12
- import { join } from 'node:path';
13
- import { getBotCapability } from './bot-profile-store.js';
14
- import { getBotOwner } from './bot-owner-store.js';
15
- import { getTeam, getDefaultTeam, DEFAULT_TEAM_ID } from './team-store.js';
16
- function readBotsInfo(dataDir) {
17
- const fp = join(dataDir, 'bots-info.json');
18
- if (!existsSync(fp))
19
- return [];
20
- try {
21
- const parsed = JSON.parse(readFileSync(fp, 'utf-8'));
22
- if (Array.isArray(parsed))
23
- return parsed;
24
- }
25
- catch { /* corrupt — empty roster */ }
26
- return [];
27
- }
28
- function hasTeamRoleFile(dataDir, larkAppId) {
29
- return existsSync(join(dataDir, 'team-roles', `${larkAppId}.md`));
30
- }
31
- /**
32
- * @param configOrder optional list of larkAppIds in bots.json (config) order;
33
- * when given, the roster is sorted to match it (and the personal dashboard).
34
- * @param liveBots optional live daemon-registry bots. When given, the roster's
35
- * bot set is THESE (authoritative — fixes an empty/stale bots-info.json
36
- * showing no bots even though daemons are running), enriched with cliId from
37
- * bots-info.json by larkAppId. When omitted, falls back to bots-info.json.
38
- */
39
- export function buildTeamRoster(dataDir, teamId = DEFAULT_TEAM_ID, configOrder, liveBots) {
40
- const team = getTeam(dataDir, teamId) ?? getDefaultTeam(dataDir);
41
- const info = readBotsInfo(dataDir);
42
- let entries;
43
- if (liveBots !== undefined) {
44
- // Live registry is the source of truth WHEN PROVIDED — including an empty
45
- // array (no daemons running ⇒ empty roster). Never fall back to a stale
46
- // bots-info.json here, or removed/offline bots would linger. Enrich
47
- // cliId/openId/name from bots-info.json (which carries cliId — the registry
48
- // doesn't) by larkAppId.
49
- const byId = new Map(info.map(e => [e.larkAppId, e]));
50
- entries = liveBots.map(lb => {
51
- const ex = byId.get(lb.larkAppId);
52
- return {
53
- larkAppId: lb.larkAppId,
54
- botOpenId: ex?.botOpenId ?? null,
55
- botName: lb.botName ?? ex?.botName ?? null,
56
- cliId: lb.cliId ?? ex?.cliId ?? '',
57
- };
58
- });
59
- }
60
- else {
61
- entries = info;
62
- }
63
- if (configOrder && configOrder.length) {
64
- const rank = new Map(configOrder.map((id, i) => [id, i]));
65
- const at = (id) => rank.has(id) ? rank.get(id) : Number.MAX_SAFE_INTEGER;
66
- // stable sort by config index; unknown bots fall to the end keeping their order
67
- entries = entries.map((b, i) => ({ b, i })).sort((x, y) => (at(x.b.larkAppId) - at(y.b.larkAppId)) || (x.i - y.i)).map(x => x.b);
68
- }
69
- const bots = entries.map((b) => {
70
- const o = getBotOwner(dataDir, b.larkAppId);
71
- return {
72
- larkAppId: b.larkAppId,
73
- name: b.botName ?? b.cliId,
74
- cliId: b.cliId,
75
- capability: getBotCapability(dataDir, b.larkAppId),
76
- hasTeamRole: hasTeamRoleFile(dataDir, b.larkAppId),
77
- owner: o ? { unionId: o.unionId, openId: o.openId, name: o.name } : null,
78
- };
79
- });
80
- return { team: { id: team.id, name: team.name, memberCount: team.members.length }, bots };
81
- }
82
- //# sourceMappingURL=team-roster.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"team-roster.js","sourceRoot":"","sources":["../../src/services/team-roster.ts"],"names":[],"mappings":"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"}