@sema-agent/server 1.322.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 +59 -3
  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
package/dist/budget.d.ts CHANGED
@@ -1,11 +1,29 @@
1
+ /**
2
+ * Cost / budget / trace wiring for the Runner (core 1.37) — pure, testable helpers kept out of the
3
+ * auto-running main.ts:
4
+ * ③ buildPricing — Model.cost catalog → injected ModelPricing (authoritative costMicroUsd).
5
+ * ④ createTracer — core's content-free TraceEvents → /metrics (spend, first-token, tool calls).
6
+ * ⑤ cappedCeiling — clamp a caller's requested per-task budget DOWN to the operator ceiling.
7
+ */
1
8
  import { type Model, type ModelPricing, type TracerHook } from "@sema-agent/core";
2
9
  import type { Metrics } from "./observability/metrics.js";
3
10
  import type { QuotaTracker } from "./observability/cost-quota.js";
4
11
  import type { FleetUsageAccumulator } from "./fleet-client.js";
5
12
  import type { FleetLeaseManager } from "./fleet-lease.js";
6
13
  import { type PromptManifestTracker } from "./observability/prompt-manifest.js";
14
+ /** ③ Per-model pricing keyed by model id (core falls back to each Model.cost when a model is absent). */
7
15
  export declare function buildPricing(models: Record<string, Model>): Record<string, ModelPricing>;
16
+ /**
17
+ * Bound the cardinality of a free-form metric label value (BL-11/BL-21). A label fed by untrusted/unbounded
18
+ * input — MCP tool names (a misconfigured/malicious server can emit thousands of dynamic names) or center
19
+ * model ids (a malformed roster) — would otherwise mint an unbounded number of metric series: a slow memory
20
+ * leak in the registry + a /metrics scrape blow-up. We track the DISTINCT values seen; once the cap is hit,
21
+ * further NEW values collapse into one `__other__` bucket (already-seen values still report exactly). The
22
+ * cap is made observable (no silent truncation) via `onOverflow`, fired once when the cap is first crossed.
23
+ */
8
24
  export declare function cardinalityGuard(cap: number, onOverflow: () => void): (value: string) => string;
25
+ /** Per-model usage accumulated for one task (shell-host contract E8). Token names mirror `turn_end.usage` /
26
+ * the contract's per-model entry; `costMicroUsd` is micro-USD (÷1e6 for USD). */
9
27
  export interface ModelUsageDelta {
10
28
  inputTokens: number;
11
29
  outputTokens: number;
@@ -13,16 +31,59 @@ export interface ModelUsageDelta {
13
31
  cacheWriteTokens: number;
14
32
  costMicroUsd: number;
15
33
  }
34
+ /**
35
+ * E8 (shell-host contract): per-task × per-model usage accumulator, fed (synchronously) by the `brain.call`
36
+ * tracer. The `TracerHook` contract is SYNC / no-IO, so we cannot persist from the hook; instead we accumulate
37
+ * here in memory and the run lifecycle DRAINS us at each turn boundary, appending the delta to the durable run
38
+ * event log. The **append-only delta** model is what makes it resume-safe: a task that suspends and resumes in a
39
+ * different process appends only its own post-resume deltas; the result echo SUMS all `model_usage` events across
40
+ * the whole (possibly multi-process) run. Memory is bounded — a task's entry is dropped on {@link drain}/{@link clear}.
41
+ */
16
42
  export declare class ModelUsageTracker {
17
43
  private readonly byTask;
18
44
  private readonly active;
45
+ /** Mark a TOP-LEVEL run active so its `brain.call` usage is tracked. **Required** — `record` ignores any taskId
46
+ * that isn't registered. This is the leak fence: delegated SUB-TASKS (team members,
47
+ * adversarial verifiers) run on throwaway core-minted sessionIds that the run lifecycle never registers/drains,
48
+ * so without this gate their usage would accumulate under ids nothing ever clears → an unbounded process-lifetime
49
+ * leak. Sub-task spend is intentionally NOT in the per-run `modelUsage` echo (it lands in `TaskStats.nested`);
50
+ * `modelUsage` is the TOP-LEVEL run's own per-model usage. Call at run start; {@link clear} unregisters. */
19
51
  register(taskId: string): void;
52
+ /** Accumulate one `brain.call`'s usage — ONLY for a registered top-level run (else a no-op; see {@link register}).
53
+ * Sync, never throws (TracerHook contract). */
20
54
  record(taskId: string, model: string, d: ModelUsageDelta): void;
55
+ /** Return the usage accumulated for this task SINCE the last drain (per neutral model id), and RESET it.
56
+ * `undefined` when nothing accrued — callers skip the durable append then. */
21
57
  drain(taskId: string): Record<string, ModelUsageDelta> | undefined;
58
+ /** Drop a task's pending accumulation AND unregister it (cleanup at run end / on an abandoned/errored leg). After
59
+ * this, further `record(taskId,…)` no-ops until a fresh {@link register}. `drain` deliberately does NOT unregister
60
+ * (the run continues across turns); only `clear` ends the run's tracking. */
22
61
  clear(taskId: string): void;
23
62
  }
24
63
  export { type PromptManifestRecord, promptManifestRecordOf, configAssembledRecordOf, PromptManifestTracker, } from "./observability/prompt-manifest.js";
64
+ /**
65
+ * ④ Bridge core's fire-and-forget trace events to /metrics (+ the E8 per-task model-usage accumulator). The hook
66
+ * is void / never throws / does no sync IO (in-memory counters only), per the TracerHook contract. `brain.call`
67
+ * fires for EVERY call (top-level + async + council sub-tasks) → `model_cost_micro_usd_total` is the authoritative
68
+ * spend, and (when a {@link ModelUsageTracker} is supplied) the per-task `modelUsage` echo's source.
69
+ */
25
70
  export declare function createTracer(metrics: Pick<Metrics, "inc" | "observe">, costQuota?: QuotaTracker, modelUsage?: ModelUsageTracker, fleetUsage?: FleetUsageAccumulator, fleetLease?: FleetLeaseManager, quotaWeightFor?: (model: string) => number, promptManifests?: PromptManifestTracker): TracerHook;
71
+ /**
72
+ * [1469] side-query 记账 seam(codex R3 high:sideQuery 不走 core tracer——brain.stream 直调不发
73
+ * brain.call——createTracer 的四路 sink(costQuota/model_cost 指标/fleetUsage 批报/fleetLease 本地扣减)
74
+ * 全部旁路)。本 seam 与 createTracer 的 brain.call 臂**同语义**喂同一组 sink:weightedTokens 同式
75
+ * (tokens×quotaWeight,weight-at-burn 固化)、micro-USD 同轴。装配点与 createTracer 同一处(main.ts),
76
+ * 传同一组实例——两臂永不分家。
77
+ *
78
+ * 已知残差(codex R3 medium,记档):cost 源=core SideQueryResult.usage.cost.total(brain 层计价),
79
+ * OpenAI cache-heavy 输入按全价入账(tracer 的 e.costMicroUsd 是 cache-family-aware 价)——方向=多收
80
+ * (保守,绝不少收);根修=core 在 SideQueryResult 上回权威 costMicroUsd(已提货 core)。model 标签/
81
+ * weight 键用**路由身份 r.model**(池配置有界)非 servedModel(provider 上报,无界)。
82
+ */
83
+ /** core `usage-accounting.cacheFamilyOf` 的私拷镜像(core exports map 只开 barrel,该函数未导出——
84
+ * 已提货 core barrel 导出,到货即换,normalizeAgentName 同款纪律)。逐字对拍源:
85
+ * dist/core/runner/usage-accounting.js(override 别名 anthropic/openai + api 判 anthropic-messages/
86
+ * bedrock-converse-stream)。undefined 入参(catalog 查不到)→ undefined,调用方走保守臂。 */
26
87
  export declare function cacheFamilyOfMirror(model: {
27
88
  api?: string;
28
89
  params?: {
@@ -42,5 +103,10 @@ export declare function createSideQueryAccountant(metrics: Pick<Metrics, "inc">,
42
103
  };
43
104
  };
44
105
  }) => void;
106
+ /**
107
+ * ⑤ Resolve a per-task budget: honor the caller's requested value but never let it EXCEED the operator
108
+ * ceiling. `0`/unset ceiling = no limit (returns the caller's value, or undefined). A non-positive /
109
+ * non-numeric request is ignored (falls back to the ceiling). Returns undefined = "no budget gate".
110
+ */
45
111
  export declare function cappedCeiling(requested: unknown, ceiling: number): number | undefined;
46
112
  //# sourceMappingURL=budget.d.ts.map
package/dist/budget.js CHANGED
@@ -1,6 +1,14 @@
1
+ /**
2
+ * Cost / budget / trace wiring for the Runner (core 1.37) — pure, testable helpers kept out of the
3
+ * auto-running main.ts:
4
+ * ③ buildPricing — Model.cost catalog → injected ModelPricing (authoritative costMicroUsd).
5
+ * ④ createTracer — core's content-free TraceEvents → /metrics (spend, first-token, tool calls).
6
+ * ⑤ cappedCeiling — clamp a caller's requested per-task budget DOWN to the operator ceiling.
7
+ */
1
8
  import { modelCostToPricing } from "@sema-agent/core";
2
9
  import { currentPrincipal } from "./observability/principal-context.js";
3
- import { promptManifestRecordOf, configAssembledRecordOf } from "./observability/prompt-manifest.js";
10
+ import { promptManifestRecordOf, configAssembledRecordOf } from "./observability/prompt-manifest.js"; // design/158 N18: see re-export block below (moved to ./observability/prompt-manifest.js)
11
+ /** ③ Per-model pricing keyed by model id (core falls back to each Model.cost when a model is absent). */
4
12
  export function buildPricing(models) {
5
13
  const pricing = {};
6
14
  for (const m of Object.values(models))
@@ -8,6 +16,14 @@ export function buildPricing(models) {
8
16
  pricing[m.id] = modelCostToPricing(m.cost);
9
17
  return pricing;
10
18
  }
19
+ /**
20
+ * Bound the cardinality of a free-form metric label value (BL-11/BL-21). A label fed by untrusted/unbounded
21
+ * input — MCP tool names (a misconfigured/malicious server can emit thousands of dynamic names) or center
22
+ * model ids (a malformed roster) — would otherwise mint an unbounded number of metric series: a slow memory
23
+ * leak in the registry + a /metrics scrape blow-up. We track the DISTINCT values seen; once the cap is hit,
24
+ * further NEW values collapse into one `__other__` bucket (already-seen values still report exactly). The
25
+ * cap is made observable (no silent truncation) via `onOverflow`, fired once when the cap is first crossed.
26
+ */
11
27
  export function cardinalityGuard(cap, onOverflow) {
12
28
  const seen = new Set();
13
29
  let overflowed = false;
@@ -25,11 +41,27 @@ export function cardinalityGuard(cap, onOverflow) {
25
41
  return value;
26
42
  };
27
43
  }
44
+ /**
45
+ * E8 (shell-host contract): per-task × per-model usage accumulator, fed (synchronously) by the `brain.call`
46
+ * tracer. The `TracerHook` contract is SYNC / no-IO, so we cannot persist from the hook; instead we accumulate
47
+ * here in memory and the run lifecycle DRAINS us at each turn boundary, appending the delta to the durable run
48
+ * event log. The **append-only delta** model is what makes it resume-safe: a task that suspends and resumes in a
49
+ * different process appends only its own post-resume deltas; the result echo SUMS all `model_usage` events across
50
+ * the whole (possibly multi-process) run. Memory is bounded — a task's entry is dropped on {@link drain}/{@link clear}.
51
+ */
28
52
  export class ModelUsageTracker {
29
53
  byTask = new Map();
30
54
  active = new Set();
55
+ /** Mark a TOP-LEVEL run active so its `brain.call` usage is tracked. **Required** — `record` ignores any taskId
56
+ * that isn't registered. This is the leak fence: delegated SUB-TASKS (team members,
57
+ * adversarial verifiers) run on throwaway core-minted sessionIds that the run lifecycle never registers/drains,
58
+ * so without this gate their usage would accumulate under ids nothing ever clears → an unbounded process-lifetime
59
+ * leak. Sub-task spend is intentionally NOT in the per-run `modelUsage` echo (it lands in `TaskStats.nested`);
60
+ * `modelUsage` is the TOP-LEVEL run's own per-model usage. Call at run start; {@link clear} unregisters. */
31
61
  register(taskId) { if (taskId)
32
62
  this.active.add(taskId); }
63
+ /** Accumulate one `brain.call`'s usage — ONLY for a registered top-level run (else a no-op; see {@link register}).
64
+ * Sync, never throws (TracerHook contract). */
33
65
  record(taskId, model, d) {
34
66
  if (!taskId || !model || !this.active.has(taskId))
35
67
  return;
@@ -50,6 +82,8 @@ export class ModelUsageTracker {
50
82
  perModel.set(model, { ...d });
51
83
  }
52
84
  }
85
+ /** Return the usage accumulated for this task SINCE the last drain (per neutral model id), and RESET it.
86
+ * `undefined` when nothing accrued — callers skip the durable append then. */
53
87
  drain(taskId) {
54
88
  const perModel = this.byTask.get(taskId);
55
89
  if (!perModel || perModel.size === 0)
@@ -60,27 +94,60 @@ export class ModelUsageTracker {
60
94
  this.byTask.delete(taskId);
61
95
  return out;
62
96
  }
97
+ /** Drop a task's pending accumulation AND unregister it (cleanup at run end / on an abandoned/errored leg). After
98
+ * this, further `record(taskId,…)` no-ops until a fresh {@link register}. `drain` deliberately does NOT unregister
99
+ * (the run continues across turns); only `clear` ends the run's tracking. */
63
100
  clear(taskId) { this.byTask.delete(taskId); this.active.delete(taskId); }
64
101
  }
102
+ // design/158 N18: PromptManifestRecord / promptManifestRecordOf / configAssembledRecordOf / PromptManifestTracker
103
+ // moved VERBATIM to ./observability/prompt-manifest.js (budget.ts's name says cost/budget; this face is
104
+ // wire-observability projection of prompt.assembled/config.assembled, unrelated). Re-exported here so existing
105
+ // importers (main.ts, runs.ts, http/server.ts, trace/project.ts, tests) keep working untouched — createTracer
106
+ // below still consumes promptManifestRecordOf/configAssembledRecordOf/PromptManifestTracker.
65
107
  export { promptManifestRecordOf, configAssembledRecordOf, PromptManifestTracker, } from "./observability/prompt-manifest.js";
108
+ /**
109
+ * ④ Bridge core's fire-and-forget trace events to /metrics (+ the E8 per-task model-usage accumulator). The hook
110
+ * is void / never throws / does no sync IO (in-memory counters only), per the TracerHook contract. `brain.call`
111
+ * fires for EVERY call (top-level + async + council sub-tasks) → `model_cost_micro_usd_total` is the authoritative
112
+ * spend, and (when a {@link ModelUsageTracker} is supplied) the per-task `modelUsage` echo's source.
113
+ */
66
114
  export function createTracer(metrics, costQuota, modelUsage, fleetUsage, fleetLease, quotaWeightFor, promptManifests) {
115
+ // Per-process cardinality guards for the two unbounded-input labels (BL-11/BL-21). 256 is generous for any
116
+ // real tool/model catalog; overflow bumps a counter so an over-cap deploy is observable, not silent.
67
117
  const toolName = cardinalityGuard(256, () => metrics.inc("metric_label_overflow_total", { label: "tool_name" }));
68
118
  const modelId = cardinalityGuard(256, () => metrics.inc("metric_label_overflow_total", { label: "model" }));
119
+ // provider flows from env/registry config (not a bounded enum) — guard it like modelId (1.127.0):
120
+ // a misconfigured registry entry must not explode Prometheus label cardinality. 64 is generous for real providers.
69
121
  const providerName = cardinalityGuard(64, () => metrics.inc("metric_label_overflow_total", { label: "provider" }));
70
122
  return (e) => {
71
123
  if (e.kind === "brain.call") {
124
+ // S18 (SILENT-FALLBACK P1): count every call by provider+model. provider is optional on the trace event —
125
+ // "unknown" = the routing layer fell through without a recognized provider (previously unobservable).
72
126
  metrics.inc("brain_calls_total", { provider: providerName(e.provider ?? "unknown"), model: modelId(e.model) });
73
127
  if (e.costMicroUsd) {
74
128
  metrics.inc("model_cost_micro_usd_total", { model: modelId(e.model) }, e.costMicroUsd);
129
+ // ⑤b attribute spend to the originating principal (ALS) — reaches council/team sub-tasks too.
75
130
  const principal = currentPrincipal();
76
131
  if (principal)
77
132
  costQuota?.add(principal, e.costMicroUsd);
78
133
  }
134
+ // E8 (shell-host): per-task × per-model usage for the `TaskStats.modelUsage` echo. `record` is a NO-OP unless
135
+ // e.taskId is a REGISTERED top-level run (the leak fence — sub-task/throwaway taskIds are never registered, so
136
+ // they neither leak nor enter the echo; their spend is in TaskStats.nested). Drained at turn boundaries into the
137
+ // durable log (resume-safe); the registered entry is dropped at run end (clear). NOT cardinality-guarded by
138
+ // model: bounded by a run's model set, and by the active-run set.
79
139
  modelUsage?.record(e.taskId, e.model, { inputTokens: e.promptTokens, outputTokens: e.completionTokens, cacheReadTokens: e.cacheRead, cacheWriteTokens: e.cacheWrite, costMicroUsd: e.costMicroUsd ?? 0 });
140
+ // weight-at-burn:加权 tokens = (prompt+completion)×模型配额倍率,在记账点固化(此后改倍率
141
+ // 不回算历史,registry ModelEntry.quotaWeight 同句契约)。weight 源=config.modelQuotaWeights(registry
142
+ // hot-apply;env lane 空表 ⇒ 1 兜底);非法回调值防御性归 1(tracer 契约 never-throws,不让坏表毒记账)。
80
143
  const qwRaw = quotaWeightFor?.(e.model);
81
144
  const qw = typeof qwRaw === "number" && Number.isFinite(qwRaw) && qwRaw > 0 ? qwRaw : 1;
82
145
  const weightedTokens = Math.round((e.promptTokens + e.completionTokens) * qw);
146
+ // P2 用量批报:principal×model 窗口累计(同 ⑤b 的 ALS 归因点 — 子任务花费也归到发起 principal),
147
+ // fleet-client 每窗口 drain→POST /api/fleet/usage。未配 fleet(accumulator 缺席)= 零行为。
83
148
  fleetUsage?.record(currentPrincipal(), e.model, e.taskId, { inputTokens: e.promptTokens, outputTokens: e.completionTokens, costMicroUsd: e.costMicroUsd ?? 0, weightedTokens, quotaWeightAtUse: qw });
149
+ // lease 消费(D4 AP):同一 ALS 归因点做 lease 本地扣减 —— 只对当前持 lease 的 principal
150
+ // 生效(FleetLeaseManager 内部判),sync + never throws。双轴=weightedTokens(配额轴)+costMicroUsd($ 轴)。
84
151
  fleetLease?.recordSpend(currentPrincipal(), { weightedTokens, costMicroUsd: e.costMicroUsd ?? 0 });
85
152
  if (e.firstTokenMs !== undefined)
86
153
  metrics.observe("brain_first_token_ms", e.firstTokenMs);
@@ -90,27 +157,75 @@ export function createTracer(metrics, costQuota, modelUsage, fleetUsage, fleetLe
90
157
  metrics.inc("tool_calls_total", { name: toolName(e.name), ok: String(e.ok) });
91
158
  }
92
159
  else if (e.kind === "task.degraded") {
160
+ // 1.40: a task was switched to a cheaper model (near-budget / rate_limit / breaker-open). Quality
161
+ // dropped → alert-worthy operational signal, by reason.
93
162
  metrics.inc("degraded_total", { reason: e.reason });
94
163
  }
95
164
  else if (e.kind === "prompt.assembled") {
165
+ // core 1.243(提示词主权批): who owned the constitution layer, per task. The
166
+ // steady state for EVERY service scenario is "core" (structural constitution — our providers all
167
+ // return role bases only). Anything else is worth eyes: "provider-assembled" = a pre-1.243-shaped
168
+ // provider tripped the migration guard (upgrade it); "replaced" = an explicit replaceAll opt-out
169
+ // (none exist in this repo today); "legacy" = a deprecated free-form `system` provider. Alert on
170
+ // `prompt_constitution_total{mode!="core"} > 0` — the "TOC lost its safety blocks and called it a
171
+ // config issue" failure class becomes a one-glance dashboard check.
96
172
  metrics.inc("prompt_constitution_total", { mode: e.constitution });
173
+ // [998]② durable half: record the whitelisted manifest for the run lifecycle to drain into a
174
+ // `prompt_assembled` event (turns/stream). register-gated (top-level runs only), sync, never persists here.
97
175
  promptManifests?.record(e.taskId, promptManifestRecordOf(e));
98
176
  }
99
177
  else if (e.kind === "config.assembled") {
178
+ // [1301]③:config catalog 观测半场——生效配置逐字段来源(default/spec/derived/host-declared+
179
+ // overrideReasons)随任务进 durable 事件日志(config_assembled),「谁设的 80」读帧不考古。
100
180
  const rec = configAssembledRecordOf(e);
101
181
  if (rec)
102
182
  promptManifests?.recordConfig(e.taskId, rec);
103
183
  }
104
184
  else if (e.kind === "compaction.phase_timings") {
185
+ // codex F6: core 1.289's `compaction.phase_timings` fires on SUCCESS (per-phase timing telemetry) — it is
186
+ // NOT an outcome, so counting it into compaction_events_total would add a fake "phase_timings" failure
187
+ // outcome for every successful compaction (poisoning the "non-success outcomes" dashboard semantics
188
+ // documented below). Record the total duration on the existing observe face instead (the
189
+ // brain_call_latency_ms precedent); non-finite values are dropped (tracer never throws, never poisons).
190
+ // 三路复审修5 核查(workflow W5 报「histogram never」):duration 观测出口就在下一行(F6 起已在),
191
+ // event 契约(core trace.d.ts)带 `durationMs: number`,budget.test.ts 咬合断言 observe 只进
192
+ // compaction_duration_ms 不进失败计数器 —— W5 判 STALE,零改。per-phase 明细走 compacted 事件的
193
+ // phaseDurations(trace/project.ts compactedEventData)上 wire,不在 /metrics 重复开面(有界纪律)。
105
194
  const d = e.durationMs;
106
195
  if (typeof d === "number" && Number.isFinite(d))
107
196
  metrics.observe("compaction_duration_ms", d);
108
197
  }
109
198
  else if (e.kind.startsWith("compaction.")) {
199
+ // core 1.257(压缩健康面): every NON-SUCCESS compaction outcome
200
+ // now emits a `compaction.*` trace frame (failed / mooted / blocked / noop / disabled / suppressed +
201
+ // the input_truncated disclosure and announce_dropped). Before these frames the only evidence of a
202
+ // failing compactor was `onError(phase:"compaction")` log lines — no aggregate, so "3 silent auto
203
+ // failures opened the breaker and manual verbs drain mooted" (the exact failure fingerprint)
204
+ // was invisible on a dashboard. Count by outcome+trigger: `compaction_events_total{outcome="failed"}`
205
+ // rising = the summarizer is failing; sustained `mooted`/`blocked` explains "202 → no compacted
206
+ // event" without log spelunking. Labels are bounded: 8 kinds × 3 triggers (frames without a trigger
207
+ // — noop/disabled/mooted/input_truncated/announce_dropped — label "none"). SUCCESS is deliberately
208
+ // not counted here: `compacted` is a TaskEvent riding the run stream, not a trace frame.
110
209
  metrics.inc("compaction_events_total", { outcome: e.kind.slice("compaction.".length), trigger: e.trigger ?? "none" });
111
210
  }
112
211
  };
113
212
  }
213
+ /**
214
+ * [1469] side-query 记账 seam(codex R3 high:sideQuery 不走 core tracer——brain.stream 直调不发
215
+ * brain.call——createTracer 的四路 sink(costQuota/model_cost 指标/fleetUsage 批报/fleetLease 本地扣减)
216
+ * 全部旁路)。本 seam 与 createTracer 的 brain.call 臂**同语义**喂同一组 sink:weightedTokens 同式
217
+ * (tokens×quotaWeight,weight-at-burn 固化)、micro-USD 同轴。装配点与 createTracer 同一处(main.ts),
218
+ * 传同一组实例——两臂永不分家。
219
+ *
220
+ * 已知残差(codex R3 medium,记档):cost 源=core SideQueryResult.usage.cost.total(brain 层计价),
221
+ * OpenAI cache-heavy 输入按全价入账(tracer 的 e.costMicroUsd 是 cache-family-aware 价)——方向=多收
222
+ * (保守,绝不少收);根修=core 在 SideQueryResult 上回权威 costMicroUsd(已提货 core)。model 标签/
223
+ * weight 键用**路由身份 r.model**(池配置有界)非 servedModel(provider 上报,无界)。
224
+ */
225
+ /** core `usage-accounting.cacheFamilyOf` 的私拷镜像(core exports map 只开 barrel,该函数未导出——
226
+ * 已提货 core barrel 导出,到货即换,normalizeAgentName 同款纪律)。逐字对拍源:
227
+ * dist/core/runner/usage-accounting.js(override 别名 anthropic/openai + api 判 anthropic-messages/
228
+ * bedrock-converse-stream)。undefined 入参(catalog 查不到)→ undefined,调用方走保守臂。 */
114
229
  export function cacheFamilyOfMirror(model) {
115
230
  if (!model)
116
231
  return undefined;
@@ -127,6 +242,10 @@ export function createSideQueryAccountant(metrics, costQuota, fleetUsage, fleetL
127
242
  const output = typeof r.usage?.output === "number" ? r.usage.output : 0;
128
243
  const cacheRead = typeof r.usage?.cacheRead === "number" ? r.usage.cacheRead : 0;
129
244
  const cacheWrite = typeof r.usage?.cacheWrite === "number" ? r.usage.cacheWrite : 0;
245
+ // codex R4 high:prompt tokens 必须按 cache family 折算(core promptTokensOf 同式)——Anthropic 族
246
+ // (input-excludes-cached)的 cache 命中几乎全部在 input 之外,不加 cacheRead/cacheWrite 就是配额轴
247
+ // 大幅少收(lease 可被 cache-heavy side query 绕穿)。family 未知(catalog 查不到)走**保守臂**
248
+ // (含 cache——OpenAI 族此臂多收,方向与 cost 残差一致:宁多勿少,记档同一条)。
130
249
  const promptTokens = r.family === "input-includes-cached" ? input : input + cacheRead + cacheWrite;
131
250
  const micro = Math.round((typeof r.usage?.cost?.total === "number" ? r.usage.cost.total : 0) * 1_000_000);
132
251
  if (micro > 0) {
@@ -138,15 +257,20 @@ export function createSideQueryAccountant(metrics, costQuota, fleetUsage, fleetL
138
257
  const qw = typeof qwRaw === "number" && Number.isFinite(qwRaw) && qwRaw > 0 ? qwRaw : 1;
139
258
  const weightedTokens = Math.round((promptTokens + output) * qw);
140
259
  if (weightedTokens > 0 || micro > 0) {
141
- fleetUsage?.record(principal, r.model, "", { inputTokens: promptTokens, outputTokens: output, costMicroUsd: micro, weightedTokens, quotaWeightAtUse: qw });
260
+ fleetUsage?.record(principal, r.model, "", { inputTokens: promptTokens, outputTokens: output, costMicroUsd: micro, weightedTokens, quotaWeightAtUse: qw }); // taskId ""(无 run 语义;accumulator 对 "" 不计 runsSeen);inputTokens=归一化总输入含 cache(fleet-bus 同口径)
142
261
  fleetLease?.recordSpend(principal, { weightedTokens, costMicroUsd: micro });
143
262
  }
144
263
  };
145
264
  }
265
+ /**
266
+ * ⑤ Resolve a per-task budget: honor the caller's requested value but never let it EXCEED the operator
267
+ * ceiling. `0`/unset ceiling = no limit (returns the caller's value, or undefined). A non-positive /
268
+ * non-numeric request is ignored (falls back to the ceiling). Returns undefined = "no budget gate".
269
+ */
146
270
  export function cappedCeiling(requested, ceiling) {
147
271
  const req = typeof requested === "number" && requested > 0 ? requested : undefined;
148
272
  if (!ceiling || ceiling <= 0)
149
- return req;
150
- return req === undefined ? ceiling : Math.min(req, ceiling);
273
+ return req; // no operator ceiling → honor caller (or none)
274
+ return req === undefined ? ceiling : Math.min(req, ceiling); // cap caller down to the ceiling
151
275
  }
152
276
  //# sourceMappingURL=budget.js.map
@@ -1,3 +1,6 @@
1
1
  import type { ToolSpec } from "@sema-agent/core";
2
+ /** Current time — the model has no clock; OA/most tasks need it. No side effects. CC-parity tool name `Now`
3
+ * (PascalCase, core 1.176 first-party rename wrap-up — the SERVICE owns this one; `nowTool` is not a core tool).
4
+ * effect:"read" so it never suspends → no durable-resume rename strand (no pending-tool checkpoint to canonicalize). */
2
5
  export declare function nowTool(): ToolSpec;
3
6
  //# sourceMappingURL=builtin-tools.d.ts.map
@@ -1,4 +1,7 @@
1
1
  import { Type } from "typebox";
2
+ /** Current time — the model has no clock; OA/most tasks need it. No side effects. CC-parity tool name `Now`
3
+ * (PascalCase, core 1.176 first-party rename wrap-up — the SERVICE owns this one; `nowTool` is not a core tool).
4
+ * effect:"read" so it never suspends → no durable-resume rename strand (no pending-tool checkpoint to canonicalize). */
2
5
  export function nowTool() {
3
6
  return {
4
7
  name: "Now",
@@ -1,6 +1,8 @@
1
1
  import type { Logger } from "../observability/logger.js";
2
2
  import { type LoadedSkill } from "./skills.js";
3
+ /** 缺省 clone host 白名单(契约条款 1;国内镜像走本名单加 https 镜像域,不开 http 口)。 */
3
4
  export declare const DEFAULT_PLUGIN_ALLOW_HOSTS: readonly string[];
5
+ /** wire 上的插件声明(registry-core PluginSpec 的宽读形——本模块只消费不裁决,未知键忽略)。 */
4
6
  export interface PluginDeclWire {
5
7
  name?: unknown;
6
8
  source?: {
@@ -17,13 +19,17 @@ export type PluginValidation = {
17
19
  name: string;
18
20
  url: string;
19
21
  sha?: string;
20
- } | {
22
+ }
23
+ /** skip=true:不装但不算失败(enabled:false / marketplace 形 v1 暂缓);skip 缺席 = 真失败(计入 failures)。 */
24
+ | {
21
25
  ok: false;
22
26
  skip?: true;
23
27
  name: string;
24
28
  reason: string;
25
29
  };
30
+ /** 条款 1/2/4:https-only、host 全等白名单、sha 40hex。纯函数,worker 侧纵深复验(不信任 wire 已验过)。 */
26
31
  export declare function validatePluginDecl(decl: PluginDeclWire, allowHosts: readonly string[]): PluginValidation;
32
+ /** 条款 3/5:clone 计划(argv 序列 + 隔离 env)。纯数据,让"姿势"可被钉死。 */
27
33
  export declare function gitClonePlan(o: {
28
34
  url: string;
29
35
  dest: string;
@@ -32,6 +38,9 @@ export declare function gitClonePlan(o: {
32
38
  steps: string[][];
33
39
  env: Record<string, string>;
34
40
  };
41
+ /** 条款 5 的 manifest 半场:`.claude-plugin/plugin.json` 的 `skillsPath`(缺省 `skills/`;cli plugin
42
+ * 布局同族)。返回 ok:true+dir:undefined = 插件没有 skills 目录(可以只有 commands——那是 cli 壳的
43
+ * 半场,worker 装 0 个 skill 不算失败);ok:false = 路径逃逸,整条拒装。 */
35
44
  export declare function resolvePluginSkillsRoot(cloneRoot: string): {
36
45
  ok: true;
37
46
  dir?: string;
@@ -41,22 +50,29 @@ export declare function resolvePluginSkillsRoot(cloneRoot: string): {
41
50
  };
42
51
  export interface ApplyPluginsResult {
43
52
  skills: LoadedSkill[];
53
+ /** 真失败(validate 拒/clone 失败且无 LKG/装载抛):单条不连坐,逐条留痕。 */
44
54
  failures: Array<{
45
55
  plugin: string;
46
56
  reason: string;
47
57
  }>;
58
+ /** 撞名让位名单(收紧④)。 */
48
59
  letGo: Array<{
49
60
  plugin: string;
50
61
  skill: string;
51
62
  }>;
63
+ /** 本轮拉取失败、沿用上次成功物化的插件名。 */
52
64
  lkgUsed: string[];
53
65
  }
66
+ /** 总入口(条款 3/7/8):逐条物化 + 装载 + 让位合并。materialize 盘位 = `<cacheRoot>/<name>/live`
67
+ * (成功后原子 rename 替换,失败保留旧盘位 = LKG)。 */
54
68
  export declare function applyCenterPlugins(baseline: LoadedSkill[], eff: {
55
69
  plugins?: unknown;
56
70
  }, opts: {
57
71
  cacheRoot: string;
58
72
  allowHosts: readonly string[];
59
73
  logger?: Logger;
74
+ /** 测试口:跳过 validate(materialize 只接受已验声明;真 git 腿用本地 bare repo,validate 层的
75
+ * https-only 单独测——两层分开,谁也不掩护谁)。生产恒 false/缺席。 */
60
76
  skipValidate?: boolean;
61
77
  runGit?: (args: string[], env: Record<string, string>) => Promise<void>;
62
78
  }): Promise<ApplyPluginsResult>;
@@ -1,16 +1,41 @@
1
+ /**
2
+ * plugins 域 worker 消费半场(契约冻结 board [1361]②/[1362] 四收紧/[1366]①;2026-07-28 开工车)。
3
+ *
4
+ * center 只存"插件从哪来"(PluginSpec 引用,永不承载可执行字节);worker 半场 = 把引用物化成本地
5
+ * 目录并把其中的 **skills** 装进 baseline(v1 装载面;commands 由 cli 壳消费——board [1363] 即 cli
6
+ * 答的命令契约稿,worker 侧本无命令面,这是分工不是降级)。挂 applyCenterSkills 同 reconcile 周期
7
+ * (boot 期,buildScenarios 之前)。
8
+ *
9
+ * 契约条款落点(与 test/center-plugins.test.ts 逐条对应):
10
+ * - https-only + `PLUGINS_ALLOW_HOSTS`(缺省 github.com):{@link validatePluginDecl}。registry-core
11
+ * 0.10.23 已在 schema 层单真源拒非 https,worker 侧**仍复验**——纵深:wire 可能来自旧 center。
12
+ * - sha 全 40hex + checkout 强制:{@link gitClonePlan}(有 sha = init+fetch-by-sha+checkout,不信
13
+ * 分支名也不拉全史;无 sha = `--depth 1` HEAD)。
14
+ * - clone 姿势隔离:GIT_CONFIG_GLOBAL/SYSTEM=/dev/null + GIT_TERMINAL_PROMPT=0(无凭据仓 fail 而非
15
+ * 挂交互 prompt)。私仓凭据走各机自己的 credential helper,永不入声明。
16
+ * - manifest 路径逃逸(../ /绝对路径/symlink 出根)= 整条拒装:{@link resolvePluginSkillsRoot}
17
+ * (realpath 后前缀判定)。
18
+ * - 撞名让位(收紧④):plugin 的 skill 与 baseline(builtin/center 直发)同名 ⇒ **plugin 让位**
19
+ * (跳过+letGo 留痕)。⚠️ 方向与 applyCenterSkills 的 center-wins 相反——center 直发 skills 过了
20
+ * publisher RBAC+发布审批,plugin 内容只是 git 仓字节,信任级不同,让位方向因此相反。
21
+ * - fail-loud 单条不连坐 + LKG(上次成功物化留盘,拉取失败沿用):{@link applyCenterPlugins}。
22
+ */
1
23
  import { execFile } from "node:child_process";
2
24
  import { promisify } from "node:util";
3
25
  import { promises as fsp, realpathSync, existsSync, readFileSync } from "node:fs";
4
26
  import { join, resolve, isAbsolute, sep } from "node:path";
5
27
  import { loadSkills } from "./skills.js";
6
28
  const execFileP = promisify(execFile);
29
+ /** 缺省 clone host 白名单(契约条款 1;国内镜像走本名单加 https 镜像域,不开 http 口)。 */
7
30
  export const DEFAULT_PLUGIN_ALLOW_HOSTS = ["github.com"];
31
+ /** 条款 1/2/4:https-only、host 全等白名单、sha 40hex。纯函数,worker 侧纵深复验(不信任 wire 已验过)。 */
8
32
  export function validatePluginDecl(decl, allowHosts) {
9
33
  const name = typeof decl.name === "string" && decl.name !== "" ? decl.name : "(unnamed)";
10
34
  if (decl.enabled === false)
11
35
  return { ok: false, skip: true, name, reason: "enabled:false" };
12
36
  const kind = decl.source?.kind;
13
37
  if (kind === "marketplace") {
38
+ // v1 暂缓:marketplace 物化(add-by-url + install-by-name)是 v2 面;skip 不连坐,warn 留痕。
14
39
  return { ok: false, skip: true, name, reason: "marketplace source: not materialized in v1 (skills lane ships git-form first)" };
15
40
  }
16
41
  if (kind !== "git")
@@ -26,6 +51,7 @@ export function validatePluginDecl(decl, allowHosts) {
26
51
  catch {
27
52
  return { ok: false, name, reason: "https url does not parse" };
28
53
  }
54
+ // host 全等匹配——evil-github.com / github.com.evil.io 都不隐含放行。
29
55
  if (!allowHosts.some((h) => h.toLowerCase() === host)) {
30
56
  return { ok: false, name, reason: `host ${host} not in PLUGINS_ALLOW_HOSTS (default github.com; extend with a comma-separated https mirror domain list)` };
31
57
  }
@@ -37,15 +63,17 @@ export function validatePluginDecl(decl, allowHosts) {
37
63
  }
38
64
  return { ok: true, name, url };
39
65
  }
66
+ /** 条款 3/5:clone 计划(argv 序列 + 隔离 env)。纯数据,让"姿势"可被钉死。 */
40
67
  export function gitClonePlan(o) {
41
68
  const env = {
42
- GIT_CONFIG_GLOBAL: "/dev/null",
69
+ GIT_CONFIG_GLOBAL: "/dev/null", // 收紧③:宿主 git 配置(insteadOf/credential/hooks)一概不继承
43
70
  GIT_CONFIG_SYSTEM: "/dev/null",
44
- GIT_TERMINAL_PROMPT: "0",
71
+ GIT_TERMINAL_PROMPT: "0", // 无凭据仓 ⇒ fail-loud,绝不挂在交互 prompt 上
45
72
  };
46
73
  if (o.sha === undefined) {
47
74
  return { steps: [["clone", "--depth", "1", "--quiet", o.url, o.dest]], env };
48
75
  }
76
+ // 有 sha:init + fetch-by-sha + checkout —— 不信分支名、不拉全史;fetch 不到该 sha = 该条失败。
49
77
  return {
50
78
  steps: [
51
79
  ["init", "--quiet", o.dest],
@@ -55,6 +83,9 @@ export function gitClonePlan(o) {
55
83
  env,
56
84
  };
57
85
  }
86
+ /** 条款 5 的 manifest 半场:`.claude-plugin/plugin.json` 的 `skillsPath`(缺省 `skills/`;cli plugin
87
+ * 布局同族)。返回 ok:true+dir:undefined = 插件没有 skills 目录(可以只有 commands——那是 cli 壳的
88
+ * 半场,worker 装 0 个 skill 不算失败);ok:false = 路径逃逸,整条拒装。 */
58
89
  export function resolvePluginSkillsRoot(cloneRoot) {
59
90
  let skillsPath = "skills";
60
91
  try {
@@ -63,22 +94,27 @@ export function resolvePluginSkillsRoot(cloneRoot) {
63
94
  skillsPath = manifest.skillsPath;
64
95
  }
65
96
  catch {
97
+ /* 无 manifest / 坏 JSON ⇒ 缺省 skills/(manifest 是可选面) */
66
98
  }
67
99
  if (isAbsolute(skillsPath))
68
100
  return { ok: false, reason: `skillsPath must be relative (got ${skillsPath})` };
69
101
  const rootReal = realpathSync(cloneRoot);
70
102
  const candidate = resolve(rootReal, skillsPath);
103
+ // 先做词法前缀判定(../ 逃逸在 realpath 之前就拒——目标可能不存在)
71
104
  if (candidate !== rootReal && !candidate.startsWith(rootReal + sep)) {
72
105
  return { ok: false, reason: `skillsPath escapes the plugin root (${skillsPath})` };
73
106
  }
74
107
  if (!existsSync(candidate))
75
108
  return { ok: true };
109
+ // symlink 出根:对存在的目标 realpath 再判一次
76
110
  const real = realpathSync(candidate);
77
111
  if (real !== rootReal && !real.startsWith(rootReal + sep)) {
78
112
  return { ok: false, reason: `skillsPath resolves outside the plugin root via symlink (${skillsPath})` };
79
113
  }
80
114
  return { ok: true, dir: candidate };
81
115
  }
116
+ /** 总入口(条款 3/7/8):逐条物化 + 装载 + 让位合并。materialize 盘位 = `<cacheRoot>/<name>/live`
117
+ * (成功后原子 rename 替换,失败保留旧盘位 = LKG)。 */
82
118
  export async function applyCenterPlugins(baseline, eff, opts) {
83
119
  const declared = Array.isArray(eff.plugins)
84
120
  ? (eff.plugins)
@@ -91,7 +127,7 @@ export async function applyCenterPlugins(baseline, eff, opts) {
91
127
  const runGit = opts.runGit ?? (async (args, env) => {
92
128
  await execFileP("git", args, { env: { ...process.env, ...env }, timeout: 120_000, maxBuffer: 4 * 1024 * 1024 });
93
129
  });
94
- const taken = new Set(baseline.map((s) => s.spec.name));
130
+ const taken = new Set(baseline.map((s) => s.spec.name)); // 让位判据:baseline(builtin+center 直发)恒赢
95
131
  for (const decl of declared) {
96
132
  const v = opts.skipValidate
97
133
  ? { ok: true, name: String(decl.name), url: String(decl.source?.url), ...(typeof decl.sha === "string" ? { sha: decl.sha } : {}) }
@@ -106,12 +142,14 @@ export async function applyCenterPlugins(baseline, eff, opts) {
106
142
  continue;
107
143
  }
108
144
  const liveDir = join(opts.cacheRoot, v.name, "live");
145
+ // ── 物化:clone 到 staging,成功后原子替换 live;失败保留旧 live = LKG ──
109
146
  const staging = join(opts.cacheRoot, v.name, `staging-${process.pid}`);
110
147
  let materialized = false;
111
148
  try {
112
149
  await fsp.rm(staging, { recursive: true, force: true });
113
150
  await fsp.mkdir(staging, { recursive: true });
114
151
  const plan = gitClonePlan({ url: v.url, dest: staging, sha: v.sha });
152
+ // clone 目标目录已建:单步 clone 允许空目录;init 形对空目录同样成立。
115
153
  for (const step of plan.steps)
116
154
  await runGit(step, plan.env);
117
155
  await fsp.rm(liveDir, { recursive: true, force: true });
@@ -122,6 +160,7 @@ export async function applyCenterPlugins(baseline, eff, opts) {
122
160
  catch (err) {
123
161
  await fsp.rm(staging, { recursive: true, force: true }).catch(() => undefined);
124
162
  if (existsSync(liveDir)) {
163
+ // LKG:拉取失败沿用上次成功物化(applyCenterSkills 同款语义)。
125
164
  opts.logger?.warn("center_plugin_fetch_failed_lkg", { plugin: v.name, error: err instanceof Error ? err.message : String(err) });
126
165
  out.lkgUsed.push(v.name);
127
166
  }
@@ -131,6 +170,7 @@ export async function applyCenterPlugins(baseline, eff, opts) {
131
170
  continue;
132
171
  }
133
172
  }
173
+ // ── 装载:skills 目录(路径逃逸=整条拒装;fail-loud 单条不连坐)──
134
174
  try {
135
175
  const rootCheck = resolvePluginSkillsRoot(liveDir);
136
176
  if (!rootCheck.ok) {
@@ -139,10 +179,11 @@ export async function applyCenterPlugins(baseline, eff, opts) {
139
179
  continue;
140
180
  }
141
181
  if (!rootCheck.dir)
142
- continue;
182
+ continue; // 无 skills 目录:合法(commands-only 插件,cli 壳的半场)
143
183
  const loaded = loadSkills(rootCheck.dir);
144
184
  for (const skill of loaded) {
145
185
  if (taken.has(skill.spec.name)) {
186
+ // 收紧④:plugin 让位(方向与 center-wins 相反,理由见模块顶注)。
146
187
  out.letGo.push({ plugin: v.name, skill: skill.spec.name });
147
188
  opts.logger?.warn("center_plugin_skill_shadowed", { plugin: v.name, skill: skill.spec.name, note: "name taken by builtin/center skill — plugin yields (contract tightening-4)" });
148
189
  continue;