@sema-agent/server 1.323.0 → 2.0.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 (539) hide show
  1. package/dist/approval-hmac.d.ts +40 -0
  2. package/dist/approval-hmac.js +67 -0
  3. package/dist/approval.d.ts +31 -0
  4. package/dist/approval.js +72 -4
  5. package/dist/audit.d.ts +26 -0
  6. package/dist/audit.js +40 -1
  7. package/dist/auth-bridge.d.ts +10 -0
  8. package/dist/auth-bridge.js +47 -4
  9. package/dist/auth-keys.d.ts +19 -0
  10. package/dist/auth-keys.js +13 -0
  11. package/dist/bake-runner/main.d.ts +5 -0
  12. package/dist/bake-runner/main.js +43 -4
  13. package/dist/bake-runner/protocol.d.ts +57 -0
  14. package/dist/bake-runner/protocol.js +58 -3
  15. package/dist/bake-runner/runner.d.ts +54 -0
  16. package/dist/bake-runner/runner.js +87 -5
  17. package/dist/bench/l8/artifact.d.ts +63 -0
  18. package/dist/bench/l8/artifact.js +61 -2
  19. package/dist/bench/l8/escape.d.ts +36 -0
  20. package/dist/bench/l8/escape.js +25 -0
  21. package/dist/bench/l8/index.d.ts +14 -0
  22. package/dist/bench/l8/index.js +14 -0
  23. package/dist/bench/l8/probes.d.ts +74 -0
  24. package/dist/bench/l8/probes.js +60 -0
  25. package/dist/bench/l8/run-probes.d.ts +43 -0
  26. package/dist/bench/l8/run-probes.js +45 -2
  27. package/dist/bench/s1/arms.d.ts +126 -0
  28. package/dist/bench/s1/arms.js +188 -13
  29. package/dist/bench/s1/live-deps.d.ts +66 -0
  30. package/dist/bench/s1/live-deps.js +249 -11
  31. package/dist/bench/s1/oracle.d.ts +49 -0
  32. package/dist/bench/s1/oracle.js +36 -1
  33. package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
  34. package/dist/bench/s1/repair-oracle-adapter.js +30 -0
  35. package/dist/bench/s1/reviewer.d.ts +38 -0
  36. package/dist/bench/s1/reviewer.js +34 -0
  37. package/dist/bench/s1/row.d.ts +77 -0
  38. package/dist/bench/s1/row.js +62 -0
  39. package/dist/bench/s1/run-firm.d.ts +47 -0
  40. package/dist/bench/s1/run-firm.js +70 -4
  41. package/dist/bench/s1/runner-ctx.d.ts +71 -0
  42. package/dist/bench/s1/runner-ctx.js +36 -0
  43. package/dist/bench/s1/tasks.d.ts +108 -0
  44. package/dist/bench/s1/tasks.js +115 -0
  45. package/dist/boot-reclaim.d.ts +19 -0
  46. package/dist/boot-reclaim.js +20 -0
  47. package/dist/brain.d.ts +25 -0
  48. package/dist/brain.js +61 -1
  49. package/dist/budget.d.ts +66 -0
  50. package/dist/budget.js +128 -4
  51. package/dist/capabilities/builtin-tools.d.ts +3 -0
  52. package/dist/capabilities/builtin-tools.js +3 -0
  53. package/dist/capabilities/center-plugins.d.ts +17 -1
  54. package/dist/capabilities/center-plugins.js +45 -4
  55. package/dist/capabilities/center-prompts.d.ts +46 -0
  56. package/dist/capabilities/center-prompts.js +57 -3
  57. package/dist/capabilities/code-review-council.d.ts +28 -0
  58. package/dist/capabilities/code-review-council.js +40 -7
  59. package/dist/capabilities/collab-wire.d.ts +2 -0
  60. package/dist/capabilities/collab-workflows.d.ts +7 -0
  61. package/dist/capabilities/collab-workflows.js +44 -1
  62. package/dist/capabilities/oa-tools.d.ts +6 -0
  63. package/dist/capabilities/oa-tools.js +10 -0
  64. package/dist/capabilities/prompt.d.ts +14 -0
  65. package/dist/capabilities/prompt.js +14 -0
  66. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  67. package/dist/capabilities/prompts/code-review.js +14 -0
  68. package/dist/capabilities/prompts/identity.d.ts +6 -0
  69. package/dist/capabilities/prompts/identity.js +6 -0
  70. package/dist/capabilities/prompts/team.d.ts +4 -0
  71. package/dist/capabilities/prompts/team.js +4 -0
  72. package/dist/capabilities/repo-tools.d.ts +11 -0
  73. package/dist/capabilities/repo-tools.js +8 -0
  74. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  75. package/dist/capabilities/sandbox-file-send.js +91 -3
  76. package/dist/capabilities/scenarios.d.ts +130 -0
  77. package/dist/capabilities/scenarios.js +180 -7
  78. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  79. package/dist/capabilities/select-environment-tool.js +30 -0
  80. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  81. package/dist/capabilities/send-user-file-tool.js +65 -1
  82. package/dist/capabilities/skills.d.ts +29 -0
  83. package/dist/capabilities/skills.js +13 -2
  84. package/dist/capabilities/team.d.ts +22 -0
  85. package/dist/capabilities/team.js +22 -2
  86. package/dist/capabilities/tool-defer.d.ts +26 -0
  87. package/dist/capabilities/tool-defer.js +3 -0
  88. package/dist/config-center/apply-effective.d.ts +65 -0
  89. package/dist/config-center/apply-effective.js +204 -12
  90. package/dist/config-center/http-client.d.ts +34 -0
  91. package/dist/config-center/http-client.js +68 -0
  92. package/dist/config-center/restart-signal.d.ts +22 -0
  93. package/dist/config-center/restart-signal.js +39 -0
  94. package/dist/config-center/skills-mcp.d.ts +20 -1
  95. package/dist/config-center/skills-mcp.js +42 -7
  96. package/dist/config-center/types.d.ts +92 -1
  97. package/dist/config-lkg.d.ts +12 -0
  98. package/dist/config-lkg.js +41 -0
  99. package/dist/config-provider.d.ts +78 -0
  100. package/dist/config-provider.js +165 -2
  101. package/dist/config-types.d.ts +546 -0
  102. package/dist/config.d.ts +64 -0
  103. package/dist/config.js +455 -60
  104. package/dist/degenerate-instrument.d.ts +38 -0
  105. package/dist/degenerate-instrument.js +55 -3
  106. package/dist/elicitation.d.ts +39 -0
  107. package/dist/elicitation.js +87 -3
  108. package/dist/env-facts.d.ts +61 -0
  109. package/dist/env-facts.js +73 -7
  110. package/dist/fleet/fleet-bus.d.ts +185 -0
  111. package/dist/fleet/fleet-bus.js +333 -27
  112. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  113. package/dist/fleet/subagent-tail-bus.js +33 -2
  114. package/dist/fleet-client.d.ts +38 -0
  115. package/dist/fleet-client.js +44 -9
  116. package/dist/fleet-lease.d.ts +46 -0
  117. package/dist/fleet-lease.js +73 -5
  118. package/dist/hooks/branch-transcript.d.ts +8 -0
  119. package/dist/hooks/branch-transcript.js +33 -0
  120. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  121. package/dist/hooks/cc-stop-prompt.js +43 -1
  122. package/dist/hooks/hook-llm.d.ts +15 -0
  123. package/dist/hooks/hook-llm.js +47 -0
  124. package/dist/hooks/hook-runner.d.ts +89 -0
  125. package/dist/hooks/hook-runner.js +327 -18
  126. package/dist/http/idempotency.d.ts +31 -0
  127. package/dist/http/idempotency.js +34 -0
  128. package/dist/http/principal-gate.d.ts +17 -0
  129. package/dist/http/principal-gate.js +35 -3
  130. package/dist/http/route-ctx.d.ts +36 -0
  131. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  132. package/dist/http/routes/approvals-assistant.js +253 -23
  133. package/dist/http/routes/attachments.js +22 -4
  134. package/dist/http/routes/capabilities.d.ts +7 -0
  135. package/dist/http/routes/capabilities.js +202 -1
  136. package/dist/http/routes/fleet.d.ts +6 -0
  137. package/dist/http/routes/fleet.js +94 -5
  138. package/dist/http/routes/images.d.ts +17 -0
  139. package/dist/http/routes/images.js +222 -14
  140. package/dist/http/routes/leader.d.ts +7 -0
  141. package/dist/http/routes/leader.js +10 -0
  142. package/dist/http/routes/memory-policy.d.ts +6 -0
  143. package/dist/http/routes/memory-policy.js +38 -6
  144. package/dist/http/routes/notify-wake.d.ts +10 -0
  145. package/dist/http/routes/notify-wake.js +19 -3
  146. package/dist/http/routes/observability.d.ts +6 -0
  147. package/dist/http/routes/observability.js +19 -2
  148. package/dist/http/routes/runs.d.ts +15 -0
  149. package/dist/http/routes/runs.js +464 -41
  150. package/dist/http/routes/session-sync.d.ts +15 -0
  151. package/dist/http/routes/session-sync.js +229 -19
  152. package/dist/http/routes/sessions-list.d.ts +6 -0
  153. package/dist/http/routes/sessions-list.js +35 -4
  154. package/dist/http/routes/sessions.d.ts +14 -0
  155. package/dist/http/routes/sessions.js +176 -31
  156. package/dist/http/routes/side-query.d.ts +8 -0
  157. package/dist/http/routes/side-query.js +26 -1
  158. package/dist/http/routes/tasks.d.ts +18 -0
  159. package/dist/http/routes/tasks.js +501 -38
  160. package/dist/http/routes/trace-usage.d.ts +10 -0
  161. package/dist/http/routes/trace-usage.js +66 -14
  162. package/dist/http/routes/workflows.d.ts +12 -0
  163. package/dist/http/routes/workflows.js +180 -19
  164. package/dist/http/run-meta.d.ts +11 -0
  165. package/dist/http/run-meta.js +6 -0
  166. package/dist/http/send.d.ts +19 -0
  167. package/dist/http/send.js +11 -0
  168. package/dist/http/server.d.ts +255 -0
  169. package/dist/http/server.js +921 -75
  170. package/dist/http/sse-log.d.ts +15 -0
  171. package/dist/http/sse-log.js +16 -0
  172. package/dist/http/tar.d.ts +9 -0
  173. package/dist/http/tar.js +21 -5
  174. package/dist/http/wire-gate.d.ts +9 -0
  175. package/dist/http/wire-gate.js +9 -0
  176. package/dist/http/wire-types.d.ts +187 -0
  177. package/dist/http/workspace-content.d.ts +8 -0
  178. package/dist/http/workspace-content.js +10 -0
  179. package/dist/images/bake-validate.d.ts +63 -0
  180. package/dist/images/bake-validate.js +71 -1
  181. package/dist/images/manifest.d.ts +19 -0
  182. package/dist/images/manifest.js +6 -1
  183. package/dist/index.d.ts +1 -5
  184. package/dist/index.js +10 -5
  185. package/dist/key-resolver.d.ts +23 -0
  186. package/dist/key-resolver.js +27 -2
  187. package/dist/leader/diffout.d.ts +23 -0
  188. package/dist/leader/diffout.js +8 -1
  189. package/dist/leader/diffup.d.ts +32 -0
  190. package/dist/leader/diffup.js +43 -0
  191. package/dist/leader/endpoint.d.ts +20 -0
  192. package/dist/leader/endpoint.js +25 -2
  193. package/dist/leader/fanout.d.ts +60 -0
  194. package/dist/leader/fanout.js +29 -3
  195. package/dist/leader/grader-env-factory.d.ts +74 -0
  196. package/dist/leader/grader-env-factory.js +62 -3
  197. package/dist/leader/leader.d.ts +97 -0
  198. package/dist/leader/leader.js +151 -4
  199. package/dist/leader/merge.d.ts +94 -0
  200. package/dist/leader/merge.js +112 -9
  201. package/dist/leader/planner.d.ts +52 -0
  202. package/dist/leader/planner.js +47 -3
  203. package/dist/leader/repair-oracle.d.ts +61 -0
  204. package/dist/leader/repair-oracle.js +59 -1
  205. package/dist/leader/repair-wire.d.ts +78 -0
  206. package/dist/leader/repair-wire.js +79 -2
  207. package/dist/leader/wire.d.ts +79 -0
  208. package/dist/leader/wire.js +255 -8
  209. package/dist/lsp/e2b-bridge.d.ts +16 -0
  210. package/dist/lsp/e2b-bridge.js +32 -4
  211. package/dist/lsp/e2b-manager.d.ts +10 -0
  212. package/dist/lsp/e2b-manager.js +18 -2
  213. package/dist/lsp/lsp-frames.d.ts +12 -0
  214. package/dist/lsp/lsp-frames.js +12 -0
  215. package/dist/lsp/manager.d.ts +12 -0
  216. package/dist/lsp/manager.js +35 -2
  217. package/dist/lsp/types.d.ts +10 -0
  218. package/dist/lsp/ws-transport.d.ts +12 -0
  219. package/dist/lsp/ws-transport.js +53 -5
  220. package/dist/lsp-evict.d.ts +14 -0
  221. package/dist/lsp-evict.js +15 -1
  222. package/dist/main.js +2132 -96
  223. package/dist/memory-export.d.ts +1 -0
  224. package/dist/memory-export.js +4 -0
  225. package/dist/memory-scope.d.ts +49 -0
  226. package/dist/memory-scope.js +87 -4
  227. package/dist/memory-sync-client.d.ts +24 -0
  228. package/dist/memory-sync-client.js +41 -2
  229. package/dist/memory-sync.d.ts +23 -0
  230. package/dist/memory-sync.js +70 -1
  231. package/dist/model-select.d.ts +39 -0
  232. package/dist/model-select.js +42 -1
  233. package/dist/observability/cost-quota.d.ts +20 -0
  234. package/dist/observability/cost-quota.js +4 -0
  235. package/dist/observability/cost-taxonomy.d.ts +45 -0
  236. package/dist/observability/cost-taxonomy.js +34 -0
  237. package/dist/observability/logger.d.ts +1 -0
  238. package/dist/observability/logger.js +6 -0
  239. package/dist/observability/metrics.d.ts +13 -0
  240. package/dist/observability/metrics.js +63 -0
  241. package/dist/observability/otel-exporter.d.ts +9 -0
  242. package/dist/observability/otel-exporter.js +11 -3
  243. package/dist/observability/principal-context.d.ts +9 -0
  244. package/dist/observability/principal-context.js +9 -0
  245. package/dist/observability/prompt-manifest.d.ts +37 -0
  246. package/dist/observability/prompt-manifest.js +35 -1
  247. package/dist/observability/rate-limit.d.ts +10 -0
  248. package/dist/observability/rate-limit.js +1 -0
  249. package/dist/observability/tool-trace.d.ts +24 -0
  250. package/dist/observability/tool-trace.js +41 -1
  251. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  252. package/dist/orchestration/hardened-vm-runner.js +119 -4
  253. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  254. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  255. package/dist/orchestration/hardened-vm-worker.js +27 -0
  256. package/dist/orchestration/subagent-steer.d.ts +44 -0
  257. package/dist/orchestration/subagent-steer.js +45 -1
  258. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  259. package/dist/orchestration/workflow-agent-steer.js +80 -1
  260. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  261. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  262. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  263. package/dist/orchestration/workflow-notify-journal.js +187 -13
  264. package/dist/parked-decide.d.ts +61 -0
  265. package/dist/parked-decide.js +58 -1
  266. package/dist/per-task-image.d.ts +54 -0
  267. package/dist/per-task-image.js +41 -0
  268. package/dist/plan-cache-probe.d.ts +35 -0
  269. package/dist/plan-cache-probe.js +18 -3
  270. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  271. package/dist/plugins/approval-exemption-store.js +28 -2
  272. package/dist/plugins/approval-store-sql.d.ts +64 -0
  273. package/dist/plugins/approval-store-sql.js +32 -0
  274. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  275. package/dist/plugins/background-agent-store-sql.js +91 -4
  276. package/dist/plugins/background-shell-support.d.ts +98 -0
  277. package/dist/plugins/background-shell-support.js +117 -13
  278. package/dist/plugins/blob-backend.d.ts +104 -0
  279. package/dist/plugins/blob-backend.js +163 -6
  280. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  281. package/dist/plugins/breaker-state-sql.js +46 -8
  282. package/dist/plugins/caching-session-store.d.ts +42 -0
  283. package/dist/plugins/caching-session-store.js +63 -3
  284. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  285. package/dist/plugins/checkpoint-store-sql.js +239 -11
  286. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  287. package/dist/plugins/file-outcome-sink.js +9 -0
  288. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  289. package/dist/plugins/file-resume-anchor-store.js +43 -4
  290. package/dist/plugins/file-run-store.d.ts +90 -0
  291. package/dist/plugins/file-run-store.js +145 -13
  292. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  293. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  294. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  295. package/dist/plugins/file-workflow-journal-store.js +10 -0
  296. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  297. package/dist/plugins/fork-routing-session-store.js +51 -3
  298. package/dist/plugins/host-platform.d.ts +69 -0
  299. package/dist/plugins/host-platform.js +81 -2
  300. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  301. package/dist/plugins/image-bake-store-sql.js +241 -7
  302. package/dist/plugins/image-index-sql.d.ts +46 -0
  303. package/dist/plugins/image-index-sql.js +113 -4
  304. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  305. package/dist/plugins/k8s-bg-scripts.js +88 -4
  306. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  307. package/dist/plugins/k8s-exec-protocol.js +41 -0
  308. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  309. package/dist/plugins/local-checkpoint-store.js +86 -7
  310. package/dist/plugins/local-session-store.d.ts +157 -0
  311. package/dist/plugins/local-session-store.js +289 -34
  312. package/dist/plugins/local-task-attachment-store.js +14 -2
  313. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  314. package/dist/plugins/mailbox-store-sql.js +39 -6
  315. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  316. package/dist/plugins/memory-engine-pg.js +122 -4
  317. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  318. package/dist/plugins/memory-engine-tidb.js +115 -5
  319. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  320. package/dist/plugins/memory-engine-vector-util.js +5 -0
  321. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  322. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  323. package/dist/plugins/memory-run-store.d.ts +63 -0
  324. package/dist/plugins/memory-run-store.js +73 -8
  325. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  326. package/dist/plugins/memory-session-policy-store.js +17 -0
  327. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  328. package/dist/plugins/memory-sync-store-pg.js +45 -2
  329. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  330. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  331. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  332. package/dist/plugins/outcome-ledger-sql.js +97 -3
  333. package/dist/plugins/pg-approval-store.d.ts +7 -0
  334. package/dist/plugins/pg-approval-store.js +7 -0
  335. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  336. package/dist/plugins/pg-breaker-state.js +6 -0
  337. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  338. package/dist/plugins/pg-checkpoint-store.js +8 -0
  339. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  340. package/dist/plugins/pg-cost-quota.js +6 -0
  341. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  342. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  343. package/dist/plugins/pg-image-bake.d.ts +9 -0
  344. package/dist/plugins/pg-image-bake.js +9 -0
  345. package/dist/plugins/pg-image-index.d.ts +9 -0
  346. package/dist/plugins/pg-image-index.js +9 -0
  347. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  348. package/dist/plugins/pg-outcome-ledger.js +9 -0
  349. package/dist/plugins/pg-pool.d.ts +50 -0
  350. package/dist/plugins/pg-pool.js +78 -0
  351. package/dist/plugins/pg-query.d.ts +11 -0
  352. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  353. package/dist/plugins/pg-rate-limiter.js +12 -2
  354. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  355. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  356. package/dist/plugins/pg-run-store.d.ts +7 -0
  357. package/dist/plugins/pg-run-store.js +7 -0
  358. package/dist/plugins/pg-safe-json.d.ts +13 -0
  359. package/dist/plugins/pg-safe-json.js +40 -4
  360. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  361. package/dist/plugins/pg-session-policy-store.js +5 -0
  362. package/dist/plugins/pg-session-storage.d.ts +72 -0
  363. package/dist/plugins/pg-session-storage.js +152 -20
  364. package/dist/plugins/pg-session-store.d.ts +10 -0
  365. package/dist/plugins/pg-session-store.js +10 -0
  366. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  367. package/dist/plugins/pg-tool-result-store.js +7 -0
  368. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  369. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  370. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  371. package/dist/plugins/pg-workflow-run-store.js +7 -0
  372. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  373. package/dist/plugins/posix-shell-fs.js +31 -1
  374. package/dist/plugins/remote-env-adb.d.ts +25 -0
  375. package/dist/plugins/remote-env-adb.js +95 -12
  376. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  377. package/dist/plugins/remote-env-e2b.js +371 -40
  378. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  379. package/dist/plugins/remote-env-file-error.js +37 -0
  380. package/dist/plugins/remote-env-host.d.ts +151 -0
  381. package/dist/plugins/remote-env-host.js +468 -70
  382. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  383. package/dist/plugins/remote-env-k8s.js +318 -32
  384. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  385. package/dist/plugins/remote-env-local-docker.js +149 -24
  386. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  387. package/dist/plugins/remote-env-ssh.js +117 -20
  388. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  389. package/dist/plugins/remote-scratchpad.js +32 -2
  390. package/dist/plugins/remote-shell.d.ts +22 -0
  391. package/dist/plugins/remote-shell.js +27 -1
  392. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  393. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  394. package/dist/plugins/roster-store-sql.d.ts +27 -0
  395. package/dist/plugins/roster-store-sql.js +54 -0
  396. package/dist/plugins/run-store-sql.d.ts +194 -0
  397. package/dist/plugins/run-store-sql.js +210 -9
  398. package/dist/plugins/s3-presign.d.ts +20 -0
  399. package/dist/plugins/s3-presign.js +49 -2
  400. package/dist/plugins/scheduler-support.d.ts +12 -0
  401. package/dist/plugins/scheduler-support.js +75 -3
  402. package/dist/plugins/send-file-ledger.d.ts +15 -0
  403. package/dist/plugins/send-file-ledger.js +53 -4
  404. package/dist/plugins/send-user-file.d.ts +77 -0
  405. package/dist/plugins/send-user-file.js +92 -4
  406. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  407. package/dist/plugins/session-policy-store-sql.js +75 -3
  408. package/dist/plugins/session-store.d.ts +45 -0
  409. package/dist/plugins/session-store.js +51 -0
  410. package/dist/plugins/sql-driver.d.ts +77 -0
  411. package/dist/plugins/sql-driver.js +4 -0
  412. package/dist/plugins/sql-escape.d.ts +8 -0
  413. package/dist/plugins/sql-escape.js +8 -0
  414. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  415. package/dist/plugins/sql-row-helpers.js +25 -0
  416. package/dist/plugins/store-backend.d.ts +103 -0
  417. package/dist/plugins/store-backend.js +120 -27
  418. package/dist/plugins/store-contracts.d.ts +62 -0
  419. package/dist/plugins/store-contracts.js +3 -0
  420. package/dist/plugins/task-attachment-store.d.ts +60 -0
  421. package/dist/plugins/task-attachment-store.js +49 -3
  422. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  423. package/dist/plugins/task-list-store-sql.js +21 -0
  424. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  425. package/dist/plugins/tidb-approval-store.js +6 -0
  426. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  427. package/dist/plugins/tidb-breaker-state.js +5 -0
  428. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  429. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  430. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  431. package/dist/plugins/tidb-cost-quota.js +1 -0
  432. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  433. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  434. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  435. package/dist/plugins/tidb-image-bake.js +8 -0
  436. package/dist/plugins/tidb-image-index.d.ts +8 -0
  437. package/dist/plugins/tidb-image-index.js +8 -0
  438. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  439. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  440. package/dist/plugins/tidb-pool.d.ts +56 -0
  441. package/dist/plugins/tidb-pool.js +181 -1
  442. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  443. package/dist/plugins/tidb-rate-limiter.js +5 -2
  444. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  445. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  446. package/dist/plugins/tidb-run-store.d.ts +7 -0
  447. package/dist/plugins/tidb-run-store.js +7 -0
  448. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  449. package/dist/plugins/tidb-session-policy-store.js +5 -0
  450. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  451. package/dist/plugins/tidb-session-storage.js +62 -3
  452. package/dist/plugins/tidb-session-store.d.ts +142 -0
  453. package/dist/plugins/tidb-session-store.js +264 -16
  454. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  455. package/dist/plugins/tidb-tool-result-store.js +7 -0
  456. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  457. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  458. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  459. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  460. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  461. package/dist/plugins/tool-result-store-sql.js +38 -2
  462. package/dist/plugins/web-search.d.ts +35 -0
  463. package/dist/plugins/web-search.js +45 -9
  464. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  465. package/dist/plugins/workflow-journal-limits.js +10 -0
  466. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  467. package/dist/plugins/workflow-journal-store-sql.js +58 -2
  468. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  469. package/dist/plugins/workflow-run-store-sql.js +84 -6
  470. package/dist/plugins/worktree-isolation.d.ts +45 -0
  471. package/dist/plugins/worktree-isolation.js +105 -6
  472. package/dist/plugins/write-behind-counter.d.ts +56 -1
  473. package/dist/plugins/write-behind-counter.js +53 -14
  474. package/dist/principal-jwt.d.ts +24 -0
  475. package/dist/principal-jwt.js +60 -5
  476. package/dist/project-memory.d.ts +22 -0
  477. package/dist/project-memory.js +144 -15
  478. package/dist/prompts-domain-validate.d.ts +28 -0
  479. package/dist/prompts-domain-validate.js +42 -1
  480. package/dist/question.d.ts +33 -0
  481. package/dist/question.js +69 -2
  482. package/dist/resource-suspend.d.ts +21 -0
  483. package/dist/resource-suspend.js +16 -0
  484. package/dist/router/route-orchestration.d.ts +78 -0
  485. package/dist/router/route-orchestration.js +77 -0
  486. package/dist/run-local.d.ts +32 -0
  487. package/dist/run-local.js +172 -8
  488. package/dist/runs.d.ts +189 -4
  489. package/dist/runs.js +465 -24
  490. package/dist/runtime-caps-resolver.d.ts +106 -0
  491. package/dist/runtime-caps-resolver.js +89 -4
  492. package/dist/runtime-governance.d.ts +84 -0
  493. package/dist/runtime-governance.js +127 -1
  494. package/dist/sandbox-pkg-source.d.ts +23 -0
  495. package/dist/sandbox-pkg-source.js +37 -0
  496. package/dist/sealed-key.d.ts +54 -0
  497. package/dist/sealed-key.js +68 -3
  498. package/dist/security.d.ts +108 -0
  499. package/dist/security.js +145 -6
  500. package/dist/sema-registry.d.ts +21 -0
  501. package/dist/sema-registry.js +21 -0
  502. package/dist/session-leaf-bus.d.ts +31 -0
  503. package/dist/session-leaf-bus.js +32 -0
  504. package/dist/session-sync-content.d.ts +46 -0
  505. package/dist/session-sync-content.js +47 -1
  506. package/dist/session-sync-kernel.d.ts +89 -0
  507. package/dist/session-sync-kernel.js +48 -3
  508. package/dist/session-sync.d.ts +125 -0
  509. package/dist/session-sync.js +181 -8
  510. package/dist/session-titler.d.ts +26 -0
  511. package/dist/session-titler.js +41 -7
  512. package/dist/session-watch.d.ts +53 -1
  513. package/dist/session-watch.js +73 -9
  514. package/dist/sighup-idle.d.ts +30 -0
  515. package/dist/sighup-idle.js +12 -1
  516. package/dist/spec-fields.d.ts +91 -3
  517. package/dist/spec-fields.js +116 -4
  518. package/dist/task-cwd.d.ts +50 -0
  519. package/dist/task-cwd.js +68 -1
  520. package/dist/task-mcp.d.ts +47 -0
  521. package/dist/task-mcp.js +29 -0
  522. package/dist/task-settings.d.ts +175 -0
  523. package/dist/task-settings.js +226 -11
  524. package/dist/task-workflow.d.ts +67 -0
  525. package/dist/task-workflow.js +75 -8
  526. package/dist/tool-approval.d.ts +91 -0
  527. package/dist/tool-approval.js +215 -0
  528. package/dist/trace/artifacts.d.ts +9 -0
  529. package/dist/trace/artifacts.js +30 -5
  530. package/dist/trace/core-keyset-guard.d.ts +18 -0
  531. package/dist/trace/ledger-sink.d.ts +43 -0
  532. package/dist/trace/ledger-sink.js +64 -5
  533. package/dist/trace/project.d.ts +133 -0
  534. package/dist/trace/project.js +189 -2
  535. package/dist/trace/redact.d.ts +19 -0
  536. package/dist/trace/redact.js +66 -9
  537. package/dist/usage-analytics.d.ts +26 -0
  538. package/dist/usage-analytics.js +26 -3
  539. package/package.json +1 -1
@@ -2,6 +2,7 @@ import { SchedulerError } from "@sema-agent/core";
2
2
  import type { SchedulerCapability, ScheduledIntent, SchedulerContext, ScheduledTaskId, ScheduledTaskSummary } from "@sema-agent/core";
3
3
  import type { SchedulerRecord } from "@sema-agent/registry-core/scheduler-store";
4
4
  export type { SchedulerRecord };
5
+ /** core `Result<T,E>` shape (harness/types) — `{ok:true,value} | {ok:false,error}`. */
5
6
  type Result<T, E> = {
6
7
  ok: true;
7
8
  value: T;
@@ -9,6 +10,7 @@ type Result<T, E> = {
9
10
  ok: false;
10
11
  error: E;
11
12
  };
13
+ /** Default caps (fail-closed bounds; design/105 §3.9). Override per deployment. */
12
14
  export declare const DEFAULT_SCHEDULER_CAPS: {
13
15
  readonly supported: true;
14
16
  readonly maxScheduledPerScope: 32;
@@ -19,8 +21,18 @@ export declare const DEFAULT_SCHEDULER_CAPS: {
19
21
  readonly supportsSessionWakeup: true;
20
22
  };
21
23
  type Caps = SchedulerCapability["schedulerCapabilities"];
24
+ /**
25
+ * PURE validation of an intent against caps + now. Returns a SchedulerError or null (ok). No IO. Testable.
26
+ * cron via core `isValidCronExpr` (RCE-safe, no shell-exec); delay/at bounded by minDelaySec + horizon.
27
+ */
22
28
  export declare function validateIntent(intent: ScheduledIntent, caps: Caps, nowMs: number): SchedulerError | null;
29
+ /** The default shared store path: `SEMA_CONFIG_DIR` → `~/.sema`, file `scheduled_tasks.json` (server + shell agree). */
23
30
  export declare function defaultSchedulerStorePath(): string;
31
+ /**
32
+ * File-backed SchedulerCapability (durable across daemon restarts). Store = a single JSON file (atomic write via
33
+ * the registry-core /node binding). The resident shell daemon reads the same store to fire intents. `now`
34
+ * injectable for tests.
35
+ */
24
36
  export declare class FileSchedulerBackend implements SchedulerCapability {
25
37
  readonly schedulerCapabilities: Caps;
26
38
  private readonly storePath;
@@ -1,3 +1,28 @@
1
+ /**
2
+ * src/plugins/scheduler-support.ts — the server-side `SchedulerCapability` backend (R7 self-wake).
3
+ *
4
+ * core 1.165.0 ships the `SchedulerCapability` seam (design/105): core 出接口 + 工具壳 (现名 CronCreate/CronDelete/
5
+ * CronList——L8 订正:CronCancel 旧名、Sleep 已 design/136 撤除、挂载在 core prepare-task 非 createHandsToolkit,
6
+ * `hasScheduler(env)` 门不变) + the `hasScheduler` gate. **持久化 /
7
+ * cron 时钟 / idle 触发 / 起新 task 全在 backend** — core is request-driven, not resident. R7 splits the backend:
8
+ * - THIS file (server) = the SchedulerCapability impl: the WRITE side — schedule/cancel/list, persisted to the
9
+ * SHARED on-disk store. Injected into `RemoteHostExecutionEnv` (the TOC host lane). deps `@sema-agent/core` (fine
10
+ * server-side).
11
+ * - The TOC shell `SchedulerDaemon` (shell-host, design R7 part3b) = the READ side: a resident process that
12
+ * polls the SAME store, resolves cron, fires due intents via the SDK (principal pinned), and reaps.
13
+ *
14
+ * The shared on-disk FORMAT is the dep-free `@sema-agent/registry-core/scheduler-store` contract; the fs binding is
15
+ * `@sema-agent/registry-core/node`. server (writer) + shell daemon (reader) share ONE impl ⇒ zero format drift.
16
+ *
17
+ * Logic ported from the shell-host's canonical `scheduler/schedulerBackend.ts` (design doc
18
+ * `R7-scheduler-rewind.md` §1: the server reuses the same schedulerBackend logic verbatim).
19
+ *
20
+ * 🔴 红线 (design/105): `principal` is `ctx` (Runner-held) NOT `intent` (model-controllable) → pinned into the
21
+ * record, passed through to runTask unchanged by the daemon (no privilege escalation). cron via core
22
+ * `isValidCronExpr` (no shell-exec / RCE). scope isolation: cancel/list touch only the caller's scope. durable:
23
+ * the store is on disk (survives a daemon restart). upsert: same (scope, when, label) overwrites (idempotent on a
24
+ * tool retry).
25
+ */
1
26
  import { join } from "node:path";
2
27
  import { homedir } from "node:os";
3
28
  import { randomBytes, createHash } from "node:crypto";
@@ -5,15 +30,27 @@ import { SchedulerError, isValidCronExpr } from "@sema-agent/core";
5
30
  import { loadSchedulerStore, saveSchedulerStore } from "@sema-agent/registry-core/node";
6
31
  const ok = (value) => ({ ok: true, value });
7
32
  const err = (error) => ({ ok: false, error });
33
+ /** Default caps (fail-closed bounds; design/105 §3.9). Override per deployment. */
8
34
  export const DEFAULT_SCHEDULER_CAPS = {
9
35
  supported: true,
10
36
  maxScheduledPerScope: 32,
11
37
  minDelaySec: 10,
12
38
  minCronIntervalSec: 60,
13
- maxScheduledHorizonSec: 60 * 60 * 24 * 30,
39
+ maxScheduledHorizonSec: 60 * 60 * 24 * 30, // 30d
40
+ // core 1.301 CronCreate durable/session 分层 ([950]): session-scoped jobs are persisted with
41
+ // lifetime:"session" and reaped by the resident shell daemon when the session ends. True here because
42
+ // this backend faithfully persists the lifetime field (schedule() below) — without the flag core's
43
+ // CronCreate refuses durable:false up front (fail-closed at the tool layer).
14
44
  supportsSessionLifetime: true,
45
+ // core 1.309 ([1000]③ ScheduleWakeup 治本位): true = a resident daemon reads this store and fires
46
+ // session-wakeup records for its own sessions (the normal co-resident TOC shape). The DEPLOYMENT flips
47
+ // this to false via SCHEDULER_SESSION_WAKEUP=false when the spawning shell knows no daemon will honor
48
+ // them (headless spawn without a resident daemon) — core's ScheduleWakeup then refuses up front instead
49
+ // of parking a wakeup that never fires. Capability = instance-lifetime snapshot (core TOCTOU 契约条款),
50
+ // so the signal rides construction, never per-call.
15
51
  supportsSessionWakeup: true,
16
52
  };
53
+ /** Human-readable `when` summary for list(). */
17
54
  function whenSummary(when) {
18
55
  if (when.kind === "cron")
19
56
  return `cron ${when.expr}`;
@@ -21,16 +58,30 @@ function whenSummary(when) {
21
58
  return `at ${new Date(when.atMs).toISOString()}`;
22
59
  return `delay ${when.delaySec}s`;
23
60
  }
61
+ /** Upsert dedup key — same (scope, LANE, when, label) overwrites (idempotent on tool retry).
62
+ * The lane term is the lifetime identity (adversarial review F1): without it a session job and a durable
63
+ * job — or two different sessions' jobs — with the same (when, label) collide, and the daemon's
64
+ * session-end reap would then silently delete what USED to be a durable/other-session job. core's cron
65
+ * shorthand defaults to session lifetime with no label, so the collision is normal usage, not an edge. */
24
66
  function dedupKey(scope, intent, sessionId) {
25
67
  const lane = intent.lifetime === "session" ? `session:${sessionId ?? ""}` : "durable";
26
68
  return createHash("sha256").update(JSON.stringify([scope, lane, intent.when, intent.label ?? ""])).digest("hex").slice(0, 16);
27
69
  }
70
+ /**
71
+ * PURE validation of an intent against caps + now. Returns a SchedulerError or null (ok). No IO. Testable.
72
+ * cron via core `isValidCronExpr` (RCE-safe, no shell-exec); delay/at bounded by minDelaySec + horizon.
73
+ */
28
74
  export function validateIntent(intent, caps, nowMs) {
29
75
  if (!intent.prompt || typeof intent.prompt !== "string")
30
76
  return new SchedulerError("invalid_schedule", "prompt is required");
31
77
  const w = intent.when;
32
78
  const horizonMs = caps.maxScheduledHorizonSec * 1000;
33
79
  if (w.kind === "cron") {
80
+ // Validate the cron is WELL-FORMED (RCE-safe — the expr never reaches a shell). The `minCronIntervalSec` FLOOR is
81
+ // NOT enforced here: realizing a cron's actual fire interval requires cron-next, which the design assigns to the
82
+ // resident daemon (it computes nextRunMs + can skip/floor a sub-interval fire). A 5-field cron's minimum interval
83
+ // is 60s, so the default 60s floor is naturally satisfied; a deployment that TIGHTENS minCronIntervalSec relies on
84
+ // the daemon to honor it. (Adversarial-review LOW: the advertised cap is daemon-enforced, not writer-enforced.)
34
85
  if (!isValidCronExpr(w.expr))
35
86
  return new SchedulerError("invalid_schedule", `invalid cron expression: ${w.expr}`);
36
87
  }
@@ -52,6 +103,7 @@ export function validateIntent(intent, caps, nowMs) {
52
103
  }
53
104
  return null;
54
105
  }
106
+ /** nextRunMs for at/delay (direct); cron left undefined here (the resident daemon computes via a cron lib). */
55
107
  function computeNextRunMs(when, nowMs) {
56
108
  if (when.kind === "at")
57
109
  return when.atMs;
@@ -59,9 +111,15 @@ function computeNextRunMs(when, nowMs) {
59
111
  return nowMs + when.delaySec * 1000;
60
112
  return undefined;
61
113
  }
114
+ /** The default shared store path: `SEMA_CONFIG_DIR` → `~/.sema`, file `scheduled_tasks.json` (server + shell agree). */
62
115
  export function defaultSchedulerStorePath() {
63
116
  return join(process.env.SEMA_CONFIG_DIR ?? join(homedir(), ".sema"), "scheduled_tasks.json");
64
117
  }
118
+ /**
119
+ * File-backed SchedulerCapability (durable across daemon restarts). Store = a single JSON file (atomic write via
120
+ * the registry-core /node binding). The resident shell daemon reads the same store to fire intents. `now`
121
+ * injectable for tests.
122
+ */
65
123
  export class FileSchedulerBackend {
66
124
  schedulerCapabilities;
67
125
  storePath;
@@ -82,6 +140,8 @@ export class FileSchedulerBackend {
82
140
  const bad = validateIntent(intent, this.schedulerCapabilities, nowMs);
83
141
  if (bad)
84
142
  return err(bad);
143
+ // A session-scoped job with no session to bind to could never be reaped (a zombie the daemon would
144
+ // fire forever) — core's CronCreate refuses this at the tool layer; refuse here too for non-tool callers.
85
145
  if (intent.lifetime === "session" && !ctx.sessionId) {
86
146
  return err(new SchedulerError("invalid_schedule", 'lifetime:"session" requires a session to bind to (ctx.sessionId missing)'));
87
147
  }
@@ -91,6 +151,7 @@ export class FileSchedulerBackend {
91
151
  const rr = r;
92
152
  return r.scope === ctx.scope && dedupKey(r.scope, { when: r.when, label: r.label, lifetime: rr.lifetime }, r.sessionId) === key;
93
153
  });
154
+ // Per-scope cap (excluding the upsert target — overwriting an existing one doesn't grow the count).
94
155
  const scopeCount = records.filter((r) => r.scope === ctx.scope).length;
95
156
  if (existingIdx < 0 && scopeCount >= this.schedulerCapabilities.maxScheduledPerScope) {
96
157
  return err(new SchedulerError("limit_exceeded", `scope at cap (${this.schedulerCapabilities.maxScheduledPerScope})`));
@@ -99,12 +160,20 @@ export class FileSchedulerBackend {
99
160
  const rec = {
100
161
  id,
101
162
  scope: ctx.scope,
102
- ...(ctx.principal ? { principal: ctx.principal } : {}),
163
+ ...(ctx.principal ? { principal: ctx.principal } : {}), // 🔴 pinned from ctx (Runner-held), never intent
103
164
  ...(ctx.sessionId ? { sessionId: ctx.sessionId } : {}),
104
165
  prompt: intent.prompt,
105
166
  when: intent.when,
106
167
  ...(intent.label ? { label: intent.label } : {}),
168
+ // core 1.265 ScheduledIntent.mode(缺省 "task" 向后兼容):persist the execution shape —
169
+ // ScheduleWakeup's stop:true keys off the LIST face's mode echo (CC 206 D9); a dropped mode forced the
170
+ // shell onto its label fallback. registry-core SchedulerRecord optional fields are additive by contract.
107
171
  ...(intent.mode ? { mode: intent.mode } : {}),
172
+ // core 1.301 lifetime/recurring ([950]/[954]): persist BOTH so the daemon can reap session-scoped
173
+ // jobs and delete a recurring:false cron after its first firing. Dropping them here was [954]-(b):
174
+ // the tool answered "once" while the record said nothing → the daemon fired forever. Additive
175
+ // SchedulerRecord fields (registry-core contract), same posture as `mode` above. recurring is a
176
+ // tri-state (undefined = cron default "fire every match") — persist only when explicitly set.
108
177
  ...(intent.lifetime ? { lifetime: intent.lifetime } : {}),
109
178
  ...(intent.recurring !== undefined ? { recurring: intent.recurring } : {}),
110
179
  createdMs: nowMs,
@@ -125,6 +194,7 @@ export class FileSchedulerBackend {
125
194
  async cancel(id, ctx) {
126
195
  const records = this.load();
127
196
  const idx = records.findIndex((r) => r.id === id);
197
+ // 🔴 scope isolation: a non-own-scope id is `not_found` (don't leak existence). Idempotent: missing = ok.
128
198
  if (idx < 0 || records[idx].scope !== ctx.scope)
129
199
  return ok(undefined);
130
200
  records.splice(idx, 1);
@@ -138,13 +208,15 @@ export class FileSchedulerBackend {
138
208
  }
139
209
  async list(ctx) {
140
210
  const summaries = this.load()
141
- .filter((r) => r.scope === ctx.scope)
211
+ .filter((r) => r.scope === ctx.scope) // 🔴 scope-scoped, not global
142
212
  .map((r) => ({
143
213
  id: r.id,
144
214
  when: whenSummary(r.when),
145
215
  ...(r.label ? { label: r.label } : {}),
146
216
  ...(r.nextRunMs !== undefined ? { nextRunMs: r.nextRunMs } : {}),
217
+ // echo the persisted mode (additive; pre-1.159.x records lack it → undefined = shell label fallback).
147
218
  ...(r.mode ? { mode: r.mode } : {}),
219
+ // echo lifetime/recurring (ScheduledTaskSummary 1.302 fields; absent on pre-1.215 records).
148
220
  ...(r.lifetime ? { lifetime: r.lifetime } : {}),
149
221
  ...(r.recurring !== undefined ? { recurring: r.recurring } : {}),
150
222
  }));
@@ -1,22 +1,29 @@
1
1
  import type { Pool as MysqlPool } from "mysql2/promise";
2
2
  import type { Pool as PgPool } from "pg";
3
3
  import type { IssuedFileLink } from "./send-user-file.js";
4
+ /** Ledger scope sentinel for single-user issuance (no principal) — mirrors scopeSegment's "_" key segment. */
4
5
  export declare const SENDFILE_SINGLE_USER_SCOPE = "_";
5
6
  export interface SendFileLedgerEntry {
7
+ /** uuidv7 — PK and the keyset cursor (time-ordered, newest = lexicographically greatest). */
6
8
  id: string;
9
+ /** Verified principal verbatim ("_" = single-user). NEVER derived from the hashed key segment (one-way). */
7
10
  scope: string;
8
11
  bucket: string;
9
12
  objectKey: string;
10
13
  track: "public" | "presigned";
11
14
  filename: string;
12
15
  size: number;
16
+ /** 0 = permanent (public track). */
13
17
  ttlSec: number;
14
18
  taskId?: string;
15
19
  sessionId?: string;
16
20
  createdAt: number;
17
21
  }
18
22
  export interface SendFileLedger {
23
+ /** Record one issued link. Idempotent on `id` (a retry after a lost ack must not duplicate). */
19
24
  record(entry: SendFileLedgerEntry): Promise<void>;
25
+ /** Newest-first page of one scope's links; keyset = `id < beforeId` (listSessions posture: fetch limit+1
26
+ * to detect more). `beforeId` absent = first page. */
20
27
  listByScope(scope: string, limit: number, beforeId?: string): Promise<SendFileLedgerEntry[]>;
21
28
  }
22
29
  export declare class TiDBSendFileLedger implements SendFileLedger {
@@ -43,15 +50,23 @@ export declare class FileSendFileLedger implements SendFileLedger {
43
50
  constructor(root: string);
44
51
  record(entry: SendFileLedgerEntry): Promise<void>;
45
52
  listByScope(scope: string, limit: number, beforeId?: string): Promise<SendFileLedgerEntry[]>;
53
+ /** Release the append-log fd (LocalBackend.close → graceful-restart re-open). */
46
54
  dispose(): void;
47
55
  }
48
56
  export interface LedgerRecordingDeps {
49
57
  ledger: SendFileLedger;
58
+ /** Best-effort reclaim of the uploaded object when the record fails (issuer.deleteObject). */
50
59
  deleteObject: (bucket: string, key: string) => Promise<void>;
51
60
  warn?: (msg: string, meta?: Record<string, unknown>) => void;
52
61
  now?: () => number;
53
62
  newId?: () => string;
54
63
  }
64
+ /**
65
+ * Wrap a lane `send` with the ledger write point: upload+verify succeed (the inner send resolved) → record →
66
+ * only then return (the tool emits the file_link frame strictly after). Record failure ⇒ fail-loud for THIS
67
+ * file + delete of the uploaded object with ONE retry; the throw is the contract either way, and its message
68
+ * states the true reclaim outcome (F2: a failed reclaim = permanent orphan, warned with coordinates).
69
+ */
55
70
  export declare function withLedgerRecording(send: (path: string, ctx: {
56
71
  taskId?: string;
57
72
  sessionId?: string;
@@ -1,6 +1,30 @@
1
+ /**
2
+ * SendUserFile server-side LEDGER (multi-tenant governance face, clay ruling 2026-07-14 — the second half of
3
+ * [768]②a: the object key carries a HASHED scope segment, so the store alone can't answer "which tenant sent
4
+ * what". This ledger is the scope↔object mapping the hash deliberately hides from URLs): one row per issued
5
+ * link, keyed by a uuidv7 `id` (time-ordered → keyset pagination), indexed by `scope` (the VERIFIED principal
6
+ * verbatim; "_" = the single-user sentinel, same as the checkpoint scope column).
7
+ *
8
+ * WRITE SEMANTICS (enforced by {@link withLedgerRecording}, wrapped around BOTH send lanes in main.ts): record
9
+ * AFTER upload+verify succeed and BEFORE the file_link frame is emitted. A record failure is FAIL-LOUD for that
10
+ * file (the governance face MUST have the row — a link the ledger can't see can't be listed or revoked) and the
11
+ * already-uploaded object is DELETED with one retry (a public-track object with no ledger row would be an
12
+ * unmanageable orphan); the thrown message reports the TRUE reclaim outcome (reclaimed vs orphan) but — 修4 —
13
+ * NEVER the coordinates or the cause (it is model-visible via the tool result; a bucket/key leak there would
14
+ * let the model rebuild the capability URL): those go to the operator log under a shared incident id.
15
+ *
16
+ * The ledger does NOT store URLs: the public-track URL is reconstructible from bucket+key, and a presigned-track
17
+ * URL is a decaying capability that would be expired by the time anyone lists it. Reads return metadata + key.
18
+ *
19
+ * Four twins behind one interface (the approval-exemption pattern): TiDB/PG = durable cross-replica SQL rows
20
+ * (`sendfile_link` table, DDL in tidb-pool.ts / pg-pool.ts); File = append-only JSONL hydrated on boot
21
+ * (fsync — a torn tail must not fabricate a row); Memory = tests / ephemeral.
22
+ */
1
23
  import { join } from "node:path";
2
24
  import { AppendLog, ensureDir, readJsonlRecords, uuidv7 } from "@sema-agent/core";
25
+ /** Ledger scope sentinel for single-user issuance (no principal) — mirrors scopeSegment's "_" key segment. */
3
26
  export const SENDFILE_SINGLE_USER_SCOPE = "_";
27
+ // ─── TiDB / MySQL twin ───────────────────────────────────────────────────────────────────────────────────
4
28
  export class TiDBSendFileLedger {
5
29
  pool;
6
30
  constructor(pool) {
@@ -8,7 +32,8 @@ export class TiDBSendFileLedger {
8
32
  }
9
33
  async record(entry) {
10
34
  await this.pool.query("INSERT INTO sendfile_link (id, scope, bucket, object_key, track, filename, byte_len, ttl_sec, task_id, session_id, created_at) " +
11
- "VALUES (?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE id = id", [entry.id, entry.scope, entry.bucket, entry.objectKey, entry.track, entry.filename, entry.size, entry.ttlSec, entry.taskId ?? null, entry.sessionId ?? null, new Date(entry.createdAt)]);
35
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE id = id", // idempotent on the uuidv7 PK (retry-safe no-op)
36
+ [entry.id, entry.scope, entry.bucket, entry.objectKey, entry.track, entry.filename, entry.size, entry.ttlSec, entry.taskId ?? null, entry.sessionId ?? null, new Date(entry.createdAt)]);
12
37
  }
13
38
  async listByScope(scope, limit, beforeId) {
14
39
  const [rows] = await this.pool.query("SELECT id, scope, bucket, object_key, track, filename, byte_len, ttl_sec, task_id, session_id, created_at FROM sendfile_link " +
@@ -16,6 +41,7 @@ export class TiDBSendFileLedger {
16
41
  return rows.map((r) => rowToEntry(r));
17
42
  }
18
43
  }
44
+ // ─── PG twin (dialect twin — $n placeholders + ON CONFLICT) ──────────────────────────────────────────────
19
45
  export class PgSendFileLedger {
20
46
  pool;
21
47
  constructor(pool) {
@@ -46,6 +72,7 @@ function rowToEntry(r) {
46
72
  createdAt: new Date(r.created_at).getTime(),
47
73
  };
48
74
  }
75
+ // ─── Memory twin (tests / ephemeral) ─────────────────────────────────────────────────────────────────────
49
76
  export class MemorySendFileLedger {
50
77
  byScope = new Map();
51
78
  async record(entry) {
@@ -55,7 +82,7 @@ export class MemorySendFileLedger {
55
82
  this.byScope.set(entry.scope, m);
56
83
  }
57
84
  if (!m.has(entry.id))
58
- m.set(entry.id, { ...entry });
85
+ m.set(entry.id, { ...entry }); // idempotent on id
59
86
  }
60
87
  async listByScope(scope, limit, beforeId) {
61
88
  const m = this.byScope.get(scope);
@@ -68,6 +95,7 @@ export class MemorySendFileLedger {
68
95
  .map((e) => ({ ...e }));
69
96
  }
70
97
  }
98
+ // ─── File twin (local lane — single append-only JSONL + boot hydrate, torn-tail-safe) ───────────────────
71
99
  export class FileSendFileLedger {
72
100
  path;
73
101
  mem = new MemorySendFileLedger();
@@ -77,6 +105,7 @@ export class FileSendFileLedger {
77
105
  ensureDir(dir);
78
106
  this.path = join(dir, "links.jsonl");
79
107
  for (const r of readJsonlRecords(this.path)) {
108
+ // hydrate defensively: a record without the identity triple can't be listed/revoked — skip, don't fabricate
80
109
  if (!r || typeof r.id !== "string" || typeof r.scope !== "string" || typeof r.objectKey !== "string")
81
110
  continue;
82
111
  void this.mem.record(r);
@@ -84,21 +113,29 @@ export class FileSendFileLedger {
84
113
  }
85
114
  async record(entry) {
86
115
  this.log ??= new AppendLog(this.path);
87
- this.log.append(entry, true);
116
+ this.log.append(entry, true); // fsync — the governance row must survive a crash
88
117
  await this.mem.record(entry);
89
118
  }
90
119
  listByScope(scope, limit, beforeId) {
91
120
  return this.mem.listByScope(scope, limit, beforeId);
92
121
  }
122
+ /** Release the append-log fd (LocalBackend.close → graceful-restart re-open). */
93
123
  dispose() {
94
124
  try {
95
125
  this.log?.close();
96
126
  }
97
127
  catch {
128
+ /* best-effort */
98
129
  }
99
130
  this.log = undefined;
100
131
  }
101
132
  }
133
+ /**
134
+ * Wrap a lane `send` with the ledger write point: upload+verify succeed (the inner send resolved) → record →
135
+ * only then return (the tool emits the file_link frame strictly after). Record failure ⇒ fail-loud for THIS
136
+ * file + delete of the uploaded object with ONE retry; the throw is the contract either way, and its message
137
+ * states the true reclaim outcome (F2: a failed reclaim = permanent orphan, warned with coordinates).
138
+ */
102
139
  export function withLedgerRecording(send, deps) {
103
140
  return async (path, ctx) => {
104
141
  const link = await send(path, ctx);
@@ -118,6 +155,18 @@ export function withLedgerRecording(send, deps) {
118
155
  });
119
156
  }
120
157
  catch (e) {
158
+ // Governance face MUST have the row — reclaim the object (an unledgered public object is unmanageable),
159
+ // then fail loud for this file. F2 (codex scope-ledger audit): the DELETE gets ONE retry (S3 DELETE is
160
+ // idempotent, so a transient blip degrades to a second attempt), and the thrown message reports the TRUE
161
+ // reclaim outcome — a failed reclaim is a PERMANENT ORPHAN (record failed + object still live) and must
162
+ // never be described as "reclaimed"; the warns carry the coordinates for manual cleanup.
163
+ // 修4 (三路复审): the THROWN message is MODEL-VISIBLE (the tool splices per-file errors into its result,
164
+ // and capabilities already expose the public endpoint) — bucket/key/underlying cause in it would let the
165
+ // model reconstruct the permanent capability URL of an object the governance face can't see. The message
166
+ // therefore carries only a fixed error code + a short incident id; coordinates and cause go to the
167
+ // OPERATOR log (warn) keyed by the same incident id.
168
+ // Backlog (deliberately not built here): a durable reclaim queue that retries beyond this request's
169
+ // lifetime — today the orphan is surfaced loudly (incident-tagged warns) and cleaned up by hand.
121
170
  const incident = (deps.newId ? deps.newId() : uuidv7()).replace(/-/g, "").slice(-12);
122
171
  let reclaimed = true;
123
172
  try {
@@ -125,7 +174,7 @@ export function withLedgerRecording(send, deps) {
125
174
  await deps.deleteObject(link.bucket, link.key);
126
175
  }
127
176
  catch {
128
- await deps.deleteObject(link.bucket, link.key);
177
+ await deps.deleteObject(link.bucket, link.key); // one retry: transient-fault degrade
129
178
  }
130
179
  }
131
180
  catch (de) {
@@ -1,42 +1,119 @@
1
+ /** SigV4 physical ceiling (AWS: X-Amz-Expires max 604800s = 7 days). */
1
2
  export declare const PRESIGN_MAX_TTL_SEC = 604800;
3
+ /**
4
+ * Multi-tenant governance (clay ruling 2026-07-14, blackboard [768]② variant a with a HASHED segment): every
5
+ * object key carries a per-tenant SCOPE SEGMENT so tenants can be listed/revoked by prefix on the store itself,
6
+ * WITHOUT leaking the principal into the (user-visible, forwardable) URL. The segment is
7
+ * `HMAC-SHA256(secretKey, "sendfile-scope:" + scope)` hex, truncated to 32 chars:
8
+ * - keyed on the S3 SECRET KEY — server-held and stable, so the mapping is deterministic per deployment but
9
+ * unforgeable/unenumerable from outside (a URL holder cannot test principal guesses without the key);
10
+ * - the "sendfile-scope:" DOMAIN SEPARATOR pins this HMAC use — the same secret signs SigV4 requests, and a
11
+ * cross-protocol collision between "scope segment" and any other HMAC-of-attacker-controlled-string use is
12
+ * exactly what domain separation exists to prevent;
13
+ * - 32 hex chars (128 bits) is a NAMESPACE label, not a secret: the cross-tenant BIRTHDAY bound at even a
14
+ * billion tenants is ~n²/2^129 ≈ 2^-69 — negligible. (The earlier 16-hex/64-bit cut had a ~2.7% birthday
15
+ * collision probability at that scale — n²/2^65, NOT the per-pair 2^-32 the old note claimed; codex audit
16
+ * F4, widened pre-release at zero cost.) Capability secrecy still lives in the uuidv7 segment. Key budget
17
+ * stays comfortable: worst-case private-track key = 9 ("sendfile/") + 32 + 1 + 36 + 1 + 128 = 207 chars,
18
+ * under both sendfile_link.object_key VARCHAR(512) and S3's 1024-byte key ceiling.
19
+ * scope undefined/"" (single-user deployments have no principal) → the literal "_" sentinel (same sentinel the
20
+ * checkpoint scope column uses for anonymous), so the key SHAPE is uniform across deployments.
21
+ * ⚠️ Objects issued before 1.190.0 have NO scope segment (`<uuidv7>/<name>`); they stay valid — the segment is
22
+ * purely additive (URLs are capability-complete either way), zero migration.
23
+ */
2
24
  export declare function scopeSegment(secretKey: string, scope: string | undefined): string;
3
25
  export interface SendUserFileConfig {
26
+ /** Internal S3/MinIO endpoint the SERVER uploads through (adapter-held creds never leave the server). */
4
27
  endpoint: string;
28
+ /** Public base URL users reach (files. subdomain / NodePort / CDN). Absent ⇒ issue() fail-louds with the fix. */
5
29
  publicEndpoint?: string;
30
+ /** Anonymous-GET bucket for the permanent track. */
6
31
  publicBucket: string;
32
+ /** Private bucket for the presigned track. */
7
33
  privateBucket: string;
34
+ /** Key prefix inside the private bucket (keeps sendfile objects apart from snapshot blobs). */
8
35
  privateKeyPrefix: string;
36
+ /** v2: endpoint the SANDBOX uploads through (presigned PUT Host-binding). Default = publicEndpoint —
37
+ * an e2b cloud sandbox can only reach the public face; an in-cluster k8s pod may prefer the internal
38
+ * endpoint (SEND_USER_FILE_SANDBOX_PUT_ENDPOINT). */
9
39
  sandboxPutEndpoint?: string;
10
40
  accessKey: string;
11
41
  secretKey: string;
12
42
  region?: string;
43
+ /** Default ttl when the tool call omits it. 0 = permanent (the settled default). */
13
44
  defaultTtlSec: number;
14
45
  }
15
46
  export interface IssuedFileLink {
16
47
  url: string;
17
48
  filename: string;
18
49
  size: number;
50
+ /** 0 = permanent (public track). */
19
51
  ttlSec: number;
20
52
  track: "public" | "presigned";
21
53
  bucket: string;
22
54
  key: string;
55
+ /** The ORIGINAL tenant scope this link was issued under (verbatim, for the server-side ledger — the KEY only
56
+ * carries the hashed segment). Absent on single-user issuance (no principal). */
23
57
  scope?: string;
24
58
  }
59
+ /**
60
+ * Collapse an arbitrary client-supplied name to ONE safe path segment: strip directories (both
61
+ * separators), control/bidi characters (the session-title sanitize class), leading dots (no hidden
62
+ * files / no "." ".."), and cap the length (S3 key segment budget; keep the extension when truncating).
63
+ * Empty in ⇒ "file".
64
+ */
25
65
  export declare function sanitizeSendFileName(name: string | undefined): string;
66
+ /** v2 (sandbox direct-upload, clay 2026-07-14): the two-phase face. `prepare` mints the FINAL object key
67
+ * plus a short-lived single-object presigned PUT on a separate STAGING key (the sandbox `curl -T`s the
68
+ * file itself — bytes never relay through the server, creds never enter the sandbox); `finalize` mints the
69
+ * user-facing link for the FINAL key. The PUT URL is a capability secret scoped to one object+method+TTL —
70
+ * callers must keep it out of model context and redact it from errors/logs (adapter posture,
71
+ * remote-env-k8s redactPresigned).
72
+ *
73
+ * STAGING two-phase (修3, closes the 1.190 Plan B residual): the PUT URL rides the sandbox exec argv, so
74
+ * any process in the sandbox can read it via /proc and re-PUT while it is valid (120s) — previously that
75
+ * meant overwriting the FINAL object AFTER server-side verification, i.e. after the user got the link.
76
+ * Now the sandbox can only ever write the staging key (`<privateKeyPrefix>staging/<seg>/<uuidv7>` in the
77
+ * PRIVATE bucket — never exposed as a public URL); the server CopyObjects it to the final random key with
78
+ * its own creds (the sandbox never sees a write capability for that key), deletes the staging object, and
79
+ * verifies size on the now-immutable final object. A late re-PUT of the expired-or-not staging URL can no
80
+ * longer touch what the user's link points at. */
26
81
  export interface PreparedDirectUpload {
82
+ /** Presigned PUT the sandbox uploads through — the STAGING key (single object, method-bound, short TTL);
83
+ * never the final key, which no sandbox-visible write capability ever exists for. */
27
84
  putUrl: string;
85
+ /** SERVER-side post-upload accounting (codex review: the in-sandbox stat is advisory — the sandbox owns
86
+ * its filesystem and the presigned PUT is UNSIGNED-PAYLOAD, so nothing binds the uploaded byte count).
87
+ * Runs the staging→final promotion with adapter creds via the internal endpoint: HEAD staging (missing ⇒
88
+ * throw — claimed upload didn't land; over-cap ⇒ DELETE staging, throw), CopyObject staging→final, DELETE
89
+ * staging, then an authoritative HEAD of the FINAL object (whose size the card must carry — the copy is
90
+ * what pins the bytes). 修2: EVERY failure past the object landing reclaims best-effort (staging and/or
91
+ * final) before throwing — a transient HEAD 5xx must not leave an unledgered orphan. */
28
92
  verifySize(maxBytes: number): Promise<number>;
93
+ /** Mint the user-facing link once the upload is verified. `size` = verifySize's reading. */
29
94
  finalize(size: number): IssuedFileLink;
30
95
  }
31
96
  export interface SendUserFileIssuer {
97
+ /** Upload bytes and mint the user-facing URL. Throws (fail-loud, typed message) on config/物理 limits.
98
+ * `scope` = the caller's VERIFIED principal (multi-tenant); it keys the hashed scope segment in the object
99
+ * key and rides back verbatim on IssuedFileLink.scope for the ledger. Omit on single-user. */
32
100
  issue(bytes: Uint8Array, filename: string | undefined, ttlSec?: number, scope?: string): Promise<IssuedFileLink>;
101
+ /** v2: mint a presigned PUT for a sandbox-side direct upload (no bytes through the server). Same `scope`
102
+ * semantics as issue() — prepare and finalize share ONE key, so the segment is fixed at prepare time. */
33
103
  prepareDirectUpload(filename: string | undefined, ttlSec?: number, scope?: string): PreparedDirectUpload;
104
+ /** Best-effort object reclaim (ledger fail-loud path: an uploaded object whose ledger record failed would be
105
+ * an unmanageable orphan — delete it). Signed DELETE against the INTERNAL endpoint with adapter creds. */
34
106
  deleteObject(bucket: string, key: string): Promise<void>;
107
+ /** The public endpoint web clients need for rendering context (bootstrap/capabilities透出). */
35
108
  readonly publicEndpoint: string | undefined;
36
109
  }
37
110
  export declare function createSendUserFileIssuer(cfg: SendUserFileConfig, deps?: {
111
+ /** Injectable upload (tests). Default = SigV4 presigned PUT against the INTERNAL endpoint + fetch. */
38
112
  upload?: (bucket: string, key: string, bytes: Uint8Array) => Promise<void>;
113
+ /** Injectable post-direct-upload accounting (tests). Default = HEAD (+ DELETE when over cap) against
114
+ * the INTERNAL endpoint with adapter creds. Returns the object's real size. */
39
115
  verify?: (bucket: string, key: string, maxBytes: number) => Promise<number>;
116
+ /** Injectable object delete (tests). Default = signed DELETE against the INTERNAL endpoint. */
40
117
  remove?: (bucket: string, key: string) => Promise<void>;
41
118
  now?: () => Date;
42
119
  }): SendUserFileIssuer;