botmux 2.47.0 → 2.47.2

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 (472) hide show
  1. package/README.en.md +10 -5
  2. package/README.md +10 -5
  3. package/dist/adapters/adopt-route.d.ts +63 -0
  4. package/dist/adapters/adopt-route.d.ts.map +1 -0
  5. package/dist/adapters/adopt-route.js +195 -0
  6. package/dist/adapters/adopt-route.js.map +1 -0
  7. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  8. package/dist/adapters/backend/tmux-backend.js +11 -0
  9. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  10. package/dist/adapters/backend/tmux-pipe-backend.d.ts +11 -0
  11. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
  12. package/dist/adapters/backend/tmux-pipe-backend.js +17 -1
  13. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
  14. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  15. package/dist/adapters/cli/claude-code.js +36 -9
  16. package/dist/adapters/cli/claude-code.js.map +1 -1
  17. package/dist/adapters/cli/coco.d.ts.map +1 -1
  18. package/dist/adapters/cli/coco.js +26 -1
  19. package/dist/adapters/cli/coco.js.map +1 -1
  20. package/dist/adapters/cli/codex-app.d.ts +4 -0
  21. package/dist/adapters/cli/codex-app.d.ts.map +1 -0
  22. package/dist/adapters/cli/codex-app.js +72 -0
  23. package/dist/adapters/cli/codex-app.js.map +1 -0
  24. package/dist/adapters/cli/codex.d.ts.map +1 -1
  25. package/dist/adapters/cli/codex.js +34 -17
  26. package/dist/adapters/cli/codex.js.map +1 -1
  27. package/dist/adapters/cli/cursor.d.ts.map +1 -1
  28. package/dist/adapters/cli/cursor.js +58 -12
  29. package/dist/adapters/cli/cursor.js.map +1 -1
  30. package/dist/adapters/cli/gemini.d.ts.map +1 -1
  31. package/dist/adapters/cli/gemini.js +5 -1
  32. package/dist/adapters/cli/gemini.js.map +1 -1
  33. package/dist/adapters/cli/hermes.d.ts +4 -0
  34. package/dist/adapters/cli/hermes.d.ts.map +1 -0
  35. package/dist/adapters/cli/hermes.js +40 -0
  36. package/dist/adapters/cli/hermes.js.map +1 -0
  37. package/dist/adapters/cli/mira.d.ts +4 -0
  38. package/dist/adapters/cli/mira.d.ts.map +1 -0
  39. package/dist/adapters/cli/mira.js +67 -0
  40. package/dist/adapters/cli/mira.js.map +1 -0
  41. package/dist/adapters/cli/mtr.d.ts +5 -0
  42. package/dist/adapters/cli/mtr.d.ts.map +1 -0
  43. package/dist/adapters/cli/mtr.js +62 -0
  44. package/dist/adapters/cli/mtr.js.map +1 -0
  45. package/dist/adapters/cli/opencode.d.ts.map +1 -1
  46. package/dist/adapters/cli/opencode.js +19 -1
  47. package/dist/adapters/cli/opencode.js.map +1 -1
  48. package/dist/adapters/cli/registry.d.ts +5 -1
  49. package/dist/adapters/cli/registry.d.ts.map +1 -1
  50. package/dist/adapters/cli/registry.js +22 -2
  51. package/dist/adapters/cli/registry.js.map +1 -1
  52. package/dist/adapters/cli/shared-hints.d.ts +1 -1
  53. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  54. package/dist/adapters/cli/shared-hints.js +2 -1
  55. package/dist/adapters/cli/shared-hints.js.map +1 -1
  56. package/dist/adapters/cli/types.d.ts +35 -2
  57. package/dist/adapters/cli/types.d.ts.map +1 -1
  58. package/dist/adapters/hook-command.d.ts +18 -0
  59. package/dist/adapters/hook-command.d.ts.map +1 -0
  60. package/dist/adapters/hook-command.js +38 -0
  61. package/dist/adapters/hook-command.js.map +1 -0
  62. package/dist/adapters/hook-installer.d.ts +14 -0
  63. package/dist/adapters/hook-installer.d.ts.map +1 -0
  64. package/dist/adapters/hook-installer.js +192 -0
  65. package/dist/adapters/hook-installer.js.map +1 -0
  66. package/dist/bot-registry.d.ts +59 -0
  67. package/dist/bot-registry.d.ts.map +1 -1
  68. package/dist/bot-registry.js +67 -0
  69. package/dist/bot-registry.js.map +1 -1
  70. package/dist/cli/bots-list-output.d.ts +8 -0
  71. package/dist/cli/bots-list-output.d.ts.map +1 -1
  72. package/dist/cli/bots-list-output.js +9 -0
  73. package/dist/cli/bots-list-output.js.map +1 -1
  74. package/dist/cli.d.ts +15 -1
  75. package/dist/cli.d.ts.map +1 -1
  76. package/dist/cli.js +603 -106
  77. package/dist/cli.js.map +1 -1
  78. package/dist/codex-app-runner.d.ts +3 -0
  79. package/dist/codex-app-runner.d.ts.map +1 -0
  80. package/dist/codex-app-runner.js +512 -0
  81. package/dist/codex-app-runner.js.map +1 -0
  82. package/dist/config.d.ts +11 -2
  83. package/dist/config.d.ts.map +1 -1
  84. package/dist/config.js +17 -4
  85. package/dist/config.js.map +1 -1
  86. package/dist/core/ask-api.d.ts +47 -0
  87. package/dist/core/ask-api.d.ts.map +1 -0
  88. package/dist/core/ask-api.js +139 -0
  89. package/dist/core/ask-api.js.map +1 -0
  90. package/dist/core/ask-args.d.ts +53 -0
  91. package/dist/core/ask-args.d.ts.map +1 -0
  92. package/dist/core/ask-args.js +122 -0
  93. package/dist/core/ask-args.js.map +1 -0
  94. package/dist/core/ask-broker.d.ts +98 -0
  95. package/dist/core/ask-broker.d.ts.map +1 -0
  96. package/dist/core/ask-broker.js +329 -0
  97. package/dist/core/ask-broker.js.map +1 -0
  98. package/dist/core/ask-hook/claude-code.d.ts +50 -0
  99. package/dist/core/ask-hook/claude-code.d.ts.map +1 -0
  100. package/dist/core/ask-hook/claude-code.js +145 -0
  101. package/dist/core/ask-hook/claude-code.js.map +1 -0
  102. package/dist/core/ask-hook/codex.d.ts +43 -0
  103. package/dist/core/ask-hook/codex.d.ts.map +1 -0
  104. package/dist/core/ask-hook/codex.js +69 -0
  105. package/dist/core/ask-hook/codex.js.map +1 -0
  106. package/dist/core/ask-hook/opencode.d.ts +41 -0
  107. package/dist/core/ask-hook/opencode.d.ts.map +1 -0
  108. package/dist/core/ask-hook/opencode.js +108 -0
  109. package/dist/core/ask-hook/opencode.js.map +1 -0
  110. package/dist/core/ask-hook/registry.d.ts +3 -0
  111. package/dist/core/ask-hook/registry.d.ts.map +1 -0
  112. package/dist/core/ask-hook/registry.js +12 -0
  113. package/dist/core/ask-hook/registry.js.map +1 -0
  114. package/dist/core/ask-hook/types.d.ts +26 -0
  115. package/dist/core/ask-hook/types.d.ts.map +1 -0
  116. package/dist/core/ask-hook/types.js +2 -0
  117. package/dist/core/ask-hook/types.js.map +1 -0
  118. package/dist/core/ask-types.d.ts +146 -0
  119. package/dist/core/ask-types.d.ts.map +1 -0
  120. package/dist/core/ask-types.js +18 -0
  121. package/dist/core/ask-types.js.map +1 -0
  122. package/dist/core/command-handler.d.ts +29 -0
  123. package/dist/core/command-handler.d.ts.map +1 -1
  124. package/dist/core/command-handler.js +787 -312
  125. package/dist/core/command-handler.js.map +1 -1
  126. package/dist/core/dashboard-ipc-server.d.ts +2 -0
  127. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  128. package/dist/core/dashboard-ipc-server.js +222 -2
  129. package/dist/core/dashboard-ipc-server.js.map +1 -1
  130. package/dist/core/role-resolver.d.ts +17 -1
  131. package/dist/core/role-resolver.d.ts.map +1 -1
  132. package/dist/core/role-resolver.js +64 -10
  133. package/dist/core/role-resolver.js.map +1 -1
  134. package/dist/core/session-discovery.d.ts.map +1 -1
  135. package/dist/core/session-discovery.js +19 -5
  136. package/dist/core/session-discovery.js.map +1 -1
  137. package/dist/core/session-manager.d.ts +1 -1
  138. package/dist/core/session-manager.d.ts.map +1 -1
  139. package/dist/core/session-manager.js +37 -20
  140. package/dist/core/session-manager.js.map +1 -1
  141. package/dist/core/trigger-session.d.ts +9 -0
  142. package/dist/core/trigger-session.d.ts.map +1 -0
  143. package/dist/core/trigger-session.js +158 -0
  144. package/dist/core/trigger-session.js.map +1 -0
  145. package/dist/core/types.d.ts +5 -0
  146. package/dist/core/types.d.ts.map +1 -1
  147. package/dist/core/types.js.map +1 -1
  148. package/dist/core/worker-pool.d.ts +141 -0
  149. package/dist/core/worker-pool.d.ts.map +1 -1
  150. package/dist/core/worker-pool.js +543 -24
  151. package/dist/core/worker-pool.js.map +1 -1
  152. package/dist/daemon.d.ts.map +1 -1
  153. package/dist/daemon.js +224 -60
  154. package/dist/daemon.js.map +1 -1
  155. package/dist/dashboard/auth.d.ts +6 -1
  156. package/dist/dashboard/auth.d.ts.map +1 -1
  157. package/dist/dashboard/auth.js +9 -1
  158. package/dist/dashboard/auth.js.map +1 -1
  159. package/dist/dashboard/connector-api.d.ts +3 -0
  160. package/dist/dashboard/connector-api.d.ts.map +1 -0
  161. package/dist/dashboard/connector-api.js +351 -0
  162. package/dist/dashboard/connector-api.js.map +1 -0
  163. package/dist/dashboard/federated-group-core.d.ts +54 -0
  164. package/dist/dashboard/federated-group-core.d.ts.map +1 -0
  165. package/dist/dashboard/federated-group-core.js +165 -0
  166. package/dist/dashboard/federated-group-core.js.map +1 -0
  167. package/dist/dashboard/federation-api.d.ts +42 -0
  168. package/dist/dashboard/federation-api.d.ts.map +1 -0
  169. package/dist/dashboard/federation-api.js +408 -0
  170. package/dist/dashboard/federation-api.js.map +1 -0
  171. package/dist/dashboard/federation-spoke-api.d.ts +76 -0
  172. package/dist/dashboard/federation-spoke-api.d.ts.map +1 -0
  173. package/dist/dashboard/federation-spoke-api.js +618 -0
  174. package/dist/dashboard/federation-spoke-api.js.map +1 -0
  175. package/dist/dashboard/team-group.d.ts +18 -0
  176. package/dist/dashboard/team-group.d.ts.map +1 -0
  177. package/dist/dashboard/team-group.js +7 -0
  178. package/dist/dashboard/team-group.js.map +1 -0
  179. package/dist/dashboard/trigger-api.d.ts +13 -0
  180. package/dist/dashboard/trigger-api.d.ts.map +1 -0
  181. package/dist/dashboard/trigger-api.js +77 -0
  182. package/dist/dashboard/trigger-api.js.map +1 -0
  183. package/dist/dashboard/web/app.js +8 -0
  184. package/dist/dashboard/web/app.js.map +1 -1
  185. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
  186. package/dist/dashboard/web/bot-defaults.js +205 -21
  187. package/dist/dashboard/web/bot-defaults.js.map +1 -1
  188. package/dist/dashboard/web/connectors.d.ts +2 -0
  189. package/dist/dashboard/web/connectors.d.ts.map +1 -0
  190. package/dist/dashboard/web/connectors.js +187 -0
  191. package/dist/dashboard/web/connectors.js.map +1 -0
  192. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  193. package/dist/dashboard/web/i18n.js +43 -5
  194. package/dist/dashboard/web/i18n.js.map +1 -1
  195. package/dist/dashboard/web/sessions.d.ts.map +1 -1
  196. package/dist/dashboard/web/sessions.js +4 -0
  197. package/dist/dashboard/web/sessions.js.map +1 -1
  198. package/dist/dashboard/web/team-federation.d.ts +3 -0
  199. package/dist/dashboard/web/team-federation.d.ts.map +1 -0
  200. package/dist/dashboard/web/team-federation.js +487 -0
  201. package/dist/dashboard/web/team-federation.js.map +1 -0
  202. package/dist/dashboard/web/workflows.js +3 -3
  203. package/dist/dashboard/web/workflows.js.map +1 -1
  204. package/dist/dashboard/webhook-routes.d.ts +19 -0
  205. package/dist/dashboard/webhook-routes.d.ts.map +1 -0
  206. package/dist/dashboard/webhook-routes.js +321 -0
  207. package/dist/dashboard/webhook-routes.js.map +1 -0
  208. package/dist/dashboard/workflow-api.d.ts +8 -1
  209. package/dist/dashboard/workflow-api.d.ts.map +1 -1
  210. package/dist/dashboard/workflow-api.js +19 -4
  211. package/dist/dashboard/workflow-api.js.map +1 -1
  212. package/dist/dashboard-web/app.js +539 -375
  213. package/dist/dashboard-web/index.html +3 -1
  214. package/dist/dashboard-web/style.css +22 -0
  215. package/dist/dashboard.js +199 -2
  216. package/dist/dashboard.js.map +1 -1
  217. package/dist/i18n/en.d.ts.map +1 -1
  218. package/dist/i18n/en.js +104 -11
  219. package/dist/i18n/en.js.map +1 -1
  220. package/dist/i18n/zh.d.ts.map +1 -1
  221. package/dist/i18n/zh.js +104 -11
  222. package/dist/i18n/zh.js.map +1 -1
  223. package/dist/im/lark/ask-card.d.ts +55 -0
  224. package/dist/im/lark/ask-card.d.ts.map +1 -0
  225. package/dist/im/lark/ask-card.js +328 -0
  226. package/dist/im/lark/ask-card.js.map +1 -0
  227. package/dist/im/lark/card-builder.d.ts +108 -3
  228. package/dist/im/lark/card-builder.d.ts.map +1 -1
  229. package/dist/im/lark/card-builder.js +480 -50
  230. package/dist/im/lark/card-builder.js.map +1 -1
  231. package/dist/im/lark/card-handler.d.ts.map +1 -1
  232. package/dist/im/lark/card-handler.js +241 -18
  233. package/dist/im/lark/card-handler.js.map +1 -1
  234. package/dist/im/lark/client.d.ts +83 -0
  235. package/dist/im/lark/client.d.ts.map +1 -1
  236. package/dist/im/lark/client.js +286 -70
  237. package/dist/im/lark/client.js.map +1 -1
  238. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  239. package/dist/im/lark/event-dispatcher.js +29 -4
  240. package/dist/im/lark/event-dispatcher.js.map +1 -1
  241. package/dist/im/lark/grant-command.d.ts +2 -1
  242. package/dist/im/lark/grant-command.d.ts.map +1 -1
  243. package/dist/im/lark/grant-command.js +3 -2
  244. package/dist/im/lark/grant-command.js.map +1 -1
  245. package/dist/im/lark/identity-cache.d.ts.map +1 -1
  246. package/dist/im/lark/identity-cache.js +3 -3
  247. package/dist/im/lark/identity-cache.js.map +1 -1
  248. package/dist/im/lark/md-card.d.ts +20 -2
  249. package/dist/im/lark/md-card.d.ts.map +1 -1
  250. package/dist/im/lark/md-card.js +49 -17
  251. package/dist/im/lark/md-card.js.map +1 -1
  252. package/dist/im/lark/message-parser.d.ts.map +1 -1
  253. package/dist/im/lark/message-parser.js +87 -31
  254. package/dist/im/lark/message-parser.js.map +1 -1
  255. package/dist/im/lark/workflow-card-handler.d.ts +2 -2
  256. package/dist/im/lark/workflow-card-handler.d.ts.map +1 -1
  257. package/dist/im/lark/workflow-card-handler.js +12 -1
  258. package/dist/im/lark/workflow-card-handler.js.map +1 -1
  259. package/dist/im/lark/workflow-progress-card.d.ts.map +1 -1
  260. package/dist/im/lark/workflow-progress-card.js +53 -0
  261. package/dist/im/lark/workflow-progress-card.js.map +1 -1
  262. package/dist/mira-output.d.ts +3 -0
  263. package/dist/mira-output.d.ts.map +1 -0
  264. package/dist/mira-output.js +136 -0
  265. package/dist/mira-output.js.map +1 -0
  266. package/dist/mira-runner.d.ts +3 -0
  267. package/dist/mira-runner.d.ts.map +1 -0
  268. package/dist/mira-runner.js +534 -0
  269. package/dist/mira-runner.js.map +1 -0
  270. package/dist/services/bot-owner-store.d.ts +28 -0
  271. package/dist/services/bot-owner-store.d.ts.map +1 -0
  272. package/dist/services/bot-owner-store.js +82 -0
  273. package/dist/services/bot-owner-store.js.map +1 -0
  274. package/dist/services/bot-profile-store.d.ts +16 -0
  275. package/dist/services/bot-profile-store.d.ts.map +1 -0
  276. package/dist/services/bot-profile-store.js +98 -0
  277. package/dist/services/bot-profile-store.js.map +1 -0
  278. package/dist/services/brand-store.d.ts +15 -0
  279. package/dist/services/brand-store.d.ts.map +1 -0
  280. package/dist/services/brand-store.js +47 -0
  281. package/dist/services/brand-store.js.map +1 -0
  282. package/dist/services/card-prefs-store.d.ts +20 -0
  283. package/dist/services/card-prefs-store.d.ts.map +1 -0
  284. package/dist/services/card-prefs-store.js +82 -0
  285. package/dist/services/card-prefs-store.js.map +1 -0
  286. package/dist/services/codex-bridge-queue.d.ts +1 -0
  287. package/dist/services/codex-bridge-queue.d.ts.map +1 -1
  288. package/dist/services/codex-bridge-queue.js +23 -0
  289. package/dist/services/codex-bridge-queue.js.map +1 -1
  290. package/dist/services/codex-transcript.d.ts +1 -0
  291. package/dist/services/codex-transcript.d.ts.map +1 -1
  292. package/dist/services/codex-transcript.js.map +1 -1
  293. package/dist/services/connector-store.d.ts +58 -0
  294. package/dist/services/connector-store.d.ts.map +1 -0
  295. package/dist/services/connector-store.js +79 -0
  296. package/dist/services/connector-store.js.map +1 -0
  297. package/dist/services/deployment-identity.d.ts +22 -0
  298. package/dist/services/deployment-identity.d.ts.map +1 -0
  299. package/dist/services/deployment-identity.js +67 -0
  300. package/dist/services/deployment-identity.js.map +1 -0
  301. package/dist/services/federation-membership-store.d.ts +23 -0
  302. package/dist/services/federation-membership-store.d.ts.map +1 -0
  303. package/dist/services/federation-membership-store.js +66 -0
  304. package/dist/services/federation-membership-store.js.map +1 -0
  305. package/dist/services/federation-roster.d.ts +54 -0
  306. package/dist/services/federation-roster.d.ts.map +1 -0
  307. package/dist/services/federation-roster.js +51 -0
  308. package/dist/services/federation-roster.js.map +1 -0
  309. package/dist/services/federation-store.d.ts +76 -0
  310. package/dist/services/federation-store.d.ts.map +1 -0
  311. package/dist/services/federation-store.js +133 -0
  312. package/dist/services/federation-store.js.map +1 -0
  313. package/dist/services/grant-store.d.ts +12 -2
  314. package/dist/services/grant-store.d.ts.map +1 -1
  315. package/dist/services/grant-store.js +51 -4
  316. package/dist/services/grant-store.js.map +1 -1
  317. package/dist/services/group-creator.d.ts +10 -0
  318. package/dist/services/group-creator.d.ts.map +1 -1
  319. package/dist/services/group-creator.js +26 -1
  320. package/dist/services/group-creator.js.map +1 -1
  321. package/dist/services/groups-store.d.ts +30 -0
  322. package/dist/services/groups-store.d.ts.map +1 -1
  323. package/dist/services/groups-store.js +85 -12
  324. package/dist/services/groups-store.js.map +1 -1
  325. package/dist/services/hermes-transcript.d.ts +7 -0
  326. package/dist/services/hermes-transcript.d.ts.map +1 -0
  327. package/dist/services/hermes-transcript.js +117 -0
  328. package/dist/services/hermes-transcript.js.map +1 -0
  329. package/dist/services/invite-store.d.ts +28 -0
  330. package/dist/services/invite-store.d.ts.map +1 -0
  331. package/dist/services/invite-store.js +85 -0
  332. package/dist/services/invite-store.js.map +1 -0
  333. package/dist/services/pairing-store.d.ts +47 -0
  334. package/dist/services/pairing-store.d.ts.map +1 -0
  335. package/dist/services/pairing-store.js +132 -0
  336. package/dist/services/pairing-store.js.map +1 -0
  337. package/dist/services/project-scanner.d.ts +10 -0
  338. package/dist/services/project-scanner.d.ts.map +1 -1
  339. package/dist/services/project-scanner.js +11 -0
  340. package/dist/services/project-scanner.js.map +1 -1
  341. package/dist/services/relay-picker.d.ts +22 -0
  342. package/dist/services/relay-picker.d.ts.map +1 -0
  343. package/dist/services/relay-picker.js +62 -0
  344. package/dist/services/relay-picker.js.map +1 -0
  345. package/dist/services/send-policy.d.ts +55 -0
  346. package/dist/services/send-policy.d.ts.map +1 -0
  347. package/dist/services/send-policy.js +47 -0
  348. package/dist/services/send-policy.js.map +1 -0
  349. package/dist/services/session-store.js +1 -1
  350. package/dist/services/session-store.js.map +1 -1
  351. package/dist/services/team-roster.d.ts +38 -0
  352. package/dist/services/team-roster.d.ts.map +1 -0
  353. package/dist/services/team-roster.js +82 -0
  354. package/dist/services/team-roster.js.map +1 -0
  355. package/dist/services/team-store.d.ts +54 -0
  356. package/dist/services/team-store.d.ts.map +1 -0
  357. package/dist/services/team-store.js +156 -0
  358. package/dist/services/team-store.js.map +1 -0
  359. package/dist/services/trigger-log-store.d.ts +46 -0
  360. package/dist/services/trigger-log-store.d.ts.map +1 -0
  361. package/dist/services/trigger-log-store.js +132 -0
  362. package/dist/services/trigger-log-store.js.map +1 -0
  363. package/dist/services/trigger-types.d.ts +57 -0
  364. package/dist/services/trigger-types.d.ts.map +1 -0
  365. package/dist/services/trigger-types.js +28 -0
  366. package/dist/services/trigger-types.js.map +1 -0
  367. package/dist/services/webhook-key.d.ts +16 -0
  368. package/dist/services/webhook-key.d.ts.map +1 -0
  369. package/dist/services/webhook-key.js +123 -0
  370. package/dist/services/webhook-key.js.map +1 -0
  371. package/dist/services/webhook-lifecycle-extractors.d.ts +15 -0
  372. package/dist/services/webhook-lifecycle-extractors.d.ts.map +1 -0
  373. package/dist/services/webhook-lifecycle-extractors.js +59 -0
  374. package/dist/services/webhook-lifecycle-extractors.js.map +1 -0
  375. package/dist/services/webhook-lifecycle-store.d.ts +45 -0
  376. package/dist/services/webhook-lifecycle-store.d.ts.map +1 -0
  377. package/dist/services/webhook-lifecycle-store.js +159 -0
  378. package/dist/services/webhook-lifecycle-store.js.map +1 -0
  379. package/dist/setup/bot-config-editor.d.ts +8 -1
  380. package/dist/setup/bot-config-editor.d.ts.map +1 -1
  381. package/dist/setup/bot-config-editor.js +20 -2
  382. package/dist/setup/bot-config-editor.js.map +1 -1
  383. package/dist/setup/ensure-tmux.d.ts +0 -22
  384. package/dist/setup/ensure-tmux.d.ts.map +1 -1
  385. package/dist/setup/ensure-tmux.js +25 -1
  386. package/dist/setup/ensure-tmux.js.map +1 -1
  387. package/dist/setup/verify-permissions.d.ts.map +1 -1
  388. package/dist/setup/verify-permissions.js +15 -1
  389. package/dist/setup/verify-permissions.js.map +1 -1
  390. package/dist/skills/definitions.d.ts +2 -0
  391. package/dist/skills/definitions.d.ts.map +1 -1
  392. package/dist/skills/definitions.js +178 -12
  393. package/dist/skills/definitions.js.map +1 -1
  394. package/dist/skills/installer.d.ts +34 -0
  395. package/dist/skills/installer.d.ts.map +1 -1
  396. package/dist/skills/installer.js +119 -2
  397. package/dist/skills/installer.js.map +1 -1
  398. package/dist/types.d.ts +29 -0
  399. package/dist/types.d.ts.map +1 -1
  400. package/dist/utils/bot-routing.d.ts +50 -0
  401. package/dist/utils/bot-routing.d.ts.map +1 -1
  402. package/dist/utils/bot-routing.js +83 -0
  403. package/dist/utils/bot-routing.js.map +1 -1
  404. package/dist/utils/daemon-discovery.d.ts +11 -0
  405. package/dist/utils/daemon-discovery.d.ts.map +1 -0
  406. package/dist/utils/daemon-discovery.js +59 -0
  407. package/dist/utils/daemon-discovery.js.map +1 -0
  408. package/dist/utils/user-token.d.ts.map +1 -1
  409. package/dist/utils/user-token.js +0 -2
  410. package/dist/utils/user-token.js.map +1 -1
  411. package/dist/worker.js +233 -51
  412. package/dist/worker.js.map +1 -1
  413. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  414. package/dist/workflows/attempt-resume.js +2 -2
  415. package/dist/workflows/attempt-resume.js.map +1 -1
  416. package/dist/workflows/definition.d.ts +412 -9
  417. package/dist/workflows/definition.d.ts.map +1 -1
  418. package/dist/workflows/definition.js +238 -3
  419. package/dist/workflows/definition.js.map +1 -1
  420. package/dist/workflows/events/payloads.d.ts +114 -11
  421. package/dist/workflows/events/payloads.d.ts.map +1 -1
  422. package/dist/workflows/events/payloads.js +46 -0
  423. package/dist/workflows/events/payloads.js.map +1 -1
  424. package/dist/workflows/events/replay.d.ts +21 -0
  425. package/dist/workflows/events/replay.d.ts.map +1 -1
  426. package/dist/workflows/events/replay.js +103 -0
  427. package/dist/workflows/events/replay.js.map +1 -1
  428. package/dist/workflows/events/schema.d.ts +1301 -606
  429. package/dist/workflows/events/schema.d.ts.map +1 -1
  430. package/dist/workflows/events/schema.js +37 -1
  431. package/dist/workflows/events/schema.js.map +1 -1
  432. package/dist/workflows/events/types.d.ts +5 -1
  433. package/dist/workflows/events/types.d.ts.map +1 -1
  434. package/dist/workflows/loader.d.ts +14 -0
  435. package/dist/workflows/loader.d.ts.map +1 -1
  436. package/dist/workflows/loader.js +27 -0
  437. package/dist/workflows/loader.js.map +1 -1
  438. package/dist/workflows/loop.js +58 -0
  439. package/dist/workflows/loop.js.map +1 -1
  440. package/dist/workflows/ops-projection.d.ts +58 -0
  441. package/dist/workflows/ops-projection.d.ts.map +1 -1
  442. package/dist/workflows/ops-projection.js +74 -0
  443. package/dist/workflows/ops-projection.js.map +1 -1
  444. package/dist/workflows/orchestrator.d.ts +65 -1
  445. package/dist/workflows/orchestrator.d.ts.map +1 -1
  446. package/dist/workflows/orchestrator.js +486 -74
  447. package/dist/workflows/orchestrator.js.map +1 -1
  448. package/dist/workflows/output-binding.d.ts +8 -1
  449. package/dist/workflows/output-binding.d.ts.map +1 -1
  450. package/dist/workflows/output-binding.js +75 -11
  451. package/dist/workflows/output-binding.js.map +1 -1
  452. package/dist/workflows/runtime.d.ts +1 -1
  453. package/dist/workflows/runtime.d.ts.map +1 -1
  454. package/dist/workflows/runtime.js +39 -4
  455. package/dist/workflows/runtime.js.map +1 -1
  456. package/dist/workflows/trigger-from-envelope.d.ts +13 -0
  457. package/dist/workflows/trigger-from-envelope.d.ts.map +1 -0
  458. package/dist/workflows/trigger-from-envelope.js +67 -0
  459. package/dist/workflows/trigger-from-envelope.js.map +1 -0
  460. package/dist/workflows/wait.d.ts +23 -2
  461. package/dist/workflows/wait.d.ts.map +1 -1
  462. package/dist/workflows/wait.js +39 -17
  463. package/dist/workflows/wait.js.map +1 -1
  464. package/package.json +1 -1
  465. package/dist/services/feishu-task-client.d.ts +0 -28
  466. package/dist/services/feishu-task-client.d.ts.map +0 -1
  467. package/dist/services/feishu-task-client.js +0 -123
  468. package/dist/services/feishu-task-client.js.map +0 -1
  469. package/dist/services/task-store.d.ts +0 -37
  470. package/dist/services/task-store.d.ts.map +0 -1
  471. package/dist/services/task-store.js +0 -115
  472. package/dist/services/task-store.js.map +0 -1
package/dist/worker.js CHANGED
@@ -22,6 +22,7 @@ import { shouldRunQuietRotation, evaluatePidResolverPullback, decideFingerprintS
22
22
  import { CodexBridgeQueue } from './services/codex-bridge-queue.js';
23
23
  import { drainCodexRollout, findCodexRolloutBySessionId, findCodexRolloutByPid, splitCodexEventsByCutoff, extractLastCodexTurn } from './services/codex-transcript.js';
24
24
  import { cocoEventsPathForSession, drainCocoEvents, findCocoSessionByPid } from './services/coco-transcript.js';
25
+ import { currentHermesStateOffset, drainHermesStateDb } from './services/hermes-transcript.js';
25
26
  import { baselineJsonlCursor } from './services/jsonl-cursor.js';
26
27
  import { dirname } from 'node:path';
27
28
  import { createServer as createHttpServer } from 'node:http';
@@ -63,7 +64,7 @@ const clientPtys = new Map();
63
64
  const writeToken = randomBytes(16).toString('hex');
64
65
  let sessionId = '';
65
66
  let lastInitConfig = null;
66
- const CLI_DISPLAY_NAMES = { 'claude-code': 'Claude', aiden: 'Aiden', coco: 'CoCo', codex: 'Codex', cursor: 'Cursor', gemini: 'Gemini', opencode: 'OpenCode', antigravity: 'Antigravity' };
67
+ const CLI_DISPLAY_NAMES = { 'claude-code': 'Claude', aiden: 'Aiden', coco: 'CoCo', codex: 'Codex', 'codex-app': 'Codex App', cursor: 'Cursor', gemini: 'Gemini', opencode: 'OpenCode', antigravity: 'Antigravity', mtr: 'MTR', hermes: 'Hermes', mira: 'Mira' };
67
68
  function cliName() { return CLI_DISPLAY_NAMES[lastInitConfig?.cliId ?? ''] ?? 'CLI'; }
68
69
  let isPromptReady = false;
69
70
  /** Mutex for async flushPending — prevents concurrent flush loops. */
@@ -199,6 +200,8 @@ let codexBridgeBaselineDone = false;
199
200
  const codexBridgeQueue = new CodexBridgeQueue();
200
201
  let codexBridgeWatcher = null;
201
202
  let codexBridgeTimer = null;
203
+ let hermesBridgeOffset = 0;
204
+ let hermesBridgeBaselineDone = false;
202
205
  /** Codex sessionId we received via writeInput but haven't yet resolved a
203
206
  * rollout file for. The poller keeps retrying — the file appears on
204
207
  * Codex's first user submit, but with some race delay after our submit
@@ -262,6 +265,11 @@ function formatHeadlessLocalTurnContent(assistantText) {
262
265
  // needed. Append-only over a shared file (instead of a per-turn marker) is
263
266
  // type-ahead safe: type-ahead'd turns each have their own [markTimeMs,
264
267
  // nextTurn.markTimeMs) window, and a stray send only fills its own bucket.
268
+ // This relies on each turn's markTimeMs reflecting when it ACTUALLY started
269
+ // processing, not when the worker marked it — the structured queue overrides
270
+ // markTimeMs to the dequeue-time transcript event (CodexBridgeQueue.ingest)
271
+ // and emitReadyCodexTurns only treats a STARTED next turn as a boundary, so
272
+ // the early back-to-back marks type-ahead produces don't collapse the windows.
265
273
  function bridgeMarkerPath() {
266
274
  if (!process.env.SESSION_DATA_DIR || !sessionId)
267
275
  return undefined;
@@ -1323,18 +1331,23 @@ function drainPathInto(path, fromOffset) {
1323
1331
  // shared with the Claude path.
1324
1332
  function codexBridgeFallbackActive() {
1325
1333
  // True for transcript-backed CLIs whose final output can be harvested
1326
- // from append-only JSONL when the model forgets to call `botmux send`.
1327
- // Codex uses ~/.codex rollouts; CoCo uses ~/.cache/coco events. Both
1328
- // work in adopt mode now that CoCo's PID→sessionId discovery is wired.
1329
- return lastInitConfig?.cliId === 'codex' || lastInitConfig?.cliId === 'coco';
1334
+ // when the model forgets to call `botmux send`.
1335
+ return lastInitConfig?.cliId === 'codex' || lastInitConfig?.cliId === 'coco' || lastInitConfig?.cliId === 'hermes';
1330
1336
  }
1331
1337
  function structuredBridgeIsCodex() {
1332
1338
  return lastInitConfig?.cliId === 'codex';
1333
1339
  }
1340
+ function structuredBridgeIsHermes() {
1341
+ return lastInitConfig?.cliId === 'hermes';
1342
+ }
1334
1343
  function structuredBridgeIngestPath(path, offset) {
1335
- return structuredBridgeIsCodex()
1336
- ? drainCodexRollout(path, offset)
1337
- : drainCocoEvents(path, offset);
1344
+ if (structuredBridgeIsCodex())
1345
+ return drainCodexRollout(path, offset);
1346
+ if (structuredBridgeIsHermes()) {
1347
+ const result = drainHermesStateDb(offset);
1348
+ return { events: result.events, newOffset: result.newOffset, pendingTail: '' };
1349
+ }
1350
+ return drainCocoEvents(path, offset);
1338
1351
  }
1339
1352
  function codexBridgeStartTimer() {
1340
1353
  if (codexBridgeTimer)
@@ -1352,6 +1365,14 @@ function codexBridgeStartTimer() {
1352
1365
  // publish a half-streamed response.
1353
1366
  codexBridgeTimer = setInterval(() => {
1354
1367
  try {
1368
+ if (structuredBridgeIsHermes()) {
1369
+ if (!hermesBridgeBaselineDone)
1370
+ hermesBridgeAttach(lastInitConfig?.resume ? 'baseline-existing' : 'fresh-empty');
1371
+ hermesBridgeIngest();
1372
+ if (isPromptReady)
1373
+ emitReadyCodexTurns();
1374
+ return;
1375
+ }
1355
1376
  if (!codexBridgeRolloutPath) {
1356
1377
  // Two discovery paths, in order: cliSessionId (known via writeInput
1357
1378
  // result for non-adopt or daemon-side probe for adopt) → exact
@@ -1405,6 +1426,22 @@ function codexBridgeStartTimer() {
1405
1426
  }
1406
1427
  }, 1000);
1407
1428
  }
1429
+ function hermesBridgeAttach(mode) {
1430
+ hermesBridgeOffset = currentHermesStateOffset();
1431
+ hermesBridgeBaselineDone = true;
1432
+ log(`Hermes bridge ${mode}: state.db offset=${hermesBridgeOffset}`);
1433
+ codexBridgeStartTimer();
1434
+ }
1435
+ function hermesBridgeIngest() {
1436
+ if (!hermesBridgeBaselineDone)
1437
+ return;
1438
+ const result = drainHermesStateDb(hermesBridgeOffset);
1439
+ hermesBridgeOffset = result.newOffset;
1440
+ codexBridgeQueue.ingest(result.events);
1441
+ if (result.events.some(e => e.kind === 'assistant_final')) {
1442
+ idleDetector?.fireIdle();
1443
+ }
1444
+ }
1408
1445
  function codexBridgeAttach(rolloutPath, mode) {
1409
1446
  codexBridgeRolloutPath = rolloutPath;
1410
1447
  if (mode === 'fresh-empty') {
@@ -1499,6 +1536,10 @@ function codexBridgeNotifyCliSessionId(cliSessionId) {
1499
1536
  }
1500
1537
  }
1501
1538
  function codexBridgeIngest() {
1539
+ if (structuredBridgeIsHermes()) {
1540
+ hermesBridgeIngest();
1541
+ return;
1542
+ }
1502
1543
  if (!codexBridgeRolloutPath || !codexBridgeBaselineDone)
1503
1544
  return;
1504
1545
  const result = structuredBridgeIngestPath(codexBridgeRolloutPath, codexBridgeOffset);
@@ -1528,7 +1569,7 @@ function codexBridgeMarkPendingTurn(messageText) {
1528
1569
  function codexBridgeDrainAndMaybeEmit() {
1529
1570
  if (!codexBridgeFallbackActive())
1530
1571
  return;
1531
- if (codexBridgeRolloutPath && codexBridgeBaselineDone) {
1572
+ if (structuredBridgeIsHermes() || (codexBridgeRolloutPath && codexBridgeBaselineDone)) {
1532
1573
  try {
1533
1574
  codexBridgeIngest();
1534
1575
  }
@@ -1548,7 +1589,17 @@ function emitReadyCodexTurns() {
1548
1589
  // should reach the thread. Skip marker IO entirely.
1549
1590
  const markers = adoptMode ? [] : readSendMarkers();
1550
1591
  const remaining = codexBridgeQueue.peek();
1551
- const nextPendingMarkTimeMs = remaining.length > 0 ? remaining[0].markTimeMs : undefined;
1592
+ // Only a STARTED pending turn can bound the last ready turn's send window.
1593
+ // An unstarted turn hasn't been dequeued yet (its user event hasn't landed),
1594
+ // so it has produced no sends to leak backwards — and under type-ahead its
1595
+ // markTimeMs is still the early flush-time mark, which would prematurely
1596
+ // (often invalidly, lower>upper) close the ready turn's window and let its
1597
+ // own send escape suppression → duplicate. A started-but-not-final turn
1598
+ // (model mid-tool-use for N+1) keeps its real overridden markTimeMs as the
1599
+ // boundary, preserving the original leak guard.
1600
+ const nextPendingMarkTimeMs = remaining.length > 0 && remaining[0].started
1601
+ ? remaining[0].markTimeMs
1602
+ : undefined;
1552
1603
  for (let i = 0; i < ready.length; i++) {
1553
1604
  const turn = ready[i];
1554
1605
  if (!turn.finalText)
@@ -1595,6 +1646,8 @@ function stopCodexBridge() {
1595
1646
  codexBridgeOffset = 0;
1596
1647
  codexBridgePendingTail = '';
1597
1648
  codexBridgeBaselineDone = false;
1649
+ hermesBridgeOffset = 0;
1650
+ hermesBridgeBaselineDone = false;
1598
1651
  codexBridgeQueue.clearPending();
1599
1652
  codexBridgeQueue.setLocalTurns(false);
1600
1653
  codexBridgePendingSessionId = undefined;
@@ -2126,8 +2179,88 @@ async function handleTuiTextInput(keys, text) {
2126
2179
  // in a single PTY chunk)
2127
2180
  const TRUST_DIALOG_PATTERN = /Yes, I trust this folder|Yes, continue/;
2128
2181
  let trustHandled = false;
2182
+ // Codex App runner sends botmux control messages as OSC sequences so they do
2183
+ // not pollute the visible terminal. Strip them before xterm rendering and
2184
+ // translate them back into worker IPC.
2185
+ const CODEX_APP_OSC_PREFIX = '\x1b]777;botmux:';
2186
+ const APP_RUNNER_OSC_CLI_IDS = new Set(['codex-app', 'mira']);
2187
+ let codexAppOscPending = '';
2188
+ function decodeCodexAppPayload(payload) {
2189
+ try {
2190
+ return JSON.parse(Buffer.from(payload, 'base64').toString('utf8'));
2191
+ }
2192
+ catch {
2193
+ return undefined;
2194
+ }
2195
+ }
2196
+ function handleCodexAppMarker(body) {
2197
+ const sep = body.indexOf(':');
2198
+ if (sep < 0)
2199
+ return;
2200
+ const kind = body.slice(0, sep);
2201
+ const payload = decodeCodexAppPayload(body.slice(sep + 1));
2202
+ if (!payload || typeof payload !== 'object')
2203
+ return;
2204
+ if (kind === 'thread' && typeof payload.threadId === 'string') {
2205
+ persistCliSessionId(payload.threadId);
2206
+ return;
2207
+ }
2208
+ if (kind === 'final' && typeof payload.content === 'string') {
2209
+ const startedAtMs = typeof payload.startedAtMs === 'number' ? payload.startedAtMs : undefined;
2210
+ const completedAtMs = typeof payload.completedAtMs === 'number' ? payload.completedAtMs : Date.now();
2211
+ if (startedAtMs !== undefined) {
2212
+ const sentByModel = readSendMarkers().some(m => m.sentAtMs >= startedAtMs && m.sentAtMs <= completedAtMs + 5_000);
2213
+ if (sentByModel) {
2214
+ log(`${cliName()} final_output suppressed (model already called botmux send)`);
2215
+ return;
2216
+ }
2217
+ }
2218
+ const turnId = typeof payload.turnId === 'string' ? payload.turnId : `${lastInitConfig?.cliId ?? 'app'}-${Date.now()}`;
2219
+ send({
2220
+ type: 'final_output',
2221
+ content: payload.content,
2222
+ lastUuid: turnId,
2223
+ turnId,
2224
+ });
2225
+ }
2226
+ }
2227
+ function splitCodexAppControl(data) {
2228
+ if (!APP_RUNNER_OSC_CLI_IDS.has(lastInitConfig?.cliId ?? '') && codexAppOscPending.length === 0)
2229
+ return data;
2230
+ const input = codexAppOscPending + data;
2231
+ codexAppOscPending = '';
2232
+ let out = '';
2233
+ let cursor = 0;
2234
+ for (;;) {
2235
+ const start = input.indexOf(CODEX_APP_OSC_PREFIX, cursor);
2236
+ if (start < 0) {
2237
+ let tailStart = input.length;
2238
+ const tail = input.slice(cursor);
2239
+ for (let n = Math.min(CODEX_APP_OSC_PREFIX.length - 1, tail.length); n > 0; n--) {
2240
+ if (CODEX_APP_OSC_PREFIX.startsWith(tail.slice(tail.length - n))) {
2241
+ tailStart = input.length - n;
2242
+ break;
2243
+ }
2244
+ }
2245
+ out += input.slice(cursor, tailStart);
2246
+ codexAppOscPending = input.slice(tailStart);
2247
+ return out;
2248
+ }
2249
+ out += input.slice(cursor, start);
2250
+ const end = input.indexOf('\x07', start + CODEX_APP_OSC_PREFIX.length);
2251
+ if (end < 0) {
2252
+ codexAppOscPending = input.slice(start);
2253
+ return out;
2254
+ }
2255
+ handleCodexAppMarker(input.slice(start + CODEX_APP_OSC_PREFIX.length, end));
2256
+ cursor = end + 1;
2257
+ }
2258
+ }
2129
2259
  // ─── Prompt Detection ────────────────────────────────────────────────────────
2130
2260
  function onPtyData(data) {
2261
+ data = splitCodexAppControl(data);
2262
+ if (data.length === 0)
2263
+ return;
2131
2264
  captureWorkflowTranscript(data);
2132
2265
  renderer?.write(data);
2133
2266
  // In tmux-attach mode, each web client has its own tmux attach PTY —
@@ -2313,10 +2446,23 @@ async function flushPending() {
2313
2446
  // Lark message. Now that the queue handles queued_command identically to
2314
2447
  // role:user (and overrides markTimeMs to the dequeue-time event timestamp
2315
2448
  // so the gate window is correct), Claude bridge can run with type-ahead
2316
- // again. Codex bridge stays serial because its queue hasn't been upgraded.
2449
+ // again.
2450
+ //
2451
+ // CoCo (0.120.32+) also tolerates type-ahead, but for a different reason
2452
+ // than Claude: it parks a submit-while-busy message in its own TUI queue
2453
+ // ("↑ Press up to edit queued messages") and only writes the user event to
2454
+ // events.jsonl when it DEQUEUES and starts processing it — i.e. AFTER the
2455
+ // previous turn's assistant_final. So the transcript stays strictly
2456
+ // interleaved (user1 → asst1 → user2 → asst2) and CodexBridgeQueue's
2457
+ // single-`collecting` attribution stays correct without the queued_command
2458
+ // upgrade Claude needed. (The submit log history.jsonl, which the adapter's
2459
+ // writeInput verification polls, IS written at submit time even for a queued
2460
+ // message, so verification doesn't spuriously fail either.) Only the Codex
2461
+ // rollout bridge stays serial — its queue hasn't been validated for the
2462
+ // back-to-back user_message ordering that type-ahead can produce there.
2317
2463
  const claudeBridgeActive = !!bridgeJsonlPath && !lastInitConfig?.adoptMode;
2318
2464
  const codexBridgeActive = codexBridgeFallbackActive();
2319
- const typeAheadAllowed = cliAdapter.supportsTypeAhead && !codexBridgeActive;
2465
+ const typeAheadAllowed = cliAdapter.supportsTypeAhead && !structuredBridgeIsCodex();
2320
2466
  if (!isPromptReady && !typeAheadAllowed)
2321
2467
  return;
2322
2468
  isFlushing = true;
@@ -2389,16 +2535,18 @@ async function flushPending() {
2389
2535
  if (result && result.submitted === false && backend) {
2390
2536
  scheduleSubmitFailureNotify(msg, result.recheck, '会话 JSONL', bridgeTurnId, result.failureReason, turnSeq);
2391
2537
  }
2392
- // Codex bridge: stop after one writeInput per idle cycle. Codex's
2393
- // bridge queue doesn't yet attribute queued_command-equivalents, so
2394
- // type-ahead'd submits would have their assistant text dropped or
2538
+ // Codex rollout bridge: stop after one writeInput per idle cycle.
2539
+ // Codex's bridge queue doesn't yet attribute queued_command-equivalents,
2540
+ // so type-ahead'd submits would have their assistant text dropped or
2395
2541
  // mis-attributed. We resume on the next idle, by which point Codex
2396
2542
  // has finished and the next message can be a normal user_message
2397
- // submit. Claude bridge no longer takes this break — its
2543
+ // submit. Claude bridge and CoCo no longer take this break — Claude's
2398
2544
  // BridgeTurnQueue handles `attachment(queued_command)` events
2399
- // identically to `role:user`, so type-ahead'd turns are correctly
2400
- // attributed and no longer need the serial-per-idle guard.
2401
- if (codexBridgeActive && pendingMessages.length > 0)
2545
+ // identically to `role:user`, and CoCo parks queued submits in its own
2546
+ // TUI queue (writing the events.jsonl user event only at dequeue time),
2547
+ // so both keep the transcript interleaved and attribute correctly. We
2548
+ // WANT CoCo to drain all pending here so they land in its TUI queue.
2549
+ if (structuredBridgeIsCodex() && pendingMessages.length > 0)
2402
2550
  break;
2403
2551
  }
2404
2552
  }
@@ -2423,12 +2571,12 @@ function sendToPty(content) {
2423
2571
  // Tear down the prompt card so the user doesn't see stale options.
2424
2572
  send({ type: 'tui_prompt_resolved', selectedText: 'user-override' });
2425
2573
  }
2426
- // See flushPending: only Codex bridge still serialises type-ahead.
2427
- // Claude bridge now attributes `attachment(queued_command)` events
2428
- // identically to `role:user`, so type-ahead'd submits land in the right
2429
- // turn and we no longer need to gate the entry path on claudeBridgeActive.
2430
- const codexBridgeActive = codexBridgeFallbackActive();
2431
- const typeAheadAllowed = cliAdapter.supportsTypeAhead && !codexBridgeActive;
2574
+ // See flushPending: only the Codex rollout bridge still serialises
2575
+ // type-ahead. Claude attributes `attachment(queued_command)` events
2576
+ // identically to `role:user`, and CoCo parks queued submits in its own TUI
2577
+ // queue, so both land type-ahead'd submits in the right turn only Codex
2578
+ // needs the entry path gated.
2579
+ const typeAheadAllowed = cliAdapter.supportsTypeAhead && !structuredBridgeIsCodex();
2432
2580
  if (isPromptReady || isFlushing || typeAheadAllowed) {
2433
2581
  log(`Writing to PTY: "${content.substring(0, 80)}"`);
2434
2582
  flushPending(); // fire-and-forget async; no-op if already flushing
@@ -2709,6 +2857,7 @@ function spawnCli(cfg) {
2709
2857
  botName: cfg.botName,
2710
2858
  botOpenId: cfg.botOpenId,
2711
2859
  locale: cfg.locale,
2860
+ model: cfg.model,
2712
2861
  });
2713
2862
  // Extra args from env (CLI_DISABLE_DEFAULT_ARGS is removed — adapters own their defaults)
2714
2863
  const extra = (process.env.CLI_EXTRA_ARGS ?? '').trim();
@@ -2723,6 +2872,15 @@ function spawnCli(cfg) {
2723
2872
  if (injectClaudeSandbox) {
2724
2873
  log('Detected root user — injecting IS_SANDBOX=1 for Claude Code');
2725
2874
  }
2875
+ // Claude Code 2.1.x:`--resume` 一个「空闲 >70min 且累计 >10 万 token」的会话会弹
2876
+ // 交互式菜单(Resume from summary / full / Don't ask again),botmux 无法导航 →
2877
+ // 进程卡死(issue #62)。把 token 阈值顶到极大让触发门永远命中 `tokens < threshold`
2878
+ // 而 return null → 菜单不弹、按 full session 原样续(走 summary 会触发 /compact,
2879
+ // 破坏 bridge 的会话连续性追踪)。用户显式设了就尊重。注意:该 key 必须同时进
2880
+ // BOTMUX_INJECTED_ENV_KEYS 白名单,否则 tmux backend 不会把它透传进 pane。
2881
+ const claudeResumeTokenThreshold = cfg.cliId === 'claude-code'
2882
+ ? process.env.CLAUDE_CODE_RESUME_TOKEN_THRESHOLD ?? '2147483647'
2883
+ : undefined;
2726
2884
  // Predict reattach vs fresh so the log line tells the truth. When a bmx-*
2727
2885
  // tmux session is still alive, TmuxBackend.spawn ignores the bin/args and
2728
2886
  // just `tmux attach-session`s — logging `Spawning: <new bin>` in that case
@@ -2742,7 +2900,15 @@ function spawnCli(cfg) {
2742
2900
  env: {
2743
2901
  ...process.env,
2744
2902
  CLAUDECODE: undefined,
2903
+ // §5 of botmux ask v0.1.7 — `botmux ask buttons` reads these to find
2904
+ // the daemon socket, route the card back to this thread, and resolve
2905
+ // the approver allowlist against session.owner. Missing env → exit 2.
2906
+ BOTMUX_SESSION_ID: cfg.sessionId,
2907
+ BOTMUX_CHAT_ID: cfg.chatId,
2908
+ BOTMUX_LARK_APP_ID: cfg.larkAppId,
2909
+ BOTMUX_ROOT_MESSAGE_ID: cfg.rootMessageId,
2745
2910
  ...(injectClaudeSandbox ? { IS_SANDBOX: '1' } : {}),
2911
+ ...(claudeResumeTokenThreshold ? { CLAUDE_CODE_RESUME_TOKEN_THRESHOLD: claudeResumeTokenThreshold } : {}),
2746
2912
  },
2747
2913
  });
2748
2914
  // Write CLI PID marker so agent-facing subcommands (`botmux send`, etc.)
@@ -2797,8 +2963,12 @@ function spawnCli(cfg) {
2797
2963
  // calling `botmux send`, harvest the final answer from the CLI transcript
2798
2964
  // and post it to Lark. Codex needs late attach because its rollout id is
2799
2965
  // discovered after the first submit; CoCo's events path is deterministic
2800
- // from botmux sessionId.
2801
- if (cfg.cliId === 'codex') {
2966
+ // from botmux sessionId. Hermes uses a global SQLite store, so baseline its
2967
+ // row id at spawn and poll for rows after each queued prompt is flushed.
2968
+ if (cfg.cliId === 'hermes') {
2969
+ hermesBridgeAttach(cfg.resume ? 'baseline-existing' : 'fresh-empty');
2970
+ }
2971
+ else if (cfg.cliId === 'codex') {
2802
2972
  if (cfg.cliSessionId) {
2803
2973
  const rolloutPath = findCodexRolloutBySessionId(cfg.cliSessionId);
2804
2974
  if (rolloutPath) {
@@ -2900,6 +3070,7 @@ function killCli() {
2900
3070
  scrollback = '';
2901
3071
  altBufferActive = false;
2902
3072
  trustHandled = false;
3073
+ codexAppOscPending = '';
2903
3074
  }
2904
3075
  // ─── HTTP + WebSocket Server ─────────────────────────────────────────────────
2905
3076
  function startWebServer(host, preferredPort) {
@@ -3077,6 +3248,10 @@ body{display:flex;flex-direction:column}
3077
3248
  #toolbar button:active{background:#7aa2f7;color:#1a1b26}
3078
3249
  #terminal{flex:1;min-height:0}
3079
3250
  #terminal .xterm{height:100%}
3251
+ /* Real scroll container is xterm's own viewport — kill iOS rubber-band bounce
3252
+ and momentum here (not just on body), and reserve gestures for pinch-zoom so
3253
+ single-finger drag is driven manually by the touch handler below. */
3254
+ #terminal .xterm-viewport{overscroll-behavior:none;-webkit-overflow-scrolling:auto;touch-action:pinch-zoom}
3080
3255
  #status{position:fixed;top:8px;right:12px;z-index:10;font:12px monospace;
3081
3256
  color:#565f89;background:#1a1b26cc;padding:2px 8px;border-radius:4px}
3082
3257
  #status.ok{color:#9ece6a}
@@ -3106,7 +3281,6 @@ body{display:flex;flex-direction:column}
3106
3281
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0/lib/addon-fit.min.js"></script>
3107
3282
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0/lib/addon-web-links.min.js"></script>
3108
3283
  <script src="https://cdn.jsdelivr.net/npm/@xterm/addon-unicode11@0/lib/addon-unicode11.min.js"></script>
3109
- <script src="https://cdn.jsdelivr.net/npm/hammerjs@2.0.8/hammer.min.js"></script>
3110
3284
  <script>
3111
3285
  var isTouch='ontouchstart'in window||navigator.maxTouchPoints>0;
3112
3286
  if(isTouch)document.getElementById('vp').content='width=1100,viewport-fit=cover';
@@ -3234,29 +3408,37 @@ if(isTouch&&hasToken){
3234
3408
  }
3235
3409
  }
3236
3410
 
3237
- // ── Two-finger touch scroll via Hammer.js (mobile) ──
3238
- // Hammer distinguishes Pan (parallel drag) from Pinch (spread/squeeze)
3239
- // internally. Pan with pointers:2 only fires for genuine two-finger scroll.
3240
- if(isTouch&&typeof Hammer!=='undefined'){
3241
- var mc=new Hammer.Manager(document.getElementById('terminal'),{touchAction:'auto',inputClass:Hammer.TouchInput});
3242
- var pinch=new Hammer.Pinch();
3243
- var pan=new Hammer.Pan({pointers:2,direction:Hammer.DIRECTION_VERTICAL,threshold:4});
3244
- pinch.recognizeWith(pan);
3245
- mc.add([pinch,pan]);
3246
- var _panPrevY=0,_panAcc=0;
3247
- mc.on('panstart',function(ev){_panPrevY=ev.center.y;_panAcc=0});
3248
- mc.on('panmove',function(ev){
3249
- var d=ev.center.y-_panPrevY;
3250
- _panPrevY=ev.center.y;
3251
- // Accumulate sub-pixel deltas; fire 1 wheel event per ~85px
3252
- // (tmux scrolls ~5 lines per wheel, line height ~17px)
3253
- _panAcc+=d;
3254
- var step=85;
3255
- while(Math.abs(_panAcc)>=step){
3256
- _sendScroll(_panAcc>0,1);
3257
- _panAcc-=(_panAcc>0?step:-step);
3258
- }
3259
- });
3411
+ // ── Single-finger touch scroll (mobile) ──
3412
+ // One finger dragging scrolls the terminal, following the finger 1:1 with no
3413
+ // elastic bounce or momentum jank. Two+ fingers are left to the browser so
3414
+ // pinch-zoom still works for reading small text.
3415
+ // • pipe / non-tmux: drive .xterm-viewport.scrollTop directly → pixel-smooth.
3416
+ // • legacy tmux copy-mode (scrollback lives in tmux, not xterm): translate
3417
+ // the drag into wheel sequences via _sendScroll, accumulating per line.
3418
+ if(isTouch){
3419
+ var _tmuxScroll=${isTmuxMode && !isPipeMode};
3420
+ var _vp=document.querySelector('#terminal .xterm-viewport');
3421
+ var _tEl=document.getElementById('terminal');
3422
+ var _tLastY=0,_tActive=false,_tAcc=0;
3423
+ _tEl.addEventListener('touchstart',function(e){
3424
+ if(e.touches.length!==1){_tActive=false;return;} // multi-touch → let browser pinch-zoom
3425
+ _tActive=true;_tLastY=e.touches[0].clientY;_tAcc=0;
3426
+ },{passive:true});
3427
+ _tEl.addEventListener('touchmove',function(e){
3428
+ if(!_tActive||e.touches.length!==1)return;
3429
+ var y=e.touches[0].clientY,dy=y-_tLastY;_tLastY=y;
3430
+ if(_tmuxScroll){
3431
+ _tAcc+=dy;var step=22; // ~1.3 lines per wheel-equiv; smaller = smoother
3432
+ while(Math.abs(_tAcc)>=step){_sendScroll(_tAcc>0,1);_tAcc-=(_tAcc>0?step:-step);}
3433
+ }else if(_vp){
3434
+ _vp.scrollTop-=dy; // drag down → reveal older content; scrollTop clamps, no bounce
3435
+ }else{
3436
+ term.scrollLines(dy>0?-1:1);
3437
+ }
3438
+ e.preventDefault(); // hard-kill native scroll/bounce/momentum
3439
+ },{passive:false});
3440
+ _tEl.addEventListener('touchend',function(){_tActive=false});
3441
+ _tEl.addEventListener('touchcancel',function(){_tActive=false});
3260
3442
  }
3261
3443
  </script>
3262
3444
  </body>