@agentproto/corpus-cli 0.1.0-alpha.3 → 0.1.0-alpha.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.mjs CHANGED
@@ -7,11 +7,12 @@ import { fileURLToPath, pathToFileURL } from 'url';
7
7
  import { z } from 'zod';
8
8
  import { randomBytes, randomUUID } from 'crypto';
9
9
  import { readFileSync, existsSync } from 'fs';
10
- import { buildDistillPrompt, parseItems, isRefinedKind, SyncRunner, resolveKnowledge, DistillRunner, systemClock, WebImporter, ImporterRunner, CorpusEventEmitter, CorpusWorkspaceReader, CorpusLinter, CorpusValidator, normalizeLanguageTag } from '@agentproto/corpus';
10
+ import { buildDistillPrompt, parseItems, isRefinedKind, SyncRunner, resolveKnowledge, DistillRunner, systemClock, WebImporter, ImporterRunner, CorpusEventEmitter, CorpusWorkspaceReader, CorpusLinter, CorpusValidator, ReadOnlyFs, normalizeLanguageTag } from '@agentproto/corpus';
11
11
  import matter2 from 'gray-matter';
12
12
  import { execFile } from 'child_process';
13
13
  import { promisify } from 'util';
14
14
  import { parseClaudeJsonOutput, spawnWithStdin } from '@agentproto/cli-exec';
15
+ import { stitchReport, buildPacks, reportConfigSchema } from '@agentproto/corpus/report';
15
16
 
16
17
  /**
17
18
  * @agentproto/corpus-cli v0.1.0-alpha
@@ -103,9 +104,9 @@ function resolvePackageJson(packageName) {
103
104
  }
104
105
  return null;
105
106
  }
106
- async function readJsonIfExists(path4) {
107
+ async function readJsonIfExists(path5) {
107
108
  try {
108
- const raw = await readFile(path4, "utf8");
109
+ const raw = await readFile(path5, "utf8");
109
110
  return JSON.parse(raw);
110
111
  } catch (err) {
111
112
  if (err.code === "ENOENT") return void 0;
@@ -114,9 +115,9 @@ async function readJsonIfExists(path4) {
114
115
  }
115
116
  async function readConfiguredPresetPackages() {
116
117
  const base = process.env["AGENTPROTO_HOME"] ?? join(homedir(), ".agentproto");
117
- const path4 = join(base, "config.json");
118
+ const path5 = join(base, "config.json");
118
119
  try {
119
- const raw = await readFile(path4, "utf8");
120
+ const raw = await readFile(path5, "utf8");
120
121
  const parsed = JSON.parse(raw);
121
122
  const list = parsed.corpusPresetPackages;
122
123
  if (Array.isArray(list) && list.length > 0) return list;
@@ -1143,18 +1144,18 @@ var AssemblyAiStt = class {
1143
1144
  ...job.language_code ? { language: job.language_code } : {}
1144
1145
  };
1145
1146
  }
1146
- async post(path4, body) {
1147
- const r = await fetch(`${this.baseUrl}${path4}`, {
1147
+ async post(path5, body) {
1148
+ const r = await fetch(`${this.baseUrl}${path5}`, {
1148
1149
  method: "POST",
1149
1150
  headers: { authorization: this.apiKey, "content-type": "application/json" },
1150
1151
  body: JSON.stringify(body)
1151
1152
  });
1152
- if (!r.ok) throw new Error(`AssemblyAI POST ${path4} ${r.status}: ${(await r.text()).slice(0, 200)}`);
1153
+ if (!r.ok) throw new Error(`AssemblyAI POST ${path5} ${r.status}: ${(await r.text()).slice(0, 200)}`);
1153
1154
  return AAI_TRANSCRIPT.parse(await r.json());
1154
1155
  }
1155
- async get(path4) {
1156
- const r = await fetch(`${this.baseUrl}${path4}`, { headers: { authorization: this.apiKey } });
1157
- if (!r.ok) throw new Error(`AssemblyAI GET ${path4} ${r.status}: ${(await r.text()).slice(0, 200)}`);
1156
+ async get(path5) {
1157
+ const r = await fetch(`${this.baseUrl}${path5}`, { headers: { authorization: this.apiKey } });
1158
+ if (!r.ok) throw new Error(`AssemblyAI GET ${path5} ${r.status}: ${(await r.text()).slice(0, 200)}`);
1158
1159
  return AAI_TRANSCRIPT.parse(await r.json());
1159
1160
  }
1160
1161
  };
@@ -2020,13 +2021,13 @@ async function readSources(root) {
2020
2021
  const out = [];
2021
2022
  for (const e of entries) {
2022
2023
  if (!e.isFile() || !e.name.endsWith(".md")) continue;
2023
- const path4 = join(e.parentPath, e.name);
2024
+ const path5 = join(e.parentPath, e.name);
2024
2025
  try {
2025
- const parsed = matter2(await readFile(path4, "utf-8"));
2026
+ const parsed = matter2(await readFile(path5, "utf-8"));
2026
2027
  const fm = SOURCE_FRONTMATTER.parse(parsed.data);
2027
2028
  if (!fm.id || !parsed.content.trim()) continue;
2028
2029
  out.push({
2029
- path: path4,
2030
+ path: path5,
2030
2031
  id: fm.id,
2031
2032
  title: fm.title ?? fm.id,
2032
2033
  body: parsed.content.trim(),
@@ -2185,6 +2186,126 @@ async function runKnowledge(args) {
2185
2186
  }
2186
2187
  return 0;
2187
2188
  }
2189
+ async function runReport(args) {
2190
+ const [sub, ...rest] = args;
2191
+ switch (sub) {
2192
+ case "packs":
2193
+ return await runReportPacks(rest);
2194
+ case "stitch":
2195
+ return await runReportStitch(rest);
2196
+ case void 0:
2197
+ return fail("report needs a subcommand (packs | stitch). Try --help.", 2);
2198
+ default:
2199
+ return fail(`unknown report subcommand "${sub}". Try --help.`, 2);
2200
+ }
2201
+ }
2202
+ function loadReportConfig(configPath) {
2203
+ const raw = readFileSync(path.resolve(process.cwd(), configPath), "utf8");
2204
+ return reportConfigSchema.parse(JSON.parse(raw));
2205
+ }
2206
+ async function runReportPacks(args) {
2207
+ let dataset;
2208
+ let configPath;
2209
+ let out;
2210
+ let viewsDir;
2211
+ for (let i = 0; i < args.length; i++) {
2212
+ const a = args[i];
2213
+ const next = () => args[++i];
2214
+ switch (a) {
2215
+ case "--config":
2216
+ configPath = next();
2217
+ break;
2218
+ case "--out":
2219
+ out = next();
2220
+ break;
2221
+ case "--views-dir":
2222
+ viewsDir = next();
2223
+ break;
2224
+ default:
2225
+ if (!a.startsWith("-") && dataset === void 0) dataset = a;
2226
+ }
2227
+ }
2228
+ const datasetPath = resolveWorkspacePath(dataset);
2229
+ if (!configPath) {
2230
+ return fail("report packs needs --config <report.config.json>.", 2);
2231
+ }
2232
+ let config;
2233
+ try {
2234
+ config = loadReportConfig(configPath);
2235
+ } catch (err) {
2236
+ return fail(
2237
+ `could not load/validate config "${configPath}": ${err instanceof Error ? err.message : String(err)}`,
2238
+ 2
2239
+ );
2240
+ }
2241
+ const reportRoot = out ? path.resolve(process.cwd(), out) : datasetPath;
2242
+ const datasetFs = new ReadOnlyFs(new NodeFsAdapter({ root: datasetPath }));
2243
+ const reportFs = new NodeFsAdapter({ root: reportRoot });
2244
+ const result = await buildPacks({
2245
+ dataset: datasetFs,
2246
+ config,
2247
+ ...viewsDir ? { viewsDir } : {}
2248
+ });
2249
+ for (const file of result.files) {
2250
+ await reportFs.writeFile(file.path, file.content);
2251
+ }
2252
+ process.stdout.write(
2253
+ `report packs \u2192 ${result.files.length} files \xB7 ${result.bibliography} sources
2254
+ ` + result.chapters.map((c) => ` ${c.id}: ${c.entryCount}`).join("\n") + "\n"
2255
+ );
2256
+ return 0;
2257
+ }
2258
+ async function runReportStitch(args) {
2259
+ let reportRoot;
2260
+ let configPath;
2261
+ let out;
2262
+ let chaptersDir;
2263
+ let viewsDir;
2264
+ for (let i = 0; i < args.length; i++) {
2265
+ const a = args[i];
2266
+ const next = () => args[++i];
2267
+ switch (a) {
2268
+ case "--config":
2269
+ configPath = next();
2270
+ break;
2271
+ case "--out":
2272
+ out = next();
2273
+ break;
2274
+ case "--chapters-dir":
2275
+ chaptersDir = next();
2276
+ break;
2277
+ case "--views-dir":
2278
+ viewsDir = next();
2279
+ break;
2280
+ default:
2281
+ if (!a.startsWith("-") && reportRoot === void 0) reportRoot = a;
2282
+ }
2283
+ }
2284
+ const root = resolveWorkspacePath(reportRoot);
2285
+ if (!configPath) {
2286
+ return fail("report stitch needs --config <report.config.json>.", 2);
2287
+ }
2288
+ let config;
2289
+ try {
2290
+ config = loadReportConfig(configPath);
2291
+ } catch (err) {
2292
+ return fail(
2293
+ `could not load/validate config "${configPath}": ${err instanceof Error ? err.message : String(err)}`,
2294
+ 2
2295
+ );
2296
+ }
2297
+ const reportFs = new NodeFsAdapter({ root });
2298
+ const { content, wordCount } = await stitchReport({
2299
+ config,
2300
+ report: reportFs,
2301
+ ...chaptersDir ? { chaptersDir } : {},
2302
+ ...viewsDir ? { viewsDir } : {}
2303
+ });
2304
+ await reportFs.writeFile(out ?? "REPORT.md", content);
2305
+ process.stdout.write(`report stitch \u2192 ${out ?? "REPORT.md"} \xB7 ${wordCount} words
2306
+ `);
2307
+ return 0;
2308
+ }
2188
2309
  var RPC_RESPONSE2 = z.object({ result: z.unknown().optional(), error: z.unknown().optional() }).loose();
2189
2310
  var RPC_MESSAGE = z.object({
2190
2311
  id: z.number().optional(),
@@ -2583,6 +2704,14 @@ Commands:
2583
2704
  knowledge [path] --tags a,b [--kind k --access scope --max n]
2584
2705
  Preview what a skill's knowledge: binding resolves to
2585
2706
  \u2014 refined entries + their provenance (filesystem).
2707
+ report packs [dataset] --config <f> [--out <dir>] [--views-dir <n>]
2708
+ Build per-chapter knowledge views + the global
2709
+ citation bibliography from a dataset. Dataset is
2710
+ mounted read-only; --out (default: dataset) is the
2711
+ only writer; --views-dir defaults to "views".
2712
+ report stitch [report] --config <f> [--out <REPORT.md>] [--chapters-dir <d> --views-dir <n>]
2713
+ Stitch front + parts + chapters + annexes + Sources
2714
+ into one REPORT.md (report-side reads only).
2586
2715
  sync [path] --config <sink.json> [--tags a,b --kind k --throttle ms]
2587
2716
  Push refined entries to an external store via a
2588
2717
  config-driven MCP sink (host-agnostic).
@@ -2622,6 +2751,8 @@ async function main(argv2) {
2622
2751
  return await runDistill(rest);
2623
2752
  case "knowledge":
2624
2753
  return await runKnowledge(rest);
2754
+ case "report":
2755
+ return await runReport(rest);
2625
2756
  case "sync":
2626
2757
  return await runSync(rest);
2627
2758
  default: