@ferax564/noma-cli 0.11.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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +199 -0
  3. package/bin/noma.mjs +8 -0
  4. package/dist/ast.d.ts +111 -0
  5. package/dist/ast.js +23 -0
  6. package/dist/ast.js.map +1 -0
  7. package/dist/book.d.ts +56 -0
  8. package/dist/book.js +120 -0
  9. package/dist/book.js.map +1 -0
  10. package/dist/cli.d.ts +2 -0
  11. package/dist/cli.js +573 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/diff.d.ts +29 -0
  14. package/dist/diff.js +77 -0
  15. package/dist/diff.js.map +1 -0
  16. package/dist/fmt.d.ts +1 -0
  17. package/dist/fmt.js +105 -0
  18. package/dist/fmt.js.map +1 -0
  19. package/dist/ids.d.ts +15 -0
  20. package/dist/ids.js +27 -0
  21. package/dist/ids.js.map +1 -0
  22. package/dist/index.d.ts +20 -0
  23. package/dist/index.js +12 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/inline.d.ts +14 -0
  26. package/dist/inline.js +83 -0
  27. package/dist/inline.js.map +1 -0
  28. package/dist/loader.d.ts +12 -0
  29. package/dist/loader.js +59 -0
  30. package/dist/loader.js.map +1 -0
  31. package/dist/parser.d.ts +7 -0
  32. package/dist/parser.js +434 -0
  33. package/dist/parser.js.map +1 -0
  34. package/dist/patch.d.ts +61 -0
  35. package/dist/patch.js +530 -0
  36. package/dist/patch.js.map +1 -0
  37. package/dist/renderer-html.d.ts +44 -0
  38. package/dist/renderer-html.js +929 -0
  39. package/dist/renderer-html.js.map +1 -0
  40. package/dist/renderer-json.d.ts +5 -0
  41. package/dist/renderer-json.js +4 -0
  42. package/dist/renderer-json.js.map +1 -0
  43. package/dist/renderer-llm.d.ts +29 -0
  44. package/dist/renderer-llm.js +275 -0
  45. package/dist/renderer-llm.js.map +1 -0
  46. package/dist/renderer-noma.d.ts +10 -0
  47. package/dist/renderer-noma.js +179 -0
  48. package/dist/renderer-noma.js.map +1 -0
  49. package/dist/renderer-site.d.ts +11 -0
  50. package/dist/renderer-site.js +175 -0
  51. package/dist/renderer-site.js.map +1 -0
  52. package/dist/validator.d.ts +24 -0
  53. package/dist/validator.js +699 -0
  54. package/dist/validator.js.map +1 -0
  55. package/dist/verify.d.ts +10 -0
  56. package/dist/verify.js +141 -0
  57. package/dist/verify.js.map +1 -0
  58. package/package.json +83 -0
  59. package/schemas/ast.schema.json +187 -0
  60. package/schemas/capability.schema.json +70 -0
  61. package/schemas/patch-op.schema.json +92 -0
  62. package/schemas/patch-transaction.schema.json +28 -0
  63. package/schemas/transcript.schema.json +95 -0
  64. package/src/ast.ts +152 -0
  65. package/src/book.ts +162 -0
  66. package/src/cli.ts +595 -0
  67. package/src/diff.ts +108 -0
  68. package/src/fmt.ts +126 -0
  69. package/src/ids.ts +42 -0
  70. package/src/index.ts +20 -0
  71. package/src/inline.ts +92 -0
  72. package/src/loader.ts +55 -0
  73. package/src/parser.ts +501 -0
  74. package/src/patch.ts +646 -0
  75. package/src/renderer-html.ts +1047 -0
  76. package/src/renderer-json.ts +9 -0
  77. package/src/renderer-llm.ts +320 -0
  78. package/src/renderer-noma.ts +220 -0
  79. package/src/renderer-site.ts +245 -0
  80. package/src/validator.ts +733 -0
  81. package/src/verify.ts +157 -0
  82. package/themes/dark.css +382 -0
  83. package/themes/default.css +537 -0
package/dist/cli.js ADDED
@@ -0,0 +1,573 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import yaml from "js-yaml";
6
+ import { parse } from "./parser.js";
7
+ import { renderHtml } from "./renderer-html.js";
8
+ import { renderLlm } from "./renderer-llm.js";
9
+ import { renderJson } from "./renderer-json.js";
10
+ import { renderNoma } from "./renderer-noma.js";
11
+ import { patchSource } from "./patch.js";
12
+ import { loadBook, loadBookChapters, isBookManifestPath } from "./book.js";
13
+ import { inlineDatasetSources } from "./loader.js";
14
+ import { renderSite } from "./renderer-site.js";
15
+ import { validate, formatDiagnostics } from "./validator.js";
16
+ import { formatSource } from "./fmt.js";
17
+ import { verifyFixtureDir } from "./verify.js";
18
+ import { diffDocs } from "./diff.js";
19
+ import { collectIdRegistry } from "./ids.js";
20
+ const HELP = `noma — readable document format for humans and agents
21
+
22
+ Usage:
23
+ noma parse <file.noma|book.yml> Print the AST as JSON
24
+ noma render <file.noma|book.yml> [opts] Render to a target format
25
+ noma check <file.noma|book.yml> Validate the document
26
+ noma export <file.noma|book.yml> [opts] Alias for render --to json
27
+ noma patch <file.noma> [opts] Apply block-level patch ops
28
+ noma init [dir] Create a starter .noma document
29
+ noma ids <file.noma|book.yml> Print canonical ID and alias registry
30
+ noma schema <name> Print bundled JSON Schema
31
+ noma fmt <file.noma> [--inplace|--out p] Re-align pipe tables in source
32
+ noma verify <fixture-dir> Run conformance suite against fixtures
33
+ noma diff <before.noma> <after.noma> --at <date> Emit ::state_change for attribute drift
34
+ noma --help Show this help
35
+ noma --version Print the CLI version
36
+
37
+ Render options:
38
+ --to <html|llm|json|noma|site> Target format (default: html). 'site' renders
39
+ a book manifest as a multi-page HTML site.
40
+ --out <path> Write to file (or directory for --to site)
41
+ --no-standalone HTML: emit body fragment without <html> wrapper
42
+ --title <text> Override document title
43
+ --theme <name> HTML theme: default | dark (default: default)
44
+ --no-unsafe HTML: block ::html / ::svg / ::script escape hatches
45
+ --strict HTML: block escape hatches and external CDN assets
46
+ --math <katex|none> Math rendering: enable KaTeX assets in standalone HTML
47
+ (default: auto-detect from doc / book manifest)
48
+ --ignore-rule <name> Suppress a validator rule (repeatable)
49
+ --exclude-stale-days <n> LLM: omit ::memory blocks whose last_seen is older
50
+ than <n> days from --now (or system clock).
51
+ --select <a,b> LLM: include only node types or directive names
52
+ --exclude <a,b> LLM: omit node types or directive names
53
+ --budget <chars> LLM: trim output to a maximum character count
54
+ --now <ISO> LLM: fix the clock used by --exclude-stale-days
55
+ (default: system clock). Useful for tests.
56
+
57
+ Check options:
58
+ --stale-days <n> Override the citation staleness window (days)
59
+ --ignore-rule <name> Suppress a validator rule (repeatable)
60
+
61
+ Patch options:
62
+ --op <json> One inline patch op (JSON object)
63
+ --ops <file.json> File containing one op, an array of ops, or
64
+ { "ops": [...], "prevalidate": true,
65
+ "postvalidate": true }
66
+ --inplace Write the result back to <file.noma>
67
+ --out <path> Write to file instead of stdout
68
+
69
+ Diff options:
70
+ --at <YYYY-MM-DD> Required. Timestamp written as at="..." on each delta.
71
+ Required so output is deterministic.
72
+ --reason <text> Embed reason="..." on every emitted state_change
73
+ --out <path> Write to file instead of stdout
74
+
75
+ Examples:
76
+ noma parse examples/thesis.noma
77
+ noma schema patch-op
78
+ noma render examples/thesis.noma --to html --out dist/thesis.html
79
+ noma render examples/thesis.noma --to llm
80
+ noma check examples/thesis.noma
81
+ noma patch examples/thesis.noma --op '{"op":"update_attribute","id":"asml-euv-moat","key":"confidence","value":0.9}' --inplace
82
+ noma diff before.noma after.noma --at 2026-05-12 --reason "Q1 refresh"
83
+ `;
84
+ function parseArgs(argv) {
85
+ const args = {
86
+ command: argv[0] ?? "",
87
+ to: "html",
88
+ standalone: true,
89
+ help: false,
90
+ inplace: false,
91
+ theme: "default",
92
+ allowEscapeHatches: true,
93
+ externalAssets: true,
94
+ ignoreRules: [],
95
+ llmSelect: [],
96
+ llmExclude: [],
97
+ };
98
+ let i = 1;
99
+ while (i < argv.length) {
100
+ const a = argv[i];
101
+ if (a === "--help" || a === "-h") {
102
+ args.help = true;
103
+ i++;
104
+ }
105
+ else if (a === "--to") {
106
+ args.to = argv[++i] ?? "html";
107
+ i++;
108
+ }
109
+ else if (a === "--out" || a === "-o") {
110
+ args.out = argv[++i];
111
+ i++;
112
+ }
113
+ else if (a === "--no-standalone") {
114
+ args.standalone = false;
115
+ i++;
116
+ }
117
+ else if (a === "--standalone") {
118
+ args.standalone = true;
119
+ i++;
120
+ }
121
+ else if (a === "--title") {
122
+ args.title = argv[++i];
123
+ i++;
124
+ }
125
+ else if (a === "--theme") {
126
+ args.theme = argv[++i] ?? "default";
127
+ i++;
128
+ }
129
+ else if (a === "--no-unsafe") {
130
+ args.allowEscapeHatches = false;
131
+ i++;
132
+ }
133
+ else if (a === "--strict") {
134
+ args.allowEscapeHatches = false;
135
+ args.externalAssets = false;
136
+ i++;
137
+ }
138
+ else if (a === "--stale-days") {
139
+ const v = Number(argv[++i]);
140
+ if (Number.isFinite(v) && v > 0)
141
+ args.staleDays = v;
142
+ i++;
143
+ }
144
+ else if (a === "--ignore-rule") {
145
+ const v = argv[++i];
146
+ if (v)
147
+ args.ignoreRules.push(v);
148
+ i++;
149
+ }
150
+ else if (a === "--math") {
151
+ const v = argv[++i];
152
+ args.math = v === "none" ? "none" : "katex";
153
+ i++;
154
+ }
155
+ else if (a === "--exclude-stale-days") {
156
+ const v = Number(argv[++i]);
157
+ if (Number.isFinite(v) && v > 0)
158
+ args.excludeStaleDays = v;
159
+ i++;
160
+ }
161
+ else if (a === "--select") {
162
+ const v = argv[++i];
163
+ if (v)
164
+ args.llmSelect.push(v);
165
+ i++;
166
+ }
167
+ else if (a === "--exclude") {
168
+ const v = argv[++i];
169
+ if (v)
170
+ args.llmExclude.push(v);
171
+ i++;
172
+ }
173
+ else if (a === "--budget") {
174
+ const v = Number(argv[++i]);
175
+ if (Number.isFinite(v) && v > 0)
176
+ args.llmBudget = v;
177
+ i++;
178
+ }
179
+ else if (a === "--now") {
180
+ args.now = argv[++i];
181
+ i++;
182
+ }
183
+ else if (a === "--op") {
184
+ args.op = argv[++i];
185
+ i++;
186
+ }
187
+ else if (a === "--ops") {
188
+ args.opsFile = argv[++i];
189
+ i++;
190
+ }
191
+ else if (a === "--inplace") {
192
+ args.inplace = true;
193
+ i++;
194
+ }
195
+ else if (a === "--reason") {
196
+ args.diffReason = argv[++i];
197
+ i++;
198
+ }
199
+ else if (a === "--at") {
200
+ args.diffAt = argv[++i];
201
+ i++;
202
+ }
203
+ else if (!a.startsWith("--") && !args.file) {
204
+ args.file = a;
205
+ i++;
206
+ }
207
+ else if (!a.startsWith("--") && !args.fileB) {
208
+ args.fileB = a;
209
+ i++;
210
+ }
211
+ else {
212
+ i++;
213
+ }
214
+ }
215
+ return args;
216
+ }
217
+ function loadTheme(name = "default") {
218
+ const safe = /^[a-z0-9-]+$/.test(name) ? name : "default";
219
+ const here = dirname(fileURLToPath(import.meta.url));
220
+ const candidates = [
221
+ resolve(here, "..", "themes", `${safe}.css`),
222
+ resolve(here, "..", "..", "themes", `${safe}.css`),
223
+ ];
224
+ for (const c of candidates) {
225
+ if (existsSync(c))
226
+ return readFileSync(c, "utf8");
227
+ }
228
+ if (safe !== "default")
229
+ return loadTheme("default");
230
+ return "";
231
+ }
232
+ function loadSchema(name) {
233
+ const safe = name.replace(/\.schema\.json$/i, "");
234
+ const filenames = {
235
+ ast: "ast.schema.json",
236
+ capability: "capability.schema.json",
237
+ "patch-op": "patch-op.schema.json",
238
+ "patch-transaction": "patch-transaction.schema.json",
239
+ transcript: "transcript.schema.json",
240
+ };
241
+ const filename = filenames[safe];
242
+ if (!filename) {
243
+ const names = Object.keys(filenames).sort().join(", ");
244
+ throw new Error(`unknown schema "${name}" (expected one of: ${names})`);
245
+ }
246
+ const here = dirname(fileURLToPath(import.meta.url));
247
+ const candidates = [
248
+ resolve(here, "..", "schemas", filename),
249
+ resolve(here, "..", "..", "schemas", filename),
250
+ ];
251
+ for (const c of candidates) {
252
+ if (existsSync(c))
253
+ return readFileSync(c, "utf8");
254
+ }
255
+ throw new Error(`schema file not found: ${filename}`);
256
+ }
257
+ function packageVersion() {
258
+ const here = dirname(fileURLToPath(import.meta.url));
259
+ const packagePath = resolve(here, "..", "package.json");
260
+ try {
261
+ const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
262
+ return typeof pkg.version === "string" ? pkg.version : "unknown";
263
+ }
264
+ catch {
265
+ return "unknown";
266
+ }
267
+ }
268
+ function output(content, out) {
269
+ if (!out) {
270
+ process.stdout.write(content + (content.endsWith("\n") ? "" : "\n"));
271
+ return;
272
+ }
273
+ const dir = dirname(out);
274
+ if (!existsSync(dir))
275
+ mkdirSync(dir, { recursive: true });
276
+ writeFileSync(out, content, "utf8");
277
+ process.stderr.write(`✓ wrote ${out}\n`);
278
+ }
279
+ function starterSource() {
280
+ return `---
281
+ title: Agent-Safe Spec
282
+ ---
283
+
284
+ # Agent-Safe Spec
285
+
286
+ ::summary
287
+ A small Noma starter document with stable block IDs for agent-safe edits.
288
+ ::
289
+
290
+ ::claim{id="core-claim" confidence=0.8}
291
+ Noma documents stay readable for humans while giving agents precise blocks to patch.
292
+ ::
293
+
294
+ ::evidence{for="core-claim" source="starter"}
295
+ This claim can be updated with \`noma patch\` without rewriting the whole file.
296
+ ::
297
+
298
+ ::risk{id="first-risk" severity="medium" owner="you"}
299
+ Replace this with the first risk your spec needs to track.
300
+ ::
301
+ `;
302
+ }
303
+ function patchTransactionFromArgs(args) {
304
+ const ops = [];
305
+ let prevalidate = false;
306
+ let postvalidate = false;
307
+ if (args.op) {
308
+ ops.push(JSON.parse(args.op));
309
+ }
310
+ if (args.opsFile) {
311
+ const raw = JSON.parse(readFileSync(resolve(args.opsFile), "utf8"));
312
+ if (isPatchTransactionPayload(raw)) {
313
+ ops.push(...raw.ops);
314
+ prevalidate = raw.prevalidate === true;
315
+ postvalidate = raw.postvalidate === true;
316
+ }
317
+ else if (Array.isArray(raw)) {
318
+ ops.push(...raw);
319
+ }
320
+ else {
321
+ ops.push(raw);
322
+ }
323
+ }
324
+ return { ops, prevalidate, postvalidate };
325
+ }
326
+ function isPatchTransactionPayload(value) {
327
+ return (typeof value === "object" &&
328
+ value !== null &&
329
+ "ops" in value &&
330
+ Array.isArray(value.ops));
331
+ }
332
+ function validatePatchSource(source, filename) {
333
+ const doc = parse(source, { filename });
334
+ inlineDatasetSources(doc);
335
+ const diagnostics = validate(doc);
336
+ const errors = diagnostics.filter((d) => d.severity === "error");
337
+ return errors.length > 0 ? formatDiagnostics(errors, filename) : "";
338
+ }
339
+ function main() {
340
+ const argv = process.argv.slice(2);
341
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
342
+ process.stdout.write(HELP);
343
+ return;
344
+ }
345
+ if (argv[0] === "--version" || argv[0] === "-v") {
346
+ process.stdout.write(`${packageVersion()}\n`);
347
+ return;
348
+ }
349
+ const args = parseArgs(argv);
350
+ if (args.help) {
351
+ process.stdout.write(HELP);
352
+ return;
353
+ }
354
+ const cmd = args.command;
355
+ if (cmd === "init") {
356
+ const targetDir = resolve(args.file ?? "noma-starter");
357
+ const targetFile = resolve(targetDir, "demo.noma");
358
+ if (existsSync(targetFile)) {
359
+ process.stderr.write(`error: ${targetFile} already exists\n`);
360
+ process.exit(2);
361
+ }
362
+ mkdirSync(targetDir, { recursive: true });
363
+ writeFileSync(targetFile, starterSource(), "utf8");
364
+ process.stderr.write(`✓ wrote ${targetFile}\n`);
365
+ process.stdout.write(`Next: noma render ${targetFile} --to html --out ${resolve(targetDir, "demo.html")}\n`);
366
+ return;
367
+ }
368
+ if (cmd === "verify") {
369
+ const dir = args.file;
370
+ if (!dir) {
371
+ console.error("noma verify: <fixture-dir> required");
372
+ process.exit(2);
373
+ }
374
+ const resolvedDir = resolve(dir);
375
+ if (!existsSync(resolvedDir)) {
376
+ console.error(`noma verify: ${dir} does not exist`);
377
+ process.exit(2);
378
+ }
379
+ const report = verifyFixtureDir(resolvedDir);
380
+ for (const f of report.fixtures) {
381
+ const tag = f.status === "pass" ? "PASS" : f.status === "fail" ? "FAIL" : "SKIP";
382
+ console.log(`${tag} ${f.name}${f.error ? ` — ${f.error}` : ""}`);
383
+ }
384
+ console.log(`\n${report.fixtures.length} fixtures, ${report.fixtures.filter((f) => f.status === "pass").length} passed`);
385
+ process.exit(report.ok ? 0 : 1);
386
+ }
387
+ if (cmd === "schema") {
388
+ if (!args.file) {
389
+ process.stderr.write("noma schema: <ast|capability|patch-op|patch-transaction|transcript> required\n");
390
+ process.exit(2);
391
+ }
392
+ try {
393
+ output(loadSchema(args.file), args.out);
394
+ }
395
+ catch (error) {
396
+ process.stderr.write(`error: ${error.message}\n`);
397
+ process.exit(2);
398
+ }
399
+ return;
400
+ }
401
+ if (cmd === "diff") {
402
+ if (!args.file || !args.fileB) {
403
+ process.stderr.write("noma diff: <before.noma> <after.noma> required\n");
404
+ process.exit(2);
405
+ }
406
+ if (!args.diffAt) {
407
+ process.stderr.write("noma diff: --at <YYYY-MM-DD> is required (output must be deterministic)\n");
408
+ process.exit(2);
409
+ }
410
+ const a = parse(readFileSync(resolve(args.file), "utf8"), { filename: args.file });
411
+ const b = parse(readFileSync(resolve(args.fileB), "utf8"), { filename: args.fileB });
412
+ const deltas = diffDocs(a, b, {
413
+ at: args.diffAt,
414
+ ...(args.diffReason !== undefined ? { reason: args.diffReason } : {}),
415
+ });
416
+ if (deltas.length === 0) {
417
+ return;
418
+ }
419
+ const deltaDoc = { type: "document", meta: {}, children: deltas };
420
+ output(renderNoma(deltaDoc), args.out);
421
+ return;
422
+ }
423
+ if (!args.file) {
424
+ process.stderr.write(`error: missing input file\n\n${HELP}`);
425
+ process.exit(2);
426
+ }
427
+ const filePath = resolve(args.file);
428
+ if (cmd === "fmt") {
429
+ if (isBookManifestPath(filePath)) {
430
+ process.stderr.write(`error: noma fmt operates on .noma source files, not book manifests\n`);
431
+ process.exit(2);
432
+ }
433
+ const formatted = formatSource(readFileSync(filePath, "utf8"));
434
+ const target = args.inplace ? filePath : args.out;
435
+ output(formatted, target);
436
+ return;
437
+ }
438
+ if ((cmd === "render" || cmd === "export") && args.to === "site") {
439
+ if (!isBookManifestPath(filePath)) {
440
+ process.stderr.write(`error: --to site requires a book manifest (.yml)\n`);
441
+ process.exit(2);
442
+ }
443
+ if (!args.out) {
444
+ process.stderr.write(`error: --to site requires --out <directory>\n`);
445
+ process.exit(2);
446
+ }
447
+ const themeCss = loadTheme(args.theme);
448
+ const { manifest, chapters } = loadBookChapters(filePath);
449
+ const allowEscapeHatches = args.allowEscapeHatches && manifest.trusted_publishing !== true;
450
+ renderSite(manifest, chapters, args.out, {
451
+ themeCss,
452
+ title: args.title,
453
+ allowEscapeHatches,
454
+ externalAssets: args.externalAssets,
455
+ ...(args.math ? { math: args.math } : {}),
456
+ });
457
+ process.stderr.write(`✓ wrote ${chapters.length + 1} pages to ${args.out}\n`);
458
+ return;
459
+ }
460
+ const manifestForTrust = isBookManifestPath(filePath)
461
+ ? yaml.load(readFileSync(filePath, "utf8"))
462
+ : null;
463
+ const allowEscapeHatches = args.allowEscapeHatches && manifestForTrust?.trusted_publishing !== true;
464
+ const doc = isBookManifestPath(filePath)
465
+ ? loadBook(filePath)
466
+ : parse(readFileSync(filePath, "utf8"), { filename: filePath });
467
+ inlineDatasetSources(doc);
468
+ switch (cmd) {
469
+ case "parse": {
470
+ output(renderJson(doc, { pretty: true }), args.out);
471
+ return;
472
+ }
473
+ case "ids": {
474
+ output(JSON.stringify(collectIdRegistry(doc), null, 2), args.out);
475
+ return;
476
+ }
477
+ case "export":
478
+ case "render": {
479
+ const to = cmd === "export" ? "json" : args.to;
480
+ switch (to) {
481
+ case "html": {
482
+ const themeCss = loadTheme(args.theme);
483
+ const html = renderHtml(doc, {
484
+ standalone: args.standalone,
485
+ title: args.title,
486
+ themeCss,
487
+ allowEscapeHatches,
488
+ externalAssets: args.externalAssets,
489
+ ...(args.math ? { math: args.math } : {}),
490
+ });
491
+ output(html, args.out);
492
+ return;
493
+ }
494
+ case "llm": {
495
+ const llmOpts = {};
496
+ if (args.excludeStaleDays !== undefined) {
497
+ const now = args.now ? new Date(args.now) : new Date();
498
+ if (Number.isNaN(now.getTime())) {
499
+ process.stderr.write(`error: --now value is not a valid date\n`);
500
+ process.exit(2);
501
+ }
502
+ llmOpts.excludeStale = { now, days: args.excludeStaleDays };
503
+ }
504
+ if (args.llmSelect.length > 0)
505
+ llmOpts.select = args.llmSelect;
506
+ if (args.llmExclude.length > 0)
507
+ llmOpts.exclude = args.llmExclude;
508
+ if (args.llmBudget !== undefined)
509
+ llmOpts.budget = args.llmBudget;
510
+ output(renderLlm(doc, llmOpts), args.out);
511
+ return;
512
+ }
513
+ case "json": {
514
+ output(renderJson(doc, { pretty: true }), args.out);
515
+ return;
516
+ }
517
+ case "noma": {
518
+ output(renderNoma(doc), args.out);
519
+ return;
520
+ }
521
+ default:
522
+ process.stderr.write(`error: unknown target "${to}"\n`);
523
+ process.exit(2);
524
+ }
525
+ return;
526
+ }
527
+ case "check": {
528
+ const diagnostics = validate(doc, {
529
+ ...(args.staleDays !== undefined ? { staleCitationDays: args.staleDays } : {}),
530
+ ...(args.ignoreRules.length > 0 ? { ignoreRules: args.ignoreRules } : {}),
531
+ });
532
+ const formatted = formatDiagnostics(diagnostics, args.file);
533
+ process.stdout.write(formatted + "\n");
534
+ const hasError = diagnostics.some((d) => d.severity === "error");
535
+ process.exit(hasError ? 1 : 0);
536
+ }
537
+ case "patch": {
538
+ const tx = patchTransactionFromArgs(args);
539
+ if (tx.ops.length === 0) {
540
+ process.stderr.write(`error: noma patch needs --op or --ops\n`);
541
+ process.exit(2);
542
+ }
543
+ if (isBookManifestPath(filePath)) {
544
+ process.stderr.write(`error: noma patch operates on .noma source files, not book manifests\n`);
545
+ process.exit(2);
546
+ }
547
+ const before = readFileSync(filePath, "utf8");
548
+ if (tx.prevalidate) {
549
+ const preErrors = validatePatchSource(before, filePath);
550
+ if (preErrors) {
551
+ process.stderr.write(`error: pre-validation failed\n${preErrors}\n`);
552
+ process.exit(1);
553
+ }
554
+ }
555
+ const printed = patchSource(before, tx.ops);
556
+ if (tx.postvalidate) {
557
+ const postErrors = validatePatchSource(printed, filePath);
558
+ if (postErrors) {
559
+ process.stderr.write(`error: post-validation failed\n${postErrors}\n`);
560
+ process.exit(1);
561
+ }
562
+ }
563
+ const target = args.inplace ? filePath : args.out;
564
+ output(printed, target);
565
+ return;
566
+ }
567
+ default:
568
+ process.stderr.write(`error: unknown command "${cmd}"\n\n${HELP}`);
569
+ process.exit(2);
570
+ }
571
+ }
572
+ main();
573
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/diff.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import type { DirectiveNode, DocumentNode } from "./ast.js";
2
+ export interface DiffOptions {
3
+ /**
4
+ * Required timestamp written as `at=` on every emitted state_change. Format:
5
+ * `YYYY-MM-DD` (or any ISO-8601 date string). Required so output is
6
+ * deterministic — same inputs always produce the same bytes.
7
+ */
8
+ at: string;
9
+ /**
10
+ * Optional reason string applied to every emitted state_change. Surfaces in
11
+ * the rendered narrative; agents typically set this to a commit message or
12
+ * a refresh trigger description.
13
+ */
14
+ reason?: string;
15
+ }
16
+ /**
17
+ * Compare two parsed documents and emit a flat list of synthesized
18
+ * `::state_change` directives describing every scalar attribute drift on
19
+ * blocks identified by `id` and present in both snapshots.
20
+ *
21
+ * v0.7 scope: only attributes defined on both sides where the value differs.
22
+ * Out of scope: attribute add (only-after), attribute delete (only-before),
23
+ * prose/heading changes, block adds/deletes, block renames, ID-less
24
+ * directives, nested-children diffs. Tracked for v0.7.1.
25
+ *
26
+ * Throws if either document contains duplicate IDs (the validator already
27
+ * flags this as an error; diff cannot reason about which copy to compare).
28
+ */
29
+ export declare function diffDocs(before: DocumentNode, after: DocumentNode, options: DiffOptions): DirectiveNode[];