kitfly 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +63 -16
  3. package/VERSION +1 -1
  4. package/dist/_raw/content/deployment/preflight.md +134 -0
  5. package/dist/_raw/content/deployment/recipes/aws-s3.md +128 -0
  6. package/dist/_raw/content/deployment/recipes/cloudflare-pages.md +73 -0
  7. package/dist/_raw/content/deployment/recipes/cloudflare-r2.md +156 -0
  8. package/dist/_raw/content/deployment/recipes/fly-io.md +57 -0
  9. package/dist/_raw/content/deployment/recipes/github-pages.md +112 -0
  10. package/dist/_raw/content/deployment/recipes/netlify.md +99 -0
  11. package/dist/_raw/content/deployment/recipes/vercel.md +88 -0
  12. package/dist/_raw/content/deployment/secrets-and-env-vars.md +75 -0
  13. package/dist/_raw/content/deployment.md +128 -0
  14. package/dist/_raw/content/guide/approaches.md +182 -0
  15. package/dist/_raw/content/guide/features.md +121 -0
  16. package/dist/_raw/content/guide/getting-started.md +112 -0
  17. package/dist/_raw/content/guide/kitfly-overview.md +209 -0
  18. package/dist/_raw/content/reference/configuration.md +259 -0
  19. package/dist/_raw/content/reference/design-catalog.md +167 -0
  20. package/dist/_raw/content/reference/environment-variables.md +66 -0
  21. package/dist/_raw/content/reference/glossary.md +92 -0
  22. package/dist/_raw/content/reference/key-concepts.md +118 -0
  23. package/dist/_raw/content/reference/plugins.md +220 -0
  24. package/dist/_raw/content/reference/structure.md +166 -0
  25. package/dist/_raw/content/reference.md +19 -0
  26. package/dist/_raw/content/templates/crucible.md +192 -0
  27. package/dist/_raw/content/templates/handbook.md +83 -0
  28. package/dist/_raw/content/templates/minimal.md +138 -0
  29. package/dist/_raw/content/templates/overview.md +187 -0
  30. package/dist/_raw/content/templates/pipeline.md +151 -0
  31. package/dist/_raw/content/templates/productbook.md +187 -0
  32. package/dist/_raw/content/templates/runbook.md +193 -0
  33. package/dist/_raw/content/templates/servicebook.md +163 -0
  34. package/dist/_raw/docs/decisions/ADR-0001-minimalist-site-code.md +118 -0
  35. package/dist/_raw/docs/decisions/ADR-0002-ai-accessibility.md +153 -0
  36. package/dist/_raw/docs/decisions/ADR-0003-single-file-bundle.md +93 -0
  37. package/dist/_raw/docs/decisions/ADR-0004-bun-runtime.md +98 -0
  38. package/dist/_raw/docs/decisions/ADR-0005-plugin-contract-and-distribution.md +110 -0
  39. package/dist/_raw/docs/decisions/DDR-0001-viewport-locked-layout.md +111 -0
  40. package/dist/_raw/docs/decisions/DDR-0002-theme-system.md +131 -0
  41. package/dist/_raw/docs/decisions/DDR-0003-bounded-logo-slot.md +106 -0
  42. package/dist/_raw/docs/decisions/DDR-0004-slides-rendering-model.md +113 -0
  43. package/dist/_raw/docs/decisions/DDR-0005-deterministic-layout-boundary.md +107 -0
  44. package/dist/_raw/docs/userguide/cli/build.md +85 -0
  45. package/dist/_raw/docs/userguide/cli/bundle.md +81 -0
  46. package/dist/_raw/docs/userguide/cli/dev.md +92 -0
  47. package/dist/_raw/docs/userguide/cli/init.md +116 -0
  48. package/dist/_raw/docs/userguide/cli/servers.md +69 -0
  49. package/dist/_raw/docs/userguide/cli/stop.md +76 -0
  50. package/dist/_raw/docs/userguide/cli/update.md +78 -0
  51. package/dist/_raw/docs/userguide/cli/version.md +65 -0
  52. package/dist/_raw/docs/userguide/cli.md +34 -0
  53. package/dist/_raw/docs/userguide/sharing.md +94 -0
  54. package/dist/_raw/schemas/plugin-schemas-notes.md +71 -0
  55. package/dist/_raw/schemas.md +42 -0
  56. package/dist/assets/brand/kitfly-favicon-32.png +0 -0
  57. package/dist/assets/brand/kitfly-icon-64.png +0 -0
  58. package/dist/assets/brand/kitfly-logo-128.png +0 -0
  59. package/dist/assets/brand/kitfly-logo-512.png +0 -0
  60. package/dist/assets/brand/kitfly-logo.svg +12132 -0
  61. package/dist/assets/brand/kitfly-neon-128.png +0 -0
  62. package/dist/assets/brand/kitfly-neon-192.png +0 -0
  63. package/dist/assets/brand/kitfly-neon-256.png +0 -0
  64. package/dist/assets/brand/kitfly-neon.png +0 -0
  65. package/dist/assets/brand/palette.md +75 -0
  66. package/dist/content/deployment/index.html +11 -0
  67. package/dist/content/deployment/preflight.html +418 -0
  68. package/dist/content/deployment/recipes/aws-s3.html +421 -0
  69. package/dist/content/deployment/recipes/cloudflare-pages.html +372 -0
  70. package/dist/content/deployment/recipes/cloudflare-r2.html +443 -0
  71. package/dist/content/deployment/recipes/fly-io.html +356 -0
  72. package/dist/content/deployment/recipes/github-pages.html +414 -0
  73. package/dist/content/deployment/recipes/index.html +11 -0
  74. package/dist/content/deployment/recipes/netlify.html +394 -0
  75. package/dist/content/deployment/recipes/vercel.html +382 -0
  76. package/dist/content/deployment/secrets-and-env-vars.html +380 -0
  77. package/dist/content/deployment.html +426 -0
  78. package/dist/content/guide/approaches.html +501 -0
  79. package/dist/content/guide/features.html +436 -0
  80. package/dist/content/guide/getting-started.html +403 -0
  81. package/dist/content/guide/index.html +11 -0
  82. package/dist/content/guide/kitfly-overview.html +544 -0
  83. package/dist/content/index.html +11 -0
  84. package/dist/content/reference/configuration.html +580 -0
  85. package/dist/content/reference/design-catalog.html +449 -0
  86. package/dist/content/reference/environment-variables.html +367 -0
  87. package/dist/content/reference/glossary.html +368 -0
  88. package/dist/content/reference/index.html +11 -0
  89. package/dist/content/reference/key-concepts.html +399 -0
  90. package/dist/content/reference/plugins.html +491 -0
  91. package/dist/content/reference/structure.html +463 -0
  92. package/dist/content/reference.html +334 -0
  93. package/dist/content/templates/crucible.html +546 -0
  94. package/dist/content/templates/handbook.html +405 -0
  95. package/dist/content/templates/index.html +11 -0
  96. package/dist/content/templates/minimal.html +447 -0
  97. package/dist/content/templates/overview.html +558 -0
  98. package/dist/content/templates/pipeline.html +494 -0
  99. package/dist/content/templates/productbook.html +540 -0
  100. package/dist/content/templates/runbook.html +543 -0
  101. package/dist/content/templates/servicebook.html +523 -0
  102. package/dist/content-index.json +540 -0
  103. package/dist/docs/decisions/ADR-0001-minimalist-site-code.html +491 -0
  104. package/dist/docs/decisions/ADR-0002-ai-accessibility.html +434 -0
  105. package/dist/docs/decisions/ADR-0003-single-file-bundle.html +412 -0
  106. package/dist/docs/decisions/ADR-0004-bun-runtime.html +409 -0
  107. package/dist/docs/decisions/ADR-0005-plugin-contract-and-distribution.html +402 -0
  108. package/dist/docs/decisions/DDR-0001-viewport-locked-layout.html +459 -0
  109. package/dist/docs/decisions/DDR-0002-theme-system.html +452 -0
  110. package/dist/docs/decisions/DDR-0003-bounded-logo-slot.html +423 -0
  111. package/dist/docs/decisions/DDR-0004-slides-rendering-model.html +399 -0
  112. package/dist/docs/decisions/DDR-0005-deterministic-layout-boundary.html +422 -0
  113. package/dist/docs/decisions/index.html +11 -0
  114. package/dist/docs/userguide/cli/build.html +408 -0
  115. package/dist/docs/userguide/cli/bundle.html +419 -0
  116. package/dist/docs/userguide/cli/dev.html +428 -0
  117. package/dist/docs/userguide/cli/index.html +11 -0
  118. package/dist/docs/userguide/cli/init.html +436 -0
  119. package/dist/docs/userguide/cli/servers.html +393 -0
  120. package/dist/docs/userguide/cli/stop.html +408 -0
  121. package/dist/docs/userguide/cli/update.html +406 -0
  122. package/dist/docs/userguide/cli/version.html +406 -0
  123. package/dist/docs/userguide/cli.html +386 -0
  124. package/dist/docs/userguide/index.html +11 -0
  125. package/dist/docs/userguide/sharing.html +465 -0
  126. package/dist/index.html +387 -0
  127. package/dist/llms.txt +18 -0
  128. package/dist/provenance.json +7 -0
  129. package/dist/schemas/index.html +11 -0
  130. package/dist/schemas/plugin-registry.schema.html +327 -0
  131. package/dist/schemas/plugin-schemas-notes.html +364 -0
  132. package/dist/schemas/plugin.schema.html +327 -0
  133. package/dist/schemas/plugins.schema.html +327 -0
  134. package/dist/schemas/v0/common.schema.html +386 -0
  135. package/dist/schemas/v0/index.html +11 -0
  136. package/dist/schemas/v0/plugin-registry.schema.html +547 -0
  137. package/dist/schemas/v0/plugin.schema.html +497 -0
  138. package/dist/schemas/v0/plugins.schema.html +406 -0
  139. package/dist/schemas/v0/site.schema.html +541 -0
  140. package/dist/schemas/v0/theme.schema.html +615 -0
  141. package/dist/schemas.html +351 -0
  142. package/dist/styles.css +1262 -0
  143. package/package.json +4 -2
  144. package/plugins-dist/callouts.css +32 -0
  145. package/plugins-dist/callouts.js +46 -0
  146. package/plugins-dist/slides-visuals.css +224 -0
  147. package/plugins-dist/slides-visuals.js +598 -0
  148. package/registry/plugins.yaml +35 -0
  149. package/schemas/README.md +10 -0
  150. package/schemas/plugin-registry.schema.json +5 -0
  151. package/schemas/plugin-schemas-notes.md +71 -0
  152. package/schemas/plugin.schema.json +5 -0
  153. package/schemas/plugins.schema.json +5 -0
  154. package/schemas/v0/common.schema.json +64 -0
  155. package/schemas/v0/plugin-registry.schema.json +225 -0
  156. package/schemas/v0/plugin.schema.json +175 -0
  157. package/schemas/v0/plugins.schema.json +84 -0
  158. package/schemas/v0/site.schema.json +56 -9
  159. package/schemas/v0/theme.schema.json +105 -22
  160. package/scripts/build.ts +155 -3
  161. package/scripts/bundle.ts +258 -95
  162. package/scripts/dev.ts +203 -1
  163. package/src/__tests__/build.test.ts +158 -1
  164. package/src/__tests__/bundle.test.ts +31 -0
  165. package/src/__tests__/cli.test.ts +14 -3
  166. package/src/__tests__/fixtures/fences/slides-visuals/invalid/bad-list-indent.md +5 -0
  167. package/src/__tests__/fixtures/fences/slides-visuals/invalid/blank-line.md +5 -0
  168. package/src/__tests__/fixtures/fences/slides-visuals/invalid/compare-object-items.md +9 -0
  169. package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
  170. package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
  171. package/src/__tests__/fixtures/fences/slides-visuals/invalid/unknown-type.md +3 -0
  172. package/src/__tests__/fixtures/fences/slides-visuals/valid/compare.md +10 -0
  173. package/src/__tests__/fixtures/fences/slides-visuals/valid/comparison-table.md +14 -0
  174. package/src/__tests__/fixtures/fences/slides-visuals/valid/funnel.md +7 -0
  175. package/src/__tests__/fixtures/fences/slides-visuals/valid/kpi.md +5 -0
  176. package/src/__tests__/fixtures/fences/slides-visuals/valid/layer-cake.md +6 -0
  177. package/src/__tests__/fixtures/fences/slides-visuals/valid/pyramid.md +6 -0
  178. package/src/__tests__/fixtures/fences/slides-visuals/valid/quadrant-grid.md +8 -0
  179. package/src/__tests__/fixtures/fences/slides-visuals/valid/scorecard.md +13 -0
  180. package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
  181. package/src/__tests__/init.test.ts +35 -0
  182. package/src/__tests__/plugin-loader.test.ts +221 -0
  183. package/src/__tests__/shared.test.ts +428 -0
  184. package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
  185. package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +114 -0
  186. package/src/__tests__/styles.test.ts +35 -0
  187. package/src/cli.ts +9 -4
  188. package/src/plugin-loader.ts +245 -0
  189. package/src/shared.ts +614 -7
  190. package/src/site/styles.css +331 -0
  191. package/src/site/template.html +66 -5
  192. package/src/templates/deck.ts +186 -0
  193. package/src/templates/driver.ts +11 -1
  194. package/src/templates/minimal.ts +1 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,40 @@
2
2
 
3
3
  All notable changes to Kitfly are documented here.
4
4
 
5
+ ## [0.2.0] - 2026-02-14
6
+
7
+ ### Added
8
+
9
+ - Slides mode: `mode: slides` for fixed-aspect, hash-routed decks (`#slide-n`) with keyboard navigation
10
+ - Slide authoring models: one-file-per-slide and intra-file `--- slide ---` segmentation
11
+ - `kitfly init --template deck` for a ready-to-edit slides starter
12
+ - Plugin system: `kitfly.plugins.yaml`, registry-backed asset injection, mode allowlists, and integrity checks (sha256 + SRI where applicable)
13
+ - `slides-visuals` plugin (widgets + deterministic figures) with strict `:::` fence validation and actionable errors
14
+ - `callouts` plugin: styled NOTE/TIP/WARNING/INFO/DANGER blockquotes via `kitfly.plugins.yaml`
15
+ - Design primitives in core styles for deterministic visuals (block flow/grid + shape modifiers)
16
+ - Server management commands: `kitfly servers`, `kitfly stop <port|all>`, `kitfly logs <port>`
17
+ - Site version resolution: `site.yaml version: auto` (read `VERSION` file) and `version: file:<path>`
18
+ - Brand logo fallback initials when logo asset is missing/unreadable
19
+
20
+ ### Changed
21
+
22
+ - Bundle output to `bundles/` (separate from `dist/`) so static-deploy and single-file outputs don't interfere
23
+
24
+ ### Fixed
25
+
26
+ - Plugin registry hardening and checksum enforcement (fail fast on mismatches)
27
+ - Dev server behavior when iterating on plugin assets (cache invalidation and parity fixes)
28
+ - Multiple `slides-visuals` parsing/rendering edge cases (list merging, list-style blocks, comparison-table layout)
29
+
30
+ ### Docs
31
+
32
+ - New Deployment section with beginner-friendly guardrails and provider recipes
33
+ - Expanded Reference docs (plugins contract, environment variables, key concepts, glossary, design catalog)
34
+
35
+ ### Deferred
36
+
37
+ - Additional live-slides plugins (`slides-charts-lite`, `slides-refresh`, `slides-embed`) planned for v0.2.1
38
+
5
39
  ## [0.1.2] - 2026-02-10
6
40
 
7
41
  ### Added
package/README.md CHANGED
@@ -12,13 +12,38 @@
12
12
 
13
13
  ---
14
14
 
15
+ ## Install
16
+
17
+ Kitfly requires [Bun](https://bun.sh) as its runtime.
18
+
19
+ ```bash
20
+ # Install Bun (if you don't have it)
21
+ curl -fsSL https://bun.sh/install | bash
22
+
23
+ # Install Kitfly globally (from npm)
24
+ bun add -g kitfly
25
+
26
+ # Verify
27
+ kitfly --version
28
+ ```
29
+
30
+ Alternative: `npm install -g kitfly` (still requires Bun, because the CLI runs with Bun).
31
+
32
+ No global install: `bunx kitfly --version`
33
+
34
+ Note: `bun`/`npm` installs the latest published release. If you’re reading `main` before a release is cut, clone this repo for the newest features.
35
+
36
+ For contributor/development setup, see [docs/development.md](docs/development.md).
37
+
38
+ ---
39
+
15
40
  ## Three Ways to Use Kitfly
16
41
 
17
- | Approach | Best For | What You Get |
18
- |----------|----------|--------------|
19
- | **`kitfly init`** | New projects | Standalone site with your own copy of the code |
20
- | **`kitfly dev ./folder`** | Existing docs | Quick preview without changing anything |
21
- | **Clone this repo** | Contributors | The kitfly engine itself |
42
+ | Approach | Best For | What You Get |
43
+ | ------------------------- | ------------- | ---------------------------------------------- |
44
+ | **`kitfly init`** | New projects | Standalone site with your own copy of the code |
45
+ | **`kitfly dev ./folder`** | Existing docs | Quick preview without changing anything |
46
+ | **Clone this repo** | Contributors | The kitfly engine itself |
22
47
 
23
48
  ### Create a Standalone Site (Recommended)
24
49
 
@@ -29,6 +54,15 @@ bun install
29
54
  bun run dev
30
55
  ```
31
56
 
57
+ Or start a slide deck:
58
+
59
+ ```bash
60
+ kitfly init my-deck --template deck
61
+ cd my-deck
62
+ bun install
63
+ bun run dev
64
+ ```
65
+
32
66
  You get a complete, self-contained site: rendering code, template, styles, config. It's yours — modify it, version it, own it. No kitfly CLI required after setup.
33
67
 
34
68
  ### Preview Existing Docs
@@ -52,7 +86,7 @@ bun run dev
52
86
 
53
87
  The `content/` folder is the actual kitfly documentation. What you see is what you get.
54
88
 
55
- See [Kitfly Overview](content/guide/kitfly-overview.md) for the full picture.
89
+ For full contributor setup (toolchain, bootstrap, local CLI), see [docs/development.md](docs/development.md). For the product overview, see [Kitfly Overview](content/guide/kitfly-overview.md).
56
90
 
57
91
  ---
58
92
 
@@ -66,15 +100,17 @@ See [Kitfly Overview](content/guide/kitfly-overview.md) for the full picture.
66
100
 
67
101
  ## What You Get
68
102
 
69
- | Feature | How |
70
- |---------|-----|
71
- | Hot reload | Edit markdown, see changes instantly |
72
- | Navigation | Auto-generated from folder structure |
73
- | Table of contents | Extracted from headings |
74
- | Dark mode | System preference + toggle |
75
- | Diagrams | Mermaid via CDN |
76
- | Syntax highlighting | Prism.js via CDN |
77
- | Offline-ready | Static HTML, no server required |
103
+ | Feature | How |
104
+ | ------------------- | ----------------------------------------------------------------------- |
105
+ | Hot reload | Edit markdown, see changes instantly |
106
+ | Navigation | Auto-generated from folder structure |
107
+ | Table of contents | Extracted from headings |
108
+ | Dark mode | System preference + toggle |
109
+ | Slides mode | `mode: slides` for fixed-aspect decks (v0.2.0+) |
110
+ | Plugins | Optional add-ons via `kitfly.plugins.yaml` (pinned + integrity-checked) |
111
+ | Diagrams | Mermaid via CDN |
112
+ | Syntax highlighting | Prism.js via CDN |
113
+ | Offline-ready | Static HTML, no server required |
78
114
 
79
115
  ## What You Don't Get
80
116
 
@@ -96,6 +132,7 @@ Create `site.yaml` (optional):
96
132
  docroot: "content"
97
133
  title: "My Documentation"
98
134
  home: "index.md"
135
+ mode: "docs" # or "slides" (v0.2.0+)
99
136
 
100
137
  brand:
101
138
  name: "My Project"
@@ -110,6 +147,16 @@ sections:
110
147
 
111
148
  Or just drop markdown files in `content/` — sections auto-discover.
112
149
 
150
+ ## Plugins
151
+
152
+ Plugins are optional CSS/JS add-ons (kept out of core) that you enable per-site.
153
+
154
+ - Config: `kitfly.plugins.yaml`
155
+ - Versions are pinned (`name@x.y.z`)
156
+ - Assets are integrity-checked (sha256)
157
+
158
+ See `content/reference/plugins.md` for the contract and examples.
159
+
113
160
  ---
114
161
 
115
162
  ## Philosophy
@@ -127,7 +174,7 @@ Kitfly is intentionally limited. The goal is a doc site that stays simple and ma
127
174
  - **Kit**: Your handbook, runbook, notebook — a collection of docs
128
175
  - **Fly**: Fast, instant, launching to the web
129
176
 
130
- *Pack your docs. Watch them fly.*
177
+ _Pack your docs. Watch them fly._
131
178
 
132
179
  ---
133
180
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -0,0 +1,134 @@
1
+ ---
2
+ title: "Preflight and Rollback"
3
+ description: "A beginner-safe checklist before you publish"
4
+ last_updated: "2026-02-12"
5
+ ---
6
+
7
+ # Preflight and Rollback
8
+
9
+ This page is intentionally simple. The goal is: publish safely, and be able to undo a bad deploy fast.
10
+
11
+ ## Preflight checklist
12
+
13
+ ### 1) Confirm what you're deploying
14
+
15
+ - You have a single folder you will deploy: `dist/`
16
+ - You know which source folder produced it (your docroot)
17
+
18
+ ### 2) Build clean
19
+
20
+ From your site root:
21
+
22
+ ```bash
23
+ make build
24
+ ```
25
+
26
+ Or:
27
+
28
+ ```bash
29
+ bun run build
30
+ ```
31
+
32
+ Expected: `dist/` exists and contains `index.html` plus assets.
33
+
34
+ ### 3) Sanity check the output
35
+
36
+ - Open the built site and click 3–5 pages
37
+ - Check images load
38
+ - Check code blocks render
39
+ - Toggle dark mode (if your theme supports it)
40
+
41
+ ### 4) Decide your URL and DNS shape
42
+
43
+ - If you can, start with a **subdomain** like `docs.example.com` (simpler DNS + easier to move later).
44
+ - Keep "apex/root" (`example.com`) for your main marketing site unless you have a reason.
45
+ - Avoid subdirectory paths (`example.com/docs/`) — Kitfly currently assumes root-level hosting.
46
+
47
+ ### 5) Verify HTTPS
48
+
49
+ After your first deploy, confirm:
50
+
51
+ - The site loads over `https://` (not just `http://`)
52
+ - The browser shows a lock icon (valid certificate)
53
+ - If your host offers "force HTTPS" or "redirect HTTP → HTTPS", enable it
54
+
55
+ All hosts in the [deployment recipes](.) provision HTTPS automatically (usually via Let's Encrypt). You just need to verify it's working.
56
+
57
+ ### 6) Confirm secrets handling (if any)
58
+
59
+ Kitfly build output is static. Most deployments need **no secrets**.
60
+
61
+ If your deployment uses credentials (AWS keys, Netlify token, etc.):
62
+
63
+ - store them in environment variables or your host's secret store
64
+ - keep them out of git
65
+
66
+ See: [Secrets and Environment Variables](secrets-and-env-vars.html)
67
+
68
+ ---
69
+
70
+ ## Rollback plan (simple and reliable)
71
+
72
+ Pick one of these before you deploy:
73
+
74
+ ### Option A: Keep the previous `dist/` folder
75
+
76
+ - Copy `dist/` to a dated folder before deploying:
77
+ - `dist-backup-YYYY-MM-DD/`
78
+ - If something breaks, deploy the backup folder again.
79
+
80
+ ### Option B: Use a "previous" deployment on your host
81
+
82
+ Many hosts keep deploy history. If they do:
83
+
84
+ - confirm you can re-promote a prior deploy
85
+ - confirm how long deploy history is retained
86
+
87
+ ---
88
+
89
+ ## Common failure modes
90
+
91
+ - **Wrong folder uploaded** (not `dist/`)
92
+ - **Old build** (you forgot to rebuild after edits)
93
+ - **DNS not updated** (domain points somewhere else)
94
+ - **Aggressive caching** (you deployed, but the browser/CDN serves old content)
95
+ - **HTTPS not provisioned yet** (some hosts take a few minutes to issue the cert)
96
+
97
+ If you suspect caching:
98
+
99
+ - hard refresh (Shift+Reload)
100
+ - try a private/incognito window
101
+ - wait a few minutes (some CDNs take time)
102
+
103
+ ---
104
+
105
+ ## Cache invalidation (for CI/CD pipelines)
106
+
107
+ If you deploy via automation and need to force-clear CDN caches, here are the common commands:
108
+
109
+ ### AWS CloudFront
110
+
111
+ ```bash
112
+ aws cloudfront create-invalidation \
113
+ --distribution-id "$KITFLY_AWS_CLOUDFRONT_DISTRIBUTION_ID" \
114
+ --paths "/*"
115
+ ```
116
+
117
+ ### Cloudflare (Pages or R2 behind Workers)
118
+
119
+ Cloudflare Pages automatically invalidates on deploy. If you use R2 with a custom Worker and need to purge:
120
+
121
+ ```bash
122
+ curl -X POST "https://api.cloudflare.com/client/v4/zones/$KITFLY_CF_ZONE_ID/purge_cache" \
123
+ -H "Authorization: Bearer $KITFLY_CF_API_TOKEN" \
124
+ -H "Content-Type: application/json" \
125
+ --data '{"purge_everything":true}'
126
+ ```
127
+
128
+ ### Netlify
129
+
130
+ Netlify invalidates automatically on every deploy. No manual purge needed.
131
+
132
+ ### Vercel
133
+
134
+ Vercel invalidates CDN cache on deploy. No manual purge needed.
@@ -0,0 +1,128 @@
1
+ ---
2
+ title: "Recipe: AWS S3"
3
+ description: "Static hosting on S3 (sync `dist/`)"
4
+ last_updated: "2026-02-12"
5
+ ---
6
+
7
+ # Recipe: AWS S3
8
+
9
+ S3 is a solid choice when you're already in AWS.
10
+
11
+ If you're not already on AWS, Netlify or GitHub Pages is usually faster to get right.
12
+
13
+ ## Prerequisites
14
+
15
+ - An AWS account
16
+ - AWS CLI installed (`aws`)
17
+ - A bucket to host your site
18
+
19
+ ## Secrets (important)
20
+
21
+ If you use access keys locally, keep them out of git and prefer least-privilege IAM.
22
+
23
+ Minimal IAM policy for deployment (scope to your bucket):
24
+
25
+ ```json
26
+ {
27
+ "Version": "2012-10-17",
28
+ "Statement": [
29
+ {
30
+ "Effect": "Allow",
31
+ "Action": ["s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
32
+ "Resource": [
33
+ "arn:aws:s3:::YOUR_BUCKET_NAME",
34
+ "arn:aws:s3:::YOUR_BUCKET_NAME/*"
35
+ ]
36
+ }
37
+ ]
38
+ }
39
+ ```
40
+
41
+ If you use CloudFront (see below), add:
42
+
43
+ ```json
44
+ {
45
+ "Effect": "Allow",
46
+ "Action": "cloudfront:CreateInvalidation",
47
+ "Resource": "arn:aws:cloudfront::ACCOUNT_ID:distribution/DISTRIBUTION_ID"
48
+ }
49
+ ```
50
+
51
+ See: [Secrets and Environment Variables](../secrets-and-env-vars.html)
52
+
53
+ ## Build
54
+
55
+ ```bash
56
+ make build
57
+ ```
58
+
59
+ ## Deploy (sync `dist/`)
60
+
61
+ ```bash
62
+ aws s3 sync dist/ "s3://$KITFLY_AWS_S3_BUCKET/" --delete
63
+ ```
64
+
65
+ Tip: `--delete` keeps the bucket from accumulating old files when pages change names.
66
+
67
+ ## CloudFront (recommended for production)
68
+
69
+ S3 alone can serve a website, but CloudFront gives you:
70
+
71
+ - HTTPS with a custom domain (via ACM certificate)
72
+ - Global CDN caching
73
+ - Better control over headers and redirects
74
+
75
+ ### Basic CloudFront setup shape
76
+
77
+ 1. **Create an ACM certificate** for your domain (must be in `us-east-1` for CloudFront):
78
+
79
+ ```bash
80
+ aws acm request-certificate \
81
+ --domain-name docs.example.com \
82
+ --validation-method DNS \
83
+ --region us-east-1
84
+ ```
85
+
86
+ 2. **Create a CloudFront distribution** with S3 as origin:
87
+ - Origin: your S3 bucket (use the S3 REST endpoint, not the website endpoint)
88
+ - Use Origin Access Control (OAC) so the bucket doesn't need to be public
89
+ - Set default root object: `index.html`
90
+ - Attach your ACM certificate
91
+ - Set alternate domain name: `docs.example.com`
92
+
93
+ 3. **Point DNS** at CloudFront:
94
+ - `docs.example.com` → **CNAME** to your CloudFront distribution domain (`d1234.cloudfront.net`)
95
+
96
+ 4. **Invalidate cache after deploy:**
97
+ ```bash
98
+ aws cloudfront create-invalidation \
99
+ --distribution-id "$KITFLY_AWS_CLOUDFRONT_DISTRIBUTION_ID" \
100
+ --paths "/*"
101
+ ```
102
+
103
+ The CloudFront console and `aws cloudfront create-distribution` CLI have many options. Start simple and add complexity as needed.
104
+
105
+ ## DNS basics (without CloudFront)
106
+
107
+ If you use S3 website hosting directly (no CloudFront):
108
+
109
+ - `docs.example.com` → **CNAME** to `YOUR_BUCKET_NAME.s3-website-REGION.amazonaws.com`
110
+
111
+ Note: S3 website hosting does not support HTTPS on custom domains. For HTTPS, put CloudFront in front.
112
+
113
+ ## About "S3 static website hosting"
114
+
115
+ AWS has an S3 "website hosting" mode. It works for simple cases, but most teams prefer putting S3 behind CloudFront:
116
+
117
+ - HTTPS on custom domains
118
+ - Global edge caching
119
+ - Better security (bucket stays private via OAC)
120
+
121
+ If you're not sure: start with the simplest approach your org already uses.
122
+
123
+ ## Verify + Rollback
124
+
125
+ - Verify: load the site, click a few pages, hard refresh, confirm HTTPS lock icon
126
+ - Rollback: re-sync the previous build output (or use S3 versioning if you enabled it)
127
+
128
+ See: [Preflight and Rollback](../preflight.html)
@@ -0,0 +1,73 @@
1
+ ---
2
+ title: "Recipe: Cloudflare Pages"
3
+ description: "Beginner-friendly Cloudflare hosting for static `dist/` output"
4
+ last_updated: "2026-02-12"
5
+ ---
6
+
7
+ # Recipe: Cloudflare Pages
8
+
9
+ Cloudflare Pages is a strong default if you want Cloudflare to "just host the static site" with CDN performance and a simple custom domain story.
10
+
11
+ If you were looking at Cloudflare R2: Pages is usually easier. R2 is object storage and is best treated as an advanced building block.
12
+
13
+ See also:
14
+
15
+ - [Recipe: Cloudflare R2](cloudflare-r2.html)
16
+
17
+ ## Prerequisites
18
+
19
+ - A Cloudflare account
20
+ - (Recommended) Your domain on Cloudflare DNS
21
+ - (For CLI deploys) `wrangler` installed: `npm i -g wrangler`
22
+
23
+ ## Build
24
+
25
+ ```bash
26
+ make build
27
+ ```
28
+
29
+ Your deployable output is the `dist/` folder.
30
+
31
+ ## Deploy (three common workflows)
32
+
33
+ ### Option A: Connect a Git repo (repeatable)
34
+
35
+ 1. Create a new Pages project in Cloudflare
36
+ 2. Connect your repo
37
+ 3. Set build command: `make build`
38
+ 4. Set output/publish directory: `dist`
39
+
40
+ Now "push to main" becomes "deploy the site".
41
+
42
+ Note: Cloudflare's build environment may not have Bun pre-installed. If the build fails, set the environment variable `BUN_VERSION=1` in the Pages project settings, or use Option B/C instead.
43
+
44
+ ### Option B: Upload static output (quick, via dashboard)
45
+
46
+ If you just want a link quickly:
47
+
48
+ 1. Build locally (`make build`)
49
+ 2. Upload the `dist/` output in the Pages UI
50
+
51
+ ### Option C: Deploy via CLI (repeatable, no git integration)
52
+
53
+ ```bash
54
+ make build
55
+ npx wrangler pages deploy dist/ --project-name=your-project-name
56
+ ```
57
+
58
+ This is useful for CI/CD pipelines or when you don't want to connect a git repo.
59
+
60
+ ## Custom domain (DNS basics)
61
+
62
+ Typical pattern:
63
+
64
+ - `docs.example.com` → **CNAME** to the Pages target Cloudflare provides
65
+
66
+ If you use Cloudflare DNS, Pages will usually guide you through the exact record to create. HTTPS is provisioned automatically.
67
+
68
+ ## Verify + Rollback
69
+
70
+ - Verify: load the site, click a few pages, hard refresh, confirm HTTPS lock icon
71
+ - Rollback: redeploy the previous build from Pages dashboard (or revert the commit if you deploy from git)
72
+
73
+ See: [Preflight and Rollback](../preflight.html)
@@ -0,0 +1,156 @@
1
+ ---
2
+ title: "Recipe: Cloudflare R2"
3
+ description: "Advanced: publish `dist/` using Cloudflare storage and edge routing"
4
+ last_updated: "2026-02-12"
5
+ ---
6
+
7
+ # Recipe: Cloudflare R2
8
+
9
+ This recipe is intentionally labeled **advanced**.
10
+
11
+ If you want the simplest Cloudflare experience for a static site, Cloudflare Pages is usually the easiest path:
12
+
13
+ - [Recipe: Cloudflare Pages](cloudflare-pages.html)
14
+
15
+ R2 is great when you want object storage as your origin and you're comfortable wiring edge routing/caching.
16
+
17
+ ## When to use this
18
+
19
+ - You're already using Cloudflare (DNS, Workers, caching)
20
+ - You want `dist/` stored as objects and served at the edge
21
+
22
+ ## Pages vs R2 (which should I choose?)
23
+
24
+ ### Choose Cloudflare Pages when…
25
+
26
+ - You want a "deploy and host" product for static sites
27
+ - You're fine with "connect a repo and publish `dist/`" as your workflow
28
+ - You want custom domains + HTTPS without a lot of plumbing
29
+
30
+ ### Choose Cloudflare R2 when…
31
+
32
+ - You specifically want object storage as the source of truth for site files
33
+ - You already have (or want) a Worker/edge layer in front
34
+ - You care about storing and serving lots of assets and want S3-like primitives
35
+
36
+ ## High-level shape
37
+
38
+ 1. Build your site to `dist/`
39
+ 2. Upload `dist/` to an R2 bucket
40
+ 3. Serve it via an edge layer (typically a Worker) and attach your domain
41
+
42
+ Important: R2 is object storage, not "a website host" by itself. You usually need something in front of it to handle requests and return the right file for a path.
43
+
44
+ ## Prerequisites
45
+
46
+ - A Cloudflare account
47
+ - A domain on Cloudflare DNS (recommended)
48
+ - `wrangler` CLI installed: `npm i -g wrangler`
49
+ - An R2 bucket created (via dashboard or `wrangler r2 bucket create <name>`)
50
+
51
+ ## Build
52
+
53
+ ```bash
54
+ make build
55
+ ```
56
+
57
+ ## Upload `dist/` to R2
58
+
59
+ ### Using wrangler (recommended for CI/CD)
60
+
61
+ Upload individual files:
62
+
63
+ ```bash
64
+ # Upload all files from dist/ to the bucket
65
+ for file in $(find dist -type f); do
66
+ key="${file#dist/}"
67
+ wrangler r2 object put "$KITFLY_CF_R2_BUCKET/$key" --file="$file"
68
+ done
69
+ ```
70
+
71
+ Or if you prefer a sync-like approach, use the rclone tool with R2's S3-compatible endpoint:
72
+
73
+ ```bash
74
+ rclone sync dist/ "r2:$KITFLY_CF_R2_BUCKET/" \
75
+ --s3-provider=Cloudflare \
76
+ --s3-access-key-id="$KITFLY_CF_R2_ACCESS_KEY_ID" \
77
+ --s3-secret-access-key="$KITFLY_CF_R2_SECRET_ACCESS_KEY" \
78
+ --s3-endpoint="https://$KITFLY_CF_R2_ACCOUNT_ID.r2.cloudflarestorage.com"
79
+ ```
80
+
81
+ ### Using the dashboard
82
+
83
+ Fine for small sites, but manual. Upload files in the R2 bucket view.
84
+
85
+ ## Serving: Worker in front of R2
86
+
87
+ A minimal Worker to serve files from R2:
88
+
89
+ ```javascript
90
+ // wrangler.toml:
91
+ // [[r2_buckets]]
92
+ // binding = "BUCKET"
93
+ // bucket_name = "your-bucket-name"
94
+
95
+ export default {
96
+ async fetch(request, env) {
97
+ const url = new URL(request.url);
98
+ let key = url.pathname.slice(1) || "index.html";
99
+ if (key.endsWith("/")) key += "index.html";
100
+
101
+ const object = await env.BUCKET.get(key);
102
+ if (!object) return new Response("Not found", { status: 404 });
103
+
104
+ const headers = new Headers();
105
+ headers.set(
106
+ "Content-Type",
107
+ object.httpMetadata?.contentType || "text/html",
108
+ );
109
+ return new Response(object.body, { headers });
110
+ },
111
+ };
112
+ ```
113
+
114
+ Deploy the Worker with `wrangler deploy` and attach your custom domain via the Cloudflare dashboard.
115
+
116
+ ## Secrets
117
+
118
+ Keep R2 credentials in environment variables and **don't** commit them. See:
119
+
120
+ - [Secrets and Environment Variables](../secrets-and-env-vars.html)
121
+
122
+ ## Caching (don't fight it)
123
+
124
+ Cloudflare will cache aggressively if you ask it to. That's great for docs sites, but it can confuse first-time deploys.
125
+
126
+ If you deploy and still see old content:
127
+
128
+ - hard refresh (Shift+Reload)
129
+ - try an incognito window
130
+ - wait a minute
131
+ - or purge cache via the Cloudflare dashboard / API (see [Preflight: Cache Invalidation](../preflight.html))
132
+
133
+ ## DNS basics
134
+
135
+ Typical pattern:
136
+
137
+ - Use a **subdomain** like `docs.example.com`
138
+ - Point it at your Worker using Cloudflare's "Custom Domains for Workers" feature
139
+
140
+ HTTPS is handled automatically when using Cloudflare DNS.
141
+
142
+ ## Verify
143
+
144
+ - Load the site from your custom domain
145
+ - Hard refresh once (caching can make you think deploy didn't work)
146
+ - Click 3–5 pages and confirm assets load
147
+ - Confirm the HTTPS lock icon
148
+
149
+ ## Rollback
150
+
151
+ Rollback options:
152
+
153
+ - re-upload the previous `dist/` objects
154
+ - or switch your Worker routing back to a prior bucket/prefix
155
+
156
+ See: [Preflight and Rollback](../preflight.html)