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,79 @@
1
+ /**
2
+ * .voidforge marker file — project identity and CLI detection.
3
+ *
4
+ * Every VoidForge project has a `.voidforge` JSON file at root.
5
+ * The CLI walks up from cwd to find it, determining the project root.
6
+ */
7
+ import { readFile, writeFile } from 'node:fs/promises';
8
+ import { existsSync } from 'node:fs';
9
+ import { join, dirname } from 'node:path';
10
+ import { randomUUID } from 'node:crypto';
11
+ import { homedir } from 'node:os';
12
+ // ── Constants ────────────────────────────────────────────
13
+ export const MARKER_FILE = '.voidforge';
14
+ // ── Read / Write ─────────────────────────────────────────
15
+ export async function readMarker(dir) {
16
+ const markerPath = join(dir, MARKER_FILE);
17
+ if (!existsSync(markerPath))
18
+ return null;
19
+ try {
20
+ const raw = await readFile(markerPath, 'utf-8');
21
+ const data = JSON.parse(raw);
22
+ if (!data.id || !data.version || !Array.isArray(data.extensions))
23
+ return null;
24
+ return data;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ export async function writeMarker(dir, marker) {
31
+ const markerPath = join(dir, MARKER_FILE);
32
+ await writeFile(markerPath, JSON.stringify(marker, null, 2) + '\n', 'utf-8');
33
+ }
34
+ export function createMarker(version, tier = 'full', extensions = []) {
35
+ return {
36
+ id: randomUUID(),
37
+ version,
38
+ created: new Date().toISOString(),
39
+ tier,
40
+ extensions,
41
+ };
42
+ }
43
+ // ── Project Detection ────────────────────────────────────
44
+ /**
45
+ * Walk up from `startDir` to find the nearest `.voidforge` marker.
46
+ * Returns the directory containing the marker, or null if none found.
47
+ */
48
+ export function findProjectRoot(startDir = process.cwd()) {
49
+ let current = startDir;
50
+ while (true) {
51
+ if (existsSync(join(current, MARKER_FILE))) {
52
+ return current;
53
+ }
54
+ const parent = dirname(current);
55
+ if (parent === current)
56
+ break; // filesystem root
57
+ current = parent;
58
+ }
59
+ return null;
60
+ }
61
+ /**
62
+ * Like findProjectRoot but throws with a user-friendly message.
63
+ */
64
+ export function requireProjectRoot(startDir = process.cwd()) {
65
+ const root = findProjectRoot(startDir);
66
+ if (!root) {
67
+ console.error('Not a VoidForge project — run `npx voidforge init` to create one.');
68
+ process.exit(1);
69
+ }
70
+ return root;
71
+ }
72
+ // ── Global Config ────────────────────────────────────────
73
+ export function getGlobalDir() {
74
+ const home = process.env['HOME'] ?? process.env['USERPROFILE'] ?? homedir();
75
+ return join(home, '.voidforge');
76
+ }
77
+ export function getVaultPath() {
78
+ return join(getGlobalDir(), 'vault.enc');
79
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Migration from v20.x — detects old-model projects (embedded wizard/)
3
+ * and converts them to v21.0 (standalone wizard, methodology-only projects).
4
+ */
5
+ export interface MigrationPlan {
6
+ projectDir: string;
7
+ hasWizardDir: boolean;
8
+ wizardFileCount: number;
9
+ hasPackageJson: boolean;
10
+ voidforgeDeps: string[];
11
+ hasMethodology: boolean;
12
+ hasMarker: boolean;
13
+ }
14
+ export interface MigrationResult {
15
+ success: boolean;
16
+ backupDir: string;
17
+ wizardFilesRemoved: number;
18
+ depsRemoved: string[];
19
+ markerCreated: boolean;
20
+ }
21
+ /**
22
+ * Detect if a directory is a v20.x project (has embedded wizard/).
23
+ */
24
+ export declare function detectV20Project(dir: string): Promise<MigrationPlan>;
25
+ /**
26
+ * Migrate a v20.x project to v21.0.
27
+ *
28
+ * 1. Create backup at ~/.voidforge/migration-backup/
29
+ * 2. Remove wizard/ directory
30
+ * 3. Remove VoidForge deps from package.json
31
+ * 4. Add .voidforge marker file
32
+ * 5. Keep all methodology files in place
33
+ */
34
+ export declare function migrateProject(projectDir: string, dryRun?: boolean): Promise<MigrationResult>;
35
+ export declare function rollbackMigration(projectDir: string, backupDir: string): Promise<void>;
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Migration from v20.x — detects old-model projects (embedded wizard/)
3
+ * and converts them to v21.0 (standalone wizard, methodology-only projects).
4
+ */
5
+ import { readdir, readFile, rm, cp, mkdir } from 'node:fs/promises';
6
+ import { existsSync } from 'node:fs';
7
+ import { join, resolve } from 'node:path';
8
+ import { createMarker, writeMarker } from './marker.js';
9
+ // ── Detection ────────────────────────────────────────────
10
+ async function countFiles(dir) {
11
+ if (!existsSync(dir))
12
+ return 0;
13
+ let count = 0;
14
+ const entries = await readdir(dir, { withFileTypes: true });
15
+ for (const entry of entries) {
16
+ if (entry.isDirectory()) {
17
+ count += await countFiles(join(dir, entry.name));
18
+ }
19
+ else {
20
+ count++;
21
+ }
22
+ }
23
+ return count;
24
+ }
25
+ /**
26
+ * Detect if a directory is a v20.x project (has embedded wizard/).
27
+ */
28
+ export async function detectV20Project(dir) {
29
+ const projectDir = resolve(dir);
30
+ const wizardDir = join(projectDir, 'wizard');
31
+ const hasWizardDir = existsSync(wizardDir) && existsSync(join(wizardDir, 'server.ts'));
32
+ const wizardFileCount = hasWizardDir ? await countFiles(wizardDir) : 0;
33
+ // Check package.json for VoidForge dependencies
34
+ const pkgPath = join(projectDir, 'package.json');
35
+ const hasPackageJson = existsSync(pkgPath);
36
+ let voidforgeDeps = [];
37
+ if (hasPackageJson) {
38
+ try {
39
+ const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
40
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
41
+ voidforgeDeps = Object.keys(allDeps).filter(d => d.startsWith('@aws-sdk/') || d === 'node-pty' || d === 'ws');
42
+ }
43
+ catch {
44
+ // Invalid package.json
45
+ }
46
+ }
47
+ const hasMethodology = existsSync(join(projectDir, 'CLAUDE.md'));
48
+ const hasMarker = existsSync(join(projectDir, '.voidforge'));
49
+ return {
50
+ projectDir,
51
+ hasWizardDir,
52
+ wizardFileCount,
53
+ hasPackageJson,
54
+ voidforgeDeps,
55
+ hasMethodology,
56
+ hasMarker,
57
+ };
58
+ }
59
+ // ── Backup ───────────────────────────────────────────────
60
+ async function createBackup(projectDir) {
61
+ const { homedir } = await import('node:os');
62
+ const backupBase = join(homedir(), '.voidforge', 'migration-backup');
63
+ await mkdir(backupBase, { recursive: true });
64
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
65
+ const projectName = projectDir.split('/').pop() ?? 'project';
66
+ const backupDir = join(backupBase, `${projectName}-${timestamp}`);
67
+ await mkdir(backupDir);
68
+ // Backup wizard/ directory
69
+ const wizardDir = join(projectDir, 'wizard');
70
+ if (existsSync(wizardDir)) {
71
+ await cp(wizardDir, join(backupDir, 'wizard'), { recursive: true });
72
+ }
73
+ // Backup package.json
74
+ const pkgPath = join(projectDir, 'package.json');
75
+ if (existsSync(pkgPath)) {
76
+ await cp(pkgPath, join(backupDir, 'package.json'));
77
+ }
78
+ // Backup package-lock.json
79
+ const lockPath = join(projectDir, 'package-lock.json');
80
+ if (existsSync(lockPath)) {
81
+ await cp(lockPath, join(backupDir, 'package-lock.json'));
82
+ }
83
+ return backupDir;
84
+ }
85
+ // ── Migration ────────────────────────────────────────────
86
+ /**
87
+ * Migrate a v20.x project to v21.0.
88
+ *
89
+ * 1. Create backup at ~/.voidforge/migration-backup/
90
+ * 2. Remove wizard/ directory
91
+ * 3. Remove VoidForge deps from package.json
92
+ * 4. Add .voidforge marker file
93
+ * 5. Keep all methodology files in place
94
+ */
95
+ export async function migrateProject(projectDir, dryRun = false) {
96
+ const plan = await detectV20Project(projectDir);
97
+ if (!plan.hasWizardDir) {
98
+ throw new Error('No wizard/ directory found — this is not a v20.x project.');
99
+ }
100
+ if (plan.hasMarker) {
101
+ throw new Error('Project already has a .voidforge marker — already migrated?');
102
+ }
103
+ if (dryRun) {
104
+ return {
105
+ success: true,
106
+ backupDir: '(dry run — no backup created)',
107
+ wizardFilesRemoved: plan.wizardFileCount,
108
+ depsRemoved: plan.voidforgeDeps,
109
+ markerCreated: true,
110
+ };
111
+ }
112
+ // 1. Create backup
113
+ const backupDir = await createBackup(projectDir);
114
+ // 2. Remove wizard/ directory
115
+ const wizardDir = join(projectDir, 'wizard');
116
+ await rm(wizardDir, { recursive: true, force: true });
117
+ // 3. Remove VoidForge deps from package.json
118
+ const depsRemoved = [];
119
+ const pkgPath = join(projectDir, 'package.json');
120
+ if (plan.hasPackageJson && plan.voidforgeDeps.length > 0) {
121
+ try {
122
+ const pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
123
+ for (const dep of plan.voidforgeDeps) {
124
+ if (pkg.dependencies?.[dep]) {
125
+ delete pkg.dependencies[dep];
126
+ depsRemoved.push(dep);
127
+ }
128
+ if (pkg.devDependencies?.[dep]) {
129
+ delete pkg.devDependencies[dep];
130
+ depsRemoved.push(dep);
131
+ }
132
+ }
133
+ const { writeFile } = await import('node:fs/promises');
134
+ await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
135
+ }
136
+ catch {
137
+ // package.json modification failed — non-fatal
138
+ }
139
+ }
140
+ // 4. Write .voidforge marker
141
+ const marker = createMarker('21.0.0', 'full');
142
+ await writeMarker(projectDir, marker);
143
+ // 5. Remove old config files that moved to the wizard package
144
+ const oldConfigs = ['vitest.config.ts', 'playwright.config.ts'];
145
+ for (const config of oldConfigs) {
146
+ const configPath = join(projectDir, config);
147
+ if (existsSync(configPath)) {
148
+ await rm(configPath);
149
+ }
150
+ }
151
+ // 6. Remove wizard-specific scripts from package.json
152
+ const scriptsDir = join(projectDir, 'scripts');
153
+ const wizardScripts = ['voidforge.ts', 'danger-room-feed.sh', 'new-project.sh', 'vault-read.ts'];
154
+ for (const script of wizardScripts) {
155
+ const scriptPath = join(scriptsDir, script);
156
+ if (existsSync(scriptPath)) {
157
+ await rm(scriptPath);
158
+ }
159
+ }
160
+ return {
161
+ success: true,
162
+ backupDir,
163
+ wizardFilesRemoved: plan.wizardFileCount,
164
+ depsRemoved,
165
+ markerCreated: true,
166
+ };
167
+ }
168
+ // ── Rollback ─────────────────────────────────────────────
169
+ export async function rollbackMigration(projectDir, backupDir) {
170
+ // Restore wizard/
171
+ const wizardBackup = join(backupDir, 'wizard');
172
+ if (existsSync(wizardBackup)) {
173
+ await cp(wizardBackup, join(projectDir, 'wizard'), { recursive: true });
174
+ }
175
+ // Restore package.json
176
+ const pkgBackup = join(backupDir, 'package.json');
177
+ if (existsSync(pkgBackup)) {
178
+ await cp(pkgBackup, join(projectDir, 'package.json'));
179
+ }
180
+ // Restore package-lock.json
181
+ const lockBackup = join(backupDir, 'package-lock.json');
182
+ if (existsSync(lockBackup)) {
183
+ await cp(lockBackup, join(projectDir, 'package-lock.json'));
184
+ }
185
+ // Remove marker (wasn't there before migration)
186
+ const markerPath = join(projectDir, '.voidforge');
187
+ if (existsSync(markerPath)) {
188
+ await rm(markerPath);
189
+ }
190
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Natural Language Deploy — resolve prose deployment descriptions to YAML frontmatter.
3
+ *
4
+ * Parse: "I want a $20/month server with SSL and daily backups"
5
+ * → { deploy: 'vps', instanceType: 't3.small', hostname: '', resilience: { backups: 'daily', ... } }
6
+ *
7
+ * Uses keyword matching and heuristics — no AI API call required.
8
+ */
9
+ export interface DeployConfig {
10
+ deploy: 'vps' | 'vercel' | 'railway' | 'cloudflare' | 'static' | 'docker';
11
+ instanceType: string;
12
+ hostname: string;
13
+ estimatedMonthlyCost: string;
14
+ resilience: {
15
+ multiEnv: boolean;
16
+ previewDeploys: boolean;
17
+ rollback: boolean;
18
+ migrations: 'auto' | 'manual' | 'no';
19
+ backups: 'daily' | 'weekly' | 'no';
20
+ healthCheck: boolean;
21
+ gracefulShutdown: boolean;
22
+ errorBoundaries: boolean;
23
+ rateLimiting: boolean;
24
+ deadLetterQueue: boolean;
25
+ };
26
+ reasoning: string[];
27
+ }
28
+ export declare function resolveDeployConfig(prose: string): DeployConfig | null;
29
+ /** Convert a DeployConfig to YAML frontmatter fragment. */
30
+ export declare function toFrontmatter(config: DeployConfig): string;
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Natural Language Deploy — resolve prose deployment descriptions to YAML frontmatter.
3
+ *
4
+ * Parse: "I want a $20/month server with SSL and daily backups"
5
+ * → { deploy: 'vps', instanceType: 't3.small', hostname: '', resilience: { backups: 'daily', ... } }
6
+ *
7
+ * Uses keyword matching and heuristics — no AI API call required.
8
+ */
9
+ const BUDGET_TIERS = [
10
+ { maxMonthly: 10, instanceType: 't3.micro', label: '~$8/mo' },
11
+ { maxMonthly: 25, instanceType: 't3.small', label: '~$17/mo' },
12
+ { maxMonthly: 50, instanceType: 't3.medium', label: '~$34/mo' },
13
+ { maxMonthly: 100, instanceType: 't3.large', label: '~$68/mo' },
14
+ { maxMonthly: Infinity, instanceType: 't3.xlarge', label: '~$136/mo' },
15
+ ];
16
+ function resolveInstanceFromBudget(budget) {
17
+ return BUDGET_TIERS.find(t => budget <= t.maxMonthly) ?? BUDGET_TIERS[BUDGET_TIERS.length - 1];
18
+ }
19
+ // ── Keyword patterns ────────────────────────────
20
+ const PLATFORM_KEYWORDS = [
21
+ { pattern: /\bvercel\b/i, target: 'vercel', reason: 'Vercel mentioned explicitly' },
22
+ { pattern: /\brailway\b/i, target: 'railway', reason: 'Railway mentioned explicitly' },
23
+ { pattern: /\bcloudflare\b/i, target: 'cloudflare', reason: 'Cloudflare mentioned explicitly' },
24
+ { pattern: /\bdocker\b|\bcontainer\b/i, target: 'docker', reason: 'Docker/container mentioned' },
25
+ { pattern: /\bstatic\s*(?:site|hosting|files?)\b/i, target: 'static', reason: 'Static site hosting' },
26
+ { pattern: /\bvps\b|\bserver\b|\bec2\b|\baws\b|\bssh\b/i, target: 'vps', reason: 'Server/VPS/AWS mentioned' },
27
+ { pattern: /\bserverless\b|\bedge\b/i, target: 'vercel', reason: 'Serverless/edge → Vercel' },
28
+ { pattern: /\bfree\s*tier\b|\bno\s*cost\b|\bfree\b/i, target: 'railway', reason: 'Free tier → Railway' },
29
+ ];
30
+ const FEATURE_KEYWORDS = [
31
+ { pattern: /\bbackup/i, key: 'backups', reason: 'Backups requested' },
32
+ { pattern: /\bssl\b|\bhttps\b|\btls\b/i, key: 'ssl', reason: 'SSL/TLS requested' },
33
+ { pattern: /\bcustom\s*domain\b|\bmy\s*domain\b/i, key: 'customDomain', reason: 'Custom domain' },
34
+ { pattern: /\brollback\b|\brevert\b/i, key: 'rollback', reason: 'Rollback requested' },
35
+ { pattern: /\bpreview\b|\bpr\s*deploy/i, key: 'previewDeploys', reason: 'Preview deploys' },
36
+ { pattern: /\bhealth\s*check\b|\bmonitoring\b|\buptime\b/i, key: 'healthCheck', reason: 'Health monitoring' },
37
+ { pattern: /\brate\s*limit/i, key: 'rateLimiting', reason: 'Rate limiting' },
38
+ { pattern: /\bgraceful\b|\bzero\s*downtime\b/i, key: 'gracefulShutdown', reason: 'Zero-downtime' },
39
+ { pattern: /\bmulti\s*(?:env|environment)\b|\bstaging\b/i, key: 'multiEnv', reason: 'Multi-environment' },
40
+ { pattern: /\berror\s*boundar/i, key: 'errorBoundaries', reason: 'Error boundaries' },
41
+ { pattern: /\bdead\s*letter\b|\bdlq\b|\bretry\s*queue\b/i, key: 'deadLetterQueue', reason: 'Dead letter queue' },
42
+ { pattern: /\bmigration/i, key: 'migrations', reason: 'Database migrations' },
43
+ ];
44
+ const SCALE_KEYWORDS = [
45
+ { pattern: /\bsmall\b|\bsimple\b|\bblog\b|\bpersonal\b|\bside\s*project\b|\bmvp\b|\bprototype\b/i, scale: 'small', reason: 'Small/simple project' },
46
+ { pattern: /\bmedium\b|\bstartup\b|\bsaas\b|\bteam\b|\bgrow/i, scale: 'medium', reason: 'Medium/startup scale' },
47
+ { pattern: /\blarge\b|\benterprise\b|\bthousands\b|\bhigh\s*traffic\b|\bscale\b|\bproduction\b/i, scale: 'large', reason: 'Large/production scale' },
48
+ ];
49
+ // ── Main resolver ───────────────────────────────
50
+ export function resolveDeployConfig(prose) {
51
+ if (!prose.trim())
52
+ return null;
53
+ const reasoning = [];
54
+ const features = new Set();
55
+ // Extract budget — prefer amounts near cost keywords, fall back to first $N
56
+ const costContextMatch = prose.match(/(?:budget|spend|cost|month|mo)[^$]*\$(\d+(?:\.\d+)?)/i)
57
+ ?? prose.match(/\$(\d+(?:\.\d+)?)(?:\s*\/\s*mo(?:nth)?)/i)
58
+ ?? prose.match(/\$(\d+(?:\.\d+)?)/i);
59
+ const budget = costContextMatch ? Math.round(parseFloat(costContextMatch[1])) : -1;
60
+ // Detect explicit platform
61
+ let deploy = 'vps'; // default
62
+ let platformDetected = false;
63
+ for (const kw of PLATFORM_KEYWORDS) {
64
+ if (kw.pattern.test(prose)) {
65
+ deploy = kw.target;
66
+ reasoning.push(kw.reason);
67
+ platformDetected = true;
68
+ break;
69
+ }
70
+ }
71
+ // Detect features
72
+ for (const kw of FEATURE_KEYWORDS) {
73
+ if (kw.pattern.test(prose)) {
74
+ features.add(kw.key);
75
+ reasoning.push(kw.reason);
76
+ }
77
+ }
78
+ // Detect scale
79
+ let scale = 'small';
80
+ for (const kw of SCALE_KEYWORDS) {
81
+ if (kw.pattern.test(prose)) {
82
+ scale = kw.scale;
83
+ reasoning.push(kw.reason);
84
+ break;
85
+ }
86
+ }
87
+ // If no platform detected, infer from features and scale
88
+ if (!platformDetected) {
89
+ if (features.has('previewDeploys') || features.has('errorBoundaries')) {
90
+ deploy = 'vercel';
91
+ reasoning.push('Preview deploys/error boundaries → Vercel (best support)');
92
+ }
93
+ else if (scale === 'large' || features.has('customDomain') || budget > 30) {
94
+ deploy = 'vps';
95
+ reasoning.push('Large scale or custom domain with budget → VPS');
96
+ }
97
+ else if (scale === 'small' && budget < 0) {
98
+ deploy = 'railway';
99
+ reasoning.push('Small project, no budget specified → Railway (easiest start)');
100
+ }
101
+ else {
102
+ deploy = 'vps';
103
+ reasoning.push('Default → VPS (most flexible)');
104
+ }
105
+ }
106
+ // Resolve instance type from budget or scale
107
+ let instanceType = '';
108
+ let estimatedCost = '';
109
+ if (deploy === 'vps') {
110
+ if (budget >= 0) {
111
+ const tier = resolveInstanceFromBudget(budget);
112
+ instanceType = tier.instanceType;
113
+ estimatedCost = tier.label;
114
+ reasoning.push(`Budget $${budget}/mo → ${tier.instanceType} (${tier.label})`);
115
+ }
116
+ else {
117
+ const scaleMap = { small: 't3.micro', medium: 't3.small', large: 't3.medium' };
118
+ const costMap = { small: '~$8/mo', medium: '~$17/mo', large: '~$34/mo' };
119
+ instanceType = scaleMap[scale];
120
+ estimatedCost = costMap[scale];
121
+ reasoning.push(`${scale} scale → ${instanceType} (${estimatedCost})`);
122
+ }
123
+ }
124
+ else {
125
+ estimatedCost = deploy === 'railway' ? 'Free tier available' :
126
+ deploy === 'vercel' ? 'Free tier available' :
127
+ deploy === 'cloudflare' ? 'Free tier available' :
128
+ deploy === 'static' ? 'Minimal (~$1/mo S3)' : 'Varies';
129
+ }
130
+ // Extract hostname if mentioned
131
+ const hostnameMatch = prose.match(/(?:domain|hostname|url)[\s:]*([a-z0-9.-]+\.[a-z]{2,})/i);
132
+ const hostname = hostnameMatch ? hostnameMatch[1] : '';
133
+ if (hostname)
134
+ reasoning.push(`Hostname detected: ${hostname}`);
135
+ // Build resilience config — defaults based on deploy target + detected features
136
+ const isVps = deploy === 'vps';
137
+ const isPlatform = ['vercel', 'railway', 'cloudflare'].includes(deploy);
138
+ const resilience = {
139
+ multiEnv: features.has('multiEnv') || scale !== 'small',
140
+ previewDeploys: features.has('previewDeploys') || (isPlatform && scale !== 'small'),
141
+ rollback: features.has('rollback') || isPlatform,
142
+ migrations: features.has('migrations') ? 'auto' : (isVps ? 'manual' : 'no'),
143
+ backups: features.has('backups') ? 'daily' : (isVps && scale !== 'small' ? 'weekly' : 'no'),
144
+ healthCheck: features.has('healthCheck') || isVps || scale !== 'small',
145
+ gracefulShutdown: features.has('gracefulShutdown') || isVps,
146
+ errorBoundaries: features.has('errorBoundaries'),
147
+ rateLimiting: features.has('rateLimiting') || scale === 'large',
148
+ deadLetterQueue: features.has('deadLetterQueue'),
149
+ };
150
+ return {
151
+ deploy,
152
+ instanceType,
153
+ hostname,
154
+ estimatedMonthlyCost: estimatedCost,
155
+ resilience,
156
+ reasoning,
157
+ };
158
+ }
159
+ /** Sanitize a string for safe YAML double-quoted interpolation. */
160
+ function yamlSafe(value) {
161
+ return value.replace(/[\\"]/g, '');
162
+ }
163
+ /** Convert a DeployConfig to YAML frontmatter fragment. */
164
+ export function toFrontmatter(config) {
165
+ const lines = [
166
+ `deploy: "${yamlSafe(config.deploy)}"`,
167
+ ];
168
+ if (config.instanceType) {
169
+ lines.push(`instance_type: "${yamlSafe(config.instanceType)}"`);
170
+ }
171
+ if (config.hostname) {
172
+ lines.push(`hostname: "${yamlSafe(config.hostname.toLowerCase())}"`);
173
+ }
174
+ lines.push('resilience:');
175
+ lines.push(` multi-env: ${config.resilience.multiEnv ? 'yes' : 'no'}`);
176
+ lines.push(` preview-deploys: ${config.resilience.previewDeploys ? 'yes' : 'no'}`);
177
+ lines.push(` rollback: ${config.resilience.rollback ? 'yes' : 'no'}`);
178
+ lines.push(` migrations: "${yamlSafe(config.resilience.migrations)}"`);
179
+ lines.push(` backups: "${yamlSafe(config.resilience.backups)}"`);
180
+ lines.push(` health-check: ${config.resilience.healthCheck ? 'yes' : 'no'}`);
181
+ lines.push(` graceful-shutdown: ${config.resilience.gracefulShutdown ? 'yes' : 'no'}`);
182
+ lines.push(` error-boundaries: ${config.resilience.errorBoundaries ? 'yes' : 'no'}`);
183
+ lines.push(` rate-limiting: ${config.resilience.rateLimiting ? 'yes' : 'no'}`);
184
+ lines.push(` dead-letter-queue: ${config.resilience.deadLetterQueue ? 'yes' : 'no'}`);
185
+ return lines.join('\n');
186
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Network utilities — shared private IP detection for WebSocket origin validation.
3
+ * Consolidates duplicate implementations from health-poller.ts and site-scanner.ts.
4
+ *
5
+ * Covers:
6
+ * - RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
7
+ * - CGNAT/Tailscale: 100.64.0.0/10 (RFC 6598)
8
+ * - Loopback: 127.0.0.0/8
9
+ * - IPv6 ULA: fd00::/8 (ZeroTier, WireGuard)
10
+ * - IPv6 loopback: ::1
11
+ */
12
+ /**
13
+ * Check if an IP address is in a private/internal range.
14
+ * Uses numeric octet parsing — NEVER string prefix matching.
15
+ * (SECURITY_AUDITOR.md: "ip.startsWith('172.2') matches public IPs like 172.200.x.x")
16
+ */
17
+ export declare function isPrivateIp(ip: string): boolean;
18
+ /**
19
+ * Check if a WebSocket/HTTP origin is from a private network.
20
+ * Extracts the hostname from the origin URL and checks if it's private.
21
+ */
22
+ export declare function isPrivateOrigin(origin: string): boolean;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Network utilities — shared private IP detection for WebSocket origin validation.
3
+ * Consolidates duplicate implementations from health-poller.ts and site-scanner.ts.
4
+ *
5
+ * Covers:
6
+ * - RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
7
+ * - CGNAT/Tailscale: 100.64.0.0/10 (RFC 6598)
8
+ * - Loopback: 127.0.0.0/8
9
+ * - IPv6 ULA: fd00::/8 (ZeroTier, WireGuard)
10
+ * - IPv6 loopback: ::1
11
+ */
12
+ /**
13
+ * Check if an IP address is in a private/internal range.
14
+ * Uses numeric octet parsing — NEVER string prefix matching.
15
+ * (SECURITY_AUDITOR.md: "ip.startsWith('172.2') matches public IPs like 172.200.x.x")
16
+ */
17
+ export function isPrivateIp(ip) {
18
+ // IPv6 checks
19
+ if (ip.includes(':')) {
20
+ const normalized = ip.replace(/^\[/, '').replace(/\]$/, '').toLowerCase();
21
+ if (normalized === '::1')
22
+ return true;
23
+ // IPv4-mapped IPv6 (::ffff:10.0.0.1) — extract and check the IPv4 part
24
+ const v4Mapped = normalized.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
25
+ if (v4Mapped)
26
+ return isPrivateIp(v4Mapped[1]);
27
+ // fd00::/8 — unique local addresses (ZeroTier, WireGuard)
28
+ if (normalized.startsWith('fd'))
29
+ return true;
30
+ // fe80::/10 — link-local
31
+ if (normalized.startsWith('fe80'))
32
+ return true;
33
+ return false;
34
+ }
35
+ // IPv4 checks — parse octets to integers
36
+ const parts = ip.split('.');
37
+ if (parts.length !== 4)
38
+ return false;
39
+ const octets = parts.map(Number);
40
+ if (octets.some(n => isNaN(n) || n < 0 || n > 255))
41
+ return false;
42
+ const [a, b] = octets;
43
+ // 10.0.0.0/8
44
+ if (a === 10)
45
+ return true;
46
+ // 172.16.0.0/12 (172.16.x.x through 172.31.x.x)
47
+ if (a === 172 && b >= 16 && b <= 31)
48
+ return true;
49
+ // 192.168.0.0/16
50
+ if (a === 192 && b === 168)
51
+ return true;
52
+ // 127.0.0.0/8 (loopback)
53
+ if (a === 127)
54
+ return true;
55
+ // 100.64.0.0/10 (CGNAT — Tailscale uses this range)
56
+ if (a === 100 && b >= 64 && b <= 127)
57
+ return true;
58
+ return false;
59
+ }
60
+ /**
61
+ * Check if a WebSocket/HTTP origin is from a private network.
62
+ * Extracts the hostname from the origin URL and checks if it's private.
63
+ */
64
+ export function isPrivateOrigin(origin) {
65
+ try {
66
+ const url = new URL(origin);
67
+ return isPrivateIp(url.hostname);
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * OAuth core — re-exports from the oauth-token-lifecycle pattern for wizard runtime use.
3
+ * ARCH-R2-012: Production code should not import from docs/patterns/ directly.
4
+ */
5
+ export { needsRefresh, handleRefreshFailure, getTokenHealth, tokenVaultKey, deserializeTokens, shouldRotateSessionToken, rotateSessionToken, validateSessionToken, } from './patterns/oauth-token-lifecycle.js';
6
+ export type { SessionTokenState } from './patterns/oauth-token-lifecycle.js';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * OAuth core — re-exports from the oauth-token-lifecycle pattern for wizard runtime use.
3
+ * ARCH-R2-012: Production code should not import from docs/patterns/ directly.
4
+ */
5
+ export { needsRefresh, handleRefreshFailure, getTokenHealth, tokenVaultKey, deserializeTokens, shouldRotateSessionToken, rotateSessionToken, validateSessionToken, } from './patterns/oauth-token-lifecycle.js';
@@ -0,0 +1 @@
1
+ export declare function openBrowser(url: string): Promise<void>;
@@ -0,0 +1,26 @@
1
+ import { execFile } from 'node:child_process';
2
+ export function openBrowser(url) {
3
+ return new Promise((resolve) => {
4
+ const platform = process.platform;
5
+ let cmd;
6
+ let args;
7
+ if (platform === 'darwin') {
8
+ cmd = 'open';
9
+ args = [url];
10
+ }
11
+ else if (platform === 'win32') {
12
+ cmd = 'cmd';
13
+ args = ['/c', 'start', '', url];
14
+ }
15
+ else {
16
+ cmd = 'xdg-open';
17
+ args = [url];
18
+ }
19
+ execFile(cmd, args, (err) => {
20
+ if (err) {
21
+ console.log(` Open ${url} in your browser to continue`);
22
+ }
23
+ resolve();
24
+ });
25
+ });
26
+ }