@elie-laloum/outpost 11.1.2 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (596) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +2 -1
  3. package/SECURITY.md +5 -1
  4. package/dist/adapters/agents/antigravity/antigravity-adapter.js +9 -0
  5. package/dist/adapters/agents/antigravity/antigravity-adapter.js.map +1 -1
  6. package/dist/adapters/agents/antigravity/antigravity-hook-plan.d.ts +3 -0
  7. package/dist/adapters/agents/antigravity/antigravity-hook-plan.js +39 -0
  8. package/dist/adapters/agents/antigravity/antigravity-hook-plan.js.map +1 -0
  9. package/dist/adapters/agents/antigravity/antigravity-hooks.constants.d.ts +3 -0
  10. package/dist/adapters/agents/antigravity/antigravity-hooks.constants.js +394 -0
  11. package/dist/adapters/agents/antigravity/antigravity-hooks.constants.js.map +1 -0
  12. package/dist/adapters/agents/antigravity/antigravity-hooks.d.ts +2 -0
  13. package/dist/adapters/agents/antigravity/antigravity-hooks.js +6 -0
  14. package/dist/adapters/agents/antigravity/antigravity-hooks.js.map +1 -0
  15. package/dist/adapters/agents/antigravity/antigravity-hooks.types.d.ts +114 -0
  16. package/dist/adapters/agents/antigravity/antigravity-hooks.types.js +2 -0
  17. package/dist/adapters/agents/antigravity/antigravity-hooks.types.js.map +1 -0
  18. package/dist/adapters/agents/antigravity/antigravity.types.d.ts +1 -0
  19. package/dist/adapters/agents/antigravity/antigravity.types.js.map +1 -1
  20. package/dist/adapters/agents/authentication.js +1 -0
  21. package/dist/adapters/agents/authentication.js.map +1 -1
  22. package/dist/adapters/agents/claude/claude-adapter.js +15 -0
  23. package/dist/adapters/agents/claude/claude-adapter.js.map +1 -1
  24. package/dist/adapters/agents/claude/claude-hook-plan.constants.d.ts +1 -0
  25. package/dist/adapters/agents/claude/claude-hook-plan.constants.js +20 -0
  26. package/dist/adapters/agents/claude/claude-hook-plan.constants.js.map +1 -0
  27. package/dist/adapters/agents/claude/claude-hook-plan.d.ts +4 -0
  28. package/dist/adapters/agents/claude/claude-hook-plan.js +60 -0
  29. package/dist/adapters/agents/claude/claude-hook-plan.js.map +1 -0
  30. package/dist/adapters/agents/claude/claude-hooks.constants.d.ts +3 -0
  31. package/dist/adapters/agents/claude/claude-hooks.constants.js +2968 -0
  32. package/dist/adapters/agents/claude/claude-hooks.constants.js.map +1 -0
  33. package/dist/adapters/agents/claude/claude-hooks.d.ts +2 -0
  34. package/dist/adapters/agents/claude/claude-hooks.js +6 -0
  35. package/dist/adapters/agents/claude/claude-hooks.js.map +1 -0
  36. package/dist/adapters/agents/claude/claude-hooks.types.d.ts +900 -0
  37. package/dist/adapters/agents/claude/claude-hooks.types.js +2 -0
  38. package/dist/adapters/agents/claude/claude-hooks.types.js.map +1 -0
  39. package/dist/adapters/agents/claude/claude-profile.d.ts +1 -0
  40. package/dist/adapters/agents/claude/claude-profile.js +23 -11
  41. package/dist/adapters/agents/claude/claude-profile.js.map +1 -1
  42. package/dist/adapters/agents/codex/codex-adapter.js +17 -1
  43. package/dist/adapters/agents/codex/codex-adapter.js.map +1 -1
  44. package/dist/adapters/agents/codex/codex-authentication.js +1 -0
  45. package/dist/adapters/agents/codex/codex-authentication.js.map +1 -1
  46. package/dist/adapters/agents/codex/codex-conversations.constants.d.ts +1 -0
  47. package/dist/adapters/agents/codex/codex-conversations.constants.js +2 -0
  48. package/dist/adapters/agents/codex/codex-conversations.constants.js.map +1 -0
  49. package/dist/adapters/agents/codex/codex-conversations.js +8 -5
  50. package/dist/adapters/agents/codex/codex-conversations.js.map +1 -1
  51. package/dist/adapters/agents/codex/codex-hook-plan.d.ts +3 -0
  52. package/dist/adapters/agents/codex/codex-hook-plan.js +72 -0
  53. package/dist/adapters/agents/codex/codex-hook-plan.js.map +1 -0
  54. package/dist/adapters/agents/codex/codex-hooks.constants.d.ts +3 -0
  55. package/dist/adapters/agents/codex/codex-hooks.constants.js +942 -0
  56. package/dist/adapters/agents/codex/codex-hooks.constants.js.map +1 -0
  57. package/dist/adapters/agents/codex/codex-hooks.d.ts +2 -0
  58. package/dist/adapters/agents/codex/codex-hooks.js +6 -0
  59. package/dist/adapters/agents/codex/codex-hooks.js.map +1 -0
  60. package/dist/adapters/agents/codex/codex-hooks.types.d.ts +255 -0
  61. package/dist/adapters/agents/codex/codex-hooks.types.js +2 -0
  62. package/dist/adapters/agents/codex/codex-hooks.types.js.map +1 -0
  63. package/dist/adapters/agents/codex/codex-provider.js +2 -2
  64. package/dist/adapters/agents/codex/codex-provider.js.map +1 -1
  65. package/dist/adapters/agents/copilot/copilot-adapter.js +14 -0
  66. package/dist/adapters/agents/copilot/copilot-adapter.js.map +1 -1
  67. package/dist/adapters/agents/copilot/copilot-hook-plan.d.ts +3 -0
  68. package/dist/adapters/agents/copilot/copilot-hook-plan.js +26 -0
  69. package/dist/adapters/agents/copilot/copilot-hook-plan.js.map +1 -0
  70. package/dist/adapters/agents/copilot/copilot-hooks.constants.d.ts +3 -0
  71. package/dist/adapters/agents/copilot/copilot-hooks.constants.js +528 -0
  72. package/dist/adapters/agents/copilot/copilot-hooks.constants.js.map +1 -0
  73. package/dist/adapters/agents/copilot/copilot-hooks.d.ts +2 -0
  74. package/dist/adapters/agents/copilot/copilot-hooks.js +6 -0
  75. package/dist/adapters/agents/copilot/copilot-hooks.js.map +1 -0
  76. package/dist/adapters/agents/copilot/copilot-hooks.types.d.ts +166 -0
  77. package/dist/adapters/agents/copilot/copilot-hooks.types.js +2 -0
  78. package/dist/adapters/agents/copilot/copilot-hooks.types.js.map +1 -0
  79. package/dist/adapters/agents/copilot/copilot.types.d.ts +1 -0
  80. package/dist/adapters/agents/copilot/copilot.types.js.map +1 -1
  81. package/dist/adapters/agents/hook-groups.d.ts +2 -0
  82. package/dist/adapters/agents/hook-groups.js +17 -0
  83. package/dist/adapters/agents/hook-groups.js.map +1 -0
  84. package/dist/adapters/agents/kimi/kimi-adapter.js +16 -1
  85. package/dist/adapters/agents/kimi/kimi-adapter.js.map +1 -1
  86. package/dist/adapters/agents/kimi/kimi-hook-plan.d.ts +3 -0
  87. package/dist/adapters/agents/kimi/kimi-hook-plan.js +33 -0
  88. package/dist/adapters/agents/kimi/kimi-hook-plan.js.map +1 -0
  89. package/dist/adapters/agents/kimi/kimi-hooks.constants.d.ts +3 -0
  90. package/dist/adapters/agents/kimi/kimi-hooks.constants.js +747 -0
  91. package/dist/adapters/agents/kimi/kimi-hooks.constants.js.map +1 -0
  92. package/dist/adapters/agents/kimi/kimi-hooks.d.ts +2 -0
  93. package/dist/adapters/agents/kimi/kimi-hooks.js +6 -0
  94. package/dist/adapters/agents/kimi/kimi-hooks.js.map +1 -0
  95. package/dist/adapters/agents/kimi/kimi-hooks.types.d.ts +226 -0
  96. package/dist/adapters/agents/kimi/kimi-hooks.types.js +2 -0
  97. package/dist/adapters/agents/kimi/kimi-hooks.types.js.map +1 -0
  98. package/dist/adapters/agents/kimi/kimi-request.js +2 -0
  99. package/dist/adapters/agents/kimi/kimi-request.js.map +1 -1
  100. package/dist/adapters/agents/kimi/kimi.constants.d.ts +1 -0
  101. package/dist/adapters/agents/kimi/kimi.constants.js +1 -0
  102. package/dist/adapters/agents/kimi/kimi.constants.js.map +1 -1
  103. package/dist/adapters/agents/kimi/kimi.types.d.ts +1 -0
  104. package/dist/adapters/agents/kimi/kimi.types.js.map +1 -1
  105. package/dist/adapters/agents/native-hooks.d.ts +4 -0
  106. package/dist/adapters/agents/native-hooks.js +63 -0
  107. package/dist/adapters/agents/native-hooks.js.map +1 -0
  108. package/dist/adapters/agents/native-hooks.types.d.ts +22 -0
  109. package/dist/adapters/agents/native-hooks.types.js +2 -0
  110. package/dist/adapters/agents/native-hooks.types.js.map +1 -0
  111. package/dist/adapters/agents/settings.types.d.ts +2 -0
  112. package/dist/adapters/agents/settings.types.js.map +1 -1
  113. package/dist/adapters/decisions/system-one-provider.constants.d.ts +1 -1
  114. package/dist/adapters/decisions/system-one-provider.constants.js +1 -1
  115. package/dist/adapters/decisions/system-one-provider.constants.js.map +1 -1
  116. package/dist/adapters/decisions/system-one-provider.js +8 -21
  117. package/dist/adapters/decisions/system-one-provider.js.map +1 -1
  118. package/dist/adapters/models/anthropic-model-provider.constants.d.ts +1 -0
  119. package/dist/adapters/models/anthropic-model-provider.constants.js +4 -0
  120. package/dist/adapters/models/anthropic-model-provider.constants.js.map +1 -1
  121. package/dist/adapters/models/anthropic-model-provider.js +7 -1
  122. package/dist/adapters/models/anthropic-model-provider.js.map +1 -1
  123. package/dist/adapters/models/http-failure.d.ts +3 -0
  124. package/dist/adapters/models/http-failure.js +43 -0
  125. package/dist/adapters/models/http-failure.js.map +1 -0
  126. package/dist/adapters/models/http-provider.js +14 -20
  127. package/dist/adapters/models/http-provider.js.map +1 -1
  128. package/dist/adapters/models/model-protocol.types.d.ts +1 -0
  129. package/dist/adapters/models/model-protocol.types.js.map +1 -1
  130. package/dist/adapters/models/model.constants.d.ts +2 -0
  131. package/dist/adapters/models/model.constants.js +17 -0
  132. package/dist/adapters/models/model.constants.js.map +1 -1
  133. package/dist/adapters/models/openai-chat-stream.js +3 -1
  134. package/dist/adapters/models/openai-chat-stream.js.map +1 -1
  135. package/dist/adapters/models/openai-responses.js +4 -0
  136. package/dist/adapters/models/openai-responses.js.map +1 -1
  137. package/dist/adapters/secrets/aws.js +5 -4
  138. package/dist/adapters/secrets/aws.js.map +1 -1
  139. package/dist/adapters/secrets/azure.constants.d.ts +1 -0
  140. package/dist/adapters/secrets/azure.constants.js +2 -0
  141. package/dist/adapters/secrets/azure.constants.js.map +1 -0
  142. package/dist/adapters/secrets/azure.js +2 -1
  143. package/dist/adapters/secrets/azure.js.map +1 -1
  144. package/dist/adapters/secrets/gcp.constants.d.ts +1 -0
  145. package/dist/adapters/secrets/gcp.constants.js +2 -0
  146. package/dist/adapters/secrets/gcp.constants.js.map +1 -0
  147. package/dist/adapters/secrets/gcp.js +11 -9
  148. package/dist/adapters/secrets/gcp.js.map +1 -1
  149. package/dist/adapters/secrets/infisical.js +3 -2
  150. package/dist/adapters/secrets/infisical.js.map +1 -1
  151. package/dist/adapters/secrets/onepassword.constants.d.ts +1 -0
  152. package/dist/adapters/secrets/onepassword.constants.js +2 -0
  153. package/dist/adapters/secrets/onepassword.constants.js.map +1 -0
  154. package/dist/adapters/secrets/onepassword.js +2 -1
  155. package/dist/adapters/secrets/onepassword.js.map +1 -1
  156. package/dist/adapters/secrets/secret-source.js +3 -1
  157. package/dist/adapters/secrets/secret-source.js.map +1 -1
  158. package/dist/adapters/secrets/vault-response.js +5 -5
  159. package/dist/adapters/secrets/vault-response.js.map +1 -1
  160. package/dist/adapters/secrets/vault.js +4 -3
  161. package/dist/adapters/secrets/vault.js.map +1 -1
  162. package/dist/adapters/testing/scripted-agent.d.ts +3 -1
  163. package/dist/adapters/testing/scripted-agent.js +3 -1
  164. package/dist/adapters/testing/scripted-agent.js.map +1 -1
  165. package/dist/adapters/tools/edit-tools.js +3 -3
  166. package/dist/adapters/tools/edit-tools.js.map +1 -1
  167. package/dist/adapters/tools/git-tools.js +16 -1
  168. package/dist/adapters/tools/git-tools.js.map +1 -1
  169. package/dist/adapters/tools/mcp-launcher.constants.d.ts +1 -1
  170. package/dist/adapters/tools/mcp-launcher.constants.js +29 -7
  171. package/dist/adapters/tools/mcp-launcher.constants.js.map +1 -1
  172. package/dist/adapters/tools/mcp-resources.js +5 -1
  173. package/dist/adapters/tools/mcp-resources.js.map +1 -1
  174. package/dist/adapters/tools/mcp.constants.d.ts +0 -6
  175. package/dist/adapters/tools/mcp.constants.js +0 -6
  176. package/dist/adapters/tools/mcp.constants.js.map +1 -1
  177. package/dist/adapters/tools/mcp.js +1 -0
  178. package/dist/adapters/tools/mcp.js.map +1 -1
  179. package/dist/adapters/tools/sandbox-files.constants.d.ts +1 -0
  180. package/dist/adapters/tools/sandbox-files.constants.js +17 -0
  181. package/dist/adapters/tools/sandbox-files.constants.js.map +1 -0
  182. package/dist/adapters/tools/sandbox-files.d.ts +1 -0
  183. package/dist/adapters/tools/sandbox-files.js +14 -1
  184. package/dist/adapters/tools/sandbox-files.js.map +1 -1
  185. package/dist/adapters/tools/tools.constants.js +1 -0
  186. package/dist/adapters/tools/tools.constants.js.map +1 -1
  187. package/dist/adapters/triggers/github-webhook.js +14 -11
  188. package/dist/adapters/triggers/github-webhook.js.map +1 -1
  189. package/dist/adapters/triggers/gitlab-webhook.js +16 -13
  190. package/dist/adapters/triggers/gitlab-webhook.js.map +1 -1
  191. package/dist/adapters/triggers/slack-request.js +10 -7
  192. package/dist/adapters/triggers/slack-request.js.map +1 -1
  193. package/dist/adapters/triggers/standard-webhook.js +10 -7
  194. package/dist/adapters/triggers/standard-webhook.js.map +1 -1
  195. package/dist/application/agent-authentication.js +4 -1
  196. package/dist/application/agent-authentication.js.map +1 -1
  197. package/dist/application/agent-turn.js +20 -5
  198. package/dist/application/agent-turn.js.map +1 -1
  199. package/dist/application/cli-hooks.constants.d.ts +2 -0
  200. package/dist/application/cli-hooks.constants.js +69 -0
  201. package/dist/application/cli-hooks.constants.js.map +1 -0
  202. package/dist/application/cli-hooks.d.ts +3 -0
  203. package/dist/application/cli-hooks.js +168 -0
  204. package/dist/application/cli-hooks.js.map +1 -0
  205. package/dist/application/cli-steering.js +33 -2
  206. package/dist/application/cli-steering.js.map +1 -1
  207. package/dist/application/custom-turn.js +10 -1
  208. package/dist/application/custom-turn.js.map +1 -1
  209. package/dist/application/diagnostic-probe.d.ts +1 -1
  210. package/dist/application/diagnostic-probe.js +7 -3
  211. package/dist/application/diagnostic-probe.js.map +1 -1
  212. package/dist/application/dispatch-observation.js +4 -0
  213. package/dist/application/dispatch-observation.js.map +1 -1
  214. package/dist/application/doctor-agent.d.ts +1 -1
  215. package/dist/application/doctor-agent.js +2 -2
  216. package/dist/application/doctor-agent.js.map +1 -1
  217. package/dist/application/doctor-deadline.d.ts +1 -0
  218. package/dist/application/doctor-deadline.js +10 -0
  219. package/dist/application/doctor-deadline.js.map +1 -0
  220. package/dist/application/doctor-image.js +9 -7
  221. package/dist/application/doctor-image.js.map +1 -1
  222. package/dist/application/doctor-sandbox.js +4 -4
  223. package/dist/application/doctor-sandbox.js.map +1 -1
  224. package/dist/application/doctor.constants.d.ts +2 -0
  225. package/dist/application/doctor.constants.js +2 -0
  226. package/dist/application/doctor.constants.js.map +1 -1
  227. package/dist/application/doctor.js +12 -8
  228. package/dist/application/doctor.js.map +1 -1
  229. package/dist/application/doctor.types.d.ts +2 -0
  230. package/dist/application/doctor.types.js.map +1 -1
  231. package/dist/application/file-sandbox.js +49 -11
  232. package/dist/application/file-sandbox.js.map +1 -1
  233. package/dist/application/harness-context.js +4 -2
  234. package/dist/application/harness-context.js.map +1 -1
  235. package/dist/application/harness-hook-transforms.d.ts +8 -0
  236. package/dist/application/harness-hook-transforms.js +115 -0
  237. package/dist/application/harness-hook-transforms.js.map +1 -0
  238. package/dist/application/harness-hooks.d.ts +5 -3
  239. package/dist/application/harness-hooks.js +37 -50
  240. package/dist/application/harness-hooks.js.map +1 -1
  241. package/dist/application/harness-loop.d.ts +2 -1
  242. package/dist/application/harness-loop.js +95 -21
  243. package/dist/application/harness-loop.js.map +1 -1
  244. package/dist/application/harness-subagent.d.ts +1 -1
  245. package/dist/application/harness-subagent.js +63 -12
  246. package/dist/application/harness-subagent.js.map +1 -1
  247. package/dist/application/harness.types.d.ts +3 -0
  248. package/dist/application/harness.types.js.map +1 -1
  249. package/dist/application/hook-invocation.d.ts +4 -0
  250. package/dist/application/hook-invocation.js +59 -0
  251. package/dist/application/hook-invocation.js.map +1 -0
  252. package/dist/application/queue-worker.js +51 -9
  253. package/dist/application/queue-worker.js.map +1 -1
  254. package/dist/application/queue-worker.types.d.ts +1 -0
  255. package/dist/application/queue-worker.types.js.map +1 -1
  256. package/dist/application/recipes/native-schemas.constants.js +1439 -218
  257. package/dist/application/recipes/native-schemas.constants.js.map +1 -1
  258. package/dist/application/recovery-inspection.js +4 -1
  259. package/dist/application/recovery-inspection.js.map +1 -1
  260. package/dist/application/remote-download.js +15 -5
  261. package/dist/application/remote-download.js.map +1 -1
  262. package/dist/application/remote-paths.d.ts +1 -0
  263. package/dist/application/remote-paths.js +7 -0
  264. package/dist/application/remote-paths.js.map +1 -0
  265. package/dist/application/remote-validation.js +40 -9
  266. package/dist/application/remote-validation.js.map +1 -1
  267. package/dist/application/remote-workspace.js +17 -2
  268. package/dist/application/remote-workspace.js.map +1 -1
  269. package/dist/application/repetition-watchdog.js +3 -1
  270. package/dist/application/repetition-watchdog.js.map +1 -1
  271. package/dist/application/sandbox-attach.js +38 -9
  272. package/dist/application/sandbox-attach.js.map +1 -1
  273. package/dist/application/sandbox-dispatch.js +7 -1
  274. package/dist/application/sandbox-dispatch.js.map +1 -1
  275. package/dist/application/schedules.js +2 -0
  276. package/dist/application/schedules.js.map +1 -1
  277. package/dist/application/secrets.js +4 -0
  278. package/dist/application/secrets.js.map +1 -1
  279. package/dist/application/tool-execution.js +28 -8
  280. package/dist/application/tool-execution.js.map +1 -1
  281. package/dist/application/transport-retention.js +3 -3
  282. package/dist/application/transport-retention.js.map +1 -1
  283. package/dist/application/workspace-fingerprint.d.ts +1 -0
  284. package/dist/application/workspace-fingerprint.js +19 -4
  285. package/dist/application/workspace-fingerprint.js.map +1 -1
  286. package/dist/cli/doctor-command.js +12 -2
  287. package/dist/cli/doctor-command.js.map +1 -1
  288. package/dist/cli/image.js +2 -0
  289. package/dist/cli/image.js.map +1 -1
  290. package/dist/cli/main.constants.d.ts +14 -2
  291. package/dist/cli/main.constants.js +27 -1
  292. package/dist/cli/main.constants.js.map +1 -1
  293. package/dist/cli/project-settings.js +7 -1
  294. package/dist/cli/project-settings.js.map +1 -1
  295. package/dist/cli/recipe-yaml.js +8 -0
  296. package/dist/cli/recipe-yaml.js.map +1 -1
  297. package/dist/cli/recovery-command.js +3 -0
  298. package/dist/cli/recovery-command.js.map +1 -1
  299. package/dist/cli/recovery-unlock-command.d.ts +2 -0
  300. package/dist/cli/recovery-unlock-command.js +19 -0
  301. package/dist/cli/recovery-unlock-command.js.map +1 -0
  302. package/dist/cli/scaffold-files.js +4 -1
  303. package/dist/cli/scaffold-files.js.map +1 -1
  304. package/dist/cli/scaffold-validation.js +3 -0
  305. package/dist/cli/scaffold-validation.js.map +1 -1
  306. package/dist/cli/scaffold.js +2 -0
  307. package/dist/cli/scaffold.js.map +1 -1
  308. package/dist/domain/agent-hook.types.d.ts +28 -0
  309. package/dist/domain/agent-hook.types.js +2 -0
  310. package/dist/domain/agent-hook.types.js.map +1 -0
  311. package/dist/domain/agent-profile-hooks.d.ts +2 -0
  312. package/dist/domain/agent-profile-hooks.js +52 -0
  313. package/dist/domain/agent-profile-hooks.js.map +1 -0
  314. package/dist/domain/agent-profile-permissions.js +11 -1
  315. package/dist/domain/agent-profile-permissions.js.map +1 -1
  316. package/dist/domain/agent-profile.constants.d.ts +1 -0
  317. package/dist/domain/agent-profile.constants.js +9 -0
  318. package/dist/domain/agent-profile.constants.js.map +1 -1
  319. package/dist/domain/agent-profile.js +6 -1
  320. package/dist/domain/agent-profile.js.map +1 -1
  321. package/dist/domain/agent-profile.types.d.ts +11 -0
  322. package/dist/domain/agent-profile.types.js.map +1 -1
  323. package/dist/domain/agent.types.d.ts +2 -0
  324. package/dist/domain/agent.types.js.map +1 -1
  325. package/dist/domain/container-image.d.ts +1 -0
  326. package/dist/domain/container-image.js +8 -0
  327. package/dist/domain/container-image.js.map +1 -0
  328. package/dist/domain/context.constants.d.ts +1 -0
  329. package/dist/domain/context.constants.js +1 -0
  330. package/dist/domain/context.constants.js.map +1 -1
  331. package/dist/domain/context.js +6 -1
  332. package/dist/domain/context.js.map +1 -1
  333. package/dist/domain/egress.js +6 -1
  334. package/dist/domain/egress.js.map +1 -1
  335. package/dist/domain/glob.js +1 -1
  336. package/dist/domain/glob.js.map +1 -1
  337. package/dist/domain/harness.js +4 -1
  338. package/dist/domain/harness.js.map +1 -1
  339. package/dist/domain/hook-command.d.ts +2 -0
  340. package/dist/domain/hook-command.js +26 -0
  341. package/dist/domain/hook-command.js.map +1 -0
  342. package/dist/domain/hook-command.types.d.ts +7 -0
  343. package/dist/domain/hook-command.types.js +2 -0
  344. package/dist/domain/hook-command.types.js.map +1 -0
  345. package/dist/domain/hook-decision.d.ts +2 -0
  346. package/dist/domain/hook-decision.js +38 -0
  347. package/dist/domain/hook-decision.js.map +1 -0
  348. package/dist/domain/hook.constants.d.ts +3 -0
  349. package/dist/domain/hook.constants.js +31 -1
  350. package/dist/domain/hook.constants.js.map +1 -1
  351. package/dist/domain/hook.js +49 -5
  352. package/dist/domain/hook.js.map +1 -1
  353. package/dist/domain/hook.types.d.ts +82 -5
  354. package/dist/domain/hook.types.js.map +1 -1
  355. package/dist/domain/mcp-server.constants.d.ts +6 -0
  356. package/dist/domain/mcp-server.constants.js +6 -0
  357. package/dist/domain/mcp-server.constants.js.map +1 -1
  358. package/dist/domain/mcp-server.js +1 -0
  359. package/dist/domain/mcp-server.js.map +1 -1
  360. package/dist/domain/permissions.types.d.ts +1 -0
  361. package/dist/domain/permissions.types.js.map +1 -1
  362. package/dist/domain/pricing.js +4 -2
  363. package/dist/domain/pricing.js.map +1 -1
  364. package/dist/domain/redaction.js +6 -3
  365. package/dist/domain/redaction.js.map +1 -1
  366. package/dist/domain/secret-fault.d.ts +4 -0
  367. package/dist/domain/secret-fault.js +11 -0
  368. package/dist/domain/secret-fault.js.map +1 -0
  369. package/dist/domain/secrets.js +3 -2
  370. package/dist/domain/secrets.js.map +1 -1
  371. package/dist/domain/steering.js +2 -0
  372. package/dist/domain/steering.js.map +1 -1
  373. package/dist/domain/steering.types.d.ts +1 -1
  374. package/dist/domain/steering.types.js.map +1 -1
  375. package/dist/domain/transport.js +5 -1
  376. package/dist/domain/transport.js.map +1 -1
  377. package/dist/domain/trigger-payload.d.ts +4 -0
  378. package/dist/domain/trigger-payload.js +15 -0
  379. package/dist/domain/trigger-payload.js.map +1 -0
  380. package/dist/domain/workflow/checkpoint.js +19 -2
  381. package/dist/domain/workflow/checkpoint.js.map +1 -1
  382. package/dist/domain/workflow/retry.constants.d.ts +1 -0
  383. package/dist/domain/workflow/retry.constants.js +1 -0
  384. package/dist/domain/workflow/retry.constants.js.map +1 -1
  385. package/dist/domain/workflow/retry.js +6 -2
  386. package/dist/domain/workflow/retry.js.map +1 -1
  387. package/dist/domain/workflow/task-runner.js +5 -3
  388. package/dist/domain/workflow/task-runner.js.map +1 -1
  389. package/dist/domain/workflow/workflow-state.js +2 -1
  390. package/dist/domain/workflow/workflow-state.js.map +1 -1
  391. package/dist/domain/workflow.types.d.ts +1 -0
  392. package/dist/domain/workflow.types.js.map +1 -1
  393. package/dist/index.d.ts +15 -1
  394. package/dist/index.js +6 -0
  395. package/dist/index.js.map +1 -1
  396. package/dist/infrastructure/conversations/transcript-store.js +32 -5
  397. package/dist/infrastructure/conversations/transcript-store.js.map +1 -1
  398. package/dist/infrastructure/files.d.ts +1 -0
  399. package/dist/infrastructure/files.js +8 -4
  400. package/dist/infrastructure/files.js.map +1 -1
  401. package/dist/infrastructure/git/integration-candidate.js +3 -2
  402. package/dist/infrastructure/git/integration-candidate.js.map +1 -1
  403. package/dist/infrastructure/git/lock-recovery.d.ts +3 -0
  404. package/dist/infrastructure/git/lock-recovery.js +58 -0
  405. package/dist/infrastructure/git/lock-recovery.js.map +1 -0
  406. package/dist/infrastructure/git/lock-recovery.types.d.ts +11 -0
  407. package/dist/infrastructure/git/lock-recovery.types.js +2 -0
  408. package/dist/infrastructure/git/lock-recovery.types.js.map +1 -0
  409. package/dist/infrastructure/git/managed-worktree.js +5 -8
  410. package/dist/infrastructure/git/managed-worktree.js.map +1 -1
  411. package/dist/infrastructure/git/verification-command.js +35 -30
  412. package/dist/infrastructure/git/verification-command.js.map +1 -1
  413. package/dist/infrastructure/git/workspace-lease.js +12 -5
  414. package/dist/infrastructure/git/workspace-lease.js.map +1 -1
  415. package/dist/infrastructure/hook-configuration.constants.d.ts +1 -0
  416. package/dist/infrastructure/hook-configuration.constants.js +59 -0
  417. package/dist/infrastructure/hook-configuration.constants.js.map +1 -0
  418. package/dist/infrastructure/hook-configuration.d.ts +3 -0
  419. package/dist/infrastructure/hook-configuration.js +16 -0
  420. package/dist/infrastructure/hook-configuration.js.map +1 -0
  421. package/dist/infrastructure/hook-configuration.types.d.ts +14 -0
  422. package/dist/infrastructure/hook-configuration.types.js +2 -0
  423. package/dist/infrastructure/hook-configuration.types.js.map +1 -0
  424. package/dist/infrastructure/http-transport.constants.d.ts +1 -0
  425. package/dist/infrastructure/http-transport.constants.js +14 -0
  426. package/dist/infrastructure/http-transport.constants.js.map +1 -0
  427. package/dist/infrastructure/http-transport.d.ts +7 -0
  428. package/dist/infrastructure/http-transport.js +19 -0
  429. package/dist/infrastructure/http-transport.js.map +1 -0
  430. package/dist/infrastructure/input-failure.d.ts +4 -0
  431. package/dist/infrastructure/input-failure.js +14 -0
  432. package/dist/infrastructure/input-failure.js.map +1 -0
  433. package/dist/infrastructure/inspection-file.d.ts +1 -0
  434. package/dist/infrastructure/inspection-file.js +8 -2
  435. package/dist/infrastructure/inspection-file.js.map +1 -1
  436. package/dist/infrastructure/local-transport.js +16 -11
  437. package/dist/infrastructure/local-transport.js.map +1 -1
  438. package/dist/infrastructure/process.constants.d.ts +1 -0
  439. package/dist/infrastructure/process.constants.js +1 -0
  440. package/dist/infrastructure/process.constants.js.map +1 -1
  441. package/dist/infrastructure/process.d.ts +1 -0
  442. package/dist/infrastructure/process.js +48 -8
  443. package/dist/infrastructure/process.js.map +1 -1
  444. package/dist/infrastructure/reservation-ledger.d.ts +2 -0
  445. package/dist/infrastructure/reservation-ledger.js +84 -0
  446. package/dist/infrastructure/reservation-ledger.js.map +1 -0
  447. package/dist/infrastructure/reservation-recovery.d.ts +4 -0
  448. package/dist/infrastructure/reservation-recovery.js +28 -0
  449. package/dist/infrastructure/reservation-recovery.js.map +1 -0
  450. package/dist/infrastructure/s3-tombstones.d.ts +3 -0
  451. package/dist/infrastructure/s3-tombstones.js +46 -0
  452. package/dist/infrastructure/s3-tombstones.js.map +1 -0
  453. package/dist/infrastructure/s3-tombstones.types.d.ts +6 -0
  454. package/dist/infrastructure/s3-tombstones.types.js +2 -0
  455. package/dist/infrastructure/s3-tombstones.types.js.map +1 -0
  456. package/dist/infrastructure/s3-transport.d.ts +2 -0
  457. package/dist/infrastructure/s3-transport.js +4 -2
  458. package/dist/infrastructure/s3-transport.js.map +1 -1
  459. package/dist/infrastructure/sse.js +6 -3
  460. package/dist/infrastructure/sse.js.map +1 -1
  461. package/dist/infrastructure/task-queue-bullmq-connection.d.ts +3 -0
  462. package/dist/infrastructure/task-queue-bullmq-connection.js +32 -0
  463. package/dist/infrastructure/task-queue-bullmq-connection.js.map +1 -0
  464. package/dist/infrastructure/task-queue-bullmq-connection.types.d.ts +8 -0
  465. package/dist/infrastructure/task-queue-bullmq-connection.types.js +2 -0
  466. package/dist/infrastructure/task-queue-bullmq-connection.types.js.map +1 -0
  467. package/dist/infrastructure/task-queue-bullmq-resources.js +21 -15
  468. package/dist/infrastructure/task-queue-bullmq-resources.js.map +1 -1
  469. package/dist/infrastructure/task-queue-bullmq-state.d.ts +1 -0
  470. package/dist/infrastructure/task-queue-bullmq-state.js +1 -0
  471. package/dist/infrastructure/task-queue-bullmq-state.js.map +1 -1
  472. package/dist/infrastructure/task-queue-bullmq.constants.d.ts +2 -1
  473. package/dist/infrastructure/task-queue-bullmq.constants.js +2 -1
  474. package/dist/infrastructure/task-queue-bullmq.constants.js.map +1 -1
  475. package/dist/infrastructure/task-queue-bullmq.js +10 -1
  476. package/dist/infrastructure/task-queue-bullmq.js.map +1 -1
  477. package/dist/infrastructure/task-queue.js +13 -4
  478. package/dist/infrastructure/task-queue.js.map +1 -1
  479. package/dist/infrastructure/transfer-copy.d.ts +1 -0
  480. package/dist/infrastructure/transfer-copy.js +16 -1
  481. package/dist/infrastructure/transfer-copy.js.map +1 -1
  482. package/dist/infrastructure/transport-archive.d.ts +3 -3
  483. package/dist/infrastructure/transport-archive.js +71 -48
  484. package/dist/infrastructure/transport-archive.js.map +1 -1
  485. package/dist/infrastructure/transport-archive.types.d.ts +3 -0
  486. package/dist/infrastructure/transport-archive.types.js.map +1 -1
  487. package/dist/infrastructure/transport-checkpoint.js +14 -4
  488. package/dist/infrastructure/transport-checkpoint.js.map +1 -1
  489. package/dist/infrastructure/transport-envelope.d.ts +1 -0
  490. package/dist/infrastructure/transport-envelope.js +22 -5
  491. package/dist/infrastructure/transport-envelope.js.map +1 -1
  492. package/dist/infrastructure/transport-reservations.constants.d.ts +2 -0
  493. package/dist/infrastructure/transport-reservations.constants.js +3 -0
  494. package/dist/infrastructure/transport-reservations.constants.js.map +1 -0
  495. package/dist/infrastructure/transport-reservations.d.ts +1 -2
  496. package/dist/infrastructure/transport-reservations.js +18 -22
  497. package/dist/infrastructure/transport-reservations.js.map +1 -1
  498. package/dist/infrastructure/transport-reservations.types.d.ts +23 -2
  499. package/dist/infrastructure/transport-reservations.types.js.map +1 -1
  500. package/dist/infrastructure/trigger-server.js +12 -9
  501. package/dist/infrastructure/trigger-server.js.map +1 -1
  502. package/dist/infrastructure/trigger-server.types.d.ts +1 -1
  503. package/dist/infrastructure/trigger-server.types.js.map +1 -1
  504. package/dist/infrastructure/workflow-checkpoint.constants.d.ts +1 -0
  505. package/dist/infrastructure/workflow-checkpoint.constants.js +1 -0
  506. package/dist/infrastructure/workflow-checkpoint.constants.js.map +1 -1
  507. package/dist/infrastructure/workspace-lock.constants.d.ts +2 -1
  508. package/dist/infrastructure/workspace-lock.constants.js +2 -1
  509. package/dist/infrastructure/workspace-lock.constants.js.map +1 -1
  510. package/dist/infrastructure/workspace-lock.js +48 -10
  511. package/dist/infrastructure/workspace-lock.js.map +1 -1
  512. package/dist/providers/cloud-cache.js +14 -9
  513. package/dist/providers/cloud-cache.js.map +1 -1
  514. package/dist/providers/cloud-cache.types.d.ts +1 -0
  515. package/dist/providers/cloud-cache.types.js.map +1 -1
  516. package/dist/providers/cloud-files.js +3 -4
  517. package/dist/providers/cloud-files.js.map +1 -1
  518. package/dist/providers/cloud-input.constants.d.ts +2 -2
  519. package/dist/providers/cloud-input.constants.js +2 -1
  520. package/dist/providers/cloud-input.constants.js.map +1 -1
  521. package/dist/providers/cloud-input.d.ts +2 -2
  522. package/dist/providers/cloud-input.js +14 -3
  523. package/dist/providers/cloud-input.js.map +1 -1
  524. package/dist/providers/container-command.js +30 -5
  525. package/dist/providers/container-command.js.map +1 -1
  526. package/dist/providers/container-egress.constants.d.ts +7 -0
  527. package/dist/providers/container-egress.constants.js +8 -0
  528. package/dist/providers/container-egress.constants.js.map +1 -0
  529. package/dist/providers/container-egress.d.ts +7 -0
  530. package/dist/providers/container-egress.js +101 -0
  531. package/dist/providers/container-egress.js.map +1 -0
  532. package/dist/providers/container-files.js +10 -11
  533. package/dist/providers/container-files.js.map +1 -1
  534. package/dist/providers/container-mounts.js +3 -0
  535. package/dist/providers/container-mounts.js.map +1 -1
  536. package/dist/providers/container-network.js +16 -1
  537. package/dist/providers/container-network.js.map +1 -1
  538. package/dist/providers/container-plan.js +7 -10
  539. package/dist/providers/container-plan.js.map +1 -1
  540. package/dist/providers/container-recovery.js +8 -3
  541. package/dist/providers/container-recovery.js.map +1 -1
  542. package/dist/providers/container.js +36 -5
  543. package/dist/providers/container.js.map +1 -1
  544. package/dist/providers/container.types.d.ts +1 -0
  545. package/dist/providers/container.types.js.map +1 -1
  546. package/dist/providers/daytona-command.constants.js +4 -1
  547. package/dist/providers/daytona-command.constants.js.map +1 -1
  548. package/dist/providers/daytona-command.js +39 -16
  549. package/dist/providers/daytona-command.js.map +1 -1
  550. package/dist/providers/daytona-files.js +5 -5
  551. package/dist/providers/daytona-files.js.map +1 -1
  552. package/dist/providers/daytona-output.js +11 -3
  553. package/dist/providers/daytona-output.js.map +1 -1
  554. package/dist/providers/daytona.js +11 -9
  555. package/dist/providers/daytona.js.map +1 -1
  556. package/dist/providers/egress/address.d.ts +3 -0
  557. package/dist/providers/egress/address.js +26 -0
  558. package/dist/providers/egress/address.js.map +1 -0
  559. package/dist/providers/egress/egress.constants.d.ts +22 -0
  560. package/dist/providers/egress/egress.constants.js +23 -0
  561. package/dist/providers/egress/egress.constants.js.map +1 -0
  562. package/dist/providers/egress/egress.types.d.ts +11 -0
  563. package/dist/providers/egress/egress.types.js +2 -0
  564. package/dist/providers/egress/egress.types.js.map +1 -0
  565. package/dist/providers/egress/firewall.d.ts +3 -0
  566. package/dist/providers/egress/firewall.js +29 -0
  567. package/dist/providers/egress/firewall.js.map +1 -0
  568. package/dist/providers/egress/main.d.ts +1 -0
  569. package/dist/providers/egress/main.js +90 -0
  570. package/dist/providers/egress/main.js.map +1 -0
  571. package/dist/providers/egress/policy.d.ts +5 -0
  572. package/dist/providers/egress/policy.js +54 -0
  573. package/dist/providers/egress/policy.js.map +1 -0
  574. package/dist/providers/egress/proxy.d.ts +2 -0
  575. package/dist/providers/egress/proxy.js +129 -0
  576. package/dist/providers/egress/proxy.js.map +1 -0
  577. package/dist/providers/egress/tls-hello.d.ts +1 -0
  578. package/dist/providers/egress/tls-hello.js +75 -0
  579. package/dist/providers/egress/tls-hello.js.map +1 -0
  580. package/dist/providers/firecracker-command.js +12 -6
  581. package/dist/providers/firecracker-command.js.map +1 -1
  582. package/dist/providers/local-files.d.ts +2 -0
  583. package/dist/providers/local-files.js +24 -0
  584. package/dist/providers/local-files.js.map +1 -0
  585. package/dist/providers/local.js +2 -20
  586. package/dist/providers/local.js.map +1 -1
  587. package/dist/providers/vercel-command.js +33 -9
  588. package/dist/providers/vercel-command.js.map +1 -1
  589. package/dist/providers/vercel.js +11 -9
  590. package/dist/providers/vercel.js.map +1 -1
  591. package/dist/testing.d.ts +1 -1
  592. package/dist/testing.js +1 -1
  593. package/dist/testing.js.map +1 -1
  594. package/package.json +2 -2
  595. package/recipe-configuration.schema.json +2164 -35
  596. package/recipe.schema.json +2512 -404
@@ -1 +1 @@
1
- {"version":3,"file":"github-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/github-webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKtE,OAAO,EACL,MAAM,EACN,gBAAgB,EAChB,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGjE,SAAS,aAAa,CAAC,OAA2B;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,UAAU,CACtD,mCAAmC,CACpC,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,OAAO,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACrE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CACjC,OAA6B;IAE7B,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,MAAM,CAAC,OAA2B,EAAE,GAAW;YACnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;gBACxC,CAAC,CAAC,SAAS,CAAC;YACd,IACE,CAAC,MAAM;gBACP,CAAC,gBAAgB,CAAC,MAAM,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAE5D,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxD,OAAO,YAAY,CAAC;gBAClB,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,CAAC;gBACtD,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC;gBAC/C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,OAAO;gBACP,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;aACxC,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { formBody, jsonBody, textBody } from \"./trigger-body.ts\";\nimport type { GithubWebhookOptions } from \"./triggers.types.ts\";\n\nfunction githubPayload(request: TriggerHttpRequest) {\n const form = request.headers[\"content-type\"]?.startsWith(\n \"application/x-www-form-urlencoded\",\n );\n if (!form) return jsonBody(textBody(request.body));\n const payload = formBody(request.body).get(\"payload\");\n if (payload === null) throw new Error(\"Missing GitHub form payload\");\n return jsonBody(payload);\n}\n\n/** Receive GitHub webhooks signed with `X-Hub-Signature-256`. */\nexport function createGithubWebhook(\n options: GithubWebhookOptions,\n): TriggerSource {\n const secrets = webhookSecret(options.secret, \"GitHub webhook\");\n return Object.freeze({\n name: \"github\",\n async verify(request: TriggerHttpRequest, now: number) {\n const signature = header(request.headers, \"x-hub-signature-256\");\n const digest = /^sha256=[0-9a-f]{64}$/i.test(signature)\n ? Buffer.from(signature.slice(7), \"hex\")\n : undefined;\n if (\n !digest ||\n !signatureMatches(await secrets(), [request.body], [digest])\n )\n throw new Error(\"GitHub signature mismatch\");\n const payload = githubPayload(request);\n const action = payloadString(payload, \"action\");\n const login = payloadString(payload, \"sender\", \"login\");\n return triggerEvent({\n source: \"github\",\n delivery: header(request.headers, \"x-github-delivery\"),\n kind: header(request.headers, \"x-github-event\"),\n ...(action ? { action } : {}),\n ...(login ? { actor: `github:${login}` } : {}),\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n },\n });\n}\n"]}
1
+ {"version":3,"file":"github-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/github-webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKtE,OAAO,EACL,MAAM,EACN,gBAAgB,EAChB,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGjE,SAAS,aAAa,CAAC,OAA2B;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,UAAU,CACtD,mCAAmC,CACpC,CAAC;IACF,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,OAAO,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACrE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CACjC,OAA6B;IAE7B,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,MAAM,CAAC,OAA2B,EAAE,GAAW;YACnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC;gBACrD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;gBACxC,CAAC,CAAC,SAAS,CAAC;YACd,IACE,CAAC,MAAM;gBACP,CAAC,gBAAgB,CAAC,MAAM,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAE5D,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,OAAO,oBAAoB,CAAC,GAAG,EAAE;gBAC/B,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;gBACvC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAChD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACxD,OAAO,YAAY,CAAC;oBAClB,MAAM,EAAE,QAAQ;oBAChB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,CAAC;oBACtD,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC;oBAC/C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9C,OAAO;oBACP,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;iBACxC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { decodeTriggerPayload } from \"../../domain/trigger-payload.ts\";\nimport { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { formBody, jsonBody, textBody } from \"./trigger-body.ts\";\nimport type { GithubWebhookOptions } from \"./triggers.types.ts\";\n\nfunction githubPayload(request: TriggerHttpRequest) {\n const form = request.headers[\"content-type\"]?.startsWith(\n \"application/x-www-form-urlencoded\",\n );\n if (!form) return jsonBody(textBody(request.body));\n const payload = formBody(request.body).get(\"payload\");\n if (payload === null) throw new Error(\"Missing GitHub form payload\");\n return jsonBody(payload);\n}\n\n/** Receive GitHub webhooks signed with `X-Hub-Signature-256`. */\nexport function createGithubWebhook(\n options: GithubWebhookOptions,\n): TriggerSource {\n const secrets = webhookSecret(options.secret, \"GitHub webhook\");\n return Object.freeze({\n name: \"github\",\n async verify(request: TriggerHttpRequest, now: number) {\n const signature = header(request.headers, \"x-hub-signature-256\");\n const digest = /^sha256=[0-9a-f]{64}$/i.test(signature)\n ? Buffer.from(signature.slice(7), \"hex\")\n : undefined;\n if (\n !digest ||\n !signatureMatches(await secrets(), [request.body], [digest])\n )\n throw new Error(\"GitHub signature mismatch\");\n return decodeTriggerPayload(() => {\n const payload = githubPayload(request);\n const action = payloadString(payload, \"action\");\n const login = payloadString(payload, \"sender\", \"login\");\n return triggerEvent({\n source: \"github\",\n delivery: header(request.headers, \"x-github-delivery\"),\n kind: header(request.headers, \"x-github-event\"),\n ...(action ? { action } : {}),\n ...(login ? { actor: `github:${login}` } : {}),\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n });\n },\n });\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { decodeTriggerPayload } from "../../domain/trigger-payload.js";
1
2
  import { triggerDefaultToleranceMs } from "../../domain/trigger.constants.js";
2
3
  import { payloadString, triggerEvent } from "../../domain/trigger.js";
3
4
  import { header, sameBytes, webhookSecret, } from "../../infrastructure/webhook-signature.js";
@@ -28,19 +29,21 @@ export function createGitlabWebhook(options) {
28
29
  name: "gitlab",
29
30
  async verify(request, now) {
30
31
  const id = await delivery(request, now);
31
- const payload = jsonBody(textBody(request.body));
32
- const action = payloadString(payload, "object_attributes", "action");
33
- const username = payloadString(payload, "user", "username") ??
34
- payloadString(payload, "user_username");
35
- return triggerEvent({
36
- source: "gitlab",
37
- delivery: id,
38
- kind: payloadString(payload, "object_kind") ??
39
- header(request.headers, "x-gitlab-event"),
40
- ...(action ? { action } : {}),
41
- ...(username ? { actor: `gitlab:${username}` } : {}),
42
- payload,
43
- receivedAt: new Date(now).toISOString(),
32
+ return decodeTriggerPayload(() => {
33
+ const payload = jsonBody(textBody(request.body));
34
+ const action = payloadString(payload, "object_attributes", "action");
35
+ const username = payloadString(payload, "user", "username") ??
36
+ payloadString(payload, "user_username");
37
+ return triggerEvent({
38
+ source: "gitlab",
39
+ delivery: id,
40
+ kind: payloadString(payload, "object_kind") ??
41
+ header(request.headers, "x-gitlab-event"),
42
+ ...(action ? { action } : {}),
43
+ ...(username ? { actor: `gitlab:${username}` } : {}),
44
+ payload,
45
+ receivedAt: new Date(now).toISOString(),
46
+ });
44
47
  });
45
48
  },
46
49
  });
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/gitlab-webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKtE,OAAO,EACL,MAAM,EACN,SAAS,EACT,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQpE,SAAS,cAAc,CAAC,OAA6B;IACnD,OAAO,gBAAgB,CACrB,OAAO,CAAC,YAAY,EACpB,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAA2B;IAChD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,EAAE;YACjC,OAAO,GAAG,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,OAAO,CAAC;QAC/D,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvD,OAAO,CACL,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAClC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAC/C,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CACjC,OAA6B;IAE7B,MAAM,QAAQ,GACZ,cAAc,IAAI,OAAO;QACvB,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC;QACzB,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,MAAM,CAAC,OAA2B,EAAE,GAAW;YACnD,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,QAAQ,GACZ,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC;gBAC1C,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAC1C,OAAO,YAAY,CAAC;gBAClB,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,EAAE;gBACZ,IAAI,EACF,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC;oBACrC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC;gBAC3C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,OAAO;gBACP,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;aACxC,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n sameBytes,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { standardVerifier } from \"./standard-webhook.ts\";\nimport { jsonBody, textBody, toleranceMs } from \"./trigger-body.ts\";\nimport type {\n DeliveryVerifier,\n GitlabSigningOptions,\n GitlabTokenOptions,\n GitlabWebhookOptions,\n} from \"./triggers.types.ts\";\n\nfunction signedDelivery(options: GitlabSigningOptions): DeliveryVerifier {\n return standardVerifier(\n options.signingToken,\n toleranceMs(options.toleranceMs, triggerDefaultToleranceMs),\n );\n}\n\nfunction tokenDelivery(options: GitlabTokenOptions): DeliveryVerifier {\n const secrets = webhookSecret(options.token, \"GitLab webhook\");\n return async (request) => {\n const supplied = Buffer.from(header(request.headers, \"x-gitlab-token\"));\n let matched = false;\n for (const token of await secrets())\n matched = sameBytes(supplied, Buffer.from(token)) || matched;\n if (!matched) throw new Error(\"GitLab token mismatch\");\n return (\n request.headers[\"idempotency-key\"] ??\n header(request.headers, \"x-gitlab-event-uuid\")\n );\n };\n}\n\n/** Receive GitLab webhooks, preferably verified with a signing token. */\nexport function createGitlabWebhook(\n options: GitlabWebhookOptions,\n): TriggerSource {\n const delivery =\n \"signingToken\" in options\n ? signedDelivery(options)\n : tokenDelivery(options);\n return Object.freeze({\n name: \"gitlab\",\n async verify(request: TriggerHttpRequest, now: number) {\n const id = await delivery(request, now);\n const payload = jsonBody(textBody(request.body));\n const action = payloadString(payload, \"object_attributes\", \"action\");\n const username =\n payloadString(payload, \"user\", \"username\") ??\n payloadString(payload, \"user_username\");\n return triggerEvent({\n source: \"gitlab\",\n delivery: id,\n kind:\n payloadString(payload, \"object_kind\") ??\n header(request.headers, \"x-gitlab-event\"),\n ...(action ? { action } : {}),\n ...(username ? { actor: `gitlab:${username}` } : {}),\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n },\n });\n}\n"]}
1
+ {"version":3,"file":"gitlab-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/gitlab-webhook.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodeTriggerPayload } from \"../../domain/trigger-payload.ts\";\nimport { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n sameBytes,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { standardVerifier } from \"./standard-webhook.ts\";\nimport { jsonBody, textBody, toleranceMs } from \"./trigger-body.ts\";\nimport type {\n DeliveryVerifier,\n GitlabSigningOptions,\n GitlabTokenOptions,\n GitlabWebhookOptions,\n} from \"./triggers.types.ts\";\n\nfunction signedDelivery(options: GitlabSigningOptions): DeliveryVerifier {\n return standardVerifier(\n options.signingToken,\n toleranceMs(options.toleranceMs, triggerDefaultToleranceMs),\n );\n}\n\nfunction tokenDelivery(options: GitlabTokenOptions): DeliveryVerifier {\n const secrets = webhookSecret(options.token, \"GitLab webhook\");\n return async (request) => {\n const supplied = Buffer.from(header(request.headers, \"x-gitlab-token\"));\n let matched = false;\n for (const token of await secrets())\n matched = sameBytes(supplied, Buffer.from(token)) || matched;\n if (!matched) throw new Error(\"GitLab token mismatch\");\n return (\n request.headers[\"idempotency-key\"] ??\n header(request.headers, \"x-gitlab-event-uuid\")\n );\n };\n}\n\n/** Receive GitLab webhooks, preferably verified with a signing token. */\nexport function createGitlabWebhook(\n options: GitlabWebhookOptions,\n): TriggerSource {\n const delivery =\n \"signingToken\" in options\n ? signedDelivery(options)\n : tokenDelivery(options);\n return Object.freeze({\n name: \"gitlab\",\n async verify(request: TriggerHttpRequest, now: number) {\n const id = await delivery(request, now);\n return decodeTriggerPayload(() => {\n const payload = jsonBody(textBody(request.body));\n const action = payloadString(payload, \"object_attributes\", \"action\");\n const username =\n payloadString(payload, \"user\", \"username\") ??\n payloadString(payload, \"user_username\");\n return triggerEvent({\n source: \"gitlab\",\n delivery: id,\n kind:\n payloadString(payload, \"object_kind\") ??\n header(request.headers, \"x-gitlab-event\"),\n ...(action ? { action } : {}),\n ...(username ? { actor: `gitlab:${username}` } : {}),\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n });\n },\n });\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { decodeTriggerPayload } from "../../domain/trigger-payload.js";
1
2
  import { triggerDefaultToleranceMs } from "../../domain/trigger.constants.js";
2
3
  import { payloadString, triggerEvent } from "../../domain/trigger.js";
3
4
  import { header, signatureMatches, timestampWithin, webhookSecret, } from "../../infrastructure/webhook-signature.js";
@@ -39,13 +40,15 @@ export function createSlackSource(options) {
39
40
  if (!digest ||
40
41
  !signatureMatches(await secrets(), [`v0:${timestamp}:`, request.body], [digest]))
41
42
  throw new Error("Slack signature mismatch");
42
- const { user, delivery, ...event } = slackPayload(request);
43
- return triggerEvent({
44
- source: "slack",
45
- ...event,
46
- delivery: delivery ?? "",
47
- ...(user ? { actor: `slack:${user}` } : {}),
48
- receivedAt: new Date(now).toISOString(),
43
+ return decodeTriggerPayload(() => {
44
+ const { user, delivery, ...event } = slackPayload(request);
45
+ return triggerEvent({
46
+ source: "slack",
47
+ ...event,
48
+ delivery: delivery ?? "",
49
+ ...(user ? { actor: `slack:${user}` } : {}),
50
+ receivedAt: new Date(now).toISOString(),
51
+ });
49
52
  });
50
53
  },
51
54
  /** Slack expects HTTP 200 within three seconds; an empty body sends no message. */
@@ -1 +1 @@
1
- {"version":3,"file":"slack-request.js","sourceRoot":"","sources":["../../../src/adapters/triggers/slack-request.ts"],"names":[],"mappings":"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","sourcesContent":["import { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n timestampWithin,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { formBody, jsonBody, toleranceMs } from \"./trigger-body.ts\";\nimport type { SlackRequestOptions } from \"./triggers.types.ts\";\n\nfunction slackPayload(request: TriggerHttpRequest) {\n const form = formBody(request.body);\n const interaction = form.get(\"payload\");\n if (interaction !== null) {\n const payload = jsonBody(interaction);\n return {\n payload,\n kind: payloadString(payload, \"type\") ?? \"interaction\",\n user: payloadString(payload, \"user\", \"id\"),\n delivery: payloadString(payload, \"trigger_id\"),\n };\n }\n const command = form.get(\"command\") ?? undefined;\n return {\n payload: Object.fromEntries(form),\n kind: \"command\",\n ...(command ? { action: command } : {}),\n user: form.get(\"user_id\") ?? undefined,\n delivery: form.get(\"trigger_id\") ?? undefined,\n };\n}\n\n/** Receive Slack slash commands and interactions signed with `X-Slack-Signature`. */\nexport function createSlackSource(options: SlackRequestOptions): TriggerSource {\n const secrets = webhookSecret(options.signingSecret, \"Slack\");\n const tolerance = toleranceMs(options.toleranceMs, triggerDefaultToleranceMs);\n return Object.freeze({\n name: \"slack\",\n async verify(request: TriggerHttpRequest, now: number) {\n const timestamp = header(request.headers, \"x-slack-request-timestamp\");\n timestampWithin(timestamp, now, tolerance);\n const signature = header(request.headers, \"x-slack-signature\");\n const digest = /^v0=[0-9a-f]{64}$/i.test(signature)\n ? Buffer.from(signature.slice(3), \"hex\")\n : undefined;\n if (\n !digest ||\n !signatureMatches(\n await secrets(),\n [`v0:${timestamp}:`, request.body],\n [digest],\n )\n )\n throw new Error(\"Slack signature mismatch\");\n const { user, delivery, ...event } = slackPayload(request);\n return triggerEvent({\n source: \"slack\",\n ...event,\n delivery: delivery ?? \"\",\n ...(user ? { actor: `slack:${user}` } : {}),\n receivedAt: new Date(now).toISOString(),\n });\n },\n /** Slack expects HTTP 200 within three seconds; an empty body sends no message. */\n reply: () => ({ status: 200 }),\n });\n}\n"]}
1
+ {"version":3,"file":"slack-request.js","sourceRoot":"","sources":["../../../src/adapters/triggers/slack-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKtE,OAAO,EACL,MAAM,EACN,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpE,SAAS,YAAY,CAAC,OAA2B;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QACtC,OAAO;YACL,OAAO;YACP,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,aAAa;YACrD,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;YAC1C,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,YAAY,CAAC;SAC/C,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;IACjD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;QACjC,IAAI,EAAE,SAAS;QACf,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,SAAS;QACtC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,SAAS;KAC9C,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,OAA4B;IAC5D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,yBAAyB,CAAC,CAAC;IAC9E,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,OAAO;QACb,KAAK,CAAC,MAAM,CAAC,OAA2B,EAAE,GAAW;YACnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;YACvE,eAAe,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;YAC3C,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC;gBACjD,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;gBACxC,CAAC,CAAC,SAAS,CAAC;YACd,IACE,CAAC,MAAM;gBACP,CAAC,gBAAgB,CACf,MAAM,OAAO,EAAE,EACf,CAAC,MAAM,SAAS,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,EAClC,CAAC,MAAM,CAAC,CACT;gBAED,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,OAAO,oBAAoB,CAAC,GAAG,EAAE;gBAC/B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;gBAC3D,OAAO,YAAY,CAAC;oBAClB,MAAM,EAAE,OAAO;oBACf,GAAG,KAAK;oBACR,QAAQ,EAAE,QAAQ,IAAI,EAAE;oBACxB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC3C,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;iBACxC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QACD,mFAAmF;QACnF,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;KAC/B,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { decodeTriggerPayload } from \"../../domain/trigger-payload.ts\";\nimport { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport { payloadString, triggerEvent } from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n timestampWithin,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { formBody, jsonBody, toleranceMs } from \"./trigger-body.ts\";\nimport type { SlackRequestOptions } from \"./triggers.types.ts\";\n\nfunction slackPayload(request: TriggerHttpRequest) {\n const form = formBody(request.body);\n const interaction = form.get(\"payload\");\n if (interaction !== null) {\n const payload = jsonBody(interaction);\n return {\n payload,\n kind: payloadString(payload, \"type\") ?? \"interaction\",\n user: payloadString(payload, \"user\", \"id\"),\n delivery: payloadString(payload, \"trigger_id\"),\n };\n }\n const command = form.get(\"command\") ?? undefined;\n return {\n payload: Object.fromEntries(form),\n kind: \"command\",\n ...(command ? { action: command } : {}),\n user: form.get(\"user_id\") ?? undefined,\n delivery: form.get(\"trigger_id\") ?? undefined,\n };\n}\n\n/** Receive Slack slash commands and interactions signed with `X-Slack-Signature`. */\nexport function createSlackSource(options: SlackRequestOptions): TriggerSource {\n const secrets = webhookSecret(options.signingSecret, \"Slack\");\n const tolerance = toleranceMs(options.toleranceMs, triggerDefaultToleranceMs);\n return Object.freeze({\n name: \"slack\",\n async verify(request: TriggerHttpRequest, now: number) {\n const timestamp = header(request.headers, \"x-slack-request-timestamp\");\n timestampWithin(timestamp, now, tolerance);\n const signature = header(request.headers, \"x-slack-signature\");\n const digest = /^v0=[0-9a-f]{64}$/i.test(signature)\n ? Buffer.from(signature.slice(3), \"hex\")\n : undefined;\n if (\n !digest ||\n !signatureMatches(\n await secrets(),\n [`v0:${timestamp}:`, request.body],\n [digest],\n )\n )\n throw new Error(\"Slack signature mismatch\");\n return decodeTriggerPayload(() => {\n const { user, delivery, ...event } = slackPayload(request);\n return triggerEvent({\n source: \"slack\",\n ...event,\n delivery: delivery ?? \"\",\n ...(user ? { actor: `slack:${user}` } : {}),\n receivedAt: new Date(now).toISOString(),\n });\n });\n },\n /** Slack expects HTTP 200 within three seconds; an empty body sends no message. */\n reply: () => ({ status: 200 }),\n });\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { decodeTriggerPayload } from "../../domain/trigger-payload.js";
1
2
  import { triggerDefaultToleranceMs } from "../../domain/trigger.constants.js";
2
3
  import { payloadString, triggerDelivery, triggerEvent, } from "../../domain/trigger.js";
3
4
  import { header, signatureMatches, timestampWithin, webhookSecret, } from "../../infrastructure/webhook-signature.js";
@@ -36,13 +37,15 @@ export function createStandardWebhook(options) {
36
37
  name: source,
37
38
  async verify(request, now) {
38
39
  const delivery = await verify(request, now);
39
- const payload = jsonBody(textBody(request.body));
40
- return triggerEvent({
41
- source,
42
- delivery,
43
- kind: payloadString(payload, "type") ?? "webhook",
44
- payload,
45
- receivedAt: new Date(now).toISOString(),
40
+ return decodeTriggerPayload(() => {
41
+ const payload = jsonBody(textBody(request.body));
42
+ return triggerEvent({
43
+ source,
44
+ delivery,
45
+ kind: payloadString(payload, "type") ?? "webhook",
46
+ payload,
47
+ receivedAt: new Date(now).toISOString(),
48
+ });
46
49
  });
47
50
  },
48
51
  });
@@ -1 +1 @@
1
- {"version":3,"file":"standard-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/standard-webhook.ts"],"names":[],"mappings":"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","sourcesContent":["import { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport {\n payloadString,\n triggerDelivery,\n triggerEvent,\n} from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSecret,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n timestampWithin,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { jsonBody, textBody, toleranceMs } from \"./trigger-body.ts\";\nimport type { StandardWebhookOptions } from \"./triggers.types.ts\";\n\nfunction signingKey(secret: string): Buffer {\n const key = secret.startsWith(\"whsec_\")\n ? Buffer.from(secret.slice(6), \"base64\")\n : Buffer.alloc(0);\n if (!key.length)\n throw new Error(\"Signing secrets must use the whsec_ format\");\n return key;\n}\n\n/** Verifies a Standard Webhooks signature and returns the message identifier. */\nexport function standardVerifier(secret: TriggerSecret, tolerance: number) {\n const secrets = webhookSecret(secret, \"Standard webhook\");\n return async (request: TriggerHttpRequest, now: number): Promise<string> => {\n const delivery = triggerDelivery(header(request.headers, \"webhook-id\"));\n const timestamp = header(request.headers, \"webhook-timestamp\");\n timestampWithin(timestamp, now, tolerance);\n const signatures = header(request.headers, \"webhook-signature\")\n .split(\" \")\n .filter((value) => value.startsWith(\"v1,\"))\n .map((value) => Buffer.from(value.slice(3), \"base64\"));\n const keys = (await secrets()).map(signingKey);\n if (\n !signatures.length ||\n !signatureMatches(\n keys,\n [`${delivery}.${timestamp}.`, request.body],\n signatures,\n )\n )\n throw new Error(\"Webhook signature mismatch\");\n return delivery;\n };\n}\n\n/** Receive webhooks signed with the Standard Webhooks scheme. */\nexport function createStandardWebhook(\n options: StandardWebhookOptions,\n): TriggerSource {\n const source = options.source ?? \"standard\";\n const verify = standardVerifier(\n options.secret,\n toleranceMs(options.toleranceMs, triggerDefaultToleranceMs),\n );\n return Object.freeze({\n name: source,\n async verify(request: TriggerHttpRequest, now: number) {\n const delivery = await verify(request, now);\n const payload = jsonBody(textBody(request.body));\n return triggerEvent({\n source,\n delivery,\n kind: payloadString(payload, \"type\") ?? \"webhook\",\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n },\n });\n}\n"]}
1
+ {"version":3,"file":"standard-webhook.js","sourceRoot":"","sources":["../../../src/adapters/triggers/standard-webhook.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodeTriggerPayload } from \"../../domain/trigger-payload.ts\";\nimport { triggerDefaultToleranceMs } from \"../../domain/trigger.constants.ts\";\nimport {\n payloadString,\n triggerDelivery,\n triggerEvent,\n} from \"../../domain/trigger.ts\";\nimport type {\n TriggerHttpRequest,\n TriggerSecret,\n TriggerSource,\n} from \"../../domain/trigger.types.ts\";\nimport {\n header,\n signatureMatches,\n timestampWithin,\n webhookSecret,\n} from \"../../infrastructure/webhook-signature.ts\";\nimport { jsonBody, textBody, toleranceMs } from \"./trigger-body.ts\";\nimport type { StandardWebhookOptions } from \"./triggers.types.ts\";\n\nfunction signingKey(secret: string): Buffer {\n const key = secret.startsWith(\"whsec_\")\n ? Buffer.from(secret.slice(6), \"base64\")\n : Buffer.alloc(0);\n if (!key.length)\n throw new Error(\"Signing secrets must use the whsec_ format\");\n return key;\n}\n\n/** Verifies a Standard Webhooks signature and returns the message identifier. */\nexport function standardVerifier(secret: TriggerSecret, tolerance: number) {\n const secrets = webhookSecret(secret, \"Standard webhook\");\n return async (request: TriggerHttpRequest, now: number): Promise<string> => {\n const delivery = triggerDelivery(header(request.headers, \"webhook-id\"));\n const timestamp = header(request.headers, \"webhook-timestamp\");\n timestampWithin(timestamp, now, tolerance);\n const signatures = header(request.headers, \"webhook-signature\")\n .split(\" \")\n .filter((value) => value.startsWith(\"v1,\"))\n .map((value) => Buffer.from(value.slice(3), \"base64\"));\n const keys = (await secrets()).map(signingKey);\n if (\n !signatures.length ||\n !signatureMatches(\n keys,\n [`${delivery}.${timestamp}.`, request.body],\n signatures,\n )\n )\n throw new Error(\"Webhook signature mismatch\");\n return delivery;\n };\n}\n\n/** Receive webhooks signed with the Standard Webhooks scheme. */\nexport function createStandardWebhook(\n options: StandardWebhookOptions,\n): TriggerSource {\n const source = options.source ?? \"standard\";\n const verify = standardVerifier(\n options.secret,\n toleranceMs(options.toleranceMs, triggerDefaultToleranceMs),\n );\n return Object.freeze({\n name: source,\n async verify(request: TriggerHttpRequest, now: number) {\n const delivery = await verify(request, now);\n return decodeTriggerPayload(() => {\n const payload = jsonBody(textBody(request.body));\n return triggerEvent({\n source,\n delivery,\n kind: payloadString(payload, \"type\") ?? \"webhook\",\n payload,\n receivedAt: new Date(now).toISOString(),\n });\n });\n },\n });\n}\n"]}
@@ -1,12 +1,15 @@
1
1
  import { readHostCredential } from "../infrastructure/host-credentials.js";
2
2
  import { requireSuccess } from "../infrastructure/process.js";
3
3
  import { credentialInstaller } from "./credential-installer.constants.js";
4
+ import { invariant } from "../domain/errors.js";
4
5
  export async function authenticateAgent(adapter, variables, lease, placement, signal) {
5
6
  const plan = adapter.credentials?.(variables);
6
7
  if (!plan)
7
8
  return {};
8
- if (placement === "host")
9
+ if (placement === "host") {
10
+ invariant(!plan.requiresSandbox, "This authentication mode requires a private sandbox home; use a sandbox provider or configure an explicit compatible model provider for local execution");
9
11
  return plan.variables;
12
+ }
10
13
  const files = [...plan.files];
11
14
  const derived = {};
12
15
  for (const credential of plan.host) {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-authentication.js","sourceRoot":"","sources":["../../src/application/agent-authentication.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAqB,EACrB,SAAoB,EACpB,KAAmB,EACnB,SAAuC,EACvC,MAAmB;IAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,SAAS,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC;IAChD,MAAM,KAAK,GAA0B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,MAAM,IAAI,UAAU,CAAC,WAAW;YAClC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;;YACxD,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM;QACd,MAAM,cAAc,CAClB;YACE,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;YAClD,MAAM;SACP,EACD,MAAM,CACP,CAAC;IACJ,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACrE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;QACjC,MAAM,cAAc,CAClB,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,WAAW,EAAE,EAAE,MAAM,EAAE,EACnE,MAAM,CACP,CAAC;IACJ,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import type {\n AgentAdapter,\n GeneratedCredential,\n} from \"../domain/agent.types.ts\";\nimport type { Variables } from \"../domain/command.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport { readHostCredential } from \"../infrastructure/host-credentials.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport { credentialInstaller } from \"./credential-installer.constants.ts\";\n\nexport async function authenticateAgent(\n adapter: AgentAdapter,\n variables: Variables,\n lease: SandboxLease,\n placement: SandboxProvider[\"placement\"],\n signal: AbortSignal,\n): Promise<Variables> {\n const plan = adapter.credentials?.(variables);\n if (!plan) return {};\n if (placement === \"host\") return plan.variables;\n const files: GeneratedCredential[] = [...plan.files];\n const derived: Record<string, string> = {};\n for (const credential of plan.host) {\n const content = await readHostCredential(credential);\n if (\"file\" in credential.destination)\n files.push({ path: credential.destination.file, content });\n else derived[credential.destination.variable] = content;\n }\n const invoke = lease.invoke.bind(lease);\n if (files.length)\n await requireSuccess(\n {\n executable: \"node\",\n arguments: [\"-e\", credentialInstaller],\n stdin: JSON.stringify({ home: lease.home, files }),\n signal,\n },\n invoke,\n );\n const credentials = Object.freeze({ ...plan.variables, ...derived });\n for (const command of plan.commands)\n await requireSuccess(\n { ...command, variables: { ...variables, ...credentials }, signal },\n invoke,\n );\n return credentials;\n}\n"]}
1
+ {"version":3,"file":"agent-authentication.js","sourceRoot":"","sources":["../../src/application/agent-authentication.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAqB,EACrB,SAAoB,EACpB,KAAmB,EACnB,SAAuC,EACvC,MAAmB;IAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzB,SAAS,CACP,CAAC,IAAI,CAAC,eAAe,EACrB,yJAAyJ,CAC1J,CAAC;QACF,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IACD,MAAM,KAAK,GAA0B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,MAAM,IAAI,UAAU,CAAC,WAAW;YAClC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;;YACxD,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM;QACd,MAAM,cAAc,CAClB;YACE,UAAU,EAAE,MAAM;YAClB,SAAS,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC;YACtC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;YAClD,MAAM;SACP,EACD,MAAM,CACP,CAAC;IACJ,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACrE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;QACjC,MAAM,cAAc,CAClB,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,GAAG,SAAS,EAAE,GAAG,WAAW,EAAE,EAAE,MAAM,EAAE,EACnE,MAAM,CACP,CAAC;IACJ,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import type {\n AgentAdapter,\n GeneratedCredential,\n} from \"../domain/agent.types.ts\";\nimport type { Variables } from \"../domain/command.types.ts\";\nimport type { SandboxLease, SandboxProvider } from \"../domain/sandbox.types.ts\";\nimport { readHostCredential } from \"../infrastructure/host-credentials.ts\";\nimport { requireSuccess } from \"../infrastructure/process.ts\";\nimport { credentialInstaller } from \"./credential-installer.constants.ts\";\nimport { invariant } from \"../domain/errors.ts\";\n\nexport async function authenticateAgent(\n adapter: AgentAdapter,\n variables: Variables,\n lease: SandboxLease,\n placement: SandboxProvider[\"placement\"],\n signal: AbortSignal,\n): Promise<Variables> {\n const plan = adapter.credentials?.(variables);\n if (!plan) return {};\n if (placement === \"host\") {\n invariant(\n !plan.requiresSandbox,\n \"This authentication mode requires a private sandbox home; use a sandbox provider or configure an explicit compatible model provider for local execution\",\n );\n return plan.variables;\n }\n const files: GeneratedCredential[] = [...plan.files];\n const derived: Record<string, string> = {};\n for (const credential of plan.host) {\n const content = await readHostCredential(credential);\n if (\"file\" in credential.destination)\n files.push({ path: credential.destination.file, content });\n else derived[credential.destination.variable] = content;\n }\n const invoke = lease.invoke.bind(lease);\n if (files.length)\n await requireSuccess(\n {\n executable: \"node\",\n arguments: [\"-e\", credentialInstaller],\n stdin: JSON.stringify({ home: lease.home, files }),\n signal,\n },\n invoke,\n );\n const credentials = Object.freeze({ ...plan.variables, ...derived });\n for (const command of plan.commands)\n await requireSuccess(\n { ...command, variables: { ...variables, ...credentials }, signal },\n invoke,\n );\n return credentials;\n}\n"]}
@@ -5,7 +5,7 @@ import { stopReason } from "./stop-reason.js";
5
5
  import { customTurn } from "./custom-turn.js";
6
6
  import { replayTurn } from "./replay-turn.js";
7
7
  import { cliSteering } from "./cli-steering.js";
8
- import { OutpostError } from "../domain/errors.js";
8
+ import { OutpostError, recordRecovery } from "../domain/errors.js";
9
9
  import { activityWatchdog } from "./activity-watchdog.js";
10
10
  import { agentOutput } from "./agent-output.js";
11
11
  import { agentFailure } from "./agent-failure.js";
@@ -13,6 +13,7 @@ import { agentConnectionFailurePattern, executionDefaults, } from "./execution.c
13
13
  import { steeringInterruption } from "./execution.constants.js";
14
14
  import { modelUsage } from "../domain/usage.js";
15
15
  import { notify } from "./observation.js";
16
+ import { openCliHooks } from "./cli-hooks.js";
16
17
  export async function turn(lease, agent, prompt, options, continuation, markers, pass, context) {
17
18
  if (agent.kind === "custom")
18
19
  return customTurn(lease, agent, prompt, options, pass, {
@@ -59,7 +60,12 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
59
60
  let status = 0;
60
61
  let interrupted = false;
61
62
  let commandCompleted = false;
63
+ let hooks;
64
+ let hookCleanupFailure;
65
+ let executionFailure;
62
66
  try {
67
+ if (agent.hooks?.handlers.length)
68
+ hooks = await openCliHooks(agent.hooks, lease, signal, (error) => controller.abort(error));
63
69
  if (agent.usage === "session")
64
70
  warnUsage(options, pass, `${agent.name}: token usage is collected after the command exits; use budget.attempts and time limits to bound execution before the final counters arrive`);
65
71
  if (agent.usage === "unavailable") {
@@ -88,7 +94,7 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
88
94
  });
89
95
  steering.start(request);
90
96
  const result = await lease.invoke({
91
- ...steering.command(command),
97
+ ...steering.command(hooks ? hooks.command(command) : command),
92
98
  signal,
93
99
  deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,
94
100
  observe(channel, chunk) {
@@ -108,9 +114,7 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
108
114
  commandCompleted = true;
109
115
  status = result.status;
110
116
  output.flush();
111
- if (controller.signal.reason instanceof OutpostError &&
112
- controller.signal.reason.code === "stuck")
113
- throw controller.signal.reason;
117
+ signal.throwIfAborted();
114
118
  if (status !== 0)
115
119
  throw new OutpostError("process", `Agent exited with status ${status}`, {
116
120
  ...result,
@@ -118,6 +122,7 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
118
122
  });
119
123
  }
120
124
  catch (cause) {
125
+ executionFailure = cause;
121
126
  const reason = stopReason(options.signal, controller.signal.reason, cause);
122
127
  if (reason)
123
128
  notify(options.observe, {
@@ -144,6 +149,14 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
144
149
  notify(options.warn, "Agent remained active after completion; its command was stopped and trailing output retained");
145
150
  }
146
151
  finally {
152
+ try {
153
+ await hooks?.close();
154
+ }
155
+ catch (error) {
156
+ hookCleanupFailure = error;
157
+ if (executionFailure)
158
+ recordRecovery(executionFailure, { hookCleanupError: error });
159
+ }
147
160
  steering.close();
148
161
  stderr.flush();
149
162
  watchdog.close();
@@ -156,6 +169,8 @@ export async function turn(lease, agent, prompt, options, continuation, markers,
156
169
  await collectAgentUsage(lease, agent, output, options, pass, commandCompleted);
157
170
  }
158
171
  options.signal?.throwIfAborted();
172
+ if (hookCleanupFailure)
173
+ throw hookCleanupFailure;
159
174
  let outcome;
160
175
  try {
161
176
  outcome = interrupted ? output.partial() : output.result();
@@ -1 +1 @@
1
- {"version":3,"file":"agent-turn.js","sourceRoot":"","sources":["../../src/application/agent-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n collectAgentUsage,\n prepareAgentUsage,\n warnUsage,\n} from \"./agent-usage.ts\";\nimport { agentRequest } from \"./agent-request.ts\";\nimport { boundedLines } from \"./output-lines.ts\";\nimport { stopReason } from \"./stop-reason.ts\";\nimport { customTurn } from \"./custom-turn.ts\";\nimport { replayTurn } from \"./replay-turn.ts\";\nimport type { Agent, AgentObservation } from \"../domain/agent.types.ts\";\nimport { cliSteering } from \"./cli-steering.ts\";\nimport { OutpostError } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { activityWatchdog } from \"./activity-watchdog.ts\";\nimport { agentOutput } from \"./agent-output.ts\";\nimport { agentFailure } from \"./agent-failure.ts\";\nimport {\n agentConnectionFailurePattern,\n executionDefaults,\n} from \"./execution.constants.ts\";\nimport type { DispatchOptions, Turn, TurnContext } from \"./execution.types.ts\";\nimport { steeringInterruption } from \"./execution.constants.ts\";\nimport { modelUsage } from \"../domain/usage.ts\";\nimport { notify } from \"./observation.ts\";\n\nexport async function turn(\n lease: SandboxLease,\n agent: Agent,\n prompt: string,\n options: DispatchOptions<unknown>,\n continuation: DispatchOptions[\"continuation\"],\n markers: readonly string[],\n pass: number,\n context: TurnContext,\n): Promise<Turn> {\n if (agent.kind === \"custom\")\n return customTurn(lease, agent, prompt, options, pass, {\n ...context,\n continuation,\n });\n if (agent.kind === \"replay\")\n return replayTurn(lease, agent, prompt, options, pass);\n const start = Date.now();\n const controller = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n let preparedConversation: string | undefined;\n const steering = cliSteering(agent, lease, options, pass, {\n conversation: () => output.conversation ?? preparedConversation,\n completed: () => output.completed,\n interrupt: () => controller.abort(steeringInterruption),\n });\n const watchdog = activityWatchdog(\n controller,\n options,\n pass,\n context.repetition,\n );\n const observe = (event: AgentObservation) => {\n steering.observe(event);\n notify(\n options.observe,\n event.kind === \"usage\" && options.prices\n ? {\n ...event,\n tokens: modelUsage(\n event.tokens,\n agent.model?.name,\n agent.usageInput !== \"uncached\",\n ),\n }\n : event,\n );\n watchdog.observe(event);\n };\n const output = agentOutput(agent, { ...options, observe }, markers, pass);\n const failure = agentFailure(agent, output);\n watchdog.refresh(false);\n const stderr = boundedLines((text, truncated) => {\n failure.observe(text);\n notify(options.observe, {\n kind: \"stderr\",\n text,\n truncated,\n pass,\n at: new Date().toISOString(),\n });\n });\n let status = 0;\n let interrupted = false;\n let commandCompleted = false;\n try {\n if (agent.usage === \"session\")\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is collected after the command exits; use budget.attempts and time limits to bound execution before the final counters arrive`,\n );\n if (agent.usage === \"unavailable\") {\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is unavailable; use budget.attempts and time limits`,\n );\n output.recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n }\n await prepareAgentUsage(lease, agent, output, continuation, signal);\n signal.throwIfAborted();\n const request = {\n text: prompt,\n ...(steering.liveInput ? { liveInput: true } : {}),\n ...(continuation ? { continuation } : {}),\n };\n const command = await agentRequest(\n agent,\n request,\n (command) =>\n lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n }),\n (id) => {\n preparedConversation = id;\n observe({\n kind: \"conversation\",\n id,\n pass,\n at: new Date().toISOString(),\n });\n },\n );\n steering.start(request);\n const result = await lease.invoke({\n ...steering.command(command),\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n observe(channel, chunk) {\n if (channel === \"stdout\") {\n try {\n output.append(chunk);\n } catch (cause) {\n controller.abort(cause);\n }\n }\n if (channel === \"stderr\") stderr.append(chunk);\n watchdog.refresh(output.completed);\n },\n });\n commandCompleted = true;\n status = result.status;\n output.flush();\n if (\n controller.signal.reason instanceof OutpostError &&\n controller.signal.reason.code === \"stuck\"\n )\n throw controller.signal.reason;\n if (status !== 0)\n throw new OutpostError(\"process\", `Agent exited with status ${status}`, {\n ...result,\n conversation: output.conversation ?? preparedConversation,\n });\n } catch (cause) {\n const reason = stopReason(options.signal, controller.signal.reason, cause);\n if (reason)\n notify(options.observe, {\n kind: \"stopped\",\n reason,\n pass,\n at: new Date().toISOString(),\n });\n options.signal?.throwIfAborted();\n interrupted = controller.signal.reason === steeringInterruption;\n if (controller.signal.reason !== \"completion\" && !interrupted) {\n const error =\n controller.signal.reason instanceof OutpostError\n ? controller.signal.reason\n : cause;\n if (\n error instanceof OutpostError &&\n error.code === \"timeout\" &&\n output.failure &&\n agentConnectionFailurePattern.test(output.failure)\n )\n throw failure.connection(error);\n stderr.flush();\n throw failure.classify(error);\n }\n if (!interrupted)\n notify(\n options.warn,\n \"Agent remained active after completion; its command was stopped and trailing output retained\",\n );\n } finally {\n steering.close();\n stderr.flush();\n watchdog.close();\n try {\n output.flush();\n } catch {\n commandCompleted = false;\n }\n await collectAgentUsage(\n lease,\n agent,\n output,\n options,\n pass,\n commandCompleted,\n );\n }\n options.signal?.throwIfAborted();\n let outcome: ReturnType<typeof output.result>;\n try {\n outcome = interrupted ? output.partial() : output.result();\n } catch (error) {\n throw failure.classify(error);\n }\n return {\n ...(preparedConversation ? { conversation: preparedConversation } : {}),\n ...outcome,\n ...(options.prices\n ? {\n usage: modelUsage(\n outcome.usage,\n agent.model?.name,\n agent.usageInput !== \"uncached\",\n ),\n }\n : {}),\n status,\n ...(interrupted ? { interrupted: \"steering\" as const } : {}),\n durationMs: Date.now() - start,\n };\n}\n"]}
1
+ {"version":3,"file":"agent-turn.js","sourceRoot":"","sources":["../../src/application/agent-turn.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n collectAgentUsage,\n prepareAgentUsage,\n warnUsage,\n} from \"./agent-usage.ts\";\nimport { agentRequest } from \"./agent-request.ts\";\nimport { boundedLines } from \"./output-lines.ts\";\nimport { stopReason } from \"./stop-reason.ts\";\nimport { customTurn } from \"./custom-turn.ts\";\nimport { replayTurn } from \"./replay-turn.ts\";\nimport type { Agent, AgentObservation } from \"../domain/agent.types.ts\";\nimport { cliSteering } from \"./cli-steering.ts\";\nimport { OutpostError, recordRecovery } from \"../domain/errors.ts\";\nimport type { SandboxLease } from \"../domain/sandbox.types.ts\";\nimport { activityWatchdog } from \"./activity-watchdog.ts\";\nimport { agentOutput } from \"./agent-output.ts\";\nimport { agentFailure } from \"./agent-failure.ts\";\nimport {\n agentConnectionFailurePattern,\n executionDefaults,\n} from \"./execution.constants.ts\";\nimport type { DispatchOptions, Turn, TurnContext } from \"./execution.types.ts\";\nimport { steeringInterruption } from \"./execution.constants.ts\";\nimport { modelUsage } from \"../domain/usage.ts\";\nimport { notify } from \"./observation.ts\";\nimport { openCliHooks } from \"./cli-hooks.ts\";\nimport type { AgentHookInstallation } from \"../domain/agent-hook.types.ts\";\n\nexport async function turn(\n lease: SandboxLease,\n agent: Agent,\n prompt: string,\n options: DispatchOptions<unknown>,\n continuation: DispatchOptions[\"continuation\"],\n markers: readonly string[],\n pass: number,\n context: TurnContext,\n): Promise<Turn> {\n if (agent.kind === \"custom\")\n return customTurn(lease, agent, prompt, options, pass, {\n ...context,\n continuation,\n });\n if (agent.kind === \"replay\")\n return replayTurn(lease, agent, prompt, options, pass);\n const start = Date.now();\n const controller = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([options.signal, controller.signal])\n : controller.signal;\n let preparedConversation: string | undefined;\n const steering = cliSteering(agent, lease, options, pass, {\n conversation: () => output.conversation ?? preparedConversation,\n completed: () => output.completed,\n interrupt: () => controller.abort(steeringInterruption),\n });\n const watchdog = activityWatchdog(\n controller,\n options,\n pass,\n context.repetition,\n );\n const observe = (event: AgentObservation) => {\n steering.observe(event);\n notify(\n options.observe,\n event.kind === \"usage\" && options.prices\n ? {\n ...event,\n tokens: modelUsage(\n event.tokens,\n agent.model?.name,\n agent.usageInput !== \"uncached\",\n ),\n }\n : event,\n );\n watchdog.observe(event);\n };\n const output = agentOutput(agent, { ...options, observe }, markers, pass);\n const failure = agentFailure(agent, output);\n watchdog.refresh(false);\n const stderr = boundedLines((text, truncated) => {\n failure.observe(text);\n notify(options.observe, {\n kind: \"stderr\",\n text,\n truncated,\n pass,\n at: new Date().toISOString(),\n });\n });\n let status = 0;\n let interrupted = false;\n let commandCompleted = false;\n let hooks: AgentHookInstallation | undefined;\n let hookCleanupFailure: unknown;\n let executionFailure: unknown;\n try {\n if (agent.hooks?.handlers.length)\n hooks = await openCliHooks(agent.hooks, lease, signal, (error) =>\n controller.abort(error),\n );\n if (agent.usage === \"session\")\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is collected after the command exits; use budget.attempts and time limits to bound execution before the final counters arrive`,\n );\n if (agent.usage === \"unavailable\") {\n warnUsage(\n options,\n pass,\n `${agent.name}: token usage is unavailable; use budget.attempts and time limits`,\n );\n output.recordUsage({ input: 0, cached: 0, output: 0, complete: false });\n }\n await prepareAgentUsage(lease, agent, output, continuation, signal);\n signal.throwIfAborted();\n const request = {\n text: prompt,\n ...(steering.liveInput ? { liveInput: true } : {}),\n ...(continuation ? { continuation } : {}),\n };\n const command = await agentRequest(\n agent,\n request,\n (command) =>\n lease.invoke({\n ...command,\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n }),\n (id) => {\n preparedConversation = id;\n observe({\n kind: \"conversation\",\n id,\n pass,\n at: new Date().toISOString(),\n });\n },\n );\n steering.start(request);\n const result = await lease.invoke({\n ...steering.command(hooks ? hooks.command(command) : command),\n signal,\n deadlineMs: options.deadlineMs ?? executionDefaults.deadlineMs,\n observe(channel, chunk) {\n if (channel === \"stdout\") {\n try {\n output.append(chunk);\n } catch (cause) {\n controller.abort(cause);\n }\n }\n if (channel === \"stderr\") stderr.append(chunk);\n watchdog.refresh(output.completed);\n },\n });\n commandCompleted = true;\n status = result.status;\n output.flush();\n signal.throwIfAborted();\n if (status !== 0)\n throw new OutpostError(\"process\", `Agent exited with status ${status}`, {\n ...result,\n conversation: output.conversation ?? preparedConversation,\n });\n } catch (cause) {\n executionFailure = cause;\n const reason = stopReason(options.signal, controller.signal.reason, cause);\n if (reason)\n notify(options.observe, {\n kind: \"stopped\",\n reason,\n pass,\n at: new Date().toISOString(),\n });\n options.signal?.throwIfAborted();\n interrupted = controller.signal.reason === steeringInterruption;\n if (controller.signal.reason !== \"completion\" && !interrupted) {\n const error =\n controller.signal.reason instanceof OutpostError\n ? controller.signal.reason\n : cause;\n if (\n error instanceof OutpostError &&\n error.code === \"timeout\" &&\n output.failure &&\n agentConnectionFailurePattern.test(output.failure)\n )\n throw failure.connection(error);\n stderr.flush();\n throw failure.classify(error);\n }\n if (!interrupted)\n notify(\n options.warn,\n \"Agent remained active after completion; its command was stopped and trailing output retained\",\n );\n } finally {\n try {\n await hooks?.close();\n } catch (error) {\n hookCleanupFailure = error;\n if (executionFailure)\n recordRecovery(executionFailure, { hookCleanupError: error });\n }\n steering.close();\n stderr.flush();\n watchdog.close();\n try {\n output.flush();\n } catch {\n commandCompleted = false;\n }\n await collectAgentUsage(\n lease,\n agent,\n output,\n options,\n pass,\n commandCompleted,\n );\n }\n options.signal?.throwIfAborted();\n if (hookCleanupFailure) throw hookCleanupFailure;\n let outcome: ReturnType<typeof output.result>;\n try {\n outcome = interrupted ? output.partial() : output.result();\n } catch (error) {\n throw failure.classify(error);\n }\n return {\n ...(preparedConversation ? { conversation: preparedConversation } : {}),\n ...outcome,\n ...(options.prices\n ? {\n usage: modelUsage(\n outcome.usage,\n agent.model?.name,\n agent.usageInput !== \"uncached\",\n ),\n }\n : {}),\n status,\n ...(interrupted ? { interrupted: \"steering\" as const } : {}),\n durationMs: Date.now() - start,\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const hookBridgeScript: string;
2
+ export declare const hookClientScript: string;
@@ -0,0 +1,69 @@
1
+ export const hookBridgeScript = String.raw `
2
+ const http = require('node:http');
3
+ const readline = require('node:readline');
4
+ const max = 1048576;
5
+ const pending = new Map();
6
+ let sequence = 0;
7
+ const server = http.createServer((request, response) => {
8
+ if (request.method !== 'POST' || request.headers.authorization !== process.env.OUTPOST_HOOK_BRIDGE_TOKEN) { response.writeHead(403); response.end(); return; }
9
+ if (pending.size >= 32) { response.writeHead(429); response.end(); return; }
10
+ let body = ''; let oversized = false;
11
+ request.setEncoding('utf8');
12
+ request.on('data', chunk => { body += chunk; if (Buffer.byteLength(body) > max) { oversized = true; request.destroy(); } });
13
+ request.on('end', () => {
14
+ if (oversized) return;
15
+ try {
16
+ const value = JSON.parse(body);
17
+ const id = ++sequence;
18
+ pending.set(id, response);
19
+ response.on('close', () => pending.delete(id));
20
+ process.stdout.write(JSON.stringify({ id, hook: value.hook, event: value.event }) + '\n');
21
+ } catch { response.writeHead(400); response.end(); }
22
+ });
23
+ });
24
+ const lines = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
25
+ lines.on('line', line => {
26
+ try { const value = JSON.parse(line); const response = pending.get(value.id); if (response) { pending.delete(value.id); response.end(JSON.stringify(value)); } }
27
+ catch { process.exitCode = 1; lines.close(); }
28
+ });
29
+ lines.on('close', () => {
30
+ for (const response of pending.values()) { response.writeHead(503); response.end(); }
31
+ server.close(); server.closeAllConnections();
32
+ });
33
+ server.listen(0, '127.0.0.1', () => process.stdout.write(JSON.stringify({ port: server.address().port }) + '\n'));
34
+ `;
35
+ export const hookClientScript = String.raw `
36
+ const http = require('node:http');
37
+ const { spawn } = require('node:child_process');
38
+ const config = JSON.parse(Buffer.from(process.argv[1], 'base64').toString());
39
+ const connection = process.env[config.variable];
40
+ if (!connection) process.exit(0);
41
+ let input = ''; const max = 1048576;
42
+ process.stdin.setEncoding('utf8');
43
+ process.stdin.on('data', chunk => { input += chunk; if (Buffer.byteLength(input) > max) { console.error('Hook input exceeds its size limit'); process.exit(2); } });
44
+ process.stdin.on('end', () => {
45
+ if (config.command) {
46
+ const command = config.command;
47
+ const child = spawn(command.executable, command.arguments || [], { cwd: command.directory || process.cwd(), env: { ...process.env, ...command.variables }, stdio: ['pipe', 'inherit', 'inherit'] });
48
+ child.on('error', () => { console.error('Cannot start hook command'); process.exitCode = 2; });
49
+ child.stdin.on('error', () => {}); child.stdin.end(input);
50
+ child.on('exit', (code, signal) => { process.exitCode = code === null ? 2 : code; });
51
+ return;
52
+ }
53
+ let event;
54
+ try { event = JSON.parse(input); } catch { console.error('Invalid hook input'); process.exitCode = 2; return; }
55
+ const { port, token } = JSON.parse(connection);
56
+ const request = http.request({ host: '127.0.0.1', port, method: 'POST', headers: { authorization: token, 'content-type': 'application/json' } }, response => {
57
+ let output = ''; response.setEncoding('utf8');
58
+ response.on('data', chunk => { output += chunk; if (Buffer.byteLength(output) > max * 2) request.destroy(new Error('Hook response too large')); });
59
+ response.on('end', () => {
60
+ try { if (response.statusCode !== 200) throw new Error('Hook bridge unavailable'); const value = JSON.parse(output); if (value.error) throw new Error(value.error); process.stdout.write(value.output || ''); }
61
+ catch (error) { console.error(error.message); process.exitCode = 2; }
62
+ });
63
+ });
64
+ request.setTimeout(config.timeoutMs, () => request.destroy(new Error('Hook bridge timed out')));
65
+ request.on('error', error => { console.error(error.message); process.exitCode = 2; });
66
+ request.end(JSON.stringify({ hook: config.index, event }));
67
+ });
68
+ `;
69
+ //# sourceMappingURL=cli-hooks.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-hooks.constants.js","sourceRoot":"","sources":["../../src/application/cli-hooks.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzC,CAAC","sourcesContent":["export const hookBridgeScript = String.raw`\nconst http = require('node:http');\nconst readline = require('node:readline');\nconst max = 1048576;\nconst pending = new Map();\nlet sequence = 0;\nconst server = http.createServer((request, response) => {\n if (request.method !== 'POST' || request.headers.authorization !== process.env.OUTPOST_HOOK_BRIDGE_TOKEN) { response.writeHead(403); response.end(); return; }\n if (pending.size >= 32) { response.writeHead(429); response.end(); return; }\n let body = ''; let oversized = false;\n request.setEncoding('utf8');\n request.on('data', chunk => { body += chunk; if (Buffer.byteLength(body) > max) { oversized = true; request.destroy(); } });\n request.on('end', () => {\n if (oversized) return;\n try {\n const value = JSON.parse(body);\n const id = ++sequence;\n pending.set(id, response);\n response.on('close', () => pending.delete(id));\n process.stdout.write(JSON.stringify({ id, hook: value.hook, event: value.event }) + '\\n');\n } catch { response.writeHead(400); response.end(); }\n });\n});\nconst lines = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });\nlines.on('line', line => {\n try { const value = JSON.parse(line); const response = pending.get(value.id); if (response) { pending.delete(value.id); response.end(JSON.stringify(value)); } }\n catch { process.exitCode = 1; lines.close(); }\n});\nlines.on('close', () => {\n for (const response of pending.values()) { response.writeHead(503); response.end(); }\n server.close(); server.closeAllConnections();\n});\nserver.listen(0, '127.0.0.1', () => process.stdout.write(JSON.stringify({ port: server.address().port }) + '\\n'));\n`;\n\nexport const hookClientScript = String.raw`\nconst http = require('node:http');\nconst { spawn } = require('node:child_process');\nconst config = JSON.parse(Buffer.from(process.argv[1], 'base64').toString());\nconst connection = process.env[config.variable];\nif (!connection) process.exit(0);\nlet input = ''; const max = 1048576;\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', chunk => { input += chunk; if (Buffer.byteLength(input) > max) { console.error('Hook input exceeds its size limit'); process.exit(2); } });\nprocess.stdin.on('end', () => {\n if (config.command) {\n const command = config.command;\n const child = spawn(command.executable, command.arguments || [], { cwd: command.directory || process.cwd(), env: { ...process.env, ...command.variables }, stdio: ['pipe', 'inherit', 'inherit'] });\n child.on('error', () => { console.error('Cannot start hook command'); process.exitCode = 2; });\n child.stdin.on('error', () => {}); child.stdin.end(input);\n child.on('exit', (code, signal) => { process.exitCode = code === null ? 2 : code; });\n return;\n }\n let event;\n try { event = JSON.parse(input); } catch { console.error('Invalid hook input'); process.exitCode = 2; return; }\n const { port, token } = JSON.parse(connection);\n const request = http.request({ host: '127.0.0.1', port, method: 'POST', headers: { authorization: token, 'content-type': 'application/json' } }, response => {\n let output = ''; response.setEncoding('utf8');\n response.on('data', chunk => { output += chunk; if (Buffer.byteLength(output) > max * 2) request.destroy(new Error('Hook response too large')); });\n response.on('end', () => {\n try { if (response.statusCode !== 200) throw new Error('Hook bridge unavailable'); const value = JSON.parse(output); if (value.error) throw new Error(value.error); process.stdout.write(value.output || ''); }\n catch (error) { console.error(error.message); process.exitCode = 2; }\n });\n });\n request.setTimeout(config.timeoutMs, () => request.destroy(new Error('Hook bridge timed out')));\n request.on('error', error => { console.error(error.message); process.exitCode = 2; });\n request.end(JSON.stringify({ hook: config.index, event }));\n});\n`;\n"]}
@@ -0,0 +1,3 @@
1
+ import type { AgentHookInstallation, AgentHookPlan } from "../domain/agent-hook.types.ts";
2
+ import type { SandboxLease } from "../domain/sandbox.types.ts";
3
+ export declare function openCliHooks(plan: AgentHookPlan, sandbox: SandboxLease, signal: AbortSignal, fail: (error: unknown) => void): Promise<AgentHookInstallation>;