@noodleseed/one 0.23.0 → 0.25.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 (256) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +2 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/author-loop.d.ts +1 -0
  5. package/dist/commands/author-loop.d.ts.map +1 -1
  6. package/dist/commands/author-loop.js +4 -0
  7. package/dist/commands/author-loop.js.map +1 -1
  8. package/dist/commands/catalog-data-core.d.ts.map +1 -1
  9. package/dist/commands/catalog-data-core.js +17 -3
  10. package/dist/commands/catalog-data-core.js.map +1 -1
  11. package/dist/commands/catalog-data-resources.js +2 -2
  12. package/dist/commands/catalog-data-resources.js.map +1 -1
  13. package/dist/commands/catalog-render.d.ts.map +1 -1
  14. package/dist/commands/catalog-render.js +6 -0
  15. package/dist/commands/catalog-render.js.map +1 -1
  16. package/dist/commands/config-values.d.ts +14 -1
  17. package/dist/commands/config-values.d.ts.map +1 -1
  18. package/dist/commands/config-values.js +51 -3
  19. package/dist/commands/config-values.js.map +1 -1
  20. package/dist/commands/deploy-ops.d.ts.map +1 -1
  21. package/dist/commands/deploy-ops.js +2 -2
  22. package/dist/commands/deploy-ops.js.map +1 -1
  23. package/dist/commands/deploy-status-ops.d.ts +1 -1
  24. package/dist/commands/deploy-status-ops.d.ts.map +1 -1
  25. package/dist/commands/deploy-status-ops.js +8 -4
  26. package/dist/commands/deploy-status-ops.js.map +1 -1
  27. package/dist/commands/devtools.d.ts +11 -0
  28. package/dist/commands/devtools.d.ts.map +1 -0
  29. package/dist/commands/devtools.js +123 -0
  30. package/dist/commands/devtools.js.map +1 -0
  31. package/dist/commands/mcp-apps.d.ts +0 -1
  32. package/dist/commands/mcp-apps.d.ts.map +1 -1
  33. package/dist/commands/mcp-apps.js +71 -122
  34. package/dist/commands/mcp-apps.js.map +1 -1
  35. package/dist/commands/shared.d.ts +6 -0
  36. package/dist/commands/shared.d.ts.map +1 -1
  37. package/dist/commands/shared.js +19 -0
  38. package/dist/commands/shared.js.map +1 -1
  39. package/dist/deploy.d.ts +1 -1
  40. package/dist/deploy.d.ts.map +1 -1
  41. package/dist/deploy.js +5 -1
  42. package/dist/deploy.js.map +1 -1
  43. package/dist/dev.d.ts.map +1 -1
  44. package/dist/dev.js +13 -1
  45. package/dist/dev.js.map +1 -1
  46. package/dist/fire.js +1 -1
  47. package/dist/fire.js.map +1 -1
  48. package/dist/flavor.d.ts +1 -1
  49. package/dist/flavor.d.ts.map +1 -1
  50. package/dist/flavor.js +12 -2
  51. package/dist/flavor.js.map +1 -1
  52. package/dist/project-scaffold-templates.d.ts.map +1 -1
  53. package/dist/project-scaffold-templates.js +2 -0
  54. package/dist/project-scaffold-templates.js.map +1 -1
  55. package/dist/validate.d.ts.map +1 -1
  56. package/dist/validate.js +50 -1
  57. package/dist/validate.js.map +1 -1
  58. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.d.ts.map +1 -1
  59. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js +96 -51
  60. package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-refs.js.map +1 -1
  61. package/node_modules/@noodle-borg/agent-kit/dist/skill-content.d.ts.map +1 -1
  62. package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js +66 -4
  63. package/node_modules/@noodle-borg/agent-kit/dist/skill-content.js.map +1 -1
  64. package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.d.ts.map +1 -1
  65. package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js +8 -3
  66. package/node_modules/@noodle-borg/agent-kit/dist/skill-operations-refs.js.map +1 -1
  67. package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
  68. package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts +18 -1
  69. package/node_modules/@noodle-borg/authoring/dist/connectors.d.ts.map +1 -1
  70. package/node_modules/@noodle-borg/authoring/dist/connectors.js +17 -4
  71. package/node_modules/@noodle-borg/authoring/dist/connectors.js.map +1 -1
  72. package/node_modules/@noodle-borg/authoring/dist/recording.js +24 -5
  73. package/node_modules/@noodle-borg/authoring/dist/recording.js.map +1 -1
  74. package/node_modules/@noodle-borg/authoring/dist/server.js +57 -3
  75. package/node_modules/@noodle-borg/authoring/dist/server.js.map +1 -1
  76. package/node_modules/@noodle-borg/connector-defs/dist/auth-variables.js +1 -1
  77. package/node_modules/@noodle-borg/connector-defs/dist/auth-variables.js.map +1 -1
  78. package/node_modules/@noodle-borg/connector-defs/dist/call-graph.d.ts +14 -0
  79. package/node_modules/@noodle-borg/connector-defs/dist/call-graph.d.ts.map +1 -0
  80. package/node_modules/@noodle-borg/connector-defs/dist/call-graph.js +66 -0
  81. package/node_modules/@noodle-borg/connector-defs/dist/call-graph.js.map +1 -0
  82. package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.d.ts +21 -0
  83. package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.d.ts.map +1 -0
  84. package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.js +102 -0
  85. package/node_modules/@noodle-borg/connector-defs/dist/compile-auth.js.map +1 -0
  86. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts +19 -4
  87. package/node_modules/@noodle-borg/connector-defs/dist/compile.d.ts.map +1 -1
  88. package/node_modules/@noodle-borg/connector-defs/dist/compile.js +67 -99
  89. package/node_modules/@noodle-borg/connector-defs/dist/compile.js.map +1 -1
  90. package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts +1 -1
  91. package/node_modules/@noodle-borg/connector-defs/dist/index.d.ts.map +1 -1
  92. package/node_modules/@noodle-borg/connector-defs/dist/index.js.map +1 -1
  93. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts +168 -10
  94. package/node_modules/@noodle-borg/connector-defs/dist/schema.d.ts.map +1 -1
  95. package/node_modules/@noodle-borg/connector-defs/dist/schema.js +72 -5
  96. package/node_modules/@noodle-borg/connector-defs/dist/schema.js.map +1 -1
  97. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts +6 -0
  98. package/node_modules/@noodle-borg/connector-http/dist/http-connector.d.ts.map +1 -1
  99. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js +2 -0
  100. package/node_modules/@noodle-borg/connector-http/dist/http-connector.js.map +1 -1
  101. package/node_modules/@noodle-borg/runtime/dist/execute.d.ts.map +1 -1
  102. package/node_modules/@noodle-borg/runtime/dist/execute.js +87 -62
  103. package/node_modules/@noodle-borg/runtime/dist/execute.js.map +1 -1
  104. package/node_modules/@noodle-borg/runtime/dist/result.d.ts +1 -1
  105. package/node_modules/@noodle-borg/runtime/dist/result.d.ts.map +1 -1
  106. package/node_modules/@noodle-borg/service/dist/credential-broker.d.ts.map +1 -1
  107. package/node_modules/@noodle-borg/service/dist/credential-broker.js +113 -11
  108. package/node_modules/@noodle-borg/service/dist/credential-broker.js.map +1 -1
  109. package/node_modules/@noodle-borg/service/dist/github/app-client.d.ts +28 -5
  110. package/node_modules/@noodle-borg/service/dist/github/app-client.d.ts.map +1 -1
  111. package/node_modules/@noodle-borg/service/dist/github/app-client.js +116 -7
  112. package/node_modules/@noodle-borg/service/dist/github/app-client.js.map +1 -1
  113. package/node_modules/@noodle-borg/service/dist/github/builder-auth.d.ts +12 -0
  114. package/node_modules/@noodle-borg/service/dist/github/builder-auth.d.ts.map +1 -0
  115. package/node_modules/@noodle-borg/service/dist/github/builder-auth.js +19 -0
  116. package/node_modules/@noodle-borg/service/dist/github/builder-auth.js.map +1 -0
  117. package/node_modules/@noodle-borg/service/dist/github/builder-main.d.ts +3 -0
  118. package/node_modules/@noodle-borg/service/dist/github/builder-main.d.ts.map +1 -0
  119. package/node_modules/@noodle-borg/service/dist/github/builder-main.js +9 -0
  120. package/node_modules/@noodle-borg/service/dist/github/builder-main.js.map +1 -0
  121. package/node_modules/@noodle-borg/service/dist/github/builder-runner.d.ts +21 -0
  122. package/node_modules/@noodle-borg/service/dist/github/builder-runner.d.ts.map +1 -0
  123. package/node_modules/@noodle-borg/service/dist/github/builder-runner.js +192 -0
  124. package/node_modules/@noodle-borg/service/dist/github/builder-runner.js.map +1 -0
  125. package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.d.ts +45 -0
  126. package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.d.ts.map +1 -0
  127. package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.js +64 -0
  128. package/node_modules/@noodle-borg/service/dist/github/cloud-run-job-executor.js.map +1 -0
  129. package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.d.ts +64 -0
  130. package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.d.ts.map +1 -0
  131. package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.js +121 -0
  132. package/node_modules/@noodle-borg/service/dist/github/deploy-pipeline.js.map +1 -0
  133. package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.d.ts +33 -0
  134. package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.d.ts.map +1 -0
  135. package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.js +14 -0
  136. package/node_modules/@noodle-borg/service/dist/github/deploy-run-executor.js.map +1 -0
  137. package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.d.ts +36 -0
  138. package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.d.ts.map +1 -0
  139. package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.js +107 -0
  140. package/node_modules/@noodle-borg/service/dist/github/deploy-run-reconciler.js.map +1 -0
  141. package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.d.ts +38 -0
  142. package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.d.ts.map +1 -0
  143. package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.js +60 -0
  144. package/node_modules/@noodle-borg/service/dist/github/fast-lane-classifier.js.map +1 -0
  145. package/node_modules/@noodle-borg/service/dist/github/local-compile.d.ts +24 -0
  146. package/node_modules/@noodle-borg/service/dist/github/local-compile.d.ts.map +1 -0
  147. package/node_modules/@noodle-borg/service/dist/github/local-compile.js +98 -0
  148. package/node_modules/@noodle-borg/service/dist/github/local-compile.js.map +1 -0
  149. package/node_modules/@noodle-borg/service/dist/github/local-process-executor.d.ts +39 -0
  150. package/node_modules/@noodle-borg/service/dist/github/local-process-executor.d.ts.map +1 -0
  151. package/node_modules/@noodle-borg/service/dist/github/local-process-executor.js +67 -0
  152. package/node_modules/@noodle-borg/service/dist/github/local-process-executor.js.map +1 -0
  153. package/node_modules/@noodle-borg/service/dist/github/run-access-mode.d.ts +18 -0
  154. package/node_modules/@noodle-borg/service/dist/github/run-access-mode.d.ts.map +1 -0
  155. package/node_modules/@noodle-borg/service/dist/github/run-access-mode.js +32 -0
  156. package/node_modules/@noodle-borg/service/dist/github/run-access-mode.js.map +1 -0
  157. package/node_modules/@noodle-borg/service/dist/github/run-token.d.ts +41 -0
  158. package/node_modules/@noodle-borg/service/dist/github/run-token.d.ts.map +1 -0
  159. package/node_modules/@noodle-borg/service/dist/github/run-token.js +59 -0
  160. package/node_modules/@noodle-borg/service/dist/github/run-token.js.map +1 -0
  161. package/node_modules/@noodle-borg/service/dist/http-util.d.ts +7 -1
  162. package/node_modules/@noodle-borg/service/dist/http-util.d.ts.map +1 -1
  163. package/node_modules/@noodle-borg/service/dist/http-util.js +14 -0
  164. package/node_modules/@noodle-borg/service/dist/http-util.js.map +1 -1
  165. package/node_modules/@noodle-borg/service/dist/index.d.ts +13 -2
  166. package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
  167. package/node_modules/@noodle-borg/service/dist/index.js +12 -1
  168. package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
  169. package/node_modules/@noodle-borg/service/dist/main.js +72 -0
  170. package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
  171. package/node_modules/@noodle-borg/service/dist/options.d.ts +26 -3
  172. package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
  173. package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts +12 -0
  174. package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts.map +1 -1
  175. package/node_modules/@noodle-borg/service/dist/registry-helpers.js +3 -0
  176. package/node_modules/@noodle-borg/service/dist/registry-helpers.js.map +1 -1
  177. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +7 -0
  178. package/node_modules/@noodle-borg/service/dist/registry-types.d.ts.map +1 -1
  179. package/node_modules/@noodle-borg/service/dist/registry.d.ts +7 -29
  180. package/node_modules/@noodle-borg/service/dist/registry.d.ts.map +1 -1
  181. package/node_modules/@noodle-borg/service/dist/registry.js +62 -57
  182. package/node_modules/@noodle-borg/service/dist/registry.js.map +1 -1
  183. package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.d.ts +3 -2
  184. package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.d.ts.map +1 -1
  185. package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.js +36 -8
  186. package/node_modules/@noodle-borg/service/dist/routes/asset-control-plane.js.map +1 -1
  187. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +3 -2
  188. package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
  189. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +100 -12
  190. package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
  191. package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.d.ts +7 -0
  192. package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.d.ts.map +1 -1
  193. package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.js +36 -1
  194. package/node_modules/@noodle-borg/service/dist/routes/github-dispatch.js.map +1 -1
  195. package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.d.ts +13 -0
  196. package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.d.ts.map +1 -0
  197. package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.js +84 -0
  198. package/node_modules/@noodle-borg/service/dist/routes/github-run-claim.js.map +1 -0
  199. package/node_modules/@noodle-borg/service/dist/routes/github-run-status.d.ts +5 -0
  200. package/node_modules/@noodle-borg/service/dist/routes/github-run-status.d.ts.map +1 -0
  201. package/node_modules/@noodle-borg/service/dist/routes/github-run-status.js +73 -0
  202. package/node_modules/@noodle-borg/service/dist/routes/github-run-status.js.map +1 -0
  203. package/node_modules/@noodle-borg/service/dist/routes/github-webhook.d.ts +23 -1
  204. package/node_modules/@noodle-borg/service/dist/routes/github-webhook.d.ts.map +1 -1
  205. package/node_modules/@noodle-borg/service/dist/routes/github-webhook.js +41 -0
  206. package/node_modules/@noodle-borg/service/dist/routes/github-webhook.js.map +1 -1
  207. package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts +4 -0
  208. package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts.map +1 -1
  209. package/node_modules/@noodle-borg/service/dist/routes/paths.js +10 -0
  210. package/node_modules/@noodle-borg/service/dist/routes/paths.js.map +1 -1
  211. package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.d.ts +85 -0
  212. package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.d.ts.map +1 -0
  213. package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.js +90 -0
  214. package/node_modules/@noodle-borg/service/dist/routes/run-deploy-auth.js.map +1 -0
  215. package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
  216. package/node_modules/@noodle-borg/service/dist/serve.js +31 -0
  217. package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
  218. package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
  219. package/node_modules/@noodle-borg/service/dist/service.js +8 -13
  220. package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
  221. package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.d.ts +1 -0
  222. package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.d.ts.map +1 -1
  223. package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.js +5 -0
  224. package/node_modules/@noodle-borg/service/dist/store/github-connections-json-file.js.map +1 -1
  225. package/node_modules/@noodle-borg/service/dist/store/github-connections.d.ts +1 -0
  226. package/node_modules/@noodle-borg/service/dist/store/github-connections.d.ts.map +1 -1
  227. package/node_modules/@noodle-borg/service/dist/store/github-connections.js +5 -0
  228. package/node_modules/@noodle-borg/service/dist/store/github-connections.js.map +1 -1
  229. package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.d.ts +120 -0
  230. package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.d.ts.map +1 -0
  231. package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.js +6 -0
  232. package/node_modules/@noodle-borg/service/dist/store/github-deploy-run-contract.js.map +1 -0
  233. package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.d.ts +6 -1
  234. package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.d.ts.map +1 -1
  235. package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.js +18 -1
  236. package/node_modules/@noodle-borg/service/dist/store/github-runs-json-file.js.map +1 -1
  237. package/node_modules/@noodle-borg/service/dist/store/github-runs.d.ts +22 -1
  238. package/node_modules/@noodle-borg/service/dist/store/github-runs.d.ts.map +1 -1
  239. package/node_modules/@noodle-borg/service/dist/store/github-runs.js +39 -2
  240. package/node_modules/@noodle-borg/service/dist/store/github-runs.js.map +1 -1
  241. package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.d.ts +13 -1
  242. package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.d.ts.map +1 -1
  243. package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js +115 -1
  244. package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js.map +1 -1
  245. package/node_modules/@noodle-borg/service/dist/store/postgres-github.d.ts +1 -0
  246. package/node_modules/@noodle-borg/service/dist/store/postgres-github.d.ts.map +1 -1
  247. package/node_modules/@noodle-borg/service/dist/store/postgres-github.js +6 -0
  248. package/node_modules/@noodle-borg/service/dist/store/postgres-github.js.map +1 -1
  249. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +15 -1
  250. package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
  251. package/node_modules/@noodle-borg/service/dist/store/postgres.js +22 -2
  252. package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
  253. package/node_modules/@noodle-borg/service/dist/store.d.ts +22 -99
  254. package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
  255. package/node_modules/@noodle-borg/service/dist/store.js.map +1 -1
  256. package/package.json +2 -2
@@ -1,17 +1,14 @@
1
- /**
2
- * The GitHub App integration seam for GHD-1 (repository connection). This phase ships routes and
3
- * persistence only — no live GitHub call is made anywhere in this slice. `GitHubAppClient` is the
4
- * narrow port the connection routes depend on; a later slice implements it against the real GitHub App
5
- * (JWT-signed app auth → installation access tokens → REST calls) once the private key / webhook secret
6
- * are wired from the credential broker. Tests and local/dev use {@link InMemoryGitHubAppClient}.
7
- */
1
+ import { createPrivateKey } from 'node:crypto';
2
+ import { SignJWT } from 'jose';
8
3
  /** Constructor-seeded fake for tests and local/dev — no network, no JWT, no live GitHub App required. */
9
4
  export class InMemoryGitHubAppClient {
10
5
  #installations;
11
6
  #repositoriesByInstallation;
7
+ #tokensByInstallation;
12
8
  constructor(seed) {
13
9
  this.#installations = new Map(seed.installations.map((installation) => [installation.id, installation]));
14
10
  this.#repositoriesByInstallation = new Map(Object.entries(seed.repositoriesByInstallation).map(([id, repos]) => [Number(id), repos]));
11
+ this.#tokensByInstallation = new Map(Object.entries(seed.tokensByInstallation ?? {}).map(([id, token]) => [Number(id), token]));
15
12
  }
16
13
  getInstallation(installationId) {
17
14
  return Promise.resolve(this.#installations.get(installationId));
@@ -19,5 +16,117 @@ export class InMemoryGitHubAppClient {
19
16
  listInstallationRepositories(installationId) {
20
17
  return Promise.resolve(this.#repositoriesByInstallation.get(installationId) ?? []);
21
18
  }
19
+ createInstallationAccessToken(installationId) {
20
+ return Promise.resolve(this.#tokensByInstallation.get(installationId) ?? {
21
+ token: `ghs-test-installation-${installationId}`,
22
+ });
23
+ }
24
+ }
25
+ /**
26
+ * Live GitHub App port: signs a short-lived app JWT locally and uses it only to ask GitHub for
27
+ * installation-scoped data/tokens. Installation access tokens are returned to the caller and never
28
+ * cached or persisted in this class.
29
+ */
30
+ export class LiveGitHubAppClient {
31
+ #appId;
32
+ #appSlug;
33
+ #privateKeyPem;
34
+ #httpFetch;
35
+ #now;
36
+ constructor(options) {
37
+ if (options.privateKeyPem === undefined || options.privateKeyPem.trim() === '') {
38
+ throw new Error('GitHub App private key is required for live GitHub calls');
39
+ }
40
+ this.#appId = options.appId;
41
+ this.#appSlug = options.appSlug;
42
+ this.#privateKeyPem = options.privateKeyPem;
43
+ this.#httpFetch = options.httpFetch ?? fetch;
44
+ this.#now = options.now ?? (() => new Date());
45
+ }
46
+ async getInstallation(installationId) {
47
+ const res = await this.#request(`/app/installations/${installationId}`, { method: 'GET' });
48
+ if (res.status === 404)
49
+ return undefined;
50
+ await assertOk(res, 'get installation');
51
+ const body = (await res.json());
52
+ const id = typeof body.id === 'number' ? body.id : undefined;
53
+ const accountLogin = typeof body.account?.login === 'string' ? body.account.login : undefined;
54
+ if (id === undefined || accountLogin === undefined)
55
+ return undefined;
56
+ return { id, accountLogin };
57
+ }
58
+ async listInstallationRepositories(installationId) {
59
+ const res = await this.#request(`/installation/repositories`, {
60
+ method: 'GET',
61
+ installationId,
62
+ });
63
+ await assertOk(res, 'list installation repositories');
64
+ const body = (await res.json());
65
+ const repositories = Array.isArray(body.repositories) ? body.repositories : [];
66
+ return repositories.flatMap((repo) => summarizeRepo(repo));
67
+ }
68
+ async createInstallationAccessToken(installationId) {
69
+ const res = await this.#request(`/app/installations/${installationId}/access_tokens`, {
70
+ method: 'POST',
71
+ });
72
+ await assertOk(res, 'create installation access token');
73
+ const body = (await res.json());
74
+ if (typeof body.token !== 'string' || body.token.length === 0) {
75
+ throw new Error('GitHub returned no installation token');
76
+ }
77
+ return {
78
+ token: body.token,
79
+ ...(typeof body.expires_at === 'string' ? { expiresAt: body.expires_at } : {}),
80
+ };
81
+ }
82
+ async #request(path, options) {
83
+ const bearer = options.installationId === undefined
84
+ ? await this.#appJwt()
85
+ : (await this.createInstallationAccessToken(options.installationId)).token;
86
+ return this.#httpFetch(`https://api.github.com${path}`, {
87
+ method: options.method,
88
+ headers: {
89
+ accept: 'application/vnd.github+json',
90
+ authorization: `Bearer ${bearer}`,
91
+ 'user-agent': `noodle-seed/${this.#appSlug}`,
92
+ 'x-github-api-version': '2022-11-28',
93
+ },
94
+ });
95
+ }
96
+ async #appJwt() {
97
+ const nowSeconds = Math.floor(this.#now().getTime() / 1000);
98
+ const privateKey = createPrivateKey(this.#privateKeyPem);
99
+ return new SignJWT({})
100
+ .setProtectedHeader({ alg: 'RS256' })
101
+ .setIssuedAt(nowSeconds - 60)
102
+ .setExpirationTime(nowSeconds + 9 * 60)
103
+ .setIssuer(this.#appId)
104
+ .sign(privateKey);
105
+ }
106
+ }
107
+ async function assertOk(res, action) {
108
+ if (res.ok)
109
+ return;
110
+ throw new Error(`GitHub ${action} failed (HTTP ${res.status})`);
111
+ }
112
+ function summarizeRepo(repo) {
113
+ if (typeof repo.id !== 'number' ||
114
+ typeof repo.full_name !== 'string' ||
115
+ typeof repo.name !== 'string' ||
116
+ typeof repo.default_branch !== 'string' ||
117
+ typeof repo.owner?.login !== 'string' ||
118
+ typeof repo.private !== 'boolean') {
119
+ return [];
120
+ }
121
+ return [
122
+ {
123
+ id: repo.id,
124
+ fullName: repo.full_name,
125
+ owner: repo.owner.login,
126
+ name: repo.name,
127
+ defaultBranch: repo.default_branch,
128
+ private: repo.private,
129
+ },
130
+ ];
22
131
  }
23
132
  //# sourceMappingURL=app-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-client.js","sourceRoot":"","sources":["../../src/github/app-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuCH,yGAAyG;AACzG,MAAM,OAAO,uBAAuB;IACzB,cAAc,CAAiD;IAC/D,2BAA2B,CAGlC;IAEF,YAAY,IAKX;QACC,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,CAC3B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAC1E,CAAC;QACF,IAAI,CAAC,2BAA2B,GAAG,IAAI,GAAG,CACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAC1F,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,cAAsB;QACpC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,4BAA4B,CAC1B,cAAsB;QAEtB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC;CACF"}
1
+ {"version":3,"file":"app-client.js","sourceRoot":"","sources":["../../src/github/app-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface GithubBuilderIdentity {
2
+ readonly email?: string;
3
+ readonly subject?: string;
4
+ }
5
+ export interface GithubBuilderIdentityVerifier {
6
+ verify(token: string, audience: string): Promise<GithubBuilderIdentity | undefined>;
7
+ }
8
+ export declare class GoogleGithubBuilderIdentityVerifier implements GithubBuilderIdentityVerifier {
9
+ #private;
10
+ verify(token: string, audience: string): Promise<GithubBuilderIdentity | undefined>;
11
+ }
12
+ //# sourceMappingURL=builder-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-auth.d.ts","sourceRoot":"","sources":["../../src/github/builder-auth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;CACrF;AAED,qBAAa,mCAAoC,YAAW,6BAA6B;;IAGjF,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC;CAiB1F"}
@@ -0,0 +1,19 @@
1
+ export class GoogleGithubBuilderIdentityVerifier {
2
+ #clientPromise;
3
+ async verify(token, audience) {
4
+ const client = await this.#client();
5
+ const ticket = await client.verifyIdToken({ idToken: token, audience });
6
+ const payload = ticket.getPayload();
7
+ if (payload === undefined)
8
+ return undefined;
9
+ return {
10
+ ...(typeof payload.email === 'string' ? { email: payload.email } : {}),
11
+ ...(typeof payload.sub === 'string' ? { subject: payload.sub } : {}),
12
+ };
13
+ }
14
+ #client() {
15
+ this.#clientPromise ??= import('google-auth-library').then(({ OAuth2Client }) => new OAuth2Client());
16
+ return this.#clientPromise;
17
+ }
18
+ }
19
+ //# sourceMappingURL=builder-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-auth.js","sourceRoot":"","sources":["../../src/github/builder-auth.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,mCAAmC;IAC9C,cAAc,CAAuD;IAErE,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,QAAgB;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACpC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5C,OAAO;YACL,GAAG,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,GAAG,CAAC,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,CAAC,cAAc,KAAK,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CACxD,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,IAAI,YAAY,EAAE,CACzC,CAAC;QACF,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=builder-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-main.d.ts","sourceRoot":"","sources":["../../src/github/builder-main.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { runCloudRunBuilder } from './builder-runner.js';
3
+ runCloudRunBuilder().catch((error) => {
4
+ const name = error instanceof Error ? error.name : 'Error';
5
+ const message = error instanceof Error ? error.message : String(error);
6
+ console.error(`builder failed (${name}): ${message}`);
7
+ process.exit(1);
8
+ });
9
+ //# sourceMappingURL=builder-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-main.js","sourceRoot":"","sources":["../../src/github/builder-main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,kBAAkB,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACnC,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC3D,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { spawn } from 'node:child_process';
2
+ import type { DeployRunRecord } from '../store.js';
3
+ export interface BuilderClaim {
4
+ readonly runToken: string;
5
+ readonly run: DeployRunRecord;
6
+ readonly repoFullName: string;
7
+ readonly repoRoot?: string;
8
+ readonly commitSha: string;
9
+ readonly githubInstallationToken: string;
10
+ readonly githubInstallationTokenExpiresAt?: string;
11
+ }
12
+ export interface BuilderRunnerOptions {
13
+ readonly env?: NodeJS.ProcessEnv;
14
+ readonly httpFetch?: typeof fetch;
15
+ readonly spawnProcess?: typeof spawn;
16
+ readonly stdout?: Pick<NodeJS.WriteStream, 'write'>;
17
+ readonly stderr?: Pick<NodeJS.WriteStream, 'write'>;
18
+ }
19
+ export declare function sanitizeBuilderChildEnv(env: NodeJS.ProcessEnv): Record<string, string>;
20
+ export declare function runCloudRunBuilder(options?: BuilderRunnerOptions): Promise<void>;
21
+ //# sourceMappingURL=builder-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-runner.d.ts","sourceRoot":"","sources":["../../src/github/builder-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,MAAM,CAAC;CACpD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACrD;AAID,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUtF;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0C1F"}
@@ -0,0 +1,192 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import { runDeployPipeline } from './deploy-pipeline.js';
6
+ import { createLocalCompile } from './local-compile.js';
7
+ const SAFE_ENV_KEYS = new Set(['PATH', 'HOME', 'TMPDIR', 'npm_config_cache', 'NPM_CONFIG_CACHE']);
8
+ export function sanitizeBuilderChildEnv(env) {
9
+ const clean = {
10
+ CI: '1',
11
+ NOODLE_DISABLE_UPDATE_CHECK: '1',
12
+ };
13
+ for (const key of SAFE_ENV_KEYS) {
14
+ const value = env[key];
15
+ if (value !== undefined && value.length > 0)
16
+ clean[key] = value;
17
+ }
18
+ return clean;
19
+ }
20
+ export async function runCloudRunBuilder(options = {}) {
21
+ const env = options.env ?? process.env;
22
+ const stdout = options.stdout ?? process.stdout;
23
+ const stderr = options.stderr ?? process.stderr;
24
+ if (env.NOODLE_BUILDER_SELF_TEST === '1') {
25
+ stdout.write('builder self-test ok\n');
26
+ return;
27
+ }
28
+ const runId = requiredEnv(env, 'NOODLE_GHD_RUN_ID');
29
+ const serviceBaseUrl = trimTrailingSlash(requiredEnv(env, 'NOODLE_GHD_SERVICE_BASE_URL'));
30
+ const claim = await claimBuilderRun({
31
+ runId,
32
+ serviceBaseUrl,
33
+ audience: env.NOODLE_GHD_ID_TOKEN_AUDIENCE ?? serviceBaseUrl,
34
+ httpFetch: options.httpFetch ?? fetch,
35
+ });
36
+ const workDir = await mkdtemp(join(tmpdir(), 'noodle-ghd-builder-'));
37
+ try {
38
+ const sourceDir = await fetchSource({
39
+ claim,
40
+ workDir,
41
+ httpFetch: options.httpFetch ?? fetch,
42
+ spawnProcess: options.spawnProcess ?? spawn,
43
+ });
44
+ const localCompile = createLocalCompile({
45
+ exportManifest: createCliManifestExporter({
46
+ env,
47
+ spawnProcess: options.spawnProcess ?? spawn,
48
+ stderr,
49
+ }),
50
+ });
51
+ await runDeployPipeline({
52
+ run: claim.run,
53
+ runToken: claim.runToken,
54
+ serviceBaseUrl,
55
+ compile: () => localCompile(sourceDir),
56
+ httpFetch: options.httpFetch ?? fetch,
57
+ });
58
+ }
59
+ finally {
60
+ await rm(workDir, { recursive: true, force: true }).catch(() => undefined);
61
+ }
62
+ }
63
+ async function claimBuilderRun(input) {
64
+ const claimUrl = `${input.serviceBaseUrl}/v1/github/runs/${encodeURIComponent(input.runId)}/claim`;
65
+ if (input.serviceBaseUrl.startsWith('http://127.0.0.1') ||
66
+ input.serviceBaseUrl.startsWith('http://localhost')) {
67
+ const res = await input.httpFetch(claimUrl, { method: 'POST' });
68
+ return parseClaimResponse(res);
69
+ }
70
+ const { GoogleAuth } = await import('google-auth-library');
71
+ const auth = new GoogleAuth();
72
+ const client = await auth.getIdTokenClient(input.audience);
73
+ const res = await client.request({ url: claimUrl, method: 'POST' });
74
+ return parseClaimBody(res.data);
75
+ }
76
+ async function parseClaimResponse(res) {
77
+ const body = await res.json().catch(() => undefined);
78
+ if (!res.ok)
79
+ throw new Error(`builder claim failed (HTTP ${res.status})`);
80
+ return parseClaimBody(body);
81
+ }
82
+ function parseClaimBody(body) {
83
+ const data = asRecord(body)?.data;
84
+ const record = asRecord(data);
85
+ const runRecord = asRecord(record?.run);
86
+ if (record === undefined ||
87
+ typeof record.runToken !== 'string' ||
88
+ runRecord === undefined ||
89
+ typeof record.repoFullName !== 'string' ||
90
+ typeof record.commitSha !== 'string' ||
91
+ typeof record.githubInstallationToken !== 'string') {
92
+ throw new Error('builder claim response was malformed');
93
+ }
94
+ return {
95
+ runToken: record.runToken,
96
+ run: runRecord,
97
+ repoFullName: record.repoFullName,
98
+ ...(typeof record.repoRoot === 'string' && record.repoRoot.length > 0
99
+ ? { repoRoot: record.repoRoot }
100
+ : {}),
101
+ commitSha: record.commitSha,
102
+ githubInstallationToken: record.githubInstallationToken,
103
+ ...(typeof record.githubInstallationTokenExpiresAt === 'string'
104
+ ? { githubInstallationTokenExpiresAt: record.githubInstallationTokenExpiresAt }
105
+ : {}),
106
+ };
107
+ }
108
+ async function fetchSource(input) {
109
+ const archiveUrl = `https://api.github.com/repos/${input.claim.repoFullName}/tarball/${input.claim.commitSha}`;
110
+ const res = await input.httpFetch(archiveUrl, {
111
+ headers: {
112
+ accept: 'application/vnd.github+json',
113
+ authorization: `Bearer ${input.claim.githubInstallationToken}`,
114
+ 'user-agent': 'noodle-seed-builder',
115
+ 'x-github-api-version': '2022-11-28',
116
+ },
117
+ });
118
+ if (!res.ok)
119
+ throw new Error(`source fetch failed (HTTP ${res.status})`);
120
+ const archive = join(input.workDir, 'source.tar.gz');
121
+ await writeFile(archive, new Uint8Array(await res.arrayBuffer()));
122
+ const checkout = join(input.workDir, 'repo');
123
+ await mkdir(checkout, { recursive: true });
124
+ await runProcess(input.spawnProcess, 'tar', ['-xzf', archive, '--strip-components=1', '-C', checkout], { env: {} });
125
+ return input.claim.repoRoot !== undefined ? resolve(checkout, input.claim.repoRoot) : checkout;
126
+ }
127
+ function createCliManifestExporter(input) {
128
+ const cliBin = input.env.NOODLE_BUILDER_CLI_BIN ?? '/app/cli/dist/bin.js';
129
+ return async ({ entrypoint }) => {
130
+ const dir = await mkdtemp(join(tmpdir(), 'noodle-ghd-export-'));
131
+ const manifestPath = join(dir, 'manifest.json');
132
+ const connectorsPath = join(dir, 'connectors.json');
133
+ try {
134
+ const result = await runProcess(input.spawnProcess, process.execPath, [
135
+ cliBin,
136
+ 'export',
137
+ 'manifest',
138
+ entrypoint,
139
+ '--output',
140
+ manifestPath,
141
+ '--connectors-output',
142
+ connectorsPath,
143
+ ], { env: sanitizeBuilderChildEnv(input.env) });
144
+ if (result.stderr.length > 0)
145
+ input.stderr.write(result.stderr);
146
+ const manifest = await readFile(manifestPath, 'utf8');
147
+ const connectors = await readFile(connectorsPath, 'utf8').catch(() => undefined);
148
+ return {
149
+ manifest,
150
+ ...(connectors !== undefined && connectors.trim() !== '' ? { connectors } : {}),
151
+ };
152
+ }
153
+ finally {
154
+ await rm(dir, { recursive: true, force: true }).catch(() => undefined);
155
+ }
156
+ };
157
+ }
158
+ async function runProcess(spawnProcess, command, args, options) {
159
+ return new Promise((resolvePromise, reject) => {
160
+ const child = spawnProcess(command, [...args], {
161
+ ...options,
162
+ stdio: ['ignore', 'pipe', 'pipe'],
163
+ });
164
+ const stdout = [];
165
+ const stderr = [];
166
+ child.stdout?.on('data', (chunk) => stdout.push(Buffer.from(chunk)));
167
+ child.stderr?.on('data', (chunk) => stderr.push(Buffer.from(chunk)));
168
+ child.on('error', reject);
169
+ child.on('close', (code) => {
170
+ const out = Buffer.concat(stdout).toString('utf8');
171
+ const err = Buffer.concat(stderr).toString('utf8');
172
+ if (code === 0)
173
+ return resolvePromise({ stdout: out, stderr: err });
174
+ reject(new Error(`${command} exited ${code ?? 'without a status'}${err ? `: ${err}` : ''}`));
175
+ });
176
+ });
177
+ }
178
+ function requiredEnv(env, name) {
179
+ const value = env[name];
180
+ if (value === undefined || value.trim() === '')
181
+ throw new Error(`${name} is required`);
182
+ return value;
183
+ }
184
+ function trimTrailingSlash(value) {
185
+ return value.replace(/\/+$/, '');
186
+ }
187
+ function asRecord(value) {
188
+ return typeof value === 'object' && value !== null
189
+ ? value
190
+ : undefined;
191
+ }
192
+ //# sourceMappingURL=builder-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder-runner.js","sourceRoot":"","sources":["../../src/github/builder-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { DeployRunDispatchInput, DeployRunExecutor } from './deploy-run-executor.js';
2
+ export interface CloudRunJobsRunRequest {
3
+ readonly name: string;
4
+ readonly body: {
5
+ readonly overrides: {
6
+ readonly containerOverrides: readonly [
7
+ {
8
+ readonly env: readonly {
9
+ readonly name: string;
10
+ readonly value: string;
11
+ }[];
12
+ }
13
+ ];
14
+ readonly taskCount: number;
15
+ readonly timeout: string;
16
+ };
17
+ };
18
+ }
19
+ export interface CloudRunJobsRunClient {
20
+ runJob(request: CloudRunJobsRunRequest): Promise<void>;
21
+ }
22
+ export interface CloudRunJobExecutorOptions {
23
+ readonly project: string;
24
+ readonly region: string;
25
+ readonly job: string;
26
+ readonly environment: string;
27
+ readonly taskTimeoutSeconds?: number;
28
+ readonly client?: CloudRunJobsRunClient;
29
+ }
30
+ /**
31
+ * Production GHD-C3 executor: launches exactly one Cloud Run Job execution for a deploy run.
32
+ * It passes only routing metadata through execution overrides. The builder claims all sensitive
33
+ * credentials from the service after startup, authenticated as its runtime service account.
34
+ */
35
+ export declare class CloudRunJobExecutor implements DeployRunExecutor {
36
+ #private;
37
+ constructor(options: CloudRunJobExecutorOptions);
38
+ dispatch(input: DeployRunDispatchInput): Promise<void>;
39
+ }
40
+ export declare function cloudRunJobName(options: {
41
+ readonly project: string;
42
+ readonly region: string;
43
+ readonly job: string;
44
+ }): string;
45
+ //# sourceMappingURL=cloud-run-job-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-run-job-executor.d.ts","sourceRoot":"","sources":["../../src/github/cloud-run-job-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE;QACb,QAAQ,CAAC,SAAS,EAAE;YAClB,QAAQ,CAAC,kBAAkB,EAAE,SAAS;gBACpC;oBACE,QAAQ,CAAC,GAAG,EAAE,SAAS;wBAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;wBAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;qBAAE,EAAE,CAAC;iBAC5E;aACF,CAAC;YACF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;SAC1B,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;CACzC;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,iBAAiB;;gBAM/C,OAAO,EAAE,0BAA0B;IAOzC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAuB7D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,CAET"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Production GHD-C3 executor: launches exactly one Cloud Run Job execution for a deploy run.
3
+ * It passes only routing metadata through execution overrides. The builder claims all sensitive
4
+ * credentials from the service after startup, authenticated as its runtime service account.
5
+ */
6
+ export class CloudRunJobExecutor {
7
+ #name;
8
+ #environment;
9
+ #taskTimeoutSeconds;
10
+ #client;
11
+ constructor(options) {
12
+ this.#name = cloudRunJobName(options);
13
+ this.#environment = options.environment;
14
+ this.#taskTimeoutSeconds = options.taskTimeoutSeconds ?? 180;
15
+ this.#client = options.client ?? new GoogleCloudRunJobsRunClient();
16
+ }
17
+ async dispatch(input) {
18
+ const body = {
19
+ overrides: {
20
+ containerOverrides: [
21
+ {
22
+ env: [
23
+ { name: 'NOODLE_GHD_RUN_ID', value: input.run.runId },
24
+ { name: 'NOODLE_GHD_SERVICE_BASE_URL', value: input.serviceBaseUrl },
25
+ { name: 'NOODLE_GHD_ENVIRONMENT', value: this.#environment },
26
+ ],
27
+ },
28
+ ],
29
+ taskCount: 1,
30
+ timeout: `${this.#taskTimeoutSeconds}s`,
31
+ },
32
+ };
33
+ try {
34
+ await this.#client.runJob({ name: this.#name, body });
35
+ }
36
+ catch {
37
+ // Fire-and-forget contract: dispatch launch failures must not make webhook delivery fail.
38
+ // The sweeper/reconciler owns retry/failover behavior.
39
+ }
40
+ }
41
+ }
42
+ export function cloudRunJobName(options) {
43
+ return `projects/${options.project}/locations/${options.region}/jobs/${options.job}`;
44
+ }
45
+ class GoogleCloudRunJobsRunClient {
46
+ #authPromise;
47
+ async runJob(request) {
48
+ const auth = await this.#auth();
49
+ const client = await auth.getClient();
50
+ const url = `https://run.googleapis.com/v2/${request.name}:run`;
51
+ await client.request({
52
+ url,
53
+ method: 'POST',
54
+ data: request.body,
55
+ });
56
+ }
57
+ #auth() {
58
+ this.#authPromise ??= import('google-auth-library').then(({ GoogleAuth }) => new GoogleAuth({
59
+ scopes: ['https://www.googleapis.com/auth/cloud-platform'],
60
+ }));
61
+ return this.#authPromise;
62
+ }
63
+ }
64
+ //# sourceMappingURL=cloud-run-job-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-run-job-executor.js","sourceRoot":"","sources":["../../src/github/cloud-run-job-executor.ts"],"names":[],"mappings":"AA8BA;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IACrB,KAAK,CAAS;IACd,YAAY,CAAS;IACrB,mBAAmB,CAAS;IAC5B,OAAO,CAAwB;IAExC,YAAY,OAAmC;QAC7C,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;QACxC,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,IAAI,GAAG,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,2BAA2B,EAAE,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAA6B;QAC1C,MAAM,IAAI,GAAmC;YAC3C,SAAS,EAAE;gBACT,kBAAkB,EAAE;oBAClB;wBACE,GAAG,EAAE;4BACH,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE;4BACrD,EAAE,IAAI,EAAE,6BAA6B,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE;4BACpE,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE;yBAC7D;qBACF;iBACF;gBACD,SAAS,EAAE,CAAC;gBACZ,OAAO,EAAE,GAAG,IAAI,CAAC,mBAAmB,GAAG;aACxC;SACF,CAAC;QACF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,0FAA0F;YAC1F,uDAAuD;QACzD,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,OAI/B;IACC,OAAO,YAAY,OAAO,CAAC,OAAO,cAAc,OAAO,CAAC,MAAM,SAAS,OAAO,CAAC,GAAG,EAAE,CAAC;AACvF,CAAC;AAED,MAAM,2BAA2B;IAC/B,YAAY,CAAqD;IAEjE,KAAK,CAAC,MAAM,CAAC,OAA+B;QAC1C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,iCAAiC,OAAO,CAAC,IAAI,MAAM,CAAC;QAChE,MAAM,MAAM,CAAC,OAAO,CAAC;YACnB,GAAG;YACH,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CACtD,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CACjB,IAAI,UAAU,CAAC;YACb,MAAM,EAAE,CAAC,gDAAgD,CAAC;SAC3D,CAAC,CACL,CAAC;QACF,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,64 @@
1
+ import type { PreparedPackagedAsset } from '@noodle-borg/compiler';
2
+ import type { DeployRunRecord } from '../store.js';
3
+ /**
4
+ * The environment-agnostic untrusted-compile → trusted-deploy pipeline (GHD-3, ADR 0132 Decision 6).
5
+ * Every executor — LocalProcess (C2), CloudRunJob (C3), the E2E harness — shares THIS orchestration;
6
+ * only the injected `compile` (how source becomes a manifest) and `httpFetch` (the wire) differ.
7
+ *
8
+ * The trust split is structural: `compile` runs untrusted source and is NEVER handed the run token or
9
+ * any privileged credential — it only reads files and returns data. Only after it succeeds does the
10
+ * pipeline use the run-scoped token to preflight/upload assets and POST the deploy.
11
+ *
12
+ * Debuggability is the organizing principle (the founder directive): the pipeline walks the run
13
+ * `building → deploying → deployed`, and EVERY failure path reports `failed` with a pre-redacted
14
+ * `errorSummary` that names the stage, the reason, and (via the route's own message) the fix — the
15
+ * exact text `noodle github runs <id>` surfaces. Status reporting is best-effort: a dropped status
16
+ * report is observability loss, never a reason to fail a deploy that otherwise succeeded.
17
+ */
18
+ /**
19
+ * One asset the worker must upload: its preflight metadata plus the bytes to PUT. `prepared` is the
20
+ * wire shape (no `absolutePath` — that stays in the sandbox; only the compile step reads bytes from it).
21
+ */
22
+ export interface PipelineAsset {
23
+ readonly prepared: Omit<PreparedPackagedAsset, 'absolutePath'>;
24
+ readonly bytes: Uint8Array;
25
+ }
26
+ /** What the untrusted compile stage produces — everything the trusted deploy needs, nothing more. */
27
+ export interface CompiledDeployInput {
28
+ readonly manifest: string;
29
+ readonly connectors?: string;
30
+ readonly serverVersion?: string;
31
+ /** Declared access mode from committed `noodle.json`; the deploy route resolves inherit → declared. */
32
+ readonly declaredAccessMode?: string;
33
+ readonly assets?: readonly PipelineAsset[];
34
+ }
35
+ export type CompileStageResult = {
36
+ readonly ok: true;
37
+ readonly input: CompiledDeployInput;
38
+ } | {
39
+ readonly ok: false;
40
+ readonly errorSummary: string;
41
+ };
42
+ export type DeployStage = 'compile' | 'preflight' | 'upload' | 'deploy';
43
+ export type DeployPipelineOutcome = {
44
+ readonly status: 'deployed';
45
+ readonly deploymentId: string;
46
+ } | {
47
+ readonly status: 'superseded';
48
+ } | {
49
+ readonly status: 'failed';
50
+ readonly stage: DeployStage;
51
+ readonly errorSummary: string;
52
+ };
53
+ export interface DeployPipelineDeps {
54
+ readonly run: DeployRunRecord;
55
+ /** Run-scoped credential for the status + preflight + deploy calls (never handed to `compile`). */
56
+ readonly runToken: string;
57
+ readonly serviceBaseUrl: string;
58
+ /** Untrusted compile — reads source, returns data; MUST NOT receive the run token. */
59
+ readonly compile: (run: DeployRunRecord) => Promise<CompileStageResult>;
60
+ /** Injected so tests use a fake and executors use global `fetch`. */
61
+ readonly httpFetch: typeof fetch;
62
+ }
63
+ export declare function runDeployPipeline(deps: DeployPipelineDeps): Promise<DeployPipelineOutcome>;
64
+ //# sourceMappingURL=deploy-pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-pipeline.d.ts","sourceRoot":"","sources":["../../src/github/deploy-pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;IAC/D,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,qGAAqG;AACrG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,uGAAuG;IACvG,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExE,MAAM,MAAM,qBAAqB,GAC7B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACjC;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,mGAAmG;IACnG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,sFAAsF;IACtF,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxE,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,OAAO,KAAK,CAAC;CAClC;AA0BD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA0HhG"}