@calo-design/cli 0.4.4 → 0.4.6
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 +44 -2
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -589,16 +589,35 @@ async function cmdUpdate() {
|
|
|
589
589
|
// Re-pin when the runtime is fully present OR merely scaffolded (package.json on disk),
|
|
590
590
|
// so a half-installed runtime self-heals via plain `update` instead of being stranded.
|
|
591
591
|
const scaffolded = fs.existsSync(path.join(runtimeDir(), "package.json"));
|
|
592
|
+
// Snapshot the pinned @calo commit SHAs BEFORE re-pinning, so we can tell whether this update
|
|
593
|
+
// actually moved anything. The design system is git-HEAD-tracked (pinned by commit, not by an
|
|
594
|
+
// npm version bump — its package.json version can sit unchanged across many real commits), so
|
|
595
|
+
// the SHA is the true "did anything change" signal.
|
|
596
|
+
const before = installedCaloShas(runtimeDir()) || {};
|
|
597
|
+
let repinned = false;
|
|
592
598
|
if (runtimeExists() || scaffolded || has("--build")) {
|
|
593
599
|
await ensureRuntime({ force: true });
|
|
594
600
|
ok("shared runtime re-pinned — every linked prototype now uses the latest Calo stack");
|
|
601
|
+
repinned = true;
|
|
595
602
|
} else {
|
|
596
603
|
log(c.dim(" No shared runtime yet — run `calo-design init` in a prototype folder to create one."));
|
|
597
604
|
}
|
|
598
|
-
//
|
|
605
|
+
// Only record an update event when the pinned code ACTUALLY changed (or we can't tell / it's a
|
|
606
|
+
// first install). A no-op re-pin — clicking Update when nothing new shipped — writes nothing,
|
|
607
|
+
// so the feed stops filling with identical "updated the design system to 0.2.0" rows.
|
|
608
|
+
const after = installedCaloShas(runtimeDir()) || {};
|
|
609
|
+
const changed = !Object.keys(before).length || JSON.stringify(before) !== JSON.stringify(after);
|
|
610
|
+
if (repinned && !changed) {
|
|
611
|
+
log(c.dim(" Already up to date — nothing new to record in the feed."));
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
// Tag the feed entry with the DS version we floated to (read fresh from disk, not require()'s
|
|
615
|
+
// cache). Bump @calo/design-system's version on real releases (`npm run release` there) to make
|
|
616
|
+
// this number meaningful — the SHA gate above already guarantees it only logs on real change.
|
|
599
617
|
let dsVersion = "";
|
|
600
618
|
try {
|
|
601
|
-
|
|
619
|
+
const pj = JSON.parse(fs.readFileSync(path.join(runtimeDir(), "node_modules", "@calo", "design-system", "package.json"), "utf8"));
|
|
620
|
+
dsVersion = pj.version || "";
|
|
602
621
|
} catch { /* runtime not present — report without a version */ }
|
|
603
622
|
await reportEvent("update", dsVersion);
|
|
604
623
|
}
|
|
@@ -640,6 +659,28 @@ async function cmdFeed() {
|
|
|
640
659
|
for (const e of data.events) log(`${c.dim(e.ts)} ${e.email} ${c.b(e.action)} ${e.target || ""}`);
|
|
641
660
|
}
|
|
642
661
|
|
|
662
|
+
// Per-prototype analytics (Design Kitchen reads this via `--json`). Same session reuse as
|
|
663
|
+
// the feed; the broker holds the Clarity token and does the caching — this is a dumb pipe.
|
|
664
|
+
async function cmdInsights() {
|
|
665
|
+
const session = await ensureSession();
|
|
666
|
+
let res;
|
|
667
|
+
try {
|
|
668
|
+
res = await fetch(`${BROKER}/v1/clarity/insights`, {
|
|
669
|
+
headers: { authorization: `Bearer ${session}` },
|
|
670
|
+
signal: AbortSignal.timeout(20000),
|
|
671
|
+
});
|
|
672
|
+
} catch (e) {
|
|
673
|
+
throw new Error(`can't reach the Calo broker at ${BROKER} (${e.message})`);
|
|
674
|
+
}
|
|
675
|
+
const text = await res.text();
|
|
676
|
+
if (!res.ok) throw new Error(`insights failed (${res.status}): ${text.slice(0, 200)}`);
|
|
677
|
+
if (has("--json")) { process.stdout.write("\n" + text + "\n"); return; }
|
|
678
|
+
const data = JSON.parse(text);
|
|
679
|
+
const protos = Object.values(data.prototypes || {});
|
|
680
|
+
log(`${data.totals?.sessions ?? 0} sessions across ${protos.length} prototype(s) · last ${data.windowDays} days`);
|
|
681
|
+
for (const p of protos) log(` ${c.b(p.slug || p.host)} ${p.sessions} sessions · ${p.activeSeconds}s active`);
|
|
682
|
+
}
|
|
683
|
+
|
|
643
684
|
// Serve the component gallery (the @calo/design-system showroom) locally, rendered LIVE from
|
|
644
685
|
// the shared runtime — so `calo-design update` keeps it current (no rebuild/redeploy). Design
|
|
645
686
|
// Kitchen auto-starts this; it also works standalone in a terminal. Runs Metro in the
|
|
@@ -706,6 +747,7 @@ function help() {
|
|
|
706
747
|
else if (cmd === "push") await cmdPush(args.slice(1));
|
|
707
748
|
else if (cmd === "share") await cmdShare(args.slice(1));
|
|
708
749
|
else if (cmd === "feed") await cmdFeed();
|
|
750
|
+
else if (cmd === "insights") await cmdInsights();
|
|
709
751
|
else if (cmd === "whoami") await cmdWhoami();
|
|
710
752
|
else if (cmd === "gallery") await cmdGallery();
|
|
711
753
|
else help();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calo-design/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "One-line setup for Calo design tooling: logs in with your Calo email and installs the calo-design skill + design-system packages. No GitHub account needed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"calo-design": "bin/cli.js"
|