@sema-agent/core 7.47.0 → 7.49.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 (431) hide show
  1. package/CHANGELOG.md +472 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +39 -32
  51. package/dist/core/arg-summary.d.ts +17 -24
  52. package/dist/core/arg-summary.js +169 -68
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +95 -66
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +32 -7
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +4 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp-server-spec.d.ts +1 -1
  101. package/dist/core/mcp.d.ts +4 -0
  102. package/dist/core/mcp.js +70 -43
  103. package/dist/core/memory-engine/content-origin.js +2 -14
  104. package/dist/core/memory-engine/engine.d.ts +32 -22
  105. package/dist/core/memory-engine/engine.js +103 -55
  106. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  107. package/dist/core/memory-engine/file-backend.js +37 -252
  108. package/dist/core/memory-engine/index.d.ts +1 -1
  109. package/dist/core/memory-engine/index.js +1 -1
  110. package/dist/core/memory-engine/layout.d.ts +139 -9
  111. package/dist/core/memory-engine/layout.js +350 -7
  112. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  113. package/dist/core/memory-engine/scope-contract.js +8 -0
  114. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  115. package/dist/core/memory-engine/session-incarnation.js +5 -2
  116. package/dist/core/memory-engine/types.d.ts +10 -1
  117. package/dist/core/memory.js +5 -17
  118. package/dist/core/model-seat.d.ts +4 -4
  119. package/dist/core/model-seat.js +1 -1
  120. package/dist/core/mounted-mcp.d.ts +57 -0
  121. package/dist/core/mounted-mcp.js +19 -0
  122. package/dist/core/namespaced-rule-name.d.ts +29 -0
  123. package/dist/core/namespaced-rule-name.js +52 -0
  124. package/dist/core/park-selfcheck.d.ts +1 -1
  125. package/dist/core/park-selfcheck.js +16 -6
  126. package/dist/core/path-guard-rows.d.ts +99 -0
  127. package/dist/core/path-guard-rows.js +45 -0
  128. package/dist/core/path-identity.d.ts +22 -16
  129. package/dist/core/path-identity.js +10 -10
  130. package/dist/core/path-rule-binding.d.ts +2 -1
  131. package/dist/core/path-rule-binding.js +3 -1
  132. package/dist/core/pause-registry.d.ts +16 -2
  133. package/dist/core/pause-registry.js +6 -0
  134. package/dist/core/permission-rule-consent.js +0 -7
  135. package/dist/core/permission-rule-model.d.ts +68 -24
  136. package/dist/core/permission-rule-model.js +105 -24
  137. package/dist/core/permission-rule-store.js +2 -2
  138. package/dist/core/permission-rules.d.ts +3 -30
  139. package/dist/core/permission-rules.js +4 -54
  140. package/dist/core/read-root-candidate.d.ts +1 -3
  141. package/dist/core/read-root-candidate.js +4 -15
  142. package/dist/core/real-approval.d.ts +4 -3
  143. package/dist/core/retired-keys.d.ts +13 -0
  144. package/dist/core/retired-keys.js +14 -0
  145. package/dist/core/roles.d.ts +2 -3
  146. package/dist/core/roles.js +15 -6
  147. package/dist/core/runner/assemble-result.d.ts +0 -7
  148. package/dist/core/runner/assemble-result.js +19 -31
  149. package/dist/core/runner/caller-roster.d.ts +78 -0
  150. package/dist/core/runner/caller-roster.js +219 -0
  151. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  152. package/dist/core/runner/checkpoint-scope.js +2 -2
  153. package/dist/core/runner/child-tree.js +2 -2
  154. package/dist/core/runner/contracts.d.ts +68 -35
  155. package/dist/core/runner/decide-continuation.d.ts +51 -3
  156. package/dist/core/runner/decide-continuation.js +76 -21
  157. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  158. package/dist/core/runner/denial-limit-arms.js +11 -9
  159. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  160. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  161. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  162. package/dist/core/runner/finish-reason-seat.js +40 -0
  163. package/dist/core/runner/gate-exit.d.ts +44 -32
  164. package/dist/core/runner/gate-exit.js +112 -25
  165. package/dist/core/runner/inherited-ask-grants.js +6 -4
  166. package/dist/core/runner/mcp-redial.d.ts +3 -3
  167. package/dist/core/runner/mcp-redial.js +3 -4
  168. package/dist/core/runner/park-commit.d.ts +1 -1
  169. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  170. package/dist/core/runner/permission-rule-lanes.js +5 -4
  171. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  172. package/dist/core/runner/prepare-artifact.js +2 -1
  173. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  174. package/dist/core/runner/prepare-ask-lane.js +12 -6
  175. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  176. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  177. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  178. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  179. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  180. package/dist/core/runner/prepare-config-doors.js +10 -5
  181. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  182. package/dist/core/runner/prepare-defer-classify.js +5 -3
  183. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  184. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  185. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  186. package/dist/core/runner/prepare-gate-stations.js +9 -7
  187. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  188. package/dist/core/runner/prepare-hands-readface.js +7 -7
  189. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  190. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  191. package/dist/core/runner/prepare-listings.d.ts +7 -24
  192. package/dist/core/runner/prepare-listings.js +4 -5
  193. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  194. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  195. package/dist/core/runner/prepare-memory.d.ts +6 -0
  196. package/dist/core/runner/prepare-memory.js +13 -13
  197. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  198. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  199. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  200. package/dist/core/runner/prepare-park-ask.js +17 -10
  201. package/dist/core/runner/prepare-policy-chain.js +24 -44
  202. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  203. package/dist/core/runner/prepare-project-context.js +3 -4
  204. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  205. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  206. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  207. package/dist/core/runner/prepare-run-refs.js +2 -1
  208. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  209. package/dist/core/runner/prepare-safety-scan.js +1 -2
  210. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  211. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  212. package/dist/core/runner/prepare-task.d.ts +1 -1
  213. package/dist/core/runner/prepare-task.js +67 -56
  214. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  215. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  216. package/dist/core/runner/resume-apply.js +7 -14
  217. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  218. package/dist/core/runner/resume-internals-and-config.js +2 -2
  219. package/dist/core/runner/resume-policy-outcome.js +5 -32
  220. package/dist/core/runner/resume-review-outcome.js +4 -1
  221. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  222. package/dist/core/runner/retired-runner-deps.js +10 -1
  223. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  224. package/dist/core/runner/run-brain-sinks.js +5 -2
  225. package/dist/core/runner/run-harness-handlers.js +27 -34
  226. package/dist/core/runner/run-leg.d.ts +0 -2
  227. package/dist/core/runner/run-leg.js +32 -33
  228. package/dist/core/runner/run-terminal-adoption.js +4 -3
  229. package/dist/core/runner/runtask.js +8 -8
  230. package/dist/core/runner/session-rule-policy.js +5 -5
  231. package/dist/core/runner/stream-settle-backstop.js +7 -4
  232. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  233. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  234. package/dist/core/runner/terminal-account.d.ts +48 -0
  235. package/dist/core/runner/terminal-account.js +186 -0
  236. package/dist/core/runner/tool-end-body.d.ts +54 -17
  237. package/dist/core/runner/tool-end-body.js +27 -2
  238. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  239. package/dist/core/runner/tool-face-overlay.js +6 -4
  240. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  241. package/dist/core/runner/tool-occurrence.js +123 -0
  242. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  243. package/dist/core/runner/tool-progress-lane.js +25 -34
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/safety-axis-vocab.d.ts +1 -1
  249. package/dist/core/safety-merge-corpus.d.ts +1 -1
  250. package/dist/core/secret-env.d.ts +16 -5
  251. package/dist/core/secret-env.js +23 -63
  252. package/dist/core/sensitive-path-policy.d.ts +19 -18
  253. package/dist/core/sensitive-path-policy.js +73 -49
  254. package/dist/core/session-policy-store.d.ts +6 -3
  255. package/dist/core/session-policy-store.js +28 -10
  256. package/dist/core/session-reconcile.d.ts +3 -0
  257. package/dist/core/session-reconcile.js +5 -4
  258. package/dist/core/session-store.d.ts +5 -0
  259. package/dist/core/session-store.js +12 -0
  260. package/dist/core/session.d.ts +13 -0
  261. package/dist/core/shared-memory/normalize.d.ts +17 -4
  262. package/dist/core/shared-memory/normalize.js +7 -7
  263. package/dist/core/shell-lexer.js +5 -4
  264. package/dist/core/shell-wrapper-table.d.ts +2 -2
  265. package/dist/core/shell-wrapper-table.js +1 -1
  266. package/dist/core/skill-grant.js +1 -1
  267. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  268. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  269. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  270. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  271. package/dist/core/stub-env.d.ts +2 -0
  272. package/dist/core/stub-env.js +1 -0
  273. package/dist/core/synthetic-read-verdict.js +2 -2
  274. package/dist/core/task-event.d.ts +59 -5
  275. package/dist/core/task-result.d.ts +1 -1
  276. package/dist/core/task-spec.d.ts +42 -9
  277. package/dist/core/terminal-cause.d.ts +94 -11
  278. package/dist/core/tighten-task-spec.d.ts +5 -4
  279. package/dist/core/tighten-task-spec.js +20 -25
  280. package/dist/core/tool-catalog-entries.d.ts +5 -7
  281. package/dist/core/tool-catalog-entries.js +14 -15
  282. package/dist/core/tool-face.d.ts +47 -0
  283. package/dist/core/tool-face.js +5 -0
  284. package/dist/core/tool-model-gate.d.ts +5 -5
  285. package/dist/core/tool-name-aliases.d.ts +35 -10
  286. package/dist/core/tool-name-aliases.js +15 -0
  287. package/dist/core/tool-name-list.d.ts +30 -0
  288. package/dist/core/tool-name-list.js +55 -0
  289. package/dist/core/tool-name-readings.d.ts +1 -9
  290. package/dist/core/tool-name-readings.js +1 -3
  291. package/dist/core/tool-policy.d.ts +195 -85
  292. package/dist/core/tool-policy.js +165 -381
  293. package/dist/core/tool-registry.d.ts +44 -1
  294. package/dist/core/tool-registry.js +26 -0
  295. package/dist/core/tool-roster.d.ts +19 -1
  296. package/dist/core/tool-roster.js +21 -2
  297. package/dist/core/tool-spec-members.d.ts +45 -0
  298. package/dist/core/tool-spec-members.js +169 -0
  299. package/dist/core/tool-spec.d.ts +46 -8
  300. package/dist/core/tools.d.ts +6 -2
  301. package/dist/core/tools.js +8 -4
  302. package/dist/core/untrusted-egress.js +29 -26
  303. package/dist/core/untrusted-text.d.ts +13 -10
  304. package/dist/core/untrusted-text.js +6 -44
  305. package/dist/core/workflow-journal-store.d.ts +4 -1
  306. package/dist/core/write-protect.d.ts +65 -29
  307. package/dist/core/write-protect.js +235 -177
  308. package/dist/engine/compaction/compaction.d.ts +2 -2
  309. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  310. package/dist/engine/execution-env/node-execution-env.js +16 -38
  311. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  312. package/dist/engine/execution-env/symlink-chain.js +32 -0
  313. package/dist/engine/harness/types.d.ts +7 -0
  314. package/dist/engine/llm/tool-turns.d.ts +3 -0
  315. package/dist/engine/llm/tool-turns.js +1 -0
  316. package/dist/engine/llm/types.d.ts +59 -23
  317. package/dist/engine/loop/agent-loop.js +16 -2
  318. package/dist/engine/session/memory-repo.js +11 -3
  319. package/dist/engine/session/repo-utils.d.ts +8 -0
  320. package/dist/engine/session/repo-utils.js +13 -0
  321. package/dist/index.d.ts +20 -23
  322. package/dist/index.js +17 -20
  323. package/dist/internal/harness.d.ts +1 -1
  324. package/dist/internal/harness.js +1 -1
  325. package/dist/internal/llm.d.ts +2 -2
  326. package/dist/internal/llm.js +1 -1
  327. package/dist/orchestration/governance-baseline-validity.js +1 -1
  328. package/dist/orchestration/run-spec.js +3 -3
  329. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  330. package/dist/orchestration/run-workflow-tool.js +38 -78
  331. package/dist/orchestration/workflow-governance.d.ts +21 -25
  332. package/dist/orchestration/workflow-governance.js +38 -78
  333. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  334. package/dist/orchestration/workflow-primitives.js +5 -12
  335. package/dist/orchestration/workflow-types.d.ts +1 -1
  336. package/dist/orchestration/workflow.d.ts +61 -11
  337. package/dist/orchestration/workflow.js +191 -119
  338. package/dist/prompt-assembly/types.d.ts +1 -1
  339. package/dist/scenarios/full-body.d.ts +1 -1
  340. package/dist/shell/lex.d.ts +0 -21
  341. package/dist/shell/lex.js +278 -70
  342. package/dist/shell/shell-words.d.ts +35 -0
  343. package/dist/shell/shell-words.js +65 -0
  344. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  345. package/dist/stores/file/checkpoint-store.js +5 -2
  346. package/dist/stores/file/index.d.ts +0 -8
  347. package/dist/stores/file/index.js +0 -12
  348. package/dist/stores/file/session-store.d.ts +3 -0
  349. package/dist/stores/file/session-store.js +44 -19
  350. package/dist/tools/artifact/artifact-tool.js +2 -0
  351. package/dist/tools/fs/bash-program-position.d.ts +17 -3
  352. package/dist/tools/fs/bash-program-position.js +25 -10
  353. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  354. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  355. package/dist/tools/fs/containment-face.d.ts +4 -0
  356. package/dist/tools/fs/containment-face.js +3 -0
  357. package/dist/tools/fs/fs-shared.d.ts +10 -0
  358. package/dist/tools/fs/fs-shared.js +18 -0
  359. package/dist/tools/fs/fs-write.js +4 -2
  360. package/dist/tools/fs/index.d.ts +3 -2
  361. package/dist/tools/fs/index.js +2 -2
  362. package/dist/tools/fs/program-read-model.d.ts +99 -23
  363. package/dist/tools/fs/program-read-model.js +129 -55
  364. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  365. package/dist/tools/fs/program-read-model.rows.js +18 -10
  366. package/dist/tools/fs/read-deny-home.d.ts +35 -30
  367. package/dist/tools/fs/read-deny-home.js +45 -38
  368. package/dist/tools/fs/read-deny.d.ts +35 -27
  369. package/dist/tools/fs/read-deny.js +126 -92
  370. package/dist/tools/fs/removal-targets.d.ts +56 -23
  371. package/dist/tools/fs/removal-targets.js +74 -87
  372. package/dist/tools/fs/safety.d.ts +29 -22
  373. package/dist/tools/fs/safety.js +17 -11
  374. package/dist/tools/fs/search.js +10 -8
  375. package/dist/tools/fs/shell-read-argv.d.ts +4 -7
  376. package/dist/tools/fs/shell-read-argv.js +6 -8
  377. package/dist/tools/fs/shell-read-bindings.d.ts +203 -46
  378. package/dist/tools/fs/shell-read-bindings.js +488 -144
  379. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  380. package/dist/tools/fs/shell-read-builtins.js +43 -0
  381. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  382. package/dist/tools/fs/shell-read-check.js +51 -42
  383. package/dist/tools/fs/shell-read-establish.js +9 -10
  384. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  385. package/dist/tools/fs/shell-read-functions.js +29 -0
  386. package/dist/tools/fs/shell-read-judge.d.ts +48 -18
  387. package/dist/tools/fs/shell-read-judge.js +33 -4
  388. package/dist/tools/fs/shell-read-plan.d.ts +13 -20
  389. package/dist/tools/fs/shell-read-plan.js +200 -194
  390. package/dist/tools/fs/shell-read-start.d.ts +80 -0
  391. package/dist/tools/fs/shell-read-start.js +99 -0
  392. package/dist/tools/fs/shell-read-word.d.ts +35 -6
  393. package/dist/tools/fs/shell-read-word.js +89 -9
  394. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  395. package/dist/tools/fs/shell-read-workdir.js +281 -0
  396. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  397. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  398. package/dist/tools/fs/shell-reentry-text.d.ts +26 -26
  399. package/dist/tools/fs/shell-reentry-text.js +31 -34
  400. package/dist/tools/task-list.d.ts +1 -2
  401. package/dist/tools/web.js +1 -1
  402. package/package.json +4 -1
  403. package/test/export-surface.snapshot.json +107 -143
  404. package/wire-changes/core@7.48.0.json +252 -0
  405. package/wire-changes/core@7.49.0.json +4765 -0
  406. package/dist/agents/teacher.d.ts +0 -159
  407. package/dist/agents/teacher.js +0 -577
  408. package/dist/agents/team.d.ts +0 -226
  409. package/dist/agents/team.js +0 -257
  410. package/dist/core/strategy-store.d.ts +0 -238
  411. package/dist/core/strategy-store.js +0 -253
  412. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  413. package/dist/orchestration/builtin-workflows.js +0 -159
  414. package/dist/scenarios/env.d.ts +0 -40
  415. package/dist/scenarios/env.js +0 -39
  416. package/dist/scenarios/scenario-registry.d.ts +0 -110
  417. package/dist/scenarios/scenario-registry.js +0 -140
  418. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  419. package/dist/scenarios/teacher-quickstart.js +0 -12
  420. package/dist/stores/cc/lockfile.d.ts +0 -10
  421. package/dist/stores/cc/lockfile.js +0 -98
  422. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  423. package/dist/stores/cc/mailbox-store.js +0 -255
  424. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  425. package/dist/stores/cc/roster-adapter.js +0 -117
  426. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  427. package/dist/stores/cc/sidecar-transcript.js +0 -264
  428. package/dist/stores/cc/task-list-store.d.ts +0 -2
  429. package/dist/stores/cc/task-list-store.js +0 -125
  430. package/dist/stores/file/strategy-store.d.ts +0 -97
  431. package/dist/stores/file/strategy-store.js +0 -341
@@ -56,7 +56,7 @@ export interface CodeToolsConfig {
56
56
  }
57
57
  /**
58
58
  * Single-source bundle of the `code` scenario's `spec.tools`-class tools, so each deployment doesn't re-wire it
59
- * (the single-source discipline; mirrors the blessed `SCENARIO_REGISTRY` "data (named bundles)" precedent).
59
+ * (the single-source discipline: a scenario is data — a named bundle).
60
60
  * Profile-as-data — the engine iterates `spec.tools` branch-free; nothing keys off the scenario name. A trusted
61
61
  * assembler (service) calls this, sets `systemPrompt = CODE_SYSTEM_PROMPT` (or `role = CODE_ROLE`) +
62
62
  * `enablePlanMode:true`, and wires the deps seams (executionEnv/onQuestion/lspManager/skillSpecs/memoryStore/
@@ -1,24 +1,3 @@
1
- /**
2
- * The ONE shell lexer: one walk over a bash command mints a structure of words made of PIECES, and every other
3
- * spelling a reader consumes — `raw`, `folded`, the quoted spans, the expansion list, the assignment fact, the
4
- * reason a value cannot be read off the text — is a view of that structure. Dialect: bash (the execution
5
- * environment's last-resort `sh` reads `$'…'`, `+=`, a subscript, `<<<`, `<(…)` and `&>` differently; see
6
- * {@link bashOnlyConstructsOf}).
7
- *
8
- * ONE walk, ONE reading: every construct bash reads is RECORDED — a redirection, a substitution, an escape, a
9
- * comment, a line break, a backgrounding `&` — never refused here. Which of them a face refuses is that face's
10
- * predicate over the result (the classify faces' residual predicate in the read-only classifier); the lexer has
11
- * no modes. Bash's own word rules hold throughout: an unquoted word-start `#` begins a comment, and only a blank
12
- * (space or tab) bounds a word — a non-breaking space or a vertical tab is a word character.
13
- *
14
- * A command bash cannot parse is a {@link LexParseFailure}, never a guessed reading: an unterminated quote,
15
- * substitution, subscript or here-document yields NO segments. A word bash reads but whose VALUE the text does not
16
- * contain carries {@link LexedWord.unresolved}; the word is still delimited and its neighbours still read.
17
- *
18
- * Line continuations. Bash removes a `\<newline>` pair before it recognises anything — except inside single quotes,
19
- * a comment and a QUOTED here-document body. Every lookahead below reads the next LOGICAL character past any
20
- * continuation, so a pair can stand inside a construct's spelling and never inside the three places bash keeps it.
21
- */
22
1
  /** The dialect this lexer reads. The execution environment falls back to `sh` when no bash is found; a reader on
23
2
  * that path must degrade every word carrying a {@link BashOnlyConstruct} to the conservative reading. */
24
3
  export declare const SHELL_LEX_DIALECT = "bash";
package/dist/shell/lex.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { shellWordsOf } from "./shell-words.js";
1
2
  export const SHELL_LEX_DIALECT = "bash";
2
3
  export const QUOTE_KINDS = Object.freeze(["'", '"', "$'", '$"', "\\"]);
3
4
  export const EXPANSION_KINDS = Object.freeze(["parameter", "command", "process", "arithmetic", "tilde", "brace", "glob"]);
@@ -67,9 +68,14 @@ export const ANSI_C_ESCAPES = {
67
68
  "?": "?",
68
69
  };
69
70
  export const SUBSTITUTION_PLACEHOLDER = " subst";
70
- export const SHELL_CONTROL_PREFIXES = new Set(["!", "if", "then", "elif", "else", "while", "until", "do", "time"]);
71
+ export const SHELL_CONTROL_PREFIXES = shellWordsOf("control_prefix");
71
72
  const COMPOUND_OPERAND_COMMANDS = new Set(["alias", "declare", "eval", "export", "let", "local", "readonly", "typeset"]);
72
- const GROUP_WORDS = new Set(["{", "}"]);
73
+ const GROUP_WORDS = shellWordsOf("group");
74
+ const DEFINITION_WORDS = shellWordsOf("definition");
75
+ const BACKGROUND_WORDS = shellWordsOf("background");
76
+ const COMPOUND_OPEN_WORDS = shellWordsOf("compound_open");
77
+ const CASE_ARM_WORDS = shellWordsOf("case_arms");
78
+ const TIMER_WORDS = shellWordsOf("timer");
73
79
  export function dollarOpensQuote(text, at) {
74
80
  const next = text[at + 1];
75
81
  if (next !== "'" && next !== '"')
@@ -134,19 +140,149 @@ function past(text, j) {
134
140
  k += 2;
135
141
  return k;
136
142
  }
137
- function parenBodyEnd(text, open) {
143
+ function heredocHeaderOf(word, dash) {
144
+ if (word.folded === "" || /[$`]/.test(word.raw))
145
+ return undefined;
146
+ return { delimiter: word.folded, quoted: /["'\\]/.test(word.raw), dash };
147
+ }
148
+ function heredocBodies(text, from, headers, inSubstitution) {
149
+ const bodies = [];
150
+ let p = from;
151
+ for (const h of headers) {
152
+ const lines = [];
153
+ for (;;) {
154
+ if (p > text.length)
155
+ return "unterminated";
156
+ let nl = text.indexOf("\n", p);
157
+ let line = nl < 0 ? text.slice(p) : text.slice(p, nl);
158
+ if (!h.quoted) {
159
+ while (nl >= 0 && /(?<!\\)(?:\\\\)*\\$/.test(line)) {
160
+ const after = text.indexOf("\n", nl + 1);
161
+ line = line.slice(0, -1) + (after < 0 ? text.slice(nl + 1) : text.slice(nl + 1, after));
162
+ nl = after;
163
+ }
164
+ }
165
+ const compared = h.dash ? line.replace(/^\t+/, "") : line;
166
+ if (compared === h.delimiter) {
167
+ p = nl < 0 ? text.length + 1 : nl + 1;
168
+ break;
169
+ }
170
+ if (inSubstitution && compared.startsWith(h.delimiter))
171
+ return "ambiguous";
172
+ if (nl < 0)
173
+ return "unterminated";
174
+ lines.push(line);
175
+ p = nl + 1;
176
+ }
177
+ bodies.push(lines.join("\n"));
178
+ }
179
+ return { bodies, resume: Math.min(p, text.length) };
180
+ }
181
+ function heredocHeaderAt(text, from, dash, op) {
182
+ let j = from;
183
+ while (text[j] === " " || text[j] === "\t" || (text[j] === "\\" && text[j + 1] === "\n"))
184
+ j += text[j] === "\\" ? 2 : 1;
185
+ const start = j;
186
+ let quote;
187
+ for (; j < text.length; j++) {
188
+ const c = text[j];
189
+ if (c === "$" || c === "`")
190
+ return fail("heredoc_delimiter_expands", start);
191
+ if (quote === "'") {
192
+ if (c === "'")
193
+ quote = undefined;
194
+ continue;
195
+ }
196
+ if (quote === '"') {
197
+ if (c === "\\")
198
+ j++;
199
+ else if (c === '"')
200
+ quote = undefined;
201
+ continue;
202
+ }
203
+ if (c === "\\") {
204
+ j++;
205
+ continue;
206
+ }
207
+ if (c === "'" || c === '"') {
208
+ quote = c;
209
+ continue;
210
+ }
211
+ if (/[ \t\n;&|()<>]/.test(c))
212
+ break;
213
+ }
214
+ if (quote !== undefined)
215
+ return "unterminated";
216
+ const raw = text.slice(start, Math.min(j, text.length));
217
+ if (raw === "" || raw.startsWith("#"))
218
+ return fail("heredoc_without_delimiter", op);
219
+ if (/[~[]/.test(raw))
220
+ return "undelimited";
221
+ const lexed = scan(raw, true);
222
+ const tokens = "command" in lexed && lexed.command.segments.length === 1 ? lexed.command.segments[0].tokens : [];
223
+ const word = tokens.length === 1 ? tokens[0] : undefined;
224
+ if (word?.kind !== "word")
225
+ return "undelimited";
226
+ const header = heredocHeaderOf(word, dash);
227
+ return header === undefined ? fail("heredoc_delimiter_expands", start) : { ...header, end: j };
228
+ }
229
+ const BASH_READING = { heredoc: true, startComment: true };
230
+ const BASH32_READINGS = [{ heredoc: false, startComment: true }, { heredoc: false, startComment: false }];
231
+ const BODY_NESTING_MAX = 64;
232
+ function walkBody(text, open, reading, inDouble, level = 0) {
233
+ if (level > BODY_NESTING_MAX)
234
+ return "undelimited";
138
235
  let depth = 0;
139
236
  let quoted;
140
237
  let wordStart = true;
141
238
  let word = "";
239
+ let heredoc = false;
240
+ const owed = [];
241
+ const nested = (at, dq) => {
242
+ const inner = walkBody(text, at, reading, dq, level + 1);
243
+ if (typeof inner === "object" && "end" in inner) {
244
+ heredoc ||= inner.heredoc;
245
+ return inner.end - 1;
246
+ }
247
+ return inner;
248
+ };
142
249
  for (let j = open; j < text.length; j++) {
143
250
  const c = text[j];
144
- if (quoted !== undefined) {
145
- if (c === "\\" && quoted === '"')
251
+ if (quoted === "'") {
252
+ if (c === "'")
253
+ quoted = undefined;
254
+ continue;
255
+ }
256
+ if (quoted === '"') {
257
+ if (c === "\\") {
146
258
  j++;
147
- else if (c === quoted)
259
+ continue;
260
+ }
261
+ if (c === '"') {
148
262
  quoted = undefined;
149
- wordStart = false;
263
+ continue;
264
+ }
265
+ if (c === "`") {
266
+ const tick = backtickBody(text, j);
267
+ if (tick === undefined)
268
+ return "unterminated";
269
+ j = tick.close;
270
+ continue;
271
+ }
272
+ const k = past(text, j + 1);
273
+ if (c === "$" && text[k] === "(") {
274
+ const r = nested(k, true);
275
+ if (typeof r !== "number")
276
+ return r;
277
+ j = r;
278
+ continue;
279
+ }
280
+ if (c === "$" && text[k] === "{") {
281
+ const close = braceExpansionEnd(text, k);
282
+ if (close === undefined)
283
+ return "unterminated";
284
+ j = close - 1;
285
+ }
150
286
  continue;
151
287
  }
152
288
  if (c === "\\") {
@@ -162,9 +298,8 @@ function parenBodyEnd(text, open) {
162
298
  if (c === "#" && wordStart) {
163
299
  const nl = text.indexOf("\n", j);
164
300
  if (nl < 0)
165
- return undefined;
166
- j = nl;
167
- wordStart = true;
301
+ return "unterminated";
302
+ j = nl - 1;
168
303
  word = "";
169
304
  continue;
170
305
  }
@@ -174,34 +309,107 @@ function parenBodyEnd(text, open) {
174
309
  word = "";
175
310
  continue;
176
311
  }
177
- if (c === "$" && text[past(text, j + 1)] === "{") {
178
- const open2 = past(text, j + 1);
179
- const close = braceExpansionEnd(text, open2);
312
+ const k = past(text, j + 1);
313
+ if (c === "$" && text[k] === "'") {
314
+ const close = ansiCQuoteClose(text, k);
180
315
  if (close === undefined)
181
- return undefined;
182
- if (UNREADABLE_EXPANSION_TEXT.test(text.slice(open2 + 1, close - 1)))
183
- return "unreadable";
316
+ return "unterminated";
317
+ j = close;
318
+ wordStart = false;
319
+ word = "";
320
+ continue;
321
+ }
322
+ if (c === "`") {
323
+ const tick = backtickBody(text, j);
324
+ if (tick === undefined)
325
+ return "unterminated";
326
+ j = tick.close;
327
+ wordStart = false;
328
+ word = "`";
329
+ continue;
330
+ }
331
+ if (reading.heredoc && c === "<" && text[k] === "<") {
332
+ const third = past(text, k + 1);
333
+ if (text[third] === "<") {
334
+ j = third;
335
+ wordStart = false;
336
+ word = "";
337
+ continue;
338
+ }
339
+ const dash = text[third] === "-";
340
+ const header = heredocHeaderAt(text, dash ? third + 1 : third, dash, j);
341
+ if (typeof header !== "object" || !("delimiter" in header))
342
+ return header;
343
+ owed.push(header);
344
+ heredoc = true;
345
+ j = header.end - 1;
346
+ wordStart = false;
347
+ word = "";
348
+ continue;
349
+ }
350
+ if ((c === "$" || c === "<" || c === ">") && text[k] === "(") {
351
+ const r = nested(k, false);
352
+ if (typeof r !== "number")
353
+ return r;
354
+ j = r;
355
+ wordStart = false;
356
+ word = "$";
357
+ continue;
358
+ }
359
+ if (reading.heredoc && c === "$" && text[k] === "{") {
360
+ const close = braceExpansionEnd(text, k);
361
+ if (close === undefined)
362
+ return "unterminated";
363
+ if (UNREADABLE_EXPANSION_TEXT.test(text.slice(k + 1, close - 1)))
364
+ return "undelimited";
184
365
  j = close - 1;
185
366
  wordStart = false;
186
367
  word = "";
187
368
  continue;
188
369
  }
189
- if (c === "<" && text[past(text, j + 1)] === "<" && text[past(text, past(text, j + 1) + 1)] !== "<")
190
- return "unreadable";
370
+ if (c === "\n" && owed.length > 0) {
371
+ const read = heredocBodies(text, j + 1, owed, true);
372
+ if (read === "unterminated")
373
+ return fail("unterminated_heredoc", j + 1);
374
+ if (read === "ambiguous")
375
+ return "undelimited";
376
+ owed.length = 0;
377
+ j = read.resume - 1;
378
+ wordStart = true;
379
+ word = "";
380
+ continue;
381
+ }
191
382
  if (c === "(")
192
383
  depth++;
193
384
  else if (c === ")") {
194
385
  depth--;
195
386
  if (depth === 0)
196
- return j + 1;
387
+ return owed.length > 0 ? "undelimited" : { end: j + 1, heredoc };
388
+ }
389
+ if (!reading.heredoc) {
390
+ wordStart = j === open ? reading.startComment && !inDouble && level === 0 : c === " " || c === "\t" || c === "\n";
391
+ continue;
197
392
  }
198
393
  const boundary = /[\s;|&()]/.test(c);
199
- if (boundary && word === "case")
200
- return "unreadable";
394
+ if (boundary && CASE_ARM_WORDS.has(word))
395
+ return "undelimited";
201
396
  word = boundary ? "" : word + c;
202
397
  wordStart = boundary;
203
398
  }
204
- return undefined;
399
+ return "unterminated";
400
+ }
401
+ function substitutionBodyEnd(text, open, inDouble) {
402
+ const read = walkBody(text, open, BASH_READING, inDouble);
403
+ if (typeof read !== "object" || !("end" in read))
404
+ return read;
405
+ if (!read.heredoc)
406
+ return read.end;
407
+ for (const reading of BASH32_READINGS) {
408
+ const counted = walkBody(text, open, reading, inDouble);
409
+ if (counted !== "unterminated" && !(typeof counted === "object" && "end" in counted && counted.end === read.end))
410
+ return "undelimited";
411
+ }
412
+ return read.end;
205
413
  }
206
414
  function braceExpansionEnd(text, open) {
207
415
  let quoted;
@@ -310,7 +518,7 @@ export function substitutionsInHeredocBody(body) {
310
518
  continue;
311
519
  }
312
520
  if (ch === "$" && body[i + 1] === "(") {
313
- const end = parenBodyEnd(body, i + 1);
521
+ const end = substitutionBodyEnd(body, i + 1, true);
314
522
  if (typeof end !== "number")
315
523
  return undefined;
316
524
  out.push({ body: body.slice(i + 2, end - 1), kind: body[i + 2] === "(" ? "arithmetic" : "command" });
@@ -541,10 +749,24 @@ class WordBuilder {
541
749
  return at;
542
750
  };
543
751
  const unitCloses = new Map([":", "=", "."].map((d) => [d, unitClose(d)]));
752
+ const lettersEnd = new Array(nf + 1).fill(nf);
753
+ for (let f = nf - 1; f >= 0; f--) {
754
+ const lower = text.charCodeAt(f) | 0x20;
755
+ lettersEnd[f] = lower >= 0x61 && lower <= 0x7a && readableAt(f) ? lettersEnd[f + 1] : f;
756
+ }
757
+ const unitEndAt = (f) => {
758
+ if (!(readableAt(f) && text[f] === "[" && readableAt(f + 1)))
759
+ return -1;
760
+ const d = text[f + 1];
761
+ const end = unitCloses.get(d)?.[f + 2] ?? -1;
762
+ if (end < 0)
763
+ return -1;
764
+ return d === ":" ? (end > f + 2 && lettersEnd[f + 2] === end ? end : -1) : end === f + 3 ? end : -1;
765
+ };
544
766
  const nextBracketClose = new Array(nf + 2).fill(-1);
545
767
  const nextSlash = new Array(nf + 1).fill(nf);
546
768
  for (let f = nf - 1; f >= 0; f--) {
547
- const unitEnd = readableAt(f) && text[f] === "[" && readableAt(f + 1) ? unitCloses.get(text[f + 1] ?? "")?.[f + 2] ?? -1 : -1;
769
+ const unitEnd = unitEndAt(f);
548
770
  nextBracketClose[f] = readableAt(f) && text[f] === "]" ? f : unitEnd >= 0 ? nextBracketClose[unitEnd + 2] : nextBracketClose[f + 1];
549
771
  nextSlash[f] = text[f] === "/" ? f : nextSlash[f + 1];
550
772
  }
@@ -584,7 +806,7 @@ class WordBuilder {
584
806
  for (let m = k + 1; m < close && !widened; m++)
585
807
  widened = this.rawQuoted[m] !== undefined;
586
808
  for (let f = j; f < closeAt && !widened; f++)
587
- widened = readableAt(f) && text[f] === "[" && readableAt(f + 1) && (unitCloses.get(text[f + 1] ?? "")?.[f + 2] ?? -1) >= 0;
809
+ widened = readableAt(f) && text[f] === "[" && readableAt(f + 1) && (text[f + 1] === ":" || text[f + 1] === "=" || text[f + 1] === ".");
588
810
  const from = this.foldedOf(k);
589
811
  const to = this.foldedOf(close + 1);
590
812
  if (!expands && widened)
@@ -748,6 +970,7 @@ function scan(source, connectorsAreText) {
748
970
  let acceptable = true;
749
971
  let timeGrammar;
750
972
  let definitionName = false;
973
+ let coprocWord;
751
974
  let afterLeadingRedirect = false;
752
975
  let assignmentSeen = false;
753
976
  let subscriptsClosed = false;
@@ -761,7 +984,7 @@ function scan(source, connectorsAreText) {
761
984
  w.opaque(source.slice(from, to), SUBSTITUTION_PLACEHOLDER, by, from, to, { kind, yields: kind === "command" && by === undefined ? "many" : "one", body });
762
985
  current().substitutions.push(body);
763
986
  };
764
- const resetPosition = () => { acceptable = true; commandWord = undefined; afterLeadingRedirect = false; assignmentSeen = false; subscriptsClosed = false; timeGrammar = undefined; definitionName = false; };
987
+ const resetPosition = () => { acceptable = true; commandWord = undefined; afterLeadingRedirect = false; assignmentSeen = false; subscriptsClosed = false; timeGrammar = undefined; definitionName = false; coprocWord = undefined; };
765
988
  const endWord = () => {
766
989
  if (!w.started)
767
990
  return undefined;
@@ -771,13 +994,13 @@ function scan(source, connectorsAreText) {
771
994
  const at = w.at;
772
995
  w = new WordBuilder();
773
996
  if (pendingHeredoc !== undefined) {
774
- const header = pendingHeredoc;
997
+ const header = heredocHeaderOf(word, pendingHeredoc.dash);
775
998
  pendingHeredoc = undefined;
776
- if (word.folded === "" || /[$`]/.test(word.raw))
999
+ if (header === undefined)
777
1000
  return fail("heredoc_delimiter_expands", at);
778
- const token = { kind: "heredoc", delimiter: word.folded, quoted: /["'\\]/.test(word.raw), body: "" };
1001
+ const token = { kind: "heredoc", delimiter: header.delimiter, quoted: header.quoted, body: "" };
779
1002
  current().tokens.push(token);
780
- pendingHeredocs.push({ delimiter: word.folded, quoted: token.quoted, dash: header.dash, token });
1003
+ pendingHeredocs.push({ ...header, token });
781
1004
  if (acceptable) {
782
1005
  if (assignmentSeen)
783
1006
  subscriptsClosed = true;
@@ -809,13 +1032,18 @@ function scan(source, connectorsAreText) {
809
1032
  resetPosition();
810
1033
  return undefined;
811
1034
  }
812
- if (acceptable && bare && word.folded === "function") {
1035
+ if (acceptable && bare && DEFINITION_WORDS.has(word.folded)) {
813
1036
  acceptable = false;
814
1037
  definitionName = true;
815
1038
  return undefined;
816
1039
  }
817
1040
  if (acceptable && bare && (SHELL_CONTROL_PREFIXES.has(word.folded) || GROUP_WORDS.has(word.folded))) {
818
- timeGrammar = word.folded === "time" ? "opt" : undefined;
1041
+ timeGrammar = TIMER_WORDS.has(word.folded) ? "opt" : undefined;
1042
+ coprocWord = undefined;
1043
+ return undefined;
1044
+ }
1045
+ if (acceptable && bare && BACKGROUND_WORDS.has(word.folded)) {
1046
+ coprocWord = "head";
819
1047
  return undefined;
820
1048
  }
821
1049
  if (acceptable && bare && timeGrammar === "opt" && word.folded === "-p") {
@@ -829,10 +1057,16 @@ function scan(source, connectorsAreText) {
829
1057
  timeGrammar = undefined;
830
1058
  if (word.assignment !== undefined && word.assignment.bare && acceptable) {
831
1059
  assignmentSeen = true;
1060
+ coprocWord = undefined;
832
1061
  return undefined;
833
1062
  }
834
- if (acceptable)
1063
+ if (acceptable && coprocWord !== "name")
835
1064
  commandWord = bare ? word.folded : undefined;
1065
+ if (coprocWord === "head" && !(bare && COMPOUND_OPEN_WORDS.has(word.folded))) {
1066
+ coprocWord = "name";
1067
+ return undefined;
1068
+ }
1069
+ coprocWord = undefined;
836
1070
  acceptable = false;
837
1071
  return undefined;
838
1072
  };
@@ -847,34 +1081,12 @@ function scan(source, connectorsAreText) {
847
1081
  return undefined;
848
1082
  };
849
1083
  const readHeredocBodies = (from) => {
850
- let p = from;
851
- for (const h of pendingHeredocs) {
852
- const lines = [];
853
- for (;;) {
854
- if (p > source.length)
855
- return fail("unterminated_heredoc", from);
856
- let nl = source.indexOf("\n", p);
857
- let line = nl < 0 ? source.slice(p) : source.slice(p, nl);
858
- if (!h.quoted) {
859
- while (nl >= 0 && /(?<!\\)(?:\\\\)*\\$/.test(line)) {
860
- const after = source.indexOf("\n", nl + 1);
861
- line = line.slice(0, -1) + (after < 0 ? source.slice(nl + 1) : source.slice(nl + 1, after));
862
- nl = after;
863
- }
864
- }
865
- if ((h.dash ? line.replace(/^\t+/, "") : line) === h.delimiter) {
866
- p = nl < 0 ? source.length + 1 : nl + 1;
867
- break;
868
- }
869
- if (nl < 0)
870
- return fail("unterminated_heredoc", from);
871
- lines.push(line);
872
- p = nl + 1;
873
- }
874
- h.token.body = lines.join("\n");
875
- }
1084
+ const read = heredocBodies(source, from, pendingHeredocs, false);
1085
+ if (typeof read !== "object")
1086
+ return fail("unterminated_heredoc", from);
1087
+ pendingHeredocs.forEach((h, k) => { h.token.body = read.bodies[k]; });
876
1088
  pendingHeredocs.length = 0;
877
- return Math.min(p, source.length);
1089
+ return read.resume;
878
1090
  };
879
1091
  for (let i = 0; i < source.length; i++) {
880
1092
  if (!inSingle) {
@@ -1006,11 +1218,9 @@ function scan(source, connectorsAreText) {
1006
1218
  }
1007
1219
  if (ch === "$" && source[n1] === "(") {
1008
1220
  const arithmetic = source[next(n1)] === "(";
1009
- const end = parenBodyEnd(source, n1);
1010
- if (end === undefined)
1011
- return fail("unterminated_command_substitution", i);
1012
- if (end === "unreadable")
1013
- return fail("undelimited_substitution", i);
1221
+ const end = substitutionBodyEnd(source, n1, inDouble);
1222
+ if (typeof end !== "number")
1223
+ return end === "unterminated" ? fail("unterminated_command_substitution", i) : end === "undelimited" ? fail("undelimited_substitution", i) : end;
1014
1224
  substitution(i, end, source.slice(n1 + 1, end - 1), arithmetic ? "arithmetic" : "command");
1015
1225
  i = end - 1;
1016
1226
  continue;
@@ -1042,11 +1252,9 @@ function scan(source, connectorsAreText) {
1042
1252
  continue;
1043
1253
  }
1044
1254
  if ((ch === "<" || ch === ">") && source[n1] === "(") {
1045
- const end = parenBodyEnd(source, n1);
1046
- if (end === undefined)
1047
- return fail("unterminated_process_substitution", i);
1048
- if (end === "unreadable")
1049
- return fail("undelimited_substitution", i);
1255
+ const end = substitutionBodyEnd(source, n1, false);
1256
+ if (typeof end !== "number")
1257
+ return end === "unterminated" ? fail("unterminated_process_substitution", i) : end === "undelimited" ? fail("undelimited_substitution", i) : end;
1050
1258
  substitution(i, end, source.slice(n1 + 1, end - 1), "process");
1051
1259
  i = end - 1;
1052
1260
  continue;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The ONE table of the words bash's grammar owns — and the builtins that move the working directory — with the part each plays for a reader.
3
+ *
4
+ * "Which word is syntax" is one fact about bash. Every reader that acts on it — the lexer's position walk, the program
5
+ * model, the read plan, the binding walk, the tightening reader, the read-only classifier, the rule model — asks it of
6
+ * THIS table through {@link shellWordsOf} instead of keeping a set of its own. A role is one question a reader asks of
7
+ * a word; a word a reader must know is a row here carrying that role. Adding a keyword is one row.
8
+ *
9
+ * The table holds every SET of words. A reader that tests the spelling of ONE word on its own (the conditional's `[[`
10
+ * and `]]`, the `in` of a loop header, the `for NAME in …; do …; done` shape the poll classifier matches) holds no set
11
+ * and compares it. A test reads the source tree for a second set of the table's words, and for a chain of comparisons
12
+ * that spells one.
13
+ *
14
+ * Measured with `compgen -k`: bash 3.2.57 and 5.3 list the same 21 words, and 5.3 adds `coproc`. The structural roles
15
+ * `control_prefix`, `group` and `block` partition exactly those 22 (3.2 reads `coproc` as a command name; the
16
+ * position walk reads it as syntax all the same — the side that judges more). `((` and `))` are no reserved words:
17
+ * they are the arithmetic command's tokens, kept for the one role that refuses every word which cannot name a program.
18
+ *
19
+ * The table also owns the four builtins that carry the shell's WORKING DIRECTORY — `cd`, `pushd`, `popd`, `dirs` — because
20
+ * "which word moves where a command stands" is the same kind of fact (they are no reserved words, so the structural
21
+ * roles above do not touch them): the working-directory thread reads where a move leads, the rule model asks whether a
22
+ * segment moved the cursor, and the program model's stack rows derive from the same roles. A move word is a row here;
23
+ * none of those readers spells the set. (Which programs the read-only classifier admits is another fact — the reference's
24
+ * read-only command set — and is not a role of this table.)
25
+ *
26
+ * Pure data and a pure projection: this module imports nothing.
27
+ */
28
+ export declare const SHELL_WORD_ROLES: readonly ["control_prefix", "group", "block", "compound_open", "loop_list_head", "loop_iterates", "loop_condition", "loop_end", "definition", "background", "case_arms", "timer", "scope_open", "scope_close", "scope_switch", "stripped_prefix", "stripped_standalone", "opaque", "rule_reserved", "base_mover", "stack_mover", "stack_editor"];
29
+ export type ShellWordRole = (typeof SHELL_WORD_ROLES)[number];
30
+ /** Every word that plays `role`. The same set object on every call: a projection is a view, not a copy to edit. */
31
+ export declare function shellWordsOf(role: ShellWordRole): ReadonlySet<string>;
32
+ /** The roles one word plays, in {@link SHELL_WORD_ROLES} order; empty for a word the table does not own. */
33
+ export declare function shellWordRolesOf(word: string): readonly ShellWordRole[];
34
+ /** Every word the table owns, in row order. */
35
+ export declare function shellWordTable(): readonly string[];
@@ -0,0 +1,65 @@
1
+ export const SHELL_WORD_ROLES = Object.freeze([
2
+ "control_prefix",
3
+ "group",
4
+ "block",
5
+ "compound_open",
6
+ "loop_list_head",
7
+ "loop_iterates",
8
+ "loop_condition",
9
+ "loop_end",
10
+ "definition",
11
+ "background",
12
+ "case_arms",
13
+ "timer",
14
+ "scope_open",
15
+ "scope_close",
16
+ "scope_switch",
17
+ "stripped_prefix",
18
+ "stripped_standalone",
19
+ "opaque",
20
+ "rule_reserved",
21
+ "base_mover",
22
+ "stack_mover",
23
+ "stack_editor",
24
+ ]);
25
+ const ROWS = [
26
+ ["!", "control_prefix", "stripped_prefix", "rule_reserved"],
27
+ ["if", "control_prefix", "compound_open", "scope_open", "stripped_prefix", "rule_reserved"],
28
+ ["then", "control_prefix", "stripped_prefix", "rule_reserved"],
29
+ ["elif", "control_prefix", "scope_switch", "stripped_prefix", "rule_reserved"],
30
+ ["else", "control_prefix", "scope_switch", "stripped_prefix", "rule_reserved"],
31
+ ["while", "control_prefix", "compound_open", "loop_condition", "scope_open", "stripped_prefix", "rule_reserved"],
32
+ ["until", "control_prefix", "compound_open", "loop_condition", "scope_open", "stripped_prefix", "rule_reserved"],
33
+ ["do", "control_prefix", "stripped_prefix", "rule_reserved"],
34
+ ["time", "control_prefix", "timer", "rule_reserved"],
35
+ ["{", "group", "compound_open", "scope_open", "stripped_standalone", "rule_reserved"],
36
+ ["}", "group", "scope_close", "stripped_standalone", "rule_reserved"],
37
+ ["for", "block", "compound_open", "loop_list_head", "loop_iterates", "scope_open", "opaque", "rule_reserved"],
38
+ ["select", "block", "compound_open", "loop_list_head", "scope_open", "opaque", "rule_reserved"],
39
+ ["case", "block", "compound_open", "case_arms", "scope_open", "opaque", "rule_reserved"],
40
+ ["esac", "block", "scope_close", "stripped_standalone", "rule_reserved"],
41
+ ["fi", "block", "scope_close", "stripped_standalone", "rule_reserved"],
42
+ ["done", "block", "loop_end", "scope_close", "stripped_standalone", "rule_reserved"],
43
+ ["function", "block", "definition", "opaque", "rule_reserved"],
44
+ ["coproc", "block", "background", "opaque", "rule_reserved"],
45
+ ["]]", "block", "stripped_standalone", "rule_reserved"],
46
+ ["in", "block", "opaque", "rule_reserved"],
47
+ ["[[", "block", "compound_open", "rule_reserved"],
48
+ ["((", "rule_reserved"],
49
+ ["))", "rule_reserved"],
50
+ ["cd", "base_mover"],
51
+ ["pushd", "base_mover", "stack_mover"],
52
+ ["popd", "base_mover", "stack_mover"],
53
+ ["dirs", "stack_editor"],
54
+ ];
55
+ const PROJECTIONS = new Map(SHELL_WORD_ROLES.map((role) => [role, new Set(ROWS.filter(([, ...roles]) => roles.includes(role)).map(([word]) => word))]));
56
+ export function shellWordsOf(role) {
57
+ return PROJECTIONS.get(role);
58
+ }
59
+ export function shellWordRolesOf(word) {
60
+ const row = ROWS.find(([w]) => w === word);
61
+ return row === undefined ? [] : SHELL_WORD_ROLES.filter((role) => row.includes(role));
62
+ }
63
+ export function shellWordTable() {
64
+ return ROWS.map(([word]) => word);
65
+ }
@@ -20,11 +20,11 @@ export declare class FileCheckpointStore implements CheckpointStore {
20
20
  * directory's writer fence and refuses a second OS process by name (see the class header). Serving
21
21
  * many writers at once remains Pg/TiDB's job — this refuses the second one, it does not coordinate it. */
22
22
  readonly durability: "durable";
23
- /** Honest declaration on the fidelity axis: the ledger is JSONL, so what survives the restart this
24
- * backend promises is the JSON PROJECTION of the row — a `Date` replays as its ISO string, a
25
- * `Map`/`Set` as `{}`, `NaN` as `null`. The in-process map holds the structured clone, which is why
26
- * the loss is invisible until something reads the disk; the declaration is what makes it visible to
27
- * the mint BEFORE the row is filed. */
23
+ /** Honest declaration on the fidelity axis: the ledger is JSONL, so what this backend holds is the JSON
24
+ * PROJECTION of the row — a `Date` reads as its ISO string, a `Map`/`Set` as `{}`, `NaN` as `null`, an
25
+ * `undefined`-valued key not at all — before a restart and after it alike (the live map is filled from the
26
+ * same JSON reading as the ledger line); the declaration is what makes the loss visible to the mint BEFORE the
27
+ * row is filed. */
28
28
  readonly fidelity: "json";
29
29
  /** F-012 L2: `reopen` here is a real resolved→pending CAS journaled to the ledger — declared, not sniffed. */
30
30
  readonly redecision: {