@sema-agent/core 7.48.0 → 7.49.1

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 (421) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +21 -28
  52. package/dist/core/arg-summary.js +235 -88
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +43 -11
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +21 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +29 -36
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/tool-turn-repair-seat.d.ts +28 -4
  243. package/dist/core/runner/tool-turn-repair-seat.js +36 -13
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/secret-env.d.ts +16 -5
  249. package/dist/core/secret-env.js +23 -63
  250. package/dist/core/sensitive-path-policy.d.ts +19 -18
  251. package/dist/core/sensitive-path-policy.js +73 -49
  252. package/dist/core/session-reconcile.d.ts +3 -0
  253. package/dist/core/session-reconcile.js +5 -4
  254. package/dist/core/session-store.d.ts +5 -0
  255. package/dist/core/session-store.js +12 -0
  256. package/dist/core/session.d.ts +13 -0
  257. package/dist/core/shared-memory/normalize.d.ts +17 -4
  258. package/dist/core/shared-memory/normalize.js +7 -7
  259. package/dist/core/shell-lexer.js +5 -4
  260. package/dist/core/shell-wrapper-projection.js +1 -1
  261. package/dist/core/skill-grant.js +1 -1
  262. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  263. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  264. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  265. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  266. package/dist/core/stub-env.d.ts +2 -0
  267. package/dist/core/stub-env.js +1 -0
  268. package/dist/core/synthetic-read-verdict.js +2 -2
  269. package/dist/core/task-event.d.ts +59 -5
  270. package/dist/core/task-result.d.ts +1 -1
  271. package/dist/core/task-spec.d.ts +42 -9
  272. package/dist/core/terminal-cause.d.ts +94 -11
  273. package/dist/core/tighten-task-spec.d.ts +5 -4
  274. package/dist/core/tighten-task-spec.js +20 -25
  275. package/dist/core/tool-catalog-entries.d.ts +5 -7
  276. package/dist/core/tool-catalog-entries.js +14 -15
  277. package/dist/core/tool-face.d.ts +47 -0
  278. package/dist/core/tool-face.js +5 -0
  279. package/dist/core/tool-model-gate.d.ts +5 -5
  280. package/dist/core/tool-name-aliases.d.ts +26 -2
  281. package/dist/core/tool-name-aliases.js +13 -0
  282. package/dist/core/tool-name-list.d.ts +30 -0
  283. package/dist/core/tool-name-list.js +55 -0
  284. package/dist/core/tool-name-readings.d.ts +1 -9
  285. package/dist/core/tool-name-readings.js +1 -3
  286. package/dist/core/tool-policy.d.ts +195 -85
  287. package/dist/core/tool-policy.js +165 -380
  288. package/dist/core/tool-registry.d.ts +44 -1
  289. package/dist/core/tool-registry.js +26 -0
  290. package/dist/core/tool-roster.d.ts +19 -1
  291. package/dist/core/tool-roster.js +21 -2
  292. package/dist/core/tool-spec-members.d.ts +45 -0
  293. package/dist/core/tool-spec-members.js +169 -0
  294. package/dist/core/tool-spec.d.ts +46 -8
  295. package/dist/core/tools.d.ts +6 -2
  296. package/dist/core/tools.js +8 -4
  297. package/dist/core/untrusted-egress.js +29 -26
  298. package/dist/core/untrusted-text.d.ts +13 -10
  299. package/dist/core/untrusted-text.js +6 -44
  300. package/dist/core/workflow-journal-store.d.ts +4 -1
  301. package/dist/core/write-protect.d.ts +65 -29
  302. package/dist/core/write-protect.js +235 -177
  303. package/dist/engine/compaction/compaction.d.ts +2 -2
  304. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  305. package/dist/engine/execution-env/node-execution-env.js +16 -38
  306. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  307. package/dist/engine/execution-env/symlink-chain.js +32 -0
  308. package/dist/engine/harness/types.d.ts +7 -0
  309. package/dist/engine/llm/tool-turns.d.ts +3 -0
  310. package/dist/engine/llm/tool-turns.js +1 -0
  311. package/dist/engine/llm/types.d.ts +59 -23
  312. package/dist/engine/loop/agent-loop.js +16 -2
  313. package/dist/engine/session/memory-repo.js +11 -3
  314. package/dist/engine/session/repo-utils.d.ts +8 -0
  315. package/dist/engine/session/repo-utils.js +13 -0
  316. package/dist/index.d.ts +20 -23
  317. package/dist/index.js +17 -20
  318. package/dist/internal/harness.d.ts +1 -1
  319. package/dist/internal/harness.js +1 -1
  320. package/dist/internal/llm.d.ts +2 -2
  321. package/dist/internal/llm.js +1 -1
  322. package/dist/orchestration/governance-baseline-validity.js +1 -1
  323. package/dist/orchestration/run-spec.js +3 -3
  324. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  325. package/dist/orchestration/run-workflow-tool.js +38 -78
  326. package/dist/orchestration/workflow-governance.d.ts +21 -25
  327. package/dist/orchestration/workflow-governance.js +38 -78
  328. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  329. package/dist/orchestration/workflow-primitives.js +5 -12
  330. package/dist/orchestration/workflow-types.d.ts +1 -1
  331. package/dist/orchestration/workflow.d.ts +61 -11
  332. package/dist/orchestration/workflow.js +189 -117
  333. package/dist/scenarios/full-body.d.ts +1 -1
  334. package/dist/shell/lex.d.ts +0 -21
  335. package/dist/shell/lex.js +250 -68
  336. package/dist/shell/shell-words.d.ts +35 -0
  337. package/dist/shell/shell-words.js +65 -0
  338. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  339. package/dist/stores/file/checkpoint-store.js +5 -2
  340. package/dist/stores/file/index.d.ts +0 -8
  341. package/dist/stores/file/index.js +0 -12
  342. package/dist/stores/file/session-store.d.ts +3 -0
  343. package/dist/stores/file/session-store.js +44 -19
  344. package/dist/tools/artifact/artifact-tool.js +2 -0
  345. package/dist/tools/fs/bash-program-position.d.ts +12 -4
  346. package/dist/tools/fs/bash-program-position.js +32 -9
  347. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  348. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  349. package/dist/tools/fs/containment-face.d.ts +4 -0
  350. package/dist/tools/fs/containment-face.js +3 -0
  351. package/dist/tools/fs/fs-shared.d.ts +10 -0
  352. package/dist/tools/fs/fs-shared.js +18 -0
  353. package/dist/tools/fs/fs-write.js +4 -2
  354. package/dist/tools/fs/index.d.ts +1 -1
  355. package/dist/tools/fs/program-read-model.d.ts +46 -20
  356. package/dist/tools/fs/program-read-model.js +50 -20
  357. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  358. package/dist/tools/fs/program-read-model.rows.js +16 -15
  359. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  360. package/dist/tools/fs/read-deny-home.js +35 -49
  361. package/dist/tools/fs/read-deny.d.ts +23 -22
  362. package/dist/tools/fs/read-deny.js +114 -89
  363. package/dist/tools/fs/removal-targets.d.ts +56 -23
  364. package/dist/tools/fs/removal-targets.js +65 -87
  365. package/dist/tools/fs/safety.d.ts +29 -22
  366. package/dist/tools/fs/safety.js +17 -11
  367. package/dist/tools/fs/search.js +10 -8
  368. package/dist/tools/fs/shell-read-argv.js +1 -1
  369. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  370. package/dist/tools/fs/shell-read-bindings.js +324 -86
  371. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  372. package/dist/tools/fs/shell-read-builtins.js +43 -0
  373. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  374. package/dist/tools/fs/shell-read-check.js +67 -43
  375. package/dist/tools/fs/shell-read-establish.js +6 -6
  376. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  377. package/dist/tools/fs/shell-read-functions.js +29 -0
  378. package/dist/tools/fs/shell-read-judge.d.ts +51 -18
  379. package/dist/tools/fs/shell-read-judge.js +40 -4
  380. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  381. package/dist/tools/fs/shell-read-plan.js +118 -113
  382. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  383. package/dist/tools/fs/shell-read-start.js +16 -9
  384. package/dist/tools/fs/shell-read-word.js +4 -0
  385. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  386. package/dist/tools/fs/shell-read-workdir.js +281 -0
  387. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  388. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  389. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  390. package/dist/tools/fs/shell-reentry-text.js +3 -11
  391. package/dist/tools/task-list.d.ts +1 -2
  392. package/dist/tools/web.js +1 -1
  393. package/package.json +4 -1
  394. package/test/export-surface.snapshot.json +107 -143
  395. package/wire-changes/core@7.49.0.json +4765 -0
  396. package/dist/agents/teacher.d.ts +0 -159
  397. package/dist/agents/teacher.js +0 -577
  398. package/dist/agents/team.d.ts +0 -226
  399. package/dist/agents/team.js +0 -257
  400. package/dist/core/strategy-store.d.ts +0 -238
  401. package/dist/core/strategy-store.js +0 -253
  402. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  403. package/dist/orchestration/builtin-workflows.js +0 -159
  404. package/dist/scenarios/env.d.ts +0 -40
  405. package/dist/scenarios/env.js +0 -39
  406. package/dist/scenarios/scenario-registry.d.ts +0 -110
  407. package/dist/scenarios/scenario-registry.js +0 -140
  408. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  409. package/dist/scenarios/teacher-quickstart.js +0 -12
  410. package/dist/stores/cc/lockfile.d.ts +0 -10
  411. package/dist/stores/cc/lockfile.js +0 -98
  412. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  413. package/dist/stores/cc/mailbox-store.js +0 -255
  414. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  415. package/dist/stores/cc/roster-adapter.js +0 -117
  416. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  417. package/dist/stores/cc/sidecar-transcript.js +0 -264
  418. package/dist/stores/cc/task-list-store.d.ts +0 -2
  419. package/dist/stores/cc/task-list-store.js +0 -125
  420. package/dist/stores/file/strategy-store.d.ts +0 -97
  421. package/dist/stores/file/strategy-store.js +0 -341
@@ -0,0 +1,128 @@
1
+ import { canonicalize } from "./canonical-json.js";
2
+ export class McpConnectionPool {
3
+ entries = new Map();
4
+ dialing = new Map();
5
+ generation = new Map();
6
+ shut = false;
7
+ static keyOf(spec, principal, kind) {
8
+ const rest = Object.fromEntries(Object.keys(spec.transport).filter((k) => k !== "kind").map((k) => [k, Reflect.get(spec.transport, k)]));
9
+ return canonicalize([spec.name, kind ?? null, rest, principal ?? null]);
10
+ }
11
+ async acquire(key, dial, opts) {
12
+ if (this.shut)
13
+ return undefined;
14
+ if (opts?.fresh === true)
15
+ this.detach(key);
16
+ let entry = this.entries.get(key);
17
+ if (entry === undefined || entry.closed) {
18
+ let pending = this.dialing.get(key);
19
+ if (pending === undefined) {
20
+ const started = this.dialNew(key, this.generation.get(key) ?? 0, dial);
21
+ pending = started;
22
+ this.dialing.set(key, started);
23
+ const settled = () => {
24
+ if (this.dialing.get(key) === started)
25
+ this.dialing.delete(key);
26
+ };
27
+ void started.then(settled, settled);
28
+ }
29
+ entry = await pending;
30
+ }
31
+ return this.lease(entry);
32
+ }
33
+ detach(key) {
34
+ this.generation.set(key, (this.generation.get(key) ?? 0) + 1);
35
+ const e = this.entries.get(key);
36
+ if (e !== undefined) {
37
+ e.current = false;
38
+ this.entries.delete(key);
39
+ }
40
+ this.dialing.delete(key);
41
+ }
42
+ close() {
43
+ this.shut = true;
44
+ }
45
+ get live() {
46
+ let n = 0;
47
+ for (const e of this.entries.values())
48
+ if (!e.closed)
49
+ n++;
50
+ return n;
51
+ }
52
+ async dialNew(key, generation, dial) {
53
+ const client = await dial();
54
+ const entry = { client, refs: 0, listeners: new Set(), holders: new Map(), meta: new Map(), nextVersion: 0, current: true, closed: false };
55
+ client.onclose = () => {
56
+ entry.closed = true;
57
+ if (this.entries.get(key) === entry)
58
+ this.entries.delete(key);
59
+ for (const fn of [...entry.listeners]) {
60
+ try {
61
+ fn();
62
+ }
63
+ catch {
64
+ }
65
+ }
66
+ };
67
+ if ((this.generation.get(key) ?? 0) === generation)
68
+ this.entries.set(key, entry);
69
+ else
70
+ entry.current = false;
71
+ return entry;
72
+ }
73
+ lease(entry) {
74
+ entry.refs++;
75
+ const mine = new Set();
76
+ let released = false;
77
+ const cached = () => {
78
+ const held = new Set([...entry.holders.values()].flat());
79
+ return [...entry.meta].filter(([name]) => held.has(name)).map(([, r]) => r.tool);
80
+ };
81
+ const lease = {
82
+ client: entry.client,
83
+ onClose: (fn) => {
84
+ mine.add(fn);
85
+ entry.listeners.add(fn);
86
+ },
87
+ openListing: () => {
88
+ const version = entry.nextVersion++;
89
+ return (tools, apply, retained) => {
90
+ for (const tool of tools) {
91
+ const prior = entry.meta.get(tool.name);
92
+ if (retained?.has(tool.name) === true) {
93
+ if (prior === undefined)
94
+ entry.meta.set(tool.name, { tool, version: -1 });
95
+ continue;
96
+ }
97
+ if (prior !== undefined && prior.version > version)
98
+ continue;
99
+ entry.meta.delete(tool.name);
100
+ entry.meta.set(tool.name, { tool, version });
101
+ }
102
+ if (!released)
103
+ entry.holders.set(lease, tools.map((t) => t.name));
104
+ entry.apply = apply;
105
+ apply(cached());
106
+ };
107
+ },
108
+ release: async () => {
109
+ if (released)
110
+ return;
111
+ released = true;
112
+ for (const fn of mine)
113
+ entry.listeners.delete(fn);
114
+ entry.refs--;
115
+ if (entry.holders.delete(lease) && entry.refs > 0)
116
+ entry.apply?.(cached());
117
+ if (entry.refs > 0)
118
+ return;
119
+ entry.current = false;
120
+ for (const [k, v] of this.entries)
121
+ if (v === entry)
122
+ this.entries.delete(k);
123
+ await entry.client.close().catch(() => undefined);
124
+ },
125
+ };
126
+ return lease;
127
+ }
128
+ }
@@ -2,7 +2,8 @@ import type { AssertAllKeysHandled } from "./ask-origin.js";
2
2
  /**
3
3
  * The closed set of failure classes ({@link McpFailure.kind}):
4
4
  * · `connect_refused` — a connect-phase errno (ECONNREFUSED / ENOTFOUND / EAI_AGAIN / EHOSTUNREACH /
5
- * ENETUNREACH / UND_ERR_CONNECT_TIMEOUT): the request provably never left;
5
+ * ENETUNREACH / UND_ERR_CONNECT_TIMEOUT), or a proxy's refusal of the tunnel
6
+ * request: the request provably never left;
6
7
  * · `connection_failed` — any other errno / undici code on the cause chain (a reset or a timeout
7
8
  * mid-exchange): the request may have run;
8
9
  * · `connection_closed` — the SDK reported the transport closed (`McpError` `ConnectionClosed`): in
@@ -1,5 +1,6 @@
1
1
  import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
2
2
  import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
+ import { proxyTunnelRefusedSentence, readConnectFailure } from "../brain/errors.js";
3
4
  export const MCP_FAILURE_KINDS = Object.freeze([
4
5
  "connect_refused",
5
6
  "connection_failed",
@@ -102,6 +103,11 @@ export const FAILURE_CLASSIFIER = [
102
103
  when: (err, at) => at.phase === "connect" && err instanceof Error && err.code === "ERR_INVALID_URL",
103
104
  reads: () => ({ kind: "invalid_config" }),
104
105
  },
106
+ {
107
+ name: "proxy refused the tunnel",
108
+ when: (err) => readConnectFailure(err).proxyRefusal !== undefined,
109
+ reads: () => ({ kind: "connect_refused" }),
110
+ },
105
111
  {
106
112
  name: "node error code, not a network errno",
107
113
  when: (err) => {
@@ -151,8 +157,13 @@ export function describeHttpTransportFailure(err) {
151
157
  return { condition: `its HTTP endpoint answered ${f.httpStatus} instead of an MCP response`, delivered: f.delivered, httpStatus: f.httpStatus };
152
158
  case "not_mcp_response":
153
159
  return { condition: "its HTTP endpoint answered something that is not an MCP response", delivered: f.delivered };
154
- case "connect_refused":
155
- return { condition: `its HTTP endpoint could not be reached (${networkErrorCode(err)})`, delivered: f.delivered };
160
+ case "connect_refused": {
161
+ const proxy = readConnectFailure(err).proxyRefusal;
162
+ return {
163
+ condition: `its HTTP endpoint could not be reached (${proxy !== undefined ? proxyTunnelRefusedSentence(proxy.status) : networkErrorCode(err)})`,
164
+ delivered: f.delivered,
165
+ };
166
+ }
156
167
  case "connection_failed":
157
168
  return { condition: `the connection to its HTTP endpoint failed (${networkErrorCode(err)})`, delivered: f.delivered };
158
169
  case "connection_closed":
@@ -1,4 +1,5 @@
1
1
  import { type ProtocolId } from "./protocol-table.js";
2
+ import { McpConnectionPool } from "./mcp-connection-pool.js";
2
3
  import { type McpDelivered, type McpFailureKind, type McpServerLiveness } from "./mcp-failure.js";
3
4
  import type { AgentTool } from "../internal/harness-types.js";
4
5
  import type { ImageContent, TextContent } from "../internal/llm.js";
@@ -626,6 +627,9 @@ reminderDisclosure?: {
626
627
  }, mcpRevocations?: {
627
628
  isRevoked(serverName: string): boolean;
628
629
  onProbeFailure?: (error: unknown) => void;
630
+ }, poolOpts?: {
631
+ pool: McpConnectionPool;
632
+ ownsPool?: boolean;
629
633
  }): Promise<MaterializedMcp>;
630
634
  /**
631
635
  * Fold the caller's AUTHORITATIVE per-tool override (design F: caller = trust root) over the server-hint axis.
package/dist/core/mcp.js CHANGED
@@ -4,6 +4,8 @@ import { resolveEnvBudget } from "./env-budget.js";
4
4
  import { MCP_NAMESPACE } from "./protocol-table.js";
5
5
  import { findNamespacePrefixCollision, mintNamespacePrefix, mintNamespacedToolName, normalizeNameSegment } from "./protocol-naming.js";
6
6
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
7
+ import { McpConnectionPool } from "./mcp-connection-pool.js";
8
+ import { MCP_RESOURCE_LIST_ALLOW, MCP_RESOURCE_READ_ALLOW } from "./mounted-mcp.js";
7
9
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
8
10
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
9
11
  import { classifyMcpFailure, describeHttpTransportFailure, livenessOf } from "./mcp-failure.js";
@@ -657,7 +659,7 @@ export function mcpToolSchemaProblem(schema) {
657
659
  }
658
660
  return undefined;
659
661
  }
660
- export async function materializeMcpTools(specs, principal, onElicit, imageResizer, reminderDisclosure, mcpRevocations) {
662
+ export async function materializeMcpTools(specs, principal, onElicit, imageResizer, reminderDisclosure, mcpRevocations, poolOpts) {
661
663
  const entries = snapshotMcpEntries(specs);
662
664
  {
663
665
  const collision = findNamespacePrefixCollision(MCP_NAMESPACE, entries.map((s) => s.name));
@@ -696,7 +698,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
696
698
  const mcpDisclosure = reminderDisclosure?.reminderMark !== undefined
697
699
  ? { mark: reminderDisclosure.reminderMark, windows: new Map(), ...(reminderDisclosure.counts !== undefined ? { counts: reminderDisclosure.counts } : {}) }
698
700
  : undefined;
699
- const clients = [];
701
+ const connections = [];
700
702
  const tools = [];
701
703
  const toolAxes = [];
702
704
  const warnings = [];
@@ -710,8 +712,8 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
710
712
  const redialsInFlight = new Set();
711
713
  const commitConnectedServer = (spec, s, transportKind) => {
712
714
  const raised = [];
713
- clients.push(s.client);
714
- const handle = { name: spec.name, spec, client: s.client, health: s.health, tools: s.tools, listedRaw: s.listedTools, transportKind, announce: s.announce, instructions: s.instructions };
715
+ connections.push({ client: s.client, close: s.close });
716
+ const handle = { name: spec.name, spec, client: s.client, openListing: s.openListing, health: s.health, tools: s.tools, listedRaw: s.listedTools, transportKind, announce: s.announce, instructions: s.instructions };
715
717
  const hIdx = serverHandles.findIndex((h) => h.name === spec.name);
716
718
  if (hIdx === -1)
717
719
  serverHandles.push(handle);
@@ -796,7 +798,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
796
798
  if (before !== undefined || owedRemoval || hadPendingAdd)
797
799
  instructionsDelta.pendingRemovals.push(name);
798
800
  };
799
- const settled = await Promise.allSettled(entries.map((spec, i) => connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKinds[i])));
801
+ const settled = await Promise.allSettled(entries.map((spec, i) => connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKinds[i], poolOpts?.pool)));
800
802
  try {
801
803
  for (let i = 0; i < entries.length; i++) {
802
804
  const r = settled[i];
@@ -822,7 +824,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
822
824
  toolAxes.push(...resourceTools.axes);
823
825
  }
824
826
  catch (mergeErr) {
825
- await Promise.allSettled(settled.map((r) => (r.status === "fulfilled" ? r.value.client.close() : Promise.resolve())));
827
+ await Promise.allSettled(settled.map((r) => (r.status === "fulfilled" ? r.value.close() : Promise.resolve())));
826
828
  throw mergeErr;
827
829
  }
828
830
  const redialOnce = async (server) => {
@@ -847,15 +849,14 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
847
849
  prior.announce.fn = undefined;
848
850
  prior.health.observe = undefined;
849
851
  serverHandles.splice(hIdx, 1);
850
- const cIdx = clients.indexOf(prior.client);
851
- if (cIdx !== -1)
852
- clients.splice(cIdx, 1);
853
- await prior.client.close().catch(() => undefined);
852
+ const cIdx = connections.findIndex((c) => c.client === prior.client);
853
+ const priorConnection = cIdx === -1 ? undefined : connections.splice(cIdx, 1)[0];
854
+ await (priorConnection?.close() ?? prior.client.close()).catch(() => undefined);
854
855
  }
855
856
  const dialKind = readDialKind(spec);
856
857
  let connected;
857
858
  try {
858
- connected = await connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKind);
859
+ connected = await connectServer(spec, principal, onElicit, imageResizer, mcpDisclosure, isServerRevoked, dialKind, poolOpts?.pool, { fresh: true });
859
860
  }
860
861
  catch (err) {
861
862
  const { kind, delivered, httpStatus } = classifyMcpFailure(err, { phase: "connect", transport: dialKind });
@@ -885,7 +886,7 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
885
886
  };
886
887
  }
887
888
  if (disposing) {
888
- await connected.client.close().catch(() => undefined);
889
+ await connected.close().catch(() => undefined);
889
890
  return declined("refused", "this materialization was disposed while the re-dial was in flight — the new connection was closed");
890
891
  }
891
892
  const raised = commitConnectedServer(spec, connected, dialKind);
@@ -934,12 +935,13 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
934
935
  continue;
935
936
  }
936
937
  try {
938
+ const cacheTools = h.openListing();
937
939
  const listed = await listToolsLenient(h.client);
938
940
  const advertised = new Set(listed.tools.map((t) => t.name));
939
941
  const retainedRaw = listed.incomplete !== undefined ? h.listedRaw.filter((t) => !advertised.has(t.name)) : [];
940
942
  const mergedRaw = retainedRaw.length > 0 ? [...listed.tools, ...retainedRaw] : listed.tools;
941
943
  const { serverTools, serverAxes, dropped, accepted } = intakeListedTools({ tools: mergedRaw }, h.spec, h.client, h.health, imageResizer, mcpDisclosure, isServerRevoked, h.transportKind);
942
- cacheMcpToolMetadata(h.client, accepted);
944
+ cacheTools(accepted, new Set(retainedRaw.map((t) => t.name)));
943
945
  const priorNames = h.tools.map((t) => t.name);
944
946
  const newNames = serverTools.map((t) => t.name);
945
947
  const added = newNames.filter((n) => !priorNames.includes(n));
@@ -995,7 +997,9 @@ export async function materializeMcpTools(specs, principal, onElicit, imageResiz
995
997
  reconnect: redialOnce,
996
998
  dispose: async () => {
997
999
  disposing = true;
998
- await Promise.allSettled(clients.map((c) => c.close()));
1000
+ await Promise.allSettled(connections.map((c) => c.close()));
1001
+ if (poolOpts?.ownsPool === true)
1002
+ poolOpts.pool.close();
999
1003
  },
1000
1004
  };
1001
1005
  }
@@ -1517,48 +1521,69 @@ async function listToolsLenient(client, options) {
1517
1521
  });
1518
1522
  return { tools: walk.items, ...(walk.incomplete !== undefined ? { incomplete: walk.incomplete } : {}) };
1519
1523
  }
1520
- async function connectServer(spec, principal, onElicit, imageResizer, reminderDisclosure, isServerRevoked, transportKind) {
1524
+ async function connectServer(spec, principal, onElicit, imageResizer, reminderDisclosure, isServerRevoked, transportKind, pool, dialOpts) {
1521
1525
  const elicitOn = spec.elicitation === true && onElicit !== undefined;
1522
1526
  const health = { dead: false, pendingElicitations: 0, lastElicitationClosedAt: 0 };
1523
- const client = new Client({ name: `sema-core/${spec.name}`, version: "0.1.0" }, { capabilities: elicitOn ? { elicitation: { form: {} } } : {} });
1524
- if (elicitOn) {
1525
- client.setRequestHandler(ElicitRequestSchema, async (request, extra) => {
1526
- health.pendingElicitations++;
1527
- try {
1528
- const p = request.params;
1529
- const req = {
1530
- server: spec.name,
1531
- message: typeof p.message === "string" ? p.message : "",
1532
- ...(p.requestedSchema !== undefined ? { requestedSchema: p.requestedSchema } : {}),
1533
- ...(principal !== undefined ? { principal } : {}),
1534
- };
1535
- const answer = await onElicit(req, extra?.signal);
1536
- return answer.action === "accept" ? { action: "accept", content: answer.content ?? {} } : { action: answer.action };
1537
- }
1538
- finally {
1539
- health.pendingElicitations--;
1540
- health.lastElicitationClosedAt = Date.now();
1541
- }
1542
- });
1543
- }
1544
- const transport = buildTransport(spec, principal, transportKind);
1545
1527
  const announce = {};
1546
1528
  const startupMs = mcpStartupTimeoutMs();
1547
1529
  const startupOpts = startupMs !== undefined ? { timeout: startupMs } : undefined;
1530
+ const dialClient = async () => {
1531
+ const client = new Client({ name: `sema-core/${spec.name}`, version: "0.1.0" }, { capabilities: elicitOn ? { elicitation: { form: {} } } : {} });
1532
+ if (elicitOn) {
1533
+ client.setRequestHandler(ElicitRequestSchema, async (request, extra) => {
1534
+ health.pendingElicitations++;
1535
+ try {
1536
+ const p = request.params;
1537
+ const req = {
1538
+ server: spec.name,
1539
+ message: typeof p.message === "string" ? p.message : "",
1540
+ ...(p.requestedSchema !== undefined ? { requestedSchema: p.requestedSchema } : {}),
1541
+ ...(principal !== undefined ? { principal } : {}),
1542
+ };
1543
+ const answer = await onElicit(req, extra?.signal);
1544
+ return answer.action === "accept" ? { action: "accept", content: answer.content ?? {} } : { action: answer.action };
1545
+ }
1546
+ finally {
1547
+ health.pendingElicitations--;
1548
+ health.lastElicitationClosedAt = Date.now();
1549
+ }
1550
+ });
1551
+ }
1552
+ const transport = buildTransport(spec, principal, transportKind);
1553
+ try {
1554
+ await client.connect(transport, startupOpts);
1555
+ }
1556
+ catch (err) {
1557
+ await client.close().catch(() => undefined);
1558
+ throw err;
1559
+ }
1560
+ return client;
1561
+ };
1562
+ const lease = pool !== undefined && !elicitOn ? await pool.acquire(McpConnectionPool.keyOf(spec, principal, transportKind), dialClient, dialOpts) : undefined;
1563
+ const client = lease !== undefined ? lease.client : await dialClient();
1564
+ const close = () => (lease !== undefined ? lease.release() : client.close());
1565
+ const openListing = () => {
1566
+ const write = lease?.openListing();
1567
+ return (tools, retained) => (write !== undefined ? write(tools, (all) => cacheMcpToolMetadata(client, all), retained) : cacheMcpToolMetadata(client, tools));
1568
+ };
1548
1569
  try {
1549
- await client.connect(transport, startupOpts);
1550
- client.onclose = () => {
1570
+ const onClosed = () => {
1551
1571
  health.dead = true;
1552
1572
  announce.fn?.();
1553
1573
  };
1574
+ if (lease !== undefined)
1575
+ lease.onClose(onClosed);
1576
+ else
1577
+ client.onclose = onClosed;
1578
+ const cacheTools = openListing();
1554
1579
  const listed = await listToolsLenient(client, startupOpts);
1555
1580
  const { serverTools, serverAxes, dropped, advisories, accepted } = intakeListedTools(listed, spec, client, health, imageResizer, reminderDisclosure, isServerRevoked, transportKind);
1556
- cacheMcpToolMetadata(client, accepted);
1581
+ cacheTools(accepted);
1557
1582
  const caps = client.getServerCapabilities();
1558
1583
  const resourceInfo = caps?.resources
1559
1584
  ? {
1560
- listAllowed: !spec.allowTools || spec.allowTools.includes("list_resources"),
1561
- readAllowed: !spec.allowTools || spec.allowTools.includes("read_resource"),
1585
+ listAllowed: !spec.allowTools || spec.allowTools.includes(MCP_RESOURCE_LIST_ALLOW),
1586
+ readAllowed: !spec.allowTools || spec.allowTools.includes(MCP_RESOURCE_READ_ALLOW),
1562
1587
  }
1563
1588
  : undefined;
1564
1589
  const rawInstructions = client.getInstructions();
@@ -1574,6 +1599,8 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
1574
1599
  return {
1575
1600
  status,
1576
1601
  client,
1602
+ close,
1603
+ openListing,
1577
1604
  health,
1578
1605
  announce,
1579
1606
  tools: serverTools,
@@ -1588,7 +1615,7 @@ async function connectServer(spec, principal, onElicit, imageResizer, reminderDi
1588
1615
  };
1589
1616
  }
1590
1617
  catch (err) {
1591
- await client.close().catch(() => undefined);
1618
+ await close().catch(() => undefined);
1592
1619
  throw err;
1593
1620
  }
1594
1621
  }
@@ -1,4 +1,4 @@
1
- import { allowedToolNames, readDeniedEntry, readToolNameList } from "../../agents/tool-filter.js";
1
+ import { resolveToolSubset } from "../../agents/tool-filter.js";
2
2
  const TOOL_CONTENT_ORIGIN_SET = { external: true, execution: true, local: true };
3
3
  export const TOOL_CONTENT_ORIGINS = Object.keys(TOOL_CONTENT_ORIGIN_SET);
4
4
  export function isToolContentOrigin(value) {
@@ -18,25 +18,13 @@ export function classifyToolContentOrigin(input) {
18
18
  export function withContentOrigin(tool, origin) {
19
19
  return Object.assign(tool, { contentOrigin: origin });
20
20
  }
21
- function selectedBy(entry, tool) {
22
- return tool.name === entry || (tool.aliases?.includes(entry) ?? false);
23
- }
24
21
  export function delegationCallIsExternal(input) {
25
22
  if (input.faces === undefined || input.pool === undefined)
26
23
  return true;
27
24
  const face = input.requestedType === undefined ? undefined : input.faces.find((f) => f.name === input.requestedType);
28
25
  if (face === undefined)
29
26
  return true;
30
- const selectedFor = (f) => {
31
- const deniedList = readToolNameList(f.denyTools);
32
- const d = deniedList.kind === "entries" ? deniedList.entries : [];
33
- const a = allowedToolNames(f.allowTools);
34
- const denies = (t) => d.some((x) => {
35
- const read = readDeniedEntry(x);
36
- return read.kind === "name" && selectedBy(read.name, t);
37
- });
38
- return input.pool.filter((t) => (a === undefined || [...a].some((x) => selectedBy(x, t))) && !denies(t));
39
- };
27
+ const selectedFor = (f) => resolveToolSubset(input.pool, f.allowTools, f.denyTools);
40
28
  if (selectedFor(face).some((t) => input.isPolluting(t)))
41
29
  return true;
42
30
  if (face.canRedelegate === true && input.faces.some((f) => selectedFor(f).some((t) => input.isPolluting(t))))
@@ -5,6 +5,7 @@ import { type OriginClearanceRow } from "./origin-clearance.js";
5
5
  import { type CommittedBinding, type EraseMemoryEntriesInput, type MemoryErasureAttestation, type TransferEvidence } from "./file-backend.js";
6
6
  import { type MemoryExportBundle, type MemoryImportReport } from "./export-bundle.js";
7
7
  import { type ChallengeAssignment, type ChallengeEvent, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, type MemoryPartitionIncidentSink, type RetrievedAccountRow, type SessionPollutionMarkOutcome, type SessionPollutionRecord, type SessionCaptureOptOutMarkOutcome, type SessionCaptureOptOutRecord, type SessionCaptureRecordStore } from "./layout.js";
8
+ import { type SessionIncarnationResolver } from "./session-incarnation.js";
8
9
  import type { HarvestReport, MemoryAnnouncement, MemoryBackend, MemoryEntry, MemoryEntryHeader, MemoryEntryOrigin, MemoryScopeEnumeration, MemorySessionHandle, ScanFinding, SessionCaptureResidueSweep } from "./types.js";
9
10
  /**
10
11
  * The RECALL-FRAMING sentence shared by every arm of the `# Memory` prompt section — the one
@@ -289,12 +290,13 @@ export interface MemoryEngineOptions {
289
290
  * for the fail-closed contract each leg must keep.
290
291
  */
291
292
  captureRecordStore?: SessionCaptureRecordStore;
292
- /** the engine half of {@link import("../runner-deps.js").RunnerDeps.memorySessionIncarnation}
293
- * (that seat owns the meaning and the value's contract); resolved through
294
- * {@link createSessionIncarnationSeat}. Absent ⇒ nothing is stamped, nothing is asked for. */
295
- sessionIncarnation?: (session: {
296
- sessionId: string;
297
- }) => string | undefined;
293
+ /** which occupant of a session id is running now — the session row's incarnation
294
+ * ({@link import("../../engine/harness/types.js").SessionMetadata.incarnation} owns the meaning: stable
295
+ * for one occupant's life, different for the next, only ever compared). The Runner fills it from the
296
+ * session it acquired ({@link import("./session-incarnation.js").sessionIncarnationResolver}); a host
297
+ * that builds an engine itself passes the same answer. Resolved through {@link createSessionIncarnationSeat}.
298
+ * Absent ⇒ nothing is stamped, nothing is asked for, every record binds by id. */
299
+ sessionIncarnation?: SessionIncarnationResolver;
298
300
  /**
299
301
  * design/336 §4.2 — the delegation settlement window in ms (default
300
302
  * {@link DEFAULT_HOLD_SETTLE_TIMEOUT_MS} = 72h): a `pending` settlement row older than this is
@@ -838,8 +840,6 @@ export interface SessionMemoryStatus {
838
840
  export declare class MemoryEngine {
839
841
  private readonly backend;
840
842
  private readonly memoryDir;
841
- /** {@link memoryDir}'s physical form as this engine first mounted it; every later mount compares, never re-resolves. */
842
- private mountedRoot;
843
843
  private readonly controlDir;
844
844
  private readonly now;
845
845
  private readonly perScopeBudgetBytes;
@@ -855,8 +855,10 @@ export declare class MemoryEngine {
855
855
  /** {@link MemoryEngineOptions.onIncident} — the advisory disclosure seat (partition + announce codes). */
856
856
  private readonly onIncident;
857
857
  private unsettleableDisclosed;
858
- /** A backend-pinned directory (FileBackend zero-copy detection). */
859
- private readonly backendPinnedRoot?;
858
+ /** The backend pins its own directory (the File backend), which the constructor proved is the memory dir:
859
+ * the entry files ARE the backend's storage (zero-copy). False = a copy-out projection of a backend
860
+ * without a directory. */
861
+ private readonly zeroCopy;
860
862
  constructor(opts: MemoryEngineOptions);
861
863
  /** the session identity axis (resolution + disclosures: `session-incarnation.ts`). */
862
864
  private readonly incarnation;
@@ -1624,8 +1626,8 @@ export declare class MemoryEngine {
1624
1626
  */
1625
1627
  sessionMemoryStatus(sessionId: string): Promise<SessionMemoryStatus>;
1626
1628
  /** The committed, side-effect-free audit read: the adoption-restricted committed view when the
1627
- * backend offers one (zero-copy File — ledger+shadow, no disk adoption), else the non-adopting
1628
- * retrieval view (copy-out File), else the backend itself (Pg/TiDB shapes — naturally committed
1629
+ * backend offers one (the File backend — ledger+shadow, no disk adoption), else a non-adopting
1630
+ * retrieval view where one is offered, else the backend itself (Pg/TiDB shapes — naturally committed
1629
1631
  * and side-effect-free per the getByIds contract clause). */
1630
1632
  private committedAuditFace;
1631
1633
  /** The COMMITTED header listing of `scopes` through the face above: the name source of the
@@ -1745,9 +1747,9 @@ export declare class MemoryEngine {
1745
1747
  * side-effect-free, or assembling one harvest mutates the store it is reading. Reading order:
1746
1748
  * - zero-copy File: the control-plane shadow IS the committed state (the disk file is the
1747
1749
  * session's own working copy — exactly what must NOT serve as the committed baseline);
1748
- * - copy-out with a `retrievalView` face (File): the lock-free non-adopting view;
1749
- * - twins (Pg/TiDB shapes): plain `getByIds` — naturally committed-state and side-effect-free
1750
- * (the contract clause on {@link MemoryBackend.getByIds}).
1750
+ * - copy-out (a backend without a directory): its `retrievalView` face when it has one, else plain
1751
+ * `getByIds` — twins (Pg/TiDB shapes) are naturally committed-state and side-effect-free (the
1752
+ * contract clause on {@link MemoryBackend.getByIds}).
1751
1753
  */
1752
1754
  private committedFrontmatterFor;
1753
1755
  /** L4/C-F9 (S2-0) — capture a gate-rejected file into control-plane quarantine FROM THE SCANNED
@@ -1788,17 +1790,25 @@ export declare class MemoryEngine {
1788
1790
  * @returns the rejection to report, or `undefined` when the index is clean/absent.
1789
1791
  */
1790
1792
  private gateDerivedIndex;
1791
- /** The file backend's verdict at an act the engine itself performs on a store path ({@link
1792
- * landsOutsideStore}): throws `memory.target_outside_store` when `path` would land outside `root`;
1793
- * each caller's existing failure lane reports it. `root` is the mount's canonical root where a
1794
- * handle exists, so a root re-pointed after the mount is judged against the one it mounted. */
1793
+ /** The act gate at every write, rename or removal the engine itself performs under the memory dir: the
1794
+ * anchor is read at the act ({@link assertRootAnchored}, with the session's `handle` where one exists),
1795
+ * and `path` must land inside the anchored root ({@link landsOutsideStore}) — else `memory.target_outside_store`;
1796
+ * each caller's existing failure lane reports it. Read at the act, not at the face's head: a face awaits
1797
+ * between its first read and its writes, and a root re-pointed (or re-anchored) in that window is judged here. */
1795
1798
  private refuseOutsideStore;
1799
+ /** {@link refuseOutsideStore} as a value, for a site whose failure lane is a report row rather than a
1800
+ * throw: the refusal's text, or `undefined` when the act may proceed. */
1801
+ private storeActRefusedText;
1802
+ /** The memory dir against its anchor ({@link anchorStoreRoot}), read every time: at every mount and at the head
1803
+ * of every face acting on the memory dir itself; answers the anchored root. With a `handle`, its mount root
1804
+ * must be the anchored one too (a handle mounted before a re-anchor names a tree the store no longer has). */
1805
+ private assertRootAnchored;
1796
1806
  /** Projection write: reads the target to skip a no-op, then writes — the same check-then-use shape
1797
1807
  * as the containment restores, so it takes the same no-follow write. A link at a projection path
1798
1808
  * is never a supported layout (the harvest scan refuses symlinked entry files outright), and this
1799
1809
  * site already reports write failures by throwing, so ELOOP joins the failures it already had. A
1800
- * target whose directory resolves outside `root` (a directory on the path is a link) is refused
1801
- * the same way, before anything is read or written ({@link landsOutsideStore}). */
1810
+ * target whose directory resolves outside the anchored root (a directory on the path is a link) is
1811
+ * refused the same way, before anything is read or written ({@link refuseOutsideStore}). */
1802
1812
  private writeIfChanged;
1803
1813
  /** Persist the canonical projection back to the session file (id minting / frontmatter completion).
1804
1814
  * C-F6 (S2-0): called ONLY after the backend transaction committed — never ahead of the journal
@@ -1822,7 +1832,7 @@ export declare class MemoryEngine {
1822
1832
  private repairProjectionSeat;
1823
1833
  /**
1824
1834
  * #366 — validate a projection-debt row against the COMMITTED state (side-effect-free read: the
1825
- * retrievalView face in copy-out, never the File backend's adopting `getByIds`). Three-valued on
1835
+ * backend's retrievalView face in copy-out when it offers one). Three-valued on
1826
1836
  * purpose: `valid` binds, `stale` clears the row (the seat claim dissolved — entry gone, moved or
1827
1837
  * renamed), and `unknown` (committed state unreadable) makes the caller DEFER the file fail-closed
1828
1838
  * — treating a transient read fault as "stale" would clear the row and mint the very duplicate