@1agh/maude 0.17.2 → 0.18.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/cli/commands/design.mjs +92 -29
- package/package.json +8 -8
- package/plugins/design/dev-server/bin/screenshot.sh +12 -0
- package/plugins/design/dev-server/boot-self-heal.ts +87 -0
- package/plugins/design/dev-server/build.ts +56 -2
- package/plugins/design/dev-server/config.schema.json +12 -0
- package/plugins/design/dev-server/dist/client.bundle.js +3 -3
- package/plugins/design/dev-server/dist/runtime/pixi-js.js +52708 -0
- package/plugins/design/dev-server/dist/runtime/react-dom.js +249 -0
- package/plugins/design/dev-server/dist/runtime/react-dom_client.js +10375 -0
- package/plugins/design/dev-server/dist/runtime/react.js +553 -0
- package/plugins/design/dev-server/dist/runtime/react_jsx-dev-runtime.js +78 -0
- package/plugins/design/dev-server/dist/runtime/react_jsx-runtime.js +103 -0
- package/plugins/design/dev-server/http.ts +5 -3
- package/plugins/design/dev-server/paths.ts +115 -0
- package/plugins/design/dev-server/runtime-bundle.ts +80 -7
- package/plugins/design/dev-server/server.ts +6 -0
- package/plugins/design/dev-server/test/boot-self-heal.test.ts +87 -0
- package/plugins/design/dev-server/test/paths.test.ts +31 -0
- package/plugins/design/dev-server/test/runtime-bundle-error-mapping.test.ts +43 -0
- package/plugins/design/templates/canvas.tsx.template +7 -7
- package/plugins/design/templates/design-system-inspiration/audience-pro/colors-presence.html +1 -1
- package/plugins/design/templates/design-system-inspiration/core/README.philosophy.md.tpl +11 -7
- package/plugins/design/templates/design-system-inspiration/core/SKILL.md.tpl +4 -3
- package/plugins/design/templates/design-system-inspiration/core/colors_and_type.css.tpl +61 -57
- package/plugins/design/templates/design-system-inspiration/core/config.json.tpl +2 -0
- package/plugins/design/templates/design-system-inspiration/core/preview/colors-accent.html +4 -4
- package/plugins/design/templates/design-system-inspiration/meta/presence-multiplayer.html +1 -1
- package/plugins/design/templates/design-system-inspiration/platform-desktop/ui_kits-desktop-showcase.html +3 -0
- package/plugins/design/templates/design-system-inspiration/platform-mobile/ui_kits-mobile-showcase.html +1 -1
- package/plugins/design/templates/design-system-inspiration/theme-both/colors-themes-side-by-side.html +6 -6
- package/plugins/design/templates/design-system-inspiration/universal/components-dialogs.html +3 -2
- package/plugins/design/templates/design-system-inspiration/universal/logo.html +2 -1
package/cli/commands/design.mjs
CHANGED
|
@@ -508,6 +508,13 @@ function escapeReg(s) {
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
function defaultPayload({ projectName, dsName }) {
|
|
511
|
+
// `--no-discovery` mode emits a deliberately NEUTRAL skeleton:
|
|
512
|
+
// achromatic grayscale, system fonts only, equal spacing/radii steps,
|
|
513
|
+
// single accent set to neutral graphite. The intent is for the project
|
|
514
|
+
// to immediately overwrite these with discovery-driven values via
|
|
515
|
+
// `/design:setup-ds`. These are NOT a "recommended starter palette" —
|
|
516
|
+
// they're an explicit placeholder that should look unfinished, so the
|
|
517
|
+
// designer is nudged toward actual decisions (DDR-026, 2026-05-25).
|
|
511
518
|
return {
|
|
512
519
|
project_name: projectName,
|
|
513
520
|
project_label: titleCase(projectName),
|
|
@@ -515,7 +522,7 @@ function defaultPayload({ projectName, dsName }) {
|
|
|
515
522
|
ds_skill_name: `${dsName}-design`,
|
|
516
523
|
ds_description: `Default design system for ${projectName}.`,
|
|
517
524
|
root_class: 'app',
|
|
518
|
-
theme_default: '
|
|
525
|
+
theme_default: 'light',
|
|
519
526
|
theme_extra: '',
|
|
520
527
|
handoff_targets: '[]',
|
|
521
528
|
active_families: JSON.stringify(['accent']),
|
|
@@ -528,38 +535,94 @@ function defaultPayload({ projectName, dsName }) {
|
|
|
528
535
|
platform_hard_rules: '',
|
|
529
536
|
content_tone: 'direct-terse',
|
|
530
537
|
mood_references_block: '_(not specified — extend during the next /design:setup-ds run)_',
|
|
531
|
-
type_scale_summary: '8-step ladder,
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
538
|
+
type_scale_summary: '8-step ladder, populated by discovery.',
|
|
539
|
+
type_scale_summary_compact: '8-step (modular ratio)',
|
|
540
|
+
voice_tone_block: 'Voice not declared yet — capture during /design:setup-ds.',
|
|
541
|
+
voice_tone_summary: 'not-declared',
|
|
542
|
+
iconography_summary: 'Icon family not declared yet — capture during /design:setup-ds.',
|
|
535
543
|
hard_rules_from_system_readme: '_(see system/<ds>/README.md Hard rules section)_',
|
|
536
544
|
hard_rules_block:
|
|
537
|
-
'- WCAG 2.1 AA contrast\n- No off-token
|
|
545
|
+
'- WCAG 2.1 AA contrast\n- No off-token values in canvases\n- Real product strings only — no placeholder copy',
|
|
538
546
|
iso_timestamp: new Date().toISOString(),
|
|
539
|
-
//
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
547
|
+
// ─── Neutral-skeleton tokens (light theme grayscale, no chroma) ───
|
|
548
|
+
bg_0: 'oklch(100% 0 0)',
|
|
549
|
+
bg_1: 'oklch(97% 0 0)',
|
|
550
|
+
bg_2: 'oklch(94% 0 0)',
|
|
551
|
+
bg_3: 'oklch(90% 0 0)',
|
|
552
|
+
bg_4: 'oklch(85% 0 0)',
|
|
553
|
+
border_subtle: 'oklch(92% 0 0)',
|
|
554
|
+
border_default: 'oklch(85% 0 0)',
|
|
555
|
+
border_strong: 'oklch(70% 0 0)',
|
|
556
|
+
border_strategy: 'fixed-token',
|
|
557
|
+
fg_0: 'oklch(15% 0 0)',
|
|
558
|
+
fg_1: 'oklch(35% 0 0)',
|
|
559
|
+
fg_2: 'oklch(55% 0 0)',
|
|
560
|
+
fg_3: 'oklch(75% 0 0)',
|
|
561
|
+
accent_strategy: 'single',
|
|
562
|
+
accent_strategy_summary: 'single accent — discovery has not been run',
|
|
563
|
+
accent_block:
|
|
564
|
+
' --accent: oklch(35% 0 0);\n --accent-hover: oklch(30% 0 0);\n --accent-active: oklch(25% 0 0);\n --accent-fg: oklch(98% 0 0);',
|
|
565
|
+
accent_rules_block:
|
|
566
|
+
'Single accent family (`--accent`, `--accent-hover`, `--accent-active`, `--accent-fg`). Project has not run discovery yet — the accent is set to neutral graphite as a placeholder. Run `/design:setup-ds` to pick a real palette.',
|
|
567
|
+
accent_rules_summary: 'Single family until discovery runs.',
|
|
568
|
+
color_space: 'oklch',
|
|
569
|
+
color_space_summary: 'OKLCH (default)',
|
|
570
|
+
color_space_block:
|
|
571
|
+
'**Color space:** OKLCH (default). Override via `config.colorSpace` if your project requires HSL, hex, or LAB.',
|
|
572
|
+
status_success: 'oklch(55% 0 0)',
|
|
573
|
+
status_warn: 'oklch(55% 0 0)',
|
|
574
|
+
status_error: 'oklch(55% 0 0)',
|
|
575
|
+
status_info: 'oklch(55% 0 0)',
|
|
576
|
+
presence_online: 'var(--status-success)',
|
|
577
|
+
presence_away: 'var(--status-warn)',
|
|
578
|
+
presence_offline: 'var(--fg-3)',
|
|
579
|
+
shadow_sm: 'none',
|
|
580
|
+
shadow_md: 'none',
|
|
581
|
+
shadow_lg: 'none',
|
|
582
|
+
radius_xs: '0',
|
|
583
|
+
radius_sm: '0',
|
|
584
|
+
radius_md: '0',
|
|
585
|
+
radius_lg: '0',
|
|
586
|
+
radius_xl: '0',
|
|
587
|
+
radius_pill: '999px',
|
|
588
|
+
space_0: '0',
|
|
589
|
+
space_1: '4px',
|
|
590
|
+
space_2: '8px',
|
|
591
|
+
space_3: '12px',
|
|
592
|
+
space_4: '16px',
|
|
593
|
+
space_5: '24px',
|
|
594
|
+
space_6: '32px',
|
|
595
|
+
space_7: '48px',
|
|
596
|
+
space_8: '64px',
|
|
597
|
+
font_display: 'system-ui, sans-serif',
|
|
598
|
+
font_body: 'system-ui, sans-serif',
|
|
599
|
+
font_mono: 'ui-monospace, monospace',
|
|
600
|
+
type_xs: '12px',
|
|
601
|
+
lh_xs: '16px',
|
|
602
|
+
type_sm: '13px',
|
|
603
|
+
lh_sm: '18px',
|
|
604
|
+
type_base: '14px',
|
|
605
|
+
lh_base: '20px',
|
|
606
|
+
type_md: '16px',
|
|
607
|
+
lh_md: '22px',
|
|
608
|
+
type_lg: '18px',
|
|
609
|
+
lh_lg: '26px',
|
|
610
|
+
type_xl: '22px',
|
|
611
|
+
lh_xl: '30px',
|
|
612
|
+
type_2xl: '28px',
|
|
613
|
+
lh_2xl: '36px',
|
|
614
|
+
type_3xl: '36px',
|
|
615
|
+
lh_3xl: '44px',
|
|
616
|
+
dur_flip: '120ms',
|
|
617
|
+
dur_panel: '200ms',
|
|
618
|
+
dur_route: '240ms',
|
|
562
619
|
dur_soft: '320ms',
|
|
620
|
+
ease_out_curve: 'ease-out',
|
|
621
|
+
ease_in_out_curve: 'ease-in-out',
|
|
622
|
+
layout_max_w: '1200px',
|
|
623
|
+
layout_gutter: 'var(--space-4)',
|
|
624
|
+
touch_target_rule:
|
|
625
|
+
'44×44 minimum on touch surfaces (iOS HIG); 48×48 if the primary platform is Android (Material). N/A on desktop-only systems.',
|
|
563
626
|
// Empty-state template fields
|
|
564
627
|
empty_subject: 'items',
|
|
565
628
|
empty_supporting: "When you create your first one, it'll show up here.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1agh/maude",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "Marketplace of Claude Code plugins by Michal Dovrtěl: `design` (canvas-first design iteration) + `flow` (generic agentic workflow loop with .ai second brain). Ships the `maude` CLI (with `mdcc` legacy alias) to scaffold workspace, run the design dev server, and manage configs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
"prepublishOnly": "bash scripts/check-version-parity.sh"
|
|
42
42
|
},
|
|
43
43
|
"optionalDependencies": {
|
|
44
|
-
"@1agh/maude-darwin-arm64": "0.
|
|
45
|
-
"@1agh/maude-darwin-x64": "0.
|
|
46
|
-
"@1agh/maude-linux-arm64": "0.
|
|
47
|
-
"@1agh/maude-linux-arm64-musl": "0.
|
|
48
|
-
"@1agh/maude-linux-x64": "0.
|
|
49
|
-
"@1agh/maude-linux-x64-musl": "0.
|
|
50
|
-
"@1agh/maude-win32-x64": "0.
|
|
44
|
+
"@1agh/maude-darwin-arm64": "0.18.1",
|
|
45
|
+
"@1agh/maude-darwin-x64": "0.18.1",
|
|
46
|
+
"@1agh/maude-linux-arm64": "0.18.1",
|
|
47
|
+
"@1agh/maude-linux-arm64-musl": "0.18.1",
|
|
48
|
+
"@1agh/maude-linux-x64": "0.18.1",
|
|
49
|
+
"@1agh/maude-linux-x64-musl": "0.18.1",
|
|
50
|
+
"@1agh/maude-win32-x64": "0.18.1"
|
|
51
51
|
},
|
|
52
52
|
"files": [
|
|
53
53
|
"cli",
|
|
@@ -64,6 +64,18 @@ else
|
|
|
64
64
|
[ -z "$OUT" ] && { echo "screenshot.sh: --out required for single-shot modes" >&2; exit 2; }
|
|
65
65
|
fi
|
|
66
66
|
|
|
67
|
+
# TSX specimens cannot be opened via file:// — the browser would see raw JSX.
|
|
68
|
+
# They must go through the dev-server route (http://localhost:PORT/<rel>),
|
|
69
|
+
# which transpiles via _canvas-shell.html?canvas=<rel>. Phase 19 / DDR-044.
|
|
70
|
+
case "$URL" in
|
|
71
|
+
file://*.tsx)
|
|
72
|
+
echo "screenshot.sh: TSX specimens cannot be screenshot via file:// (the browser sees raw JSX)." >&2
|
|
73
|
+
echo " Use --port instead — the dev-server compiles TSX through _canvas-shell.html?canvas=<rel>." >&2
|
|
74
|
+
echo " Example: screenshot.sh --port 4399 --full --out shot.png (set the active canvas in the browser first)" >&2
|
|
75
|
+
exit 2
|
|
76
|
+
;;
|
|
77
|
+
esac
|
|
78
|
+
|
|
67
79
|
# ---------- url resolution ----------
|
|
68
80
|
if [ -z "$URL" ]; then
|
|
69
81
|
REPO="${ROOT:-${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}}"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Boot-time artifact check — Phase 19 / DDR-044, simplified in v0.18.1.
|
|
2
|
+
//
|
|
3
|
+
// The two artifacts the server cannot run without:
|
|
4
|
+
// - dist/client.bundle.js (the React shell that hydrates the / route)
|
|
5
|
+
// - dist/runtime/react.js (pre-built canvas-runtime bundle for TSX iframes)
|
|
6
|
+
//
|
|
7
|
+
// Both are committed to git per DDR-044 and ship in every distribution:
|
|
8
|
+
// npm tarball (via package.json#files override of .gitignore), marketplace
|
|
9
|
+
// cache (negation entries in .gitignore preserve them through git clone),
|
|
10
|
+
// and bun --compile binary (embedded via the build pipeline).
|
|
11
|
+
//
|
|
12
|
+
// v0.18.0 ALSO tried to `bun install --production` if node_modules/react
|
|
13
|
+
// was missing. That assumption was wrong: (a) npm install of the root
|
|
14
|
+
// @1agh/maude package never installs nested workspace deps, (b) the
|
|
15
|
+
// compiled binary's import.meta.url resolves to the virtual /$bunfs/root
|
|
16
|
+
// so existsSync against it always failed and the self-heal false-triggered,
|
|
17
|
+
// (c) standalone bun --compile binaries don't inherit shell PATH the same
|
|
18
|
+
// way subshells do, so even when bun WAS available, Bun.spawn(['bun',...])
|
|
19
|
+
// failed with ENOENT. The greenfield npm-install user hit all three at
|
|
20
|
+
// once and got a stacktrace. v0.18.1 drops the install/build attempt
|
|
21
|
+
// entirely — pre-built runtime bundles ship with the artifact, no fix-up
|
|
22
|
+
// pass needed.
|
|
23
|
+
|
|
24
|
+
import { existsSync } from 'node:fs';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
|
|
27
|
+
import { DEV_SERVER_ROOT, DIST_DIR, RUNTIME_BUNDLES_DIR } from './paths.ts';
|
|
28
|
+
|
|
29
|
+
export interface SelfHealOptions {
|
|
30
|
+
/** Defaults to DEV_SERVER_ROOT from paths.ts (real disk install dir). */
|
|
31
|
+
here?: string;
|
|
32
|
+
/** Defaults to console.error; tests override to capture. */
|
|
33
|
+
log?: (msg: string) => void;
|
|
34
|
+
/** Defaults to process.exit; tests override to assert without aborting. */
|
|
35
|
+
exit?: (code: number) => never;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface SelfHealResult {
|
|
39
|
+
/** Names of artifacts the check verified are present. */
|
|
40
|
+
verified: ('client.bundle.js' | 'runtime/react.js')[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Verify the committed artifacts the dev-server depends on are reachable
|
|
45
|
+
* from the resolved install dir. If anything is missing, exit with a clear
|
|
46
|
+
* remediation message — this means the install is broken, not a transient
|
|
47
|
+
* first-boot gap. Always passes for npm installs, marketplace cache clones,
|
|
48
|
+
* and `bun --compile` binaries built on a freshly-built repo.
|
|
49
|
+
*/
|
|
50
|
+
export async function bootSelfHeal(opts: SelfHealOptions = {}): Promise<SelfHealResult> {
|
|
51
|
+
const here = opts.here ?? DEV_SERVER_ROOT;
|
|
52
|
+
const log = opts.log ?? ((m) => console.error(m));
|
|
53
|
+
const exit =
|
|
54
|
+
opts.exit ??
|
|
55
|
+
((code: number) => {
|
|
56
|
+
process.exit(code);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const dist = here === DEV_SERVER_ROOT ? DIST_DIR : join(here, 'dist');
|
|
60
|
+
const runtime = here === DEV_SERVER_ROOT ? RUNTIME_BUNDLES_DIR : join(dist, 'runtime');
|
|
61
|
+
|
|
62
|
+
const missing: string[] = [];
|
|
63
|
+
if (!existsSync(join(dist, 'client.bundle.js'))) missing.push('dist/client.bundle.js');
|
|
64
|
+
if (!existsSync(join(runtime, 'react.js'))) missing.push('dist/runtime/react.js');
|
|
65
|
+
|
|
66
|
+
if (missing.length > 0) {
|
|
67
|
+
log(
|
|
68
|
+
[
|
|
69
|
+
'',
|
|
70
|
+
' ⚠ dev-server install is missing committed artifacts:',
|
|
71
|
+
...missing.map((m) => ` - ${m}`),
|
|
72
|
+
'',
|
|
73
|
+
` Looked under: ${here}`,
|
|
74
|
+
'',
|
|
75
|
+
' This means your install is corrupted or pre-Phase-19.1. Fix:',
|
|
76
|
+
' npm uninstall -g @1agh/maude && npm i -g @1agh/maude',
|
|
77
|
+
' (or remove + re-add the marketplace plugin in Claude Code)',
|
|
78
|
+
'',
|
|
79
|
+
].join('\n')
|
|
80
|
+
);
|
|
81
|
+
exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
verified: ['client.bundle.js', 'runtime/react.js'],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -65,13 +65,29 @@ function ensureDist() {
|
|
|
65
65
|
if (!existsSync(DIST)) mkdirSync(DIST, { recursive: true });
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
async function readPluginVersion(): Promise<{ version: string }> {
|
|
69
|
+
// plugins/design/dev-server/ → plugins/design/.claude-plugin/plugin.json
|
|
70
|
+
const manifest = join(ROOT, '..', '.claude-plugin', 'plugin.json');
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(await Bun.file(manifest).text()) as { version?: unknown };
|
|
73
|
+
if (typeof parsed.version === 'string') return { version: parsed.version };
|
|
74
|
+
} catch {
|
|
75
|
+
/* fall through to dev default */
|
|
76
|
+
}
|
|
77
|
+
return { version: 'dev' };
|
|
78
|
+
}
|
|
79
|
+
|
|
68
80
|
// ---------- (a) Client JSX bundle ----------
|
|
69
81
|
|
|
70
82
|
async function buildClient(): Promise<{ outBytes: number; outPath: string }> {
|
|
71
83
|
ensureDist();
|
|
72
84
|
const outPath = join(DIST, 'client.bundle.js');
|
|
73
|
-
//
|
|
74
|
-
|
|
85
|
+
// Wordmark sub-line version. Read from plugins/design/.claude-plugin/plugin.json —
|
|
86
|
+
// that file ships in both npm installs AND marketplace-cache clones (it's the
|
|
87
|
+
// plugin manifest, always present). The old `../../../package.json` hop
|
|
88
|
+
// resolved to the repo root in dev but ENOENT'd in marketplace caches where
|
|
89
|
+
// the maude bundle isn't installed as a package. DDR-044, Phase 19.
|
|
90
|
+
const pkg = await readPluginVersion();
|
|
75
91
|
const result = await Bun.build({
|
|
76
92
|
entrypoints: [join(ROOT, 'client/app.jsx')],
|
|
77
93
|
outdir: DIST,
|
|
@@ -120,6 +136,35 @@ async function buildCss(): Promise<{ outBytes: number; outPath: string }> {
|
|
|
120
136
|
return { outBytes: code.byteLength, outPath };
|
|
121
137
|
}
|
|
122
138
|
|
|
139
|
+
// ---------- (b.5) Pre-built runtime bundles (Phase 19.1 / v0.18.1) ----------
|
|
140
|
+
//
|
|
141
|
+
// /_canvas-runtime/<slug>.js used to lazy-build on first request via Bun.build.
|
|
142
|
+
// That required a real disk node_modules/react reachable by walking up from
|
|
143
|
+
// the dev-server dir — false in compiled binaries (paths are virtual) AND
|
|
144
|
+
// false in npm installs (npm doesn't install nested workspace deps).
|
|
145
|
+
// Pre-building all 6 sub-bundles at release time + shipping in dist/runtime/
|
|
146
|
+
// eliminates the runtime dependency on disk node_modules entirely.
|
|
147
|
+
|
|
148
|
+
async function buildRuntimeBundles(): Promise<{ outDir: string; count: number; bytes: number }> {
|
|
149
|
+
// Defer import so build.ts can run in --dry-run without pulling react.
|
|
150
|
+
const { RUNTIME_PACKAGES, getRuntimeBundle, slugFor } = await import('./runtime-bundle.ts');
|
|
151
|
+
const outDir = join(DIST, 'runtime');
|
|
152
|
+
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
|
|
153
|
+
let bytes = 0;
|
|
154
|
+
for (const pkg of RUNTIME_PACKAGES) {
|
|
155
|
+
const slug = slugFor(pkg);
|
|
156
|
+
// skipPrebuilt: don't reuse a previous build's output. minify in release.
|
|
157
|
+
const bundle = await getRuntimeBundle(pkg, {
|
|
158
|
+
skipPrebuilt: true,
|
|
159
|
+
minify: MODE === 'release',
|
|
160
|
+
});
|
|
161
|
+
const outPath = join(outDir, `${slug}.js`);
|
|
162
|
+
await Bun.write(outPath, bundle.js);
|
|
163
|
+
bytes += bundle.js.length;
|
|
164
|
+
}
|
|
165
|
+
return { outDir, count: RUNTIME_PACKAGES.length, bytes };
|
|
166
|
+
}
|
|
167
|
+
|
|
123
168
|
// ---------- (c) Server binary (bun build --compile, per-platform) ----------
|
|
124
169
|
|
|
125
170
|
// Per-target oxc-parser binding embed. Bun 1.3.4+ regressed `--compile` NAPI
|
|
@@ -357,6 +402,15 @@ async function main() {
|
|
|
357
402
|
`[build] styles.css ${css.outBytes.toLocaleString()} B (${(t2 - t1).toFixed(0)} ms)`
|
|
358
403
|
);
|
|
359
404
|
|
|
405
|
+
// Pre-built runtime bundles — ship to disk so /_canvas-runtime/* never
|
|
406
|
+
// needs a runtime Bun.build (which would need disk node_modules/react,
|
|
407
|
+
// absent in compiled binaries + npm installs). Phase 19.1 / v0.18.1.
|
|
408
|
+
const runtime = await buildRuntimeBundles();
|
|
409
|
+
const t2b = performance.now();
|
|
410
|
+
console.log(
|
|
411
|
+
`[build] dist/runtime/*.js ${runtime.bytes.toLocaleString()} B in ${runtime.count} files (${(t2b - t2).toFixed(0)} ms)`
|
|
412
|
+
);
|
|
413
|
+
|
|
360
414
|
if (MODE === 'release') {
|
|
361
415
|
const targets: PlatformTarget[] = FLAG_TARGET
|
|
362
416
|
? [FLAG_TARGET as PlatformTarget]
|
|
@@ -116,6 +116,18 @@
|
|
|
116
116
|
},
|
|
117
117
|
"default": ["accent"]
|
|
118
118
|
},
|
|
119
|
+
"accentStrategy": {
|
|
120
|
+
"type": "string",
|
|
121
|
+
"description": "How many --accent* families exist. The completeness-critic C7 gates the actual family count against this declaration. Default: 'single' (backwards-compatible). 'chromatic-N' is parameterized — write the literal N (e.g. 'chromatic-5'). Per DDR-043.",
|
|
122
|
+
"pattern": "^(single|paired|chromatic-[1-9][0-9]?)$",
|
|
123
|
+
"default": "single"
|
|
124
|
+
},
|
|
125
|
+
"colorSpace": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"enum": ["oklch", "hsl", "hex", "lab"],
|
|
128
|
+
"description": "Color space the project uses in tokens CSS. The completeness-critic V2 gates the actual token format against this declaration. Default: 'oklch' (backwards-compatible). Per DDR-043.",
|
|
129
|
+
"default": "oklch"
|
|
130
|
+
},
|
|
119
131
|
"designSystems": {
|
|
120
132
|
"type": "array",
|
|
121
133
|
"description": "Design systems available in this project. Single-DS projects have one entry; multi-DS projects (marketing vs. admin vs. mobile) list each here. Each canvas's .meta.json declares which DS it uses via the 'designSystem' field.",
|