@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
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Where a text the read plan (`shell-read-plan.ts`) plans starts: a nested text's start — its names, the deny floors the
3
+ * words handing it on carry, the user its shell runs as, its standard input and its working directory — and where each
4
+ * segment's standard input comes from. A nested plan parsed against the declarations' working directory is re-based onto
5
+ * the segment it sits in ({@link rebasePlan}), unless it starts in a working directory of its own.
6
+ */
7
+ import type { LexedSegment } from "../../shell/lex.js";
8
+ import type { BindingTable, FloorValue, InheritedFunctions, NameReader } from "./shell-read-bindings.js";
9
+ import type { TargetUser } from "./program-read-model.js";
10
+ import type { StdinText } from "./shell-reentry-text.js";
11
+ import type { ReadCandidate, ShellReadPlan } from "./shell-read-plan.js";
12
+ /** Where a nested text starts its names: a substitution body inherits the table of the segment it sits in (a subshell
13
+ * holds every variable of the shell that forks it); a text the shell runs later or elsewhere (a code body, `eval`'s
14
+ * text, a child shell's `-c`) starts from the text's own start — every name unknown, `HOME` the declared home unless
15
+ * the enclosing text binds it anywhere. `boundAnywhere` answers for the enclosing texts. */
16
+ export interface PlanStart {
17
+ readonly initial: NameReader;
18
+ readonly boundAnywhere: (name: string) => boolean;
19
+ /** `HOME` may already hold something other than the declared home where the nested text starts. */
20
+ readonly homeTouched: boolean;
21
+ /** The attributes, name references and deny floors in force where the nested text starts. */
22
+ readonly inherited: BindingTable["inherited"];
23
+ /** The working directories it starts in, where they are not the enclosing segment's (a login shell starts in its user's
24
+ * home; `"unmodelled"` — a home the text does not settle). */
25
+ readonly bases?: readonly string[] | "unmodelled";
26
+ /** The thread of the shell that runs the text, where the text runs in that shell or a fork of it ({@link HeldThread}). */
27
+ readonly thread?: HeldThread;
28
+ /** What the shell around the text holds where the text runs in that shell or a fork of it — a literal `eval` text, a
29
+ * substitution body, a text run later (a `trap` action): each function and builtin key as it stands there
30
+ * ({@link InheritedFunctions}). A text a new process runs (a child shell's `-c`) holds none: every builtin enabled, no function. */
31
+ readonly names?: InheritedFunctions;
32
+ /** What arrives on its own standard input (the input of the shell running it). */
33
+ readonly stdin?: readonly StdinText[];
34
+ }
35
+ /** The thread of the shell that runs a text, at the segment that hands it on: a literal `eval` text is not a new plan but the next
36
+ * segment of the same thread, so it starts in all of it and hands the working directory and the physical mode back; a substitution
37
+ * body (a fork) and a text run later start in what the shell holds and hand nothing back. `functions`: the names a call may mean
38
+ * (the shell's definition heads and the ones an `eval` text defines), `unread` those whose bodies the nested plan has not read — an
39
+ * `eval` text reads the shell's bodies through the names they bind, every other text has none of them in front of it. */
40
+ export interface HeldThread {
41
+ readonly physical: boolean;
42
+ readonly functions: ReadonlySet<string>;
43
+ readonly unread: ReadonlySet<string>;
44
+ }
45
+ /** What a shell holds at a segment, for a text that runs in it or in a fork of it ({@link PlanStart.names}): each function and builtin key
46
+ * as it stands there, and the names a call to one of its functions may change — the ones the text reads a call of: an `eval` text names
47
+ * the shell's functions (`bound`: what a call to one of them changes); a substitution body and a text run later read none of their bodies
48
+ * (the shell's functions are {@link HeldThread.unread} there: a call to one makes every name unknown), so they name none. */
49
+ export declare function heldAt(table: BindingTable, bound?: InheritedFunctions["bound"]): InheritedFunctions;
50
+ /** What a segment says of the start of a text it hands a shell to run later: the deny floors of the words it holds as
51
+ * written, the user the shell runs as ({@link TargetUser}), and the shell's standard input. */
52
+ export interface NestedStart {
53
+ readonly floors?: ReadonlyMap<string, readonly FloorValue[]>;
54
+ readonly as?: TargetUser;
55
+ readonly stdin?: readonly StdinText[];
56
+ }
57
+ /** Where a text run later starts ({@link NestedStart}): the later start, with the shell's standard input, the floors of the
58
+ * words that hand it on, and — run as another user — that user's `HOME` (the caller's, the target's, or either) and, for
59
+ * a login shell, the target's home as its working directory. */
60
+ export declare function startedAt(later: PlanStart, at: NestedStart | undefined): PlanStart;
61
+ /** A planner that plans each text once per start: a segment read in several readings hands most of its nested texts (a
62
+ * substitution's body, a launched shell's text) on alike in every reading. */
63
+ export declare function plannedOnce<K, P>(plan: (text: string, kind: K, at?: NestedStart) => P): (text: string, kind: K, at?: NestedStart) => P;
64
+ /**
65
+ * What arrives on each segment's standard input: the pipe it is reached through (`piped`, what the segment before it
66
+ * prints); else the input of the group (`{ …; }`, `( … )`) it stands in — a group a pipe feeds hands each member that
67
+ * pipe; else the input the text itself was handed (`start`: a shell's `-c` text reads that shell's standard input).
68
+ */
69
+ export declare function stdinFeeds(segments: readonly LexedSegment[], start: readonly StdinText[], piped: (si: number) => readonly StdinText[]): (si: number) => readonly StdinText[];
70
+ /**
71
+ * A nested plan (a substitution body, a here-document's substitution, a launcher's command string) was parsed
72
+ * against the declarations' working directory; the segment it sits in may stand elsewhere (`cd sub && cat <<EOF
73
+ * $(cat secret)`), so its relative candidates are re-based onto the ENCLOSING segment's bases — every base the
74
+ * nested text derived from the start is carried over by prefix, an unsettled enclosing base leaves every
75
+ * relative candidate unplaced, and absolute candidates are untouched. Recursive: a nested plan's own nested plans
76
+ * derive from the same start. A candidate left unplaced is judged where the text stood when it lost track (its floor,
77
+ * {@link ReadCandidate.floorBases}): the places the nested text was in move with it like its bases, and an enclosing segment that
78
+ * lost its base itself hands on its own floor (`floor`).
79
+ */
80
+ export declare function rebasePlan(plan: ShellReadPlan, from: string, to: ReadCandidate["bases"], floor?: readonly string[]): ShellReadPlan;
@@ -0,0 +1,99 @@
1
+ const NO_NAMES = new Set();
2
+ export function heldAt(table, bound = NO_NAMES) {
3
+ return { start: (key) => table.stateOf(key), bound };
4
+ }
5
+ const ROOT_HOMES = ["/root", "/var/root"];
6
+ export function startedAt(later, at) {
7
+ if (at === undefined)
8
+ return later;
9
+ const fed = at.stdin !== undefined && at.stdin.length > 0 ? { ...later, stdin: at.stdin } : later;
10
+ const withFloors = at.floors === undefined || at.floors.size === 0 ? fed : { ...fed, inherited: { ...fed.inherited, floors: joinedFloors(fed.inherited.floors, at.floors) } };
11
+ const as = at.as;
12
+ if (as === undefined || as.home === "caller")
13
+ return withFloors;
14
+ const homes = as.name === "root" ? ROOT_HOMES : undefined;
15
+ const target = homes === undefined ? "unknown" : homes.map((spelled) => ({ spelled }));
16
+ const caller = later.initial("HOME");
17
+ const home = as.home === "target" ? target : caller === "unknown" || target === "unknown" ? "unknown" : [...caller, ...target];
18
+ return {
19
+ ...withFloors,
20
+ initial: (name) => (name === "HOME" ? home : withFloors.initial(name)),
21
+ homeTouched: true,
22
+ ...(as.login ? { bases: homes ?? "unmodelled" } : {}),
23
+ };
24
+ }
25
+ export function plannedOnce(plan) {
26
+ const planned = new Map();
27
+ return (text, kind, at) => {
28
+ const key = JSON.stringify([kind, text, [...(at?.floors ?? [])], at?.as, at?.stdin]);
29
+ if (!planned.has(key))
30
+ planned.set(key, plan(text, kind, at));
31
+ return planned.get(key);
32
+ };
33
+ }
34
+ function joinedFloors(a, b) {
35
+ const out = new Map(a);
36
+ for (const [name, floors] of b)
37
+ out.set(name, [...(out.get(name) ?? []), ...floors]);
38
+ return out;
39
+ }
40
+ export function stdinFeeds(segments, start, piped) {
41
+ const opener = [];
42
+ const enclosing = [];
43
+ const open = [];
44
+ segments.forEach((segment, si) => {
45
+ enclosing[si] = open.at(-1);
46
+ let opens = false;
47
+ for (const t of segment.tokens) {
48
+ if ((t.kind === "group" && t.op === "(") || (t.kind === "word" && t.raw === "{")) {
49
+ open.push(si);
50
+ opens = true;
51
+ }
52
+ else if ((t.kind === "group" && t.op === ")") || (t.kind === "word" && t.raw === "}"))
53
+ open.pop();
54
+ }
55
+ opener[si] = opens ? si : enclosing[si];
56
+ });
57
+ const fedAt = (si) => {
58
+ if (si > 0 && segments[si].connector === "|")
59
+ return [...new Map(piped(si).map((s) => [JSON.stringify(s), s])).values()];
60
+ const group = opener[si] !== si ? opener[si] : enclosing[si];
61
+ return group !== undefined ? fedAt(group) : start;
62
+ };
63
+ return fedAt;
64
+ }
65
+ export function rebasePlan(plan, from, to, floor) {
66
+ if (to !== "unmodelled" && to.length === 1 && to[0] === from)
67
+ return plan;
68
+ const fromSep = from.endsWith("/") || from.endsWith("\\") ? from : `${from}/`;
69
+ const moveInto = (into, b) => {
70
+ if (b === from)
71
+ return [...into];
72
+ if (b.startsWith(fromSep))
73
+ return into.map((t) => `${t.endsWith("/") || t.endsWith("\\") ? t : `${t}/`}${b.slice(fromSep.length)}`);
74
+ return [b];
75
+ };
76
+ const moveBase = (b) => (to === "unmodelled" ? [] : moveInto(to, b));
77
+ const floorAt = to === "unmodelled" ? floor : to;
78
+ const moveFloor = (bases, into) => [...new Set(bases.flatMap((b) => moveInto(into, b)))];
79
+ const moveCandidate = (c) => {
80
+ if (c.bases === "unmodelled")
81
+ return c.floorBases === undefined || floorAt === undefined ? c : { ...c, floorBases: moveFloor(c.floorBases, floorAt) };
82
+ if (c.bases.length === 0)
83
+ return c;
84
+ if (to === "unmodelled")
85
+ return floor === undefined ? { ...c, bases: "unmodelled" } : { ...c, bases: "unmodelled", floorBases: moveFloor(c.bases, floor) };
86
+ return { ...c, bases: [...new Set(c.bases.flatMap(moveBase))] };
87
+ };
88
+ return {
89
+ ...plan,
90
+ segments: plan.segments.map((s) => ({
91
+ ...s,
92
+ reads: s.reads.map(moveCandidate),
93
+ redirects: s.redirects.map((r) => (r.target === undefined ? r : { ...r, target: moveCandidate(r.target) })),
94
+ ...(s.baseMove !== undefined ? { baseMove: { target: typeof s.baseMove.target === "string" ? s.baseMove.target : moveCandidate(s.baseMove.target) } } : {}),
95
+ bases: s.bases === "unmodelled" || to === "unmodelled" ? "unmodelled" : [...new Set(s.bases.flatMap(moveBase))],
96
+ nested: s.nested.map((n) => rebasePlan(n, from, to, floor)),
97
+ })),
98
+ };
99
+ }
@@ -18,7 +18,7 @@ export interface Read {
18
18
  readonly raw: string;
19
19
  readonly folded: string;
20
20
  /** A pattern's names are matched by this spelling where it is not {@link folded} (a class the judge widens, read as
21
- * any one character — {@link LexedWord.judged}, {@link patternOf}); `folded` stays the name opened where none match. */
21
+ * any one character — {@link LexedWord.judged}, {@link judgedSpellingOf}); `folded` stays the name opened where none match. */
22
22
  readonly pattern?: string;
23
23
  readonly expands: WordExpands;
24
24
  /** The names the word refers to were read through the table: its expansion IS the spelling above (and, where the
@@ -38,17 +38,46 @@ export interface Read {
38
38
  /** The reads of a segment's words against the binding table at that segment (`homeDir` = the declared home, the
39
39
  * state `HOME` starts in). A word that refers to no name, or only to a `HOME` the text has not touched (`~/x`, placed
40
40
  * by the establishment at the declared home), reads as written. */
41
- export declare function readsOf(words: readonly LexedWord[], table: BindingTable | undefined, homeDir: string | undefined): Read[];
41
+ export declare function readsOf(words: readonly LexedWord[], table: BindingTable | undefined, homeDir: string | undefined, split?: boolean): Read[];
42
+ /** One reading of a segment: the binding table with each name its words read held to ONE value (or, past
43
+ * {@link READINGS_MAX}, made unknown — every value it held stays a deny-floor spelling, {@link BindingTable.floorOf}),
44
+ * the reads of its argv against it ({@link readsOf}), and the argv the shell hands the program in it — a word whose
45
+ * names settle into one value that is no pattern is that value, as a literal word (a reader of the program position,
46
+ * of a launcher's fields, of a program's options reads it as it reads a literal word); any other word as written, its
47
+ * names' deny floors in `floors` (a shell that re-reads the word — `sh -c`, `eval`, a launcher's shell — starts with
48
+ * them: the word names in that text what it names here). */
49
+ export interface SegmentReading {
50
+ readonly table: BindingTable;
51
+ readonly reads: readonly Read[];
52
+ readonly argv: readonly LexedWord[];
53
+ readonly floors: ReadonlyMap<string, readonly FloorValue[]>;
54
+ }
55
+ /**
56
+ * The readings of one segment's words (its argv and its redirection targets): the names they read through the table that
57
+ * may hold several values here, in the order the words read them (the program position first), each held to one value
58
+ * per reading — every combination while the readings stay within {@link READINGS_MAX}, so the program position, a
59
+ * launcher's fields, a re-entered text and an operand are spelled from the same values (`$P` read twice takes one value
60
+ * in a reading: the shell expands both alike); a name past that bound is unknown in every reading — its word as written,
61
+ * every value it held a deny floor — never a sample of its combinations. A segment whose names hold one value each has
62
+ * one reading.
63
+ */
64
+ export declare function segmentReadingsOf(argv: readonly LexedWord[], targets: readonly LexedWord[], table: BindingTable, homeDir: string | undefined): SegmentReading[];
42
65
  /** The spelling a reader names a value by, read directly as a path — for a pattern, the name the program opens where it
43
66
  * matches nothing: its text, a leading `~` spelled as the literal tilde it is ({@link literalTildeSpelling}, the lexer's
44
67
  * spelling of a written one) — the shell never tilde-expands what a quoted piece or an expansion produced, so a value that
45
68
  * starts with `~` starts with a literal one (`X=/w; rm \~$X/*` reads `./~/w/*`, as `rm \~/w/*` does). A shell that
46
69
  * re-parses the value reads {@link programTextOf} instead. */
47
70
  export declare const spellingOf: (v: BoundValue) => string;
48
- /** The spelling a pattern value's names are matched by, where it is not {@link spellingOf}: its runs as a reader judges
49
- * them (a class the judge widens as `?`, the lexer's `WordExpansion.pattern.judged`) — a candidate's
50
- * `pattern`. */
51
- export declare function patternOf(v: BoundValue): string | undefined;
71
+ /** The pattern a PART of a pattern word is matched by (an option value attached to its option word, `--file=["!"a]*`; an
72
+ * assignment-shaped word's value, `if=["!"a]*`): the word's own judged spelling (`pattern`) past the text in front of
73
+ * the part — bash expands the WHOLE word, so the names the part may take are those the word's widened spelling reaches
74
+ * (a superset: a name is judged whether or not the word in front of it matches too). `undefined` where the word carries
75
+ * none, the part is not the end of the word's spelling, or the text in front holds a widened class itself (its judged
76
+ * spelling no longer lines up). */
77
+ export declare function partPattern(word: {
78
+ readonly folded: string;
79
+ readonly pattern?: string;
80
+ }, part: string): string | undefined;
52
81
  /** A candidate under another name (a value of several, a backup, a copy's child): the word's `pattern` matched the word,
53
82
  * not that name — the name is matched by its own text. */
54
83
  export declare function renamed<C extends {
@@ -1,13 +1,13 @@
1
1
  import { argvOf, lexShell, literalTildeSpelling, UNRESOLVED_SENTENCE } from "../../shell/lex.js";
2
2
  import { expansionInWord, extglobOpenerIn, globInWord, homeExpansionOf } from "./bash-readonly-classifier.js";
3
- import { wordFloorValues, wordValues } from "./shell-read-bindings.js";
4
- export function readsOf(words, table, homeDir) {
3
+ import { floorOf, judgedSpellingOf, namesIn, wordFloorValues, wordValues } from "./shell-read-bindings.js";
4
+ export function readsOf(words, table, homeDir, split = false) {
5
5
  return words.map((word) => {
6
- const refersToName = word.pieces.some((p) => p.expansion?.kind === "parameter");
6
+ const refersToName = word.pieces.some((p) => p.expansion?.kind === "parameter") || namesIn(word).length > 0;
7
7
  const asWritten = { word, raw: word.raw, folded: word.folded, ...(word.judged !== undefined ? { pattern: word.judged } : {}) };
8
8
  if (!refersToName && table?.homeTouched !== true)
9
9
  return { ...asWritten, expands: expandsOf(word) };
10
- const values = wordValues(word, table, false);
10
+ const values = wordValues(word, table, false, undefined, split);
11
11
  if (values === undefined)
12
12
  return { ...asWritten, expands: expandsOf(word) };
13
13
  if (values === "unknown") {
@@ -18,7 +18,7 @@ export function readsOf(words, table, homeDir) {
18
18
  const refersToHome = word.pieces.some((p) => p.expansion?.kind === "tilde" || (p.expansion?.kind === "parameter" && p.expansion.name === "HOME"));
19
19
  const declared = refersToHome && homeDir !== undefined && table?.homeTouched === true ? wordValues(word, table, false, new Map([["HOME", [{ spelled: homeDir }]]])) : undefined;
20
20
  const floor = declared !== undefined && declared !== "unknown" && declared[0] !== undefined ? spellingOf(declared[0]) : undefined;
21
- const pattern = patternOf(values[0]);
21
+ const pattern = judgedSpellingOf(values[0]);
22
22
  return {
23
23
  word,
24
24
  raw: word.raw,
@@ -31,12 +31,92 @@ export function readsOf(words, table, homeDir) {
31
31
  };
32
32
  });
33
33
  }
34
+ const READINGS_MAX = 64;
35
+ export function segmentReadingsOf(argv, targets, table, homeDir) {
36
+ const several = new Map();
37
+ for (const word of [...argv, ...targets]) {
38
+ for (const name of namesReadIn(word, table)) {
39
+ const state = table.stateOf(name);
40
+ if (state !== "unknown" && state.length > 1)
41
+ several.set(name, state);
42
+ }
43
+ }
44
+ let overlays = [new Map()];
45
+ const past = [];
46
+ for (const [name, values] of several) {
47
+ if (past.length > 0 || overlays.length * values.length > READINGS_MAX) {
48
+ past.push(name);
49
+ continue;
50
+ }
51
+ overlays = overlays.flatMap((o) => values.map((v) => new Map(o).set(name, [v])));
52
+ }
53
+ for (const o of overlays)
54
+ for (const name of past)
55
+ o.set(name, "unknown");
56
+ return overlays.map((overlay) => {
57
+ const reading = overlay.size === 0 ? table : overlaidTable(table, overlay);
58
+ const fielded = readsOf(argv, reading, homeDir, true).flatMap((r) => {
59
+ const fields = r.values?.length === 1 ? r.values[0].fields : undefined;
60
+ return fields === undefined ? [r] : fields.map((f) => ({ word: argumentWordOf(f, f) ?? r.word, raw: f, folded: spellingOf({ spelled: f }), expands: false, settled: true, values: [{ spelled: f }] }));
61
+ });
62
+ const floors = new Map();
63
+ for (const r of fielded) {
64
+ if (r.settled === true)
65
+ continue;
66
+ for (const p of r.word.pieces) {
67
+ const name = p.expansion?.kind === "parameter" ? p.expansion.name : undefined;
68
+ if (name === undefined)
69
+ continue;
70
+ const held = reading.stateOf(name);
71
+ const floor = [...(held === "unknown" ? [] : held.map(floorOf)), ...reading.floorOf(name)];
72
+ if (floor.length > 0)
73
+ floors.set(name, floor);
74
+ }
75
+ }
76
+ return { table: reading, reads: fielded, argv: fielded.map((r) => valuedWord(r.word, r)), floors };
77
+ });
78
+ }
79
+ function namesReadIn(word, table) {
80
+ return [...namesIn(word), ...(table.homeTouched && word.pieces.some((p) => p.expansion?.kind === "tilde" && p.expansion.body === "~") ? ["HOME"] : [])];
81
+ }
82
+ function overlaidTable(table, overlay) {
83
+ return {
84
+ stateOf: (name) => overlay.get(name) ?? table.stateOf(name),
85
+ isInteger: (name) => table.isInteger(name),
86
+ ifsTouched: table.ifsTouched,
87
+ homeTouched: table.homeTouched,
88
+ rebound: table.rebound,
89
+ providedByShell: (name) => table.providedByShell(name),
90
+ functionState: (name) => table.functionState(name),
91
+ builtinState: (name) => table.builtinState(name),
92
+ floorOf: (name) => {
93
+ const held = table.stateOf(name);
94
+ return overlay.get(name) !== "unknown" || held === "unknown" ? table.floorOf(name) : [...table.floorOf(name), ...held.map(floorOf)];
95
+ },
96
+ inherited: table.inherited,
97
+ };
98
+ }
99
+ function valuedWord(word, r) {
100
+ const v = r.values?.length === 1 ? r.values[0] : undefined;
101
+ if (word.assignment !== undefined || v === undefined || v.glob === true || v.spelled === word.folded)
102
+ return word;
103
+ return argumentWordOf(v.spelled, r.raw) ?? word;
104
+ }
105
+ function argumentWordOf(text, raw) {
106
+ const quoted = text.replace(/[^A-Za-z0-9_./+@:%=,-]/g, (c) => (c === "'" ? "\\'" : `'${c}'`));
107
+ const lexed = lexShell(`: ${quoted === "" ? "''" : quoted}`);
108
+ const words = "parseFailure" in lexed || lexed.segments.length !== 1 ? undefined : argvOf(lexed.segments[0]);
109
+ return words?.length === 2 ? { ...words[1], raw } : undefined;
110
+ }
34
111
  export const spellingOf = (v) => literalTildeSpelling(v.spelled);
35
- export function patternOf(v) {
36
- if (v.glob !== true)
112
+ export function partPattern(word, part) {
113
+ if (word.pattern === undefined || part === word.folded || !word.folded.endsWith(part))
114
+ return undefined;
115
+ const front = word.folded.slice(0, word.folded.length - part.length);
116
+ if (!word.pattern.startsWith(front))
37
117
  return undefined;
38
- const judged = literalTildeSpelling(v.parts.map((p) => (p.pattern ? p.judged : p.text)).join(""));
39
- return judged === spellingOf(v) ? undefined : judged;
118
+ const judged = word.pattern.slice(front.length);
119
+ return judged === part ? undefined : judged;
40
120
  }
41
121
  export function renamed(c, spelled) {
42
122
  const { pattern: _matched, ...rest } = c;
@@ -0,0 +1,156 @@
1
+ /**
2
+ * THE WORKING-DIRECTORY THREAD — where a command stands at each of its segments, and what `PWD` / `OLDPWD` hold there.
3
+ * ONE walk (`shell-read-plan.ts` drives it, segment by segment, beside the binding thread) over a CLOSED word set that
4
+ * moves the base ({@link BaseShift}): `cd` in its forms — a bare relative target searched through `CDPATH` first, `cd -`
5
+ * going to `OLDPWD`, a bare `cd` to `HOME`, `-P` / `set -P` leaving `PWD` a spelling the text does not hold — `pushd` /
6
+ * `popd` with the stack the text pushed, and a literal `eval` text read as the text it is, in this shell. Any other text
7
+ * that may move the base where the plan cannot follow it (`source`, a non-literal `eval`, a computed program word, a
8
+ * call into a function body or a code body that may move, an option the stack reading does not follow) LOSES it: what
9
+ * stands after it cannot be placed. A move inside a subshell, a pipeline member or a function body nobody called is read
10
+ * as a move too — a candidate SET, more places, never fewer (a move may also fail: the unmoved place stays a candidate
11
+ * unless an `&&` run proves the move ran).
12
+ */
13
+ import type { Bare } from "./shell-read-argv.js";
14
+ import type { BindingTable, WorkingDirectoryState } from "./shell-read-bindings.js";
15
+ import type { Read } from "./shell-read-word.js";
16
+ import { type LexedWord } from "../../shell/lex.js";
17
+ import { type FunctionCall } from "./shell-read-functions.js";
18
+ /** A working directory the shell could be standing in, with the latest move this candidate assumes did NOT run
19
+ * (`skippedCd`), and what the shell holds there: `pwd` — what `PWD` spells (absent: not the base's spelling — a physical
20
+ * move, or a start the plan does not place), `old` — what `OLDPWD` holds (absent: what the shell inherited, unknown),
21
+ * `stack` — the directories the text pushed and has not popped, top first (absent: the text changed the stack in a way
22
+ * this walk does not follow; what lies below the text's own entries is the shell's, unknown). */
23
+ export interface BaseCandidate {
24
+ readonly base: string;
25
+ readonly skippedCd: number;
26
+ readonly pwd?: string;
27
+ readonly old?: string;
28
+ readonly dirStack?: readonly string[];
29
+ }
30
+ /** How one segment moves the base — the closed word set. `cd`: a `cd` (`push`: a `pushd DIR`) to a target, the
31
+ * declared-home spelling of an unsettled target for the deny floor; `swap`: `pushd` with no directory; `pop`: `popd`;
32
+ * `stack`: the stack changes and the base does not (`pushd -n`, `popd -n`, `dirs -c`); `eval`: a literal `eval` text;
33
+ * `lost`: a move this walk does not follow. */
34
+ export type BaseShift = {
35
+ readonly kind: "cd";
36
+ readonly target: Bare | "home" | "previous";
37
+ readonly physical: boolean;
38
+ readonly push?: true;
39
+ } | {
40
+ readonly kind: "swap" | "pop" | "stack" | "lost";
41
+ } | {
42
+ readonly kind: "eval";
43
+ readonly text: string;
44
+ };
45
+ /** What the walk asks of the plan around it: the declared home (a `~` target), whether the text binds a name anywhere
46
+ * (`OLDPWD` — then `cd -` reads the table's value; `PWD` — then a move's `OLDPWD` is not the base the candidate stood
47
+ * in), and where a literal `eval` text started at a candidate ends ({@link WorkdirThread.end}). */
48
+ export interface WorkdirContext {
49
+ readonly homeDir?: string;
50
+ readonly textBinds: (name: string) => boolean;
51
+ readonly evalEnd: (text: string, from: BaseCandidate, table: BindingTable) => {
52
+ readonly end: readonly BaseCandidate[] | "unmodelled";
53
+ readonly physical: boolean;
54
+ };
55
+ }
56
+ /** One segment's move as the walk applies it: the shift, whether an `&&` run proves it ran, the first segment of the
57
+ * reader's `&&` run, the names there, and whether `cdable_vars` may be on (a bare name may be a variable's value). */
58
+ export interface ShiftAt {
59
+ readonly shift: BaseShift;
60
+ readonly provable: boolean;
61
+ readonly andRunStart: number;
62
+ readonly table: CommandTable;
63
+ readonly cdable: boolean;
64
+ }
65
+ /** The names at a `cd` segment with the command's own prefix assignments in force (`HOME=/ cd`), and which names those are. */
66
+ export interface CommandTable extends BindingTable {
67
+ readonly commandSets: ReadonlySet<string>;
68
+ }
69
+ export declare class WorkdirThread {
70
+ /** The start is where the shell stands (not a placeholder a nested plan is re-based from): `PWD` reads it. */
71
+ private readonly readable;
72
+ private candidates;
73
+ private lostAt;
74
+ /** The reachable bases at the moment the walk lost track — the deny floor of a word it cannot place. */
75
+ private floors;
76
+ /** `set -P` (or `-o physical`) may be on — a text it began in, an `eval` text that set it — : a later move leaves `PWD` a physical
77
+ * spelling the text does not hold, and a `..` in a target resolves links the plan cannot see. */
78
+ private physical;
79
+ /** The last segment whose move was applied or lost track ({@link WorkingDirectoryState.movedAt}). */
80
+ private movedAt;
81
+ constructor(start: readonly BaseCandidate[] | readonly string[] | "unmodelled",
82
+ /** The start is where the shell stands (not a placeholder a nested plan is re-based from): `PWD` reads it. */
83
+ readable: boolean,
84
+ /** The physical mode may already be on where the text starts (an `eval` text run in a shell that set it). */
85
+ startsPhysical?: boolean);
86
+ get lost(): boolean;
87
+ get floorBases(): readonly string[] | undefined;
88
+ /** The candidates a reader whose `&&` run starts at `andRunStart` may stand in. */
89
+ reachable(andRunStart: number): readonly BaseCandidate[];
90
+ /** Where the text ends: every candidate, or `unmodelled`. */
91
+ end(): readonly BaseCandidate[] | "unmodelled";
92
+ /** What `PWD` / `OLDPWD` hold for a reader whose `&&` run starts at `andRunStart`. */
93
+ where(andRunStart: number): WorkingDirectoryState;
94
+ /** `set -P` / `set -o physical`: from here on a move's `PWD` is a physical spelling. */
95
+ setPhysical(): void;
96
+ /** Where the text ends the physical mode may be on (an `eval` text hands it back to the shell that ran it). */
97
+ get mayBePhysical(): boolean;
98
+ /** Stop placing anything from segment `at` on: the reachable bases (and a target's floor spellings) become the deny floor. */
99
+ lose(at: number, reachable: readonly BaseCandidate[], floorTargets?: readonly string[]): void;
100
+ /** Apply segment `si`'s move. */
101
+ shift(si: number, at: ShiftAt, ctx: WorkdirContext): void;
102
+ /** Where one candidate goes: the places (the CDPATH entries a bare target is searched through, then the target itself),
103
+ * each with the `PWD`, `OLDPWD` and stack the move leaves — or `lost`. */
104
+ private movedFrom;
105
+ }
106
+ /** Does bash search `CDPATH` for this `cd` target: not an absolute one, not `.` / `..`, not one starting `./` / `../`? */
107
+ export declare function searchesCdPath(dir: string): boolean;
108
+ /** The base shift of a `cd` / `pushd` / `popd` / `dirs` segment, read off its arguments as the program receives them (and
109
+ * the move the plan reports for it: a `cd` target, or `unmodelled` for a stack move it cannot name), or `undefined` for
110
+ * another program. `targetOf` turns the target word into its candidate (and records it as a read where the caller does). */
111
+ export declare function baseShiftOf(program: string, args: readonly Read[], targetOf: (r: Read) => Bare): {
112
+ shift: BaseShift;
113
+ reported?: Bare | "home" | "previous" | "unmodelled";
114
+ } | undefined;
115
+ /** May this text move the base of the shell that runs it: a program of the closed set or one running text in this shell,
116
+ * a computed program word, a call into one of `functions` — or text the lexer cannot read? */
117
+ export declare function textMayMove(text: string, functions: ReadonlySet<string>): boolean;
118
+ /** Does this text turn the physical mode on in the shell that runs it? An `eval` text that does is no text to skip. */
119
+ export declare function textSetsPhysical(text: string): boolean;
120
+ /** The table a `cd` / `pushd` reads `HOME`, `CDPATH` and `OLDPWD` from: the segment's own, with each prefix assignment in
121
+ * front of the builtin (`HOME=/ cd`, `CDPATH=/ cd usr`) holding its value there — it is in the builtin's environment. A
122
+ * prefix value naming an earlier prefix's name (`HOME=/ CDPATH=$HOME cd usr`) reads it as bash 5 does (the earlier
123
+ * assignment applied) and as bash 3.2 does (the value before the command): both. */
124
+ export declare function withCommandEnvironment(table: BindingTable, argv: readonly LexedWord[]): CommandTable;
125
+ /** Does this text call one of `functions` (a program word naming one) — or is it text the lexer cannot read? */
126
+ export declare function textCalls(text: string, functions: ReadonlySet<string>): boolean;
127
+ /** May a segment with these words move the base ({@link textMayMove})? */
128
+ export declare function segmentMayMove(argv: readonly LexedWord[], functions: ReadonlySet<string>): boolean;
129
+ /** What the walk reads of a whole text before it walks it: the text's functions (the names a program word can be one of;
130
+ * whether it IS one at a segment is the binding thread's answer, `callAt`); per segment whether it may move the base
131
+ * ({@link segmentMayMove}), may call a function, runs code bodies later (`trap`, `alias`, …), turns on the physical mode
132
+ * (`set -P`, `set -o physical`); whether a function body may move the base; where `cdable_vars` goes on. */
133
+ export interface TextMoves {
134
+ readonly functions: ReadonlySet<string>;
135
+ /** The names whose bodies the plan has not read (an `eval` text defined them). */
136
+ readonly unread: ReadonlySet<string>;
137
+ readonly mayMove: readonly boolean[];
138
+ /** Segment `si` may call a function (read before the walk, to bound where bodies run). */
139
+ readonly mayCallAt: readonly boolean[];
140
+ /** Segment `si` may run a function body: it may call one, hands a code body to run later, or runs text the plan does not read. */
141
+ readonly runsBodyAt: readonly boolean[];
142
+ readonly bodiesAt: readonly (readonly string[])[];
143
+ readonly physicalAt: readonly boolean[];
144
+ readonly cdableFrom: number;
145
+ readonly bodyMoves: boolean;
146
+ /** The function segment `si`'s program word names where the walk stands (`table`) — {@link functionCallOf}. */
147
+ callAt(si: number, table: BindingTable): FunctionCall | undefined;
148
+ /** The segment may call a function a literal `eval` text defined: its body is not read — it may move the base and bind any name. */
149
+ callsUnread(si: number, table: BindingTable): boolean;
150
+ /** The segment runs a body that may move the base where the walk cannot follow it: a call when a body may move or whose body is not read, a code body that may move or call one. */
151
+ losesBaseAt(si: number, table: BindingTable): boolean;
152
+ }
153
+ export declare function textMovesOf(defined: ReadonlySet<string>, argvs: readonly (readonly LexedWord[])[], inFunctionBody: (si: number) => boolean, inherited?: {
154
+ readonly functions: ReadonlySet<string>;
155
+ readonly unread: ReadonlySet<string>;
156
+ }): TextMoves;