@humwick/server 0.130.1 → 0.130.2

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 (437) hide show
  1. package/README.md +5 -0
  2. package/docs/guides/tools-administration.md +4 -0
  3. package/docs/guides/tools-coordination.md +1 -0
  4. package/docs/guides/tools-tasks.md +8 -0
  5. package/docs/guides/workflows.md +58 -0
  6. package/docs/openapi.json +414 -1
  7. package/package.json +8 -17
  8. package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
  9. package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
  10. package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
  11. package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
  12. package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
  13. package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
  14. package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
  15. package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
  16. package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
  17. package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
  18. package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
  19. package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
  20. package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
  21. package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
  22. package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
  23. package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
  24. package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
  25. package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
  26. package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
  27. package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
  28. package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
  29. package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
  30. package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
  31. package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
  32. package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
  33. package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
  34. package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
  35. package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
  36. package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
  37. package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
  38. package/public/assets/{fleet-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
  39. package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
  40. package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
  41. package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
  42. package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
  43. package/public/assets/index-CRHep3M9.js +15 -0
  44. package/public/assets/index-MYAIwYTX.css +2 -0
  45. package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
  46. package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
  47. package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
  48. package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
  49. package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
  50. package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
  51. package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
  52. package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
  53. package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
  54. package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
  55. package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
  56. package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
  57. package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
  58. package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
  59. package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
  60. package/public/assets/projects-Br2Bd2h1.js +2 -0
  61. package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
  62. package/public/assets/provider-display-DsuWMvVL.js +2 -0
  63. package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
  64. package/public/assets/run-card-CpKqRbhg.js +2 -0
  65. package/public/assets/scroll-text-BKXS1ahr.js +2 -0
  66. package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
  67. package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
  68. package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
  69. package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
  70. package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
  71. package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
  72. package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
  73. package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
  74. package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
  75. package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
  76. package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
  77. package/public/assets/token-estimate-Co-Jdphh.js +2 -0
  78. package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
  79. package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
  80. package/public/assets/use-project-list-59LheVP7.js +2 -0
  81. package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
  82. package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
  83. package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
  84. package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
  85. package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
  86. package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
  87. package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
  88. package/public/cosmos.html +4 -4
  89. package/public/index.html +31 -29
  90. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  91. package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
  92. package/runner/src/adapters/claude-effort.ts +2 -4
  93. package/runner/src/adapters/codex-launch-config.ts +4 -5
  94. package/runner/src/adapters/codex.ts +1 -1
  95. package/runner/src/adapters/opencode-provider.ts +7 -22
  96. package/runner/src/adapters/opencode.ts +4 -4
  97. package/runner/src/agent-runner/credentials.ts +42 -12
  98. package/runner/src/agent-runner/inbox.ts +27 -0
  99. package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
  100. package/runner/src/bin/claude.ts +4 -0
  101. package/runner/src/bin/codex.ts +4 -0
  102. package/runner/src/bin/opencode.ts +4 -0
  103. package/runner/src/index.ts +5 -2
  104. package/runner/src/provider-setup.ts +34 -0
  105. package/runner/src/providers.ts +2 -1
  106. package/runner/src/runner-core.ts +18 -23
  107. package/runner/src/spawn-input.ts +2 -1
  108. package/runner/src/test-run-dedup.ts +59 -56
  109. package/scripts/cd-config.ts +8 -0
  110. package/scripts/gate-run-lease.ts +10 -7
  111. package/scripts/gate.sh +5 -1
  112. package/src/branch-land-notice.ts +93 -0
  113. package/src/branch-landed.ts +7 -76
  114. package/src/bus.ts +19 -20
  115. package/src/cd-deploy-notify.ts +30 -2
  116. package/src/cd-host-lag-notify.ts +7 -6
  117. package/src/ci/incidents.ts +2 -2
  118. package/src/ci/monitor.ts +5 -8
  119. package/src/ci/root-missing.ts +2 -7
  120. package/src/ci/transition-notify.ts +7 -39
  121. package/src/cli/cd-pauses.ts +19 -0
  122. package/src/cli/orchestrator.ts +1 -1
  123. package/src/cli/state.ts +2 -19
  124. package/src/cli/task-edit.ts +22 -0
  125. package/src/cli/task.ts +3 -1
  126. package/src/cli/workflow.ts +8 -2
  127. package/src/commands-db.ts +3 -3
  128. package/src/config-store-write.ts +13 -1
  129. package/src/config-store.ts +25 -14
  130. package/src/db/activity-async.ts +6 -1
  131. package/src/db/activity-write-ops.ts +12 -1
  132. package/src/db/activity.ts +1 -14
  133. package/src/db/agent-search.ts +1 -15
  134. package/src/db/agents-async.ts +52 -5
  135. package/src/db/agents-write-ops.ts +12 -3
  136. package/src/db/agents.ts +81 -54
  137. package/src/db/ci-incidents-async.ts +5 -5
  138. package/src/db/ci-incidents-write-ops.ts +2 -2
  139. package/src/db/command-row.ts +10 -2
  140. package/src/db/commands-list-query.ts +2 -0
  141. package/src/db/commands-spawn-read.ts +1 -1
  142. package/src/db/config-store-write-ops.ts +7 -2
  143. package/src/db/continuation-archives-async.ts +5 -0
  144. package/src/db/continuation-archives-write-ops.ts +7 -0
  145. package/src/db/continuations.ts +2 -2
  146. package/src/db/db-writer-worker.ts +8 -1
  147. package/src/db/deploy-events-async.ts +1 -0
  148. package/src/db/deploy-events-read-ops.ts +2 -1
  149. package/src/db/deploy-events.ts +35 -4
  150. package/src/db/hosts-registration.ts +10 -2
  151. package/src/db/hosts.ts +9 -6
  152. package/src/db/inbox.ts +0 -14
  153. package/src/db/index.ts +2 -0
  154. package/src/db/integrations-async.ts +8 -0
  155. package/src/db/integrations-ops.ts +15 -0
  156. package/src/db/integrations.ts +15 -21
  157. package/src/db/issue-lifecycle.ts +3 -4
  158. package/src/db/issue-refs-async.ts +20 -0
  159. package/src/db/issue-refs-write-ops.ts +29 -0
  160. package/src/db/issue-refs.ts +7 -8
  161. package/src/db/long-running-work.ts +2 -2
  162. package/src/db/main-connection-writes.ts +23 -2
  163. package/src/db/maintenance-job-reconcile.ts +61 -0
  164. package/src/db/maintenance-job-runs-async.ts +14 -0
  165. package/src/db/maintenance-job-write-ops.ts +9 -0
  166. package/src/db/mappers.ts +2 -14
  167. package/src/db/merge-lease.ts +1 -15
  168. package/src/db/migrations.ts +7 -15
  169. package/src/db/orchestrators.ts +4 -72
  170. package/src/db/pairs.ts +1 -13
  171. package/src/db/project-profile-instructions.ts +50 -0
  172. package/src/db/prompt-versions.ts +9 -2
  173. package/src/db/provider-config-history.ts +8 -3
  174. package/src/db/provider-model-seed.ts +34 -0
  175. package/src/db/read-op-marshaling-fixtures.ts +5 -0
  176. package/src/db/read-ops.ts +4 -0
  177. package/src/db/routing-policy.ts +2 -3
  178. package/src/db/schema.ts +9 -3
  179. package/src/db/spawn-delegation-state.ts +11 -4
  180. package/src/db/stats-async.ts +4 -3
  181. package/src/db/task-entity.ts +23 -2
  182. package/src/db/task-list.ts +3 -1
  183. package/src/db/tasks.ts +1 -17
  184. package/src/db/timer-ingress.ts +7 -1
  185. package/src/db/token-db-write-ops.ts +17 -0
  186. package/src/db/token-standing.ts +15 -11
  187. package/src/db/workflow-contact.ts +1 -1
  188. package/src/db/workflow-task-read-ops.ts +30 -0
  189. package/src/db/write-ops.ts +6 -0
  190. package/src/db/writer-gateway.ts +17 -11
  191. package/src/dispatch-availability.ts +10 -6
  192. package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
  193. package/src/host/disk-alert.ts +121 -0
  194. package/src/lifecycle-manager.ts +3 -2
  195. package/src/maintenance/cd-watcher.ts +3 -3
  196. package/src/maintenance/critical-job-watchdog.ts +16 -17
  197. package/src/maintenance/index.ts +1 -0
  198. package/src/maintenance/jobs.ts +3 -2
  199. package/src/maintenance/scheduler.ts +84 -128
  200. package/src/maintenance/stalled-delivery-pager.ts +6 -5
  201. package/src/maintenance/workspaces.ts +1 -1
  202. package/src/managed-policy.ts +31 -27
  203. package/src/mcp/index.ts +5 -2
  204. package/src/mcp/output-descriptions.ts +8 -8
  205. package/src/mcp/presentation.ts +4 -4
  206. package/src/mcp/project-profile-instructions.ts +32 -0
  207. package/src/mcp/tool-groups.ts +1 -1
  208. package/src/mcp/tools-spawn.ts +4 -3
  209. package/src/mcp-agent-action.ts +1 -2
  210. package/src/mcp-issue-ref-tools.ts +12 -11
  211. package/src/mcp-maintenance-tools.ts +2 -2
  212. package/src/mcp-profile-trust-tools.ts +4 -4
  213. package/src/mcp-provider-catalog.ts +2 -2
  214. package/src/mcp-task-tools.ts +11 -5
  215. package/src/mcp-team-template-tools.ts +3 -3
  216. package/src/mcp-workflow-tools.ts +10 -3
  217. package/src/notification-types.ts +2 -1
  218. package/src/operator-alarm.ts +26 -11
  219. package/src/project-instructions.ts +4 -0
  220. package/src/project-profile-instruction-text.ts +6 -0
  221. package/src/project-profile-instructions.ts +20 -0
  222. package/src/provider-catalog-store.ts +3 -49
  223. package/src/provider-config-store.ts +12 -11
  224. package/src/provider-model-seed.ts +1 -18
  225. package/src/provider-quota-config-store.ts +5 -4
  226. package/src/provider-secrets.test-fixture.ts +3 -3
  227. package/src/recipe-runner.ts +2 -2
  228. package/src/repo-config-source.ts +10 -4
  229. package/src/routes/agent-profiles.ts +6 -6
  230. package/src/routes/agents-spawn.ts +1 -1
  231. package/src/routes/agents.ts +6 -6
  232. package/src/routes/commands-listing.ts +4 -0
  233. package/src/routes/commands.ts +2 -2
  234. package/src/routes/continuation-archives.ts +2 -2
  235. package/src/routes/index.ts +10 -1
  236. package/src/routes/integrations.ts +24 -50
  237. package/src/routes/issue-refs.ts +7 -7
  238. package/src/routes/orchestrator-bootstrap.ts +1 -1
  239. package/src/routes/orchestrator-host-registration.ts +2 -2
  240. package/src/routes/orchestrator-host-utilization.ts +3 -1
  241. package/src/routes/orchestrator-proxy.ts +2 -2
  242. package/src/routes/orchestrator.ts +2 -2
  243. package/src/routes/project-profile-instructions.ts +27 -0
  244. package/src/routes/project-trust.ts +2 -2
  245. package/src/routes/provider-config.ts +6 -6
  246. package/src/routes/provider-quota-config.ts +2 -2
  247. package/src/routes/settings.ts +5 -5
  248. package/src/routes/stats.ts +6 -6
  249. package/src/routes/task-http.ts +15 -1
  250. package/src/routes/task-issues.ts +11 -26
  251. package/src/routes/tasks.ts +22 -53
  252. package/src/routes/team-templates.ts +5 -5
  253. package/src/routes/teams-config.ts +2 -2
  254. package/src/routes/tokens.ts +12 -5
  255. package/src/routes/workflows.ts +20 -5
  256. package/src/routing-policy-normalize.ts +1 -2
  257. package/src/routing-step-defaults.ts +0 -2
  258. package/src/runner-token-mint-limit.ts +63 -0
  259. package/src/runtime-grant.ts +4 -2
  260. package/src/runtime-tokens.ts +39 -7
  261. package/src/security.ts +13 -20
  262. package/src/server-background.ts +1 -1
  263. package/src/server.ts +5 -2
  264. package/src/services/host-utilization.ts +23 -0
  265. package/src/services/idle-epics.ts +5 -6
  266. package/src/services/issue-lifecycle.ts +57 -61
  267. package/src/services/issue-refs.ts +9 -13
  268. package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
  269. package/src/services/kernel-timers-ingress.ts +1 -1
  270. package/src/services/landed-ancestry.ts +19 -3
  271. package/src/services/memory-areas.ts +15 -51
  272. package/src/services/plan-ci-notice.ts +57 -0
  273. package/src/services/plan-ci-recovery.ts +2 -55
  274. package/src/services/plan-wake-digest.ts +1 -0
  275. package/src/services/profile-trust.ts +4 -3
  276. package/src/services/project-config-read.ts +70 -0
  277. package/src/services/project-profile-instructions.ts +54 -0
  278. package/src/services/provisioning-harness/budget-baseline.json +4 -4
  279. package/src/services/restart-spawn.ts +61 -49
  280. package/src/services/self-care-state.ts +2 -1
  281. package/src/services/self-effort.ts +5 -5
  282. package/src/services/send-message.ts +5 -1
  283. package/src/services/spawn-agent.ts +13 -2
  284. package/src/services/spawn-chain-inspector.ts +6 -13
  285. package/src/services/spawn-policy.ts +68 -0
  286. package/src/services/spawn-tree-cleanup.ts +2 -2
  287. package/src/services/task-dispatch.ts +3 -0
  288. package/src/services/task-state-reconcile.ts +6 -14
  289. package/src/services/team-templates.ts +9 -8
  290. package/src/services/transient-agent-reaper.ts +3 -1
  291. package/src/services/workflow-auto-start.ts +25 -13
  292. package/src/services/workflow-ci-main.ts +1 -1
  293. package/src/services/workflow-deferred-cleanup.ts +4 -2
  294. package/src/services/workflow-effect-driver.ts +2 -0
  295. package/src/services/workflow-effects.ts +18 -11
  296. package/src/services/workflow-land-notice.ts +10 -0
  297. package/src/services/workflow-pause-text.ts +43 -0
  298. package/src/services/workflow-reconcile.ts +13 -11
  299. package/src/services/workflow-run-view.ts +2 -0
  300. package/src/services/workflow-runs.ts +29 -13
  301. package/src/services/workflow-supervisor-state.ts +5 -0
  302. package/src/services/workflow-supervisor.ts +7 -3
  303. package/src/settings/registry.ts +1 -2
  304. package/src/spawn-command.ts +4 -4
  305. package/src/spawn-models.ts +10 -12
  306. package/src/spawn-placement.ts +1 -1
  307. package/src/spawn-targets.ts +1 -1
  308. package/src/startup-context-injection.ts +1 -0
  309. package/src/state-adoption/cd-cutover.ts +53 -7
  310. package/src/state-adoption/fleet-cutover.ts +35 -0
  311. package/src/state-adoption/fleet-plan.ts +36 -0
  312. package/src/state-adoption/index.ts +2 -2
  313. package/src/state-adoption/linux-plan.ts +2 -2
  314. package/src/state-adoption/linux.ts +2 -2
  315. package/src/state-adoption/macos-plan.ts +2 -2
  316. package/src/state-adoption/macos.ts +1 -1
  317. package/src/steward.ts +7 -6
  318. package/src/task-dispatch-live.ts +1 -1
  319. package/src/task-dispatcher.ts +1 -1
  320. package/src/teams-config-store.ts +4 -3
  321. package/src/token-db-write.ts +10 -0
  322. package/src/workspace-command-settle.ts +2 -1
  323. package/src/workspace-steward-wake.ts +2 -2
  324. package/node_modules/@humwick/kernel/LICENSE +0 -167
  325. package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
  326. package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
  327. package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
  328. package/node_modules/@humwick/kernel/config.ts +0 -111
  329. package/node_modules/@humwick/kernel/contract.ts +0 -572
  330. package/node_modules/@humwick/kernel/control-authz.ts +0 -281
  331. package/node_modules/@humwick/kernel/control.ts +0 -645
  332. package/node_modules/@humwick/kernel/effects.ts +0 -493
  333. package/node_modules/@humwick/kernel/event-log.ts +0 -319
  334. package/node_modules/@humwick/kernel/http-transport.ts +0 -384
  335. package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
  336. package/node_modules/@humwick/kernel/identity.ts +0 -248
  337. package/node_modules/@humwick/kernel/index.ts +0 -28
  338. package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
  339. package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
  340. package/node_modules/@humwick/kernel/landing.ts +0 -953
  341. package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
  342. package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
  343. package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
  344. package/node_modules/@humwick/kernel/message-authority.ts +0 -281
  345. package/node_modules/@humwick/kernel/module-host.ts +0 -722
  346. package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
  347. package/node_modules/@humwick/kernel/package.json +0 -39
  348. package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
  349. package/node_modules/@humwick/kernel/persistence.ts +0 -510
  350. package/node_modules/@humwick/kernel/registry.ts +0 -60
  351. package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
  352. package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
  353. package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
  354. package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
  355. package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
  356. package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
  357. package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
  358. package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
  359. package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
  360. package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
  361. package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
  362. package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
  363. package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
  364. package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
  365. package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
  366. package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
  367. package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
  368. package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
  369. package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
  370. package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
  371. package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
  372. package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
  373. package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
  374. package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
  375. package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
  376. package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
  377. package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
  378. package/node_modules/@humwick/offload/LICENSE +0 -167
  379. package/node_modules/@humwick/offload/README.md +0 -57
  380. package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
  381. package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
  382. package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
  383. package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
  384. package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
  385. package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
  386. package/node_modules/@humwick/offload/dist/envelope.js +0 -80
  387. package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
  388. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
  389. package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
  390. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
  391. package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
  392. package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
  393. package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
  394. package/node_modules/@humwick/offload/dist/index.js +0 -5
  395. package/node_modules/@humwick/offload/dist/index.js.map +0 -1
  396. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
  397. package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
  398. package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
  399. package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
  400. package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
  401. package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
  402. package/node_modules/@humwick/offload/dist/types.js +0 -176
  403. package/node_modules/@humwick/offload/dist/types.js.map +0 -1
  404. package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
  405. package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
  406. package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
  407. package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
  408. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
  409. package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
  410. package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
  411. package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
  412. package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
  413. package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
  414. package/node_modules/@humwick/offload/dist/worker.js +0 -1
  415. package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
  416. package/node_modules/@humwick/offload/package.json +0 -42
  417. package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
  418. package/node_modules/@humwick/offload/src/envelope.ts +0 -92
  419. package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
  420. package/node_modules/@humwick/offload/src/index.ts +0 -4
  421. package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
  422. package/node_modules/@humwick/offload/src/types.ts +0 -235
  423. package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
  424. package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
  425. package/node_modules/@humwick/offload/src/worker.ts +0 -5
  426. package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
  427. package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
  428. package/public/assets/index-B7ZerHLY.css +0 -2
  429. package/public/assets/index-BU3uWo2t.js +0 -15
  430. package/public/assets/projects-B_lmcqfO.js +0 -2
  431. package/public/assets/provider-display-DbLWpP3j.js +0 -2
  432. package/public/assets/run-card-CO_bguQf.js +0 -2
  433. package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
  434. package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
  435. package/runner/src/gate-run-lease-probe.ts +0 -38
  436. package/src/db/claude-catalog-reconcile.ts +0 -27
  437. package/src/routing-model-aliases.ts +0 -21
@@ -1,493 +0,0 @@
1
- import { lookup as lookupHost } from "node:dns/promises";
2
- import { request as httpRequest } from "node:http";
3
- import { request as httpsRequest } from "node:https";
4
- import { Readable } from "node:stream";
5
- import type { Clock, Disposable, Logger, Rng, Transport } from "./contract";
6
-
7
- function assertDelay(value: number, name: string, allowZero: boolean): void {
8
- if (!Number.isFinite(value) || value < 0 || (!allowZero && value === 0)) {
9
- const qualifier = allowZero ? "a non-negative" : "a positive";
10
- throw new RangeError(`${name} must be ${qualifier} finite number`);
11
- }
12
- }
13
-
14
- /** A logger that discards every record. Useful as the default ModuleCtx.log in tests. */
15
- export function createSilentLogger(): Logger {
16
- const noop = (): void => {};
17
- return { debug: noop, info: noop, warn: noop, error: noop };
18
- }
19
-
20
- /** A logger that forwards to the host console, tagging each record with its level. */
21
- export function createConsoleLogger(): Logger {
22
- const write = (level: "debug" | "info" | "warn" | "error") =>
23
- (message: string, fields?: Readonly<Record<string, unknown>>): void => {
24
- if (fields) console[level](message, fields);
25
- else console[level](message);
26
- };
27
- return { debug: write("debug"), info: write("info"), warn: write("warn"), error: write("error") };
28
- }
29
-
30
- /** Production wall-clock provider. Ambient time and timers stop at this kernel boundary. */
31
- export function createRealClock(): Clock {
32
- return {
33
- now: () => Date.now(),
34
- sleep(ms) {
35
- assertDelay(ms, "sleep delay", true);
36
- return new Promise((resolve) => setTimeout(resolve, ms));
37
- },
38
- every(ms, fn) {
39
- assertDelay(ms, "interval", false);
40
- const timer = setInterval(fn, ms);
41
- let disposed = false;
42
- return {
43
- dispose() {
44
- if (disposed) return;
45
- disposed = true;
46
- clearInterval(timer);
47
- },
48
- };
49
- },
50
- };
51
- }
52
-
53
- interface ScheduledAction {
54
- readonly id: number;
55
- due: number;
56
- readonly interval?: number;
57
- readonly run: () => void;
58
- }
59
-
60
- export interface ControllableClock extends Clock {
61
- /** Advance virtual time, firing due actions in stable registration order. */
62
- advanceBy(ms: number): void;
63
- /** Advance to an absolute virtual timestamp. Time cannot move backwards. */
64
- advanceTo(timestamp: number): void;
65
- }
66
-
67
- /**
68
- * A clock for deterministic tests and replay. It never consults or waits for wall time.
69
- * Scheduled work only runs when the caller advances the clock.
70
- */
71
- export function createControllableClock(initialNow = 0): ControllableClock {
72
- if (!Number.isFinite(initialNow)) throw new RangeError("initial time must be a finite number");
73
-
74
- let now = initialNow;
75
- let nextId = 1;
76
- const scheduled = new Map<number, ScheduledAction>();
77
-
78
- function schedule(delay: number, run: () => void, interval?: number): Disposable {
79
- const action: ScheduledAction = { id: nextId++, due: now + delay, interval, run };
80
- scheduled.set(action.id, action);
81
- return { dispose: () => scheduled.delete(action.id) };
82
- }
83
-
84
- function nextDueAtOrBefore(timestamp: number): ScheduledAction | undefined {
85
- let next: ScheduledAction | undefined;
86
- for (const action of scheduled.values()) {
87
- if (action.due > timestamp) continue;
88
- if (!next || action.due < next.due || (action.due === next.due && action.id < next.id)) next = action;
89
- }
90
- return next;
91
- }
92
-
93
- const clock: ControllableClock = {
94
- now: () => now,
95
- sleep(ms) {
96
- assertDelay(ms, "sleep delay", true);
97
- return new Promise((resolve) => {
98
- schedule(ms, resolve);
99
- });
100
- },
101
- every(ms, fn) {
102
- assertDelay(ms, "interval", false);
103
- return schedule(ms, fn, ms);
104
- },
105
- advanceBy(ms) {
106
- assertDelay(ms, "advance", true);
107
- clock.advanceTo(now + ms);
108
- },
109
- advanceTo(timestamp) {
110
- if (!Number.isFinite(timestamp)) throw new RangeError("target time must be a finite number");
111
- if (timestamp < now) throw new RangeError("controllable clock cannot move backwards");
112
-
113
- let action = nextDueAtOrBefore(timestamp);
114
- while (action) {
115
- now = action.due;
116
- if (action.interval === undefined) {
117
- scheduled.delete(action.id);
118
- } else {
119
- // Reschedule first so dispose() from inside the callback cancels the next firing.
120
- action.due += action.interval;
121
- }
122
- action.run();
123
- action = nextDueAtOrBefore(timestamp);
124
- }
125
- now = timestamp;
126
- },
127
- };
128
-
129
- return clock;
130
- }
131
-
132
- function assertJitterArgs(baseMs: number, spread: number): void {
133
- assertDelay(baseMs, "jitter base", true);
134
- assertDelay(spread, "jitter spread", true);
135
- }
136
-
137
- function jitter(random: () => number, baseMs: number, spread: number): number {
138
- assertJitterArgs(baseMs, spread);
139
- // spread is a ratio: 0.2 produces a value within baseMs +/- 20%.
140
- const factor = 1 + (random() * 2 - 1) * spread;
141
- return Math.max(0, Math.round(baseMs * factor));
142
- }
143
-
144
- /** Production cryptographic RNG provider. It never delegates to Math.random(). */
145
- export function createSystemRng(): Rng {
146
- const random = (): number => {
147
- const value = new Uint32Array(1);
148
- crypto.getRandomValues(value);
149
- return value[0]! / 0x1_0000_0000;
150
- };
151
-
152
- return {
153
- uuid: () => crypto.randomUUID(),
154
- random,
155
- jitter: (baseMs, spread) => jitter(random, baseMs, spread),
156
- };
157
- }
158
-
159
- function hashSeed(seed: string): number {
160
- // FNV-1a provides a small, stable conversion from string seeds to 32-bit state.
161
- let hash = 0x811c9dc5;
162
- for (let i = 0; i < seed.length; i++) {
163
- hash ^= seed.charCodeAt(i);
164
- hash = Math.imul(hash, 0x01000193);
165
- }
166
- return hash >>> 0;
167
- }
168
-
169
- /** Stable seeded RNG (Mulberry32) for deterministic tests and workflow replay. */
170
- export function createSeededRng(seed: number | string): Rng {
171
- if (typeof seed === "number" && !Number.isFinite(seed)) throw new RangeError("RNG seed must be finite");
172
- let state = typeof seed === "string" ? hashSeed(seed) : Math.trunc(seed) >>> 0;
173
-
174
- const nextUint32 = (): number => {
175
- state = (state + 0x6d2b79f5) >>> 0;
176
- let value = state;
177
- value = Math.imul(value ^ (value >>> 15), value | 1);
178
- value ^= value + Math.imul(value ^ (value >>> 7), value | 61);
179
- return (value ^ (value >>> 14)) >>> 0;
180
- };
181
- const random = (): number => nextUint32() / 0x1_0000_0000;
182
-
183
- const uuid = (): string => {
184
- const bytes = new Uint8Array(16);
185
- for (let offset = 0; offset < bytes.length; offset += 4) {
186
- const value = nextUint32();
187
- bytes[offset] = value >>> 24;
188
- bytes[offset + 1] = value >>> 16;
189
- bytes[offset + 2] = value >>> 8;
190
- bytes[offset + 3] = value;
191
- }
192
- bytes[6] = (bytes[6]! & 0x0f) | 0x40;
193
- bytes[8] = (bytes[8]! & 0x3f) | 0x80;
194
- const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
195
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
196
- };
197
-
198
- return {
199
- uuid,
200
- random,
201
- jitter: (baseMs, spread) => jitter(random, baseMs, spread),
202
- };
203
- }
204
-
205
- /**
206
- * Baseline protection for destinations modules should never need to reach directly.
207
- * Caller-provided rules extend this list by default.
208
- */
209
- export const DEFAULT_NET_DENY_LIST = Object.freeze([
210
- "localhost",
211
- "metadata.google.internal",
212
- "metadata.google",
213
- "0.0.0.0/8",
214
- "10.0.0.0/8",
215
- "100.64.0.0/10",
216
- "127.0.0.0/8",
217
- "169.254.0.0/16",
218
- "172.16.0.0/12",
219
- "192.0.0.0/24",
220
- "192.168.0.0/16",
221
- "198.18.0.0/15",
222
- "224.0.0.0/4",
223
- "240.0.0.0/4",
224
- "::/128",
225
- "::1/128",
226
- "::/96",
227
- "::ffff:0:0/96",
228
- "64:ff9b::/96",
229
- "64:ff9b:1::/48",
230
- "2001:db8::/32",
231
- "fc00::/7",
232
- "fe80::/10",
233
- "ff00::/8",
234
- ] as const);
235
-
236
- export interface NetResolvedAddress {
237
- readonly address: string;
238
- readonly family: 4 | 6;
239
- }
240
-
241
- export interface NetConnectionPin extends NetResolvedAddress {
242
- readonly hostname: string;
243
- }
244
-
245
- type ResolverCapability = (hostname: string) => Promise<readonly NetResolvedAddress[]>;
246
- type FetchCapability = (url: string, init: RequestInit | undefined, pin: NetConnectionPin) => Promise<Response>;
247
-
248
- export interface NetTransportOptions {
249
- /** Hostname or IPv4/IPv6 CIDR rules. Hostname rules include all subdomains. */
250
- denyList?: readonly string[];
251
- /** Defaults stay active unless this explicit escape hatch is disabled. */
252
- includeDefaultDenyList?: boolean;
253
- /** Trusted injected host capability; production uses a socket pinned to the vetted address. */
254
- fetch?: FetchCapability;
255
- /** Injected hostname resolver; production defaults to the operating-system resolver. */
256
- resolve?: ResolverCapability;
257
- }
258
-
259
- type ParsedRule =
260
- | { readonly source: string; readonly kind: "hostname"; readonly hostname: string }
261
- | { readonly source: string; readonly kind: "cidr"; readonly bits: 32 | 128; readonly network: bigint; readonly prefix: number };
262
-
263
- function parseIpv4(value: string): bigint | undefined {
264
- const parts = value.split(".");
265
- if (parts.length !== 4) return undefined;
266
- let result = 0n;
267
- for (const part of parts) {
268
- if (!/^\d+$/.test(part)) return undefined;
269
- if (part.length > 1 && part.startsWith("0")) return undefined;
270
- const octet = Number(part);
271
- if (octet > 255) return undefined;
272
- result = (result << 8n) | BigInt(octet);
273
- }
274
- return result;
275
- }
276
-
277
- function parseIpv6(value: string): bigint | undefined {
278
- let address = value.toLowerCase();
279
- if (address.startsWith("[") && address.endsWith("]")) address = address.slice(1, -1);
280
- if (address.includes("%")) return undefined;
281
-
282
- const doubleColon = address.indexOf("::");
283
- if (doubleColon !== -1 && doubleColon !== address.lastIndexOf("::")) return undefined;
284
- const left = (doubleColon === -1 ? address : address.slice(0, doubleColon)).split(":").filter(Boolean);
285
- const right = (doubleColon === -1 ? "" : address.slice(doubleColon + 2)).split(":").filter(Boolean);
286
-
287
- function expandIpv4Tail(parts: string[]): boolean {
288
- const tail = parts.at(-1);
289
- if (!tail?.includes(".")) return true;
290
- const ipv4 = parseIpv4(tail);
291
- if (ipv4 === undefined) return false;
292
- parts.splice(parts.length - 1, 1, ((ipv4 >> 16n) & 0xffffn).toString(16), (ipv4 & 0xffffn).toString(16));
293
- return true;
294
- }
295
-
296
- if (!expandIpv4Tail(left) || !expandIpv4Tail(right)) return undefined;
297
- const missing = 8 - left.length - right.length;
298
- if ((doubleColon === -1 && missing !== 0) || (doubleColon !== -1 && missing < 1)) return undefined;
299
- const groups = [...left, ...Array.from({ length: missing }, () => "0"), ...right];
300
- if (groups.length !== 8) return undefined;
301
-
302
- let result = 0n;
303
- for (const group of groups) {
304
- if (!/^[0-9a-f]{1,4}$/.test(group)) return undefined;
305
- result = (result << 16n) | BigInt(`0x${group}`);
306
- }
307
- return result;
308
- }
309
-
310
- function mask(bits: 32 | 128, prefix: number): bigint {
311
- if (prefix === 0) return 0n;
312
- return ((1n << BigInt(prefix)) - 1n) << BigInt(bits - prefix);
313
- }
314
-
315
- function parseRule(source: string): ParsedRule {
316
- const value = source.trim();
317
- if (!value) throw new TypeError("net deny-list rules must not be empty");
318
-
319
- const slash = value.lastIndexOf("/");
320
- if (slash !== -1) {
321
- const address = value.slice(0, slash);
322
- const parsedPrefix = Number(value.slice(slash + 1));
323
- const ipv4 = parseIpv4(address);
324
- const ipv6 = ipv4 === undefined ? parseIpv6(address) : undefined;
325
- const bits = ipv4 !== undefined ? 32 : ipv6 !== undefined ? 128 : undefined;
326
- if (!bits || !Number.isInteger(parsedPrefix) || parsedPrefix < 0 || parsedPrefix > bits) {
327
- throw new TypeError(`invalid net deny-list CIDR rule '${source}'`);
328
- }
329
- const addressValue = ipv4 ?? ipv6!;
330
- const prefixMask = mask(bits, parsedPrefix);
331
- return { source, kind: "cidr", bits, network: addressValue & prefixMask, prefix: parsedPrefix };
332
- }
333
-
334
- let hostname = value.startsWith(".") ? value.slice(1) : value;
335
- try {
336
- hostname = new URL(`http://${hostname}/`).hostname;
337
- } catch {
338
- throw new TypeError(`invalid net deny-list hostname rule '${source}'`);
339
- }
340
- hostname = hostname.toLowerCase().replace(/\.+$/, "");
341
- if (!hostname) throw new TypeError(`invalid net deny-list hostname rule '${source}'`);
342
- return { source, kind: "hostname", hostname };
343
- }
344
-
345
- function normalizeHostname(hostname: string): string {
346
- return hostname.toLowerCase().replace(/\.+$/, "");
347
- }
348
-
349
- function matchingRule(hostname: string, rules: readonly ParsedRule[]): ParsedRule | undefined {
350
- const normalized = normalizeHostname(hostname);
351
- const unbracketed = normalized.startsWith("[") && normalized.endsWith("]") ? normalized.slice(1, -1) : normalized;
352
- const ipv4 = parseIpv4(unbracketed);
353
- const ipv6 = ipv4 === undefined ? parseIpv6(unbracketed) : undefined;
354
-
355
- return rules.find((rule) => {
356
- if (rule.kind === "hostname") return normalized === rule.hostname || normalized.endsWith(`.${rule.hostname}`);
357
- const address = rule.bits === 32 ? ipv4 : ipv6;
358
- return address !== undefined && (address & mask(rule.bits, rule.prefix)) === rule.network;
359
- });
360
- }
361
-
362
- export class NetEgressDeniedError extends Error {
363
- constructor(
364
- readonly hostname: string,
365
- readonly rule: string,
366
- ) {
367
- super(`outbound HTTP to host '${hostname}' was refused by net deny-list rule '${rule}'`);
368
- this.name = "NetEgressDeniedError";
369
- }
370
- }
371
-
372
- export class NetRedirectRefusedError extends Error {
373
- constructor(readonly hostname: string) {
374
- super(`outbound HTTP redirect from host '${hostname}' was refused; follow it explicitly through ctx.net`);
375
- this.name = "NetRedirectRefusedError";
376
- }
377
- }
378
-
379
- export class NetEgressResolutionError extends Error {
380
- constructor(readonly hostname: string, options?: ErrorOptions) {
381
- super(`outbound HTTP to host '${hostname}' was refused because its address could not be resolved safely`, options);
382
- this.name = "NetEgressResolutionError";
383
- }
384
- }
385
-
386
- const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
387
-
388
- async function defaultResolver(hostname: string): Promise<readonly NetResolvedAddress[]> {
389
- const addresses = await lookupHost(hostname, { all: true, verbatim: true });
390
- return addresses.map(({ address, family }) => {
391
- if (family !== 4 && family !== 6) throw new TypeError(`resolver returned an unsupported address family`);
392
- return { address, family };
393
- });
394
- }
395
-
396
- async function pinnedFetch(url: string, init: RequestInit | undefined, pin: NetConnectionPin): Promise<Response> {
397
- const request = new Request(url, init);
398
- const body = request.body ? Buffer.from(await request.arrayBuffer()) : undefined;
399
- const requestCapability = request.url.startsWith("https:") ? httpsRequest : httpRequest;
400
- const requestHeaders: Record<string, string> = {};
401
- request.headers.forEach((value, name) => {
402
- requestHeaders[name] = value;
403
- });
404
-
405
- return await new Promise<Response>((resolve, reject) => {
406
- const outgoing = requestCapability(request.url, {
407
- method: request.method,
408
- headers: requestHeaders,
409
- family: pin.family,
410
- signal: request.signal,
411
- // Supplying the exact vetted address here is the security boundary: the socket
412
- // cannot perform a second DNS lookup and therefore cannot be DNS-rebound.
413
- lookup: (_hostname, options, callback) => {
414
- if (options.all) callback(null, [{ address: pin.address, family: pin.family }]);
415
- else callback(null, pin.address, pin.family);
416
- },
417
- }, (incoming) => {
418
- const headers = new Headers();
419
- for (let index = 0; index < incoming.rawHeaders.length; index += 2) {
420
- headers.append(incoming.rawHeaders[index]!, incoming.rawHeaders[index + 1]!);
421
- }
422
- resolve(new Response(Readable.toWeb(incoming) as unknown as ReadableStream, {
423
- status: incoming.statusCode,
424
- statusText: incoming.statusMessage,
425
- headers,
426
- }));
427
- });
428
- outgoing.on("error", reject);
429
- outgoing.end(body);
430
- });
431
- }
432
-
433
- /** Create the outbound HTTP provider used as ModuleCtx.net. */
434
- export function createNetTransport(options: NetTransportOptions = {}): Transport {
435
- const sources = [
436
- ...(options.includeDefaultDenyList === false ? [] : DEFAULT_NET_DENY_LIST),
437
- ...(options.denyList ?? []),
438
- ];
439
- const rules = sources.map(parseRule);
440
- const fetchCapability = options.fetch ?? pinnedFetch;
441
- const resolver = options.resolve ?? defaultResolver;
442
-
443
- return {
444
- async fetch(input, init) {
445
- let url: URL;
446
- try {
447
- url = new URL(input);
448
- } catch {
449
- throw new TypeError(`ctx.net.fetch requires an absolute HTTP(S) URL`);
450
- }
451
- if (url.protocol !== "http:" && url.protocol !== "https:") {
452
- throw new TypeError(`ctx.net.fetch refuses non-HTTP protocol '${url.protocol}'`);
453
- }
454
-
455
- const hostname = normalizeHostname(url.hostname);
456
- url.hostname = hostname;
457
- const denied = matchingRule(hostname, rules);
458
- if (denied) throw new NetEgressDeniedError(url.hostname, denied.source);
459
-
460
- const unbracketed = hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
461
- const literalIpv4 = parseIpv4(unbracketed);
462
- const literalIpv6 = literalIpv4 === undefined ? parseIpv6(unbracketed) : undefined;
463
- let addresses: readonly NetResolvedAddress[];
464
- if (literalIpv4 !== undefined || literalIpv6 !== undefined) {
465
- addresses = [{ address: unbracketed, family: literalIpv4 !== undefined ? 4 : 6 }];
466
- } else {
467
- try {
468
- addresses = await resolver(hostname);
469
- } catch (cause) {
470
- throw new NetEgressResolutionError(hostname, { cause });
471
- }
472
- }
473
-
474
- if (addresses.length === 0) throw new NetEgressResolutionError(hostname);
475
- for (const address of addresses) {
476
- const valid = address.family === 4 ? parseIpv4(address.address) : address.family === 6 ? parseIpv6(address.address) : undefined;
477
- if (valid === undefined) throw new NetEgressResolutionError(hostname);
478
- const addressDenied = matchingRule(address.address, rules);
479
- if (addressDenied) throw new NetEgressDeniedError(hostname, addressDenied.source);
480
- }
481
- const selected = addresses[0]!;
482
- const pin: NetConnectionPin = { hostname, address: selected.address, family: selected.family };
483
-
484
- // Manual redirect handling is a security invariant: an allowed URL must not make
485
- // the host fetch a second, denied URL behind this gate.
486
- const response = await fetchCapability(url.href, { ...init, redirect: "manual" }, pin);
487
- if (REDIRECT_STATUSES.has(response.status) && init?.redirect !== "manual") {
488
- throw new NetRedirectRefusedError(url.hostname);
489
- }
490
- return response;
491
- },
492
- };
493
- }