kitfly 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -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/slides-authoring-guidelines.md +129 -0
- package/dist/_raw/content/reference/structure.md +166 -0
- package/dist/_raw/content/reference.md +20 -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/slides-authoring-guidelines.html +418 -0
- package/dist/content/reference/structure.html +463 -0
- package/dist/content/reference.html +335 -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 +549 -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 +390 -0
- package/plugins-dist/slides-visuals.js +689 -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 +158 -3
- package/scripts/bundle.ts +261 -95
- package/scripts/dev.ts +301 -11
- package/src/__tests__/build.test.ts +220 -1
- package/src/__tests__/bundle.test.ts +31 -0
- package/src/__tests__/cli.test.ts +14 -3
- package/src/__tests__/dev-plugin-errors.test.ts +20 -0
- 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/flow-branching-no-source.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/flow-converging-no-target.md +6 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/indented-fence.md +4 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/staircase-empty-steps.md +3 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/stat-grid-missing-fields.md +5 -0
- package/src/__tests__/fixtures/fences/slides-visuals/invalid/timeline-horizontal-no-events.md +2 -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/flow-branching-no-split.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-branching.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging-no-merge.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/flow-converging.md +8 -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/staircase-down.md +7 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/staircase.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/stat-grid.md +8 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-horizontal.md +9 -0
- package/src/__tests__/fixtures/fences/slides-visuals/valid/timeline-vertical.md +10 -0
- package/src/__tests__/init.test.ts +35 -0
- package/src/__tests__/plugin-loader.test.ts +221 -0
- package/src/__tests__/shared.test.ts +451 -0
- package/src/__tests__/slides-visuals-fence-contract.test.ts +28 -0
- package/src/__tests__/slides-visuals-runtime-regressions.bun.test.ts +147 -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 +650 -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
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,
|
|
@@ -32,6 +35,7 @@ import {
|
|
|
32
35
|
escapeHtml,
|
|
33
36
|
// File utilities
|
|
34
37
|
exists,
|
|
38
|
+
filterUnknownSlidesVisualsTypeDiagnostics,
|
|
35
39
|
// Provenance
|
|
36
40
|
generateProvenance,
|
|
37
41
|
// YAML/Config parsing
|
|
@@ -39,12 +43,15 @@ import {
|
|
|
39
43
|
type Provenance,
|
|
40
44
|
// Markdown utilities
|
|
41
45
|
parseFrontmatter,
|
|
46
|
+
parseYaml,
|
|
42
47
|
resolveStylesPath,
|
|
43
48
|
resolveTemplatePath,
|
|
49
|
+
rewriteRelativeAssetUrls,
|
|
44
50
|
// Types
|
|
45
51
|
type SiteConfig,
|
|
46
52
|
slugify,
|
|
47
53
|
validatePath,
|
|
54
|
+
validateSlidesVisualsFences,
|
|
48
55
|
} from "../src/shared.ts";
|
|
49
56
|
import { generateThemeCSS, getPrismUrls, loadTheme, type Theme } from "../src/theme.ts";
|
|
50
57
|
|
|
@@ -161,6 +168,7 @@ async function renderFile(
|
|
|
161
168
|
provenance: Provenance,
|
|
162
169
|
config: SiteConfig,
|
|
163
170
|
theme: Theme,
|
|
171
|
+
plugins: PluginInjections,
|
|
164
172
|
): Promise<string> {
|
|
165
173
|
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
166
174
|
const content = await readFile(filePath, "utf-8");
|
|
@@ -198,12 +206,15 @@ async function renderFile(
|
|
|
198
206
|
const themeCSS = generateThemeCSS(theme);
|
|
199
207
|
const prismUrls = getPrismUrls(theme);
|
|
200
208
|
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
209
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
201
210
|
|
|
202
211
|
return template
|
|
212
|
+
.replace("{{BODY_CLASS}}", "mode-docs")
|
|
203
213
|
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
204
214
|
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
205
215
|
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
206
216
|
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
217
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
207
218
|
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
208
219
|
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
209
220
|
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
@@ -218,6 +229,8 @@ async function renderFile(
|
|
|
218
229
|
.replace("{{TOC}}", toc)
|
|
219
230
|
.replace("{{FOOTER}}", footer)
|
|
220
231
|
.replace("{{THEME_CSS}}", themeCSS)
|
|
232
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
233
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
221
234
|
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
222
235
|
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
223
236
|
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
@@ -229,6 +242,7 @@ function renderGettingStarted(
|
|
|
229
242
|
provenance: Provenance,
|
|
230
243
|
config: SiteConfig,
|
|
231
244
|
theme: Theme,
|
|
245
|
+
plugins: PluginInjections,
|
|
232
246
|
): string {
|
|
233
247
|
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
234
248
|
const htmlContent = `
|
|
@@ -259,12 +273,15 @@ sections:
|
|
|
259
273
|
const prismUrls = getPrismUrls(theme);
|
|
260
274
|
const pathPrefix = "./";
|
|
261
275
|
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
276
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
262
277
|
|
|
263
278
|
return template
|
|
279
|
+
.replace("{{BODY_CLASS}}", "mode-docs")
|
|
264
280
|
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
265
281
|
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
266
282
|
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
267
283
|
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
284
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
268
285
|
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
269
286
|
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
270
287
|
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
@@ -279,6 +296,116 @@ sections:
|
|
|
279
296
|
.replace("{{TOC}}", "")
|
|
280
297
|
.replace("{{FOOTER}}", buildFooter(provenance, config))
|
|
281
298
|
.replace("{{THEME_CSS}}", themeCSS)
|
|
299
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
300
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
301
|
+
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
302
|
+
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
303
|
+
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async function renderSlidesIndex(
|
|
307
|
+
template: string,
|
|
308
|
+
files: ContentFile[],
|
|
309
|
+
provenance: Provenance,
|
|
310
|
+
config: SiteConfig,
|
|
311
|
+
theme: Theme,
|
|
312
|
+
plugins: PluginInjections,
|
|
313
|
+
): Promise<string> {
|
|
314
|
+
const uiVersion = provenance.version ? `v${provenance.version}` : "unversioned";
|
|
315
|
+
const pathPrefix = "./";
|
|
316
|
+
const slides = await collectSlides(files);
|
|
317
|
+
let validateFences = false;
|
|
318
|
+
try {
|
|
319
|
+
const raw = await readFile(join(ROOT, "kitfly.plugins.yaml"), "utf-8");
|
|
320
|
+
const parsed = parseYaml(raw) as unknown as Record<string, unknown>;
|
|
321
|
+
const enabled = Array.isArray(parsed?.plugins) ? (parsed.plugins as unknown[]) : [];
|
|
322
|
+
validateFences = enabled.some((p) => typeof p === "string" && p.startsWith("slides-visuals@"));
|
|
323
|
+
} catch {
|
|
324
|
+
// no config, skip
|
|
325
|
+
}
|
|
326
|
+
const renderedSlides = await Promise.all(
|
|
327
|
+
slides.map(async (slide, i) => {
|
|
328
|
+
let inner = "";
|
|
329
|
+
if (slide.kind === "markdown") {
|
|
330
|
+
if (validateFences) {
|
|
331
|
+
const diagnostics = filterUnknownSlidesVisualsTypeDiagnostics(
|
|
332
|
+
validateSlidesVisualsFences(slide.body),
|
|
333
|
+
);
|
|
334
|
+
if (diagnostics.length) {
|
|
335
|
+
const msg = diagnostics
|
|
336
|
+
.slice(0, 12)
|
|
337
|
+
.map((d) => ` - ${slide.sourcePath}:${d.line} ${d.message}`)
|
|
338
|
+
.join("\n");
|
|
339
|
+
throw new Error(`slides-visuals fence contract violations:\n${msg}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
inner = marked.parse(slide.body) as string;
|
|
343
|
+
} else if (slide.kind === "yaml") {
|
|
344
|
+
inner = `<pre><code class="language-yaml">${escapeHtml(slide.body)}</code></pre>`;
|
|
345
|
+
} else {
|
|
346
|
+
let prettyJson = slide.body;
|
|
347
|
+
try {
|
|
348
|
+
prettyJson = JSON.stringify(JSON.parse(slide.body), null, 2);
|
|
349
|
+
} catch {
|
|
350
|
+
// Use original if not valid JSON
|
|
351
|
+
}
|
|
352
|
+
inner = `<pre><code class="language-json">${escapeHtml(prettyJson)}</code></pre>`;
|
|
353
|
+
}
|
|
354
|
+
inner = rewriteRelativeAssetUrls(inner, slide.sourceUrlPath, pathPrefix);
|
|
355
|
+
|
|
356
|
+
const activeClass = i === 0 ? " active" : "";
|
|
357
|
+
const classToken = slide.className ? ` ${slide.className}` : "";
|
|
358
|
+
return `<section id="${slide.id}" class="slide${classToken}${activeClass}" data-slide-index="${i}">${inner}</section>`;
|
|
359
|
+
}),
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const htmlContent = `
|
|
363
|
+
<div class="slides-shell" style="--slide-aspect: ${config.aspect || "16/9"}">
|
|
364
|
+
<div class="slide-viewport">
|
|
365
|
+
<div class="slide-frame">
|
|
366
|
+
${renderedSlides.join("\n")}
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
<div class="slide-nav" aria-label="Slide navigation">
|
|
370
|
+
<button class="slide-prev" type="button" aria-label="Previous slide">Prev</button>
|
|
371
|
+
<span class="slide-counter">1 / ${slides.length}</span>
|
|
372
|
+
<button class="slide-next" type="button" aria-label="Next slide">Next</button>
|
|
373
|
+
<div class="slide-progress" role="presentation">
|
|
374
|
+
<span class="slide-progress-bar" style="width: ${(1 / slides.length) * 100}%"></span>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
</div>`;
|
|
378
|
+
|
|
379
|
+
const nav = buildSlideNav(slides, config, "slide-1");
|
|
380
|
+
const brandTarget = config.brand.external ? ' target="_blank" rel="noopener"' : "";
|
|
381
|
+
const logoClass = config.brand.logoType === "wordmark" ? "logo-wordmark" : "logo-icon";
|
|
382
|
+
const themeCSS = generateThemeCSS(theme);
|
|
383
|
+
const prismUrls = getPrismUrls(theme);
|
|
384
|
+
const brandInitial = escapeHtml(config.brand.name.trim().charAt(0).toUpperCase() || "K");
|
|
385
|
+
|
|
386
|
+
return template
|
|
387
|
+
.replace("{{BODY_CLASS}}", "mode-slides")
|
|
388
|
+
.replace(/\{\{PATH_PREFIX\}\}/g, pathPrefix)
|
|
389
|
+
.replace(/\{\{BRAND_URL\}\}/g, config.brand.url)
|
|
390
|
+
.replace(/\{\{BRAND_TARGET\}\}/g, brandTarget)
|
|
391
|
+
.replace(/\{\{BRAND_NAME\}\}/g, config.brand.name)
|
|
392
|
+
.replace(/\{\{BRAND_INITIAL\}\}/g, brandInitial)
|
|
393
|
+
.replace(/\{\{BRAND_LOGO\}\}/g, config.brand.logo || "assets/brand/logo.png")
|
|
394
|
+
.replace(/\{\{BRAND_FAVICON\}\}/g, config.brand.favicon || "assets/brand/favicon.png")
|
|
395
|
+
.replace(/\{\{BRAND_LOGO_CLASS\}\}/g, logoClass)
|
|
396
|
+
.replace(/\{\{SITE_TITLE\}\}/g, config.title)
|
|
397
|
+
.replace("{{TITLE}}", config.title)
|
|
398
|
+
.replace("{{VERSION}}", uiVersion)
|
|
399
|
+
.replace("{{BRANCH}}", provenance.gitBranch)
|
|
400
|
+
.replace("{{BREADCRUMBS}}", "")
|
|
401
|
+
.replace("{{PAGE_META}}", "")
|
|
402
|
+
.replace("{{NAV}}", nav)
|
|
403
|
+
.replace("{{CONTENT}}", htmlContent)
|
|
404
|
+
.replace("{{TOC}}", "")
|
|
405
|
+
.replace("{{FOOTER}}", buildFooter(provenance, config))
|
|
406
|
+
.replace("{{THEME_CSS}}", themeCSS)
|
|
407
|
+
.replace("{{PLUGIN_HEAD}}", plugins.head)
|
|
408
|
+
.replace("{{PLUGIN_BODY_END}}", plugins.bodyEnd)
|
|
282
409
|
.replace("{{PRISM_LIGHT_URL}}", prismUrls.light)
|
|
283
410
|
.replace("{{PRISM_DARK_URL}}", prismUrls.dark)
|
|
284
411
|
.replace("{{HOT_RELOAD_SCRIPT}}", "");
|
|
@@ -333,6 +460,12 @@ async function buildSite() {
|
|
|
333
460
|
// Read template
|
|
334
461
|
const template = await readFile(await resolveTemplatePath(ROOT), "utf-8");
|
|
335
462
|
|
|
463
|
+
// Load plugin injections (optional; no-op when kitfly.plugins.yaml is absent)
|
|
464
|
+
const plugins = await loadPluginInjections({
|
|
465
|
+
root: ROOT,
|
|
466
|
+
mode: config.mode === "slides" ? "slides" : "docs",
|
|
467
|
+
});
|
|
468
|
+
|
|
336
469
|
// Copy CSS
|
|
337
470
|
const css = await readFile(await resolveStylesPath(ROOT), "utf-8");
|
|
338
471
|
await writeFile(join(DIST, "styles.css"), css);
|
|
@@ -370,13 +503,23 @@ async function buildSite() {
|
|
|
370
503
|
|
|
371
504
|
if (files.length === 0) {
|
|
372
505
|
// No content - render Getting Started page
|
|
373
|
-
const html = renderGettingStarted(template, provenance, config, theme);
|
|
506
|
+
const html = renderGettingStarted(template, provenance, config, theme, plugins);
|
|
374
507
|
await writeFile(join(DIST, "index.html"), html);
|
|
375
508
|
console.log(" ✓ index.html (Getting Started)");
|
|
376
509
|
console.log(`\n\x1b[33mNo content found. Create site.yaml or content/ directory.\x1b[0m`);
|
|
377
510
|
return;
|
|
378
511
|
}
|
|
379
512
|
|
|
513
|
+
if (config.mode === "slides") {
|
|
514
|
+
const html = await renderSlidesIndex(template, files, provenance, config, theme, plugins);
|
|
515
|
+
await writeFile(join(DIST, "index.html"), html);
|
|
516
|
+
console.log(` ✓ index.html (slides mode, ${files.length} source files)`);
|
|
517
|
+
await generateAIAccessibility(DIST, files, config, provenance);
|
|
518
|
+
console.log(`\n\x1b[32mBuild complete! Output in ${OUT_DIR}/\x1b[0m`);
|
|
519
|
+
console.log(`\nTo view locally: open ${OUT_DIR}/index.html`);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
|
|
380
523
|
for (const file of files) {
|
|
381
524
|
const html = await renderFile(
|
|
382
525
|
file.path,
|
|
@@ -386,6 +529,7 @@ async function buildSite() {
|
|
|
386
529
|
provenance,
|
|
387
530
|
config,
|
|
388
531
|
theme,
|
|
532
|
+
plugins,
|
|
389
533
|
);
|
|
390
534
|
|
|
391
535
|
// Create output path
|
|
@@ -403,7 +547,16 @@ async function buildSite() {
|
|
|
403
547
|
if (homePath) {
|
|
404
548
|
try {
|
|
405
549
|
await stat(homePath);
|
|
406
|
-
const homeHtml = await renderFile(
|
|
550
|
+
const homeHtml = await renderFile(
|
|
551
|
+
homePath,
|
|
552
|
+
"",
|
|
553
|
+
template,
|
|
554
|
+
files,
|
|
555
|
+
provenance,
|
|
556
|
+
config,
|
|
557
|
+
theme,
|
|
558
|
+
plugins,
|
|
559
|
+
);
|
|
407
560
|
await writeFile(join(DIST, "index.html"), homeHtml);
|
|
408
561
|
console.log(` ✓ index.html (from ${config.home})`);
|
|
409
562
|
} catch {
|
|
@@ -417,6 +570,7 @@ async function buildSite() {
|
|
|
417
570
|
provenance,
|
|
418
571
|
config,
|
|
419
572
|
theme,
|
|
573
|
+
plugins,
|
|
420
574
|
);
|
|
421
575
|
await writeFile(join(DIST, "index.html"), indexHtml);
|
|
422
576
|
console.log(" ✓ index.html");
|
|
@@ -433,6 +587,7 @@ async function buildSite() {
|
|
|
433
587
|
provenance,
|
|
434
588
|
config,
|
|
435
589
|
theme,
|
|
590
|
+
plugins,
|
|
436
591
|
);
|
|
437
592
|
await writeFile(join(DIST, "index.html"), indexHtml);
|
|
438
593
|
console.log(" ✓ index.html");
|