@raven.js/cli 1.1.1 → 1.2.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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # RavenJS CLI
2
2
 
3
- The RavenJS CLI is designed for **Agent consumption**. AI skills (raven-setup, raven-add, raven-learn, raven-use) invoke it via `bunx raven`. Humans typically run only `bunx raven init`; all other workflows go through skills.
3
+ The RavenJS CLI is designed for **Agent consumption**. AI skills (raven-setup, raven-add, raven-learn, raven-use) invoke it via `bunx raven`. To get skills into your project, use **install-raven** (e.g. `npx install-raven`); then run `bunx raven init` to create the raven root, or let raven-setup do it.
4
4
 
5
- **Install**: Project-local (recommended). Requires Bun `>=1.0`:
5
+ **Install** (project-local, recommended). Requires Bun `>=1.0`:
6
6
 
7
7
  ```bash
8
8
  bun add -d @raven.js/cli
@@ -12,16 +12,19 @@ bun add -d @raven.js/cli
12
12
 
13
13
  | Command | Description |
14
14
  |---------|-------------|
15
- | `bunx raven init` | Initialize AI skills and raven root. Run once before using raven-setup. |
16
- | `bunx raven add <module>` | Add a module. Installs dependencies (`dependsOn`) in topological order, copies files, and rewrites `@ravenjs/*` imports to relative paths. |
17
- | `bunx raven status` | Installation status for all modules. Output is JSON for Agent consumption. |
15
+ | `bunx raven init` | Initialize raven root (directory and `raven.yaml`). Install AI skills with install-raven first. |
16
+ | `bunx raven add <module>` | Add a module (e.g. `core`). Reads from **embedded source** (no network). Installs `dependsOn` in topological order, copies files, and rewrites `@ravenjs/*` / `@raven.js/*` imports to relative paths. |
17
+ | `bunx raven status` | Show RavenJS installation status (core, modules). Output is JSON for Agent consumption. |
18
18
 
19
19
  ## Options
20
20
 
21
21
  | Option | Description |
22
22
  |--------|-------------|
23
23
  | `--root <dir>` | RavenJS root directory (default: `raven`). Overridable via `RAVEN_ROOT`. |
24
- | `--source <path>` | Local module source path instead of GitHub. Overridable via `RAVEN_SOURCE`. |
25
- | `--registry <path>` | Path to registry JSON (default: bundled with CLI). Overridable via `RAVEN_DEFAULT_REGISTRY_PATH`. |
24
+ | `--registry <path>` | Path to registry JSON (default: same dir as CLI). Overridable via `RAVEN_DEFAULT_REGISTRY_PATH`. |
26
25
  | `--verbose, -v` | Verbose output. |
27
26
 
27
+ ## Offline behavior
28
+
29
+ The CLI embeds module source at build time (`dist/source/<module>/`). `raven add <module>` reads from this embedded source and does not perform any network requests.
30
+
package/dist/raven CHANGED
@@ -1,7 +1,8 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
+ // @bun
2
3
 
3
4
  // index.ts
4
- import { cac } from "cac";
5
+ import { Command } from "commander";
5
6
  import { mkdir, readdir, stat, readFile, writeFile, access } from "fs/promises";
6
7
  import { join, dirname, resolve, isAbsolute } from "path";
7
8
  import { cwd } from "process";
@@ -14,8 +15,6 @@ var __dirname2 = dirname(fileURLToPath(import.meta.url));
14
15
  function loadCliVersion() {
15
16
  return process.env.RAVEN_CLI_VERSION ?? "0.0.0";
16
17
  }
17
- var GITHUB_REPO = "myWsq/RavenJS";
18
- var GITHUB_RAW_URL = `https://raw.githubusercontent.com/${GITHUB_REPO}`;
19
18
  var DEFAULT_ROOT = "raven";
20
19
  async function fileExists(path) {
21
20
  try {
@@ -41,20 +40,12 @@ async function loadRegistry(options) {
41
40
  return JSON.parse(content);
42
41
  }
43
42
  }
44
- console.error("registry.json not found. Run 'bun run build' in packages/cli first, or use --registry <path>.");
43
+ console.error("registry.json not found. Run 'bun run build' in packages/cli first.");
45
44
  process.exit(1);
46
45
  }
47
46
  function getRoot(options) {
48
47
  return options.root || process.env.RAVEN_ROOT || DEFAULT_ROOT;
49
48
  }
50
- function getSource(options) {
51
- return options.source || process.env.RAVEN_SOURCE;
52
- }
53
- function resolveSourcePath(source) {
54
- if (!source || source === "github")
55
- return;
56
- return isAbsolute(source) ? source : resolve(cwd(), source);
57
- }
58
49
  async function verboseLog(message, options) {
59
50
  if (options?.verbose) {
60
51
  console.log(message);
@@ -174,64 +165,34 @@ function replaceRavenImports(content, fromModuleDir, registry) {
174
165
  }
175
166
  return out;
176
167
  }
177
- async function downloadFile(url, destPath) {
178
- const response = await fetch(url);
179
- if (!response.ok) {
180
- throw new Error(`Failed to download ${url}: ${response.status}`);
181
- }
182
- const content = await response.text();
183
- await ensureDir(dirname(destPath));
184
- await writeFile(destPath, content);
185
- }
186
- async function copyLocalFile(srcPath, destPath) {
187
- if (!await fileExists(srcPath)) {
188
- throw new Error(`Missing local file: ${srcPath}`);
189
- }
190
- await ensureDir(dirname(destPath));
191
- const content = await readFile(srcPath);
192
- await writeFile(destPath, content);
193
- }
194
168
  var SOURCE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
195
169
  function isSourceFile(file) {
196
170
  return SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext));
197
171
  }
198
- async function downloadModule(registry, moduleName, version, destDir, options, targetSubdir) {
172
+ async function installModule(registry, moduleName, destDir, options, targetSubdir) {
199
173
  const module = registry.modules[moduleName];
200
174
  if (!module) {
201
175
  throw new Error(`Module ${moduleName} not found in registry`);
202
176
  }
203
- const sourcePath = resolveSourcePath(getSource(options || {}));
204
- if (sourcePath) {
205
- verboseLog(`Using local source: ${sourcePath}`, options);
206
- }
207
- verboseLog(`Downloading ${moduleName} files...`, options);
177
+ verboseLog(`Installing ${moduleName} files...`, options);
178
+ const embeddedSourceDir = join(__dirname2, "source");
208
179
  const fromModuleDir = targetSubdir ?? moduleName;
209
180
  const modifiedFiles = [];
210
- const downloads = module.files.map(async (file) => {
181
+ const copies = module.files.map(async (file) => {
211
182
  let destPath;
212
- if (module.fileMapping && module.fileMapping[file]) {
183
+ if (module.fileMapping?.[file]) {
213
184
  destPath = join(destDir, module.fileMapping[file]);
214
185
  } else if (targetSubdir) {
215
186
  destPath = join(destDir, targetSubdir, file);
216
187
  } else {
217
188
  destPath = join(destDir, moduleName, file);
218
189
  }
219
- verboseLog(` Downloading ${file}...`, options);
220
- let content;
221
- if (sourcePath) {
222
- const primaryPath = join(sourcePath, "modules", moduleName, file);
223
- const fallbackPath = join(sourcePath, moduleName, file);
224
- const src = await fileExists(primaryPath) ? primaryPath : await fileExists(fallbackPath) ? fallbackPath : "";
225
- if (!src)
226
- throw new Error(`Missing local file: ${primaryPath}`);
227
- content = await readFile(src, "utf-8");
228
- } else {
229
- const url = `${GITHUB_RAW_URL}/v${version}/modules/${moduleName}/${file}`;
230
- const response = await fetch(url);
231
- if (!response.ok)
232
- throw new Error(`Failed to download ${url}: ${response.status}`);
233
- content = await response.text();
190
+ verboseLog(` Copying ${file}...`, options);
191
+ const srcPath = join(embeddedSourceDir, moduleName, file);
192
+ if (!await fileExists(srcPath)) {
193
+ throw new Error(`Missing embedded source file: ${srcPath}`);
234
194
  }
195
+ let content = await readFile(srcPath, "utf-8");
235
196
  if (isSourceFile(file)) {
236
197
  content = replaceRavenImports(content, fromModuleDir, registry);
237
198
  }
@@ -239,35 +200,7 @@ async function downloadModule(registry, moduleName, version, destDir, options, t
239
200
  await writeFile(destPath, content);
240
201
  modifiedFiles.push(destPath);
241
202
  });
242
- await Promise.all(downloads);
243
- return modifiedFiles;
244
- }
245
- async function downloadAiResources(registry, version, destDir, options) {
246
- const ai = registry.ai;
247
- if (!ai?.claude) {
248
- throw new Error("AI resources not found in registry");
249
- }
250
- const mapping = ai.claude;
251
- const entries = Object.entries(mapping);
252
- const sourcePath = resolveSourcePath(getSource(options || {}));
253
- if (sourcePath) {
254
- verboseLog(`Using local source: ${sourcePath}`, options);
255
- }
256
- verboseLog("Downloading AI resources...", options);
257
- const modifiedFiles = [];
258
- const downloads = entries.map(async ([file, destRel]) => {
259
- const destPath = join(destDir, destRel);
260
- verboseLog(` Downloading ${file}...`, options);
261
- if (sourcePath) {
262
- const sourceFile = join(sourcePath, "packages", "ai", file);
263
- await copyLocalFile(sourceFile, destPath);
264
- } else {
265
- const url = `${GITHUB_RAW_URL}/v${version}/packages/ai/${file}`;
266
- await downloadFile(url, destPath);
267
- }
268
- modifiedFiles.push(destPath);
269
- });
270
- await Promise.all(downloads);
203
+ await Promise.all(copies);
271
204
  return modifiedFiles;
272
205
  }
273
206
  async function cmdInit(options) {
@@ -287,29 +220,28 @@ async function cmdInit(options) {
287
220
  await createRavenYaml(ravenDir, version);
288
221
  modifiedFiles.push(ravenYamlPath);
289
222
  }
290
- const dotClaudeDir = join(targetDir, ".claude");
291
- await ensureDir(dotClaudeDir);
292
- const aiFiles = await downloadAiResources(registry, version, targetDir, options);
293
- modifiedFiles.push(...aiFiles);
294
223
  };
295
224
  if (options?.verbose) {
296
225
  await doInit();
297
226
  } else {
298
227
  const s = makeSpinner();
299
- s.start("Initializing RavenJS...");
228
+ s.start("Initializing raven root...");
300
229
  try {
301
230
  await doInit();
302
231
  } catch (e) {
303
232
  s.stop("Initialization failed");
304
233
  error(e.message);
305
234
  }
306
- s.stop("Initializing RavenJS...");
235
+ s.stop("Initializing raven root...");
307
236
  }
308
- success("RavenJS initialized successfully!");
237
+ success("RavenJS raven root initialized. Install AI skills with: install-raven (or npx install-raven).");
309
238
  printSectionHeader("Modified Files");
310
239
  for (const file of modifiedFiles) {
311
240
  printListItem(file);
312
241
  }
242
+ printSectionHeader("Status");
243
+ const status = await getStatus(registry, options);
244
+ console.log(JSON.stringify(status));
313
245
  }
314
246
  async function createRavenYaml(destDir, version) {
315
247
  const content = stringify({ version });
@@ -334,14 +266,14 @@ async function cmdAdd(moduleName, options) {
334
266
  if (!available.includes(moduleName)) {
335
267
  error(`Unknown module: ${moduleName}`);
336
268
  }
337
- const { ravenDir, version } = await ensureRavenInstalled(options);
269
+ const { ravenDir } = await ensureRavenInstalled(options);
338
270
  const installed = await getInstalledModules(ravenDir, registry);
339
271
  const order = getInstallOrder(moduleName, registry, installed);
340
272
  try {
341
273
  const modifiedFiles = [];
342
274
  const allDependencies = {};
343
275
  for (const name of order) {
344
- const files = await downloadModule(registry, name, version, ravenDir, options);
276
+ const files = await installModule(registry, name, ravenDir, options);
345
277
  modifiedFiles.push(...files);
346
278
  const mod = registry.modules[name];
347
279
  if (mod?.dependencies) {
@@ -354,6 +286,8 @@ async function cmdAdd(moduleName, options) {
354
286
  modifiedFiles,
355
287
  dependencies: allDependencies
356
288
  }));
289
+ const status = await getStatus(registry, options);
290
+ console.log(JSON.stringify(status));
357
291
  } catch (e) {
358
292
  error(e.message);
359
293
  }
@@ -407,15 +341,6 @@ async function getStatus(registry, options) {
407
341
  }
408
342
  await traverseDir(ravenDir, ravenDir);
409
343
  }
410
- let latestVersion;
411
- try {
412
- const response = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`);
413
- if (response.ok) {
414
- const data = await response.json();
415
- latestVersion = data.tag_name.replace(/^v/, "");
416
- }
417
- } catch (e) {
418
- }
419
344
  if (moduleStatus.length === 0) {
420
345
  for (const name of knownModules) {
421
346
  const mod = registry.modules[name];
@@ -431,7 +356,6 @@ async function getStatus(registry, options) {
431
356
  return {
432
357
  modules: moduleStatus,
433
358
  version: currentVersion,
434
- latestVersion,
435
359
  modifiedFiles,
436
360
  fileHashes
437
361
  };
@@ -441,13 +365,13 @@ async function cmdStatus(options) {
441
365
  const status = await getStatus(registry, options);
442
366
  console.log(JSON.stringify(status));
443
367
  }
444
- var cli = cac("raven");
445
- cli.version(loadCliVersion()).help();
446
- cli.option("--registry <path>", "Registry json path (default: same dir as CLI)").option("--root <dir>", "RavenJS root directory (default: raven)").option("--source <path>", "Local module source path (default: github)").option("--verbose, -v", "Verbose output");
447
- cli.command("init", "Initialize RavenJS AI resources").action((options) => cmdInit(options));
448
- cli.command("add <module>", "Add a module (e.g., core)").action((module, options) => cmdAdd(module, options));
449
- cli.command("status", "Show RavenJS installation status (core, modules)").action((options) => cmdStatus(options));
450
- cli.parse();
368
+ var program = new Command("raven");
369
+ program.version(loadCliVersion());
370
+ program.option("--registry <path>", "Registry json path (default: same dir as CLI)").option("--root <dir>", "RavenJS root directory (default: raven)").option("-v, --verbose", "Verbose output");
371
+ program.command("init").description("Initialize raven root (directory and raven.yaml). Install AI skills with install-raven.").action(() => cmdInit(program.opts()));
372
+ program.command("add <module>").description("Add a module (e.g., core)").action((module) => cmdAdd(module, program.opts()));
373
+ program.command("status").description("Show RavenJS installation status (core, modules)").action(() => cmdStatus(program.opts()));
374
+ program.parse();
451
375
 
452
- //# debugId=BB7C5D0CB5BDF0EF64756E2164756E21
376
+ //# debugId=18CE5936F1B83A4764756E2164756E21
453
377
  //# sourceMappingURL=raven.map
package/dist/raven.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../index.ts"],
4
4
  "sourcesContent": [
5
- "#!/usr/bin/env node\n\nimport { cac } from \"cac\";\nimport { mkdir, readdir, stat, readFile, writeFile, access } from \"fs/promises\";\nimport { join, dirname, resolve, isAbsolute } from \"path\";\nimport { cwd } from \"process\";\nimport { createHash } from \"crypto\";\nimport { fileURLToPath } from \"url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nimport pc from \"picocolors\";\nimport { spinner as makeSpinner, log } from \"@clack/prompts\";\nimport { parse, stringify } from \"yaml\";\n\nfunction loadCliVersion(): string {\n return process.env.RAVEN_CLI_VERSION ?? \"0.0.0\";\n}\n\nconst GITHUB_REPO = \"myWsq/RavenJS\";\nconst GITHUB_RAW_URL = `https://raw.githubusercontent.com/${GITHUB_REPO}`;\nconst DEFAULT_ROOT = \"raven\";\n\ninterface CLIOptions {\n verbose?: boolean;\n root?: string;\n source?: string;\n prerelease?: boolean;\n registry?: string;\n}\n\ninterface RegistryModule {\n files: string[];\n fileMapping?: Record<string, string>;\n dependencies?: Record<string, string>;\n dependsOn?: string[];\n description?: string;\n}\n\ninterface RegistryAi {\n claude: Record<string, string>;\n}\n\ninterface Registry {\n version: string;\n modules: Record<string, RegistryModule>;\n ai: RegistryAi;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function loadRegistry(options?: {\n registry?: string;\n}): Promise<Registry> {\n const candidates: string[] = [];\n if (options?.registry) {\n candidates.push(\n isAbsolute(options.registry)\n ? options.registry\n : resolve(cwd(), options.registry),\n );\n }\n if (process.env.RAVEN_DEFAULT_REGISTRY_PATH) {\n const p = process.env.RAVEN_DEFAULT_REGISTRY_PATH;\n candidates.push(isAbsolute(p) ? p : resolve(cwd(), p));\n }\n candidates.push(join(__dirname, \"registry.json\"));\n\n for (const p of candidates) {\n if (await fileExists(p)) {\n const content = await readFile(p, \"utf-8\");\n return JSON.parse(content) as Registry;\n }\n }\n console.error(\n \"registry.json not found. Run 'bun run build' in packages/cli first, or use --registry <path>.\",\n );\n process.exit(1);\n}\n\nfunction getRoot(options: CLIOptions): string {\n return options.root || process.env.RAVEN_ROOT || DEFAULT_ROOT;\n}\n\nfunction getSource(options: CLIOptions): string | undefined {\n return options.source || process.env.RAVEN_SOURCE;\n}\n\nfunction resolveSourcePath(source?: string): string | undefined {\n if (!source || source === \"github\") return undefined;\n return isAbsolute(source) ? source : resolve(cwd(), source);\n}\n\nasync function verboseLog(message: string, options?: CLIOptions) {\n if (options?.verbose) {\n console.log(message);\n }\n}\n\nfunction error(message: string): never {\n // Use stderr for programmatic consumption (e.g. tests, piping). @clack/prompts\n // log.error writes to stdout which breaks stderr-based assertions.\n console.error(message);\n process.exit(1);\n}\n\nfunction success(message: string) {\n log.success(message);\n}\n\nfunction printSectionHeader(title: string) {\n log.step(title);\n}\n\nfunction printListItem(item: string) {\n log.message(item, { symbol: pc.dim(\"-\") });\n}\n\nasync function ensureDir(path: string) {\n try {\n await mkdir(path, { recursive: true });\n } catch (e: any) {\n if (e.code !== \"EEXIST\") throw e;\n }\n}\n\nasync function isDirEmpty(path: string): Promise<boolean> {\n try {\n const entries = await readdir(path);\n return entries.length === 0;\n } catch (e: any) {\n if (e.code === \"ENOENT\") return true;\n throw e;\n }\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch (e: any) {\n if (e.code === \"ENOENT\") return false;\n throw e;\n }\n}\n\nasync function ensureRavenInstalled(\n options: CLIOptions,\n): Promise<{ ravenDir: string; version: string }> {\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n if (!(await pathExists(ravenDir))) {\n error(`RavenJS not installed at ${root}/. Run 'raven init' first.`);\n }\n\n const yamlPath = join(ravenDir, \"raven.yaml\");\n try {\n const content = await readFile(yamlPath, \"utf-8\");\n const config = parse(content) as RavenYamlConfig;\n if (!config?.version) {\n error(\"Invalid raven.yaml: version field is missing\");\n }\n return { ravenDir, version: config.version };\n } catch (e: any) {\n error(`Failed to load raven.yaml: ${e.message}`);\n }\n}\n\nfunction getModuleNames(registry: Registry): string[] {\n return Object.keys(registry.modules);\n}\n\nfunction getInstallOrder(\n moduleName: string,\n registry: Registry,\n installed: Set<string>,\n): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const path: string[] = [];\n let cycle: string[] | null = null;\n\n function visit(name: string) {\n if (recStack.has(name)) {\n const idx = path.indexOf(name);\n cycle = path.slice(idx).concat(name);\n return;\n }\n if (visited.has(name)) return;\n visited.add(name);\n recStack.add(name);\n path.push(name);\n\n const mod = registry.modules[name];\n if (mod?.dependsOn) {\n for (const dep of mod.dependsOn) {\n if (registry.modules[dep]) visit(dep);\n }\n }\n if (!installed.has(name)) {\n result.push(name);\n }\n path.pop();\n recStack.delete(name);\n }\n\n visit(moduleName);\n if (cycle !== null) {\n error(`Circular dependency: ${(cycle as string[]).join(\" -> \")}`);\n }\n return result;\n}\n\nconst RAVENJS_PREFIX = \"@raven.js/\";\n\nfunction replaceRavenImports(\n content: string,\n fromModuleDir: string,\n registry: Registry,\n): string {\n const moduleNames = Object.keys(registry.modules);\n let out = content;\n const depth = fromModuleDir.split(\"/\").filter(Boolean).length;\n const prefix = depth > 0 ? \"../\".repeat(depth) : \"./\";\n for (const modName of moduleNames) {\n const pkg = `${RAVENJS_PREFIX}${modName}`;\n const rel = prefix + modName;\n\n const dq = new RegExp(\n `from\\\\s+\"${pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\"`,\n \"g\",\n );\n const sq = new RegExp(\n `from\\\\s+'${pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}'`,\n \"g\",\n );\n out = out.replace(dq, `from \"${rel}\"`).replace(sq, `from '${rel}'`);\n }\n return out;\n}\n\nasync function downloadFile(url: string, destPath: string): Promise<void> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to download ${url}: ${response.status}`);\n }\n const content = await response.text();\n await ensureDir(dirname(destPath));\n await writeFile(destPath, content);\n}\n\nasync function copyLocalFile(srcPath: string, destPath: string): Promise<void> {\n if (!(await fileExists(srcPath))) {\n throw new Error(`Missing local file: ${srcPath}`);\n }\n await ensureDir(dirname(destPath));\n const content = await readFile(srcPath);\n await writeFile(destPath, content);\n}\n\nconst SOURCE_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\"];\n\nfunction isSourceFile(file: string): boolean {\n return SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext));\n}\n\nasync function downloadModule(\n registry: Registry,\n moduleName: string,\n version: string,\n destDir: string,\n options?: CLIOptions,\n targetSubdir?: string,\n): Promise<string[]> {\n const module = registry.modules[moduleName];\n if (!module) {\n throw new Error(`Module ${moduleName} not found in registry`);\n }\n\n const sourcePath = resolveSourcePath(getSource(options || {}));\n if (sourcePath) {\n verboseLog(`Using local source: ${sourcePath}`, options);\n }\n verboseLog(`Downloading ${moduleName} files...`, options);\n\n const fromModuleDir = targetSubdir ?? moduleName;\n\n const modifiedFiles: string[] = [];\n const downloads = module.files.map(async (file: string) => {\n let destPath: string;\n\n if (module.fileMapping && module.fileMapping[file]) {\n destPath = join(destDir, module.fileMapping[file]);\n } else if (targetSubdir) {\n destPath = join(destDir, targetSubdir, file);\n } else {\n destPath = join(destDir, moduleName, file);\n }\n\n verboseLog(` Downloading ${file}...`, options);\n\n let content: string;\n if (sourcePath) {\n const primaryPath = join(sourcePath, \"modules\", moduleName, file);\n const fallbackPath = join(sourcePath, moduleName, file);\n const src = (await fileExists(primaryPath))\n ? primaryPath\n : (await fileExists(fallbackPath))\n ? fallbackPath\n : \"\";\n if (!src) throw new Error(`Missing local file: ${primaryPath}`);\n content = await readFile(src, \"utf-8\");\n } else {\n const url = `${GITHUB_RAW_URL}/v${version}/modules/${moduleName}/${file}`;\n const response = await fetch(url);\n if (!response.ok)\n throw new Error(`Failed to download ${url}: ${response.status}`);\n content = await response.text();\n }\n\n if (isSourceFile(file)) {\n content = replaceRavenImports(content, fromModuleDir, registry);\n }\n\n await ensureDir(dirname(destPath));\n await writeFile(destPath, content);\n modifiedFiles.push(destPath);\n });\n\n await Promise.all(downloads);\n return modifiedFiles;\n}\n\nasync function downloadAiResources(\n registry: Registry,\n version: string,\n destDir: string,\n options?: CLIOptions,\n): Promise<string[]> {\n const ai = registry.ai;\n if (!ai?.claude) {\n throw new Error(\"AI resources not found in registry\");\n }\n\n const mapping = ai.claude;\n const entries = Object.entries(mapping);\n\n const sourcePath = resolveSourcePath(getSource(options || {}));\n if (sourcePath) {\n verboseLog(`Using local source: ${sourcePath}`, options);\n }\n verboseLog(\"Downloading AI resources...\", options);\n\n const modifiedFiles: string[] = [];\n const downloads = entries.map(async ([file, destRel]) => {\n const destPath = join(destDir, destRel);\n verboseLog(` Downloading ${file}...`, options);\n\n if (sourcePath) {\n const sourceFile = join(sourcePath, \"packages\", \"ai\", file);\n await copyLocalFile(sourceFile, destPath);\n } else {\n const url = `${GITHUB_RAW_URL}/v${version}/packages/ai/${file}`;\n await downloadFile(url, destPath);\n }\n modifiedFiles.push(destPath);\n });\n\n await Promise.all(downloads);\n return modifiedFiles;\n}\n\nasync function cmdInit(options: CLIOptions) {\n const registry = await loadRegistry(options);\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n verboseLog(`Initializing RavenJS in ${targetDir}`, options);\n\n const version = registry.version;\n const modifiedFiles: string[] = [];\n\n const ravenRootExists = await pathExists(ravenDir);\n const ravenYamlPath = join(ravenDir, \"raven.yaml\");\n const ravenYamlExists = await pathExists(ravenYamlPath);\n\n const doInit = async () => {\n if (!ravenRootExists || !ravenYamlExists) {\n await ensureDir(ravenDir);\n await createRavenYaml(ravenDir, version);\n modifiedFiles.push(ravenYamlPath);\n }\n\n const dotClaudeDir = join(targetDir, \".claude\");\n await ensureDir(dotClaudeDir);\n const aiFiles = await downloadAiResources(\n registry,\n version,\n targetDir,\n options,\n );\n modifiedFiles.push(...aiFiles);\n };\n\n if (options?.verbose) {\n await doInit();\n } else {\n const s = makeSpinner();\n s.start(\"Initializing RavenJS...\");\n try {\n await doInit();\n } catch (e: any) {\n s.stop(\"Initialization failed\");\n error(e.message);\n }\n s.stop(\"Initializing RavenJS...\");\n }\n\n success(\"RavenJS initialized successfully!\");\n\n printSectionHeader(\"Modified Files\");\n for (const file of modifiedFiles) {\n printListItem(file);\n }\n}\n\ninterface RavenYamlConfig {\n version: string;\n}\n\nasync function createRavenYaml(destDir: string, version: string) {\n const content = stringify({ version });\n await writeFile(join(destDir, \"raven.yaml\"), content);\n}\n\nasync function getInstalledModules(\n ravenDir: string,\n registry: Registry,\n): Promise<Set<string>> {\n const installed = new Set<string>();\n for (const name of getModuleNames(registry)) {\n const modDir = join(ravenDir, name);\n if ((await pathExists(modDir)) && !(await isDirEmpty(modDir))) {\n installed.add(name);\n }\n }\n return installed;\n}\n\nasync function cmdAdd(moduleName: string, options: CLIOptions) {\n const registry = await loadRegistry(options);\n if (!moduleName) {\n error(\n `Please specify a module to add. Available: ${getModuleNames(registry).join(\", \")}`,\n );\n }\n\n const available = getModuleNames(registry);\n\n if (!available.includes(moduleName)) {\n error(`Unknown module: ${moduleName}`);\n }\n\n const { ravenDir, version } = await ensureRavenInstalled(options);\n\n const installed = await getInstalledModules(ravenDir, registry);\n const order = getInstallOrder(moduleName, registry, installed);\n\n try {\n const modifiedFiles: string[] = [];\n const allDependencies: Record<string, string> = {};\n for (const name of order) {\n const files = await downloadModule(\n registry,\n name,\n version,\n ravenDir,\n options,\n );\n modifiedFiles.push(...files);\n const mod = registry.modules[name];\n if (mod?.dependencies) {\n Object.assign(allDependencies, mod.dependencies);\n }\n }\n\n console.log(\n JSON.stringify({\n success: true,\n moduleName,\n modifiedFiles,\n dependencies: allDependencies,\n }),\n );\n } catch (e: any) {\n error(e.message);\n }\n}\n\n// === SECTION: Status ===\n\ninterface ModuleInfo {\n name: string;\n description?: string;\n installed: boolean;\n /** 模块目录的绝对路径 */\n installDir?: string;\n}\n\ninterface StatusResult {\n modules: ModuleInfo[];\n version?: string;\n latestVersion?: string;\n modifiedFiles?: string[];\n fileHashes?: Record<string, string>;\n}\n\nasync function computeFileHash(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nasync function getStatus(\n registry: Registry,\n options: CLIOptions,\n): Promise<StatusResult> {\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n let currentVersion: string | undefined;\n const modifiedFiles: string[] = [];\n const fileHashes: Record<string, string> = {};\n\n const knownModules = getModuleNames(registry).sort();\n const moduleStatus: ModuleInfo[] = [];\n\n if (await pathExists(ravenDir)) {\n const yamlPath = join(ravenDir, \"raven.yaml\");\n try {\n const content = await readFile(yamlPath, \"utf-8\");\n const config = parse(content) as RavenYamlConfig;\n if (config?.version) {\n currentVersion = config.version;\n }\n } catch (_e) {\n // raven.yaml missing or invalid\n }\n\n for (const name of knownModules) {\n const modDir = join(ravenDir, name);\n const installed =\n (await pathExists(modDir)) && !(await isDirEmpty(modDir));\n const mod = registry.modules[name];\n moduleStatus.push({\n name,\n description: mod?.description,\n installed,\n installDir: resolve(modDir),\n });\n }\n\n // Compute file hashes for all files in raven/\n async function traverseDir(dir: string, baseDir: string) {\n const dirEntries = await readdir(dir, { withFileTypes: true });\n for (const e of dirEntries) {\n const fullPath = join(dir, e.name);\n const relPath = fullPath.slice(baseDir.length + 1);\n if (e.isDirectory()) {\n await traverseDir(fullPath, baseDir);\n } else {\n const hash = await computeFileHash(fullPath);\n fileHashes[relPath] = hash;\n }\n }\n }\n await traverseDir(ravenDir, ravenDir);\n }\n\n // Try to get latest version from GitHub\n let latestVersion: string | undefined;\n try {\n const response = await fetch(\n `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`,\n );\n if (response.ok) {\n const data = await response.json();\n latestVersion = data.tag_name.replace(/^v/, \"\");\n }\n } catch (e) {\n // ignore if can't fetch latest version\n }\n\n if (moduleStatus.length === 0) {\n for (const name of knownModules) {\n const mod = registry.modules[name];\n const modDir = join(ravenDir, name);\n moduleStatus.push({\n name,\n description: mod?.description,\n installed: false,\n installDir: resolve(modDir),\n });\n }\n }\n\n return {\n modules: moduleStatus,\n version: currentVersion,\n latestVersion,\n modifiedFiles,\n fileHashes,\n };\n}\n\ninterface StatusCLIOptions extends CLIOptions {}\n\nasync function cmdStatus(options: StatusCLIOptions) {\n const registry = await loadRegistry(options);\n const status = await getStatus(registry, options);\n console.log(JSON.stringify(status));\n}\n\nconst cli = cac(\"raven\");\ncli.version(loadCliVersion()).help();\n\ncli\n .option(\"--registry <path>\", \"Registry json path (default: same dir as CLI)\")\n .option(\"--root <dir>\", \"RavenJS root directory (default: raven)\")\n .option(\"--source <path>\", \"Local module source path (default: github)\")\n .option(\"--verbose, -v\", \"Verbose output\");\n\ncli\n .command(\"init\", \"Initialize RavenJS AI resources\")\n .action((options) => cmdInit(options as CLIOptions));\n\ncli\n .command(\"add <module>\", \"Add a module (e.g., core)\")\n .action((module, options) => cmdAdd(module, options as CLIOptions));\n\ncli\n .command(\"status\", \"Show RavenJS installation status (core, modules)\")\n .action((options) => cmdStatus(options as StatusCLIOptions));\n\ncli.parse();\n"
5
+ "#!/usr/bin/env bun\n\nimport { Command } from \"commander\";\nimport { mkdir, readdir, stat, readFile, writeFile, access } from \"fs/promises\";\nimport { join, dirname, resolve, isAbsolute } from \"path\";\nimport { cwd } from \"process\";\nimport { createHash } from \"crypto\";\nimport { fileURLToPath } from \"url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nimport pc from \"picocolors\";\nimport { spinner as makeSpinner, log } from \"@clack/prompts\";\nimport { parse, stringify } from \"yaml\";\n\nfunction loadCliVersion(): string {\n return process.env.RAVEN_CLI_VERSION ?? \"0.0.0\";\n}\n\nconst DEFAULT_ROOT = \"raven\";\n\ninterface CLIOptions {\n verbose?: boolean;\n root?: string;\n prerelease?: boolean;\n registry?: string;\n}\n\ninterface RegistryModule {\n files: string[];\n fileMapping?: Record<string, string>;\n dependencies?: Record<string, string>;\n dependsOn?: string[];\n description?: string;\n}\n\ninterface Registry {\n version: string;\n modules: Record<string, RegistryModule>;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function loadRegistry(options?: {\n registry?: string;\n}): Promise<Registry> {\n const candidates: string[] = [];\n if (options?.registry) {\n candidates.push(\n isAbsolute(options.registry)\n ? options.registry\n : resolve(cwd(), options.registry),\n );\n }\n if (process.env.RAVEN_DEFAULT_REGISTRY_PATH) {\n const p = process.env.RAVEN_DEFAULT_REGISTRY_PATH;\n candidates.push(isAbsolute(p) ? p : resolve(cwd(), p));\n }\n candidates.push(join(__dirname, \"registry.json\"));\n\n for (const p of candidates) {\n if (await fileExists(p)) {\n const content = await readFile(p, \"utf-8\");\n return JSON.parse(content) as Registry;\n }\n }\n console.error(\n \"registry.json not found. Run 'bun run build' in packages/cli first.\",\n );\n process.exit(1);\n}\n\nfunction getRoot(options: CLIOptions): string {\n return options.root || process.env.RAVEN_ROOT || DEFAULT_ROOT;\n}\n\nasync function verboseLog(message: string, options?: CLIOptions) {\n if (options?.verbose) {\n console.log(message);\n }\n}\n\nfunction error(message: string): never {\n // Use stderr for programmatic consumption (e.g. tests, piping). @clack/prompts\n // log.error writes to stdout which breaks stderr-based assertions.\n console.error(message);\n process.exit(1);\n}\n\nfunction success(message: string) {\n log.success(message);\n}\n\nfunction printSectionHeader(title: string) {\n log.step(title);\n}\n\nfunction printListItem(item: string) {\n log.message(item, { symbol: pc.dim(\"-\") });\n}\n\nasync function ensureDir(path: string) {\n try {\n await mkdir(path, { recursive: true });\n } catch (e: any) {\n if (e.code !== \"EEXIST\") throw e;\n }\n}\n\nasync function isDirEmpty(path: string): Promise<boolean> {\n try {\n const entries = await readdir(path);\n return entries.length === 0;\n } catch (e: any) {\n if (e.code === \"ENOENT\") return true;\n throw e;\n }\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch (e: any) {\n if (e.code === \"ENOENT\") return false;\n throw e;\n }\n}\n\nasync function ensureRavenInstalled(\n options: CLIOptions,\n): Promise<{ ravenDir: string; version: string }> {\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n if (!(await pathExists(ravenDir))) {\n error(`RavenJS not installed at ${root}/. Run 'raven init' first.`);\n }\n\n const yamlPath = join(ravenDir, \"raven.yaml\");\n try {\n const content = await readFile(yamlPath, \"utf-8\");\n const config = parse(content) as RavenYamlConfig;\n if (!config?.version) {\n error(\"Invalid raven.yaml: version field is missing\");\n }\n return { ravenDir, version: config.version };\n } catch (e: any) {\n error(`Failed to load raven.yaml: ${e.message}`);\n }\n}\n\nfunction getModuleNames(registry: Registry): string[] {\n return Object.keys(registry.modules);\n}\n\nfunction getInstallOrder(\n moduleName: string,\n registry: Registry,\n installed: Set<string>,\n): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const path: string[] = [];\n let cycle: string[] | null = null;\n\n function visit(name: string) {\n if (recStack.has(name)) {\n const idx = path.indexOf(name);\n cycle = path.slice(idx).concat(name);\n return;\n }\n if (visited.has(name)) return;\n visited.add(name);\n recStack.add(name);\n path.push(name);\n\n const mod = registry.modules[name];\n if (mod?.dependsOn) {\n for (const dep of mod.dependsOn) {\n if (registry.modules[dep]) visit(dep);\n }\n }\n if (!installed.has(name)) {\n result.push(name);\n }\n path.pop();\n recStack.delete(name);\n }\n\n visit(moduleName);\n if (cycle !== null) {\n error(`Circular dependency: ${(cycle as string[]).join(\" -> \")}`);\n }\n return result;\n}\n\nconst RAVENJS_PREFIX = \"@raven.js/\";\n\nfunction replaceRavenImports(\n content: string,\n fromModuleDir: string,\n registry: Registry,\n): string {\n const moduleNames = Object.keys(registry.modules);\n let out = content;\n const depth = fromModuleDir.split(\"/\").filter(Boolean).length;\n const prefix = depth > 0 ? \"../\".repeat(depth) : \"./\";\n for (const modName of moduleNames) {\n const pkg = `${RAVENJS_PREFIX}${modName}`;\n const rel = prefix + modName;\n\n const dq = new RegExp(\n `from\\\\s+\"${pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}\"`,\n \"g\",\n );\n const sq = new RegExp(\n `from\\\\s+'${pkg.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}'`,\n \"g\",\n );\n out = out.replace(dq, `from \"${rel}\"`).replace(sq, `from '${rel}'`);\n }\n return out;\n}\n\nconst SOURCE_EXTENSIONS = [\".ts\", \".tsx\", \".js\", \".jsx\"];\n\nfunction isSourceFile(file: string): boolean {\n return SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext));\n}\n\nasync function installModule(\n registry: Registry,\n moduleName: string,\n destDir: string,\n options?: CLIOptions,\n targetSubdir?: string,\n): Promise<string[]> {\n const module = registry.modules[moduleName];\n if (!module) {\n throw new Error(`Module ${moduleName} not found in registry`);\n }\n\n verboseLog(`Installing ${moduleName} files...`, options);\n\n const embeddedSourceDir = join(__dirname, \"source\");\n const fromModuleDir = targetSubdir ?? moduleName;\n\n const modifiedFiles: string[] = [];\n const copies = module.files.map(async (file: string) => {\n let destPath: string;\n\n if (module.fileMapping?.[file]) {\n destPath = join(destDir, module.fileMapping[file]);\n } else if (targetSubdir) {\n destPath = join(destDir, targetSubdir, file);\n } else {\n destPath = join(destDir, moduleName, file);\n }\n\n verboseLog(` Copying ${file}...`, options);\n\n const srcPath = join(embeddedSourceDir, moduleName, file);\n if (!(await fileExists(srcPath))) {\n throw new Error(`Missing embedded source file: ${srcPath}`);\n }\n\n let content = await readFile(srcPath, \"utf-8\");\n\n if (isSourceFile(file)) {\n content = replaceRavenImports(content, fromModuleDir, registry);\n }\n\n await ensureDir(dirname(destPath));\n await writeFile(destPath, content);\n modifiedFiles.push(destPath);\n });\n\n await Promise.all(copies);\n return modifiedFiles;\n}\n\nasync function cmdInit(options: CLIOptions) {\n const registry = await loadRegistry(options);\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n verboseLog(`Initializing RavenJS in ${targetDir}`, options);\n\n const version = registry.version;\n const modifiedFiles: string[] = [];\n\n const ravenRootExists = await pathExists(ravenDir);\n const ravenYamlPath = join(ravenDir, \"raven.yaml\");\n const ravenYamlExists = await pathExists(ravenYamlPath);\n\n const doInit = async () => {\n if (!ravenRootExists || !ravenYamlExists) {\n await ensureDir(ravenDir);\n await createRavenYaml(ravenDir, version);\n modifiedFiles.push(ravenYamlPath);\n }\n };\n\n if (options?.verbose) {\n await doInit();\n } else {\n const s = makeSpinner();\n s.start(\"Initializing raven root...\");\n try {\n await doInit();\n } catch (e: any) {\n s.stop(\"Initialization failed\");\n error(e.message);\n }\n s.stop(\"Initializing raven root...\");\n }\n\n success(\"RavenJS raven root initialized. Install AI skills with: install-raven (or npx install-raven).\");\n\n printSectionHeader(\"Modified Files\");\n for (const file of modifiedFiles) {\n printListItem(file);\n }\n\n printSectionHeader(\"Status\");\n const status = await getStatus(registry, options);\n console.log(JSON.stringify(status));\n}\n\ninterface RavenYamlConfig {\n version: string;\n}\n\nasync function createRavenYaml(destDir: string, version: string) {\n const content = stringify({ version });\n await writeFile(join(destDir, \"raven.yaml\"), content);\n}\n\nasync function getInstalledModules(\n ravenDir: string,\n registry: Registry,\n): Promise<Set<string>> {\n const installed = new Set<string>();\n for (const name of getModuleNames(registry)) {\n const modDir = join(ravenDir, name);\n if ((await pathExists(modDir)) && !(await isDirEmpty(modDir))) {\n installed.add(name);\n }\n }\n return installed;\n}\n\nasync function cmdAdd(moduleName: string, options: CLIOptions) {\n const registry = await loadRegistry(options);\n if (!moduleName) {\n error(\n `Please specify a module to add. Available: ${getModuleNames(registry).join(\", \")}`,\n );\n }\n\n const available = getModuleNames(registry);\n\n if (!available.includes(moduleName)) {\n error(`Unknown module: ${moduleName}`);\n }\n\n const { ravenDir } = await ensureRavenInstalled(options);\n\n const installed = await getInstalledModules(ravenDir, registry);\n const order = getInstallOrder(moduleName, registry, installed);\n\n try {\n const modifiedFiles: string[] = [];\n const allDependencies: Record<string, string> = {};\n for (const name of order) {\n const files = await installModule(\n registry,\n name,\n ravenDir,\n options,\n );\n modifiedFiles.push(...files);\n const mod = registry.modules[name];\n if (mod?.dependencies) {\n Object.assign(allDependencies, mod.dependencies);\n }\n }\n\n // Two JSON lines for Agent: add result + status in one call to save tokens.\n console.log(\n JSON.stringify({\n success: true,\n moduleName,\n modifiedFiles,\n dependencies: allDependencies,\n }),\n );\n const status = await getStatus(registry, options);\n console.log(JSON.stringify(status));\n } catch (e: any) {\n error(e.message);\n }\n}\n\n// === SECTION: Status ===\n\ninterface ModuleInfo {\n name: string;\n description?: string;\n installed: boolean;\n /** 模块目录的绝对路径 */\n installDir?: string;\n}\n\ninterface StatusResult {\n modules: ModuleInfo[];\n version?: string;\n modifiedFiles?: string[];\n fileHashes?: Record<string, string>;\n}\n\nasync function computeFileHash(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nasync function getStatus(\n registry: Registry,\n options: CLIOptions,\n): Promise<StatusResult> {\n const targetDir = cwd();\n const root = getRoot(options);\n const ravenDir = join(targetDir, root);\n\n let currentVersion: string | undefined;\n const modifiedFiles: string[] = [];\n const fileHashes: Record<string, string> = {};\n\n const knownModules = getModuleNames(registry).sort();\n const moduleStatus: ModuleInfo[] = [];\n\n if (await pathExists(ravenDir)) {\n const yamlPath = join(ravenDir, \"raven.yaml\");\n try {\n const content = await readFile(yamlPath, \"utf-8\");\n const config = parse(content) as RavenYamlConfig;\n if (config?.version) {\n currentVersion = config.version;\n }\n } catch (_e) {\n // raven.yaml missing or invalid\n }\n\n for (const name of knownModules) {\n const modDir = join(ravenDir, name);\n const installed =\n (await pathExists(modDir)) && !(await isDirEmpty(modDir));\n const mod = registry.modules[name];\n moduleStatus.push({\n name,\n description: mod?.description,\n installed,\n installDir: resolve(modDir),\n });\n }\n\n // Compute file hashes for all files in raven/\n async function traverseDir(dir: string, baseDir: string) {\n const dirEntries = await readdir(dir, { withFileTypes: true });\n for (const e of dirEntries) {\n const fullPath = join(dir, e.name);\n const relPath = fullPath.slice(baseDir.length + 1);\n if (e.isDirectory()) {\n await traverseDir(fullPath, baseDir);\n } else {\n const hash = await computeFileHash(fullPath);\n fileHashes[relPath] = hash;\n }\n }\n }\n await traverseDir(ravenDir, ravenDir);\n }\n\n if (moduleStatus.length === 0) {\n for (const name of knownModules) {\n const mod = registry.modules[name];\n const modDir = join(ravenDir, name);\n moduleStatus.push({\n name,\n description: mod?.description,\n installed: false,\n installDir: resolve(modDir),\n });\n }\n }\n\n return {\n modules: moduleStatus,\n version: currentVersion,\n modifiedFiles,\n fileHashes,\n };\n}\n\ninterface StatusCLIOptions extends CLIOptions {}\n\nasync function cmdStatus(options: StatusCLIOptions) {\n const registry = await loadRegistry(options);\n const status = await getStatus(registry, options);\n console.log(JSON.stringify(status));\n}\n\nconst program = new Command(\"raven\");\nprogram.version(loadCliVersion());\n\nprogram\n .option(\"--registry <path>\", \"Registry json path (default: same dir as CLI)\")\n .option(\"--root <dir>\", \"RavenJS root directory (default: raven)\")\n .option(\"-v, --verbose\", \"Verbose output\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize raven root (directory and raven.yaml). Install AI skills with install-raven.\")\n .action(() => cmdInit(program.opts() as CLIOptions));\n\nprogram\n .command(\"add <module>\")\n .description(\"Add a module (e.g., core)\")\n .action((module: string) => cmdAdd(module, program.opts() as CLIOptions));\n\nprogram\n .command(\"status\")\n .description(\"Show RavenJS installation status (core, modules)\")\n .action(() => cmdStatus(program.opts() as StatusCLIOptions));\n\nprogram.parse();\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "BB7C5D0CB5BDF0EF64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "18CE5936F1B83A4764756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.1",
2
+ "version": "1.2.0",
3
3
  "modules": {
4
4
  "sql": {
5
5
  "files": [
@@ -38,13 +38,5 @@
38
38
  "dependsOn": [],
39
39
  "description": "RavenJS core framework providing HTTP services, routing, hooks, and state management. Designed for building web services and handling request/response cycles."
40
40
  }
41
- },
42
- "ai": {
43
- "claude": {
44
- "raven-add/skill.md": ".claude/skills/raven-add/SKILL.md",
45
- "raven-learn/skill.md": ".claude/skills/raven-learn/SKILL.md",
46
- "raven-setup/skill.md": ".claude/skills/raven-setup/SKILL.md",
47
- "raven-use/skill.md": ".claude/skills/raven-use/SKILL.md"
48
- }
49
41
  }
50
42
  }
@@ -0,0 +1,14 @@
1
+ # REQUIRED READING
2
+
3
+ To understand the architecture, concepts, API, and usage, read:
4
+
5
+ - [README.md](./README.md)
6
+ - [index.ts](./index.ts)
7
+
8
+ # OPTIONAL READING
9
+
10
+ | Document | Read when… |
11
+ |----------|------------|
12
+ | [PLUGIN.md](./PLUGIN.md) | You are creating a plugin — covers `definePlugin`, all three state patterns, and plugin-specific gotchas. |
13
+ | [router.ts](./router.ts) | You need to understand or extend route matching (Radix tree, path params, wildcards). |
14
+ | [standard-schema.ts](./standard-schema.ts) | You need to integrate validation (Zod, Valibot) or implement Standard Schema–compatible validation. |