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,409 @@
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>ADR-0004: Bun Runtime - 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">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" class="active">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="../../docs/userguide/cli/build.html">Docs</a><span class="separator">›</span><a href="../../docs/decisions/ADR-0001-minimalist-site-code.html">Decisions</a><span class="separator">›</span><span>ADR-0004-bun-runtime</span></nav>
139
+
140
+ <h1 id="adr-0004-bun-runtime">ADR-0004: Bun Runtime</h1>
141
+ <h2 id="status">Status</h2>
142
+ <p>Accepted</p>
143
+ <h2 id="context">Context</h2>
144
+ <p>Kitfly is a TypeScript CLI tool and static site generator. It needs a JavaScript runtime that can:</p>
145
+ <ol>
146
+ <li>Execute TypeScript directly (no transpilation step)</li>
147
+ <li>Run fast — dev server startup, build times, and test execution should feel instant</li>
148
+ <li>Provide a built-in test runner (reduce dev dependencies)</li>
149
+ <li>Support the Node.js API surface used by kitfly (fs, path, http)</li>
150
+ </ol>
151
+ <p>The project has a strict minimalism goal (ADR-0001): single production dependency (<code>marked</code>), minimal toolchain complexity.</p>
152
+ <h2 id="decision">Decision</h2>
153
+ <p>Use <strong>Bun</strong> as the primary runtime for development, testing, and production execution.</p>
154
+ <h3 id="what-bun-provides">What Bun Provides</h3>
155
+ <table>
156
+ <thead>
157
+ <tr>
158
+ <th>Capability</th>
159
+ <th>Replaces</th>
160
+ </tr>
161
+ </thead>
162
+ <tbody><tr>
163
+ <td>Native TypeScript execution</td>
164
+ <td><code>tsc</code> compilation step, <code>ts-node</code>, <code>tsx</code></td>
165
+ </tr>
166
+ <tr>
167
+ <td>Built-in test runner</td>
168
+ <td>Separate test framework install (jest/mocha for execution)</td>
169
+ </tr>
170
+ <tr>
171
+ <td>Fast startup (~25ms)</td>
172
+ <td>Node.js cold start (~100-200ms)</td>
173
+ </tr>
174
+ <tr>
175
+ <td>Built-in package manager</td>
176
+ <td>npm/yarn/pnpm (for install speed)</td>
177
+ </tr>
178
+ <tr>
179
+ <td><code>Bun.serve()</code> HTTP server</td>
180
+ <td>Express, Koa, or manual <code>http.createServer</code></td>
181
+ </tr>
182
+ </tbody></table>
183
+ <h3 id="runtime-boundary">Runtime Boundary</h3>
184
+ <p>Kitfly&#39;s source code uses standard Node.js APIs (<code>node:fs/promises</code>, <code>node:path</code>, <code>node:http</code>) rather than Bun-specific APIs where possible. The main Bun-specific usage is:</p>
185
+ <ul>
186
+ <li><code>Bun.serve()</code> in the dev server (<code>scripts/dev.ts</code>)</li>
187
+ <li><code>bun run</code> as the script executor</li>
188
+ <li><code>bun test</code> via vitest (which uses Bun&#39;s runtime)</li>
189
+ </ul>
190
+ <h3 id="user-requirement">User Requirement</h3>
191
+ <p>Users must have Bun installed to run <code>kitfly</code>. This is documented in getting-started and enforced at CLI startup. Bun installation is a single command on all major platforms:</p>
192
+ <pre><code class="language-bash">curl -fsSL https://bun.sh/install | bash
193
+ </code></pre>
194
+ <h3 id="test-runner">Test Runner</h3>
195
+ <p>Tests use <strong>vitest</strong> running on the Bun runtime. This provides:</p>
196
+ <ul>
197
+ <li>vitest&#39;s assertion API and test organization</li>
198
+ <li>Bun&#39;s fast execution speed</li>
199
+ <li>Watch mode for development (<code>bun test:watch</code>)</li>
200
+ </ul>
201
+ <h2 id="consequences">Consequences</h2>
202
+ <h3 id="positive">Positive</h3>
203
+ <ul>
204
+ <li><strong>No build step</strong>: TypeScript executes directly — <code>bun run src/cli.ts</code> just works</li>
205
+ <li><strong>Fast iteration</strong>: Dev server starts in under 100ms, full test suite runs in ~500ms (427 tests)</li>
206
+ <li><strong>Fewer dependencies</strong>: No need for <code>ts-node</code>, <code>tsx</code>, or a separate transpiler</li>
207
+ <li><strong>Aligned with minimalism</strong>: Bun&#39;s built-in capabilities reduce the toolchain surface</li>
208
+ </ul>
209
+ <h3 id="negative">Negative</h3>
210
+ <ul>
211
+ <li><strong>Bun is a user prerequisite</strong>: Users who only have Node.js installed need to install Bun first</li>
212
+ <li><strong>Ecosystem maturity</strong>: Bun is newer than Node.js — edge cases in compatibility exist (though kitfly&#39;s API surface is well-supported)</li>
213
+ <li><strong>CI consideration</strong>: CI environments need Bun installed (GitHub Actions: <code>oven-sh/setup-bun</code>)</li>
214
+ </ul>
215
+ <h3 id="neutral">Neutral</h3>
216
+ <ul>
217
+ <li>The standard Node.js API usage means a future port to Node.js (with a TypeScript loader) is feasible if needed</li>
218
+ <li>Bun&#39;s package manager is used for <code>bun install</code> but <code>package.json</code> remains standard — compatible with npm/yarn if users prefer for dependency management</li>
219
+ </ul>
220
+ <h2 id="alternatives-considered">Alternatives Considered</h2>
221
+ <h3 id="nodejs-tsx">Node.js + tsx</h3>
222
+ <p>Node.js with <code>tsx</code> for TypeScript execution. Viable but slower startup, requires additional dev dependency, and doesn&#39;t provide a built-in test runner or fast HTTP server.</p>
223
+ <h3 id="deno">Deno</h3>
224
+ <p>Native TypeScript support and built-in tooling. Rejected because Deno&#39;s module resolution (URL imports, import maps) would complicate the project structure and <code>kitfly init</code> copy model. Bun&#39;s Node.js compatibility is more aligned with kitfly&#39;s design.</p>
225
+ <h3 id="nodejs-esbuild-compilation">Node.js + esbuild compilation</h3>
226
+ <p>Compile TypeScript to JavaScript, ship compiled output. Rejected because it adds a build step to the development workflow and contradicts the &quot;edit and run&quot; simplicity goal.</p>
227
+
228
+ </article>
229
+ <aside class="toc"><span class="toc-title">On this page</span><ul><li><a href="#status">Status</a></li><li><a href="#context">Context</a></li><li><a href="#decision">Decision</a></li><li class="toc-h3"><a href="#what-bun-provides">What Bun Provides</a></li><li class="toc-h3"><a href="#runtime-boundary">Runtime Boundary</a></li><li class="toc-h3"><a href="#user-requirement">User Requirement</a></li><li class="toc-h3"><a href="#test-runner">Test Runner</a></li><li><a href="#consequences">Consequences</a></li><li class="toc-h3"><a href="#positive">Positive</a></li><li class="toc-h3"><a href="#negative">Negative</a></li><li class="toc-h3"><a href="#neutral">Neutral</a></li><li><a href="#alternatives-considered">Alternatives Considered</a></li><li class="toc-h3"><a href="#nodejs-tsx">Node.js + tsx</a></li><li class="toc-h3"><a href="#deno">Deno</a></li><li class="toc-h3"><a href="#nodejs-esbuild-compilation">Node.js + esbuild compilation</a></li></ul></aside>
230
+ </main>
231
+ </div>
232
+
233
+ <footer class="site-footer">
234
+ <div class="footer-content">
235
+ <div class="footer-left">
236
+ <span class="footer-version">v0.2.1</span>
237
+ <span class="footer-separator">·</span>
238
+ <span class="footer-commit" title="Commit: 30dfc01">Published 2026-02-15</span>
239
+ </div>
240
+ <div class="footer-center">
241
+ <span class="footer-copyright"><a href="https://3leaps.net" class="footer-link">© 2026 3 Leaps, LLC</a></span>
242
+ <span class="footer-separator">·</span><a href="/" class="footer-link">Kitfly</a>
243
+ </div>
244
+ <div class="footer-right">
245
+ <a href="https://kitfly.dev" class="footer-link">Built with Kitfly</a>
246
+ </div>
247
+ </div>
248
+ </footer>
249
+ <!-- Syntax highlighting - Prism.js -->
250
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
251
+ <script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
252
+ <!-- Mermaid diagram support -->
253
+ <script type="module">
254
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
255
+
256
+ function getMermaidTheme() {
257
+ const theme = document.documentElement.getAttribute('data-theme');
258
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
259
+ const isDark = theme === 'dark' || (!theme && prefersDark);
260
+ return isDark ? 'dark' : 'neutral';
261
+ }
262
+
263
+ mermaid.initialize({
264
+ startOnLoad: true,
265
+ theme: getMermaidTheme()
266
+ });
267
+
268
+ // Re-render mermaid diagrams when theme changes
269
+ window.reinitMermaid = async function() {
270
+ mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
271
+ const diagrams = document.querySelectorAll('.mermaid');
272
+ for (const el of diagrams) {
273
+ const code = el.getAttribute('data-mermaid-source');
274
+ if (code) {
275
+ el.innerHTML = code;
276
+ el.removeAttribute('data-processed');
277
+ }
278
+ }
279
+ await mermaid.run({ nodes: diagrams });
280
+ };
281
+ </script>
282
+
283
+ <script>
284
+ function toggleTheme() {
285
+ const html = document.documentElement;
286
+ const current = html.getAttribute('data-theme');
287
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
288
+
289
+ let next;
290
+ if (current === 'dark') {
291
+ next = 'light';
292
+ } else if (current === 'light') {
293
+ next = 'dark';
294
+ } else {
295
+ // No explicit theme set, toggle from system preference
296
+ next = prefersDark ? 'light' : 'dark';
297
+ }
298
+
299
+ html.setAttribute('data-theme', next);
300
+ localStorage.setItem('theme', next);
301
+
302
+ // Switch Prism theme
303
+ const prismLight = document.getElementById('prism-light');
304
+ const prismDark = document.getElementById('prism-dark');
305
+ if (next === 'dark') {
306
+ prismLight?.setAttribute('disabled', '');
307
+ prismDark?.removeAttribute('disabled');
308
+ } else {
309
+ prismLight?.removeAttribute('disabled');
310
+ prismDark?.setAttribute('disabled', '');
311
+ }
312
+
313
+ // Re-render mermaid diagrams with new theme
314
+ if (window.reinitMermaid) {
315
+ window.reinitMermaid();
316
+ }
317
+ }
318
+
319
+ // Slides mode hash routing
320
+ (function initSlidesMode() {
321
+ const shell = document.querySelector('.slides-shell');
322
+ if (!shell) return;
323
+
324
+ const slides = Array.from(document.querySelectorAll('.slide'));
325
+ if (!slides.length) return;
326
+
327
+ const prevBtn = document.querySelector('.slide-prev');
328
+ const nextBtn = document.querySelector('.slide-next');
329
+ const counter = document.querySelector('.slide-counter');
330
+ const progressBar = document.querySelector('.slide-progress-bar');
331
+ const navLinks = Array.from(document.querySelectorAll('.sidebar-nav a[href^="#slide-"]'));
332
+ let current = 0;
333
+
334
+ function setActive(n) {
335
+ current = Math.max(0, Math.min(n, slides.length - 1));
336
+ slides.forEach((slide, idx) => slide.classList.toggle('active', idx === current));
337
+ navLinks.forEach((link) => {
338
+ const active = link.getAttribute('href') === '#' + slides[current].id;
339
+ link.classList.toggle('active', active);
340
+ });
341
+ if (counter) counter.textContent = (current + 1) + ' / ' + slides.length;
342
+ if (progressBar) progressBar.style.width = (((current + 1) / slides.length) * 100) + '%';
343
+ if (prevBtn) prevBtn.disabled = current === 0;
344
+ if (nextBtn) nextBtn.disabled = current === slides.length - 1;
345
+ history.replaceState(null, '', '#' + slides[current].id);
346
+ }
347
+
348
+ function setFromHash() {
349
+ const hash = window.location.hash || '';
350
+ const idx = slides.findIndex((s) => '#' + s.id === hash);
351
+ if (idx >= 0) setActive(idx);
352
+ else setActive(0);
353
+ }
354
+
355
+ prevBtn?.addEventListener('click', () => setActive(current - 1));
356
+ nextBtn?.addEventListener('click', () => setActive(current + 1));
357
+
358
+ document.addEventListener('keydown', (e) => {
359
+ if (e.key === 'ArrowRight' || e.key === ' ') {
360
+ e.preventDefault();
361
+ setActive(current + 1);
362
+ } else if (e.key === 'ArrowLeft') {
363
+ e.preventDefault();
364
+ setActive(current - 1);
365
+ } else if (e.key === 'Home') {
366
+ e.preventDefault();
367
+ setActive(0);
368
+ } else if (e.key === 'End') {
369
+ e.preventDefault();
370
+ setActive(slides.length - 1);
371
+ }
372
+ });
373
+
374
+ window.addEventListener('hashchange', setFromHash);
375
+ setFromHash();
376
+ })();
377
+
378
+ // Copy code button
379
+ document.querySelectorAll('.prose pre code').forEach(block => {
380
+ const button = document.createElement('button');
381
+ button.className = 'copy-button';
382
+ button.textContent = 'Copy';
383
+ button.onclick = async () => {
384
+ await navigator.clipboard.writeText(block.textContent);
385
+ button.textContent = 'Copied!';
386
+ setTimeout(() => button.textContent = 'Copy', 2000);
387
+ };
388
+ block.parentElement.appendChild(button);
389
+ });
390
+
391
+ // Mobile nav toggle
392
+ function toggleNav() {
393
+ document.querySelector('.sidebar').classList.toggle('open');
394
+ }
395
+
396
+ // Close nav when clicking outside on mobile
397
+ document.addEventListener('click', (e) => {
398
+ const sidebar = document.querySelector('.sidebar');
399
+ const toggle = document.querySelector('.nav-toggle');
400
+ if (sidebar.classList.contains('open') &&
401
+ !sidebar.contains(e.target) &&
402
+ !toggle.contains(e.target)) {
403
+ sidebar.classList.remove('open');
404
+ }
405
+ });
406
+ </script>
407
+
408
+ </body>
409
+ </html>