@sema-agent/core 7.55.0 → 7.57.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 (502) hide show
  1. package/CHANGELOG.md +1054 -0
  2. package/LICENSE +1 -1
  3. package/dist/agents/cascade.js +1 -1
  4. package/dist/agents/cc-peer-directory.js +1 -0
  5. package/dist/agents/child-model-seat.d.ts +0 -11
  6. package/dist/agents/child-model-seat.js +0 -3
  7. package/dist/agents/list-agents-tool.d.ts +3 -1
  8. package/dist/agents/list-agents-tool.js +7 -7
  9. package/dist/agents/org-delivery-gate.js +3 -4
  10. package/dist/agents/peer-directory.d.ts +22 -4
  11. package/dist/agents/peer-directory.js +24 -2
  12. package/dist/agents/peer-held-queue.d.ts +69 -49
  13. package/dist/agents/peer-held-queue.js +255 -106
  14. package/dist/agents/peer-session-drain.js +65 -45
  15. package/dist/agents/repair-loop.js +2 -2
  16. package/dist/agents/send-message-tool.js +7 -6
  17. package/dist/agents/subagent.d.ts +6 -4
  18. package/dist/agents/subagent.js +72 -68
  19. package/dist/agents/tool-filter.d.ts +7 -5
  20. package/dist/agents/tool-filter.js +12 -9
  21. package/dist/agents/verify.d.ts +3 -2
  22. package/dist/agents/verify.js +3 -3
  23. package/dist/brain/anthropic.js +45 -80
  24. package/dist/brain/media-degrade.d.ts +18 -7
  25. package/dist/brain/media-degrade.js +13 -2
  26. package/dist/brain/model-capability.d.ts +37 -0
  27. package/dist/brain/model-capability.js +34 -0
  28. package/dist/brain/model-presets.d.ts +2 -8
  29. package/dist/brain/model-presets.js +1 -6
  30. package/dist/brain/open-responses.js +23 -34
  31. package/dist/brain/openai.js +25 -96
  32. package/dist/brain/provider-dialect.d.ts +3 -2
  33. package/dist/brain/provider-dialect.js +2 -2
  34. package/dist/brain/reasoning-request.d.ts +96 -0
  35. package/dist/brain/reasoning-request.js +174 -0
  36. package/dist/brain/reasoning.d.ts +11 -11
  37. package/dist/brain/reasoning.js +4 -3
  38. package/dist/brain/request-params.d.ts +13 -4
  39. package/dist/brain/request-params.js +21 -5
  40. package/dist/brain/status-sink.d.ts +20 -0
  41. package/dist/brain/status-sink.js +7 -0
  42. package/dist/brain/stream-engine.d.ts +9 -0
  43. package/dist/brain/stream-engine.js +24 -10
  44. package/dist/brain/stream-shared.d.ts +5 -4
  45. package/dist/brain/stream-shared.js +4 -4
  46. package/dist/core/a2a.d.ts +2 -1
  47. package/dist/core/a2a.js +19 -13
  48. package/dist/core/agent-definition.d.ts +10 -0
  49. package/dist/core/allow-entry.d.ts +23 -23
  50. package/dist/core/allow-entry.js +42 -46
  51. package/dist/core/allow-rule-shadow.d.ts +3 -3
  52. package/dist/core/approval-object.d.ts +21 -5
  53. package/dist/core/approval-object.js +44 -17
  54. package/dist/core/ask-origin.d.ts +66 -20
  55. package/dist/core/ask-origin.js +63 -23
  56. package/dist/core/ask-question.d.ts +51 -8
  57. package/dist/core/ask-question.js +3 -4
  58. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  59. package/dist/core/ask-unresolvable-notice.js +16 -2
  60. package/dist/core/auto-compaction.d.ts +71 -6
  61. package/dist/core/auto-compaction.js +42 -26
  62. package/dist/core/background-agent-store.d.ts +6 -2
  63. package/dist/core/background-agent-store.js +1 -1
  64. package/dist/core/checkpoint-generation.d.ts +53 -0
  65. package/dist/core/checkpoint-generation.js +35 -0
  66. package/dist/core/checkpoint-queries.d.ts +180 -0
  67. package/dist/core/checkpoint-queries.js +272 -0
  68. package/dist/core/checkpoint-requirements.d.ts +19 -1
  69. package/dist/core/checkpoint-requirements.js +6 -0
  70. package/dist/core/checkpoint-store.d.ts +105 -53
  71. package/dist/core/checkpoint-store.js +43 -20
  72. package/dist/core/cross-boundary-taint.d.ts +6 -5
  73. package/dist/core/cross-boundary-taint.js +5 -5
  74. package/dist/core/decision-receipt.d.ts +37 -3
  75. package/dist/core/decision-receipt.js +17 -17
  76. package/dist/core/delegation-not-started.d.ts +6 -0
  77. package/dist/core/delegation-not-started.js +17 -0
  78. package/dist/core/engine-attestation.d.ts +93 -0
  79. package/dist/core/engine-attestation.js +70 -0
  80. package/dist/core/engine-capabilities.d.ts +4 -1
  81. package/dist/core/engine-capabilities.js +1 -1
  82. package/dist/core/engine-notice.d.ts +32 -12
  83. package/dist/core/engine-notice.js +6 -0
  84. package/dist/core/file-history-store.d.ts +104 -22
  85. package/dist/core/file-history-store.js +37 -19
  86. package/dist/core/gate-fold.d.ts +1 -1
  87. package/dist/core/gate-fold.js +22 -10
  88. package/dist/core/gate-lanes.js +73 -65
  89. package/dist/core/gate-outcome.d.ts +26 -5
  90. package/dist/core/gate-outcome.js +26 -0
  91. package/dist/core/governance-codes.d.ts +5 -1
  92. package/dist/core/governance-codes.js +6 -0
  93. package/dist/core/hooks.d.ts +19 -18
  94. package/dist/core/hooks.js +3 -1
  95. package/dist/core/host-floor.d.ts +128 -0
  96. package/dist/core/host-floor.js +206 -0
  97. package/dist/core/host-target.d.ts +38 -3
  98. package/dist/core/host-target.js +38 -5
  99. package/dist/core/mailbox-store.d.ts +62 -1
  100. package/dist/core/mailbox-store.js +59 -0
  101. package/dist/core/mcp-name-judge.d.ts +46 -0
  102. package/dist/core/mcp-name-judge.js +61 -0
  103. package/dist/core/mcp-probe.d.ts +1 -1
  104. package/dist/core/mcp-probe.js +2 -5
  105. package/dist/core/mcp.d.ts +5 -1
  106. package/dist/core/mcp.js +70 -64
  107. package/dist/core/memory-engine/consolidation-driver.js +4 -3
  108. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  109. package/dist/core/memory-engine/distiller.js +26 -17
  110. package/dist/core/memory-engine/engine.js +4 -4
  111. package/dist/core/memory-engine/layout.d.ts +60 -8
  112. package/dist/core/memory-engine/layout.js +70 -8
  113. package/dist/core/model-seat.d.ts +10 -3
  114. package/dist/core/mods/classic-events.d.ts +67 -0
  115. package/dist/core/mods/classic-events.js +1 -0
  116. package/dist/core/mods/dollar.d.ts +13 -0
  117. package/dist/core/mods/extension-call.d.ts +31 -0
  118. package/dist/core/mods/extension-call.js +43 -0
  119. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  120. package/dist/core/mods/kernel/dispatch.js +140 -69
  121. package/dist/core/mods/kernel/events.d.ts +47 -11
  122. package/dist/core/mods/kernel/events.js +66 -42
  123. package/dist/core/mods/kernel/index.d.ts +4 -4
  124. package/dist/core/mods/kernel/index.js +2 -2
  125. package/dist/core/mods/kernel/receive.d.ts +39 -5
  126. package/dist/core/mods/kernel/receive.js +290 -17
  127. package/dist/core/mods/kernel/registration.d.ts +33 -2
  128. package/dist/core/mods/kernel/registration.js +6 -7
  129. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  130. package/dist/core/mods/kernel/site-rules.js +24 -42
  131. package/dist/core/mods/spec-seats.d.ts +69 -0
  132. package/dist/core/mods/spec-seats.js +114 -0
  133. package/dist/core/mods/stations.d.ts +28 -8
  134. package/dist/core/mods/stations.js +29 -13
  135. package/dist/core/mods/tool-call.d.ts +79 -0
  136. package/dist/core/mods/tool-call.js +152 -0
  137. package/dist/core/namespaced-rule-name.d.ts +32 -38
  138. package/dist/core/namespaced-rule-name.js +29 -36
  139. package/dist/core/parent-spec-seat.d.ts +6 -1
  140. package/dist/core/parent-spec-seat.js +2 -0
  141. package/dist/core/park-selfcheck.js +3 -0
  142. package/dist/core/permission-rule-consent.d.ts +24 -3
  143. package/dist/core/permission-rule-consent.js +136 -41
  144. package/dist/core/permission-rule-model.d.ts +57 -5
  145. package/dist/core/permission-rule-model.js +90 -31
  146. package/dist/core/permission-rule-org.d.ts +6 -2
  147. package/dist/core/permission-rule-org.js +8 -4
  148. package/dist/core/permission-rule-provider.d.ts +5 -2
  149. package/dist/core/permission-rule-provider.js +41 -11
  150. package/dist/core/permission-rule-store.d.ts +3 -2
  151. package/dist/core/permission-rule-store.js +11 -2
  152. package/dist/core/permission-rule-sync.js +3 -2
  153. package/dist/core/permission-rule-syntax.d.ts +5 -4
  154. package/dist/core/permission-rule-syntax.js +2 -2
  155. package/dist/core/permission-rules.d.ts +4 -4
  156. package/dist/core/permission-rules.js +11 -20
  157. package/dist/core/persisted-rule-arms.d.ts +2 -2
  158. package/dist/core/persisted-rule-arms.js +10 -12
  159. package/dist/core/principal-name.d.ts +20 -0
  160. package/dist/core/principal-name.js +22 -0
  161. package/dist/core/prompt-section-seat.js +4 -6
  162. package/dist/core/protocol-http-auth.d.ts +40 -5
  163. package/dist/core/protocol-http-auth.js +168 -4
  164. package/dist/core/protocol-naming.d.ts +20 -0
  165. package/dist/core/protocol-naming.js +20 -3
  166. package/dist/core/read-only-shell.d.ts +20 -5
  167. package/dist/core/read-only-shell.js +29 -14
  168. package/dist/core/remote-env.d.ts +37 -1
  169. package/dist/core/remote-env.js +11 -0
  170. package/dist/core/resume-startup-cause.d.ts +24 -2
  171. package/dist/core/resume-startup-cause.js +20 -1
  172. package/dist/core/retired-keys.d.ts +16 -0
  173. package/dist/core/retired-keys.js +16 -4
  174. package/dist/core/rewrite-rejudge.d.ts +60 -0
  175. package/dist/core/rewrite-rejudge.js +36 -0
  176. package/dist/core/roles.d.ts +28 -1
  177. package/dist/core/roles.js +81 -26
  178. package/dist/core/rule-lane-reads.d.ts +20 -15
  179. package/dist/core/rule-lane-reads.js +45 -17
  180. package/dist/core/rule-owner.d.ts +3 -3
  181. package/dist/core/rule-owner.js +3 -2
  182. package/dist/core/runner/announce-once-ledger.d.ts +14 -0
  183. package/dist/core/runner/announce-once-ledger.js +5 -0
  184. package/dist/core/runner/assemble-result.d.ts +1 -0
  185. package/dist/core/runner/assemble-result.js +1 -1
  186. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  187. package/dist/core/runner/caller-roster.d.ts +16 -4
  188. package/dist/core/runner/caller-roster.js +33 -6
  189. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  190. package/dist/core/runner/capability-withheld-seat.js +24 -0
  191. package/dist/core/runner/classifier-ladder.d.ts +7 -9
  192. package/dist/core/runner/classifier-ladder.js +3 -3
  193. package/dist/core/runner/compact-session.d.ts +10 -0
  194. package/dist/core/runner/compact-session.js +202 -0
  195. package/dist/core/runner/compaction-call-options.d.ts +2 -2
  196. package/dist/core/runner/compaction-seams.d.ts +21 -1
  197. package/dist/core/runner/compaction-seams.js +11 -8
  198. package/dist/core/runner/construction-doors.js +3 -0
  199. package/dist/core/runner/contracts.d.ts +50 -40
  200. package/dist/core/runner/cross-boundary-lane.d.ts +17 -13
  201. package/dist/core/runner/cross-boundary-lane.js +40 -27
  202. package/dist/core/runner/denial-limit-arms.d.ts +2 -2
  203. package/dist/core/runner/denial-limit-arms.js +1 -1
  204. package/dist/core/runner/derived-route-fallback.d.ts +13 -0
  205. package/dist/core/runner/derived-route-fallback.js +6 -0
  206. package/dist/core/runner/env-capability-census.d.ts +3 -2
  207. package/dist/core/runner/env-capability-census.js +9 -3
  208. package/dist/core/runner/file-history-request.d.ts +18 -0
  209. package/dist/core/runner/file-history-request.js +21 -13
  210. package/dist/core/runner/file-history-restore.d.ts +45 -0
  211. package/dist/core/runner/file-history-restore.js +46 -0
  212. package/dist/core/runner/gate-exit.d.ts +3 -3
  213. package/dist/core/runner/gate-exit.js +4 -3
  214. package/dist/core/runner/image.d.ts +7 -17
  215. package/dist/core/runner/image.js +9 -60
  216. package/dist/core/runner/permission-rule-lanes.d.ts +11 -11
  217. package/dist/core/runner/permission-rule-lanes.js +39 -17
  218. package/dist/core/runner/person-path-rows.d.ts +12 -9
  219. package/dist/core/runner/person-path-rows.js +18 -7
  220. package/dist/core/runner/prepare-acquire-reconcile.d.ts +3 -0
  221. package/dist/core/runner/prepare-acquire-reconcile.js +2 -1
  222. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  223. package/dist/core/runner/prepare-ask-lane.js +5 -2
  224. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  225. package/dist/core/runner/prepare-caps-and-workflow.js +4 -3
  226. package/dist/core/runner/prepare-config-doors.d.ts +35 -38
  227. package/dist/core/runner/prepare-config-doors.js +46 -28
  228. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  229. package/dist/core/runner/prepare-defer-classify.js +7 -8
  230. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  231. package/dist/core/runner/prepare-file-history.js +7 -39
  232. package/dist/core/runner/prepare-gate-stations.d.ts +1 -1
  233. package/dist/core/runner/prepare-gate-stations.js +10 -1
  234. package/dist/core/runner/prepare-hands-readface.d.ts +5 -9
  235. package/dist/core/runner/prepare-hands-readface.js +17 -14
  236. package/dist/core/runner/prepare-inherited-gate.d.ts +6 -3
  237. package/dist/core/runner/prepare-inherited-gate.js +5 -3
  238. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  239. package/dist/core/runner/prepare-park-ask.d.ts +2 -0
  240. package/dist/core/runner/prepare-park-ask.js +7 -7
  241. package/dist/core/runner/prepare-policy-chain.d.ts +6 -3
  242. package/dist/core/runner/prepare-policy-chain.js +67 -76
  243. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  244. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  245. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  246. package/dist/core/runner/prepare-prompt-inputs.js +3 -5
  247. package/dist/core/runner/prepare-protocol-tools.d.ts +2 -0
  248. package/dist/core/runner/prepare-protocol-tools.js +3 -3
  249. package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
  250. package/dist/core/runner/prepare-safety-scan.js +0 -17
  251. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  252. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  253. package/dist/core/runner/prepare-task.d.ts +5 -2
  254. package/dist/core/runner/prepare-task.js +48 -43
  255. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +20 -4
  256. package/dist/core/runner/prepare-tool-disclosure-mount.js +33 -23
  257. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  258. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  259. package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -2
  260. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  261. package/dist/core/runner/resume-admission.js +1 -1
  262. package/dist/core/runner/resume-apply.js +11 -12
  263. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  264. package/dist/core/runner/resume-claim.d.ts +4 -2
  265. package/dist/core/runner/resume-claim.js +15 -8
  266. package/dist/core/runner/retired-runner-deps.js +1 -0
  267. package/dist/core/runner/rewind-files.d.ts +12 -0
  268. package/dist/core/runner/rewind-files.js +90 -0
  269. package/dist/core/runner/run-attachment-seats.js +2 -1
  270. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  271. package/dist/core/runner/run-brain-sinks.js +4 -2
  272. package/dist/core/runner/run-harness-handlers.js +12 -4
  273. package/dist/core/runner/run-leg.d.ts +1 -1
  274. package/dist/core/runner/run-leg.js +40 -39
  275. package/dist/core/runner/run-notification-lane.d.ts +2 -0
  276. package/dist/core/runner/run-notification-lane.js +2 -2
  277. package/dist/core/runner/run-recovery-lanes.js +3 -4
  278. package/dist/core/runner/run-settle-and-teardown.js +7 -12
  279. package/dist/core/runner/run-terminal-adoption.js +3 -4
  280. package/dist/core/runner/run-turn-boundary.js +4 -15
  281. package/dist/core/runner/runtask.d.ts +10 -0
  282. package/dist/core/runner/runtask.js +35 -42
  283. package/dist/core/runner/send-message-continuation.js +1 -1
  284. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  285. package/dist/core/runner/session-read-file-states.js +28 -0
  286. package/dist/core/runner/session-rule-policy.js +4 -3
  287. package/dist/core/runner/session-verb-doors.d.ts +28 -0
  288. package/dist/core/runner/session-verb-doors.js +48 -0
  289. package/dist/core/runner/session-write-ledger.d.ts +30 -0
  290. package/dist/core/runner/session-write-ledger.js +101 -0
  291. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  292. package/dist/core/runner/shell-env-withheld.js +51 -0
  293. package/dist/core/runner/skills-seat.js +6 -2
  294. package/dist/core/runner/stream-settle-backstop.js +12 -15
  295. package/dist/core/runner/sub-agent-deny-lists.d.ts +25 -3
  296. package/dist/core/runner/sub-agent-deny-lists.js +25 -17
  297. package/dist/core/runner/synthetic-tools.d.ts +6 -0
  298. package/dist/core/runner/synthetic-tools.js +4 -1
  299. package/dist/core/runner/teardown-bounded.d.ts +1 -0
  300. package/dist/core/runner/teardown-bounded.js +1 -0
  301. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  302. package/dist/core/runner/tool-disclosure.js +1 -3
  303. package/dist/core/runner/tool-end-body.d.ts +1 -1
  304. package/dist/core/runner/tool-end-body.js +10 -9
  305. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  306. package/dist/core/runner/tool-not-executed.js +11 -0
  307. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  308. package/dist/core/runner/tool-occurrence.js +7 -0
  309. package/dist/core/runner/turn-attachments.d.ts +33 -15
  310. package/dist/core/runner/turn-attachments.js +62 -37
  311. package/dist/core/runner-deps.d.ts +7 -7
  312. package/dist/core/safety-axis-vocab.d.ts +6 -4
  313. package/dist/core/safety-axis-vocab.js +6 -5
  314. package/dist/core/safety-merge-corpus.js +11 -3
  315. package/dist/core/secret-env.d.ts +30 -3
  316. package/dist/core/secret-env.js +47 -8
  317. package/dist/core/select-model.js +3 -3
  318. package/dist/core/session-policy-store.d.ts +32 -15
  319. package/dist/core/session-policy-store.js +156 -36
  320. package/dist/core/session-store.d.ts +29 -10
  321. package/dist/core/session-store.js +51 -19
  322. package/dist/core/session.d.ts +82 -16
  323. package/dist/core/session.js +53 -0
  324. package/dist/core/shell-read-silence.d.ts +11 -12
  325. package/dist/core/shell-read-silence.js +9 -5
  326. package/dist/core/shell-run-candidates.js +3 -1
  327. package/dist/core/shell-wrapper-projection.d.ts +1 -1
  328. package/dist/core/shell-wrapper-projection.js +1 -1
  329. package/dist/core/shell-wrapper-table.d.ts +14 -7
  330. package/dist/core/shell-wrapper-table.js +5 -4
  331. package/dist/core/side-query.js +10 -1
  332. package/dist/core/skill-grant.d.ts +7 -2
  333. package/dist/core/skill-grant.js +5 -0
  334. package/dist/core/skills-directory.js +6 -2
  335. package/dist/core/store-contracts/background-agent-store-contract.js +1 -0
  336. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  337. package/dist/core/store-contracts/checkpoint-store-contract.js +141 -2
  338. package/dist/core/store-contracts/file-history-store-contract.js +40 -1
  339. package/dist/core/store-contracts/mailbox-store-contract.js +49 -1
  340. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  341. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  342. package/dist/core/store-contracts/session-repo-contract.js +51 -0
  343. package/dist/core/store-contracts/session-store-contract.d.ts +2 -1
  344. package/dist/core/store-contracts/session-store-contract.js +150 -14
  345. package/dist/core/stub-env.d.ts +2 -0
  346. package/dist/core/stub-env.js +1 -0
  347. package/dist/core/synthetic-read-verdict.js +3 -3
  348. package/dist/core/task-event.d.ts +32 -4
  349. package/dist/core/task-notification.d.ts +16 -12
  350. package/dist/core/task-registry-agent.d.ts +8 -4
  351. package/dist/core/task-registry-agent.js +14 -8
  352. package/dist/core/task-registry-shared.d.ts +35 -6
  353. package/dist/core/task-registry-shared.js +11 -0
  354. package/dist/core/task-registry.d.ts +10 -1
  355. package/dist/core/task-registry.js +12 -2
  356. package/dist/core/task-result.d.ts +18 -0
  357. package/dist/core/task-spec.d.ts +18 -13
  358. package/dist/core/tighten-task-spec.js +2 -1
  359. package/dist/core/tool-catalog-entries.d.ts +23 -0
  360. package/dist/core/tool-catalog-entries.js +14 -2
  361. package/dist/core/tool-check-reading.d.ts +11 -0
  362. package/dist/core/tool-check-reading.js +11 -6
  363. package/dist/core/tool-model-gate.d.ts +2 -2
  364. package/dist/core/tool-name-aliases.d.ts +48 -18
  365. package/dist/core/tool-name-aliases.js +36 -19
  366. package/dist/core/tool-name-readings.d.ts +6 -32
  367. package/dist/core/tool-name-readings.js +2 -9
  368. package/dist/core/tool-policy.d.ts +78 -204
  369. package/dist/core/tool-policy.js +152 -204
  370. package/dist/core/tool-result-store.js +3 -0
  371. package/dist/core/tool-roster.d.ts +14 -19
  372. package/dist/core/tool-roster.js +11 -44
  373. package/dist/core/tool-spec-members.js +7 -2
  374. package/dist/core/tool-spec.d.ts +19 -11
  375. package/dist/core/tools.js +49 -9
  376. package/dist/core/trace.d.ts +6 -3
  377. package/dist/core/trace.js +2 -1
  378. package/dist/core/types.d.ts +1 -1
  379. package/dist/core/untrusted-egress.d.ts +20 -0
  380. package/dist/core/untrusted-egress.js +77 -3
  381. package/dist/core/user-attachment.d.ts +8 -1
  382. package/dist/core/user-attachment.js +64 -4
  383. package/dist/core/wiring-manifest.d.ts +9 -0
  384. package/dist/core/wiring-manifest.js +1 -0
  385. package/dist/core/workflow-journal-store.js +1 -1
  386. package/dist/engine/compaction/compaction.js +3 -2
  387. package/dist/engine/execution-env/node-execution-env.d.ts +7 -3
  388. package/dist/engine/execution-env/node-execution-env.js +11 -2
  389. package/dist/engine/harness/agent-harness.d.ts +32 -6
  390. package/dist/engine/harness/agent-harness.js +65 -9
  391. package/dist/engine/harness/types.d.ts +29 -2
  392. package/dist/engine/llm/types.d.ts +28 -11
  393. package/dist/engine/loop/agent-loop.d.ts +23 -4
  394. package/dist/engine/loop/agent-loop.js +42 -30
  395. package/dist/engine/loop/types.d.ts +16 -6
  396. package/dist/engine/session/memory-repo.d.ts +9 -2
  397. package/dist/engine/session/memory-repo.js +11 -1
  398. package/dist/engine/session/repo-utils.d.ts +6 -5
  399. package/dist/engine/session/repo-utils.js +14 -6
  400. package/dist/index.d.ts +34 -17
  401. package/dist/index.js +22 -11
  402. package/dist/internal/harness-types.d.ts +1 -1
  403. package/dist/internal/harness.d.ts +2 -1
  404. package/dist/internal/harness.js +1 -0
  405. package/dist/internal/llm.d.ts +1 -1
  406. package/dist/orchestration/run-workflow-tool.d.ts +6 -4
  407. package/dist/orchestration/run-workflow-tool.js +5 -3
  408. package/dist/orchestration/workflow.d.ts +3 -0
  409. package/dist/orchestration/workflow.js +36 -18
  410. package/dist/primitives/credential-ref.d.ts +89 -0
  411. package/dist/primitives/credential-ref.js +125 -0
  412. package/dist/primitives/index.d.ts +2 -0
  413. package/dist/primitives/index.js +1 -0
  414. package/dist/prompt-assembly/artifact.d.ts +2 -2
  415. package/dist/prompt-assembly/artifact.js +5 -3
  416. package/dist/prompt-assembly/assemble.d.ts +3 -2
  417. package/dist/prompt-assembly/assemble.js +1 -1
  418. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  419. package/dist/prompt-assembly/catalog/schema.js +34 -2
  420. package/dist/prompt-assembly/catalog/sections.js +0 -1
  421. package/dist/prompt-assembly/composer.d.ts +3 -1
  422. package/dist/prompt-assembly/composer.js +1 -1
  423. package/dist/prompt-assembly/event-registry.js +1 -0
  424. package/dist/prompt-assembly/overlay.js +3 -3
  425. package/dist/prompt-assembly/renderers.d.ts +1 -1
  426. package/dist/prompt-assembly/renderers.js +0 -3
  427. package/dist/prompt-assembly/role-base.d.ts +15 -0
  428. package/dist/prompt-assembly/role-base.js +9 -0
  429. package/dist/prompt-assembly/select.d.ts +39 -14
  430. package/dist/prompt-assembly/select.js +47 -16
  431. package/dist/prompt-assembly/sugar.d.ts +17 -11
  432. package/dist/prompt-assembly/sugar.js +8 -3
  433. package/dist/prompt-assembly/tool-catalog.d.ts +37 -3
  434. package/dist/prompt-assembly/tool-catalog.js +114 -4
  435. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  436. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  437. package/dist/prompt-assembly/types.d.ts +0 -7
  438. package/dist/scenarios/full-body.d.ts +11 -11
  439. package/dist/scenarios/full-body.js +4 -3
  440. package/dist/shell/lex.js +10 -1
  441. package/dist/stores/file/adoption/adopt.js +4 -3
  442. package/dist/stores/file/adoption/marker.js +3 -2
  443. package/dist/stores/file/checkpoint-store.d.ts +21 -4
  444. package/dist/stores/file/checkpoint-store.js +38 -7
  445. package/dist/stores/file/file-history-store.js +18 -11
  446. package/dist/stores/file/index.js +2 -1
  447. package/dist/stores/file/mailbox-store.d.ts +2 -1
  448. package/dist/stores/file/mailbox-store.js +26 -1
  449. package/dist/stores/file/permission-rule-adopt.js +4 -3
  450. package/dist/stores/file/permission-rule-store.js +11 -5
  451. package/dist/stores/file/session-store.d.ts +29 -6
  452. package/dist/stores/file/session-store.js +42 -50
  453. package/dist/tools/artifact/artifact-tool.js +3 -2
  454. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  455. package/dist/tools/fs/bash-program-position.js +56 -9
  456. package/dist/tools/fs/bash-readonly-classifier.d.ts +15 -19
  457. package/dist/tools/fs/bash-readonly-classifier.js +5 -10
  458. package/dist/tools/fs/fs-bash.js +15 -8
  459. package/dist/tools/fs/fs-glob.d.ts +86 -0
  460. package/dist/tools/fs/fs-glob.js +226 -0
  461. package/dist/tools/fs/fs-read.js +14 -14
  462. package/dist/tools/fs/fs-search-tools.js +7 -7
  463. package/dist/tools/fs/pattern-kill-guard.d.ts +23 -0
  464. package/dist/tools/fs/pattern-kill-guard.js +429 -0
  465. package/dist/tools/fs/pdf.d.ts +9 -6
  466. package/dist/tools/fs/pdf.js +3 -3
  467. package/dist/tools/fs/program-read-model.d.ts +57 -7
  468. package/dist/tools/fs/program-read-model.js +11 -1
  469. package/dist/tools/fs/program-read-model.rows.js +78 -21
  470. package/dist/tools/fs/read-deny-home.js +3 -2
  471. package/dist/tools/fs/removal-targets.d.ts +17 -7
  472. package/dist/tools/fs/removal-targets.js +47 -20
  473. package/dist/tools/fs/search.d.ts +10 -0
  474. package/dist/tools/fs/search.js +20 -26
  475. package/dist/tools/fs/shell-read-argv.js +89 -12
  476. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  477. package/dist/tools/fs/shell-read-bindings.js +41 -0
  478. package/dist/tools/fs/shell-read-check.d.ts +10 -0
  479. package/dist/tools/fs/shell-read-check.js +13 -20
  480. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  481. package/dist/tools/fs/shell-read-environment.js +3 -2
  482. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  483. package/dist/tools/fs/shell-read-establish.js +19 -20
  484. package/dist/tools/fs/shell-read-identity.d.ts +12 -9
  485. package/dist/tools/fs/shell-read-identity.js +9 -4
  486. package/dist/tools/fs/shell-read-plan.js +24 -16
  487. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  488. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  489. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  490. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  491. package/dist/tools/fs/shell-reentry-text.js +40 -2
  492. package/dist/tools/todo.js +63 -63
  493. package/dist/tools/web.d.ts +19 -14
  494. package/dist/tools/web.js +46 -61
  495. package/package.json +1 -1
  496. package/test/export-surface.snapshot.json +221 -7
  497. package/wire-changes/core-stores-sql@7.57.0.json +29 -0
  498. package/wire-changes/core@7.56.0.json +3891 -0
  499. package/wire-changes/core@7.57.0.json +1487 -0
  500. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  501. package/wire-changes/mods-kernel@7.57.0.json +29 -0
  502. package/wire-changes/primitives@7.57.0.json +245 -0
@@ -4,6 +4,7 @@ import { MAX_EXEC_OUTPUT_BYTES } from "../../core/exec-output-tail.js";
4
4
  import { anchorSpelling, hasBinaryExtension, isWinFormPath, pathFamilyOf } from "./safety.js";
5
5
  import { HomeViewUnreadError, homeViewsOf } from "./read-deny-home.js";
6
6
  import { createEntryDenyJudge } from "./dir-entries.js";
7
+ import { compileFsGlob, fsGlobClass } from "./fs-glob.js";
7
8
  import { thrownText } from "../../core/thrown-value.js";
8
9
  const WALK_MAX_FILES = 5000;
9
10
  const WALK_MAX_DEPTH = 32;
@@ -78,32 +79,31 @@ export function splitGlobParam(glob) {
78
79
  export function shellQuote(s) {
79
80
  return `'${s.replace(/'/g, `'\\''`)}'`;
80
81
  }
81
- function globTokenToRegExp(token, anchored, glob = false, report) {
82
- const charToRe = (ch) => ch === "*" ? "[^/]*" : ch === "?" ? "[^/]" : ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
83
- let re = "";
82
+ export function compileGlobToken(token, anchored, glob = false, report) {
83
+ const unitOf = (ch) => (ch === "*" ? { kind: "star" } : ch === "?" ? { kind: "one" } : { kind: "text", text: ch });
84
+ const tokens = [];
84
85
  for (let i = 0; i < token.length; i++) {
85
86
  const c = token[i];
86
87
  if (c === "*") {
87
88
  if (token[i + 1] === "*") {
88
- re += ".*";
89
+ tokens.push({ kind: "globstar" });
89
90
  i++;
90
91
  if (token[i + 1] === "/")
91
92
  i++;
92
93
  }
93
94
  else
94
- re += "[^/]*";
95
+ tokens.push({ kind: "star" });
95
96
  }
96
97
  else if (c === "?")
97
- re += "[^/]";
98
+ tokens.push({ kind: "one" });
98
99
  else if (glob && c === "{") {
99
100
  const close = token.indexOf("}", i);
100
101
  if (close > i + 1) {
101
- const alts = token.slice(i + 1, close).split(",").map((alt) => [...alt].map(charToRe).join(""));
102
- re += `(?:${alts.join("|")})`;
102
+ tokens.push({ kind: "alt", alternatives: token.slice(i + 1, close).split(",").map((alt) => [...alt].map(unitOf)) });
103
103
  i = close;
104
104
  }
105
105
  else {
106
- re += "\\{";
106
+ tokens.push({ kind: "text", text: "{" });
107
107
  if (report)
108
108
  report.degraded = true;
109
109
  }
@@ -122,34 +122,28 @@ function globTokenToRegExp(token, anchored, glob = false, report) {
122
122
  let cls;
123
123
  if (close !== -1) {
124
124
  const body = token.slice(bodyStart, close).replace(/[\\[\]]/g, "\\$&").replace(/\//g, "");
125
- cls = `[${neg ? "^/" : ""}${body}]`;
126
- try {
127
- new RegExp(cls);
128
- }
129
- catch {
130
- cls = undefined;
131
- }
125
+ cls = fsGlobClass(`[${neg ? "^/" : ""}${body}]`);
132
126
  }
133
127
  if (cls !== undefined) {
134
- re += cls;
128
+ tokens.push({ kind: "class", class: cls });
135
129
  i = close;
136
130
  }
137
131
  else {
138
- re += "\\[";
132
+ tokens.push({ kind: "text", text: "[" });
139
133
  if (report)
140
134
  report.degraded = true;
141
135
  }
142
136
  }
143
137
  else
144
- re += c.replace(/[.+^${}()|[\]\\]/g, "\\$&");
138
+ tokens.push({ kind: "text", text: c });
145
139
  }
146
- return new RegExp(`${anchored ? "^" : "(^|/)"}${re}$`);
140
+ return compileFsGlob(tokens, anchored ? "start" : "segment");
147
141
  }
148
142
  export function invalidGlobTokens(glob) {
149
143
  const bad = [];
150
144
  for (const token of splitGlobParam(glob)) {
151
145
  const report = { degraded: false };
152
- globTokenToRegExp(normalizeGlobToken(token), globIsAnchored(token), true, report);
146
+ compileGlobToken(normalizeGlobToken(token), globIsAnchored(token), true, report);
153
147
  if (report.degraded)
154
148
  bad.push(token);
155
149
  }
@@ -187,7 +181,7 @@ export function gitignoreMatcher(content) {
187
181
  const anchored = pat.startsWith("/");
188
182
  if (anchored)
189
183
  pat = pat.replace(/^\/+/, "");
190
- return { neg, dirOnly, anchored, re: globTokenToRegExp(pat, anchored), bare: pat };
184
+ return { neg, dirOnly, anchored, re: compileGlobToken(pat, anchored), bare: pat };
191
185
  });
192
186
  return (relRaw, isDir) => {
193
187
  const rel = relRaw.replace(/\\/g, "/");
@@ -834,7 +828,7 @@ export async function jsGrepDetailed(env, root, p, signal, guards, deny, denyOut
834
828
  return rel(abs);
835
829
  };
836
830
  if (p.glob) {
837
- const globRes = splitGlobParam(p.glob).map((g) => globTokenToRegExp(normalizeGlobToken(g), globIsAnchored(g), true));
831
+ const globRes = splitGlobParam(p.glob).map((g) => compileGlobToken(normalizeGlobToken(g), globIsAnchored(g), true));
838
832
  if (globRes.length > 0)
839
833
  files = files.filter((f) => globRes.some((re) => re.test(rel(f).replace(/\\/g, "/"))));
840
834
  }
@@ -842,7 +836,7 @@ export async function jsGrepDetailed(env, root, p, signal, guards, deny, denyOut
842
836
  if (p.type) {
843
837
  const tg = TYPE_GLOBS[p.type.toLowerCase()];
844
838
  if (tg) {
845
- const typeRe = globTokenToRegExp(tg, false, true);
839
+ const typeRe = compileGlobToken(tg, false, true);
846
840
  files = files.filter((f) => typeRe.test(basename(f)));
847
841
  }
848
842
  else {
@@ -1380,7 +1374,7 @@ export async function runGlobDetailed(env, root, pattern, opts = {}, signal) {
1380
1374
  }
1381
1375
  const pat = normalizeGlobToken(pattern);
1382
1376
  const anchored = globIsAnchored(pattern);
1383
- const re = globTokenToRegExp(pat, anchored, true);
1377
+ const re = compileGlobToken(pat, anchored, true);
1384
1378
  const startPrefix = start.replace(/[\\/]+$/, "") + (start.includes("\\") ? "\\" : "/");
1385
1379
  const startRelPrefix = startPrefix.startsWith(rootPrefix) ? startPrefix.slice(rootPrefix.length) : startPrefix;
1386
1380
  const toStartRel = (p) => {
@@ -1396,7 +1390,7 @@ export async function runGlobDetailed(env, root, pattern, opts = {}, signal) {
1396
1390
  const prunable = anchored && !groupSpansSlash;
1397
1391
  const firstStarStar = patternSegs.findIndex((s) => s.includes("**"));
1398
1392
  const starStarIdx = firstStarStar === -1 ? Infinity : firstStarStar;
1399
- const segRes = prunable ? patternSegs.map((s) => globTokenToRegExp(s, true, true)) : [];
1393
+ const segRes = prunable ? patternSegs.map((s) => compileGlobToken(s, true, true)) : [];
1400
1394
  const isLiteralSeg = (s) => s.length > 0 && !/[*?[{]/.test(s);
1401
1395
  const literalAt = prunable ? patternSegs.map((s) => (isLiteralSeg(s) ? s : undefined)) : [];
1402
1396
  const literalAfterStarStar = new Set(prunable ? patternSegs.filter((s, i) => i > starStarIdx && isLiteralSeg(s)) : []);
@@ -21,9 +21,46 @@ function mayOwnNextWord(row, tok) {
21
21
  return k === tok.length;
22
22
  return false;
23
23
  }
24
+ class OperandBase {
25
+ base;
26
+ taken = [];
27
+ move(spec, value, settled, at) {
28
+ if (spec?.rebases !== true)
29
+ return;
30
+ if (!settled)
31
+ this.base = "unsettled";
32
+ else if (namesOwnPlace(value))
33
+ this.base = value;
34
+ else if (this.base !== "unsettled")
35
+ this.base = this.base === undefined ? value : joinSpelling(this.base, value);
36
+ if (typeof this.base === "string" && this.base !== "unsettled")
37
+ this.taken.push({ at, base: this.base });
38
+ }
39
+ of(r) {
40
+ if (this.base === undefined || namesOwnPlace(r.folded))
41
+ return r;
42
+ if (this.base === "unsettled" || r.expands !== false)
43
+ return { ...r, expands: "unresolvable" };
44
+ return { word: r.word, raw: r.raw, folded: joinSpelling(this.base, r.folded), expands: false };
45
+ }
46
+ covers(unsettled) {
47
+ const out = new Set();
48
+ for (const u of unsettled) {
49
+ if (namesOwnPlace(u.folded) || u.folded.split("/").includes(".."))
50
+ continue;
51
+ for (const t of this.taken)
52
+ if (t.at < u.at)
53
+ out.add(t.base);
54
+ }
55
+ return [...out].map((b) => readOfText(b));
56
+ }
57
+ }
58
+ const namesOwnPlace = (spelled) => spelled.startsWith("/") || spelled.startsWith("~");
59
+ const joinSpelling = (base, rel) => (base.endsWith("/") ? `${base}${rel}` : `${base}/${rel}`);
24
60
  const rootValue = (spec) => spec?.walks === true || spec?.delivers === "operands";
25
61
  class RootsGathered {
26
62
  positional = [];
63
+ opened = new Map();
27
64
  places = [];
28
65
  maybeValues = new Set();
29
66
  stdinOperands = 0;
@@ -50,16 +87,23 @@ class RootsGathered {
50
87
  if (this.maybeValues.has(r))
51
88
  this.slotOwned = true;
52
89
  }
53
- operand(r, namesPath, stdin) {
90
+ operand(r, namesPath, stdin, opened = r) {
54
91
  if (stdin) {
55
92
  if (!this.maybeValues.has(r))
56
93
  this.stdinOperands++;
57
94
  }
58
- else if (namesPath)
95
+ else if (namesPath) {
59
96
  this.positional.push(r);
97
+ if (opened !== r)
98
+ this.opened.set(r, opened);
99
+ }
100
+ }
101
+ cover(place) {
102
+ this.places.push(bare(place, "traversal_root"));
60
103
  }
61
104
  restart() {
62
105
  this.positional.length = 0;
106
+ this.opened.clear();
63
107
  this.places.length = 0;
64
108
  this.stdinOperands = 0;
65
109
  this.slotOwned = false;
@@ -71,7 +115,7 @@ class RootsGathered {
71
115
  const reads = this.unsettled
72
116
  ? [...this.positional, ...(this.slotWord !== undefined ? [this.slotWord] : []), ...(walksCwdWithoutOperand(row) ? [readOfText(".")] : [])]
73
117
  : walksCwdWithoutOperand(row) && leftOver <= (this.slotOwned ? 1 : 0) ? [...this.positional, readOfText(".")] : [...this.positional];
74
- return [...reads.map((r) => bare(r, "traversal_root")), ...this.places];
118
+ return [...reads.map((r) => bare(this.opened.get(r) ?? r, "traversal_root")), ...this.places];
75
119
  }
76
120
  }
77
121
  export const programTextSentence = (language) => `runs inline ${language} program text, which may open files this station does not read`;
@@ -178,6 +222,9 @@ export function unlistedWords(reads, toks, from, launcherIndices, provenance, ct
178
222
  pushAssignment(reads, toks[j].word, provenance);
179
223
  }
180
224
  const gathered = new RootsGathered();
225
+ let base = new OperandBase();
226
+ const valueAt = new Set();
227
+ const unsettledAt = [];
181
228
  let slotWord;
182
229
  const pastOperand = new Set();
183
230
  let globs = "expanded";
@@ -251,6 +298,8 @@ export function unlistedWords(reads, toks, from, launcherIndices, provenance, ct
251
298
  walkFrom = argvStart + 2 + sub.at;
252
299
  relocated = sub.relocated;
253
300
  gathered.restart();
301
+ base = new OperandBase();
302
+ unsettledAt.length = 0;
254
303
  walk(sub.row, walkFrom, toks.length, true);
255
304
  }
256
305
  else
@@ -268,10 +317,12 @@ export function unlistedWords(reads, toks, from, launcherIndices, provenance, ct
268
317
  return;
269
318
  case "dash-word-operand":
270
319
  pastOperand.add(j);
271
- reads.push(bare(r, provenance));
320
+ reads.push(bare(base.of(r), provenance));
272
321
  speculate(start, "whole");
273
322
  return;
274
323
  case "value": {
324
+ base.move(e.spec, r.folded, e.consumed && r.expands === false, j);
325
+ valueAt.add(j);
275
326
  if (!e.consumed) {
276
327
  gathered.value(r, e, false);
277
328
  if (r.expands !== "unresolvable")
@@ -299,19 +350,23 @@ export function unlistedWords(reads, toks, from, launcherIndices, provenance, ct
299
350
  return;
300
351
  }
301
352
  {
353
+ base.move(e.reading.spec, literalTildeSpelling(e.reading.attached), r.expands === false, j);
302
354
  const named = roleReads(r, "option_value", literalTildeSpelling(e.reading.attached), e.reading.role, globs, ctx, pastOperand.has(j));
303
355
  reads.push(...named);
304
356
  gathered.attached(named, e.reading.spec);
305
357
  }
306
358
  return;
307
359
  case "operand": {
308
- const role = e.dash === undefined ? (e.slot ?? e.role) : undefined;
309
- const named = role !== undefined ? roleReads(r, provenance, r.folded, role, globs, ctx) : [bare(r, provenance)];
310
360
  const inSlot = j === slotWord;
361
+ const o = inSlot || e.dash !== undefined ? r : base.of(r);
362
+ const role = e.dash === undefined ? (e.slot ?? e.role) : undefined;
363
+ const named = role !== undefined ? roleReads(o, provenance, o.folded, role, globs, ctx) : [bare(o, provenance)];
311
364
  if (inSlot)
312
365
  gathered.slot(r);
313
366
  else
314
- gathered.operand(r, named.some((c) => c.denyOnly !== true), e.dash === "stdin");
367
+ gathered.operand(r, named.some((c) => c.denyOnly !== true), e.dash === "stdin", o);
368
+ if (!inSlot && e.dash === undefined && r.expands !== false)
369
+ unsettledAt.push({ at: j, folded: r.folded });
315
370
  reads.push(...named);
316
371
  speculate(start, r.word.assignment !== undefined ? "whole" : "containment");
317
372
  const values = reads.length;
@@ -323,6 +378,11 @@ export function unlistedWords(reads, toks, from, launcherIndices, provenance, ct
323
378
  }
324
379
  }
325
380
  if (walkRow !== undefined && argv !== undefined && selectsContentsTraversal(walkRow, toks.slice(walkFrom).map((x) => x.folded))) {
381
+ for (const j of expanding)
382
+ if (j >= walkFrom && !valueAt.has(j))
383
+ unsettledAt.push({ at: j, folded: toks[j].folded });
384
+ for (const place of base.covers(unsettledAt))
385
+ gathered.cover(place);
326
386
  for (const root of gathered.roots(walkRow))
327
387
  reads.push(relocated ? { ...root, expands: "unresolvable" } : root);
328
388
  }
@@ -372,6 +432,9 @@ function walkListed(row, argReads, first, last, expanding, reads, ctx, relocated
372
432
  const slice = argReads.slice(first, last);
373
433
  const args = slice.map((r) => r.folded);
374
434
  const gathered = new RootsGathered();
435
+ const base = new OperandBase();
436
+ const valueAt = new Set();
437
+ const unsettledAt = [];
375
438
  let unexplained = false;
376
439
  const globs = valuesAreLiteral(row, args) ? "literal" : "expanded";
377
440
  noteDeliveredOperands(row, args, ctx);
@@ -391,9 +454,11 @@ function walkListed(row, argReads, first, last, expanding, reads, ctx, relocated
391
454
  break;
392
455
  case "dash-word-operand":
393
456
  pastOperand.add(e.at);
394
- reads.push(bare(slice[e.at], "operand"));
457
+ reads.push(bare(base.of(slice[e.at]), "operand"));
395
458
  break;
396
459
  case "value": {
460
+ base.move(e.spec, t, e.consumed && slice[e.at].expands === false, e.at);
461
+ valueAt.add(e.at);
397
462
  if (expanding.has(first + e.at))
398
463
  break;
399
464
  gathered.value(slice[e.at], e, opensPath(offer(e.at, t, e.role, "option_value", !e.consumed)));
@@ -409,6 +474,7 @@ function walkListed(row, argReads, first, last, expanding, reads, ctx, relocated
409
474
  reads.push(bare(slice[e.at], "option_value", payload));
410
475
  break;
411
476
  }
477
+ base.move(e.reading.spec, literalTildeSpelling(e.reading.attached), slice[e.at].expands === false, e.at);
412
478
  gathered.attached(offer(e.at, literalTildeSpelling(e.reading.attached), e.reading.role, "option_value", pastOperand.has(e.at)), e.reading.spec);
413
479
  break;
414
480
  case "operand": {
@@ -428,11 +494,17 @@ function walkListed(row, argReads, first, last, expanding, reads, ctx, relocated
428
494
  break;
429
495
  }
430
496
  let opens = true;
431
- if (e.role !== undefined)
432
- opens = opensPath(offer(e.at, t, e.role, "operand"));
497
+ const o = base.of(slice[e.at]);
498
+ if (e.role !== undefined) {
499
+ const named = roleReads(o, "operand", o.folded, e.role, globs, ctx);
500
+ reads.push(...named);
501
+ opens = opensPath(named);
502
+ }
433
503
  else
434
- reads.push(bare(slice[e.at], "operand"));
435
- gathered.operand(slice[e.at], opens, false);
504
+ reads.push(bare(o, "operand"));
505
+ gathered.operand(slice[e.at], opens, false, o);
506
+ if (slice[e.at].expands !== false)
507
+ unsettledAt.push({ at: e.at, folded: t });
436
508
  if (row?.operands?.assignmentArguments !== "not-paths")
437
509
  pushAssignment(reads, slice[e.at].word, "operand");
438
510
  break;
@@ -444,6 +516,11 @@ function walkListed(row, argReads, first, last, expanding, reads, ctx, relocated
444
516
  reads[i] = { ...reads[i], speculative: "containment" };
445
517
  }
446
518
  if (row !== undefined && selectsContentsTraversal(row, args)) {
519
+ for (let k = 0; k < slice.length; k++)
520
+ if (expanding.has(first + k) && !valueAt.has(k))
521
+ unsettledAt.push({ at: k, folded: args[k] });
522
+ for (const place of base.covers(unsettledAt))
523
+ gathered.cover(place);
447
524
  for (const root of gathered.roots(row))
448
525
  reads.push(relocated ? { ...root, expands: "unresolvable" } : root);
449
526
  }
@@ -106,6 +106,37 @@ export declare const functionKey: (name: string) => string;
106
106
  /** What a function name is at a reader: `defined` — it certainly is one; `absent` — it certainly is not; `maybe` — a branch,
107
107
  * a loop, a body that may not have run, a removal that may not have found it. */
108
108
  export type FunctionState = "defined" | "maybe" | "absent";
109
+ /** The function names a segment exports to child shells — the `-f` function flag with export (`export` always exports;
110
+ * `declare` / `typeset` need `-x`), its bare-name operands. A child `bash -c` inherits them as functions
111
+ * ({@link inheritedExportedFunctions}); their definitions are text this reader does not hold, so a call to one shadows
112
+ * the builtin of the name (#1628). */
113
+ export declare function exportedFunctionNames(argv: readonly LexedWord[]): string[];
114
+ /** A function the CHILD inherits through its ENVIRONMENT: bash exports a function as a `BASH_FUNC_<name>%%` variable
115
+ * (older bashes `BASH_FUNC_<name>()`), and a child reading that variable from its environment defines `<name>` as a
116
+ * function whose body the engine cannot read. Delivered on a child's env by `env BASH_FUNC_x%%=… cmd` (env's own
117
+ * assignment grammar accepts the `%%` name the shell's does not). Each such assignment word of a segment names an
118
+ * inherited function — the same law as {@link exportedFunctionNames}, a different delivery; a value the shell rewrites
119
+ * (`env "BASH_FUNC_$n%%=…"`) names a function the text cannot settle and is not tracked (KL-1628-a). */
120
+ export declare function envFunctionNames(argv: readonly LexedWord[]): string[];
121
+ /** Whether the BODY of a function a child shell inherits is text the engine read: `read` — the text (or a shell above it)
122
+ * defines the function it exports (`f(){ …; }; export -f f`, `declare -fx f`), so the body's segments are read where it
123
+ * is defined; `unread` — delivered on an environment (`BASH_FUNC_f%%=…`, {@link envFunctionNames}), or exported with no
124
+ * definition the text holds (one a `source` or an `eval` made): a body nobody read. */
125
+ export type InheritedBody = "read" | "unread";
126
+ /** The functions a text's child shells inherit, each with its {@link InheritedBody}: what the shell running the text
127
+ * inherited; then each name the text exports — `read` where the text defines it, else what it was inherited as, else
128
+ * `unread`; then each name it delivers on an environment, `unread` whatever else holds it. */
129
+ export declare function inheritedFunctionsOf(segments: readonly {
130
+ readonly argv: readonly LexedWord[];
131
+ readonly defines: readonly string[];
132
+ }[], inherited: ReadonlyMap<string, InheritedBody> | undefined): ReadonlyMap<string, InheritedBody>;
133
+ /** What a child shell (`bash -c`) inherits from a parent that EXPORTED functions ({@link exportedFunctionNames}): each
134
+ * such name is a `defined` function in the child — bash looks a function up before the builtin of its name, so
135
+ * `declare X=…` run under an exported `declare` function is the FUNCTION (it binds nothing), not the declaration
136
+ * builtin. Every other function key is `absent` (a child inherits only exported functions), every builtin enabled;
137
+ * the child holds none of their bodies, so a call to one may change any name (`bound: "all"`). The existing binding
138
+ * carrier ({@link PlanStart.names}), not a second table (#1628). */
139
+ export declare function inheritedExportedFunctions(names: ReadonlyMap<string, InheritedBody>): InheritedFunctions;
109
140
  /** One binding a segment makes: a name and what it now holds (`unknown` = made unknown). `prefix`: a binding that may or
110
141
  * may not take effect (a prefix assignment to a special builtin, which may or may not outlive its command; an `unset` of a
111
142
  * function, which a read-only function refuses). `loopVar`: a `for` loop's variable, held through its body. */
@@ -46,6 +46,47 @@ const isFunctionKey = (name) => name.startsWith(FUNCTION_KEY_PREFIX);
46
46
  const FUNCTION_DEFINED = [{ spelled: "defined" }];
47
47
  const FUNCTION_ABSENT = [{ spelled: "absent" }];
48
48
  const isDefinedValue = (v) => v.spelled === "defined";
49
+ const EXPORT_FUNCTION_BUILTINS = new Set(["export", "declare", "typeset"]);
50
+ export function exportedFunctionNames(argv) {
51
+ const program = readProgramPosition(argv).program;
52
+ const prog = program?.basename;
53
+ if (program === undefined || prog === undefined || !EXPORT_FUNCTION_BUILTINS.has(prog))
54
+ return [];
55
+ const literal = (w) => w.expansions.length === 0;
56
+ const rest = argv.slice(program.index + 1);
57
+ const flags = new Set(rest.filter((w) => literal(w) && /^-[A-Za-z]+$/.test(w.folded)).flatMap((w) => [...w.folded.slice(1)]));
58
+ if (!flags.has("f") || !(prog === "export" || flags.has("x")))
59
+ return [];
60
+ return rest.filter((w) => literal(w) && w.assignment === undefined && /^[A-Za-z_][A-Za-z0-9_]*$/.test(w.folded)).map((w) => w.folded);
61
+ }
62
+ export function envFunctionNames(argv) {
63
+ const out = [];
64
+ for (const w of argv) {
65
+ if (w.expansions.length !== 0)
66
+ continue;
67
+ const m = /^BASH_FUNC_([A-Za-z_][A-Za-z0-9_]*)(?:%%|\(\))=/.exec(w.folded);
68
+ if (m !== null)
69
+ out.push(m[1]);
70
+ }
71
+ return out;
72
+ }
73
+ export function inheritedFunctionsOf(segments, inherited) {
74
+ const defined = new Set(segments.flatMap((s) => s.defines));
75
+ const out = new Map(inherited ?? []);
76
+ for (const s of segments)
77
+ for (const name of exportedFunctionNames(s.argv))
78
+ out.set(name, defined.has(name) ? "read" : out.get(name) ?? "unread");
79
+ for (const s of segments)
80
+ for (const name of envFunctionNames(s.argv))
81
+ out.set(name, "unread");
82
+ return out;
83
+ }
84
+ export function inheritedExportedFunctions(names) {
85
+ return {
86
+ start: (key) => (isFunctionKey(key) ? (names.has(key.slice(FUNCTION_KEY_PREFIX.length)) ? FUNCTION_DEFINED : FUNCTION_ABSENT) : BUILTIN_ENABLED),
87
+ bound: "all",
88
+ };
89
+ }
49
90
  const ATTRIBUTE_KINDS = { integer: "integer", transformed: "transformed", frozen: "frozen" };
50
91
  const EVERY_ATTRIBUTE = Object.values(ATTRIBUTE_KINDS).map((kind) => ({ kind }));
51
92
  export function projectSegment(segment) {
@@ -20,6 +20,7 @@
20
20
  import type { ExecutionEnv } from "../../internal/harness-types.js";
21
21
  import { violationDetails } from "./safety.js";
22
22
  import { type ShellReadPlan } from "./shell-read-plan.js";
23
+ import { type ReadLanding } from "./shell-read-identity.js";
23
24
  import { type HomeViewSource } from "./read-deny-home.js";
24
25
  import { type EstablishedRead, type ShellReadBoundary, type ShellReadDisposition, type ShellReadFinding, type ShellReadSeat } from "./shell-read-judge.js";
25
26
  import type { ReadRootGrantCandidate } from "../../core/tool-spec.js";
@@ -169,9 +170,18 @@ export type ShellReadAdmission = (toolName: string, toolCallId: string | undefin
169
170
  isError: true;
170
171
  details?: unknown;
171
172
  } | undefined>;
173
+ /** Where the station's last non-refused judgment of a call found its reads land (`readLandingsOf`): the judgment its
174
+ * admission holds for the call id — the one the spawn re-establishes — read without consuming it. `undefined` ⇒ the
175
+ * station holds none (a refused judgment records nothing). Its readers take it right where the latest judgment is a
176
+ * non-refused one of the bytes they hold: the park when the filed bytes are the judged ones, the resumed leg's execution
177
+ * station after its belt. A judgment that settles after a newer one replaced it is what the spawn would re-establish too:
178
+ * the spawn then refuses bytes the entry does not describe, and a row bound to it vetoes the resume wherever the two
179
+ * commands' reads differ (fail-closed either way). */
180
+ export type ShellReadLandings = (toolCallId: string) => readonly ReadLanding[] | undefined;
172
181
  export interface ShellReadStation {
173
182
  readonly check: ShellReadCheck;
174
183
  readonly admit: ShellReadAdmission;
184
+ readonly landings: ShellReadLandings;
175
185
  }
176
186
  export interface ShellReadStationOptions {
177
187
  readonly env: ExecutionEnv;
@@ -3,19 +3,20 @@ import { errorResult } from "../../core/tools.js";
3
3
  import { BASH_READONLY_CONFINEMENT_NOTE } from "./fs-shared.js";
4
4
  import { isAbsoluteForFamily, normalizeAbsPathLexically, pathFamilyOf, violationDetails, withinAnyRoot } from "./safety.js";
5
5
  import { checkedReadDenyHomes, fitMiddle, READ_DENY_SENTENCE_PART_MAX, readDenySentence } from "./read-deny.js";
6
- import { NOT_AUTO_ALLOWED, programPositionRefusalSentence, readProgramPosition } from "./bash-program-position.js";
6
+ import { NOT_AUTO_ALLOWED, declinedProgramSentence } from "./bash-program-position.js";
7
7
  import { bashClassifyDefaultAllow } from "./bash-readonly-classifier.js";
8
8
  import { planShellReads } from "./shell-read-plan.js";
9
9
  import { createShellReadEstablisher, establishShellReadsLexically } from "./shell-read-establish.js";
10
+ import { readLandingsOf } from "./shell-read-identity.js";
10
11
  import { declaredReadDenyHomes, homeViewsAt } from "./read-deny-home.js";
11
12
  import { anyOptionWord, programArgs } from "./shell-read-write-targets.js";
12
13
  import { shellReadFaceWords } from "./shell-read-face.js";
13
14
  import { passesUnasked } from "./shell-read-device.js";
14
15
  import { programRow, selectedOptions } from "./program-read-model.js";
16
+ import { refusedByRemoval, SHELL_REMOVAL_COMMANDS } from "./removal-targets.js";
15
17
  import { allFindings, anyFaceGuards, decideShellRead, denyRowAtOrBelow, foldShellReadFindings, judgeEstablishedPlan, readRootGrantCandidateOf, stationGuards, writeFaceGuards, } from "./shell-read-judge.js";
16
18
  import { seatOf } from "../../core/tool-name-readings.js";
17
19
  import { normalizeReadRootCandidate } from "../../core/read-root-candidate.js";
18
- import { argvOf, lexShellText } from "../../shell/lex.js";
19
20
  import { assertNoRetiredShellReadBoundaryKeys } from "../../core/retired-keys.js";
20
21
  function containmentDetails(paths) {
21
22
  return { type: "readonly_out_of_root", code: "readonly_out_of_root", paths };
@@ -26,7 +27,6 @@ function unestablishedDetails() {
26
27
  function findingDetails(finding, paths) {
27
28
  return finding === "unestablishable" || finding === "declined" || finding === "unanswered" ? unestablishedDetails() : containmentDetails(paths);
28
29
  }
29
- const REMOVAL_COMMANDS = new Set(["rm", "rmdir"]);
30
30
  const WRITES_BENEATH = {
31
31
  cp: () => true,
32
32
  mv: () => true,
@@ -74,15 +74,16 @@ function writesPlacedOf(judged, boundary) {
74
74
  if (UNPLACED_OPTIONS[verb]?.(programArgs(s.segment).map((w) => w.spelled)) === true)
75
75
  return false;
76
76
  const beneath = WRITES_BENEATH[verb]?.(s.segment) === true;
77
+ const removal = SHELL_REMOVAL_COMMANDS.includes(verb);
77
78
  for (const f of s.findings) {
78
79
  if (f.read.candidate.face !== "write")
79
80
  continue;
80
81
  const target = f.read.target;
81
82
  if (f.read.established === "unestablishable" || target === undefined || isPattern(f) || f.kind !== "none" || (f.containment !== "inside" && f.containment !== "open"))
82
83
  return false;
83
- if (beneath && denyRowAtOrBelow(f.read, boundary, !REMOVAL_COMMANDS.has(verb)))
84
+ if (beneath && denyRowAtOrBelow(f.read, boundary, !removal))
84
85
  return false;
85
- if (REMOVAL_COMMANDS.has(verb) && writeRoots.some((root) => withinAnyRoot([target], root)))
86
+ if (removal && !refusedByRemoval(f.read) && writeRoots.some((root) => withinAnyRoot([target], root)))
86
87
  return false;
87
88
  }
88
89
  return true;
@@ -182,19 +183,6 @@ function shellCommandOf(args) {
182
183
  const command = args?.command;
183
184
  return typeof command === "string" ? command : undefined;
184
185
  }
185
- function declineSentence(segment) {
186
- const lexed = lexShellText(segment.text);
187
- if (!("reject" in lexed) && lexed.segments[0] !== undefined) {
188
- const pos = readProgramPosition(argvOf(lexed.segments[0]));
189
- if (pos.refusal !== undefined)
190
- return programPositionRefusalSentence(pos.refusal);
191
- if (pos.argvFromStdin) {
192
- const runs = pos.program?.basename ?? "the program it runs";
193
- return `"${segment.text.trim()}" hands ${runs} its operands on its standard input, which this station does not read ${NOT_AUTO_ALLOWED}`;
194
- }
195
- }
196
- return `"${segment.text.trim()}" runs a program this station cannot name ${NOT_AUTO_ALLOWED}`;
197
- }
198
186
  const ACCOUNT_PART_MAX = READ_DENY_SENTENCE_PART_MAX;
199
187
  const CAUSE_SPELLING_MAX = 64;
200
188
  function fitCause(cause) {
@@ -236,7 +224,7 @@ function findingAccount(fold, boundary) {
236
224
  return `the text given to ${reenteredPrograms(fold)} — as an argument, on standard input, or in the file it names — runs as shell text this station does not parse ${NOT_AUTO_ALLOWED}`;
237
225
  return `the command's text could not be read as shell, so where it ${verb} cannot be established ${NOT_AUTO_ALLOWED}`;
238
226
  case "declined":
239
- return fold.declined !== undefined ? declineSentence(fold.declined) : `the station could not read which program runs ${NOT_AUTO_ALLOWED}`;
227
+ return fold.declined !== undefined ? declinedProgramSentence(fold.declined.text) : `the station could not read which program runs ${NOT_AUTO_ALLOWED}`;
240
228
  case "identity_changed":
241
229
  return `"${fitMiddle(w?.read.candidate.raw ?? "?", ACCOUNT_PART_MAX)}" resolves to "${fitMiddle(w?.read.target ?? "?", ACCOUNT_PART_MAX)}" now, not where it resolved when this call was judged`;
242
230
  case "deny_hit":
@@ -408,6 +396,7 @@ export function createShellReadStation(opts) {
408
396
  };
409
397
  const admissions = new Map();
410
398
  const remember = (toolCallId, a) => {
399
+ admissions.delete(toolCallId);
411
400
  if (admissions.size >= ADMISSION_MAX) {
412
401
  const oldest = admissions.keys().next().value;
413
402
  if (oldest !== undefined)
@@ -491,5 +480,9 @@ export function createShellReadStation(opts) {
491
480
  const r = refusalOf(toolName, identity, a.boundary, []);
492
481
  return refused(errorResult(r.sentence, containmentDetails(changed.map((c) => c.target).filter((t) => t !== undefined))));
493
482
  };
494
- return { check, admit };
483
+ const landings = (toolCallId) => {
484
+ const a = admissions.get(toolCallId);
485
+ return a !== undefined ? readLandingsOf(a.established) : undefined;
486
+ };
487
+ return { check, admit, landings };
495
488
  }
@@ -9,7 +9,8 @@
9
9
  * establisher and the write guards are handed an {@link ObservedFilesystem}, never the environment, so a lookup they make
10
10
  * cannot escape the record.
11
11
  *
12
- * What is NOT a failure: a conclusive absence (`not_found`, `not_directory` — the answer is "nothing there") and an adapter
12
+ * What is NOT a failure: a conclusive absence (`not_found`, `not_directory`, `name_too_long` — the answer is "nothing there", or
13
+ * "nothing can be there": the program that opens such a name fails the same way) and an adapter
13
14
  * that has no filesystem surface (`not_supported` — its answer that there is no file face: a chain it answers so keeps the
14
15
  * lexical reading). Everything else is, and is recorded wherever it falls — a resolver that answered nothing at all in the
15
16
  * command included: a lookup that failed (`permission_denied`, `timeout`, `unknown`, a throw) is a resolver failing, whose
@@ -47,6 +48,9 @@ export interface ObservedEnvironment {
47
48
  /** Records that came from outside the door: the declared roots' own lookup and the home views a read could not be placed against. */
48
49
  adopt(records: readonly Incomplete[]): void;
49
50
  }
51
+ /** The answers that say NOTHING IS THERE — no entry (`not_found`), nothing reachable under a non-directory (`not_directory`), a
52
+ * name the filesystem cannot hold (`name_too_long`): the station's one reading of an absence, wherever a lookup is read. */
53
+ export declare const isAbsence: (code: string) => boolean;
50
54
  /** The declared roots, canonicalized ONCE per establisher (through the same door), with what that lookup could not finish —
51
55
  * merged into every establishment. `known`: the caller already holds them as canonical identities and they are used verbatim
52
56
  * (re-resolving one that was since swapped for a link would substitute the link's target for the root that was approved). */
@@ -1,6 +1,7 @@
1
1
  import { canonicalPathIsAuthoritative } from "../../core/remote-env.js";
2
2
  const OBSERVED = Symbol("observedFilesystem");
3
- const CONCLUSIVE = new Set(["not_found", "not_directory", "not_supported"]);
3
+ export const isAbsence = (code) => code === "not_found" || code === "not_directory" || code === "name_too_long";
4
+ const conclusive = (code) => isAbsence(code) || code === "not_supported";
4
5
  export function canonicalRootsOnce(env, readRoots, known) {
5
6
  let once = known ? Promise.resolve({ roots: readRoots, incomplete: [] }) : undefined;
6
7
  return (signal) => (once ??= (async () => {
@@ -21,7 +22,7 @@ export function observeEnvironment(env) {
21
22
  const records = [];
22
23
  const note = (op, path, what, code) => void records.push({ op, detail: `"${path}" ${what} (${code})` });
23
24
  const watch = (op, path, what, ask) => new Promise((resolve) => resolve(ask())).then((r) => {
24
- if (!r.ok && !CONCLUSIVE.has(r.error.code))
25
+ if (!r.ok && !conclusive(r.error.code))
25
26
  note(op, path, what, r.error.code);
26
27
  return r;
27
28
  }, (e) => {
@@ -43,6 +43,7 @@ import { type ObservedEnvironment } from "./shell-read-environment.js";
43
43
  import type { ShellReadPlan, ShellReadSegment } from "./shell-read-plan.js";
44
44
  import type { EstablishedRead, ShellReadBoundary } from "./shell-read-judge.js";
45
45
  import type { HomeViewSource } from "./read-deny-home.js";
46
+ import { type FsGlob } from "./fs-glob.js";
46
47
  /**
47
48
  * How many directories one glob operand may enumerate, and how many names it may
48
49
  * match, before the leg gives up and answers `unestablishable`.
@@ -54,6 +55,20 @@ import type { HomeViewSource } from "./read-deny-home.js";
54
55
  */
55
56
  export declare const MAX_GLOB_DIRS = 256;
56
57
  export declare const MAX_GLOB_MATCHES = 8192;
58
+ /**
59
+ * Compile ONE path segment of a shell glob into a whole-name matcher (the engine in `fs-glob.ts`), or `undefined` when the
60
+ * pattern uses a construct this matcher does not model (the caller then fails closed).
61
+ *
62
+ * Modelled: `*` (any run of non-separator characters), `?` (one), and bracket expressions with `!`/`^`
63
+ * negation, `a-z` ranges, and a literal `]` in first position. A POSIX class (`[[:alpha:]]`) is deliberately widened to
64
+ * "any one character" rather than refused — the lexer spells such a class, and one holding a quoted character, `?` —
65
+ * over-matching only adds candidates to verify, the safe direction here, while refusing would cost a usable idiom.
66
+ *
67
+ * NOT modelled: a backslash. Its escaping semantics interact with the lexer's quote folding (which has
68
+ * already rewritten the token), so a segment carrying one is failed closed rather than guessed at. The
69
+ * leading-dot rule is not a property of the pattern's own text and lives in {@link globSegmentMatches}.
70
+ */
71
+ export declare function compileGlobSegment(pattern: string): FsGlob | undefined;
57
72
  /** The reads of one plan, established: per segment, in the plan's own order, with nested plans beside. */
58
73
  export interface EstablishedPlan {
59
74
  readonly plan: ShellReadPlan;