@caupulican/pi-adaptative 0.85.3 → 0.85.8

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 (411) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/bun/cli.d.ts +1 -1
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +1 -0
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/core/agent-session-runtime.d.ts +1 -1
  7. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  8. package/dist/core/agent-session-runtime.js +1 -1
  9. package/dist/core/agent-session-runtime.js.map +1 -1
  10. package/dist/core/agent-session-services.d.ts.map +1 -1
  11. package/dist/core/agent-session-services.js +2 -0
  12. package/dist/core/agent-session-services.js.map +1 -1
  13. package/dist/core/agent-session.d.ts +12 -8
  14. package/dist/core/agent-session.d.ts.map +1 -1
  15. package/dist/core/agent-session.js +82 -88
  16. package/dist/core/agent-session.js.map +1 -1
  17. package/dist/core/auth-guidance.d.ts.map +1 -1
  18. package/dist/core/auth-guidance.js +3 -0
  19. package/dist/core/auth-guidance.js.map +1 -1
  20. package/dist/core/auth-storage.d.ts +2 -2
  21. package/dist/core/auth-storage.d.ts.map +1 -1
  22. package/dist/core/auth-storage.js +2 -2
  23. package/dist/core/auth-storage.js.map +1 -1
  24. package/dist/core/autonomy/lane-tool-surface.d.ts +2 -0
  25. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  26. package/dist/core/autonomy/lane-tool-surface.js +4 -3
  27. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  28. package/dist/core/background-lane-controller.d.ts +4 -0
  29. package/dist/core/background-lane-controller.d.ts.map +1 -1
  30. package/dist/core/background-lane-controller.js +2 -0
  31. package/dist/core/background-lane-controller.js.map +1 -1
  32. package/dist/core/background-tool-task-controller.d.ts +12 -7
  33. package/dist/core/background-tool-task-controller.d.ts.map +1 -1
  34. package/dist/core/background-tool-task-controller.js +55 -19
  35. package/dist/core/background-tool-task-controller.js.map +1 -1
  36. package/dist/core/bash-executor.js +2 -2
  37. package/dist/core/bash-executor.js.map +1 -1
  38. package/dist/core/bedrock-scope.d.ts +26 -0
  39. package/dist/core/bedrock-scope.d.ts.map +1 -0
  40. package/dist/core/bedrock-scope.js +178 -0
  41. package/dist/core/bedrock-scope.js.map +1 -0
  42. package/dist/core/billing-failover-controller.d.ts +2 -2
  43. package/dist/core/billing-failover-controller.d.ts.map +1 -1
  44. package/dist/core/billing-failover-controller.js +1 -1
  45. package/dist/core/billing-failover-controller.js.map +1 -1
  46. package/dist/core/compaction-controller.d.ts +8 -2
  47. package/dist/core/compaction-controller.d.ts.map +1 -1
  48. package/dist/core/compaction-controller.js +73 -3
  49. package/dist/core/compaction-controller.js.map +1 -1
  50. package/dist/core/compaction-support.d.ts +2 -2
  51. package/dist/core/compaction-support.d.ts.map +1 -1
  52. package/dist/core/compaction-support.js +9 -1
  53. package/dist/core/compaction-support.js.map +1 -1
  54. package/dist/core/context/artifact-retrieval.d.ts +1 -1
  55. package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
  56. package/dist/core/context/artifact-retrieval.js +1 -1
  57. package/dist/core/context/artifact-retrieval.js.map +1 -1
  58. package/dist/core/context/context-artifacts.d.ts +6 -6
  59. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  60. package/dist/core/context/context-artifacts.js +151 -63
  61. package/dist/core/context/context-artifacts.js.map +1 -1
  62. package/dist/core/context/context-composition.js +1 -1
  63. package/dist/core/context/context-composition.js.map +1 -1
  64. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  65. package/dist/core/context/context-store-retention.js +5 -2
  66. package/dist/core/context/context-store-retention.js.map +1 -1
  67. package/dist/core/context/file-store-memory-provider.js +1 -1
  68. package/dist/core/context/file-store-memory-provider.js.map +1 -1
  69. package/dist/core/context/tool-output-packer.d.ts +1 -1
  70. package/dist/core/context/tool-output-packer.d.ts.map +1 -1
  71. package/dist/core/context/tool-output-packer.js +1 -1
  72. package/dist/core/context/tool-output-packer.js.map +1 -1
  73. package/dist/core/context-gc.d.ts.map +1 -1
  74. package/dist/core/context-gc.js +7 -5
  75. package/dist/core/context-gc.js.map +1 -1
  76. package/dist/core/context-pipeline.d.ts +2 -2
  77. package/dist/core/context-pipeline.d.ts.map +1 -1
  78. package/dist/core/context-pipeline.js +8 -4
  79. package/dist/core/context-pipeline.js.map +1 -1
  80. package/dist/core/cost/cost-summary.d.ts +1 -1
  81. package/dist/core/cost/cost-summary.d.ts.map +1 -1
  82. package/dist/core/cost/cost-summary.js +1 -1
  83. package/dist/core/cost/cost-summary.js.map +1 -1
  84. package/dist/core/cost/daily-usage.d.ts +1 -1
  85. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  86. package/dist/core/cost/daily-usage.js +2 -2
  87. package/dist/core/cost/daily-usage.js.map +1 -1
  88. package/dist/core/cost/session-usage.d.ts +1 -1
  89. package/dist/core/cost/session-usage.d.ts.map +1 -1
  90. package/dist/core/cost/session-usage.js +1 -1
  91. package/dist/core/cost/session-usage.js.map +1 -1
  92. package/dist/core/delegation/worker-actions.js +1 -1
  93. package/dist/core/delegation/worker-actions.js.map +1 -1
  94. package/dist/core/delegation/worker-attempt-executor.d.ts +1 -1
  95. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  96. package/dist/core/delegation/worker-attempt-executor.js +3 -2
  97. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  98. package/dist/core/delegation/worker-conversation-store.d.ts +2 -1
  99. package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -1
  100. package/dist/core/delegation/worker-conversation-store.js +3 -2
  101. package/dist/core/delegation/worker-conversation-store.js.map +1 -1
  102. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  103. package/dist/core/delegation/worker-delegation-controller.js +6 -0
  104. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  105. package/dist/core/extensions/builtin.d.ts +2 -2
  106. package/dist/core/extensions/builtin.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin.js +2 -2
  108. package/dist/core/extensions/builtin.js.map +1 -1
  109. package/dist/core/extensions/bundled-virtual-modules.d.ts +2 -0
  110. package/dist/core/extensions/bundled-virtual-modules.d.ts.map +1 -0
  111. package/dist/core/extensions/bundled-virtual-modules.js +129 -0
  112. package/dist/core/extensions/bundled-virtual-modules.js.map +1 -0
  113. package/dist/core/extensions/factory-runtime.d.ts +22 -0
  114. package/dist/core/extensions/factory-runtime.d.ts.map +1 -0
  115. package/dist/core/extensions/factory-runtime.js +334 -0
  116. package/dist/core/extensions/factory-runtime.js.map +1 -0
  117. package/dist/core/extensions/index.d.ts +1 -1
  118. package/dist/core/extensions/index.d.ts.map +1 -1
  119. package/dist/core/extensions/index.js +1 -1
  120. package/dist/core/extensions/index.js.map +1 -1
  121. package/dist/core/extensions/lifecycle.d.ts +13 -0
  122. package/dist/core/extensions/lifecycle.d.ts.map +1 -0
  123. package/dist/core/extensions/lifecycle.js +52 -0
  124. package/dist/core/extensions/lifecycle.js.map +1 -0
  125. package/dist/core/extensions/loader.d.ts +3 -24
  126. package/dist/core/extensions/loader.d.ts.map +1 -1
  127. package/dist/core/extensions/loader.js +21 -528
  128. package/dist/core/extensions/loader.js.map +1 -1
  129. package/dist/core/extensions/virtual-modules.d.ts +51 -0
  130. package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
  131. package/dist/core/extensions/virtual-modules.js +59 -0
  132. package/dist/core/extensions/virtual-modules.js.map +1 -0
  133. package/dist/core/foreground-recovery-controller.d.ts +26 -2
  134. package/dist/core/foreground-recovery-controller.d.ts.map +1 -1
  135. package/dist/core/foreground-recovery-controller.js +112 -3
  136. package/dist/core/foreground-recovery-controller.js.map +1 -1
  137. package/dist/core/foreground-terminal-handoff-controller.d.ts +27 -0
  138. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -0
  139. package/dist/core/foreground-terminal-handoff-controller.js +56 -0
  140. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -0
  141. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  142. package/dist/core/goal-loop-controller.js +5 -0
  143. package/dist/core/goal-loop-controller.js.map +1 -1
  144. package/dist/core/goals/compact-goal-context.d.ts +1 -1
  145. package/dist/core/goals/compact-goal-context.d.ts.map +1 -1
  146. package/dist/core/goals/compact-goal-context.js +1 -1
  147. package/dist/core/goals/compact-goal-context.js.map +1 -1
  148. package/dist/core/goals/goal-auto-continue-controller.d.ts +3 -0
  149. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -1
  150. package/dist/core/goals/goal-auto-continue-controller.js +28 -7
  151. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -1
  152. package/dist/core/goals/goal-session-controller.d.ts +1 -1
  153. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  154. package/dist/core/goals/goal-session-controller.js +1 -1
  155. package/dist/core/goals/goal-session-controller.js.map +1 -1
  156. package/dist/core/http-dispatcher.d.ts +1 -1
  157. package/dist/core/http-dispatcher.d.ts.map +1 -1
  158. package/dist/core/http-dispatcher.js +1 -1
  159. package/dist/core/http-dispatcher.js.map +1 -1
  160. package/dist/core/human-input-controller.d.ts +9 -0
  161. package/dist/core/human-input-controller.d.ts.map +1 -1
  162. package/dist/core/human-input-controller.js +60 -5
  163. package/dist/core/human-input-controller.js.map +1 -1
  164. package/dist/core/human-input.d.ts +12 -0
  165. package/dist/core/human-input.d.ts.map +1 -1
  166. package/dist/core/human-input.js +59 -12
  167. package/dist/core/human-input.js.map +1 -1
  168. package/dist/core/index.d.ts +3 -2
  169. package/dist/core/index.d.ts.map +1 -1
  170. package/dist/core/index.js +2 -1
  171. package/dist/core/index.js.map +1 -1
  172. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  173. package/dist/core/local-runtime-controller.js +15 -9
  174. package/dist/core/local-runtime-controller.js.map +1 -1
  175. package/dist/core/memory/providers/file-store.d.ts +1 -0
  176. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  177. package/dist/core/memory/providers/file-store.js +253 -126
  178. package/dist/core/memory/providers/file-store.js.map +1 -1
  179. package/dist/core/memory/providers/user-memory-archive.js +1 -1
  180. package/dist/core/memory/providers/user-memory-archive.js.map +1 -1
  181. package/dist/core/model-capability.d.ts +15 -1
  182. package/dist/core/model-capability.d.ts.map +1 -1
  183. package/dist/core/model-capability.js +24 -1
  184. package/dist/core/model-capability.js.map +1 -1
  185. package/dist/core/model-registry.d.ts +7 -1
  186. package/dist/core/model-registry.d.ts.map +1 -1
  187. package/dist/core/model-registry.js +22 -1
  188. package/dist/core/model-registry.js.map +1 -1
  189. package/dist/core/model-resolver.d.ts +1 -1
  190. package/dist/core/model-resolver.d.ts.map +1 -1
  191. package/dist/core/model-resolver.js +1 -1
  192. package/dist/core/model-resolver.js.map +1 -1
  193. package/dist/core/model-router-controller.d.ts +6 -6
  194. package/dist/core/model-router-controller.d.ts.map +1 -1
  195. package/dist/core/model-router-controller.js +6 -6
  196. package/dist/core/model-router-controller.js.map +1 -1
  197. package/dist/core/model-selection-controller.js +1 -1
  198. package/dist/core/model-selection-controller.js.map +1 -1
  199. package/dist/core/model-tool-protocol.d.ts +1 -1
  200. package/dist/core/model-tool-protocol.d.ts.map +1 -1
  201. package/dist/core/model-tool-protocol.js +1 -1
  202. package/dist/core/model-tool-protocol.js.map +1 -1
  203. package/dist/core/models/context-sizing.d.ts +1 -0
  204. package/dist/core/models/context-sizing.d.ts.map +1 -1
  205. package/dist/core/models/context-sizing.js +4 -1
  206. package/dist/core/models/context-sizing.js.map +1 -1
  207. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  208. package/dist/core/models/default-model-suggestions.js +20 -10
  209. package/dist/core/models/default-model-suggestions.js.map +1 -1
  210. package/dist/core/models/llamacpp-runtime.d.ts +39 -11
  211. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -1
  212. package/dist/core/models/llamacpp-runtime.js +87 -31
  213. package/dist/core/models/llamacpp-runtime.js.map +1 -1
  214. package/dist/core/models/local-execution-planner.d.ts +24 -0
  215. package/dist/core/models/local-execution-planner.d.ts.map +1 -0
  216. package/dist/core/models/local-execution-planner.js +119 -0
  217. package/dist/core/models/local-execution-planner.js.map +1 -0
  218. package/dist/core/models/local-inference-profile.d.ts +34 -0
  219. package/dist/core/models/local-inference-profile.d.ts.map +1 -0
  220. package/dist/core/models/local-inference-profile.js +74 -0
  221. package/dist/core/models/local-inference-profile.js.map +1 -0
  222. package/dist/core/models/local-runtime.d.ts +23 -4
  223. package/dist/core/models/local-runtime.d.ts.map +1 -1
  224. package/dist/core/models/local-runtime.js +12 -9
  225. package/dist/core/models/local-runtime.js.map +1 -1
  226. package/dist/core/models/managed-ollama-model.d.ts +26 -0
  227. package/dist/core/models/managed-ollama-model.d.ts.map +1 -0
  228. package/dist/core/models/managed-ollama-model.js +59 -0
  229. package/dist/core/models/managed-ollama-model.js.map +1 -0
  230. package/dist/core/models/model-ref.js +11 -11
  231. package/dist/core/models/model-ref.js.map +1 -1
  232. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +10 -20
  233. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -1
  234. package/dist/core/models/prism-llamacpp-lifecycle.js +11 -31
  235. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -1
  236. package/dist/core/models/prism-llamacpp-server-probe.d.ts +10 -0
  237. package/dist/core/models/prism-llamacpp-server-probe.d.ts.map +1 -0
  238. package/dist/core/models/prism-llamacpp-server-probe.js +36 -0
  239. package/dist/core/models/prism-llamacpp-server-probe.js.map +1 -0
  240. package/dist/core/models/runtime-arbiter.d.ts +3 -0
  241. package/dist/core/models/runtime-arbiter.d.ts.map +1 -1
  242. package/dist/core/models/runtime-arbiter.js +2 -1
  243. package/dist/core/models/runtime-arbiter.js.map +1 -1
  244. package/dist/core/orchestration/model-binding.d.ts +1 -1
  245. package/dist/core/orchestration/model-binding.d.ts.map +1 -1
  246. package/dist/core/orchestration/model-binding.js +1 -1
  247. package/dist/core/orchestration/model-binding.js.map +1 -1
  248. package/dist/core/orchestration/task-profile-writer.js +1 -1
  249. package/dist/core/orchestration/task-profile-writer.js.map +1 -1
  250. package/dist/core/process-matrix/runtime.d.ts +15 -1
  251. package/dist/core/process-matrix/runtime.d.ts.map +1 -1
  252. package/dist/core/process-matrix/runtime.js +55 -34
  253. package/dist/core/process-matrix/runtime.js.map +1 -1
  254. package/dist/core/reflection-controller.d.ts +4 -3
  255. package/dist/core/reflection-controller.d.ts.map +1 -1
  256. package/dist/core/reflection-controller.js +2 -2
  257. package/dist/core/reflection-controller.js.map +1 -1
  258. package/dist/core/research/model-fitness-controller.js +1 -1
  259. package/dist/core/research/model-fitness-controller.js.map +1 -1
  260. package/dist/core/research/research-lane-controller.d.ts +2 -2
  261. package/dist/core/research/research-lane-controller.d.ts.map +1 -1
  262. package/dist/core/research/research-lane-controller.js +15 -6
  263. package/dist/core/research/research-lane-controller.js.map +1 -1
  264. package/dist/core/resource-loader.d.ts +10 -19
  265. package/dist/core/resource-loader.d.ts.map +1 -1
  266. package/dist/core/resource-loader.js +8 -70
  267. package/dist/core/resource-loader.js.map +1 -1
  268. package/dist/core/runtime-builder.d.ts +5 -1
  269. package/dist/core/runtime-builder.d.ts.map +1 -1
  270. package/dist/core/runtime-builder.js +50 -7
  271. package/dist/core/runtime-builder.js.map +1 -1
  272. package/dist/core/scout-controller.d.ts +4 -3
  273. package/dist/core/scout-controller.d.ts.map +1 -1
  274. package/dist/core/scout-controller.js +2 -1
  275. package/dist/core/scout-controller.js.map +1 -1
  276. package/dist/core/sdk.d.ts +2 -2
  277. package/dist/core/sdk.d.ts.map +1 -1
  278. package/dist/core/sdk.js +13 -11
  279. package/dist/core/sdk.js.map +1 -1
  280. package/dist/core/security/context-threat-scanner.d.ts +14 -0
  281. package/dist/core/security/context-threat-scanner.d.ts.map +1 -0
  282. package/dist/core/security/context-threat-scanner.js +71 -0
  283. package/dist/core/security/context-threat-scanner.js.map +1 -0
  284. package/dist/core/session-supervision-runtime.d.ts +4 -1
  285. package/dist/core/session-supervision-runtime.d.ts.map +1 -1
  286. package/dist/core/session-supervision-runtime.js +49 -11
  287. package/dist/core/session-supervision-runtime.js.map +1 -1
  288. package/dist/core/settings-manager.d.ts +13 -0
  289. package/dist/core/settings-manager.d.ts.map +1 -1
  290. package/dist/core/settings-manager.js +60 -1
  291. package/dist/core/settings-manager.js.map +1 -1
  292. package/dist/core/system-prompt-builder.d.ts +5 -2
  293. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  294. package/dist/core/system-prompt-builder.js +22 -10
  295. package/dist/core/system-prompt-builder.js.map +1 -1
  296. package/dist/core/system-prompt.d.ts +3 -0
  297. package/dist/core/system-prompt.d.ts.map +1 -1
  298. package/dist/core/system-prompt.js +181 -55
  299. package/dist/core/system-prompt.js.map +1 -1
  300. package/dist/core/tool-protocol-controller.d.ts.map +1 -1
  301. package/dist/core/tool-protocol-controller.js +5 -3
  302. package/dist/core/tool-protocol-controller.js.map +1 -1
  303. package/dist/core/tool-recovery-logger.js +1 -1
  304. package/dist/core/tool-recovery-logger.js.map +1 -1
  305. package/dist/core/tools/artifact-retrieve.js +1 -1
  306. package/dist/core/tools/artifact-retrieve.js.map +1 -1
  307. package/dist/core/tools/bash.d.ts +2 -2
  308. package/dist/core/tools/bash.d.ts.map +1 -1
  309. package/dist/core/tools/bash.js +16 -4
  310. package/dist/core/tools/bash.js.map +1 -1
  311. package/dist/core/tools/edit-diff.d.ts +2 -0
  312. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  313. package/dist/core/tools/edit-diff.js +9 -1
  314. package/dist/core/tools/edit-diff.js.map +1 -1
  315. package/dist/core/tools/edit.d.ts +5 -8
  316. package/dist/core/tools/edit.d.ts.map +1 -1
  317. package/dist/core/tools/edit.js +88 -55
  318. package/dist/core/tools/edit.js.map +1 -1
  319. package/dist/core/tools/extensionify-runtime.d.ts +44 -0
  320. package/dist/core/tools/extensionify-runtime.d.ts.map +1 -0
  321. package/dist/core/tools/extensionify-runtime.js +115 -0
  322. package/dist/core/tools/extensionify-runtime.js.map +1 -0
  323. package/dist/core/tools/extensionify.d.ts +9 -30
  324. package/dist/core/tools/extensionify.d.ts.map +1 -1
  325. package/dist/core/tools/extensionify.js +10 -140
  326. package/dist/core/tools/extensionify.js.map +1 -1
  327. package/dist/core/tools/file-mutation-intent.d.ts +42 -15
  328. package/dist/core/tools/file-mutation-intent.d.ts.map +1 -1
  329. package/dist/core/tools/file-mutation-intent.js +271 -77
  330. package/dist/core/tools/file-mutation-intent.js.map +1 -1
  331. package/dist/core/tools/find.d.ts +1 -1
  332. package/dist/core/tools/find.d.ts.map +1 -1
  333. package/dist/core/tools/find.js +1 -1
  334. package/dist/core/tools/find.js.map +1 -1
  335. package/dist/core/tools/index.d.ts +3 -5
  336. package/dist/core/tools/index.d.ts.map +1 -1
  337. package/dist/core/tools/index.js +8 -44
  338. package/dist/core/tools/index.js.map +1 -1
  339. package/dist/core/tools/ls.d.ts +1 -1
  340. package/dist/core/tools/ls.d.ts.map +1 -1
  341. package/dist/core/tools/ls.js +1 -1
  342. package/dist/core/tools/ls.js.map +1 -1
  343. package/dist/core/tools/output-accumulator.d.ts +1 -1
  344. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  345. package/dist/core/tools/output-accumulator.js +1 -1
  346. package/dist/core/tools/output-accumulator.js.map +1 -1
  347. package/dist/core/tools/render-utils.js +1 -1
  348. package/dist/core/tools/render-utils.js.map +1 -1
  349. package/dist/core/tools/search-command-guard.d.ts +8 -0
  350. package/dist/core/tools/search-command-guard.d.ts.map +1 -1
  351. package/dist/core/tools/search-command-guard.js +54 -0
  352. package/dist/core/tools/search-command-guard.js.map +1 -1
  353. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  354. package/dist/core/tools/shell-contract-router.js +9 -4
  355. package/dist/core/tools/shell-contract-router.js.map +1 -1
  356. package/dist/core/tools/shell-session.d.ts.map +1 -1
  357. package/dist/core/tools/shell-session.js +6 -4
  358. package/dist/core/tools/shell-session.js.map +1 -1
  359. package/dist/core/tools/tool-definition-factory.d.ts +32 -0
  360. package/dist/core/tools/tool-definition-factory.d.ts.map +1 -0
  361. package/dist/core/tools/tool-definition-factory.js +55 -0
  362. package/dist/core/tools/tool-definition-factory.js.map +1 -0
  363. package/dist/core/tools/write.d.ts +5 -10
  364. package/dist/core/tools/write.d.ts.map +1 -1
  365. package/dist/core/tools/write.js +92 -73
  366. package/dist/core/tools/write.js.map +1 -1
  367. package/dist/core/util/atomic-file.d.ts.map +1 -1
  368. package/dist/core/util/atomic-file.js +79 -32
  369. package/dist/core/util/atomic-file.js.map +1 -1
  370. package/dist/index.d.ts +3 -2
  371. package/dist/index.d.ts.map +1 -1
  372. package/dist/index.js +3 -2
  373. package/dist/index.js.map +1 -1
  374. package/dist/main.d.ts +2 -0
  375. package/dist/main.d.ts.map +1 -1
  376. package/dist/main.js +24 -18
  377. package/dist/main.js.map +1 -1
  378. package/dist/modes/interactive/auth-dialogs-controller.d.ts +6 -0
  379. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -1
  380. package/dist/modes/interactive/auth-dialogs-controller.js +59 -12
  381. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -1
  382. package/dist/modes/interactive/auto-learn-controller.js +1 -1
  383. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  384. package/dist/modes/interactive/components/tool-execution.js +1 -1
  385. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  386. package/dist/modes/interactive/interactive-event-controller.js +1 -1
  387. package/dist/modes/interactive/interactive-event-controller.js.map +1 -1
  388. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  389. package/dist/modes/interactive/interactive-mode.js +1 -1
  390. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  391. package/dist/modes/interactive/local-model-commands.d.ts +1 -1
  392. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  393. package/dist/modes/interactive/local-model-commands.js +51 -8
  394. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  395. package/dist/utils/child-process.js +1 -1
  396. package/dist/utils/child-process.js.map +1 -1
  397. package/docs/providers.md +34 -10
  398. package/docs/tool-boundary-performance-roadmap-2026-08-02.md +21 -18
  399. package/examples/extensions/built-in-tool-renderer.ts +1 -1
  400. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  401. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  402. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  403. package/examples/extensions/minimal-mode.ts +1 -1
  404. package/examples/extensions/prompt-customizer.ts +2 -2
  405. package/examples/extensions/sandbox/package-lock.json +2 -2
  406. package/examples/extensions/sandbox/package.json +1 -1
  407. package/examples/extensions/ssh.ts +17 -0
  408. package/examples/extensions/with-deps/package-lock.json +2 -2
  409. package/examples/extensions/with-deps/package.json +1 -1
  410. package/npm-shrinkwrap.json +240 -260
  411. package/package.json +9 -7
@@ -16,55 +16,82 @@ export interface FileMutationIntentOperations {
16
16
  access(path: string, mode: number): Promise<void>;
17
17
  copyFileExclusive(sourcePath: string, targetPath: string): Promise<void>;
18
18
  hashFile(path: string, signal?: AbortSignal): Promise<string>;
19
+ readPayload(path: string): Promise<string>;
19
20
  removeFile(path: string): Promise<void>;
21
+ stagePayload(content: string, ttlMs: number): Promise<string>;
20
22
  }
21
- export interface PreparedFileMutation {
22
- intentId: string;
23
+ export interface FileMutationLease {
23
24
  kind: FileMutationKind;
24
25
  path: string;
25
26
  displayPath: string;
26
- }
27
- export interface FileMutationLease extends PreparedFileMutation {
28
27
  identity?: FilePathIdentity;
29
28
  }
30
29
  export interface FileContentReference {
31
30
  contentRef: string;
32
31
  byteLength: number;
33
32
  }
33
+ export interface FileMutationPayloadReference {
34
+ payloadRef: string;
35
+ byteLength: number;
36
+ }
37
+ export type FileMutationPreflightFailureReason = "write_collision" | "edit_missing" | "edit_not_file";
38
+ export declare class FileMutationPreflightError extends Error {
39
+ readonly reason: FileMutationPreflightFailureReason;
40
+ constructor(reason: FileMutationPreflightFailureReason, message: string);
41
+ }
34
42
  export interface FileMutationIntentControllerOptions {
35
43
  operations?: FileMutationIntentOperations;
36
- intentLimit?: number;
37
44
  contentReferenceLimit?: number;
38
- intentTtlMs?: number;
39
45
  contentReferenceTtlMs?: number;
46
+ mutationPayloadLimit?: number;
47
+ mutationPayloadByteLimit?: number;
48
+ mutationPayloadTtlMs?: number;
40
49
  now?: () => number;
41
50
  }
42
51
  export declare const localFileMutationIntentOperations: FileMutationIntentOperations;
43
52
  /**
44
- * Session-owned authority for two-phase file mutation intents and bounded exact-content references.
45
- * It retains only fixed-size metadata; file bytes remain owned by the filesystem.
53
+ * Session-owned harness authority for file-mutation preflight, stale-target checks,
54
+ * and bounded exact-content references. It retains only fixed-size metadata; file
55
+ * bytes remain owned by the filesystem.
46
56
  */
47
57
  export declare class FileMutationIntentController {
48
58
  private readonly operations;
49
- private readonly intentLimit;
50
59
  private readonly contentReferenceLimit;
51
- private readonly intentTtlMs;
52
60
  private readonly contentReferenceTtlMs;
61
+ private readonly mutationPayloadLimit;
62
+ private readonly mutationPayloadByteLimit;
63
+ private readonly mutationPayloadTtlMs;
53
64
  private readonly now;
54
- private readonly intents;
55
- private readonly intentByPath;
56
65
  private readonly contentReferences;
66
+ private readonly mutationPayloads;
67
+ private mutationPayloadBytes;
68
+ private lastMutationPayloadExpiresAt;
69
+ private mutationPayloadOperationTail;
57
70
  constructor(options?: FileMutationIntentControllerOptions);
58
- prepare(kind: FileMutationKind, path: string, signal?: AbortSignal, displayPath?: string): Promise<PreparedFileMutation>;
59
- consume(intentId: string, kind: FileMutationKind, path: string): FileMutationLease;
71
+ prepare(kind: FileMutationKind, path: string, signal?: AbortSignal, displayPath?: string): Promise<FileMutationLease>;
60
72
  assertCurrent(lease: FileMutationLease, signal?: AbortSignal): Promise<void>;
61
73
  rememberContent(sourcePath: string, content: string): FileContentReference;
74
+ retainMutationPayload(kind: FileMutationKind, payload: string): Promise<FileMutationPayloadReference | undefined>;
75
+ readMutationPayload(payloadRef: string, kind: FileMutationKind, signal?: AbortSignal): Promise<string>;
76
+ assertMutationPayload(payloadRef: string, kind: FileMutationKind, signal?: AbortSignal): Promise<void>;
77
+ assertContentReference(contentRef: string, signal?: AbortSignal): Promise<void>;
78
+ copyMutationPayload(payloadRef: string, targetPath: string, signal?: AbortSignal): Promise<FileContentReference>;
79
+ discardMutationPayload(payloadRef: string): Promise<void>;
80
+ /** Release every payload owned by this controller without touching another controller's files. */
81
+ dispose(): Promise<void>;
62
82
  copyReferencedContent(contentRef: string, targetPath: string, signal?: AbortSignal): Promise<FileContentReference>;
83
+ private requireVerifiedContentReference;
84
+ private requireMutationPayload;
85
+ private requireVerifiedMutationPayload;
86
+ private verifySource;
87
+ private copyVerifiedSource;
63
88
  private assertCreatableParent;
64
89
  private rememberContentDigest;
65
90
  private touchContentReference;
66
91
  private removeFailedCopy;
67
- private deleteIntent;
92
+ private deleteMutationPayload;
93
+ private runMutationPayloadOperation;
94
+ private pruneExpiredMutationPayloads;
68
95
  private pruneExpired;
69
96
  }
70
97
  //# sourceMappingURL=file-mutation-intent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-mutation-intent.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-intent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-mutation-intent.d.ts","sourceRoot":"","sources":["../../../src/core/tools/file-mutation-intent.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,38 @@
1
1
  import { createHash, randomUUID } from "node:crypto";
2
- import { constants } from "node:fs";
3
- import { access, copyFile, lstat, open, stat, unlink } from "node:fs/promises";
4
- import { dirname, resolve } from "node:path";
5
- const DEFAULT_INTENT_LIMIT = 64;
2
+ import { constants, rmSync } from "node:fs";
3
+ import { access, copyFile, lstat, mkdtemp, open, readFile, stat, unlink, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { dirname, join, resolve } from "node:path";
6
6
  const DEFAULT_CONTENT_REFERENCE_LIMIT = 64;
7
- const DEFAULT_INTENT_TTL_MS = 10 * 60 * 1000;
8
7
  const DEFAULT_CONTENT_REFERENCE_TTL_MS = 60 * 60 * 1000;
8
+ const DEFAULT_MUTATION_PAYLOAD_LIMIT = 8;
9
+ const DEFAULT_MUTATION_PAYLOAD_BYTE_LIMIT = 16 * 1024 * 1024;
10
+ const DEFAULT_MUTATION_PAYLOAD_TTL_MS = 10 * 60 * 1000;
9
11
  const HASH_BUFFER_BYTES = 64 * 1024;
10
12
  const CONTENT_REFERENCE_PREFIX = "file-content:";
13
+ const MUTATION_PAYLOAD_REFERENCE_PREFIX = "file-mutation:";
14
+ const LOCAL_MUTATION_PAYLOAD_DIRECTORY_PREFIX = "pi-file-mutation-payloads-";
15
+ const LOCAL_MUTATION_PAYLOAD_PROCESS_BYTE_LIMIT = 64 * 1024 * 1024;
16
+ const LOCAL_MUTATION_PAYLOAD_PROCESS_FILE_LIMIT = 64;
17
+ let localMutationPayloadDirectoryPromise;
18
+ let localMutationPayloadDirectory;
19
+ let localMutationPayloadCleanupRegistered = false;
20
+ let localMutationPayloadOperationTail = Promise.resolve();
21
+ let localMutationPayloadBytes = 0;
22
+ const localMutationPayloadFiles = new Map();
23
+ class MutationPayloadCapacityError extends Error {
24
+ constructor() {
25
+ super("Process mutation payload cache is full.");
26
+ this.name = "MutationPayloadCapacityError";
27
+ }
28
+ }
29
+ export class FileMutationPreflightError extends Error {
30
+ constructor(reason, message) {
31
+ super(message);
32
+ this.name = "FileMutationPreflightError";
33
+ this.reason = reason;
34
+ }
35
+ }
11
36
  function isMissingPathError(error) {
12
37
  return (typeof error === "object" &&
13
38
  error !== null &&
@@ -19,10 +44,6 @@ function errorCode(error) {
19
44
  ? error.code
20
45
  : undefined;
21
46
  }
22
- function normalizedPath(path) {
23
- const absolutePath = resolve(path);
24
- return process.platform === "win32" ? absolutePath.toLocaleLowerCase("en-US") : absolutePath;
25
- }
26
47
  function positiveBound(value, fallback, label) {
27
48
  const resolvedValue = value ?? fallback;
28
49
  if (!Number.isSafeInteger(resolvedValue) || resolvedValue < 1) {
@@ -85,27 +106,95 @@ async function hashLocalFile(path, signal) {
85
106
  await handle.close();
86
107
  }
87
108
  }
109
+ async function getLocalMutationPayloadDirectory() {
110
+ localMutationPayloadDirectoryPromise ??= mkdtemp(join(tmpdir(), LOCAL_MUTATION_PAYLOAD_DIRECTORY_PREFIX)).then((path) => {
111
+ localMutationPayloadDirectory = path;
112
+ if (!localMutationPayloadCleanupRegistered) {
113
+ localMutationPayloadCleanupRegistered = true;
114
+ process.once("exit", () => {
115
+ if (localMutationPayloadDirectory) {
116
+ try {
117
+ rmSync(localMutationPayloadDirectory, { recursive: true, force: true });
118
+ }
119
+ catch {
120
+ // Process shutdown cannot safely retry filesystem cleanup.
121
+ }
122
+ }
123
+ });
124
+ }
125
+ return path;
126
+ });
127
+ return localMutationPayloadDirectoryPromise;
128
+ }
129
+ async function stageLocalMutationPayload(content, ttlMs) {
130
+ const byteLength = Buffer.byteLength(content, "utf8");
131
+ let stagedPath = "";
132
+ const operation = localMutationPayloadOperationTail.then(async () => {
133
+ for (const [path, record] of localMutationPayloadFiles) {
134
+ if (record.expiresAt > Date.now())
135
+ continue;
136
+ localMutationPayloadFiles.delete(path);
137
+ localMutationPayloadBytes -= record.byteLength;
138
+ try {
139
+ await unlink(path);
140
+ }
141
+ catch (error) {
142
+ if (!isMissingPathError(error))
143
+ throw error;
144
+ }
145
+ }
146
+ if (localMutationPayloadFiles.size >= LOCAL_MUTATION_PAYLOAD_PROCESS_FILE_LIMIT ||
147
+ localMutationPayloadBytes + byteLength > LOCAL_MUTATION_PAYLOAD_PROCESS_BYTE_LIMIT) {
148
+ throw new MutationPayloadCapacityError();
149
+ }
150
+ stagedPath = join(await getLocalMutationPayloadDirectory(), randomUUID());
151
+ await writeFile(stagedPath, content, { encoding: "utf8", flag: "wx", mode: 0o600 });
152
+ localMutationPayloadFiles.set(stagedPath, { byteLength, expiresAt: Date.now() + ttlMs });
153
+ localMutationPayloadBytes += byteLength;
154
+ });
155
+ localMutationPayloadOperationTail = operation.catch(() => { });
156
+ await operation;
157
+ return stagedPath;
158
+ }
159
+ async function removeLocalMutationPayloadOrFile(path) {
160
+ const operation = localMutationPayloadOperationTail.then(async () => {
161
+ const record = localMutationPayloadFiles.get(path);
162
+ if (record !== undefined) {
163
+ localMutationPayloadFiles.delete(path);
164
+ localMutationPayloadBytes -= record.byteLength;
165
+ }
166
+ await unlink(path);
167
+ });
168
+ localMutationPayloadOperationTail = operation.catch(() => { });
169
+ await operation;
170
+ }
88
171
  export const localFileMutationIntentOperations = {
89
172
  inspect: inspectLocalPath,
90
173
  access,
91
174
  copyFileExclusive: (sourcePath, targetPath) => copyFile(sourcePath, targetPath, constants.COPYFILE_EXCL),
92
175
  hashFile: hashLocalFile,
93
- removeFile: unlink,
176
+ readPayload: (path) => readFile(path, "utf8"),
177
+ removeFile: removeLocalMutationPayloadOrFile,
178
+ stagePayload: stageLocalMutationPayload,
94
179
  };
95
180
  /**
96
- * Session-owned authority for two-phase file mutation intents and bounded exact-content references.
97
- * It retains only fixed-size metadata; file bytes remain owned by the filesystem.
181
+ * Session-owned harness authority for file-mutation preflight, stale-target checks,
182
+ * and bounded exact-content references. It retains only fixed-size metadata; file
183
+ * bytes remain owned by the filesystem.
98
184
  */
99
185
  export class FileMutationIntentController {
100
186
  constructor(options = {}) {
101
- this.intents = new Map();
102
- this.intentByPath = new Map();
103
187
  this.contentReferences = new Map();
188
+ this.mutationPayloads = new Map();
189
+ this.mutationPayloadBytes = 0;
190
+ this.lastMutationPayloadExpiresAt = 0;
191
+ this.mutationPayloadOperationTail = Promise.resolve();
104
192
  this.operations = options.operations ?? localFileMutationIntentOperations;
105
- this.intentLimit = positiveBound(options.intentLimit, DEFAULT_INTENT_LIMIT, "Intent limit");
106
193
  this.contentReferenceLimit = positiveBound(options.contentReferenceLimit, DEFAULT_CONTENT_REFERENCE_LIMIT, "Content reference limit");
107
- this.intentTtlMs = positiveBound(options.intentTtlMs, DEFAULT_INTENT_TTL_MS, "Intent TTL");
108
194
  this.contentReferenceTtlMs = positiveBound(options.contentReferenceTtlMs, DEFAULT_CONTENT_REFERENCE_TTL_MS, "Content reference TTL");
195
+ this.mutationPayloadLimit = positiveBound(options.mutationPayloadLimit, DEFAULT_MUTATION_PAYLOAD_LIMIT, "Mutation payload limit");
196
+ this.mutationPayloadByteLimit = positiveBound(options.mutationPayloadByteLimit, DEFAULT_MUTATION_PAYLOAD_BYTE_LIMIT, "Mutation payload byte limit");
197
+ this.mutationPayloadTtlMs = positiveBound(options.mutationPayloadTtlMs, DEFAULT_MUTATION_PAYLOAD_TTL_MS, "Mutation payload TTL");
109
198
  this.now = options.now ?? Date.now;
110
199
  }
111
200
  async prepare(kind, path, signal, displayPath = path) {
@@ -116,16 +205,19 @@ export class FileMutationIntentController {
116
205
  let identity;
117
206
  if (kind === "write") {
118
207
  const existing = await this.operations.inspect(absolutePath, false);
119
- if (existing)
120
- throw new Error(`Write collision: ${displayPath} already exists.`);
208
+ if (existing) {
209
+ throw new FileMutationPreflightError("write_collision", `Write collision: ${displayPath} already exists.`);
210
+ }
121
211
  await this.assertCreatableParent(absolutePath);
122
212
  }
123
213
  else {
124
214
  const existing = await this.operations.inspect(absolutePath, true);
125
- if (!existing)
126
- throw new Error(`Could not edit file: ${displayPath}. Error code: ENOENT.`);
127
- if (existing.kind !== "file")
128
- throw new Error(`Could not edit file: ${displayPath}. Target is not a regular file.`);
215
+ if (!existing) {
216
+ throw new FileMutationPreflightError("edit_missing", `Could not edit file: ${displayPath}. Error code: ENOENT.`);
217
+ }
218
+ if (existing.kind !== "file") {
219
+ throw new FileMutationPreflightError("edit_not_file", `Could not edit file: ${displayPath}. Target is not a regular file.`);
220
+ }
129
221
  try {
130
222
  await this.operations.access(absolutePath, constants.R_OK | constants.W_OK);
131
223
  }
@@ -137,46 +229,11 @@ export class FileMutationIntentController {
137
229
  }
138
230
  if (signal?.aborted)
139
231
  throw new Error("Operation aborted");
140
- const key = `${kind}\0${normalizedPath(absolutePath)}`;
141
- const priorIntentId = this.intentByPath.get(key);
142
- if (priorIntentId)
143
- this.deleteIntent(priorIntentId);
144
- while (this.intents.size >= this.intentLimit) {
145
- const oldestIntentId = this.intents.keys().next().value;
146
- if (typeof oldestIntentId !== "string")
147
- break;
148
- this.deleteIntent(oldestIntentId);
149
- }
150
- const intentId = randomUUID();
151
- const record = {
152
- intentId,
232
+ return {
153
233
  kind,
154
234
  path: absolutePath,
155
235
  displayPath,
156
236
  ...(identity ? { identity } : {}),
157
- expiresAt: this.now() + this.intentTtlMs,
158
- };
159
- this.intents.set(intentId, record);
160
- this.intentByPath.set(key, intentId);
161
- return { intentId, kind, path: absolutePath, displayPath };
162
- }
163
- consume(intentId, kind, path) {
164
- this.pruneExpired();
165
- const record = this.intents.get(intentId);
166
- if (!record)
167
- throw new Error("File mutation intent is invalid, expired, or belongs to another session.");
168
- this.deleteIntent(intentId);
169
- if (record.kind !== kind)
170
- throw new Error(`File mutation intent is for ${record.kind}, not ${kind}.`);
171
- if (normalizedPath(record.path) !== normalizedPath(path)) {
172
- throw new Error("File mutation intent path does not match the commit path.");
173
- }
174
- return {
175
- intentId: record.intentId,
176
- kind: record.kind,
177
- path: record.path,
178
- displayPath: record.displayPath,
179
- ...(record.identity ? { identity: record.identity } : {}),
180
237
  };
181
238
  }
182
239
  async assertCurrent(lease, signal) {
@@ -184,16 +241,16 @@ export class FileMutationIntentController {
184
241
  throw new Error("Operation aborted");
185
242
  if (lease.kind === "write") {
186
243
  if (await this.operations.inspect(lease.path, false)) {
187
- throw new Error(`Write collision: ${lease.displayPath} already exists; the prepared intent is stale.`);
244
+ throw new FileMutationPreflightError("write_collision", `Write collision: ${lease.displayPath} became occupied after preflight; no content was overwritten.`);
188
245
  }
189
246
  return;
190
247
  }
191
248
  const current = await this.operations.inspect(lease.path, true);
192
249
  if (!current || current.kind !== "file") {
193
- throw new Error(`Could not edit file: ${lease.displayPath}. The prepared target no longer exists.`);
250
+ throw new Error(`Could not edit file: ${lease.displayPath}. The target no longer exists after preflight.`);
194
251
  }
195
252
  if (!identitiesMatch(lease.identity, current.identity)) {
196
- throw new Error(`Could not edit file: ${lease.displayPath}. The file changed after preparation; prepare again.`);
253
+ throw new Error(`Could not edit file: ${lease.displayPath}. The file changed during edit execution; read it again before retrying.`);
197
254
  }
198
255
  try {
199
256
  await this.operations.access(lease.path, constants.R_OK | constants.W_OK);
@@ -207,7 +264,97 @@ export class FileMutationIntentController {
207
264
  const digest = createHash("sha256").update(content, "utf8").digest("hex");
208
265
  return this.rememberContentDigest(sourcePath, digest, Buffer.byteLength(content, "utf8"));
209
266
  }
267
+ async retainMutationPayload(kind, payload) {
268
+ return this.runMutationPayloadOperation(async () => {
269
+ await this.pruneExpiredMutationPayloads();
270
+ const byteLength = Buffer.byteLength(payload, "utf8");
271
+ if (byteLength > this.mutationPayloadByteLimit)
272
+ return undefined;
273
+ while (this.mutationPayloads.size >= this.mutationPayloadLimit ||
274
+ this.mutationPayloadBytes + byteLength > this.mutationPayloadByteLimit) {
275
+ const oldestPayloadRef = this.mutationPayloads.keys().next().value;
276
+ if (typeof oldestPayloadRef !== "string")
277
+ return undefined;
278
+ await this.deleteMutationPayload(oldestPayloadRef, true);
279
+ }
280
+ // Keep insertion and expiry order identical, even if the wall clock moves backward. Expiry
281
+ // pruning can then stop at the first live record instead of rescanning every retained payload.
282
+ const expiresAt = Math.max(this.lastMutationPayloadExpiresAt, this.now() + this.mutationPayloadTtlMs);
283
+ this.lastMutationPayloadExpiresAt = expiresAt;
284
+ let sourcePath;
285
+ try {
286
+ sourcePath = await this.operations.stagePayload(payload, this.mutationPayloadTtlMs);
287
+ }
288
+ catch (error) {
289
+ if (error instanceof MutationPayloadCapacityError)
290
+ return undefined;
291
+ throw error;
292
+ }
293
+ const payloadRef = `${MUTATION_PAYLOAD_REFERENCE_PREFIX}${randomUUID()}`;
294
+ this.mutationPayloads.set(payloadRef, {
295
+ payloadRef,
296
+ kind,
297
+ sourcePath,
298
+ digest: createHash("sha256").update(payload, "utf8").digest("hex"),
299
+ byteLength,
300
+ expiresAt,
301
+ });
302
+ this.mutationPayloadBytes += byteLength;
303
+ return { payloadRef, byteLength };
304
+ });
305
+ }
306
+ async readMutationPayload(payloadRef, kind, signal) {
307
+ return this.runMutationPayloadOperation(async () => {
308
+ const record = await this.requireMutationPayload(payloadRef, kind, signal);
309
+ const payload = await this.operations.readPayload(record.sourcePath);
310
+ if (createHash("sha256").update(payload, "utf8").digest("hex") !== record.digest) {
311
+ await this.deleteMutationPayload(payloadRef);
312
+ throw new Error("Retained file mutation payload changed after it was cached.");
313
+ }
314
+ return payload;
315
+ });
316
+ }
317
+ async assertMutationPayload(payloadRef, kind, signal) {
318
+ await this.runMutationPayloadOperation(async () => {
319
+ await this.requireVerifiedMutationPayload(payloadRef, kind, signal);
320
+ });
321
+ }
322
+ async assertContentReference(contentRef, signal) {
323
+ await this.requireVerifiedContentReference(contentRef, signal);
324
+ }
325
+ async copyMutationPayload(payloadRef, targetPath, signal) {
326
+ return this.runMutationPayloadOperation(async () => {
327
+ const record = await this.requireVerifiedMutationPayload(payloadRef, "write", signal);
328
+ await this.copyVerifiedSource(record, targetPath, signal);
329
+ await this.deleteMutationPayload(payloadRef);
330
+ return this.rememberContentDigest(targetPath, record.digest, record.byteLength);
331
+ });
332
+ }
333
+ async discardMutationPayload(payloadRef) {
334
+ await this.runMutationPayloadOperation(() => this.deleteMutationPayload(payloadRef));
335
+ }
336
+ /** Release every payload owned by this controller without touching another controller's files. */
337
+ async dispose() {
338
+ await this.runMutationPayloadOperation(async () => {
339
+ let firstError;
340
+ for (const payloadRef of [...this.mutationPayloads.keys()]) {
341
+ try {
342
+ await this.deleteMutationPayload(payloadRef, true);
343
+ }
344
+ catch (error) {
345
+ firstError ??= error;
346
+ }
347
+ }
348
+ if (firstError)
349
+ throw firstError;
350
+ });
351
+ }
210
352
  async copyReferencedContent(contentRef, targetPath, signal) {
353
+ const record = await this.requireVerifiedContentReference(contentRef, signal);
354
+ await this.copyVerifiedSource(record, targetPath, signal);
355
+ return this.rememberContentDigest(targetPath, record.digest, record.byteLength);
356
+ }
357
+ async requireVerifiedContentReference(contentRef, signal) {
211
358
  this.pruneExpired();
212
359
  const record = this.contentReferences.get(contentRef);
213
360
  if (!record)
@@ -215,17 +362,51 @@ export class FileMutationIntentController {
215
362
  this.touchContentReference(record);
216
363
  if (signal?.aborted)
217
364
  throw new Error("Operation aborted");
365
+ try {
366
+ await this.verifySource(record, signal, "File content reference source");
367
+ }
368
+ catch (error) {
369
+ this.contentReferences.delete(contentRef);
370
+ throw error;
371
+ }
372
+ return record;
373
+ }
374
+ async requireMutationPayload(payloadRef, kind, signal) {
375
+ await this.pruneExpiredMutationPayloads();
376
+ if (signal?.aborted)
377
+ throw new Error("Operation aborted");
378
+ const record = this.mutationPayloads.get(payloadRef);
379
+ if (!record) {
380
+ throw new Error("File mutation payload reference is invalid, expired, or belongs to another session.");
381
+ }
382
+ if (record.kind !== kind) {
383
+ throw new Error(`File mutation payload reference is for ${record.kind}, not ${kind}.`);
384
+ }
385
+ return record;
386
+ }
387
+ async requireVerifiedMutationPayload(payloadRef, kind, signal) {
388
+ const record = await this.requireMutationPayload(payloadRef, kind, signal);
389
+ try {
390
+ await this.verifySource(record, signal, "Retained file mutation payload");
391
+ }
392
+ catch (error) {
393
+ await this.deleteMutationPayload(payloadRef);
394
+ throw error;
395
+ }
396
+ return record;
397
+ }
398
+ async verifySource(record, signal, label) {
218
399
  let sourceDigest;
219
400
  try {
220
401
  sourceDigest = await this.operations.hashFile(record.sourcePath, signal);
221
402
  }
222
403
  catch (error) {
223
- throw new Error(`File content reference source is unavailable: ${String(error)}.`);
224
- }
225
- if (sourceDigest !== record.digest) {
226
- this.contentReferences.delete(contentRef);
227
- throw new Error("File content reference source changed after it was cached.");
404
+ throw new Error(`${label} is unavailable: ${String(error)}.`);
228
405
  }
406
+ if (sourceDigest !== record.digest)
407
+ throw new Error(`${label} changed after it was cached.`);
408
+ }
409
+ async copyVerifiedSource(record, targetPath, signal) {
229
410
  await this.operations.copyFileExclusive(record.sourcePath, targetPath);
230
411
  let targetDigest;
231
412
  try {
@@ -239,7 +420,6 @@ export class FileMutationIntentController {
239
420
  await this.removeFailedCopy(targetPath, new Error("copied bytes did not match the cached digest"));
240
421
  throw new Error("File content copy changed while it was being created; the target was removed.");
241
422
  }
242
- return this.rememberContentDigest(targetPath, record.digest, record.byteLength);
243
423
  }
244
424
  async assertCreatableParent(path) {
245
425
  let candidate = dirname(path);
@@ -301,21 +481,35 @@ export class FileMutationIntentController {
301
481
  throw new Error(`Copied content verification failed (${String(cause)}), and the newly created target could not be removed: ${String(cleanupError)}.`);
302
482
  }
303
483
  }
304
- deleteIntent(intentId) {
305
- const record = this.intents.get(intentId);
484
+ async deleteMutationPayload(payloadRef, strict = false) {
485
+ const record = this.mutationPayloads.get(payloadRef);
306
486
  if (!record)
307
487
  return;
308
- this.intents.delete(intentId);
309
- const key = `${record.kind}\0${normalizedPath(record.path)}`;
310
- if (this.intentByPath.get(key) === intentId)
311
- this.intentByPath.delete(key);
488
+ this.mutationPayloads.delete(payloadRef);
489
+ this.mutationPayloadBytes -= record.byteLength;
490
+ try {
491
+ await this.operations.removeFile(record.sourcePath);
492
+ }
493
+ catch (error) {
494
+ if (strict && !isMissingPathError(error))
495
+ throw error;
496
+ }
312
497
  }
313
- pruneExpired() {
498
+ runMutationPayloadOperation(operation) {
499
+ const run = this.mutationPayloadOperationTail.then(operation, operation);
500
+ this.mutationPayloadOperationTail = run.then(() => undefined, () => undefined);
501
+ return run;
502
+ }
503
+ async pruneExpiredMutationPayloads() {
314
504
  const now = this.now();
315
- for (const [intentId, record] of this.intents) {
316
- if (record.expiresAt <= now)
317
- this.deleteIntent(intentId);
505
+ for (const [payloadRef, record] of this.mutationPayloads) {
506
+ if (record.expiresAt > now)
507
+ break;
508
+ await this.deleteMutationPayload(payloadRef, true);
318
509
  }
510
+ }
511
+ pruneExpired() {
512
+ const now = this.now();
319
513
  for (const [contentRef, record] of this.contentReferences) {
320
514
  if (record.expiresAt <= now)
321
515
  this.contentReferences.delete(contentRef);