@classic-homes/slides 0.2.0 → 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/README.md +4 -2
- package/dist/{chunk-TXNQKBWJ.js → chunk-33EPZMT6.js} +2 -2
- package/dist/{chunk-TM3TNVHB.js → chunk-7FROOJCY.js} +260 -96
- package/dist/chunk-7FROOJCY.js.map +1 -0
- package/dist/{chunk-CKVKX2ZD.js → chunk-MYY5GZC2.js} +2 -2
- package/dist/cli.js +15 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.js +13 -124
- package/dist/index.js.map +1 -1
- package/dist/{mcp-5R6YD3QW.js → mcp-DGMQTIQI.js} +4 -4
- package/dist/node.d.ts +2 -2
- package/dist/node.js +2 -2
- package/dist/{render-CZ4g2fa9.d.ts → render-DTz7tLKM.d.ts} +14 -1
- package/package.json +11 -3
- package/dist/chunk-TM3TNVHB.js.map +0 -1
- /package/dist/{chunk-TXNQKBWJ.js.map → chunk-33EPZMT6.js.map} +0 -0
- /package/dist/{chunk-CKVKX2ZD.js.map → chunk-MYY5GZC2.js.map} +0 -0
- /package/dist/{mcp-5R6YD3QW.js.map → mcp-DGMQTIQI.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
parseDeckSource,
|
|
3
3
|
renderDeck,
|
|
4
4
|
stringifyDeck
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7FROOJCY.js";
|
|
6
6
|
|
|
7
7
|
// src/node/index.ts
|
|
8
8
|
import { readFile, stat, writeFile } from "fs/promises";
|
|
@@ -73,4 +73,4 @@ export {
|
|
|
73
73
|
saveDeckFile,
|
|
74
74
|
buildDeckFile
|
|
75
75
|
};
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-MYY5GZC2.js.map
|
package/dist/cli.js
CHANGED
|
@@ -4,18 +4,18 @@ import {
|
|
|
4
4
|
deckJsonSchema,
|
|
5
5
|
describeLayout,
|
|
6
6
|
listLayouts
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-33EPZMT6.js";
|
|
8
8
|
import {
|
|
9
9
|
buildDeckFile,
|
|
10
10
|
fileImageResolver,
|
|
11
11
|
loadDeckFile
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MYY5GZC2.js";
|
|
13
13
|
import {
|
|
14
14
|
DeckError,
|
|
15
15
|
formatIssues,
|
|
16
16
|
renderDeck,
|
|
17
17
|
validateDeck
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7FROOJCY.js";
|
|
19
19
|
|
|
20
20
|
// src/node/cli.ts
|
|
21
21
|
import { watch } from "fs";
|
|
@@ -105,8 +105,18 @@ ${"".padEnd(12)} Use for: ${l.whenToUse}
|
|
|
105
105
|
case "schema":
|
|
106
106
|
return void console.log(JSON.stringify(deckJsonSchema(), null, 2));
|
|
107
107
|
case "mcp": {
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
let mcp;
|
|
109
|
+
try {
|
|
110
|
+
mcp = await import("./mcp-DGMQTIQI.js");
|
|
111
|
+
} catch (e) {
|
|
112
|
+
if (e.code === "ERR_MODULE_NOT_FOUND") {
|
|
113
|
+
throw new Error(
|
|
114
|
+
"The MCP server needs @modelcontextprotocol/sdk. Run it with:\n npx -y -p @classic-homes/slides -p @modelcontextprotocol/sdk classic-slides mcp"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
throw e;
|
|
118
|
+
}
|
|
119
|
+
return mcp.runStdio(values.root);
|
|
110
120
|
}
|
|
111
121
|
default:
|
|
112
122
|
throw new Error(`Unknown command "${cmd}".
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * classic-slides — build branded Classic Homes decks from YAML.\n */\nimport { watch } from 'node:fs';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { AUTHORING_GUIDE, deckJsonSchema, describeLayout, listLayouts } from '../catalog.js';\nimport { renderDeck } from '../render.js';\nimport { DeckError, formatIssues, validateDeck } from '../validate.js';\nimport { buildDeckFile, fileImageResolver, loadDeckFile } from './index.js';\n\nconst HELP = `classic-slides — branded Classic Homes presentations\n\nUsage\n classic-slides new <file.yaml> [--starter basic|journey] Start a deck from a starter\n classic-slides build <file.yaml> [-o out.html] Render one self-contained HTML file\n classic-slides dev <file.yaml> [--port 4321] Live preview; reloads on save\n classic-slides validate <file.yaml> Check for errors and crowded slides\n classic-slides layouts [name] List layouts, or show one in detail\n classic-slides guide Print the authoring guide\n classic-slides schema Print the deck JSON Schema\n classic-slides mcp [--root dir] Run the MCP server on stdio\n`;\n\nconst pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\n\nasync function main() {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n out: { type: 'string', short: 'o' },\n port: { type: 'string', default: '4321' },\n starter: { type: 'string', default: 'basic' },\n root: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [cmd, arg] = positionals;\n\n if (!cmd || values.help) return void process.stdout.write(HELP);\n\n switch (cmd) {\n case 'new': {\n if (!arg) throw new Error('Usage: classic-slides new <file.yaml>');\n const target = resolve(arg.endsWith('.yaml') || arg.endsWith('.yml') ? arg : `${arg}.yaml`);\n if (\n await access(target).then(\n () => true,\n () => false\n )\n )\n throw new Error(`${target} already exists.`);\n const starter = join(pkgRoot, 'starters', `${values.starter}.yaml`);\n await mkdir(dirname(target), { recursive: true });\n await copyFile(starter, target);\n console.log(`Created ${target}\\nNext: classic-slides dev ${basename(target)}`);\n return;\n }\n case 'build': {\n if (!arg) throw new Error('Usage: classic-slides build <file.yaml>');\n const r = await buildDeckFile(arg, {\n out: values.out,\n onWarning: (w) => console.warn(`⚠ ${w}`),\n });\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n console.log(`✔ ${r.out} — ${r.slideCount} slides, ${(r.bytes / 1024 / 1024).toFixed(2)} MB`);\n return;\n }\n case 'validate': {\n if (!arg) throw new Error('Usage: classic-slides validate <file.yaml>');\n const v = validateDeck(await loadDeckFile(resolve(arg)));\n console.log(v.issues.length ? formatIssues(v.issues) : '✔ Valid, no warnings');\n process.exitCode = v.ok ? 0 : 1;\n return;\n }\n case 'dev':\n return dev(arg, Number(values.port));\n case 'layouts': {\n if (arg) {\n const d = describeLayout(arg);\n if (!d) throw new Error(`Unknown layout \"${arg}\".`);\n console.log(JSON.stringify(d, null, 2));\n } else {\n for (const l of listLayouts())\n console.log(\n `${l.name.padEnd(12)} ${l.description}\\n${''.padEnd(12)} Use for: ${l.whenToUse}\\n`\n );\n }\n return;\n }\n case 'guide':\n return void console.log(AUTHORING_GUIDE);\n case 'schema':\n return void console.log(JSON.stringify(deckJsonSchema(), null, 2));\n case 'mcp': {\n const { runStdio } = await import('./mcp.js');\n return runStdio(values.root);\n }\n default:\n throw new Error(`Unknown command \"${cmd}\".\\n\\n${HELP}`);\n }\n}\n\n/** Preview server: renders on every request and reloads the page when the deck folder changes. */\nasync function dev(file: string | undefined, port: number) {\n if (!file) throw new Error('Usage: classic-slides dev <file.yaml>');\n const abs = resolve(file);\n const dir = dirname(abs);\n const clients = new Set<import('node:http').ServerResponse>();\n const reload = `<script>new EventSource('/__reload').onmessage=()=>location.reload()</script>`;\n\n const errorPage = (msg: string) =>\n `<!doctype html><meta charset=\"utf-8\"><title>Deck error</title><body style=\"font:15px/1.5 ui-monospace,monospace;padding:40px;background:#fdf2f2;color:#7f1d1d\"><h2 style=\"font-family:system-ui\">Deck has problems</h2><pre style=\"white-space:pre-wrap\">${msg\n .replace(/&/g, '&')\n .replace(/</g, '<')}</pre>${reload}`;\n\n createServer(async (req, res) => {\n if (req.url === '/__reload') {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n });\n res.write(': ok\\n\\n');\n clients.add(res);\n req.on('close', () => clients.delete(res));\n return;\n }\n let html: string;\n try {\n const deck = await loadDeckFile(abs);\n const r = await renderDeck(deck, {\n resolveImage: fileImageResolver(dir),\n embedSource: false,\n });\n html = r.html.replace('</body>', `${reload}</body>`);\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n } catch (e) {\n html = errorPage(\n e instanceof DeckError ? formatIssues(e.issues) : e instanceof Error ? e.message : String(e)\n );\n }\n res.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' });\n res.end(html);\n }).listen(port, () =>\n console.log(`Previewing ${file} at http://localhost:${port} (Ctrl+C to stop)`)\n );\n\n let timer: NodeJS.Timeout | undefined;\n watch(dir, { recursive: true }, (_, name) => {\n if (name && /\\.html$/.test(name)) return;\n clearTimeout(timer);\n timer = setTimeout(() => clients.forEach((c) => c.write('data: reload\\n\\n')), 120);\n });\n}\n\nmain().catch((e) => {\n console.error(e instanceof DeckError ? e.message : `✖ ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/node/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * classic-slides — build branded Classic Homes decks from YAML.\n */\nimport { watch } from 'node:fs';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { createServer } from 'node:http';\nimport { basename, dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parseArgs } from 'node:util';\nimport { AUTHORING_GUIDE, deckJsonSchema, describeLayout, listLayouts } from '../catalog.js';\nimport { renderDeck } from '../render.js';\nimport { DeckError, formatIssues, validateDeck } from '../validate.js';\nimport { buildDeckFile, fileImageResolver, loadDeckFile } from './index.js';\n\nconst HELP = `classic-slides — branded Classic Homes presentations\n\nUsage\n classic-slides new <file.yaml> [--starter basic|journey] Start a deck from a starter\n classic-slides build <file.yaml> [-o out.html] Render one self-contained HTML file\n classic-slides dev <file.yaml> [--port 4321] Live preview; reloads on save\n classic-slides validate <file.yaml> Check for errors and crowded slides\n classic-slides layouts [name] List layouts, or show one in detail\n classic-slides guide Print the authoring guide\n classic-slides schema Print the deck JSON Schema\n classic-slides mcp [--root dir] Run the MCP server on stdio\n`;\n\nconst pkgRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');\n\nasync function main() {\n const { positionals, values } = parseArgs({\n allowPositionals: true,\n options: {\n out: { type: 'string', short: 'o' },\n port: { type: 'string', default: '4321' },\n starter: { type: 'string', default: 'basic' },\n root: { type: 'string' },\n help: { type: 'boolean', short: 'h' },\n },\n });\n const [cmd, arg] = positionals;\n\n if (!cmd || values.help) return void process.stdout.write(HELP);\n\n switch (cmd) {\n case 'new': {\n if (!arg) throw new Error('Usage: classic-slides new <file.yaml>');\n const target = resolve(arg.endsWith('.yaml') || arg.endsWith('.yml') ? arg : `${arg}.yaml`);\n if (\n await access(target).then(\n () => true,\n () => false\n )\n )\n throw new Error(`${target} already exists.`);\n const starter = join(pkgRoot, 'starters', `${values.starter}.yaml`);\n await mkdir(dirname(target), { recursive: true });\n await copyFile(starter, target);\n console.log(`Created ${target}\\nNext: classic-slides dev ${basename(target)}`);\n return;\n }\n case 'build': {\n if (!arg) throw new Error('Usage: classic-slides build <file.yaml>');\n const r = await buildDeckFile(arg, {\n out: values.out,\n onWarning: (w) => console.warn(`⚠ ${w}`),\n });\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n console.log(`✔ ${r.out} — ${r.slideCount} slides, ${(r.bytes / 1024 / 1024).toFixed(2)} MB`);\n return;\n }\n case 'validate': {\n if (!arg) throw new Error('Usage: classic-slides validate <file.yaml>');\n const v = validateDeck(await loadDeckFile(resolve(arg)));\n console.log(v.issues.length ? formatIssues(v.issues) : '✔ Valid, no warnings');\n process.exitCode = v.ok ? 0 : 1;\n return;\n }\n case 'dev':\n return dev(arg, Number(values.port));\n case 'layouts': {\n if (arg) {\n const d = describeLayout(arg);\n if (!d) throw new Error(`Unknown layout \"${arg}\".`);\n console.log(JSON.stringify(d, null, 2));\n } else {\n for (const l of listLayouts())\n console.log(\n `${l.name.padEnd(12)} ${l.description}\\n${''.padEnd(12)} Use for: ${l.whenToUse}\\n`\n );\n }\n return;\n }\n case 'guide':\n return void console.log(AUTHORING_GUIDE);\n case 'schema':\n return void console.log(JSON.stringify(deckJsonSchema(), null, 2));\n case 'mcp': {\n // The MCP SDK is an optional peer so apps that only render decks don't install it.\n let mcp: typeof import('./mcp.js');\n try {\n mcp = await import('./mcp.js');\n } catch (e) {\n if ((e as { code?: string }).code === 'ERR_MODULE_NOT_FOUND') {\n throw new Error(\n 'The MCP server needs @modelcontextprotocol/sdk. Run it with:\\n npx -y -p @classic-homes/slides -p @modelcontextprotocol/sdk classic-slides mcp'\n );\n }\n throw e;\n }\n return mcp.runStdio(values.root);\n }\n default:\n throw new Error(`Unknown command \"${cmd}\".\\n\\n${HELP}`);\n }\n}\n\n/** Preview server: renders on every request and reloads the page when the deck folder changes. */\nasync function dev(file: string | undefined, port: number) {\n if (!file) throw new Error('Usage: classic-slides dev <file.yaml>');\n const abs = resolve(file);\n const dir = dirname(abs);\n const clients = new Set<import('node:http').ServerResponse>();\n const reload = `<script>new EventSource('/__reload').onmessage=()=>location.reload()</script>`;\n\n const errorPage = (msg: string) =>\n `<!doctype html><meta charset=\"utf-8\"><title>Deck error</title><body style=\"font:15px/1.5 ui-monospace,monospace;padding:40px;background:#fdf2f2;color:#7f1d1d\"><h2 style=\"font-family:system-ui\">Deck has problems</h2><pre style=\"white-space:pre-wrap\">${msg\n .replace(/&/g, '&')\n .replace(/</g, '<')}</pre>${reload}`;\n\n createServer(async (req, res) => {\n if (req.url === '/__reload') {\n res.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-cache',\n connection: 'keep-alive',\n });\n res.write(': ok\\n\\n');\n clients.add(res);\n req.on('close', () => clients.delete(res));\n return;\n }\n let html: string;\n try {\n const deck = await loadDeckFile(abs);\n const r = await renderDeck(deck, {\n resolveImage: fileImageResolver(dir),\n embedSource: false,\n });\n html = r.html.replace('</body>', `${reload}</body>`);\n if (r.warnings.length) console.warn(formatIssues(r.warnings));\n } catch (e) {\n html = errorPage(\n e instanceof DeckError ? formatIssues(e.issues) : e instanceof Error ? e.message : String(e)\n );\n }\n res.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' });\n res.end(html);\n }).listen(port, () =>\n console.log(`Previewing ${file} at http://localhost:${port} (Ctrl+C to stop)`)\n );\n\n let timer: NodeJS.Timeout | undefined;\n watch(dir, { recursive: true }, (_, name) => {\n if (name && /\\.html$/.test(name)) return;\n clearTimeout(timer);\n timer = setTimeout(() => clients.forEach((c) => c.write('data: reload\\n\\n')), 120);\n });\n}\n\nmain().catch((e) => {\n console.error(e instanceof DeckError ? e.message : `✖ ${e instanceof Error ? e.message : e}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { D as Deck, a as DeckError, b as DeckInput, c as DeckSchema, I as ImageResolver, L as LAYOUTS, d as LayoutDef, e as LayoutIssue, f as LayoutName, R as RenderOptions, g as RenderResult, S as SlideData, h as SlideInput, i as SlideSchema, V as ValidationResult, j as collectImageSources, k as extractDeckSource, l as formatIssues, m as formatPath, n as getLayout, r as renderDeck, v as validateDeck } from './render-
|
|
1
|
+
export { D as Deck, a as DeckError, b as DeckInput, c as DeckSchema, I as ImageResolver, L as LAYOUTS, d as LayoutDef, e as LayoutIssue, f as LayoutName, P as PREVIEW_SIZE, R as RenderOptions, g as RenderResult, S as SlideData, h as SlideInput, i as SlideSchema, V as ValidationResult, j as collectImageSources, k as extractDeckSource, l as formatIssues, m as formatPath, n as getLayout, r as renderDeck, v as validateDeck } from './render-DTz7tLKM.js';
|
|
2
2
|
import * as zod_to_json_schema from 'zod-to-json-schema';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
@@ -145,5 +145,17 @@ interface LayoutEditorInfo {
|
|
|
145
145
|
declare function commonSlideFields(): EditorField[];
|
|
146
146
|
declare function layoutEditorInfo(name: string): LayoutEditorInfo | undefined;
|
|
147
147
|
declare function allLayoutEditorInfo(): LayoutEditorInfo[];
|
|
148
|
+
/**
|
|
149
|
+
* Stand-in image for new slides: a neutral frame reading "Add a photo".
|
|
150
|
+
* It validates (so a fresh slide previews immediately) but lint warns until
|
|
151
|
+
* it is replaced.
|
|
152
|
+
*/
|
|
153
|
+
declare const PLACEHOLDER_IMAGE: string;
|
|
154
|
+
declare function isPlaceholderImage(src: string | undefined): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* A new slide for a layout, ready to edit: the layout's example with sample
|
|
157
|
+
* image paths swapped for {@link PLACEHOLDER_IMAGE}. Always passes validation.
|
|
158
|
+
*/
|
|
159
|
+
declare function blankSlide(name: string): Record<string, unknown> | undefined;
|
|
148
160
|
|
|
149
|
-
export { AUTHORING_GUIDE, type EditableDeck, type EditorField, LOGO_SVG, type LayoutEditorInfo, PALETTE, type SlideRef, addSlide, allLayoutEditorInfo, commonSlideFields, deckJsonSchema, describeLayout, escapeHtml, findSlide, inline, layoutEditorInfo, listLayouts, moveSlide, outline, parseDeckSource, prose, removeSlide, stringifyDeck, updateSlide };
|
|
161
|
+
export { AUTHORING_GUIDE, type EditableDeck, type EditorField, LOGO_SVG, type LayoutEditorInfo, PALETTE, PLACEHOLDER_IMAGE, type SlideRef, addSlide, allLayoutEditorInfo, blankSlide, commonSlideFields, deckJsonSchema, describeLayout, escapeHtml, findSlide, inline, isPlaceholderImage, layoutEditorInfo, listLayouts, moveSlide, outline, parseDeckSource, prose, removeSlide, stringifyDeck, updateSlide };
|
package/dist/index.js
CHANGED
|
@@ -11,149 +11,34 @@ import {
|
|
|
11
11
|
deckJsonSchema,
|
|
12
12
|
describeLayout,
|
|
13
13
|
listLayouts
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-33EPZMT6.js";
|
|
15
15
|
import {
|
|
16
16
|
DeckError,
|
|
17
17
|
DeckSchema,
|
|
18
|
-
Image,
|
|
19
|
-
Item,
|
|
20
18
|
LAYOUTS,
|
|
21
19
|
LOGO_SVG,
|
|
22
20
|
PALETTE,
|
|
21
|
+
PLACEHOLDER_IMAGE,
|
|
22
|
+
PREVIEW_SIZE,
|
|
23
23
|
SlideSchema,
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
allLayoutEditorInfo,
|
|
25
|
+
blankSlide,
|
|
26
26
|
collectImageSources,
|
|
27
|
+
commonSlideFields,
|
|
27
28
|
escapeHtml,
|
|
28
29
|
extractDeckSource,
|
|
29
30
|
formatIssues,
|
|
30
31
|
formatPath,
|
|
31
32
|
getLayout,
|
|
32
33
|
inline,
|
|
34
|
+
isPlaceholderImage,
|
|
35
|
+
layoutEditorInfo,
|
|
33
36
|
parseDeckSource,
|
|
34
37
|
prose,
|
|
35
38
|
renderDeck,
|
|
36
39
|
stringifyDeck,
|
|
37
40
|
validateDeck
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
|
|
40
|
-
// src/editor.ts
|
|
41
|
-
import { z } from "zod";
|
|
42
|
-
var MULTILINE = /* @__PURE__ */ new Set(["lead", "body", "text", "quote", "footnote", "sub", "notes", "caption"]);
|
|
43
|
-
var LABELS = {
|
|
44
|
-
eyebrowSub: "Eyebrow subtitle",
|
|
45
|
-
showJourney: "Show journey strip",
|
|
46
|
-
stepDone: "Step completed",
|
|
47
|
-
mediaSide: "Photo side",
|
|
48
|
-
imageAspect: "Photo shape",
|
|
49
|
-
numberFrom: "First badge number",
|
|
50
|
-
url: "URL",
|
|
51
|
-
id: "Slide id"
|
|
52
|
-
};
|
|
53
|
-
function labelFor(key) {
|
|
54
|
-
if (LABELS[key]) return LABELS[key];
|
|
55
|
-
const words = key.replace(/([A-Z])/g, " $1").toLowerCase();
|
|
56
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
57
|
-
}
|
|
58
|
-
function unwrap(schema) {
|
|
59
|
-
let s = schema;
|
|
60
|
-
let required = true;
|
|
61
|
-
let dflt;
|
|
62
|
-
let description = schema.description;
|
|
63
|
-
for (; ; ) {
|
|
64
|
-
description ??= s.description;
|
|
65
|
-
if (s instanceof z.ZodOptional || s instanceof z.ZodNullable) {
|
|
66
|
-
required = false;
|
|
67
|
-
s = s.unwrap();
|
|
68
|
-
} else if (s instanceof z.ZodDefault) {
|
|
69
|
-
required = false;
|
|
70
|
-
dflt = s._def.defaultValue();
|
|
71
|
-
s = s._def.innerType;
|
|
72
|
-
} else break;
|
|
73
|
-
}
|
|
74
|
-
return { inner: s, required, default: dflt, description };
|
|
75
|
-
}
|
|
76
|
-
function isText(s) {
|
|
77
|
-
return s === Text || s instanceof z.ZodString && s.description === Text.description;
|
|
78
|
-
}
|
|
79
|
-
function describeField(key, schema) {
|
|
80
|
-
const { inner, required, default: dflt, description } = unwrap(schema);
|
|
81
|
-
const base = {
|
|
82
|
-
key,
|
|
83
|
-
label: labelFor(key),
|
|
84
|
-
required,
|
|
85
|
-
...description ? { description } : {},
|
|
86
|
-
...dflt !== void 0 ? { default: dflt } : {},
|
|
87
|
-
...MULTILINE.has(key) ? { multiline: true } : {}
|
|
88
|
-
};
|
|
89
|
-
if (inner === Image) return { ...base, kind: "image" };
|
|
90
|
-
if (inner === Item) return { ...base, kind: "item" };
|
|
91
|
-
if (isText(inner)) return { ...base, kind: "inline" };
|
|
92
|
-
if (inner instanceof z.ZodString) return { ...base, kind: "string" };
|
|
93
|
-
if (inner instanceof z.ZodBoolean) return { ...base, kind: "boolean" };
|
|
94
|
-
if (inner instanceof z.ZodEnum) return { ...base, kind: "enum", options: [...inner.options] };
|
|
95
|
-
if (inner instanceof z.ZodLiteral) return { ...base, kind: "enum", options: [inner.value] };
|
|
96
|
-
if (inner instanceof z.ZodNumber) {
|
|
97
|
-
return {
|
|
98
|
-
...base,
|
|
99
|
-
kind: "number",
|
|
100
|
-
integer: inner.isInt,
|
|
101
|
-
...inner.minValue !== null ? { min: inner.minValue } : {},
|
|
102
|
-
...inner.maxValue !== null ? { max: inner.maxValue } : {}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
if (inner instanceof z.ZodUnion) {
|
|
106
|
-
const opts = inner.options;
|
|
107
|
-
if (opts.every((o) => o instanceof z.ZodLiteral)) {
|
|
108
|
-
return {
|
|
109
|
-
...base,
|
|
110
|
-
kind: "enum",
|
|
111
|
-
options: opts.map((o) => o.value)
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
return { ...base, kind: "string" };
|
|
115
|
-
}
|
|
116
|
-
if (inner instanceof z.ZodArray) {
|
|
117
|
-
const el = inner.element;
|
|
118
|
-
return {
|
|
119
|
-
...base,
|
|
120
|
-
kind: "list",
|
|
121
|
-
of: { ...describeField("", el), label: labelFor(key.replace(/s$/, "")) },
|
|
122
|
-
...inner._def.minLength ? { min: inner._def.minLength.value } : {},
|
|
123
|
-
...inner._def.maxLength ? { max: inner._def.maxLength.value } : {}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
if (inner instanceof z.ZodObject) {
|
|
127
|
-
return {
|
|
128
|
-
...base,
|
|
129
|
-
kind: "group",
|
|
130
|
-
fields: Object.entries(inner.shape).map(
|
|
131
|
-
([k, v]) => describeField(k, v)
|
|
132
|
-
)
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
return { ...base, kind: "string" };
|
|
136
|
-
}
|
|
137
|
-
function commonSlideFields() {
|
|
138
|
-
return Object.entries(baseSlide).map(([k, v]) => describeField(k, v));
|
|
139
|
-
}
|
|
140
|
-
function layoutEditorInfo(name) {
|
|
141
|
-
const layout = getLayout(name);
|
|
142
|
-
if (!layout) return void 0;
|
|
143
|
-
return {
|
|
144
|
-
name: layout.name,
|
|
145
|
-
description: layout.description,
|
|
146
|
-
whenToUse: layout.whenToUse,
|
|
147
|
-
defaults: layout.defaults ?? {},
|
|
148
|
-
fields: Object.entries(layout.shape).map(
|
|
149
|
-
([k, v]) => describeField(k, v)
|
|
150
|
-
),
|
|
151
|
-
example: layout.example
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
function allLayoutEditorInfo() {
|
|
155
|
-
return LAYOUTS.map((l) => layoutEditorInfo(l.name));
|
|
156
|
-
}
|
|
41
|
+
} from "./chunk-7FROOJCY.js";
|
|
157
42
|
export {
|
|
158
43
|
AUTHORING_GUIDE,
|
|
159
44
|
DeckError,
|
|
@@ -161,9 +46,12 @@ export {
|
|
|
161
46
|
LAYOUTS,
|
|
162
47
|
LOGO_SVG,
|
|
163
48
|
PALETTE,
|
|
49
|
+
PLACEHOLDER_IMAGE,
|
|
50
|
+
PREVIEW_SIZE,
|
|
164
51
|
SlideSchema,
|
|
165
52
|
addSlide,
|
|
166
53
|
allLayoutEditorInfo,
|
|
54
|
+
blankSlide,
|
|
167
55
|
collectImageSources,
|
|
168
56
|
commonSlideFields,
|
|
169
57
|
deckJsonSchema,
|
|
@@ -175,6 +63,7 @@ export {
|
|
|
175
63
|
formatPath,
|
|
176
64
|
getLayout,
|
|
177
65
|
inline,
|
|
66
|
+
isPlaceholderImage,
|
|
178
67
|
layoutEditorInfo,
|
|
179
68
|
listLayouts,
|
|
180
69
|
moveSlide,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -9,17 +9,17 @@ import {
|
|
|
9
9
|
AUTHORING_GUIDE,
|
|
10
10
|
describeLayout,
|
|
11
11
|
listLayouts
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-33EPZMT6.js";
|
|
13
13
|
import {
|
|
14
14
|
buildDeckFile,
|
|
15
15
|
loadDeckFile,
|
|
16
16
|
saveDeckFile
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-MYY5GZC2.js";
|
|
18
18
|
import {
|
|
19
19
|
formatIssues,
|
|
20
20
|
stringifyDeck,
|
|
21
21
|
validateDeck
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-7FROOJCY.js";
|
|
23
23
|
|
|
24
24
|
// src/node/mcp.ts
|
|
25
25
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -317,4 +317,4 @@ export {
|
|
|
317
317
|
createSlidesMcpServer,
|
|
318
318
|
runStdio
|
|
319
319
|
};
|
|
320
|
-
//# sourceMappingURL=mcp-
|
|
320
|
+
//# sourceMappingURL=mcp-DGMQTIQI.js.map
|
package/dist/node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RenderOptions, g as RenderResult, I as ImageResolver } from './render-
|
|
2
|
-
export { r as renderDeck } from './render-
|
|
1
|
+
import { R as RenderOptions, g as RenderResult, I as ImageResolver } from './render-DTz7tLKM.js';
|
|
2
|
+
export { r as renderDeck } from './render-DTz7tLKM.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/** Largest single image we inline without warning. Big photos bloat the deck file. */
|
package/dist/node.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
fileImageResolver,
|
|
5
5
|
loadDeckFile,
|
|
6
6
|
saveDeckFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-MYY5GZC2.js";
|
|
8
8
|
import {
|
|
9
9
|
renderDeck
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7FROOJCY.js";
|
|
11
11
|
export {
|
|
12
12
|
IMAGE_WARN_BYTES,
|
|
13
13
|
buildDeckFile,
|
|
@@ -110,6 +110,15 @@ declare class DeckError extends Error {
|
|
|
110
110
|
constructor(issues: LayoutIssue[]);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Size to lay a preview out at before scaling it down. Slides are responsive
|
|
115
|
+
* and switch to a stacked layout below ~840px wide, so small previews should
|
|
116
|
+
* render at this size and use a CSS transform.
|
|
117
|
+
*/
|
|
118
|
+
declare const PREVIEW_SIZE: {
|
|
119
|
+
readonly width: 1280;
|
|
120
|
+
readonly height: 720;
|
|
121
|
+
};
|
|
113
122
|
type ImageResolver = (src: string) => Promise<string> | string;
|
|
114
123
|
interface RenderOptions {
|
|
115
124
|
/**
|
|
@@ -120,11 +129,15 @@ interface RenderOptions {
|
|
|
120
129
|
resolveImage?: ImageResolver;
|
|
121
130
|
/** Embed the deck source (JSON, without image data) so the HTML can be re-opened for editing. Default true. */
|
|
122
131
|
embedSource?: boolean;
|
|
132
|
+
/** 0-based rendered slide to open on (ignored when the URL has #slide-N). Handy for editor previews. */
|
|
133
|
+
initialSlide?: number;
|
|
123
134
|
}
|
|
124
135
|
interface RenderResult {
|
|
125
136
|
html: string;
|
|
126
137
|
deck: Deck;
|
|
127
138
|
slideCount: number;
|
|
139
|
+
/** For each deck slide, the 0-based indices of the rendered slides it produced (a walkthrough yields several). */
|
|
140
|
+
slideMap: number[][];
|
|
128
141
|
warnings: ReturnType<typeof validateDeck>['issues'];
|
|
129
142
|
}
|
|
130
143
|
/** Collects every image src in the deck (any object with a string `src`). */
|
|
@@ -133,4 +146,4 @@ declare function renderDeck(input: unknown, options?: RenderOptions): Promise<Re
|
|
|
133
146
|
/** Pulls the embedded deck source back out of a rendered HTML file. */
|
|
134
147
|
declare function extractDeckSource(html: string): unknown | undefined;
|
|
135
148
|
|
|
136
|
-
export { type Deck as D, type ImageResolver as I, LAYOUTS as L, type RenderOptions as R, type SlideData as S, type ValidationResult as V, DeckError as a, type DeckInput as b, DeckSchema as c, type LayoutDef as d, type LayoutIssue as e, type LayoutName as f, type RenderResult as g, type SlideInput as h, SlideSchema as i, collectImageSources as j, extractDeckSource as k, formatIssues as l, formatPath as m, getLayout as n, renderDeck as r, validateDeck as v };
|
|
149
|
+
export { type Deck as D, type ImageResolver as I, LAYOUTS as L, PREVIEW_SIZE as P, type RenderOptions as R, type SlideData as S, type ValidationResult as V, DeckError as a, type DeckInput as b, DeckSchema as c, type LayoutDef as d, type LayoutIssue as e, type LayoutName as f, type RenderResult as g, type SlideInput as h, SlideSchema as i, collectImageSources as j, extractDeckSource as k, formatIssues as l, formatPath as m, getLayout as n, renderDeck as r, validateDeck as v };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classic-homes/slides",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Branded Classic Homes presentations from structured deck files: schema, layouts, renderer, CLI and MCP server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -52,18 +52,26 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@classic-homes/theme-tokens": "^0.4.0",
|
|
55
|
-
"@modelcontextprotocol/sdk": "^1.11.0",
|
|
56
55
|
"qrcode": "^1.5.4",
|
|
57
56
|
"yaml": "^2.6.0",
|
|
58
57
|
"zod": "^3.25.0",
|
|
59
58
|
"zod-to-json-schema": "^3.24.0"
|
|
60
59
|
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"@modelcontextprotocol/sdk": "^1.11.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"@modelcontextprotocol/sdk": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
61
68
|
"devDependencies": {
|
|
62
69
|
"@types/node": "^22.0.0",
|
|
63
70
|
"@types/qrcode": "^1.5.5",
|
|
64
71
|
"tsup": "^8.0.0",
|
|
65
72
|
"tsx": "^4.0.0",
|
|
66
73
|
"typescript": "^5.3.0",
|
|
67
|
-
"vitest": "^4.1.10"
|
|
74
|
+
"vitest": "^4.1.10",
|
|
75
|
+
"@modelcontextprotocol/sdk": "^1.11.0"
|
|
68
76
|
}
|
|
69
77
|
}
|