thevoidforge 21.0.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 (328) hide show
  1. package/dist/scripts/vault-read.d.ts +11 -0
  2. package/dist/scripts/vault-read.js +89 -0
  3. package/dist/scripts/voidforge.d.ts +20 -0
  4. package/dist/scripts/voidforge.js +404 -0
  5. package/dist/tsconfig.tsbuildinfo +1 -0
  6. package/dist/wizard/api/auth.d.ts +5 -0
  7. package/dist/wizard/api/auth.js +133 -0
  8. package/dist/wizard/api/blueprint.d.ts +45 -0
  9. package/dist/wizard/api/blueprint.js +184 -0
  10. package/dist/wizard/api/cloud-providers.d.ts +16 -0
  11. package/dist/wizard/api/cloud-providers.js +363 -0
  12. package/dist/wizard/api/credentials.d.ts +1 -0
  13. package/dist/wizard/api/credentials.js +258 -0
  14. package/dist/wizard/api/danger-room.d.ts +18 -0
  15. package/dist/wizard/api/danger-room.js +401 -0
  16. package/dist/wizard/api/deploy.d.ts +4 -0
  17. package/dist/wizard/api/deploy.js +164 -0
  18. package/dist/wizard/api/prd.d.ts +1 -0
  19. package/dist/wizard/api/prd.js +363 -0
  20. package/dist/wizard/api/project.d.ts +1 -0
  21. package/dist/wizard/api/project.js +239 -0
  22. package/dist/wizard/api/projects.d.ts +6 -0
  23. package/dist/wizard/api/projects.js +648 -0
  24. package/dist/wizard/api/provision.d.ts +4 -0
  25. package/dist/wizard/api/provision.js +535 -0
  26. package/dist/wizard/api/terminal.d.ts +25 -0
  27. package/dist/wizard/api/terminal.js +241 -0
  28. package/dist/wizard/api/users.d.ts +6 -0
  29. package/dist/wizard/api/users.js +244 -0
  30. package/dist/wizard/api/war-room.d.ts +14 -0
  31. package/dist/wizard/api/war-room.js +45 -0
  32. package/dist/wizard/lib/ad-platform-core.d.ts +6 -0
  33. package/dist/wizard/lib/ad-platform-core.js +1 -0
  34. package/dist/wizard/lib/adapters/index.d.ts +52 -0
  35. package/dist/wizard/lib/adapters/index.js +38 -0
  36. package/dist/wizard/lib/adapters/sandbox-bank.d.ts +17 -0
  37. package/dist/wizard/lib/adapters/sandbox-bank.js +77 -0
  38. package/dist/wizard/lib/adapters/sandbox.d.ts +39 -0
  39. package/dist/wizard/lib/adapters/sandbox.js +174 -0
  40. package/dist/wizard/lib/adapters/stripe.d.ts +19 -0
  41. package/dist/wizard/lib/adapters/stripe.js +143 -0
  42. package/dist/wizard/lib/adapters/types.d.ts +9 -0
  43. package/dist/wizard/lib/adapters/types.js +10 -0
  44. package/dist/wizard/lib/agent-memory.d.ts +36 -0
  45. package/dist/wizard/lib/agent-memory.js +114 -0
  46. package/dist/wizard/lib/anomaly-detection.d.ts +59 -0
  47. package/dist/wizard/lib/anomaly-detection.js +122 -0
  48. package/dist/wizard/lib/anthropic.d.ts +21 -0
  49. package/dist/wizard/lib/anthropic.js +105 -0
  50. package/dist/wizard/lib/asset-scanner.d.ts +23 -0
  51. package/dist/wizard/lib/asset-scanner.js +107 -0
  52. package/dist/wizard/lib/audit-log.d.ts +23 -0
  53. package/dist/wizard/lib/audit-log.js +70 -0
  54. package/dist/wizard/lib/autonomy-controller.d.ts +76 -0
  55. package/dist/wizard/lib/autonomy-controller.js +183 -0
  56. package/dist/wizard/lib/body-parser.d.ts +2 -0
  57. package/dist/wizard/lib/body-parser.js +36 -0
  58. package/dist/wizard/lib/build-analytics.d.ts +39 -0
  59. package/dist/wizard/lib/build-analytics.js +91 -0
  60. package/dist/wizard/lib/build-step.d.ts +21 -0
  61. package/dist/wizard/lib/build-step.js +104 -0
  62. package/dist/wizard/lib/campaign-proposer.d.ts +39 -0
  63. package/dist/wizard/lib/campaign-proposer.js +180 -0
  64. package/dist/wizard/lib/campaign-state-machine.d.ts +63 -0
  65. package/dist/wizard/lib/campaign-state-machine.js +114 -0
  66. package/dist/wizard/lib/ci-generator.d.ts +14 -0
  67. package/dist/wizard/lib/ci-generator.js +187 -0
  68. package/dist/wizard/lib/claude-merge.d.ts +38 -0
  69. package/dist/wizard/lib/claude-merge.js +115 -0
  70. package/dist/wizard/lib/codegen/erd-gen.d.ts +16 -0
  71. package/dist/wizard/lib/codegen/erd-gen.js +98 -0
  72. package/dist/wizard/lib/codegen/integrations.d.ts +18 -0
  73. package/dist/wizard/lib/codegen/integrations.js +189 -0
  74. package/dist/wizard/lib/codegen/openapi-gen.d.ts +15 -0
  75. package/dist/wizard/lib/codegen/openapi-gen.js +79 -0
  76. package/dist/wizard/lib/codegen/prisma-types.d.ts +15 -0
  77. package/dist/wizard/lib/codegen/prisma-types.js +44 -0
  78. package/dist/wizard/lib/codegen/seed-gen.d.ts +16 -0
  79. package/dist/wizard/lib/codegen/seed-gen.js +128 -0
  80. package/dist/wizard/lib/compliance.d.ts +51 -0
  81. package/dist/wizard/lib/compliance.js +112 -0
  82. package/dist/wizard/lib/correlation-engine.d.ts +59 -0
  83. package/dist/wizard/lib/correlation-engine.js +151 -0
  84. package/dist/wizard/lib/cost-estimator.d.ts +22 -0
  85. package/dist/wizard/lib/cost-estimator.js +72 -0
  86. package/dist/wizard/lib/cost-tracker.d.ts +27 -0
  87. package/dist/wizard/lib/cost-tracker.js +37 -0
  88. package/dist/wizard/lib/daemon-aggregator.d.ts +71 -0
  89. package/dist/wizard/lib/daemon-aggregator.js +204 -0
  90. package/dist/wizard/lib/daemon-core.d.ts +6 -0
  91. package/dist/wizard/lib/daemon-core.js +5 -0
  92. package/dist/wizard/lib/dashboard-data.d.ts +132 -0
  93. package/dist/wizard/lib/dashboard-data.js +336 -0
  94. package/dist/wizard/lib/dashboard-ws.d.ts +25 -0
  95. package/dist/wizard/lib/dashboard-ws.js +91 -0
  96. package/dist/wizard/lib/deep-current.d.ts +77 -0
  97. package/dist/wizard/lib/deep-current.js +234 -0
  98. package/dist/wizard/lib/deploy-coordinator.d.ts +40 -0
  99. package/dist/wizard/lib/deploy-coordinator.js +86 -0
  100. package/dist/wizard/lib/deploy-log.d.ts +28 -0
  101. package/dist/wizard/lib/deploy-log.js +52 -0
  102. package/dist/wizard/lib/desktop-notify.d.ts +27 -0
  103. package/dist/wizard/lib/desktop-notify.js +98 -0
  104. package/dist/wizard/lib/dns/cloudflare-dns.d.ts +35 -0
  105. package/dist/wizard/lib/dns/cloudflare-dns.js +216 -0
  106. package/dist/wizard/lib/dns/cloudflare-registrar.d.ts +31 -0
  107. package/dist/wizard/lib/dns/cloudflare-registrar.js +148 -0
  108. package/dist/wizard/lib/dns/types.d.ts +22 -0
  109. package/dist/wizard/lib/dns/types.js +4 -0
  110. package/dist/wizard/lib/document-discovery.d.ts +33 -0
  111. package/dist/wizard/lib/document-discovery.js +145 -0
  112. package/dist/wizard/lib/env-validator.d.ts +14 -0
  113. package/dist/wizard/lib/env-validator.js +205 -0
  114. package/dist/wizard/lib/env-writer.d.ts +13 -0
  115. package/dist/wizard/lib/env-writer.js +26 -0
  116. package/dist/wizard/lib/exec.d.ts +30 -0
  117. package/dist/wizard/lib/exec.js +52 -0
  118. package/dist/wizard/lib/experiment.d.ts +70 -0
  119. package/dist/wizard/lib/experiment.js +169 -0
  120. package/dist/wizard/lib/extensions.d.ts +20 -0
  121. package/dist/wizard/lib/extensions.js +183 -0
  122. package/dist/wizard/lib/financial/adapter-factory.d.ts +47 -0
  123. package/dist/wizard/lib/financial/adapter-factory.js +225 -0
  124. package/dist/wizard/lib/financial/billing/base.d.ts +6 -0
  125. package/dist/wizard/lib/financial/billing/base.js +1 -0
  126. package/dist/wizard/lib/financial/billing/google-billing.d.ts +56 -0
  127. package/dist/wizard/lib/financial/billing/google-billing.js +298 -0
  128. package/dist/wizard/lib/financial/billing/meta-billing.d.ts +54 -0
  129. package/dist/wizard/lib/financial/billing/meta-billing.js +243 -0
  130. package/dist/wizard/lib/financial/billing/tiktok-billing.d.ts +54 -0
  131. package/dist/wizard/lib/financial/billing/tiktok-billing.js +260 -0
  132. package/dist/wizard/lib/financial/campaign/base.d.ts +13 -0
  133. package/dist/wizard/lib/financial/campaign/base.js +1 -0
  134. package/dist/wizard/lib/financial/campaign/google-campaign.d.ts +42 -0
  135. package/dist/wizard/lib/financial/campaign/google-campaign.js +388 -0
  136. package/dist/wizard/lib/financial/campaign/meta-campaign.d.ts +41 -0
  137. package/dist/wizard/lib/financial/campaign/meta-campaign.js +311 -0
  138. package/dist/wizard/lib/financial/campaign/sandbox-campaign.d.ts +45 -0
  139. package/dist/wizard/lib/financial/campaign/sandbox-campaign.js +261 -0
  140. package/dist/wizard/lib/financial/campaign/tiktok-campaign.d.ts +40 -0
  141. package/dist/wizard/lib/financial/campaign/tiktok-campaign.js +350 -0
  142. package/dist/wizard/lib/financial/funding-auto.d.ts +44 -0
  143. package/dist/wizard/lib/financial/funding-auto.js +52 -0
  144. package/dist/wizard/lib/financial/funding-policy.d.ts +60 -0
  145. package/dist/wizard/lib/financial/funding-policy.js +179 -0
  146. package/dist/wizard/lib/financial/platform-planner.d.ts +47 -0
  147. package/dist/wizard/lib/financial/platform-planner.js +134 -0
  148. package/dist/wizard/lib/financial/reconciliation-engine.d.ts +78 -0
  149. package/dist/wizard/lib/financial/reconciliation-engine.js +193 -0
  150. package/dist/wizard/lib/financial/registry.d.ts +22 -0
  151. package/dist/wizard/lib/financial/registry.js +26 -0
  152. package/dist/wizard/lib/financial/reporting.d.ts +96 -0
  153. package/dist/wizard/lib/financial/reporting.js +198 -0
  154. package/dist/wizard/lib/financial/stablecoin/base.d.ts +6 -0
  155. package/dist/wizard/lib/financial/stablecoin/base.js +1 -0
  156. package/dist/wizard/lib/financial/stablecoin/circle.d.ts +54 -0
  157. package/dist/wizard/lib/financial/stablecoin/circle.js +367 -0
  158. package/dist/wizard/lib/financial/stablecoin/mercury.d.ts +24 -0
  159. package/dist/wizard/lib/financial/stablecoin/mercury.js +171 -0
  160. package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.d.ts +47 -0
  161. package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.js +202 -0
  162. package/dist/wizard/lib/financial/treasury-planner.d.ts +52 -0
  163. package/dist/wizard/lib/financial/treasury-planner.js +128 -0
  164. package/dist/wizard/lib/financial-core.d.ts +6 -0
  165. package/dist/wizard/lib/financial-core.js +5 -0
  166. package/dist/wizard/lib/financial-vault.d.ts +34 -0
  167. package/dist/wizard/lib/financial-vault.js +199 -0
  168. package/dist/wizard/lib/frontmatter.d.ts +30 -0
  169. package/dist/wizard/lib/frontmatter.js +96 -0
  170. package/dist/wizard/lib/gap-analysis.d.ts +37 -0
  171. package/dist/wizard/lib/gap-analysis.js +218 -0
  172. package/dist/wizard/lib/github.d.ts +22 -0
  173. package/dist/wizard/lib/github.js +261 -0
  174. package/dist/wizard/lib/headless-deploy.d.ts +14 -0
  175. package/dist/wizard/lib/headless-deploy.js +452 -0
  176. package/dist/wizard/lib/health-monitor.d.ts +15 -0
  177. package/dist/wizard/lib/health-monitor.js +91 -0
  178. package/dist/wizard/lib/health-poller.d.ts +9 -0
  179. package/dist/wizard/lib/health-poller.js +123 -0
  180. package/dist/wizard/lib/heartbeat.d.ts +15 -0
  181. package/dist/wizard/lib/heartbeat.js +827 -0
  182. package/dist/wizard/lib/http-helpers.d.ts +9 -0
  183. package/dist/wizard/lib/http-helpers.js +24 -0
  184. package/dist/wizard/lib/image-gen.d.ts +56 -0
  185. package/dist/wizard/lib/image-gen.js +159 -0
  186. package/dist/wizard/lib/instance-sizing.d.ts +26 -0
  187. package/dist/wizard/lib/instance-sizing.js +51 -0
  188. package/dist/wizard/lib/kongo/analytics.d.ts +29 -0
  189. package/dist/wizard/lib/kongo/analytics.js +179 -0
  190. package/dist/wizard/lib/kongo/campaigns.d.ts +52 -0
  191. package/dist/wizard/lib/kongo/campaigns.js +91 -0
  192. package/dist/wizard/lib/kongo/client.d.ts +58 -0
  193. package/dist/wizard/lib/kongo/client.js +221 -0
  194. package/dist/wizard/lib/kongo/jobs.d.ts +57 -0
  195. package/dist/wizard/lib/kongo/jobs.js +122 -0
  196. package/dist/wizard/lib/kongo/pages.d.ts +60 -0
  197. package/dist/wizard/lib/kongo/pages.js +150 -0
  198. package/dist/wizard/lib/kongo/provisioner.d.ts +64 -0
  199. package/dist/wizard/lib/kongo/provisioner.js +116 -0
  200. package/dist/wizard/lib/kongo/seed.d.ts +49 -0
  201. package/dist/wizard/lib/kongo/seed.js +237 -0
  202. package/dist/wizard/lib/kongo/types.d.ts +323 -0
  203. package/dist/wizard/lib/kongo/types.js +11 -0
  204. package/dist/wizard/lib/kongo/variants.d.ts +57 -0
  205. package/dist/wizard/lib/kongo/variants.js +88 -0
  206. package/dist/wizard/lib/kongo/webhooks.d.ts +41 -0
  207. package/dist/wizard/lib/kongo/webhooks.js +112 -0
  208. package/dist/wizard/lib/marker.d.ts +28 -0
  209. package/dist/wizard/lib/marker.js +79 -0
  210. package/dist/wizard/lib/migrator.d.ts +35 -0
  211. package/dist/wizard/lib/migrator.js +190 -0
  212. package/dist/wizard/lib/natural-language-deploy.d.ts +30 -0
  213. package/dist/wizard/lib/natural-language-deploy.js +186 -0
  214. package/dist/wizard/lib/network.d.ts +22 -0
  215. package/dist/wizard/lib/network.js +72 -0
  216. package/dist/wizard/lib/oauth-core.d.ts +6 -0
  217. package/dist/wizard/lib/oauth-core.js +5 -0
  218. package/dist/wizard/lib/open-browser.d.ts +1 -0
  219. package/dist/wizard/lib/open-browser.js +26 -0
  220. package/dist/wizard/lib/patterns/ad-billing-adapter.d.ts +209 -0
  221. package/dist/wizard/lib/patterns/ad-billing-adapter.js +269 -0
  222. package/dist/wizard/lib/patterns/ad-platform-adapter.d.ts +200 -0
  223. package/dist/wizard/lib/patterns/ad-platform-adapter.js +212 -0
  224. package/dist/wizard/lib/patterns/daemon-process.d.ts +88 -0
  225. package/dist/wizard/lib/patterns/daemon-process.js +271 -0
  226. package/dist/wizard/lib/patterns/financial-transaction.d.ts +161 -0
  227. package/dist/wizard/lib/patterns/financial-transaction.js +132 -0
  228. package/dist/wizard/lib/patterns/funding-plan.d.ts +136 -0
  229. package/dist/wizard/lib/patterns/funding-plan.js +200 -0
  230. package/dist/wizard/lib/patterns/oauth-token-lifecycle.d.ts +94 -0
  231. package/dist/wizard/lib/patterns/oauth-token-lifecycle.js +139 -0
  232. package/dist/wizard/lib/patterns/outbound-rate-limiter.d.ts +67 -0
  233. package/dist/wizard/lib/patterns/outbound-rate-limiter.js +216 -0
  234. package/dist/wizard/lib/patterns/revenue-source-adapter.d.ts +96 -0
  235. package/dist/wizard/lib/patterns/revenue-source-adapter.js +182 -0
  236. package/dist/wizard/lib/patterns/stablecoin-adapter.d.ts +218 -0
  237. package/dist/wizard/lib/patterns/stablecoin-adapter.js +264 -0
  238. package/dist/wizard/lib/prd-validator.d.ts +39 -0
  239. package/dist/wizard/lib/prd-validator.js +137 -0
  240. package/dist/wizard/lib/project-init.d.ts +24 -0
  241. package/dist/wizard/lib/project-init.js +193 -0
  242. package/dist/wizard/lib/project-registry.d.ts +86 -0
  243. package/dist/wizard/lib/project-registry.js +359 -0
  244. package/dist/wizard/lib/provision-manifest.d.ts +44 -0
  245. package/dist/wizard/lib/provision-manifest.js +164 -0
  246. package/dist/wizard/lib/provisioner-registry.d.ts +15 -0
  247. package/dist/wizard/lib/provisioner-registry.js +34 -0
  248. package/dist/wizard/lib/provisioners/aws-vps.d.ts +6 -0
  249. package/dist/wizard/lib/provisioners/aws-vps.js +643 -0
  250. package/dist/wizard/lib/provisioners/cloudflare.d.ts +6 -0
  251. package/dist/wizard/lib/provisioners/cloudflare.js +300 -0
  252. package/dist/wizard/lib/provisioners/docker.d.ts +6 -0
  253. package/dist/wizard/lib/provisioners/docker.js +75 -0
  254. package/dist/wizard/lib/provisioners/http-client.d.ts +20 -0
  255. package/dist/wizard/lib/provisioners/http-client.js +79 -0
  256. package/dist/wizard/lib/provisioners/railway.d.ts +6 -0
  257. package/dist/wizard/lib/provisioners/railway.js +413 -0
  258. package/dist/wizard/lib/provisioners/scripts/caddyfile.d.ts +10 -0
  259. package/dist/wizard/lib/provisioners/scripts/caddyfile.js +54 -0
  260. package/dist/wizard/lib/provisioners/scripts/deploy-vps.d.ts +10 -0
  261. package/dist/wizard/lib/provisioners/scripts/deploy-vps.js +112 -0
  262. package/dist/wizard/lib/provisioners/scripts/docker-compose.d.ts +11 -0
  263. package/dist/wizard/lib/provisioners/scripts/docker-compose.js +91 -0
  264. package/dist/wizard/lib/provisioners/scripts/dockerfile.d.ts +5 -0
  265. package/dist/wizard/lib/provisioners/scripts/dockerfile.js +185 -0
  266. package/dist/wizard/lib/provisioners/scripts/ecosystem-config.d.ts +10 -0
  267. package/dist/wizard/lib/provisioners/scripts/ecosystem-config.js +36 -0
  268. package/dist/wizard/lib/provisioners/scripts/provision-vps.d.ts +14 -0
  269. package/dist/wizard/lib/provisioners/scripts/provision-vps.js +202 -0
  270. package/dist/wizard/lib/provisioners/scripts/rollback-vps.d.ts +10 -0
  271. package/dist/wizard/lib/provisioners/scripts/rollback-vps.js +67 -0
  272. package/dist/wizard/lib/provisioners/self-deploy.d.ts +41 -0
  273. package/dist/wizard/lib/provisioners/self-deploy.js +185 -0
  274. package/dist/wizard/lib/provisioners/static-s3.d.ts +6 -0
  275. package/dist/wizard/lib/provisioners/static-s3.js +235 -0
  276. package/dist/wizard/lib/provisioners/types.d.ts +40 -0
  277. package/dist/wizard/lib/provisioners/types.js +4 -0
  278. package/dist/wizard/lib/provisioners/vercel.d.ts +6 -0
  279. package/dist/wizard/lib/provisioners/vercel.js +287 -0
  280. package/dist/wizard/lib/pty-manager.d.ts +42 -0
  281. package/dist/wizard/lib/pty-manager.js +231 -0
  282. package/dist/wizard/lib/rate-limiter-core.d.ts +5 -0
  283. package/dist/wizard/lib/rate-limiter-core.js +5 -0
  284. package/dist/wizard/lib/reconciliation.d.ts +43 -0
  285. package/dist/wizard/lib/reconciliation.js +173 -0
  286. package/dist/wizard/lib/revenue-types.d.ts +5 -0
  287. package/dist/wizard/lib/revenue-types.js +1 -0
  288. package/dist/wizard/lib/route-optimizer.d.ts +28 -0
  289. package/dist/wizard/lib/route-optimizer.js +93 -0
  290. package/dist/wizard/lib/s3-deploy.d.ts +19 -0
  291. package/dist/wizard/lib/s3-deploy.js +156 -0
  292. package/dist/wizard/lib/safety-tiers.d.ts +76 -0
  293. package/dist/wizard/lib/safety-tiers.js +134 -0
  294. package/dist/wizard/lib/sentry-generator.d.ts +15 -0
  295. package/dist/wizard/lib/sentry-generator.js +116 -0
  296. package/dist/wizard/lib/server-config.d.ts +13 -0
  297. package/dist/wizard/lib/server-config.js +23 -0
  298. package/dist/wizard/lib/service-install.d.ts +18 -0
  299. package/dist/wizard/lib/service-install.js +182 -0
  300. package/dist/wizard/lib/site-scanner.d.ts +80 -0
  301. package/dist/wizard/lib/site-scanner.js +262 -0
  302. package/dist/wizard/lib/ssh-deploy.d.ts +25 -0
  303. package/dist/wizard/lib/ssh-deploy.js +225 -0
  304. package/dist/wizard/lib/templates.d.ts +24 -0
  305. package/dist/wizard/lib/templates.js +219 -0
  306. package/dist/wizard/lib/totp.d.ts +35 -0
  307. package/dist/wizard/lib/totp.js +276 -0
  308. package/dist/wizard/lib/tower-auth.d.ts +43 -0
  309. package/dist/wizard/lib/tower-auth.js +352 -0
  310. package/dist/wizard/lib/tower-rate-limit.d.ts +14 -0
  311. package/dist/wizard/lib/tower-rate-limit.js +61 -0
  312. package/dist/wizard/lib/tower-session.d.ts +28 -0
  313. package/dist/wizard/lib/tower-session.js +119 -0
  314. package/dist/wizard/lib/treasury-backup.d.ts +23 -0
  315. package/dist/wizard/lib/treasury-backup.js +126 -0
  316. package/dist/wizard/lib/treasury-heartbeat.d.ts +82 -0
  317. package/dist/wizard/lib/treasury-heartbeat.js +1104 -0
  318. package/dist/wizard/lib/updater.d.ts +29 -0
  319. package/dist/wizard/lib/updater.js +190 -0
  320. package/dist/wizard/lib/user-manager.d.ts +39 -0
  321. package/dist/wizard/lib/user-manager.js +182 -0
  322. package/dist/wizard/lib/vault.d.ts +26 -0
  323. package/dist/wizard/lib/vault.js +161 -0
  324. package/dist/wizard/router.d.ts +5 -0
  325. package/dist/wizard/router.js +15 -0
  326. package/dist/wizard/server.d.ts +18 -0
  327. package/dist/wizard/server.js +436 -0
  328. package/package.json +59 -0
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Cloudflare provisioner — creates a real Workers/Pages project via API + generates wrangler.toml.
3
+ * v3.8.0: Includes GitHub source at creation time for auto-deploy (ADR-011, ADR-015).
4
+ */
5
+ import { writeFile } from 'node:fs/promises';
6
+ import { join } from 'node:path';
7
+ import { httpsPost, httpsGet, httpsDelete, safeJsonParse, slugify } from './http-client.js';
8
+ import { recordResourcePending, recordResourceCreated } from '../provision-manifest.js';
9
+ import { appendEnvSection } from '../env-writer.js';
10
+ const DEPLOY_POLL_INTERVAL_MS = 5000;
11
+ const DEPLOY_POLL_TIMEOUT_MS = 300_000;
12
+ export const cloudflareProvisioner = {
13
+ async validate(ctx) {
14
+ const errors = [];
15
+ if (!ctx.projectDir)
16
+ errors.push('Project directory is required');
17
+ if (!ctx.credentials['cloudflare-api-token'])
18
+ errors.push('Cloudflare API token is required');
19
+ return errors;
20
+ },
21
+ async provision(ctx, emit) {
22
+ const files = [];
23
+ const resources = [];
24
+ const outputs = {};
25
+ const token = ctx.credentials['cloudflare-api-token'];
26
+ const slug = slugify(ctx.projectName);
27
+ const headers = {
28
+ 'Authorization': `Bearer ${token}`,
29
+ 'Content-Type': 'application/json',
30
+ };
31
+ // Step 1: Get account ID
32
+ emit({ step: 'cf-account', status: 'started', message: 'Fetching Cloudflare account' });
33
+ let accountId = '';
34
+ try {
35
+ const res = await httpsGet('api.cloudflare.com', '/client/v4/accounts?page=1&per_page=1', {
36
+ 'Authorization': `Bearer ${token}`,
37
+ });
38
+ if (res.status !== 200) {
39
+ throw new Error(`Cloudflare API returned ${res.status}`);
40
+ }
41
+ const data = safeJsonParse(res.body);
42
+ if (!data?.success || !data?.result || data.result.length === 0) {
43
+ throw new Error('No Cloudflare account found for this token');
44
+ }
45
+ accountId = data.result[0].id;
46
+ outputs['CF_ACCOUNT_ID'] = accountId;
47
+ emit({ step: 'cf-account', status: 'done', message: `Account: ${data.result[0].name}` });
48
+ }
49
+ catch (err) {
50
+ emit({ step: 'cf-account', status: 'error', message: 'Failed to fetch Cloudflare account', detail: err.message });
51
+ return { success: false, resources, outputs, files, error: err.message };
52
+ }
53
+ // GitHub source info (used in project creation and deploy polling)
54
+ const ghOwner = ctx.credentials['_github-owner'];
55
+ const ghRepo = ctx.credentials['_github-repo-name'];
56
+ // Step 2: Create Pages project
57
+ emit({ step: 'cf-project', status: 'started', message: 'Creating Cloudflare Pages project' });
58
+ try {
59
+ await recordResourcePending(ctx.runId, 'cf-pages-project', slug, 'global');
60
+ const projectPayload = {
61
+ name: slug,
62
+ production_branch: 'main',
63
+ };
64
+ if (ghOwner && ghRepo) {
65
+ projectPayload.source = {
66
+ type: 'github',
67
+ config: {
68
+ owner: ghOwner,
69
+ repo_name: ghRepo,
70
+ production_branch: 'main',
71
+ pr_comments_enabled: true,
72
+ deployments_enabled: true,
73
+ },
74
+ };
75
+ projectPayload.build_config = {
76
+ build_command: ctx.framework === 'django' ? '' : 'npm run build',
77
+ destination_dir: ctx.framework === 'next.js' ? 'out' : 'dist',
78
+ };
79
+ }
80
+ const body = JSON.stringify(projectPayload);
81
+ const res = await httpsPost('api.cloudflare.com', `/client/v4/accounts/${accountId}/pages/projects`, headers, body);
82
+ if (res.status === 200 || res.status === 201) {
83
+ const data = safeJsonParse(res.body);
84
+ const projectName = data?.result?.name ?? slug;
85
+ const subdomain = data?.result?.subdomain ?? `${slug}.pages.dev`;
86
+ resources.push({ type: 'cf-pages-project', id: projectName, region: 'global' });
87
+ await recordResourceCreated(ctx.runId, 'cf-pages-project', projectName, 'global');
88
+ outputs['CF_PROJECT_NAME'] = projectName;
89
+ outputs['CF_PROJECT_URL'] = `https://${subdomain}`;
90
+ emit({ step: 'cf-project', status: 'done', message: `Pages project "${projectName}" created — ${subdomain}` });
91
+ }
92
+ else if (res.status === 409) {
93
+ // Project exists — track it so cleanup knows about it
94
+ resources.push({ type: 'cf-pages-project', id: slug, region: 'global' });
95
+ await recordResourceCreated(ctx.runId, 'cf-pages-project', slug, 'global');
96
+ emit({ step: 'cf-project', status: 'done', message: `Project "${slug}" already exists on Cloudflare — will use existing` });
97
+ outputs['CF_PROJECT_NAME'] = slug;
98
+ outputs['CF_PROJECT_URL'] = `https://${slug}.pages.dev`;
99
+ }
100
+ else {
101
+ const data = safeJsonParse(res.body);
102
+ const errMsg = data?.errors?.[0]?.message || `Cloudflare API returned ${res.status}`;
103
+ throw new Error(errMsg);
104
+ }
105
+ }
106
+ catch (err) {
107
+ emit({ step: 'cf-project', status: 'error', message: 'Failed to create Pages project', detail: err.message });
108
+ return { success: false, resources, outputs, files, error: err.message };
109
+ }
110
+ // Step 3: Add custom domain if hostname provided
111
+ const projectName = outputs['CF_PROJECT_NAME'] || slug;
112
+ if (ctx.hostname && accountId) {
113
+ emit({ step: 'cf-domain', status: 'started', message: `Adding domain ${ctx.hostname} to Pages project` });
114
+ try {
115
+ const domainBody = JSON.stringify({ name: ctx.hostname });
116
+ const domainRes = await httpsPost('api.cloudflare.com', `/client/v4/accounts/${accountId}/pages/projects/${projectName}/domains`, headers, domainBody);
117
+ if (domainRes.status === 200 || domainRes.status === 201) {
118
+ outputs['CF_CUSTOM_DOMAIN'] = ctx.hostname;
119
+ emit({ step: 'cf-domain', status: 'done', message: `Domain "${ctx.hostname}" added to Pages project` });
120
+ }
121
+ else if (domainRes.status === 409) {
122
+ emit({ step: 'cf-domain', status: 'done', message: `Domain "${ctx.hostname}" already configured on Pages project` });
123
+ outputs['CF_CUSTOM_DOMAIN'] = ctx.hostname;
124
+ }
125
+ else {
126
+ const errData = safeJsonParse(domainRes.body);
127
+ throw new Error(errData?.errors?.[0]?.message || `Pages domains API returned ${domainRes.status}`);
128
+ }
129
+ }
130
+ catch (err) {
131
+ emit({ step: 'cf-domain', status: 'error', message: 'Failed to add domain to Pages project', detail: err.message });
132
+ // Non-fatal
133
+ }
134
+ }
135
+ // Step 4: Create D1 database if requested
136
+ if (ctx.database === 'sqlite') {
137
+ emit({ step: 'cf-d1', status: 'started', message: 'Creating D1 database' });
138
+ try {
139
+ await recordResourcePending(ctx.runId, 'cf-d1-database', `${slug}-db`, 'global');
140
+ const body = JSON.stringify({ name: `${slug}-db` });
141
+ const res = await httpsPost('api.cloudflare.com', `/client/v4/accounts/${accountId}/d1/database`, headers, body);
142
+ if (res.status === 200 || res.status === 201) {
143
+ const data = safeJsonParse(res.body);
144
+ const dbId = data?.result?.uuid ?? '';
145
+ if (dbId) {
146
+ resources.push({ type: 'cf-d1-database', id: dbId, region: 'global' });
147
+ await recordResourceCreated(ctx.runId, 'cf-d1-database', dbId, 'global');
148
+ outputs['CF_D1_DATABASE_ID'] = dbId;
149
+ outputs['CF_D1_DATABASE_NAME'] = `${slug}-db`;
150
+ }
151
+ emit({ step: 'cf-d1', status: 'done', message: `D1 database "${slug}-db" created` });
152
+ }
153
+ else {
154
+ const data = safeJsonParse(res.body);
155
+ throw new Error(data?.errors?.[0]?.message || `D1 creation returned ${res.status}`);
156
+ }
157
+ }
158
+ catch (err) {
159
+ emit({ step: 'cf-d1', status: 'error', message: 'Failed to create D1 database', detail: err.message });
160
+ // Non-fatal
161
+ }
162
+ }
163
+ else {
164
+ emit({ step: 'cf-d1', status: 'skipped', message: 'No database requested' });
165
+ }
166
+ // Step 5: Generate wrangler.toml
167
+ emit({ step: 'cf-config', status: 'started', message: 'Generating wrangler.toml' });
168
+ try {
169
+ let config = `# wrangler.toml — Cloudflare Workers/Pages configuration
170
+ # Generated by VoidForge
171
+ # Deploy with: npx wrangler pages deploy ./dist
172
+
173
+ name = "${slug}"
174
+ compatibility_date = "${new Date().toISOString().slice(0, 10)}"
175
+ pages_build_output_dir = "./dist"
176
+
177
+ [vars]
178
+ ENVIRONMENT = "production"
179
+ `;
180
+ if (outputs['CF_D1_DATABASE_ID']) {
181
+ config += `
182
+ [[d1_databases]]
183
+ binding = "DB"
184
+ database_name = "${slug}-db"
185
+ database_id = "${outputs['CF_D1_DATABASE_ID']}"
186
+ `;
187
+ }
188
+ await writeFile(join(ctx.projectDir, 'wrangler.toml'), config, 'utf-8');
189
+ files.push('wrangler.toml');
190
+ emit({ step: 'cf-config', status: 'done', message: 'Generated wrangler.toml' });
191
+ }
192
+ catch (err) {
193
+ emit({ step: 'cf-config', status: 'error', message: 'Failed to write wrangler.toml', detail: err.message });
194
+ }
195
+ // Step 6: Poll for deployment (if GitHub-linked, deploy triggered by push)
196
+ if (ghOwner && ghRepo && accountId) {
197
+ emit({ step: 'cf-deploy', status: 'started', message: 'Waiting for Cloudflare Pages deployment...' });
198
+ try {
199
+ const start = Date.now();
200
+ let deployUrl = '';
201
+ while (Date.now() - start < DEPLOY_POLL_TIMEOUT_MS) {
202
+ await new Promise(r => setTimeout(r, DEPLOY_POLL_INTERVAL_MS));
203
+ if (ctx.abortSignal?.aborted)
204
+ break;
205
+ const depRes = await httpsGet('api.cloudflare.com', `/client/v4/accounts/${accountId}/pages/projects/${projectName}/deployments?sort_by=created_on&sort_order=desc&per_page=1`, { 'Authorization': `Bearer ${token}` });
206
+ if (depRes.status !== 200)
207
+ continue;
208
+ const depData = safeJsonParse(depRes.body);
209
+ const latest = depData?.result?.[0];
210
+ if (!latest)
211
+ continue;
212
+ const stage = latest.latest_stage;
213
+ if (stage?.name === 'deploy' && stage?.status === 'success') {
214
+ deployUrl = latest.url ? `https://${latest.url}` : outputs['CF_PROJECT_URL'] || '';
215
+ break;
216
+ }
217
+ if (stage?.status === 'failure') {
218
+ emit({ step: 'cf-deploy', status: 'error', message: 'Cloudflare Pages deployment failed', detail: 'Check the Cloudflare dashboard for build logs' });
219
+ break;
220
+ }
221
+ const elapsed = Math.round((Date.now() - start) / 1000);
222
+ if (elapsed % 15 === 0) {
223
+ emit({ step: 'cf-deploy', status: 'started', message: `Deploy status: ${stage?.name || 'queued'} / ${stage?.status || 'waiting'}... (${elapsed}s)` });
224
+ }
225
+ }
226
+ if (deployUrl) {
227
+ outputs['DEPLOY_URL'] = deployUrl;
228
+ emit({ step: 'cf-deploy', status: 'done', message: `Live at ${deployUrl}` });
229
+ }
230
+ else if (!ctx.abortSignal?.aborted) {
231
+ emit({ step: 'cf-deploy', status: 'error', message: 'Deployment polling timed out — check Cloudflare dashboard' });
232
+ }
233
+ }
234
+ catch (err) {
235
+ emit({ step: 'cf-deploy', status: 'error', message: 'Failed to poll deployment', detail: err.message });
236
+ }
237
+ }
238
+ else if (!ghOwner || !ghRepo) {
239
+ emit({ step: 'cf-deploy', status: 'skipped', message: 'No GitHub repo linked — deploy manually with: npx wrangler pages deploy ./dist' });
240
+ }
241
+ // Step 7: Write .env
242
+ emit({ step: 'cf-env', status: 'started', message: 'Writing Cloudflare config to .env' });
243
+ try {
244
+ const envLines = [
245
+ `# VoidForge Cloudflare — generated ${new Date().toISOString()}`,
246
+ `CF_ACCOUNT_ID=${accountId}`,
247
+ `CF_PROJECT_NAME=${outputs['CF_PROJECT_NAME'] || slug}`,
248
+ ];
249
+ if (outputs['CF_PROJECT_URL'])
250
+ envLines.push(`CF_PROJECT_URL=${outputs['CF_PROJECT_URL']}`);
251
+ if (outputs['CF_D1_DATABASE_ID'])
252
+ envLines.push(`CF_D1_DATABASE_ID=${outputs['CF_D1_DATABASE_ID']}`);
253
+ if (outputs['DEPLOY_URL'])
254
+ envLines.push(`DEPLOY_URL=${outputs['DEPLOY_URL']}`);
255
+ envLines.push(ghOwner ? '# Auto-deploys on push to main' : '# Deploy with: npx wrangler pages deploy ./dist');
256
+ await appendEnvSection(ctx.projectDir, envLines);
257
+ emit({ step: 'cf-env', status: 'done', message: 'Cloudflare config written to .env' });
258
+ }
259
+ catch (err) {
260
+ emit({ step: 'cf-env', status: 'error', message: 'Failed to write .env', detail: err.message });
261
+ }
262
+ return { success: true, resources, outputs, files };
263
+ },
264
+ async cleanup(resources, credentials) {
265
+ const token = credentials['cloudflare-api-token'];
266
+ if (!token)
267
+ return;
268
+ // Need account ID for API calls — fetch it
269
+ let accountId = '';
270
+ try {
271
+ const res = await httpsGet('api.cloudflare.com', '/client/v4/accounts?page=1&per_page=1', {
272
+ 'Authorization': `Bearer ${token}`,
273
+ });
274
+ const data = safeJsonParse(res.body);
275
+ accountId = data?.result?.[0]?.id ?? '';
276
+ }
277
+ catch {
278
+ return;
279
+ }
280
+ if (!accountId)
281
+ return;
282
+ for (const resource of [...resources].reverse()) {
283
+ try {
284
+ switch (resource.type) {
285
+ case 'cf-d1-database': {
286
+ await httpsDelete('api.cloudflare.com', `/client/v4/accounts/${accountId}/d1/database/${resource.id}`, { 'Authorization': `Bearer ${token}` });
287
+ break;
288
+ }
289
+ case 'cf-pages-project': {
290
+ await httpsDelete('api.cloudflare.com', `/client/v4/accounts/${accountId}/pages/projects/${resource.id}`, { 'Authorization': `Bearer ${token}` });
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ catch (err) {
296
+ console.error(`Failed to cleanup ${resource.type} ${resource.id}:`, err.message);
297
+ }
298
+ }
299
+ },
300
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Docker provisioner — generates Dockerfile + docker-compose.yml locally.
3
+ * No cloud API calls. Files only.
4
+ */
5
+ import type { Provisioner } from './types.js';
6
+ export declare const dockerProvisioner: Provisioner;
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Docker provisioner — generates Dockerfile + docker-compose.yml locally.
3
+ * No cloud API calls. Files only.
4
+ */
5
+ import { writeFile } from 'node:fs/promises';
6
+ import { join } from 'node:path';
7
+ import { generateDockerfile, generateDockerignore } from './scripts/dockerfile.js';
8
+ import { generateDockerCompose } from './scripts/docker-compose.js';
9
+ export const dockerProvisioner = {
10
+ async validate(ctx) {
11
+ const errors = [];
12
+ if (!ctx.projectDir)
13
+ errors.push('Project directory is required');
14
+ if (!ctx.projectName)
15
+ errors.push('Project name is required');
16
+ return errors;
17
+ },
18
+ async provision(ctx, emit) {
19
+ const files = [];
20
+ const framework = ctx.framework || 'express';
21
+ // Step 1: Generate Dockerfile
22
+ emit({ step: 'dockerfile', status: 'started', message: 'Generating Dockerfile' });
23
+ try {
24
+ const dockerfile = generateDockerfile(framework);
25
+ const dockerfilePath = join(ctx.projectDir, 'Dockerfile');
26
+ await writeFile(dockerfilePath, dockerfile, 'utf-8');
27
+ files.push('Dockerfile');
28
+ emit({ step: 'dockerfile', status: 'done', message: `Dockerfile generated (${framework})` });
29
+ }
30
+ catch (err) {
31
+ emit({ step: 'dockerfile', status: 'error', message: 'Failed to write Dockerfile', detail: err.message });
32
+ return { success: false, resources: [], outputs: {}, files, error: err.message };
33
+ }
34
+ // Step 2: Generate docker-compose.yml
35
+ emit({ step: 'docker-compose', status: 'started', message: 'Generating docker-compose.yml' });
36
+ try {
37
+ const compose = generateDockerCompose({
38
+ projectName: ctx.projectName,
39
+ framework,
40
+ database: ctx.database || 'none',
41
+ cache: ctx.cache || 'none',
42
+ });
43
+ const composePath = join(ctx.projectDir, 'docker-compose.yml');
44
+ await writeFile(composePath, compose, 'utf-8');
45
+ files.push('docker-compose.yml');
46
+ emit({ step: 'docker-compose', status: 'done', message: 'docker-compose.yml generated' });
47
+ }
48
+ catch (err) {
49
+ emit({ step: 'docker-compose', status: 'error', message: 'Failed to write docker-compose.yml', detail: err.message });
50
+ return { success: false, resources: [], outputs: {}, files, error: err.message };
51
+ }
52
+ // Step 3: Generate .dockerignore
53
+ emit({ step: 'dockerignore', status: 'started', message: 'Generating .dockerignore' });
54
+ try {
55
+ const ignore = generateDockerignore();
56
+ const ignorePath = join(ctx.projectDir, '.dockerignore');
57
+ await writeFile(ignorePath, ignore, 'utf-8');
58
+ files.push('.dockerignore');
59
+ emit({ step: 'dockerignore', status: 'done', message: '.dockerignore generated' });
60
+ }
61
+ catch (err) {
62
+ emit({ step: 'dockerignore', status: 'error', message: 'Failed to write .dockerignore', detail: err.message });
63
+ return { success: false, resources: [], outputs: {}, files, error: err.message };
64
+ }
65
+ return {
66
+ success: true,
67
+ resources: [],
68
+ outputs: {},
69
+ files,
70
+ };
71
+ },
72
+ async cleanup(_resources, _credentials) {
73
+ // Docker provisioner creates local files only — nothing to clean up
74
+ },
75
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Shared HTTPS client for provisioner API calls.
3
+ * Uses raw node:https — no dependencies.
4
+ *
5
+ * Security: All callers hardcode hostnames (api.cloudflare.com, etc.).
6
+ * Never pass user-controlled input as the hostname parameter.
7
+ */
8
+ interface HttpResponse {
9
+ status: number;
10
+ body: string;
11
+ }
12
+ export declare function httpsGet(hostname: string, path: string, headers: Record<string, string>, timeout?: number): Promise<HttpResponse>;
13
+ export declare function httpsPost(hostname: string, path: string, headers: Record<string, string>, body?: string, timeout?: number): Promise<HttpResponse>;
14
+ export declare function httpsPut(hostname: string, path: string, headers: Record<string, string>, body?: string, timeout?: number): Promise<HttpResponse>;
15
+ export declare function httpsDelete(hostname: string, path: string, headers: Record<string, string>, timeout?: number): Promise<HttpResponse>;
16
+ /** Slugify a name for use as a cloud resource identifier. Strips non-alphanumeric, trims hyphens. */
17
+ export declare function slugify(name: string): string;
18
+ /** Safely parse JSON — returns null on invalid input instead of throwing. */
19
+ export declare function safeJsonParse(body: string): unknown;
20
+ export {};
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Shared HTTPS client for provisioner API calls.
3
+ * Uses raw node:https — no dependencies.
4
+ *
5
+ * Security: All callers hardcode hostnames (api.cloudflare.com, etc.).
6
+ * Never pass user-controlled input as the hostname parameter.
7
+ */
8
+ import { request as httpsRequest } from 'node:https';
9
+ export function httpsGet(hostname, path, headers, timeout) {
10
+ return httpsCallWithRetry('GET', hostname, path, headers, undefined, timeout);
11
+ }
12
+ export function httpsPost(hostname, path, headers, body, timeout) {
13
+ return httpsCallWithRetry('POST', hostname, path, headers, body, timeout);
14
+ }
15
+ export function httpsPut(hostname, path, headers, body, timeout) {
16
+ return httpsCallWithRetry('PUT', hostname, path, headers, body, timeout);
17
+ }
18
+ export function httpsDelete(hostname, path, headers, timeout) {
19
+ return httpsCallWithRetry('DELETE', hostname, path, headers, undefined, timeout);
20
+ }
21
+ /** Slugify a name for use as a cloud resource identifier. Strips non-alphanumeric, trims hyphens. */
22
+ export function slugify(name) {
23
+ const slug = name.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').slice(0, 40);
24
+ return slug || 'voidforge-project';
25
+ }
26
+ /** Safely parse JSON — returns null on invalid input instead of throwing. */
27
+ export function safeJsonParse(body) {
28
+ try {
29
+ return JSON.parse(body);
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ const DEFAULT_TIMEOUT = 30000;
36
+ const MAX_RETRIES = 1;
37
+ const RETRY_DELAY_MS = 2000;
38
+ const TRANSIENT_CODES = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'EPIPE'];
39
+ /**
40
+ * Wrapper around httpsCall that retries once on transient network errors.
41
+ * Transient errors: ECONNRESET, ETIMEDOUT, ENOTFOUND, EPIPE, socket hang up.
42
+ */
43
+ async function httpsCallWithRetry(method, hostname, path, headers, body, timeout) {
44
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
45
+ try {
46
+ return await httpsCall(method, hostname, path, headers, body, timeout);
47
+ }
48
+ catch (err) {
49
+ const code = err.code;
50
+ const isTransient = TRANSIENT_CODES.includes(code || '') ||
51
+ err.message.includes('socket hang up');
52
+ if (attempt < MAX_RETRIES && isTransient) {
53
+ await new Promise(r => setTimeout(r, RETRY_DELAY_MS));
54
+ continue;
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ // Unreachable — the loop always returns or throws — but TypeScript needs this
60
+ throw new Error('Retry loop exited unexpectedly');
61
+ }
62
+ function httpsCall(method, hostname, path, headers, body, timeout) {
63
+ return new Promise((resolve, reject) => {
64
+ const opts = { hostname, path, method, headers, timeout: timeout ?? DEFAULT_TIMEOUT };
65
+ if (body) {
66
+ headers['Content-Length'] = String(Buffer.byteLength(body));
67
+ }
68
+ const req = httpsRequest(opts, (res) => {
69
+ let data = '';
70
+ res.on('data', (chunk) => { data += chunk.toString(); });
71
+ res.on('end', () => resolve({ status: res.statusCode ?? 0, body: data }));
72
+ });
73
+ req.on('error', reject);
74
+ req.on('timeout', () => { req.destroy(); reject(new Error('Request timed out')); });
75
+ if (body)
76
+ req.write(body);
77
+ req.end();
78
+ });
79
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Railway provisioner — creates a real Railway project via GraphQL API + generates railway.toml.
3
+ * v3.8.0: Creates service with GitHub source, sets env vars, polls deploy (ADR-015).
4
+ */
5
+ import type { Provisioner } from './types.js';
6
+ export declare const railwayProvisioner: Provisioner;