kitfly 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +63 -16
  3. package/VERSION +1 -1
  4. package/dist/_raw/content/deployment/preflight.md +134 -0
  5. package/dist/_raw/content/deployment/recipes/aws-s3.md +128 -0
  6. package/dist/_raw/content/deployment/recipes/cloudflare-pages.md +73 -0
  7. package/dist/_raw/content/deployment/recipes/cloudflare-r2.md +156 -0
  8. package/dist/_raw/content/deployment/recipes/fly-io.md +57 -0
  9. package/dist/_raw/content/deployment/recipes/github-pages.md +112 -0
  10. package/dist/_raw/content/deployment/recipes/netlify.md +99 -0
  11. package/dist/_raw/content/deployment/recipes/vercel.md +88 -0
  12. package/dist/_raw/content/deployment/secrets-and-env-vars.md +75 -0
  13. package/dist/_raw/content/deployment.md +128 -0
  14. package/dist/_raw/content/guide/approaches.md +182 -0
  15. package/dist/_raw/content/guide/features.md +121 -0
  16. package/dist/_raw/content/guide/getting-started.md +112 -0
  17. package/dist/_raw/content/guide/kitfly-overview.md +209 -0
  18. package/dist/_raw/content/reference/configuration.md +259 -0
  19. package/dist/_raw/content/reference/design-catalog.md +167 -0
  20. package/dist/_raw/content/reference/environment-variables.md +66 -0
  21. package/dist/_raw/content/reference/glossary.md +92 -0
  22. package/dist/_raw/content/reference/key-concepts.md +118 -0
  23. package/dist/_raw/content/reference/plugins.md +220 -0
  24. package/dist/_raw/content/reference/structure.md +166 -0
  25. package/dist/_raw/content/reference.md +19 -0
  26. package/dist/_raw/content/templates/crucible.md +192 -0
  27. package/dist/_raw/content/templates/handbook.md +83 -0
  28. package/dist/_raw/content/templates/minimal.md +138 -0
  29. package/dist/_raw/content/templates/overview.md +187 -0
  30. package/dist/_raw/content/templates/pipeline.md +151 -0
  31. package/dist/_raw/content/templates/productbook.md +187 -0
  32. package/dist/_raw/content/templates/runbook.md +193 -0
  33. package/dist/_raw/content/templates/servicebook.md +163 -0
  34. package/dist/_raw/docs/decisions/ADR-0001-minimalist-site-code.md +118 -0
  35. package/dist/_raw/docs/decisions/ADR-0002-ai-accessibility.md +153 -0
  36. package/dist/_raw/docs/decisions/ADR-0003-single-file-bundle.md +93 -0
  37. package/dist/_raw/docs/decisions/ADR-0004-bun-runtime.md +98 -0
  38. package/dist/_raw/docs/decisions/ADR-0005-plugin-contract-and-distribution.md +110 -0
  39. package/dist/_raw/docs/decisions/DDR-0001-viewport-locked-layout.md +111 -0
  40. package/dist/_raw/docs/decisions/DDR-0002-theme-system.md +131 -0
  41. package/dist/_raw/docs/decisions/DDR-0003-bounded-logo-slot.md +106 -0
  42. package/dist/_raw/docs/decisions/DDR-0004-slides-rendering-model.md +113 -0
  43. package/dist/_raw/docs/decisions/DDR-0005-deterministic-layout-boundary.md +107 -0
  44. package/dist/_raw/docs/userguide/cli/build.md +85 -0
  45. package/dist/_raw/docs/userguide/cli/bundle.md +81 -0
  46. package/dist/_raw/docs/userguide/cli/dev.md +92 -0
  47. package/dist/_raw/docs/userguide/cli/init.md +116 -0
  48. package/dist/_raw/docs/userguide/cli/servers.md +69 -0
  49. package/dist/_raw/docs/userguide/cli/stop.md +76 -0
  50. package/dist/_raw/docs/userguide/cli/update.md +78 -0
  51. package/dist/_raw/docs/userguide/cli/version.md +65 -0
  52. package/dist/_raw/docs/userguide/cli.md +34 -0
  53. package/dist/_raw/docs/userguide/sharing.md +94 -0
  54. package/dist/_raw/schemas/plugin-schemas-notes.md +71 -0
  55. package/dist/_raw/schemas.md +42 -0
  56. package/dist/assets/brand/kitfly-favicon-32.png +0 -0
  57. package/dist/assets/brand/kitfly-icon-64.png +0 -0
  58. package/dist/assets/brand/kitfly-logo-128.png +0 -0
  59. package/dist/assets/brand/kitfly-logo-512.png +0 -0
  60. package/dist/assets/brand/kitfly-logo.svg +12132 -0
  61. package/dist/assets/brand/kitfly-neon-128.png +0 -0
  62. package/dist/assets/brand/kitfly-neon-192.png +0 -0
  63. package/dist/assets/brand/kitfly-neon-256.png +0 -0
  64. package/dist/assets/brand/kitfly-neon.png +0 -0
  65. package/dist/assets/brand/palette.md +75 -0
  66. package/dist/content/deployment/index.html +11 -0
  67. package/dist/content/deployment/preflight.html +418 -0
  68. package/dist/content/deployment/recipes/aws-s3.html +421 -0
  69. package/dist/content/deployment/recipes/cloudflare-pages.html +372 -0
  70. package/dist/content/deployment/recipes/cloudflare-r2.html +443 -0
  71. package/dist/content/deployment/recipes/fly-io.html +356 -0
  72. package/dist/content/deployment/recipes/github-pages.html +414 -0
  73. package/dist/content/deployment/recipes/index.html +11 -0
  74. package/dist/content/deployment/recipes/netlify.html +394 -0
  75. package/dist/content/deployment/recipes/vercel.html +382 -0
  76. package/dist/content/deployment/secrets-and-env-vars.html +380 -0
  77. package/dist/content/deployment.html +426 -0
  78. package/dist/content/guide/approaches.html +501 -0
  79. package/dist/content/guide/features.html +436 -0
  80. package/dist/content/guide/getting-started.html +403 -0
  81. package/dist/content/guide/index.html +11 -0
  82. package/dist/content/guide/kitfly-overview.html +544 -0
  83. package/dist/content/index.html +11 -0
  84. package/dist/content/reference/configuration.html +580 -0
  85. package/dist/content/reference/design-catalog.html +449 -0
  86. package/dist/content/reference/environment-variables.html +367 -0
  87. package/dist/content/reference/glossary.html +368 -0
  88. package/dist/content/reference/index.html +11 -0
  89. package/dist/content/reference/key-concepts.html +399 -0
  90. package/dist/content/reference/plugins.html +491 -0
  91. package/dist/content/reference/structure.html +463 -0
  92. package/dist/content/reference.html +334 -0
  93. package/dist/content/templates/crucible.html +546 -0
  94. package/dist/content/templates/handbook.html +405 -0
  95. package/dist/content/templates/index.html +11 -0
  96. package/dist/content/templates/minimal.html +447 -0
  97. package/dist/content/templates/overview.html +558 -0
  98. package/dist/content/templates/pipeline.html +494 -0
  99. package/dist/content/templates/productbook.html +540 -0
  100. package/dist/content/templates/runbook.html +543 -0
  101. package/dist/content/templates/servicebook.html +523 -0
  102. package/dist/content-index.json +540 -0
  103. package/dist/docs/decisions/ADR-0001-minimalist-site-code.html +491 -0
  104. package/dist/docs/decisions/ADR-0002-ai-accessibility.html +434 -0
  105. package/dist/docs/decisions/ADR-0003-single-file-bundle.html +412 -0
  106. package/dist/docs/decisions/ADR-0004-bun-runtime.html +409 -0
  107. package/dist/docs/decisions/ADR-0005-plugin-contract-and-distribution.html +402 -0
  108. package/dist/docs/decisions/DDR-0001-viewport-locked-layout.html +459 -0
  109. package/dist/docs/decisions/DDR-0002-theme-system.html +452 -0
  110. package/dist/docs/decisions/DDR-0003-bounded-logo-slot.html +423 -0
  111. package/dist/docs/decisions/DDR-0004-slides-rendering-model.html +399 -0
  112. package/dist/docs/decisions/DDR-0005-deterministic-layout-boundary.html +422 -0
  113. package/dist/docs/decisions/index.html +11 -0
  114. package/dist/docs/userguide/cli/build.html +408 -0
  115. package/dist/docs/userguide/cli/bundle.html +419 -0
  116. package/dist/docs/userguide/cli/dev.html +428 -0
  117. package/dist/docs/userguide/cli/index.html +11 -0
  118. package/dist/docs/userguide/cli/init.html +436 -0
  119. package/dist/docs/userguide/cli/servers.html +393 -0
  120. package/dist/docs/userguide/cli/stop.html +408 -0
  121. package/dist/docs/userguide/cli/update.html +406 -0
  122. package/dist/docs/userguide/cli/version.html +406 -0
  123. package/dist/docs/userguide/cli.html +386 -0
  124. package/dist/docs/userguide/index.html +11 -0
  125. package/dist/docs/userguide/sharing.html +465 -0
  126. package/dist/index.html +387 -0
  127. package/dist/llms.txt +18 -0
  128. package/dist/provenance.json +7 -0
  129. package/dist/schemas/index.html +11 -0
  130. package/dist/schemas/plugin-registry.schema.html +327 -0
  131. package/dist/schemas/plugin-schemas-notes.html +364 -0
  132. package/dist/schemas/plugin.schema.html +327 -0
  133. package/dist/schemas/plugins.schema.html +327 -0
  134. package/dist/schemas/v0/common.schema.html +386 -0
  135. package/dist/schemas/v0/index.html +11 -0
  136. package/dist/schemas/v0/plugin-registry.schema.html +547 -0
  137. package/dist/schemas/v0/plugin.schema.html +497 -0
  138. package/dist/schemas/v0/plugins.schema.html +406 -0
  139. package/dist/schemas/v0/site.schema.html +541 -0
  140. package/dist/schemas/v0/theme.schema.html +615 -0
  141. package/dist/schemas.html +351 -0
  142. package/dist/styles.css +1262 -0
  143. package/package.json +4 -2
  144. package/plugins-dist/callouts.css +32 -0
  145. package/plugins-dist/callouts.js +46 -0
  146. package/plugins-dist/slides-visuals.css +224 -0
  147. package/plugins-dist/slides-visuals.js +598 -0
  148. package/registry/plugins.yaml +35 -0
  149. package/schemas/README.md +10 -0
  150. package/schemas/plugin-registry.schema.json +5 -0
  151. package/schemas/plugin-schemas-notes.md +71 -0
  152. package/schemas/plugin.schema.json +5 -0
  153. package/schemas/plugins.schema.json +5 -0
  154. package/schemas/v0/common.schema.json +64 -0
  155. package/schemas/v0/plugin-registry.schema.json +225 -0
  156. package/schemas/v0/plugin.schema.json +175 -0
  157. package/schemas/v0/plugins.schema.json +84 -0
  158. package/schemas/v0/site.schema.json +56 -9
  159. package/schemas/v0/theme.schema.json +105 -22
  160. package/scripts/build.ts +155 -3
  161. package/scripts/bundle.ts +258 -95
  162. package/scripts/dev.ts +203 -1
  163. package/src/__tests__/build.test.ts +158 -1
  164. package/src/__tests__/bundle.test.ts +31 -0
  165. package/src/__tests__/cli.test.ts +14 -3
  166. package/src/__tests__/fixtures/fences/slides-visuals/invalid/bad-list-indent.md +5 -0
  167. package/src/__tests__/fixtures/fences/slides-visuals/invalid/blank-line.md +5 -0
  168. package/src/__tests__/fixtures/fences/slides-visuals/invalid/compare-object-items.md +9 -0
  169. package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
  170. package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
  171. package/src/__tests__/fixtures/fences/slides-visuals/invalid/unknown-type.md +3 -0
  172. package/src/__tests__/fixtures/fences/slides-visuals/valid/compare.md +10 -0
  173. package/src/__tests__/fixtures/fences/slides-visuals/valid/comparison-table.md +14 -0
  174. package/src/__tests__/fixtures/fences/slides-visuals/valid/funnel.md +7 -0
  175. package/src/__tests__/fixtures/fences/slides-visuals/valid/kpi.md +5 -0
  176. package/src/__tests__/fixtures/fences/slides-visuals/valid/layer-cake.md +6 -0
  177. package/src/__tests__/fixtures/fences/slides-visuals/valid/pyramid.md +6 -0
  178. package/src/__tests__/fixtures/fences/slides-visuals/valid/quadrant-grid.md +8 -0
  179. package/src/__tests__/fixtures/fences/slides-visuals/valid/scorecard.md +13 -0
  180. package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
  181. package/src/__tests__/init.test.ts +35 -0
  182. package/src/__tests__/plugin-loader.test.ts +221 -0
  183. package/src/__tests__/shared.test.ts +428 -0
  184. package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
  185. package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +114 -0
  186. package/src/__tests__/styles.test.ts +35 -0
  187. package/src/cli.ts +9 -4
  188. package/src/plugin-loader.ts +245 -0
  189. package/src/shared.ts +614 -7
  190. package/src/site/styles.css +331 -0
  191. package/src/site/template.html +66 -5
  192. package/src/templates/deck.ts +186 -0
  193. package/src/templates/driver.ts +11 -1
  194. package/src/templates/minimal.ts +1 -0
@@ -0,0 +1,71 @@
1
+ ---
2
+ title: "Plugin Schema Notes"
3
+ description: "Rationale and validation rules for plugin.yaml and registry/plugins.yaml schemas"
4
+ last_updated: "2026-02-12"
5
+ status: "draft"
6
+ tags:
7
+ - plugins
8
+ - schemas
9
+ - supply-chain
10
+ ---
11
+
12
+ # Plugin Schema Notes (v0.2.0)
13
+
14
+ This note accompanies the draft schemas:
15
+
16
+ - `schemas/plugin.schema.json` → `schemas/v0/plugin.schema.json` (plugin.yaml)
17
+ - `schemas/plugin-registry.schema.json` → `schemas/v0/plugin-registry.schema.json` (registry/plugins.yaml)
18
+
19
+ ## Hook validation rules (plugin.yaml)
20
+
21
+ The `hooks` block is validated as a strict object:
22
+
23
+ - Allowed keys: `marked-extension`, `template-head`, `template-body-end`
24
+ - Value type: boolean (`true`/`false`) only
25
+ - Unknown keys: **invalid** (schema rejects via `additionalProperties: false`)
26
+
27
+ Rationale: Contract-first + minimal loader. Unknown hooks should be caught at validation time rather than ignored at runtime.
28
+
29
+ ## Supply chain constraints
30
+
31
+ - `dependencies.cdn[]` requires both `url` and `integrity`.
32
+ - `integrity` must be an SRI string (`sha256|sha384|sha512` + base64).
33
+ - Registry entries use **per-asset** SHA256 checksums: `assets.assetSha256.js` and/or `assets.assetSha256.css`.
34
+
35
+ Rationale: The brief mandates SRI on all CDN resources; the schema encodes this as required fields, not optional hints.
36
+
37
+ Rationale (checksums): Release-time `CHECKSUMS.yaml` 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 (`assetSha256`) keeps room for future parallel algorithms without overloading a generic `checksums` structure.
38
+
39
+ ## Registry asset types
40
+
41
+ The registry schema intentionally only supports `assets.js` and `assets.css` in v0.2.0.
42
+
43
+ Rationale: Keep the contract minimal; add additional asset types only when a concrete plugin requires them.
44
+
45
+ ## Local registries (`baseUrl: ""`)
46
+
47
+ For offline/local registries that only reference on-disk assets (e.g. `plugins-dist/...`), `baseUrl` may be an empty string.
48
+
49
+ ## Mode allowlisting (`modes`)
50
+
51
+ Both plugin manifests (`plugin.yaml`) and registry entries may include an optional `modes` field.
52
+
53
+ Semantics:
54
+
55
+ - Omitted: allowed in **all** Kitfly modes
56
+ - Present with values (e.g. `["docs"]`): allowed only in those modes
57
+ - Present but empty (`[]`): blocked in **all** modes (useful for temporarily disabling a plugin without removing it from `kitfly.plugins.yaml`)
58
+
59
+ Rationale: Kitfly has two primary rendering modes (`docs` and `slides`). Mode allowlisting is an intentionally small mechanism to keep plugins predictable and easy to dogfood across both surfaces.
60
+
61
+ ## Version range validation
62
+
63
+ The `kitfly` field is required and validated as a simple “space-separated comparator” string (e.g. `>=0.2.0 <1.0.0`).
64
+
65
+ 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.
66
+
67
+ ## Atomic plugins (no plugin-to-plugin dependencies)
68
+
69
+ The schema defines `dependencies` with `additionalProperties: false` and only allows a `cdn` field.
70
+
71
+ Rationale: This makes `dependencies.plugins` (or any other dependency category) invalid by construction, matching the “atomic plugins” decision.
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/plugin.schema.json",
4
+ "$ref": "./v0/plugin.schema.json"
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/plugins.schema.json",
4
+ "$ref": "./v0/plugins.schema.json"
5
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/v0/common.schema.json",
4
+ "$version": "0.2.0",
5
+ "title": "Kitfly Common Schema Definitions",
6
+ "description": "Shared $defs used across Kitfly schemas (v0).",
7
+ "$defs": {
8
+ "kitflyMode": {
9
+ "type": "string",
10
+ "description": "Kitfly rendering mode.",
11
+ "enum": [
12
+ "docs",
13
+ "slides"
14
+ ],
15
+ "examples": [
16
+ "docs",
17
+ "slides"
18
+ ]
19
+ },
20
+ "kitflyModesAllowlist": {
21
+ "type": "array",
22
+ "description": "Optional allowlist for where a plugin may run. If omitted, plugin is allowed in all modes. If present and empty, plugin is blocked in all modes.",
23
+ "items": {
24
+ "$ref": "#/$defs/kitflyMode"
25
+ },
26
+ "uniqueItems": true
27
+ },
28
+ "semver": {
29
+ "type": "string",
30
+ "description": "Semantic version string (semver).",
31
+ "pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
32
+ "examples": [
33
+ "1.0.0",
34
+ "1.2.3-beta.1"
35
+ ]
36
+ },
37
+ "semverRange": {
38
+ "type": "string",
39
+ "description": "Version compatibility range (space-separated comparators). Example: \">=0.2.0 <1.0.0\"",
40
+ "minLength": 1,
41
+ "maxLength": 80,
42
+ "pattern": "^\\s*(?:[<>=~^]*\\s*)?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:\\s+(?:[<>=~^]*\\s*)?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*))*\\s*$",
43
+ "examples": [
44
+ ">=0.2.0 <1.0.0"
45
+ ]
46
+ },
47
+ "sriIntegrity": {
48
+ "type": "string",
49
+ "description": "Subresource Integrity value (sha256/sha384/sha512 base64).",
50
+ "pattern": "^(sha256|sha384|sha512)-[A-Za-z0-9+/=]+$",
51
+ "examples": [
52
+ "sha384-abcDEF123+/="
53
+ ]
54
+ },
55
+ "checksumSha256": {
56
+ "type": "string",
57
+ "description": "SHA256 checksum (hex) prefixed with sha256:",
58
+ "pattern": "^sha256:[0-9a-fA-F]{64}$",
59
+ "examples": [
60
+ "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
61
+ ]
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,225 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/v0/plugin-registry.schema.json",
4
+ "$version": "0.2.0",
5
+ "title": "Plugin Registry",
6
+ "description": "Schema for kitfly canonical plugin registry (registry/plugins.yaml).",
7
+ "type": "object",
8
+ "required": [
9
+ "version",
10
+ "updated",
11
+ "baseUrl",
12
+ "plugins"
13
+ ],
14
+ "properties": {
15
+ "$schema": {
16
+ "type": "string",
17
+ "description": "Schema reference for validation"
18
+ },
19
+ "version": {
20
+ "type": "integer",
21
+ "description": "Registry schema version",
22
+ "minimum": 1,
23
+ "examples": [
24
+ 1
25
+ ]
26
+ },
27
+ "updated": {
28
+ "type": "string",
29
+ "description": "Last update date (YYYY-MM-DD)",
30
+ "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
31
+ "examples": [
32
+ "2026-02-04"
33
+ ]
34
+ },
35
+ "baseUrl": {
36
+ "type": "string",
37
+ "description": "Base URL used for templating plugin asset URLs via ${baseUrl}",
38
+ "minLength": 0,
39
+ "maxLength": 200,
40
+ "examples": [
41
+ "https://github.com/3leaps/kitfly/releases/download"
42
+ ]
43
+ },
44
+ "plugins": {
45
+ "type": "object",
46
+ "description": "Plugin entries keyed by plugin id",
47
+ "minProperties": 0,
48
+ "patternProperties": {
49
+ "^[a-z][a-z0-9-]*$": {
50
+ "$ref": "#/$defs/registryPlugin"
51
+ }
52
+ },
53
+ "additionalProperties": false
54
+ }
55
+ },
56
+ "additionalProperties": false,
57
+ "$defs": {
58
+ "registryAssets": {
59
+ "type": "object",
60
+ "description": "Plugin asset URLs. Strings may include ${baseUrl} templating.",
61
+ "required": [
62
+ "assetSha256"
63
+ ],
64
+ "properties": {
65
+ "js": {
66
+ "type": "string",
67
+ "description": "JavaScript bundle URL (may include ${baseUrl})",
68
+ "minLength": 1
69
+ },
70
+ "css": {
71
+ "type": "string",
72
+ "description": "CSS bundle URL (may include ${baseUrl})",
73
+ "minLength": 1
74
+ },
75
+ "assetSha256": {
76
+ "type": "object",
77
+ "description": "Per-asset SHA256 checksums (sha256:<hex>) keyed by asset type.",
78
+ "properties": {
79
+ "js": {
80
+ "$ref": "./common.schema.json#/$defs/checksumSha256"
81
+ },
82
+ "css": {
83
+ "$ref": "./common.schema.json#/$defs/checksumSha256"
84
+ }
85
+ },
86
+ "additionalProperties": false
87
+ }
88
+ },
89
+ "additionalProperties": false,
90
+ "allOf": [
91
+ {
92
+ "anyOf": [
93
+ {
94
+ "required": [
95
+ "js"
96
+ ]
97
+ },
98
+ {
99
+ "required": [
100
+ "css"
101
+ ]
102
+ }
103
+ ]
104
+ },
105
+ {
106
+ "if": {
107
+ "required": [
108
+ "js"
109
+ ]
110
+ },
111
+ "then": {
112
+ "properties": {
113
+ "assetSha256": {
114
+ "required": [
115
+ "js"
116
+ ]
117
+ }
118
+ }
119
+ }
120
+ },
121
+ {
122
+ "if": {
123
+ "required": [
124
+ "css"
125
+ ]
126
+ },
127
+ "then": {
128
+ "properties": {
129
+ "assetSha256": {
130
+ "required": [
131
+ "css"
132
+ ]
133
+ }
134
+ }
135
+ }
136
+ }
137
+ ]
138
+ },
139
+ "registryPlugin": {
140
+ "type": "object",
141
+ "required": [
142
+ "name",
143
+ "description",
144
+ "version",
145
+ "contract",
146
+ "kitfly",
147
+ "license",
148
+ "verified",
149
+ "assets"
150
+ ],
151
+ "properties": {
152
+ "name": {
153
+ "type": "string",
154
+ "description": "Human-readable plugin name",
155
+ "minLength": 1,
156
+ "maxLength": 80
157
+ },
158
+ "description": {
159
+ "type": "string",
160
+ "description": "Short description used in listing/help output",
161
+ "minLength": 1,
162
+ "maxLength": 160
163
+ },
164
+ "version": {
165
+ "$ref": "./common.schema.json#/$defs/semver"
166
+ },
167
+ "contract": {
168
+ "type": "string",
169
+ "description": "Plugin contract version this plugin implements (stringified integer)",
170
+ "pattern": "^[0-9]+$",
171
+ "examples": [
172
+ "1"
173
+ ]
174
+ },
175
+ "kitfly": {
176
+ "$ref": "./common.schema.json#/$defs/semverRange"
177
+ },
178
+ "license": {
179
+ "type": "string",
180
+ "description": "License identifier (typically SPDX, e.g. MIT)",
181
+ "minLength": 1,
182
+ "maxLength": 50
183
+ },
184
+ "verified": {
185
+ "type": "boolean",
186
+ "description": "If true, plugin is first-party / reviewed (canonical registry)"
187
+ },
188
+ "modes": {
189
+ "$ref": "./common.schema.json#/$defs/kitflyModesAllowlist"
190
+ },
191
+ "assets": {
192
+ "$ref": "#/$defs/registryAssets"
193
+ }
194
+ },
195
+ "additionalProperties": false
196
+ }
197
+ },
198
+ "examples": [
199
+ {
200
+ "$schema": "./schemas/v0/plugin-registry.schema.json",
201
+ "version": 1,
202
+ "updated": "2026-02-04",
203
+ "baseUrl": "https://github.com/3leaps/kitfly/releases/download",
204
+ "plugins": {
205
+ "latex": {
206
+ "name": "LaTeX/KaTeX Math Rendering",
207
+ "description": "Render LaTeX math expressions with KaTeX",
208
+ "version": "1.0.0",
209
+ "contract": "1",
210
+ "kitfly": ">=0.2.0 <1.0.0",
211
+ "license": "MIT",
212
+ "verified": true,
213
+ "assets": {
214
+ "js": "${baseUrl}/v1.0.0/latex.js",
215
+ "css": "${baseUrl}/v1.0.0/latex.css",
216
+ "assetSha256": {
217
+ "js": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
218
+ "css": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
219
+ }
220
+ }
221
+ }
222
+ }
223
+ }
224
+ ]
225
+ }
@@ -0,0 +1,175 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/v0/plugin.schema.json",
4
+ "$version": "0.2.0",
5
+ "title": "Plugin Manifest",
6
+ "description": "Contract for kitfly plugins (plugin.yaml). Plugins are atomic (no plugin-to-plugin dependencies).",
7
+ "type": "object",
8
+ "required": [
9
+ "name",
10
+ "version",
11
+ "contract",
12
+ "description",
13
+ "license",
14
+ "kitfly",
15
+ "main"
16
+ ],
17
+ "properties": {
18
+ "$schema": {
19
+ "type": "string",
20
+ "description": "Schema reference for validation"
21
+ },
22
+ "name": {
23
+ "type": "string",
24
+ "description": "Plugin identifier (used as registry key and folder name)",
25
+ "pattern": "^[a-z][a-z0-9-]*$",
26
+ "minLength": 1,
27
+ "maxLength": 40,
28
+ "examples": [
29
+ "latex",
30
+ "callouts",
31
+ "slides-widgets"
32
+ ]
33
+ },
34
+ "version": {
35
+ "$ref": "./common.schema.json#/$defs/semver"
36
+ },
37
+ "contract": {
38
+ "type": "string",
39
+ "description": "Plugin contract version this plugin implements (stringified integer)",
40
+ "pattern": "^[0-9]+$",
41
+ "examples": [
42
+ "1"
43
+ ]
44
+ },
45
+ "description": {
46
+ "type": "string",
47
+ "description": "Short human-readable description of the plugin",
48
+ "minLength": 1,
49
+ "maxLength": 140
50
+ },
51
+ "license": {
52
+ "type": "string",
53
+ "description": "License identifier (typically SPDX, e.g. MIT)",
54
+ "minLength": 1,
55
+ "maxLength": 50,
56
+ "examples": [
57
+ "MIT"
58
+ ]
59
+ },
60
+ "kitfly": {
61
+ "$ref": "./common.schema.json#/$defs/semverRange"
62
+ },
63
+ "dependencies": {
64
+ "type": "object",
65
+ "description": "External resources required by the plugin (plugin-to-plugin dependencies are not allowed)",
66
+ "properties": {
67
+ "cdn": {
68
+ "type": "array",
69
+ "description": "External CDN resources (SRI integrity is required for every entry)",
70
+ "items": {
71
+ "$ref": "#/$defs/cdnResource"
72
+ }
73
+ }
74
+ },
75
+ "additionalProperties": false
76
+ },
77
+ "hooks": {
78
+ "type": "object",
79
+ "description": "Hook declarations (unknown hooks are invalid)",
80
+ "properties": {
81
+ "marked-extension": {
82
+ "type": "boolean",
83
+ "description": "Plugin provides a marked extension"
84
+ },
85
+ "template-head": {
86
+ "type": "boolean",
87
+ "description": "Plugin injects content into <head>"
88
+ },
89
+ "template-body-end": {
90
+ "type": "boolean",
91
+ "description": "Plugin injects content before </body>"
92
+ }
93
+ },
94
+ "additionalProperties": false
95
+ },
96
+ "main": {
97
+ "type": "string",
98
+ "description": "Plugin entry point (relative path within the plugin package)",
99
+ "pattern": "^[^\\0]+\\.(ts|js)$",
100
+ "examples": [
101
+ "index.ts"
102
+ ]
103
+ },
104
+ "test-docs": {
105
+ "type": "array",
106
+ "description": "Glob patterns for validation corpus docs used in kitfly plugin testing",
107
+ "items": {
108
+ "type": "string",
109
+ "minLength": 1
110
+ },
111
+ "minItems": 1,
112
+ "examples": [
113
+ [
114
+ "test-docs/latex-samples/*.md"
115
+ ]
116
+ ]
117
+ },
118
+ "modes": {
119
+ "$ref": "./common.schema.json#/$defs/kitflyModesAllowlist"
120
+ }
121
+ },
122
+ "additionalProperties": false,
123
+ "$defs": {
124
+ "cdnResource": {
125
+ "type": "object",
126
+ "required": [
127
+ "url",
128
+ "integrity"
129
+ ],
130
+ "properties": {
131
+ "url": {
132
+ "type": "string",
133
+ "description": "CDN URL (HTTPS required)",
134
+ "pattern": "^https://.+",
135
+ "minLength": 9
136
+ },
137
+ "integrity": {
138
+ "$ref": "./common.schema.json#/$defs/sriIntegrity"
139
+ }
140
+ },
141
+ "additionalProperties": false
142
+ }
143
+ },
144
+ "examples": [
145
+ {
146
+ "$schema": "./schemas/v0/plugin.schema.json",
147
+ "name": "latex",
148
+ "version": "1.0.0",
149
+ "contract": "1",
150
+ "description": "LaTeX/KaTeX math rendering",
151
+ "license": "MIT",
152
+ "kitfly": ">=0.2.0 <1.0.0",
153
+ "dependencies": {
154
+ "cdn": [
155
+ {
156
+ "url": "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js",
157
+ "integrity": "sha384-abcDEF123+/="
158
+ },
159
+ {
160
+ "url": "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css",
161
+ "integrity": "sha384-abcDEF123+/="
162
+ }
163
+ ]
164
+ },
165
+ "hooks": {
166
+ "marked-extension": true,
167
+ "template-head": true
168
+ },
169
+ "main": "index.ts",
170
+ "test-docs": [
171
+ "test-docs/latex-samples/*.md"
172
+ ]
173
+ }
174
+ ]
175
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://kitfly.app/schemas/v0/plugins.schema.json",
4
+ "$version": "0.2.0",
5
+ "title": "Plugin Configuration",
6
+ "description": "Configuration for enabling Kitfly plugins (kitfly.plugins.yaml). Canonical plugins are specified as pinned strings (name@x.y.z). Third-party plugins are objects and require explicit opt-in at build/dev time.",
7
+ "type": "object",
8
+ "required": [
9
+ "plugins"
10
+ ],
11
+ "properties": {
12
+ "$schema": {
13
+ "type": "string",
14
+ "description": "Schema reference for validation"
15
+ },
16
+ "plugins": {
17
+ "type": "array",
18
+ "minItems": 0,
19
+ "items": {
20
+ "oneOf": [
21
+ {
22
+ "type": "string",
23
+ "description": "Canonical plugin reference with strict version pinning (name@x.y.z).",
24
+ "pattern": "^[a-z][a-z0-9-]*@(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$",
25
+ "examples": [
26
+ "latex@1.0.0",
27
+ "slides-widgets@0.2.0-beta.1"
28
+ ]
29
+ },
30
+ {
31
+ "type": "object",
32
+ "description": "Third-party plugin reference (requires --allow-untrusted).",
33
+ "required": [
34
+ "name",
35
+ "source",
36
+ "sha256"
37
+ ],
38
+ "properties": {
39
+ "name": {
40
+ "type": "string",
41
+ "description": "Plugin identifier (used for caching and logging).",
42
+ "pattern": "^[a-z][a-z0-9-]*$",
43
+ "minLength": 1,
44
+ "maxLength": 40
45
+ },
46
+ "source": {
47
+ "type": "string",
48
+ "description": "Plugin source locator (e.g. github:owner/repo@ref or https://... ).",
49
+ "minLength": 1,
50
+ "maxLength": 200
51
+ },
52
+ "sha256": {
53
+ "type": "string",
54
+ "description": "Expected SHA256 checksum (hex) for the fetched plugin bundle.",
55
+ "pattern": "^[0-9a-fA-F]{64}$"
56
+ }
57
+ },
58
+ "additionalProperties": false
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ },
64
+ "additionalProperties": false,
65
+ "examples": [
66
+ {
67
+ "$schema": "./schemas/v0/plugins.schema.json",
68
+ "plugins": [
69
+ "latex@1.0.0",
70
+ "callouts@1.2.0"
71
+ ]
72
+ },
73
+ {
74
+ "$schema": "./schemas/v0/plugins.schema.json",
75
+ "plugins": [
76
+ {
77
+ "name": "custom-plugin",
78
+ "source": "github:someuser/their-plugin@v1.0.0",
79
+ "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
80
+ }
81
+ ]
82
+ }
83
+ ]
84
+ }