@calo-design/cli 0.3.0 → 0.4.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/README.md +10 -0
- package/bin/cli.js +16 -1
- package/bin/login.js +1 -1
- package/bin/mirror-push.js +16 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,16 @@ npx @calo-design/cli login # one-time: your Calo email + the emailed code
|
|
|
18
18
|
npx @calo-design/cli init # skill + the shared ds/flows runtime, and a prototype here
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
> **`@calo-design/cli` is a public npm package.** If npx reports it can't be found — "not in
|
|
22
|
+
> this registry", "404", or "not a public package" — your npm is pointed at a private or
|
|
23
|
+
> corporate registry that doesn't carry it (common on managed laptops). Check with
|
|
24
|
+
> `npm config get registry` (it should be `https://registry.npmjs.org/`). To run regardless
|
|
25
|
+
> of your `.npmrc`, pin just this scope to public npm:
|
|
26
|
+
>
|
|
27
|
+
> ```bash
|
|
28
|
+
> npx --@calo-design:registry=https://registry.npmjs.org/ @calo-design/cli login
|
|
29
|
+
> ```
|
|
30
|
+
|
|
21
31
|
`init` does two machine-level things every time: it installs the skill into
|
|
22
32
|
`~/.claude/skills/`, and it ensures the shared runtime at `~/.designchef/runtime/` — one
|
|
23
33
|
copy of `@calo/design-system`, `@calo/flows`, Expo and the peers, shared by every
|
package/bin/cli.js
CHANGED
|
@@ -131,9 +131,23 @@ function runtimeExists() {
|
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// expo-router needs babel-preset-expo (its Babel plugin injects the route require.context);
|
|
135
|
+
// without a babel.config.js, `expo export` produces an empty, routeless app. The shared
|
|
136
|
+
// runtime isn't always scaffolded with one, so guarantee it. Linked prototypes inherit it
|
|
137
|
+
// via writeThinConfigs; push staging backstops it again (see mirror-push.js).
|
|
138
|
+
function ensureBabelConfig(dir) {
|
|
139
|
+
const p = path.join(dir, "babel.config.js");
|
|
140
|
+
if (fs.existsSync(p)) return;
|
|
141
|
+
fs.writeFileSync(p, 'module.exports = (api) => {\n api.cache(true);\n return { presets: ["babel-preset-expo"] };\n};\n');
|
|
142
|
+
}
|
|
143
|
+
|
|
134
144
|
async function ensureRuntime({ force } = {}) {
|
|
135
145
|
const rt = runtimeDir();
|
|
136
|
-
if (!force && runtimeExists()) {
|
|
146
|
+
if (!force && runtimeExists()) {
|
|
147
|
+
ensureBabelConfig(rt); // backfill: runtimes built before this shipped no babel.config.js
|
|
148
|
+
ok(`shared runtime ready (${tilde(rt)})`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
137
151
|
log(c.b("\n[runtime] Building the shared Calo runtime (one-time, ~a couple of minutes)"));
|
|
138
152
|
fs.mkdirSync(rt, { recursive: true });
|
|
139
153
|
if (force) {
|
|
@@ -144,6 +158,7 @@ async function ensureRuntime({ force } = {}) {
|
|
|
144
158
|
if (!scaffoldExpoApp(rt)) throw new Error("runtime scaffold failed");
|
|
145
159
|
}
|
|
146
160
|
await installCaloDeps(rt);
|
|
161
|
+
ensureBabelConfig(rt); // a freshly scaffolded runtime may also lack one
|
|
147
162
|
fs.writeFileSync(
|
|
148
163
|
runtimeManifestPath(),
|
|
149
164
|
JSON.stringify({ builtAt: new Date().toISOString(), pkgSpecs: PKG_SPECS, peers: PEERS }, null, 2) + "\n"
|
package/bin/login.js
CHANGED
|
@@ -179,7 +179,7 @@ async function publishWeb({ slug, project, tarball }) {
|
|
|
179
179
|
const text = await res.text();
|
|
180
180
|
let json;
|
|
181
181
|
try { json = text ? JSON.parse(text) : {}; } catch { json = { raw: text }; }
|
|
182
|
-
if (!res.ok) throw new Error(json.error || `publish-web → HTTP ${res.status}
|
|
182
|
+
if (!res.ok) throw new Error([json.error || `publish-web → HTTP ${res.status}`, json.detail].filter(Boolean).join("\n "));
|
|
183
183
|
return json;
|
|
184
184
|
}
|
|
185
185
|
|
package/bin/mirror-push.js
CHANGED
|
@@ -122,6 +122,18 @@ function writeJSON(p, obj) {
|
|
|
122
122
|
fs.writeFileSync(p, JSON.stringify(obj, null, 2) + "\n");
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// A babel.config.js with babel-preset-expo MUST exist wherever `expo export` runs. Without
|
|
126
|
+
// it the expo-router Babel plugin never injects the route require.context, so the export is
|
|
127
|
+
// a routeless, empty shell (no screens, no design system, no assets). The shared runtime
|
|
128
|
+
// doesn't always ship one, so guarantee it: prefer the prototype's own config, else default.
|
|
129
|
+
function ensureBabelConfig(dir, fallbackFrom) {
|
|
130
|
+
const dst = path.join(dir, "babel.config.js");
|
|
131
|
+
if (fs.existsSync(dst)) return;
|
|
132
|
+
const fb = fallbackFrom && path.join(fallbackFrom, "babel.config.js");
|
|
133
|
+
if (fb && fs.existsSync(fb)) { fs.cpSync(fb, dst); return; }
|
|
134
|
+
fs.writeFileSync(dst, 'module.exports = (api) => {\n api.cache(true);\n return { presets: ["babel-preset-expo"] };\n};\n');
|
|
135
|
+
}
|
|
136
|
+
|
|
125
137
|
function stageProject({ root, stage, slug, title, ad }) {
|
|
126
138
|
// Copy the author's routes + assets verbatim.
|
|
127
139
|
const stageSrcParent = path.join(stage, path.relative(root, path.dirname(ad)));
|
|
@@ -164,6 +176,9 @@ function stageProject({ root, stage, slug, title, ad }) {
|
|
|
164
176
|
const src = path.join(runtimeDir(), f);
|
|
165
177
|
if (fs.existsSync(src)) fs.cpSync(src, path.join(stage, f));
|
|
166
178
|
}
|
|
179
|
+
// The runtime may not have a babel.config.js; without one the staged export is an empty,
|
|
180
|
+
// routeless app. Backstop it from the prototype's own config, else a default.
|
|
181
|
+
ensureBabelConfig(stage, root);
|
|
167
182
|
|
|
168
183
|
writeMetroConfig(stage);
|
|
169
184
|
linkNodeModules(stage);
|
|
@@ -213,7 +228,7 @@ function injectBackChrome({ stagedAppDir, mirrorChromeDir, libRel }) {
|
|
|
213
228
|
if (fs.existsSync(layout)) {
|
|
214
229
|
const cur = fs.readFileSync(layout, "utf8");
|
|
215
230
|
const standard = /useFonts\(caloFonts\)/.test(cur) && /<Stack/.test(cur);
|
|
216
|
-
if (!standard) warn("custom root _layout detected — Mirror wraps it with a Stack;
|
|
231
|
+
if (!standard) warn("custom root _layout detected — Mirror wraps it with a Stack; providers in the ROOT layout won't carry over. Move them to a nested layout (e.g. src/app/(group)/_layout.tsx), which the Mirror preserves.");
|
|
217
232
|
}
|
|
218
233
|
fs.writeFileSync(
|
|
219
234
|
layout,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@calo-design/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
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": { "calo-design": "bin/cli.js" },
|
|
6
6
|
"files": ["bin"],
|