@calo-design/cli 0.4.3 → 0.4.4
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/bin/cli.js +72 -0
- package/bin/templates/gallery-assets/component-gallery/meal-photo.png +0 -0
- package/bin/templates/gallery-assets/component-gallery/smoothie-photo.png +0 -0
- package/bin/templates/gallery-assets/live-flows/active-subscriber-home/ingredient-penne.png +0 -0
- package/bin/templates/gallery-index.tsx +1678 -0
- package/bin/templates/gallery-suppress.ts +50 -0
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -408,6 +408,44 @@ export default function Index() {
|
|
|
408
408
|
`);
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
+
// The component gallery's routes: a root layout (fonts + providers, no local imports so it's
|
|
412
|
+
// portable) and the @calo/design-system showroom (bundled with the CLI) as the index route.
|
|
413
|
+
// Always (re)written so a `calo-design update` + relaunch also ships the latest showroom.
|
|
414
|
+
function writeGalleryApp(projectRoot) {
|
|
415
|
+
const srcDir = path.join(projectRoot, "src");
|
|
416
|
+
const appDir = path.join(srcDir, "app");
|
|
417
|
+
fs.mkdirSync(appDir, { recursive: true });
|
|
418
|
+
// Silences known non-actionable RNW-on-React-19 dev warnings (nested Pressables, deprecated
|
|
419
|
+
// style props) so the embedded gallery has a clean overlay. Imported first in _layout.
|
|
420
|
+
fs.cpSync(path.join(__dirname, "templates", "gallery-suppress.ts"), path.join(srcDir, "suppress-dev-warnings.ts"));
|
|
421
|
+
fs.writeFileSync(path.join(appDir, "_layout.tsx"), `import "../suppress-dev-warnings";
|
|
422
|
+
import { Stack } from "expo-router";
|
|
423
|
+
import { useFonts } from "expo-font";
|
|
424
|
+
import { CaloBottomSheetProvider, CaloScreen, caloFonts, caloTokens } from "@calo/design-system";
|
|
425
|
+
import { SafeAreaProvider } from "react-native-safe-area-context";
|
|
426
|
+
|
|
427
|
+
export default function Layout() {
|
|
428
|
+
const [loaded] = useFonts(caloFonts);
|
|
429
|
+
return (
|
|
430
|
+
<SafeAreaProvider>
|
|
431
|
+
{loaded ? (
|
|
432
|
+
<CaloBottomSheetProvider>
|
|
433
|
+
<Stack screenOptions={{ headerShown: false, contentStyle: { backgroundColor: caloTokens.color.canvas } }} />
|
|
434
|
+
</CaloBottomSheetProvider>
|
|
435
|
+
) : (
|
|
436
|
+
<CaloScreen />
|
|
437
|
+
)}
|
|
438
|
+
</SafeAreaProvider>
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
`);
|
|
442
|
+
const showroom = fs.readFileSync(path.join(__dirname, "templates", "gallery-index.tsx"), "utf8");
|
|
443
|
+
fs.writeFileSync(path.join(appDir, "index.tsx"), showroom);
|
|
444
|
+
// The showroom require()s a few local images (../assets/... from src/app) — ship them too.
|
|
445
|
+
const assetsSrc = path.join(__dirname, "templates", "gallery-assets");
|
|
446
|
+
if (fs.existsSync(assetsSrc)) fs.cpSync(assetsSrc, path.join(projectRoot, "src", "assets"), { recursive: true });
|
|
447
|
+
}
|
|
448
|
+
|
|
411
449
|
function writeGitignore(projectRoot) {
|
|
412
450
|
const gi = path.join(projectRoot, ".gitignore");
|
|
413
451
|
const needed = ["node_modules/", ".expo/", "dist/", "*.log"];
|
|
@@ -602,6 +640,37 @@ async function cmdFeed() {
|
|
|
602
640
|
for (const e of data.events) log(`${c.dim(e.ts)} ${e.email} ${c.b(e.action)} ${e.target || ""}`);
|
|
603
641
|
}
|
|
604
642
|
|
|
643
|
+
// Serve the component gallery (the @calo/design-system showroom) locally, rendered LIVE from
|
|
644
|
+
// the shared runtime — so `calo-design update` keeps it current (no rebuild/redeploy). Design
|
|
645
|
+
// Kitchen auto-starts this; it also works standalone in a terminal. Runs Metro in the
|
|
646
|
+
// foreground so whoever launched it owns the process lifecycle.
|
|
647
|
+
async function cmdGallery() {
|
|
648
|
+
if (!runtimeExists()) {
|
|
649
|
+
throw new Error("The Calo runtime isn't set up on this machine yet — run `calo-design init` first, then retry.");
|
|
650
|
+
}
|
|
651
|
+
const dir = path.join(designchefHome(), "gallery");
|
|
652
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
653
|
+
// Materialize / refresh a thin project linked to the shared runtime (same machinery as
|
|
654
|
+
// a linked prototype), then swap in the showroom routes.
|
|
655
|
+
writeThinConfigs(dir);
|
|
656
|
+
ensureBabelConfig(dir);
|
|
657
|
+
writeMetroConfig(dir);
|
|
658
|
+
writeGitignore(dir);
|
|
659
|
+
linkNodeModules(dir);
|
|
660
|
+
writeGalleryApp(dir);
|
|
661
|
+
|
|
662
|
+
let port = "8091";
|
|
663
|
+
const pj = args.find((a) => a.startsWith("--port="));
|
|
664
|
+
if (pj) port = pj.slice(7);
|
|
665
|
+
else { const pi = args.indexOf("--port"); if (pi >= 0) port = args[pi + 1] || port; }
|
|
666
|
+
if (!/^\d+$/.test(port)) port = "8091";
|
|
667
|
+
|
|
668
|
+
log(c.b(`\n[gallery] Serving the Calo component gallery on http://localhost:${port}`));
|
|
669
|
+
log(c.dim(` Live from the shared runtime (${tilde(runtimeDir())}) — always the installed @calo/design-system.`));
|
|
670
|
+
log(c.dim(" First launch compiles the design system (~30–60s). Ctrl-C to stop."));
|
|
671
|
+
run("npx", ["expo", "start", "--web", "--port", port], { cwd: dir });
|
|
672
|
+
}
|
|
673
|
+
|
|
605
674
|
function help() {
|
|
606
675
|
log(`${c.b("calo-design")} — one-line setup for Calo design tooling
|
|
607
676
|
|
|
@@ -617,6 +686,8 @@ function help() {
|
|
|
617
686
|
${c.dim(" push --slug x --title \"…\" --owner \"…\" --screenshot path --dry-run --direct")}
|
|
618
687
|
${c.dim("share")} publish THIS web prototype (React/Vite/CRA/Next) to Cloudflare Pages → share link
|
|
619
688
|
${c.dim(" share --slug x --dir dist --build --project calo-prototypes --dry-run")}
|
|
689
|
+
${c.dim("gallery")} serve the @calo/design-system component gallery locally (live from the runtime)
|
|
690
|
+
${c.dim(" gallery --port 8091")}
|
|
620
691
|
|
|
621
692
|
Login is required once before init; the session refreshes automatically.
|
|
622
693
|
init always installs the skill and ensures the shared ds/flows runtime on your machine;
|
|
@@ -636,6 +707,7 @@ function help() {
|
|
|
636
707
|
else if (cmd === "share") await cmdShare(args.slice(1));
|
|
637
708
|
else if (cmd === "feed") await cmdFeed();
|
|
638
709
|
else if (cmd === "whoami") await cmdWhoami();
|
|
710
|
+
else if (cmd === "gallery") await cmdGallery();
|
|
639
711
|
else help();
|
|
640
712
|
} catch (err) {
|
|
641
713
|
// Diagnostics go to stderr so stdout stays pure for machine callers (The Pass parses
|
|
Binary file
|