botmux 2.9.1 → 2.9.3

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 (330) hide show
  1. package/README.en.md +140 -76
  2. package/README.md +134 -75
  3. package/dist/adapters/backend/pty-backend.d.ts +6 -0
  4. package/dist/adapters/backend/pty-backend.d.ts.map +1 -1
  5. package/dist/adapters/backend/pty-backend.js +10 -0
  6. package/dist/adapters/backend/pty-backend.js.map +1 -1
  7. package/dist/adapters/backend/session-backend-selector.d.ts +11 -0
  8. package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -0
  9. package/dist/adapters/backend/session-backend-selector.js +26 -0
  10. package/dist/adapters/backend/session-backend-selector.js.map +1 -0
  11. package/dist/adapters/backend/tmux-backend.d.ts +80 -3
  12. package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
  13. package/dist/adapters/backend/tmux-backend.js +301 -49
  14. package/dist/adapters/backend/tmux-backend.js.map +1 -1
  15. package/dist/adapters/backend/tmux-pipe-backend.d.ts +100 -0
  16. package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -0
  17. package/dist/adapters/backend/tmux-pipe-backend.js +473 -0
  18. package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -0
  19. package/dist/adapters/cli/aiden.d.ts.map +1 -1
  20. package/dist/adapters/cli/aiden.js +5 -0
  21. package/dist/adapters/cli/aiden.js.map +1 -1
  22. package/dist/adapters/cli/claude-code.d.ts +40 -1
  23. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  24. package/dist/adapters/cli/claude-code.js +470 -49
  25. package/dist/adapters/cli/claude-code.js.map +1 -1
  26. package/dist/adapters/cli/coco.d.ts.map +1 -1
  27. package/dist/adapters/cli/coco.js +191 -9
  28. package/dist/adapters/cli/coco.js.map +1 -1
  29. package/dist/adapters/cli/codex.d.ts.map +1 -1
  30. package/dist/adapters/cli/codex.js +94 -17
  31. package/dist/adapters/cli/codex.js.map +1 -1
  32. package/dist/adapters/cli/shared-hints.d.ts +2 -2
  33. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  34. package/dist/adapters/cli/shared-hints.js +7 -5
  35. package/dist/adapters/cli/shared-hints.js.map +1 -1
  36. package/dist/adapters/cli/types.d.ts +38 -1
  37. package/dist/adapters/cli/types.d.ts.map +1 -1
  38. package/dist/autostart.d.ts +14 -0
  39. package/dist/autostart.d.ts.map +1 -0
  40. package/dist/autostart.js +357 -0
  41. package/dist/autostart.js.map +1 -0
  42. package/dist/bot-registry.d.ts +29 -3
  43. package/dist/bot-registry.d.ts.map +1 -1
  44. package/dist/bot-registry.js +91 -12
  45. package/dist/bot-registry.js.map +1 -1
  46. package/dist/cli/arg-utils.d.ts +11 -0
  47. package/dist/cli/arg-utils.d.ts.map +1 -0
  48. package/dist/cli/arg-utils.js +25 -0
  49. package/dist/cli/arg-utils.js.map +1 -0
  50. package/dist/cli/create-group-resolver.d.ts +32 -0
  51. package/dist/cli/create-group-resolver.d.ts.map +1 -0
  52. package/dist/cli/create-group-resolver.js +70 -0
  53. package/dist/cli/create-group-resolver.js.map +1 -0
  54. package/dist/cli/quoted-render.d.ts +30 -0
  55. package/dist/cli/quoted-render.d.ts.map +1 -0
  56. package/dist/cli/quoted-render.js +29 -0
  57. package/dist/cli/quoted-render.js.map +1 -0
  58. package/dist/cli.js +916 -272
  59. package/dist/cli.js.map +1 -1
  60. package/dist/config.d.ts +6 -0
  61. package/dist/config.d.ts.map +1 -1
  62. package/dist/config.js +18 -8
  63. package/dist/config.js.map +1 -1
  64. package/dist/core/command-handler.d.ts +43 -0
  65. package/dist/core/command-handler.d.ts.map +1 -1
  66. package/dist/core/command-handler.js +167 -64
  67. package/dist/core/command-handler.js.map +1 -1
  68. package/dist/core/dashboard-events.d.ts +57 -0
  69. package/dist/core/dashboard-events.d.ts.map +1 -0
  70. package/dist/core/dashboard-events.js +23 -0
  71. package/dist/core/dashboard-events.js.map +1 -0
  72. package/dist/core/dashboard-ipc-server.d.ts +43 -0
  73. package/dist/core/dashboard-ipc-server.d.ts.map +1 -0
  74. package/dist/core/dashboard-ipc-server.js +481 -0
  75. package/dist/core/dashboard-ipc-server.js.map +1 -0
  76. package/dist/core/dashboard-locate.d.ts +20 -0
  77. package/dist/core/dashboard-locate.d.ts.map +1 -0
  78. package/dist/core/dashboard-locate.js +26 -0
  79. package/dist/core/dashboard-locate.js.map +1 -0
  80. package/dist/core/dashboard-rows.d.ts +31 -0
  81. package/dist/core/dashboard-rows.d.ts.map +1 -0
  82. package/dist/core/dashboard-rows.js +65 -0
  83. package/dist/core/dashboard-rows.js.map +1 -0
  84. package/dist/core/inherit-peer.d.ts +14 -0
  85. package/dist/core/inherit-peer.d.ts.map +1 -0
  86. package/dist/core/inherit-peer.js +32 -0
  87. package/dist/core/inherit-peer.js.map +1 -0
  88. package/dist/core/scheduler.d.ts +24 -0
  89. package/dist/core/scheduler.d.ts.map +1 -1
  90. package/dist/core/scheduler.js +93 -2
  91. package/dist/core/scheduler.js.map +1 -1
  92. package/dist/core/session-activity.d.ts +3 -0
  93. package/dist/core/session-activity.d.ts.map +1 -0
  94. package/dist/core/session-activity.js +20 -0
  95. package/dist/core/session-activity.js.map +1 -0
  96. package/dist/core/session-discovery.d.ts +39 -0
  97. package/dist/core/session-discovery.d.ts.map +1 -1
  98. package/dist/core/session-discovery.js +114 -21
  99. package/dist/core/session-discovery.js.map +1 -1
  100. package/dist/core/session-manager.d.ts +72 -0
  101. package/dist/core/session-manager.d.ts.map +1 -1
  102. package/dist/core/session-manager.js +396 -106
  103. package/dist/core/session-manager.js.map +1 -1
  104. package/dist/core/types.d.ts +27 -2
  105. package/dist/core/types.d.ts.map +1 -1
  106. package/dist/core/types.js +14 -3
  107. package/dist/core/types.js.map +1 -1
  108. package/dist/core/worker-pool.d.ts +72 -3
  109. package/dist/core/worker-pool.d.ts.map +1 -1
  110. package/dist/core/worker-pool.js +459 -38
  111. package/dist/core/worker-pool.js.map +1 -1
  112. package/dist/daemon.d.ts.map +1 -1
  113. package/dist/daemon.js +645 -314
  114. package/dist/daemon.js.map +1 -1
  115. package/dist/dashboard/aggregator.d.ts +41 -0
  116. package/dist/dashboard/aggregator.d.ts.map +1 -0
  117. package/dist/dashboard/aggregator.js +125 -0
  118. package/dist/dashboard/aggregator.js.map +1 -0
  119. package/dist/dashboard/auth.d.ts +23 -0
  120. package/dist/dashboard/auth.d.ts.map +1 -0
  121. package/dist/dashboard/auth.js +66 -0
  122. package/dist/dashboard/auth.js.map +1 -0
  123. package/dist/dashboard/operator-selector.d.ts +20 -0
  124. package/dist/dashboard/operator-selector.d.ts.map +1 -0
  125. package/dist/dashboard/operator-selector.js +39 -0
  126. package/dist/dashboard/operator-selector.js.map +1 -0
  127. package/dist/dashboard/registry.d.ts +35 -0
  128. package/dist/dashboard/registry.d.ts.map +1 -0
  129. package/dist/dashboard/registry.js +74 -0
  130. package/dist/dashboard/registry.js.map +1 -0
  131. package/dist/dashboard/web/app.d.ts +2 -0
  132. package/dist/dashboard/web/app.d.ts.map +1 -0
  133. package/dist/dashboard/web/app.js +45 -0
  134. package/dist/dashboard/web/app.js.map +1 -0
  135. package/dist/dashboard/web/bot-defaults.d.ts +2 -0
  136. package/dist/dashboard/web/bot-defaults.d.ts.map +1 -0
  137. package/dist/dashboard/web/bot-defaults.js +201 -0
  138. package/dist/dashboard/web/bot-defaults.js.map +1 -0
  139. package/dist/dashboard/web/groups.d.ts +16 -0
  140. package/dist/dashboard/web/groups.d.ts.map +1 -0
  141. package/dist/dashboard/web/groups.js +584 -0
  142. package/dist/dashboard/web/groups.js.map +1 -0
  143. package/dist/dashboard/web/schedules.d.ts +2 -0
  144. package/dist/dashboard/web/schedules.d.ts.map +1 -0
  145. package/dist/dashboard/web/schedules.js +105 -0
  146. package/dist/dashboard/web/schedules.js.map +1 -0
  147. package/dist/dashboard/web/sessions.d.ts +2 -0
  148. package/dist/dashboard/web/sessions.d.ts.map +1 -0
  149. package/dist/dashboard/web/sessions.js +374 -0
  150. package/dist/dashboard/web/sessions.js.map +1 -0
  151. package/dist/dashboard/web/store.d.ts +23 -0
  152. package/dist/dashboard/web/store.d.ts.map +1 -0
  153. package/dist/dashboard/web/store.js +82 -0
  154. package/dist/dashboard/web/store.js.map +1 -0
  155. package/dist/dashboard-web/app.js +263 -0
  156. package/dist/dashboard-web/index.html +23 -0
  157. package/dist/dashboard-web/style.css +93 -0
  158. package/dist/dashboard.d.ts +2 -0
  159. package/dist/dashboard.d.ts.map +1 -0
  160. package/dist/dashboard.js +639 -0
  161. package/dist/dashboard.js.map +1 -0
  162. package/dist/im/lark/card-builder.d.ts +18 -1
  163. package/dist/im/lark/card-builder.d.ts.map +1 -1
  164. package/dist/im/lark/card-builder.js +70 -9
  165. package/dist/im/lark/card-builder.js.map +1 -1
  166. package/dist/im/lark/card-handler.d.ts.map +1 -1
  167. package/dist/im/lark/card-handler.js +123 -109
  168. package/dist/im/lark/card-handler.js.map +1 -1
  169. package/dist/im/lark/client.d.ts +35 -0
  170. package/dist/im/lark/client.d.ts.map +1 -1
  171. package/dist/im/lark/client.js +114 -11
  172. package/dist/im/lark/client.js.map +1 -1
  173. package/dist/im/lark/event-dispatcher.d.ts +88 -6
  174. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  175. package/dist/im/lark/event-dispatcher.js +398 -62
  176. package/dist/im/lark/event-dispatcher.js.map +1 -1
  177. package/dist/im/lark/forwarded-renderer.d.ts +23 -0
  178. package/dist/im/lark/forwarded-renderer.d.ts.map +1 -0
  179. package/dist/im/lark/forwarded-renderer.js +105 -0
  180. package/dist/im/lark/forwarded-renderer.js.map +1 -0
  181. package/dist/im/lark/md-card.d.ts +73 -0
  182. package/dist/im/lark/md-card.d.ts.map +1 -0
  183. package/dist/im/lark/md-card.js +332 -0
  184. package/dist/im/lark/md-card.js.map +1 -0
  185. package/dist/im/lark/merge-forward.d.ts +32 -0
  186. package/dist/im/lark/merge-forward.d.ts.map +1 -0
  187. package/dist/im/lark/merge-forward.js +110 -0
  188. package/dist/im/lark/merge-forward.js.map +1 -0
  189. package/dist/im/lark/message-parser.d.ts +9 -3
  190. package/dist/im/lark/message-parser.d.ts.map +1 -1
  191. package/dist/im/lark/message-parser.js +48 -13
  192. package/dist/im/lark/message-parser.js.map +1 -1
  193. package/dist/im/lark/quote-hint.d.ts +18 -0
  194. package/dist/im/lark/quote-hint.d.ts.map +1 -0
  195. package/dist/im/lark/quote-hint.js +23 -0
  196. package/dist/im/lark/quote-hint.js.map +1 -0
  197. package/dist/services/bridge-fallback-gate.d.ts +42 -0
  198. package/dist/services/bridge-fallback-gate.d.ts.map +1 -0
  199. package/dist/services/bridge-fallback-gate.js +12 -0
  200. package/dist/services/bridge-fallback-gate.js.map +1 -0
  201. package/dist/services/bridge-rotation-policy.d.ts +139 -0
  202. package/dist/services/bridge-rotation-policy.d.ts.map +1 -0
  203. package/dist/services/bridge-rotation-policy.js +125 -0
  204. package/dist/services/bridge-rotation-policy.js.map +1 -0
  205. package/dist/services/bridge-turn-queue.d.ts +154 -0
  206. package/dist/services/bridge-turn-queue.d.ts.map +1 -0
  207. package/dist/services/bridge-turn-queue.js +316 -0
  208. package/dist/services/bridge-turn-queue.js.map +1 -0
  209. package/dist/services/chat-first-seen-store.d.ts +27 -0
  210. package/dist/services/chat-first-seen-store.d.ts.map +1 -0
  211. package/dist/services/chat-first-seen-store.js +114 -0
  212. package/dist/services/chat-first-seen-store.js.map +1 -0
  213. package/dist/services/claude-transcript.d.ts +268 -0
  214. package/dist/services/claude-transcript.d.ts.map +1 -0
  215. package/dist/services/claude-transcript.js +798 -0
  216. package/dist/services/claude-transcript.js.map +1 -0
  217. package/dist/services/coco-transcript.d.ts +35 -0
  218. package/dist/services/coco-transcript.d.ts.map +1 -0
  219. package/dist/services/coco-transcript.js +192 -0
  220. package/dist/services/coco-transcript.js.map +1 -0
  221. package/dist/services/codex-bridge-queue.d.ts +56 -0
  222. package/dist/services/codex-bridge-queue.d.ts.map +1 -0
  223. package/dist/services/codex-bridge-queue.js +150 -0
  224. package/dist/services/codex-bridge-queue.js.map +1 -0
  225. package/dist/services/codex-transcript.d.ts +84 -0
  226. package/dist/services/codex-transcript.d.ts.map +1 -0
  227. package/dist/services/codex-transcript.js +298 -0
  228. package/dist/services/codex-transcript.js.map +1 -0
  229. package/dist/services/group-creator.d.ts +23 -0
  230. package/dist/services/group-creator.d.ts.map +1 -0
  231. package/dist/services/group-creator.js +75 -0
  232. package/dist/services/group-creator.js.map +1 -0
  233. package/dist/services/groups-store.d.ts +98 -0
  234. package/dist/services/groups-store.d.ts.map +1 -0
  235. package/dist/services/groups-store.js +213 -0
  236. package/dist/services/groups-store.js.map +1 -0
  237. package/dist/services/oncall-store.d.ts +80 -8
  238. package/dist/services/oncall-store.d.ts.map +1 -1
  239. package/dist/services/oncall-store.js +265 -55
  240. package/dist/services/oncall-store.js.map +1 -1
  241. package/dist/services/project-scanner.d.ts +1 -2
  242. package/dist/services/project-scanner.d.ts.map +1 -1
  243. package/dist/services/project-scanner.js +118 -68
  244. package/dist/services/project-scanner.js.map +1 -1
  245. package/dist/services/schedule-store.d.ts +5 -0
  246. package/dist/services/schedule-store.d.ts.map +1 -1
  247. package/dist/services/schedule-store.js +77 -1
  248. package/dist/services/schedule-store.js.map +1 -1
  249. package/dist/services/session-store.d.ts +22 -0
  250. package/dist/services/session-store.d.ts.map +1 -1
  251. package/dist/services/session-store.js +62 -4
  252. package/dist/services/session-store.js.map +1 -1
  253. package/dist/setup/bots-store.d.ts +3 -0
  254. package/dist/setup/bots-store.d.ts.map +1 -0
  255. package/dist/setup/bots-store.js +24 -0
  256. package/dist/setup/bots-store.js.map +1 -0
  257. package/dist/setup/detect-platform.d.ts +14 -0
  258. package/dist/setup/detect-platform.d.ts.map +1 -0
  259. package/dist/setup/detect-platform.js +139 -0
  260. package/dist/setup/detect-platform.js.map +1 -0
  261. package/dist/setup/ensure-fonts.d.ts +13 -0
  262. package/dist/setup/ensure-fonts.d.ts.map +1 -0
  263. package/dist/setup/ensure-fonts.js +225 -0
  264. package/dist/setup/ensure-fonts.js.map +1 -0
  265. package/dist/setup/ensure-tmux.d.ts +60 -0
  266. package/dist/setup/ensure-tmux.d.ts.map +1 -0
  267. package/dist/setup/ensure-tmux.js +236 -0
  268. package/dist/setup/ensure-tmux.js.map +1 -0
  269. package/dist/setup/index.d.ts +9 -0
  270. package/dist/setup/index.d.ts.map +1 -0
  271. package/dist/setup/index.js +46 -0
  272. package/dist/setup/index.js.map +1 -0
  273. package/dist/setup/lark-scopes.json +301 -0
  274. package/dist/setup/register-app.d.ts +52 -0
  275. package/dist/setup/register-app.d.ts.map +1 -0
  276. package/dist/setup/register-app.js +91 -0
  277. package/dist/setup/register-app.js.map +1 -0
  278. package/dist/setup/verify-permissions.d.ts +115 -0
  279. package/dist/setup/verify-permissions.d.ts.map +1 -0
  280. package/dist/setup/verify-permissions.js +207 -0
  281. package/dist/setup/verify-permissions.js.map +1 -0
  282. package/dist/skills/definitions.d.ts +4 -0
  283. package/dist/skills/definitions.d.ts.map +1 -1
  284. package/dist/skills/definitions.js +133 -19
  285. package/dist/skills/definitions.js.map +1 -1
  286. package/dist/skills/installer.d.ts +3 -1
  287. package/dist/skills/installer.d.ts.map +1 -1
  288. package/dist/skills/installer.js +18 -3
  289. package/dist/skills/installer.js.map +1 -1
  290. package/dist/types.d.ts +44 -0
  291. package/dist/types.d.ts.map +1 -1
  292. package/dist/utils/bot-routing.d.ts +6 -0
  293. package/dist/utils/bot-routing.d.ts.map +1 -0
  294. package/dist/utils/bot-routing.js +50 -0
  295. package/dist/utils/bot-routing.js.map +1 -0
  296. package/dist/utils/file-lock.d.ts +2 -0
  297. package/dist/utils/file-lock.d.ts.map +1 -0
  298. package/dist/utils/file-lock.js +114 -0
  299. package/dist/utils/file-lock.js.map +1 -0
  300. package/dist/utils/font-installer.js +1 -1
  301. package/dist/utils/font-installer.js.map +1 -1
  302. package/dist/utils/idle-detector.d.ts +6 -0
  303. package/dist/utils/idle-detector.d.ts.map +1 -1
  304. package/dist/utils/idle-detector.js +25 -4
  305. package/dist/utils/idle-detector.js.map +1 -1
  306. package/dist/utils/logger.d.ts +10 -0
  307. package/dist/utils/logger.d.ts.map +1 -1
  308. package/dist/utils/logger.js +60 -8
  309. package/dist/utils/logger.js.map +1 -1
  310. package/dist/utils/render-dimensions.d.ts +48 -0
  311. package/dist/utils/render-dimensions.d.ts.map +1 -0
  312. package/dist/utils/render-dimensions.js +55 -0
  313. package/dist/utils/render-dimensions.js.map +1 -0
  314. package/dist/utils/screen-analyzer.d.ts.map +1 -1
  315. package/dist/utils/screen-analyzer.js +24 -0
  316. package/dist/utils/screen-analyzer.js.map +1 -1
  317. package/dist/utils/screenshot-renderer.d.ts.map +1 -1
  318. package/dist/utils/screenshot-renderer.js +67 -23
  319. package/dist/utils/screenshot-renderer.js.map +1 -1
  320. package/dist/utils/terminal-renderer.d.ts +16 -0
  321. package/dist/utils/terminal-renderer.d.ts.map +1 -1
  322. package/dist/utils/terminal-renderer.js +40 -23
  323. package/dist/utils/terminal-renderer.js.map +1 -1
  324. package/dist/utils/transient-snapshot.d.ts +28 -0
  325. package/dist/utils/transient-snapshot.d.ts.map +1 -0
  326. package/dist/utils/transient-snapshot.js +96 -0
  327. package/dist/utils/transient-snapshot.js.map +1 -0
  328. package/dist/worker.js +2248 -83
  329. package/dist/worker.js.map +1 -1
  330. package/package.json +12 -5
@@ -0,0 +1,100 @@
1
+ import type { SessionBackend, SpawnOpts } from './types.js';
2
+ /** Convert `\n` to `\r\n` while leaving existing `\r\n` alone. Exported for
3
+ * unit tests; used to normalise tmux capture-pane output before sending it
4
+ * to xterm.js (which treats bare LF as "down one row, keep column"). */
5
+ export declare function normaliseCaptureLineEndings(s: string): string;
6
+ export declare class TmuxPipeBackend implements SessionBackend {
7
+ /** Real tmux pane address (e.g. "0:2.0") or botmux session name (bmx-*). */
8
+ private readonly paneTarget;
9
+ private readonly fifoPath;
10
+ private readStream;
11
+ private readonly dataCbs;
12
+ private readonly exitCbs;
13
+ private lifecycleTimer;
14
+ private cols;
15
+ private rows;
16
+ private exited;
17
+ /** Set after pipe-pane subscription is active so kill() knows to cancel it. */
18
+ private pipeAttached;
19
+ private readonly createSession;
20
+ private readonly ownsSession;
21
+ private readonly _isReattach;
22
+ /** Claude Code session JSONL path — set by worker for claude-code sessions so
23
+ * the claude-code adapter can verify paste+Enter submissions via file growth. */
24
+ claudeJsonlPath?: string;
25
+ /** PID of the spawned Claude Code child — used by the claude-code adapter to
26
+ * follow Claude's authoritative session id via ~/.claude/sessions/<pid>.json. */
27
+ cliPid?: number;
28
+ /** Working directory the CLI was spawned in — cross-checked against the pid
29
+ * file's cwd field so a recycled PID can't mislead the resolver. */
30
+ cliCwd?: string;
31
+ /** Whether this backend re-attached to an existing bmx-* tmux session
32
+ * (rather than creating a new detached one). Mirrors TmuxBackend.isReattach
33
+ * so the worker can branch on reattach behaviour without a private-cast. */
34
+ get isReattach(): boolean;
35
+ constructor(paneTarget: string, opts?: {
36
+ createSession?: boolean;
37
+ ownsSession?: boolean;
38
+ isReattach?: boolean;
39
+ });
40
+ /** spawn() sets up the pipe-pane subscription + fifo reader. In managed
41
+ * mode it first creates a detached bmx-* tmux session that runs the CLI. */
42
+ spawn(bin: string, args: string[], opts: SpawnOpts): void;
43
+ write(data: string): void;
44
+ sendText(text: string): void;
45
+ sendSpecialKeys(...keys: string[]): void;
46
+ pasteText(text: string): void;
47
+ private exitCopyModeIfNeeded;
48
+ enterCopyMode(): void;
49
+ sendCopyModeCommand(xCommand: string): void;
50
+ resize(cols: number, rows: number): void;
51
+ onData(cb: (data: string) => void): void;
52
+ onExit(cb: (code: number | null, signal: string | null) => void): void;
53
+ kill(): void;
54
+ destroySession(): void;
55
+ getChildPid(): number | null;
56
+ getAttachInfo(): null;
57
+ private startLifecycleWatcher;
58
+ private stopLifecycleWatcher;
59
+ private handlePaneExit;
60
+ private createDetachedSession;
61
+ private applySessionOptions;
62
+ /** Snapshot the full pane history WITH ANSI escapes (`-S - -E -`).
63
+ *
64
+ * Used by web reattach so a brand-new web client sees the whole prior
65
+ * conversation. For the screenshot / screen_update fast path use
66
+ * `captureViewport()` instead — that one only returns the visible pane
67
+ * and is safe to seed a transient xterm-headless with.
68
+ *
69
+ * IMPORTANT: tmux capture-pane separates rows with bare `\n`, no `\r`.
70
+ * xterm.js (and any VT100-compliant emulator) treats a bare LF as
71
+ * "move down one row, keep column" — every captured line lands further
72
+ * to the right than the previous one. Normalising every `\n` to `\r\n`
73
+ * makes the snapshot render correctly. The live pipe-pane stream itself
74
+ * doesn't need this fix — applications write proper `\r\n`. */
75
+ captureCurrentScreen(): string;
76
+ /** Snapshot ONLY the currently visible pane (no scrollback). Equivalent to
77
+ * `tmux capture-pane` with no `-S`/`-E` flags, which defaults to the
78
+ * viewport. This is the right input for a transient xterm-headless seed:
79
+ * the snapshot row count matches the transient terminal's row count, so
80
+ * no normal-buffer scroll happens and the rendered screenshot lines up
81
+ * with what the user is seeing in the web terminal right now. */
82
+ captureViewport(): string;
83
+ private captureWithBounds;
84
+ /** Current real tmux pane dimensions. Drives transient-renderer sizing so
85
+ * the screenshot canvas matches whatever the web client resized the pane
86
+ * to. Returns null if tmux can't be queried (pane gone, server gone). */
87
+ getPaneSize(): {
88
+ cols: number;
89
+ rows: number;
90
+ } | null;
91
+ /** Cheap probe: is the adopted pane currently in the alternate screen
92
+ * buffer? Used by captureCurrentScreen to decide whether the snapshot
93
+ * needs an alt-buffer-enter prefix for correct rendering. */
94
+ private isPaneInAltBuffer;
95
+ /** True if the underlying pane is still addressable in tmux. Cheap check —
96
+ * used by callers to detect "user closed the pane while we were piping". */
97
+ isPaneAlive(): boolean;
98
+ private fireExit;
99
+ }
100
+ //# sourceMappingURL=tmux-pipe-backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-pipe-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-pipe-backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,473 @@
1
+ /**
2
+ * TmuxPipeBackend — observe a user-owned tmux pane WITHOUT attaching to its
3
+ * session. Used by /adopt mode to avoid the renderer conflict that arises
4
+ * when a normal `tmux attach-session` client coexists with a tmux -CC
5
+ * (iTerm2 control mode) client on the same server (interleaved ANSI vs
6
+ * control-protocol writes corrupt cursor / status-bar / alt-screen state).
7
+ *
8
+ * Architecture (no PTY, no attach):
9
+ * - mkfifo a unique fifo under /tmp
10
+ * - `tmux pipe-pane -O -t <pane> 'cat > <fifo>'` — tmux replicates every
11
+ * byte the pane writes into the fifo (append-only, '-O' overwrites any
12
+ * existing pipe).
13
+ * - fs.createReadStream(<fifo>) — we read tmux's verbatim ANSI stream.
14
+ * - All writes (sendText / sendSpecialKeys / pasteText / copy-mode keys)
15
+ * go through `tmux send-keys / paste-buffer -t <pane>` — so the pane's
16
+ * real address ("0:2.0") is the addressing target, not a synthetic
17
+ * session name.
18
+ * - `tmux capture-pane -e -p -t <pane> -S -` returns the current screen
19
+ * with ANSI; the worker uses it to seed new web-terminal connections
20
+ * so they don't start from a blank screen.
21
+ *
22
+ * The user's source session is never attached, never zoomed, never
23
+ * grouped — fully zero-touch from tmux's perspective beyond the pipe-pane
24
+ * subscription, which is automatically detached when we kill the backend.
25
+ */
26
+ import * as fs from 'node:fs';
27
+ import { execSync, execFileSync, spawnSync } from 'node:child_process';
28
+ import { tmpdir } from 'node:os';
29
+ import { join } from 'node:path';
30
+ import { randomBytes } from 'node:crypto';
31
+ import { tmuxEnv } from '../../setup/ensure-tmux.js';
32
+ import { buildBotmuxEnvAssignments, resolveUserShell, SHELL_WRAPPER_SCRIPT, TmuxBackend } from './tmux-backend.js';
33
+ function shellescape(s) {
34
+ // Single-quote-escape, replacing internal ' with '\''
35
+ return `'${s.replace(/'/g, "'\\''")}'`;
36
+ }
37
+ /** Convert `\n` to `\r\n` while leaving existing `\r\n` alone. Exported for
38
+ * unit tests; used to normalise tmux capture-pane output before sending it
39
+ * to xterm.js (which treats bare LF as "down one row, keep column"). */
40
+ export function normaliseCaptureLineEndings(s) {
41
+ return s.replace(/\r?\n/g, '\r\n');
42
+ }
43
+ export class TmuxPipeBackend {
44
+ /** Real tmux pane address (e.g. "0:2.0") or botmux session name (bmx-*). */
45
+ paneTarget;
46
+ fifoPath;
47
+ readStream = null;
48
+ dataCbs = [];
49
+ exitCbs = [];
50
+ lifecycleTimer = null;
51
+ cols = 200;
52
+ rows = 50;
53
+ exited = false;
54
+ /** Set after pipe-pane subscription is active so kill() knows to cancel it. */
55
+ pipeAttached = false;
56
+ createSession;
57
+ ownsSession;
58
+ _isReattach;
59
+ /** Claude Code session JSONL path — set by worker for claude-code sessions so
60
+ * the claude-code adapter can verify paste+Enter submissions via file growth. */
61
+ claudeJsonlPath;
62
+ /** PID of the spawned Claude Code child — used by the claude-code adapter to
63
+ * follow Claude's authoritative session id via ~/.claude/sessions/<pid>.json. */
64
+ cliPid;
65
+ /** Working directory the CLI was spawned in — cross-checked against the pid
66
+ * file's cwd field so a recycled PID can't mislead the resolver. */
67
+ cliCwd;
68
+ /** Whether this backend re-attached to an existing bmx-* tmux session
69
+ * (rather than creating a new detached one). Mirrors TmuxBackend.isReattach
70
+ * so the worker can branch on reattach behaviour without a private-cast. */
71
+ get isReattach() {
72
+ return this._isReattach;
73
+ }
74
+ constructor(paneTarget, opts) {
75
+ this.paneTarget = paneTarget;
76
+ this.createSession = opts?.createSession ?? false;
77
+ this.ownsSession = opts?.ownsSession ?? false;
78
+ this._isReattach = opts?.isReattach ?? false;
79
+ // Per-instance fifo so concurrent adopt sessions don't collide.
80
+ this.fifoPath = join(tmpdir(), `botmux-pipe-${randomBytes(8).toString('hex')}.fifo`);
81
+ }
82
+ // ─── SessionBackend implementation ────────────────────────────────────────
83
+ /** spawn() sets up the pipe-pane subscription + fifo reader. In managed
84
+ * mode it first creates a detached bmx-* tmux session that runs the CLI. */
85
+ spawn(bin, args, opts) {
86
+ this.cols = opts.cols;
87
+ this.rows = opts.rows;
88
+ if (this.createSession) {
89
+ this.createDetachedSession(bin, args, opts);
90
+ }
91
+ else if (this.ownsSession && this._isReattach) {
92
+ // Backfill tmux options on an existing bmx-* session — daemon may have
93
+ // been upgraded since the session was originally created, and options
94
+ // like set-clipboard / window-size largest are idempotent to re-apply.
95
+ this.applySessionOptions();
96
+ }
97
+ // Step 1: create the fifo. mkfifo is POSIX; linux/darwin both have it.
98
+ spawnSync('mkfifo', [this.fifoPath], { stdio: 'ignore' });
99
+ // Step 2: open the read end with O_RDWR (no O_NONBLOCK).
100
+ //
101
+ // Why O_RDWR? Avoids the fifo open chicken-and-egg: opening O_RDONLY
102
+ // alone blocks until a writer arrives, opening O_WRONLY alone blocks
103
+ // until a reader arrives. Holding both ends ourselves makes either
104
+ // peer's open() return immediately.
105
+ //
106
+ // Why NOT O_NONBLOCK? libuv's ReadStream issues blocking read() calls
107
+ // from its threadpool — that's how it stays responsive without
108
+ // burning CPU. With O_NONBLOCK the very first read() on an empty
109
+ // fifo returns EAGAIN, which libuv surfaces as an error, and the
110
+ // stream dies before tmux ever gets a chance to write a byte. (This
111
+ // exact bug ate the bridge final_output pipeline on first ship: an
112
+ // strace showed worker only read its IPC fd, never the fifo.)
113
+ const fd = fs.openSync(this.fifoPath, fs.constants.O_RDWR);
114
+ this.readStream = fs.createReadStream('', { fd, autoClose: false, highWaterMark: 64 * 1024 });
115
+ this.readStream.on('data', (chunk) => {
116
+ const data = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
117
+ for (const cb of this.dataCbs) {
118
+ try {
119
+ cb(data);
120
+ }
121
+ catch { /* listener crash shouldn't kill the stream */ }
122
+ }
123
+ });
124
+ this.readStream.on('error', (err) => {
125
+ // Errors are best-effort logged via the worker's stderr (we can't
126
+ // pull a logger in a backend without circular imports). Don't fire
127
+ // exit — the user's CLI is still alive, we just lost realtime view.
128
+ process.stderr.write(`[tmux-pipe-backend] read error: ${err?.message ?? err}\n`);
129
+ });
130
+ // Step 3: ask tmux to replicate the pane's bytes into our fifo.
131
+ // -O causes tmux to overwrite any prior pipe-pane subscription.
132
+ // The shell command must redirect to the fifo; tmux runs it via /bin/sh.
133
+ try {
134
+ execSync(`tmux pipe-pane -O -t ${shellescape(this.paneTarget)} 'cat > ${shellescape(this.fifoPath)}'`, { stdio: 'ignore', timeout: 5000, env: tmuxEnv() });
135
+ this.pipeAttached = true;
136
+ this.startLifecycleWatcher();
137
+ }
138
+ catch (err) {
139
+ this.fireExit(1, null);
140
+ throw err;
141
+ }
142
+ }
143
+ write(data) {
144
+ // No PTY to write to — interpret as a literal send-keys.
145
+ this.sendText(data);
146
+ }
147
+ sendText(text) {
148
+ if (this.exited)
149
+ return;
150
+ this.exitCopyModeIfNeeded();
151
+ execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-l', '--', text], {
152
+ stdio: 'ignore',
153
+ timeout: 5000,
154
+ env: tmuxEnv(),
155
+ });
156
+ }
157
+ sendSpecialKeys(...keys) {
158
+ if (this.exited)
159
+ return;
160
+ this.exitCopyModeIfNeeded();
161
+ execFileSync('tmux', ['send-keys', '-t', this.paneTarget, ...keys], {
162
+ stdio: 'ignore',
163
+ timeout: 5000,
164
+ env: tmuxEnv(),
165
+ });
166
+ }
167
+ pasteText(text) {
168
+ if (this.exited)
169
+ return;
170
+ this.exitCopyModeIfNeeded();
171
+ execFileSync('tmux', ['load-buffer', '-'], {
172
+ input: text,
173
+ stdio: ['pipe', 'ignore', 'ignore'],
174
+ timeout: 5000,
175
+ env: tmuxEnv(),
176
+ });
177
+ execFileSync('tmux', ['paste-buffer', '-t', this.paneTarget, '-d'], {
178
+ stdio: 'ignore',
179
+ timeout: 5000,
180
+ env: tmuxEnv(),
181
+ });
182
+ }
183
+ exitCopyModeIfNeeded() {
184
+ if (this.exited)
185
+ return;
186
+ try {
187
+ const inMode = execFileSync('tmux', ['display-message', '-p', '-t', this.paneTarget, '#{pane_in_mode}'], {
188
+ encoding: 'utf-8',
189
+ stdio: ['ignore', 'pipe', 'ignore'],
190
+ timeout: 1000,
191
+ env: tmuxEnv(),
192
+ }).trim();
193
+ if (inMode === '1') {
194
+ execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-X', 'cancel'], {
195
+ stdio: 'ignore',
196
+ timeout: 1000,
197
+ env: tmuxEnv(),
198
+ });
199
+ }
200
+ }
201
+ catch {
202
+ // Pane may be gone or tmux may be restarting; keep the original write path best-effort.
203
+ }
204
+ }
205
+ enterCopyMode() {
206
+ if (this.exited)
207
+ return;
208
+ execFileSync('tmux', ['copy-mode', '-e', '-t', this.paneTarget], {
209
+ stdio: 'ignore',
210
+ timeout: 5000,
211
+ env: tmuxEnv(),
212
+ });
213
+ }
214
+ sendCopyModeCommand(xCommand) {
215
+ if (this.exited)
216
+ return;
217
+ execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-X', xCommand], {
218
+ stdio: 'ignore',
219
+ timeout: 5000,
220
+ env: tmuxEnv(),
221
+ });
222
+ }
223
+ resize(cols, rows) {
224
+ this.cols = cols;
225
+ this.rows = rows;
226
+ if (this.ownsSession) {
227
+ execFileSync('tmux', ['resize-window', '-t', this.paneTarget, '-x', String(cols), '-y', String(rows)], {
228
+ stdio: 'ignore',
229
+ timeout: 5000,
230
+ env: tmuxEnv(),
231
+ });
232
+ }
233
+ }
234
+ onData(cb) {
235
+ this.dataCbs.push(cb);
236
+ }
237
+ onExit(cb) {
238
+ this.exitCbs.push(cb);
239
+ }
240
+ kill() {
241
+ if (this.exited)
242
+ return;
243
+ this.exited = true;
244
+ this.stopLifecycleWatcher();
245
+ // Cancel tmux's pipe subscription. Calling pipe-pane without a command
246
+ // turns it off for the target pane.
247
+ if (this.pipeAttached) {
248
+ try {
249
+ execSync(`tmux pipe-pane -t ${shellescape(this.paneTarget)}`, { stdio: 'ignore', timeout: 3000, env: tmuxEnv() });
250
+ }
251
+ catch { /* pane may already be gone — benign */ }
252
+ this.pipeAttached = false;
253
+ }
254
+ if (this.readStream) {
255
+ try {
256
+ this.readStream.destroy();
257
+ }
258
+ catch { /* already closed */ }
259
+ this.readStream = null;
260
+ }
261
+ try {
262
+ fs.unlinkSync(this.fifoPath);
263
+ }
264
+ catch { /* already gone */ }
265
+ }
266
+ destroySession() {
267
+ this.kill();
268
+ if (this.ownsSession) {
269
+ TmuxBackend.killSession(this.paneTarget);
270
+ }
271
+ }
272
+ getChildPid() {
273
+ try {
274
+ const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_pid}'`,
275
+ // Explicit stdio: execSync's default leaks the child's stderr to the
276
+ // parent — when tmux server is unavailable this would spam
277
+ // "error connecting to /tmp/tmux-UID/default" into daemon-error.log
278
+ // every poll. Capture stderr in the result instead.
279
+ // tmuxEnv() also strips $TMUX so we don't target a dead parent server.
280
+ { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 3000, env: tmuxEnv() }).trim();
281
+ const pid = parseInt(out, 10);
282
+ return pid > 0 ? pid : null;
283
+ }
284
+ catch {
285
+ return null;
286
+ }
287
+ }
288
+ getAttachInfo() {
289
+ return null;
290
+ }
291
+ // ─── Pipe-specific helpers ────────────────────────────────────────────────
292
+ startLifecycleWatcher() {
293
+ this.stopLifecycleWatcher();
294
+ this.lifecycleTimer = setInterval(() => {
295
+ if (this.exited)
296
+ return;
297
+ try {
298
+ const paneId = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_id}'`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
299
+ if (!paneId)
300
+ this.handlePaneExit();
301
+ }
302
+ catch {
303
+ this.handlePaneExit();
304
+ }
305
+ }, 1000);
306
+ }
307
+ stopLifecycleWatcher() {
308
+ if (this.lifecycleTimer) {
309
+ clearInterval(this.lifecycleTimer);
310
+ this.lifecycleTimer = null;
311
+ }
312
+ }
313
+ handlePaneExit() {
314
+ if (this.exited)
315
+ return;
316
+ this.exited = true;
317
+ this.stopLifecycleWatcher();
318
+ if (this.readStream) {
319
+ try {
320
+ this.readStream.destroy();
321
+ }
322
+ catch { /* already closed */ }
323
+ this.readStream = null;
324
+ }
325
+ try {
326
+ fs.unlinkSync(this.fifoPath);
327
+ }
328
+ catch { /* already gone */ }
329
+ this.fireExit(1, null);
330
+ }
331
+ createDetachedSession(bin, args, opts) {
332
+ const shellSpec = resolveUserShell();
333
+ const envAssignments = buildBotmuxEnvAssignments(opts.env);
334
+ execFileSync('tmux', [
335
+ 'new-session',
336
+ '-d',
337
+ '-s', this.paneTarget,
338
+ '-x', String(opts.cols),
339
+ '-y', String(opts.rows),
340
+ '--',
341
+ shellSpec.shell, ...shellSpec.flags, '-c', SHELL_WRAPPER_SCRIPT, '_',
342
+ opts.cwd,
343
+ ...envAssignments,
344
+ bin, ...args,
345
+ ], {
346
+ cwd: opts.cwd,
347
+ stdio: 'ignore',
348
+ timeout: 5000,
349
+ env: tmuxEnv(opts.env),
350
+ });
351
+ this.applySessionOptions();
352
+ }
353
+ applySessionOptions() {
354
+ const t = shellescape(this.paneTarget);
355
+ const env = tmuxEnv();
356
+ try {
357
+ execSync(`tmux set-option -t ${t} status off`, { stdio: 'ignore', env });
358
+ execSync(`tmux set-option -t ${t} mouse on`, { stdio: 'ignore', env });
359
+ execSync(`tmux set-option -s set-clipboard on`, { stdio: 'ignore', env });
360
+ execSync(`tmux set-option -t ${t} history-limit 50000`, { stdio: 'ignore', env });
361
+ execSync(`tmux set-option -t ${t} window-size largest`, { stdio: 'ignore', env });
362
+ }
363
+ catch { /* session may not be ready yet — benign */ }
364
+ }
365
+ /** Snapshot the full pane history WITH ANSI escapes (`-S - -E -`).
366
+ *
367
+ * Used by web reattach so a brand-new web client sees the whole prior
368
+ * conversation. For the screenshot / screen_update fast path use
369
+ * `captureViewport()` instead — that one only returns the visible pane
370
+ * and is safe to seed a transient xterm-headless with.
371
+ *
372
+ * IMPORTANT: tmux capture-pane separates rows with bare `\n`, no `\r`.
373
+ * xterm.js (and any VT100-compliant emulator) treats a bare LF as
374
+ * "move down one row, keep column" — every captured line lands further
375
+ * to the right than the previous one. Normalising every `\n` to `\r\n`
376
+ * makes the snapshot render correctly. The live pipe-pane stream itself
377
+ * doesn't need this fix — applications write proper `\r\n`. */
378
+ captureCurrentScreen() {
379
+ return this.captureWithBounds('-S - -E -');
380
+ }
381
+ /** Snapshot ONLY the currently visible pane (no scrollback). Equivalent to
382
+ * `tmux capture-pane` with no `-S`/`-E` flags, which defaults to the
383
+ * viewport. This is the right input for a transient xterm-headless seed:
384
+ * the snapshot row count matches the transient terminal's row count, so
385
+ * no normal-buffer scroll happens and the rendered screenshot lines up
386
+ * with what the user is seeing in the web terminal right now. */
387
+ captureViewport() {
388
+ // No `-S`/`-E` flags = tmux default = current viewport only.
389
+ return this.captureWithBounds('');
390
+ }
391
+ captureWithBounds(bounds) {
392
+ if (this.exited)
393
+ return '';
394
+ try {
395
+ const altOn = this.isPaneInAltBuffer();
396
+ const raw = execSync(`tmux capture-pane -e -p -t ${shellescape(this.paneTarget)}${bounds ? ' ' + bounds : ''}`,
397
+ // Explicit stdio — see getChildPid for why default leaks tmux stderr.
398
+ { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000, maxBuffer: 16 * 1024 * 1024, env: tmuxEnv() });
399
+ const normalised = normaliseCaptureLineEndings(raw);
400
+ if (altOn) {
401
+ // The pane's CLI (e.g. Claude Code, vim) is in the alternate screen
402
+ // buffer. capture-pane returns the alt-buffer's content but no
403
+ // mode-switch escape sequence — we have to bracket the snapshot
404
+ // with `enter alt screen + home + clear` so xterm.js renders it in
405
+ // the alt buffer instead of leaking it into the main buffer where
406
+ // it would persist after the application exits.
407
+ return `\x1b[?1049h\x1b[H\x1b[2J${normalised}`;
408
+ }
409
+ return normalised;
410
+ }
411
+ catch {
412
+ return '';
413
+ }
414
+ }
415
+ /** Current real tmux pane dimensions. Drives transient-renderer sizing so
416
+ * the screenshot canvas matches whatever the web client resized the pane
417
+ * to. Returns null if tmux can't be queried (pane gone, server gone). */
418
+ getPaneSize() {
419
+ if (this.exited)
420
+ return null;
421
+ try {
422
+ const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_width} #{pane_height}'`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
423
+ const [cols, rows] = out.split(/\s+/).map(s => parseInt(s, 10));
424
+ if (Number.isFinite(cols) && Number.isFinite(rows) && cols > 0 && rows > 0) {
425
+ return { cols, rows };
426
+ }
427
+ return null;
428
+ }
429
+ catch {
430
+ return null;
431
+ }
432
+ }
433
+ /** Cheap probe: is the adopted pane currently in the alternate screen
434
+ * buffer? Used by captureCurrentScreen to decide whether the snapshot
435
+ * needs an alt-buffer-enter prefix for correct rendering. */
436
+ isPaneInAltBuffer() {
437
+ try {
438
+ const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{alternate_on}'`,
439
+ // Explicit stdio — see getChildPid for why default leaks tmux stderr.
440
+ { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
441
+ return out === '1';
442
+ }
443
+ catch {
444
+ return false;
445
+ }
446
+ }
447
+ /** True if the underlying pane is still addressable in tmux. Cheap check —
448
+ * used by callers to detect "user closed the pane while we were piping". */
449
+ isPaneAlive() {
450
+ if (this.exited)
451
+ return false;
452
+ try {
453
+ execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} ''`, {
454
+ stdio: 'ignore',
455
+ timeout: 2000,
456
+ env: tmuxEnv(),
457
+ });
458
+ return true;
459
+ }
460
+ catch {
461
+ return false;
462
+ }
463
+ }
464
+ fireExit(code, signal) {
465
+ for (const cb of this.exitCbs) {
466
+ try {
467
+ cb(code, signal);
468
+ }
469
+ catch { /* listener crash is benign */ }
470
+ }
471
+ }
472
+ }
473
+ //# sourceMappingURL=tmux-pipe-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-pipe-backend.js","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-pipe-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEnH,SAAS,WAAW,CAAC,CAAS;IAC5B,sDAAsD;IACtD,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC;AAED;;yEAEyE;AACzE,MAAM,UAAU,2BAA2B,CAAC,CAAS;IACnD,OAAO,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,OAAO,eAAe;IAC1B,4EAA4E;IAC3D,UAAU,CAAS;IACnB,QAAQ,CAAS;IAC1B,UAAU,GAAyB,IAAI,CAAC;IAC/B,OAAO,GAA+B,EAAE,CAAC;IACzC,OAAO,GAAgE,EAAE,CAAC;IACnF,cAAc,GAA0B,IAAI,CAAC;IAC7C,IAAI,GAAG,GAAG,CAAC;IACX,IAAI,GAAG,EAAE,CAAC;IACV,MAAM,GAAG,KAAK,CAAC;IACvB,+EAA+E;IACvE,YAAY,GAAG,KAAK,CAAC;IACZ,aAAa,CAAU;IACvB,WAAW,CAAU;IACrB,WAAW,CAAU;IAEtC;sFACkF;IAClF,eAAe,CAAU;IACzB;sFACkF;IAClF,MAAM,CAAU;IAChB;yEACqE;IACrE,MAAM,CAAU;IAEhB;;iFAE6E;IAC7E,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,YAAY,UAAkB,EAAE,IAA+E;QAC7G,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,KAAK,CAAC;QAClD,IAAI,CAAC,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,KAAK,CAAC;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC;QAC7C,gEAAgE;QAChE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvF,CAAC;IAED,6EAA6E;IAE7E;iFAC6E;IAC7E,KAAK,CAAC,GAAW,EAAE,IAAc,EAAE,IAAe;QAChD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEtB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC9C,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAChD,uEAAuE;YACvE,sEAAsE;YACtE,uEAAuE;YACvE,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;QAED,uEAAuE;QACvE,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE1D,yDAAyD;QACzD,EAAE;QACF,qEAAqE;QACrE,qEAAqE;QACrE,mEAAmE;QACnE,oCAAoC;QACpC,EAAE;QACF,sEAAsE;QACtE,+DAA+D;QAC/D,iEAAiE;QACjE,iEAAiE;QACjE,oEAAoE;QACpE,mEAAmE;QACnE,8DAA8D;QAC9D,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAE9F,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACnC,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACxE,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,8CAA8C,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,EAAE;YACvC,kEAAkE;YAClE,mEAAmE;YACnE,oEAAoE;YACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QAEH,gEAAgE;QAChE,gEAAgE;QAChE,yEAAyE;QACzE,IAAI,CAAC;YACH,QAAQ,CACN,wBAAwB,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAC5F,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACnD,CAAC;YACF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACvB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAY;QAChB,yDAAyD;QACzD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;YAC3E,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAED,eAAe,CAAC,GAAG,IAAc;QAC/B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;YAClE,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,IAAY;QACpB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE;YACzC,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;YACnC,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE;YAClE,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QAExB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAAE;gBACvG,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;gBACnC,OAAO,EAAE,IAAI;gBACb,GAAG,EAAE,OAAO,EAAE;aACf,CAAC,CAAC,IAAI,EAAE,CAAC;YAEV,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnB,YAAY,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;oBACzE,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,IAAI;oBACb,GAAG,EAAE,OAAO,EAAE;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,wFAAwF;QAC1F,CAAC;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,YAAY,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,EAAE;YAC/D,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,QAAgB;QAClC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,YAAY,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;YACzE,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,EAAE;SACf,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,IAAY;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,YAAY,CAAC,MAAM,EAAE,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;gBACrG,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE,IAAI;gBACb,GAAG,EAAE,OAAO,EAAE;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,CAAC,EAA0B;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,CAAC,EAAwD;QAC7D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,uEAAuE;QACvE,oCAAoC;QACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,QAAQ,CAAC,qBAAqB,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YACpH,CAAC;YAAC,MAAM,CAAC,CAAC,uCAAuC,CAAC,CAAC;YACnD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC;gBAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;YACjE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACpE,CAAC;IAED,cAAc;QACZ,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,WAAW;QACT,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAClB,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB;YAC1E,qEAAqE;YACrE,2DAA2D;YAC3D,oEAAoE;YACpE,oDAAoD;YACpD,uEAAuE;YACvE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACtF,CAAC,IAAI,EAAE,CAAC;YACT,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC9B,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAErE,qBAAqB;QAC3B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;YACrC,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO;YACxB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,QAAQ,CACrB,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,EACzE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACtF,CAAC,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM;oBAAE,IAAI,CAAC,cAAc,EAAE,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC;IAEO,oBAAoB;QAC1B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAEO,cAAc;QACpB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,CAAC;gBAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;YACjE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC;YAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAClE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACzB,CAAC;IAEO,qBAAqB,CAAC,GAAW,EAAE,IAAc,EAAE,IAAe;QACxE,MAAM,SAAS,GAAG,gBAAgB,EAAE,CAAC;QACrC,MAAM,cAAc,GAAG,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3D,YAAY,CAAC,MAAM,EAAE;YACnB,aAAa;YACb,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,UAAU;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,IAAI;YACJ,SAAS,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,GAAG;YACpE,IAAI,CAAC,GAAG;YACR,GAAG,cAAc;YACjB,GAAG,EAAE,GAAG,IAAI;SACb,EAAE;YACD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;SACvB,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAEO,mBAAmB;QACzB,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,QAAQ,CAAC,sBAAsB,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACzE,QAAQ,CAAC,sBAAsB,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YACvE,QAAQ,CAAC,qCAAqC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1E,QAAQ,CAAC,sBAAsB,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YAClF,QAAQ,CAAC,sBAAsB,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC,CAAC,2CAA2C,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;;;;oEAYgE;IAChE,oBAAoB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;sEAKkE;IAClE,eAAe;QACb,6DAA6D;QAC7D,OAAO,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAEO,iBAAiB,CAAC,MAAc;QACtC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,QAAQ,CAClB,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACzF,sEAAsE;YACtE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACnH,CAAC;YACF,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;YACpD,IAAI,KAAK,EAAE,CAAC;gBACV,oEAAoE;gBACpE,+DAA+D;gBAC/D,gEAAgE;gBAChE,mEAAmE;gBACnE,kEAAkE;gBAClE,gDAAgD;gBAChD,OAAO,2BAA2B,UAAU,EAAE,CAAC;YACjD,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;8EAE0E;IAC1E,WAAW;QACT,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAClB,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,iCAAiC,EAC3F,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACtF,CAAC,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChE,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC3E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACxB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;kEAE8D;IACtD,iBAAiB;QACvB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAClB,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,oBAAoB;YAC9E,sEAAsE;YACtE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CACtF,CAAC,IAAI,EAAE,CAAC;YACT,OAAO,GAAG,KAAK,GAAG,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;iFAC6E;IAC7E,WAAW;QACT,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC9B,IAAI,CAAC;YACH,QAAQ,CAAC,8BAA8B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;gBACxE,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE,IAAI;gBACb,GAAG,EAAE,OAAO,EAAE;aACf,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,QAAQ,CAAC,IAAmB,EAAE,MAAqB;QACzD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,CAAC;gBAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAMxD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAgCpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
1
+ {"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAMxD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAsCpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
@@ -17,6 +17,11 @@ export function createAidenAdapter(pathOverride) {
17
17
  args.push('--permission-mode', 'agentFull');
18
18
  return args;
19
19
  },
20
+ buildResumeCommand({ sessionId }) {
21
+ // Aiden uses botmux's sessionId directly — no rotation, no separate
22
+ // CLI-native id, so cliSessionId isn't consulted.
23
+ return `aiden --resume ${sessionId}`;
24
+ },
20
25
  async writeInput(pty, content) {
21
26
  if (pty.sendText && pty.sendSpecialKeys) {
22
27
  pty.sendText(content);
@@ -1 +1 @@
1
- {"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;YACD,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS,EAAG,kBAAkB;QACjD,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}
1
+ {"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;YACD,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,CAAC,EAAE,SAAS,EAAE;YAC9B,oEAAoE;YACpE,kDAAkD;YAClD,OAAO,kBAAkB,SAAS,EAAE,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS,EAAG,kBAAkB;QACjD,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}