kitfly 0.1.2 → 0.2.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.
Files changed (209) hide show
  1. package/CHANGELOG.md +46 -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/slides-authoring-guidelines.md +129 -0
  25. package/dist/_raw/content/reference/structure.md +166 -0
  26. package/dist/_raw/content/reference.md +20 -0
  27. package/dist/_raw/content/templates/crucible.md +192 -0
  28. package/dist/_raw/content/templates/handbook.md +83 -0
  29. package/dist/_raw/content/templates/minimal.md +138 -0
  30. package/dist/_raw/content/templates/overview.md +187 -0
  31. package/dist/_raw/content/templates/pipeline.md +151 -0
  32. package/dist/_raw/content/templates/productbook.md +187 -0
  33. package/dist/_raw/content/templates/runbook.md +193 -0
  34. package/dist/_raw/content/templates/servicebook.md +163 -0
  35. package/dist/_raw/docs/decisions/ADR-0001-minimalist-site-code.md +118 -0
  36. package/dist/_raw/docs/decisions/ADR-0002-ai-accessibility.md +153 -0
  37. package/dist/_raw/docs/decisions/ADR-0003-single-file-bundle.md +93 -0
  38. package/dist/_raw/docs/decisions/ADR-0004-bun-runtime.md +98 -0
  39. package/dist/_raw/docs/decisions/ADR-0005-plugin-contract-and-distribution.md +110 -0
  40. package/dist/_raw/docs/decisions/DDR-0001-viewport-locked-layout.md +111 -0
  41. package/dist/_raw/docs/decisions/DDR-0002-theme-system.md +131 -0
  42. package/dist/_raw/docs/decisions/DDR-0003-bounded-logo-slot.md +106 -0
  43. package/dist/_raw/docs/decisions/DDR-0004-slides-rendering-model.md +113 -0
  44. package/dist/_raw/docs/decisions/DDR-0005-deterministic-layout-boundary.md +107 -0
  45. package/dist/_raw/docs/userguide/cli/build.md +85 -0
  46. package/dist/_raw/docs/userguide/cli/bundle.md +81 -0
  47. package/dist/_raw/docs/userguide/cli/dev.md +92 -0
  48. package/dist/_raw/docs/userguide/cli/init.md +116 -0
  49. package/dist/_raw/docs/userguide/cli/servers.md +69 -0
  50. package/dist/_raw/docs/userguide/cli/stop.md +76 -0
  51. package/dist/_raw/docs/userguide/cli/update.md +78 -0
  52. package/dist/_raw/docs/userguide/cli/version.md +65 -0
  53. package/dist/_raw/docs/userguide/cli.md +34 -0
  54. package/dist/_raw/docs/userguide/sharing.md +94 -0
  55. package/dist/_raw/schemas/plugin-schemas-notes.md +71 -0
  56. package/dist/_raw/schemas.md +42 -0
  57. package/dist/assets/brand/kitfly-favicon-32.png +0 -0
  58. package/dist/assets/brand/kitfly-icon-64.png +0 -0
  59. package/dist/assets/brand/kitfly-logo-128.png +0 -0
  60. package/dist/assets/brand/kitfly-logo-512.png +0 -0
  61. package/dist/assets/brand/kitfly-logo.svg +12132 -0
  62. package/dist/assets/brand/kitfly-neon-128.png +0 -0
  63. package/dist/assets/brand/kitfly-neon-192.png +0 -0
  64. package/dist/assets/brand/kitfly-neon-256.png +0 -0
  65. package/dist/assets/brand/kitfly-neon.png +0 -0
  66. package/dist/assets/brand/palette.md +75 -0
  67. package/dist/content/deployment/index.html +11 -0
  68. package/dist/content/deployment/preflight.html +418 -0
  69. package/dist/content/deployment/recipes/aws-s3.html +421 -0
  70. package/dist/content/deployment/recipes/cloudflare-pages.html +372 -0
  71. package/dist/content/deployment/recipes/cloudflare-r2.html +443 -0
  72. package/dist/content/deployment/recipes/fly-io.html +356 -0
  73. package/dist/content/deployment/recipes/github-pages.html +414 -0
  74. package/dist/content/deployment/recipes/index.html +11 -0
  75. package/dist/content/deployment/recipes/netlify.html +394 -0
  76. package/dist/content/deployment/recipes/vercel.html +382 -0
  77. package/dist/content/deployment/secrets-and-env-vars.html +380 -0
  78. package/dist/content/deployment.html +426 -0
  79. package/dist/content/guide/approaches.html +501 -0
  80. package/dist/content/guide/features.html +436 -0
  81. package/dist/content/guide/getting-started.html +403 -0
  82. package/dist/content/guide/index.html +11 -0
  83. package/dist/content/guide/kitfly-overview.html +544 -0
  84. package/dist/content/index.html +11 -0
  85. package/dist/content/reference/configuration.html +580 -0
  86. package/dist/content/reference/design-catalog.html +449 -0
  87. package/dist/content/reference/environment-variables.html +367 -0
  88. package/dist/content/reference/glossary.html +368 -0
  89. package/dist/content/reference/index.html +11 -0
  90. package/dist/content/reference/key-concepts.html +399 -0
  91. package/dist/content/reference/plugins.html +491 -0
  92. package/dist/content/reference/slides-authoring-guidelines.html +418 -0
  93. package/dist/content/reference/structure.html +463 -0
  94. package/dist/content/reference.html +335 -0
  95. package/dist/content/templates/crucible.html +546 -0
  96. package/dist/content/templates/handbook.html +405 -0
  97. package/dist/content/templates/index.html +11 -0
  98. package/dist/content/templates/minimal.html +447 -0
  99. package/dist/content/templates/overview.html +558 -0
  100. package/dist/content/templates/pipeline.html +494 -0
  101. package/dist/content/templates/productbook.html +540 -0
  102. package/dist/content/templates/runbook.html +543 -0
  103. package/dist/content/templates/servicebook.html +523 -0
  104. package/dist/content-index.json +549 -0
  105. package/dist/docs/decisions/ADR-0001-minimalist-site-code.html +491 -0
  106. package/dist/docs/decisions/ADR-0002-ai-accessibility.html +434 -0
  107. package/dist/docs/decisions/ADR-0003-single-file-bundle.html +412 -0
  108. package/dist/docs/decisions/ADR-0004-bun-runtime.html +409 -0
  109. package/dist/docs/decisions/ADR-0005-plugin-contract-and-distribution.html +402 -0
  110. package/dist/docs/decisions/DDR-0001-viewport-locked-layout.html +459 -0
  111. package/dist/docs/decisions/DDR-0002-theme-system.html +452 -0
  112. package/dist/docs/decisions/DDR-0003-bounded-logo-slot.html +423 -0
  113. package/dist/docs/decisions/DDR-0004-slides-rendering-model.html +399 -0
  114. package/dist/docs/decisions/DDR-0005-deterministic-layout-boundary.html +422 -0
  115. package/dist/docs/decisions/index.html +11 -0
  116. package/dist/docs/userguide/cli/build.html +408 -0
  117. package/dist/docs/userguide/cli/bundle.html +419 -0
  118. package/dist/docs/userguide/cli/dev.html +428 -0
  119. package/dist/docs/userguide/cli/index.html +11 -0
  120. package/dist/docs/userguide/cli/init.html +436 -0
  121. package/dist/docs/userguide/cli/servers.html +393 -0
  122. package/dist/docs/userguide/cli/stop.html +408 -0
  123. package/dist/docs/userguide/cli/update.html +406 -0
  124. package/dist/docs/userguide/cli/version.html +406 -0
  125. package/dist/docs/userguide/cli.html +386 -0
  126. package/dist/docs/userguide/index.html +11 -0
  127. package/dist/docs/userguide/sharing.html +465 -0
  128. package/dist/index.html +387 -0
  129. package/dist/llms.txt +18 -0
  130. package/dist/provenance.json +7 -0
  131. package/dist/schemas/index.html +11 -0
  132. package/dist/schemas/plugin-registry.schema.html +327 -0
  133. package/dist/schemas/plugin-schemas-notes.html +364 -0
  134. package/dist/schemas/plugin.schema.html +327 -0
  135. package/dist/schemas/plugins.schema.html +327 -0
  136. package/dist/schemas/v0/common.schema.html +386 -0
  137. package/dist/schemas/v0/index.html +11 -0
  138. package/dist/schemas/v0/plugin-registry.schema.html +547 -0
  139. package/dist/schemas/v0/plugin.schema.html +497 -0
  140. package/dist/schemas/v0/plugins.schema.html +406 -0
  141. package/dist/schemas/v0/site.schema.html +541 -0
  142. package/dist/schemas/v0/theme.schema.html +615 -0
  143. package/dist/schemas.html +351 -0
  144. package/dist/styles.css +1262 -0
  145. package/package.json +4 -2
  146. package/plugins-dist/callouts.css +32 -0
  147. package/plugins-dist/callouts.js +46 -0
  148. package/plugins-dist/slides-visuals.css +390 -0
  149. package/plugins-dist/slides-visuals.js +689 -0
  150. package/registry/plugins.yaml +35 -0
  151. package/schemas/README.md +10 -0
  152. package/schemas/plugin-registry.schema.json +5 -0
  153. package/schemas/plugin-schemas-notes.md +71 -0
  154. package/schemas/plugin.schema.json +5 -0
  155. package/schemas/plugins.schema.json +5 -0
  156. package/schemas/v0/common.schema.json +64 -0
  157. package/schemas/v0/plugin-registry.schema.json +225 -0
  158. package/schemas/v0/plugin.schema.json +175 -0
  159. package/schemas/v0/plugins.schema.json +84 -0
  160. package/schemas/v0/site.schema.json +56 -9
  161. package/schemas/v0/theme.schema.json +105 -22
  162. package/scripts/build.ts +158 -3
  163. package/scripts/bundle.ts +261 -95
  164. package/scripts/dev.ts +301 -11
  165. package/src/__tests__/build.test.ts +220 -1
  166. package/src/__tests__/bundle.test.ts +31 -0
  167. package/src/__tests__/cli.test.ts +14 -3
  168. package/src/__tests__/dev-plugin-errors.test.ts +20 -0
  169. package/src/__tests__/fixtures/fences/slides-visuals/invalid/bad-list-indent.md +5 -0
  170. package/src/__tests__/fixtures/fences/slides-visuals/invalid/blank-line.md +5 -0
  171. package/src/__tests__/fixtures/fences/slides-visuals/invalid/compare-object-items.md +9 -0
  172. package/src/__tests__/fixtures/fences/slides-visuals/invalid/flow-branching-no-source.md +5 -0
  173. package/src/__tests__/fixtures/fences/slides-visuals/invalid/flow-converging-no-target.md +6 -0
  174. package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
  175. package/src/__tests__/fixtures/fences/slides-visuals/invalid/staircase-empty-steps.md +3 -0
  176. package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
  177. package/src/__tests__/fixtures/fences/slides-visuals/invalid/timeline-horizontal-no-events.md +2 -0
  178. package/src/__tests__/fixtures/fences/slides-visuals/invalid/unknown-type.md +3 -0
  179. package/src/__tests__/fixtures/fences/slides-visuals/valid/compare.md +10 -0
  180. package/src/__tests__/fixtures/fences/slides-visuals/valid/comparison-table.md +14 -0
  181. package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-branching-no-split.md +7 -0
  182. package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-branching.md +8 -0
  183. package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging-no-merge.md +7 -0
  184. package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging.md +8 -0
  185. package/src/__tests__/fixtures/fences/slides-visuals/valid/funnel.md +7 -0
  186. package/src/__tests__/fixtures/fences/slides-visuals/valid/kpi.md +5 -0
  187. package/src/__tests__/fixtures/fences/slides-visuals/valid/layer-cake.md +6 -0
  188. package/src/__tests__/fixtures/fences/slides-visuals/valid/pyramid.md +6 -0
  189. package/src/__tests__/fixtures/fences/slides-visuals/valid/quadrant-grid.md +8 -0
  190. package/src/__tests__/fixtures/fences/slides-visuals/valid/scorecard.md +13 -0
  191. package/src/__tests__/fixtures/fences/slides-visuals/valid/staircase-down.md +7 -0
  192. package/src/__tests__/fixtures/fences/slides-visuals/valid/staircase.md +8 -0
  193. package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
  194. package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-horizontal.md +9 -0
  195. package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-vertical.md +10 -0
  196. package/src/__tests__/init.test.ts +35 -0
  197. package/src/__tests__/plugin-loader.test.ts +221 -0
  198. package/src/__tests__/shared.test.ts +451 -0
  199. package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
  200. package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +147 -0
  201. package/src/__tests__/styles.test.ts +35 -0
  202. package/src/cli.ts +9 -4
  203. package/src/plugin-loader.ts +245 -0
  204. package/src/shared.ts +650 -7
  205. package/src/site/styles.css +331 -0
  206. package/src/site/template.html +66 -5
  207. package/src/templates/deck.ts +186 -0
  208. package/src/templates/driver.ts +11 -1
  209. package/src/templates/minimal.ts +1 -0
@@ -0,0 +1,75 @@
1
+ # Kitfly Brand Palette
2
+
3
+ ## Primary Colors
4
+
5
+ | Name | Hex | RGB | Usage |
6
+ | --------- | --------- | ----------------- | ------------------------------------- |
7
+ | **Navy** | `#152F46` | rgb(21, 47, 70) | Document shape, headers, primary text |
8
+ | **Teal** | `#007182` | rgb(0, 113, 130) | Feather/wing, links, accents |
9
+ | **Coral** | `#D17059` | rgb(209, 112, 89) | Call-to-action, energy accent |
10
+
11
+ ## Secondary Colors
12
+
13
+ | Name | Hex | RGB | Usage |
14
+ | ------------------- | --------- | ------------------ | -------------------------------------------- |
15
+ | **Dark Background** | `#0D1117` | rgb(13, 17, 23) | Dark mode backgrounds (GitHub-style neutral) |
16
+ | **Teal Mid** | `#0A6172` | rgb(10, 97, 114) | Hover states, secondary accent |
17
+ | **Teal Light** | `#709EA6` | rgb(112, 158, 166) | Disabled states, subtle borders |
18
+
19
+ ## Neutral Colors
20
+
21
+ | Name | Hex | RGB | Usage |
22
+ | -------------- | --------- | ------------------ | ------------------------------- |
23
+ | **White** | `#FFFFFF` | rgb(255, 255, 255) | Backgrounds, text on dark |
24
+ | **Light Gray** | `#F5F7F8` | rgb(245, 247, 248) | Code blocks, subtle backgrounds |
25
+ | **Mid Gray** | `#6B7280` | rgb(107, 114, 128) | Secondary text, borders |
26
+ | **Dark Gray** | `#374151` | rgb(55, 65, 81) | Body text |
27
+
28
+ ## CSS Variables
29
+
30
+ ```css
31
+ :root {
32
+ /* Primary */
33
+ --kitfly-navy: #152f46;
34
+ --kitfly-teal: #007182;
35
+ --kitfly-coral: #d17059;
36
+
37
+ /* Secondary */
38
+ --kitfly-dark-bg: #0d1117;
39
+ --kitfly-teal-mid: #0a6172;
40
+ --kitfly-teal-light: #709ea6;
41
+
42
+ /* Neutral */
43
+ --kitfly-white: #ffffff;
44
+ --kitfly-gray-100: #f5f7f8;
45
+ --kitfly-gray-500: #6b7280;
46
+ --kitfly-gray-700: #374151;
47
+ }
48
+ ```
49
+
50
+ ## Dark Mode
51
+
52
+ | Light Mode | Dark Mode |
53
+ | ---------------------- | ----------------------- |
54
+ | Navy text on white | White text on deep navy |
55
+ | Teal accents | Teal light accents |
56
+ | Light gray backgrounds | Deep navy backgrounds |
57
+
58
+ ## Color Swatches
59
+
60
+ ```
61
+ Navy ████████ #152F46
62
+ Teal ████████ #007182
63
+ Coral ████████ #D17059
64
+ Dark BG ████████ #0D1117
65
+ Teal Mid ████████ #0A6172
66
+ Teal Light ████████ #709EA6
67
+ ```
68
+
69
+ ## Brand Rationale
70
+
71
+ - **Navy**: Professional, trustworthy - represents the "kit" (document/container)
72
+ - **Teal**: Fresh, tech-forward - represents "fly" (motion, speed)
73
+ - **Coral**: Energy, action - draws attention to CTAs without being aggressive
74
+
75
+ The palette avoids pure black for better readability and uses blue-green tones that work well in both light and dark modes.
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta http-equiv="refresh" content="0; url=./secrets-and-env-vars.html">
6
+ <title>Redirecting...</title>
7
+ </head>
8
+ <body>
9
+ <p>Redirecting to <a href="./secrets-and-env-vars.html">secrets-and-env-vars</a>...</p>
10
+ </body>
11
+ </html>
@@ -0,0 +1,418 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Preflight and Rollback - Kitfly Docs</title>
7
+ <link rel="icon" type="image/png" sizes="32x32" href="../../assets/brand/kitfly-favicon-32.png">
8
+ <link rel="icon" type="image/png" sizes="64x64" href="../../assets/brand/kitfly-neon-256.png">
9
+ <link rel="stylesheet" href="../../styles.css">
10
+ <style id="kitfly-theme">
11
+ :root { --color-bg: #ffffff;
12
+ --color-bg-sidebar: #f5f7f8;
13
+ --color-text: #374151;
14
+ --color-text-muted: #6b7280;
15
+ --color-border: #e5e7eb;
16
+ --color-link: #007182;
17
+ --color-link-hover: #0a6172;
18
+ --color-accent: #152F46;
19
+ --color-code-bg: #f5f7f8;
20
+ --color-logo: #152F46;
21
+ --sidebar-width: 280px;
22
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
23
+ --font-headings: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
24
+ --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
25
+ html { font-size: 16px; }
26
+ @media (prefers-color-scheme: dark) {
27
+ :root:not([data-theme="light"]) { --color-bg: #0d1117;
28
+ --color-bg-sidebar: #152F46;
29
+ --color-text: #e5e7eb;
30
+ --color-text-muted: #9ca3af;
31
+ --color-border: #374151;
32
+ --color-link: #709EA6;
33
+ --color-link-hover: #8fb5bc;
34
+ --color-accent: #f9fafb;
35
+ --color-code-bg: #152F46;
36
+ --color-logo: #f9fafb; }
37
+ }
38
+ [data-theme="dark"] { --color-bg: #0d1117;
39
+ --color-bg-sidebar: #152F46;
40
+ --color-text: #e5e7eb;
41
+ --color-text-muted: #9ca3af;
42
+ --color-border: #374151;
43
+ --color-link: #709EA6;
44
+ --color-link-hover: #8fb5bc;
45
+ --color-accent: #f9fafb;
46
+ --color-code-bg: #152F46;
47
+ --color-logo: #f9fafb; }
48
+ [data-theme="light"] { --color-bg: #ffffff;
49
+ --color-bg-sidebar: #f5f7f8;
50
+ --color-text: #374151;
51
+ --color-text-muted: #6b7280;
52
+ --color-border: #e5e7eb;
53
+ --color-link: #007182;
54
+ --color-link-hover: #0a6172;
55
+ --color-accent: #152F46;
56
+ --color-code-bg: #f5f7f8;
57
+ --color-logo: #152F46;
58
+ --sidebar-width: 280px;
59
+ --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
60
+ --font-headings: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
61
+ --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }
62
+ </style>
63
+ <!-- Syntax highlighting - Prism.js -->
64
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism.min.css" id="prism-light">
65
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1/themes/prism-okaidia.min.css" id="prism-dark" disabled>
66
+
67
+ <script>
68
+ // Apply saved theme immediately to prevent flash
69
+ (function() {
70
+ const saved = localStorage.getItem('theme');
71
+ if (saved) {
72
+ document.documentElement.setAttribute('data-theme', saved);
73
+ }
74
+ // Set Prism theme based on saved or system preference
75
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
76
+ const isDark = saved === 'dark' || (!saved && prefersDark);
77
+ if (isDark) {
78
+ document.getElementById('prism-light')?.setAttribute('disabled', '');
79
+ document.getElementById('prism-dark')?.removeAttribute('disabled');
80
+ }
81
+ })();
82
+ </script>
83
+ </head>
84
+ <body class="mode-docs">
85
+ <div class="mobile-header">
86
+ <button class="nav-toggle" onclick="toggleNav()" aria-label="Toggle navigation">
87
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
88
+ <path d="M3 12h18M3 6h18M3 18h18"/>
89
+ </svg>
90
+ </button>
91
+ <a href="../../" class="mobile-logo" title="Home" data-initial="K">
92
+ <img src="../../assets/brand/kitfly-neon-256.png" alt="Kitfly" class="logo-img logo-icon" onerror="this.onerror=null;this.style.display='none';this.parentElement.classList.add('logo-fallback')"/>
93
+ </a>
94
+ <button class="mobile-theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
95
+ <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
96
+ <circle cx="12" cy="12" r="5"/>
97
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
98
+ </svg>
99
+ <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
100
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
101
+ </svg>
102
+ </button>
103
+ </div>
104
+ <div class="layout">
105
+ <nav class="sidebar">
106
+ <div class="sidebar-header">
107
+ <div class="logo logo-icon">
108
+ <a href="/" class="logo-icon" data-initial="K">
109
+ <img src="../../assets/brand/kitfly-neon-256.png" alt="Kitfly" class="logo-img" onerror="this.onerror=null;this.style.display='none';this.parentElement.classList.add('logo-fallback')"/>
110
+ </a>
111
+ <span class="logo-text">
112
+ <a href="/" class="brand">Kitfly</a>
113
+ <a href="../../" class="product">Kitfly Docs</a>
114
+ </span>
115
+ </div>
116
+ <div class="header-tools">
117
+ <button class="theme-toggle" onclick="toggleTheme()" title="Toggle theme" aria-label="Toggle theme">
118
+ <svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
119
+ <circle cx="12" cy="12" r="5"/>
120
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/>
121
+ </svg>
122
+ <svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
123
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
124
+ </svg>
125
+ </button>
126
+ <div class="sidebar-meta">
127
+ <span class="meta-version">v0.2.1</span>
128
+ <span class="meta-branch">HEAD</span>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ <div class="sidebar-nav">
133
+ <ul><li><a href="../../index.html" class="nav-home">Home</a></li><li><span class="nav-section">Guide</span><ul><li><a href="../../content/guide/approaches.html">approaches</a></li><li><a href="../../content/guide/features.html">features</a></li><li><a href="../../content/guide/getting-started.html">getting-started</a></li><li><a href="../../content/guide/kitfly-overview.html">kitfly-overview</a></li></ul></li><li><span class="nav-section">Templates</span><ul><li><a href="../../content/templates/crucible.html">crucible</a></li><li><a href="../../content/templates/handbook.html">handbook</a></li><li><a href="../../content/templates/minimal.html">minimal</a></li><li><a href="../../content/templates/overview.html">overview</a></li><li><a href="../../content/templates/pipeline.html">pipeline</a></li><li><a href="../../content/templates/productbook.html">productbook</a></li><li><a href="../../content/templates/runbook.html">runbook</a></li><li><a href="../../content/templates/servicebook.html">servicebook</a></li></ul></li><li><a href="../../content/reference.html" class="nav-section">Reference</a><ul><li><a href="../../content/reference/configuration.html">configuration</a></li><li><a href="../../content/reference/design-catalog.html">design-catalog</a></li><li><a href="../../content/reference/environment-variables.html">environment-variables</a></li><li><a href="../../content/reference/glossary.html">glossary</a></li><li><a href="../../content/reference/key-concepts.html">key-concepts</a></li><li><a href="../../content/reference/plugins.html">plugins</a></li><li><a href="../../content/reference/slides-authoring-guidelines.html">slides-authoring-guidelines</a></li><li><a href="../../content/reference/structure.html">structure</a></li></ul></li><li><a href="../../content/deployment.html" class="nav-section">Deployment</a><ul><li><a href="../../content/deployment/preflight.html" class="active">preflight</a></li><li><details><summary class="nav-group">recipes</summary><ul><li><a href="../../content/deployment/recipes/aws-s3.html">aws-s3</a></li><li><a href="../../content/deployment/recipes/cloudflare-pages.html">cloudflare-pages</a></li><li><a href="../../content/deployment/recipes/cloudflare-r2.html">cloudflare-r2</a></li><li><a href="../../content/deployment/recipes/fly-io.html">fly-io</a></li><li><a href="../../content/deployment/recipes/github-pages.html">github-pages</a></li><li><a href="../../content/deployment/recipes/netlify.html">netlify</a></li><li><a href="../../content/deployment/recipes/vercel.html">vercel</a></li></ul></details></li><li><a href="../../content/deployment/secrets-and-env-vars.html">secrets-and-env-vars</a></li></ul></li><li><span class="nav-section">User Guide</span><ul><li><details><summary class="nav-group"><a href="../../docs/userguide/cli.html">cli</a></summary><ul><li><a href="../../docs/userguide/cli/build.html">build</a></li><li><a href="../../docs/userguide/cli/bundle.html">bundle</a></li><li><a href="../../docs/userguide/cli/dev.html">dev</a></li><li><a href="../../docs/userguide/cli/init.html">init</a></li><li><a href="../../docs/userguide/cli/servers.html">servers</a></li><li><a href="../../docs/userguide/cli/stop.html">stop</a></li><li><a href="../../docs/userguide/cli/update.html">update</a></li><li><a href="../../docs/userguide/cli/version.html">version</a></li></ul></details></li><li><a href="../../docs/userguide/sharing.html">sharing</a></li></ul></li><li><span class="nav-section">Decisions</span><ul><li><a href="../../docs/decisions/ADR-0001-minimalist-site-code.html">ADR-0001-minimalist-site-code</a></li><li><a href="../../docs/decisions/ADR-0002-ai-accessibility.html">ADR-0002-ai-accessibility</a></li><li><a href="../../docs/decisions/ADR-0003-single-file-bundle.html">ADR-0003-single-file-bundle</a></li><li><a href="../../docs/decisions/ADR-0004-bun-runtime.html">ADR-0004-bun-runtime</a></li><li><a href="../../docs/decisions/ADR-0005-plugin-contract-and-distribution.html">ADR-0005-plugin-contract-and-distribution</a></li><li><a href="../../docs/decisions/DDR-0001-viewport-locked-layout.html">DDR-0001-viewport-locked-layout</a></li><li><a href="../../docs/decisions/DDR-0002-theme-system.html">DDR-0002-theme-system</a></li><li><a href="../../docs/decisions/DDR-0003-bounded-logo-slot.html">DDR-0003-bounded-logo-slot</a></li><li><a href="../../docs/decisions/DDR-0004-slides-rendering-model.html">DDR-0004-slides-rendering-model</a></li><li><a href="../../docs/decisions/DDR-0005-deterministic-layout-boundary.html">DDR-0005-deterministic-layout-boundary</a></li></ul></li><li><a href="../../schemas.html" class="nav-section">Schemas</a><ul><li><a href="../../schemas/plugin-registry.schema.html">plugin-registry.schema</a></li><li><a href="../../schemas/plugin-schemas-notes.html">plugin-schemas-notes</a></li><li><a href="../../schemas/plugin.schema.html">plugin.schema</a></li><li><a href="../../schemas/plugins.schema.html">plugins.schema</a></li><li><details><summary class="nav-group">v0</summary><ul><li><a href="../../schemas/v0/common.schema.html">common.schema</a></li><li><a href="../../schemas/v0/plugin-registry.schema.html">plugin-registry.schema</a></li><li><a href="../../schemas/v0/plugin.schema.html">plugin.schema</a></li><li><a href="../../schemas/v0/plugins.schema.html">plugins.schema</a></li><li><a href="../../schemas/v0/site.schema.html">site.schema</a></li><li><a href="../../schemas/v0/theme.schema.html">theme.schema</a></li></ul></details></li></ul></li></ul>
134
+ </div>
135
+ </nav>
136
+ <main class="content">
137
+ <article class="prose">
138
+ <nav class="breadcrumbs"><a href="../../content/guide/approaches.html">Content</a><span class="separator">›</span><a href="../../content/deployment/preflight.html">Deployment</a><span class="separator">›</span><span>preflight</span></nav>
139
+ <div class="page-meta">Last updated: 2026-02-12</div>
140
+ <h1 id="preflight-and-rollback">Preflight and Rollback</h1>
141
+ <p>This page is intentionally simple. The goal is: publish safely, and be able to undo a bad deploy fast.</p>
142
+ <h2 id="preflight-checklist">Preflight checklist</h2>
143
+ <h3 id="1-confirm-what-youre-deploying">1) Confirm what you&#39;re deploying</h3>
144
+ <ul>
145
+ <li>You have a single folder you will deploy: <code>dist/</code></li>
146
+ <li>You know which source folder produced it (your docroot)</li>
147
+ </ul>
148
+ <h3 id="2-build-clean">2) Build clean</h3>
149
+ <p>From your site root:</p>
150
+ <pre><code class="language-bash">make build
151
+ </code></pre>
152
+ <p>Or:</p>
153
+ <pre><code class="language-bash">bun run build
154
+ </code></pre>
155
+ <p>Expected: <code>dist/</code> exists and contains <code>index.html</code> plus assets.</p>
156
+ <h3 id="3-sanity-check-the-output">3) Sanity check the output</h3>
157
+ <ul>
158
+ <li>Open the built site and click 3–5 pages</li>
159
+ <li>Check images load</li>
160
+ <li>Check code blocks render</li>
161
+ <li>Toggle dark mode (if your theme supports it)</li>
162
+ </ul>
163
+ <h3 id="4-decide-your-url-and-dns-shape">4) Decide your URL and DNS shape</h3>
164
+ <ul>
165
+ <li>If you can, start with a <strong>subdomain</strong> like <code>docs.example.com</code> (simpler DNS + easier to move later).</li>
166
+ <li>Keep &quot;apex/root&quot; (<code>example.com</code>) for your main marketing site unless you have a reason.</li>
167
+ <li>Avoid subdirectory paths (<code>example.com/docs/</code>) — Kitfly currently assumes root-level hosting.</li>
168
+ </ul>
169
+ <h3 id="5-verify-https">5) Verify HTTPS</h3>
170
+ <p>After your first deploy, confirm:</p>
171
+ <ul>
172
+ <li>The site loads over <code>https://</code> (not just <code>http://</code>)</li>
173
+ <li>The browser shows a lock icon (valid certificate)</li>
174
+ <li>If your host offers &quot;force HTTPS&quot; or &quot;redirect HTTP → HTTPS&quot;, enable it</li>
175
+ </ul>
176
+ <p>All hosts in the <a href=".">deployment recipes</a> provision HTTPS automatically (usually via Let&#39;s Encrypt). You just need to verify it&#39;s working.</p>
177
+ <h3 id="6-confirm-secrets-handling-if-any">6) Confirm secrets handling (if any)</h3>
178
+ <p>Kitfly build output is static. Most deployments need <strong>no secrets</strong>.</p>
179
+ <p>If your deployment uses credentials (AWS keys, Netlify token, etc.):</p>
180
+ <ul>
181
+ <li>store them in environment variables or your host&#39;s secret store</li>
182
+ <li>keep them out of git</li>
183
+ </ul>
184
+ <p>See: <a href="secrets-and-env-vars.html">Secrets and Environment Variables</a></p>
185
+ <hr>
186
+ <h2 id="rollback-plan-simple-and-reliable">Rollback plan (simple and reliable)</h2>
187
+ <p>Pick one of these before you deploy:</p>
188
+ <h3 id="option-a-keep-the-previous-dist-folder">Option A: Keep the previous <code>dist/</code> folder</h3>
189
+ <ul>
190
+ <li>Copy <code>dist/</code> to a dated folder before deploying:<ul>
191
+ <li><code>dist-backup-YYYY-MM-DD/</code></li>
192
+ </ul>
193
+ </li>
194
+ <li>If something breaks, deploy the backup folder again.</li>
195
+ </ul>
196
+ <h3 id="option-b-use-a-previous-deployment-on-your-host">Option B: Use a &quot;previous&quot; deployment on your host</h3>
197
+ <p>Many hosts keep deploy history. If they do:</p>
198
+ <ul>
199
+ <li>confirm you can re-promote a prior deploy</li>
200
+ <li>confirm how long deploy history is retained</li>
201
+ </ul>
202
+ <hr>
203
+ <h2 id="common-failure-modes">Common failure modes</h2>
204
+ <ul>
205
+ <li><strong>Wrong folder uploaded</strong> (not <code>dist/</code>)</li>
206
+ <li><strong>Old build</strong> (you forgot to rebuild after edits)</li>
207
+ <li><strong>DNS not updated</strong> (domain points somewhere else)</li>
208
+ <li><strong>Aggressive caching</strong> (you deployed, but the browser/CDN serves old content)</li>
209
+ <li><strong>HTTPS not provisioned yet</strong> (some hosts take a few minutes to issue the cert)</li>
210
+ </ul>
211
+ <p>If you suspect caching:</p>
212
+ <ul>
213
+ <li>hard refresh (Shift+Reload)</li>
214
+ <li>try a private/incognito window</li>
215
+ <li>wait a few minutes (some CDNs take time)</li>
216
+ </ul>
217
+ <hr>
218
+ <h2 id="cache-invalidation-for-cicd-pipelines">Cache invalidation (for CI/CD pipelines)</h2>
219
+ <p>If you deploy via automation and need to force-clear CDN caches, here are the common commands:</p>
220
+ <h3 id="aws-cloudfront">AWS CloudFront</h3>
221
+ <pre><code class="language-bash">aws cloudfront create-invalidation \
222
+ --distribution-id &quot;$KITFLY_AWS_CLOUDFRONT_DISTRIBUTION_ID&quot; \
223
+ --paths &quot;/*&quot;
224
+ </code></pre>
225
+ <h3 id="cloudflare-pages-or-r2-behind-workers">Cloudflare (Pages or R2 behind Workers)</h3>
226
+ <p>Cloudflare Pages automatically invalidates on deploy. If you use R2 with a custom Worker and need to purge:</p>
227
+ <pre><code class="language-bash">curl -X POST &quot;https://api.cloudflare.com/client/v4/zones/$KITFLY_CF_ZONE_ID/purge_cache&quot; \
228
+ -H &quot;Authorization: Bearer $KITFLY_CF_API_TOKEN&quot; \
229
+ -H &quot;Content-Type: application/json&quot; \
230
+ --data &#39;{&quot;purge_everything&quot;:true}&#39;
231
+ </code></pre>
232
+ <h3 id="netlify">Netlify</h3>
233
+ <p>Netlify invalidates automatically on every deploy. No manual purge needed.</p>
234
+ <h3 id="vercel">Vercel</h3>
235
+ <p>Vercel invalidates CDN cache on deploy. No manual purge needed.</p>
236
+
237
+ </article>
238
+ <aside class="toc"><span class="toc-title">On this page</span><ul><li><a href="#preflight-checklist">Preflight checklist</a></li><li class="toc-h3"><a href="#1-confirm-what-youre-deploying">1) Confirm what you&#39;re deploying</a></li><li class="toc-h3"><a href="#2-build-clean">2) Build clean</a></li><li class="toc-h3"><a href="#3-sanity-check-the-output">3) Sanity check the output</a></li><li class="toc-h3"><a href="#4-decide-your-url-and-dns-shape">4) Decide your URL and DNS shape</a></li><li class="toc-h3"><a href="#5-verify-https">5) Verify HTTPS</a></li><li class="toc-h3"><a href="#6-confirm-secrets-handling-if-any">6) Confirm secrets handling (if any)</a></li><li><a href="#rollback-plan-simple-and-reliable">Rollback plan (simple and reliable)</a></li><li class="toc-h3"><a href="#option-b-use-a-previous-deployment-on-your-host">Option B: Use a &quot;previous&quot; deployment on your host</a></li><li><a href="#common-failure-modes">Common failure modes</a></li><li><a href="#cache-invalidation-for-cicd-pipelines">Cache invalidation (for CI/CD pipelines)</a></li><li class="toc-h3"><a href="#aws-cloudfront">AWS CloudFront</a></li><li class="toc-h3"><a href="#cloudflare-pages-or-r2-behind-workers">Cloudflare (Pages or R2 behind Workers)</a></li><li class="toc-h3"><a href="#netlify">Netlify</a></li><li class="toc-h3"><a href="#vercel">Vercel</a></li></ul></aside>
239
+ </main>
240
+ </div>
241
+
242
+ <footer class="site-footer">
243
+ <div class="footer-content">
244
+ <div class="footer-left">
245
+ <span class="footer-version">v0.2.1</span>
246
+ <span class="footer-separator">·</span>
247
+ <span class="footer-commit" title="Commit: 30dfc01">Published 2026-02-15</span>
248
+ </div>
249
+ <div class="footer-center">
250
+ <span class="footer-copyright"><a href="https://3leaps.net" class="footer-link">© 2026 3 Leaps, LLC</a></span>
251
+ <span class="footer-separator">·</span><a href="/" class="footer-link">Kitfly</a>
252
+ </div>
253
+ <div class="footer-right">
254
+ <a href="https://kitfly.dev" class="footer-link">Built with Kitfly</a>
255
+ </div>
256
+ </div>
257
+ </footer>
258
+ <!-- Syntax highlighting - Prism.js -->
259
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
260
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
261
+ <!-- Mermaid diagram support -->
262
+ <script type="module">
263
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
264
+
265
+ function getMermaidTheme() {
266
+ const theme = document.documentElement.getAttribute('data-theme');
267
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
268
+ const isDark = theme === 'dark' || (!theme && prefersDark);
269
+ return isDark ? 'dark' : 'neutral';
270
+ }
271
+
272
+ mermaid.initialize({
273
+ startOnLoad: true,
274
+ theme: getMermaidTheme()
275
+ });
276
+
277
+ // Re-render mermaid diagrams when theme changes
278
+ window.reinitMermaid = async function() {
279
+ mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
280
+ const diagrams = document.querySelectorAll('.mermaid');
281
+ for (const el of diagrams) {
282
+ const code = el.getAttribute('data-mermaid-source');
283
+ if (code) {
284
+ el.innerHTML = code;
285
+ el.removeAttribute('data-processed');
286
+ }
287
+ }
288
+ await mermaid.run({ nodes: diagrams });
289
+ };
290
+ </script>
291
+
292
+ <script>
293
+ function toggleTheme() {
294
+ const html = document.documentElement;
295
+ const current = html.getAttribute('data-theme');
296
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
297
+
298
+ let next;
299
+ if (current === 'dark') {
300
+ next = 'light';
301
+ } else if (current === 'light') {
302
+ next = 'dark';
303
+ } else {
304
+ // No explicit theme set, toggle from system preference
305
+ next = prefersDark ? 'light' : 'dark';
306
+ }
307
+
308
+ html.setAttribute('data-theme', next);
309
+ localStorage.setItem('theme', next);
310
+
311
+ // Switch Prism theme
312
+ const prismLight = document.getElementById('prism-light');
313
+ const prismDark = document.getElementById('prism-dark');
314
+ if (next === 'dark') {
315
+ prismLight?.setAttribute('disabled', '');
316
+ prismDark?.removeAttribute('disabled');
317
+ } else {
318
+ prismLight?.removeAttribute('disabled');
319
+ prismDark?.setAttribute('disabled', '');
320
+ }
321
+
322
+ // Re-render mermaid diagrams with new theme
323
+ if (window.reinitMermaid) {
324
+ window.reinitMermaid();
325
+ }
326
+ }
327
+
328
+ // Slides mode hash routing
329
+ (function initSlidesMode() {
330
+ const shell = document.querySelector('.slides-shell');
331
+ if (!shell) return;
332
+
333
+ const slides = Array.from(document.querySelectorAll('.slide'));
334
+ if (!slides.length) return;
335
+
336
+ const prevBtn = document.querySelector('.slide-prev');
337
+ const nextBtn = document.querySelector('.slide-next');
338
+ const counter = document.querySelector('.slide-counter');
339
+ const progressBar = document.querySelector('.slide-progress-bar');
340
+ const navLinks = Array.from(document.querySelectorAll('.sidebar-nav a[href^="#slide-"]'));
341
+ let current = 0;
342
+
343
+ function setActive(n) {
344
+ current = Math.max(0, Math.min(n, slides.length - 1));
345
+ slides.forEach((slide, idx) => slide.classList.toggle('active', idx === current));
346
+ navLinks.forEach((link) => {
347
+ const active = link.getAttribute('href') === '#' + slides[current].id;
348
+ link.classList.toggle('active', active);
349
+ });
350
+ if (counter) counter.textContent = (current + 1) + ' / ' + slides.length;
351
+ if (progressBar) progressBar.style.width = (((current + 1) / slides.length) * 100) + '%';
352
+ if (prevBtn) prevBtn.disabled = current === 0;
353
+ if (nextBtn) nextBtn.disabled = current === slides.length - 1;
354
+ history.replaceState(null, '', '#' + slides[current].id);
355
+ }
356
+
357
+ function setFromHash() {
358
+ const hash = window.location.hash || '';
359
+ const idx = slides.findIndex((s) => '#' + s.id === hash);
360
+ if (idx >= 0) setActive(idx);
361
+ else setActive(0);
362
+ }
363
+
364
+ prevBtn?.addEventListener('click', () => setActive(current - 1));
365
+ nextBtn?.addEventListener('click', () => setActive(current + 1));
366
+
367
+ document.addEventListener('keydown', (e) => {
368
+ if (e.key === 'ArrowRight' || e.key === ' ') {
369
+ e.preventDefault();
370
+ setActive(current + 1);
371
+ } else if (e.key === 'ArrowLeft') {
372
+ e.preventDefault();
373
+ setActive(current - 1);
374
+ } else if (e.key === 'Home') {
375
+ e.preventDefault();
376
+ setActive(0);
377
+ } else if (e.key === 'End') {
378
+ e.preventDefault();
379
+ setActive(slides.length - 1);
380
+ }
381
+ });
382
+
383
+ window.addEventListener('hashchange', setFromHash);
384
+ setFromHash();
385
+ })();
386
+
387
+ // Copy code button
388
+ document.querySelectorAll('.prose pre code').forEach(block => {
389
+ const button = document.createElement('button');
390
+ button.className = 'copy-button';
391
+ button.textContent = 'Copy';
392
+ button.onclick = async () => {
393
+ await navigator.clipboard.writeText(block.textContent);
394
+ button.textContent = 'Copied!';
395
+ setTimeout(() => button.textContent = 'Copy', 2000);
396
+ };
397
+ block.parentElement.appendChild(button);
398
+ });
399
+
400
+ // Mobile nav toggle
401
+ function toggleNav() {
402
+ document.querySelector('.sidebar').classList.toggle('open');
403
+ }
404
+
405
+ // Close nav when clicking outside on mobile
406
+ document.addEventListener('click', (e) => {
407
+ const sidebar = document.querySelector('.sidebar');
408
+ const toggle = document.querySelector('.nav-toggle');
409
+ if (sidebar.classList.contains('open') &&
410
+ !sidebar.contains(e.target) &&
411
+ !toggle.contains(e.target)) {
412
+ sidebar.classList.remove('open');
413
+ }
414
+ });
415
+ </script>
416
+
417
+ </body>
418
+ </html>