@kurajs/cli 0.0.1 → 0.0.2

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.
Files changed (2) hide show
  1. package/dist/cli.js +32 -14
  2. package/package.json +9 -4
package/dist/cli.js CHANGED
@@ -1,12 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  // Kura CLI.
3
- // kura index [--out app/_index.bin] [--model Xenova/bge-m3]
4
- // Build the search index for the current Kura docs app: embed every doc from the
5
- // June-frozen app/_content.ts and write a compact index the app loads at runtime.
3
+ // kura index [--model Xenova/bge-m3]
4
+ // Build the search index + precompiled MDX for the current Kura docs app and FREEZE both
5
+ // as importable modules (app/_index.ts, app/_mdx.ts) so the worker bundle imports them
6
+ // and never reads the filesystem (Workers-safe; mirrors June's app/_content.ts freeze).
7
+ // A content hash short-circuits re-embedding when nothing changed (cheap to run pre-dev).
6
8
  import { buildIndex } from "@kurajs/docs/search";
7
9
  import { transformers } from "@kurajs/transformers";
8
10
  import fs from "node:fs";
9
11
  import path from "node:path";
12
+ import crypto from "node:crypto";
10
13
  import { pathToFileURL } from "node:url";
11
14
  function arg(name, def) {
12
15
  const i = process.argv.indexOf(`--${name}`);
@@ -19,8 +22,9 @@ async function cmdIndex() {
19
22
  console.error("kura index: app/_content.ts not found — run `june gen` first (in a Kura docs app).");
20
23
  process.exit(1);
21
24
  }
22
- const out = arg("out", path.join("app", "_index.bin"));
23
25
  const model = arg("model", "Xenova/bge-m3");
26
+ const indexTs = path.join(cwd, "app", "_index.ts");
27
+ const mdxTs = path.join(cwd, "app", "_mdx.ts");
24
28
  const mod = (await import(pathToFileURL(contentPath).href));
25
29
  const DOCS = mod.DOCS ?? [];
26
30
  if (!DOCS.length) {
@@ -49,18 +53,31 @@ async function cmdIndex() {
49
53
  if (e.locale === locale)
50
54
  variants.push(e);
51
55
  const allEntries = [...DOCS, ...variants];
56
+ // Content hash — skip the (slow) embed when nothing changed, so `kura index` is cheap to run
57
+ // before every dev/build. Covers locale + slug + body of every entry, plus the model id.
58
+ const hashInput = JSON.stringify([model, allEntries.map((e) => [e.locale ?? "", e.slug, e.body])]);
59
+ const contentHash = crypto.createHash("sha256").update(hashInput).digest("hex").slice(0, 16);
60
+ if (fs.existsSync(mdxTs) && fs.existsSync(indexTs)) {
61
+ const prev = fs.readFileSync(indexTs, "utf8").match(/CONTENT_HASH = "([^"]+)"/)?.[1];
62
+ if (prev === contentHash) {
63
+ console.log(`kura index: up to date (${allEntries.length} docs, hash ${contentHash}) — skipped`);
64
+ return;
65
+ }
66
+ }
52
67
  const localeTag = locales.size ? ` (+${variants.length} variants across ${locales.size} locales)` : "";
53
68
  console.log(`kura index: embedding ${DOCS.length} docs${localeTag} (model ${model})…`);
54
69
  const t0 = Date.now();
55
70
  const bytes = await buildIndex({ entries: allEntries, embedder: transformers({ model }) });
56
- fs.mkdirSync(path.dirname(out), { recursive: true });
57
- fs.writeFileSync(out, bytes);
58
- console.log(`kura index: wrote ${out} (${(fs.statSync(out).size / 1024).toFixed(0)}KB) in ${((Date.now() - t0) / 1000).toFixed(1)}s`);
59
- // Precompile MDX -> static HTML with curated components (build-time; Workers-safe at
60
- // runtime). Bucketed by locale: "default" for the flat (default-locale) files, plus one
61
- // bucket per variant locale. The app picks the bucket per entry.
71
+ const b64 = Buffer.from(bytes).toString("base64");
72
+ fs.mkdirSync(path.dirname(indexTs), { recursive: true });
73
+ fs.writeFileSync(indexTs, "// AUTO-GENERATED by `kura index` do not edit. Frozen search index (base64) so the worker\n" +
74
+ "// bundle imports it instead of reading the filesystem (Workers-safe).\n" +
75
+ `export const CONTENT_HASH = ${JSON.stringify(contentHash)};\n` +
76
+ `export const INDEX_B64 = ${JSON.stringify(b64)};\n`);
77
+ console.log(`kura index: wrote app/_index.ts (${(bytes.length / 1024).toFixed(0)}KB index) in ${((Date.now() - t0) / 1000).toFixed(1)}s`);
78
+ // Precompile MDX -> static HTML with curated components (build-time; Workers-safe at runtime).
79
+ // Bucketed by locale: "default" for the flat (default-locale) files, plus one per variant locale.
62
80
  const { mdxToHtml } = await import("@kurajs/docs/mdx");
63
- const mdxOut = path.join(cwd, "app", "_mdx.json");
64
81
  const map = { default: {} };
65
82
  let ok = 0;
66
83
  const render = async (bucket, e) => {
@@ -76,16 +93,17 @@ async function cmdIndex() {
76
93
  await render("default", d);
77
94
  for (const e of variants)
78
95
  await render(e.locale, e);
79
- fs.writeFileSync(mdxOut, JSON.stringify(map));
96
+ fs.writeFileSync(mdxTs, "// AUTO-GENERATED by `kura index` — do not edit. Frozen precompiled MDX (locale → slug → html).\n" +
97
+ `export const MDX: Record<string, Record<string, string>> = ${JSON.stringify(map)};\n`);
80
98
  const total = Object.values(map).reduce((n, b) => n + Object.keys(b).length, 0);
81
99
  const tag = locales.size ? ` across ${locales.size + 1} locales` : "";
82
- console.log(`kura index: rendered ${ok}/${total} docs via MDX${tag} -> ${path.relative(cwd, mdxOut)}`);
100
+ console.log(`kura index: rendered ${ok}/${total} docs via MDX${tag} -> app/_mdx.ts`);
83
101
  }
84
102
  const cmd = process.argv[2];
85
103
  if (cmd === "index") {
86
104
  await cmdIndex();
87
105
  }
88
106
  else {
89
- console.log("Kura CLI\n kura index [--out app/_index.bin] [--model <hf-model>] build the docs search index");
107
+ console.log("Kura CLI\n kura index [--model <hf-model>] build & freeze the docs search index + MDX");
90
108
  process.exit(cmd ? 1 : 0);
91
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurajs/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "description": "Kura CLI — build the docs search index (kura index).",
6
6
  "bin": {
@@ -15,7 +15,7 @@
15
15
  "license": "MIT",
16
16
  "dependencies": {
17
17
  "@kurajs/core": "^0.0.1",
18
- "@kurajs/docs": "^0.0.1",
18
+ "@kurajs/docs": "^0.0.2",
19
19
  "@kurajs/transformers": "^0.0.1"
20
20
  },
21
21
  "peerDependencies": {
@@ -25,7 +25,7 @@
25
25
  "@huggingface/transformers": "3.8.1",
26
26
  "typescript": "^5.7.0"
27
27
  },
28
- "author": "Yi-Ru Lin",
28
+ "author": "Lawrence Lin",
29
29
  "publishConfig": {
30
30
  "access": "public"
31
31
  },
@@ -38,5 +38,10 @@
38
38
  "search",
39
39
  "index",
40
40
  "mcp"
41
- ]
41
+ ],
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/kurajs/kura.git",
45
+ "directory": "packages/cli"
46
+ }
42
47
  }