@marver-design/marver 0.17.0 → 0.19.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 +96 -0
- package/README.md +3 -1
- package/dist/bake-kaf5kGZ7.mjs +747 -0
- package/dist/{build-D_g53Bp2.mjs → build-7ed5H2vT.mjs} +215 -13
- package/dist/cli.mjs +19 -11
- package/dist/{comments-oYcZ3cE-.mjs → comments-ClVgfQib.mjs} +1 -1
- package/dist/{daemon-Bbh_jmui.mjs → daemon-DbHvLQUL.mjs} +1 -1
- package/dist/{dev-LnIISva5.mjs → dev-D3mP2x27.mjs} +205 -10
- package/dist/{init-B7YhcN2o.mjs → init-BQYCS3EU.mjs} +2 -2
- package/dist/{manifest-CaslQIAO.mjs → manifest-B01PSyDc.mjs} +34 -7
- package/dist/{marver-id-gate-D6By7XHj.mjs → marver-id-gate-B_idGdHm.mjs} +1 -1
- package/dist/{plugin-D2msH1cj.mjs → plugin-DI-7NAnx.mjs} +108 -29
- package/dist/{poster-BEjUcQP3.mjs → poster-DNh6N27C.mjs} +1 -1
- package/dist/publish-bakes-Dp-ZFk3d.mjs +216 -0
- package/dist/{serve-Bcwfpvhl.mjs → serve-z5qtj_wJ.mjs} +3 -3
- package/dist/{share-Gqo_Ygqw.mjs → share--bdSc4G5.mjs} +1 -1
- package/dist/{shot-BzQ0PXKH.mjs → shot-BFEuYbaz.mjs} +1 -1
- package/dist/{shot-DlmTO8AF.mjs → shot-DMDvDbeP.mjs} +14 -7
- package/dist/{work-lzC-lPY0.mjs → work-0YopuMt9.mjs} +1 -1
- package/docs/publish.md +27 -5
- package/docs/sticky-notes.md +43 -0
- package/package.json +2 -1
- package/src/client/content/diagram.tsx +27 -1
- package/src/client/content/index.tsx +2 -2
- package/src/client/content/md.ts +48 -0
- package/src/client/frame-host/bridge.js +4 -9
- package/src/client/frame-host/main.tsx +20 -6
- package/src/client/shell/App.tsx +14 -63
- package/src/client/shell/Comments.tsx +77 -14
- package/src/client/shell/Play.tsx +6 -3
- package/src/client/shell/canvas/Canvas.tsx +12 -3
- package/src/client/shell/canvas/FrameNode.tsx +99 -89
- package/src/client/shell/canvas/Sticky.tsx +284 -0
- package/src/client/shell/canvas/admission.ts +70 -0
- package/src/client/shell/canvas/sleep.ts +194 -0
- package/src/client/shell/goto.ts +72 -0
- package/src/client/shell/notes.ts +151 -0
- package/src/client/shell/store.ts +36 -18
- package/src/client/shell/styles.css +92 -25
- package/src/client/shell/tidy.ts +20 -2
- package/src/shared/sleep-rule.ts +41 -0
- package/templates/AGENTS-embedded.md +15 -0
- package/templates/AGENTS-studio.md +15 -0
- package/templates/instructions/craft.md +9 -0
- package/templates/instructions/publish.md +62 -9
- package/templates/instructions/shape.md +62 -0
- package/src/client/frame-host/serialize.ts +0 -195
- package/src/client/shell/canvas/snapshots.ts +0 -233
|
@@ -1,13 +1,156 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as ROUTE, r as NAME } from "./cli.mjs";
|
|
2
2
|
import { a as listBoardFiles, d as flatten, f as isBoardName, n as checkBoardsDir, s as readRegistry, t as boardFields, u as buildTree } from "./boards-BmxcT3Lc.mjs";
|
|
3
|
-
import {
|
|
4
|
-
import { n as tailwind3Css, r as tailwind4Plugin, t as marverPlugin } from "./plugin-
|
|
3
|
+
import { c as loadConfig, r as scanFrames, u as detectHost } from "./manifest-B01PSyDc.mjs";
|
|
4
|
+
import { n as tailwind3Css, r as tailwind4Plugin, t as marverPlugin } from "./plugin-DI-7NAnx.mjs";
|
|
5
5
|
import { cpSync, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { basename, dirname, join, sep } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { createHash, randomBytes } from "node:crypto";
|
|
9
9
|
import { build } from "vite";
|
|
10
10
|
import react from "@vitejs/plugin-react";
|
|
11
|
+
import { Marked } from "marked";
|
|
12
|
+
//#region src/server/css-fix.ts
|
|
13
|
+
/** Every `-webkit-backdrop-filter` declaration (the property itself, never a custom property that
|
|
14
|
+
* happens to end in it) is mirrored by the standard one right after it, in order, importance and
|
|
15
|
+
* all - the standard cascade then resolves exactly as the prefixed one did - unless the declaration
|
|
16
|
+
* list it belongs to declares the standard property already. The list is the enclosing block's own
|
|
17
|
+
* declarations: nested rules, their preludes included, are blanked. Strings and comments are masked
|
|
18
|
+
* first, so a brace or a declaration inside one is content, not syntax; values come from the
|
|
19
|
+
* original text. */
|
|
20
|
+
function keepBackdropFilter(css) {
|
|
21
|
+
const masked = maskCustomProperties(maskParens(css.replace(/\/\*[\s\S]*?\*\/|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\\[\s\S]/g, (m) => " ".repeat(m.length))));
|
|
22
|
+
const PREFIXED = /(^|[^-\w])-webkit-backdrop-filter\s*:/gi;
|
|
23
|
+
const seen = /* @__PURE__ */ new Set();
|
|
24
|
+
const edits = [];
|
|
25
|
+
for (const m of masked.matchAll(PREFIXED)) {
|
|
26
|
+
const p = m.index + m[1].length;
|
|
27
|
+
let depth = 0, open = -1;
|
|
28
|
+
for (let i = p - 1; i >= 0; i--) {
|
|
29
|
+
const c = masked[i];
|
|
30
|
+
if (c === "}") depth++;
|
|
31
|
+
else if (c === "{") {
|
|
32
|
+
if (depth === 0) {
|
|
33
|
+
open = i;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
depth--;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (open < 0 || seen.has(open)) continue;
|
|
40
|
+
seen.add(open);
|
|
41
|
+
let close = masked.length;
|
|
42
|
+
depth = 0;
|
|
43
|
+
for (let i = open + 1; i < masked.length; i++) {
|
|
44
|
+
const c = masked[i];
|
|
45
|
+
if (c === "{") depth++;
|
|
46
|
+
else if (c === "}") {
|
|
47
|
+
if (depth === 0) {
|
|
48
|
+
close = i;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
depth--;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const own = masked.slice(open + 1, close).split("");
|
|
55
|
+
depth = 0;
|
|
56
|
+
let seg = 0;
|
|
57
|
+
for (let i = 0; i < own.length; i++) {
|
|
58
|
+
const c = own[i];
|
|
59
|
+
if (depth === 0 && c === ";") {
|
|
60
|
+
seg = i + 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (c === "{") {
|
|
64
|
+
if (depth === 0) for (let k = seg; k < i; k++) own[k] = " ";
|
|
65
|
+
depth++;
|
|
66
|
+
}
|
|
67
|
+
if (depth) own[i] = " ";
|
|
68
|
+
if (c === "}") {
|
|
69
|
+
depth--;
|
|
70
|
+
if (depth === 0) seg = i + 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const list = own.join("");
|
|
74
|
+
const decls = [];
|
|
75
|
+
let paren = 0, from = 0;
|
|
76
|
+
for (let i = 0; i <= list.length; i++) {
|
|
77
|
+
const c = list[i];
|
|
78
|
+
if (c === "(" || c === "[") paren++;
|
|
79
|
+
else if (c === ")" || c === "]") paren = Math.max(0, paren - 1);
|
|
80
|
+
if (i === list.length || c === ";" && paren === 0) {
|
|
81
|
+
const text = list.slice(from, i), colon = text.indexOf(":");
|
|
82
|
+
if (colon > 0) decls.push({
|
|
83
|
+
prop: text.slice(0, colon).trim().toLowerCase(),
|
|
84
|
+
valueAt: from + colon + 1,
|
|
85
|
+
end: i
|
|
86
|
+
});
|
|
87
|
+
from = i + 1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (decls.some((x) => x.prop === "backdrop-filter")) continue;
|
|
91
|
+
for (const x of decls) {
|
|
92
|
+
if (x.prop !== "-webkit-backdrop-filter") continue;
|
|
93
|
+
const value = css.slice(open + 1 + x.valueAt, open + 1 + x.end).trim();
|
|
94
|
+
if (value) edits.push({
|
|
95
|
+
at: open + 1 + x.end,
|
|
96
|
+
text: `;backdrop-filter:${value}`
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
let out = css;
|
|
101
|
+
for (const e of edits.sort((a, b) => b.at - a.at)) out = out.slice(0, e.at) + e.text + out.slice(e.at);
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/** What sits inside parentheses is a value - `var(--f,{})`, `url(#a{b)` - never a rule: blanked,
|
|
105
|
+
* same length (values are copied from the original text). */
|
|
106
|
+
function maskParens(masked) {
|
|
107
|
+
const out = masked.split("");
|
|
108
|
+
let depth = 0;
|
|
109
|
+
for (let i = 0; i < out.length; i++) {
|
|
110
|
+
const c = out[i];
|
|
111
|
+
if (c === ")" && depth) {
|
|
112
|
+
depth--;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (depth) out[i] = " ";
|
|
116
|
+
if (c === "(") depth++;
|
|
117
|
+
}
|
|
118
|
+
return out.join("");
|
|
119
|
+
}
|
|
120
|
+
/** A custom property's value may hold anything, braces, brackets and semicolons included (CSS
|
|
121
|
+
* Variables 1): blanked, same length, so no brace or property name inside one reads as syntax. */
|
|
122
|
+
function maskCustomProperties(masked) {
|
|
123
|
+
const out = masked.split("");
|
|
124
|
+
const re = /(^|[;{\s])--[^\s:;{}]+\s*:/g;
|
|
125
|
+
for (const m of masked.matchAll(re)) {
|
|
126
|
+
let depth = 0, i = m.index + m[0].length;
|
|
127
|
+
for (; i < masked.length; i++) {
|
|
128
|
+
const c = masked[i];
|
|
129
|
+
if (c === "(" || c === "[" || c === "{") depth++;
|
|
130
|
+
else if (c === ")" || c === "]" || c === "}") {
|
|
131
|
+
if (depth === 0) break;
|
|
132
|
+
depth--;
|
|
133
|
+
} else if (c === ";" && depth === 0) break;
|
|
134
|
+
out[i] = " ";
|
|
135
|
+
}
|
|
136
|
+
re.lastIndex = i;
|
|
137
|
+
}
|
|
138
|
+
return out.join("");
|
|
139
|
+
}
|
|
140
|
+
function cssFixPlugin() {
|
|
141
|
+
return {
|
|
142
|
+
name: "marver:css-fix",
|
|
143
|
+
transform(code, id) {
|
|
144
|
+
if (!/\.css$/.test(id.split("?")[0])) return;
|
|
145
|
+
const fixed = keepBackdropFilter(code);
|
|
146
|
+
return fixed === code ? void 0 : {
|
|
147
|
+
code: fixed,
|
|
148
|
+
map: null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
11
154
|
//#region src/server/build.ts
|
|
12
155
|
/**
|
|
13
156
|
* `marver build` - the static adapter.
|
|
@@ -51,7 +194,37 @@ function scanAssetRefs(src, moduleId) {
|
|
|
51
194
|
}
|
|
52
195
|
if (posterM) out.push(posterM[1]);
|
|
53
196
|
}
|
|
54
|
-
for (const tpl of templates)
|
|
197
|
+
for (const tpl of templates) out.push(...markdownImageRefs(tpl.slice(1, -1)));
|
|
198
|
+
return out;
|
|
199
|
+
}
|
|
200
|
+
/** Markdown images in prose, through the parser: inline and reference-style, titles and
|
|
201
|
+
* parentheses in paths handled, code never counted. Decoded the way the client's assetUrl
|
|
202
|
+
* decodes (one pass; a path still carrying `%` is refused there and skipped here). Md content
|
|
203
|
+
* inside frames and sticky notes alike. */
|
|
204
|
+
function markdownImageRefs(md) {
|
|
205
|
+
const out = [];
|
|
206
|
+
const walk = (tokens) => {
|
|
207
|
+
for (const t of tokens) {
|
|
208
|
+
if (t.type === "image" && typeof t.href === "string") {
|
|
209
|
+
let p = t.href.trim();
|
|
210
|
+
try {
|
|
211
|
+
p = decodeURIComponent(p);
|
|
212
|
+
} catch {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (!p.includes("%")) out.push(p);
|
|
216
|
+
}
|
|
217
|
+
if (t.type !== "code" && t.type !== "codespan") {
|
|
218
|
+
if (Array.isArray(t.tokens)) walk(t.tokens);
|
|
219
|
+
if (Array.isArray(t.items)) walk(t.items);
|
|
220
|
+
if (Array.isArray(t.rows)) for (const row of t.rows) walk(row.map((c) => ({ tokens: c.tokens })));
|
|
221
|
+
if (Array.isArray(t.header)) walk(t.header.map((c) => ({ tokens: c.tokens })));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
try {
|
|
226
|
+
walk(new Marked({ gfm: true }).lexer(md));
|
|
227
|
+
} catch {}
|
|
55
228
|
return out;
|
|
56
229
|
}
|
|
57
230
|
/** Same shape the client's assetUrl accepts: relative, inside design/assets/, no tricks. */
|
|
@@ -193,12 +366,13 @@ function publishedManifest(manifest, pubFrames, publishedNames, strip) {
|
|
|
193
366
|
...manifest.project ? { project: manifest.project } : {},
|
|
194
367
|
...pubFolders.length ? { folders: pubFolders } : {},
|
|
195
368
|
...pubBoards.length ? { boards: pubBoards } : {},
|
|
196
|
-
scenes: manifest.scenes.filter((s) => pubScenes.has(s.name)).map(({ name, title, description, brief }) => ({
|
|
369
|
+
scenes: manifest.scenes.filter((s) => pubScenes.has(s.name)).map(({ name, title, description, brief, note }) => ({
|
|
197
370
|
name,
|
|
198
371
|
frames: pubFrames.filter((f) => f.scene === name).length,
|
|
199
372
|
...title ? { title } : {},
|
|
200
373
|
...description ? { description } : {},
|
|
201
|
-
...brief && !strip ? { brief } : {}
|
|
374
|
+
...brief && !strip ? { brief } : {},
|
|
375
|
+
...note ? { note } : {}
|
|
202
376
|
})),
|
|
203
377
|
frames: pubFrames
|
|
204
378
|
};
|
|
@@ -306,7 +480,7 @@ export function layoutChain(fileKey) {
|
|
|
306
480
|
}
|
|
307
481
|
`;
|
|
308
482
|
}
|
|
309
|
-
async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
483
|
+
async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds, textures = true) {
|
|
310
484
|
const config = await loadConfig(root);
|
|
311
485
|
const host = detectHost(root);
|
|
312
486
|
const pkgDir = packageDir();
|
|
@@ -332,10 +506,11 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
332
506
|
for (const b of Object.values(boards)) for (const node of Array.isArray(b?.nodes) ? b.nodes : []) if (typeof node?.frame === "string") wanted.add(node.frame);
|
|
333
507
|
frames = manifest.frames.filter((f) => wanted.has(f.id));
|
|
334
508
|
}
|
|
335
|
-
const
|
|
509
|
+
const pubFrames = strip ? frames.map((f) => ({
|
|
336
510
|
...f,
|
|
337
511
|
file: opaquePath(f.id, f.kind === "html" ? ".html" : "")
|
|
338
|
-
})) : frames
|
|
512
|
+
})) : frames;
|
|
513
|
+
const pubManifest = publishedManifest(manifest, pubFrames, publishedNames, strip);
|
|
339
514
|
for (const n of publishedNames) {
|
|
340
515
|
const pb = policy.boards[n];
|
|
341
516
|
if (pb?.type !== "slides" && pb?.open !== "slides") continue;
|
|
@@ -367,7 +542,9 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
367
542
|
const t = boardFields(allBoards[n], isBoardName).title;
|
|
368
543
|
return t ? [[n, t]] : [];
|
|
369
544
|
}));
|
|
545
|
+
const bakeGen = textures ? Date.now() : void 0;
|
|
370
546
|
const data = {
|
|
547
|
+
bakes: bakeGen,
|
|
371
548
|
manifest: pubManifest,
|
|
372
549
|
boards,
|
|
373
550
|
names: publishedNames,
|
|
@@ -413,7 +590,7 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
413
590
|
clientDir,
|
|
414
591
|
config,
|
|
415
592
|
detectedThemeCss: host.themeCss
|
|
416
|
-
}));
|
|
593
|
+
}), cssFixPlugin());
|
|
417
594
|
process.env.NODE_ENV = "production";
|
|
418
595
|
const result = await build({
|
|
419
596
|
configFile: false,
|
|
@@ -462,7 +639,7 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
462
639
|
const page = (srcDir, entryName, outPath) => {
|
|
463
640
|
const entry = chunks.find((c) => c.isEntry && c.name === entryName);
|
|
464
641
|
const links = cssFor(entryName).map((f) => `<link rel="stylesheet" href="/${f}" />`).join("\n ");
|
|
465
|
-
const html = readFileSync(join(clientDir, srcDir, "index.html"), "utf8").replaceAll("{{ROUTE}}", ROUTE).replace("<script type=\"module\" src=\"{{ENTRY}}\"><\/script>", `${links}\n <script type="module" src="/${entry.fileName}"><\/script>`);
|
|
642
|
+
const html = readFileSync(join(clientDir, srcDir, "index.html"), "utf8").replaceAll("{{ROUTE}}", ROUTE).replace("<script type=\"module\" src=\"{{ENTRY}}\"><\/script>", `${links}\n <script type="module" src="/${entry.fileName}"><\/script>`).replace(/<head([^>]*)>/, (m) => entryName === "frame" && bakeGen ? `${m}\n <meta name="mv-bakes" content="${bakeGen}">` : m);
|
|
466
643
|
mkdirSync(dirname(join(outDir, outPath)), { recursive: true });
|
|
467
644
|
writeFileSync(join(outDir, outPath), html);
|
|
468
645
|
};
|
|
@@ -470,7 +647,7 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
470
647
|
page("frame-host", "frame", `${ROUTE.slice(1)}/frame/index.html`);
|
|
471
648
|
page("stage", "stage", `${ROUTE.slice(1)}/stage/index.html`);
|
|
472
649
|
cpSync(join(clientDir, "shell", "favicon"), join(outDir, ROUTE.slice(1), "favicon"), { recursive: true });
|
|
473
|
-
cpSync(join(clientDir, "frame-host",
|
|
650
|
+
for (const f of ["bridge.js", "inspect.js"]) cpSync(join(clientDir, "frame-host", f), join(outDir, "assets", f));
|
|
474
651
|
const frameCss = cssFor("frame").map((f) => `<link rel="stylesheet" href="/${f}" />`).join("\n");
|
|
475
652
|
for (const f of frames.filter((x) => x.kind === "html")) {
|
|
476
653
|
const src = readFileSync(join(root, f.file), "utf8");
|
|
@@ -478,6 +655,7 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
478
655
|
let html = src.includes("</head>") ? src.replace("</head>", `${inject}</head>`) : inject + src;
|
|
479
656
|
const shim = `<script>(function(){var a=Element.prototype.attachShadow;if(a)Element.prototype.attachShadow=function(i){if(i&&i.mode==='closed')window.__mvClosedShadow=1;return a.call(this,i)};})();<\/script>`;
|
|
480
657
|
html = /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (m) => m + shim) : shim + html;
|
|
658
|
+
if (bakeGen) html = /<head[^>]*>/i.test(html) ? html.replace(/<head[^>]*>/i, (m) => `${m}<meta name="mv-bakes" content="${bakeGen}">`) : `<meta name="mv-bakes" content="${bakeGen}">` + html;
|
|
481
659
|
const dest = strip ? opaquePath(f.id, ".html") : f.file;
|
|
482
660
|
mkdirSync(dirname(join(outDir, dest)), { recursive: true });
|
|
483
661
|
writeFileSync(join(outDir, dest), html);
|
|
@@ -500,11 +678,12 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
500
678
|
const rel = file.startsWith(rootP + "/") ? file.slice(rootP.length + 1) : file;
|
|
501
679
|
for (const r of scanAssetRefs(src, rel)) refs.add(r);
|
|
502
680
|
}
|
|
681
|
+
for (const note of [...pubManifest.frames.map((f) => f.note), ...pubManifest.scenes.map((s) => s.note)]) if (note) for (const r of markdownImageRefs(note)) refs.add(r);
|
|
503
682
|
let copiedAssets = 0;
|
|
504
683
|
const realAssets = existsSync(assetsDir) ? realpathSync(assetsDir) : null;
|
|
505
684
|
for (const r of refs) {
|
|
506
685
|
if (!isLocalAssetRef(r) || !r.endsWith(".poster.png") || existsSync(join(assetsDir, r))) continue;
|
|
507
|
-
const { ensurePoster } = await import("./poster-
|
|
686
|
+
const { ensurePoster } = await import("./poster-DNh6N27C.mjs");
|
|
508
687
|
const g = await ensurePoster(assetsDir, r.slice(0, -11));
|
|
509
688
|
if (!g.ok) throw new Error(`design/assets/${r}: ${g.error}`);
|
|
510
689
|
console.log(` poster: rendered design/assets/${r} (${g.width}×${g.height})`);
|
|
@@ -569,8 +748,31 @@ async function buildSite(root, boardsFlag, allBoardsFlag, embedSeeds) {
|
|
|
569
748
|
...config.share.frontDoor === false ? { frontDoor: false } : {},
|
|
570
749
|
...config.share.notify === false ? { notify: false } : {}
|
|
571
750
|
}));
|
|
751
|
+
let textureLine = " textures: skipped (--no-textures)";
|
|
752
|
+
if (textures && bakeGen) {
|
|
753
|
+
const { bakePublished } = await import("./publish-bakes-Dp-ZFk3d.mjs");
|
|
754
|
+
const pubFrameFile = new Map(pubFrames.map((f) => [f.id, f]));
|
|
755
|
+
const r = await bakePublished({
|
|
756
|
+
root,
|
|
757
|
+
outDir,
|
|
758
|
+
gen: bakeGen,
|
|
759
|
+
boards,
|
|
760
|
+
themes: config.themes,
|
|
761
|
+
log: (l) => console.log(l),
|
|
762
|
+
frames: pubFrames,
|
|
763
|
+
viewports: config.viewports,
|
|
764
|
+
allScenes: includeAll,
|
|
765
|
+
urlFor: (id, theme) => {
|
|
766
|
+
const f = pubFrameFile.get(id);
|
|
767
|
+
if (!f) return null;
|
|
768
|
+
return f.kind === "html" ? `/${f.file}?theme=${encodeURIComponent(theme)}&r=${bakeGen}` : `/__mv/frame/?id=${encodeURIComponent(id)}&theme=${encodeURIComponent(theme)}&r=${bakeGen}`;
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
textureLine = r === null ? ` textures: none - no Chrome on this machine; frames with glass will rest live (install Chrome, or ship as is)` : r.asked === 0 ? " textures: nothing to compile" : ` textures: ${r.asleep} frame view${r.asleep === 1 ? "" : "s"} asleep under certified glass, ${r.live} with live glass, ${r.plain} without effects (${r.asked} asked: every published node x ${config.themes.length || 1} theme${config.themes.length === 1 ? "" : "s"}; ${(r.bytes / 1024).toFixed(0)} KB, ${(r.ms / 1e3).toFixed(1)} s)`;
|
|
772
|
+
}
|
|
572
773
|
console.log(`\n ${NAME} build → design/.dist`);
|
|
573
774
|
console.log(` boards: ${publishedNames.map((n) => `${n} (${rights[n]})`).join(", ")}`);
|
|
775
|
+
console.log(textureLine);
|
|
574
776
|
console.log(` frames: ${frames.length}${includeAll ? "" : ` of ${manifest.frames.length} (build-time filter)`}`);
|
|
575
777
|
if (copiedAssets) console.log(` assets: ${copiedAssets} referenced file${copiedAssets === 1 ? "" : "s"} from design/assets/ (unreferenced assets never ship)`);
|
|
576
778
|
if (!includeAll && existsSync(join(root, "public"))) console.log(` note: the host public/ directory ships in full - the --boards filter covers frames, not public assets`);
|
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
3
|
import { cac } from "cac";
|
|
3
4
|
import { readFileSync, realpathSync } from "node:fs";
|
|
4
5
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -31,6 +32,13 @@ function slideSize(frame) {
|
|
|
31
32
|
return frame.slide ? SLIDE_INTRINSIC : null;
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
35
|
+
//#region src/cli/name.ts
|
|
36
|
+
var name_exports = /* @__PURE__ */ __exportAll({
|
|
37
|
+
NAME: () => NAME,
|
|
38
|
+
PKG: () => PKG,
|
|
39
|
+
ROUTE: () => ROUTE
|
|
40
|
+
});
|
|
41
|
+
//#endregion
|
|
34
42
|
//#region src/cli/index.ts
|
|
35
43
|
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
36
44
|
if (major < 22 || major === 22 && minor < 18) {
|
|
@@ -64,14 +72,14 @@ const resolve$1 = (dir) => {
|
|
|
64
72
|
};
|
|
65
73
|
const cli = cac(NAME);
|
|
66
74
|
cli.command("init", "Scaffold design/ in this repo").option("--mode <mode>", "studio | embedded", { default: "studio" }).option("--no-demo", "Skip the demo scene (the demo ships unless this flag is passed)").option("--root <dir>", "Host repo root", { default: "." }).action(async (opts) => {
|
|
67
|
-
const { init } = await import("./init-
|
|
75
|
+
const { init } = await import("./init-BQYCS3EU.mjs");
|
|
68
76
|
init(resolve$1(opts.root), {
|
|
69
77
|
mode: opts.mode === "embedded" ? "embedded" : "studio",
|
|
70
78
|
demo: opts.demo !== false
|
|
71
79
|
});
|
|
72
80
|
});
|
|
73
81
|
for (const [name, desc] of [["dev", "Start the local canvas (everything on: hot reload, comments, Live Jam)"], ["canvas", "Start the local canvas - same as dev"]]) cli.command(name, desc).option("--root <dir>", "Host repo root", { default: "." }).option("--port <port>", "Port (default 5199)").action(async (opts) => {
|
|
74
|
-
const { dev } = await import("./dev-
|
|
82
|
+
const { dev } = await import("./dev-D3mP2x27.mjs");
|
|
75
83
|
let port;
|
|
76
84
|
if (opts.port !== void 0) {
|
|
77
85
|
const n = Number(opts.port);
|
|
@@ -80,18 +88,18 @@ for (const [name, desc] of [["dev", "Start the local canvas (everything on: hot
|
|
|
80
88
|
}
|
|
81
89
|
await dev(resolve$1(opts.root), port);
|
|
82
90
|
});
|
|
83
|
-
cli.command("build", "Static export → design/.dist (what ships comes from design/publish.json - publishing is default-closed)").option("--boards <names>", "Publish only these boards (comma-separated); overrides the publish policy").option("--all-boards", "Publish every board - the loud override for the default-closed policy").option("--embed-seeds", "Copy comment history INTO the web root (identifying - every event carries its author's email)").option("--root <dir>", "Host repo root", { default: "." }).action(async (opts) => {
|
|
84
|
-
const { buildSite } = await import("./build-
|
|
91
|
+
cli.command("build", "Static export → design/.dist (what ships comes from design/publish.json - publishing is default-closed)").option("--boards <names>", "Publish only these boards (comma-separated); overrides the publish policy").option("--all-boards", "Publish every board - the loud override for the default-closed policy").option("--embed-seeds", "Copy comment history INTO the web root (identifying - every event carries its author's email)").option("--no-textures", "Skip compiling the glass textures the published frames rest under (needs Chrome; a CI without one skips on its own)").option("--root <dir>", "Host repo root", { default: "." }).action(async (opts) => {
|
|
92
|
+
const { buildSite } = await import("./build-7ed5H2vT.mjs");
|
|
85
93
|
try {
|
|
86
94
|
const boards = opts.boards === void 0 ? void 0 : typeof opts.boards === "string" ? opts.boards : "";
|
|
87
|
-
await buildSite(resolve$1(opts.root), boards, opts.allBoards === true, opts.embedSeeds === true);
|
|
95
|
+
await buildSite(resolve$1(opts.root), boards, opts.allBoards === true, opts.embedSeeds === true, opts.textures !== false && !process.env.MARVER_NO_TEXTURES);
|
|
88
96
|
} catch (err) {
|
|
89
97
|
console.error(`[${NAME}] build failed: ${err.message}`);
|
|
90
98
|
process.exit(1);
|
|
91
99
|
}
|
|
92
100
|
});
|
|
93
101
|
cli.command("serve", "Serve design/.dist (set MARVER_PASSWORD to gate it)").option("--root <dir>", "Host repo root", { default: "." }).option("--port <port>", "Port (default $PORT or 4199)").action(async (opts) => {
|
|
94
|
-
const { serve } = await import("./serve-
|
|
102
|
+
const { serve } = await import("./serve-z5qtj_wJ.mjs");
|
|
95
103
|
let port;
|
|
96
104
|
if (opts.port !== void 0) {
|
|
97
105
|
const n = Number(opts.port);
|
|
@@ -100,7 +108,7 @@ cli.command("serve", "Serve design/.dist (set MARVER_PASSWORD to gate it)").opti
|
|
|
100
108
|
serve(resolve$1(opts.root), port);
|
|
101
109
|
});
|
|
102
110
|
cli.command("comments <action> [value]", "Comment collaboration: connect <url> · sync · list · reply <thread> · resolve <thread> · invite <email> · revoke <email>").option("--root <dir>", "Host repo root", { default: "." }).option("--token <token>", "connect: the canvas's MARVER_CLI_TOKEN (default $MARVER_CLI_TOKEN) - the identity-mode path").option("--invite <token>", "connect: claim this invite instead of signing in").option("--canvas-password <password>", "connect: the canvas gate password (default $MARVER_PASSWORD or prompt)").option("--email <email>", "connect: account email (skips the prompt)").option("--password <password>", "connect: account password (skips the prompt - mind your shell history)").option("--name <name>", "connect --invite: display name for the new account").option("--open", "list: only unresolved threads").option("--json", "list: machine-readable output").option("--board <board>", "scope to one board").option("--body <text>", "reply: the reply text").option("--addressed-in <frame>", "resolve: the variant frame that answered the feedback").action(async (action, value, opts) => {
|
|
103
|
-
const { commentsCommand } = await import("./comments-
|
|
111
|
+
const { commentsCommand } = await import("./comments-ClVgfQib.mjs");
|
|
104
112
|
try {
|
|
105
113
|
await commentsCommand(resolve$1(opts.root), action, value, opts);
|
|
106
114
|
} catch (err) {
|
|
@@ -109,7 +117,7 @@ cli.command("comments <action> [value]", "Comment collaboration: connect <url>
|
|
|
109
117
|
}
|
|
110
118
|
});
|
|
111
119
|
cli.command("share <action> [value]", "Sharing roster (owner): add <who> · remove <who> · block/unblock <email> · general <mode> · list · requests · explain <who> · who").option("--root <dir>", "Host repo root", { default: "." }).option("--role <role>", "add / requests --approve: view (default) or comment").option("--expires <iso>", "add: expiry timestamp, e.g. 2026-12-31T00:00:00Z").option("--approve <email>", "requests: approve this pending request (canvas-wide in v1)").option("--decline <email>", "requests: decline this pending request (silent to the asker)").option("--json", "list: machine-readable output").action(async (action, value, opts) => {
|
|
112
|
-
const { shareCommand } = await import("./share
|
|
120
|
+
const { shareCommand } = await import("./share--bdSc4G5.mjs");
|
|
113
121
|
try {
|
|
114
122
|
await shareCommand(resolve$1(opts.root), action, value, opts);
|
|
115
123
|
} catch (err) {
|
|
@@ -118,7 +126,7 @@ cli.command("share <action> [value]", "Sharing roster (owner): add <who> · remo
|
|
|
118
126
|
}
|
|
119
127
|
});
|
|
120
128
|
cli.command("work <action> [...frames]", "Working state on the canvas: start <scene/frame ...> · done <scene/frame ...> | --all · list").option("--root <dir>", "Host repo root", { default: "." }).option("--ttl <minutes>", "start: minutes before the glow self-expires (default 10, max 30)").option("--all", "done: clear every working frame").action(async (action, frames, opts) => {
|
|
121
|
-
const { workCommand } = await import("./work-
|
|
129
|
+
const { workCommand } = await import("./work-0YopuMt9.mjs");
|
|
122
130
|
try {
|
|
123
131
|
await workCommand(resolve$1(opts.root), action, frames ?? [], opts);
|
|
124
132
|
} catch (err) {
|
|
@@ -136,7 +144,7 @@ cli.command("boards", "The sidebar as files: every folder and board in reading o
|
|
|
136
144
|
}
|
|
137
145
|
});
|
|
138
146
|
cli.command("shot [...frames]", "Render frames headless and print the PNG paths (needs `dev` running): ids, --scene <name> or --all").option("--root <dir>", "Host repo root", { default: "." }).option("--scene <name>", "Every frame of one scene").option("--all", "Every frame of the canvas").option("--theme <name>", "Theme to render (default: light)").option("--scale <n>", "Device pixels per CSS px, 1-4 (default: 2; 4 for print-quality stills)").option("--json", "Print the results as JSON ({ results: [...] }) instead of paths").action(async (frames, opts) => {
|
|
139
|
-
const { shotCommand } = await import("./shot-
|
|
147
|
+
const { shotCommand } = await import("./shot-BFEuYbaz.mjs");
|
|
140
148
|
try {
|
|
141
149
|
await shotCommand(resolve$1(opts.root), frames, opts);
|
|
142
150
|
} catch (err) {
|
|
@@ -148,4 +156,4 @@ cli.help();
|
|
|
148
156
|
cli.version(version());
|
|
149
157
|
cli.parse();
|
|
150
158
|
//#endregion
|
|
151
|
-
export {
|
|
159
|
+
export { ROUTE as a, PKG as i, CONTENT_WIDTH as n, slideSize as o, NAME as r, name_exports as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as NAME } from "./cli.mjs";
|
|
2
2
|
import { n as replay } from "./events-B3LBn74P.mjs";
|
|
3
3
|
import { i as readLog, r as listBoards, t as appendEvents } from "./comments-DZyobpxG.mjs";
|
|
4
4
|
import { a as syncOnce, i as loadCollab, n as connectClaim, r as connectToken, t as connect } from "./sync-BZaCWqK-.mjs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as replay } from "./events-B3LBn74P.mjs";
|
|
2
2
|
import { i as readLog, r as listBoards, t as appendEvents } from "./comments-DZyobpxG.mjs";
|
|
3
3
|
import { n as localProfile } from "./profile-BjAPAJSb.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { a as toFrameId } from "./manifest-B01PSyDc.mjs";
|
|
5
5
|
import { workActivity } from "./work-CLrmY-vQ.mjs";
|
|
6
6
|
import { r as deviceId, t as has } from "./ledger-Bu0BjqIe.mjs";
|
|
7
7
|
import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, watch, writeFileSync, writeSync } from "node:fs";
|