@kurajs/cli 0.0.3 → 0.0.5
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/dist/cli.js +110 -9
- package/package.json +11 -6
package/dist/cli.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
// and never reads the filesystem (Workers-safe; mirrors June's app/_content.ts freeze).
|
|
7
7
|
// A content hash short-circuits re-embedding when nothing changed (cheap to run pre-dev).
|
|
8
8
|
import { buildIndex } from "@kurajs/docs/search";
|
|
9
|
-
import { transformers } from "@kurajs/transformers";
|
|
10
9
|
import fs from "node:fs";
|
|
11
10
|
import path from "node:path";
|
|
12
11
|
import crypto from "node:crypto";
|
|
12
|
+
import { spawn } from "node:child_process";
|
|
13
13
|
import { pathToFileURL } from "node:url";
|
|
14
14
|
function arg(name, def) {
|
|
15
15
|
const i = process.argv.indexOf(`--${name}`);
|
|
@@ -73,6 +73,12 @@ async function cmdIndex() {
|
|
|
73
73
|
const localeTag = locales.size ? ` (+${variants.length} variants across ${locales.size} locales)` : "";
|
|
74
74
|
console.log(`kura index: embedding ${DOCS.length} docs${localeTag} (model ${model})…`);
|
|
75
75
|
const t0 = Date.now();
|
|
76
|
+
// Lazy import: only the embed path needs the ML stack, so --no-embed sites never load it
|
|
77
|
+
// (and never install @kurajs/transformers — it's an optional peer).
|
|
78
|
+
const { transformers } = await import("@kurajs/transformers").catch(() => {
|
|
79
|
+
console.error("kura index: embedding needs @kurajs/transformers — install it, or use --no-embed.");
|
|
80
|
+
return process.exit(1);
|
|
81
|
+
});
|
|
76
82
|
const bytes = await buildIndex({ entries: allEntries, embedder: transformers({ model }) });
|
|
77
83
|
const b64 = Buffer.from(bytes).toString("base64");
|
|
78
84
|
fs.writeFileSync(indexTs, stamp +
|
|
@@ -111,13 +117,108 @@ async function cmdIndex() {
|
|
|
111
117
|
const tag = locales.size ? ` across ${locales.size + 1} locales` : "";
|
|
112
118
|
console.log(`kura index: rendered ${ok}/${total} docs via MDX${tag} -> app/_mdx.ts`);
|
|
113
119
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
// One Kura surface over June: dev / build / deploy each freeze content (june gen) + the search
|
|
121
|
+
// index/MDX (kura index), then hand off to the `june` bin — which loads its own TS source and
|
|
122
|
+
// owns the dev watch supervisor. Users only ever type `kura`.
|
|
123
|
+
const flag = (name) => process.argv.includes(`--${name}`);
|
|
124
|
+
// Forward extra args to june, dropping the kura-only flags (--no-embed, --model <v>).
|
|
125
|
+
function passthrough() {
|
|
126
|
+
const out = [];
|
|
127
|
+
const a = process.argv.slice(3);
|
|
128
|
+
for (let i = 0; i < a.length; i++) {
|
|
129
|
+
if (a[i] === "--no-embed")
|
|
130
|
+
continue;
|
|
131
|
+
if (a[i] === "--model") {
|
|
132
|
+
i++;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
out.push(a[i]);
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
117
138
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
139
|
+
// Find the `june` bin shim, walking up so it works both in a standalone app (local node_modules)
|
|
140
|
+
// and a workspace member (the bin is hoisted to the root node_modules/.bin).
|
|
141
|
+
function findJuneBin(cwd) {
|
|
142
|
+
const name = process.platform === "win32" ? "june.cmd" : "june";
|
|
143
|
+
let dir = cwd;
|
|
144
|
+
for (;;) {
|
|
145
|
+
const p = path.join(dir, "node_modules", ".bin", name);
|
|
146
|
+
if (fs.existsSync(p))
|
|
147
|
+
return p;
|
|
148
|
+
const parent = path.dirname(dir);
|
|
149
|
+
if (parent === dir)
|
|
150
|
+
return null;
|
|
151
|
+
dir = parent;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Run the app's `june` bin (it handles TS loading + the dev watcher); resolve with its exit code.
|
|
155
|
+
function runJune(cwd, args) {
|
|
156
|
+
const bin = findJuneBin(cwd);
|
|
157
|
+
if (!bin) {
|
|
158
|
+
console.error("kura: couldn't find the `june` bin — is @junejs/cli installed?");
|
|
159
|
+
return Promise.resolve(1);
|
|
160
|
+
}
|
|
161
|
+
return new Promise((resolve) => {
|
|
162
|
+
const child = spawn(bin, args, { stdio: "inherit" });
|
|
163
|
+
child.on("error", (e) => {
|
|
164
|
+
console.error(`kura: couldn't run june (${e.message}).`);
|
|
165
|
+
resolve(1);
|
|
166
|
+
});
|
|
167
|
+
child.on("exit", (code) => resolve(code ?? 0));
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// Run `kura index` in a SHORT-LIVED child so the embedder's native runtime (onnxruntime) is
|
|
171
|
+
// loaded and torn down in its own process — keeping the long-running dev/build/deploy parent
|
|
172
|
+
// ML-free (and dodging ORT's noisy teardown on some platforms).
|
|
173
|
+
function runKuraIndex(cwd) {
|
|
174
|
+
const args = [process.argv[1], "index"];
|
|
175
|
+
if (flag("no-embed"))
|
|
176
|
+
args.push("--no-embed");
|
|
177
|
+
const model = arg("model");
|
|
178
|
+
if (model)
|
|
179
|
+
args.push("--model", model);
|
|
180
|
+
return new Promise((resolve) => {
|
|
181
|
+
const child = spawn(process.execPath, args, { stdio: "inherit", cwd });
|
|
182
|
+
child.on("error", (e) => { console.error(`kura: index failed (${e.message}).`); resolve(1); });
|
|
183
|
+
child.on("exit", (code) => resolve(code ?? 0));
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
async function freeze(cwd) {
|
|
187
|
+
let code = await runJune(cwd, ["gen"]); // june gen → app/_content.ts
|
|
188
|
+
if (code)
|
|
189
|
+
process.exit(code);
|
|
190
|
+
code = await runKuraIndex(cwd); // kura index → app/_index.ts + _mdx.ts (own process)
|
|
191
|
+
if (code)
|
|
192
|
+
process.exit(code);
|
|
193
|
+
}
|
|
194
|
+
const cmd = process.argv[2];
|
|
195
|
+
const cwd = process.cwd();
|
|
196
|
+
switch (cmd) {
|
|
197
|
+
case "index":
|
|
198
|
+
await cmdIndex();
|
|
199
|
+
break;
|
|
200
|
+
case "dev":
|
|
201
|
+
await freeze(cwd);
|
|
202
|
+
process.exit(await runJune(cwd, ["dev", ...passthrough()]));
|
|
203
|
+
break;
|
|
204
|
+
case "build":
|
|
205
|
+
await freeze(cwd);
|
|
206
|
+
process.exit(await runJune(cwd, ["build", ...passthrough()]));
|
|
207
|
+
break;
|
|
208
|
+
case "deploy": {
|
|
209
|
+
await freeze(cwd);
|
|
210
|
+
const dargs = ["deploy"];
|
|
211
|
+
for (const f of ["dry-run", "prod", "skip-migrate", "allow-destructive"])
|
|
212
|
+
if (flag(f))
|
|
213
|
+
dargs.push(`--${f}`);
|
|
214
|
+
process.exit(await runJune(cwd, dargs));
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
default:
|
|
218
|
+
console.log("Kura CLI\n" +
|
|
219
|
+
" kura dev [--no-embed] freeze content + index, then run the dev server\n" +
|
|
220
|
+
" kura build [--no-embed] freeze + build the Worker bundle\n" +
|
|
221
|
+
" kura deploy [--no-embed] freeze + deploy to Cloudflare ([--dry-run] [--prod])\n" +
|
|
222
|
+
" kura index [--no-embed] [--model <hf-model>] (re)build the search index + MDX only");
|
|
223
|
+
process.exit(cmd ? 1 : 0);
|
|
123
224
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kurajs/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Kura CLI — build
|
|
5
|
+
"description": "Kura CLI — dev, build, deploy, and index a Kura docs app (one surface over June).",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kura": "dist/cli.js"
|
|
8
8
|
},
|
|
@@ -15,14 +15,19 @@
|
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@kurajs/core": "^0.0.1",
|
|
18
|
-
"@kurajs/docs": "^0.0.3"
|
|
19
|
-
"@kurajs/transformers": "^0.0.1"
|
|
18
|
+
"@kurajs/docs": "^0.0.3"
|
|
20
19
|
},
|
|
21
20
|
"peerDependencies": {
|
|
22
|
-
"@
|
|
21
|
+
"@junejs/cli": "^0.0.25",
|
|
22
|
+
"@kurajs/transformers": "^0.0.1"
|
|
23
|
+
},
|
|
24
|
+
"peerDependenciesMeta": {
|
|
25
|
+
"@kurajs/transformers": {
|
|
26
|
+
"optional": true
|
|
27
|
+
}
|
|
23
28
|
},
|
|
24
29
|
"devDependencies": {
|
|
25
|
-
"@
|
|
30
|
+
"@kurajs/transformers": "*",
|
|
26
31
|
"typescript": "^5.7.0"
|
|
27
32
|
},
|
|
28
33
|
"author": "Lawrence Lin",
|