aontu 0.63.0 → 0.64.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 (61) hide show
  1. package/README.md +6 -6
  2. package/dist/aontu.d.ts +3 -3
  3. package/dist/aontu.js +4 -6
  4. package/dist/aontu.js.map +1 -1
  5. package/dist/aontumodel.js +6 -12
  6. package/dist/aontumodel.js.map +1 -1
  7. package/dist/casing.d.ts +5 -0
  8. package/dist/casing.js +90 -0
  9. package/dist/casing.js.map +1 -0
  10. package/dist/cli.d.ts +2 -2
  11. package/dist/cli.js +147 -335
  12. package/dist/cli.js.map +1 -1
  13. package/dist/helpdoc.js +1 -1
  14. package/dist/helpdoc.js.map +1 -1
  15. package/dist/hints.js +3 -0
  16. package/dist/hints.js.map +1 -1
  17. package/dist/lsp.d.ts +1 -1
  18. package/dist/mcp.js +0 -36
  19. package/dist/mcp.js.map +1 -1
  20. package/dist/mod-tool.js +16 -1
  21. package/dist/mod-tool.js.map +1 -1
  22. package/dist/profile.d.ts +9 -0
  23. package/dist/profile.js +28 -0
  24. package/dist/profile.js.map +1 -0
  25. package/dist/trace.d.ts +21 -0
  26. package/dist/trace.js +107 -0
  27. package/dist/trace.js.map +1 -0
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/dist/unify.js +1 -6
  30. package/dist/unify.js.map +1 -1
  31. package/dist/val/CmpFuncVal.d.ts +2 -0
  32. package/dist/val/CmpFuncVal.js +47 -13
  33. package/dist/val/CmpFuncVal.js.map +1 -1
  34. package/dist/val/NomFuncVal.js +11 -13
  35. package/dist/val/NomFuncVal.js.map +1 -1
  36. package/dist/val/ReferFuncVal.js +3 -0
  37. package/dist/val/ReferFuncVal.js.map +1 -1
  38. package/package.json +1 -1
  39. package/skill/tasks.md +9 -7
  40. package/src/aontu.ts +3 -8
  41. package/src/aontumodel.ts +6 -12
  42. package/src/casing.ts +95 -0
  43. package/src/cli.ts +162 -359
  44. package/src/helpdoc.ts +1 -1
  45. package/src/hints.ts +3 -0
  46. package/src/mcp.ts +0 -39
  47. package/src/mod-tool.ts +18 -1
  48. package/src/profile.ts +42 -0
  49. package/src/trace.ts +157 -0
  50. package/src/unify.ts +1 -6
  51. package/src/val/CmpFuncVal.ts +66 -20
  52. package/src/val/NomFuncVal.ts +3 -5
  53. package/src/val/ReferFuncVal.ts +4 -0
  54. package/dist/lower.d.ts +0 -23
  55. package/dist/lower.js +0 -528
  56. package/dist/lower.js.map +0 -1
  57. package/dist/render.d.ts +0 -53
  58. package/dist/render.js +0 -432
  59. package/dist/render.js.map +0 -1
  60. package/src/lower.ts +0 -586
  61. package/src/render.ts +0 -580
package/dist/cli.js CHANGED
@@ -13,8 +13,8 @@ exports.runRelations = runRelations;
13
13
  exports.runReaches = runReaches;
14
14
  exports.runView = runView;
15
15
  exports.runJsonSchema = runJsonSchema;
16
- exports.runRender = runRender;
17
16
  exports.runTemplate = runTemplate;
17
+ exports.runTrace = runTrace;
18
18
  exports.runMod = runMod;
19
19
  exports.runHash = runHash;
20
20
  exports.runGet = runGet;
@@ -40,8 +40,8 @@ const node_path_1 = require("node:path");
40
40
  const node_os_1 = require("node:os");
41
41
  const node_readline_1 = require("node:readline");
42
42
  const aontu_1 = require("./aontu");
43
+ const trace_1 = require("./trace");
43
44
  const template_1 = require("./template");
44
- const mcp_1 = require("./mcp");
45
45
  const report_sarif_1 = require("./report-sarif");
46
46
  const lsp_server_1 = require("./lsp-server");
47
47
  const mcp_server_1 = require("./mcp-server");
@@ -67,11 +67,10 @@ const HELP = `Usage: aontu [options] [file]
67
67
  aontu view <kind> [options] <file>...
68
68
  aontu view --views <path> [--check] [options] <file>
69
69
  aontu jsonschema [--at <path>] [--strict] [options] <file>
70
- aontu render [--at <path>] [--profile <file>]... [--unit <path>]
71
- [--stdout | --out <dir> | --check <dir> | --coverage]
72
- [--coverage-at <path>] [--strict] <file>
73
70
  aontu template [--resugar] [--check] [--marker <token>]
74
71
  [--profile <file>] <file>
72
+ aontu trace [--at <path>] [--format json] [--marker <token>]
73
+ [--profile <file>] <file>
75
74
  aontu hash [options] <file>
76
75
  aontu mod tidy|verify|vendor|manifest [options] [dir]
77
76
  aontu get <path> [options] <file>
@@ -317,37 +316,11 @@ View exit codes: 0 rendered, 1 --check mismatch or lossy under
317
316
  --strict, 2 usage or --max-rows exceeded, 4 the document does not stand
318
317
  up on its own, or a relation, root or path that names nothing.
319
318
 
320
- Render options:
321
- --at <path> Render the value at this path ($.a.b); the root by
322
- default
323
- --profile <file> A profile document, aontu: render: Lang: {lang,
324
- ...}, vetted against aontu:render; repeatable,
325
- one per language
326
- --unit <path> Render only the unit with this path
327
- --stdout One unit's bytes and nothing else (with --unit when
328
- the instance has several)
329
- --out <dir> Write every unit below dir, or nothing; never deletes
330
- --check <dir> Compare every unit with dir/<path>; drift is listed
331
- --coverage Report what the render read and what it did not:
332
- model paths no output consumed, and rendered
333
- declarations no rule produced. Writes nothing
334
- --coverage-at <p> Measure coverage under this path only, instead of
335
- the document root
336
- --strict Refuse the opaque escapes (a text declaration, a raw
337
- block)
338
- --format <f> text (default) or json, the whole report; json
339
- carries the dispatch trace, one entry per emitted
340
- piece
341
-
342
- Render exit codes: 0 rendered, 1 lossy under --strict or drift under
343
- --check, 2 usage or I/O (a refused unit path included), 4 the document
344
- does not stand up or the instance is not aontu:code.
345
-
346
- A render entry file whose extension is not .aon is a TEMPLATE: a
347
- generator in the target's own syntax, whose marker lines carry aontu
348
- and whose other lines are output. It is desugared before it is
349
- evaluated, and a language the table does not know names its marker with
350
- --marker, or declares it once in a profile file that --profile reads.
319
+ A template entry file whose extension is not .aon is a GENERATOR: a
320
+ document in the target's own syntax, whose marker lines carry aontu and
321
+ whose other lines are output. It is desugared before it is evaluated,
322
+ and a language the table does not know names its marker with --marker,
323
+ or declares it once in a profile file that --profile reads.
351
324
 
352
325
  Template options:
353
326
  --resugar The file is the canonical aontu; print the template
@@ -457,11 +430,11 @@ Fmt options:
457
430
  The fmt verb prints one document in the agreed form; with no file it
458
431
  reads standard input. Several files need one of the options above.
459
432
 
460
- A file whose extension is not .aon is a GENERATOR, as it is for render:
461
- the aontu its marker lines carry is formatted, the marker stands at the
462
- left margin with the aontu indented after it, and every line of output
463
- is held on a line of its own. A file with no marker line in it is
464
- another language's, and is refused.
433
+ A file whose extension is not .aon is a GENERATOR, as it is for
434
+ template: the aontu its marker lines carry is formatted, the marker
435
+ stands at the left margin with the aontu indented after it, and every
436
+ line of output is held on a line of its own. A file with no marker line
437
+ in it is another language's, and is refused.
465
438
 
466
439
  Fmt exit codes: 0 formatted or clean, 1 a --check file would change or
467
440
  a --strict finding, 2 usage, 4 a document does not parse.
@@ -1764,6 +1737,12 @@ const VIEW_USAGE_CODES = [
1764
1737
  ];
1765
1738
  const MOD_HELP = 'aontu mod tidy|verify|vendor|manifest [dir] (try --help)';
1766
1739
  function runMod(argv) {
1740
+ const trusted = takeTrust(argv);
1741
+ if (null == trusted) {
1742
+ return 2;
1743
+ }
1744
+ argv = trusted.argv;
1745
+ const trust = trusted.trust;
1767
1746
  const rest = [];
1768
1747
  let format = 'text';
1769
1748
  let against;
@@ -1819,10 +1798,11 @@ function runMod(argv) {
1819
1798
  process.stderr.write('aontu: --against is a manifest option\n');
1820
1799
  return 2;
1821
1800
  }
1822
- const report = 'tidy' === sub ? (0, mod_tool_1.modTidy)(dir, modToolOptions()) :
1823
- 'verify' === sub ? (0, mod_tool_1.modVerify)(dir, modToolOptions()) :
1824
- 'vendor' === sub ? (0, mod_tool_1.modVendor)(dir, modToolOptions()) :
1825
- (0, mod_tool_1.modManifest)(dir, modToolOptions(), against);
1801
+ const modopts = modToolOptions(trust, (0, node_path_1.resolve)(dir));
1802
+ const report = 'tidy' === sub ? (0, mod_tool_1.modTidy)(dir, modopts) :
1803
+ 'verify' === sub ? (0, mod_tool_1.modVerify)(dir, modopts) :
1804
+ 'vendor' === sub ? (0, mod_tool_1.modVendor)(dir, modopts) :
1805
+ (0, mod_tool_1.modManifest)(dir, modopts, against);
1826
1806
  process.stdout.write(('json' === format ?
1827
1807
  (0, aontu_1.exactJSON)({ aontu: { version: version(), verb: 'mod ' + sub }, ...report }, 2) :
1828
1808
  modText(sub, report)) + '\n');
@@ -1843,11 +1823,16 @@ const MOD_EXIT = {
1843
1823
  // The tooling's evaluator: the same standalone evaluation the module
1844
1824
  // resolver verifies with (ts/src/mod.ts), and for the same reason —
1845
1825
  // only the engine can say what a module MEANS.
1846
- function modToolOptions() {
1826
+ function modToolOptions(trust, entryRoot) {
1827
+ const opts = verbOpts(trust, entryRoot);
1828
+ // The user cache lives outside any confinement root, so a confined
1829
+ // run reads the vendor tree only -- as the evaluator's own module
1830
+ // leg already does when a root is set.
1831
+ const rooted = null != opts.trust?.include?.root;
1847
1832
  return {
1848
- cache: (0, mod_1.modCacheDir)(),
1833
+ ...(rooted ? {} : { cache: (0, mod_1.modCacheDir)() }),
1849
1834
  eval: (src, path) => {
1850
- const a0 = new aontu_1.Aontu();
1835
+ const a0 = new aontu_1.Aontu(opts);
1851
1836
  const ctx = a0.ctx({ collect: true });
1852
1837
  const val = a0.unify(src, { path }, ctx);
1853
1838
  return {
@@ -1981,6 +1966,108 @@ function runRelations(argv) {
1981
1966
  }
1982
1967
  return RELATIONS_EXIT[report.verdict];
1983
1968
  }
1969
+ const TRACE_HELP = 'aontu trace [--at <path>] [--format json] [--marker <token>] ' +
1970
+ '[--profile <file>] <file>';
1971
+ // WHAT WROTE THIS LINE. Every piece a rule stamped, under the
1972
+ // component tree, with the file it reached, the rule set that wrote it
1973
+ // and the model node the dispatch matched.
1974
+ function runTrace(argv) {
1975
+ const trusted = takeTrust(argv);
1976
+ if (null == trusted) {
1977
+ return 2;
1978
+ }
1979
+ argv = trusted.argv;
1980
+ const trust = trusted.trust;
1981
+ const rest = [];
1982
+ const profileFiles = [];
1983
+ let format = 'text';
1984
+ let at = undefined;
1985
+ let marker = undefined;
1986
+ for (let i = 0; i < argv.length; i++) {
1987
+ const arg = argv[i];
1988
+ if ('-h' === arg || '--help' === arg) {
1989
+ process.stdout.write(HELP);
1990
+ return 0;
1991
+ }
1992
+ if ('--format' === arg) {
1993
+ const f = argv[++i];
1994
+ if ('text' !== f && 'json' !== f) {
1995
+ process.stderr.write('aontu: --format needs text or json\n');
1996
+ return 2;
1997
+ }
1998
+ format = f;
1999
+ }
2000
+ else if ('--at' === arg) {
2001
+ at = argv[++i];
2002
+ if (null == at) {
2003
+ process.stderr.write('aontu: --at needs a path\n');
2004
+ return 2;
2005
+ }
2006
+ }
2007
+ else if ('--marker' === arg) {
2008
+ marker = argv[++i];
2009
+ if (null == marker) {
2010
+ process.stderr.write('aontu: --marker needs a token\n');
2011
+ return 2;
2012
+ }
2013
+ }
2014
+ else if ('--profile' === arg) {
2015
+ const pf = argv[++i];
2016
+ if (null == pf) {
2017
+ process.stderr.write('aontu: --profile needs a file\n');
2018
+ return 2;
2019
+ }
2020
+ profileFiles.push(pf);
2021
+ }
2022
+ else if (arg.startsWith('-')) {
2023
+ process.stderr.write(`aontu: unknown trace option ${arg} (try --help)\n`);
2024
+ return 2;
2025
+ }
2026
+ else {
2027
+ rest.push(arg);
2028
+ }
2029
+ }
2030
+ if (1 !== rest.length) {
2031
+ process.stderr.write(`aontu: trace needs one file\n${TRACE_HELP}\n`);
2032
+ return 2;
2033
+ }
2034
+ let src;
2035
+ try {
2036
+ src = (0, node_fs_1.readFileSync)(rest[0], 'utf8');
2037
+ }
2038
+ catch (err) {
2039
+ process.stderr.write(`aontu: cannot read ${err.path}: ${err.message}\n`);
2040
+ return 2;
2041
+ }
2042
+ const declared = loadProfiles(profileFiles, trust);
2043
+ if ('number' === typeof declared) {
2044
+ return declared;
2045
+ }
2046
+ // A GENERATOR IS AN ENTRY, not a preprocessing step: the file whose
2047
+ // provenance is asked for is the one the author edits.
2048
+ if (!rest[0].endsWith('.aon')) {
2049
+ src = (0, template_1.desugarTemplate)(src, marker ??
2050
+ (0, template_1.markerFromProfiles)(declared, rest[0]) ?? (0, template_1.markerFor)(rest[0]));
2051
+ }
2052
+ const report = (0, trace_1.traceRun)(src, {
2053
+ path: rest[0], at,
2054
+ ...verbOpts(trust, entryRootOf(rest[0])),
2055
+ });
2056
+ if ('error' === report.verdict) {
2057
+ // An error report always carries its findings.
2058
+ const errors = report.errors;
2059
+ process.stderr.write(errors.map(renderFinding).join('\n') + '\n');
2060
+ return 4;
2061
+ }
2062
+ if ('json' === format) {
2063
+ process.stdout.write(JSON.stringify({ trace: report.trace }) + '\n');
2064
+ return 0;
2065
+ }
2066
+ for (const e of report.trace) {
2067
+ process.stdout.write([e.file, e.at, e.node, e.rule].join('\t') + '\n');
2068
+ }
2069
+ return 0;
2070
+ }
1984
2071
  function runReaches(argv) {
1985
2072
  const trusted = takeTrust(argv);
1986
2073
  if (null == trusted) {
@@ -2530,281 +2617,6 @@ function runJsonSchema(argv) {
2530
2617
  return 'error' === report.verdict ? 4 :
2531
2618
  strict && 'lossy' === report.verdict ? 1 : 0;
2532
2619
  }
2533
- const RENDER_HELP = 'aontu render [--at <path>] [--profile <file>]... [--unit <path>] ' +
2534
- '[--stdout | --out <dir> | --check <dir> | --coverage] ' +
2535
- '[--coverage-at <path>] [--strict] [--marker <token>] <file> (try --help)';
2536
- function runRender(argv) {
2537
- const trusted = takeTrust(argv);
2538
- if (null == trusted) {
2539
- return 2;
2540
- }
2541
- argv = trusted.argv;
2542
- const trust = trusted.trust;
2543
- const files = [];
2544
- const profileFiles = [];
2545
- let format = 'text';
2546
- let at = undefined;
2547
- let unit = undefined;
2548
- let out = undefined;
2549
- let check = undefined;
2550
- let toStdout = false;
2551
- let strict = false;
2552
- let coverage = false;
2553
- let coverageAt = undefined;
2554
- let marker = undefined;
2555
- for (let i = 0; i < argv.length; i++) {
2556
- const arg = argv[i];
2557
- if ('-h' === arg || '--help' === arg) {
2558
- process.stdout.write(HELP);
2559
- return 0;
2560
- }
2561
- if ('--format' === arg) {
2562
- const f = argv[++i];
2563
- if ('text' !== f && 'json' !== f) {
2564
- process.stderr.write('aontu: --format needs text or json\n');
2565
- return 2;
2566
- }
2567
- format = f;
2568
- }
2569
- else if ('--at' === arg) {
2570
- at = argv[++i];
2571
- if (null == at) {
2572
- process.stderr.write('aontu: --at needs a path\n');
2573
- return 2;
2574
- }
2575
- }
2576
- else if ('--unit' === arg) {
2577
- unit = argv[++i];
2578
- if (null == unit) {
2579
- process.stderr.write('aontu: --unit needs a unit path\n');
2580
- return 2;
2581
- }
2582
- }
2583
- else if ('--profile' === arg) {
2584
- const pf = argv[++i];
2585
- if (null == pf) {
2586
- process.stderr.write('aontu: --profile needs a file\n');
2587
- return 2;
2588
- }
2589
- profileFiles.push(pf);
2590
- }
2591
- else if ('--out' === arg) {
2592
- out = argv[++i];
2593
- if (null == out) {
2594
- process.stderr.write('aontu: --out needs a directory\n');
2595
- return 2;
2596
- }
2597
- }
2598
- else if ('--check' === arg) {
2599
- check = argv[++i];
2600
- if (null == check) {
2601
- process.stderr.write('aontu: --check needs a directory\n');
2602
- return 2;
2603
- }
2604
- }
2605
- else if ('--stdout' === arg) {
2606
- toStdout = true;
2607
- }
2608
- else if ('--coverage' === arg) {
2609
- coverage = true;
2610
- }
2611
- else if ('--marker' === arg) {
2612
- marker = argv[++i];
2613
- if (null == marker) {
2614
- process.stderr.write('aontu: --marker needs a token\n');
2615
- return 2;
2616
- }
2617
- }
2618
- else if ('--coverage-at' === arg) {
2619
- coverageAt = argv[++i];
2620
- if (null == coverageAt) {
2621
- process.stderr.write('aontu: --coverage-at needs a path\n');
2622
- return 2;
2623
- }
2624
- }
2625
- else if ('--strict' === arg) {
2626
- strict = true;
2627
- }
2628
- else if (arg.startsWith('-')) {
2629
- process.stderr.write(`aontu: unknown render option ${arg} (try --help)\n`);
2630
- return 2;
2631
- }
2632
- else {
2633
- files.push(arg);
2634
- }
2635
- }
2636
- if (1 !== files.length) {
2637
- process.stderr.write(`aontu: render needs one file\n${RENDER_HELP}\n`);
2638
- return 2;
2639
- }
2640
- const modes = [toStdout, undefined !== out, undefined !== check, coverage]
2641
- .filter((on) => on).length;
2642
- if (1 < modes) {
2643
- process.stderr.write('aontu: render takes one of --stdout, --out, --check or --coverage\n');
2644
- return 2;
2645
- }
2646
- // A NARROWER MEASURE NEEDS SOMETHING TO NARROW. `--coverage-at`
2647
- // without `--coverage` asks for a report the run does not compute,
2648
- // and answering silently would be the wrong half of the request.
2649
- if (undefined !== coverageAt && !coverage) {
2650
- process.stderr.write('aontu: --coverage-at needs --coverage\n');
2651
- return 2;
2652
- }
2653
- let src;
2654
- try {
2655
- src = (0, node_fs_1.readFileSync)(files[0], 'utf8');
2656
- }
2657
- catch (err) {
2658
- process.stderr.write(`aontu: cannot read ${err.path}: ${err.message}\n`);
2659
- return 2;
2660
- }
2661
- const loadedProfiles = loadProfiles(profileFiles, trust);
2662
- if ('number' === typeof loadedProfiles) {
2663
- return loadedProfiles;
2664
- }
2665
- const profiles = loadedProfiles;
2666
- if (!files[0].endsWith('.aon')) {
2667
- src = (0, template_1.desugarTemplate)(src, marker ??
2668
- (0, template_1.markerFromProfiles)(profiles, files[0]) ?? (0, template_1.markerFor)(files[0]));
2669
- }
2670
- // A RENDER WITH NO PROFILE PRODUCES NO UNITS, and said so with zero
2671
- // bytes and exit 0. The profile is what maps a model onto a
2672
- // language, so without one there is nothing for the renderer to
2673
- // write -- which is a usable answer only if the caller is told.
2674
- const noProfiles = 0 === profiles.length;
2675
- const report = (0, aontu_1.render)(src, {
2676
- at, unit, strict, profiles, path: files[0],
2677
- coverage, coverageAt,
2678
- // THE JSON REPORT CARRIES THE TRACE (D9), which is what the shape
2679
- // there has always said; a text run computes it only when the
2680
- // coverage report needs it.
2681
- trace: 'json' === format,
2682
- ...verbOpts(trust, entryRootOf(files[0])),
2683
- });
2684
- // Said once, whatever the format: stdout stays the report.
2685
- if ('error' !== report.verdict && 0 === report.units.length) {
2686
- vacuous('nothing was rendered', noProfiles
2687
- ? 'no profile was given, and the document declares none' +
2688
- ' (see aontu help tasks)'
2689
- : 'the document produced no units under this profile');
2690
- }
2691
- if ('json' === format) {
2692
- process.stdout.write((0, aontu_1.exactJSON)({
2693
- aontu: { version: version(), verb: 'render' },
2694
- verdict: report.verdict,
2695
- units: report.units,
2696
- lossy: report.lossy,
2697
- ...(null == report.errors ? {} : { errors: report.errors }),
2698
- ...(null == report.trace ? {} : { trace: report.trace }),
2699
- ...(null == report.coverage ? {} : { coverage: report.coverage }),
2700
- }, 2) + '\n');
2701
- return renderExit(report, 0);
2702
- }
2703
- if ('error' === report.verdict) {
2704
- process.stderr.write(report.errors.map(renderFinding).join('\n') + '\n');
2705
- return renderExit(report, 0);
2706
- }
2707
- let drift = 0;
2708
- if (toStdout) {
2709
- // ONE UNIT'S BYTES AND NOTHING ELSE, so the output can be piped
2710
- // into a formatter or a file.
2711
- if (1 !== report.units.length) {
2712
- process.stderr.write('aontu: --stdout needs exactly one unit, and the instance has ' +
2713
- `${report.units.length}; --unit names one\n`);
2714
- return 2;
2715
- }
2716
- process.stdout.write(report.units[0].text);
2717
- }
2718
- else if (undefined !== out) {
2719
- // EVERY UNIT BELOW <dir>, OR NOTHING: every unit rendered first
2720
- // (the report above), and no file touched unless all did. The
2721
- // directory is realpath-confined; a unit path is already a relative
2722
- // descent (render_path refuses the rest), and the check here is
2723
- // against the symlink inside it. render never deletes.
2724
- for (const u of report.units) {
2725
- if ((0, mcp_1.outsideRoot)(out, (0, node_path_1.resolve)(out, u.path))) {
2726
- process.stderr.write(`aontu: ${u.path} escapes ${out}\n`);
2727
- return 2;
2728
- }
2729
- }
2730
- for (const u of report.units) {
2731
- const full = (0, node_path_1.resolve)(out, u.path);
2732
- try {
2733
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(full), { recursive: true });
2734
- (0, node_fs_1.writeFileSync)(full, u.text, 'utf8');
2735
- }
2736
- catch (err) {
2737
- process.stderr.write(`aontu: cannot write ${u.path}: ${err.message}\n`);
2738
- return 2;
2739
- }
2740
- process.stderr.write(`wrote ${u.path}\n`);
2741
- }
2742
- }
2743
- else if (undefined !== check) {
2744
- // RENDER AND COMPARE: a unit whose bytes differ from the file at
2745
- // <dir>/<path>, or whose file is absent, is drift, listed by path.
2746
- // The CI form.
2747
- for (const u of report.units) {
2748
- let have = undefined;
2749
- try {
2750
- have = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(check, u.path), 'utf8');
2751
- }
2752
- catch {
2753
- // Absent is drift, reported below.
2754
- }
2755
- if (undefined === have) {
2756
- drift++;
2757
- process.stderr.write(`aontu: ${u.path} is missing from ${check}\n`);
2758
- }
2759
- else if (have !== u.text) {
2760
- drift++;
2761
- process.stderr.write(`aontu: ${u.path} differs from the rendered unit\n`);
2762
- }
2763
- }
2764
- }
2765
- else if (coverage) {
2766
- // THE COVERAGE REPORT (P7), one line per finding and a count at
2767
- // the end: dead model first, then the declarations no rule
2768
- // produced. A clean report is the count line alone.
2769
- const cov = report.coverage;
2770
- for (const d of cov.dead) {
2771
- process.stdout.write(`dead: ${d}\n`);
2772
- }
2773
- for (const u of cov.unruled) {
2774
- process.stdout.write(`unruled: ${u.unit} ${u.path}\n`);
2775
- }
2776
- process.stdout.write(`coverage: ${cov.read.length} path(s) read, ${cov.dead.length} ` +
2777
- `no output consumed, ${cov.unruled.length} declaration(s) ` +
2778
- 'no rule produced\n');
2779
- }
2780
- else {
2781
- // THE SUMMARY: one line per unit -- its path, its language and its
2782
- // size -- since several units have no one text to print.
2783
- for (const u of report.units) {
2784
- process.stdout.write(`${u.path}\t${u.lang}\t${u.text.length} bytes\n`);
2785
- }
2786
- }
2787
- for (const l of report.lossy) {
2788
- process.stderr.write(`lossy: ${l.unit} ${l.path} tier ${l.tier} ${l.construct}: ${l.reason}\n`);
2789
- }
2790
- return renderExit(report, drift);
2791
- }
2792
- // D8's exit table over a report: a refused unit path is usage (2), a
2793
- // strict refusal is lossy (1), any other error is the document's (4);
2794
- // drift under --check is 1.
2795
- function renderExit(report, drift) {
2796
- if ('error' === report.verdict) {
2797
- const errors = report.errors;
2798
- if (errors.every((f) => 'render_path' === f.code)) {
2799
- return 2;
2800
- }
2801
- if (errors.every((f) => 'render_strict' === f.code)) {
2802
- return 1;
2803
- }
2804
- return 4;
2805
- }
2806
- return 0 < drift ? 1 : 0;
2807
- }
2808
2620
  const TEMPLATE_HELP = 'aontu template [--resugar] [--check] [--marker <token>] <file> (try --help)';
2809
2621
  function runTemplate(argv) {
2810
2622
  const trusted = takeTrust(argv);
@@ -2896,9 +2708,9 @@ function runTemplate(argv) {
2896
2708
  return 0;
2897
2709
  }
2898
2710
  // The profiles named by --profile, vetted, or the exit code that says
2899
- // why not. A profile is a language declared as data: `render` matches
2900
- // one to a unit by `lang`, and `template` and `fmt` match one to a file
2901
- // by the extensions its `template.ext` names.
2711
+ // why not. A profile is a language declared as data: `template` and
2712
+ // `fmt` match one to a file by the extensions its `template.ext`
2713
+ // names.
2902
2714
  function loadProfiles(profileFiles, trust) {
2903
2715
  const profiles = [];
2904
2716
  const langs = new Map();
@@ -2911,7 +2723,7 @@ function loadProfiles(profileFiles, trust) {
2911
2723
  process.stderr.write(`aontu: cannot read ${err.path}: ${err.message}\n`);
2912
2724
  return 2;
2913
2725
  }
2914
- const loaded = (0, aontu_1.renderProfile)(text, { path: (0, node_path_1.resolve)(pf), ...verbOpts(trust, entryRootOf(pf)) });
2726
+ const loaded = (0, aontu_1.loadProfile)(text, { path: (0, node_path_1.resolve)(pf), ...verbOpts(trust, entryRootOf(pf)) });
2915
2727
  if (undefined !== loaded.errors) {
2916
2728
  process.stderr.write(loaded.errors.map(renderFinding).join('\n') + '\n');
2917
2729
  return 4;
@@ -3583,8 +3395,8 @@ function runFmt(argv) {
3583
3395
  }
3584
3396
  else if ('--marker' === arg) {
3585
3397
  // THE MARKER SAYS THE FILE IS A GENERATOR, whatever its
3586
- // extension: `render` and `template` take the same option for
3587
- // the same reason, a language the table has never seen.
3398
+ // extension: `fmt` and `template` take the same option for the
3399
+ // same reason, a language the table has never seen.
3588
3400
  marker = argv[++i];
3589
3401
  if (null == marker) {
3590
3402
  process.stderr.write('aontu: --marker needs a token\n');
@@ -3991,8 +3803,8 @@ function runInit(argv) {
3991
3803
  const KNOWN_VERBS = [
3992
3804
  'agentsmd', 'allow', 'breaking', 'explain', 'fmt', 'get', 'hash',
3993
3805
  'help', 'init', 'jsonschema', 'lsp', 'mcp', 'mod', 'reaches',
3994
- 'relations', 'render', 'set', 'subsume', 'template', 'trim', 'vet',
3995
- 'view', 'why',
3806
+ 'relations', 'set', 'subsume', 'template', 'trace', 'trim',
3807
+ 'vet', 'view', 'why',
3996
3808
  ];
3997
3809
  exports.KNOWN_VERBS = KNOWN_VERBS;
3998
3810
  // looksLikeVerb reports whether an unreadable argument was meant as a
@@ -4112,12 +3924,12 @@ function main(argv, servers = SERVERS) {
4112
3924
  if ('jsonschema' === argv[2]) {
4113
3925
  return finish(runJsonSchema(argv.slice(3)));
4114
3926
  }
4115
- if ('render' === argv[2]) {
4116
- return finish(runRender(argv.slice(3)));
4117
- }
4118
3927
  if ('template' === argv[2]) {
4119
3928
  return finish(runTemplate(argv.slice(3)));
4120
3929
  }
3930
+ if ('trace' === argv[2]) {
3931
+ return finish(runTrace(argv.slice(3)));
3932
+ }
4121
3933
  if ('reaches' === argv[2]) {
4122
3934
  return finish(runReaches(argv.slice(3)));
4123
3935
  }
@@ -4212,5 +4024,5 @@ function main(argv, servers = SERVERS) {
4212
4024
  else {
4213
4025
  runStdin(mode, format, trust).then((code) => finish(code));
4214
4026
  }
4215
- } /* node:coverage ignore next 20 */
4027
+ } /* node:coverage ignore next 21 */
4216
4028
  //# sourceMappingURL=cli.js.map