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
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
"title": "Site Configuration",
|
|
6
6
|
"description": "Configuration for Kitfly static site generator",
|
|
7
7
|
"type": "object",
|
|
8
|
-
"required": [
|
|
8
|
+
"required": [
|
|
9
|
+
"title",
|
|
10
|
+
"brand",
|
|
11
|
+
"sections"
|
|
12
|
+
],
|
|
9
13
|
"properties": {
|
|
10
14
|
"schemaVersion": {
|
|
11
15
|
"type": "string",
|
|
@@ -25,8 +29,35 @@
|
|
|
25
29
|
},
|
|
26
30
|
"version": {
|
|
27
31
|
"type": "string",
|
|
28
|
-
"description": "Site version
|
|
29
|
-
"examples": [
|
|
32
|
+
"description": "Site version shown in footer provenance. Supports literal values, auto (read VERSION in site root), or file:<path> (read from relative file).",
|
|
33
|
+
"examples": [
|
|
34
|
+
"1.0.0",
|
|
35
|
+
"2024.03",
|
|
36
|
+
"draft",
|
|
37
|
+
"auto",
|
|
38
|
+
"file:VERSION",
|
|
39
|
+
"file:./meta/site version.txt"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"mode": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"description": "Site layout mode",
|
|
45
|
+
"enum": [
|
|
46
|
+
"docs",
|
|
47
|
+
"slides"
|
|
48
|
+
],
|
|
49
|
+
"default": "docs"
|
|
50
|
+
},
|
|
51
|
+
"aspect": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Slide aspect ratio (only applies when mode is slides)",
|
|
54
|
+
"enum": [
|
|
55
|
+
"16/9",
|
|
56
|
+
"4/3",
|
|
57
|
+
"3/2",
|
|
58
|
+
"16/10"
|
|
59
|
+
],
|
|
60
|
+
"default": "16/9"
|
|
30
61
|
},
|
|
31
62
|
"home": {
|
|
32
63
|
"type": "string",
|
|
@@ -35,7 +66,10 @@
|
|
|
35
66
|
"brand": {
|
|
36
67
|
"type": "object",
|
|
37
68
|
"description": "Brand configuration for logo and links",
|
|
38
|
-
"required": [
|
|
69
|
+
"required": [
|
|
70
|
+
"name",
|
|
71
|
+
"url"
|
|
72
|
+
],
|
|
39
73
|
"properties": {
|
|
40
74
|
"name": {
|
|
41
75
|
"type": "string",
|
|
@@ -64,7 +98,10 @@
|
|
|
64
98
|
"logoType": {
|
|
65
99
|
"type": "string",
|
|
66
100
|
"description": "Logo type: icon (square) or wordmark (wide)",
|
|
67
|
-
"enum": [
|
|
101
|
+
"enum": [
|
|
102
|
+
"icon",
|
|
103
|
+
"wordmark"
|
|
104
|
+
],
|
|
68
105
|
"default": "icon"
|
|
69
106
|
}
|
|
70
107
|
},
|
|
@@ -76,7 +113,10 @@
|
|
|
76
113
|
"minItems": 1,
|
|
77
114
|
"items": {
|
|
78
115
|
"type": "object",
|
|
79
|
-
"required": [
|
|
116
|
+
"required": [
|
|
117
|
+
"name",
|
|
118
|
+
"path"
|
|
119
|
+
],
|
|
80
120
|
"properties": {
|
|
81
121
|
"name": {
|
|
82
122
|
"type": "string",
|
|
@@ -90,7 +130,9 @@
|
|
|
90
130
|
"files": {
|
|
91
131
|
"type": "array",
|
|
92
132
|
"description": "Specific files to include (for root-level sections)",
|
|
93
|
-
"items": {
|
|
133
|
+
"items": {
|
|
134
|
+
"type": "string"
|
|
135
|
+
}
|
|
94
136
|
},
|
|
95
137
|
"maxDepth": {
|
|
96
138
|
"type": "integer",
|
|
@@ -102,7 +144,9 @@
|
|
|
102
144
|
"exclude": {
|
|
103
145
|
"type": "array",
|
|
104
146
|
"description": "Glob patterns to exclude from auto-discovery",
|
|
105
|
-
"items": {
|
|
147
|
+
"items": {
|
|
148
|
+
"type": "string"
|
|
149
|
+
}
|
|
106
150
|
}
|
|
107
151
|
},
|
|
108
152
|
"additionalProperties": false
|
|
@@ -126,7 +170,10 @@
|
|
|
126
170
|
"maxItems": 10,
|
|
127
171
|
"items": {
|
|
128
172
|
"type": "object",
|
|
129
|
-
"required": [
|
|
173
|
+
"required": [
|
|
174
|
+
"text",
|
|
175
|
+
"url"
|
|
176
|
+
],
|
|
130
177
|
"properties": {
|
|
131
178
|
"text": {
|
|
132
179
|
"type": "string",
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
"type": "string",
|
|
15
15
|
"description": "Theme name for identification",
|
|
16
16
|
"maxLength": 50,
|
|
17
|
-
"examples": [
|
|
17
|
+
"examples": [
|
|
18
|
+
"Kitfly Default",
|
|
19
|
+
"GitHub",
|
|
20
|
+
"Paper"
|
|
21
|
+
]
|
|
18
22
|
},
|
|
19
23
|
"layout": {
|
|
20
24
|
"type": "object",
|
|
@@ -25,7 +29,11 @@
|
|
|
25
29
|
"description": "Sidebar width (CSS length value)",
|
|
26
30
|
"pattern": "^[0-9]+(px|rem|em|%)$",
|
|
27
31
|
"default": "280px",
|
|
28
|
-
"examples": [
|
|
32
|
+
"examples": [
|
|
33
|
+
"280px",
|
|
34
|
+
"320px",
|
|
35
|
+
"18rem"
|
|
36
|
+
]
|
|
29
37
|
}
|
|
30
38
|
},
|
|
31
39
|
"additionalProperties": false
|
|
@@ -33,10 +41,17 @@
|
|
|
33
41
|
"colors": {
|
|
34
42
|
"type": "object",
|
|
35
43
|
"description": "Color palettes for light and dark modes",
|
|
36
|
-
"required": [
|
|
44
|
+
"required": [
|
|
45
|
+
"light",
|
|
46
|
+
"dark"
|
|
47
|
+
],
|
|
37
48
|
"properties": {
|
|
38
|
-
"light": {
|
|
39
|
-
|
|
49
|
+
"light": {
|
|
50
|
+
"$ref": "#/$defs/colorPalette"
|
|
51
|
+
},
|
|
52
|
+
"dark": {
|
|
53
|
+
"$ref": "#/$defs/colorPalette"
|
|
54
|
+
}
|
|
40
55
|
},
|
|
41
56
|
"additionalProperties": false
|
|
42
57
|
},
|
|
@@ -47,13 +62,25 @@
|
|
|
47
62
|
"light": {
|
|
48
63
|
"type": "string",
|
|
49
64
|
"description": "Prism theme for light mode",
|
|
50
|
-
"enum": [
|
|
65
|
+
"enum": [
|
|
66
|
+
"default",
|
|
67
|
+
"coy",
|
|
68
|
+
"solarized-light",
|
|
69
|
+
"tomorrow"
|
|
70
|
+
],
|
|
51
71
|
"default": "default"
|
|
52
72
|
},
|
|
53
73
|
"dark": {
|
|
54
74
|
"type": "string",
|
|
55
75
|
"description": "Prism theme for dark mode",
|
|
56
|
-
"enum": [
|
|
76
|
+
"enum": [
|
|
77
|
+
"okaidia",
|
|
78
|
+
"tomorrow-night",
|
|
79
|
+
"nord",
|
|
80
|
+
"dracula",
|
|
81
|
+
"one-dark",
|
|
82
|
+
"synthwave84"
|
|
83
|
+
],
|
|
57
84
|
"default": "okaidia"
|
|
58
85
|
}
|
|
59
86
|
},
|
|
@@ -66,19 +93,31 @@
|
|
|
66
93
|
"body": {
|
|
67
94
|
"type": "string",
|
|
68
95
|
"description": "Font preset for body text",
|
|
69
|
-
"enum": [
|
|
96
|
+
"enum": [
|
|
97
|
+
"system",
|
|
98
|
+
"mono",
|
|
99
|
+
"serif",
|
|
100
|
+
"readable"
|
|
101
|
+
],
|
|
70
102
|
"default": "system"
|
|
71
103
|
},
|
|
72
104
|
"headings": {
|
|
73
105
|
"type": "string",
|
|
74
106
|
"description": "Font preset for headings",
|
|
75
|
-
"enum": [
|
|
107
|
+
"enum": [
|
|
108
|
+
"system",
|
|
109
|
+
"mono",
|
|
110
|
+
"serif",
|
|
111
|
+
"readable"
|
|
112
|
+
],
|
|
76
113
|
"default": "system"
|
|
77
114
|
},
|
|
78
115
|
"code": {
|
|
79
116
|
"type": "string",
|
|
80
117
|
"description": "Font preset for code blocks",
|
|
81
|
-
"enum": [
|
|
118
|
+
"enum": [
|
|
119
|
+
"mono"
|
|
120
|
+
],
|
|
82
121
|
"default": "mono"
|
|
83
122
|
},
|
|
84
123
|
"baseSize": {
|
|
@@ -86,12 +125,22 @@
|
|
|
86
125
|
"description": "Base font size",
|
|
87
126
|
"pattern": "^[0-9]+(px|rem|em)$",
|
|
88
127
|
"default": "16px",
|
|
89
|
-
"examples": [
|
|
128
|
+
"examples": [
|
|
129
|
+
"16px",
|
|
130
|
+
"17px",
|
|
131
|
+
"1rem"
|
|
132
|
+
]
|
|
90
133
|
},
|
|
91
134
|
"scale": {
|
|
92
135
|
"type": "string",
|
|
93
136
|
"description": "Type scale ratio for heading sizes",
|
|
94
|
-
"enum": [
|
|
137
|
+
"enum": [
|
|
138
|
+
"1.125",
|
|
139
|
+
"1.2",
|
|
140
|
+
"1.25",
|
|
141
|
+
"1.333",
|
|
142
|
+
"1.5"
|
|
143
|
+
],
|
|
95
144
|
"default": "1.25"
|
|
96
145
|
}
|
|
97
146
|
},
|
|
@@ -103,61 +152,95 @@
|
|
|
103
152
|
"colorPalette": {
|
|
104
153
|
"type": "object",
|
|
105
154
|
"description": "Color palette for a single mode (light or dark)",
|
|
106
|
-
"required": [
|
|
155
|
+
"required": [
|
|
156
|
+
"background",
|
|
157
|
+
"surface",
|
|
158
|
+
"text",
|
|
159
|
+
"heading",
|
|
160
|
+
"primary",
|
|
161
|
+
"border"
|
|
162
|
+
],
|
|
107
163
|
"properties": {
|
|
108
164
|
"background": {
|
|
109
165
|
"type": "string",
|
|
110
166
|
"description": "Page background color",
|
|
111
167
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
112
|
-
"examples": [
|
|
168
|
+
"examples": [
|
|
169
|
+
"#ffffff",
|
|
170
|
+
"#0f1e2b"
|
|
171
|
+
]
|
|
113
172
|
},
|
|
114
173
|
"surface": {
|
|
115
174
|
"type": "string",
|
|
116
175
|
"description": "Elevated surface color (cards, code blocks)",
|
|
117
176
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
118
|
-
"examples": [
|
|
177
|
+
"examples": [
|
|
178
|
+
"#f5f7f8",
|
|
179
|
+
"#152F46"
|
|
180
|
+
]
|
|
119
181
|
},
|
|
120
182
|
"text": {
|
|
121
183
|
"type": "string",
|
|
122
184
|
"description": "Primary body text color",
|
|
123
185
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
124
|
-
"examples": [
|
|
186
|
+
"examples": [
|
|
187
|
+
"#374151",
|
|
188
|
+
"#e5e7eb"
|
|
189
|
+
]
|
|
125
190
|
},
|
|
126
191
|
"textMuted": {
|
|
127
192
|
"type": "string",
|
|
128
193
|
"description": "Secondary/muted text color",
|
|
129
194
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
130
|
-
"examples": [
|
|
195
|
+
"examples": [
|
|
196
|
+
"#6b7280",
|
|
197
|
+
"#9ca3af"
|
|
198
|
+
]
|
|
131
199
|
},
|
|
132
200
|
"heading": {
|
|
133
201
|
"type": "string",
|
|
134
202
|
"description": "Heading text color",
|
|
135
203
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
136
|
-
"examples": [
|
|
204
|
+
"examples": [
|
|
205
|
+
"#152F46",
|
|
206
|
+
"#f9fafb"
|
|
207
|
+
]
|
|
137
208
|
},
|
|
138
209
|
"primary": {
|
|
139
210
|
"type": "string",
|
|
140
211
|
"description": "Primary accent color (links, buttons)",
|
|
141
212
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
142
|
-
"examples": [
|
|
213
|
+
"examples": [
|
|
214
|
+
"#007182",
|
|
215
|
+
"#4db8c7"
|
|
216
|
+
]
|
|
143
217
|
},
|
|
144
218
|
"primaryHover": {
|
|
145
219
|
"type": "string",
|
|
146
220
|
"description": "Primary color hover state",
|
|
147
221
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
148
|
-
"examples": [
|
|
222
|
+
"examples": [
|
|
223
|
+
"#005c6a",
|
|
224
|
+
"#6cc9d6"
|
|
225
|
+
]
|
|
149
226
|
},
|
|
150
227
|
"accent": {
|
|
151
228
|
"type": "string",
|
|
152
229
|
"description": "Secondary accent color (highlights, CTAs)",
|
|
153
230
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
154
|
-
"examples": [
|
|
231
|
+
"examples": [
|
|
232
|
+
"#D17059",
|
|
233
|
+
"#e8947f"
|
|
234
|
+
]
|
|
155
235
|
},
|
|
156
236
|
"border": {
|
|
157
237
|
"type": "string",
|
|
158
238
|
"description": "Border and divider color",
|
|
159
239
|
"pattern": "^#[0-9a-fA-F]{6}$",
|
|
160
|
-
"examples": [
|
|
240
|
+
"examples": [
|
|
241
|
+
"#e5e7eb",
|
|
242
|
+
"#374151"
|
|
243
|
+
]
|
|
161
244
|
}
|
|
162
245
|
},
|
|
163
246
|
"additionalProperties": false
|
package/scripts/build.ts
CHANGED
|
@@ -16,15 +16,18 @@ import { copyFile, cp, mkdir, readdir, readFile, stat, writeFile } from "node:fs
|
|
|
16
16
|
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
17
17
|
import { marked, Renderer } from "marked";
|
|
18
18
|
import { ENGINE_ASSETS_DIR } from "../src/engine.ts";
|
|
19
|
+
import { loadPluginInjections, type PluginInjections } from "../src/plugin-loader.ts";
|
|
19
20
|
import {
|
|
20
21
|
buildBreadcrumbsStatic,
|
|
21
22
|
buildFooter,
|
|
22
23
|
buildNavStatic,
|
|
23
24
|
buildPageMeta,
|
|
25
|
+
buildSlideNav,
|
|
24
26
|
buildToc,
|
|
25
27
|
type ContentFile,
|
|
26
|
-
// Navigation/template building
|
|
27
28
|
collectFiles,
|
|
29
|
+
// Navigation/template building
|
|
30
|
+
collectSlides,
|
|
28
31
|
envBool,
|
|
29
32
|
// Config helpers
|
|
30
33
|
envString,
|
|
@@ -39,12 +42,15 @@ import {
|
|
|
39
42
|
type Provenance,
|
|
40
43
|
// Markdown utilities
|
|
41
44
|
parseFrontmatter,
|
|
45
|
+
parseYaml,
|
|
42
46
|
resolveStylesPath,
|
|
43
47
|
resolveTemplatePath,
|
|
48
|
+
rewriteRelativeAssetUrls,
|
|
44
49
|
// Types
|
|
45
50
|
type SiteConfig,
|
|
46
51
|
slugify,
|
|
47
52
|
validatePath,
|
|
53
|
+
validateSlidesVisualsFences,
|
|
48
54
|
} from "../src/shared.ts";
|
|
49
55
|
import { generateThemeCSS, getPrismUrls, loadTheme, type Theme } from "../src/theme.ts";
|
|
50
56
|
|
|
@@ -161,6 +167,7 @@ async function renderFile(
|
|
|
161
167
|
provenance: Provenance,
|
|
162
168
|
config: SiteConfig,
|
|
163
169
|
theme: Theme,
|
|
170
|
+
plugins: PluginInjections,
|
|
164
171
|
): Promise<string> {
|
|
165
172
|
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
166
173
|
const content = await readFile(filePath, "utf-8");
|
|
@@ -198,12 +205,15 @@ async function renderFile(
|
|
|
198
205
|
const themeCSS = generateThemeCSS(theme);
|
|
199
206
|
const prismUrls = getPrismUrls(theme);
|
|
200
207
|
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
208
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
201
209
|
|
|
202
210
|
return template
|
|
211
|
+
.replace("{{BODY_CLASS}}", "mode-docs")
|
|
203
212
|
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
204
213
|
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
205
214
|
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
206
215
|
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
216
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
207
217
|
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
208
218
|
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
209
219
|
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
@@ -218,6 +228,8 @@ async function renderFile(
|
|
|
218
228
|
.replace("{{TOC}}", toc)
|
|
219
229
|
.replace("{{FOOTER}}", footer)
|
|
220
230
|
.replace("{{THEME_CSS}}", themeCSS)
|
|
231
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
232
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
221
233
|
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
222
234
|
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
223
235
|
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
@@ -229,6 +241,7 @@ function renderGettingStarted(
|
|
|
229
241
|
provenance: Provenance,
|
|
230
242
|
config: SiteConfig,
|
|
231
243
|
theme: Theme,
|
|
244
|
+
plugins: PluginInjections,
|
|
232
245
|
): string {
|
|
233
246
|
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
234
247
|
const htmlContent = `
|
|
@@ -259,12 +272,15 @@ sections:
|
|
|
259
272
|
const prismUrls = getPrismUrls(theme);
|
|
260
273
|
const pathPrefix = "./";
|
|
261
274
|
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
275
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
262
276
|
|
|
263
277
|
return template
|
|
278
|
+
.replace("{{BODY_CLASS}}", "mode-docs")
|
|
264
279
|
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
265
280
|
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
266
281
|
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
267
282
|
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
283
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
268
284
|
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
269
285
|
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
270
286
|
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
@@ -279,6 +295,114 @@ sections:
|
|
|
279
295
|
.replace("{{TOC}}", "")
|
|
280
296
|
.replace("{{FOOTER}}", buildFooter(provenance, config))
|
|
281
297
|
.replace("{{THEME_CSS}}", themeCSS)
|
|
298
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
299
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
300
|
+
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
301
|
+
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
302
|
+
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async function renderSlidesIndex(
|
|
306
|
+
template: string,
|
|
307
|
+
files: ContentFile[],
|
|
308
|
+
provenance: Provenance,
|
|
309
|
+
config: SiteConfig,
|
|
310
|
+
theme: Theme,
|
|
311
|
+
plugins: PluginInjections,
|
|
312
|
+
): Promise<string> {
|
|
313
|
+
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
314
|
+
const pathPrefix = "./";
|
|
315
|
+
const slides = await collectSlides(files);
|
|
316
|
+
let validateFences = false;
|
|
317
|
+
try {
|
|
318
|
+
const raw = await readFile(join(ROOT, "kitfly.plugins.yaml"), "utf-8");
|
|
319
|
+
const parsed = parseYaml(raw) as unknown as Record<string, unknown>;
|
|
320
|
+
const enabled = Array.isArray(parsed?.plugins) ? (parsed.plugins as unknown[]) : [];
|
|
321
|
+
validateFences = enabled.some((p) => typeof p === "string" && p.startsWith("slides-visuals@"));
|
|
322
|
+
} catch {
|
|
323
|
+
// no config, skip
|
|
324
|
+
}
|
|
325
|
+
const renderedSlides = await Promise.all(
|
|
326
|
+
slides.map(async (slide, i) => {
|
|
327
|
+
let inner = "";
|
|
328
|
+
if (slide.kind === "markdown") {
|
|
329
|
+
if (validateFences) {
|
|
330
|
+
const diagnostics = validateSlidesVisualsFences(slide.body);
|
|
331
|
+
if (diagnostics.length) {
|
|
332
|
+
const msg = diagnostics
|
|
333
|
+
.slice(0, 12)
|
|
334
|
+
.map((d) => ` - ${slide.sourcePath}:${d.line} ${d.message}`)
|
|
335
|
+
.join("\n");
|
|
336
|
+
throw new Error(`slides-visuals fence contract violations:\n${msg}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
inner = marked.parse(slide.body) as string;
|
|
340
|
+
} else if (slide.kind === "yaml") {
|
|
341
|
+
inner = `<pre><code class="language-yaml">${escapeHtml(slide.body)}</code></pre>`;
|
|
342
|
+
} else {
|
|
343
|
+
let prettyJson = slide.body;
|
|
344
|
+
try {
|
|
345
|
+
prettyJson = JSON.stringify(JSON.parse(slide.body), null, 2);
|
|
346
|
+
} catch {
|
|
347
|
+
// Use original if not valid JSON
|
|
348
|
+
}
|
|
349
|
+
inner = `<pre><code class="language-json">${escapeHtml(prettyJson)}</code></pre>`;
|
|
350
|
+
}
|
|
351
|
+
inner = rewriteRelativeAssetUrls(inner, slide.sourceUrlPath, pathPrefix);
|
|
352
|
+
|
|
353
|
+
const activeClass = i === 0 ? " active" : "";
|
|
354
|
+
const classToken = slide.className ? ` ${slide.className}` : "";
|
|
355
|
+
return `<section id="${slide.id}" class="slide${classToken}${activeClass}" data-slide-index="${i}">${inner}</section>`;
|
|
356
|
+
}),
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
const htmlContent = `
|
|
360
|
+
<div class="slides-shell" style="--slide-aspect: ${config.aspect || "16/9"}">
|
|
361
|
+
<div class="slide-viewport">
|
|
362
|
+
<div class="slide-frame">
|
|
363
|
+
${renderedSlides.join("\n")}
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
<div class="slide-nav" aria-label="Slide navigation">
|
|
367
|
+
<button class="slide-prev" type="button" aria-label="Previous slide">Prev</button>
|
|
368
|
+
<span class="slide-counter">1 / ${slides.length}</span>
|
|
369
|
+
<button class="slide-next" type="button" aria-label="Next slide">Next</button>
|
|
370
|
+
<div class="slide-progress" role="presentation">
|
|
371
|
+
<span class="slide-progress-bar" style="width: ${(1 / slides.length) * 100}%"></span>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
</div>`;
|
|
375
|
+
|
|
376
|
+
const nav = buildSlideNav(slides, config, "slide-1");
|
|
377
|
+
const brandTarget = config.brand.external ? ' target="_blank" rel="noopener"' : "";
|
|
378
|
+
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
379
|
+
const themeCSS = generateThemeCSS(theme);
|
|
380
|
+
const prismUrls = getPrismUrls(theme);
|
|
381
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
382
|
+
|
|
383
|
+
return template
|
|
384
|
+
.replace("{{BODY_CLASS}}", "mode-slides")
|
|
385
|
+
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
386
|
+
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
387
|
+
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
388
|
+
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
389
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
390
|
+
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
391
|
+
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
392
|
+
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
393
|
+
.replace(/\{\{SITE_TITLE\}\}/g, config.title)
|
|
394
|
+
.replace("{{TITLE}}", config.title)
|
|
395
|
+
.replace("{{VERSION}}", uiVersion)
|
|
396
|
+
.replace("{{BRANCH}}", provenance.gitBranch)
|
|
397
|
+
.replace("{{BREADCRUMBS}}", "")
|
|
398
|
+
.replace("{{PAGE_META}}", "")
|
|
399
|
+
.replace("{{NAV}}", nav)
|
|
400
|
+
.replace("{{CONTENT}}", htmlContent)
|
|
401
|
+
.replace("{{TOC}}", "")
|
|
402
|
+
.replace("{{FOOTER}}", buildFooter(provenance, config))
|
|
403
|
+
.replace("{{THEME_CSS}}", themeCSS)
|
|
404
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
405
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
282
406
|
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
283
407
|
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
284
408
|
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
@@ -333,6 +457,12 @@ async function buildSite() {
|
|
|
333
457
|
// Read template
|
|
334
458
|
const template = await readFile(await resolveTemplatePath(ROOT), "utf-8");
|
|
335
459
|
|
|
460
|
+
// Load plugin injections (optional; no-op when kitfly.plugins.yaml is absent)
|
|
461
|
+
const plugins = await loadPluginInjections({
|
|
462
|
+
root: ROOT,
|
|
463
|
+
mode: config.mode === "slides" ? "slides" : "docs",
|
|
464
|
+
});
|
|
465
|
+
|
|
336
466
|
// Copy CSS
|
|
337
467
|
const css = await readFile(await resolveStylesPath(ROOT), "utf-8");
|
|
338
468
|
await writeFile(join(DIST, "styles.css"), css);
|
|
@@ -370,13 +500,23 @@ async function buildSite() {
|
|
|
370
500
|
|
|
371
501
|
if (files.length === 0) {
|
|
372
502
|
// No content - render Getting Started page
|
|
373
|
-
const html = renderGettingStarted(template, provenance, config, theme);
|
|
503
|
+
const html = renderGettingStarted(template, provenance, config, theme, plugins);
|
|
374
504
|
await writeFile(join(DIST, "index.html"), html);
|
|
375
505
|
console.log(" ✓ index.html (Getting Started)");
|
|
376
506
|
console.log(`\n\x1b[33mNo content found. Create site.yaml or content/ directory.\x1b[0m`);
|
|
377
507
|
return;
|
|
378
508
|
}
|
|
379
509
|
|
|
510
|
+
if (config.mode === "slides") {
|
|
511
|
+
const html = await renderSlidesIndex(template, files, provenance, config, theme, plugins);
|
|
512
|
+
await writeFile(join(DIST, "index.html"), html);
|
|
513
|
+
console.log(` ✓ index.html (slides mode, ${files.length} source files)`);
|
|
514
|
+
await generateAIAccessibility(DIST, files, config, provenance);
|
|
515
|
+
console.log(`\n\x1b[32mBuild complete! Output in ${OUT_DIR}/\x1b[0m`);
|
|
516
|
+
console.log(`\nTo view locally: open ${OUT_DIR}/index.html`);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
380
520
|
for (const file of files) {
|
|
381
521
|
const html = await renderFile(
|
|
382
522
|
file.path,
|
|
@@ -386,6 +526,7 @@ async function buildSite() {
|
|
|
386
526
|
provenance,
|
|
387
527
|
config,
|
|
388
528
|
theme,
|
|
529
|
+
plugins,
|
|
389
530
|
);
|
|
390
531
|
|
|
391
532
|
// Create output path
|
|
@@ -403,7 +544,16 @@ async function buildSite() {
|
|
|
403
544
|
if (homePath) {
|
|
404
545
|
try {
|
|
405
546
|
await stat(homePath);
|
|
406
|
-
const homeHtml = await renderFile(
|
|
547
|
+
const homeHtml = await renderFile(
|
|
548
|
+
homePath,
|
|
549
|
+
"",
|
|
550
|
+
template,
|
|
551
|
+
files,
|
|
552
|
+
provenance,
|
|
553
|
+
config,
|
|
554
|
+
theme,
|
|
555
|
+
plugins,
|
|
556
|
+
);
|
|
407
557
|
await writeFile(join(DIST, "index.html"), homeHtml);
|
|
408
558
|
console.log(` ✓ index.html (from ${config.home})`);
|
|
409
559
|
} catch {
|
|
@@ -417,6 +567,7 @@ async function buildSite() {
|
|
|
417
567
|
provenance,
|
|
418
568
|
config,
|
|
419
569
|
theme,
|
|
570
|
+
plugins,
|
|
420
571
|
);
|
|
421
572
|
await writeFile(join(DIST, "index.html"), indexHtml);
|
|
422
573
|
console.log(" ✓ index.html");
|
|
@@ -433,6 +584,7 @@ async function buildSite() {
|
|
|
433
584
|
provenance,
|
|
434
585
|
config,
|
|
435
586
|
theme,
|
|
587
|
+
plugins,
|
|
436
588
|
);
|
|
437
589
|
await writeFile(join(DIST, "index.html"), indexHtml);
|
|
438
590
|
console.log(" ✓ index.html");
|