kitfly 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +63 -16
- package/VERSION +1 -1
- package/dist/_raw/content/deployment/preflight.md +134 -0
- package/dist/_raw/content/deployment/recipes/aws-s3.md +128 -0
- package/dist/_raw/content/deployment/recipes/cloudflare-pages.md +73 -0
- package/dist/_raw/content/deployment/recipes/cloudflare-r2.md +156 -0
- package/dist/_raw/content/deployment/recipes/fly-io.md +57 -0
- package/dist/_raw/content/deployment/recipes/github-pages.md +112 -0
- package/dist/_raw/content/deployment/recipes/netlify.md +99 -0
- package/dist/_raw/content/deployment/recipes/vercel.md +88 -0
- package/dist/_raw/content/deployment/secrets-and-env-vars.md +75 -0
- package/dist/_raw/content/deployment.md +128 -0
- package/dist/_raw/content/guide/approaches.md +182 -0
- package/dist/_raw/content/guide/features.md +121 -0
- package/dist/_raw/content/guide/getting-started.md +112 -0
- package/dist/_raw/content/guide/kitfly-overview.md +209 -0
- package/dist/_raw/content/reference/configuration.md +259 -0
- package/dist/_raw/content/reference/design-catalog.md +167 -0
- package/dist/_raw/content/reference/environment-variables.md +66 -0
- package/dist/_raw/content/reference/glossary.md +92 -0
- package/dist/_raw/content/reference/key-concepts.md +118 -0
- package/dist/_raw/content/reference/plugins.md +220 -0
- package/dist/_raw/content/reference/structure.md +166 -0
- package/dist/_raw/content/reference.md +19 -0
- package/dist/_raw/content/templates/crucible.md +192 -0
- package/dist/_raw/content/templates/handbook.md +83 -0
- package/dist/_raw/content/templates/minimal.md +138 -0
- package/dist/_raw/content/templates/overview.md +187 -0
- package/dist/_raw/content/templates/pipeline.md +151 -0
- package/dist/_raw/content/templates/productbook.md +187 -0
- package/dist/_raw/content/templates/runbook.md +193 -0
- package/dist/_raw/content/templates/servicebook.md +163 -0
- package/dist/_raw/docs/decisions/ADR-0001-minimalist-site-code.md +118 -0
- package/dist/_raw/docs/decisions/ADR-0002-ai-accessibility.md +153 -0
- package/dist/_raw/docs/decisions/ADR-0003-single-file-bundle.md +93 -0
- package/dist/_raw/docs/decisions/ADR-0004-bun-runtime.md +98 -0
- package/dist/_raw/docs/decisions/ADR-0005-plugin-contract-and-distribution.md +110 -0
- package/dist/_raw/docs/decisions/DDR-0001-viewport-locked-layout.md +111 -0
- package/dist/_raw/docs/decisions/DDR-0002-theme-system.md +131 -0
- package/dist/_raw/docs/decisions/DDR-0003-bounded-logo-slot.md +106 -0
- package/dist/_raw/docs/decisions/DDR-0004-slides-rendering-model.md +113 -0
- package/dist/_raw/docs/decisions/DDR-0005-deterministic-layout-boundary.md +107 -0
- package/dist/_raw/docs/userguide/cli/build.md +85 -0
- package/dist/_raw/docs/userguide/cli/bundle.md +81 -0
- package/dist/_raw/docs/userguide/cli/dev.md +92 -0
- package/dist/_raw/docs/userguide/cli/init.md +116 -0
- package/dist/_raw/docs/userguide/cli/servers.md +69 -0
- package/dist/_raw/docs/userguide/cli/stop.md +76 -0
- package/dist/_raw/docs/userguide/cli/update.md +78 -0
- package/dist/_raw/docs/userguide/cli/version.md +65 -0
- package/dist/_raw/docs/userguide/cli.md +34 -0
- package/dist/_raw/docs/userguide/sharing.md +94 -0
- package/dist/_raw/schemas/plugin-schemas-notes.md +71 -0
- package/dist/_raw/schemas.md +42 -0
- package/dist/assets/brand/kitfly-favicon-32.png +0 -0
- package/dist/assets/brand/kitfly-icon-64.png +0 -0
- package/dist/assets/brand/kitfly-logo-128.png +0 -0
- package/dist/assets/brand/kitfly-logo-512.png +0 -0
- package/dist/assets/brand/kitfly-logo.svg +12132 -0
- package/dist/assets/brand/kitfly-neon-128.png +0 -0
- package/dist/assets/brand/kitfly-neon-192.png +0 -0
- package/dist/assets/brand/kitfly-neon-256.png +0 -0
- package/dist/assets/brand/kitfly-neon.png +0 -0
- package/dist/assets/brand/palette.md +75 -0
- package/dist/content/deployment/index.html +11 -0
- package/dist/content/deployment/preflight.html +418 -0
- package/dist/content/deployment/recipes/aws-s3.html +421 -0
- package/dist/content/deployment/recipes/cloudflare-pages.html +372 -0
- package/dist/content/deployment/recipes/cloudflare-r2.html +443 -0
- package/dist/content/deployment/recipes/fly-io.html +356 -0
- package/dist/content/deployment/recipes/github-pages.html +414 -0
- package/dist/content/deployment/recipes/index.html +11 -0
- package/dist/content/deployment/recipes/netlify.html +394 -0
- package/dist/content/deployment/recipes/vercel.html +382 -0
- package/dist/content/deployment/secrets-and-env-vars.html +380 -0
- package/dist/content/deployment.html +426 -0
- package/dist/content/guide/approaches.html +501 -0
- package/dist/content/guide/features.html +436 -0
- package/dist/content/guide/getting-started.html +403 -0
- package/dist/content/guide/index.html +11 -0
- package/dist/content/guide/kitfly-overview.html +544 -0
- package/dist/content/index.html +11 -0
- package/dist/content/reference/configuration.html +580 -0
- package/dist/content/reference/design-catalog.html +449 -0
- package/dist/content/reference/environment-variables.html +367 -0
- package/dist/content/reference/glossary.html +368 -0
- package/dist/content/reference/index.html +11 -0
- package/dist/content/reference/key-concepts.html +399 -0
- package/dist/content/reference/plugins.html +491 -0
- package/dist/content/reference/structure.html +463 -0
- package/dist/content/reference.html +334 -0
- package/dist/content/templates/crucible.html +546 -0
- package/dist/content/templates/handbook.html +405 -0
- package/dist/content/templates/index.html +11 -0
- package/dist/content/templates/minimal.html +447 -0
- package/dist/content/templates/overview.html +558 -0
- package/dist/content/templates/pipeline.html +494 -0
- package/dist/content/templates/productbook.html +540 -0
- package/dist/content/templates/runbook.html +543 -0
- package/dist/content/templates/servicebook.html +523 -0
- package/dist/content-index.json +540 -0
- package/dist/docs/decisions/ADR-0001-minimalist-site-code.html +491 -0
- package/dist/docs/decisions/ADR-0002-ai-accessibility.html +434 -0
- package/dist/docs/decisions/ADR-0003-single-file-bundle.html +412 -0
- package/dist/docs/decisions/ADR-0004-bun-runtime.html +409 -0
- package/dist/docs/decisions/ADR-0005-plugin-contract-and-distribution.html +402 -0
- package/dist/docs/decisions/DDR-0001-viewport-locked-layout.html +459 -0
- package/dist/docs/decisions/DDR-0002-theme-system.html +452 -0
- package/dist/docs/decisions/DDR-0003-bounded-logo-slot.html +423 -0
- package/dist/docs/decisions/DDR-0004-slides-rendering-model.html +399 -0
- package/dist/docs/decisions/DDR-0005-deterministic-layout-boundary.html +422 -0
- package/dist/docs/decisions/index.html +11 -0
- package/dist/docs/userguide/cli/build.html +408 -0
- package/dist/docs/userguide/cli/bundle.html +419 -0
- package/dist/docs/userguide/cli/dev.html +428 -0
- package/dist/docs/userguide/cli/index.html +11 -0
- package/dist/docs/userguide/cli/init.html +436 -0
- package/dist/docs/userguide/cli/servers.html +393 -0
- package/dist/docs/userguide/cli/stop.html +408 -0
- package/dist/docs/userguide/cli/update.html +406 -0
- package/dist/docs/userguide/cli/version.html +406 -0
- package/dist/docs/userguide/cli.html +386 -0
- package/dist/docs/userguide/index.html +11 -0
- package/dist/docs/userguide/sharing.html +465 -0
- package/dist/index.html +387 -0
- package/dist/llms.txt +18 -0
- package/dist/provenance.json +7 -0
- package/dist/schemas/index.html +11 -0
- package/dist/schemas/plugin-registry.schema.html +327 -0
- package/dist/schemas/plugin-schemas-notes.html +364 -0
- package/dist/schemas/plugin.schema.html +327 -0
- package/dist/schemas/plugins.schema.html +327 -0
- package/dist/schemas/v0/common.schema.html +386 -0
- package/dist/schemas/v0/index.html +11 -0
- package/dist/schemas/v0/plugin-registry.schema.html +547 -0
- package/dist/schemas/v0/plugin.schema.html +497 -0
- package/dist/schemas/v0/plugins.schema.html +406 -0
- package/dist/schemas/v0/site.schema.html +541 -0
- package/dist/schemas/v0/theme.schema.html +615 -0
- package/dist/schemas.html +351 -0
- package/dist/styles.css +1262 -0
- package/package.json +4 -2
- package/plugins-dist/callouts.css +32 -0
- package/plugins-dist/callouts.js +46 -0
- package/plugins-dist/slides-visuals.css +224 -0
- package/plugins-dist/slides-visuals.js +598 -0
- package/registry/plugins.yaml +35 -0
- package/schemas/README.md +10 -0
- package/schemas/plugin-registry.schema.json +5 -0
- package/schemas/plugin-schemas-notes.md +71 -0
- package/schemas/plugin.schema.json +5 -0
- package/schemas/plugins.schema.json +5 -0
- package/schemas/v0/common.schema.json +64 -0
- package/schemas/v0/plugin-registry.schema.json +225 -0
- package/schemas/v0/plugin.schema.json +175 -0
- package/schemas/v0/plugins.schema.json +84 -0
- package/schemas/v0/site.schema.json +56 -9
- package/schemas/v0/theme.schema.json +105 -22
- package/scripts/build.ts +155 -3
- package/scripts/bundle.ts +258 -95
- package/scripts/dev.ts +203 -1
- package/src/__tests__/build.test.ts +158 -1
- package/src/__tests__/bundle.test.ts +31 -0
- package/src/__tests__/cli.test.ts +14 -3
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/bad-list-indent.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/blank-line.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/compare-object-items.md +9 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/unknown-type.md +3 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/compare.md +10 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/comparison-table.md +14 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/funnel.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/kpi.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/layer-cake.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/pyramid.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/quadrant-grid.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/scorecard.md +13 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
- package/src/__tests__/init.test.ts +35 -0
- package/src/__tests__/plugin-loader.test.ts +221 -0
- package/src/__tests__/shared.test.ts +428 -0
- package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
- package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +114 -0
- package/src/__tests__/styles.test.ts +35 -0
- package/src/cli.ts +9 -4
- package/src/plugin-loader.ts +245 -0
- package/src/shared.ts +614 -7
- package/src/site/styles.css +331 -0
- package/src/site/template.html +66 -5
- package/src/templates/deck.ts +186 -0
- package/src/templates/driver.ts +11 -1
- package/src/templates/minimal.ts +1 -0
|
@@ -0,0 +1,364 @@
|
|
|
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>Plugin Schema Notes - 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.0</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/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">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" class="active">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="../schemas/plugin-registry.schema.html">Schemas</a><span class="separator">›</span><span>plugin-schemas-notes</span></nav>
|
|
139
|
+
<div class="page-meta">Last updated: 2026-02-12</div>
|
|
140
|
+
<h1 id="plugin-schema-notes-v020">Plugin Schema Notes (v0.2.0)</h1>
|
|
141
|
+
<p>This note accompanies the draft schemas:</p>
|
|
142
|
+
<ul>
|
|
143
|
+
<li><code>schemas/plugin.schema.json</code> → <code>schemas/v0/plugin.schema.json</code> (plugin.yaml)</li>
|
|
144
|
+
<li><code>schemas/plugin-registry.schema.json</code> → <code>schemas/v0/plugin-registry.schema.json</code> (registry/plugins.yaml)</li>
|
|
145
|
+
</ul>
|
|
146
|
+
<h2 id="hook-validation-rules-pluginyaml">Hook validation rules (plugin.yaml)</h2>
|
|
147
|
+
<p>The <code>hooks</code> block is validated as a strict object:</p>
|
|
148
|
+
<ul>
|
|
149
|
+
<li>Allowed keys: <code>marked-extension</code>, <code>template-head</code>, <code>template-body-end</code></li>
|
|
150
|
+
<li>Value type: boolean (<code>true</code>/<code>false</code>) only</li>
|
|
151
|
+
<li>Unknown keys: <strong>invalid</strong> (schema rejects via <code>additionalProperties: false</code>)</li>
|
|
152
|
+
</ul>
|
|
153
|
+
<p>Rationale: Contract-first + minimal loader. Unknown hooks should be caught at validation time rather than ignored at runtime.</p>
|
|
154
|
+
<h2 id="supply-chain-constraints">Supply chain constraints</h2>
|
|
155
|
+
<ul>
|
|
156
|
+
<li><code>dependencies.cdn[]</code> requires both <code>url</code> and <code>integrity</code>.</li>
|
|
157
|
+
<li><code>integrity</code> must be an SRI string (<code>sha256|sha384|sha512</code> + base64).</li>
|
|
158
|
+
<li>Registry entries use <strong>per-asset</strong> SHA256 checksums: <code>assets.assetSha256.js</code> and/or <code>assets.assetSha256.css</code>.</li>
|
|
159
|
+
</ul>
|
|
160
|
+
<p>Rationale: The brief mandates SRI on all CDN resources; the schema encodes this as required fields, not optional hints.</p>
|
|
161
|
+
<p>Rationale (checksums): Release-time <code>CHECKSUMS.yaml</code> is per-asset, and install-time verification should validate each fetched asset independently (JS and CSS can be cached and verified separately). Using an algorithm-specific field name (<code>assetSha256</code>) keeps room for future parallel algorithms without overloading a generic <code>checksums</code> structure.</p>
|
|
162
|
+
<h2 id="registry-asset-types">Registry asset types</h2>
|
|
163
|
+
<p>The registry schema intentionally only supports <code>assets.js</code> and <code>assets.css</code> in v0.2.0.</p>
|
|
164
|
+
<p>Rationale: Keep the contract minimal; add additional asset types only when a concrete plugin requires them.</p>
|
|
165
|
+
<h2 id="local-registries-baseurl-">Local registries (<code>baseUrl: ""</code>)</h2>
|
|
166
|
+
<p>For offline/local registries that only reference on-disk assets (e.g. <code>plugins-dist/...</code>), <code>baseUrl</code> may be an empty string.</p>
|
|
167
|
+
<h2 id="mode-allowlisting-modes">Mode allowlisting (<code>modes</code>)</h2>
|
|
168
|
+
<p>Both plugin manifests (<code>plugin.yaml</code>) and registry entries may include an optional <code>modes</code> field.</p>
|
|
169
|
+
<p>Semantics:</p>
|
|
170
|
+
<ul>
|
|
171
|
+
<li>Omitted: allowed in <strong>all</strong> Kitfly modes</li>
|
|
172
|
+
<li>Present with values (e.g. <code>["docs"]</code>): allowed only in those modes</li>
|
|
173
|
+
<li>Present but empty (<code>[]</code>): blocked in <strong>all</strong> modes (useful for temporarily disabling a plugin without removing it from <code>kitfly.plugins.yaml</code>)</li>
|
|
174
|
+
</ul>
|
|
175
|
+
<p>Rationale: Kitfly has two primary rendering modes (<code>docs</code> and <code>slides</code>). Mode allowlisting is an intentionally small mechanism to keep plugins predictable and easy to dogfood across both surfaces.</p>
|
|
176
|
+
<h2 id="version-range-validation">Version range validation</h2>
|
|
177
|
+
<p>The <code>kitfly</code> field is required and validated as a simple “space-separated comparator” string (e.g. <code>>=0.2.0 <1.0.0</code>).</p>
|
|
178
|
+
<p>Rationale: JSON Schema cannot fully validate npm/semver range syntax without embedding a custom parser. This pattern check is intentionally minimal: it enforces “looks like comparator(s) + semver” while leaving exact semantics to the loader.</p>
|
|
179
|
+
<h2 id="atomic-plugins-no-plugin-to-plugin-dependencies">Atomic plugins (no plugin-to-plugin dependencies)</h2>
|
|
180
|
+
<p>The schema defines <code>dependencies</code> with <code>additionalProperties: false</code> and only allows a <code>cdn</code> field.</p>
|
|
181
|
+
<p>Rationale: This makes <code>dependencies.plugins</code> (or any other dependency category) invalid by construction, matching the “atomic plugins” decision.</p>
|
|
182
|
+
|
|
183
|
+
</article>
|
|
184
|
+
<aside class="toc"><span class="toc-title">On this page</span><ul><li><a href="#hook-validation-rules-pluginyaml">Hook validation rules (plugin.yaml)</a></li><li><a href="#supply-chain-constraints">Supply chain constraints</a></li><li><a href="#registry-asset-types">Registry asset types</a></li><li><a href="#version-range-validation">Version range validation</a></li><li><a href="#atomic-plugins-no-plugin-to-plugin-dependencies">Atomic plugins (no plugin-to-plugin dependencies)</a></li></ul></aside>
|
|
185
|
+
</main>
|
|
186
|
+
</div>
|
|
187
|
+
|
|
188
|
+
<footer class="site-footer">
|
|
189
|
+
<div class="footer-content">
|
|
190
|
+
<div class="footer-left">
|
|
191
|
+
<span class="footer-version">v0.2.0</span>
|
|
192
|
+
<span class="footer-separator">·</span>
|
|
193
|
+
<span class="footer-commit" title="Commit: 33ccd68">Published 2026-02-15</span>
|
|
194
|
+
</div>
|
|
195
|
+
<div class="footer-center">
|
|
196
|
+
<span class="footer-copyright"><a href="https://3leaps.net" class="footer-link">© 2026 3 Leaps, LLC</a></span>
|
|
197
|
+
<span class="footer-separator">·</span><a href="/" class="footer-link">Kitfly</a>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="footer-right">
|
|
200
|
+
<a href="https://kitfly.dev" class="footer-link">Built with Kitfly</a>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</footer>
|
|
204
|
+
<!-- Syntax highlighting - Prism.js -->
|
|
205
|
+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/components/prism-core.min.js"></script>
|
|
206
|
+
<script src="https://cdn.jsdelivr.net/npm/prismjs@1/plugins/autoloader/prism-autoloader.min.js"></script>
|
|
207
|
+
<!-- Mermaid diagram support -->
|
|
208
|
+
<script type="module">
|
|
209
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
210
|
+
|
|
211
|
+
function getMermaidTheme() {
|
|
212
|
+
const theme = document.documentElement.getAttribute('data-theme');
|
|
213
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
214
|
+
const isDark = theme === 'dark' || (!theme && prefersDark);
|
|
215
|
+
return isDark ? 'dark' : 'neutral';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
mermaid.initialize({
|
|
219
|
+
startOnLoad: true,
|
|
220
|
+
theme: getMermaidTheme()
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Re-render mermaid diagrams when theme changes
|
|
224
|
+
window.reinitMermaid = async function() {
|
|
225
|
+
mermaid.initialize({ startOnLoad: false, theme: getMermaidTheme() });
|
|
226
|
+
const diagrams = document.querySelectorAll('.mermaid');
|
|
227
|
+
for (const el of diagrams) {
|
|
228
|
+
const code = el.getAttribute('data-mermaid-source');
|
|
229
|
+
if (code) {
|
|
230
|
+
el.innerHTML = code;
|
|
231
|
+
el.removeAttribute('data-processed');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
await mermaid.run({ nodes: diagrams });
|
|
235
|
+
};
|
|
236
|
+
</script>
|
|
237
|
+
|
|
238
|
+
<script>
|
|
239
|
+
function toggleTheme() {
|
|
240
|
+
const html = document.documentElement;
|
|
241
|
+
const current = html.getAttribute('data-theme');
|
|
242
|
+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
243
|
+
|
|
244
|
+
let next;
|
|
245
|
+
if (current === 'dark') {
|
|
246
|
+
next = 'light';
|
|
247
|
+
} else if (current === 'light') {
|
|
248
|
+
next = 'dark';
|
|
249
|
+
} else {
|
|
250
|
+
// No explicit theme set, toggle from system preference
|
|
251
|
+
next = prefersDark ? 'light' : 'dark';
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
html.setAttribute('data-theme', next);
|
|
255
|
+
localStorage.setItem('theme', next);
|
|
256
|
+
|
|
257
|
+
// Switch Prism theme
|
|
258
|
+
const prismLight = document.getElementById('prism-light');
|
|
259
|
+
const prismDark = document.getElementById('prism-dark');
|
|
260
|
+
if (next === 'dark') {
|
|
261
|
+
prismLight?.setAttribute('disabled', '');
|
|
262
|
+
prismDark?.removeAttribute('disabled');
|
|
263
|
+
} else {
|
|
264
|
+
prismLight?.removeAttribute('disabled');
|
|
265
|
+
prismDark?.setAttribute('disabled', '');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Re-render mermaid diagrams with new theme
|
|
269
|
+
if (window.reinitMermaid) {
|
|
270
|
+
window.reinitMermaid();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Slides mode hash routing
|
|
275
|
+
(function initSlidesMode() {
|
|
276
|
+
const shell = document.querySelector('.slides-shell');
|
|
277
|
+
if (!shell) return;
|
|
278
|
+
|
|
279
|
+
const slides = Array.from(document.querySelectorAll('.slide'));
|
|
280
|
+
if (!slides.length) return;
|
|
281
|
+
|
|
282
|
+
const prevBtn = document.querySelector('.slide-prev');
|
|
283
|
+
const nextBtn = document.querySelector('.slide-next');
|
|
284
|
+
const counter = document.querySelector('.slide-counter');
|
|
285
|
+
const progressBar = document.querySelector('.slide-progress-bar');
|
|
286
|
+
const navLinks = Array.from(document.querySelectorAll('.sidebar-nav a[href^="#slide-"]'));
|
|
287
|
+
let current = 0;
|
|
288
|
+
|
|
289
|
+
function setActive(n) {
|
|
290
|
+
current = Math.max(0, Math.min(n, slides.length - 1));
|
|
291
|
+
slides.forEach((slide, idx) => slide.classList.toggle('active', idx === current));
|
|
292
|
+
navLinks.forEach((link) => {
|
|
293
|
+
const active = link.getAttribute('href') === '#' + slides[current].id;
|
|
294
|
+
link.classList.toggle('active', active);
|
|
295
|
+
});
|
|
296
|
+
if (counter) counter.textContent = (current + 1) + ' / ' + slides.length;
|
|
297
|
+
if (progressBar) progressBar.style.width = (((current + 1) / slides.length) * 100) + '%';
|
|
298
|
+
if (prevBtn) prevBtn.disabled = current === 0;
|
|
299
|
+
if (nextBtn) nextBtn.disabled = current === slides.length - 1;
|
|
300
|
+
history.replaceState(null, '', '#' + slides[current].id);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function setFromHash() {
|
|
304
|
+
const hash = window.location.hash || '';
|
|
305
|
+
const idx = slides.findIndex((s) => '#' + s.id === hash);
|
|
306
|
+
if (idx >= 0) setActive(idx);
|
|
307
|
+
else setActive(0);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
prevBtn?.addEventListener('click', () => setActive(current - 1));
|
|
311
|
+
nextBtn?.addEventListener('click', () => setActive(current + 1));
|
|
312
|
+
|
|
313
|
+
document.addEventListener('keydown', (e) => {
|
|
314
|
+
if (e.key === 'ArrowRight' || e.key === ' ') {
|
|
315
|
+
e.preventDefault();
|
|
316
|
+
setActive(current + 1);
|
|
317
|
+
} else if (e.key === 'ArrowLeft') {
|
|
318
|
+
e.preventDefault();
|
|
319
|
+
setActive(current - 1);
|
|
320
|
+
} else if (e.key === 'Home') {
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
setActive(0);
|
|
323
|
+
} else if (e.key === 'End') {
|
|
324
|
+
e.preventDefault();
|
|
325
|
+
setActive(slides.length - 1);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
window.addEventListener('hashchange', setFromHash);
|
|
330
|
+
setFromHash();
|
|
331
|
+
})();
|
|
332
|
+
|
|
333
|
+
// Copy code button
|
|
334
|
+
document.querySelectorAll('.prose pre code').forEach(block => {
|
|
335
|
+
const button = document.createElement('button');
|
|
336
|
+
button.className = 'copy-button';
|
|
337
|
+
button.textContent = 'Copy';
|
|
338
|
+
button.onclick = async () => {
|
|
339
|
+
await navigator.clipboard.writeText(block.textContent);
|
|
340
|
+
button.textContent = 'Copied!';
|
|
341
|
+
setTimeout(() => button.textContent = 'Copy', 2000);
|
|
342
|
+
};
|
|
343
|
+
block.parentElement.appendChild(button);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// Mobile nav toggle
|
|
347
|
+
function toggleNav() {
|
|
348
|
+
document.querySelector('.sidebar').classList.toggle('open');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Close nav when clicking outside on mobile
|
|
352
|
+
document.addEventListener('click', (e) => {
|
|
353
|
+
const sidebar = document.querySelector('.sidebar');
|
|
354
|
+
const toggle = document.querySelector('.nav-toggle');
|
|
355
|
+
if (sidebar.classList.contains('open') &&
|
|
356
|
+
!sidebar.contains(e.target) &&
|
|
357
|
+
!toggle.contains(e.target)) {
|
|
358
|
+
sidebar.classList.remove('open');
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
</script>
|
|
362
|
+
|
|
363
|
+
</body>
|
|
364
|
+
</html>
|