@sema-agent/core 7.54.1 → 7.56.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 (621) hide show
  1. package/CHANGELOG.md +950 -0
  2. package/dist/agents/agent-transcript-tool.js +2 -1
  3. package/dist/agents/builtin-agents.d.ts +12 -14
  4. package/dist/agents/cascade.js +1 -1
  5. package/dist/agents/cc-peer-directory.d.ts +36 -0
  6. package/dist/agents/cc-peer-directory.js +139 -0
  7. package/dist/agents/cc-peer-wire.d.ts +105 -0
  8. package/dist/agents/cc-peer-wire.js +98 -0
  9. package/dist/agents/cc-uds-peer-channel.d.ts +40 -0
  10. package/dist/agents/cc-uds-peer-channel.js +457 -0
  11. package/dist/agents/child-model-seat.d.ts +0 -11
  12. package/dist/agents/child-model-seat.js +0 -3
  13. package/dist/agents/cross-session-envelope.d.ts +4 -1
  14. package/dist/agents/cross-session-envelope.js +8 -1
  15. package/dist/agents/cross-session-judge.d.ts +2 -2
  16. package/dist/agents/list-agents-tool.d.ts +3 -1
  17. package/dist/agents/list-agents-tool.js +9 -8
  18. package/dist/agents/observer.d.ts +4 -5
  19. package/dist/agents/observer.js +2 -1
  20. package/dist/agents/peer-admission.d.ts +6 -0
  21. package/dist/agents/peer-admission.js +4 -1
  22. package/dist/agents/peer-directory.d.ts +65 -13
  23. package/dist/agents/peer-directory.js +90 -25
  24. package/dist/agents/peer-notices.d.ts +1 -1
  25. package/dist/agents/peer-session-drain.d.ts +3 -1
  26. package/dist/agents/peer-session-drain.js +3 -2
  27. package/dist/agents/read-inbox-tool.js +2 -1
  28. package/dist/agents/repair-loop.js +2 -2
  29. package/dist/agents/retain-ledger.d.ts +1 -1
  30. package/dist/agents/roster-store.d.ts +1 -1
  31. package/dist/agents/send-message-tool.d.ts +10 -0
  32. package/dist/agents/send-message-tool.js +37 -8
  33. package/dist/agents/subagent.d.ts +39 -82
  34. package/dist/agents/subagent.js +109 -106
  35. package/dist/agents/tool-filter.d.ts +31 -46
  36. package/dist/agents/tool-filter.js +13 -33
  37. package/dist/agents/verify.d.ts +6 -5
  38. package/dist/agents/verify.js +3 -3
  39. package/dist/brain/anthropic.js +43 -81
  40. package/dist/brain/errors.d.ts +15 -0
  41. package/dist/brain/errors.js +10 -0
  42. package/dist/brain/media-degrade.d.ts +18 -7
  43. package/dist/brain/media-degrade.js +13 -2
  44. package/dist/brain/model-capability.d.ts +37 -0
  45. package/dist/brain/model-capability.js +34 -0
  46. package/dist/brain/model-presets.d.ts +6 -12
  47. package/dist/brain/model-presets.js +1 -6
  48. package/dist/brain/open-responses.js +27 -35
  49. package/dist/brain/openai.js +30 -98
  50. package/dist/brain/provider-dialect.d.ts +39 -3
  51. package/dist/brain/provider-dialect.js +28 -0
  52. package/dist/brain/reasoning-request.d.ts +96 -0
  53. package/dist/brain/reasoning-request.js +174 -0
  54. package/dist/brain/reasoning.d.ts +12 -12
  55. package/dist/brain/reasoning.js +4 -3
  56. package/dist/brain/request-params.d.ts +62 -9
  57. package/dist/brain/request-params.js +42 -7
  58. package/dist/brain/retry.d.ts +1 -1
  59. package/dist/brain/route-adjudicator.d.ts +15 -0
  60. package/dist/brain/route-adjudicator.js +15 -0
  61. package/dist/brain/status-sink.d.ts +20 -0
  62. package/dist/brain/status-sink.js +7 -0
  63. package/dist/brain/stream-engine.js +6 -5
  64. package/dist/brain/stream-shared.d.ts +1 -1
  65. package/dist/core/a2a.d.ts +2 -1
  66. package/dist/core/a2a.js +19 -13
  67. package/dist/core/advisor-verdict.d.ts +120 -0
  68. package/dist/core/advisor-verdict.js +92 -0
  69. package/dist/core/agent-definition.d.ts +17 -8
  70. package/dist/core/allow-entry.d.ts +69 -36
  71. package/dist/core/allow-entry.js +81 -52
  72. package/dist/core/allow-rule-shadow.d.ts +10 -3
  73. package/dist/core/approval-object.d.ts +2 -1
  74. package/dist/core/approval-object.js +6 -6
  75. package/dist/core/ask-origin.d.ts +127 -29
  76. package/dist/core/ask-origin.js +87 -25
  77. package/dist/core/ask-question.d.ts +51 -8
  78. package/dist/core/ask-question.js +12 -7
  79. package/dist/core/ask-unresolvable-notice.d.ts +8 -3
  80. package/dist/core/ask-unresolvable-notice.js +16 -2
  81. package/dist/core/auto-compaction.d.ts +11 -8
  82. package/dist/core/auto-compaction.js +4 -2
  83. package/dist/core/auto-mode-arming.d.ts +2 -2
  84. package/dist/core/auto-mode-defaults.d.ts +8 -8
  85. package/dist/core/auto-mode-prompt-assets.d.ts +3 -3
  86. package/dist/core/auto-mode-prompt.d.ts +1 -1
  87. package/dist/core/auto-mode.d.ts +17 -9
  88. package/dist/core/auto-mode.js +9 -6
  89. package/dist/core/background-agent-store.d.ts +3 -3
  90. package/dist/core/canonical-json.d.ts +1 -1
  91. package/dist/core/canonical-json.js +2 -2
  92. package/dist/core/checkpoint-generation.d.ts +53 -0
  93. package/dist/core/checkpoint-generation.js +35 -0
  94. package/dist/core/checkpoint-queries.d.ts +180 -0
  95. package/dist/core/checkpoint-queries.js +272 -0
  96. package/dist/core/checkpoint-requirements.d.ts +19 -4
  97. package/dist/core/checkpoint-requirements.js +8 -14
  98. package/dist/core/checkpoint-store.d.ts +165 -72
  99. package/dist/core/checkpoint-store.js +79 -82
  100. package/dist/core/child-clamp-seats.d.ts +6 -0
  101. package/dist/core/child-clamp-seats.js +3 -16
  102. package/dist/core/compliance.d.ts +2 -2
  103. package/dist/core/context-edit.d.ts +6 -7
  104. package/dist/core/cross-boundary-taint.d.ts +11 -4
  105. package/dist/core/cross-boundary-taint.js +3 -3
  106. package/dist/core/decision-receipt.d.ts +37 -3
  107. package/dist/core/decision-receipt.js +19 -19
  108. package/dist/core/delegation-not-started.d.ts +6 -0
  109. package/dist/core/delegation-not-started.js +17 -0
  110. package/dist/core/effective-path-target.d.ts +1 -1
  111. package/dist/core/engine-attestation.d.ts +93 -0
  112. package/dist/core/engine-attestation.js +70 -0
  113. package/dist/core/engine-capabilities.d.ts +4 -1
  114. package/dist/core/engine-capabilities.js +1 -1
  115. package/dist/core/engine-notice.d.ts +45 -12
  116. package/dist/core/exec-output-tail.d.ts +1 -1
  117. package/dist/core/file-history-retention.d.ts +1 -1
  118. package/dist/core/file-history-store.d.ts +147 -21
  119. package/dist/core/file-history-store.js +58 -32
  120. package/dist/core/gate-fold.d.ts +1 -1
  121. package/dist/core/gate-fold.js +24 -11
  122. package/dist/core/gate-lanes.js +81 -68
  123. package/dist/core/gate-outcome.d.ts +40 -6
  124. package/dist/core/gate-outcome.js +56 -0
  125. package/dist/core/governance-codes.d.ts +17 -3
  126. package/dist/core/governance-codes.js +16 -0
  127. package/dist/core/hands-band.d.ts +1 -1
  128. package/dist/core/hooks.d.ts +21 -20
  129. package/dist/core/hooks.js +3 -1
  130. package/dist/core/host-floor.d.ts +128 -0
  131. package/dist/core/host-floor.js +206 -0
  132. package/dist/core/host-target.d.ts +84 -0
  133. package/dist/core/host-target.js +92 -0
  134. package/dist/core/image-downsample.d.ts +1 -1
  135. package/dist/core/lsp-diagnostics.d.ts +4 -4
  136. package/dist/core/lsp.d.ts +3 -3
  137. package/dist/core/mailbox-store.d.ts +4 -0
  138. package/dist/core/mcp-connection-pool.d.ts +18 -2
  139. package/dist/core/mcp-connection-pool.js +53 -6
  140. package/dist/core/mcp-failure.d.ts +23 -4
  141. package/dist/core/mcp-failure.js +26 -11
  142. package/dist/core/mcp-listing-drift.d.ts +10 -0
  143. package/dist/core/mcp-listing-drift.js +6 -0
  144. package/dist/core/mcp-server-link.d.ts +173 -0
  145. package/dist/core/mcp-server-link.js +127 -0
  146. package/dist/core/mcp-server-spec.d.ts +4 -2
  147. package/dist/core/mcp-session-end.d.ts +26 -0
  148. package/dist/core/mcp-session-end.js +29 -0
  149. package/dist/core/mcp-startup-request.d.ts +17 -0
  150. package/dist/core/mcp-startup-request.js +17 -0
  151. package/dist/core/mcp.d.ts +17 -13
  152. package/dist/core/mcp.js +240 -189
  153. package/dist/core/media-byte-cap.d.ts +1 -1
  154. package/dist/core/memory-engine/delegation-settlement.js +15 -24
  155. package/dist/core/memory-engine/engine.d.ts +9 -9
  156. package/dist/core/memory-engine/engine.js +4 -4
  157. package/dist/core/memory-engine/layout.d.ts +60 -8
  158. package/dist/core/memory-engine/layout.js +65 -6
  159. package/dist/core/memory-engine/provenance-wording.d.ts +1 -1
  160. package/dist/core/memory-engine/tools.js +4 -1
  161. package/dist/core/mode-policy.d.ts +1 -1
  162. package/dist/core/model-seat.d.ts +10 -3
  163. package/dist/core/mods/classic-events.d.ts +67 -0
  164. package/dist/core/mods/classic-events.js +1 -0
  165. package/dist/core/mods/dollar.d.ts +13 -0
  166. package/dist/core/mods/extension-call.d.ts +31 -0
  167. package/dist/core/mods/extension-call.js +43 -0
  168. package/dist/core/mods/kernel/dispatch.d.ts +20 -3
  169. package/dist/core/mods/kernel/dispatch.js +140 -69
  170. package/dist/core/mods/kernel/events.d.ts +47 -11
  171. package/dist/core/mods/kernel/events.js +66 -42
  172. package/dist/core/mods/kernel/index.d.ts +4 -4
  173. package/dist/core/mods/kernel/index.js +2 -2
  174. package/dist/core/mods/kernel/receive.d.ts +39 -5
  175. package/dist/core/mods/kernel/receive.js +290 -17
  176. package/dist/core/mods/kernel/registration.d.ts +33 -2
  177. package/dist/core/mods/kernel/registration.js +6 -7
  178. package/dist/core/mods/kernel/site-rules.d.ts +44 -16
  179. package/dist/core/mods/kernel/site-rules.js +24 -42
  180. package/dist/core/mods/spec-seats.d.ts +69 -0
  181. package/dist/core/mods/spec-seats.js +114 -0
  182. package/dist/core/mods/stations.d.ts +28 -8
  183. package/dist/core/mods/stations.js +29 -13
  184. package/dist/core/mods/tool-call.d.ts +79 -0
  185. package/dist/core/mods/tool-call.js +152 -0
  186. package/dist/core/namespaced-rule-name.d.ts +44 -24
  187. package/dist/core/namespaced-rule-name.js +50 -43
  188. package/dist/core/output-style.d.ts +1 -1
  189. package/dist/core/param-rule-reach.d.ts +15 -0
  190. package/dist/core/param-rule-reach.js +30 -0
  191. package/dist/core/parent-spec-seat.d.ts +13 -1
  192. package/dist/core/parent-spec-seat.js +6 -0
  193. package/dist/core/park-selfcheck.js +1 -0
  194. package/dist/core/pause-registry.d.ts +16 -5
  195. package/dist/core/pause-registry.js +6 -2
  196. package/dist/core/peer-channel.d.ts +70 -0
  197. package/dist/core/peer-channel.js +1 -0
  198. package/dist/core/permission-rule-consent.d.ts +30 -5
  199. package/dist/core/permission-rule-consent.js +147 -50
  200. package/dist/core/permission-rule-model.d.ts +245 -65
  201. package/dist/core/permission-rule-model.js +421 -107
  202. package/dist/core/permission-rule-org.d.ts +6 -2
  203. package/dist/core/permission-rule-org.js +7 -3
  204. package/dist/core/permission-rule-provider.d.ts +6 -2
  205. package/dist/core/permission-rule-provider.js +41 -11
  206. package/dist/core/permission-rule-store.d.ts +22 -26
  207. package/dist/core/permission-rule-store.js +12 -6
  208. package/dist/core/permission-rule-sync.d.ts +11 -2
  209. package/dist/core/permission-rule-sync.js +11 -3
  210. package/dist/core/permission-rule-syntax.d.ts +5 -4
  211. package/dist/core/permission-rule-syntax.js +2 -2
  212. package/dist/core/permission-rules.d.ts +53 -15
  213. package/dist/core/permission-rules.js +125 -100
  214. package/dist/core/persisted-rule-arms.d.ts +6 -4
  215. package/dist/core/persisted-rule-arms.js +10 -12
  216. package/dist/core/present-plan-tool.js +3 -1
  217. package/dist/core/principal-name.d.ts +20 -0
  218. package/dist/core/principal-name.js +22 -0
  219. package/dist/core/prompt-section-seat.js +4 -6
  220. package/dist/core/protocol-http-auth.d.ts +26 -5
  221. package/dist/core/protocol-http-auth.js +137 -4
  222. package/dist/core/protocol-naming.d.ts +2 -2
  223. package/dist/core/read-only-shell-table.d.ts +1 -1
  224. package/dist/core/read-only-shell.d.ts +1 -1
  225. package/dist/core/retired-keys.d.ts +16 -0
  226. package/dist/core/retired-keys.js +16 -4
  227. package/dist/core/rewrite-rejudge.d.ts +60 -0
  228. package/dist/core/rewrite-rejudge.js +36 -0
  229. package/dist/core/roles.d.ts +34 -3
  230. package/dist/core/roles.js +66 -53
  231. package/dist/core/rule-lane-reads.d.ts +20 -15
  232. package/dist/core/rule-lane-reads.js +45 -17
  233. package/dist/core/rule-offer-read.d.ts +53 -0
  234. package/dist/core/rule-offer-read.js +146 -0
  235. package/dist/core/rule-owner.d.ts +46 -0
  236. package/dist/core/rule-owner.js +29 -0
  237. package/dist/core/runner/advisor-instructions.d.ts +70 -0
  238. package/dist/core/runner/advisor-instructions.js +61 -0
  239. package/dist/core/runner/advisor-tool.d.ts +33 -0
  240. package/dist/core/runner/advisor-tool.js +112 -0
  241. package/dist/core/runner/announce-once-ledger.d.ts +18 -26
  242. package/dist/core/runner/announce-once-ledger.js +19 -46
  243. package/dist/core/runner/approval-feedback.js +6 -3
  244. package/dist/core/runner/assemble-result.d.ts +2 -1
  245. package/dist/core/runner/assemble-result.js +1 -1
  246. package/dist/core/runner/call-hook-stations.d.ts +3 -2
  247. package/dist/core/runner/caller-roster.d.ts +21 -2
  248. package/dist/core/runner/caller-roster.js +38 -0
  249. package/dist/core/runner/capability-withheld-seat.d.ts +5 -0
  250. package/dist/core/runner/capability-withheld-seat.js +24 -0
  251. package/dist/core/runner/classifier-ladder.d.ts +33 -13
  252. package/dist/core/runner/classifier-ladder.js +15 -14
  253. package/dist/core/runner/compaction-restate.d.ts +10 -6
  254. package/dist/core/runner/compaction-restate.js +9 -3
  255. package/dist/core/runner/construction-doors.js +3 -0
  256. package/dist/core/runner/contracts.d.ts +40 -33
  257. package/dist/core/runner/conversation-segment.d.ts +28 -0
  258. package/dist/core/runner/conversation-segment.js +42 -0
  259. package/dist/core/runner/cross-boundary-lane.d.ts +21 -16
  260. package/dist/core/runner/cross-boundary-lane.js +58 -34
  261. package/dist/core/runner/decide-continuation.d.ts +7 -4
  262. package/dist/core/runner/decide-continuation.js +2 -2
  263. package/dist/core/runner/denial-limit-arms.d.ts +4 -4
  264. package/dist/core/runner/denial-limit-arms.js +1 -1
  265. package/dist/core/runner/derived-route-fallback.d.ts +24 -24
  266. package/dist/core/runner/derived-route-fallback.js +9 -7
  267. package/dist/core/runner/file-history-request.d.ts +18 -0
  268. package/dist/core/runner/file-history-request.js +21 -13
  269. package/dist/core/runner/file-history-restore.d.ts +45 -0
  270. package/dist/core/runner/file-history-restore.js +46 -0
  271. package/dist/core/runner/gate-exit.d.ts +9 -3
  272. package/dist/core/runner/gate-exit.js +11 -5
  273. package/dist/core/runner/image.d.ts +7 -17
  274. package/dist/core/runner/image.js +9 -60
  275. package/dist/core/runner/initial-run-state.js +1 -1
  276. package/dist/core/runner/permission-rule-lanes.d.ts +6 -6
  277. package/dist/core/runner/permission-rule-lanes.js +38 -15
  278. package/dist/core/runner/person-path-rows.d.ts +12 -9
  279. package/dist/core/runner/person-path-rows.js +19 -8
  280. package/dist/core/runner/prepare-advisor.d.ts +63 -0
  281. package/dist/core/runner/prepare-advisor.js +77 -0
  282. package/dist/core/runner/prepare-ask-lane.d.ts +2 -2
  283. package/dist/core/runner/prepare-ask-lane.js +5 -2
  284. package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -6
  285. package/dist/core/runner/prepare-caps-and-workflow.js +5 -4
  286. package/dist/core/runner/prepare-config-doors.d.ts +31 -38
  287. package/dist/core/runner/prepare-config-doors.js +57 -34
  288. package/dist/core/runner/prepare-defer-classify.d.ts +4 -3
  289. package/dist/core/runner/prepare-defer-classify.js +7 -8
  290. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
  291. package/dist/core/runner/prepare-delegation-surface.js +1 -1
  292. package/dist/core/runner/prepare-file-history.d.ts +48 -8
  293. package/dist/core/runner/prepare-file-history.js +41 -73
  294. package/dist/core/runner/prepare-gate-stations.d.ts +2 -5
  295. package/dist/core/runner/prepare-gate-stations.js +12 -8
  296. package/dist/core/runner/prepare-hands-readface.d.ts +2 -8
  297. package/dist/core/runner/prepare-hands-readface.js +15 -14
  298. package/dist/core/runner/prepare-inherited-gate.d.ts +11 -7
  299. package/dist/core/runner/prepare-inherited-gate.js +8 -6
  300. package/dist/core/runner/prepare-memory-engine-session.js +1 -1
  301. package/dist/core/runner/prepare-park-ask.js +12 -12
  302. package/dist/core/runner/prepare-policy-chain.d.ts +7 -4
  303. package/dist/core/runner/prepare-policy-chain.js +68 -81
  304. package/dist/core/runner/prepare-project-context.d.ts +5 -2
  305. package/dist/core/runner/prepare-project-context.js +6 -3
  306. package/dist/core/runner/prepare-prompt-assembly.d.ts +5 -7
  307. package/dist/core/runner/prepare-prompt-assembly.js +10 -8
  308. package/dist/core/runner/prepare-prompt-inputs.d.ts +11 -9
  309. package/dist/core/runner/prepare-prompt-inputs.js +4 -6
  310. package/dist/core/runner/prepare-protocol-tools.d.ts +4 -2
  311. package/dist/core/runner/prepare-protocol-tools.js +5 -4
  312. package/dist/core/runner/prepare-safety-scan.d.ts +9 -12
  313. package/dist/core/runner/prepare-safety-scan.js +8 -23
  314. package/dist/core/runner/prepare-suspend-saga.d.ts +2 -0
  315. package/dist/core/runner/prepare-suspend-saga.js +5 -6
  316. package/dist/core/runner/prepare-task.d.ts +1 -1
  317. package/dist/core/runner/prepare-task.js +41 -35
  318. package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +7 -4
  319. package/dist/core/runner/prepare-tool-disclosure-mount.js +24 -18
  320. package/dist/core/runner/prepare-turn-wiring.d.ts +0 -4
  321. package/dist/core/runner/prepare-turn-wiring.js +2 -7
  322. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -4
  323. package/dist/core/runner/prepare-wiring-manifest.js +3 -3
  324. package/dist/core/runner/resume-admission.js +1 -1
  325. package/dist/core/runner/resume-apply.js +11 -12
  326. package/dist/core/runner/resume-checkpoint-screen.js +3 -0
  327. package/dist/core/runner/resume-claim.d.ts +4 -2
  328. package/dist/core/runner/resume-claim.js +15 -8
  329. package/dist/core/runner/resume-policy-outcome.js +1 -1
  330. package/dist/core/runner/retired-runner-deps.js +2 -1
  331. package/dist/core/runner/rewind-files.d.ts +15 -0
  332. package/dist/core/runner/rewind-files.js +132 -0
  333. package/dist/core/runner/run-attachment-seats.js +2 -2
  334. package/dist/core/runner/run-brain-sinks.d.ts +4 -1
  335. package/dist/core/runner/run-brain-sinks.js +4 -2
  336. package/dist/core/runner/run-compaction-machinery.d.ts +1 -1
  337. package/dist/core/runner/run-compaction-machinery.js +2 -12
  338. package/dist/core/runner/run-git-lane.d.ts +1 -0
  339. package/dist/core/runner/run-harness-handlers.js +14 -7
  340. package/dist/core/runner/run-leg.d.ts +1 -1
  341. package/dist/core/runner/run-leg.js +43 -18
  342. package/dist/core/runner/run-settle-and-teardown.js +3 -2
  343. package/dist/core/runner/run-telemetry-and-budget-seats.js +1 -1
  344. package/dist/core/runner/run-turn-boundary.d.ts +1 -0
  345. package/dist/core/runner/run-turn-boundary.js +15 -22
  346. package/dist/core/runner/runtask.d.ts +3 -0
  347. package/dist/core/runner/runtask.js +8 -9
  348. package/dist/core/runner/session-read-file-states.d.ts +15 -0
  349. package/dist/core/runner/session-read-file-states.js +28 -0
  350. package/dist/core/runner/session-rule-policy.d.ts +22 -21
  351. package/dist/core/runner/session-rule-policy.js +17 -31
  352. package/dist/core/runner/shell-env-withheld.d.ts +33 -0
  353. package/dist/core/runner/shell-env-withheld.js +51 -0
  354. package/dist/core/runner/side-call-account.d.ts +32 -8
  355. package/dist/core/runner/side-call-account.js +23 -1
  356. package/dist/core/runner/skills-seat.js +6 -2
  357. package/dist/core/runner/stream-settle-backstop.js +1 -1
  358. package/dist/core/runner/strict-output-schema.d.ts +1 -1
  359. package/dist/core/runner/sub-agent-deny-lists.js +4 -6
  360. package/dist/core/runner/synthetic-tools.d.ts +16 -13
  361. package/dist/core/runner/synthetic-tools.js +8 -3
  362. package/dist/core/runner/tool-disclosure.d.ts +10 -12
  363. package/dist/core/runner/tool-disclosure.js +3 -4
  364. package/dist/core/runner/tool-end-body.d.ts +1 -1
  365. package/dist/core/runner/tool-end-body.js +10 -9
  366. package/dist/core/runner/tool-face-overlay.d.ts +2 -1
  367. package/dist/core/runner/tool-face-overlay.js +17 -1
  368. package/dist/core/runner/tool-not-executed.d.ts +5 -0
  369. package/dist/core/runner/tool-not-executed.js +11 -0
  370. package/dist/core/runner/tool-occurrence.d.ts +8 -0
  371. package/dist/core/runner/tool-occurrence.js +7 -0
  372. package/dist/core/runner/tool-progress-lane.d.ts +2 -2
  373. package/dist/core/runner/tool-turn-repair-seat.d.ts +3 -2
  374. package/dist/core/runner/turn-attachments.d.ts +91 -80
  375. package/dist/core/runner/turn-attachments.js +62 -37
  376. package/dist/core/runner-deps.d.ts +42 -42
  377. package/dist/core/runtime-caps.d.ts +4 -4
  378. package/dist/core/safety-axis-vocab.d.ts +6 -4
  379. package/dist/core/safety-axis-vocab.js +6 -5
  380. package/dist/core/safety-merge-corpus.js +26 -2
  381. package/dist/core/same-plain-value.d.ts +40 -0
  382. package/dist/core/same-plain-value.js +49 -0
  383. package/dist/core/scheduler.d.ts +1 -1
  384. package/dist/core/secret-env.d.ts +26 -3
  385. package/dist/core/secret-env.js +44 -8
  386. package/dist/core/select-model.js +3 -3
  387. package/dist/core/sensitive-path-policy.d.ts +1 -1
  388. package/dist/core/sensitive-path-policy.js +1 -1
  389. package/dist/core/session-policy-store.d.ts +102 -35
  390. package/dist/core/session-policy-store.js +210 -48
  391. package/dist/core/session-reconcile.d.ts +2 -2
  392. package/dist/core/session-store.d.ts +106 -37
  393. package/dist/core/session-store.js +165 -91
  394. package/dist/core/session.d.ts +101 -57
  395. package/dist/core/session.js +53 -0
  396. package/dist/core/shared-memory/tools.js +3 -1
  397. package/dist/core/shared-memory/types.d.ts +1 -1
  398. package/dist/core/shell-read-silence.d.ts +11 -12
  399. package/dist/core/shell-read-silence.js +9 -5
  400. package/dist/core/shell-run-candidates.js +3 -1
  401. package/dist/core/shell-wrapper-projection.js +1 -1
  402. package/dist/core/shell-wrapper-table.d.ts +14 -7
  403. package/dist/core/shell-wrapper-table.js +5 -4
  404. package/dist/core/side-query.d.ts +10 -0
  405. package/dist/core/side-query.js +15 -1
  406. package/dist/core/skill-grant.d.ts +7 -2
  407. package/dist/core/skill-grant.js +5 -0
  408. package/dist/core/skills-directory.js +6 -2
  409. package/dist/core/store-contracts/checkpoint-store-contract.d.ts +11 -1
  410. package/dist/core/store-contracts/checkpoint-store-contract.js +168 -3
  411. package/dist/core/store-contracts/file-history-store-contract.js +74 -4
  412. package/dist/core/store-contracts/peer-directory-contract.d.ts +7 -2
  413. package/dist/core/store-contracts/peer-directory-contract.js +14 -2
  414. package/dist/core/store-contracts/session-policy-store-contract.d.ts +7 -0
  415. package/dist/core/store-contracts/session-policy-store-contract.js +130 -0
  416. package/dist/core/store-contracts/session-repo-contract.js +176 -0
  417. package/dist/core/store-contracts/session-store-contract.d.ts +6 -8
  418. package/dist/core/store-contracts/session-store-contract.js +361 -51
  419. package/dist/core/store-contracts/workflow-journal-store-contract.js +26 -1
  420. package/dist/core/stub-env.d.ts +2 -0
  421. package/dist/core/stub-env.js +1 -0
  422. package/dist/core/surrogate-safe-slice.d.ts +3 -3
  423. package/dist/core/synthetic-read-verdict.js +3 -3
  424. package/dist/core/task-event.d.ts +42 -8
  425. package/dist/core/task-notification.d.ts +19 -15
  426. package/dist/core/task-registry-agent.d.ts +4 -4
  427. package/dist/core/task-registry-shared.d.ts +4 -4
  428. package/dist/core/task-registry-shared.js +1 -0
  429. package/dist/core/task-registry.d.ts +13 -4
  430. package/dist/core/task-registry.js +14 -2
  431. package/dist/core/task-result.d.ts +21 -3
  432. package/dist/core/task-spec.d.ts +69 -64
  433. package/dist/core/task-stream.d.ts +6 -6
  434. package/dist/core/task-tool-shape.d.ts +4 -4
  435. package/dist/core/tighten-task-spec.d.ts +1 -1
  436. package/dist/core/tighten-task-spec.js +2 -1
  437. package/dist/core/tool-catalog-entries.d.ts +36 -2
  438. package/dist/core/tool-catalog-entries.js +69 -43
  439. package/dist/core/tool-check-reading.d.ts +11 -0
  440. package/dist/core/tool-check-reading.js +11 -6
  441. package/dist/core/tool-conformance.js +1 -0
  442. package/dist/core/tool-errors.d.ts +2 -2
  443. package/dist/core/tool-face-reader.js +5 -3
  444. package/dist/core/tool-face.d.ts +21 -2
  445. package/dist/core/tool-face.js +1 -1
  446. package/dist/core/tool-model-gate.d.ts +5 -5
  447. package/dist/core/tool-name-aliases.d.ts +29 -8
  448. package/dist/core/tool-name-aliases.js +22 -4
  449. package/dist/core/tool-name-readings.d.ts +10 -43
  450. package/dist/core/tool-name-readings.js +2 -11
  451. package/dist/core/tool-policy.d.ts +85 -196
  452. package/dist/core/tool-policy.js +150 -175
  453. package/dist/core/tool-registry.d.ts +14 -7
  454. package/dist/core/tool-registry.js +17 -7
  455. package/dist/core/tool-result-store.js +5 -1
  456. package/dist/core/tool-roster.d.ts +57 -33
  457. package/dist/core/tool-roster.js +56 -68
  458. package/dist/core/tool-spec-members.js +8 -3
  459. package/dist/core/tool-spec.d.ts +53 -31
  460. package/dist/core/tools.js +51 -10
  461. package/dist/core/trace.d.ts +6 -2
  462. package/dist/core/types.d.ts +1 -1
  463. package/dist/core/untrusted-egress.d.ts +1 -1
  464. package/dist/core/untrusted-text.d.ts +1 -1
  465. package/dist/core/user-attachment.d.ts +8 -1
  466. package/dist/core/user-attachment.js +64 -4
  467. package/dist/core/warm-resume.d.ts +1 -1
  468. package/dist/core/wiring-manifest.d.ts +58 -0
  469. package/dist/core/wiring-manifest.js +14 -5
  470. package/dist/core/workflow-journal-store.d.ts +62 -0
  471. package/dist/core/workflow-journal-store.js +78 -2
  472. package/dist/core/workflow-run-store.d.ts +6 -0
  473. package/dist/core/workflow-run-store.js +2 -0
  474. package/dist/engine/compaction/compaction.d.ts +9 -9
  475. package/dist/engine/compaction/compaction.js +3 -2
  476. package/dist/engine/execution-env/node-execution-env.d.ts +26 -8
  477. package/dist/engine/execution-env/node-execution-env.js +54 -24
  478. package/dist/engine/harness/agent-harness.d.ts +39 -9
  479. package/dist/engine/harness/agent-harness.js +87 -33
  480. package/dist/engine/harness/types.d.ts +58 -9
  481. package/dist/engine/harness/types.js +12 -1
  482. package/dist/engine/llm/types.d.ts +36 -19
  483. package/dist/engine/llm/validation.d.ts +4 -1
  484. package/dist/engine/llm/validation.js +13 -1
  485. package/dist/engine/loop/agent-loop.d.ts +23 -1
  486. package/dist/engine/loop/agent-loop.js +26 -34
  487. package/dist/engine/loop/types.d.ts +31 -19
  488. package/dist/engine/lsp/node-lsp-manager.d.ts +2 -2
  489. package/dist/engine/session/memory-repo.d.ts +18 -12
  490. package/dist/engine/session/memory-repo.js +24 -9
  491. package/dist/engine/session/parent-chain-guard.d.ts +3 -2
  492. package/dist/engine/session/parent-chain-guard.js +1 -1
  493. package/dist/engine/session/repo-utils.d.ts +32 -3
  494. package/dist/engine/session/repo-utils.js +50 -5
  495. package/dist/index.d.ts +47 -23
  496. package/dist/index.js +35 -17
  497. package/dist/internal/harness-types.d.ts +1 -1
  498. package/dist/internal/harness.d.ts +3 -3
  499. package/dist/internal/harness.js +2 -2
  500. package/dist/internal/llm.d.ts +2 -2
  501. package/dist/internal/llm.js +1 -1
  502. package/dist/orchestration/goal.js +2 -2
  503. package/dist/orchestration/run-workflow-tool.d.ts +8 -6
  504. package/dist/orchestration/run-workflow-tool.js +10 -6
  505. package/dist/orchestration/workflow-size-guideline.d.ts +4 -4
  506. package/dist/orchestration/workflow-types.d.ts +18 -0
  507. package/dist/orchestration/workflow-types.js +6 -0
  508. package/dist/orchestration/workflow.d.ts +5 -13
  509. package/dist/orchestration/workflow.js +57 -49
  510. package/dist/prompt-assembly/artifact.d.ts +2 -2
  511. package/dist/prompt-assembly/artifact.js +5 -3
  512. package/dist/prompt-assembly/assemble.d.ts +3 -2
  513. package/dist/prompt-assembly/assemble.js +1 -1
  514. package/dist/prompt-assembly/catalog/schema.d.ts +43 -12
  515. package/dist/prompt-assembly/catalog/schema.js +34 -2
  516. package/dist/prompt-assembly/catalog/sections.js +0 -1
  517. package/dist/prompt-assembly/composer.d.ts +3 -1
  518. package/dist/prompt-assembly/composer.js +1 -1
  519. package/dist/prompt-assembly/event-registry.js +2 -0
  520. package/dist/prompt-assembly/overlay.js +3 -3
  521. package/dist/prompt-assembly/renderers.d.ts +1 -1
  522. package/dist/prompt-assembly/renderers.js +0 -3
  523. package/dist/prompt-assembly/role-base.d.ts +15 -0
  524. package/dist/prompt-assembly/role-base.js +9 -0
  525. package/dist/prompt-assembly/select.d.ts +39 -14
  526. package/dist/prompt-assembly/select.js +47 -16
  527. package/dist/prompt-assembly/sugar.d.ts +17 -11
  528. package/dist/prompt-assembly/sugar.js +8 -3
  529. package/dist/prompt-assembly/tool-catalog.d.ts +39 -2
  530. package/dist/prompt-assembly/tool-catalog.js +117 -4
  531. package/dist/prompt-assembly/turn-snapshot.d.ts +4 -10
  532. package/dist/prompt-assembly/turn-snapshot.js +0 -3
  533. package/dist/prompt-assembly/types.d.ts +0 -7
  534. package/dist/prompts/default.d.ts +14 -14
  535. package/dist/scenarios/full-body.d.ts +15 -15
  536. package/dist/scenarios/full-body.js +4 -3
  537. package/dist/shell/lex.js +10 -1
  538. package/dist/stores/file/adoption/adopt.d.ts +4 -3
  539. package/dist/stores/file/adoption/adopt.js +27 -33
  540. package/dist/stores/file/adoption/marker.d.ts +6 -13
  541. package/dist/stores/file/adoption/marker.js +9 -17
  542. package/dist/stores/file/checkpoint-store.d.ts +24 -0
  543. package/dist/stores/file/checkpoint-store.js +45 -7
  544. package/dist/stores/file/file-history-store.d.ts +20 -19
  545. package/dist/stores/file/file-history-store.js +157 -141
  546. package/dist/stores/file/fs-atomic.d.ts +15 -0
  547. package/dist/stores/file/fs-atomic.js +89 -14
  548. package/dist/stores/file/index.d.ts +1 -1
  549. package/dist/stores/file/index.js +2 -1
  550. package/dist/stores/file/mailbox-store.d.ts +3 -0
  551. package/dist/stores/file/mailbox-store.js +3 -1
  552. package/dist/stores/file/permission-rule-adopt.d.ts +1 -1
  553. package/dist/stores/file/permission-rule-adopt.js +18 -18
  554. package/dist/stores/file/permission-rule-store.d.ts +18 -2
  555. package/dist/stores/file/permission-rule-store.js +31 -18
  556. package/dist/stores/file/session-policy-store.d.ts +3 -3
  557. package/dist/stores/file/session-store.d.ts +54 -16
  558. package/dist/stores/file/session-store.js +114 -85
  559. package/dist/stores/file/workflow-journal-store.d.ts +10 -4
  560. package/dist/stores/file/workflow-journal-store.js +28 -13
  561. package/dist/tools/artifact/artifact-text.d.ts +1 -1
  562. package/dist/tools/artifact/artifact-tool.js +5 -3
  563. package/dist/tools/fs/bash-program-position.d.ts +19 -2
  564. package/dist/tools/fs/bash-program-position.js +56 -9
  565. package/dist/tools/fs/bash-readonly-classifier.d.ts +3 -3
  566. package/dist/tools/fs/fs-bash.d.ts +2 -2
  567. package/dist/tools/fs/fs-bash.js +8 -6
  568. package/dist/tools/fs/fs-glob.d.ts +86 -0
  569. package/dist/tools/fs/fs-glob.js +226 -0
  570. package/dist/tools/fs/fs-read.js +14 -14
  571. package/dist/tools/fs/fs-search-tools.js +7 -7
  572. package/dist/tools/fs/fs-shared.d.ts +8 -8
  573. package/dist/tools/fs/gh-rate-limit.d.ts +1 -1
  574. package/dist/tools/fs/notebook.d.ts +2 -2
  575. package/dist/tools/fs/pattern-kill-guard.d.ts +22 -0
  576. package/dist/tools/fs/pattern-kill-guard.js +397 -0
  577. package/dist/tools/fs/pdf.d.ts +9 -6
  578. package/dist/tools/fs/pdf.js +3 -3
  579. package/dist/tools/fs/program-read-model.d.ts +57 -7
  580. package/dist/tools/fs/program-read-model.js +11 -1
  581. package/dist/tools/fs/program-read-model.rows.js +78 -21
  582. package/dist/tools/fs/read-deny-home.js +3 -2
  583. package/dist/tools/fs/read-deny.d.ts +29 -7
  584. package/dist/tools/fs/read-deny.js +63 -22
  585. package/dist/tools/fs/removal-targets.d.ts +18 -8
  586. package/dist/tools/fs/removal-targets.js +47 -20
  587. package/dist/tools/fs/safety.d.ts +9 -9
  588. package/dist/tools/fs/search.d.ts +16 -6
  589. package/dist/tools/fs/search.js +20 -26
  590. package/dist/tools/fs/shell-read-argv.js +89 -12
  591. package/dist/tools/fs/shell-read-bindings.d.ts +31 -0
  592. package/dist/tools/fs/shell-read-bindings.js +41 -0
  593. package/dist/tools/fs/shell-read-check.js +12 -20
  594. package/dist/tools/fs/shell-read-environment.d.ts +5 -1
  595. package/dist/tools/fs/shell-read-environment.js +3 -2
  596. package/dist/tools/fs/shell-read-establish.d.ts +15 -0
  597. package/dist/tools/fs/shell-read-establish.js +19 -20
  598. package/dist/tools/fs/shell-read-judge.d.ts +4 -0
  599. package/dist/tools/fs/shell-read-judge.js +5 -2
  600. package/dist/tools/fs/shell-read-plan.js +24 -16
  601. package/dist/tools/fs/shell-read-start.d.ts +6 -1
  602. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -1
  603. package/dist/tools/fs/shell-read-write-targets.js +2 -3
  604. package/dist/tools/fs/shell-reentry-text.d.ts +9 -0
  605. package/dist/tools/fs/shell-reentry-text.js +40 -2
  606. package/dist/tools/loop-tick.d.ts +2 -2
  607. package/dist/tools/scheduler-tools.js +5 -1
  608. package/dist/tools/task-list.d.ts +7 -7
  609. package/dist/tools/task-list.js +5 -1
  610. package/dist/tools/todo.js +65 -64
  611. package/dist/tools/web.d.ts +20 -15
  612. package/dist/tools/web.js +55 -69
  613. package/dist/tools/worktree.d.ts +3 -3
  614. package/dist/tools/worktree.js +3 -1
  615. package/package.json +1 -1
  616. package/test/export-surface.snapshot.json +5894 -5638
  617. package/wire-changes/core@7.55.0.json +3318 -0
  618. package/wire-changes/core@7.56.0.json +3891 -0
  619. package/wire-changes/mods-kernel@7.56.0.json +303 -0
  620. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +0 -39
  621. package/dist/core/store-contracts/session-store-incarnation-contract.js +0 -95
@@ -25,14 +25,14 @@ export declare const MAX_READ_BYTES: number;
25
25
  * explicit slice, with guidance to stream a portion via bash (`sed -n` / `head -c`) instead, which
26
26
  * never loads the whole file. */
27
27
  export declare const SLICED_READ_MAX_BYTES: number;
28
- /** The byte cap Edit refuses ABOVE (CC's own constant, verbatim). CC stats the target before touching
28
+ /** The byte cap Edit refuses ABOVE. CC stats the target before touching
29
29
  * it and refuses with a formatted-size message when it exceeds this. Without the gate, Edit goes
30
30
  * straight to a whole-file `readBinaryFile` (twice: the `old_string:""` full-overwrite branch and the
31
31
  * normal find/replace branch), so a multi-GB target is an unguarded OOM lever an ordinary Edit call
32
32
  * can pull. The shape is Read's: a pre-read `env.fileInfo` stat plus a post-read TOCTOU recheck
33
33
  * ({@link SLICED_READ_MAX_BYTES} above). */
34
34
  export declare const MAX_EDIT_BYTES: number;
35
- /** `Edit`'s human-readable byte-count formatter (CC `pl()` verbatim: bytes below 1KB, else
35
+ /** `Edit`'s human-readable byte-count formatter (bytes below 1KB, else
36
36
  * KB/MB/GB with one decimal, trailing ".0" stripped). */
37
37
  export declare function formatByteSize(n: number): string;
38
38
  /** Node's own string-length ceiling (`buffer.constants.MAX_STRING_LENGTH` — ~512MiB on V8/Node 24)
@@ -103,7 +103,7 @@ export interface RecordedEdit {
103
103
  export declare function applyRecordedEdit(text: string, edit: RecordedEdit): string;
104
104
  /** Render the read-before-edit refusal, appending the slice/bash escape hatch when the target is over
105
105
  * the Read byte cap — a bare "read it first" is un-followable there (a default whole-file Read
106
- * refuses such files). Best-effort: an un-stattable file keeps the bare CC-verbatim refusal.
106
+ * refuses such files). Best-effort: an un-stattable file keeps the bare refusal.
107
107
  *
108
108
  * `fallbackHint` is a caller-supplied parenthetical for the case NO branch below diagnosed anything
109
109
  * (all three writing tools pass {@link READ_REFUSED_ESCAPE_HINT} — the Read-refuses-this-file
@@ -332,7 +332,7 @@ export declare function createShellOverflowSpoolFence(env: ExecutionEnv): (path:
332
332
  * executable. Full `bash` keeps the precise form.
333
333
  */
334
334
  export declare function shellRecoveryHint(path: string, readOnly: boolean | undefined): string;
335
- /** CC 2.1.198 live-verbatim Edit/Write success trailer — appended to every Edit/Write success message
335
+ /** Edit/Write success trailer — appended to every Edit/Write success message
336
336
  * (NOT NotebookEdit — CC ships it without the trailer). */
337
337
  export declare const FILE_STATE_TRAILER = " (file state is current in your context \u2014 no need to Read it back)";
338
338
  export declare const CWD_SENTINEL = "__cc_cwd_9f2c1b__";
@@ -383,11 +383,11 @@ export declare function ipynbRedirect(toolName: string, path: string): string |
383
383
  * ends in "\n". Behavior is identical for content WITHOUT a trailing newline. Shared by read_file's
384
384
  * `total`, edit_file/write_file's "N lines" report, and the persisted ReadFileState.totalLines. */
385
385
  export declare function countLines(s: string): number;
386
- /** CC 2.1.204 VERBATIM: the reminder served when a DEFAULT whole-file Read hits a startup-seeded,
386
+ /** The reminder served when a DEFAULT whole-file Read hits a startup-seeded,
387
387
  * unchanged file. `filePath` is the CANONICAL key (CC passes the resolved full path, matching the
388
388
  * `Contents of <path>` header its context seeding emits — deployments seeding files should title the
389
389
  * injected block the same way so the back-reference lands). Locked verbatim by test: the BODY and
390
- * close tag stay CC-verbatim; the open tag alone is rendered by the mint home and carries the session
390
+ * close tag stay fixed; the open tag alone is rendered by the mint home and carries the session
391
391
  * mark when one is threaded (the recorded wire-form divergence). */
392
392
  export declare function seededFileUnchangedReminder(filePath: string, mark?: string): string;
393
393
  /**
@@ -404,7 +404,7 @@ export declare function seededFileUnchangedReminder(filePath: string, mark?: str
404
404
  */
405
405
  export declare function isReadDedupStubResult(resultText: string): boolean;
406
406
  /** Pre-seed the hands' read state for a file whose FULL, disk-verbatim text was injected into the
407
- * model's context at startup (CC 2.1.204 `seededFromContext` seeding of the memory preload; sema:
407
+ * model's context at startup (`seededFromContext` seeding of the memory preload; sema:
408
408
  * ProjectMemoryLoad.seededFiles → prepare-task).
409
409
  * `content` MUST be the file's exact disk text at load time — the Read tool's seeded dedup treats a
410
410
  * hash match as "unchanged"; a truncated/annotated variant must NOT be seeded (CC exempts those via
@@ -505,7 +505,7 @@ export type ReadFileStateShrink =
505
505
  transmissions: ReadonlyArray<string>;
506
506
  };
507
507
  export declare function applyContextShrinkToReadFileState(state: ReadFileState, shrink: ReadFileStateShrink): void;
508
- /** CC 2.1.198 verbatim skeleton: the ENOENT error body for a
508
+ /** The ENOENT error body for a
509
509
  * missing Read/Edit target — `File does not exist. Note: your current working directory is <cwd>.`
510
510
  * plus a `Did you mean <sibling>?` correction when the parent directory holds a near-name (case
511
511
  * variant / same stem different extension — the high-frequency self-heal path). Best-effort: a
@@ -1,5 +1,5 @@
1
1
  /**
2
- * gh rate-limit hint (CC 2.1.198 parity).
2
+ * gh rate-limit hint.
3
3
  *
4
4
  * CC appends a one-shot <system-reminder> to a FOREGROUND Bash result when a `gh` invocation hits the
5
5
  * GitHub API rate limit, so the model sleeps/schedules instead of hammering retries. The command gate,
@@ -1,6 +1,6 @@
1
1
  import type { ImageContent } from "../../internal/llm.js";
2
2
  /**
3
- * The Read tool's Jupyter-notebook projection: `.ipynb` is rendered as cells with outputs (CC 2.1.220
3
+ * The Read tool's Jupyter-notebook projection: `.ipynb` is rendered as cells with outputs (reference
4
4
  * parity), never as raw JSON text. Raw-JSON rendering lets a notebook's base64 outputs overflow the
5
5
  * Read token cap, auto-paginate into an `isPartialView` entry, and thereby lock NotebookEdit out via
6
6
  * the requireRead gate — with the marker's own offset/limit hint pointing at a range that itself
@@ -80,7 +80,7 @@ export interface NotebookRender {
80
80
  imageChars: number;
81
81
  }
82
82
  /**
83
- * CC `eI_`/`tI_`/`Atd`: render projected cells to content blocks. Tag shape is CC-verbatim, including
83
+ * Render projected cells to content blocks. Tag shape is the reference's, including
84
84
  * the deliberately malformed closing tag `</cell id="X">`; `<cell_type>` only when not code,
85
85
  * `<language>` only for code cells whose language !== "python". Output text rides with a leading "\n"
86
86
  * and adjacent text blocks merge with "\n", so an all-text notebook collapses to a single text block.
@@ -0,0 +1,22 @@
1
+ import type { ExecutionEnv } from "../../internal/harness.js";
2
+ /** One killer the command spells and the questions to put to `pgrep` for it, or why the question cannot be put. */
3
+ export interface PatternKillReading {
4
+ readonly text: string;
5
+ readonly probes: readonly (readonly string[])[];
6
+ /** Set when a word of the selector is decided only when the command runs. */
7
+ readonly computed?: string;
8
+ /** Set when the kill names every process the caller may signal — this agent's own among them — so there is nothing to ask. */
9
+ readonly everyProcess?: true;
10
+ }
11
+ /** The killers a command text spells, read off the plan the read station plans (nothing is read from disk or run). */
12
+ export declare function patternKillReadings(command: string, cwd: string): PatternKillReading[];
13
+ /**
14
+ * The refusal for a command whose pattern-kill would select this agent's own process or one above it — or undefined (run it).
15
+ * `cwd`: where the command stands, for the plan's read of its words (nothing is read from disk). Remote environments and
16
+ * Windows are not asked: their process table is not this one.
17
+ */
18
+ export declare function patternKillRefusal(command: string, env: ExecutionEnv, cwd: string, signal?: AbortSignal): Promise<{
19
+ content: string;
20
+ isError: true;
21
+ details?: unknown;
22
+ } | undefined>;
@@ -0,0 +1,397 @@
1
+ import { spawn } from "node:child_process";
2
+ import { readFile } from "node:fs/promises";
3
+ import { errorResult } from "../../core/tools.js";
4
+ import { isRemoteExecutionEnv } from "../../core/remote-env.js";
5
+ import { inheritedHostEnv } from "../../core/secret-env.js";
6
+ import { inlineUntrusted } from "../../core/untrusted-text.js";
7
+ import { planShellReads } from "./shell-read-plan.js";
8
+ import { programArgs } from "./shell-read-write-targets.js";
9
+ const PROBE_TIMEOUT_MS = 5_000;
10
+ const ANCESTOR_HOPS_MAX = 128;
11
+ const SHELL_PID_WORD = /^\$(?:\$|\{\$\}|BASHPID|\{BASHPID\})$/;
12
+ const NAME_SELECTION_KEEPS_ANCESTORS = process.platform === "linux" ? [] : ["-a"];
13
+ const SIGNAL_ONLY_FIRST_ARGUMENT = process.platform !== "linux";
14
+ const HANDLER_SELECTS_BY_SIGNAL = process.platform === "linux";
15
+ const LONG_OPTIONS = new Map([
16
+ ["signal", "signal"], ["ignore-ancestors", "A"], ["require-handler", "H"], ["count", "c"], ["cgroup", "cgroup"], ["delimiter", "d"], ["list-name", "l"],
17
+ ["list-full", "a"], ["full", "f"], ["pgroup", "g"], ["group", "G"], ["ignore-case", "i"], ["newest", "n"], ["oldest", "o"], ["older", "O"], ["parent", "P"],
18
+ ["session", "s"], ["terminal", "t"], ["euid", "u"], ["uid", "U"], ["inverse", "v"], ["lightweight", "w"], ["exact", "x"], ["pidfile", "F"], ["logpidfile", "L"],
19
+ ["echo", "e"], ["ns", "ns"], ["nslist", "nslist"], ["queue", "q"], ["runstates", "r"], ["help", "h"], ["version", "V"],
20
+ ]);
21
+ function longKeyOf(name) {
22
+ if (!name.startsWith("--") || name.length < 3)
23
+ return undefined;
24
+ const word = name.slice(2);
25
+ const exact = LONG_OPTIONS.get(word);
26
+ if (exact !== undefined)
27
+ return exact;
28
+ const named = [...LONG_OPTIONS].filter(([o]) => o.startsWith(word));
29
+ return named.length === 1 ? named[0][1] : undefined;
30
+ }
31
+ const QUEUE_PAYLOAD = process.platform === "linux";
32
+ const VALUED_LETTERS = new Set(["F", "g", "G", "P", "s", "t", "u", "U", "N", "T", "O", "d", "r", ...(QUEUE_PAYLOAD ? ["q"] : [])]);
33
+ const VALUED_LONG_ONLY = new Set(["signal", "cgroup", "ns", "nslist"]);
34
+ const OUTPUT_LETTERS = new Set(["c", "e", "d", ...(QUEUE_PAYLOAD ? ["q"] : [])]);
35
+ const takesValueKey = (key) => VALUED_LETTERS.has(key) || VALUED_LONG_ONLY.has(key);
36
+ const fateOfKey = (key) => (key === "signal" ? "signal" : OUTPUT_LETTERS.has(key) ? "drop" : "ask");
37
+ function bundledLetters(w, valued = VALUED_LETTERS) {
38
+ if (!/^-[A-Za-z]/.test(w))
39
+ return undefined;
40
+ const letters = [];
41
+ for (const ch of w.slice(1)) {
42
+ letters.push(ch);
43
+ if (valued.has(ch))
44
+ break;
45
+ }
46
+ return letters;
47
+ }
48
+ const SIGNAL_NAMES = new Set([
49
+ "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "IOT", "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", "CONT",
50
+ "CHLD", "CLD", "TTIN", "TTOU", "IO", "POLL", "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1", "USR2", "STKFLT", "PWR", "LOST", "UNUSED", "THR", "LIBRT",
51
+ ]);
52
+ const SIGNAL_WORD = /^-(?:\d+|(?:SIG)?(?:RT(?:MIN|MAX)(?:[+-]\d+)?|([A-Z][A-Z0-9]*)))$/i;
53
+ const isSignalWord = (w) => {
54
+ const m = SIGNAL_WORD.exec(w);
55
+ return m !== null && (m[1] === undefined || SIGNAL_NAMES.has(m[1].toUpperCase()));
56
+ };
57
+ function selectorWords(allWords, killer) {
58
+ const signalAt = killer !== "pkill" ? -1 : SIGNAL_ONLY_FIRST_ARGUMENT ? (isSignalWord(allWords[0] ?? "") ? 0 : -1) : allWords.findIndex(isSignalWord);
59
+ const signalWord = signalAt < 0 ? undefined : allWords[signalAt].slice(1);
60
+ const words = signalAt < 0 ? allWords : allWords.filter((_, i) => i !== signalAt);
61
+ const out = [];
62
+ let ended = false;
63
+ let requireHandler = false;
64
+ let signalOption;
65
+ let valueOf;
66
+ for (const w of words) {
67
+ if (valueOf !== undefined) {
68
+ if (valueOf === "ask")
69
+ out.push(w);
70
+ else if (valueOf === "signal")
71
+ signalOption = w;
72
+ valueOf = undefined;
73
+ continue;
74
+ }
75
+ if (ended || w === "--") {
76
+ ended ||= w === "--";
77
+ out.push(w);
78
+ continue;
79
+ }
80
+ const [, longName, longValue] = /^(--[^=]*)(?:=(.*))?$/s.exec(w) ?? [];
81
+ const key = longName === undefined ? undefined : longKeyOf(longName);
82
+ if (key !== undefined && (takesValueKey(key) || longValue === undefined)) {
83
+ if (key === "H")
84
+ requireHandler = true;
85
+ const fate = fateOfKey(key);
86
+ if (fate === "ask")
87
+ out.push(w);
88
+ if (takesValueKey(key) && longValue === undefined)
89
+ valueOf = fate;
90
+ else if (fate === "signal" && longValue !== undefined)
91
+ signalOption = longValue;
92
+ continue;
93
+ }
94
+ const letters = bundledLetters(w);
95
+ if (letters === undefined) {
96
+ out.push(w);
97
+ continue;
98
+ }
99
+ if (letters.includes("H"))
100
+ requireHandler = true;
101
+ const last = letters[letters.length - 1];
102
+ const fate = fateOfKey(last);
103
+ const kept = letters.filter((ch) => fateOfKey(ch) === "ask").join("");
104
+ const attached = VALUED_LETTERS.has(last) ? w.slice(1 + letters.length) : "";
105
+ if (kept !== "")
106
+ out.push(`-${kept}${fate === "ask" ? attached : ""}`);
107
+ if (VALUED_LETTERS.has(last) && attached === "")
108
+ valueOf = fate;
109
+ }
110
+ const signal = signalOption ?? signalWord;
111
+ return HANDLER_SELECTS_BY_SIGNAL && requireHandler && signal !== undefined ? ["--signal", signal, ...out] : out;
112
+ }
113
+ const negatesSelection = (words) => words.some((w) => w === "--inverse" || (bundledLetters(w)?.includes("v") ?? false));
114
+ function selectsOnlyShellChildren(words) {
115
+ return words.some((w, i) => {
116
+ if (w === "-P" || w === "--parent")
117
+ return SHELL_PID_WORD.test(words[i + 1] ?? "");
118
+ const attached = /^(?:-P|--parent=)(.+)$/.exec(w);
119
+ return attached !== null && SHELL_PID_WORD.test(attached[1]);
120
+ });
121
+ }
122
+ const literalName = (name) => name.replace(/[\\.[\]{}()*+?^$|]/g, "\\$&");
123
+ function wordsOf(segment) {
124
+ const args = programArgs(segment);
125
+ const rewritten = args.find((a) => a.rewritten === true);
126
+ const computed = segment.reentry === "argv" ? "its arguments arrive on a stream" : rewritten === undefined ? undefined : `\`${inlineUntrusted(rewritten.raw, 60)}\` is expanded by the shell when the command runs`;
127
+ return { words: args.map((a) => a.spelled), ...(computed !== undefined ? { computed } : {}) };
128
+ }
129
+ const shown = (segment) => inlineUntrusted(segment.text, 200);
130
+ function readPkill(segment) {
131
+ const { words, computed } = wordsOf(segment);
132
+ if (selectsOnlyShellChildren(words)) {
133
+ return negatesSelection(words) ? { text: shown(segment), probes: [], computed: "`-v` negates the selection, so `-P` of the shell's pid no longer limits it to the shell's children" } : undefined;
134
+ }
135
+ if (computed !== undefined)
136
+ return { text: shown(segment), probes: [], computed };
137
+ const selectors = selectorWords(words, "pkill");
138
+ return selectors.length === 0 ? undefined : { text: shown(segment), probes: [selectors] };
139
+ }
140
+ const OPT_FLAG = { does: "flag" };
141
+ const OPT_FILTER = { does: "filter" };
142
+ const OPT_VALUED = { does: "valued" };
143
+ const OPT_CONTEXT = { does: "context" };
144
+ const OPT_REGEX = { does: "regex" };
145
+ const OPT_GROUP = { does: "group" };
146
+ const OPT_USER = { does: "select", pgrep: "-u" };
147
+ const OPT_TTY = { does: "select", pgrep: "-t" };
148
+ const KILLALL_OPTIONS = new Map([
149
+ ["-u", OPT_USER], ["--user", OPT_USER], ["-t", OPT_TTY],
150
+ ["-Z", OPT_CONTEXT], ["--context", OPT_CONTEXT],
151
+ ["-r", OPT_REGEX], ["-m", OPT_REGEX], ["--regexp", OPT_REGEX],
152
+ ["-I", { does: "ignoreCase" }], ["--ignore-case", { does: "ignoreCase" }],
153
+ ["-g", OPT_GROUP], ["--process-group", OPT_GROUP],
154
+ ["-s", OPT_VALUED], ["--signal", OPT_VALUED], ["-o", OPT_VALUED], ["--older-than", OPT_VALUED], ["-y", OPT_VALUED], ["--younger-than", OPT_VALUED],
155
+ ["-n", OPT_VALUED], ["--ns", OPT_VALUED], ["-c", OPT_FILTER],
156
+ ["-e", OPT_FLAG], ["--exact", OPT_FLAG], ["-i", OPT_FLAG], ["--interactive", OPT_FLAG], ["-l", OPT_FLAG], ["--list", OPT_FLAG], ["-q", OPT_FLAG], ["--quiet", OPT_FLAG],
157
+ ["-v", OPT_FLAG], ["--verbose", OPT_FLAG], ["-V", OPT_FLAG], ["--version", OPT_FLAG], ["-w", OPT_FLAG], ["--wait", OPT_FLAG], ["-d", OPT_FLAG], ["-z", OPT_FLAG], ["--help", OPT_FLAG],
158
+ ]);
159
+ const takesValue = (opt) => opt !== undefined && (opt.does === "select" || opt.does === "context" || opt.does === "filter" || opt.does === "valued");
160
+ const OPTIONS_END_AT_FIRST_NAME = process.platform !== "linux";
161
+ const KILLALL_VALUED_LETTERS = new Set([...KILLALL_OPTIONS].filter(([spelling, opt]) => !spelling.startsWith("--") && takesValue(opt)).map(([spelling]) => spelling.slice(1)));
162
+ function optionsOf(w) {
163
+ if (w.startsWith("--")) {
164
+ const eq = w.indexOf("=");
165
+ return [eq < 0 ? { opt: w } : { opt: w.slice(0, eq), attached: w.slice(eq + 1) }];
166
+ }
167
+ const letters = bundledLetters(w, KILLALL_VALUED_LETTERS);
168
+ if (letters === undefined)
169
+ return [{ opt: w }];
170
+ const rest = w.slice(1 + letters.length);
171
+ return letters.map((ch, i) => ({ opt: `-${ch}`, ...(i === letters.length - 1 && rest !== "" ? { attached: rest } : {}) }));
172
+ }
173
+ function readKillallWords(words) {
174
+ const names = [];
175
+ const selecting = new Map();
176
+ let filter;
177
+ let byContext = false;
178
+ let regex = false;
179
+ let ignoreCase = false;
180
+ for (let i = 0; i < words.length; i++) {
181
+ const w = words[i];
182
+ if (w === "--") {
183
+ names.push(...words.slice(i + 1));
184
+ break;
185
+ }
186
+ if (!w.startsWith("-") || w === "-") {
187
+ names.push(w);
188
+ if (OPTIONS_END_AT_FIRST_NAME) {
189
+ names.push(...words.slice(i + 1));
190
+ break;
191
+ }
192
+ continue;
193
+ }
194
+ if (isSignalWord(w))
195
+ continue;
196
+ for (const { opt: spelling, attached } of optionsOf(w)) {
197
+ const opt = KILLALL_OPTIONS.get(spelling);
198
+ if (opt === undefined || (attached !== undefined && !takesValue(opt)))
199
+ return { unreadable: `\`${inlineUntrusted(w, 60)}\` is not a form of a \`killall\` option this check reads` };
200
+ if (opt.does === "group")
201
+ return { unreadable: "`-g` signals the whole process group of each match, a set this check cannot list" };
202
+ const value = takesValue(opt) ? (attached ?? words[++i]) : undefined;
203
+ if (opt.does === "select" && value !== undefined)
204
+ selecting.set(opt.pgrep, value);
205
+ else if (opt.does === "filter" && value !== undefined)
206
+ filter = value;
207
+ else if (opt.does === "context")
208
+ byContext = true;
209
+ else if (opt.does === "regex")
210
+ regex = true;
211
+ else if (opt.does === "ignoreCase")
212
+ ignoreCase = true;
213
+ }
214
+ }
215
+ if (filter !== undefined && !names.includes(filter))
216
+ names.push(filter);
217
+ if (byContext && names.length === 0 && selecting.size === 0)
218
+ return { unreadable: "`-Z` selects by security context, a set this check cannot ask `pgrep` for" };
219
+ return { names, selecting: [...selecting].flat(), regex, ignoreCase };
220
+ }
221
+ function readKillall(segment) {
222
+ const read = wordsOf(segment);
223
+ if (read.computed !== undefined)
224
+ return { text: shown(segment), probes: [], computed: read.computed };
225
+ const sel = readKillallWords(read.words);
226
+ if ("unreadable" in sel)
227
+ return { text: shown(segment), probes: [], computed: sel.unreadable };
228
+ const narrow = sel.ignoreCase ? ["-i"] : [];
229
+ const pattern = (n) => [...(n.startsWith("-") ? ["--"] : []), sel.regex ? n : literalName(n)];
230
+ const probes = sel.names.length > 0 ? sel.names.map((n) => [...NAME_SELECTION_KEEPS_ANCESTORS, ...(sel.regex ? [] : ["-x"]), ...narrow, ...sel.selecting, ...pattern(n)]) : sel.selecting.length === 0 ? [] : [[...NAME_SELECTION_KEEPS_ANCESTORS, ...sel.selecting]];
231
+ return { text: shown(segment), probes };
232
+ }
233
+ function readSelector(segment) {
234
+ const read = wordsOf(segment);
235
+ if (read.computed !== undefined)
236
+ return { text: shown(segment), probes: [], computed: read.computed };
237
+ if (segment.verb?.basename === "pidof") {
238
+ const names = read.words.filter((w, i) => !w.startsWith("-") && read.words[i - 1] !== "-o");
239
+ return { text: shown(segment), probes: names.map((n) => [...NAME_SELECTION_KEEPS_ANCESTORS, "-x", literalName(n)]) };
240
+ }
241
+ return { text: shown(segment), probes: [selectorWords(read.words, "pgrep")] };
242
+ }
243
+ const SELECTORS = new Set(["pgrep", "pidof"]);
244
+ const EVERY_PROCESS_PID = /^-0*1$/;
245
+ function readKill(segment) {
246
+ const { words } = wordsOf(segment);
247
+ const slot = words[0] === "-s" || words[0] === "-n" ? 2 : words[0]?.startsWith("-") === true && words[0] !== "--" ? 1 : 0;
248
+ const rest = words.slice(slot);
249
+ const pids = rest[0] === "--" ? rest.slice(1) : rest;
250
+ return pids.some((w) => EVERY_PROCESS_PID.test(w)) ? { text: shown(segment), probes: [], everyProcess: true } : undefined;
251
+ }
252
+ const isFedKill = (s) => s.verb?.basename === "kill" && (s.reentry === "argv" || programArgs(s).some((a) => a.rewritten === true));
253
+ const feedsKill = (plan) => plan.segments.some((s) => isFedKill(s) || s.nested.some(feedsKill));
254
+ function selectorsIn(plan) {
255
+ return plan.segments.flatMap((s) => [...(SELECTORS.has(s.verb?.basename ?? "") ? [s] : []), ...s.nested.flatMap(selectorsIn)]);
256
+ }
257
+ function readingsOf(plan, seen = new Set()) {
258
+ const out = [];
259
+ const take = (s, read) => {
260
+ if (seen.has(s))
261
+ return;
262
+ seen.add(s);
263
+ const r = read();
264
+ if (r !== undefined)
265
+ out.push(r);
266
+ };
267
+ for (const s of plan.segments) {
268
+ const program = s.verb?.basename;
269
+ if (program === "pkill")
270
+ take(s, () => readPkill(s));
271
+ else if (program === "killall")
272
+ take(s, () => readKillall(s));
273
+ else if (program === "kill")
274
+ take(s, () => readKill(s));
275
+ for (const n of s.nested)
276
+ out.push(...readingsOf(n, seen));
277
+ }
278
+ if (feedsKill(plan))
279
+ for (const s of selectorsIn(plan))
280
+ take(s, () => readSelector(s));
281
+ return out;
282
+ }
283
+ export function patternKillReadings(command, cwd) {
284
+ return readingsOf(planShellReads(command, { readers: new Set(), cwd, roots: [cwd], cdPath: "unknown" }));
285
+ }
286
+ function runProbe(program, args, signal) {
287
+ return new Promise((resolve) => {
288
+ let stdout = "";
289
+ let stderr = "";
290
+ let settled = false;
291
+ const settle = (r) => {
292
+ if (settled)
293
+ return;
294
+ settled = true;
295
+ clearTimeout(timer);
296
+ signal?.removeEventListener("abort", onAbort);
297
+ resolve(r);
298
+ };
299
+ const child = spawn(program, [...args], { env: inheritedHostEnv("scrub"), stdio: ["ignore", "pipe", "pipe"], windowsHide: true });
300
+ const stop = (why) => {
301
+ child.kill("SIGKILL");
302
+ settle({ ok: false, why });
303
+ };
304
+ const timer = setTimeout(() => stop(`${program} did not answer within ${PROBE_TIMEOUT_MS / 1000}s`), PROBE_TIMEOUT_MS);
305
+ const onAbort = () => stop("the call was cancelled");
306
+ signal?.addEventListener("abort", onAbort, { once: true });
307
+ child.stdout.on("data", (c) => { stdout += c.toString("utf8"); });
308
+ child.stderr.on("data", (c) => { stderr += c.toString("utf8"); });
309
+ child.on("error", (e) => settle({ ok: false, why: e.code === "ENOENT" ? `${program} is not available here` : `${program} could not start (${e.code ?? e.message})` }));
310
+ child.on("close", (code) => settle(code === 0 || code === 1 ? { ok: true, stdout, code } : { ok: false, why: `${program} exited ${code ?? "by signal"}${stderr.trim() === "" ? "" : `: ${inlineUntrusted(stderr, 120)}`}` }));
311
+ });
312
+ }
313
+ async function selected(args, signal) {
314
+ const run = await runProbe("pgrep", args, signal);
315
+ if (!run.ok)
316
+ return { why: run.why };
317
+ return { pids: run.code === 1 ? [] : run.stdout.split("\n").flatMap((line) => { const m = /^\s*(\d+)\b/.exec(line); return m === null ? [] : [Number(m[1])]; }) };
318
+ }
319
+ async function selfAndAncestors(signal) {
320
+ const chain = [process.pid];
321
+ if (process.platform === "linux") {
322
+ for (let pid = process.pid; chain.length <= ANCESTOR_HOPS_MAX && pid > 1;) {
323
+ let stat;
324
+ try {
325
+ stat = await readFile(`/proc/${pid}/stat`, "utf8");
326
+ }
327
+ catch {
328
+ return tableAncestors(signal);
329
+ }
330
+ const parent = Number(stat.slice(stat.lastIndexOf(")") + 2).split(" ")[1]);
331
+ if (!(parent > 0) || parent === pid)
332
+ break;
333
+ chain.push(parent);
334
+ pid = parent;
335
+ }
336
+ return { pids: chain };
337
+ }
338
+ return tableAncestors(signal);
339
+ }
340
+ async function tableAncestors(signal) {
341
+ const run = await runProbe("ps", ["-A", "-o", "pid=", "-o", "ppid="], signal);
342
+ if (!run.ok)
343
+ return { why: run.why };
344
+ const parentOf = new Map();
345
+ for (const line of run.stdout.split("\n")) {
346
+ const m = /^\s*(\d+)\s+(\d+)\s*$/.exec(line);
347
+ if (m !== null)
348
+ parentOf.set(Number(m[1]), Number(m[2]));
349
+ }
350
+ const chain = [process.pid];
351
+ for (let pid = parentOf.get(process.pid); pid !== undefined && pid > 0 && !chain.includes(pid) && chain.length <= ANCESTOR_HOPS_MAX; pid = parentOf.get(pid))
352
+ chain.push(pid);
353
+ return chain.length > 1 ? { pids: chain } : { why: "this process's parent could not be read from the process table" };
354
+ }
355
+ const WAY_OUT = "or stop the process by its PID, or target your own children with `pkill -P $$ ...`";
356
+ const SENTENCE = {
357
+ hit: (f) => `Error (Bash): refusing to run \`${f.text}\` — its selection includes ${f.own ? "this agent's own process" : "a process above this agent (the shell or program that started it)"} (PID ${f.pid}), so running it would terminate the session that is running this command. Narrow the pattern (a word that is in your launcher's command line matches the launcher), ${WAY_OUT}.`,
358
+ computed: (f) => `Error (Bash): refusing to run \`${f.text}\` — which processes it selects is decided when the command runs (${f.why}), so it cannot first be checked against this agent's own process and the processes above it. Write the pattern into the command as a literal, ${WAY_OUT}.`,
359
+ unavailable: (f) => `Error (Bash): refusing to run \`${f.text}\` — the check that its selection holds neither this agent's own process nor a process above it could not run (${f.why}). Stop the process by its PID, or target your own children with \`pkill -P $$ ...\`.`,
360
+ };
361
+ export async function patternKillRefusal(command, env, cwd, signal) {
362
+ if (process.platform === "win32" || isRemoteExecutionEnv(env))
363
+ return undefined;
364
+ const readings = patternKillReadings(command, cwd);
365
+ if (readings.length === 0)
366
+ return undefined;
367
+ const found = [];
368
+ const asked = await Promise.all(readings.map(async (r) => ({ r, answers: await Promise.all(r.probes.map((p) => selected(p, signal))) })));
369
+ let ancestry;
370
+ for (const { r, answers } of asked) {
371
+ if (r.computed !== undefined)
372
+ found.push({ kind: "computed", text: r.text, why: r.computed });
373
+ if (r.everyProcess === true)
374
+ found.push({ kind: "hit", text: r.text, pid: process.pid, own: true });
375
+ for (const a of answers) {
376
+ if ("why" in a) {
377
+ found.push({ kind: "unavailable", text: r.text, why: a.why });
378
+ continue;
379
+ }
380
+ if (a.pids.length === 0)
381
+ continue;
382
+ ancestry ??= await selfAndAncestors(signal);
383
+ if ("why" in ancestry) {
384
+ found.push({ kind: "unavailable", text: r.text, why: ancestry.why });
385
+ continue;
386
+ }
387
+ const pid = ancestry.pids.find((p) => a.pids.includes(p));
388
+ if (pid !== undefined)
389
+ found.push({ kind: "hit", text: r.text, pid, own: pid === process.pid });
390
+ }
391
+ }
392
+ const f = found.find((x) => x.kind === "hit") ?? found.find((x) => x.kind === "computed") ?? found[0];
393
+ if (f === undefined || signal?.aborted === true)
394
+ return undefined;
395
+ const text = f.kind === "hit" ? SENTENCE.hit(f) : f.kind === "computed" ? SENTENCE.computed(f) : SENTENCE.unavailable(f);
396
+ return errorResult(inlineUntrusted(text, 1_200), { type: "bash_self_kill_refused", code: "bash_self_kill_refused", finding: f.kind, ...(f.kind === "hit" ? { pid: f.pid, relation: f.own ? "engine" : "ancestor" } : {}) });
397
+ }
@@ -54,19 +54,22 @@ export declare function getPdfPageCount(env: ExecutionEnv, absPath: string, byte
54
54
  export declare const PDF_FALLBACK_RENDER_PAGES = 5;
55
55
  /**
56
56
  * PDF capability profile of the SERVING model, consumed by the Read tool's degradation chain (v2):
57
- * - `document` — the brain path can forward a native `{type:"document"}` block (today: anthropic-messages
58
- * WITH vision — anthropic.ts drops document blocks for no-vision models — or an explicit `input`
59
- * declaration containing "document" for a future capability bit).
60
- * - `vision` — `Model.input` contains "image" (absent metadata fails open = today's behavior).
57
+ * - `document` — the brain path can forward a native `{type:"document"}` block: the anthropic-messages lane on a
58
+ * model that holds image input (anthropic.ts drops document blocks exactly when it withholds images).
59
+ * - `vision` — the model holds image input (`capabilityHeld`, the one capability reading; an undeclared `input`
60
+ * is held, as every request reads it).
61
61
  * Structural parameter (no deep Model import): `prepare-task` passes the task's resolved Model.
62
62
  */
63
63
  export interface PdfModelCapabilities {
64
64
  document: boolean;
65
65
  vision: boolean;
66
66
  }
67
- /** Derive {@link PdfModelCapabilities} from a Model-shaped object. `undefined` model = fully capable
68
- * (fail-open: no metadata ⇒ preserve the native document-block behavior, brain-level placeholder guards). */
67
+ /** Derive {@link PdfModelCapabilities} from a Model-shaped object. `undefined` model, or a value with neither `api` nor
68
+ * `input` = fully capable (fail-open: no metadata ⇒ preserve the native document-block behavior, brain-level placeholder
69
+ * guards) — the one reader that looks at the absence itself. A value with an `input` and no `api` is read by its declaration:
70
+ * `vision` follows the image capability and `document` is false (only the anthropic-messages lane forwards a document block). */
69
71
  export declare function pdfModelCapabilitiesOf(model?: {
72
+ id?: string;
70
73
  api?: string;
71
74
  input?: readonly string[];
72
75
  }): PdfModelCapabilities;
@@ -1,4 +1,5 @@
1
1
  import { isTimeCutCode } from "../../internal/harness.js";
2
+ import { capabilityHeld } from "../../brain/model-capability.js";
2
3
  export const PDF_MAX_PAGES_PER_READ = 20;
3
4
  export const PDF_INLINE_PAGE_THRESHOLD = 10;
4
5
  export const PDF_MAX_EXTRACT_SIZE = 100 * 1024 * 1024;
@@ -52,9 +53,8 @@ export const PDF_FALLBACK_RENDER_PAGES = 5;
52
53
  export function pdfModelCapabilitiesOf(model) {
53
54
  if (!model || (model.api === undefined && model.input === undefined))
54
55
  return { document: true, vision: true };
55
- const vision = model.input === undefined ? true : model.input.includes("image");
56
- const document = model.input?.includes("document") === true || (model.api === "anthropic-messages" && vision);
57
- return { document, vision };
56
+ const vision = capabilityHeld(model, "image");
57
+ return { document: model.api === "anthropic-messages" && vision, vision };
58
58
  }
59
59
  export const PDF_EXEC_TIMEOUT_SEC = 120;
60
60
  function cutOf(e) {