@animalabs/agent-framework 0.22.1 → 0.22.3

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 (946) hide show
  1. package/README.md +4 -2
  2. package/dist/src/agent.d.ts +266 -28
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +539 -104
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server-core.d.ts +41 -0
  7. package/dist/src/api/mcp-server-core.d.ts.map +1 -0
  8. package/dist/src/api/mcp-server-core.js +593 -0
  9. package/dist/src/api/mcp-server-core.js.map +1 -0
  10. package/dist/src/api/mcp-server.d.ts +2 -36
  11. package/dist/src/api/mcp-server.d.ts.map +1 -1
  12. package/dist/src/api/mcp-server.js +15 -595
  13. package/dist/src/api/mcp-server.js.map +1 -1
  14. package/dist/src/api/server.d.ts +9 -1
  15. package/dist/src/api/server.d.ts.map +1 -1
  16. package/dist/src/api/server.js +55 -27
  17. package/dist/src/api/server.js.map +1 -1
  18. package/dist/src/api/types.d.ts +10 -2
  19. package/dist/src/api/types.d.ts.map +1 -1
  20. package/dist/src/branch-names.d.ts +14 -0
  21. package/dist/src/branch-names.d.ts.map +1 -0
  22. package/dist/src/branch-names.js +22 -0
  23. package/dist/src/branch-names.js.map +1 -0
  24. package/dist/src/closest-names.d.ts +28 -0
  25. package/dist/src/closest-names.d.ts.map +1 -0
  26. package/dist/src/closest-names.js +98 -0
  27. package/dist/src/closest-names.js.map +1 -0
  28. package/dist/src/code-execution/py-runner.d.ts +16 -5
  29. package/dist/src/code-execution/py-runner.d.ts.map +1 -1
  30. package/dist/src/code-execution/py-runner.js +186 -74
  31. package/dist/src/code-execution/py-runner.js.map +1 -1
  32. package/dist/src/code-execution/runtime-py.d.ts.map +1 -1
  33. package/dist/src/code-execution/runtime-py.js +49 -3
  34. package/dist/src/code-execution/runtime-py.js.map +1 -1
  35. package/dist/src/code-execution/tool-definition.d.ts +12 -1
  36. package/dist/src/code-execution/tool-definition.d.ts.map +1 -1
  37. package/dist/src/code-execution/tool-definition.js +21 -3
  38. package/dist/src/code-execution/tool-definition.js.map +1 -1
  39. package/dist/src/config-checks.d.ts +28 -0
  40. package/dist/src/config-checks.d.ts.map +1 -0
  41. package/dist/src/config-checks.js +52 -0
  42. package/dist/src/config-checks.js.map +1 -0
  43. package/dist/src/deadline-timer.d.ts +21 -0
  44. package/dist/src/deadline-timer.d.ts.map +1 -0
  45. package/dist/src/deadline-timer.js +43 -0
  46. package/dist/src/deadline-timer.js.map +1 -0
  47. package/dist/src/error-message.d.ts +30 -0
  48. package/dist/src/error-message.d.ts.map +1 -0
  49. package/dist/src/error-message.js +50 -0
  50. package/dist/src/error-message.js.map +1 -0
  51. package/dist/src/framework.d.ts +1212 -192
  52. package/dist/src/framework.d.ts.map +1 -1
  53. package/dist/src/framework.js +6686 -1835
  54. package/dist/src/framework.js.map +1 -1
  55. package/dist/src/gate/event-gate.d.ts +8 -0
  56. package/dist/src/gate/event-gate.d.ts.map +1 -1
  57. package/dist/src/gate/event-gate.js +27 -3
  58. package/dist/src/gate/event-gate.js.map +1 -1
  59. package/dist/src/gate/gate-script.d.ts.map +1 -1
  60. package/dist/src/gate/gate-script.js.map +1 -1
  61. package/dist/src/index.d.ts +5 -3
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +5 -3
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/mcpl/capability-grant.d.ts.map +1 -1
  66. package/dist/src/mcpl/channel-registry.d.ts +170 -13
  67. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  68. package/dist/src/mcpl/channel-registry.js +499 -258
  69. package/dist/src/mcpl/channel-registry.js.map +1 -1
  70. package/dist/src/mcpl/checkpoint-manager.d.ts +21 -1
  71. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -1
  72. package/dist/src/mcpl/checkpoint-manager.js +91 -30
  73. package/dist/src/mcpl/checkpoint-manager.js.map +1 -1
  74. package/dist/src/mcpl/conversation-router.d.ts +19 -3
  75. package/dist/src/mcpl/conversation-router.d.ts.map +1 -1
  76. package/dist/src/mcpl/conversation-router.js +23 -8
  77. package/dist/src/mcpl/conversation-router.js.map +1 -1
  78. package/dist/src/mcpl/convert-block.d.ts +20 -0
  79. package/dist/src/mcpl/convert-block.d.ts.map +1 -0
  80. package/dist/src/mcpl/convert-block.js +89 -0
  81. package/dist/src/mcpl/convert-block.js.map +1 -0
  82. package/dist/src/mcpl/errors.d.ts +13 -0
  83. package/dist/src/mcpl/errors.d.ts.map +1 -1
  84. package/dist/src/mcpl/errors.js +28 -0
  85. package/dist/src/mcpl/errors.js.map +1 -1
  86. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -1
  87. package/dist/src/mcpl/feature-set-manager.js +4 -3
  88. package/dist/src/mcpl/feature-set-manager.js.map +1 -1
  89. package/dist/src/mcpl/hook-orchestrator.d.ts +23 -0
  90. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
  91. package/dist/src/mcpl/hook-orchestrator.js +83 -72
  92. package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
  93. package/dist/src/mcpl/inbound-source.d.ts +114 -0
  94. package/dist/src/mcpl/inbound-source.d.ts.map +1 -0
  95. package/dist/src/mcpl/inbound-source.js +83 -0
  96. package/dist/src/mcpl/inbound-source.js.map +1 -0
  97. package/dist/src/mcpl/index.d.ts +3 -1
  98. package/dist/src/mcpl/index.d.ts.map +1 -1
  99. package/dist/src/mcpl/index.js +3 -1
  100. package/dist/src/mcpl/index.js.map +1 -1
  101. package/dist/src/mcpl/inference-router.d.ts +15 -11
  102. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  103. package/dist/src/mcpl/inference-router.js +153 -84
  104. package/dist/src/mcpl/inference-router.js.map +1 -1
  105. package/dist/src/mcpl/log-value.d.ts +54 -0
  106. package/dist/src/mcpl/log-value.d.ts.map +1 -0
  107. package/dist/src/mcpl/log-value.js +109 -0
  108. package/dist/src/mcpl/log-value.js.map +1 -0
  109. package/dist/src/mcpl/prose-stream-router.d.ts +6 -6
  110. package/dist/src/mcpl/prose-stream-router.d.ts.map +1 -1
  111. package/dist/src/mcpl/prose-stream-router.js +4 -4
  112. package/dist/src/mcpl/prose-stream-router.js.map +1 -1
  113. package/dist/src/mcpl/push-coalescer.d.ts +64 -7
  114. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  115. package/dist/src/mcpl/push-coalescer.js +121 -24
  116. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  117. package/dist/src/mcpl/push-handler.d.ts +38 -8
  118. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  119. package/dist/src/mcpl/push-handler.js +77 -78
  120. package/dist/src/mcpl/push-handler.js.map +1 -1
  121. package/dist/src/mcpl/reference-fetcher.d.ts +14 -2
  122. package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
  123. package/dist/src/mcpl/reference-fetcher.js +72 -30
  124. package/dist/src/mcpl/reference-fetcher.js.map +1 -1
  125. package/dist/src/mcpl/references.d.ts +49 -14
  126. package/dist/src/mcpl/references.d.ts.map +1 -1
  127. package/dist/src/mcpl/references.js +74 -21
  128. package/dist/src/mcpl/references.js.map +1 -1
  129. package/dist/src/mcpl/refusal-lines.d.ts +37 -0
  130. package/dist/src/mcpl/refusal-lines.d.ts.map +1 -0
  131. package/dist/src/mcpl/refusal-lines.js +61 -0
  132. package/dist/src/mcpl/refusal-lines.js.map +1 -0
  133. package/dist/src/mcpl/scope-manager.d.ts.map +1 -1
  134. package/dist/src/mcpl/server-connection.d.ts +107 -12
  135. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  136. package/dist/src/mcpl/server-connection.js +470 -139
  137. package/dist/src/mcpl/server-connection.js.map +1 -1
  138. package/dist/src/mcpl/server-registry.d.ts +10 -1
  139. package/dist/src/mcpl/server-registry.d.ts.map +1 -1
  140. package/dist/src/mcpl/server-registry.js +14 -3
  141. package/dist/src/mcpl/server-registry.js.map +1 -1
  142. package/dist/src/mcpl/skip-reply-wake.d.ts +36 -0
  143. package/dist/src/mcpl/skip-reply-wake.d.ts.map +1 -0
  144. package/dist/src/mcpl/skip-reply-wake.js +55 -0
  145. package/dist/src/mcpl/skip-reply-wake.js.map +1 -0
  146. package/dist/src/mcpl/tool-classes.d.ts +1 -1
  147. package/dist/src/mcpl/tool-classes.d.ts.map +1 -1
  148. package/dist/src/mcpl/tool-classes.js +3 -2
  149. package/dist/src/mcpl/tool-classes.js.map +1 -1
  150. package/dist/src/mcpl/tool-lifecycle.d.ts.map +1 -1
  151. package/dist/src/mcpl/tool-lifecycle.js.map +1 -1
  152. package/dist/src/mcpl/transport.d.ts +74 -7
  153. package/dist/src/mcpl/transport.d.ts.map +1 -1
  154. package/dist/src/mcpl/transport.js +209 -22
  155. package/dist/src/mcpl/transport.js.map +1 -1
  156. package/dist/src/mcpl/types.d.ts +43 -28
  157. package/dist/src/mcpl/types.d.ts.map +1 -1
  158. package/dist/src/mcpl/types.js.map +1 -1
  159. package/dist/src/mcpl/visible-content.d.ts +15 -0
  160. package/dist/src/mcpl/visible-content.d.ts.map +1 -1
  161. package/dist/src/mcpl/visible-content.js +25 -0
  162. package/dist/src/mcpl/visible-content.js.map +1 -1
  163. package/dist/src/module-registry.d.ts +19 -1
  164. package/dist/src/module-registry.d.ts.map +1 -1
  165. package/dist/src/module-registry.js +54 -25
  166. package/dist/src/module-registry.js.map +1 -1
  167. package/dist/src/modules/api/index.d.ts.map +1 -1
  168. package/dist/src/modules/api/index.js +1 -1
  169. package/dist/src/modules/api/index.js.map +1 -1
  170. package/dist/src/modules/discord/discord-js-client.d.ts +1 -0
  171. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  172. package/dist/src/modules/discord/discord-js-client.js +25 -9
  173. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  174. package/dist/src/modules/discord/index.d.ts +29 -3
  175. package/dist/src/modules/discord/index.d.ts.map +1 -1
  176. package/dist/src/modules/discord/index.js +383 -145
  177. package/dist/src/modules/discord/index.js.map +1 -1
  178. package/dist/src/modules/discord/types.d.ts +14 -1
  179. package/dist/src/modules/discord/types.d.ts.map +1 -1
  180. package/dist/src/modules/health/index.d.ts.map +1 -1
  181. package/dist/src/modules/health/index.js +2 -1
  182. package/dist/src/modules/health/index.js.map +1 -1
  183. package/dist/src/modules/history/index.d.ts +3 -1
  184. package/dist/src/modules/history/index.d.ts.map +1 -1
  185. package/dist/src/modules/history/index.js +359 -127
  186. package/dist/src/modules/history/index.js.map +1 -1
  187. package/dist/src/modules/history/semantic.d.ts +28 -1
  188. package/dist/src/modules/history/semantic.d.ts.map +1 -1
  189. package/dist/src/modules/history/semantic.js +177 -32
  190. package/dist/src/modules/history/semantic.js.map +1 -1
  191. package/dist/src/modules/unknown-tool.d.ts +10 -0
  192. package/dist/src/modules/unknown-tool.d.ts.map +1 -0
  193. package/dist/src/modules/unknown-tool.js +17 -0
  194. package/dist/src/modules/unknown-tool.js.map +1 -0
  195. package/dist/src/modules/workspace/branch-intent.d.ts.map +1 -1
  196. package/dist/src/modules/workspace/branch-intent.js.map +1 -1
  197. package/dist/src/modules/workspace/disk-agreement.d.ts +54 -6
  198. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  199. package/dist/src/modules/workspace/disk-agreement.js +93 -27
  200. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  201. package/dist/src/modules/workspace/effects.d.ts +64 -6
  202. package/dist/src/modules/workspace/effects.d.ts.map +1 -1
  203. package/dist/src/modules/workspace/effects.js +291 -44
  204. package/dist/src/modules/workspace/effects.js.map +1 -1
  205. package/dist/src/modules/workspace/index.d.ts +127 -27
  206. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  207. package/dist/src/modules/workspace/index.js +821 -248
  208. package/dist/src/modules/workspace/index.js.map +1 -1
  209. package/dist/src/modules/workspace/observe.d.ts +117 -15
  210. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  211. package/dist/src/modules/workspace/observe.js +436 -51
  212. package/dist/src/modules/workspace/observe.js.map +1 -1
  213. package/dist/src/modules/workspace/reconcile.d.ts +75 -8
  214. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  215. package/dist/src/modules/workspace/reconcile.js +576 -68
  216. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  217. package/dist/src/modules/workspace/types.d.ts +42 -3
  218. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  219. package/dist/src/modules/workspace/types.js.map +1 -1
  220. package/dist/src/modules/workspace/watcher.d.ts +7 -2
  221. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  222. package/dist/src/modules/workspace/watcher.js +28 -4
  223. package/dist/src/modules/workspace/watcher.js.map +1 -1
  224. package/dist/src/operator-log.d.ts.map +1 -1
  225. package/dist/src/operator-log.js.map +1 -1
  226. package/dist/src/prose-drafts.d.ts +240 -0
  227. package/dist/src/prose-drafts.d.ts.map +1 -0
  228. package/dist/src/prose-drafts.js +362 -0
  229. package/dist/src/prose-drafts.js.map +1 -0
  230. package/dist/src/prose-segments.d.ts +21 -2
  231. package/dist/src/prose-segments.d.ts.map +1 -1
  232. package/dist/src/prose-segments.js +46 -9
  233. package/dist/src/prose-segments.js.map +1 -1
  234. package/dist/src/provider-waits.d.ts.map +1 -1
  235. package/dist/src/provider-waits.js.map +1 -1
  236. package/dist/src/queue.d.ts.map +1 -1
  237. package/dist/src/record-journal.d.ts.map +1 -1
  238. package/dist/src/record-journal.js.map +1 -1
  239. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  240. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  241. package/dist/src/recovery/offline-branch.d.ts +1 -0
  242. package/dist/src/recovery/offline-branch.d.ts.map +1 -1
  243. package/dist/src/recovery/offline-branch.js +32 -25
  244. package/dist/src/recovery/offline-branch.js.map +1 -1
  245. package/dist/src/recovery/recover-cli.js.map +1 -1
  246. package/dist/src/runtime/liveness-watchdog.d.ts.map +1 -1
  247. package/dist/src/runtime/liveness-watchdog.js.map +1 -1
  248. package/dist/src/safe-slice.d.ts +5 -1
  249. package/dist/src/safe-slice.d.ts.map +1 -1
  250. package/dist/src/safe-slice.js +9 -1
  251. package/dist/src/safe-slice.js.map +1 -1
  252. package/dist/src/shutdown.d.ts.map +1 -1
  253. package/dist/src/shutdown.js.map +1 -1
  254. package/dist/src/stored-removal.d.ts +73 -0
  255. package/dist/src/stored-removal.d.ts.map +1 -0
  256. package/dist/src/stored-removal.js +100 -0
  257. package/dist/src/stored-removal.js.map +1 -0
  258. package/dist/src/thinking-token-stamp.js.map +1 -1
  259. package/dist/src/tool-image-ledger.d.ts +87 -19
  260. package/dist/src/tool-image-ledger.d.ts.map +1 -1
  261. package/dist/src/tool-image-ledger.js +135 -32
  262. package/dist/src/tool-image-ledger.js.map +1 -1
  263. package/dist/src/tool-presentation.d.ts +9 -0
  264. package/dist/src/tool-presentation.d.ts.map +1 -1
  265. package/dist/src/tool-presentation.js +257 -60
  266. package/dist/src/tool-presentation.js.map +1 -1
  267. package/dist/src/tool-result-guard.d.ts.map +1 -1
  268. package/dist/src/tool-result-guard.js +7 -10
  269. package/dist/src/tool-result-guard.js.map +1 -1
  270. package/dist/src/tool-result-history.d.ts +32 -3
  271. package/dist/src/tool-result-history.d.ts.map +1 -1
  272. package/dist/src/tool-result-history.js +106 -19
  273. package/dist/src/tool-result-history.js.map +1 -1
  274. package/dist/src/tune-out/coordinator.d.ts +25 -1
  275. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  276. package/dist/src/tune-out/coordinator.js +260 -65
  277. package/dist/src/tune-out/coordinator.js.map +1 -1
  278. package/dist/src/tune-out/tools.d.ts +1 -1
  279. package/dist/src/tune-out/tools.d.ts.map +1 -1
  280. package/dist/src/types/agent.d.ts +59 -11
  281. package/dist/src/types/agent.d.ts.map +1 -1
  282. package/dist/src/types/events.d.ts +17 -0
  283. package/dist/src/types/events.d.ts.map +1 -1
  284. package/dist/src/types/framework.d.ts +31 -5
  285. package/dist/src/types/framework.d.ts.map +1 -1
  286. package/dist/src/types/inference-log.d.ts +1 -1
  287. package/dist/src/types/inference-log.d.ts.map +1 -1
  288. package/dist/src/types/module.d.ts +30 -7
  289. package/dist/src/types/module.d.ts.map +1 -1
  290. package/dist/src/types/trace.d.ts +151 -11
  291. package/dist/src/types/trace.d.ts.map +1 -1
  292. package/dist/src/usage/usage-tracker.d.ts +5 -0
  293. package/dist/src/usage/usage-tracker.d.ts.map +1 -1
  294. package/dist/src/usage/usage-tracker.js +35 -8
  295. package/dist/src/usage/usage-tracker.js.map +1 -1
  296. package/package.json +10 -9
  297. package/src/agent.ts +572 -105
  298. package/src/api/mcp-server-core.ts +681 -0
  299. package/src/api/mcp-server.ts +16 -685
  300. package/src/api/server.ts +55 -30
  301. package/src/api/types.ts +10 -2
  302. package/src/branch-names.ts +19 -0
  303. package/src/closest-names.ts +94 -0
  304. package/src/code-execution/py-runner.ts +200 -76
  305. package/src/code-execution/runtime-py.ts +49 -3
  306. package/src/code-execution/tool-definition.ts +28 -4
  307. package/src/config-checks.ts +48 -0
  308. package/src/deadline-timer.ts +44 -0
  309. package/src/error-message.ts +48 -0
  310. package/src/framework.ts +7158 -1936
  311. package/src/gate/event-gate.ts +28 -3
  312. package/src/index.ts +12 -3
  313. package/src/mcpl/channel-registry.ts +615 -289
  314. package/src/mcpl/checkpoint-manager.ts +104 -29
  315. package/src/mcpl/conversation-router.ts +28 -8
  316. package/src/mcpl/convert-block.ts +97 -0
  317. package/src/mcpl/errors.ts +28 -0
  318. package/src/mcpl/feature-set-manager.ts +4 -3
  319. package/src/mcpl/hook-orchestrator.ts +84 -77
  320. package/src/mcpl/inbound-source.ts +156 -0
  321. package/src/mcpl/index.ts +10 -1
  322. package/src/mcpl/inference-router.ts +174 -99
  323. package/src/mcpl/log-value.ts +116 -0
  324. package/src/mcpl/prose-stream-router.ts +6 -6
  325. package/src/mcpl/push-coalescer.ts +124 -24
  326. package/src/mcpl/push-handler.ts +86 -84
  327. package/src/mcpl/reference-fetcher.ts +71 -26
  328. package/src/mcpl/references.ts +81 -22
  329. package/src/mcpl/refusal-lines.ts +59 -0
  330. package/src/mcpl/server-connection.ts +496 -142
  331. package/src/mcpl/server-registry.ts +15 -4
  332. package/src/mcpl/skip-reply-wake.ts +73 -0
  333. package/src/mcpl/tool-classes.ts +3 -2
  334. package/src/mcpl/transport.ts +219 -26
  335. package/src/mcpl/types.ts +18 -3
  336. package/src/mcpl/visible-content.ts +27 -0
  337. package/src/module-registry.ts +58 -23
  338. package/src/modules/api/index.ts +1 -1
  339. package/src/modules/discord/discord-js-client.ts +26 -10
  340. package/src/modules/discord/index.ts +395 -160
  341. package/src/modules/discord/types.ts +15 -2
  342. package/src/modules/health/index.ts +2 -1
  343. package/src/modules/history/index.ts +410 -120
  344. package/src/modules/history/semantic.ts +189 -32
  345. package/src/modules/unknown-tool.ts +16 -0
  346. package/src/modules/workspace/disk-agreement.ts +125 -21
  347. package/src/modules/workspace/effects.ts +279 -35
  348. package/src/modules/workspace/index.ts +841 -261
  349. package/src/modules/workspace/observe.ts +456 -56
  350. package/src/modules/workspace/reconcile.ts +688 -76
  351. package/src/modules/workspace/types.ts +41 -2
  352. package/src/modules/workspace/watcher.ts +27 -4
  353. package/src/prose-drafts.ts +481 -0
  354. package/src/prose-segments.ts +51 -8
  355. package/src/recovery/offline-branch.ts +36 -29
  356. package/src/safe-slice.ts +9 -1
  357. package/src/stored-removal.ts +126 -0
  358. package/src/tool-image-ledger.ts +153 -34
  359. package/src/tool-presentation.ts +224 -40
  360. package/src/tool-result-guard.ts +7 -8
  361. package/src/tool-result-history.ts +124 -20
  362. package/src/tune-out/coordinator.ts +259 -65
  363. package/src/types/agent.ts +59 -13
  364. package/src/types/events.ts +17 -0
  365. package/src/types/framework.ts +31 -5
  366. package/src/types/inference-log.ts +1 -1
  367. package/src/types/module.ts +31 -7
  368. package/src/types/trace.ts +158 -12
  369. package/src/usage/usage-tracker.ts +32 -8
  370. package/dist/test/activation-request-sanitize.test.d.ts +0 -2
  371. package/dist/test/activation-request-sanitize.test.d.ts.map +0 -1
  372. package/dist/test/activation-request-sanitize.test.js +0 -89
  373. package/dist/test/activation-request-sanitize.test.js.map +0 -1
  374. package/dist/test/agent-cache-ttl.test.d.ts +0 -2
  375. package/dist/test/agent-cache-ttl.test.d.ts.map +0 -1
  376. package/dist/test/agent-cache-ttl.test.js +0 -41
  377. package/dist/test/agent-cache-ttl.test.js.map +0 -1
  378. package/dist/test/agent-runtime-settings.test.d.ts +0 -2
  379. package/dist/test/agent-runtime-settings.test.d.ts.map +0 -1
  380. package/dist/test/agent-runtime-settings.test.js +0 -462
  381. package/dist/test/agent-runtime-settings.test.js.map +0 -1
  382. package/dist/test/api-admin-gate.test.d.ts +0 -2
  383. package/dist/test/api-admin-gate.test.d.ts.map +0 -1
  384. package/dist/test/api-admin-gate.test.js +0 -116
  385. package/dist/test/api-admin-gate.test.js.map +0 -1
  386. package/dist/test/assistant-persist-refusal.test.d.ts +0 -2
  387. package/dist/test/assistant-persist-refusal.test.d.ts.map +0 -1
  388. package/dist/test/assistant-persist-refusal.test.js +0 -63
  389. package/dist/test/assistant-persist-refusal.test.js.map +0 -1
  390. package/dist/test/batched-wake-locus.test.d.ts +0 -2
  391. package/dist/test/batched-wake-locus.test.d.ts.map +0 -1
  392. package/dist/test/batched-wake-locus.test.js +0 -166
  393. package/dist/test/batched-wake-locus.test.js.map +0 -1
  394. package/dist/test/busy-agent-scheduler.test.d.ts +0 -2
  395. package/dist/test/busy-agent-scheduler.test.d.ts.map +0 -1
  396. package/dist/test/busy-agent-scheduler.test.js +0 -92
  397. package/dist/test/busy-agent-scheduler.test.js.map +0 -1
  398. package/dist/test/channel-incoming-targeting.test.d.ts +0 -2
  399. package/dist/test/channel-incoming-targeting.test.d.ts.map +0 -1
  400. package/dist/test/channel-incoming-targeting.test.js +0 -81
  401. package/dist/test/channel-incoming-targeting.test.js.map +0 -1
  402. package/dist/test/channel-label-history.test.d.ts +0 -2
  403. package/dist/test/channel-label-history.test.d.ts.map +0 -1
  404. package/dist/test/channel-label-history.test.js +0 -424
  405. package/dist/test/channel-label-history.test.js.map +0 -1
  406. package/dist/test/channel-lifecycle-provenance.test.d.ts +0 -2
  407. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +0 -1
  408. package/dist/test/channel-lifecycle-provenance.test.js +0 -47
  409. package/dist/test/channel-lifecycle-provenance.test.js.map +0 -1
  410. package/dist/test/channel-registry-routing.test.d.ts +0 -2
  411. package/dist/test/channel-registry-routing.test.d.ts.map +0 -1
  412. package/dist/test/channel-registry-routing.test.js +0 -446
  413. package/dist/test/channel-registry-routing.test.js.map +0 -1
  414. package/dist/test/channel-registry-typing.test.d.ts +0 -2
  415. package/dist/test/channel-registry-typing.test.d.ts.map +0 -1
  416. package/dist/test/channel-registry-typing.test.js +0 -91
  417. package/dist/test/channel-registry-typing.test.js.map +0 -1
  418. package/dist/test/channels-changed-respond-first.test.d.ts +0 -2
  419. package/dist/test/channels-changed-respond-first.test.d.ts.map +0 -1
  420. package/dist/test/channels-changed-respond-first.test.js +0 -74
  421. package/dist/test/channels-changed-respond-first.test.js.map +0 -1
  422. package/dist/test/checkpoint-attribution.test.d.ts +0 -2
  423. package/dist/test/checkpoint-attribution.test.d.ts.map +0 -1
  424. package/dist/test/checkpoint-attribution.test.js +0 -200
  425. package/dist/test/checkpoint-attribution.test.js.map +0 -1
  426. package/dist/test/code-execution.test.d.ts +0 -11
  427. package/dist/test/code-execution.test.d.ts.map +0 -1
  428. package/dist/test/code-execution.test.js +0 -1272
  429. package/dist/test/code-execution.test.js.map +0 -1
  430. package/dist/test/component-defaults.test.d.ts +0 -2
  431. package/dist/test/component-defaults.test.d.ts.map +0 -1
  432. package/dist/test/component-defaults.test.js +0 -54
  433. package/dist/test/component-defaults.test.js.map +0 -1
  434. package/dist/test/conversation-fork-injection-scoping.test.d.ts +0 -2
  435. package/dist/test/conversation-fork-injection-scoping.test.d.ts.map +0 -1
  436. package/dist/test/conversation-fork-injection-scoping.test.js +0 -200
  437. package/dist/test/conversation-fork-injection-scoping.test.js.map +0 -1
  438. package/dist/test/conversation-router.test.d.ts +0 -2
  439. package/dist/test/conversation-router.test.d.ts.map +0 -1
  440. package/dist/test/conversation-router.test.js +0 -174
  441. package/dist/test/conversation-router.test.js.map +0 -1
  442. package/dist/test/conversation-routing.test.d.ts +0 -7
  443. package/dist/test/conversation-routing.test.d.ts.map +0 -1
  444. package/dist/test/conversation-routing.test.js +0 -387
  445. package/dist/test/conversation-routing.test.js.map +0 -1
  446. package/dist/test/deferred-wake-integrity.test.d.ts +0 -29
  447. package/dist/test/deferred-wake-integrity.test.d.ts.map +0 -1
  448. package/dist/test/deferred-wake-integrity.test.js +0 -320
  449. package/dist/test/deferred-wake-integrity.test.js.map +0 -1
  450. package/dist/test/discord-awareness-outbox.test.d.ts +0 -2
  451. package/dist/test/discord-awareness-outbox.test.d.ts.map +0 -1
  452. package/dist/test/discord-awareness-outbox.test.js +0 -267
  453. package/dist/test/discord-awareness-outbox.test.js.map +0 -1
  454. package/dist/test/discord-history-delete-window.test.d.ts +0 -2
  455. package/dist/test/discord-history-delete-window.test.d.ts.map +0 -1
  456. package/dist/test/discord-history-delete-window.test.js +0 -81
  457. package/dist/test/discord-history-delete-window.test.js.map +0 -1
  458. package/dist/test/discord-history-sync.test.d.ts +0 -2
  459. package/dist/test/discord-history-sync.test.d.ts.map +0 -1
  460. package/dist/test/discord-history-sync.test.js +0 -56
  461. package/dist/test/discord-history-sync.test.js.map +0 -1
  462. package/dist/test/ephemeral-settle.test.d.ts +0 -2
  463. package/dist/test/ephemeral-settle.test.d.ts.map +0 -1
  464. package/dist/test/ephemeral-settle.test.js +0 -354
  465. package/dist/test/ephemeral-settle.test.js.map +0 -1
  466. package/dist/test/event-gate-passthrough.test.d.ts +0 -15
  467. package/dist/test/event-gate-passthrough.test.d.ts.map +0 -1
  468. package/dist/test/event-gate-passthrough.test.js +0 -289
  469. package/dist/test/event-gate-passthrough.test.js.map +0 -1
  470. package/dist/test/event-gate-policy-mutation.test.d.ts +0 -2
  471. package/dist/test/event-gate-policy-mutation.test.d.ts.map +0 -1
  472. package/dist/test/event-gate-policy-mutation.test.js +0 -137
  473. package/dist/test/event-gate-policy-mutation.test.js.map +0 -1
  474. package/dist/test/event-gate-rate-limit.test.d.ts +0 -2
  475. package/dist/test/event-gate-rate-limit.test.d.ts.map +0 -1
  476. package/dist/test/event-gate-rate-limit.test.js +0 -627
  477. package/dist/test/event-gate-rate-limit.test.js.map +0 -1
  478. package/dist/test/event-gate-script.test.d.ts +0 -2
  479. package/dist/test/event-gate-script.test.d.ts.map +0 -1
  480. package/dist/test/event-gate-script.test.js +0 -95
  481. package/dist/test/event-gate-script.test.js.map +0 -1
  482. package/dist/test/event-gate-selfwake.test.d.ts +0 -15
  483. package/dist/test/event-gate-selfwake.test.d.ts.map +0 -1
  484. package/dist/test/event-gate-selfwake.test.js +0 -125
  485. package/dist/test/event-gate-selfwake.test.js.map +0 -1
  486. package/dist/test/event-gate-tags.test.d.ts +0 -2
  487. package/dist/test/event-gate-tags.test.d.ts.map +0 -1
  488. package/dist/test/event-gate-tags.test.js +0 -76
  489. package/dist/test/event-gate-tags.test.js.map +0 -1
  490. package/dist/test/event-gate.test.d.ts +0 -2
  491. package/dist/test/event-gate.test.d.ts.map +0 -1
  492. package/dist/test/event-gate.test.js +0 -919
  493. package/dist/test/event-gate.test.js.map +0 -1
  494. package/dist/test/explicit-prose-routing.test.d.ts +0 -11
  495. package/dist/test/explicit-prose-routing.test.d.ts.map +0 -1
  496. package/dist/test/explicit-prose-routing.test.js +0 -1394
  497. package/dist/test/explicit-prose-routing.test.js.map +0 -1
  498. package/dist/test/framework.test.d.ts +0 -5
  499. package/dist/test/framework.test.d.ts.map +0 -1
  500. package/dist/test/framework.test.js +0 -1048
  501. package/dist/test/framework.test.js.map +0 -1
  502. package/dist/test/gather-context-timeout.test.d.ts +0 -2
  503. package/dist/test/gather-context-timeout.test.d.ts.map +0 -1
  504. package/dist/test/gather-context-timeout.test.js +0 -120
  505. package/dist/test/gather-context-timeout.test.js.map +0 -1
  506. package/dist/test/health-snapshot.test.d.ts +0 -2
  507. package/dist/test/health-snapshot.test.d.ts.map +0 -1
  508. package/dist/test/health-snapshot.test.js +0 -74
  509. package/dist/test/health-snapshot.test.js.map +0 -1
  510. package/dist/test/helpers/coalescing-fixture.d.ts +0 -72
  511. package/dist/test/helpers/coalescing-fixture.d.ts.map +0 -1
  512. package/dist/test/helpers/coalescing-fixture.js +0 -146
  513. package/dist/test/helpers/coalescing-fixture.js.map +0 -1
  514. package/dist/test/helpers/coalescing-kill-child.d.ts +0 -2
  515. package/dist/test/helpers/coalescing-kill-child.d.ts.map +0 -1
  516. package/dist/test/helpers/coalescing-kill-child.js +0 -24
  517. package/dist/test/helpers/coalescing-kill-child.js.map +0 -1
  518. package/dist/test/helpers/mock-membrane.d.ts +0 -53
  519. package/dist/test/helpers/mock-membrane.d.ts.map +0 -1
  520. package/dist/test/helpers/mock-membrane.js +0 -168
  521. package/dist/test/helpers/mock-membrane.js.map +0 -1
  522. package/dist/test/helpers/pytc-stop-rows.d.ts +0 -11
  523. package/dist/test/helpers/pytc-stop-rows.d.ts.map +0 -1
  524. package/dist/test/helpers/pytc-stop-rows.js +0 -143
  525. package/dist/test/helpers/pytc-stop-rows.js.map +0 -1
  526. package/dist/test/helpers/quiesce-crash-child.d.ts +0 -2
  527. package/dist/test/helpers/quiesce-crash-child.d.ts.map +0 -1
  528. package/dist/test/helpers/quiesce-crash-child.js +0 -156
  529. package/dist/test/helpers/quiesce-crash-child.js.map +0 -1
  530. package/dist/test/history-module-overview.test.d.ts +0 -2
  531. package/dist/test/history-module-overview.test.d.ts.map +0 -1
  532. package/dist/test/history-module-overview.test.js +0 -711
  533. package/dist/test/history-module-overview.test.js.map +0 -1
  534. package/dist/test/history-module-realstore.test.d.ts +0 -2
  535. package/dist/test/history-module-realstore.test.d.ts.map +0 -1
  536. package/dist/test/history-module-realstore.test.js +0 -363
  537. package/dist/test/history-module-realstore.test.js.map +0 -1
  538. package/dist/test/history-module-semantic.test.d.ts +0 -2
  539. package/dist/test/history-module-semantic.test.d.ts.map +0 -1
  540. package/dist/test/history-module-semantic.test.js +0 -213
  541. package/dist/test/history-module-semantic.test.js.map +0 -1
  542. package/dist/test/history-module-ux.test.d.ts +0 -2
  543. package/dist/test/history-module-ux.test.d.ts.map +0 -1
  544. package/dist/test/history-module-ux.test.js +0 -304
  545. package/dist/test/history-module-ux.test.js.map +0 -1
  546. package/dist/test/history-module.test.d.ts +0 -2
  547. package/dist/test/history-module.test.d.ts.map +0 -1
  548. package/dist/test/history-module.test.js +0 -619
  549. package/dist/test/history-module.test.js.map +0 -1
  550. package/dist/test/history-semantic-review-findings.test.d.ts +0 -2
  551. package/dist/test/history-semantic-review-findings.test.d.ts.map +0 -1
  552. package/dist/test/history-semantic-review-findings.test.js +0 -338
  553. package/dist/test/history-semantic-review-findings.test.js.map +0 -1
  554. package/dist/test/history-semantic-sync-converges.test.d.ts +0 -2
  555. package/dist/test/history-semantic-sync-converges.test.d.ts.map +0 -1
  556. package/dist/test/history-semantic-sync-converges.test.js +0 -109
  557. package/dist/test/history-semantic-sync-converges.test.js.map +0 -1
  558. package/dist/test/host-quiesce.test.d.ts +0 -2
  559. package/dist/test/host-quiesce.test.d.ts.map +0 -1
  560. package/dist/test/host-quiesce.test.js +0 -863
  561. package/dist/test/host-quiesce.test.js.map +0 -1
  562. package/dist/test/inference-exhaustion-rewind.test.d.ts +0 -2
  563. package/dist/test/inference-exhaustion-rewind.test.d.ts.map +0 -1
  564. package/dist/test/inference-exhaustion-rewind.test.js +0 -309
  565. package/dist/test/inference-exhaustion-rewind.test.js.map +0 -1
  566. package/dist/test/inference-failure-bounds.test.d.ts +0 -2
  567. package/dist/test/inference-failure-bounds.test.d.ts.map +0 -1
  568. package/dist/test/inference-failure-bounds.test.js +0 -1201
  569. package/dist/test/inference-failure-bounds.test.js.map +0 -1
  570. package/dist/test/inference-failure-observability.test.d.ts +0 -2
  571. package/dist/test/inference-failure-observability.test.d.ts.map +0 -1
  572. package/dist/test/inference-failure-observability.test.js +0 -84
  573. package/dist/test/inference-failure-observability.test.js.map +0 -1
  574. package/dist/test/journal-tool.test.d.ts +0 -2
  575. package/dist/test/journal-tool.test.d.ts.map +0 -1
  576. package/dist/test/journal-tool.test.js +0 -33
  577. package/dist/test/journal-tool.test.js.map +0 -1
  578. package/dist/test/kv-unified-open-flight-retry.test.d.ts +0 -2
  579. package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +0 -1
  580. package/dist/test/kv-unified-open-flight-retry.test.js +0 -189
  581. package/dist/test/kv-unified-open-flight-retry.test.js.map +0 -1
  582. package/dist/test/kv-unified-wiring.test.d.ts +0 -2
  583. package/dist/test/kv-unified-wiring.test.d.ts.map +0 -1
  584. package/dist/test/kv-unified-wiring.test.js +0 -95
  585. package/dist/test/kv-unified-wiring.test.js.map +0 -1
  586. package/dist/test/late-events-after-stop.test.d.ts +0 -2
  587. package/dist/test/late-events-after-stop.test.d.ts.map +0 -1
  588. package/dist/test/late-events-after-stop.test.js +0 -122
  589. package/dist/test/late-events-after-stop.test.js.map +0 -1
  590. package/dist/test/liveness-watchdog.test.d.ts +0 -2
  591. package/dist/test/liveness-watchdog.test.d.ts.map +0 -1
  592. package/dist/test/liveness-watchdog.test.js +0 -94
  593. package/dist/test/liveness-watchdog.test.js.map +0 -1
  594. package/dist/test/machine-close-provenance.test.d.ts +0 -2
  595. package/dist/test/machine-close-provenance.test.d.ts.map +0 -1
  596. package/dist/test/machine-close-provenance.test.js +0 -116
  597. package/dist/test/machine-close-provenance.test.js.map +0 -1
  598. package/dist/test/maintenance-timer.test.d.ts +0 -2
  599. package/dist/test/maintenance-timer.test.d.ts.map +0 -1
  600. package/dist/test/maintenance-timer.test.js +0 -265
  601. package/dist/test/maintenance-timer.test.js.map +0 -1
  602. package/dist/test/mcpl-access-provider.test.d.ts +0 -2
  603. package/dist/test/mcpl-access-provider.test.d.ts.map +0 -1
  604. package/dist/test/mcpl-access-provider.test.js +0 -20
  605. package/dist/test/mcpl-access-provider.test.js.map +0 -1
  606. package/dist/test/mcpl-awareness-barrier.test.d.ts +0 -2
  607. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +0 -1
  608. package/dist/test/mcpl-awareness-barrier.test.js +0 -769
  609. package/dist/test/mcpl-awareness-barrier.test.js.map +0 -1
  610. package/dist/test/mcpl-capability-grant.test.d.ts +0 -10
  611. package/dist/test/mcpl-capability-grant.test.d.ts.map +0 -1
  612. package/dist/test/mcpl-capability-grant.test.js +0 -111
  613. package/dist/test/mcpl-capability-grant.test.js.map +0 -1
  614. package/dist/test/mcpl-capability-scoping.test.d.ts +0 -2
  615. package/dist/test/mcpl-capability-scoping.test.d.ts.map +0 -1
  616. package/dist/test/mcpl-capability-scoping.test.js +0 -266
  617. package/dist/test/mcpl-capability-scoping.test.js.map +0 -1
  618. package/dist/test/mcpl-child-env.test.d.ts +0 -2
  619. package/dist/test/mcpl-child-env.test.d.ts.map +0 -1
  620. package/dist/test/mcpl-child-env.test.js +0 -158
  621. package/dist/test/mcpl-child-env.test.js.map +0 -1
  622. package/dist/test/mcpl-coalescing.test.d.ts +0 -2
  623. package/dist/test/mcpl-coalescing.test.d.ts.map +0 -1
  624. package/dist/test/mcpl-coalescing.test.js +0 -1125
  625. package/dist/test/mcpl-coalescing.test.js.map +0 -1
  626. package/dist/test/mcpl-config-diagnostics.test.d.ts +0 -2
  627. package/dist/test/mcpl-config-diagnostics.test.d.ts.map +0 -1
  628. package/dist/test/mcpl-config-diagnostics.test.js +0 -452
  629. package/dist/test/mcpl-config-diagnostics.test.js.map +0 -1
  630. package/dist/test/mcpl-empty-content.test.d.ts +0 -2
  631. package/dist/test/mcpl-empty-content.test.d.ts.map +0 -1
  632. package/dist/test/mcpl-empty-content.test.js +0 -368
  633. package/dist/test/mcpl-empty-content.test.js.map +0 -1
  634. package/dist/test/mcpl-gate-roundtrip.test.d.ts +0 -2
  635. package/dist/test/mcpl-gate-roundtrip.test.d.ts.map +0 -1
  636. package/dist/test/mcpl-gate-roundtrip.test.js +0 -285
  637. package/dist/test/mcpl-gate-roundtrip.test.js.map +0 -1
  638. package/dist/test/mcpl-list-status.test.d.ts +0 -2
  639. package/dist/test/mcpl-list-status.test.d.ts.map +0 -1
  640. package/dist/test/mcpl-list-status.test.js +0 -82
  641. package/dist/test/mcpl-list-status.test.js.map +0 -1
  642. package/dist/test/mcpl-manifest-changed.test.d.ts +0 -2
  643. package/dist/test/mcpl-manifest-changed.test.d.ts.map +0 -1
  644. package/dist/test/mcpl-manifest-changed.test.js +0 -178
  645. package/dist/test/mcpl-manifest-changed.test.js.map +0 -1
  646. package/dist/test/mcpl-push-convert.test.d.ts +0 -2
  647. package/dist/test/mcpl-push-convert.test.d.ts.map +0 -1
  648. package/dist/test/mcpl-push-convert.test.js +0 -42
  649. package/dist/test/mcpl-push-convert.test.js.map +0 -1
  650. package/dist/test/mcpl-reconnect-events.test.d.ts +0 -2
  651. package/dist/test/mcpl-reconnect-events.test.d.ts.map +0 -1
  652. package/dist/test/mcpl-reconnect-events.test.js +0 -144
  653. package/dist/test/mcpl-reconnect-events.test.js.map +0 -1
  654. package/dist/test/mcpl-reconnect-reregistration.test.d.ts +0 -2
  655. package/dist/test/mcpl-reconnect-reregistration.test.d.ts.map +0 -1
  656. package/dist/test/mcpl-reconnect-reregistration.test.js +0 -236
  657. package/dist/test/mcpl-reconnect-reregistration.test.js.map +0 -1
  658. package/dist/test/mcpl-reference-fetcher.test.d.ts +0 -2
  659. package/dist/test/mcpl-reference-fetcher.test.d.ts.map +0 -1
  660. package/dist/test/mcpl-reference-fetcher.test.js +0 -427
  661. package/dist/test/mcpl-reference-fetcher.test.js.map +0 -1
  662. package/dist/test/mcpl-reference-fields.test.d.ts +0 -2
  663. package/dist/test/mcpl-reference-fields.test.d.ts.map +0 -1
  664. package/dist/test/mcpl-reference-fields.test.js +0 -149
  665. package/dist/test/mcpl-reference-fields.test.js.map +0 -1
  666. package/dist/test/mcpl-request-timeout.test.d.ts +0 -2
  667. package/dist/test/mcpl-request-timeout.test.d.ts.map +0 -1
  668. package/dist/test/mcpl-request-timeout.test.js +0 -138
  669. package/dist/test/mcpl-request-timeout.test.js.map +0 -1
  670. package/dist/test/mcpl-runtime-lifecycle.test.d.ts +0 -7
  671. package/dist/test/mcpl-runtime-lifecycle.test.d.ts.map +0 -1
  672. package/dist/test/mcpl-runtime-lifecycle.test.js +0 -142
  673. package/dist/test/mcpl-runtime-lifecycle.test.js.map +0 -1
  674. package/dist/test/mcpl-tool-class-listing.test.d.ts +0 -2
  675. package/dist/test/mcpl-tool-class-listing.test.d.ts.map +0 -1
  676. package/dist/test/mcpl-tool-class-listing.test.js +0 -147
  677. package/dist/test/mcpl-tool-class-listing.test.js.map +0 -1
  678. package/dist/test/mcpl-tool-classes.test.d.ts +0 -7
  679. package/dist/test/mcpl-tool-classes.test.d.ts.map +0 -1
  680. package/dist/test/mcpl-tool-classes.test.js +0 -80
  681. package/dist/test/mcpl-tool-classes.test.js.map +0 -1
  682. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts +0 -2
  683. package/dist/test/mcpl-tool-lifecycle-e2e.test.d.ts.map +0 -1
  684. package/dist/test/mcpl-tool-lifecycle-e2e.test.js +0 -237
  685. package/dist/test/mcpl-tool-lifecycle-e2e.test.js.map +0 -1
  686. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts +0 -11
  687. package/dist/test/mcpl-tool-lifecycle-emitter.test.d.ts.map +0 -1
  688. package/dist/test/mcpl-tool-lifecycle-emitter.test.js +0 -412
  689. package/dist/test/mcpl-tool-lifecycle-emitter.test.js.map +0 -1
  690. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts +0 -2
  691. package/dist/test/mcpl-tool-lifecycle-script.test.d.ts.map +0 -1
  692. package/dist/test/mcpl-tool-lifecycle-script.test.js +0 -288
  693. package/dist/test/mcpl-tool-lifecycle-script.test.js.map +0 -1
  694. package/dist/test/mcpl-tool-lifecycle.test.d.ts +0 -11
  695. package/dist/test/mcpl-tool-lifecycle.test.d.ts.map +0 -1
  696. package/dist/test/mcpl-tool-lifecycle.test.js +0 -270
  697. package/dist/test/mcpl-tool-lifecycle.test.js.map +0 -1
  698. package/dist/test/mcpl-ws-transport.test.d.ts +0 -2
  699. package/dist/test/mcpl-ws-transport.test.d.ts.map +0 -1
  700. package/dist/test/mcpl-ws-transport.test.js +0 -258
  701. package/dist/test/mcpl-ws-transport.test.js.map +0 -1
  702. package/dist/test/module-context-integration.test.d.ts +0 -18
  703. package/dist/test/module-context-integration.test.d.ts.map +0 -1
  704. package/dist/test/module-context-integration.test.js +0 -181
  705. package/dist/test/module-context-integration.test.js.map +0 -1
  706. package/dist/test/offline-recovery-branch.test.d.ts +0 -2
  707. package/dist/test/offline-recovery-branch.test.d.ts.map +0 -1
  708. package/dist/test/offline-recovery-branch.test.js +0 -226
  709. package/dist/test/offline-recovery-branch.test.js.map +0 -1
  710. package/dist/test/operator-surgery.test.d.ts +0 -2
  711. package/dist/test/operator-surgery.test.d.ts.map +0 -1
  712. package/dist/test/operator-surgery.test.js +0 -398
  713. package/dist/test/operator-surgery.test.js.map +0 -1
  714. package/dist/test/ops-alert.test.d.ts +0 -2
  715. package/dist/test/ops-alert.test.d.ts.map +0 -1
  716. package/dist/test/ops-alert.test.js +0 -153
  717. package/dist/test/ops-alert.test.js.map +0 -1
  718. package/dist/test/overbudget-drain-breaker.test.d.ts +0 -2
  719. package/dist/test/overbudget-drain-breaker.test.d.ts.map +0 -1
  720. package/dist/test/overbudget-drain-breaker.test.js +0 -197
  721. package/dist/test/overbudget-drain-breaker.test.js.map +0 -1
  722. package/dist/test/per-agent-delivery.test.d.ts +0 -2
  723. package/dist/test/per-agent-delivery.test.d.ts.map +0 -1
  724. package/dist/test/per-agent-delivery.test.js +0 -108
  725. package/dist/test/per-agent-delivery.test.js.map +0 -1
  726. package/dist/test/physical-window-restart.test.d.ts +0 -14
  727. package/dist/test/physical-window-restart.test.d.ts.map +0 -1
  728. package/dist/test/physical-window-restart.test.js +0 -222
  729. package/dist/test/physical-window-restart.test.js.map +0 -1
  730. package/dist/test/placed-reaction-baseline.test.d.ts +0 -2
  731. package/dist/test/placed-reaction-baseline.test.d.ts.map +0 -1
  732. package/dist/test/placed-reaction-baseline.test.js +0 -312
  733. package/dist/test/placed-reaction-baseline.test.js.map +0 -1
  734. package/dist/test/present-while-acting.test.d.ts +0 -19
  735. package/dist/test/present-while-acting.test.d.ts.map +0 -1
  736. package/dist/test/present-while-acting.test.js +0 -706
  737. package/dist/test/present-while-acting.test.js.map +0 -1
  738. package/dist/test/prose-segments.test.d.ts +0 -2
  739. package/dist/test/prose-segments.test.d.ts.map +0 -1
  740. package/dist/test/prose-segments.test.js +0 -52
  741. package/dist/test/prose-segments.test.js.map +0 -1
  742. package/dist/test/prose-stream-router.test.d.ts +0 -2
  743. package/dist/test/prose-stream-router.test.d.ts.map +0 -1
  744. package/dist/test/prose-stream-router.test.js +0 -171
  745. package/dist/test/prose-stream-router.test.js.map +0 -1
  746. package/dist/test/provider-acceleration-cooldown.test.d.ts +0 -2
  747. package/dist/test/provider-acceleration-cooldown.test.d.ts.map +0 -1
  748. package/dist/test/provider-acceleration-cooldown.test.js +0 -435
  749. package/dist/test/provider-acceleration-cooldown.test.js.map +0 -1
  750. package/dist/test/provider-waits.test.d.ts +0 -2
  751. package/dist/test/provider-waits.test.d.ts.map +0 -1
  752. package/dist/test/provider-waits.test.js +0 -2196
  753. package/dist/test/provider-waits.test.js.map +0 -1
  754. package/dist/test/puppet-tool-call.test.d.ts +0 -2
  755. package/dist/test/puppet-tool-call.test.d.ts.map +0 -1
  756. package/dist/test/puppet-tool-call.test.js +0 -224
  757. package/dist/test/puppet-tool-call.test.js.map +0 -1
  758. package/dist/test/puppet-turn-reservation.test.d.ts +0 -2
  759. package/dist/test/puppet-turn-reservation.test.d.ts.map +0 -1
  760. package/dist/test/puppet-turn-reservation.test.js +0 -139
  761. package/dist/test/puppet-turn-reservation.test.js.map +0 -1
  762. package/dist/test/reaction-baseline-platform.test.d.ts +0 -2
  763. package/dist/test/reaction-baseline-platform.test.d.ts.map +0 -1
  764. package/dist/test/reaction-baseline-platform.test.js +0 -124
  765. package/dist/test/reaction-baseline-platform.test.js.map +0 -1
  766. package/dist/test/record-journal.test.d.ts +0 -6
  767. package/dist/test/record-journal.test.d.ts.map +0 -1
  768. package/dist/test/record-journal.test.js +0 -269
  769. package/dist/test/record-journal.test.js.map +0 -1
  770. package/dist/test/refusal-reaction-baseline.test.d.ts +0 -2
  771. package/dist/test/refusal-reaction-baseline.test.d.ts.map +0 -1
  772. package/dist/test/refusal-reaction-baseline.test.js +0 -81
  773. package/dist/test/refusal-reaction-baseline.test.js.map +0 -1
  774. package/dist/test/refusal-rewind.test.d.ts +0 -2
  775. package/dist/test/refusal-rewind.test.d.ts.map +0 -1
  776. package/dist/test/refusal-rewind.test.js +0 -108
  777. package/dist/test/refusal-rewind.test.js.map +0 -1
  778. package/dist/test/refusal-single-call.test.d.ts +0 -2
  779. package/dist/test/refusal-single-call.test.d.ts.map +0 -1
  780. package/dist/test/refusal-single-call.test.js +0 -177
  781. package/dist/test/refusal-single-call.test.js.map +0 -1
  782. package/dist/test/release-changelog.test.d.ts +0 -2
  783. package/dist/test/release-changelog.test.d.ts.map +0 -1
  784. package/dist/test/release-changelog.test.js +0 -159
  785. package/dist/test/release-changelog.test.js.map +0 -1
  786. package/dist/test/same-round-think-policy.test.d.ts +0 -2
  787. package/dist/test/same-round-think-policy.test.d.ts.map +0 -1
  788. package/dist/test/same-round-think-policy.test.js +0 -853
  789. package/dist/test/same-round-think-policy.test.js.map +0 -1
  790. package/dist/test/save-recent-image.test.d.ts +0 -26
  791. package/dist/test/save-recent-image.test.d.ts.map +0 -1
  792. package/dist/test/save-recent-image.test.js +0 -974
  793. package/dist/test/save-recent-image.test.js.map +0 -1
  794. package/dist/test/shutdown-errors.test.d.ts +0 -2
  795. package/dist/test/shutdown-errors.test.d.ts.map +0 -1
  796. package/dist/test/shutdown-errors.test.js +0 -662
  797. package/dist/test/shutdown-errors.test.js.map +0 -1
  798. package/dist/test/silent-heartbeat-rows.test.d.ts +0 -2
  799. package/dist/test/silent-heartbeat-rows.test.d.ts.map +0 -1
  800. package/dist/test/silent-heartbeat-rows.test.js +0 -451
  801. package/dist/test/silent-heartbeat-rows.test.js.map +0 -1
  802. package/dist/test/silent-heartbeat.test.d.ts +0 -2
  803. package/dist/test/silent-heartbeat.test.d.ts.map +0 -1
  804. package/dist/test/silent-heartbeat.test.js +0 -165
  805. package/dist/test/silent-heartbeat.test.js.map +0 -1
  806. package/dist/test/state-scaling-e2e.test.d.ts +0 -22
  807. package/dist/test/state-scaling-e2e.test.d.ts.map +0 -1
  808. package/dist/test/state-scaling-e2e.test.js +0 -206
  809. package/dist/test/state-scaling-e2e.test.js.map +0 -1
  810. package/dist/test/state-scaling.test.d.ts +0 -12
  811. package/dist/test/state-scaling.test.d.ts.map +0 -1
  812. package/dist/test/state-scaling.test.js +0 -251
  813. package/dist/test/state-scaling.test.js.map +0 -1
  814. package/dist/test/stop-with-work-in-flight.test.d.ts +0 -23
  815. package/dist/test/stop-with-work-in-flight.test.d.ts.map +0 -1
  816. package/dist/test/stop-with-work-in-flight.test.js +0 -672
  817. package/dist/test/stop-with-work-in-flight.test.js.map +0 -1
  818. package/dist/test/surgery-marks-receipt.test.d.ts +0 -2
  819. package/dist/test/surgery-marks-receipt.test.d.ts.map +0 -1
  820. package/dist/test/surgery-marks-receipt.test.js +0 -540
  821. package/dist/test/surgery-marks-receipt.test.js.map +0 -1
  822. package/dist/test/thinking-token-stamp.test.d.ts +0 -12
  823. package/dist/test/thinking-token-stamp.test.d.ts.map +0 -1
  824. package/dist/test/thinking-token-stamp.test.js +0 -129
  825. package/dist/test/thinking-token-stamp.test.js.map +0 -1
  826. package/dist/test/timezone.test.d.ts +0 -2
  827. package/dist/test/timezone.test.d.ts.map +0 -1
  828. package/dist/test/timezone.test.js +0 -18
  829. package/dist/test/timezone.test.js.map +0 -1
  830. package/dist/test/tool-batch-hook.test.d.ts +0 -8
  831. package/dist/test/tool-batch-hook.test.d.ts.map +0 -1
  832. package/dist/test/tool-batch-hook.test.js +0 -275
  833. package/dist/test/tool-batch-hook.test.js.map +0 -1
  834. package/dist/test/tool-policy.test.d.ts +0 -2
  835. package/dist/test/tool-policy.test.d.ts.map +0 -1
  836. package/dist/test/tool-policy.test.js +0 -51
  837. package/dist/test/tool-policy.test.js.map +0 -1
  838. package/dist/test/tool-presentation.test.d.ts +0 -2
  839. package/dist/test/tool-presentation.test.d.ts.map +0 -1
  840. package/dist/test/tool-presentation.test.js +0 -268
  841. package/dist/test/tool-presentation.test.js.map +0 -1
  842. package/dist/test/tool-result-content.test.d.ts +0 -2
  843. package/dist/test/tool-result-content.test.d.ts.map +0 -1
  844. package/dist/test/tool-result-content.test.js +0 -37
  845. package/dist/test/tool-result-content.test.js.map +0 -1
  846. package/dist/test/tool-result-guard.test.d.ts +0 -2
  847. package/dist/test/tool-result-guard.test.d.ts.map +0 -1
  848. package/dist/test/tool-result-guard.test.js +0 -3607
  849. package/dist/test/tool-result-guard.test.js.map +0 -1
  850. package/dist/test/tool-result-history.test.d.ts +0 -7
  851. package/dist/test/tool-result-history.test.d.ts.map +0 -1
  852. package/dist/test/tool-result-history.test.js +0 -156
  853. package/dist/test/tool-result-history.test.js.map +0 -1
  854. package/dist/test/tool-result-spill.test.d.ts +0 -13
  855. package/dist/test/tool-result-spill.test.d.ts.map +0 -1
  856. package/dist/test/tool-result-spill.test.js +0 -586
  857. package/dist/test/tool-result-spill.test.js.map +0 -1
  858. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +0 -2
  859. package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +0 -1
  860. package/dist/test/tool-wrapper-prose-guard-integration.test.js +0 -485
  861. package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +0 -1
  862. package/dist/test/tool-wrapper-prose-guard.test.d.ts +0 -2
  863. package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +0 -1
  864. package/dist/test/tool-wrapper-prose-guard.test.js +0 -34
  865. package/dist/test/tool-wrapper-prose-guard.test.js.map +0 -1
  866. package/dist/test/tools-observe-parser-conformance.test.d.ts +0 -2
  867. package/dist/test/tools-observe-parser-conformance.test.d.ts.map +0 -1
  868. package/dist/test/tools-observe-parser-conformance.test.js +0 -129
  869. package/dist/test/tools-observe-parser-conformance.test.js.map +0 -1
  870. package/dist/test/trunk-channel-routing.test.d.ts +0 -19
  871. package/dist/test/trunk-channel-routing.test.d.ts.map +0 -1
  872. package/dist/test/trunk-channel-routing.test.js +0 -329
  873. package/dist/test/trunk-channel-routing.test.js.map +0 -1
  874. package/dist/test/tune-out-e2e.test.d.ts +0 -2
  875. package/dist/test/tune-out-e2e.test.d.ts.map +0 -1
  876. package/dist/test/tune-out-e2e.test.js +0 -142
  877. package/dist/test/tune-out-e2e.test.js.map +0 -1
  878. package/dist/test/tune-out-gate-composition.test.d.ts +0 -2
  879. package/dist/test/tune-out-gate-composition.test.d.ts.map +0 -1
  880. package/dist/test/tune-out-gate-composition.test.js +0 -221
  881. package/dist/test/tune-out-gate-composition.test.js.map +0 -1
  882. package/dist/test/tune-out-lifecycle.test.d.ts +0 -2
  883. package/dist/test/tune-out-lifecycle.test.d.ts.map +0 -1
  884. package/dist/test/tune-out-lifecycle.test.js +0 -121
  885. package/dist/test/tune-out-lifecycle.test.js.map +0 -1
  886. package/dist/test/turn-trigger-provenance.test.d.ts +0 -2
  887. package/dist/test/turn-trigger-provenance.test.d.ts.map +0 -1
  888. package/dist/test/turn-trigger-provenance.test.js +0 -137
  889. package/dist/test/turn-trigger-provenance.test.js.map +0 -1
  890. package/dist/test/unconvertible-tool-result.test.d.ts +0 -2
  891. package/dist/test/unconvertible-tool-result.test.d.ts.map +0 -1
  892. package/dist/test/unconvertible-tool-result.test.js +0 -358
  893. package/dist/test/unconvertible-tool-result.test.js.map +0 -1
  894. package/dist/test/usage-accounting.test.d.ts +0 -2
  895. package/dist/test/usage-accounting.test.d.ts.map +0 -1
  896. package/dist/test/usage-accounting.test.js +0 -13
  897. package/dist/test/usage-accounting.test.js.map +0 -1
  898. package/dist/test/usage-tracker.test.d.ts +0 -2
  899. package/dist/test/usage-tracker.test.d.ts.map +0 -1
  900. package/dist/test/usage-tracker.test.js +0 -129
  901. package/dist/test/usage-tracker.test.js.map +0 -1
  902. package/dist/test/utils-surface.test.d.ts +0 -2
  903. package/dist/test/utils-surface.test.d.ts.map +0 -1
  904. package/dist/test/utils-surface.test.js +0 -145
  905. package/dist/test/utils-surface.test.js.map +0 -1
  906. package/dist/test/workspace-branch-continuation.test.d.ts +0 -15
  907. package/dist/test/workspace-branch-continuation.test.d.ts.map +0 -1
  908. package/dist/test/workspace-branch-continuation.test.js +0 -183
  909. package/dist/test/workspace-branch-continuation.test.js.map +0 -1
  910. package/dist/test/workspace-materialize-freshness.test.d.ts +0 -16
  911. package/dist/test/workspace-materialize-freshness.test.d.ts.map +0 -1
  912. package/dist/test/workspace-materialize-freshness.test.js +0 -252
  913. package/dist/test/workspace-materialize-freshness.test.js.map +0 -1
  914. package/dist/test/workspace-path-containment.test.d.ts +0 -19
  915. package/dist/test/workspace-path-containment.test.d.ts.map +0 -1
  916. package/dist/test/workspace-path-containment.test.js +0 -91
  917. package/dist/test/workspace-path-containment.test.js.map +0 -1
  918. package/dist/test/workspace-read-file-from-disk.test.d.ts +0 -17
  919. package/dist/test/workspace-read-file-from-disk.test.d.ts.map +0 -1
  920. package/dist/test/workspace-read-file-from-disk.test.js +0 -174
  921. package/dist/test/workspace-read-file-from-disk.test.js.map +0 -1
  922. package/dist/test/workspace-read-image.test.d.ts +0 -2
  923. package/dist/test/workspace-read-image.test.d.ts.map +0 -1
  924. package/dist/test/workspace-read-image.test.js +0 -597
  925. package/dist/test/workspace-read-image.test.js.map +0 -1
  926. package/dist/test/workspace-read-text.test.d.ts +0 -2
  927. package/dist/test/workspace-read-text.test.d.ts.map +0 -1
  928. package/dist/test/workspace-read-text.test.js +0 -101
  929. package/dist/test/workspace-read-text.test.js.map +0 -1
  930. package/dist/test/workspace-restore-order.test.d.ts +0 -16
  931. package/dist/test/workspace-restore-order.test.d.ts.map +0 -1
  932. package/dist/test/workspace-restore-order.test.js +0 -140
  933. package/dist/test/workspace-restore-order.test.js.map +0 -1
  934. package/dist/test/workspace-three-way.test.d.ts +0 -12
  935. package/dist/test/workspace-three-way.test.d.ts.map +0 -1
  936. package/dist/test/workspace-three-way.test.js +0 -3194
  937. package/dist/test/workspace-three-way.test.js.map +0 -1
  938. package/dist/test/workspace-watcher.test.d.ts +0 -2
  939. package/dist/test/workspace-watcher.test.d.ts.map +0 -1
  940. package/dist/test/workspace-watcher.test.js +0 -281
  941. package/dist/test/workspace-watcher.test.js.map +0 -1
  942. package/dist/test/xml-round-persist.test.d.ts +0 -19
  943. package/dist/test/xml-round-persist.test.d.ts.map +0 -1
  944. package/dist/test/xml-round-persist.test.js +0 -235
  945. package/dist/test/xml-round-persist.test.js.map +0 -1
  946. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -19,7 +19,7 @@
19
19
  * identity, and what they showed — a listing, an absence — is accepted only
20
20
  * if each is still the directory its logical path names afterwards. A walk records which
21
21
  * directories it listed completely, and only those prove a file absent: an
22
- * unreadable directory, an ignored subtree, the file cap, a symlink the walk
22
+ * unreadable directory, an ignored subtree, the walk cap, a symlink the walk
23
23
  * doesn't descend, or a directory that changed while it was listed leave
24
24
  * everything beneath them unproven. Outside a walk, absence is proven the
25
25
  * same way: by a directory inside the mount, still at its path, that lacks
@@ -41,7 +41,7 @@ import { constants as fsConstants } from 'node:fs';
41
41
  import type { BigIntStats } from 'node:fs';
42
42
  import { lstat, mkdir, open, readdir, realpath, stat, statfs } from 'node:fs/promises';
43
43
  import type { FileHandle } from 'node:fs/promises';
44
- import { dirname, join, sep } from 'node:path';
44
+ import { dirname, join, posix, sep } from 'node:path';
45
45
  import { sameRootIdentity, type Fingerprint, type RootIdentity } from './disk-agreement.js';
46
46
 
47
47
  export interface MountView {
@@ -56,6 +56,11 @@ export interface MountView {
56
56
  /** Text above this size is not ingested. */
57
57
  maxFileSize: number;
58
58
  ignore: string[];
59
+ /**
60
+ * Other mounts' directories nested inside this one, mount-relative. Every
61
+ * pass passes over them, named or not, as another mount's directory.
62
+ */
63
+ others: readonly string[];
59
64
  }
60
65
 
61
66
  export type StatFingerprint = Omit<Fingerprint, 'hashedAt'>;
@@ -70,13 +75,16 @@ export const NONBLOCK = typeof fsConstants.O_NONBLOCK === 'number' ? fsConstants
70
75
 
71
76
  export type Observation =
72
77
  | { kind: 'absent' }
73
- | { kind: 'file'; size: number; mtimeMs: number; fp: StatFingerprint }
78
+ /** `mode`: the file's permission bits (`st_mode & 0o777`). */
79
+ | { kind: 'file'; size: number; mtimeMs: number; mode: number; fp: StatFingerprint }
74
80
  | { kind: 'unobserved'; reason: string };
75
81
 
76
82
  export interface ReadResult {
77
83
  kind: 'read';
78
84
  size: number;
79
85
  mtimeMs: number;
86
+ /** The permission bits of the inode the bytes were read from. */
87
+ mode: number;
80
88
  fp: Fingerprint;
81
89
  hash: string;
82
90
  /** The whole file, when it is at most the requested limit. */
@@ -503,7 +511,7 @@ export async function observePath(view: MountView, rootReal: string, relativePat
503
511
  } else if (!info.isFile()) {
504
512
  return { kind: 'unobserved', reason: 'not a regular file' };
505
513
  }
506
- return { kind: 'file', size: Number(info.size), mtimeMs: Number(info.mtimeMs), fp: statFingerprint(info) };
514
+ return { kind: 'file', size: Number(info.size), mtimeMs: Number(info.mtimeMs), mode: Number(info.mode & 0o777n), fp: statFingerprint(info) };
507
515
  }
508
516
 
509
517
  /**
@@ -570,10 +578,42 @@ async function openContained(
570
578
  }
571
579
  }
572
580
 
581
+ /**
582
+ * Read an open file from its start, at most `limit` bytes, and whether it
583
+ * goes on past them. Where the file ends is what the reads find: `sizeHint`,
584
+ * the size its fstat gave, only sizes the first buffer. Once a buffer is
585
+ * full, one byte read past it tells whether the file goes on. At the limit,
586
+ * that byte says it does, and isn't kept. Short of it, the file has grown
587
+ * since its fstat: the byte is kept, and the read goes on in a larger buffer,
588
+ * up to the limit. A file that has shrunk ends where the reads find its end.
589
+ * A fractional `limit` allows the whole bytes in it.
590
+ */
591
+ export async function readPrefix(handle: FileHandle, limit: number, sizeHint: number): Promise<{ bytes: Buffer; more: boolean }> {
592
+ const cap = Math.floor(limit);
593
+ const next = Buffer.alloc(1);
594
+ let bytes = Buffer.alloc(Math.min(cap, sizeHint));
595
+ let length = 0;
596
+ for (;;) {
597
+ while (length < bytes.length) {
598
+ const { bytesRead } = await handle.read(bytes, length, bytes.length - length, length);
599
+ if (bytesRead === 0) return { bytes: bytes.subarray(0, length), more: false };
600
+ length += bytesRead;
601
+ }
602
+ if ((await handle.read(next, 0, 1, length)).bytesRead === 0) return { bytes, more: false };
603
+ if (length === cap) return { bytes, more: true };
604
+ // Longer than its fstat said: read on, up to the limit.
605
+ const grown = Buffer.alloc(Math.min(cap, Math.max(2 * length, length + 64 * 1024)));
606
+ bytes.copy(grown, 0, 0, length);
607
+ grown[length++] = next[0];
608
+ bytes = grown;
609
+ }
610
+ }
611
+
573
612
  /**
574
613
  * Read and hash a mount-relative file through one located descriptor. The
575
- * whole file is returned when it is at most `limit` bytes; larger files are
576
- * hashed in chunks and only their head is kept.
614
+ * whole file is returned when it is at most `limit` bytes, both at its fstat
615
+ * and as read; any other file, including one that grew past `limit` since its
616
+ * fstat, is hashed in chunks and only its head is kept.
577
617
  */
578
618
  export async function readPath(
579
619
  view: MountView,
@@ -588,12 +628,18 @@ export async function readPath(
588
628
  const hashedAt = Date.now();
589
629
  const size = Number(info.size);
590
630
  const fp: Fingerprint = { ...statFingerprint(info), hashedAt };
591
- if (size <= limit) {
592
- const bytes = await handle.readFile();
631
+ // A file within the limit at its fstat is read no further than the limit,
632
+ // so one that has grown past it since is hashed below, from its start,
633
+ // never loaded whole. One over the limit at its fstat is hashed below
634
+ // without that read.
635
+ const within = size <= limit ? await readPrefix(handle, limit, size) : null;
636
+ if (within && !within.more) {
637
+ const { bytes } = within;
593
638
  return {
594
639
  kind: 'read',
595
640
  size: bytes.byteLength,
596
641
  mtimeMs: Number(info.mtimeMs),
642
+ mode: Number(info.mode & 0o777n),
597
643
  fp: { ...fp, size: bytes.byteLength },
598
644
  hash: createHash('sha256').update(bytes).digest('hex'),
599
645
  bytes,
@@ -615,6 +661,7 @@ export async function readPath(
615
661
  kind: 'read',
616
662
  size: offset,
617
663
  mtimeMs: Number(info.mtimeMs),
664
+ mode: Number(info.mode & 0o777n),
618
665
  fp: { ...fp, size: offset },
619
666
  hash: hash.digest('hex'),
620
667
  bytes: null,
@@ -672,24 +719,98 @@ export function sniffImageMime(head: Buffer): string | undefined {
672
719
  // ===========================================================================
673
720
 
674
721
  export interface Walk {
675
- /** Regular files seen. */
722
+ /** Regular files the walk took: the pass observes each one. */
676
723
  files: Set<string>;
724
+ /**
725
+ * Regular files a listing showed that the walk didn't take, past its cap
726
+ * or outside the stretch a resumed walk covered: present, and not
727
+ * observed by this pass.
728
+ */
729
+ seen: Set<string>;
730
+ /**
731
+ * The names in `others` that it doesn't pass over by design and that the walk took, as it
732
+ * takes files, against its cap: the pass observes these by path. The rest
733
+ * are present, and not observed by this pass.
734
+ */
735
+ othersTaken: Set<string>;
677
736
  /** Directories seen. */
678
737
  dirs: Set<string>;
679
- /** Names seen that are neither (symlinks, sockets…), or ignored: present, unproven. */
738
+ /**
739
+ * Names seen that are neither (symlinks, sockets…), or that the walk passes
740
+ * over by design (another mount's directory, the ignore list, an editor's
741
+ * file name): present, unproven.
742
+ */
680
743
  others: Map<string, string>;
681
- /** Directories listed completely. */
744
+ /**
745
+ * Directories whose listing the walk read whole, and that were still the
746
+ * directory at their path once it had: every name in one is in `files`,
747
+ * `seen`, `dirs` or `others`, so a name in none of them is absent.
748
+ */
682
749
  complete: Set<string>;
683
750
  /** Directories that don't exist (everything beneath them is absent). */
684
751
  missing: Set<string>;
685
752
  /**
686
753
  * Where the walk didn't reach, and why. `error` and `cap` regions may hide
687
754
  * files the listing would show. An `ignored` region is passed over by
688
- * design: one that hides a tracked entry is reported as incomplete, and
689
- * one that hides nothing is counted as passed over. A `symlink` region is
690
- * never walked; the pass reports the link itself by path.
755
+ * design: one that hides a tracked entry, or is the pass's whole scope, is
756
+ * reported as incomplete, and any other is counted as passed over. A
757
+ * `symlink` region is never walked; the pass reports the link itself by
758
+ * path.
691
759
  */
692
760
  incomplete: Array<{ path: string; reason: string; kind: 'error' | 'cap' | 'ignored' | 'symlink' }>;
761
+ /**
762
+ * When the walk cap stopped the walk, the last entry it took. A walk that
763
+ * resumes after it takes the entries after it first, in the walk's order
764
+ * (`compareInWalk`), then wraps to the start of its scope.
765
+ */
766
+ stoppedAfter?: string;
767
+ }
768
+
769
+ /** Names compare by UTF-16 code unit, the same on every platform and filesystem. */
770
+ function compareNames(a: string, b: string): number {
771
+ return a < b ? -1 : a > b ? 1 : 0;
772
+ }
773
+
774
+ /**
775
+ * Where file `a` falls against file `b` in the walk's order: in each
776
+ * directory, its files by name, then its subdirectories by name, each with
777
+ * everything beneath it. A resumed walk relies on visiting files in the
778
+ * order it compares positions by, so the walk sorts each listing itself
779
+ * rather than take `readdir`'s order, which is the platform's (Node returns
780
+ * UTF-8 byte order on Linux, which differs from this one for some names).
781
+ */
782
+ function compareInWalk(a: string, b: string): number {
783
+ const x = a.split('/');
784
+ const y = b.split('/');
785
+ for (let i = 0; ; i++) {
786
+ const lastX = i === x.length - 1;
787
+ const lastY = i === y.length - 1;
788
+ if (x[i] !== y[i]) {
789
+ if (lastX && lastY) return compareNames(x[i]!, y[i]!);
790
+ if (lastX) return -1; // a directory's files come before its subdirectories
791
+ if (lastY) return 1;
792
+ return compareNames(x[i]!, y[i]!);
793
+ }
794
+ if (lastX && lastY) return 0;
795
+ if (lastX) return -1;
796
+ if (lastY) return 1;
797
+ }
798
+ }
799
+
800
+ /**
801
+ * Where the subtree of directory `dir` falls against file `at` in the walk's
802
+ * order: wholly before it, holding it (an ancestor of it), or wholly after it.
803
+ */
804
+ function subtreeAgainst(dir: string, at: string): 'before' | 'holds' | 'after' {
805
+ if (dir === '') return 'holds';
806
+ const d = dir.split('/');
807
+ const p = at.split('/');
808
+ for (let i = 0; i < d.length; i++) {
809
+ // `at` is a file in the directory above d[i], whose files come first.
810
+ if (i === p.length - 1) return 'after';
811
+ if (d[i] !== p[i]) return compareNames(d[i]!, p[i]!) < 0 ? 'before' : 'after';
812
+ }
813
+ return 'holds';
693
814
  }
694
815
 
695
816
  /**
@@ -705,6 +826,101 @@ export function coveredByIgnore(relativePath: string, patterns: string[]): boole
705
826
  return false;
706
827
  }
707
828
 
829
+ /**
830
+ * The ignore patterns a walk that names `scope` reads beneath it: a pattern
831
+ * covering the scope itself, or a directory above it, doesn't apply beneath
832
+ * it (#276); one covering only something inside it does.
833
+ */
834
+ export function ignoreBeneath(scope: string, patterns: string[]): string[] {
835
+ return patterns.filter((pattern) => !coveredByIgnore(scope, [pattern]));
836
+ }
837
+
838
+ /**
839
+ * Names editors give the files they keep beside the one being edited: vim's
840
+ * swap files (`.name.swp`, and `.name.swx` while it checks it can make one),
841
+ * backups ending in `~`, and Sublime Text's save-in-progress files, ending
842
+ * in `.subl…tmp`. A walk passes over an entry with such a name as it passes
843
+ * over what the ignore list covers, a directory with what lies beneath it,
844
+ * and the watcher ignores it; a sync that names one takes it in. They are
845
+ * the families chokidar's `atomic` option hid from the watcher, but that
846
+ * tested them against the whole path, unanchored, so it also hid
847
+ * `report.v2.swp`, and under a directory with a dot in its name, a plain
848
+ * `notes.swp`. Here each is matched against an entry's name, to its end,
849
+ * and vim's from its start.
850
+ */
851
+ const EDITOR_FILE = /^\..+\.sw[px]$|~$|\.subl.*\.tmp$/;
852
+
853
+ /** The walk's reason for an entry the mount's ignore list covers. */
854
+ export const IGNORED = 'ignored by the mount';
855
+ /** The walk's reason for an entry `EDITOR_FILE` names. */
856
+ const EDITOR_FILE_REASON = "an editor's swap or backup file";
857
+
858
+ /** Whether a reason the walk gave an entry is one it passes over by design. */
859
+ export function passedOverByDesign(why: string | undefined): boolean {
860
+ return why === IGNORED || why === EDITOR_FILE_REASON || why === OTHER_MOUNT;
861
+ }
862
+
863
+ /** Why a pass passes over a directory that another mount nested in this one holds, and what lies beneath it. */
864
+ export const OTHER_MOUNT = "another mount's directory";
865
+
866
+ /**
867
+ * Whether a mount-relative path is another mount's directory, or lies
868
+ * beneath one, read as a join reads it: `.` and `..` segments within the
869
+ * path and repeated or trailing separators resolved, links not followed. A
870
+ * stored key such as `a//b/x`, which chronicle accepts, is read as `a/b/x`.
871
+ * A leading `..` that climbs above the mount's root is left as written.
872
+ * Every nested-mount check (a pass's, a walk's, a push's, grep's) asks this.
873
+ */
874
+ export function inOtherMount(relativePath: string, others: readonly string[]): boolean {
875
+ const lexical = posix.normalize(relativePath).replace(/\/+$/, '');
876
+ return others.some((dir) => lexical === dir || lexical.startsWith(dir + '/'));
877
+ }
878
+
879
+ /**
880
+ * Why a walk passes over an entry by design, by its mount-relative path and
881
+ * its name: another mount's directory, the ignore list, or an editor's file
882
+ * name. Undefined when none covers it.
883
+ */
884
+ function passedOverBecause(relativePath: string, name: string, patterns: string[], others: readonly string[]): string | undefined {
885
+ if (inOtherMount(relativePath, others)) return OTHER_MOUNT;
886
+ if (isIgnored(relativePath, name, patterns)) return IGNORED;
887
+ if (EDITOR_FILE.test(name)) return EDITOR_FILE_REASON;
888
+ return undefined;
889
+ }
890
+
891
+ /**
892
+ * Why a sync without a path, and the watcher, pass over a mount-relative
893
+ * path: the path itself or a directory above it is passed over by design, as
894
+ * the walk reads each entry by its path and name. A path in another mount's
895
+ * directory is that mount's, whatever else covers a directory above it.
896
+ * Undefined when nothing covers it.
897
+ */
898
+ export function passedOverAt(relativePath: string, patterns: string[], others: readonly string[]): string | undefined {
899
+ if (inOtherMount(relativePath, others)) return OTHER_MOUNT;
900
+ const segments = relativePath.split('/').filter(Boolean);
901
+ for (let i = 0; i < segments.length; i++) {
902
+ const why = passedOverBecause(segments.slice(0, i + 1).join('/'), segments[i]!, patterns, others);
903
+ if (why !== undefined) return why;
904
+ }
905
+ return undefined;
906
+ }
907
+
908
+ /**
909
+ * Why a walk of `scope` passes over a directory between it and a path beneath
910
+ * it: the first directory strictly beneath the scope and above the path that
911
+ * the mount passes over by design, by its path and name, with the patterns
912
+ * the walk reads there. Undefined when none is.
913
+ */
914
+ export function passedOverBetween(scope: string, relativePath: string, patterns: string[], others: readonly string[]): string | undefined {
915
+ const segments = relativePath.split('/').filter(Boolean);
916
+ const from = scope === '' ? 0 : scope.split('/').filter(Boolean).length;
917
+ for (let i = from; i < segments.length - 1; i++) {
918
+ const why = passedOverBecause(segments.slice(0, i + 1).join('/'), segments[i]!, patterns, others);
919
+ if (why !== undefined) return why;
920
+ }
921
+ return undefined;
922
+ }
923
+
708
924
  /** Simple ignore patterns, as the watcher and the old walk read them. */
709
925
  export function isIgnored(relativePath: string, name: string, patterns: string[]): boolean {
710
926
  for (const pattern of patterns) {
@@ -740,17 +956,55 @@ async function checkChild(view: MountView, rootReal: string, parent: CheckedDir,
740
956
 
741
957
  /**
742
958
  * List a directory scope ('' for the mount root), descending when recursive,
743
- * up to `cap` files in total. A scope that resolves outside the mount is not
744
- * listed at all; beneath it, the walk only descends real directories, never
745
- * symlinks. Each directory's listing counts only if, once listed, it is still
746
- * the directory at its path: a directory moved or replaced meanwhile is an
747
- * incomplete region, contributing no names and proving nothing absent.
959
+ * taking up to `cap` entries in the walk's order (`compareInWalk`): files,
960
+ * and links or other entries that aren't directories. A scope
961
+ * that resolves outside the mount is not listed at all; beneath it, the walk
962
+ * only descends real directories, never symlinks. Each directory's listing
963
+ * counts only if, once listed, it is still the directory at its path: a
964
+ * directory moved or replaced meanwhile is an incomplete region, contributing
965
+ * no names and proving nothing absent.
966
+ *
967
+ * Each listing is read whole and every name in it recorded, so the files the
968
+ * cap leaves are known present (`seen`) and a name the listing lacks is
969
+ * proven absent, whichever files were taken. Once the cap is reached, no
970
+ * further directory is listed.
971
+ *
972
+ * With `resumeAfter` (an entry in the scope, from an earlier walk's
973
+ * `stoppedAfter`), a recursive walk takes the entries after it first, then
974
+ * wraps to the start of the scope, so repeated walks cover a scope larger
975
+ * than the cap.
748
976
  */
749
977
  export async function walkScope(
750
978
  view: MountView, rootReal: string, scope: string, recursive: boolean, cap: number,
751
- opts: { named?: boolean } = {},
979
+ opts: { named?: boolean; resumeAfter?: string } = {},
752
980
  ): Promise<Walk> {
753
- const walk: Walk = { files: new Set(), dirs: new Set(), others: new Map(), complete: new Set(), missing: new Set(), incomplete: [] };
981
+ const walk: Walk = {
982
+ files: new Set(), seen: new Set(), othersTaken: new Set(), dirs: new Set(), others: new Map(), complete: new Set(), missing: new Set(),
983
+ incomplete: [],
984
+ };
985
+ // A walk that isn't named passes over a scope the mount passes over by
986
+ // design, at it or a directory above it, as its parent's listing would pass
987
+ // over its entry: a name rule (a bare-name ignore entry, an editor's name)
988
+ // doesn't match what lies beneath, as a path rule (`cache/**`) does. So a
989
+ // listing, glob or grep there never starts tracking what the mount leaves
990
+ // out, and a stored copy beneath it is unobserved, as beneath any region
991
+ // passed over by design. Its region says how to take what's there in: a
992
+ // sync that names it, whose scope is walked (#276), below.
993
+ // Another mount's directory is passed over by every walk, named or not,
994
+ // and no sync of this mount takes it in, so its region gives no advice.
995
+ if (scope !== '' && inOtherMount(scope, view.others)) {
996
+ walk.others.set(scope, OTHER_MOUNT);
997
+ walk.incomplete.push({ path: scope, reason: OTHER_MOUNT, kind: 'ignored' });
998
+ return walk;
999
+ }
1000
+ if (!opts.named && scope !== '') {
1001
+ const why = passedOverAt(scope, view.ignore, view.others);
1002
+ if (why !== undefined) {
1003
+ walk.others.set(scope, why);
1004
+ walk.incomplete.push({ path: scope, reason: `${why}: a sync that names this path takes in what's there, editors' files aside`, kind: 'ignored' });
1005
+ return walk;
1006
+ }
1007
+ }
754
1008
  const top = await checkDir(view, rootReal, scope);
755
1009
  if (top.kind === 'absent') {
756
1010
  walk.missing.add(scope);
@@ -760,20 +1014,87 @@ export async function walkScope(
760
1014
  walk.incomplete.push({ path: scope, reason: top.outside ? 'the directory resolves outside the mount' : top.reason, kind: 'error' });
761
1015
  return walk;
762
1016
  }
763
- let capped = false;
764
1017
  // A scope a path sync names is walked even where the ignore list covers
765
1018
  // it: a pattern covering the scope itself, or a directory above it, doesn't
766
1019
  // apply beneath it. So a named directory's contents are synced, as a named
767
- // file is (agent-framework #276). A listing keeps the ignore: its pass
768
- // would otherwise start tracking what it lists.
769
- const ignore = opts.named ? view.ignore.filter((pattern) => !coveredByIgnore(scope, [pattern])) : view.ignore;
1020
+ // file is (agent-framework #276), apart from what a pattern covering only
1021
+ // something inside it covers, and editors' files, which are passed over
1022
+ // there as anywhere. A listing keeps the ignore: its pass would otherwise
1023
+ // start tracking what it lists.
1024
+ const ignore = opts.named ? ignoreBeneath(scope, view.ignore) : view.ignore;
1025
+ // A position outside the scope, or for a walk that doesn't descend, is no
1026
+ // position in this walk's order.
1027
+ const after = recursive && opts.resumeAfter !== undefined && (scope === '' || opts.resumeAfter.startsWith(scope + '/'))
1028
+ ? opts.resumeAfter
1029
+ : undefined;
1030
+
1031
+ /** A listing's entries that aren't directories or ignored, in the walk's order, each a regular file or not. */
1032
+ type Listing = { leaves: Array<[string, boolean]>; subdirs: string[]; dev: string; ino: string };
1033
+ /**
1034
+ * Each directory is listed once: a resumed walk visits the ones holding its
1035
+ * position on both sides of it, and the second visit reuses the listing
1036
+ * while the directory at its path is still the one it was read from.
1037
+ */
1038
+ const listings = new Map<string, Listing | null>();
1039
+ const visited = new Set<string>();
1040
+ /** Paths already reported as errors, so a second visit doesn't report them again. */
1041
+ const failed = new Set<string>();
1042
+ const fail = (path: string, reason: string): void => {
1043
+ if (failed.has(path)) return;
1044
+ failed.add(path);
1045
+ walk.incomplete.push({ path, reason, kind: 'error' });
1046
+ };
1047
+ let left = cap;
1048
+ let lastTaken: string | undefined;
770
1049
 
771
- const visit = async (dir: CheckedDir): Promise<void> => {
1050
+ /**
1051
+ * Take back what the walk read at or beneath `rel`, a directory replaced
1052
+ * or gone since it was listed: it describes the directory that was there,
1053
+ * so no listing there proves anything absent, the entries and
1054
+ * subdirectories they left untaken aren't the cap's to report, and a
1055
+ * subdirectory proven missing there proves nothing about what's there
1056
+ * now. What was taken stays taken: the pass observes it by path.
1057
+ */
1058
+ const dropBeneath = (rel: string): void => {
1059
+ const beneath = (path: string): boolean => rel === '' || path.startsWith(rel + '/');
1060
+ for (const [path, listing] of listings) {
1061
+ if (path !== rel && !beneath(path)) continue;
1062
+ if (listing) {
1063
+ for (const [leaf, isFile] of listing.leaves) if (isFile) walk.seen.delete(leaf);
1064
+ for (const sub of listing.subdirs) walk.dirs.delete(sub);
1065
+ }
1066
+ walk.complete.delete(path);
1067
+ listings.set(path, null);
1068
+ }
1069
+ // The links, ignored names and other entries those listings showed, and
1070
+ // the regions they gave rise to, described the directory that was there.
1071
+ for (const [path] of walk.others) if (beneath(path) && !walk.othersTaken.has(path)) walk.others.delete(path);
1072
+ for (let i = walk.incomplete.length - 1; i >= 0; i--) {
1073
+ const region = walk.incomplete[i]!;
1074
+ if ((region.kind === 'symlink' || region.kind === 'ignored') && beneath(region.path)) walk.incomplete.splice(i, 1);
1075
+ }
1076
+ for (const path of walk.missing) if (beneath(path)) walk.missing.delete(path);
1077
+ };
1078
+
1079
+ const list = async (dir: CheckedDir): Promise<Listing | null> => {
772
1080
  const rel = dir.rel;
773
- if (capped) {
774
- walk.incomplete.push({ path: rel, reason: `not visited: the file cap (${cap}) was reached`, kind: 'cap' });
775
- return;
1081
+ const known = listings.get(rel);
1082
+ if (known === null) return null;
1083
+ if (known !== undefined) {
1084
+ // The scope's own directory comes back as the same CheckedDir, so its
1085
+ // identity is checked against the path again, as a subdirectory's is
1086
+ // by the fresh check that brought it here.
1087
+ const now = dir.identity();
1088
+ if (known.dev === now.dev && known.ino === now.ino && await dir.stillHere()) return known;
1089
+ dropBeneath(rel);
1090
+ fail(rel, CHANGED_WALK);
1091
+ return null;
776
1092
  }
1093
+ listings.set(rel, null);
1094
+ // Reading a directory is a check of it too, and replaces an earlier proof
1095
+ // that it was missing: the scope's own directory, read afresh on the
1096
+ // wrap, has no check of its own.
1097
+ walk.missing.delete(rel);
777
1098
  let entries;
778
1099
  try {
779
1100
  entries = await readdir(dir.real, { withFileTypes: true });
@@ -782,37 +1103,38 @@ export async function walkScope(
782
1103
  if (code === 'ENOENT' || code === 'ENOTDIR') {
783
1104
  // Gone since it was checked: absent beneath only if that can be shown.
784
1105
  const proof = rel === '' ? ROOT_UNAVAILABLE : await confirmAbsent(view, rootReal, rel, 'beneath');
785
- if (typeof proof === 'string') walk.incomplete.push({ path: rel, reason: proof, kind: 'error' });
786
- else walk.missing.add(rel);
787
- return;
1106
+ if (typeof proof === 'string') fail(rel, proof);
1107
+ else {
1108
+ walk.missing.add(rel);
1109
+ // Nothing was listed, so a later check that finds it again, on the
1110
+ // wrap, lists it afresh.
1111
+ listings.delete(rel);
1112
+ }
1113
+ return null;
788
1114
  }
789
- walk.incomplete.push({ path: rel, reason: `cannot list (${code ?? String(err)})`, kind: 'error' });
790
- return;
1115
+ fail(rel, `cannot list (${code ?? String(err)})`);
1116
+ return null;
791
1117
  }
792
- const files: string[] = [];
1118
+ entries.sort((a, b) => compareNames(a.name, b.name));
1119
+ const leaves: Array<[string, boolean]> = [];
793
1120
  const subdirs: string[] = [];
794
1121
  const others: Array<[string, string]> = [];
795
1122
  const regions: Walk['incomplete'] = [];
796
- let reachedCap = false;
797
1123
  for (const entry of entries) {
798
1124
  const childRel = rel ? `${rel}/${entry.name}` : entry.name;
799
- if (isIgnored(childRel, entry.name, ignore)) {
800
- others.push([childRel, 'ignored by the mount']);
801
- regions.push({ path: childRel, reason: 'ignored by the mount', kind: 'ignored' });
1125
+ const passedOver = passedOverBecause(childRel, entry.name, ignore, view.others);
1126
+ if (passedOver !== undefined) {
1127
+ others.push([childRel, passedOver]);
1128
+ regions.push({ path: childRel, reason: passedOver, kind: 'ignored' });
802
1129
  continue;
803
1130
  }
804
1131
  if (entry.isDirectory()) {
805
1132
  subdirs.push(childRel);
806
1133
  } else if (entry.isFile()) {
807
- if (walk.files.size + files.length >= cap) {
808
- capped = true;
809
- reachedCap = true;
810
- regions.push({ path: rel, reason: `the file cap (${cap}) was reached`, kind: 'cap' });
811
- break;
812
- }
813
- files.push(childRel);
1134
+ leaves.push([childRel, true]);
814
1135
  } else {
815
1136
  const symlink = entry.isSymbolicLink();
1137
+ leaves.push([childRel, false]);
816
1138
  others.push([childRel, symlink ? 'a symlink' : 'not a regular file']);
817
1139
  if (symlink) regions.push({ path: childRel, reason: 'a symlink, not walked', kind: 'symlink' });
818
1140
  }
@@ -820,25 +1142,103 @@ export async function walkScope(
820
1142
  // A listing of a directory that was moved or replaced meanwhile says
821
1143
  // nothing about this path: neither its names nor its absences count.
822
1144
  if (!(await dir.stillHere())) {
823
- walk.incomplete.push({ path: rel, reason: CHANGED_WALK, kind: 'error' });
824
- return;
1145
+ fail(rel, CHANGED_WALK);
1146
+ return null;
825
1147
  }
826
- for (const f of files) walk.files.add(f);
1148
+ for (const [p, isFile] of leaves) if (isFile) walk.seen.add(p);
827
1149
  for (const d of subdirs) walk.dirs.add(d);
828
1150
  for (const [p, why] of others) walk.others.set(p, why);
829
1151
  walk.incomplete.push(...regions);
830
- if (reachedCap) return;
831
1152
  walk.complete.add(rel);
1153
+ const listing = { leaves, subdirs, ...dir.identity() };
1154
+ listings.set(rel, listing);
1155
+ return listing;
1156
+ };
1157
+
1158
+ type Stretch = 'all' | 'after' | 'upto';
1159
+ const fileIn = (stretch: Stretch, file: string): boolean =>
1160
+ stretch === 'all' || (compareInWalk(file, after!) > 0) === (stretch === 'after');
1161
+ const dirIn = (stretch: Stretch, dir: string): boolean => {
1162
+ if (stretch === 'all') return true;
1163
+ const at = subtreeAgainst(dir, after!);
1164
+ return at === 'holds' || at === (stretch === 'after' ? 'after' : 'before');
1165
+ };
1166
+
1167
+ const visit = async (dir: CheckedDir, stretch: Stretch): Promise<void> => {
1168
+ visited.add(dir.rel);
1169
+ const listing = await list(dir);
1170
+ if (!listing) return;
1171
+ // A link or other entry that isn't a directory is taken as a file is,
1172
+ // against the cap: the pass observes each one it takes, and following a
1173
+ // link can read as much as a file.
1174
+ for (const [leaf, isFile] of listing.leaves) {
1175
+ if (left === 0) break;
1176
+ if (!fileIn(stretch, leaf)) continue;
1177
+ left--;
1178
+ if (isFile) {
1179
+ walk.seen.delete(leaf);
1180
+ walk.files.add(leaf);
1181
+ } else {
1182
+ walk.othersTaken.add(leaf);
1183
+ }
1184
+ lastTaken = leaf;
1185
+ }
832
1186
  if (!recursive) return;
833
- for (const sub of subdirs) {
1187
+ for (const sub of listing.subdirs) {
1188
+ // Once the cap is reached, no further directory is listed.
1189
+ if (left === 0) break;
1190
+ if (!dirIn(stretch, sub)) continue;
834
1191
  const child = await checkChild(view, rootReal, dir, sub);
835
- if (child.kind === 'checked') await visit(child.dir);
836
- else if (child.kind === 'absent') walk.missing.add(sub);
837
- else walk.incomplete.push({ path: sub, reason: child.reason, kind: 'error' });
1192
+ // This check replaces what an earlier one proved of `sub` itself, such
1193
+ // as missing on the after stretch and found again on the wrap. What was
1194
+ // proven beneath a directory that is still the same one stands, and
1195
+ // list() drops it from one that isn't.
1196
+ walk.missing.delete(sub);
1197
+ if (child.kind === 'checked') {
1198
+ await visit(child.dir, stretch);
1199
+ continue;
1200
+ }
1201
+ // On the wrap, a directory listed on the first stretch that isn't the
1202
+ // directory there now: what the walk read of it describes another.
1203
+ dropBeneath(sub);
1204
+ if (child.kind === 'absent') walk.missing.add(sub);
1205
+ else fail(sub, child.reason);
838
1206
  }
839
1207
  };
840
1208
 
841
- await visit(top.dir);
1209
+ if (after === undefined) {
1210
+ await visit(top.dir, 'all');
1211
+ } else {
1212
+ await visit(top.dir, 'after');
1213
+ if (left > 0) await visit(top.dir, 'upto');
1214
+ }
1215
+
1216
+ // What the cap left: directories holding entries not taken, and
1217
+ // directories a listing showed that weren't listed. A walk that doesn't
1218
+ // descend leaves its subdirectories by design.
1219
+ const capped = `the walk cap (${cap}) was reached`;
1220
+ const holdingUntaken = new Set<string>();
1221
+ for (const f of walk.seen) holdingUntaken.add(parentOf(f));
1222
+ for (const [p, why] of walk.others) if (!passedOverByDesign(why) && !walk.othersTaken.has(p)) holdingUntaken.add(parentOf(p));
1223
+ for (const d of holdingUntaken) {
1224
+ walk.incomplete.push({ path: d, reason: `${capped} before everything here was taken`, kind: 'cap' });
1225
+ }
1226
+ let unlisted = 0;
1227
+ if (recursive) {
1228
+ for (const d of walk.dirs) {
1229
+ if (visited.has(d) || walk.missing.has(d) || failed.has(d)) continue;
1230
+ unlisted++;
1231
+ walk.incomplete.push({ path: d, reason: `not visited: ${capped}`, kind: 'cap' });
1232
+ }
1233
+ }
1234
+ // The cap stopped the walk only if it left something: a walk whose last
1235
+ // file used up the cap covered its scope. A directory the walk didn't list
1236
+ // counts as left, even one that holds nothing it would take (empty, or
1237
+ // only names it passes over by design): telling them apart would take
1238
+ // another read. Such a
1239
+ // walk keeps its place and reports the directory as not visited, and the
1240
+ // next one lists it on its way to the wrap.
1241
+ if (left === 0 && lastTaken !== undefined && (holdingUntaken.size > 0 || unlisted > 0)) walk.stoppedAfter = lastTaken;
842
1242
  return walk;
843
1243
  }
844
1244
 
@@ -855,7 +1255,7 @@ export function provenAbsent(walk: Walk, path: string): boolean {
855
1255
  if (walk.missing.has(dir)) return true;
856
1256
  const child = dir ? `${dir}/${parts[i]}` : parts[i]!;
857
1257
  if (walk.complete.has(dir)) {
858
- if (walk.others.has(child)) return false; // present, but unproven
1258
+ if (walk.others.has(child) || walk.seen.has(child)) return false; // present, but unproven
859
1259
  if (i === parts.length - 1) return !walk.files.has(child) && !walk.dirs.has(child);
860
1260
  if (!walk.dirs.has(child)) return true; // no directory there: nothing beneath can exist
861
1261
  }