voidforge-build 23.9.1
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.
- package/dist/.claude/agents/adolin-brand.md +40 -0
- package/dist/.claude/agents/ahsoka-access-control.md +56 -0
- package/dist/.claude/agents/alfred-dependencies.md +43 -0
- package/dist/.claude/agents/alia-threat-detect.md +40 -0
- package/dist/.claude/agents/anakin-dark-side.md +41 -0
- package/dist/.claude/agents/aquaman-deep-dive.md +43 -0
- package/dist/.claude/agents/aragorn-orchestration.md +39 -0
- package/dist/.claude/agents/archer-greenfield.md +48 -0
- package/dist/.claude/agents/armin-clever.md +39 -0
- package/dist/.claude/agents/arwen-ui-polish.md +42 -0
- package/dist/.claude/agents/ashitaka-tech-debt.md +39 -0
- package/dist/.claude/agents/asuka-performance.md +39 -0
- package/dist/.claude/agents/bail-organa-governance.md +37 -0
- package/dist/.claude/agents/banner-database.md +44 -0
- package/dist/.claude/agents/barton-smoke-test.md +59 -0
- package/dist/.claude/agents/bashir-field-medic.md +63 -0
- package/dist/.claude/agents/batgirl-detail.md +43 -0
- package/dist/.claude/agents/batman-qa.md +73 -0
- package/dist/.claude/agents/bayta-evals.md +41 -0
- package/dist/.claude/agents/beast-boy-cross-env.md +43 -0
- package/dist/.claude/agents/beerus-destroyer.md +39 -0
- package/dist/.claude/agents/bel-riose-orchestration.md +40 -0
- package/dist/.claude/agents/beru-subprocess.md +37 -0
- package/dist/.claude/agents/bilbo-microcopy.md +43 -0
- package/dist/.claude/agents/black-canary-monitoring.md +43 -0
- package/dist/.claude/agents/bliss-ai-safety.md +40 -0
- package/dist/.claude/agents/bo-katan-perimeter.md +40 -0
- package/dist/.claude/agents/bombadil-forge-sync.md +62 -0
- package/dist/.claude/agents/boromir-hubris.md +40 -0
- package/dist/.claude/agents/breeze-platform-relations.md +40 -0
- package/dist/.claude/agents/bucky-legacy.md +43 -0
- package/dist/.claude/agents/bulma-engineering.md +40 -0
- package/dist/.claude/agents/calcifer-daemon.md +39 -0
- package/dist/.claude/agents/cara-dune-enforcement.md +37 -0
- package/dist/.claude/agents/cassian-recon.md +37 -0
- package/dist/.claude/agents/cc-persistent-process.md +39 -0
- package/dist/.claude/agents/celeborn-design-system.md +40 -0
- package/dist/.claude/agents/celebrimbor-forge-artist.md +62 -0
- package/dist/.claude/agents/chakotay-bridge.md +47 -0
- package/dist/.claude/agents/chani-worm-rider.md +61 -0
- package/dist/.claude/agents/chewie-dependency-audit.md +41 -0
- package/dist/.claude/agents/chrome-discovery.md +37 -0
- package/dist/.claude/agents/constantine-cursed-code.md +59 -0
- package/dist/.claude/agents/coulson-release.md +64 -0
- package/dist/.claude/agents/crusher-diagnostics.md +48 -0
- package/dist/.claude/agents/cyborg-system-integration.md +43 -0
- package/dist/.claude/agents/dalinar-positioning.md +40 -0
- package/dist/.claude/agents/daneel-model-migration.md +40 -0
- package/dist/.claude/agents/data-tech-debt.md +48 -0
- package/dist/.claude/agents/dax-legacy-wisdom.md +48 -0
- package/dist/.claude/agents/deathstroke-adversarial.md +59 -0
- package/dist/.claude/agents/denji-determination.md +39 -0
- package/dist/.claude/agents/din-djarin-bounty.md +42 -0
- package/dist/.claude/agents/dockson-treasury.md +67 -0
- package/dist/.claude/agents/dori-integration-check.md +37 -0
- package/dist/.claude/agents/dors-observability.md +40 -0
- package/dist/.claude/agents/drax-exact-match.md +42 -0
- package/dist/.claude/agents/ducem-token-economics.md +41 -0
- package/dist/.claude/agents/duncan-relay.md +40 -0
- package/dist/.claude/agents/duo-teardown.md +38 -0
- package/dist/.claude/agents/ed-network-scan.md +38 -0
- package/dist/.claude/agents/elrond-ux-strategy.md +39 -0
- package/dist/.claude/agents/eowyn-delight.md +56 -0
- package/dist/.claude/agents/erwin-strategy.md +39 -0
- package/dist/.claude/agents/ezra-catches-missed.md +40 -0
- package/dist/.claude/agents/ezri-session-analyst.md +45 -0
- package/dist/.claude/agents/falcon-migration.md +43 -0
- package/dist/.claude/agents/faramir-judgment.md +40 -0
- package/dist/.claude/agents/faye-resourceful.md +39 -0
- package/dist/.claude/agents/fenring-passive-monitor.md +37 -0
- package/dist/.claude/agents/fern-protocol.md +37 -0
- package/dist/.claude/agents/feyd-adversarial.md +41 -0
- package/dist/.claude/agents/flash-rapid-test.md +43 -0
- package/dist/.claude/agents/friday-automation.md +42 -0
- package/dist/.claude/agents/frieren-long-term.md +39 -0
- package/dist/.claude/agents/frodo-critical-path.md +40 -0
- package/dist/.claude/agents/fury-initiative.md +65 -0
- package/dist/.claude/agents/gaal-prompt-arch.md +41 -0
- package/dist/.claude/agents/galadriel-frontend.md +69 -0
- package/dist/.claude/agents/gamora-perf-assassin.md +43 -0
- package/dist/.claude/agents/gandalf-setup-wizard.md +63 -0
- package/dist/.claude/agents/gen-docs.md +37 -0
- package/dist/.claude/agents/ghanima-paired-monitor.md +37 -0
- package/dist/.claude/agents/gimli-performance.md +41 -0
- package/dist/.claude/agents/giyu-silent-guard.md +39 -0
- package/dist/.claude/agents/glorfindel-rendering.md +40 -0
- package/dist/.claude/agents/gohan-hidden-power.md +39 -0
- package/dist/.claude/agents/gojo-infinite-scale.md +39 -0
- package/dist/.claude/agents/goku-scaling.md +39 -0
- package/dist/.claude/agents/goldberry-change-detect.md +37 -0
- package/dist/.claude/agents/gordon-escalation.md +42 -0
- package/dist/.claude/agents/green-arrow-precision.md +43 -0
- package/dist/.claude/agents/green-lantern-scenarios.md +43 -0
- package/dist/.claude/agents/grogu-tiny-vulns.md +38 -0
- package/dist/.claude/agents/groot-caching.md +43 -0
- package/dist/.claude/agents/gurney-delivery.md +40 -0
- package/dist/.claude/agents/haku-deploy-wizard.md +65 -0
- package/dist/.claude/agents/haldir-boundaries.md +40 -0
- package/dist/.claude/agents/han-vuln-hunter.md +40 -0
- package/dist/.claude/agents/hange-experimentation.md +39 -0
- package/dist/.claude/agents/harah-protocol.md +38 -0
- package/dist/.claude/agents/hawkgirl-regression-sweep.md +43 -0
- package/dist/.claude/agents/heero-mission-deploy.md +39 -0
- package/dist/.claude/agents/hera-navigation.md +41 -0
- package/dist/.claude/agents/hill-mission-control.md +43 -0
- package/dist/.claude/agents/himmel-legacy.md +37 -0
- package/dist/.claude/agents/hober-tool-schema.md +40 -0
- package/dist/.claude/agents/hoid-copywriting.md +40 -0
- package/dist/.claude/agents/howl-migration.md +39 -0
- package/dist/.claude/agents/hughes-observability.md +37 -0
- package/dist/.claude/agents/huntress-flaky-bugs.md +42 -0
- package/dist/.claude/agents/irulan-historian.md +37 -0
- package/dist/.claude/agents/jake-reporter.md +45 -0
- package/dist/.claude/agents/janeway-novel-arch.md +48 -0
- package/dist/.claude/agents/janov-context-eng.md +40 -0
- package/dist/.claude/agents/jarvis-status.md +42 -0
- package/dist/.claude/agents/jean-pragmatic.md +39 -0
- package/dist/.claude/agents/jessica-voice.md +40 -0
- package/dist/.claude/agents/jet-maintenance.md +39 -0
- package/dist/.claude/agents/jin-disciplined-adv.md +39 -0
- package/dist/.claude/agents/kaji-intelligence.md +39 -0
- package/dist/.claude/agents/kaladin-organic-growth.md +40 -0
- package/dist/.claude/agents/kallen-hard-deploy.md +39 -0
- package/dist/.claude/agents/kanan-intuitive.md +41 -0
- package/dist/.claude/agents/kaoru-harmony.md +37 -0
- package/dist/.claude/agents/kaworu-solver.md +39 -0
- package/dist/.claude/agents/kelsier-growth.md +64 -0
- package/dist/.claude/agents/kenobi-security.md +70 -0
- package/dist/.claude/agents/kim-api-design.md +49 -0
- package/dist/.claude/agents/kira-pragmatic.md +48 -0
- package/dist/.claude/agents/kishibe-hardening.md +39 -0
- package/dist/.claude/agents/kohaku-rapid-response.md +36 -0
- package/dist/.claude/agents/krillin-support.md +36 -0
- package/dist/.claude/agents/kusanagi-devops.md +70 -0
- package/dist/.claude/agents/la-forge-reliability.md +63 -0
- package/dist/.claude/agents/lang-micro-changes.md +43 -0
- package/dist/.claude/agents/legolas-precision.md +42 -0
- package/dist/.claude/agents/leia-secrets.md +41 -0
- package/dist/.claude/agents/lelouch-orchestration.md +39 -0
- package/dist/.claude/agents/leto-ii-persistence.md +40 -0
- package/dist/.claude/agents/leto-protection.md +40 -0
- package/dist/.claude/agents/levi-deploy.md +40 -0
- package/dist/.claude/agents/liet-kynes-deep-system.md +40 -0
- package/dist/.claude/agents/lift-social-media.md +40 -0
- package/dist/.claude/agents/loki-chaos.md +58 -0
- package/dist/.claude/agents/lucius-config.md +43 -0
- package/dist/.claude/agents/luke-audit-journey.md +41 -0
- package/dist/.claude/agents/manhunter-shapeshifting.md +43 -0
- package/dist/.claude/agents/marsh-competitive-intel.md +41 -0
- package/dist/.claude/agents/maul-red-team.md +57 -0
- package/dist/.claude/agents/merry-pair-review.md +40 -0
- package/dist/.claude/agents/mikasa-protection.md +39 -0
- package/dist/.claude/agents/miles-teg-perf.md +40 -0
- package/dist/.claude/agents/milim-load-test.md +39 -0
- package/dist/.claude/agents/misato-operations.md +39 -0
- package/dist/.claude/agents/mob-capacity.md +39 -0
- package/dist/.claude/agents/mohiam-authentication.md +40 -0
- package/dist/.claude/agents/mon-mothma-security-mgmt.md +41 -0
- package/dist/.claude/agents/mugen-chaos.md +39 -0
- package/dist/.claude/agents/mule-adversarial-ai.md +41 -0
- package/dist/.claude/agents/mustang-cleanup.md +39 -0
- package/dist/.claude/agents/nanami-structured-ops.md +39 -0
- package/dist/.claude/agents/nausicaa-resources.md +39 -0
- package/dist/.claude/agents/navani-technical-seo.md +40 -0
- package/dist/.claude/agents/nebula-optimization.md +43 -0
- package/dist/.claude/agents/nightwing-regression.md +59 -0
- package/dist/.claude/agents/nobara-direct-fix.md +39 -0
- package/dist/.claude/agents/nog-solutions.md +48 -0
- package/dist/.claude/agents/nori-asset-scanner.md +37 -0
- package/dist/.claude/agents/obrien-root-cause.md +48 -0
- package/dist/.claude/agents/odo-structural-anomaly.md +48 -0
- package/dist/.claude/agents/okoye-data-integrity.md +43 -0
- package/dist/.claude/agents/olivier-hardening.md +39 -0
- package/dist/.claude/agents/oracle-static-analysis.md +59 -0
- package/dist/.claude/agents/ori-prompt-crafter.md +37 -0
- package/dist/.claude/agents/padme-data-protection.md +42 -0
- package/dist/.claude/agents/paris-route-planner.md +47 -0
- package/dist/.claude/agents/parker-connections.md +43 -0
- package/dist/.claude/agents/paul-orchestration.md +40 -0
- package/dist/.claude/agents/picard-architecture.md +64 -0
- package/dist/.claude/agents/piccolo-tactics.md +39 -0
- package/dist/.claude/agents/pike-bold-decisions.md +48 -0
- package/dist/.claude/agents/pippin-discovery.md +40 -0
- package/dist/.claude/agents/plo-koon-edge-cases.md +37 -0
- package/dist/.claude/agents/power-chaotic.md +39 -0
- package/dist/.claude/agents/qui-gon-subtle-vulns.md +40 -0
- package/dist/.claude/agents/radagast-edge-cases.md +41 -0
- package/dist/.claude/agents/raoden-conversion.md +41 -0
- package/dist/.claude/agents/raven-deep-analysis.md +43 -0
- package/dist/.claude/agents/red-hood-aggressive.md +47 -0
- package/dist/.claude/agents/rei-dangerous-tasks.md +39 -0
- package/dist/.claude/agents/reigen-debugger.md +39 -0
- package/dist/.claude/agents/rengoku-intense-monitor.md +39 -0
- package/dist/.claude/agents/rex-infrastructure.md +41 -0
- package/dist/.claude/agents/rhodes-production.md +43 -0
- package/dist/.claude/agents/riker-review.md +62 -0
- package/dist/.claude/agents/rimuru-adapter.md +39 -0
- package/dist/.claude/agents/riza-backup.md +39 -0
- package/dist/.claude/agents/robin-apprentice.md +42 -0
- package/dist/.claude/agents/rocket-scrappy.md +43 -0
- package/dist/.claude/agents/rogers-api-design.md +43 -0
- package/dist/.claude/agents/romanoff-integrations.md +44 -0
- package/dist/.claude/agents/sabine-unconventional.md +40 -0
- package/dist/.claude/agents/salvor-model-selection.md +42 -0
- package/dist/.claude/agents/samwise-accessibility.md +43 -0
- package/dist/.claude/agents/sarene-outreach.md +40 -0
- package/dist/.claude/agents/sasha-resources.md +37 -0
- package/dist/.claude/agents/scotty-infrastructure.md +48 -0
- package/dist/.claude/agents/seldon-ai.md +67 -0
- package/dist/.claude/agents/senku-provisioning.md +40 -0
- package/dist/.claude/agents/sentaro-scheduling.md +37 -0
- package/dist/.claude/agents/seven-optimization.md +48 -0
- package/dist/.claude/agents/shallan-creative.md +40 -0
- package/dist/.claude/agents/sheeana-transport.md +40 -0
- package/dist/.claude/agents/shuri-innovation.md +43 -0
- package/dist/.claude/agents/silver-surfer-herald.md +90 -0
- package/dist/.claude/agents/siona-evasion.md +41 -0
- package/dist/.claude/agents/sisko-campaign.md +68 -0
- package/dist/.claude/agents/spike-routing.md +40 -0
- package/dist/.claude/agents/spock-schema.md +62 -0
- package/dist/.claude/agents/starfire-brute-force.md +43 -0
- package/dist/.claude/agents/stark-backend.md +71 -0
- package/dist/.claude/agents/steris-budget.md +41 -0
- package/dist/.claude/agents/stilgar-channel-security.md +40 -0
- package/dist/.claude/agents/strange-service-arch.md +44 -0
- package/dist/.claude/agents/sung-workers.md +39 -0
- package/dist/.claude/agents/superman-strength-test.md +43 -0
- package/dist/.claude/agents/suzaku-execution.md +39 -0
- package/dist/.claude/agents/szeth-compliance.md +40 -0
- package/dist/.claude/agents/tanjiro-persistent.md +39 -0
- package/dist/.claude/agents/tchalla-quality.md +43 -0
- package/dist/.claude/agents/thanos-gauntlet.md +68 -0
- package/dist/.claude/agents/theoden-rally.md +40 -0
- package/dist/.claude/agents/thor-queues.md +44 -0
- package/dist/.claude/agents/thufir-protocol-parsing.md +40 -0
- package/dist/.claude/agents/todo-brute-force.md +39 -0
- package/dist/.claude/agents/torres-site-scanner.md +47 -0
- package/dist/.claude/agents/totoro-guardian.md +39 -0
- package/dist/.claude/agents/tpol-disciplined.md +48 -0
- package/dist/.claude/agents/treebeard-deliberation.md +41 -0
- package/dist/.claude/agents/troi-prd-compliance.md +64 -0
- package/dist/.claude/agents/trunks-rollback.md +39 -0
- package/dist/.claude/agents/tuvok-deep-current.md +63 -0
- package/dist/.claude/agents/uhura-integration.md +47 -0
- package/dist/.claude/agents/valkyrie-recovery.md +43 -0
- package/dist/.claude/agents/vegeta-monitoring.md +39 -0
- package/dist/.claude/agents/veldora-dormant.md +37 -0
- package/dist/.claude/agents/vin-analytics.md +41 -0
- package/dist/.claude/agents/vision-data-analysis.md +43 -0
- package/dist/.claude/agents/wanda-seldon-validation.md +38 -0
- package/dist/.claude/agents/wanda-state.md +43 -0
- package/dist/.claude/agents/wax-paid-ads.md +40 -0
- package/dist/.claude/agents/wayne-ab-testing.md +40 -0
- package/dist/.claude/agents/whis-precision.md +39 -0
- package/dist/.claude/agents/windu-input-validation.md +41 -0
- package/dist/.claude/agents/winry-maintenance.md +39 -0
- package/dist/.claude/agents/wonder-woman-truth.md +43 -0
- package/dist/.claude/agents/wong-documentation.md +58 -0
- package/dist/.claude/agents/worf-security-arch.md +49 -0
- package/dist/.claude/agents/yoda-auth.md +57 -0
- package/dist/.claude/agents/yueh-trust-verify.md +40 -0
- package/dist/.claude/agents/zatanna-impossible.md +43 -0
- package/dist/.claude/agents/zechs-rival.md +39 -0
- package/dist/.claude/agents/zenitsu-alerts.md +37 -0
- package/dist/.claude/commands/ai.md +84 -0
- package/dist/.claude/commands/architect.md +107 -0
- package/dist/.claude/commands/assemble.md +223 -0
- package/dist/.claude/commands/assess.md +86 -0
- package/dist/.claude/commands/blueprint.md +135 -0
- package/dist/.claude/commands/build.md +138 -0
- package/dist/.claude/commands/campaign.md +224 -0
- package/dist/.claude/commands/cultivation.md +184 -0
- package/dist/.claude/commands/current.md +128 -0
- package/dist/.claude/commands/dangerroom.md +74 -0
- package/dist/.claude/commands/debrief.md +180 -0
- package/dist/.claude/commands/deploy.md +108 -0
- package/dist/.claude/commands/devops.md +160 -0
- package/dist/.claude/commands/engage.md +135 -0
- package/dist/.claude/commands/gauntlet.md +179 -0
- package/dist/.claude/commands/git.md +104 -0
- package/dist/.claude/commands/grow.md +160 -0
- package/dist/.claude/commands/imagine.md +126 -0
- package/dist/.claude/commands/portfolio.md +51 -0
- package/dist/.claude/commands/prd.md +113 -0
- package/dist/.claude/commands/qa.md +130 -0
- package/dist/.claude/commands/review.md +9 -0
- package/dist/.claude/commands/security.md +9 -0
- package/dist/.claude/commands/sentinel.md +90 -0
- package/dist/.claude/commands/test.md +114 -0
- package/dist/.claude/commands/thumper.md +116 -0
- package/dist/.claude/commands/treasury.md +117 -0
- package/dist/.claude/commands/ux.md +132 -0
- package/dist/.claude/commands/vault.md +198 -0
- package/dist/.claude/commands/void.md +148 -0
- package/dist/CHANGELOG.md +2621 -0
- package/dist/CLAUDE.md +292 -0
- package/dist/HOLOCRON.md +859 -0
- package/dist/VERSION.md +149 -0
- package/dist/docs/NAMING_REGISTRY.md +479 -0
- package/dist/docs/methods/AI_INTELLIGENCE.md +276 -0
- package/dist/docs/methods/ASSEMBLER.md +142 -0
- package/dist/docs/methods/BACKEND_ENGINEER.md +165 -0
- package/dist/docs/methods/BUILD_JOURNAL.md +214 -0
- package/dist/docs/methods/BUILD_PROTOCOL.md +436 -0
- package/dist/docs/methods/CAMPAIGN.md +569 -0
- package/dist/docs/methods/CONTEXT_MANAGEMENT.md +189 -0
- package/dist/docs/methods/DEEP_CURRENT.md +184 -0
- package/dist/docs/methods/DEVOPS_ENGINEER.md +297 -0
- package/dist/docs/methods/FIELD_MEDIC.md +265 -0
- package/dist/docs/methods/FORGE_ARTIST.md +108 -0
- package/dist/docs/methods/FORGE_KEEPER.md +270 -0
- package/dist/docs/methods/GAUNTLET.md +364 -0
- package/dist/docs/methods/GROWTH_STRATEGIST.md +466 -0
- package/dist/docs/methods/HEARTBEAT.md +168 -0
- package/dist/docs/methods/MCP_INTEGRATION.md +139 -0
- package/dist/docs/methods/MUSTER.md +152 -0
- package/dist/docs/methods/PRD_GENERATOR.md +186 -0
- package/dist/docs/methods/PRODUCT_DESIGN_FRONTEND.md +252 -0
- package/dist/docs/methods/QA_ENGINEER.md +360 -0
- package/dist/docs/methods/RELEASE_MANAGER.md +145 -0
- package/dist/docs/methods/SECURITY_AUDITOR.md +328 -0
- package/dist/docs/methods/SUB_AGENTS.md +375 -0
- package/dist/docs/methods/SYSTEMS_ARCHITECT.md +180 -0
- package/dist/docs/methods/TESTING.md +359 -0
- package/dist/docs/methods/THUMPER.md +175 -0
- package/dist/docs/methods/TIME_VAULT.md +120 -0
- package/dist/docs/methods/TREASURY.md +184 -0
- package/dist/docs/methods/TROUBLESHOOTING.md +265 -0
- package/dist/docs/patterns/README.md +52 -0
- package/dist/docs/patterns/ad-billing-adapter.ts +537 -0
- package/dist/docs/patterns/ad-platform-adapter.ts +421 -0
- package/dist/docs/patterns/ai-classifier.ts +195 -0
- package/dist/docs/patterns/ai-eval.ts +272 -0
- package/dist/docs/patterns/ai-orchestrator.ts +341 -0
- package/dist/docs/patterns/ai-router.ts +194 -0
- package/dist/docs/patterns/ai-tool-schema.ts +237 -0
- package/dist/docs/patterns/api-route.ts +241 -0
- package/dist/docs/patterns/backtest-engine.ts +499 -0
- package/dist/docs/patterns/browser-review.ts +292 -0
- package/dist/docs/patterns/combobox.tsx +300 -0
- package/dist/docs/patterns/component.tsx +262 -0
- package/dist/docs/patterns/daemon-process.ts +338 -0
- package/dist/docs/patterns/data-pipeline.ts +297 -0
- package/dist/docs/patterns/database-migration.ts +466 -0
- package/dist/docs/patterns/e2e-test.ts +629 -0
- package/dist/docs/patterns/error-handling.ts +312 -0
- package/dist/docs/patterns/execution-safety.ts +601 -0
- package/dist/docs/patterns/financial-transaction.ts +366 -0
- package/dist/docs/patterns/funding-plan.ts +462 -0
- package/dist/docs/patterns/game-entity.ts +137 -0
- package/dist/docs/patterns/game-loop.ts +113 -0
- package/dist/docs/patterns/game-state.ts +143 -0
- package/dist/docs/patterns/job-queue.ts +225 -0
- package/dist/docs/patterns/kongo-integration.ts +164 -0
- package/dist/docs/patterns/middleware.ts +363 -0
- package/dist/docs/patterns/mobile-screen.tsx +139 -0
- package/dist/docs/patterns/mobile-service.ts +167 -0
- package/dist/docs/patterns/multi-tenant.ts +382 -0
- package/dist/docs/patterns/oauth-token-lifecycle.ts +223 -0
- package/dist/docs/patterns/outbound-rate-limiter.ts +260 -0
- package/dist/docs/patterns/prompt-template.ts +195 -0
- package/dist/docs/patterns/revenue-source-adapter.ts +311 -0
- package/dist/docs/patterns/service.ts +224 -0
- package/dist/docs/patterns/sse-endpoint.ts +118 -0
- package/dist/docs/patterns/stablecoin-adapter.ts +511 -0
- package/dist/docs/patterns/third-party-script.ts +68 -0
- package/dist/scripts/thumper/gom-jabbar.sh +241 -0
- package/dist/scripts/thumper/relay.sh +610 -0
- package/dist/scripts/thumper/scan.sh +359 -0
- package/dist/scripts/thumper/thumper.sh +190 -0
- package/dist/scripts/thumper/water-rings.sh +76 -0
- package/dist/scripts/vault-read.d.ts +11 -0
- package/dist/scripts/vault-read.js +89 -0
- package/dist/scripts/voidforge.d.ts +21 -0
- package/dist/scripts/voidforge.js +614 -0
- package/dist/wizard/api/auth.d.ts +5 -0
- package/dist/wizard/api/auth.js +139 -0
- package/dist/wizard/api/blueprint.d.ts +34 -0
- package/dist/wizard/api/blueprint.js +161 -0
- package/dist/wizard/api/cloud-providers.d.ts +16 -0
- package/dist/wizard/api/cloud-providers.js +363 -0
- package/dist/wizard/api/credentials.d.ts +1 -0
- package/dist/wizard/api/credentials.js +265 -0
- package/dist/wizard/api/danger-room.d.ts +24 -0
- package/dist/wizard/api/danger-room.js +274 -0
- package/dist/wizard/api/deploy.d.ts +4 -0
- package/dist/wizard/api/deploy.js +164 -0
- package/dist/wizard/api/prd.d.ts +1 -0
- package/dist/wizard/api/prd.js +363 -0
- package/dist/wizard/api/project.d.ts +1 -0
- package/dist/wizard/api/project.js +241 -0
- package/dist/wizard/api/projects-data.d.ts +5 -0
- package/dist/wizard/api/projects-data.js +234 -0
- package/dist/wizard/api/projects-list.d.ts +5 -0
- package/dist/wizard/api/projects-list.js +227 -0
- package/dist/wizard/api/projects.d.ts +7 -0
- package/dist/wizard/api/projects.js +273 -0
- package/dist/wizard/api/provision-status.d.ts +5 -0
- package/dist/wizard/api/provision-status.js +47 -0
- package/dist/wizard/api/provision-steps.d.ts +21 -0
- package/dist/wizard/api/provision-steps.js +44 -0
- package/dist/wizard/api/provision-validate.d.ts +22 -0
- package/dist/wizard/api/provision-validate.js +164 -0
- package/dist/wizard/api/provision.d.ts +2 -0
- package/dist/wizard/api/provision.js +239 -0
- package/dist/wizard/api/terminal.d.ts +25 -0
- package/dist/wizard/api/terminal.js +246 -0
- package/dist/wizard/api/users.d.ts +6 -0
- package/dist/wizard/api/users.js +244 -0
- package/dist/wizard/api/war-room.d.ts +16 -0
- package/dist/wizard/api/war-room.js +70 -0
- package/dist/wizard/danger-room.config.json +5 -0
- package/dist/wizard/lib/ad-platform-core.d.ts +6 -0
- package/dist/wizard/lib/ad-platform-core.js +1 -0
- package/dist/wizard/lib/adapters/index.d.ts +52 -0
- package/dist/wizard/lib/adapters/index.js +38 -0
- package/dist/wizard/lib/adapters/sandbox-bank.d.ts +17 -0
- package/dist/wizard/lib/adapters/sandbox-bank.js +77 -0
- package/dist/wizard/lib/adapters/sandbox.d.ts +39 -0
- package/dist/wizard/lib/adapters/sandbox.js +174 -0
- package/dist/wizard/lib/adapters/stripe.d.ts +19 -0
- package/dist/wizard/lib/adapters/stripe.js +143 -0
- package/dist/wizard/lib/adapters/types.d.ts +9 -0
- package/dist/wizard/lib/adapters/types.js +10 -0
- package/dist/wizard/lib/agent-memory.d.ts +36 -0
- package/dist/wizard/lib/agent-memory.js +114 -0
- package/dist/wizard/lib/agent-registry.d.ts +21 -0
- package/dist/wizard/lib/agent-registry.js +105 -0
- package/dist/wizard/lib/anomaly-detection.d.ts +59 -0
- package/dist/wizard/lib/anomaly-detection.js +122 -0
- package/dist/wizard/lib/anthropic.d.ts +21 -0
- package/dist/wizard/lib/anthropic.js +105 -0
- package/dist/wizard/lib/asset-scanner.d.ts +23 -0
- package/dist/wizard/lib/asset-scanner.js +107 -0
- package/dist/wizard/lib/audit-log.d.ts +23 -0
- package/dist/wizard/lib/audit-log.js +70 -0
- package/dist/wizard/lib/autonomy-controller.d.ts +76 -0
- package/dist/wizard/lib/autonomy-controller.js +184 -0
- package/dist/wizard/lib/body-parser.d.ts +2 -0
- package/dist/wizard/lib/body-parser.js +36 -0
- package/dist/wizard/lib/build-analytics.d.ts +39 -0
- package/dist/wizard/lib/build-analytics.js +91 -0
- package/dist/wizard/lib/build-step.d.ts +21 -0
- package/dist/wizard/lib/build-step.js +104 -0
- package/dist/wizard/lib/campaign-proposer.d.ts +39 -0
- package/dist/wizard/lib/campaign-proposer.js +181 -0
- package/dist/wizard/lib/campaign-state-machine.d.ts +63 -0
- package/dist/wizard/lib/campaign-state-machine.js +114 -0
- package/dist/wizard/lib/ci-generator.d.ts +14 -0
- package/dist/wizard/lib/ci-generator.js +187 -0
- package/dist/wizard/lib/claude-merge.d.ts +38 -0
- package/dist/wizard/lib/claude-merge.js +115 -0
- package/dist/wizard/lib/codegen/erd-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/erd-gen.js +98 -0
- package/dist/wizard/lib/codegen/integrations.d.ts +18 -0
- package/dist/wizard/lib/codegen/integrations.js +189 -0
- package/dist/wizard/lib/codegen/openapi-gen.d.ts +15 -0
- package/dist/wizard/lib/codegen/openapi-gen.js +79 -0
- package/dist/wizard/lib/codegen/prisma-types.d.ts +15 -0
- package/dist/wizard/lib/codegen/prisma-types.js +44 -0
- package/dist/wizard/lib/codegen/seed-gen.d.ts +16 -0
- package/dist/wizard/lib/codegen/seed-gen.js +128 -0
- package/dist/wizard/lib/compliance.d.ts +51 -0
- package/dist/wizard/lib/compliance.js +112 -0
- package/dist/wizard/lib/correlation-engine.d.ts +59 -0
- package/dist/wizard/lib/correlation-engine.js +152 -0
- package/dist/wizard/lib/cost-estimator.d.ts +22 -0
- package/dist/wizard/lib/cost-estimator.js +72 -0
- package/dist/wizard/lib/cost-tracker.d.ts +27 -0
- package/dist/wizard/lib/cost-tracker.js +37 -0
- package/dist/wizard/lib/daemon-aggregator.d.ts +76 -0
- package/dist/wizard/lib/daemon-aggregator.js +241 -0
- package/dist/wizard/lib/daemon-core.d.ts +16 -0
- package/dist/wizard/lib/daemon-core.js +39 -0
- package/dist/wizard/lib/dashboard-data.d.ts +123 -0
- package/dist/wizard/lib/dashboard-data.js +314 -0
- package/dist/wizard/lib/dashboard-ws.d.ts +28 -0
- package/dist/wizard/lib/dashboard-ws.js +117 -0
- package/dist/wizard/lib/deep-current.d.ts +77 -0
- package/dist/wizard/lib/deep-current.js +247 -0
- package/dist/wizard/lib/deploy-coordinator.d.ts +40 -0
- package/dist/wizard/lib/deploy-coordinator.js +86 -0
- package/dist/wizard/lib/deploy-log.d.ts +28 -0
- package/dist/wizard/lib/deploy-log.js +52 -0
- package/dist/wizard/lib/desktop-notify.d.ts +27 -0
- package/dist/wizard/lib/desktop-notify.js +98 -0
- package/dist/wizard/lib/dns/cloudflare-dns.d.ts +35 -0
- package/dist/wizard/lib/dns/cloudflare-dns.js +216 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.d.ts +31 -0
- package/dist/wizard/lib/dns/cloudflare-registrar.js +148 -0
- package/dist/wizard/lib/dns/types.d.ts +22 -0
- package/dist/wizard/lib/dns/types.js +4 -0
- package/dist/wizard/lib/document-discovery.d.ts +33 -0
- package/dist/wizard/lib/document-discovery.js +145 -0
- package/dist/wizard/lib/env-validator.d.ts +14 -0
- package/dist/wizard/lib/env-validator.js +205 -0
- package/dist/wizard/lib/env-writer.d.ts +13 -0
- package/dist/wizard/lib/env-writer.js +26 -0
- package/dist/wizard/lib/exec.d.ts +30 -0
- package/dist/wizard/lib/exec.js +52 -0
- package/dist/wizard/lib/experiment.d.ts +70 -0
- package/dist/wizard/lib/experiment.js +169 -0
- package/dist/wizard/lib/extensions.d.ts +20 -0
- package/dist/wizard/lib/extensions.js +183 -0
- package/dist/wizard/lib/financial/adapter-factory.d.ts +47 -0
- package/dist/wizard/lib/financial/adapter-factory.js +225 -0
- package/dist/wizard/lib/financial/billing/base.d.ts +6 -0
- package/dist/wizard/lib/financial/billing/base.js +1 -0
- package/dist/wizard/lib/financial/billing/google-billing.d.ts +56 -0
- package/dist/wizard/lib/financial/billing/google-billing.js +298 -0
- package/dist/wizard/lib/financial/billing/meta-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/meta-billing.js +243 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.d.ts +54 -0
- package/dist/wizard/lib/financial/billing/tiktok-billing.js +260 -0
- package/dist/wizard/lib/financial/campaign/base.d.ts +13 -0
- package/dist/wizard/lib/financial/campaign/base.js +1 -0
- package/dist/wizard/lib/financial/campaign/campaign-common.d.ts +21 -0
- package/dist/wizard/lib/financial/campaign/campaign-common.js +58 -0
- package/dist/wizard/lib/financial/campaign/google-api.d.ts +35 -0
- package/dist/wizard/lib/financial/campaign/google-api.js +118 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.d.ts +38 -0
- package/dist/wizard/lib/financial/campaign/google-campaign.js +186 -0
- package/dist/wizard/lib/financial/campaign/meta-api.d.ts +28 -0
- package/dist/wizard/lib/financial/campaign/meta-api.js +93 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.d.ts +32 -0
- package/dist/wizard/lib/financial/campaign/meta-campaign.js +189 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.d.ts +45 -0
- package/dist/wizard/lib/financial/campaign/sandbox-campaign.js +261 -0
- package/dist/wizard/lib/financial/campaign/tiktok-api.d.ts +25 -0
- package/dist/wizard/lib/financial/campaign/tiktok-api.js +81 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.d.ts +37 -0
- package/dist/wizard/lib/financial/campaign/tiktok-campaign.js +155 -0
- package/dist/wizard/lib/financial/funding-auto.d.ts +44 -0
- package/dist/wizard/lib/financial/funding-auto.js +52 -0
- package/dist/wizard/lib/financial/funding-policy.d.ts +60 -0
- package/dist/wizard/lib/financial/funding-policy.js +179 -0
- package/dist/wizard/lib/financial/platform-planner.d.ts +47 -0
- package/dist/wizard/lib/financial/platform-planner.js +134 -0
- package/dist/wizard/lib/financial/reconciliation-engine.d.ts +78 -0
- package/dist/wizard/lib/financial/reconciliation-engine.js +193 -0
- package/dist/wizard/lib/financial/registry.d.ts +22 -0
- package/dist/wizard/lib/financial/registry.js +26 -0
- package/dist/wizard/lib/financial/reporting.d.ts +96 -0
- package/dist/wizard/lib/financial/reporting.js +198 -0
- package/dist/wizard/lib/financial/stablecoin/base.d.ts +6 -0
- package/dist/wizard/lib/financial/stablecoin/base.js +1 -0
- package/dist/wizard/lib/financial/stablecoin/circle.d.ts +54 -0
- package/dist/wizard/lib/financial/stablecoin/circle.js +367 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.d.ts +24 -0
- package/dist/wizard/lib/financial/stablecoin/mercury.js +171 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.d.ts +47 -0
- package/dist/wizard/lib/financial/stablecoin/sandbox-stablecoin.js +202 -0
- package/dist/wizard/lib/financial/treasury-planner.d.ts +52 -0
- package/dist/wizard/lib/financial/treasury-planner.js +128 -0
- package/dist/wizard/lib/financial-core.d.ts +6 -0
- package/dist/wizard/lib/financial-core.js +5 -0
- package/dist/wizard/lib/financial-vault.d.ts +34 -0
- package/dist/wizard/lib/financial-vault.js +200 -0
- package/dist/wizard/lib/frontmatter.d.ts +30 -0
- package/dist/wizard/lib/frontmatter.js +99 -0
- package/dist/wizard/lib/gap-analysis.d.ts +37 -0
- package/dist/wizard/lib/gap-analysis.js +218 -0
- package/dist/wizard/lib/github.d.ts +22 -0
- package/dist/wizard/lib/github.js +261 -0
- package/dist/wizard/lib/headless-deploy.d.ts +14 -0
- package/dist/wizard/lib/headless-deploy.js +452 -0
- package/dist/wizard/lib/health-monitor.d.ts +15 -0
- package/dist/wizard/lib/health-monitor.js +91 -0
- package/dist/wizard/lib/health-poller.d.ts +9 -0
- package/dist/wizard/lib/health-poller.js +123 -0
- package/dist/wizard/lib/heartbeat-lifecycle.d.ts +71 -0
- package/dist/wizard/lib/heartbeat-lifecycle.js +107 -0
- package/dist/wizard/lib/heartbeat-scheduler.d.ts +26 -0
- package/dist/wizard/lib/heartbeat-scheduler.js +155 -0
- package/dist/wizard/lib/heartbeat.d.ts +22 -0
- package/dist/wizard/lib/heartbeat.js +538 -0
- package/dist/wizard/lib/herald.d.ts +28 -0
- package/dist/wizard/lib/herald.js +167 -0
- package/dist/wizard/lib/http-helpers.d.ts +9 -0
- package/dist/wizard/lib/http-helpers.js +24 -0
- package/dist/wizard/lib/image-gen.d.ts +56 -0
- package/dist/wizard/lib/image-gen.js +159 -0
- package/dist/wizard/lib/instance-sizing.d.ts +26 -0
- package/dist/wizard/lib/instance-sizing.js +51 -0
- package/dist/wizard/lib/kongo/analytics.d.ts +29 -0
- package/dist/wizard/lib/kongo/analytics.js +179 -0
- package/dist/wizard/lib/kongo/campaigns.d.ts +52 -0
- package/dist/wizard/lib/kongo/campaigns.js +91 -0
- package/dist/wizard/lib/kongo/client.d.ts +58 -0
- package/dist/wizard/lib/kongo/client.js +221 -0
- package/dist/wizard/lib/kongo/jobs.d.ts +57 -0
- package/dist/wizard/lib/kongo/jobs.js +122 -0
- package/dist/wizard/lib/kongo/pages.d.ts +60 -0
- package/dist/wizard/lib/kongo/pages.js +150 -0
- package/dist/wizard/lib/kongo/provisioner.d.ts +64 -0
- package/dist/wizard/lib/kongo/provisioner.js +116 -0
- package/dist/wizard/lib/kongo/seed.d.ts +49 -0
- package/dist/wizard/lib/kongo/seed.js +237 -0
- package/dist/wizard/lib/kongo/types.d.ts +323 -0
- package/dist/wizard/lib/kongo/types.js +11 -0
- package/dist/wizard/lib/kongo/variants.d.ts +57 -0
- package/dist/wizard/lib/kongo/variants.js +88 -0
- package/dist/wizard/lib/kongo/webhooks.d.ts +41 -0
- package/dist/wizard/lib/kongo/webhooks.js +112 -0
- package/dist/wizard/lib/marker.d.ts +28 -0
- package/dist/wizard/lib/marker.js +79 -0
- package/dist/wizard/lib/migrator.d.ts +35 -0
- package/dist/wizard/lib/migrator.js +190 -0
- package/dist/wizard/lib/natural-language-deploy.d.ts +30 -0
- package/dist/wizard/lib/natural-language-deploy.js +186 -0
- package/dist/wizard/lib/network.d.ts +22 -0
- package/dist/wizard/lib/network.js +72 -0
- package/dist/wizard/lib/oauth-core.d.ts +6 -0
- package/dist/wizard/lib/oauth-core.js +5 -0
- package/dist/wizard/lib/open-browser.d.ts +1 -0
- package/dist/wizard/lib/open-browser.js +26 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.d.ts +209 -0
- package/dist/wizard/lib/patterns/ad-billing-adapter.js +269 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.d.ts +200 -0
- package/dist/wizard/lib/patterns/ad-platform-adapter.js +212 -0
- package/dist/wizard/lib/patterns/daemon-process.d.ts +88 -0
- package/dist/wizard/lib/patterns/daemon-process.js +271 -0
- package/dist/wizard/lib/patterns/financial-transaction.d.ts +171 -0
- package/dist/wizard/lib/patterns/financial-transaction.js +154 -0
- package/dist/wizard/lib/patterns/funding-plan.d.ts +136 -0
- package/dist/wizard/lib/patterns/funding-plan.js +200 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.d.ts +94 -0
- package/dist/wizard/lib/patterns/oauth-token-lifecycle.js +139 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.d.ts +67 -0
- package/dist/wizard/lib/patterns/outbound-rate-limiter.js +216 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.d.ts +96 -0
- package/dist/wizard/lib/patterns/revenue-source-adapter.js +182 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.d.ts +218 -0
- package/dist/wizard/lib/patterns/stablecoin-adapter.js +264 -0
- package/dist/wizard/lib/prd-validator.d.ts +39 -0
- package/dist/wizard/lib/prd-validator.js +137 -0
- package/dist/wizard/lib/project-init.d.ts +24 -0
- package/dist/wizard/lib/project-init.js +228 -0
- package/dist/wizard/lib/project-registry.d.ts +86 -0
- package/dist/wizard/lib/project-registry.js +359 -0
- package/dist/wizard/lib/project-scope.d.ts +64 -0
- package/dist/wizard/lib/project-scope.js +96 -0
- package/dist/wizard/lib/project-vault.d.ts +47 -0
- package/dist/wizard/lib/project-vault.js +221 -0
- package/dist/wizard/lib/provision-manifest.d.ts +44 -0
- package/dist/wizard/lib/provision-manifest.js +164 -0
- package/dist/wizard/lib/provisioner-registry.d.ts +15 -0
- package/dist/wizard/lib/provisioner-registry.js +34 -0
- package/dist/wizard/lib/provisioners/aws-config.d.ts +36 -0
- package/dist/wizard/lib/provisioners/aws-config.js +56 -0
- package/dist/wizard/lib/provisioners/aws-ec2.d.ts +19 -0
- package/dist/wizard/lib/provisioners/aws-ec2.js +241 -0
- package/dist/wizard/lib/provisioners/aws-rds.d.ts +10 -0
- package/dist/wizard/lib/provisioners/aws-rds.js +199 -0
- package/dist/wizard/lib/provisioners/aws-vps.d.ts +6 -0
- package/dist/wizard/lib/provisioners/aws-vps.js +231 -0
- package/dist/wizard/lib/provisioners/cloudflare.d.ts +6 -0
- package/dist/wizard/lib/provisioners/cloudflare.js +300 -0
- package/dist/wizard/lib/provisioners/docker.d.ts +6 -0
- package/dist/wizard/lib/provisioners/docker.js +75 -0
- package/dist/wizard/lib/provisioners/http-client.d.ts +20 -0
- package/dist/wizard/lib/provisioners/http-client.js +79 -0
- package/dist/wizard/lib/provisioners/railway-config.d.ts +24 -0
- package/dist/wizard/lib/provisioners/railway-config.js +220 -0
- package/dist/wizard/lib/provisioners/railway-deploy.d.ts +19 -0
- package/dist/wizard/lib/provisioners/railway-deploy.js +205 -0
- package/dist/wizard/lib/provisioners/railway.d.ts +6 -0
- package/dist/wizard/lib/provisioners/railway.js +45 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/caddyfile.js +54 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/deploy-vps.js +112 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.d.ts +11 -0
- package/dist/wizard/lib/provisioners/scripts/docker-compose.js +91 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.d.ts +5 -0
- package/dist/wizard/lib/provisioners/scripts/dockerfile.js +185 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/ecosystem-config.js +36 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.d.ts +14 -0
- package/dist/wizard/lib/provisioners/scripts/provision-vps.js +202 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.d.ts +10 -0
- package/dist/wizard/lib/provisioners/scripts/rollback-vps.js +67 -0
- package/dist/wizard/lib/provisioners/self-deploy.d.ts +41 -0
- package/dist/wizard/lib/provisioners/self-deploy.js +185 -0
- package/dist/wizard/lib/provisioners/static-s3.d.ts +6 -0
- package/dist/wizard/lib/provisioners/static-s3.js +235 -0
- package/dist/wizard/lib/provisioners/types.d.ts +40 -0
- package/dist/wizard/lib/provisioners/types.js +4 -0
- package/dist/wizard/lib/provisioners/vercel.d.ts +6 -0
- package/dist/wizard/lib/provisioners/vercel.js +287 -0
- package/dist/wizard/lib/pty-manager.d.ts +42 -0
- package/dist/wizard/lib/pty-manager.js +244 -0
- package/dist/wizard/lib/rate-limiter-core.d.ts +5 -0
- package/dist/wizard/lib/rate-limiter-core.js +5 -0
- package/dist/wizard/lib/reconciliation.d.ts +43 -0
- package/dist/wizard/lib/reconciliation.js +173 -0
- package/dist/wizard/lib/revenue-types.d.ts +5 -0
- package/dist/wizard/lib/revenue-types.js +1 -0
- package/dist/wizard/lib/route-optimizer.d.ts +28 -0
- package/dist/wizard/lib/route-optimizer.js +93 -0
- package/dist/wizard/lib/s3-deploy.d.ts +19 -0
- package/dist/wizard/lib/s3-deploy.js +156 -0
- package/dist/wizard/lib/safety-tiers.d.ts +76 -0
- package/dist/wizard/lib/safety-tiers.js +134 -0
- package/dist/wizard/lib/sentry-generator.d.ts +15 -0
- package/dist/wizard/lib/sentry-generator.js +116 -0
- package/dist/wizard/lib/server-config.d.ts +13 -0
- package/dist/wizard/lib/server-config.js +23 -0
- package/dist/wizard/lib/service-install.d.ts +18 -0
- package/dist/wizard/lib/service-install.js +182 -0
- package/dist/wizard/lib/site-scanner.d.ts +80 -0
- package/dist/wizard/lib/site-scanner.js +262 -0
- package/dist/wizard/lib/ssh-deploy.d.ts +25 -0
- package/dist/wizard/lib/ssh-deploy.js +225 -0
- package/dist/wizard/lib/templates.d.ts +24 -0
- package/dist/wizard/lib/templates.js +219 -0
- package/dist/wizard/lib/totp.d.ts +35 -0
- package/dist/wizard/lib/totp.js +277 -0
- package/dist/wizard/lib/tower-auth.d.ts +43 -0
- package/dist/wizard/lib/tower-auth.js +352 -0
- package/dist/wizard/lib/tower-rate-limit.d.ts +14 -0
- package/dist/wizard/lib/tower-rate-limit.js +61 -0
- package/dist/wizard/lib/tower-session.d.ts +28 -0
- package/dist/wizard/lib/tower-session.js +119 -0
- package/dist/wizard/lib/treasury-backup.d.ts +23 -0
- package/dist/wizard/lib/treasury-backup.js +127 -0
- package/dist/wizard/lib/treasury-circuit-breakers.d.ts +28 -0
- package/dist/wizard/lib/treasury-circuit-breakers.js +74 -0
- package/dist/wizard/lib/treasury-handlers.d.ts +21 -0
- package/dist/wizard/lib/treasury-handlers.js +281 -0
- package/dist/wizard/lib/treasury-heartbeat.d.ts +18 -0
- package/dist/wizard/lib/treasury-heartbeat.js +20 -0
- package/dist/wizard/lib/treasury-io.d.ts +107 -0
- package/dist/wizard/lib/treasury-io.js +254 -0
- package/dist/wizard/lib/treasury-jobs.d.ts +14 -0
- package/dist/wizard/lib/treasury-jobs.js +589 -0
- package/dist/wizard/lib/treasury-migrator.d.ts +59 -0
- package/dist/wizard/lib/treasury-migrator.js +227 -0
- package/dist/wizard/lib/treasury-reader.d.ts +52 -0
- package/dist/wizard/lib/treasury-reader.js +235 -0
- package/dist/wizard/lib/updater.d.ts +29 -0
- package/dist/wizard/lib/updater.js +203 -0
- package/dist/wizard/lib/user-manager.d.ts +39 -0
- package/dist/wizard/lib/user-manager.js +182 -0
- package/dist/wizard/lib/vault.d.ts +26 -0
- package/dist/wizard/lib/vault.js +161 -0
- package/dist/wizard/router.d.ts +12 -0
- package/dist/wizard/router.js +58 -0
- package/dist/wizard/server.d.ts +18 -0
- package/dist/wizard/server.js +427 -0
- package/dist/wizard/ui/app.js +1357 -0
- package/dist/wizard/ui/danger-room-prophecy.js +217 -0
- package/dist/wizard/ui/danger-room.html +27 -0
- package/dist/wizard/ui/danger-room.js +29 -0
- package/dist/wizard/ui/deploy.html +181 -0
- package/dist/wizard/ui/deploy.js +616 -0
- package/dist/wizard/ui/favicon.svg +11 -0
- package/dist/wizard/ui/index.html +407 -0
- package/dist/wizard/ui/lobby.html +235 -0
- package/dist/wizard/ui/lobby.js +843 -0
- package/dist/wizard/ui/login.html +111 -0
- package/dist/wizard/ui/login.js +199 -0
- package/dist/wizard/ui/project.html +285 -0
- package/dist/wizard/ui/project.js +324 -0
- package/dist/wizard/ui/rollback.js +107 -0
- package/dist/wizard/ui/styles.css +1040 -0
- package/dist/wizard/ui/tower.html +177 -0
- package/dist/wizard/ui/tower.js +445 -0
- package/dist/wizard/ui/war-room-prophecy.js +217 -0
- package/dist/wizard/ui/war-room.html +27 -0
- package/dist/wizard/ui/war-room.js +29 -0
- package/package.json +60 -0
|
@@ -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,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway provisioner — configuration, GraphQL helpers, template deployment,
|
|
3
|
+
* config file generation, and cleanup.
|
|
4
|
+
*/
|
|
5
|
+
import type { ProvisionContext, ProvisionEmitter, CreatedResource } from './types.js';
|
|
6
|
+
/** Execute a Railway GraphQL query. */
|
|
7
|
+
export declare function gql(token: string, query: string, variables?: Record<string, unknown>): Promise<{
|
|
8
|
+
status: number;
|
|
9
|
+
body: string;
|
|
10
|
+
}>;
|
|
11
|
+
export declare const DEPLOY_POLL_INTERVAL_MS = 5000;
|
|
12
|
+
export declare const DEPLOY_POLL_TIMEOUT_MS = 300000;
|
|
13
|
+
/** Validate Railway provisioner context. */
|
|
14
|
+
export declare function validateRailwayContext(ctx: ProvisionContext): string[];
|
|
15
|
+
/** Deploy a database/redis template or fall back to serviceCreate. */
|
|
16
|
+
export declare function deployTemplate(token: string, projectId: string, environmentId: string, ctx: ProvisionContext, resources: CreatedResource[], templateName: string, resourceLabel: string, displayName: string, emit: ProvisionEmitter): Promise<void>;
|
|
17
|
+
/** Generate railway.toml configuration file. */
|
|
18
|
+
export declare function generateRailwayConfig(ctx: ProvisionContext, projectId: string, files: string[], emit: ProvisionEmitter): Promise<void>;
|
|
19
|
+
/** Write Railway environment details to .env. */
|
|
20
|
+
export declare function writeRailwayEnv(ctx: ProvisionContext, projectId: string, outputs: Record<string, string>, ghOwner: string | undefined, emit: ProvisionEmitter): Promise<void>;
|
|
21
|
+
/** Step 7: Poll for Railway deployment completion. */
|
|
22
|
+
export declare function pollDeployment(ctx: ProvisionContext, token: string, serviceId: string, environmentId: string, outputs: Record<string, string>, ghOwner: string | undefined, emit: ProvisionEmitter): Promise<void>;
|
|
23
|
+
/** Delete Railway project (services are deleted with it). */
|
|
24
|
+
export declare function cleanupRailway(resources: CreatedResource[], credentials: Record<string, string>): Promise<void>;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway provisioner — configuration, GraphQL helpers, template deployment,
|
|
3
|
+
* config file generation, and cleanup.
|
|
4
|
+
*/
|
|
5
|
+
import { writeFile } from 'node:fs/promises';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { httpsPost, safeJsonParse } from './http-client.js';
|
|
8
|
+
import { recordResourcePending, recordResourceCreated } from '../provision-manifest.js';
|
|
9
|
+
import { appendEnvSection } from '../env-writer.js';
|
|
10
|
+
/** Execute a Railway GraphQL query. */
|
|
11
|
+
export function gql(token, query, variables) {
|
|
12
|
+
const body = JSON.stringify({ query, variables });
|
|
13
|
+
return httpsPost('backboard.railway.com', '/graphql/v2', {
|
|
14
|
+
'Authorization': `Bearer ${token}`,
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
}, body);
|
|
17
|
+
}
|
|
18
|
+
export const DEPLOY_POLL_INTERVAL_MS = 5000;
|
|
19
|
+
export const DEPLOY_POLL_TIMEOUT_MS = 300_000;
|
|
20
|
+
/** Validate Railway provisioner context. */
|
|
21
|
+
export function validateRailwayContext(ctx) {
|
|
22
|
+
const errors = [];
|
|
23
|
+
if (!ctx.projectDir)
|
|
24
|
+
errors.push('Project directory is required');
|
|
25
|
+
if (!ctx.credentials['railway-token'])
|
|
26
|
+
errors.push('Railway API token is required');
|
|
27
|
+
return errors;
|
|
28
|
+
}
|
|
29
|
+
/** Deploy a database/redis template or fall back to serviceCreate. */
|
|
30
|
+
export async function deployTemplate(token, projectId, environmentId, ctx, resources, templateName, resourceLabel, displayName, emit) {
|
|
31
|
+
await recordResourcePending(ctx.runId, 'railway-service', `${projectId}-${resourceLabel}`, 'global');
|
|
32
|
+
// Only attempt templateDeploy if we have a valid environment ID
|
|
33
|
+
if (environmentId) {
|
|
34
|
+
try {
|
|
35
|
+
const res = await gql(token, `
|
|
36
|
+
mutation($projectId: String!, $environmentId: String!, $template: String!) {
|
|
37
|
+
templateDeploy(input: {
|
|
38
|
+
projectId: $projectId,
|
|
39
|
+
environmentId: $environmentId,
|
|
40
|
+
services: [{ template: $template, hasDomain: false }]
|
|
41
|
+
}) {
|
|
42
|
+
projectId
|
|
43
|
+
workflowId
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`, { projectId, environmentId, template: templateName });
|
|
47
|
+
if (res.status === 200) {
|
|
48
|
+
const data = safeJsonParse(res.body);
|
|
49
|
+
if (!data?.errors || data.errors.length === 0) {
|
|
50
|
+
resources.push({ type: 'railway-service', id: `${projectId}-${resourceLabel}`, region: 'global' });
|
|
51
|
+
await recordResourceCreated(ctx.runId, 'railway-service', `${projectId}-${resourceLabel}`, 'global');
|
|
52
|
+
emit({ step: `railway-${resourceLabel}`, status: 'done', message: `${displayName} deployed via template — connection string available in Railway dashboard` });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Fall through to serviceCreate fallback
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Fallback: create a bare service (user configures the database image in dashboard)
|
|
62
|
+
const svcRes = await gql(token, `
|
|
63
|
+
mutation($projectId: String!, $name: String!) {
|
|
64
|
+
serviceCreate(input: { projectId: $projectId, name: $name }) {
|
|
65
|
+
id
|
|
66
|
+
name
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`, { projectId, name: `${ctx.projectName}-${templateName}` });
|
|
70
|
+
if (svcRes.status === 200) {
|
|
71
|
+
const svcData = safeJsonParse(svcRes.body);
|
|
72
|
+
const svcId = svcData?.data?.serviceCreate?.id;
|
|
73
|
+
if (svcId) {
|
|
74
|
+
resources.push({ type: 'railway-service', id: svcId, region: 'global' });
|
|
75
|
+
await recordResourceCreated(ctx.runId, 'railway-service', svcId, 'global');
|
|
76
|
+
emit({ step: `railway-${resourceLabel}`, status: 'done', message: `${displayName} service created — configure database image in Railway dashboard` });
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
emit({ step: `railway-${resourceLabel}`, status: 'error', message: `${displayName} service creation returned no ID`, detail: 'Create the database manually in the Railway dashboard' });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
emit({ step: `railway-${resourceLabel}`, status: 'error', message: `Failed to create ${displayName} service (API returned ${svcRes.status})`, detail: 'Create the database manually in the Railway dashboard' });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Generate railway.toml configuration file. */
|
|
87
|
+
export async function generateRailwayConfig(ctx, projectId, files, emit) {
|
|
88
|
+
emit({ step: 'railway-config', status: 'started', message: 'Generating railway.toml' });
|
|
89
|
+
try {
|
|
90
|
+
const framework = ctx.framework || 'express';
|
|
91
|
+
const startCommand = framework === 'next.js'
|
|
92
|
+
? 'npm run start'
|
|
93
|
+
: framework === 'django'
|
|
94
|
+
? 'gunicorn config.wsgi:application --bind 0.0.0.0:$PORT'
|
|
95
|
+
: 'node dist/index.js';
|
|
96
|
+
const buildCommand = framework === 'django'
|
|
97
|
+
? 'pip install -r requirements.txt && python manage.py collectstatic --noinput'
|
|
98
|
+
: 'npm ci && npm run build';
|
|
99
|
+
const config = `# railway.toml — Railway deployment configuration
|
|
100
|
+
# Generated by VoidForge
|
|
101
|
+
# Deploy with: railway link ${projectId} && railway up
|
|
102
|
+
|
|
103
|
+
[build]
|
|
104
|
+
builder = "nixpacks"
|
|
105
|
+
buildCommand = "${buildCommand}"
|
|
106
|
+
|
|
107
|
+
[deploy]
|
|
108
|
+
startCommand = "${startCommand}"
|
|
109
|
+
healthcheckPath = "/"
|
|
110
|
+
restartPolicyType = "on_failure"
|
|
111
|
+
restartPolicyMaxRetries = 3
|
|
112
|
+
`;
|
|
113
|
+
await writeFile(join(ctx.projectDir, 'railway.toml'), config, 'utf-8');
|
|
114
|
+
files.push('railway.toml');
|
|
115
|
+
emit({ step: 'railway-config', status: 'done', message: 'Generated railway.toml' });
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
emit({ step: 'railway-config', status: 'error', message: 'Failed to write railway.toml', detail: err.message });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Write Railway environment details to .env. */
|
|
122
|
+
export async function writeRailwayEnv(ctx, projectId, outputs, ghOwner, emit) {
|
|
123
|
+
emit({ step: 'railway-env', status: 'started', message: 'Writing Railway config to .env' });
|
|
124
|
+
try {
|
|
125
|
+
const envLines = [
|
|
126
|
+
`# VoidForge Railway — generated ${new Date().toISOString()}`,
|
|
127
|
+
`RAILWAY_PROJECT_ID=${projectId}`,
|
|
128
|
+
`RAILWAY_PROJECT_NAME=${outputs['RAILWAY_PROJECT_NAME'] || ctx.projectName}`,
|
|
129
|
+
];
|
|
130
|
+
if (outputs['DEPLOY_URL'])
|
|
131
|
+
envLines.push(`DEPLOY_URL=${outputs['DEPLOY_URL']}`);
|
|
132
|
+
envLines.push(ghOwner ? '# Auto-deploys on push to main' : `# Deploy with: railway link ${projectId} && railway up`);
|
|
133
|
+
await appendEnvSection(ctx.projectDir, envLines);
|
|
134
|
+
emit({ step: 'railway-env', status: 'done', message: 'Railway config written to .env' });
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
emit({ step: 'railway-env', status: 'error', message: 'Failed to write .env', detail: err.message });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Step 7: Poll for Railway deployment completion. */
|
|
141
|
+
export async function pollDeployment(ctx, token, serviceId, environmentId, outputs, ghOwner, emit) {
|
|
142
|
+
if (!serviceId || !environmentId) {
|
|
143
|
+
if (!ghOwner) {
|
|
144
|
+
emit({ step: 'railway-deploy', status: 'skipped', message: 'No GitHub repo linked — deploy manually with: railway link && railway up' });
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
emit({ step: 'railway-deploy', status: 'started', message: 'Waiting for Railway deployment...' });
|
|
149
|
+
try {
|
|
150
|
+
const start = Date.now();
|
|
151
|
+
let deployUrl = '';
|
|
152
|
+
while (Date.now() - start < DEPLOY_POLL_TIMEOUT_MS) {
|
|
153
|
+
await new Promise(r => setTimeout(r, DEPLOY_POLL_INTERVAL_MS));
|
|
154
|
+
if (ctx.abortSignal?.aborted)
|
|
155
|
+
break;
|
|
156
|
+
const depRes = await gql(token, `
|
|
157
|
+
query($serviceId: String!) {
|
|
158
|
+
service(id: $serviceId) {
|
|
159
|
+
serviceInstances { edges { node {
|
|
160
|
+
domains { serviceDomains { domain } }
|
|
161
|
+
latestDeployment { status }
|
|
162
|
+
} } }
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
`, { serviceId });
|
|
166
|
+
if (depRes.status === 200) {
|
|
167
|
+
const depData = safeJsonParse(depRes.body);
|
|
168
|
+
const instance = depData?.data?.service?.serviceInstances?.edges?.[0]?.node;
|
|
169
|
+
const deployStatus = instance?.latestDeployment?.status;
|
|
170
|
+
const domain = instance?.domains?.serviceDomains?.[0]?.domain;
|
|
171
|
+
if (deployStatus === 'SUCCESS' && domain) {
|
|
172
|
+
deployUrl = `https://${domain}`;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
if (deployStatus === 'FAILED' || deployStatus === 'CRASHED') {
|
|
176
|
+
emit({ step: 'railway-deploy', status: 'error', message: `Deployment ${deployStatus.toLowerCase()} — check Railway dashboard` });
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const elapsed = Math.round((Date.now() - start) / 1000);
|
|
181
|
+
if (elapsed % 15 === 0) {
|
|
182
|
+
emit({ step: 'railway-deploy', status: 'started', message: `Waiting for deployment... (${elapsed}s)` });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (deployUrl) {
|
|
186
|
+
outputs['DEPLOY_URL'] = deployUrl;
|
|
187
|
+
if (!outputs['RAILWAY_CUSTOM_DOMAIN']) {
|
|
188
|
+
outputs['RAILWAY_DOMAIN'] = deployUrl.replace('https://', '');
|
|
189
|
+
}
|
|
190
|
+
emit({ step: 'railway-deploy', status: 'done', message: `Live at ${deployUrl}` });
|
|
191
|
+
}
|
|
192
|
+
else if (!ctx.abortSignal?.aborted) {
|
|
193
|
+
emit({ step: 'railway-deploy', status: 'error', message: 'Deployment polling timed out — check Railway dashboard' });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
emit({ step: 'railway-deploy', status: 'error', message: 'Failed to poll deployment', detail: err.message });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** Delete Railway project (services are deleted with it). */
|
|
201
|
+
export async function cleanupRailway(resources, credentials) {
|
|
202
|
+
const token = credentials['railway-token'];
|
|
203
|
+
if (!token)
|
|
204
|
+
return;
|
|
205
|
+
for (const resource of resources) {
|
|
206
|
+
if (resource.type === 'railway-project') {
|
|
207
|
+
try {
|
|
208
|
+
await gql(token, `
|
|
209
|
+
mutation($id: String!) {
|
|
210
|
+
projectDelete(id: $id)
|
|
211
|
+
}
|
|
212
|
+
`, { id: resource.id });
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
console.error(`Failed to delete Railway project ${resource.id}:`, err.message);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Plugins are deleted with the project — no need to delete separately
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway provisioner — deployment logic: project creation, service management,
|
|
3
|
+
* GitHub linking, custom domains, environment variables, and deploy polling.
|
|
4
|
+
*/
|
|
5
|
+
import type { ProvisionContext, ProvisionEmitter, CreatedResource } from './types.js';
|
|
6
|
+
/** Step 1: Create Railway project. Returns projectId or null on failure. */
|
|
7
|
+
export declare function createProject(ctx: ProvisionContext, token: string, resources: CreatedResource[], outputs: Record<string, string>, emit: ProvisionEmitter): Promise<string | null>;
|
|
8
|
+
/** Fetch the default environment ID for a Railway project. */
|
|
9
|
+
export declare function fetchEnvironmentId(token: string, projectId: string, emit: ProvisionEmitter): Promise<string>;
|
|
10
|
+
/** Step 2: Add database service if requested (ADR-019: template services). */
|
|
11
|
+
export declare function addDatabaseService(ctx: ProvisionContext, token: string, projectId: string, environmentId: string, resources: CreatedResource[], outputs: Record<string, string>, emit: ProvisionEmitter): Promise<void>;
|
|
12
|
+
/** Step 3: Add Redis service if cache requested (ADR-019: template services). */
|
|
13
|
+
export declare function addRedisService(ctx: ProvisionContext, token: string, projectId: string, environmentId: string, resources: CreatedResource[], emit: ProvisionEmitter): Promise<void>;
|
|
14
|
+
/** Step 4: Create service with GitHub source (ADR-015). Returns serviceId. */
|
|
15
|
+
export declare function createGitHubService(ctx: ProvisionContext, token: string, projectId: string, resources: CreatedResource[], emit: ProvisionEmitter): Promise<string>;
|
|
16
|
+
/** Step 5: Add custom domain to Railway service. */
|
|
17
|
+
export declare function addCustomDomain(ctx: ProvisionContext, token: string, projectId: string, serviceId: string, environmentId: string, outputs: Record<string, string>, emit: ProvisionEmitter): Promise<void>;
|
|
18
|
+
/** Step 6: Set environment variables on the service. */
|
|
19
|
+
export declare function setEnvironmentVariables(ctx: ProvisionContext, token: string, projectId: string, serviceId: string, environmentId: string, emit: ProvisionEmitter): Promise<void>;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway provisioner — deployment logic: project creation, service management,
|
|
3
|
+
* GitHub linking, custom domains, environment variables, and deploy polling.
|
|
4
|
+
*/
|
|
5
|
+
import { safeJsonParse } from './http-client.js';
|
|
6
|
+
import { recordResourcePending, recordResourceCreated } from '../provision-manifest.js';
|
|
7
|
+
import { gql, deployTemplate } from './railway-config.js';
|
|
8
|
+
/** Step 1: Create Railway project. Returns projectId or null on failure. */
|
|
9
|
+
export async function createProject(ctx, token, resources, outputs, emit) {
|
|
10
|
+
emit({ step: 'railway-project', status: 'started', message: 'Creating Railway project' });
|
|
11
|
+
try {
|
|
12
|
+
await recordResourcePending(ctx.runId, 'railway-project', ctx.projectName, 'global');
|
|
13
|
+
const res = await gql(token, `
|
|
14
|
+
mutation($name: String!) {
|
|
15
|
+
projectCreate(input: { name: $name }) {
|
|
16
|
+
id
|
|
17
|
+
name
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`, { name: ctx.projectName });
|
|
21
|
+
if (res.status !== 200) {
|
|
22
|
+
throw new Error(`Railway API returned ${res.status}`);
|
|
23
|
+
}
|
|
24
|
+
const data = safeJsonParse(res.body);
|
|
25
|
+
if (data.errors && data.errors.length > 0) {
|
|
26
|
+
throw new Error(data.errors[0].message);
|
|
27
|
+
}
|
|
28
|
+
const projectId = data.data?.projectCreate?.id ?? '';
|
|
29
|
+
if (!projectId)
|
|
30
|
+
throw new Error('No project ID returned');
|
|
31
|
+
resources.push({ type: 'railway-project', id: projectId, region: 'global' });
|
|
32
|
+
await recordResourceCreated(ctx.runId, 'railway-project', projectId, 'global');
|
|
33
|
+
outputs['RAILWAY_PROJECT_ID'] = projectId;
|
|
34
|
+
outputs['RAILWAY_PROJECT_NAME'] = data.data?.projectCreate?.name ?? ctx.projectName;
|
|
35
|
+
emit({ step: 'railway-project', status: 'done', message: `Project "${outputs['RAILWAY_PROJECT_NAME']}" created on Railway` });
|
|
36
|
+
return projectId;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
emit({ step: 'railway-project', status: 'error', message: 'Failed to create Railway project', detail: err.message });
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Fetch the default environment ID for a Railway project. */
|
|
44
|
+
export async function fetchEnvironmentId(token, projectId, emit) {
|
|
45
|
+
try {
|
|
46
|
+
const envRes = await gql(token, `
|
|
47
|
+
query($projectId: String!) {
|
|
48
|
+
project(id: $projectId) {
|
|
49
|
+
environments { edges { node { id name } } }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`, { projectId });
|
|
53
|
+
if (envRes.status === 200) {
|
|
54
|
+
const envData = safeJsonParse(envRes.body);
|
|
55
|
+
const edges = envData?.data?.project?.environments?.edges ?? [];
|
|
56
|
+
const prodEnv = edges.find(e => e.node.name === 'production') || edges[0];
|
|
57
|
+
return prodEnv?.node.id ?? '';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
emit({ step: 'railway-env', status: 'error', message: 'Could not fetch project environment — database/redis services will use fallback creation', detail: 'Environment query failed' });
|
|
62
|
+
}
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
/** Step 2: Add database service if requested (ADR-019: template services). */
|
|
66
|
+
export async function addDatabaseService(ctx, token, projectId, environmentId, resources, outputs, emit) {
|
|
67
|
+
if (ctx.database === 'postgres' || ctx.database === 'mysql') {
|
|
68
|
+
const dbType = ctx.database === 'postgres' ? 'Postgres' : 'MySQL';
|
|
69
|
+
const templateName = ctx.database === 'postgres' ? 'postgres' : 'mysql';
|
|
70
|
+
emit({ step: 'railway-db', status: 'started', message: `Adding ${dbType} service to Railway project` });
|
|
71
|
+
try {
|
|
72
|
+
await deployTemplate(token, projectId, environmentId, ctx, resources, templateName, 'db', dbType, emit);
|
|
73
|
+
outputs['RAILWAY_DB_TYPE'] = dbType;
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
emit({ step: 'railway-db', status: 'error', message: `Failed to add ${dbType} service`, detail: err.message });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
emit({ step: 'railway-db', status: 'skipped', message: ctx.database === 'sqlite' ? 'SQLite — no remote database service needed' : 'No database requested' });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Step 3: Add Redis service if cache requested (ADR-019: template services). */
|
|
84
|
+
export async function addRedisService(ctx, token, projectId, environmentId, resources, emit) {
|
|
85
|
+
if (ctx.cache === 'redis') {
|
|
86
|
+
emit({ step: 'railway-redis', status: 'started', message: 'Adding Redis service to Railway project' });
|
|
87
|
+
try {
|
|
88
|
+
await deployTemplate(token, projectId, environmentId, ctx, resources, 'redis', 'redis', 'Redis', emit);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
emit({ step: 'railway-redis', status: 'error', message: 'Failed to add Redis service', detail: err.message });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
emit({ step: 'railway-redis', status: 'skipped', message: 'No cache requested' });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Step 4: Create service with GitHub source (ADR-015). Returns serviceId. */
|
|
99
|
+
export async function createGitHubService(ctx, token, projectId, resources, emit) {
|
|
100
|
+
const ghOwner = ctx.credentials['_github-owner'];
|
|
101
|
+
const ghRepo = ctx.credentials['_github-repo-name'];
|
|
102
|
+
if (!projectId || !ghOwner || !ghRepo)
|
|
103
|
+
return '';
|
|
104
|
+
emit({ step: 'railway-service', status: 'started', message: `Creating service linked to ${ghOwner}/${ghRepo}` });
|
|
105
|
+
try {
|
|
106
|
+
const svcRes = await gql(token, `
|
|
107
|
+
mutation($projectId: String!, $repo: String!) {
|
|
108
|
+
serviceCreate(input: {
|
|
109
|
+
projectId: $projectId,
|
|
110
|
+
source: { repo: $repo }
|
|
111
|
+
}) {
|
|
112
|
+
id
|
|
113
|
+
name
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
`, { projectId, repo: `${ghOwner}/${ghRepo}` });
|
|
117
|
+
if (svcRes.status === 200) {
|
|
118
|
+
const svcData = safeJsonParse(svcRes.body);
|
|
119
|
+
if (svcData?.errors?.length) {
|
|
120
|
+
emit({ step: 'railway-service', status: 'error', message: 'Failed to create service', detail: svcData.errors[0].message });
|
|
121
|
+
return '';
|
|
122
|
+
}
|
|
123
|
+
const serviceId = svcData?.data?.serviceCreate?.id ?? '';
|
|
124
|
+
if (serviceId) {
|
|
125
|
+
resources.push({ type: 'railway-service', id: serviceId, region: 'global' });
|
|
126
|
+
await recordResourceCreated(ctx.runId, 'railway-service', serviceId, 'global');
|
|
127
|
+
}
|
|
128
|
+
emit({ step: 'railway-service', status: 'done', message: 'Service created — linked to GitHub repo' });
|
|
129
|
+
return serviceId;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
emit({ step: 'railway-service', status: 'error', message: 'Failed to create service', detail: err.message });
|
|
134
|
+
}
|
|
135
|
+
return '';
|
|
136
|
+
}
|
|
137
|
+
/** Step 5: Add custom domain to Railway service. */
|
|
138
|
+
export async function addCustomDomain(ctx, token, projectId, serviceId, environmentId, outputs, emit) {
|
|
139
|
+
if (ctx.hostname && projectId && serviceId && environmentId) {
|
|
140
|
+
emit({ step: 'railway-domain', status: 'started', message: `Adding domain ${ctx.hostname} to Railway service` });
|
|
141
|
+
try {
|
|
142
|
+
const domRes = await gql(token, `
|
|
143
|
+
mutation($projectId: String!, $environmentId: String!, $serviceId: String!, $domain: String!) {
|
|
144
|
+
customDomainCreate(input: { projectId: $projectId, environmentId: $environmentId, serviceId: $serviceId, domain: $domain }) {
|
|
145
|
+
id
|
|
146
|
+
domain
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
`, { projectId, environmentId, serviceId, domain: ctx.hostname });
|
|
150
|
+
if (domRes.status !== 200)
|
|
151
|
+
throw new Error(`Railway API returned ${domRes.status}`);
|
|
152
|
+
const domData = safeJsonParse(domRes.body);
|
|
153
|
+
if (domData?.errors && domData.errors.length > 0) {
|
|
154
|
+
throw new Error(domData.errors[0].message);
|
|
155
|
+
}
|
|
156
|
+
const domain = domData?.data?.customDomainCreate?.domain ?? ctx.hostname;
|
|
157
|
+
outputs['RAILWAY_CUSTOM_DOMAIN'] = domain;
|
|
158
|
+
emit({ step: 'railway-domain', status: 'done', message: `Domain "${domain}" added to Railway service` });
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
emit({ step: 'railway-domain', status: 'error', message: 'Failed to add domain to Railway', detail: err.message });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (ctx.hostname && projectId && (!serviceId || !environmentId)) {
|
|
165
|
+
emit({ step: 'railway-domain', status: 'skipped', message: 'Cannot add domain — service or environment not available. Add domain manually in Railway dashboard.' });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Step 6: Set environment variables on the service. */
|
|
169
|
+
export async function setEnvironmentVariables(ctx, token, projectId, serviceId, environmentId, emit) {
|
|
170
|
+
if (!serviceId || !environmentId)
|
|
171
|
+
return;
|
|
172
|
+
emit({ step: 'railway-envvars', status: 'started', message: 'Setting environment variables' });
|
|
173
|
+
try {
|
|
174
|
+
const variables = {};
|
|
175
|
+
if (ctx.database === 'postgres' || ctx.database === 'mysql') {
|
|
176
|
+
variables['DATABASE_URL'] = ctx.database === 'postgres'
|
|
177
|
+
? '${{Postgres.DATABASE_URL}}'
|
|
178
|
+
: '${{MySQL.DATABASE_URL}}';
|
|
179
|
+
}
|
|
180
|
+
if (ctx.cache === 'redis') {
|
|
181
|
+
variables['REDIS_URL'] = '${{Redis.REDIS_URL}}';
|
|
182
|
+
}
|
|
183
|
+
if (Object.keys(variables).length > 0) {
|
|
184
|
+
await gql(token, `
|
|
185
|
+
mutation($input: VariableCollectionUpsertInput!) {
|
|
186
|
+
variableCollectionUpsert(input: $input)
|
|
187
|
+
}
|
|
188
|
+
`, {
|
|
189
|
+
input: {
|
|
190
|
+
projectId,
|
|
191
|
+
serviceId,
|
|
192
|
+
environmentId,
|
|
193
|
+
variables,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
emit({ step: 'railway-envvars', status: 'done', message: `Set ${Object.keys(variables).length} environment variables` });
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
emit({ step: 'railway-envvars', status: 'done', message: 'No environment variables to set' });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
emit({ step: 'railway-envvars', status: 'error', message: 'Failed to set env vars', detail: err.message });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway provisioner — orchestrator that coordinates project creation,
|
|
3
|
+
* service deployment, config generation, and cleanup.
|
|
4
|
+
*/
|
|
5
|
+
import { validateRailwayContext, generateRailwayConfig, writeRailwayEnv, cleanupRailway, pollDeployment } from './railway-config.js';
|
|
6
|
+
import { createProject, fetchEnvironmentId, addDatabaseService, addRedisService, createGitHubService, addCustomDomain, setEnvironmentVariables, } from './railway-deploy.js';
|
|
7
|
+
export const railwayProvisioner = {
|
|
8
|
+
async validate(ctx) {
|
|
9
|
+
return validateRailwayContext(ctx);
|
|
10
|
+
},
|
|
11
|
+
async provision(ctx, emit) {
|
|
12
|
+
const files = [];
|
|
13
|
+
const resources = [];
|
|
14
|
+
const outputs = {};
|
|
15
|
+
const token = ctx.credentials['railway-token'];
|
|
16
|
+
const ghOwner = ctx.credentials['_github-owner'];
|
|
17
|
+
// Step 1: Create Railway project
|
|
18
|
+
const projectId = await createProject(ctx, token, resources, outputs, emit);
|
|
19
|
+
if (!projectId) {
|
|
20
|
+
return { success: false, resources, outputs, files, error: outputs['error'] || 'Failed to create Railway project' };
|
|
21
|
+
}
|
|
22
|
+
// Fetch the default environment ID — shared by all subsequent steps
|
|
23
|
+
const environmentId = await fetchEnvironmentId(token, projectId, emit);
|
|
24
|
+
// Step 2: Add database service if requested
|
|
25
|
+
await addDatabaseService(ctx, token, projectId, environmentId, resources, outputs, emit);
|
|
26
|
+
// Step 3: Add Redis service if cache requested
|
|
27
|
+
await addRedisService(ctx, token, projectId, environmentId, resources, emit);
|
|
28
|
+
// Step 4: Create service with GitHub source
|
|
29
|
+
const serviceId = await createGitHubService(ctx, token, projectId, resources, emit);
|
|
30
|
+
// Step 5: Add custom domain
|
|
31
|
+
await addCustomDomain(ctx, token, projectId, serviceId, environmentId, outputs, emit);
|
|
32
|
+
// Step 6: Set environment variables
|
|
33
|
+
await setEnvironmentVariables(ctx, token, projectId, serviceId, environmentId, emit);
|
|
34
|
+
// Step 7: Poll for deployment
|
|
35
|
+
await pollDeployment(ctx, token, serviceId, environmentId, outputs, ghOwner, emit);
|
|
36
|
+
// Step 8: Generate railway.toml
|
|
37
|
+
await generateRailwayConfig(ctx, projectId, files, emit);
|
|
38
|
+
// Step 9: Write .env
|
|
39
|
+
await writeRailwayEnv(ctx, projectId, outputs, ghOwner, emit);
|
|
40
|
+
return { success: true, resources, outputs, files };
|
|
41
|
+
},
|
|
42
|
+
async cleanup(resources, credentials) {
|
|
43
|
+
await cleanupRailway(resources, credentials);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template: Caddyfile — reverse proxy + automatic HTTPS + security headers.
|
|
3
|
+
* Written to projectDir/infra/Caddyfile
|
|
4
|
+
*/
|
|
5
|
+
interface CaddyfileOptions {
|
|
6
|
+
framework: string;
|
|
7
|
+
hostname?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateCaddyfile(opts: CaddyfileOptions): string;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template: Caddyfile — reverse proxy + automatic HTTPS + security headers.
|
|
3
|
+
* Written to projectDir/infra/Caddyfile
|
|
4
|
+
*/
|
|
5
|
+
export function generateCaddyfile(opts) {
|
|
6
|
+
const port = opts.framework === 'django' ? '8000' : '3000';
|
|
7
|
+
const siteAddress = opts.hostname || ':80';
|
|
8
|
+
const comment = opts.hostname
|
|
9
|
+
? `# Caddyfile — Reverse proxy for ${opts.hostname}
|
|
10
|
+
# Generated by VoidForge
|
|
11
|
+
#
|
|
12
|
+
# Caddy will auto-provision HTTPS via Let's Encrypt.
|
|
13
|
+
# If using Cloudflare proxy (orange cloud), set SSL mode to "Full" in Cloudflare dashboard.
|
|
14
|
+
#
|
|
15
|
+
# Usage:
|
|
16
|
+
# 1. Copy to server: scp Caddyfile user@host:/etc/caddy/Caddyfile
|
|
17
|
+
# 2. Reload: sudo systemctl reload caddy`
|
|
18
|
+
: `# Caddyfile — Reverse proxy with automatic HTTPS
|
|
19
|
+
# Generated by VoidForge
|
|
20
|
+
#
|
|
21
|
+
# Usage:
|
|
22
|
+
# 1. Replace :80 with your domain (e.g. example.com)
|
|
23
|
+
# 2. Copy to server: scp Caddyfile user@host:/etc/caddy/Caddyfile
|
|
24
|
+
# 3. Reload: sudo systemctl reload caddy
|
|
25
|
+
#
|
|
26
|
+
# Caddy auto-provisions HTTPS certificates via Let's Encrypt
|
|
27
|
+
# when you replace :80 with a real domain name.`;
|
|
28
|
+
return `${comment}
|
|
29
|
+
|
|
30
|
+
${siteAddress} {
|
|
31
|
+
reverse_proxy localhost:${port}
|
|
32
|
+
|
|
33
|
+
# Security headers
|
|
34
|
+
header {
|
|
35
|
+
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
|
36
|
+
X-Content-Type-Options nosniff
|
|
37
|
+
X-Frame-Options DENY
|
|
38
|
+
Referrer-Policy strict-origin-when-cross-origin
|
|
39
|
+
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
|
40
|
+
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'"
|
|
41
|
+
-Server
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Gzip compression
|
|
45
|
+
encode gzip
|
|
46
|
+
|
|
47
|
+
# Access logs
|
|
48
|
+
log {
|
|
49
|
+
output file /var/log/caddy/access.log
|
|
50
|
+
format json
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
}
|