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,426 @@
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>Deployment - 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="active" class="nav-section">Deployment</a><ul><li><a href="../content/deployment/preflight.html">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><span>deployment</span></nav>
139
+ <div class="page-meta">Last updated: 2026-02-12</div>
140
+ <h1 id="deployment">Deployment</h1>
141
+ <p>Kitfly builds a static site. Deployment is just &quot;upload the <code>dist/</code> folder&quot;.</p>
142
+ <p>Before you pick a host, read this once:</p>
143
+ <h2 id="safety-first-please-read">Safety first (please read)</h2>
144
+ <h3 id="do">Do</h3>
145
+ <ul>
146
+ <li>Keep secrets out of your repo. Use environment variables or your host&#39;s secret store.</li>
147
+ <li>Use least-privilege credentials (scoped token, minimal permissions).</li>
148
+ <li>Deploy from a clean build: <code>make build</code> (or <code>bun run build</code>) and upload <code>dist/</code>.</li>
149
+ <li>Keep a rollback path: retain the previous <code>dist/</code> somewhere you can restore quickly.</li>
150
+ <li>Verify HTTPS works after your first deploy (most hosts provide it free).</li>
151
+ </ul>
152
+ <h3 id="dont">Don&#39;t</h3>
153
+ <ul>
154
+ <li>Don&#39;t commit <code>.env</code> files or cloud credentials.</li>
155
+ <li>Don&#39;t &quot;just make the bucket public&quot; unless you understand the blast radius.</li>
156
+ <li>Don&#39;t deploy from a random working tree state you can&#39;t reproduce.</li>
157
+ </ul>
158
+ <p>Next: read <a href="deployment/secrets-and-env-vars.html">Secrets and Environment Variables</a> and <a href="deployment/preflight.html">Preflight</a>.</p>
159
+ <hr>
160
+ <h2 id="build-vs-bundle-two-shipping-modes">Build vs bundle (two &quot;shipping&quot; modes)</h2>
161
+ <p>Kitfly has two ways to get your writing out into the world:</p>
162
+ <ul>
163
+ <li><strong>Host it</strong>: <code>kitfly build</code> → upload the <code>dist/</code> folder to a static host (the rest of this section).</li>
164
+ <li><strong>Send it</strong>: <code>kitfly bundle</code> → one HTML file you can email/Slack/upload (offline-friendly).</li>
165
+ </ul>
166
+ <p>If you&#39;re not sure which you want, start with <strong>bundle</strong> for internal reviews and <strong>build</strong> when you want a permanent link.</p>
167
+ <h2 id="which-host-should-i-pick">Which host should I pick?</h2>
168
+ <p>Use this as a quick menu:</p>
169
+ <h3 id="easiest-beginner-friendly">Easiest (beginner-friendly)</h3>
170
+ <ul>
171
+ <li><p><strong>Cloudflare Pages</strong> — a clean &quot;static site host&quot; with great CDN + custom domains.
172
+ Recipe: <a href="deployment/recipes/cloudflare-pages.html">Cloudflare Pages</a></p>
173
+ </li>
174
+ <li><p><strong>Netlify</strong> — simplest &quot;upload <code>dist/</code>&quot; flow, easy custom domains.
175
+ Recipe: <a href="deployment/recipes/netlify.html">Netlify</a></p>
176
+ </li>
177
+ <li><p><strong>GitHub Pages</strong> — great if your docs live in GitHub already.
178
+ Recipe: <a href="deployment/recipes/github-pages.html">GitHub Pages</a></p>
179
+ </li>
180
+ <li><p><strong>Vercel</strong> — fast CDN, clean UI, good &quot;push to deploy&quot; experience.
181
+ Recipe: <a href="deployment/recipes/vercel.html">Vercel</a></p>
182
+ </li>
183
+ </ul>
184
+ <h3 id="if-youre-already-on-a-platform">If you&#39;re already on a platform</h3>
185
+ <ul>
186
+ <li><p><strong>AWS S3</strong> — straightforward static hosting; best if your org is already in AWS.
187
+ Recipe: <a href="deployment/recipes/aws-s3.html">AWS S3</a></p>
188
+ </li>
189
+ <li><p><strong>Cloudflare R2</strong> — advanced; object storage that you usually put behind Pages/Workers.
190
+ Recipe: <a href="deployment/recipes/cloudflare-r2.html">Cloudflare R2</a></p>
191
+ </li>
192
+ </ul>
193
+ <h3 id="i-want-an-app-host">&quot;I want an app host&quot;</h3>
194
+ <ul>
195
+ <li><strong>Fly.io</strong> — good when you want a small always-on service (private/internal, auth, etc.).
196
+ Recipe: <a href="deployment/recipes/fly-io.html">Fly.io</a></li>
197
+ </ul>
198
+ <hr>
199
+ <h2 id="base-path-subdirectory-hosting">Base path / subdirectory hosting</h2>
200
+ <p>Kitfly currently generates sites that assume they are served from the root of a domain (<code>/</code>).</p>
201
+ <p>If you deploy to a subdirectory path (for example, GitHub Pages project sites serve at <code>/&lt;repo-name&gt;/</code>), internal links and asset references may break.</p>
202
+ <p><strong>Workarounds:</strong></p>
203
+ <ul>
204
+ <li>Use a <strong>custom domain</strong> or <strong>subdomain</strong> (<code>docs.example.com</code>) pointed at your host — this avoids the subdirectory issue entirely.</li>
205
+ <li>For GitHub Pages specifically, use a &quot;user/org&quot; site (<code>&lt;org&gt;.github.io</code>) which serves at root, or configure a custom domain.</li>
206
+ </ul>
207
+ <p>Base path support is being considered for a future release.</p>
208
+ <hr>
209
+ <h2 id="dns-basics-quick-primer">DNS basics (quick primer)</h2>
210
+ <p>If you bring your own domain, you&#39;ll do one of these:</p>
211
+ <ul>
212
+ <li><strong>Subdomain</strong> (<code>docs.example.com</code>) → usually a <strong>CNAME</strong> to your host target.</li>
213
+ <li><strong>Apex/root</strong> (<code>example.com</code>) → often <strong>A/AAAA</strong> records, or an &quot;ALIAS/ANAME&quot; feature (varies by DNS provider).</li>
214
+ </ul>
215
+ <p>Quick definitions:</p>
216
+ <ul>
217
+ <li><strong>A</strong> = IPv4 address record</li>
218
+ <li><strong>AAAA</strong> = IPv6 address record</li>
219
+ <li><strong>CNAME</strong> = alias one name to another name</li>
220
+ </ul>
221
+ <p>Each recipe calls out the common DNS pattern for that host.</p>
222
+ <hr>
223
+ <h2 id="https">HTTPS</h2>
224
+ <p>Every host in this section provides free HTTPS (via Let&#39;s Encrypt or equivalent). After your first deploy:</p>
225
+ <ul>
226
+ <li>Verify HTTPS works: load <code>https://your-domain.com</code> and check the lock icon.</li>
227
+ <li>If your host offers &quot;force HTTPS&quot; or &quot;redirect HTTP → HTTPS&quot;, enable it.</li>
228
+ <li>Don&#39;t serve docs over plain HTTP in production.</li>
229
+ </ul>
230
+ <hr>
231
+ <h2 id="common-workflow-host-agnostic">Common workflow (host-agnostic)</h2>
232
+ <ol>
233
+ <li>Build: <code>make build</code> (outputs <code>dist/</code>)</li>
234
+ <li>Preview locally (optional): open the built site in a browser</li>
235
+ <li>Deploy: upload/sync <code>dist/</code></li>
236
+ <li>Verify: load the site, click around, hard refresh</li>
237
+ <li>Confirm HTTPS works (first deploy)</li>
238
+ <li>Roll back if needed: redeploy the previous <code>dist/</code></li>
239
+ </ol>
240
+ <p>If you&#39;re not sure what an environment variable is (or how to set one), see:</p>
241
+ <ul>
242
+ <li><a href="reference/environment-variables.html">Reference: Environment Variables</a></li>
243
+ </ul>
244
+
245
+ </article>
246
+ <aside class="toc"><span class="toc-title">On this page</span><ul><li><a href="#safety-first-please-read">Safety first (please read)</a></li><li class="toc-h3"><a href="#do">Do</a></li><li class="toc-h3"><a href="#dont">Don&#39;t</a></li><li><a href="#build-vs-bundle-two-shipping-modes">Build vs bundle (two &quot;shipping&quot; modes)</a></li><li><a href="#which-host-should-i-pick">Which host should I pick?</a></li><li class="toc-h3"><a href="#easiest-beginner-friendly">Easiest (beginner-friendly)</a></li><li class="toc-h3"><a href="#if-youre-already-on-a-platform">If you&#39;re already on a platform</a></li><li class="toc-h3"><a href="#i-want-an-app-host">&quot;I want an app host&quot;</a></li><li><a href="#base-path-subdirectory-hosting">Base path / subdirectory hosting</a></li><li><a href="#dns-basics-quick-primer">DNS basics (quick primer)</a></li><li><a href="#https">HTTPS</a></li><li><a href="#common-workflow-host-agnostic">Common workflow (host-agnostic)</a></li></ul></aside>
247
+ </main>
248
+ </div>
249
+
250
+ <footer class="site-footer">
251
+ <div class="footer-content">
252
+ <div class="footer-left">
253
+ <span class="footer-version">v0.2.1</span>
254
+ <span class="footer-separator">·</span>
255
+ <span class="footer-commit" title="Commit: 30dfc01">Published 2026-02-15</span>
256
+ </div>
257
+ <div class="footer-center">
258
+ <span class="footer-copyright"><a href="https://3leaps.net" class="footer-link">© 2026 3 Leaps, LLC</a></span>
259
+ <span class="footer-separator">·</span><a href="/" class="footer-link">Kitfly</a>
260
+ </div>
261
+ <div class="footer-right">
262
+ <a href="https://kitfly.dev" class="footer-link">Built with Kitfly</a>
263
+ </div>
264
+ </div>
265
+ </footer>
266
+ <!-- Syntax highlighting - Prism.js -->
267
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
268
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
269
+ <!-- Mermaid diagram support -->
270
+ <script type="module">
271
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
272
+
273
+ function getMermaidTheme() {
274
+ const theme = document.documentElement.getAttribute('data-theme');
275
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
276
+ const isDark = theme === 'dark' || (!theme && prefersDark);
277
+ return isDark ? 'dark' : 'neutral';
278
+ }
279
+
280
+ mermaid.initialize({
281
+ startOnLoad: true,
282
+ theme: getMermaidTheme()
283
+ });
284
+
285
+ // Re-render mermaid diagrams when theme changes
286
+ window.reinitMermaid = async function() {
287
+ mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
288
+ const diagrams = document.querySelectorAll('.mermaid');
289
+ for (const el of diagrams) {
290
+ const code = el.getAttribute('data-mermaid-source');
291
+ if (code) {
292
+ el.innerHTML = code;
293
+ el.removeAttribute('data-processed');
294
+ }
295
+ }
296
+ await mermaid.run({ nodes: diagrams });
297
+ };
298
+ </script>
299
+
300
+ <script>
301
+ function toggleTheme() {
302
+ const html = document.documentElement;
303
+ const current = html.getAttribute('data-theme');
304
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
305
+
306
+ let next;
307
+ if (current === 'dark') {
308
+ next = 'light';
309
+ } else if (current === 'light') {
310
+ next = 'dark';
311
+ } else {
312
+ // No explicit theme set, toggle from system preference
313
+ next = prefersDark ? 'light' : 'dark';
314
+ }
315
+
316
+ html.setAttribute('data-theme', next);
317
+ localStorage.setItem('theme', next);
318
+
319
+ // Switch Prism theme
320
+ const prismLight = document.getElementById('prism-light');
321
+ const prismDark = document.getElementById('prism-dark');
322
+ if (next === 'dark') {
323
+ prismLight?.setAttribute('disabled', '');
324
+ prismDark?.removeAttribute('disabled');
325
+ } else {
326
+ prismLight?.removeAttribute('disabled');
327
+ prismDark?.setAttribute('disabled', '');
328
+ }
329
+
330
+ // Re-render mermaid diagrams with new theme
331
+ if (window.reinitMermaid) {
332
+ window.reinitMermaid();
333
+ }
334
+ }
335
+
336
+ // Slides mode hash routing
337
+ (function initSlidesMode() {
338
+ const shell = document.querySelector('.slides-shell');
339
+ if (!shell) return;
340
+
341
+ const slides = Array.from(document.querySelectorAll('.slide'));
342
+ if (!slides.length) return;
343
+
344
+ const prevBtn = document.querySelector('.slide-prev');
345
+ const nextBtn = document.querySelector('.slide-next');
346
+ const counter = document.querySelector('.slide-counter');
347
+ const progressBar = document.querySelector('.slide-progress-bar');
348
+ const navLinks = Array.from(document.querySelectorAll('.sidebar-nav a[href^="#slide-"]'));
349
+ let current = 0;
350
+
351
+ function setActive(n) {
352
+ current = Math.max(0, Math.min(n, slides.length - 1));
353
+ slides.forEach((slide, idx) => slide.classList.toggle('active', idx === current));
354
+ navLinks.forEach((link) => {
355
+ const active = link.getAttribute('href') === '#' + slides[current].id;
356
+ link.classList.toggle('active', active);
357
+ });
358
+ if (counter) counter.textContent = (current + 1) + ' / ' + slides.length;
359
+ if (progressBar) progressBar.style.width = (((current + 1) / slides.length) * 100) + '%';
360
+ if (prevBtn) prevBtn.disabled = current === 0;
361
+ if (nextBtn) nextBtn.disabled = current === slides.length - 1;
362
+ history.replaceState(null, '', '#' + slides[current].id);
363
+ }
364
+
365
+ function setFromHash() {
366
+ const hash = window.location.hash || '';
367
+ const idx = slides.findIndex((s) => '#' + s.id === hash);
368
+ if (idx >= 0) setActive(idx);
369
+ else setActive(0);
370
+ }
371
+
372
+ prevBtn?.addEventListener('click', () => setActive(current - 1));
373
+ nextBtn?.addEventListener('click', () => setActive(current + 1));
374
+
375
+ document.addEventListener('keydown', (e) => {
376
+ if (e.key === 'ArrowRight' || e.key === ' ') {
377
+ e.preventDefault();
378
+ setActive(current + 1);
379
+ } else if (e.key === 'ArrowLeft') {
380
+ e.preventDefault();
381
+ setActive(current - 1);
382
+ } else if (e.key === 'Home') {
383
+ e.preventDefault();
384
+ setActive(0);
385
+ } else if (e.key === 'End') {
386
+ e.preventDefault();
387
+ setActive(slides.length - 1);
388
+ }
389
+ });
390
+
391
+ window.addEventListener('hashchange', setFromHash);
392
+ setFromHash();
393
+ })();
394
+
395
+ // Copy code button
396
+ document.querySelectorAll('.prose pre code').forEach(block => {
397
+ const button = document.createElement('button');
398
+ button.className = 'copy-button';
399
+ button.textContent = 'Copy';
400
+ button.onclick = async () => {
401
+ await navigator.clipboard.writeText(block.textContent);
402
+ button.textContent = 'Copied!';
403
+ setTimeout(() => button.textContent = 'Copy', 2000);
404
+ };
405
+ block.parentElement.appendChild(button);
406
+ });
407
+
408
+ // Mobile nav toggle
409
+ function toggleNav() {
410
+ document.querySelector('.sidebar').classList.toggle('open');
411
+ }
412
+
413
+ // Close nav when clicking outside on mobile
414
+ document.addEventListener('click', (e) => {
415
+ const sidebar = document.querySelector('.sidebar');
416
+ const toggle = document.querySelector('.nav-toggle');
417
+ if (sidebar.classList.contains('open') &&
418
+ !sidebar.contains(e.target) &&
419
+ !toggle.contains(e.target)) {
420
+ sidebar.classList.remove('open');
421
+ }
422
+ });
423
+ </script>
424
+
425
+ </body>
426
+ </html>