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
package/dist/daemon.js CHANGED
@@ -27,8 +27,8 @@ import { scanMultipleProjects } from './services/project-scanner.js';
27
27
  import { buildRepoSelectCard, buildStreamingCard, getCliDisplayName } from './im/lark/card-builder.js';
28
28
  import { t as tr, botLocale, localeForBot } from './i18n/index.js';
29
29
  import { createCliAdapterSync } from './adapters/cli/registry.js';
30
- import { initWorkerPool, setActiveSessionsRegistry, forkWorker, killWorker, scheduleCardPatch, setCurrentCliVersion, CARD_POSTING_SENTINEL, parkStreamCard, closeSession as closeSessionHelper, ensureCliEnv, writableTerminalLinkFor, } from './core/worker-pool.js';
31
- import { ipcRoute, jsonRes, readJsonBody, setBotName, setLarkAppId, startIpcServer, setWorkflowRunner } from './core/dashboard-ipc-server.js';
30
+ import { initWorkerPool, setActiveSessionsRegistry, forkWorker, killWorker, scheduleCardPatch, setCurrentCliVersion, CARD_POSTING_SENTINEL, parkStreamCard, closeSession as closeSessionHelper, } from './core/worker-pool.js';
31
+ import { ipcRoute, jsonRes, readJsonBody, setBotName, setLarkAppId, startIpcServer } from './core/dashboard-ipc-server.js';
32
32
  import { saveFrozenCards } from './services/frozen-card-store.js';
33
33
  import { DAEMON_COMMANDS, PASSTHROUGH_COMMANDS, handleCommand, parseSlashCommandInvocation, parseForceTopicInvocation } from './core/command-handler.js';
34
34
  import { findInheritablePeer } from './core/inherit-peer.js';
@@ -60,9 +60,6 @@ import { resolveWait } from './workflows/wait.js';
60
60
  import { replay } from './workflows/events/replay.js';
61
61
  import { isValidRunId, readRunSnapshot } from './workflows/ops-projection.js';
62
62
  import { AttemptResumeManager } from './workflows/attempt-resume.js';
63
- import { setCardDispatcher as setAskCardDispatcher, registerAsk as registerAskBroker, } from './core/ask-broker.js';
64
- import { parseAskBody, resolveAskApprovers } from './core/ask-api.js';
65
- import { createLarkAskCardDispatcher } from './im/lark/ask-card.js';
66
63
  // ─── State ───────────────────────────────────────────────────────────────────
67
64
  const activeSessions = new Map();
68
65
  const workflowEventWatchers = new Map();
@@ -727,11 +724,7 @@ async function resolveDashboardWait(runId, resolution, comment) {
727
724
  resolution,
728
725
  by: 'dashboard',
729
726
  comment,
730
- },
731
- // v0.2: pass def so resolveWait can write activitySucceeded for
732
- // `decision` node reject instead of activityFailed. entry.ctx.def
733
- // is the live, in-memory snapshot already loaded for this run.
734
- { def: entry.ctx.def });
727
+ });
735
728
  const after = replay(await entry.ctx.log.readAll());
736
729
  // Fire-and-forget re-drive — same pattern as Lark card path
737
730
  // (workflowApprovalResolved hook). Don't await; the dashboard caller
@@ -936,7 +929,7 @@ function beginNewTurn(ds, title) {
936
929
  const dsBotCfg = getBot(ds.larkAppId).config;
937
930
  const prevTitle = ds.currentTurnTitle || ds.session.title || getCliDisplayName(dsBotCfg.cliId);
938
931
  const prevMode = ds.displayMode ?? 'hidden';
939
- const frozenCard = buildStreamingCard(ds.session.sessionId, sessionAnchorId(ds), readUrl, prevTitle, ds.lastScreenContent ?? '', previousStatus, dsBotCfg.cliId, prevMode, ds.streamCardNonce, ds.currentImageKey, !!ds.adoptedFrom, false, localeForBot(ds.larkAppId), previousUsageLimit, writableTerminalLinkFor(ds));
932
+ const frozenCard = buildStreamingCard(ds.session.sessionId, sessionAnchorId(ds), readUrl, prevTitle, ds.lastScreenContent ?? '', previousStatus, dsBotCfg.cliId, prevMode, ds.streamCardNonce, ds.currentImageKey, !!ds.adoptedFrom, false, localeForBot(ds.larkAppId), previousUsageLimit);
940
933
  scheduleCardPatch(ds, frozenCard);
941
934
  if (ds.streamCardNonce && ds.streamCardId !== CARD_POSTING_SENTINEL) {
942
935
  if (!ds.frozenCards)
@@ -1081,28 +1074,6 @@ ipcRoute('POST', '/api/workflows/runs/:runId/cancel', async (req, res, params) =
1081
1074
  }
1082
1075
  return jsonRes(res, 200, result);
1083
1076
  });
1084
- /** Heavy deps for triggerWorkflowRun, shared by the catalog `…/run` route and
1085
- * the `/api/trigger` (kind=workflow) thin layer. */
1086
- function workflowTriggerDeps() {
1087
- return {
1088
- spawnSubagent: workflowSpawnFn(),
1089
- botResolver: resolveBotSnapshot,
1090
- makeRuntimeContext: (log, def, spawnSubagent) => ({
1091
- log,
1092
- def,
1093
- spawnSubagent,
1094
- hostExecutors: createDefaultHostExecutorRegistry(),
1095
- reconcilers: createDefaultProviderReconcilers(),
1096
- loadEffectInput: (activityId, attemptId) => loadEffectInputSidecar(log, activityId, attemptId),
1097
- }),
1098
- attachRuntime: (runId, ctx) => attachWorkflowEventWatcher(runId, ctx),
1099
- driveRun: (runId) => {
1100
- driveWorkflowRun(runId).catch((err) => {
1101
- logger.warn(`[workflow:${runId}] trigger drive failed: ${err instanceof Error ? err.message : String(err)}`);
1102
- });
1103
- },
1104
- };
1105
- }
1106
1077
  ipcRoute('POST', '/api/workflows/definitions/:id/run', async (req, res, params) => {
1107
1078
  const workflowId = params.id;
1108
1079
  if (!isValidWorkflowId(workflowId)) {
@@ -1135,7 +1106,24 @@ ipcRoute('POST', '/api/workflows/definitions/:id/run', async (req, res, params)
1135
1106
  rawParams,
1136
1107
  chatBinding,
1137
1108
  initiator: 'dashboard',
1138
- }, workflowTriggerDeps());
1109
+ }, {
1110
+ spawnSubagent: workflowSpawnFn(),
1111
+ botResolver: resolveBotSnapshot,
1112
+ makeRuntimeContext: (log, def, spawnSubagent) => ({
1113
+ log,
1114
+ def,
1115
+ spawnSubagent,
1116
+ hostExecutors: createDefaultHostExecutorRegistry(),
1117
+ reconcilers: createDefaultProviderReconcilers(),
1118
+ loadEffectInput: (activityId, attemptId) => loadEffectInputSidecar(log, activityId, attemptId),
1119
+ }),
1120
+ attachRuntime: (runId, ctx) => attachWorkflowEventWatcher(runId, ctx),
1121
+ driveRun: (runId) => {
1122
+ driveWorkflowRun(runId).catch((err) => {
1123
+ logger.warn(`[workflow:${runId}] dashboard-trigger drive failed: ${err instanceof Error ? err.message : String(err)}`);
1124
+ });
1125
+ },
1126
+ });
1139
1127
  if (!result.ok) {
1140
1128
  const status = result.error === 'unknown_workflow' ? 404 :
1141
1129
  result.error === 'invalid_params' ? 400 :
@@ -1144,83 +1132,6 @@ ipcRoute('POST', '/api/workflows/definitions/:id/run', async (req, res, params)
1144
1132
  }
1145
1133
  return jsonRes(res, 200, result);
1146
1134
  });
1147
- // ─── botmux ask v0.1.7 IPC route ─────────────────────────────────────────────
1148
- //
1149
- // CLI side: `botmux ask buttons --options "..."` POSTs here and keeps the
1150
- // connection open until the broker settles the ask. Long keep-alive is OK —
1151
- // the request's lifetime is bounded by `body.timeoutMs` which the broker
1152
- // enforces. Default fetch on the CLI side has no read timeout.
1153
- ipcRoute('POST', '/api/asks', async (req, res) => {
1154
- let raw;
1155
- try {
1156
- raw = await readJsonBody(req);
1157
- }
1158
- catch {
1159
- return jsonRes(res, 400, { ok: false, error: 'bad_json' });
1160
- }
1161
- const parsed = parseAskBody(raw);
1162
- if ('error' in parsed)
1163
- return jsonRes(res, 400, { ok: false, error: parsed.error });
1164
- const approvers = resolveAskApprovers({
1165
- larkAppId: parsed.larkAppId,
1166
- sessionId: parsed.sessionId,
1167
- explicit: parsed.approvers,
1168
- getBotAllowedUsers: (id) => {
1169
- try {
1170
- return getBot(id).resolvedAllowedUsers;
1171
- }
1172
- catch {
1173
- return [];
1174
- }
1175
- },
1176
- getSessionOwner: (sid) => {
1177
- for (const ds of activeSessions.values()) {
1178
- if (ds.session.sessionId === sid)
1179
- return ds.ownerOpenId;
1180
- }
1181
- return undefined;
1182
- },
1183
- });
1184
- if (approvers.size === 0) {
1185
- // Nobody can answer — fail loud rather than registering a
1186
- // guaranteed-timeout. CLI side maps this to exit 2.
1187
- return jsonRes(res, 400, { ok: false, error: 'no_approvers' });
1188
- }
1189
- const result = await registerAskBroker({
1190
- larkAppId: parsed.larkAppId,
1191
- chatId: parsed.chatId,
1192
- rootMessageId: parsed.rootMessageId,
1193
- sessionId: parsed.sessionId,
1194
- approvers,
1195
- questions: parsed.questions,
1196
- timeoutMs: parsed.timeoutMs,
1197
- });
1198
- return jsonRes(res, 200, result);
1199
- });
1200
- // ─── adopt-session 查询端点 ───────────────────────────────────────────────────
1201
- // CLI side(botmux hook)通过祖先 PID 匹配 adopt 会话,路由 askUserQuestion。
1202
- // GET /api/adopt-session/:pid — 返回该 pid 对应的 adopt 会话路由信息。
1203
- // 仅匹配**当前活跃**的 adopt 会话(按 originalCliPid)。残留风险:OS 的 PID 复用——
1204
- // 若原 adopt 的 Claude 已退出、同号 PID 被别的进程复用,理论上可能误命中;但 hook
1205
- // 进程是该 Claude 的子孙,只有 Claude 仍在跑时其祖先链里才会出现这个 PID,且 session
1206
- // 必须仍在 activeSessions 里,复用窗口极小,可接受(不为此引入进程级鉴权)。
1207
- ipcRoute('GET', '/api/adopt-session/:pid', (_req, res, params) => {
1208
- const pid = Number(params.pid);
1209
- if (!Number.isInteger(pid) || pid <= 0) {
1210
- return jsonRes(res, 400, { ok: false, error: 'bad_pid' });
1211
- }
1212
- for (const ds of activeSessions.values()) {
1213
- if (ds.adoptedFrom?.originalCliPid === pid) {
1214
- return jsonRes(res, 200, {
1215
- sessionId: ds.session.sessionId,
1216
- chatId: ds.chatId,
1217
- larkAppId: ds.larkAppId,
1218
- rootMessageId: sessionAnchorId(ds),
1219
- });
1220
- }
1221
- }
1222
- return jsonRes(res, 404, { ok: false, error: 'no_adopt_session' });
1223
- });
1224
1135
  function parseTriggerChatBinding(raw) {
1225
1136
  if (!raw || typeof raw !== 'object' || Array.isArray(raw))
1226
1137
  return undefined;
@@ -1311,31 +1222,6 @@ function resolveBotDefaultWorkingDir(larkAppId) {
1311
1222
  `falling back to repo-select card`);
1312
1223
  return undefined;
1313
1224
  }
1314
- /**
1315
- * Resolve the pinned working dir for a brand-new topic via the layered lookup:
1316
- * 1) an existing oncall binding (this bot or a sibling)
1317
- * 2) this bot's defaultOncall — auto-binds a brand-new chat when the flag is on
1318
- * (this WRITES state, so it must run identically on every spawn path)
1319
- * 3) a sibling session's workingDir (cross-bot / chat-scope inheritance)
1320
- * 4) this bot's `defaultWorkingDir` (pure runtime fallback)
1321
- * Returns the dir plus the oncall / inherited source so callers can log the reason.
1322
- * Shared by the normal spawn path and the first-message `/repo` command branch so
1323
- * both honor the defaultOncall auto-bind the same way.
1324
- */
1325
- async function resolvePinnedWorkingDir(ctx) {
1326
- let oncallEntry = findOncallChatForAnyBot(ctx.chatId);
1327
- if (!oncallEntry) {
1328
- oncallEntry = await maybeAutoBindDefaultOncall(ctx.larkAppId, ctx.chatId, ctx.chatType);
1329
- }
1330
- const inheritedFrom = !oncallEntry
1331
- ? findInheritablePeer({ scope: ctx.scope, anchor: ctx.anchor, chatId: ctx.chatId, chatType: ctx.chatType, selfAppId: ctx.larkAppId })
1332
- : null;
1333
- const botDefaultWorkingDir = (!oncallEntry && !inheritedFrom)
1334
- ? resolveBotDefaultWorkingDir(ctx.larkAppId)
1335
- : undefined;
1336
- const pinnedWorkingDir = oncallEntry?.workingDir ?? inheritedFrom?.workingDir ?? botDefaultWorkingDir;
1337
- return { pinnedWorkingDir, oncallEntry, inheritedFrom };
1338
- }
1339
1225
  async function replyInvalidWorkingDirs(anchor, larkAppId, ds) {
1340
1226
  const bot = getBot(larkAppId);
1341
1227
  const invalid = invalidWorkingDirs({
@@ -1393,7 +1279,6 @@ async function handleNewTopic(data, ctx) {
1393
1279
  logger.info(`[/t] Force-topic invocation: prompt="${forceTopic.prompt.substring(0, 60)}" (scope=${scope}, anchor=${anchor.substring(0, 12)})`);
1394
1280
  }
1395
1281
  const senderOpenId = data.sender?.sender_id?.open_id;
1396
- const senderUnionId = data.sender?.sender_id?.union_id;
1397
1282
  const botCfg = getBot(larkAppId).config;
1398
1283
  logger.info(`New session: "${content.substring(0, 60)}" (scope=${scope}, anchor=${anchor.substring(0, 12)}, resources: ${resources.length}, active: ${getActiveCount()}, messageId: ${messageId}, chatId: ${chatId})`);
1399
1284
  if (await handleWorkflowCommandIfAny(cmdContent, anchor, chatId, larkAppId, senderOpenId)) {
@@ -1426,26 +1311,9 @@ async function handleNewTopic(data, ctx) {
1426
1311
  const now = Date.now();
1427
1312
  session.larkAppId = larkAppId;
1428
1313
  session.ownerOpenId = senderOpenId;
1429
- session.ownerUnionId = senderUnionId;
1430
1314
  session.lastCallerOpenId = senderOpenId;
1431
1315
  session.lastMessageAt = new Date(now).toISOString();
1432
1316
  session.scope = scope;
1433
- // First-message `/repo`: seed the same pending-repo state the card flow
1434
- // uses, so the `/repo` handler launches the CLI straight away —
1435
- // `/repo <arg>` in that repo, bare `/repo` in the default workingDir —
1436
- // instead of taking the mid-session close+recreate path or re-showing the
1437
- // card. Use the SAME pinned-dir resolver as the normal spawn path (incl.
1438
- // defaultOncall auto-bind) so a bound/auto-bound chat still launches in the
1439
- // right place when no arg is given.
1440
- let cmdPending;
1441
- if (cmd === '/repo') {
1442
- const { pinnedWorkingDir } = await resolvePinnedWorkingDir({ scope, anchor, chatId, chatType, larkAppId });
1443
- if (pinnedWorkingDir)
1444
- session.workingDir = pinnedWorkingDir;
1445
- // pendingPrompt is empty (the message *is* the command), so the CLI just
1446
- // boots and waits for the user's next message; no sender tag needed.
1447
- cmdPending = { pendingRepo: true, pendingPrompt: '', workingDir: pinnedWorkingDir };
1448
- }
1449
1317
  sessionStore.updateSession(session);
1450
1318
  activeSessions.set(sessionKey(anchor, larkAppId), {
1451
1319
  session,
@@ -1461,7 +1329,6 @@ async function handleNewTopic(data, ctx) {
1461
1329
  lastMessageAt: now,
1462
1330
  hasHistory: false,
1463
1331
  ownerOpenId: senderOpenId,
1464
- ...cmdPending,
1465
1332
  });
1466
1333
  // Pass mention-stripped content so /command argument parsing works.
1467
1334
  await handleCommand(cmd, anchor, { ...parsed, content: commandContent }, commandDeps, larkAppId);
@@ -1503,24 +1370,36 @@ async function handleNewTopic(data, ctx) {
1503
1370
  const now = Date.now();
1504
1371
  session.larkAppId = larkAppId;
1505
1372
  session.ownerOpenId = senderOpenId;
1506
- session.ownerUnionId = senderUnionId;
1507
- session.lastCallerOpenId = senderOpenId;
1508
- // First turn of a brand-new topic: seed quoteTarget* so the very first
1509
- // `botmux send` can --mention-back / 引用 the triggering message (chat scope).
1510
- // Without this the first reply hits hasQuoteTargetSender=false (exit 2) and
1511
- // chat-scope首条不引用. Use the event's sender open_id (correct app scope).
1512
- session.quoteTargetId = parsed.messageId;
1513
- session.quoteTargetSenderOpenId = senderOpenId;
1514
- session.quoteTargetSenderIsBot = parsed.senderType === 'app' || parsed.senderType === 'bot';
1515
1373
  session.lastMessageAt = new Date(now).toISOString();
1516
1374
  session.scope = scope;
1517
1375
  sessionStore.updateSession(session);
1518
1376
  messageQueue.ensureQueue(anchor);
1519
1377
  messageQueue.appendMessage(anchor, parsed);
1520
- // Pin the working dir via the layered oncall / inherit / default lookup
1521
- // (auto-binds a defaultOncall chat as a side effect). Shared with the
1522
- // first-message `/repo` command branch so both paths stay consistent.
1523
- const { pinnedWorkingDir, oncallEntry, inheritedFrom } = await resolvePinnedWorkingDir({ scope, anchor, chatId, chatType, larkAppId });
1378
+ // Oncall group: pin working dir from the chat-level binding, even if a
1379
+ // sibling bot (running in another daemon) is the one that persisted it.
1380
+ // Layered lookup:
1381
+ // 1) any existing binding (this bot or sibling)
1382
+ // 2) this bot's defaultOncall — auto-binds the chat if it's brand new
1383
+ // and the flag is on. Once auto-bound, the chat appears in oncallChats
1384
+ // so the next handleNewTopic sees it via (1).
1385
+ let oncallEntry = findOncallChatForAnyBot(chatId);
1386
+ if (!oncallEntry) {
1387
+ oncallEntry = await maybeAutoBindDefaultOncall(larkAppId, chatId, chatType);
1388
+ }
1389
+ // Cross-bot / chat-scope inheritance: reuse a sibling session's workingDir
1390
+ // and skip the repo card. Same block lives in handleThreadReply's auto-create
1391
+ // branch — both handlers land unowned messages after the 4fec43c routing
1392
+ // change. Helper is shared.
1393
+ const inheritedFrom = !oncallEntry
1394
+ ? findInheritablePeer({ scope, anchor, chatId, chatType, selfAppId: larkAppId })
1395
+ : null;
1396
+ // Last-resort fallback: this bot's `defaultWorkingDir`. Pure runtime — no
1397
+ // oncall binding written, no permission-model change. Lets a single-repo
1398
+ // bot skip the repo-select card without committing to oncall semantics.
1399
+ const botDefaultWorkingDir = (!oncallEntry && !inheritedFrom)
1400
+ ? resolveBotDefaultWorkingDir(larkAppId)
1401
+ : undefined;
1402
+ const pinnedWorkingDir = oncallEntry?.workingDir ?? inheritedFrom?.workingDir ?? botDefaultWorkingDir;
1524
1403
  const ds = {
1525
1404
  session,
1526
1405
  worker: null,
@@ -1771,16 +1650,10 @@ async function handleThreadReply(data, ctx) {
1771
1650
  if (ds) {
1772
1651
  markSessionActivity(ds);
1773
1652
  const callerOpenId = parsed.senderId || data?.sender?.sender_id?.open_id;
1774
- // quoteTargetId changes every inbound message (always a new message_id), so
1775
- // — unlike lastCallerOpenId — persist unconditionally. Powers `botmux send`'s
1776
- // default chat-scope quote chain + --mention-back.
1777
- ds.session.quoteTargetId = parsed.messageId;
1778
- ds.session.quoteTargetSenderOpenId = callerOpenId;
1779
- ds.session.quoteTargetSenderIsBot = isForeignBot;
1780
1653
  if (callerOpenId && ds.session.lastCallerOpenId !== callerOpenId) {
1781
1654
  ds.session.lastCallerOpenId = callerOpenId;
1655
+ sessionStore.updateSession(ds.session);
1782
1656
  }
1783
- sessionStore.updateSession(ds.session);
1784
1657
  }
1785
1658
  // If waiting for repo selection, buffer the message and remind user
1786
1659
  if (ds?.pendingRepo) {
@@ -1795,18 +1668,13 @@ async function handleThreadReply(data, ctx) {
1795
1668
  });
1796
1669
  enriched += `\n\n${tr('daemon.enriched_mentions_label', undefined, localeForBot(larkAppId))}\n${mentionLines.join('\n')}`;
1797
1670
  }
1798
- // Stamp a buffered follow-up with its own <sender> tag ONLY when it comes
1799
- // from a different user than the first message (ds.pendingSender) — the
1800
- // deferred spawn already carries that sender's <sender> block, and the
1801
- // follow-ups now fold into the same <user_message>, so a same-user tag is
1802
- // pure duplication. A differing sender still gets attributed so the CLI can
1803
- // tell multi-user buffered messages apart after repo selection unlocks.
1804
- const followUpSender = await getThreadSender();
1805
- if (followUpSender?.openId && followUpSender.openId !== ds.pendingSender?.openId) {
1806
- const followUpSenderTag = renderSenderTag(followUpSender);
1807
- if (followUpSenderTag)
1808
- enriched = `${followUpSenderTag}\n${enriched}`;
1809
- }
1671
+ // Stamp each buffered follow-up with its own <sender> tag pendingFollowUps
1672
+ // can contain messages from multiple users while a single ds.pendingSender
1673
+ // is fixed at the first message, so without per-message attribution the
1674
+ // CLI can't tell which user said what after repo selection unlocks the spawn.
1675
+ const followUpSenderTag = renderSenderTag(await getThreadSender());
1676
+ if (followUpSenderTag)
1677
+ enriched = `${followUpSenderTag}\n${enriched}`;
1810
1678
  if (!ds.pendingFollowUps)
1811
1679
  ds.pendingFollowUps = [];
1812
1680
  ds.pendingFollowUps.push(enriched);
@@ -1831,24 +1699,15 @@ async function handleThreadReply(data, ctx) {
1831
1699
  logger.info(`No active session for ${scope}-scope ${anchor}, auto-creating new session...`);
1832
1700
  refreshCliVersion(botCfg.cliId, botCfg.cliPathOverride);
1833
1701
  const senderOId = data.sender?.sender_id?.open_id;
1834
- const senderUId = data.sender?.sender_id?.union_id;
1835
1702
  // For thread-scope: rootMessageId = anchor (real thread root).
1836
1703
  // For chat-scope: rootMessageId = the message_id that triggered this auto-create
1837
1704
  // (used as audit trail; routing key is chatId).
1838
1705
  const rootIdForStore = scope === 'thread' ? anchor : parsed.messageId;
1839
1706
  const session = sessionStore.createSession(autoCreateChatId, rootIdForStore, parsed.content.substring(0, 50), autoCreateChatType);
1840
1707
  const now = Date.now();
1841
- // Bot-started handoff sessions have no human owner; keeping the bot as
1842
- // owner makes daemon-generated footers wake that bot again.
1843
- const ownerOpenId = isForeignBot ? undefined : senderOId;
1844
- const ownerUnionId = isForeignBot ? undefined : senderUId;
1845
1708
  session.larkAppId = larkAppId;
1846
- session.ownerOpenId = ownerOpenId;
1847
- session.ownerUnionId = ownerUnionId;
1709
+ session.ownerOpenId = senderOId;
1848
1710
  session.lastCallerOpenId = senderOId;
1849
- session.quoteTargetId = parsed.messageId;
1850
- session.quoteTargetSenderOpenId = senderOId;
1851
- session.quoteTargetSenderIsBot = isForeignBot;
1852
1711
  session.lastMessageAt = new Date(now).toISOString();
1853
1712
  session.scope = scope;
1854
1713
  sessionStore.updateSession(session);
@@ -1900,7 +1759,7 @@ async function handleThreadReply(data, ctx) {
1900
1759
  pendingAttachments: attachments.length > 0 ? attachments : undefined,
1901
1760
  pendingMentions: parsed.mentions,
1902
1761
  pendingSender: autoCreateSender,
1903
- ownerOpenId,
1762
+ ownerOpenId: senderOId,
1904
1763
  currentTurnTitle: parsed.content.substring(0, 50),
1905
1764
  workingDir: pinnedWorkingDir,
1906
1765
  };
@@ -2046,23 +1905,12 @@ export async function startDaemon(botIndex) {
2046
1905
  }
2047
1906
  const cfg = botConfigs[idx];
2048
1907
  registerBot(cfg);
2049
- // 启动即为本 bot 的 CLI 预装环境(skills + askUserQuestion hook + 兜底 skill)。
2050
- // 关键:adopt 路径会跳过 ensureCliSkills,若重启后第一次就是 adopt 一个外部
2051
- // claude 会话,必须保证此时全局 ~/.claude/settings.json 已带 hook——否则"全局
2052
- // hook 适配 adopt"不成立。这里幂等、best-effort,不阻塞启动。
2053
- try {
2054
- ensureCliEnv(cfg.cliId, cfg.cliPathOverride);
2055
- }
2056
- catch (err) {
2057
- logger.warn(`[hook] startup ensureCliEnv failed for ${cfg.cliId}: ${err instanceof Error ? err.message : String(err)}`);
2058
- }
2059
1908
  sessionStore.init(cfg.larkAppId);
2060
1909
  chatFirstSeenStore.init(cfg.larkAppId);
2061
1910
  // Watch schedules.json for external writes (e.g. `botmux schedule add`
2062
1911
  // running in a separate node process) so dashboard event bus stays in sync.
2063
1912
  scheduleStore.startExternalWriteWatcher();
2064
1913
  logger.info(`Bot ${idx}/${botConfigs.length}: ${cfg.larkAppId} (cli: ${cfg.cliId})`);
2065
- setAskCardDispatcher(createLarkAskCardDispatcher());
2066
1914
  writePidFile();
2067
1915
  const memoryDiagnostics = startMemoryDiagnostics();
2068
1916
  // Publish self-descriptor for the dashboard registry. The dashboard sibling
@@ -2097,9 +1945,6 @@ export async function startDaemon(botIndex) {
2097
1945
  // Expose the activeSessions Map (owned by daemon) to worker-pool readers,
2098
1946
  // so dashboard IPC and other consumers can list/lookup live sessions.
2099
1947
  setActiveSessionsRegistry(activeSessions);
2100
- // Wire the workflow runner for /api/trigger (kind=workflow): reuse the same
2101
- // heavy deps as the catalog run route.
2102
- setWorkflowRunner((input) => triggerWorkflowRun(input, workflowTriggerDeps()));
2103
1948
  // Seed dashboard IPC botName with the bot's config id; the friendly name from
2104
1949
  // /bot/v3/info is wired into the registry descriptor (below) but the IPC server
2105
1950
  // also needs its own copy for SessionRow.botName.
@@ -2203,7 +2048,7 @@ export async function startDaemon(botIndex) {
2203
2048
  });
2204
2049
  }
2205
2050
  // Restore active sessions from previous run
2206
- await restoreActiveSessions(activeSessions);
2051
+ restoreActiveSessions(activeSessions);
2207
2052
  await attachColdWorkflowRuns(cfg.larkAppId);
2208
2053
  // Start scheduler in every daemon. Each daemon owns exactly one bot, so
2209
2054
  // each filters to only execute tasks whose `larkAppId` matches its bot