diff --git a/.gitignore b/.gitignore
index f14ef6d..ae11783 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-# Build artifacts (root only — do not ignore the cmd/devopsgen package)
+# Build artifacts (root only — do not ignore the cmd/devopsgen package)
/devopsgen
/devopsgen.exe
*.exe
@@ -29,4 +29,6 @@ templates/local/
# Generated output
/dist/
/Dockerfile
-/kubernetes/
\ No newline at end of file
+/kubernetes/
+# cloudflare cli state
+.cloudflare/
diff --git a/README.md b/README.md
index a1edfd1..fc0a991 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Developer-oriented DevOps scaffolding tool. DevOpsGen generates deterministic
Dockerfiles, GitHub Actions workflows, and Kubernetes manifests from a small,
explicit configuration.
-> Documentation: **[React documentation site](docs/web/dist/index.html)** —
+> Documentation: **[devopsgen.bangkah.tech](https://devopsgen.bangkah.tech/)** —
> screenshots of every command, the interactive wizard, flags reference and
> exit codes. Build it with `npm run build` inside `docs/web`.
diff --git a/docs/web/.gitignore b/docs/web/.gitignore
index c824a78..54b5637 100644
--- a/docs/web/.gitignore
+++ b/docs/web/.gitignore
@@ -1,3 +1,13 @@
-node_modules/
+node_modules/
.ssr/
.DS_Store
+
+# wrangler files
+.wrangler
+.dev.vars*
+!.dev.vars.example
+.env*
+!.env.example
+
+# cloudflare build output
+.cloudflare/
diff --git a/docs/web/cloudflare.config.ts b/docs/web/cloudflare.config.ts
new file mode 100644
index 0000000..06e343d
--- /dev/null
+++ b/docs/web/cloudflare.config.ts
@@ -0,0 +1,16 @@
+import { defineConfig } from "cf/config";
+
+export default defineConfig({
+ worker: {
+ name: "devopsgen-docs",
+ compatibilityDate: "2026-09-21",
+ observability: {
+ enabled: true,
+ },
+ workersDev: false,
+ domains: ["devopsgen.bangkah.tech"],
+ assets: {
+ notFoundHandling: "single-page-application",
+ },
+ },
+});
diff --git a/docs/web/dist/.assetsignore b/docs/web/dist/.assetsignore
new file mode 100644
index 0000000..29ec648
--- /dev/null
+++ b/docs/web/dist/.assetsignore
@@ -0,0 +1,2 @@
+wrangler.json
+.dev.vars
diff --git a/docs/web/dist/assets/index-CNcHcO5J.js b/docs/web/dist/assets/index-Bpn6tfSv.js
similarity index 98%
rename from docs/web/dist/assets/index-CNcHcO5J.js
rename to docs/web/dist/assets/index-Bpn6tfSv.js
index 0ee3903..6aa11c9 100644
--- a/docs/web/dist/assets/index-CNcHcO5J.js
+++ b/docs/web/dist/assets/index-Bpn6tfSv.js
@@ -22,4 +22,4 @@ case $? in
3) devopsgen init --force --stack go --registry ghcr --image you/myapp --port 8080 ;;
2) echo "fix your flags" >&2 ;;
*) echo "see devopsgen validate output" >&2 ;;
-esac`}),(0,d.jsx)(`div`,{className:`callout callout-info`,children:`Codes are part of DevOpsGen's compatibility promise: bumping a major version may add new codes, but existing ones keep their meaning.`})]})}var re=`https://bangkahdev.github.io/DevOpsGen/`,x=[{path:``,component:_,title:`DevOpsGen — DevOps scaffolding for Go & Node.js projects`,description:`DevOpsGen generates production-ready Dockerfiles, GitHub Actions pipelines and Kubernetes manifests for Go and Node.js projects, with safe dry-run plans, automatic backups and config validation.`,keywords:`DevOpsGen, dockerfile generator, github actions generator, kubernetes manifests, go, nodejs, scaffolding, ci cd`,ogImage:`img/init-success.png`},{path:`getting-started`,component:v,title:`Getting Started — DevOpsGen Docs`,description:`Install DevOpsGen via go install or a release binary, then generate a complete Docker, CI and Kubernetes setup for your project with a single command.`,keywords:`DevOpsGen install, go install, quickstart, getting started`,ogImage:`img/init-success.png`},{path:`wizard`,component:y,title:`Interactive Wizard — DevOpsGen Docs`,description:`DevOpsGen launches an interactive TUI wizard that walks through stack detection, ports, container images and Kubernetes options, then writes the generated configuration.`,keywords:`DevOpsGen wizard, tui, bubbletea, interactive`,ogImage:`img/wizard.png`},{path:`init`,component:b,title:`init command — DevOpsGen Docs`,description:`Full reference for devopsgen init flags: stack, app type, CI provider, registry, image, port, Kubernetes ingress, health path, dry-run and force overwrite behaviour.`,keywords:`devopsgen init, flags, dry-run, force, image, ingress`,ogImage:`img/init-success.png`},{path:`detect`,component:ee,title:`detect command — DevOpsGen Docs`,description:`devopsgen detect inspects the current project and reports the programming stack, the files it based its decision on, and candidate application types.`,keywords:`devopsgen detect, stack detection, go.mod, package.json`,ogImage:`img/detect.png`},{path:`validate`,component:te,title:`validate command — DevOpsGen Docs`,description:`devopsgen validate statically checks generated Dockerfiles, GitHub Actions workflows and Kubernetes manifests: FROM digests, action pinning, naming rules, probes and more.`,keywords:`devopsgen validate, dockerfile lint, workflow lint, kubernetes manifest lint`,ogImage:`img/validate.png`},{path:`exit-codes`,component:ne,title:`Exit codes — DevOpsGen Docs`,description:`Every devopsgen command exits with a documented status code: 0 success, 1 general error, 2 invalid configuration, 3 file conflicts, 4 validation failure, 5 ambiguous detection.`,keywords:`devopsgen exit codes, ci integration, pipeline status`,ogImage:`img/validate.png`}],ie=[{label:`Overview`,items:[`getting-started`,`wizard`]},{label:`Command reference`,items:[`init`,`detect`,`validate`]},{label:`Operations`,items:[`exit-codes`]}];function S({rel:e,activePath:t,children:n}){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`a`,{className:`skip`,href:`#main`,children:`skip to content`}),(0,d.jsxs)(`header`,{className:`topbar`,children:[(0,d.jsxs)(`a`,{className:`brand`,href:e||`./`,children:[(0,d.jsx)(`span`,{className:`brand-mark`,children:`DG`}),(0,d.jsx)(`span`,{className:`brand-name`,children:`DevOpsGen`}),(0,d.jsx)(`span`,{className:`brand-sub`,children:`DOCS`})]}),(0,d.jsx)(`a`,{className:`gh-pill`,href:`https://github.com/Bangkahdev/DevOpsGen`,rel:`noopener noreferrer`,target:`_blank`,children:`GitHub`})]}),(0,d.jsxs)(`div`,{className:`shell`,children:[(0,d.jsxs)(`aside`,{className:`sidebar`,"aria-label":`Documentation navigation`,children:[(0,d.jsx)(`a`,{className:`side-link side-home${t===``?` is-active`:``}`,href:e||`./`,children:`Home`}),ie.map(n=>(0,d.jsxs)(`div`,{className:`side-group`,children:[(0,d.jsx)(`p`,{className:`group-label`,children:n.label}),(0,d.jsx)(`ul`,{children:n.items.map(n=>{let r=x.find(e=>e.path===n);return(0,d.jsx)(`li`,{children:(0,d.jsx)(`a`,{className:`side-link${t===n?` is-active`:``}`,href:`${e}${n}/`,"aria-current":t===n?`page`:void 0,children:r?r.path.replace(/-/g,` `):n})},n)})})]},n.label))]}),(0,d.jsx)(`main`,{id:`main`,children:n})]}),(0,d.jsxs)(`footer`,{className:`footer`,children:[(0,d.jsxs)(`p`,{children:[`DevOpsGen — deterministic DevOps scaffolding for Go & Node.js.`,` `,(0,d.jsx)(`a`,{href:`${e}getting-started/`,children:`Get started`}),` or browse the`,` `,(0,d.jsx)(`a`,{href:`${e}exit-codes/`,children:`exit codes`}),`.`]}),(0,d.jsxs)(`p`,{className:`footer-links`,children:[(0,d.jsx)(`a`,{href:re,children:`canonical site`}),` · `,(0,d.jsx)(`a`,{href:`https://github.com/Bangkahdev/DevOpsGen`,children:`source code`})]})]})]})}var ae=x.find(e=>e.path===location.pathname.replace(/\/$/,``).replace(/^.*\//,``))??null,oe=ae&&ae.path===``?``:`../`,se=ae??x[0];(0,l.createRoot)(document.getElementById(`root`)).render((0,d.jsx)(S,{rel:oe,activePath:ae?ae.path:``,children:(0,d.jsx)(se.component,{rel:oe})}));
\ No newline at end of file
+esac`}),(0,d.jsx)(`div`,{className:`callout callout-info`,children:`Codes are part of DevOpsGen's compatibility promise: bumping a major version may add new codes, but existing ones keep their meaning.`})]})}var re=`https://devopsgen.bangkah.tech/`,x=[{path:``,component:_,title:`DevOpsGen — DevOps scaffolding for Go & Node.js projects`,description:`DevOpsGen generates production-ready Dockerfiles, GitHub Actions pipelines and Kubernetes manifests for Go and Node.js projects, with safe dry-run plans, automatic backups and config validation.`,keywords:`DevOpsGen, dockerfile generator, github actions generator, kubernetes manifests, go, nodejs, scaffolding, ci cd`,ogImage:`img/init-success.png`},{path:`getting-started`,component:v,title:`Getting Started — DevOpsGen Docs`,description:`Install DevOpsGen via go install or a release binary, then generate a complete Docker, CI and Kubernetes setup for your project with a single command.`,keywords:`DevOpsGen install, go install, quickstart, getting started`,ogImage:`img/init-success.png`},{path:`wizard`,component:y,title:`Interactive Wizard — DevOpsGen Docs`,description:`DevOpsGen launches an interactive TUI wizard that walks through stack detection, ports, container images and Kubernetes options, then writes the generated configuration.`,keywords:`DevOpsGen wizard, tui, bubbletea, interactive`,ogImage:`img/wizard.png`},{path:`init`,component:b,title:`init command — DevOpsGen Docs`,description:`Full reference for devopsgen init flags: stack, app type, CI provider, registry, image, port, Kubernetes ingress, health path, dry-run and force overwrite behaviour.`,keywords:`devopsgen init, flags, dry-run, force, image, ingress`,ogImage:`img/init-success.png`},{path:`detect`,component:ee,title:`detect command — DevOpsGen Docs`,description:`devopsgen detect inspects the current project and reports the programming stack, the files it based its decision on, and candidate application types.`,keywords:`devopsgen detect, stack detection, go.mod, package.json`,ogImage:`img/detect.png`},{path:`validate`,component:te,title:`validate command — DevOpsGen Docs`,description:`devopsgen validate statically checks generated Dockerfiles, GitHub Actions workflows and Kubernetes manifests: FROM digests, action pinning, naming rules, probes and more.`,keywords:`devopsgen validate, dockerfile lint, workflow lint, kubernetes manifest lint`,ogImage:`img/validate.png`},{path:`exit-codes`,component:ne,title:`Exit codes — DevOpsGen Docs`,description:`Every devopsgen command exits with a documented status code: 0 success, 1 general error, 2 invalid configuration, 3 file conflicts, 4 validation failure, 5 ambiguous detection.`,keywords:`devopsgen exit codes, ci integration, pipeline status`,ogImage:`img/validate.png`}],ie=[{label:`Overview`,items:[`getting-started`,`wizard`]},{label:`Command reference`,items:[`init`,`detect`,`validate`]},{label:`Operations`,items:[`exit-codes`]}];function S({rel:e,activePath:t,children:n}){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`a`,{className:`skip`,href:`#main`,children:`skip to content`}),(0,d.jsxs)(`header`,{className:`topbar`,children:[(0,d.jsxs)(`a`,{className:`brand`,href:e||`./`,children:[(0,d.jsx)(`span`,{className:`brand-mark`,children:`DG`}),(0,d.jsx)(`span`,{className:`brand-name`,children:`DevOpsGen`}),(0,d.jsx)(`span`,{className:`brand-sub`,children:`DOCS`})]}),(0,d.jsx)(`a`,{className:`gh-pill`,href:`https://github.com/Bangkahdev/DevOpsGen`,rel:`noopener noreferrer`,target:`_blank`,children:`GitHub`})]}),(0,d.jsxs)(`div`,{className:`shell`,children:[(0,d.jsxs)(`aside`,{className:`sidebar`,"aria-label":`Documentation navigation`,children:[(0,d.jsx)(`a`,{className:`side-link side-home${t===``?` is-active`:``}`,href:e||`./`,children:`Home`}),ie.map(n=>(0,d.jsxs)(`div`,{className:`side-group`,children:[(0,d.jsx)(`p`,{className:`group-label`,children:n.label}),(0,d.jsx)(`ul`,{children:n.items.map(n=>{let r=x.find(e=>e.path===n);return(0,d.jsx)(`li`,{children:(0,d.jsx)(`a`,{className:`side-link${t===n?` is-active`:``}`,href:`${e}${n}/`,"aria-current":t===n?`page`:void 0,children:r?r.path.replace(/-/g,` `):n})},n)})})]},n.label))]}),(0,d.jsx)(`main`,{id:`main`,children:n})]}),(0,d.jsxs)(`footer`,{className:`footer`,children:[(0,d.jsxs)(`p`,{children:[`DevOpsGen — deterministic DevOps scaffolding for Go & Node.js.`,` `,(0,d.jsx)(`a`,{href:`${e}getting-started/`,children:`Get started`}),` or browse the`,` `,(0,d.jsx)(`a`,{href:`${e}exit-codes/`,children:`exit codes`}),`.`]}),(0,d.jsxs)(`p`,{className:`footer-links`,children:[(0,d.jsx)(`a`,{href:re,children:`canonical site`}),` · `,(0,d.jsx)(`a`,{href:`https://github.com/Bangkahdev/DevOpsGen`,children:`source code`})]})]})]})}var ae=x.find(e=>e.path===location.pathname.replace(/\/$/,``).replace(/^.*\//,``))??null,oe=ae&&ae.path===``?``:`../`,se=ae??x[0];(0,l.createRoot)(document.getElementById(`root`)).render((0,d.jsx)(S,{rel:oe,activePath:ae?ae.path:``,children:(0,d.jsx)(se.component,{rel:oe})}));
\ No newline at end of file
diff --git a/docs/web/dist/detect/index.html b/docs/web/dist/detect/index.html
index f3682a7..a1718c7 100644
--- a/docs/web/dist/detect/index.html
+++ b/docs/web/dist/detect/index.html
@@ -6,21 +6,21 @@
Inspect the current project and report what DevOpsGen would scaffold for it: the programming stack, the exact files that shaped the decision, and the candidate application types.
devopsgen detect inside a Go module — chain of evidence straight from the filesystem.
Reading the output
Line
Meaning
stack: go
The detected programming stack (go or nodejs).
indicators: go.mod, ...
The files that produced evidence — your audit trail for why the stack matched.
app-type candidates: binary
Application types plausible for this project; the wizard default comes from here too.
How it decides
Go — go.mod and its module directive looking like module example.com/app.
Node.js — package.json, plus its dependencies, and lockfile flavours (npm / pnpm) that later steer Docker image commands.
Ambiguity or zero indicators produce a distinct exit code (5) so scripts can branch safely — see exit codes.
Detection semantics: DevOpsGen detects in the current working directory, not in --output-dir. Run it from the project you want scanned.
Inspect the current project and report what DevOpsGen would scaffold for it: the programming stack, the exact files that shaped the decision, and the candidate application types.
devopsgen detect inside a Go module — chain of evidence straight from the filesystem.
Reading the output
Line
Meaning
stack: go
The detected programming stack (go or nodejs).
indicators: go.mod, ...
The files that produced evidence — your audit trail for why the stack matched.
app-type candidates: binary
Application types plausible for this project; the wizard default comes from here too.
How it decides
Go — go.mod and its module directive looking like module example.com/app.
Node.js — package.json, plus its dependencies, and lockfile flavours (npm / pnpm) that later steer Docker image commands.
Ambiguity or zero indicators produce a distinct exit code (5) so scripts can branch safely — see exit codes.
Detection semantics: DevOpsGen detects in the current working directory, not in --output-dir. Run it from the project you want scanned.