@elie-laloum/outpost 4.2.0 → 6.0.1

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 (642) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +13 -11
  3. package/SECURITY.md +2 -0
  4. package/dist/adapters/agents/antigravity-adapter.d.ts +3 -0
  5. package/dist/adapters/agents/antigravity-adapter.js +39 -0
  6. package/dist/adapters/agents/antigravity-adapter.js.map +1 -0
  7. package/dist/adapters/agents/antigravity-authentication.d.ts +2 -0
  8. package/dist/adapters/agents/antigravity-authentication.js +27 -0
  9. package/dist/adapters/agents/antigravity-authentication.js.map +1 -0
  10. package/dist/adapters/agents/antigravity-diagnostics.d.ts +1 -0
  11. package/dist/adapters/agents/antigravity-diagnostics.js +6 -0
  12. package/dist/adapters/agents/antigravity-diagnostics.js.map +1 -0
  13. package/dist/adapters/agents/antigravity-events.d.ts +2 -0
  14. package/dist/adapters/agents/antigravity-events.js +66 -0
  15. package/dist/adapters/agents/antigravity-events.js.map +1 -0
  16. package/dist/adapters/agents/antigravity-request.d.ts +5 -0
  17. package/dist/adapters/agents/antigravity-request.js +29 -0
  18. package/dist/adapters/agents/antigravity-request.js.map +1 -0
  19. package/dist/adapters/agents/antigravity.types.d.ts +7 -0
  20. package/dist/adapters/agents/antigravity.types.js +2 -0
  21. package/dist/adapters/agents/antigravity.types.js.map +1 -0
  22. package/dist/adapters/agents/authentication.constants.d.ts +23 -0
  23. package/dist/adapters/agents/authentication.constants.js +13 -0
  24. package/dist/adapters/agents/authentication.constants.js.map +1 -0
  25. package/dist/adapters/agents/authentication.d.ts +11 -0
  26. package/dist/adapters/agents/authentication.js +75 -0
  27. package/dist/adapters/agents/authentication.js.map +1 -0
  28. package/dist/adapters/agents/authentication.types.d.ts +20 -0
  29. package/dist/adapters/agents/authentication.types.js +2 -0
  30. package/dist/adapters/agents/authentication.types.js.map +1 -0
  31. package/dist/adapters/agents/claude-adapter.d.ts +2 -2
  32. package/dist/adapters/agents/claude-adapter.js +32 -2
  33. package/dist/adapters/agents/claude-adapter.js.map +1 -1
  34. package/dist/adapters/agents/claude-authentication.d.ts +2 -0
  35. package/dist/adapters/agents/claude-authentication.js +34 -0
  36. package/dist/adapters/agents/claude-authentication.js.map +1 -0
  37. package/dist/adapters/agents/claude-request.d.ts +2 -2
  38. package/dist/adapters/agents/claude-request.js +3 -3
  39. package/dist/adapters/agents/claude-request.js.map +1 -1
  40. package/dist/adapters/agents/cli-diagnostics.constants.d.ts +6 -6
  41. package/dist/adapters/agents/cli-diagnostics.constants.js +6 -6
  42. package/dist/adapters/agents/cli-diagnostics.constants.js.map +1 -1
  43. package/dist/adapters/agents/cli-diagnostics.d.ts +1 -0
  44. package/dist/adapters/agents/cli-diagnostics.js +11 -0
  45. package/dist/adapters/agents/cli-diagnostics.js.map +1 -1
  46. package/dist/adapters/agents/codex-adapter.d.ts +2 -2
  47. package/dist/adapters/agents/codex-adapter.js +19 -1
  48. package/dist/adapters/agents/codex-adapter.js.map +1 -1
  49. package/dist/adapters/agents/codex-authentication.d.ts +3 -0
  50. package/dist/adapters/agents/codex-authentication.js +47 -0
  51. package/dist/adapters/agents/codex-authentication.js.map +1 -0
  52. package/dist/adapters/agents/codex-provider.d.ts +2 -2
  53. package/dist/adapters/agents/codex-provider.js +1 -1
  54. package/dist/adapters/agents/codex-provider.js.map +1 -1
  55. package/dist/adapters/agents/codex-request.d.ts +2 -2
  56. package/dist/adapters/agents/codex-request.js +3 -3
  57. package/dist/adapters/agents/codex-request.js.map +1 -1
  58. package/dist/adapters/agents/copilot-adapter.d.ts +3 -0
  59. package/dist/adapters/agents/copilot-adapter.js +39 -0
  60. package/dist/adapters/agents/copilot-adapter.js.map +1 -0
  61. package/dist/adapters/agents/copilot-authentication.d.ts +2 -0
  62. package/dist/adapters/agents/copilot-authentication.js +45 -0
  63. package/dist/adapters/agents/copilot-authentication.js.map +1 -0
  64. package/dist/adapters/agents/copilot-diagnostics.d.ts +1 -0
  65. package/dist/adapters/agents/copilot-diagnostics.js +6 -0
  66. package/dist/adapters/agents/copilot-diagnostics.js.map +1 -0
  67. package/dist/adapters/agents/copilot-events.d.ts +2 -0
  68. package/dist/adapters/agents/copilot-events.js +50 -0
  69. package/dist/adapters/agents/copilot-events.js.map +1 -0
  70. package/dist/adapters/agents/copilot-request.d.ts +5 -0
  71. package/dist/adapters/agents/copilot-request.js +19 -0
  72. package/dist/adapters/agents/copilot-request.js.map +1 -0
  73. package/dist/adapters/agents/copilot.types.d.ts +6 -0
  74. package/dist/adapters/agents/copilot.types.js +2 -0
  75. package/dist/adapters/agents/copilot.types.js.map +1 -0
  76. package/dist/adapters/agents/event-decoder.d.ts +2 -2
  77. package/dist/adapters/agents/event-decoder.js +6 -5
  78. package/dist/adapters/agents/event-decoder.js.map +1 -1
  79. package/dist/adapters/agents/kimi-adapter.d.ts +3 -0
  80. package/dist/adapters/agents/kimi-adapter.js +35 -0
  81. package/dist/adapters/agents/kimi-adapter.js.map +1 -0
  82. package/dist/adapters/agents/kimi-authentication.d.ts +2 -0
  83. package/dist/adapters/agents/kimi-authentication.js +48 -0
  84. package/dist/adapters/agents/kimi-authentication.js.map +1 -0
  85. package/dist/adapters/agents/kimi-diagnostics.d.ts +1 -0
  86. package/dist/adapters/agents/kimi-diagnostics.js +6 -0
  87. package/dist/adapters/agents/kimi-diagnostics.js.map +1 -0
  88. package/dist/adapters/agents/kimi-events.d.ts +2 -0
  89. package/dist/adapters/agents/kimi-events.js +51 -0
  90. package/dist/adapters/agents/kimi-events.js.map +1 -0
  91. package/dist/adapters/agents/kimi-request.d.ts +5 -0
  92. package/dist/adapters/agents/kimi-request.js +28 -0
  93. package/dist/adapters/agents/kimi-request.js.map +1 -0
  94. package/dist/adapters/agents/kimi.types.d.ts +6 -0
  95. package/dist/adapters/agents/kimi.types.js +2 -0
  96. package/dist/adapters/agents/kimi.types.js.map +1 -0
  97. package/dist/adapters/agents/model-support.constants.d.ts +8 -0
  98. package/dist/adapters/agents/model-support.constants.js +28 -0
  99. package/dist/adapters/agents/model-support.constants.js.map +1 -0
  100. package/dist/adapters/agents/model-support.d.ts +4 -0
  101. package/dist/adapters/agents/model-support.js +11 -0
  102. package/dist/adapters/agents/model-support.js.map +1 -0
  103. package/dist/adapters/agents/protocol-fixtures.constants.d.ts +2 -2
  104. package/dist/adapters/agents/protocol-fixtures.constants.js +135 -9
  105. package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
  106. package/dist/adapters/agents/protocol-fixtures.types.d.ts +1 -0
  107. package/dist/adapters/agents/protocol-fixtures.types.js.map +1 -1
  108. package/dist/adapters/agents/protocol.d.ts +1 -0
  109. package/dist/adapters/agents/protocol.js +9 -0
  110. package/dist/adapters/agents/protocol.js.map +1 -1
  111. package/dist/adapters/agents/settings.types.d.ts +11 -3
  112. package/dist/adapters/agents/settings.types.js.map +1 -1
  113. package/dist/adapters/models/anthropic-model-provider.constants.d.ts +3 -0
  114. package/dist/adapters/models/anthropic-model-provider.constants.js +17 -0
  115. package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -0
  116. package/dist/adapters/models/anthropic-model-provider.d.ts +3 -0
  117. package/dist/adapters/models/anthropic-model-provider.js +31 -0
  118. package/dist/adapters/models/anthropic-model-provider.js.map +1 -0
  119. package/dist/adapters/models/anthropic-model-provider.types.d.ts +7 -0
  120. package/dist/adapters/models/anthropic-model-provider.types.js +2 -0
  121. package/dist/adapters/models/anthropic-model-provider.types.js.map +1 -0
  122. package/dist/adapters/models/anthropic-request.d.ts +4 -0
  123. package/dist/adapters/models/anthropic-request.js +81 -0
  124. package/dist/adapters/models/anthropic-request.js.map +1 -0
  125. package/dist/adapters/models/anthropic-response.d.ts +3 -0
  126. package/dist/adapters/models/anthropic-response.js +55 -0
  127. package/dist/adapters/models/anthropic-response.js.map +1 -0
  128. package/dist/adapters/models/anthropic-stream.d.ts +2 -0
  129. package/dist/adapters/models/anthropic-stream.js +96 -0
  130. package/dist/adapters/models/anthropic-stream.js.map +1 -0
  131. package/dist/adapters/models/http-provider.d.ts +3 -0
  132. package/dist/adapters/models/http-provider.js +113 -0
  133. package/dist/adapters/models/http-provider.js.map +1 -0
  134. package/dist/adapters/models/{openai-http.js → model-http.js} +1 -1
  135. package/dist/adapters/models/model-http.js.map +1 -0
  136. package/dist/adapters/models/model-protocol.types.d.ts +41 -0
  137. package/dist/adapters/models/model-protocol.types.js +2 -0
  138. package/dist/adapters/models/model-protocol.types.js.map +1 -0
  139. package/dist/adapters/models/model-request.d.ts +2 -0
  140. package/dist/adapters/models/model-request.js +18 -0
  141. package/dist/adapters/models/model-request.js.map +1 -0
  142. package/dist/adapters/models/model-response.d.ts +7 -0
  143. package/dist/adapters/models/model-response.js +41 -0
  144. package/dist/adapters/models/model-response.js.map +1 -0
  145. package/dist/adapters/models/{openai-compatible.constants.js → model.constants.js} +6 -1
  146. package/dist/adapters/models/model.constants.js.map +1 -0
  147. package/dist/adapters/models/openai-chat-stream.d.ts +2 -0
  148. package/dist/adapters/models/openai-chat-stream.js +66 -0
  149. package/dist/adapters/models/openai-chat-stream.js.map +1 -0
  150. package/dist/adapters/models/openai-chat.d.ts +4 -0
  151. package/dist/adapters/models/openai-chat.js +108 -0
  152. package/dist/adapters/models/openai-chat.js.map +1 -0
  153. package/dist/adapters/models/openai-model-provider.d.ts +3 -0
  154. package/dist/adapters/models/openai-model-provider.js +13 -0
  155. package/dist/adapters/models/openai-model-provider.js.map +1 -0
  156. package/dist/adapters/models/openai-model-provider.types.d.ts +4 -0
  157. package/dist/adapters/models/openai-model-provider.types.js +2 -0
  158. package/dist/adapters/models/openai-model-provider.types.js.map +1 -0
  159. package/dist/adapters/models/openai-protocols.d.ts +2 -0
  160. package/dist/adapters/models/openai-protocols.js +22 -0
  161. package/dist/adapters/models/openai-protocols.js.map +1 -0
  162. package/dist/adapters/models/openai-responses-stream.d.ts +2 -0
  163. package/dist/adapters/models/openai-responses-stream.js +35 -0
  164. package/dist/adapters/models/openai-responses-stream.js.map +1 -0
  165. package/dist/adapters/models/openai-responses.d.ts +4 -0
  166. package/dist/adapters/models/openai-responses.js +107 -0
  167. package/dist/adapters/models/openai-responses.js.map +1 -0
  168. package/dist/adapters/models/openai-usage.d.ts +3 -0
  169. package/dist/adapters/models/openai-usage.js +20 -0
  170. package/dist/adapters/models/openai-usage.js.map +1 -0
  171. package/dist/adapters/models/stop-reasons.constants.d.ts +4 -0
  172. package/dist/adapters/models/stop-reasons.constants.js +19 -0
  173. package/dist/adapters/models/stop-reasons.constants.js.map +1 -0
  174. package/dist/adapters/models/stream-events.d.ts +3 -0
  175. package/dist/adapters/models/stream-events.js +22 -0
  176. package/dist/adapters/models/stream-events.js.map +1 -0
  177. package/dist/adapters/tools/edit-tools.d.ts +2 -0
  178. package/dist/adapters/tools/edit-tools.js +84 -0
  179. package/dist/adapters/tools/edit-tools.js.map +1 -0
  180. package/dist/adapters/tools/file-tools.d.ts +2 -0
  181. package/dist/adapters/tools/file-tools.js +97 -0
  182. package/dist/adapters/tools/file-tools.js.map +1 -0
  183. package/dist/adapters/tools/git-tools.d.ts +2 -0
  184. package/dist/adapters/tools/git-tools.js +54 -0
  185. package/dist/adapters/tools/git-tools.js.map +1 -0
  186. package/dist/adapters/tools/sandbox-files.d.ts +10 -0
  187. package/dist/adapters/tools/sandbox-files.js +60 -0
  188. package/dist/adapters/tools/sandbox-files.js.map +1 -0
  189. package/dist/adapters/tools/search-tools.d.ts +2 -0
  190. package/dist/adapters/tools/search-tools.js +65 -0
  191. package/dist/adapters/tools/search-tools.js.map +1 -0
  192. package/dist/adapters/tools/shell-tools.d.ts +3 -0
  193. package/dist/adapters/tools/shell-tools.js +38 -0
  194. package/dist/adapters/tools/shell-tools.js.map +1 -0
  195. package/dist/adapters/tools/tools.constants.d.ts +11 -0
  196. package/dist/adapters/tools/tools.constants.js +17 -0
  197. package/dist/adapters/tools/tools.constants.js.map +1 -0
  198. package/dist/adapters/tools/tools.types.d.ts +41 -0
  199. package/dist/adapters/tools/tools.types.js +2 -0
  200. package/dist/adapters/tools/tools.types.js.map +1 -0
  201. package/dist/application/activity-watchdog.js +15 -2
  202. package/dist/application/activity-watchdog.js.map +1 -1
  203. package/dist/application/agent-authentication.d.ts +4 -0
  204. package/dist/application/agent-authentication.js +32 -0
  205. package/dist/application/agent-authentication.js.map +1 -0
  206. package/dist/application/agent-bootstrap.constants.d.ts +2 -5
  207. package/dist/application/agent-bootstrap.constants.js +29 -4
  208. package/dist/application/agent-bootstrap.constants.js.map +1 -1
  209. package/dist/application/agent-bootstrap.d.ts +2 -2
  210. package/dist/application/agent-bootstrap.js +35 -12
  211. package/dist/application/agent-bootstrap.js.map +1 -1
  212. package/dist/application/agent-bootstrap.types.d.ts +20 -0
  213. package/dist/application/agent-bootstrap.types.js +2 -0
  214. package/dist/application/agent-bootstrap.types.js.map +1 -0
  215. package/dist/application/agent-storage.d.ts +3 -2
  216. package/dist/application/agent-storage.js +9 -2
  217. package/dist/application/agent-storage.js.map +1 -1
  218. package/dist/application/agent-turn.d.ts +3 -3
  219. package/dist/application/agent-turn.js +7 -1
  220. package/dist/application/agent-turn.js.map +1 -1
  221. package/dist/application/attach.js +1 -0
  222. package/dist/application/attach.js.map +1 -1
  223. package/dist/application/credential-installer.constants.d.ts +1 -0
  224. package/dist/application/credential-installer.constants.js +22 -0
  225. package/dist/application/credential-installer.constants.js.map +1 -0
  226. package/dist/application/custom-turn.d.ts +5 -0
  227. package/dist/application/custom-turn.js +190 -0
  228. package/dist/application/custom-turn.js.map +1 -0
  229. package/dist/application/dispatch-observation.d.ts +3 -0
  230. package/dist/application/dispatch-observation.js +51 -0
  231. package/dist/application/dispatch-observation.js.map +1 -0
  232. package/dist/application/dispatch-observation.types.d.ts +5 -0
  233. package/dist/application/dispatch-observation.types.js +2 -0
  234. package/dist/application/dispatch-observation.types.js.map +1 -0
  235. package/dist/application/dispatch-validation.d.ts +2 -2
  236. package/dist/application/dispatch-validation.js.map +1 -1
  237. package/dist/application/dispatch.js +8 -3
  238. package/dist/application/dispatch.js.map +1 -1
  239. package/dist/application/doctor-agent.constants.d.ts +2 -8
  240. package/dist/application/doctor-agent.constants.js +40 -6
  241. package/dist/application/doctor-agent.constants.js.map +1 -1
  242. package/dist/application/doctor-agent.d.ts +2 -1
  243. package/dist/application/doctor-agent.js +11 -3
  244. package/dist/application/doctor-agent.js.map +1 -1
  245. package/dist/application/doctor-image.js +7 -9
  246. package/dist/application/doctor-image.js.map +1 -1
  247. package/dist/application/doctor-protocol.js +6 -6
  248. package/dist/application/doctor-protocol.js.map +1 -1
  249. package/dist/application/doctor-protocol.types.d.ts +1 -1
  250. package/dist/application/doctor-protocol.types.js.map +1 -1
  251. package/dist/application/doctor-sandbox.js +6 -9
  252. package/dist/application/doctor-sandbox.js.map +1 -1
  253. package/dist/application/doctor-sandbox.types.d.ts +2 -2
  254. package/dist/application/doctor-sandbox.types.js.map +1 -1
  255. package/dist/application/doctor.constants.d.ts +1 -1
  256. package/dist/application/doctor.constants.js +1 -1
  257. package/dist/application/doctor.constants.js.map +1 -1
  258. package/dist/application/doctor.js +12 -13
  259. package/dist/application/doctor.js.map +1 -1
  260. package/dist/application/doctor.types.d.ts +12 -4
  261. package/dist/application/doctor.types.js.map +1 -1
  262. package/dist/application/execution.d.ts +2 -2
  263. package/dist/application/execution.js +1 -1
  264. package/dist/application/execution.js.map +1 -1
  265. package/dist/application/execution.types.d.ts +9 -2
  266. package/dist/application/execution.types.js.map +1 -1
  267. package/dist/application/harness-context.d.ts +2 -0
  268. package/dist/application/harness-context.js +54 -0
  269. package/dist/application/harness-context.js.map +1 -0
  270. package/dist/application/harness-history.d.ts +3 -0
  271. package/dist/application/harness-history.js +17 -0
  272. package/dist/application/harness-history.js.map +1 -0
  273. package/dist/application/harness-hooks.d.ts +9 -0
  274. package/dist/application/harness-hooks.js +90 -0
  275. package/dist/application/harness-hooks.js.map +1 -0
  276. package/dist/application/harness-loop.d.ts +2 -0
  277. package/dist/application/harness-loop.js +132 -0
  278. package/dist/application/harness-loop.js.map +1 -0
  279. package/dist/application/harness.types.d.ts +55 -0
  280. package/dist/application/harness.types.js +2 -0
  281. package/dist/application/harness.types.js.map +1 -0
  282. package/dist/application/lifecycle.constants.d.ts +1 -1
  283. package/dist/application/lifecycle.constants.js +1 -1
  284. package/dist/application/lifecycle.constants.js.map +1 -1
  285. package/dist/application/outpost.types.d.ts +6 -7
  286. package/dist/application/outpost.types.js.map +1 -1
  287. package/dist/application/recovery-retention.js +65 -24
  288. package/dist/application/recovery-retention.js.map +1 -1
  289. package/dist/application/remote-download.js +1 -1
  290. package/dist/application/remote-download.js.map +1 -1
  291. package/dist/application/sandbox-agents.js +14 -5
  292. package/dist/application/sandbox-agents.js.map +1 -1
  293. package/dist/application/sandbox-attach.js +5 -2
  294. package/dist/application/sandbox-attach.js.map +1 -1
  295. package/dist/application/sandbox-dispatch.js +3 -5
  296. package/dist/application/sandbox-dispatch.js.map +1 -1
  297. package/dist/application/sandbox-provision.js +13 -10
  298. package/dist/application/sandbox-provision.js.map +1 -1
  299. package/dist/application/sandbox-session.types.d.ts +13 -8
  300. package/dist/application/sandbox-session.types.js.map +1 -1
  301. package/dist/application/sandbox.js +6 -3
  302. package/dist/application/sandbox.js.map +1 -1
  303. package/dist/application/speculation.js +1 -1
  304. package/dist/application/speculation.js.map +1 -1
  305. package/dist/application/speculation.types.d.ts +3 -3
  306. package/dist/application/speculation.types.js.map +1 -1
  307. package/dist/application/startup-recovery.js +1 -1
  308. package/dist/application/startup-recovery.js.map +1 -1
  309. package/dist/application/storage-reservation.js +9 -2
  310. package/dist/application/storage-reservation.js.map +1 -1
  311. package/dist/application/tasks.types.d.ts +2 -2
  312. package/dist/application/tasks.types.js.map +1 -1
  313. package/dist/application/tool-execution.d.ts +3 -0
  314. package/dist/application/tool-execution.js +211 -0
  315. package/dist/application/tool-execution.js.map +1 -0
  316. package/dist/cli/commands.js +4 -2
  317. package/dist/cli/commands.js.map +1 -1
  318. package/dist/cli/doctor-command.js +11 -7
  319. package/dist/cli/doctor-command.js.map +1 -1
  320. package/dist/cli/init-authentication.d.ts +4 -1
  321. package/dist/cli/init-authentication.js +28 -34
  322. package/dist/cli/init-authentication.js.map +1 -1
  323. package/dist/cli/init-command.js +6 -6
  324. package/dist/cli/init-command.js.map +1 -1
  325. package/dist/cli/main.constants.d.ts +54 -17
  326. package/dist/cli/main.constants.js +74 -12
  327. package/dist/cli/main.constants.js.map +1 -1
  328. package/dist/cli/recovery-command.js +1 -1
  329. package/dist/cli/recovery-command.js.map +1 -1
  330. package/dist/cli/scaffold-files.js +6 -5
  331. package/dist/cli/scaffold-files.js.map +1 -1
  332. package/dist/cli/scaffold-validation.js +26 -16
  333. package/dist/cli/scaffold-validation.js.map +1 -1
  334. package/dist/cli/scaffold.constants.d.ts +0 -1
  335. package/dist/cli/scaffold.constants.js +5 -2
  336. package/dist/cli/scaffold.constants.js.map +1 -1
  337. package/dist/cli/scaffold.js +8 -4
  338. package/dist/cli/scaffold.js.map +1 -1
  339. package/dist/cli/scaffold.types.d.ts +9 -3
  340. package/dist/cli/scaffold.types.js.map +1 -1
  341. package/dist/cli/starters.js +8 -10
  342. package/dist/cli/starters.js.map +1 -1
  343. package/dist/domain/agent-model.d.ts +3 -0
  344. package/dist/domain/agent-model.js +22 -0
  345. package/dist/domain/agent-model.js.map +1 -0
  346. package/dist/domain/agent.d.ts +4 -0
  347. package/dist/domain/agent.js +32 -0
  348. package/dist/domain/agent.js.map +1 -0
  349. package/dist/domain/agent.types.d.ts +105 -2
  350. package/dist/domain/agent.types.js.map +1 -1
  351. package/dist/domain/authentication.constants.d.ts +3 -0
  352. package/dist/domain/authentication.constants.js +11 -0
  353. package/dist/domain/authentication.constants.js.map +1 -0
  354. package/dist/domain/authentication.d.ts +3 -0
  355. package/dist/domain/authentication.js +22 -0
  356. package/dist/domain/authentication.js.map +1 -0
  357. package/dist/domain/authentication.types.d.ts +5 -0
  358. package/dist/domain/authentication.types.js +2 -0
  359. package/dist/domain/authentication.types.js.map +1 -0
  360. package/dist/domain/context.constants.d.ts +7 -0
  361. package/dist/domain/context.constants.js +8 -0
  362. package/dist/domain/context.constants.js.map +1 -0
  363. package/dist/domain/context.d.ts +4 -0
  364. package/dist/domain/context.js +81 -0
  365. package/dist/domain/context.js.map +1 -0
  366. package/dist/domain/context.types.d.ts +26 -0
  367. package/dist/domain/context.types.js +2 -0
  368. package/dist/domain/context.types.js.map +1 -0
  369. package/dist/domain/dispatch-telemetry.types.d.ts +12 -0
  370. package/dist/domain/dispatch-telemetry.types.js +2 -0
  371. package/dist/domain/dispatch-telemetry.types.js.map +1 -0
  372. package/dist/domain/errors.types.d.ts +1 -1
  373. package/dist/domain/errors.types.js.map +1 -1
  374. package/dist/domain/glob.d.ts +2 -0
  375. package/dist/domain/glob.js +25 -0
  376. package/dist/domain/glob.js.map +1 -0
  377. package/dist/domain/glob.types.d.ts +1 -0
  378. package/dist/domain/glob.types.js +2 -0
  379. package/dist/domain/glob.types.js.map +1 -0
  380. package/dist/domain/harness.constants.d.ts +11 -0
  381. package/dist/domain/harness.constants.js +24 -0
  382. package/dist/domain/harness.constants.js.map +1 -0
  383. package/dist/domain/harness.d.ts +2 -0
  384. package/dist/domain/harness.js +89 -0
  385. package/dist/domain/harness.js.map +1 -0
  386. package/dist/domain/harness.types.d.ts +60 -0
  387. package/dist/domain/harness.types.js +2 -0
  388. package/dist/domain/harness.types.js.map +1 -0
  389. package/dist/domain/hook.constants.d.ts +3 -0
  390. package/dist/domain/hook.constants.js +10 -0
  391. package/dist/domain/hook.constants.js.map +1 -0
  392. package/dist/domain/hook.d.ts +3 -0
  393. package/dist/domain/hook.js +25 -0
  394. package/dist/domain/hook.js.map +1 -0
  395. package/dist/domain/hook.types.d.ts +66 -0
  396. package/dist/domain/hook.types.js +2 -0
  397. package/dist/domain/hook.types.js.map +1 -0
  398. package/dist/domain/instructions.d.ts +3 -0
  399. package/dist/domain/instructions.js +25 -0
  400. package/dist/domain/instructions.js.map +1 -0
  401. package/dist/domain/model-messages.d.ts +5 -0
  402. package/dist/domain/model-messages.js +81 -0
  403. package/dist/domain/model-messages.js.map +1 -0
  404. package/dist/domain/model-messages.types.d.ts +6 -0
  405. package/dist/domain/model-messages.types.js +2 -0
  406. package/dist/domain/model-messages.types.js.map +1 -0
  407. package/dist/domain/model.constants.d.ts +4 -0
  408. package/dist/domain/model.constants.js +16 -0
  409. package/dist/domain/model.constants.js.map +1 -0
  410. package/dist/domain/model.types.d.ts +59 -2
  411. package/dist/domain/model.types.js.map +1 -1
  412. package/dist/domain/permissions.d.ts +3 -0
  413. package/dist/domain/permissions.js +92 -0
  414. package/dist/domain/permissions.js.map +1 -0
  415. package/dist/domain/permissions.types.d.ts +34 -0
  416. package/dist/domain/permissions.types.js +2 -0
  417. package/dist/domain/permissions.types.js.map +1 -0
  418. package/dist/domain/response.js +3 -2
  419. package/dist/domain/response.js.map +1 -1
  420. package/dist/domain/response.types.d.ts +12 -0
  421. package/dist/domain/response.types.js.map +1 -1
  422. package/dist/domain/skill.constants.d.ts +2 -0
  423. package/dist/domain/skill.constants.js +8 -0
  424. package/dist/domain/skill.constants.js.map +1 -0
  425. package/dist/domain/skill.d.ts +8 -0
  426. package/dist/domain/skill.js +79 -0
  427. package/dist/domain/skill.js.map +1 -0
  428. package/dist/domain/skill.types.d.ts +18 -0
  429. package/dist/domain/skill.types.js +2 -0
  430. package/dist/domain/skill.types.js.map +1 -0
  431. package/dist/domain/standard-schema.d.ts +6 -0
  432. package/dist/domain/standard-schema.js +45 -0
  433. package/dist/domain/standard-schema.js.map +1 -0
  434. package/dist/domain/tool-schema.d.ts +3 -0
  435. package/dist/domain/tool-schema.js +109 -0
  436. package/dist/domain/tool-schema.js.map +1 -0
  437. package/dist/domain/tool.constants.d.ts +4 -0
  438. package/dist/domain/tool.constants.js +36 -0
  439. package/dist/domain/tool.constants.js.map +1 -0
  440. package/dist/domain/tool.d.ts +4 -0
  441. package/dist/domain/tool.js +66 -0
  442. package/dist/domain/tool.js.map +1 -0
  443. package/dist/domain/tool.types.d.ts +62 -0
  444. package/dist/domain/tool.types.js +2 -0
  445. package/dist/domain/tool.types.js.map +1 -0
  446. package/dist/domain/transcript.d.ts +4 -0
  447. package/dist/domain/transcript.js +48 -0
  448. package/dist/domain/transcript.js.map +1 -0
  449. package/dist/domain/transcript.types.d.ts +15 -0
  450. package/dist/domain/transcript.types.js +2 -0
  451. package/dist/domain/transcript.types.js.map +1 -0
  452. package/dist/domain/workflow/workflow-state.js +13 -6
  453. package/dist/domain/workflow/workflow-state.js.map +1 -1
  454. package/dist/domain/workflow.d.ts +1 -1
  455. package/dist/domain/workflow.js.map +1 -1
  456. package/dist/domain/workflow.types.d.ts +4 -0
  457. package/dist/domain/workflow.types.js.map +1 -1
  458. package/dist/index.d.ts +35 -13
  459. package/dist/index.js +19 -6
  460. package/dist/index.js.map +1 -1
  461. package/dist/infrastructure/conversations/harness-store.d.ts +3 -0
  462. package/dist/infrastructure/conversations/harness-store.js +27 -0
  463. package/dist/infrastructure/conversations/harness-store.js.map +1 -0
  464. package/dist/infrastructure/conversations/harness-transcript.d.ts +2 -0
  465. package/dist/infrastructure/conversations/harness-transcript.js +50 -0
  466. package/dist/infrastructure/conversations/harness-transcript.js.map +1 -0
  467. package/dist/infrastructure/conversations/harness-transcript.types.d.ts +18 -0
  468. package/dist/infrastructure/conversations/harness-transcript.types.js +2 -0
  469. package/dist/infrastructure/conversations/harness-transcript.types.js.map +1 -0
  470. package/dist/infrastructure/conversations.d.ts +4 -1
  471. package/dist/infrastructure/conversations.js +3 -0
  472. package/dist/infrastructure/conversations.js.map +1 -1
  473. package/dist/infrastructure/conversations.types.d.ts +1 -0
  474. package/dist/infrastructure/conversations.types.js.map +1 -1
  475. package/dist/infrastructure/custom-reporter.d.ts +2 -0
  476. package/dist/infrastructure/custom-reporter.js +33 -0
  477. package/dist/infrastructure/custom-reporter.js.map +1 -0
  478. package/dist/infrastructure/custom-reporter.types.d.ts +13 -0
  479. package/dist/infrastructure/custom-reporter.types.js +2 -0
  480. package/dist/infrastructure/custom-reporter.types.js.map +1 -0
  481. package/dist/infrastructure/git/git.constants.d.ts +1 -1
  482. package/dist/infrastructure/git/git.constants.js +2 -0
  483. package/dist/infrastructure/git/git.constants.js.map +1 -1
  484. package/dist/infrastructure/host-credentials.constants.d.ts +1 -0
  485. package/dist/infrastructure/host-credentials.constants.js +2 -0
  486. package/dist/infrastructure/host-credentials.constants.js.map +1 -0
  487. package/dist/infrastructure/host-credentials.d.ts +4 -0
  488. package/dist/infrastructure/host-credentials.js +89 -0
  489. package/dist/infrastructure/host-credentials.js.map +1 -0
  490. package/dist/infrastructure/inspection-path.js +4 -3
  491. package/dist/infrastructure/inspection-path.js.map +1 -1
  492. package/dist/infrastructure/journal.constants.d.ts +1 -0
  493. package/dist/infrastructure/journal.constants.js +2 -0
  494. package/dist/infrastructure/journal.constants.js.map +1 -0
  495. package/dist/infrastructure/journal.js +7 -71
  496. package/dist/infrastructure/journal.js.map +1 -1
  497. package/dist/infrastructure/journal.types.d.ts +0 -2
  498. package/dist/infrastructure/journal.types.js.map +1 -1
  499. package/dist/infrastructure/local-transport.js +9 -4
  500. package/dist/infrastructure/local-transport.js.map +1 -1
  501. package/dist/infrastructure/opentelemetry-dispatch.d.ts +6 -0
  502. package/dist/infrastructure/opentelemetry-dispatch.js +70 -0
  503. package/dist/infrastructure/opentelemetry-dispatch.js.map +1 -0
  504. package/dist/infrastructure/opentelemetry.constants.d.ts +3 -0
  505. package/dist/infrastructure/opentelemetry.constants.js +3 -0
  506. package/dist/infrastructure/opentelemetry.constants.js.map +1 -1
  507. package/dist/infrastructure/opentelemetry.js +4 -0
  508. package/dist/infrastructure/opentelemetry.js.map +1 -1
  509. package/dist/infrastructure/opentelemetry.types.d.ts +3 -3
  510. package/dist/infrastructure/opentelemetry.types.js.map +1 -1
  511. package/dist/infrastructure/reporter.js +27 -2
  512. package/dist/infrastructure/reporter.js.map +1 -1
  513. package/dist/infrastructure/repository-transport.constants.d.ts +1 -0
  514. package/dist/infrastructure/repository-transport.constants.js +2 -0
  515. package/dist/infrastructure/repository-transport.constants.js.map +1 -0
  516. package/dist/infrastructure/repository-transport.d.ts +2 -0
  517. package/dist/infrastructure/repository-transport.js +9 -0
  518. package/dist/infrastructure/repository-transport.js.map +1 -0
  519. package/dist/infrastructure/resource-activity-inspection.js +22 -26
  520. package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
  521. package/dist/infrastructure/resource-activity.constants.d.ts +0 -1
  522. package/dist/infrastructure/resource-activity.constants.js +0 -1
  523. package/dist/infrastructure/resource-activity.constants.js.map +1 -1
  524. package/dist/infrastructure/resource-activity.js +22 -85
  525. package/dist/infrastructure/resource-activity.js.map +1 -1
  526. package/dist/infrastructure/resource-activity.types.d.ts +2 -2
  527. package/dist/infrastructure/resource-activity.types.js.map +1 -1
  528. package/dist/infrastructure/settings.d.ts +1 -1
  529. package/dist/infrastructure/settings.js +3 -3
  530. package/dist/infrastructure/settings.js.map +1 -1
  531. package/dist/infrastructure/sse.d.ts +2 -0
  532. package/dist/infrastructure/sse.js +64 -0
  533. package/dist/infrastructure/sse.js.map +1 -0
  534. package/dist/infrastructure/sse.types.d.ts +4 -0
  535. package/dist/infrastructure/sse.types.js +2 -0
  536. package/dist/infrastructure/sse.types.js.map +1 -0
  537. package/dist/infrastructure/storage-inventory.constants.js +1 -0
  538. package/dist/infrastructure/storage-inventory.constants.js.map +1 -1
  539. package/dist/infrastructure/storage-inventory.types.d.ts +1 -1
  540. package/dist/infrastructure/storage-inventory.types.js.map +1 -1
  541. package/dist/infrastructure/storage-reservations.types.d.ts +0 -8
  542. package/dist/infrastructure/storage-reservations.types.js.map +1 -1
  543. package/dist/infrastructure/transport-conversations.d.ts +2 -2
  544. package/dist/infrastructure/transport-conversations.js +8 -1
  545. package/dist/infrastructure/transport-conversations.js.map +1 -1
  546. package/dist/infrastructure/transport-journal.js +2 -1
  547. package/dist/infrastructure/transport-journal.js.map +1 -1
  548. package/dist/infrastructure/transport-reservations.d.ts +1 -1
  549. package/dist/infrastructure/transport-reservations.js +14 -8
  550. package/dist/infrastructure/transport-reservations.js.map +1 -1
  551. package/dist/providers/agents.d.ts +9 -4
  552. package/dist/providers/agents.js +6 -3
  553. package/dist/providers/agents.js.map +1 -1
  554. package/dist/providers/daytona.d.ts +1 -1
  555. package/dist/providers/daytona.js +1 -1
  556. package/dist/providers/daytona.js.map +1 -1
  557. package/dist/providers/docker.d.ts +1 -1
  558. package/dist/providers/docker.js +1 -1
  559. package/dist/providers/docker.js.map +1 -1
  560. package/dist/providers/factories.d.ts +2 -2
  561. package/dist/providers/factories.js +3 -3
  562. package/dist/providers/factories.js.map +1 -1
  563. package/dist/providers/firecracker.d.ts +1 -1
  564. package/dist/providers/firecracker.js +1 -1
  565. package/dist/providers/firecracker.js.map +1 -1
  566. package/dist/providers/local.d.ts +1 -1
  567. package/dist/providers/local.js +1 -1
  568. package/dist/providers/local.js.map +1 -1
  569. package/dist/providers/podman.d.ts +1 -1
  570. package/dist/providers/podman.js +1 -1
  571. package/dist/providers/podman.js.map +1 -1
  572. package/dist/providers/vercel.d.ts +1 -1
  573. package/dist/providers/vercel.js +1 -1
  574. package/dist/providers/vercel.js.map +1 -1
  575. package/dist/providers/versions.constants.d.ts +3 -1
  576. package/dist/providers/versions.constants.js +3 -1
  577. package/dist/providers/versions.constants.js.map +1 -1
  578. package/package.json +3 -3
  579. package/dist/adapters/agents/gemini-adapter.d.ts +0 -3
  580. package/dist/adapters/agents/gemini-adapter.js +0 -15
  581. package/dist/adapters/agents/gemini-adapter.js.map +0 -1
  582. package/dist/adapters/agents/gemini-diagnostics.d.ts +0 -2
  583. package/dist/adapters/agents/gemini-diagnostics.js +0 -15
  584. package/dist/adapters/agents/gemini-diagnostics.js.map +0 -1
  585. package/dist/adapters/agents/gemini-events.d.ts +0 -2
  586. package/dist/adapters/agents/gemini-events.js +0 -50
  587. package/dist/adapters/agents/gemini-events.js.map +0 -1
  588. package/dist/adapters/agents/gemini-request.d.ts +0 -4
  589. package/dist/adapters/agents/gemini-request.js +0 -23
  590. package/dist/adapters/agents/gemini-request.js.map +0 -1
  591. package/dist/adapters/agents/gemini.types.d.ts +0 -6
  592. package/dist/adapters/agents/gemini.types.js +0 -2
  593. package/dist/adapters/agents/gemini.types.js.map +0 -1
  594. package/dist/adapters/models/openai-compatible.constants.js.map +0 -1
  595. package/dist/adapters/models/openai-compatible.d.ts +0 -3
  596. package/dist/adapters/models/openai-compatible.js +0 -78
  597. package/dist/adapters/models/openai-compatible.js.map +0 -1
  598. package/dist/adapters/models/openai-compatible.types.d.ts +0 -14
  599. package/dist/adapters/models/openai-compatible.types.js +0 -2
  600. package/dist/adapters/models/openai-compatible.types.js.map +0 -1
  601. package/dist/adapters/models/openai-http.js.map +0 -1
  602. package/dist/adapters/models/openai-request.d.ts +0 -4
  603. package/dist/adapters/models/openai-request.js +0 -46
  604. package/dist/adapters/models/openai-request.js.map +0 -1
  605. package/dist/adapters/models/openai-response.d.ts +0 -3
  606. package/dist/adapters/models/openai-response.js +0 -65
  607. package/dist/adapters/models/openai-response.js.map +0 -1
  608. package/dist/cli/init-authentication.constants.d.ts +0 -13
  609. package/dist/cli/init-authentication.constants.js +0 -10
  610. package/dist/cli/init-authentication.constants.js.map +0 -1
  611. package/dist/infrastructure/artifact-store.d.ts +0 -3
  612. package/dist/infrastructure/artifact-store.js +0 -110
  613. package/dist/infrastructure/artifact-store.js.map +0 -1
  614. package/dist/infrastructure/artifact-store.types.d.ts +0 -6
  615. package/dist/infrastructure/artifact-store.types.js +0 -2
  616. package/dist/infrastructure/artifact-store.types.js.map +0 -1
  617. package/dist/infrastructure/journal-retention.constants.d.ts +0 -4
  618. package/dist/infrastructure/journal-retention.constants.js +0 -5
  619. package/dist/infrastructure/journal-retention.constants.js.map +0 -1
  620. package/dist/infrastructure/journal-retention.d.ts +0 -2
  621. package/dist/infrastructure/journal-retention.js +0 -51
  622. package/dist/infrastructure/journal-retention.js.map +0 -1
  623. package/dist/infrastructure/storage-mutation-lock.constants.d.ts +0 -5
  624. package/dist/infrastructure/storage-mutation-lock.constants.js +0 -6
  625. package/dist/infrastructure/storage-mutation-lock.constants.js.map +0 -1
  626. package/dist/infrastructure/storage-mutation-lock.d.ts +0 -1
  627. package/dist/infrastructure/storage-mutation-lock.js +0 -21
  628. package/dist/infrastructure/storage-mutation-lock.js.map +0 -1
  629. package/dist/infrastructure/storage-reservations.constants.d.ts +0 -4
  630. package/dist/infrastructure/storage-reservations.constants.js +0 -5
  631. package/dist/infrastructure/storage-reservations.constants.js.map +0 -1
  632. package/dist/infrastructure/storage-reservations.d.ts +0 -2
  633. package/dist/infrastructure/storage-reservations.js +0 -150
  634. package/dist/infrastructure/storage-reservations.js.map +0 -1
  635. package/dist/infrastructure/workflow-checkpoint.d.ts +0 -3
  636. package/dist/infrastructure/workflow-checkpoint.js +0 -84
  637. package/dist/infrastructure/workflow-checkpoint.js.map +0 -1
  638. package/dist/infrastructure/workflow-checkpoint.types.d.ts +0 -6
  639. package/dist/infrastructure/workflow-checkpoint.types.js +0 -2
  640. package/dist/infrastructure/workflow-checkpoint.types.js.map +0 -1
  641. /package/dist/adapters/models/{openai-http.d.ts → model-http.d.ts} +0 -0
  642. /package/dist/adapters/models/{openai-compatible.constants.d.ts → model.constants.d.ts} +0 -0
@@ -0,0 +1,55 @@
1
+ import type { AgentEvent, CustomAgent } from "../domain/agent.types.ts";
2
+ import type { ModelContentBlock, ModelMessage, ModelProvider, ModelResult, ModelToolCallBlock } from "../domain/model.types.ts";
3
+ import type { SandboxLease } from "../domain/sandbox.types.ts";
4
+ import type { HarnessTool } from "../domain/tool.types.ts";
5
+ import type { DispatchOptions, TurnContext } from "./execution.types.ts";
6
+ export interface HarnessRuntime {
7
+ readonly agent: CustomAgent;
8
+ readonly tools: readonly HarnessTool[];
9
+ readonly modelProvider: ModelProvider;
10
+ readonly sandbox: SandboxLease;
11
+ readonly signal: AbortSignal;
12
+ emit(event: AgentEvent): void;
13
+ hold(): () => void;
14
+ }
15
+ export interface ToolCallBatch {
16
+ readonly concurrent: boolean;
17
+ readonly calls: readonly PreparedCall[];
18
+ }
19
+ export type ValidatedInput = {
20
+ readonly value: unknown;
21
+ } | {
22
+ readonly outcome: ToolOutcome;
23
+ };
24
+ export interface ToolOutcome {
25
+ readonly content: string;
26
+ readonly isError: boolean;
27
+ }
28
+ export interface HarnessHistory {
29
+ readonly messages: readonly ModelMessage[];
30
+ append(message: ModelMessage): Promise<void>;
31
+ replace(messages: readonly ModelMessage[]): Promise<void>;
32
+ }
33
+ export interface CustomTurnContext extends TurnContext {
34
+ readonly continuation?: DispatchOptions["continuation"];
35
+ }
36
+ export interface LoopState {
37
+ readonly history: HarnessHistory;
38
+ readonly step: number;
39
+ toolCalls: number;
40
+ }
41
+ export type StopHandler = (runtime: HarnessRuntime, state: LoopState, result: ModelResult, content: readonly ModelContentBlock[]) => Promise<string | undefined>;
42
+ export interface PreparedCall {
43
+ readonly call: ModelToolCallBlock;
44
+ readonly tool?: HarnessTool;
45
+ readonly input?: unknown;
46
+ readonly outcome?: ToolOutcome;
47
+ }
48
+ export interface ToolDenial {
49
+ readonly deny: string;
50
+ }
51
+ export type BlockRenderers = {
52
+ readonly [Type in ModelContentBlock["type"]]: (block: Extract<ModelContentBlock, {
53
+ type: Type;
54
+ }>) => string;
55
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=harness.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.types.js","sourceRoot":"","sources":["../../src/application/harness.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentEvent, CustomAgent } from \"../domain/agent.types.ts\";\nimport type {\n ModelContentBlock,\n ModelMessage,\n ModelProvider,\n ModelResult,\n ModelToolCallBlock,\n} from \"../domain/model.types.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport type { HarnessTool } from \"../domain/tool.types.ts\";\nimport type { DispatchOptions, TurnContext } from \"./execution.types.ts\";\n\nexport interface HarnessRuntime {\n readonly agent: CustomAgent;\n readonly tools: readonly HarnessTool[];\n readonly modelProvider: ModelProvider;\n readonly sandbox: SandboxLease;\n readonly signal: AbortSignal;\n emit(event: AgentEvent): void;\n hold(): () => void;\n}\n\nexport interface ToolCallBatch {\n readonly concurrent: boolean;\n readonly calls: readonly PreparedCall[];\n}\n\nexport type ValidatedInput =\n { readonly value: unknown } | { readonly outcome: ToolOutcome };\n\nexport interface ToolOutcome {\n readonly content: string;\n readonly isError: boolean;\n}\n\nexport interface HarnessHistory {\n readonly messages: readonly ModelMessage[];\n append(message: ModelMessage): Promise<void>;\n replace(messages: readonly ModelMessage[]): Promise<void>;\n}\n\nexport interface CustomTurnContext extends TurnContext {\n readonly continuation?: DispatchOptions[\"continuation\"];\n}\n\nexport interface LoopState {\n readonly history: HarnessHistory;\n readonly step: number;\n toolCalls: number;\n}\n\nexport type StopHandler = (\n runtime: HarnessRuntime,\n state: LoopState,\n result: ModelResult,\n content: readonly ModelContentBlock[],\n) => Promise<string | undefined>;\n\nexport interface PreparedCall {\n readonly call: ModelToolCallBlock;\n readonly tool?: HarnessTool;\n readonly input?: unknown;\n readonly outcome?: ToolOutcome;\n}\n\nexport interface ToolDenial {\n readonly deny: string;\n}\n\nexport type BlockRenderers = {\n readonly [Type in ModelContentBlock[\"type\"]]: (\n block: Extract<ModelContentBlock, { type: Type }>,\n ) => string;\n};\n"]}
@@ -1,2 +1,2 @@
1
1
  export declare const hookDeadlineMs = 600000;
2
- export declare const warmConfigurationKeys: readonly ["repository", "branch", "provider", "workspace", "copies", "hooks", "limits", "bootstrap", "conversationHome", "includeUncommitted"];
2
+ export declare const warmConfigurationKeys: readonly ["repository", "branch", "sandboxProvider", "workspace", "copies", "hooks", "limits", "bootstrap", "conversationHome", "includeUncommitted"];
@@ -2,7 +2,7 @@ export const hookDeadlineMs = 600_000;
2
2
  export const warmConfigurationKeys = [
3
3
  "repository",
4
4
  "branch",
5
- "provider",
5
+ "sandboxProvider",
6
6
  "workspace",
7
7
  "copies",
8
8
  "hooks",
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.constants.js","sourceRoot":"","sources":["../../src/application/lifecycle.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,YAAY;IACZ,QAAQ;IACR,UAAU;IACV,WAAW;IACX,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;IACX,kBAAkB;IAClB,oBAAoB;CACZ,CAAC","sourcesContent":["export const hookDeadlineMs = 600_000;\nexport const warmConfigurationKeys = [\n \"repository\",\n \"branch\",\n \"provider\",\n \"workspace\",\n \"copies\",\n \"hooks\",\n \"limits\",\n \"bootstrap\",\n \"conversationHome\",\n \"includeUncommitted\",\n] as const;\n"]}
1
+ {"version":3,"file":"lifecycle.constants.js","sourceRoot":"","sources":["../../src/application/lifecycle.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,YAAY;IACZ,QAAQ;IACR,iBAAiB;IACjB,WAAW;IACX,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;IACX,kBAAkB;IAClB,oBAAoB;CACZ,CAAC","sourcesContent":["export const hookDeadlineMs = 600_000;\nexport const warmConfigurationKeys = [\n \"repository\",\n \"branch\",\n \"sandboxProvider\",\n \"workspace\",\n \"copies\",\n \"hooks\",\n \"limits\",\n \"bootstrap\",\n \"conversationHome\",\n \"includeUncommitted\",\n] as const;\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { Transport, TransportReference } from "../domain/transport.types.ts";
2
- import type { AgentAdapter } from "../domain/agent.types.ts";
2
+ import type { Agent } from "../domain/agent.types.ts";
3
3
  import type { Command, CommandResult } from "../domain/command.types.ts";
4
4
  import type { Brief } from "../domain/prompts.types.ts";
5
5
  import type { SandboxProvider } from "../domain/sandbox.types.ts";
@@ -21,11 +21,11 @@ export interface WorkspaceOptions {
21
21
  }
22
22
  export interface Workspace extends WorkspaceRecord {
23
23
  dispatch<T = undefined>(options: Omit<SandboxOptions, Exclude<keyof WorkspaceOptions, "hooks" | "label"> | "workspace"> & DispatchOptions<T> & {
24
- readonly agent: AgentAdapter;
24
+ readonly agent: Agent;
25
25
  }): Promise<DispatchResult<T>>;
26
26
  sandbox(options?: Omit<SandboxOptions, Exclude<keyof WorkspaceOptions, "hooks" | "label"> | "workspace">): Promise<Sandbox>;
27
27
  attach(options: Omit<SandboxOptions, Exclude<keyof WorkspaceOptions, "hooks" | "label"> | "workspace"> & AttachOptions & {
28
- readonly agent: AgentAdapter;
28
+ readonly agent: Agent;
29
29
  }): Promise<AttachResult>;
30
30
  close(options?: {
31
31
  readonly preserve?: boolean;
@@ -35,8 +35,8 @@ export interface Workspace extends WorkspaceRecord {
35
35
  }
36
36
  export interface SandboxOptions extends WorkspaceOptions {
37
37
  readonly includeUncommitted?: boolean;
38
- readonly agent?: AgentAdapter;
39
- readonly provider?: SandboxProvider;
38
+ readonly agent?: Agent;
39
+ readonly sandboxProvider?: SandboxProvider;
40
40
  readonly workspace?: Workspace;
41
41
  readonly hooks?: LifecycleHooks;
42
42
  readonly signal?: AbortSignal;
@@ -48,7 +48,7 @@ export interface SandboxOptions extends WorkspaceOptions {
48
48
  }
49
49
  export interface AttachOptions {
50
50
  readonly ask?: VariableQuestion;
51
- readonly agent?: AgentAdapter;
51
+ readonly agent?: Agent;
52
52
  readonly brief?: Brief;
53
53
  readonly continuation?: {
54
54
  readonly id: string;
@@ -69,7 +69,6 @@ export interface DispatchResult<T> extends Execution<T> {
69
69
  readonly transcript?: string;
70
70
  readonly transcriptReference?: TransportReference;
71
71
  readonly logReference?: TransportReference;
72
- readonly log?: string;
73
72
  readonly retainedDirectory?: string;
74
73
  resume<U = undefined>(options: ContinuationOptions<U>): Promise<DispatchResult<U>>;
75
74
  fork<U = undefined>(options: ContinuationOptions<U>): Promise<DispatchResult<U>>;
@@ -1 +1 @@
1
- {"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Transport,\n TransportReference,\n} from \"../domain/transport.types.ts\";\nimport type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { StorageReservationOptions } from \"../infrastructure/storage-reservations.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly storageQuota?: Omit<StorageReservationOptions, \"signal\">;\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: AgentAdapter },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: AgentAdapter },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: AgentAdapter;\n readonly provider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n readonly recoveryTransport?: Transport;\n readonly activityTransport?: Transport;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: AgentAdapter;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly logReference?: TransportReference;\n readonly log?: string;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"outpost.types.js","sourceRoot":"","sources":["../../src/application/outpost.types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n Transport,\n TransportReference,\n} from \"../domain/transport.types.ts\";\nimport type { Agent } from \"../domain/agent.types.ts\";\nimport type { Command, CommandResult } from \"../domain/command.types.ts\";\nimport type { Brief } from \"../domain/prompts.types.ts\";\nimport type { SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport type {\n BranchPolicy,\n Commit,\n Disposal,\n LifecycleHooks,\n StageLimits,\n WorkspaceRecord,\n} from \"../domain/workspace.types.ts\";\nimport type { StorageReservationOptions } from \"../infrastructure/storage-reservations.types.ts\";\nimport type { Logging } from \"../infrastructure/journal.types.ts\";\nimport type {\n SandboxDiagnosticOptions,\n SandboxDiagnosticReport,\n} from \"./doctor-sandbox.types.ts\";\nimport type { DispatchOptions, Execution } from \"./execution.types.ts\";\nimport type { VariableQuestion } from \"./interactive-brief.types.ts\";\n\nexport interface WorkspaceOptions {\n readonly storageQuota?: Omit<StorageReservationOptions, \"signal\">;\n readonly signal?: AbortSignal;\n readonly repository?: string;\n readonly branch?: BranchPolicy;\n readonly copies?: readonly string[];\n readonly limits?: StageLimits;\n readonly label?: string;\n readonly hooks?: LifecycleHooks;\n}\n\nexport interface Workspace extends WorkspaceRecord {\n dispatch<T = undefined>(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n DispatchOptions<T> & { readonly agent: Agent },\n ): Promise<DispatchResult<T>>;\n sandbox(\n options?: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n >,\n ): Promise<Sandbox>;\n attach(\n options: Omit<\n SandboxOptions,\n Exclude<keyof WorkspaceOptions, \"hooks\" | \"label\"> | \"workspace\"\n > &\n AttachOptions & { readonly agent: Agent },\n ): Promise<AttachResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n integrate(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\nexport interface SandboxOptions extends WorkspaceOptions {\n readonly includeUncommitted?: boolean;\n readonly agent?: Agent;\n readonly sandboxProvider?: SandboxProvider;\n readonly workspace?: Workspace;\n readonly hooks?: LifecycleHooks;\n readonly signal?: AbortSignal;\n readonly logging?: Logging;\n readonly bootstrap?: boolean;\n readonly conversationHome?: string;\n readonly recoveryTransport?: Transport;\n readonly activityTransport?: Transport;\n}\n\nexport interface AttachOptions {\n readonly ask?: VariableQuestion;\n readonly agent?: Agent;\n readonly brief?: Brief;\n readonly continuation?: { readonly id: string; readonly fork?: boolean };\n readonly signal?: AbortSignal;\n readonly terminal?: Command[\"terminal\"];\n}\n\nexport interface AttachResult extends CommandResult, Disposal {\n readonly commits: readonly Commit[];\n readonly branch: string;\n readonly directory: string;\n}\n\nexport interface DispatchResult<T> extends Execution<T> {\n readonly branch: string;\n readonly directory: string;\n readonly commits: readonly Commit[];\n readonly transcript?: string;\n readonly transcriptReference?: TransportReference;\n readonly logReference?: TransportReference;\n readonly retainedDirectory?: string;\n resume<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n fork<U = undefined>(\n options: ContinuationOptions<U>,\n ): Promise<DispatchResult<U>>;\n}\n\nexport type ContinuationOptions<T = undefined> = DispatchOptions<T> &\n Omit<SandboxOptions, \"agent\">;\n\nexport interface WarmDispatchResult<T> extends Omit<\n DispatchResult<T>,\n \"resume\" | \"fork\"\n> {\n resume<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n fork<U = undefined>(\n options: DispatchOptions<U>,\n ): Promise<WarmDispatchResult<U>>;\n}\n\nexport interface Sandbox {\n diagnose(\n options?: SandboxDiagnosticOptions,\n ): Promise<SandboxDiagnosticReport>;\n readonly workspace: Workspace;\n readonly root: string;\n dispatch<T = undefined>(\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n resume<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n fork<T = undefined>(\n id: string,\n options: DispatchOptions<T>,\n ): Promise<WarmDispatchResult<T>>;\n attach(options?: AttachOptions): Promise<AttachResult>;\n command(command: Command): Promise<CommandResult>;\n close(options?: { readonly preserve?: boolean }): Promise<Disposal>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n"]}
@@ -1,9 +1,11 @@
1
1
  import { planTransportRetention, pruneTransportRetention, } from "./transport-retention.js";
2
- import { lstat, rm } from "node:fs/promises";
2
+ import { lstat } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { repositoryTransport } from "../infrastructure/repository-transport.js";
5
+ import { repositoryStorageDirectory } from "../infrastructure/repository-transport.constants.js";
3
6
  import { OutpostError, invariant } from "../domain/errors.js";
4
7
  import { git } from "../infrastructure/git/command.js";
5
8
  import { lock, lockPath } from "../infrastructure/git/lock.js";
6
- import { closedJournal } from "../infrastructure/journal-retention.js";
7
9
  import { inspectRecovery } from "./recovery-inspection.js";
8
10
  import { retentionPolicy } from "./recovery-retention-policy.js";
9
11
  async function workspaceReason(entry, inspection) {
@@ -60,7 +62,7 @@ export async function planRecoveryRetention(options) {
60
62
  });
61
63
  const entries = [];
62
64
  const inspectedAt = new Date().toISOString();
63
- const complete = inspection.complete && inspection.git?.complete !== false;
65
+ let complete = inspection.complete && inspection.git?.complete !== false;
64
66
  for (const category of inspection.categories) {
65
67
  for (const entry of category.entries) {
66
68
  let reason = "RECOVERY_DATA_PROTECTED";
@@ -73,14 +75,6 @@ export async function planRecoveryRetention(options) {
73
75
  if (category.name === "workspaces" &&
74
76
  policy.scopes.includes("clean-workspaces"))
75
77
  reason = await workspaceReason(entry, inspection);
76
- if (category.name === "logs" &&
77
- policy.scopes.includes("closed-logs") &&
78
- entry.kind === "file" &&
79
- entry.name.endsWith(".jsonl") &&
80
- (await closedJournal(entry.path)))
81
- reason = "ELIGIBLE";
82
- if (category.name === "logs" && entry.name.endsWith(".closed.json"))
83
- reason = "CLOSURE_RECORD_PROTECTED";
84
78
  if (reason === "ELIGIBLE" &&
85
79
  (!entry.modifiedAt ||
86
80
  Date.parse(inspectedAt) - Date.parse(entry.modifiedAt) <
@@ -102,14 +96,56 @@ export async function planRecoveryRetention(options) {
102
96
  });
103
97
  }
104
98
  }
99
+ const logs = await planTransportRetention({
100
+ transporter: repositoryTransport(inspection.repository),
101
+ policy: {
102
+ version: 1,
103
+ scopes: policy.scopes.filter((scope) => scope === "closed-logs"),
104
+ minAgeMs: policy.minAgeMs,
105
+ },
106
+ ...(options.maxEntries === undefined
107
+ ? {}
108
+ : { maxEntries: options.maxEntries }),
109
+ });
110
+ for (const entry of logs.entries.filter((entry) => entry.category === "logs")) {
111
+ let bytes = 0;
112
+ for (const object of entry.objects ?? []) {
113
+ try {
114
+ bytes += (await lstat(join(inspection.repository, ".outpost", repositoryStorageDirectory, "objects", `${object.key}.object`))).size;
115
+ }
116
+ catch {
117
+ complete = false;
118
+ }
119
+ }
120
+ const container = entries.findIndex((value) => value.category === "storage" &&
121
+ value.path ===
122
+ join(inspection.repository, ".outpost", repositoryStorageDirectory, "objects"));
123
+ const stored = entries[container];
124
+ if (!stored || stored.bytes < bytes)
125
+ complete = false;
126
+ if (stored)
127
+ entries[container] = {
128
+ ...stored,
129
+ bytes: Math.max(0, stored.bytes - bytes),
130
+ };
131
+ entries.push({ ...entry, bytes, eligible: entry.eligible && complete });
132
+ }
133
+ complete = complete && logs.complete;
134
+ if (!complete) {
135
+ for (let index = 0; index < entries.length; index++) {
136
+ const entry = entries[index];
137
+ if (entry.eligible)
138
+ entries[index] = {
139
+ ...entry,
140
+ eligible: false,
141
+ reason: "INCOMPLETE_INVENTORY",
142
+ };
143
+ }
144
+ }
105
145
  const projectedBytes = inspection.usage.bytes -
106
146
  entries
107
147
  .filter((entry) => entry.eligible)
108
- .reduce((sum, entry) => sum +
109
- entry.bytes +
110
- (entry.category === "logs"
111
- ? (entries.find((other) => other.path === `${entry.path}.closed.json`)?.bytes ?? 0)
112
- : 0), 0);
148
+ .reduce((sum, entry) => sum + entry.bytes, 0);
113
149
  const workspaces = entries.filter((entry) => entry.category === "workspaces" && !entry.eligible).length;
114
150
  const exceeded = (policy.maxBytes !== undefined && projectedBytes > policy.maxBytes) ||
115
151
  (policy.maxWorkspaces !== undefined && workspaces > policy.maxWorkspaces);
@@ -170,14 +206,19 @@ export async function pruneRecoveryRetention(plan, options) {
170
206
  }
171
207
  }
172
208
  else {
173
- const release = await lock(plan.repository, `journal:${entry.path}`);
174
- try {
175
- invariant(entry.category === "logs" && (await closedJournal(entry.path)), "Journal changed before pruning");
176
- await rm(entry.path);
177
- await rm(`${entry.path}.closed.json`);
178
- }
179
- finally {
180
- await release();
209
+ const result = await pruneTransportRetention({
210
+ ...plan,
211
+ source: "transport",
212
+ policy: {
213
+ version: 1,
214
+ scopes: ["closed-logs"],
215
+ minAgeMs: plan.policy.minAgeMs,
216
+ },
217
+ entries: [candidate],
218
+ }, { transporter: repositoryTransport(plan.repository) });
219
+ if (!result.removed.includes(entry.path)) {
220
+ retained.push(...result.retained);
221
+ continue;
181
222
  }
182
223
  }
183
224
  removed.push(entry.path);
@@ -1 +1 @@
1
- {"version":3,"file":"recovery-retention.js","sourceRoot":"","sources":["../../src/application/recovery-retention.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransportStoreOptions } from \"../domain/transport.types.ts\";\nimport {\n planTransportRetention,\n pruneTransportRetention,\n} from \"./transport-retention.ts\";\nimport { lstat, rm } from \"node:fs/promises\";\nimport { OutpostError, invariant } from \"../domain/errors.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { lock, lockPath } from \"../infrastructure/git/lock.ts\";\nimport { closedJournal } from \"../infrastructure/journal-retention.ts\";\nimport type { StorageEntry } from \"../infrastructure/storage-inventory.types.ts\";\nimport type { RecoveryInspection } from \"./recovery-inspection.types.ts\";\nimport { inspectRecovery } from \"./recovery-inspection.ts\";\nimport { retentionPolicy } from \"./recovery-retention-policy.ts\";\nimport type {\n RecoveryPruneResult,\n RecoveryRetainedEntry,\n RecoveryQuotaOptions,\n RecoveryRetentionEntry,\n RecoveryRetentionOptions,\n RecoveryRetentionPlan,\n} from \"./recovery-retention.types.ts\";\n\nasync function workspaceReason(\n entry: StorageEntry,\n inspection: RecoveryInspection,\n): Promise<string> {\n if (inspection.resources?.complete === false)\n return \"RESOURCE_ACTIVITY_UNKNOWN\";\n if (\n inspection.resources?.entries.some(\n (resource) => resource.record?.workspace === entry.path,\n )\n )\n return \"RESOURCE_ACTIVITY_RECORDED\";\n const workspace = inspection.git?.workspaces.find(\n (value) => value.path === entry.path,\n );\n if (!workspace || workspace.state !== \"registered\")\n return \"WORKSPACE_UNREGISTERED_OR_UNKNOWN\";\n if (workspace.branch === null) return \"DETACHED_WORKSPACE\";\n if (workspace.dirty) return \"DIRTY_WORKSPACE\";\n if (workspace.locked) return \"GIT_LOCKED_WORKSPACE\";\n try {\n await lstat(lockPath(inspection.repository, workspace.branch));\n return \"OPERATION_LOCK_PRESENT\";\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ))\n return \"OWNERSHIP_UNKNOWN\";\n }\n try {\n const ignored = await git(entry.path, [\n \"ls-files\",\n \"--others\",\n \"--ignored\",\n \"--exclude-standard\",\n \"-z\",\n ]);\n if (ignored.length) return \"IGNORED_FILES\";\n } catch {\n return \"WORKSPACE_STATE_UNKNOWN\";\n }\n return \"ELIGIBLE\";\n}\n\nexport async function planRecoveryRetention(\n options: RecoveryRetentionOptions,\n): Promise<RecoveryRetentionPlan> {\n if (options.transporter) return planTransportRetention(options);\n retentionPolicy(options.policy);\n const policy = structuredClone(options.policy);\n const inspection = await inspectRecovery({\n ...options,\n git: true,\n locks: true,\n resources: true,\n });\n const entries: RecoveryRetentionEntry[] = [];\n const inspectedAt = new Date().toISOString();\n const complete = inspection.complete && inspection.git?.complete !== false;\n for (const category of inspection.categories) {\n for (const entry of category.entries) {\n let reason = \"RECOVERY_DATA_PROTECTED\";\n if (category.name === \"locks\") reason = \"OWNERSHIP_RECORD_PROTECTED\";\n if (category.name === \"logs\") reason = \"LOG_ACTIVITY_OR_CONTENT_UNKNOWN\";\n if (category.name === \"workspaces\") reason = \"SCOPE_NOT_SELECTED\";\n if (\n category.name === \"workspaces\" &&\n policy.scopes.includes(\"clean-workspaces\")\n )\n reason = await workspaceReason(entry, inspection);\n if (\n category.name === \"logs\" &&\n policy.scopes.includes(\"closed-logs\") &&\n entry.kind === \"file\" &&\n entry.name.endsWith(\".jsonl\") &&\n (await closedJournal(entry.path))\n )\n reason = \"ELIGIBLE\";\n if (category.name === \"logs\" && entry.name.endsWith(\".closed.json\"))\n reason = \"CLOSURE_RECORD_PROTECTED\";\n if (\n reason === \"ELIGIBLE\" &&\n (!entry.modifiedAt ||\n Date.parse(inspectedAt) - Date.parse(entry.modifiedAt) <\n policy.minAgeMs)\n )\n reason = \"RETENTION_AGE\";\n if (reason === \"ELIGIBLE\" && (!complete || !entry.complete))\n reason = \"INCOMPLETE_INVENTORY\";\n const workspace = inspection.git?.workspaces.find(\n (value) => value.path === entry.path,\n );\n entries.push({\n path: entry.path,\n category: category.name,\n bytes: entry.bytes,\n eligible: reason === \"ELIGIBLE\",\n reason,\n ...(entry.modifiedAt ? { modifiedAt: entry.modifiedAt } : {}),\n ...(workspace?.state === \"registered\" && workspace.branch\n ? { branch: workspace.branch, head: workspace.head }\n : {}),\n });\n }\n }\n const projectedBytes =\n inspection.usage.bytes -\n entries\n .filter((entry) => entry.eligible)\n .reduce(\n (sum, entry) =>\n sum +\n entry.bytes +\n (entry.category === \"logs\"\n ? (entries.find(\n (other) => other.path === `${entry.path}.closed.json`,\n )?.bytes ?? 0)\n : 0),\n 0,\n );\n const workspaces = entries.filter(\n (entry) => entry.category === \"workspaces\" && !entry.eligible,\n ).length;\n const exceeded =\n (policy.maxBytes !== undefined && projectedBytes > policy.maxBytes) ||\n (policy.maxWorkspaces !== undefined && workspaces > policy.maxWorkspaces);\n return {\n repository: inspection.repository,\n policy,\n inspectedAt,\n inspection,\n entries,\n complete,\n usageBytes: inspection.usage.bytes,\n projectedBytes,\n quota: !complete ? \"unknown\" : exceeded ? \"exceeded\" : \"within\",\n };\n}\n\nexport async function pruneRecoveryRetention(\n plan: RecoveryRetentionPlan,\n options?: TransportStoreOptions,\n): Promise<RecoveryPruneResult> {\n if (plan.source === \"transport\") {\n invariant(options, \"Transport retention requires its transporter\");\n return pruneTransportRetention(plan, options);\n }\n invariant(!options, \"Local retention does not accept a transporter\");\n retentionPolicy(plan.policy);\n invariant(plan.complete, \"Cannot prune an incomplete retention plan\");\n const removed: string[] = [];\n const retained: RecoveryRetainedEntry[] = [];\n for (const candidate of plan.entries.filter((entry) => entry.eligible)) {\n const fresh = await planRecoveryRetention({\n repository: plan.repository,\n policy: plan.policy,\n });\n const entry = fresh.entries.find((value) => value.path === candidate.path);\n if (\n !entry?.eligible ||\n entry.head !== candidate.head ||\n entry.branch !== candidate.branch ||\n entry.bytes !== candidate.bytes ||\n entry.modifiedAt !== candidate.modifiedAt\n ) {\n retained.push({ path: candidate.path, reason: \"PLAN_CHANGED\" });\n continue;\n }\n try {\n if (entry.category === \"workspaces\" && entry.branch) {\n const release = await lock(plan.repository, entry.branch);\n try {\n const status = await git(entry.path, [\n \"status\",\n \"--porcelain=v1\",\n \"--ignored\",\n \"--untracked-files=all\",\n ]);\n invariant(!status.length, \"Workspace changed before pruning\");\n invariant(\n (await git(entry.path, [\"rev-parse\", \"HEAD\"])).trim() ===\n entry.head,\n \"Workspace HEAD changed before pruning\",\n );\n invariant(\n (\n await git(entry.path, [\"symbolic-ref\", \"--short\", \"HEAD\"])\n ).trim() === entry.branch,\n \"Workspace branch changed before pruning\",\n );\n await git(plan.repository, [\"worktree\", \"remove\", entry.path]);\n } finally {\n await release();\n }\n } else {\n const release = await lock(plan.repository, `journal:${entry.path}`);\n try {\n invariant(\n entry.category === \"logs\" && (await closedJournal(entry.path)),\n \"Journal changed before pruning\",\n );\n await rm(entry.path);\n await rm(`${entry.path}.closed.json`);\n } finally {\n await release();\n }\n }\n removed.push(entry.path);\n } catch {\n retained.push({\n path: candidate.path,\n reason: \"REVALIDATION_OR_REMOVAL_FAILED\",\n });\n }\n }\n return {\n removed,\n retained,\n after: await planRecoveryRetention({\n repository: plan.repository,\n policy: plan.policy,\n }),\n };\n}\n\nexport async function assertRecoveryQuota(\n options: RecoveryQuotaOptions,\n): Promise<void> {\n invariant(\n Number.isSafeInteger(options.maxBytes) && options.maxBytes >= 0,\n \"maxBytes must be a nonnegative integer\",\n );\n const reserve = options.reserveBytes ?? 0;\n invariant(\n Number.isSafeInteger(reserve) && reserve >= 0,\n \"reserveBytes must be a nonnegative integer\",\n );\n const inspection = await inspectRecovery(options);\n if (\n !inspection.complete ||\n inspection.usage.bytes + reserve > options.maxBytes\n )\n throw new OutpostError(\n \"workspace\",\n \"Outpost storage quota admission refused\",\n {\n usageBytes: inspection.usage.bytes,\n reserveBytes: reserve,\n maxBytes: options.maxBytes,\n complete: inspection.complete,\n },\n );\n}\n"]}
1
+ {"version":3,"file":"recovery-retention.js","sourceRoot":"","sources":["../../src/application/recovery-retention.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAE,0BAA0B,EAAE,MAAM,qDAAqD,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAG/D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAUjE,KAAK,UAAU,eAAe,CAC5B,KAAmB,EACnB,UAA8B;IAE9B,IAAI,UAAU,CAAC,SAAS,EAAE,QAAQ,KAAK,KAAK;QAC1C,OAAO,2BAA2B,CAAC;IACrC,IACE,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAChC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,KAAK,CAAC,IAAI,CACxD;QAED,OAAO,4BAA4B,CAAC;IACtC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CACrC,CAAC;IACF,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,KAAK,KAAK,YAAY;QAChD,OAAO,mCAAmC,CAAC;IAC7C,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,oBAAoB,CAAC;IAC3D,IAAI,SAAS,CAAC,KAAK;QAAE,OAAO,iBAAiB,CAAC;IAC9C,IAAI,SAAS,CAAC,MAAM;QAAE,OAAO,sBAAsB,CAAC;IACpD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,OAAO,wBAAwB,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CACH,KAAK;YACL,OAAO,KAAK,KAAK,QAAQ;YACzB,MAAM,IAAI,KAAK;YACf,KAAK,CAAC,IAAI,KAAK,QAAQ,CACxB;YACC,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;YACpC,UAAU;YACV,UAAU;YACV,WAAW;YACX,oBAAoB;YACpB,IAAI;SACL,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,eAAe,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,yBAAyB,CAAC;IACnC,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAiC;IAEjC,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChE,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC;QACvC,GAAG,OAAO;QACV,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,IAAI,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,EAAE,QAAQ,KAAK,KAAK,CAAC;IACzE,KAAK,MAAM,QAAQ,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,MAAM,GAAG,yBAAyB,CAAC;YACvC,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM,GAAG,4BAA4B,CAAC;YACrE,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM;gBAAE,MAAM,GAAG,iCAAiC,CAAC;YACzE,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,GAAG,oBAAoB,CAAC;YAClE,IACE,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAC9B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAE1C,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACpD,IACE,MAAM,KAAK,UAAU;gBACrB,CAAC,CAAC,KAAK,CAAC,UAAU;oBAChB,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;wBACpD,MAAM,CAAC,QAAQ,CAAC;gBAEpB,MAAM,GAAG,eAAe,CAAC;YAC3B,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;gBACzD,MAAM,GAAG,sBAAsB,CAAC;YAClC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CACrC,CAAC;YACF,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBACvB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,QAAQ,EAAE,MAAM,KAAK,UAAU;gBAC/B,MAAM;gBACN,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,GAAG,CAAC,SAAS,EAAE,KAAK,KAAK,YAAY,IAAI,SAAS,CAAC,MAAM;oBACvD,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE;oBACpD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;QACxC,WAAW,EAAE,mBAAmB,CAAC,UAAU,CAAC,UAAU,CAAC;QACvD,MAAM,EAAE;YACN,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,aAAa,CAAC;YAChE,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B;QACD,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS;YAClC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;KACxC,CAAC,CAAC;IACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,MAAM,CACrC,EAAE,CAAC;QACF,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC;gBACH,KAAK,IAAI,CACP,MAAM,KAAK,CACT,IAAI,CACF,UAAU,CAAC,UAAU,EACrB,UAAU,EACV,0BAA0B,EAC1B,SAAS,EACT,GAAG,MAAM,CAAC,GAAG,SAAS,CACvB,CACF,CACF,CAAC,IAAI,CAAC;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,GAAG,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CACjC,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,QAAQ,KAAK,SAAS;YAC5B,KAAK,CAAC,IAAI;gBACR,IAAI,CACF,UAAU,CAAC,UAAU,EACrB,UAAU,EACV,0BAA0B,EAC1B,SAAS,CACV,CACN,CAAC;QACF,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK;YAAE,QAAQ,GAAG,KAAK,CAAC;QACtD,IAAI,MAAM;YACR,OAAO,CAAC,SAAS,CAAC,GAAG;gBACnB,GAAG,MAAM;gBACT,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;aACzC,CAAC;QACJ,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;IACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,QAAQ;gBAChB,OAAO,CAAC,KAAK,CAAC,GAAG;oBACf,GAAG,KAAK;oBACR,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,sBAAsB;iBAC/B,CAAC;QACN,CAAC;IACH,CAAC;IACD,MAAM,cAAc,GAClB,UAAU,CAAC,KAAK,CAAC,KAAK;QACtB,OAAO;aACJ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;aACjC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAC9D,CAAC,MAAM,CAAC;IACT,MAAM,QAAQ,GACZ,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;QACnE,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IAC5E,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,MAAM;QACN,WAAW;QACX,UAAU;QACV,OAAO;QACP,QAAQ;QACR,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK;QAClC,cAAc;QACd,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAA2B,EAC3B,OAA+B;IAE/B,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,SAAS,CAAC,OAAO,EAAE,8CAA8C,CAAC,CAAC;QACnE,OAAO,uBAAuB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,SAAS,CAAC,CAAC,OAAO,EAAE,+CAA+C,CAAC,CAAC;IACrE,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,2CAA2C,CAAC,CAAC;IACtE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC;YACxC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3E,IACE,CAAC,KAAK,EAAE,QAAQ;YAChB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;YAC7B,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YACjC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK;YAC/B,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU,EACzC,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC1D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;wBACnC,QAAQ;wBACR,gBAAgB;wBAChB,WAAW;wBACX,uBAAuB;qBACxB,CAAC,CAAC;oBACH,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,kCAAkC,CAAC,CAAC;oBAC9D,SAAS,CACP,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;wBACnD,KAAK,CAAC,IAAI,EACZ,uCAAuC,CACxC,CAAC;oBACF,SAAS,CACP,CACE,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAC3D,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,MAAM,EACzB,yCAAyC,CAC1C,CAAC;oBACF,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBACjE,CAAC;wBAAS,CAAC;oBACT,MAAM,OAAO,EAAE,CAAC;gBAClB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C;oBACE,GAAG,IAAI;oBACP,MAAM,EAAE,WAAW;oBACnB,MAAM,EAAE;wBACN,OAAO,EAAE,CAAC;wBACV,MAAM,EAAE,CAAC,aAAa,CAAC;wBACvB,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;qBAC/B;oBACD,OAAO,EAAE,CAAC,SAAS,CAAC;iBACrB,EACD,EAAE,WAAW,EAAE,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CACtD,CAAC;gBACF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;oBAClC,SAAS;gBACX,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,gCAAgC;aACzC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO;QACP,QAAQ;QACR,KAAK,EAAE,MAAM,qBAAqB,CAAC;YACjC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAA6B;IAE7B,SAAS,CACP,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,EAC/D,wCAAwC,CACzC,CAAC;IACF,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC;IAC1C,SAAS,CACP,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAC7C,4CAA4C,CAC7C,CAAC;IACF,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAClD,IACE,CAAC,UAAU,CAAC,QAAQ;QACpB,UAAU,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC,QAAQ;QAEnD,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,yCAAyC,EACzC;YACE,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK;YAClC,YAAY,EAAE,OAAO;YACrB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,UAAU,CAAC,QAAQ;SAC9B,CACF,CAAC;AACN,CAAC","sourcesContent":["import type { TransportStoreOptions } from \"../domain/transport.types.ts\";\nimport {\n planTransportRetention,\n pruneTransportRetention,\n} from \"./transport-retention.ts\";\nimport { lstat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { repositoryTransport } from \"../infrastructure/repository-transport.ts\";\nimport { repositoryStorageDirectory } from \"../infrastructure/repository-transport.constants.ts\";\nimport { OutpostError, invariant } from \"../domain/errors.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { lock, lockPath } from \"../infrastructure/git/lock.ts\";\nimport type { StorageEntry } from \"../infrastructure/storage-inventory.types.ts\";\nimport type { RecoveryInspection } from \"./recovery-inspection.types.ts\";\nimport { inspectRecovery } from \"./recovery-inspection.ts\";\nimport { retentionPolicy } from \"./recovery-retention-policy.ts\";\nimport type {\n RecoveryPruneResult,\n RecoveryRetainedEntry,\n RecoveryQuotaOptions,\n RecoveryRetentionEntry,\n RecoveryRetentionOptions,\n RecoveryRetentionPlan,\n} from \"./recovery-retention.types.ts\";\n\nasync function workspaceReason(\n entry: StorageEntry,\n inspection: RecoveryInspection,\n): Promise<string> {\n if (inspection.resources?.complete === false)\n return \"RESOURCE_ACTIVITY_UNKNOWN\";\n if (\n inspection.resources?.entries.some(\n (resource) => resource.record?.workspace === entry.path,\n )\n )\n return \"RESOURCE_ACTIVITY_RECORDED\";\n const workspace = inspection.git?.workspaces.find(\n (value) => value.path === entry.path,\n );\n if (!workspace || workspace.state !== \"registered\")\n return \"WORKSPACE_UNREGISTERED_OR_UNKNOWN\";\n if (workspace.branch === null) return \"DETACHED_WORKSPACE\";\n if (workspace.dirty) return \"DIRTY_WORKSPACE\";\n if (workspace.locked) return \"GIT_LOCKED_WORKSPACE\";\n try {\n await lstat(lockPath(inspection.repository, workspace.branch));\n return \"OPERATION_LOCK_PRESENT\";\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ENOENT\"\n ))\n return \"OWNERSHIP_UNKNOWN\";\n }\n try {\n const ignored = await git(entry.path, [\n \"ls-files\",\n \"--others\",\n \"--ignored\",\n \"--exclude-standard\",\n \"-z\",\n ]);\n if (ignored.length) return \"IGNORED_FILES\";\n } catch {\n return \"WORKSPACE_STATE_UNKNOWN\";\n }\n return \"ELIGIBLE\";\n}\n\nexport async function planRecoveryRetention(\n options: RecoveryRetentionOptions,\n): Promise<RecoveryRetentionPlan> {\n if (options.transporter) return planTransportRetention(options);\n retentionPolicy(options.policy);\n const policy = structuredClone(options.policy);\n const inspection = await inspectRecovery({\n ...options,\n git: true,\n locks: true,\n resources: true,\n });\n const entries: RecoveryRetentionEntry[] = [];\n const inspectedAt = new Date().toISOString();\n let complete = inspection.complete && inspection.git?.complete !== false;\n for (const category of inspection.categories) {\n for (const entry of category.entries) {\n let reason = \"RECOVERY_DATA_PROTECTED\";\n if (category.name === \"locks\") reason = \"OWNERSHIP_RECORD_PROTECTED\";\n if (category.name === \"logs\") reason = \"LOG_ACTIVITY_OR_CONTENT_UNKNOWN\";\n if (category.name === \"workspaces\") reason = \"SCOPE_NOT_SELECTED\";\n if (\n category.name === \"workspaces\" &&\n policy.scopes.includes(\"clean-workspaces\")\n )\n reason = await workspaceReason(entry, inspection);\n if (\n reason === \"ELIGIBLE\" &&\n (!entry.modifiedAt ||\n Date.parse(inspectedAt) - Date.parse(entry.modifiedAt) <\n policy.minAgeMs)\n )\n reason = \"RETENTION_AGE\";\n if (reason === \"ELIGIBLE\" && (!complete || !entry.complete))\n reason = \"INCOMPLETE_INVENTORY\";\n const workspace = inspection.git?.workspaces.find(\n (value) => value.path === entry.path,\n );\n entries.push({\n path: entry.path,\n category: category.name,\n bytes: entry.bytes,\n eligible: reason === \"ELIGIBLE\",\n reason,\n ...(entry.modifiedAt ? { modifiedAt: entry.modifiedAt } : {}),\n ...(workspace?.state === \"registered\" && workspace.branch\n ? { branch: workspace.branch, head: workspace.head }\n : {}),\n });\n }\n }\n const logs = await planTransportRetention({\n transporter: repositoryTransport(inspection.repository),\n policy: {\n version: 1,\n scopes: policy.scopes.filter((scope) => scope === \"closed-logs\"),\n minAgeMs: policy.minAgeMs,\n },\n ...(options.maxEntries === undefined\n ? {}\n : { maxEntries: options.maxEntries }),\n });\n for (const entry of logs.entries.filter(\n (entry) => entry.category === \"logs\",\n )) {\n let bytes = 0;\n for (const object of entry.objects ?? []) {\n try {\n bytes += (\n await lstat(\n join(\n inspection.repository,\n \".outpost\",\n repositoryStorageDirectory,\n \"objects\",\n `${object.key}.object`,\n ),\n )\n ).size;\n } catch {\n complete = false;\n }\n }\n const container = entries.findIndex(\n (value) =>\n value.category === \"storage\" &&\n value.path ===\n join(\n inspection.repository,\n \".outpost\",\n repositoryStorageDirectory,\n \"objects\",\n ),\n );\n const stored = entries[container];\n if (!stored || stored.bytes < bytes) complete = false;\n if (stored)\n entries[container] = {\n ...stored,\n bytes: Math.max(0, stored.bytes - bytes),\n };\n entries.push({ ...entry, bytes, eligible: entry.eligible && complete });\n }\n complete = complete && logs.complete;\n if (!complete) {\n for (let index = 0; index < entries.length; index++) {\n const entry = entries[index]!;\n if (entry.eligible)\n entries[index] = {\n ...entry,\n eligible: false,\n reason: \"INCOMPLETE_INVENTORY\",\n };\n }\n }\n const projectedBytes =\n inspection.usage.bytes -\n entries\n .filter((entry) => entry.eligible)\n .reduce((sum, entry) => sum + entry.bytes, 0);\n const workspaces = entries.filter(\n (entry) => entry.category === \"workspaces\" && !entry.eligible,\n ).length;\n const exceeded =\n (policy.maxBytes !== undefined && projectedBytes > policy.maxBytes) ||\n (policy.maxWorkspaces !== undefined && workspaces > policy.maxWorkspaces);\n return {\n repository: inspection.repository,\n policy,\n inspectedAt,\n inspection,\n entries,\n complete,\n usageBytes: inspection.usage.bytes,\n projectedBytes,\n quota: !complete ? \"unknown\" : exceeded ? \"exceeded\" : \"within\",\n };\n}\n\nexport async function pruneRecoveryRetention(\n plan: RecoveryRetentionPlan,\n options?: TransportStoreOptions,\n): Promise<RecoveryPruneResult> {\n if (plan.source === \"transport\") {\n invariant(options, \"Transport retention requires its transporter\");\n return pruneTransportRetention(plan, options);\n }\n invariant(!options, \"Local retention does not accept a transporter\");\n retentionPolicy(plan.policy);\n invariant(plan.complete, \"Cannot prune an incomplete retention plan\");\n const removed: string[] = [];\n const retained: RecoveryRetainedEntry[] = [];\n for (const candidate of plan.entries.filter((entry) => entry.eligible)) {\n const fresh = await planRecoveryRetention({\n repository: plan.repository,\n policy: plan.policy,\n });\n const entry = fresh.entries.find((value) => value.path === candidate.path);\n if (\n !entry?.eligible ||\n entry.head !== candidate.head ||\n entry.branch !== candidate.branch ||\n entry.bytes !== candidate.bytes ||\n entry.modifiedAt !== candidate.modifiedAt\n ) {\n retained.push({ path: candidate.path, reason: \"PLAN_CHANGED\" });\n continue;\n }\n try {\n if (entry.category === \"workspaces\" && entry.branch) {\n const release = await lock(plan.repository, entry.branch);\n try {\n const status = await git(entry.path, [\n \"status\",\n \"--porcelain=v1\",\n \"--ignored\",\n \"--untracked-files=all\",\n ]);\n invariant(!status.length, \"Workspace changed before pruning\");\n invariant(\n (await git(entry.path, [\"rev-parse\", \"HEAD\"])).trim() ===\n entry.head,\n \"Workspace HEAD changed before pruning\",\n );\n invariant(\n (\n await git(entry.path, [\"symbolic-ref\", \"--short\", \"HEAD\"])\n ).trim() === entry.branch,\n \"Workspace branch changed before pruning\",\n );\n await git(plan.repository, [\"worktree\", \"remove\", entry.path]);\n } finally {\n await release();\n }\n } else {\n const result = await pruneTransportRetention(\n {\n ...plan,\n source: \"transport\",\n policy: {\n version: 1,\n scopes: [\"closed-logs\"],\n minAgeMs: plan.policy.minAgeMs,\n },\n entries: [candidate],\n },\n { transporter: repositoryTransport(plan.repository) },\n );\n if (!result.removed.includes(entry.path)) {\n retained.push(...result.retained);\n continue;\n }\n }\n removed.push(entry.path);\n } catch {\n retained.push({\n path: candidate.path,\n reason: \"REVALIDATION_OR_REMOVAL_FAILED\",\n });\n }\n }\n return {\n removed,\n retained,\n after: await planRecoveryRetention({\n repository: plan.repository,\n policy: plan.policy,\n }),\n };\n}\n\nexport async function assertRecoveryQuota(\n options: RecoveryQuotaOptions,\n): Promise<void> {\n invariant(\n Number.isSafeInteger(options.maxBytes) && options.maxBytes >= 0,\n \"maxBytes must be a nonnegative integer\",\n );\n const reserve = options.reserveBytes ?? 0;\n invariant(\n Number.isSafeInteger(reserve) && reserve >= 0,\n \"reserveBytes must be a nonnegative integer\",\n );\n const inspection = await inspectRecovery(options);\n if (\n !inspection.complete ||\n inspection.usage.bytes + reserve > options.maxBytes\n )\n throw new OutpostError(\n \"workspace\",\n \"Outpost storage quota admission refused\",\n {\n usageBytes: inspection.usage.bytes,\n reserveBytes: reserve,\n maxBytes: options.maxBytes,\n complete: inspection.complete,\n },\n );\n}\n"]}
@@ -13,7 +13,7 @@ export async function downloadChanges(context, synchronized, transfer) {
13
13
  .split("\0")
14
14
  .filter(Boolean);
15
15
  for (const file of incoming) {
16
- if (/^\.outpost\/(locks|recovery|workspaces|logs)(\/|$)/i.test(file))
16
+ if (/^\.outpost\/(locks|recovery|workspaces|logs|conversations)(\/|$)/i.test(file))
17
17
  throw new OutpostError("workspace", "Remote file overlaps Outpost runtime state", { file });
18
18
  await safeDestination(join(transfer, "incoming"), file);
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote-download.js","sourceRoot":"","sources":["../../src/application/remote-download.ts"],"names":[],"mappings":"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","sourcesContent":["import { cp, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, posix } from \"node:path\";\nimport { downloadHistory } from \"./remote-history.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport {\n fileManifest,\n parseManifest,\n sameFile,\n sameLocalFile,\n} from \"../infrastructure/file-manifest.ts\";\nimport type { FileManifestEntry } from \"../domain/sandbox.types.ts\";\nimport { safeDestination } from \"../infrastructure/files.ts\";\nimport type {\n RemoteChanges,\n RemoteWorkspaceContext,\n} from \"./remote-workspace.types.ts\";\n\nexport async function downloadChanges(\n context: RemoteWorkspaceContext,\n synchronized: string,\n transfer: string,\n): Promise<RemoteChanges> {\n const { workspace, lease, remoteBundle, run } = context;\n const head = (await run([\"rev-parse\", \"HEAD\"])).trim(),\n patch = join(transfer, \"remote.patch\");\n await run([\"diff\", \"--binary\", \"HEAD\", `--output=${remoteBundle}.patch`]);\n await lease.download(`${remoteBundle}.patch`, patch);\n const incoming = (\n await run([\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"])\n )\n .split(\"\\0\")\n .filter(Boolean);\n for (const file of incoming) {\n if (/^\\.outpost\\/(locks|recovery|workspaces|logs)(\\/|$)/i.test(file))\n throw new OutpostError(\n \"workspace\",\n \"Remote file overlaps Outpost runtime state\",\n { file },\n );\n await safeDestination(join(transfer, \"incoming\"), file);\n }\n let manifest: readonly FileManifestEntry[] | undefined;\n if (lease.fileTransfers) {\n manifest = parseManifest(\n await lease.fileTransfers.manifest(lease.root, incoming),\n incoming,\n );\n await writeFile(join(transfer, \"manifest.json\"), JSON.stringify(manifest), {\n mode: 0o600,\n });\n const changed: FileManifestEntry[] = [];\n for (const entry of manifest) {\n const previous = context.transferred?.get(entry.path);\n if (\n previous &&\n sameFile(previous, entry) &&\n sameLocalFile(\n entry,\n await fileManifest(workspace.directory, entry.path),\n )\n ) {\n const target = await safeDestination(\n join(transfer, \"incoming\"),\n entry.path,\n );\n await mkdir(dirname(target), { recursive: true });\n await cp(\n await safeDestination(workspace.directory, entry.path),\n target,\n { dereference: false, verbatimSymlinks: true },\n );\n continue;\n }\n changed.push(entry);\n }\n await lease.fileTransfers.downloadBatch(\n lease.root,\n changed,\n join(transfer, \"incoming\"),\n );\n for (const entry of manifest) {\n if (\n !sameLocalFile(\n entry,\n await fileManifest(join(transfer, \"incoming\"), entry.path),\n )\n )\n throw new OutpostError(\"workspace\", \"Incoming file checksum mismatch\", {\n file: entry.path,\n });\n }\n } else\n for (const file of incoming) {\n await lease.download(\n posix.join(lease.root, file),\n await safeDestination(join(transfer, \"incoming\"), file),\n );\n }\n if (head !== synchronized) {\n await downloadHistory(context, synchronized, head, transfer);\n }\n\n return { head, patch, incoming, ...(manifest ? { manifest } : {}) };\n}\n"]}
1
+ {"version":3,"file":"remote-download.js","sourceRoot":"","sources":["../../src/application/remote-download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,aAAa,GACd,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAM7D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA+B,EAC/B,YAAoB,EACpB,QAAgB;IAEhB,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACxD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACpD,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACzC,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,YAAY,QAAQ,CAAC,CAAC,CAAC;IAC1E,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,YAAY,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,CACf,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAChE;SACE,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IACE,mEAAmE,CAAC,IAAI,CACtE,IAAI,CACL;YAED,MAAM,IAAI,YAAY,CACpB,WAAW,EACX,4CAA4C,EAC5C,EAAE,IAAI,EAAE,CACT,CAAC;QACJ,MAAM,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,QAAkD,CAAC;IACvD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,QAAQ,GAAG,aAAa,CACtB,MAAM,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,EACxD,QAAQ,CACT,CAAC;QACF,MAAM,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE;YACzE,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QACH,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtD,IACE,QAAQ;gBACR,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;gBACzB,aAAa,CACX,KAAK,EACL,MAAM,YAAY,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CACpD,EACD,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAC1B,KAAK,CAAC,IAAI,CACX,CAAC;gBACF,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,MAAM,EAAE,CACN,MAAM,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EACtD,MAAM,EACN,EAAE,WAAW,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAC/C,CAAC;gBACF,SAAS;YACX,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,MAAM,KAAK,CAAC,aAAa,CAAC,aAAa,CACrC,KAAK,CAAC,IAAI,EACV,OAAO,EACP,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAC3B,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IACE,CAAC,aAAa,CACZ,KAAK,EACL,MAAM,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAC3D;gBAED,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,iCAAiC,EAAE;oBACrE,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC,CAAC;QACP,CAAC;IACH,CAAC;;QACC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,KAAK,CAAC,QAAQ,CAClB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAC5B,MAAM,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CACxD,CAAC;QACJ,CAAC;IACH,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtE,CAAC","sourcesContent":["import { cp, mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, posix } from \"node:path\";\nimport { downloadHistory } from \"./remote-history.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport {\n fileManifest,\n parseManifest,\n sameFile,\n sameLocalFile,\n} from \"../infrastructure/file-manifest.ts\";\nimport type { FileManifestEntry } from \"../domain/sandbox.types.ts\";\nimport { safeDestination } from \"../infrastructure/files.ts\";\nimport type {\n RemoteChanges,\n RemoteWorkspaceContext,\n} from \"./remote-workspace.types.ts\";\n\nexport async function downloadChanges(\n context: RemoteWorkspaceContext,\n synchronized: string,\n transfer: string,\n): Promise<RemoteChanges> {\n const { workspace, lease, remoteBundle, run } = context;\n const head = (await run([\"rev-parse\", \"HEAD\"])).trim(),\n patch = join(transfer, \"remote.patch\");\n await run([\"diff\", \"--binary\", \"HEAD\", `--output=${remoteBundle}.patch`]);\n await lease.download(`${remoteBundle}.patch`, patch);\n const incoming = (\n await run([\"ls-files\", \"--others\", \"--exclude-standard\", \"-z\"])\n )\n .split(\"\\0\")\n .filter(Boolean);\n for (const file of incoming) {\n if (\n /^\\.outpost\\/(locks|recovery|workspaces|logs|conversations)(\\/|$)/i.test(\n file,\n )\n )\n throw new OutpostError(\n \"workspace\",\n \"Remote file overlaps Outpost runtime state\",\n { file },\n );\n await safeDestination(join(transfer, \"incoming\"), file);\n }\n let manifest: readonly FileManifestEntry[] | undefined;\n if (lease.fileTransfers) {\n manifest = parseManifest(\n await lease.fileTransfers.manifest(lease.root, incoming),\n incoming,\n );\n await writeFile(join(transfer, \"manifest.json\"), JSON.stringify(manifest), {\n mode: 0o600,\n });\n const changed: FileManifestEntry[] = [];\n for (const entry of manifest) {\n const previous = context.transferred?.get(entry.path);\n if (\n previous &&\n sameFile(previous, entry) &&\n sameLocalFile(\n entry,\n await fileManifest(workspace.directory, entry.path),\n )\n ) {\n const target = await safeDestination(\n join(transfer, \"incoming\"),\n entry.path,\n );\n await mkdir(dirname(target), { recursive: true });\n await cp(\n await safeDestination(workspace.directory, entry.path),\n target,\n { dereference: false, verbatimSymlinks: true },\n );\n continue;\n }\n changed.push(entry);\n }\n await lease.fileTransfers.downloadBatch(\n lease.root,\n changed,\n join(transfer, \"incoming\"),\n );\n for (const entry of manifest) {\n if (\n !sameLocalFile(\n entry,\n await fileManifest(join(transfer, \"incoming\"), entry.path),\n )\n )\n throw new OutpostError(\"workspace\", \"Incoming file checksum mismatch\", {\n file: entry.path,\n });\n }\n } else\n for (const file of incoming) {\n await lease.download(\n posix.join(lease.root, file),\n await safeDestination(join(transfer, \"incoming\"), file),\n );\n }\n if (head !== synchronized) {\n await downloadHistory(context, synchronized, head, transfer);\n }\n\n return { head, patch, incoming, ...(manifest ? { manifest } : {}) };\n}\n"]}
@@ -1,18 +1,27 @@
1
1
  import { invariant } from "../domain/errors.js";
2
2
  import { resolveVariables } from "../infrastructure/settings.js";
3
+ import { authenticateAgent } from "./agent-authentication.js";
3
4
  import { prepareAdapter } from "./agent-bootstrap.js";
4
5
  import { storageFor } from "./agent-storage.js";
5
6
  export function sandboxAgents(context) {
6
- const { options, provider, workspace, runtime, prepared, staging } = context;
7
+ const { options, sandboxProvider, workspace, runtime, prepared, staging } = context;
7
8
  const known = new Set();
9
+ const authenticated = new Map();
8
10
  const selectAgent = async (selected, signal) => {
9
11
  invariant(selected, "Provide an agent on the sandbox or this operation");
10
12
  if (!prepared.has(selected))
11
- prepared.set(selected, provider.placement === "remote" && options.bootstrap !== false
13
+ prepared.set(selected, sandboxProvider.placement === "remote" && options.bootstrap !== false
12
14
  ? await prepareAdapter(selected, runtime, signal)
13
15
  : selected);
14
- const variables = await resolveVariables(workspace.repository, selected.variables, provider.variables);
16
+ const variables = await resolveVariables(workspace.repository, selected.variables, sandboxProvider.variables);
15
17
  const adapter = prepared.get(selected);
18
+ if (adapter.kind === "cli" &&
19
+ authenticated.get(adapter.name)?.adapter !== adapter)
20
+ authenticated.set(adapter.name, {
21
+ adapter,
22
+ variables: await authenticateAgent(adapter, variables, runtime, sandboxProvider.placement, signal),
23
+ });
24
+ const credentials = adapter.kind === "cli" ? authenticated.get(adapter.name)?.variables : {};
16
25
  return {
17
26
  selected,
18
27
  adapter,
@@ -21,7 +30,7 @@ export function sandboxAgents(context) {
21
30
  invoke(command) {
22
31
  return runtime.invoke({
23
32
  ...command,
24
- variables: { ...variables, ...command.variables },
33
+ variables: { ...variables, ...credentials, ...command.variables },
25
34
  });
26
35
  },
27
36
  },
@@ -35,7 +44,7 @@ export function sandboxAgents(context) {
35
44
  invariant(storage, "This adapter does not support native conversations");
36
45
  const found = await storage.locate(id, workspace.repository, options.conversationHome);
37
46
  if (found.reference !== undefined ||
38
- provider.placement !== "host" ||
47
+ sandboxProvider.placement !== "host" ||
39
48
  workspace.directory !== workspace.repository)
40
49
  await storage.restore(found, {
41
50
  repository: workspace.repository,
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-agents.js","sourceRoot":"","sources":["../../src/application/sandbox-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentAdapter } from \"../domain/agent.types.ts\";\nimport type { Command } from \"../domain/command.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport function sandboxAgents(context: ProvisionedSandbox): SandboxAgents {\n const { options, provider, workspace, runtime, prepared, staging } = context;\n const known = new Set<string>();\n const selectAgent = async (\n selected: AgentAdapter | undefined,\n signal: AbortSignal,\n ) => {\n invariant(selected, \"Provide an agent on the sandbox or this operation\");\n if (!prepared.has(selected))\n prepared.set(\n selected,\n provider.placement === \"remote\" && options.bootstrap !== false\n ? await prepareAdapter(selected, runtime, signal)\n : selected,\n );\n const variables = await resolveVariables(\n workspace.repository,\n selected.variables,\n provider.variables,\n );\n const adapter = prepared.get(selected)!;\n return {\n selected,\n adapter,\n executionLease: {\n ...runtime,\n invoke(command: Command) {\n return runtime.invoke({\n ...command,\n variables: { ...variables, ...command.variables },\n });\n },\n },\n };\n };\n const conversationKey = (agent: AgentAdapter, id: string) =>\n `${agent.storage?.name ?? agent.conversations ?? agent.name}:${id}`;\n const restore = async (id: string, agent: AgentAdapter) => {\n if (known.has(conversationKey(agent, id))) return;\n const storage = storageFor(agent);\n invariant(storage, \"This adapter does not support native conversations\");\n const found = await storage.locate(\n id,\n workspace.repository,\n options.conversationHome,\n );\n if (\n found.reference !== undefined ||\n provider.placement !== \"host\" ||\n workspace.directory !== workspace.repository\n )\n await storage.restore(found, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n });\n known.add(conversationKey(agent, id));\n };\n\n return {\n selectAgent,\n restore,\n remember: (agent, id) => {\n known.add(conversationKey(agent, id));\n },\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-agents.js","sourceRoot":"","sources":["../../src/application/sandbox-agents.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent } from \"../domain/agent.types.ts\";\nimport type { Command } from \"../domain/command.types.ts\";\nimport { invariant } from \"../domain/errors.ts\";\nimport { resolveVariables } from \"../infrastructure/settings.ts\";\nimport { authenticateAgent } from \"./agent-authentication.ts\";\nimport { prepareAdapter } from \"./agent-bootstrap.ts\";\nimport { storageFor } from \"./agent-storage.ts\";\nimport type {\n AuthenticatedAgent,\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport function sandboxAgents(context: ProvisionedSandbox): SandboxAgents {\n const { options, sandboxProvider, workspace, runtime, prepared, staging } =\n context;\n const known = new Set<string>();\n const authenticated = new Map<string, AuthenticatedAgent>();\n const selectAgent = async (\n selected: Agent | undefined,\n signal: AbortSignal,\n ) => {\n invariant(selected, \"Provide an agent on the sandbox or this operation\");\n if (!prepared.has(selected))\n prepared.set(\n selected,\n sandboxProvider.placement === \"remote\" && options.bootstrap !== false\n ? await prepareAdapter(selected, runtime, signal)\n : selected,\n );\n const variables = await resolveVariables(\n workspace.repository,\n selected.variables,\n sandboxProvider.variables,\n );\n const adapter = prepared.get(selected)!;\n if (\n adapter.kind === \"cli\" &&\n authenticated.get(adapter.name)?.adapter !== adapter\n )\n authenticated.set(adapter.name, {\n adapter,\n variables: await authenticateAgent(\n adapter,\n variables,\n runtime,\n sandboxProvider.placement,\n signal,\n ),\n });\n const credentials =\n adapter.kind === \"cli\" ? authenticated.get(adapter.name)?.variables : {};\n return {\n selected,\n adapter,\n executionLease: {\n ...runtime,\n invoke(command: Command) {\n return runtime.invoke({\n ...command,\n variables: { ...variables, ...credentials, ...command.variables },\n });\n },\n },\n };\n };\n const conversationKey = (agent: Agent, id: string) =>\n `${agent.storage?.name ?? agent.conversations ?? agent.name}:${id}`;\n const restore = async (id: string, agent: Agent) => {\n if (known.has(conversationKey(agent, id))) return;\n const storage = storageFor(agent);\n invariant(storage, \"This adapter does not support native conversations\");\n const found = await storage.locate(\n id,\n workspace.repository,\n options.conversationHome,\n );\n if (\n found.reference !== undefined ||\n sandboxProvider.placement !== \"host\" ||\n workspace.directory !== workspace.repository\n )\n await storage.restore(found, {\n repository: workspace.repository,\n sandbox: runtime,\n staging,\n });\n known.add(conversationKey(agent, id));\n };\n\n return {\n selectAgent,\n restore,\n remember: (agent, id) => {\n known.add(conversationKey(agent, id));\n },\n };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { invariant } from "../domain/errors.js";
1
2
  import { git } from "../infrastructure/git/command.js";
2
3
  import { commits } from "../infrastructure/git/history.js";
3
4
  import { restoreTerminal } from "../infrastructure/terminal.js";
@@ -5,7 +6,8 @@ import { renderBrief } from "./brief-renderer.js";
5
6
  import { executionDefaults } from "./execution.constants.js";
6
7
  import { completeBrief } from "./interactive-brief.js";
7
8
  export async function attachInSandbox(context, agents, settings) {
8
- const { options, provider, workspace, sync, stop } = context;
9
+ const { options, sandboxProvider, workspace, sync, stop } = context;
10
+ invariant((settings.agent ?? options.agent)?.kind === "cli", "This harness does not support interactive attachment");
9
11
  const { selectAgent, restore } = agents;
10
12
  const signal = settings.signal
11
13
  ? AbortSignal.any([settings.signal, stop.signal])
@@ -15,8 +17,9 @@ export async function attachInSandbox(context, agents, settings) {
15
17
  await restore(settings.continuation.id, selected);
16
18
  const brief = await completeBrief(settings.brief, signal, settings.ask);
17
19
  const text = brief
18
- ? await renderBrief(brief, workspace, executionLease, provider.placement === "host", settings)
20
+ ? await renderBrief(brief, workspace, executionLease, sandboxProvider.placement === "host", settings)
19
21
  : undefined;
22
+ invariant(adapter.kind === "cli", "This harness does not support interactive attachment");
20
23
  const command = adapter.request({
21
24
  interactive: true,
22
25
  ...(text === undefined ? {} : { text }),
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-attach.js","sourceRoot":"","sources":["../../src/application/sandbox-attach.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CommandResult } from \"../domain/command.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { restoreTerminal } from \"../infrastructure/terminal.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport { completeBrief } from \"./interactive-brief.ts\";\nimport type { AttachOptions, AttachResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function attachInSandbox(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n settings: AttachOptions,\n): Promise<AttachResult> {\n const { options, provider, workspace, sync, stop } = context;\n const { selectAgent, restore } = agents;\n const signal = settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n settings.agent ?? options.agent,\n signal,\n );\n if (settings.continuation) await restore(settings.continuation.id, selected);\n const brief = await completeBrief(settings.brief, signal, settings.ask);\n const text = brief\n ? await renderBrief(\n brief,\n workspace,\n executionLease,\n provider.placement === \"host\",\n settings,\n )\n : undefined;\n const command = adapter.request({\n interactive: true,\n ...(text === undefined ? {} : { text }),\n ...(settings.continuation ? { continuation: settings.continuation } : {}),\n });\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n let output: CommandResult;\n try {\n output = await executionLease.invoke({\n ...command,\n ...(settings.terminal ? { terminal: settings.terminal } : {}),\n deadlineMs: executionDefaults.attachMs,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n restoreTerminal();\n await sync?.pull();\n }\n return {\n ...output,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n ),\n };\n}\n"]}
1
+ {"version":3,"file":"sandbox-attach.js","sourceRoot":"","sources":["../../src/application/sandbox-attach.ts"],"names":[],"mappings":"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","sourcesContent":["import { invariant } from \"../domain/errors.ts\";\nimport type { CommandResult } from \"../domain/command.types.ts\";\nimport { git } from \"../infrastructure/git/command.ts\";\nimport { commits } from \"../infrastructure/git/history.ts\";\nimport { restoreTerminal } from \"../infrastructure/terminal.ts\";\nimport { renderBrief } from \"./brief-renderer.ts\";\nimport { executionDefaults } from \"./execution.constants.ts\";\nimport { completeBrief } from \"./interactive-brief.ts\";\nimport type { AttachOptions, AttachResult } from \"./outpost.types.ts\";\nimport type {\n ProvisionedSandbox,\n SandboxAgents,\n} from \"./sandbox-session.types.ts\";\n\nexport async function attachInSandbox(\n context: ProvisionedSandbox,\n agents: SandboxAgents,\n settings: AttachOptions,\n): Promise<AttachResult> {\n const { options, sandboxProvider, workspace, sync, stop } = context;\n invariant(\n (settings.agent ?? options.agent)?.kind === \"cli\",\n \"This harness does not support interactive attachment\",\n );\n const { selectAgent, restore } = agents;\n const signal = settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal;\n const { selected, adapter, executionLease } = await selectAgent(\n settings.agent ?? options.agent,\n signal,\n );\n if (settings.continuation) await restore(settings.continuation.id, selected);\n const brief = await completeBrief(settings.brief, signal, settings.ask);\n const text = brief\n ? await renderBrief(\n brief,\n workspace,\n executionLease,\n sandboxProvider.placement === \"host\",\n settings,\n )\n : undefined;\n invariant(\n adapter.kind === \"cli\",\n \"This harness does not support interactive attachment\",\n );\n const command = adapter.request({\n interactive: true,\n ...(text === undefined ? {} : { text }),\n ...(settings.continuation ? { continuation: settings.continuation } : {}),\n });\n const baseline = (\n await git(workspace.directory, [\"rev-parse\", \"HEAD\"])\n ).trim();\n let output: CommandResult;\n try {\n output = await executionLease.invoke({\n ...command,\n ...(settings.terminal ? { terminal: settings.terminal } : {}),\n deadlineMs: executionDefaults.attachMs,\n signal: settings.signal\n ? AbortSignal.any([settings.signal, stop.signal])\n : stop.signal,\n });\n } finally {\n restoreTerminal();\n await sync?.pull();\n }\n return {\n ...output,\n branch: workspace.branch,\n directory: workspace.directory,\n commits: await commits(\n workspace.directory,\n baseline,\n options.limits?.collectMs,\n ),\n };\n}\n"]}
@@ -9,7 +9,7 @@ import { preflightDispatch } from "./dispatch-validation.js";
9
9
  import { execute } from "./execution.js";
10
10
  import { notify } from "./observation.js";
11
11
  export async function dispatchInSandbox(context, agents, result, dispatch) {
12
- const { options, provider, workspace, runtime, sync, stop, staging } = context;
12
+ const { options, sandboxProvider, workspace, runtime, sync, stop, staging } = context;
13
13
  const { selectAgent, restore } = agents;
14
14
  await preflightDispatch(dispatch, workspace.repository, dispatch.agent ?? options.agent);
15
15
  const signal = dispatch.signal
@@ -34,14 +34,14 @@ export async function dispatchInSandbox(context, agents, result, dispatch) {
34
34
  staging,
35
35
  ...(options.conversationHome ? { home: options.conversationHome } : {}),
36
36
  ...(dispatch.warn ? { warn: dispatch.warn } : {}),
37
- local: provider.placement === "host",
37
+ local: sandboxProvider.placement === "host",
38
38
  });
39
39
  captured.set(id, location);
40
40
  transcript = location;
41
41
  return location;
42
42
  };
43
43
  try {
44
- execution = await execute(workspace, executionLease, adapter, provider.placement === "host", {
44
+ execution = await execute(workspace, executionLease, adapter, sandboxProvider.placement === "host", {
45
45
  ...dispatch,
46
46
  signal,
47
47
  observe(event) {
@@ -100,7 +100,6 @@ export async function dispatchInSandbox(context, agents, result, dispatch) {
100
100
  directory: workspace.directory,
101
101
  commits: changes,
102
102
  transcript: transcript?.file,
103
- log: log.file,
104
103
  logReference: log.reference,
105
104
  transcriptReference: transcript?.reference,
106
105
  });
@@ -113,7 +112,6 @@ export async function dispatchInSandbox(context, agents, result, dispatch) {
113
112
  directory: workspace.directory,
114
113
  commits: changes,
115
114
  ...(transcript ? { transcript: transcript.file } : {}),
116
- ...(log.file ? { log: log.file } : {}),
117
115
  ...(log.reference ? { logReference: log.reference } : {}),
118
116
  ...(transcript?.reference
119
117
  ? { transcriptReference: transcript.reference }