botmux 2.66.0-canary.1 → 2.66.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. package/dist/adapters/backend/sandbox.d.ts +111 -37
  2. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  3. package/dist/adapters/backend/sandbox.js +373 -343
  4. package/dist/adapters/backend/sandbox.js.map +1 -1
  5. package/dist/adapters/cli/claude-code.d.ts.map +1 -1
  6. package/dist/adapters/cli/claude-code.js +1 -6
  7. package/dist/adapters/cli/claude-code.js.map +1 -1
  8. package/dist/adapters/cli/coco.d.ts.map +1 -1
  9. package/dist/adapters/cli/coco.js +8 -0
  10. package/dist/adapters/cli/coco.js.map +1 -1
  11. package/dist/adapters/cli/types.d.ts +7 -1
  12. package/dist/adapters/cli/types.d.ts.map +1 -1
  13. package/dist/adapters/coco-ask-plugin.d.ts +25 -0
  14. package/dist/adapters/coco-ask-plugin.d.ts.map +1 -0
  15. package/dist/adapters/coco-ask-plugin.js +71 -0
  16. package/dist/adapters/coco-ask-plugin.js.map +1 -0
  17. package/dist/bot-registry.d.ts +8 -1
  18. package/dist/bot-registry.d.ts.map +1 -1
  19. package/dist/bot-registry.js +3 -0
  20. package/dist/bot-registry.js.map +1 -1
  21. package/dist/cli/workflow.d.ts.map +1 -1
  22. package/dist/cli/workflow.js +4 -11
  23. package/dist/cli/workflow.js.map +1 -1
  24. package/dist/cli.d.ts.map +1 -1
  25. package/dist/cli.js +46 -141
  26. package/dist/cli.js.map +1 -1
  27. package/dist/core/ask-hook/coco.d.ts +22 -0
  28. package/dist/core/ask-hook/coco.d.ts.map +1 -0
  29. package/dist/core/ask-hook/coco.js +35 -0
  30. package/dist/core/ask-hook/coco.js.map +1 -0
  31. package/dist/core/ask-hook/registry.d.ts.map +1 -1
  32. package/dist/core/ask-hook/registry.js +6 -0
  33. package/dist/core/ask-hook/registry.js.map +1 -1
  34. package/dist/core/coco-picker-keys.d.ts +31 -0
  35. package/dist/core/coco-picker-keys.d.ts.map +1 -0
  36. package/dist/core/coco-picker-keys.js +60 -0
  37. package/dist/core/coco-picker-keys.js.map +1 -0
  38. package/dist/core/command-handler.d.ts.map +1 -1
  39. package/dist/core/command-handler.js +50 -26
  40. package/dist/core/command-handler.js.map +1 -1
  41. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  42. package/dist/core/dashboard-ipc-server.js +50 -5
  43. package/dist/core/dashboard-ipc-server.js.map +1 -1
  44. package/dist/core/inflight-input-tracker.d.ts +46 -0
  45. package/dist/core/inflight-input-tracker.d.ts.map +1 -0
  46. package/dist/core/inflight-input-tracker.js +54 -0
  47. package/dist/core/inflight-input-tracker.js.map +1 -0
  48. package/dist/core/restart-report.d.ts +3 -2
  49. package/dist/core/restart-report.d.ts.map +1 -1
  50. package/dist/core/restart-report.js +17 -12
  51. package/dist/core/restart-report.js.map +1 -1
  52. package/dist/core/session-manager.js +8 -8
  53. package/dist/core/session-manager.js.map +1 -1
  54. package/dist/core/trigger-session.js +2 -2
  55. package/dist/core/trigger-session.js.map +1 -1
  56. package/dist/core/worker-pool.d.ts +22 -8
  57. package/dist/core/worker-pool.d.ts.map +1 -1
  58. package/dist/core/worker-pool.js +78 -19
  59. package/dist/core/worker-pool.js.map +1 -1
  60. package/dist/daemon.d.ts +4 -0
  61. package/dist/daemon.d.ts.map +1 -1
  62. package/dist/daemon.js +107 -286
  63. package/dist/daemon.js.map +1 -1
  64. package/dist/dashboard/auth.d.ts.map +1 -1
  65. package/dist/dashboard/auth.js +1 -7
  66. package/dist/dashboard/auth.js.map +1 -1
  67. package/dist/dashboard/web/app.d.ts.map +1 -1
  68. package/dist/dashboard/web/app.js +29 -4
  69. package/dist/dashboard/web/app.js.map +1 -1
  70. package/dist/dashboard/web/i18n.js +2 -2
  71. package/dist/dashboard/web/i18n.js.map +1 -1
  72. package/dist/dashboard-web/app.js +608 -789
  73. package/dist/dashboard-web/index.html +0 -1
  74. package/dist/dashboard-web/style.css +0 -224
  75. package/dist/dashboard.js +21 -9
  76. package/dist/dashboard.js.map +1 -1
  77. package/dist/i18n/en.d.ts.map +1 -1
  78. package/dist/i18n/en.js +116 -1
  79. package/dist/i18n/en.js.map +1 -1
  80. package/dist/i18n/zh.d.ts.map +1 -1
  81. package/dist/i18n/zh.js +116 -1
  82. package/dist/i18n/zh.js.map +1 -1
  83. package/dist/im/lark/ask-card.d.ts.map +1 -1
  84. package/dist/im/lark/ask-card.js +40 -35
  85. package/dist/im/lark/ask-card.js.map +1 -1
  86. package/dist/im/lark/card-builder.d.ts +9 -1
  87. package/dist/im/lark/card-builder.d.ts.map +1 -1
  88. package/dist/im/lark/card-builder.js +24 -10
  89. package/dist/im/lark/card-builder.js.map +1 -1
  90. package/dist/im/lark/card-handler.d.ts +0 -12
  91. package/dist/im/lark/card-handler.d.ts.map +1 -1
  92. package/dist/im/lark/card-handler.js +30 -46
  93. package/dist/im/lark/card-handler.js.map +1 -1
  94. package/dist/im/lark/event-dispatcher.js +3 -3
  95. package/dist/im/lark/event-dispatcher.js.map +1 -1
  96. package/dist/im/lark/md-card.d.ts +3 -1
  97. package/dist/im/lark/md-card.d.ts.map +1 -1
  98. package/dist/im/lark/md-card.js +7 -6
  99. package/dist/im/lark/md-card.js.map +1 -1
  100. package/dist/im/lark/quote-hint.d.ts +2 -1
  101. package/dist/im/lark/quote-hint.d.ts.map +1 -1
  102. package/dist/im/lark/quote-hint.js +3 -2
  103. package/dist/im/lark/quote-hint.js.map +1 -1
  104. package/dist/im/lark/relay-target-routing.d.ts +2 -3
  105. package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
  106. package/dist/im/lark/relay-target-routing.js +34 -10
  107. package/dist/im/lark/relay-target-routing.js.map +1 -1
  108. package/dist/im/lark/workflow-card-handler.d.ts +2 -1
  109. package/dist/im/lark/workflow-card-handler.d.ts.map +1 -1
  110. package/dist/im/lark/workflow-card-handler.js +4 -4
  111. package/dist/im/lark/workflow-card-handler.js.map +1 -1
  112. package/dist/im/lark/workflow-cards.d.ts +2 -1
  113. package/dist/im/lark/workflow-cards.d.ts.map +1 -1
  114. package/dist/im/lark/workflow-cards.js +27 -26
  115. package/dist/im/lark/workflow-cards.js.map +1 -1
  116. package/dist/im/lark/workflow-progress-card.d.ts +6 -1
  117. package/dist/im/lark/workflow-progress-card.d.ts.map +1 -1
  118. package/dist/im/lark/workflow-progress-card.js +24 -20
  119. package/dist/im/lark/workflow-progress-card.js.map +1 -1
  120. package/dist/im/lark/workflow-slash-command.d.ts +2 -29
  121. package/dist/im/lark/workflow-slash-command.d.ts.map +1 -1
  122. package/dist/im/lark/workflow-slash-command.js +25 -77
  123. package/dist/im/lark/workflow-slash-command.js.map +1 -1
  124. package/dist/services/sandbox-land.d.ts +29 -4
  125. package/dist/services/sandbox-land.d.ts.map +1 -1
  126. package/dist/services/sandbox-land.js +361 -57
  127. package/dist/services/sandbox-land.js.map +1 -1
  128. package/dist/skills/definitions.d.ts.map +1 -1
  129. package/dist/skills/definitions.js +4 -208
  130. package/dist/skills/definitions.js.map +1 -1
  131. package/dist/types.d.ts +19 -0
  132. package/dist/types.d.ts.map +1 -1
  133. package/dist/worker.js +315 -41
  134. package/dist/worker.js.map +1 -1
  135. package/dist/workflows/definition.d.ts +96 -96
  136. package/dist/workflows/events/payloads.d.ts +4 -4
  137. package/dist/workflows/events/schema.d.ts +16 -16
  138. package/dist/workflows/fanout.d.ts.map +1 -1
  139. package/dist/workflows/fanout.js +2 -1
  140. package/dist/workflows/fanout.js.map +1 -1
  141. package/package.json +1 -1
  142. package/dist/dashboard/v3-runs-api.d.ts +0 -26
  143. package/dist/dashboard/v3-runs-api.d.ts.map +0 -1
  144. package/dist/dashboard/v3-runs-api.js +0 -67
  145. package/dist/dashboard/v3-runs-api.js.map +0 -1
  146. package/dist/dashboard/web/v3-terminal.d.ts +0 -11
  147. package/dist/dashboard/web/v3-terminal.d.ts.map +0 -1
  148. package/dist/dashboard/web/v3-terminal.js +0 -143
  149. package/dist/dashboard/web/v3-terminal.js.map +0 -1
  150. package/dist/dashboard/web/v3.d.ts +0 -2
  151. package/dist/dashboard/web/v3.d.ts.map +0 -1
  152. package/dist/dashboard/web/v3.js +0 -538
  153. package/dist/dashboard/web/v3.js.map +0 -1
  154. package/dist/im/lark/v3-blocked-card-handler.d.ts +0 -28
  155. package/dist/im/lark/v3-blocked-card-handler.d.ts.map +0 -1
  156. package/dist/im/lark/v3-blocked-card-handler.js +0 -130
  157. package/dist/im/lark/v3-blocked-card-handler.js.map +0 -1
  158. package/dist/im/lark/v3-blocked-card.d.ts +0 -75
  159. package/dist/im/lark/v3-blocked-card.d.ts.map +0 -1
  160. package/dist/im/lark/v3-blocked-card.js +0 -206
  161. package/dist/im/lark/v3-blocked-card.js.map +0 -1
  162. package/dist/im/lark/v3-gate-card-handler.d.ts +0 -31
  163. package/dist/im/lark/v3-gate-card-handler.d.ts.map +0 -1
  164. package/dist/im/lark/v3-gate-card-handler.js +0 -97
  165. package/dist/im/lark/v3-gate-card-handler.js.map +0 -1
  166. package/dist/im/lark/v3-gate-card.d.ts +0 -47
  167. package/dist/im/lark/v3-gate-card.d.ts.map +0 -1
  168. package/dist/im/lark/v3-gate-card.js +0 -119
  169. package/dist/im/lark/v3-gate-card.js.map +0 -1
  170. package/dist/im/lark/v3-loop-grant-card-handler.d.ts +0 -28
  171. package/dist/im/lark/v3-loop-grant-card-handler.d.ts.map +0 -1
  172. package/dist/im/lark/v3-loop-grant-card-handler.js +0 -90
  173. package/dist/im/lark/v3-loop-grant-card-handler.js.map +0 -1
  174. package/dist/im/lark/v3-loop-grant-card.d.ts +0 -46
  175. package/dist/im/lark/v3-loop-grant-card.d.ts.map +0 -1
  176. package/dist/im/lark/v3-loop-grant-card.js +0 -119
  177. package/dist/im/lark/v3-loop-grant-card.js.map +0 -1
  178. package/dist/im/lark/v3-revisit-grant-card-handler.d.ts +0 -29
  179. package/dist/im/lark/v3-revisit-grant-card-handler.d.ts.map +0 -1
  180. package/dist/im/lark/v3-revisit-grant-card-handler.js +0 -88
  181. package/dist/im/lark/v3-revisit-grant-card-handler.js.map +0 -1
  182. package/dist/im/lark/v3-revisit-grant-card.d.ts +0 -52
  183. package/dist/im/lark/v3-revisit-grant-card.d.ts.map +0 -1
  184. package/dist/im/lark/v3-revisit-grant-card.js +0 -123
  185. package/dist/im/lark/v3-revisit-grant-card.js.map +0 -1
  186. package/dist/workflows/v3/architect.d.ts +0 -37
  187. package/dist/workflows/v3/architect.d.ts.map +0 -1
  188. package/dist/workflows/v3/architect.js +0 -220
  189. package/dist/workflows/v3/architect.js.map +0 -1
  190. package/dist/workflows/v3/bot-resolve.d.ts +0 -21
  191. package/dist/workflows/v3/bot-resolve.d.ts.map +0 -1
  192. package/dist/workflows/v3/bot-resolve.js +0 -47
  193. package/dist/workflows/v3/bot-resolve.js.map +0 -1
  194. package/dist/workflows/v3/cli-run.d.ts +0 -24
  195. package/dist/workflows/v3/cli-run.d.ts.map +0 -1
  196. package/dist/workflows/v3/cli-run.js +0 -265
  197. package/dist/workflows/v3/cli-run.js.map +0 -1
  198. package/dist/workflows/v3/contract.d.ts +0 -302
  199. package/dist/workflows/v3/contract.d.ts.map +0 -1
  200. package/dist/workflows/v3/contract.js +0 -91
  201. package/dist/workflows/v3/contract.js.map +0 -1
  202. package/dist/workflows/v3/daemon-run.d.ts +0 -311
  203. package/dist/workflows/v3/daemon-run.d.ts.map +0 -1
  204. package/dist/workflows/v3/daemon-run.js +0 -755
  205. package/dist/workflows/v3/daemon-run.js.map +0 -1
  206. package/dist/workflows/v3/dag.d.ts +0 -332
  207. package/dist/workflows/v3/dag.d.ts.map +0 -1
  208. package/dist/workflows/v3/dag.js +0 -1040
  209. package/dist/workflows/v3/dag.js.map +0 -1
  210. package/dist/workflows/v3/ephemeral-pool.d.ts +0 -29
  211. package/dist/workflows/v3/ephemeral-pool.d.ts.map +0 -1
  212. package/dist/workflows/v3/ephemeral-pool.js +0 -331
  213. package/dist/workflows/v3/ephemeral-pool.js.map +0 -1
  214. package/dist/workflows/v3/grill-state.d.ts +0 -92
  215. package/dist/workflows/v3/grill-state.d.ts.map +0 -1
  216. package/dist/workflows/v3/grill-state.js +0 -151
  217. package/dist/workflows/v3/grill-state.js.map +0 -1
  218. package/dist/workflows/v3/host.d.ts +0 -88
  219. package/dist/workflows/v3/host.d.ts.map +0 -1
  220. package/dist/workflows/v3/host.js +0 -352
  221. package/dist/workflows/v3/host.js.map +0 -1
  222. package/dist/workflows/v3/human-gate.d.ts +0 -85
  223. package/dist/workflows/v3/human-gate.d.ts.map +0 -1
  224. package/dist/workflows/v3/human-gate.js +0 -153
  225. package/dist/workflows/v3/human-gate.js.map +0 -1
  226. package/dist/workflows/v3/journal.d.ts +0 -205
  227. package/dist/workflows/v3/journal.d.ts.map +0 -1
  228. package/dist/workflows/v3/journal.js +0 -64
  229. package/dist/workflows/v3/journal.js.map +0 -1
  230. package/dist/workflows/v3/manifest.d.ts +0 -17
  231. package/dist/workflows/v3/manifest.d.ts.map +0 -1
  232. package/dist/workflows/v3/manifest.js +0 -266
  233. package/dist/workflows/v3/manifest.js.map +0 -1
  234. package/dist/workflows/v3/ops-projection.d.ts +0 -109
  235. package/dist/workflows/v3/ops-projection.d.ts.map +0 -1
  236. package/dist/workflows/v3/ops-projection.js +0 -0
  237. package/dist/workflows/v3/ops-projection.js.map +0 -1
  238. package/dist/workflows/v3/orchestrator.d.ts +0 -168
  239. package/dist/workflows/v3/orchestrator.d.ts.map +0 -1
  240. package/dist/workflows/v3/orchestrator.js +0 -417
  241. package/dist/workflows/v3/orchestrator.js.map +0 -1
  242. package/dist/workflows/v3/runtime.d.ts +0 -193
  243. package/dist/workflows/v3/runtime.d.ts.map +0 -1
  244. package/dist/workflows/v3/runtime.js +0 -1266
  245. package/dist/workflows/v3/runtime.js.map +0 -1
  246. package/dist/workflows/v3/spec.d.ts +0 -32
  247. package/dist/workflows/v3/spec.d.ts.map +0 -1
  248. package/dist/workflows/v3/spec.js +0 -173
  249. package/dist/workflows/v3/spec.js.map +0 -1
  250. package/dist/workflows/v3/state.d.ts +0 -74
  251. package/dist/workflows/v3/state.d.ts.map +0 -1
  252. package/dist/workflows/v3/state.js +0 -353
  253. package/dist/workflows/v3/state.js.map +0 -1
@@ -1,21 +1,39 @@
1
+ /**
2
+ * Mount an overlayfs: reads fall through to `lower` (real, zero copy); writes
3
+ * copy-up into `upper` (the landable changeset). `work` is overlayfs scratch on
4
+ * the same fs as `upper`. Returns true iff `mount` exited 0.
5
+ */
6
+ export declare function mountOverlay(opts: {
7
+ lower: string;
8
+ upper: string;
9
+ work: string;
10
+ merged: string;
11
+ }): boolean;
12
+ /** True iff `path` is currently a mountpoint (host-side overlay still mounted). */
13
+ export declare function isMounted(path: string): boolean;
14
+ /** Unmount an overlay merged dir. Best-effort: lazy-umount (`-l`) if a normal
15
+ * umount fails (busy fd from a still-draining child). No-op if not a mount. */
16
+ export declare function unmountOverlay(merged: string): void;
1
17
  export interface SandboxPlan {
2
- /** Host path of the per-session writable project copy (a `git clone` of the
3
- * source). Mounted INSIDE the sandbox at `projectMount`, not at this path. */
4
- workDir: string;
5
- /** In-sandbox path the clone is mounted at — MUST equal the original
6
- * workingDir the CLI was given (e.g. codex `-C <dir>`), so the CLI's existing
7
- * args resolve to the clone. Also the child's chdir. */
18
+ /** In-sandbox path the project is bound at equals the original workingDir the
19
+ * CLI was given, so the CLI's existing path args resolve. Also the child's chdir. */
8
20
  projectMount: string;
9
- /** Per-session scoped HOME bound over the real home path so every CLI's
10
- * hardcoded `~/.<cli>` resolves into this de-identified area. */
11
- scopedHome: string;
12
- /** Daemon-mediated `botmux send` outbox the ONLY IPC surface bound in, so
13
- * bots.json / Lark creds never enter the sandbox. */
21
+ /** Host path of the merged project overlay (reads=real lower, writes=upper). */
22
+ projectMerged: string;
23
+ /** In-sandbox path the home overlay is bound at — equals the real home path so
24
+ * every CLI's hardcoded `~/.<cli>` resolves there. */
25
+ home: string;
26
+ /** Host path of the merged home overlay. */
27
+ homeMerged: string;
28
+ /** Daemon-mediated `botmux send` outbox — bound LAST so it wins over any mask. */
14
29
  outbox: string;
15
- /** Extra read-only paths the toolchain lives under (node/CLI binaries via
16
- * fnm, the botmux dist) — re-exposed AFTER the scoped-home mask because on
17
- * this host they sit under $HOME (e.g. ~/.local/share/fnm, ~/iserver/botmux). */
18
- toolchainRo: string[];
30
+ /** Per-bot privacy masks: directories blanked with an empty tmpfs. */
31
+ hideDirs: string[];
32
+ /** Per-bot privacy masks: files blanked with a read-only empty placeholder. */
33
+ hideFiles: {
34
+ path: string;
35
+ empty: string;
36
+ }[];
19
37
  /** Keep network egress. File-only scope ⇒ default true (npm/pip/git work). */
20
38
  net?: boolean;
21
39
  }
@@ -23,42 +41,49 @@ export interface SandboxPlan {
23
41
  * Build the bwrap argv prefix. Final spawn becomes:
24
42
  * bwrap <these args> -- <cliBin> <cliArgs...>
25
43
  *
26
- * Mount order matters: the scoped HOME is bound over the real home FIRST, then
27
- * toolchain/work/outbox paths (some under home) are re-bound on top bwrap
28
- * applies binds in order, so the later, more specific mounts win.
44
+ * Mount order matters (later mounts win): the whole real fs read-only first, then
45
+ * the home + project merged overlays bind over it (so writes there are isolated),
46
+ * then privacy masks blank specific paths, then the outbox binds LAST so it stays
47
+ * writable even if a mask covers a parent dir.
29
48
  */
30
49
  export declare function buildSandboxArgs(plan: SandboxPlan): string[];
31
- /**
32
- * Materialise a de-identified config dir inside `scopedHome`: copy ONLY the
33
- * auth/config files from the host's real config, never history/sessions.
34
- * `dereference` resolves symlinks (codex's config.toml → config.toml.old) into
35
- * real files, since the symlink target won't exist inside the masked home.
36
- *
37
- * Returns false if this CLI has no persistent config to scope (hermes/aiden/…).
38
- */
39
- export declare function seedScopedConfig(cliId: string, scopedHome: string, projectMount?: string): boolean;
40
50
  /** Is file-sandbox enabled for this session? Spike gate = env; the real
41
- * per-bot BotConfig.sandbox flag is a follow-up. */
51
+ * per-bot BotConfig.sandbox flag is decided by the caller. */
42
52
  export declare function sandboxEnabled(): boolean;
43
53
  export interface SandboxSpawn {
44
54
  /** Replace the CLI binary with this (always 'bwrap'). */
45
55
  bin: string;
46
56
  /** bwrap args + '--' + original (bin, ...args). */
47
57
  args: string[];
48
- /** Env overrides to merge into childEnv (HOME, PATH, BOTMUX_SEND_RELAY). */
58
+ /** Env overrides to merge into childEnv (HOME, PATH, BOTMUX_SEND_RELAY, proxies). */
49
59
  env: Record<string, string>;
50
60
  /** Outbox dir the daemon watcher must service. */
51
61
  outbox: string;
52
- /** Per-session project copy (for logging / landing). */
62
+ /** Project overlay UPPER dir — THE LANDABLE CHANGESET (used by sandbox-land). */
53
63
  workDir: string;
54
- /** Remove the per-session sandbox tree. */
64
+ /** HOME overlay UPPER dir (/var/tmp/botmux-sbx/<sid>/home-upper). The sandboxed
65
+ * CLI's $HOME writes — INCLUDING its session jsonl under CLAUDE_CONFIG_DIR —
66
+ * land here (invisible at the real path). The worker redirects its bridge/idle
67
+ * watch into this via sandboxedClaudeDataDir() so it sees the CLI's turns. */
68
+ homeUpper: string;
69
+ /** Unmount the overlays + remove the per-session sandbox tree. */
55
70
  cleanup: () => void;
56
71
  }
72
+ /** The path where a sandboxed session's CLI actually writes a $HOME-relative
73
+ * data dir (e.g. CLAUDE_CONFIG_DIR / `.claude-runtime`): the HOME overlay's
74
+ * ephemeral UPPER copy. The worker redirects its jsonl/bridge watch here so it
75
+ * sees the sandboxed CLI's writes (which are invisible at the real host path).
76
+ * Mirrors prepareSandbox's homeUpper layout — keep in sync. */
77
+ export declare function sandboxedClaudeDataDir(sessionId: string, realDataDir: string): string;
57
78
  /**
58
79
  * Build the sandboxed spawn for a CLI session, or return null when sandboxing
59
- * is off / unsupported. Creates per-session dirs under
60
- * <dataDir>/sandboxes/<sessionId>/, clones the source project, seeds a
61
- * de-identified config dir, and installs a `botmux` shim on PATH.
80
+ * is off / unsupported / a required overlay mount fails (fail-safe = the worker
81
+ * treats null as a hard error and does NOT silently run unsandboxed).
82
+ *
83
+ * Layout under <dataDir>/sandboxes/<sessionId>/: outbox, shimbin, proj-upper
84
+ * (the landable changeset), proj-work, proj-merged, home-merged. The HOME
85
+ * overlay's upper/work live under /var/tmp/botmux-sbx/<sessionId>/ because
86
+ * overlayfs forbids upper/work inside the lower (= the real home).
62
87
  */
63
88
  export declare function prepareSandbox(opts: {
64
89
  /** Whether the sandbox is on for THIS session (per-bot BotConfig.sandbox OR
@@ -71,7 +96,51 @@ export declare function prepareSandbox(opts: {
71
96
  dataDir: string;
72
97
  cliBin: string;
73
98
  cliArgs: string[];
99
+ /** Per-bot privacy masks (opt-in, no defaults). Paths existing as dirs are
100
+ * blanked with a tmpfs; files with an empty read-only placeholder. */
101
+ hidePaths?: string[];
74
102
  }): SandboxSpawn | null;
103
+ /**
104
+ * Re-attach the daemon/worker side to an ALREADY-spawned sandbox session WITHOUT
105
+ * touching the overlays. Used on daemon-restart reattach to a persistent
106
+ * (tmux/herdr/zellij) pane whose bwrap'd CLI is still alive: the CLI is bound to
107
+ * its own namespace-pinned overlay, so we must NOT unmount/remount (that would
108
+ * leave a duplicate host-side mount the CLI isn't using). We only need the outbox
109
+ * path back so the watcher can keep servicing the live CLI's `botmux send`, plus
110
+ * the workDir (upper changeset for landing) and a cleanup that tears the residue
111
+ * down at close/exit. Returns null if the session has no sandbox tree on disk
112
+ * (never sandboxed). Linux-only, mirrors prepareSandbox's layout.
113
+ */
114
+ export declare function attachSandboxOutbox(opts: {
115
+ sessionId: string;
116
+ dataDir: string;
117
+ }): {
118
+ outbox: string;
119
+ workDir: string;
120
+ cleanup: () => void;
121
+ } | null;
122
+ /**
123
+ * Reclaim leaked sandbox residue.
124
+ *
125
+ * Two classes of leak are reclaimed:
126
+ * 1. NON-ACTIVE orphans — sid not in `activeSessionIds`: the session is gone, so
127
+ * any leftover mount/dir is pure residue (the original startup-sweep case,
128
+ * guarding against a daemon crash/kill that skipped killCli()).
129
+ * 2. ACTIVE-but-DEAD — sid IS in `activeSessionIds`, yet NEITHER of its merged
130
+ * overlays is still mounted. This closes the blind spot where a sandboxed
131
+ * worker was SIGKILL'd (straggler reaper) or crashed: the session stays
132
+ * status='active' on disk, so the old "skip if active" rule would let the
133
+ * leaked upper/work dirs survive across restarts indefinitely. We only GC an
134
+ * active sid when its mounts are ALREADY gone — we NEVER tear down a live
135
+ * mount (a CLI persisting in a tmux/herdr/zellij pane is still bound to it),
136
+ * so a genuinely-live persistent session keeps its changeset.
137
+ *
138
+ * Safe to call repeatedly: wire once at daemon bootstrap AND on a periodic timer
139
+ * (the SIGKILL/straggler path can't run worker-side killCli(), so a startup-only
140
+ * sweep would let a crashed-active session's mount survive for the whole next
141
+ * daemon lifetime — one daemon per bot can run for days).
142
+ */
143
+ export declare function sweepOrphanSandboxes(dataDir: string, activeSessionIds: Set<string>): void;
75
144
  export interface RelayRequest {
76
145
  contentFile?: unknown;
77
146
  attachments?: unknown;
@@ -101,9 +170,14 @@ export declare function validateRelayRequest(req: RelayRequest): {
101
170
  /**
102
171
  * TOCTOU-safe copy of an outbox file (`outbox/<name>`, name already validated as
103
172
  * a plain basename) into a host-private `dest`. Opens with O_NOFOLLOW so a
104
- * symlink swapped in by the sandbox AFTER validation is rejected at open time;
105
- * reads from the fd (not the path), so the inode can't be swapped under us.
106
- * Returns false (reject) on symlink / non-regular / any error.
173
+ * symlink swapped in by the sandbox AFTER validation is rejected at open time,
174
+ * and O_NONBLOCK so opening a FIFO/special the sandbox dropped into the (rw-bound)
175
+ * outbox returns IMMEDIATELY instead of blocking the synchronous watcher tick
176
+ * forever (a FIFO with no writer would otherwise hang the whole worker event
177
+ * loop — an agent-triggerable DoS). After open we fstat-reject anything that
178
+ * isn't a regular file (a FIFO opened O_NONBLOCK|O_RDONLY succeeds but isFile()
179
+ * is false → rejected here). Reads from the fd (not the path), so the inode can't
180
+ * be swapped under us. Returns false (reject) on symlink / non-regular / any error.
107
181
  */
108
182
  export declare function materializeOutboxFile(outbox: string, name: string, dest: string): boolean;
109
183
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/sandbox.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,WAAW;IAC1B;mFAC+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB;;6DAEyD;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB;sEACkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB;0DACsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf;;sFAEkF;IAClF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAmB5D;AA2CD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CA0BlG;AA4ED;qDACqD;AACrD,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAoDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC;;sFAEkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,YAAY,GAAG,IAAI,CA2FtB;AAOD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAQD,MAAM,WAAW,cAAc;IAAG,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAAE;AAEpG;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAwB1H;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,IAAI,CAkE5G"}
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/sandbox.ts"],"names":[],"mappings":"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"}