aontu 0.53.0 → 0.55.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/dist/aontu.d.ts +3 -2
- package/dist/aontu.js +36 -7
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +500 -8
- package/dist/cli.js.map +1 -1
- package/dist/ctx.d.ts +5 -0
- package/dist/ctx.js +1 -0
- package/dist/ctx.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/err.js +7 -1
- package/dist/err.js.map +1 -1
- package/dist/graph.d.ts +2 -5
- package/dist/graph.js +83 -46
- package/dist/graph.js.map +1 -1
- package/dist/hcanon.js +9 -10
- package/dist/hcanon.js.map +1 -1
- package/dist/hints.js +94 -26
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.js +34 -0
- package/dist/jsonschema.js.map +1 -1
- package/dist/lang.js +593 -191
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +86 -6
- package/dist/lsp.js.map +1 -1
- package/dist/mcp.js +153 -6
- package/dist/mcp.js.map +1 -1
- package/dist/mod-tool.js +42 -8
- package/dist/mod-tool.js.map +1 -1
- package/dist/mod.d.ts +4 -0
- package/dist/mod.js +97 -2
- package/dist/mod.js.map +1 -1
- package/dist/patch.d.ts +5 -0
- package/dist/patch.js +25 -25
- package/dist/patch.js.map +1 -1
- package/dist/provenance.d.ts +1 -0
- package/dist/provenance.js +2 -1
- package/dist/provenance.js.map +1 -1
- package/dist/query.js.map +1 -1
- package/dist/reach.d.ts +1 -0
- package/dist/reach.js +49 -21
- package/dist/reach.js.map +1 -1
- package/dist/relation.d.ts +4 -0
- package/dist/relation.js +125 -200
- package/dist/relation.js.map +1 -1
- package/dist/sig.d.ts +25 -0
- package/dist/sig.js +277 -0
- package/dist/sig.js.map +1 -0
- package/dist/sigdecl.d.ts +2 -0
- package/dist/sigdecl.js +11 -0
- package/dist/sigdecl.js.map +1 -0
- package/dist/siggate.d.ts +4 -0
- package/dist/siggate.js +90 -0
- package/dist/siggate.js.map +1 -0
- package/dist/std.js +75 -16
- package/dist/std.js.map +1 -1
- package/dist/subsume.js +57 -10
- package/dist/subsume.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/unify.d.ts +2 -2
- package/dist/unify.js +93 -114
- package/dist/unify.js.map +1 -1
- package/dist/utility.d.ts +1 -2
- package/dist/utility.js +7 -61
- package/dist/utility.js.map +1 -1
- package/dist/val/AggFuncVal.d.ts +12 -1
- package/dist/val/AggFuncVal.js +165 -3
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/BagVal.d.ts +2 -0
- package/dist/val/BagVal.js +56 -8
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/ConstraintVal.js +33 -5
- package/dist/val/ConstraintVal.js.map +1 -1
- package/dist/val/ContainerKindVal.d.ts +35 -0
- package/dist/val/ContainerKindVal.js +99 -0
- package/dist/val/ContainerKindVal.js.map +1 -0
- package/dist/val/CopyFuncVal.js +0 -7
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/DisjunctVal.d.ts +1 -2
- package/dist/val/DisjunctVal.js +146 -39
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/ExpectVal.js +37 -2
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FuncBaseVal.d.ts +1 -0
- package/dist/val/FuncBaseVal.js +19 -8
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/GraphAtomVal.d.ts +39 -0
- package/dist/val/GraphAtomVal.js +184 -0
- package/dist/val/GraphAtomVal.js.map +1 -0
- package/dist/val/JunctionVal.js +22 -5
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/ListVal.js +27 -34
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/MapVal.d.ts +1 -0
- package/dist/val/MapVal.js +82 -35
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/PathFuncVal.d.ts +2 -2
- package/dist/val/PathFuncVal.js +75 -16
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PathVal.d.ts +25 -0
- package/dist/val/PathVal.js +150 -0
- package/dist/val/PathVal.js.map +1 -0
- package/dist/val/PlusOpVal.d.ts +2 -1
- package/dist/val/PlusOpVal.js +50 -35
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +2 -0
- package/dist/val/PrefVal.js +159 -32
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RecurseVal.d.ts +19 -0
- package/dist/val/RecurseVal.js +217 -0
- package/dist/val/RecurseVal.js.map +1 -0
- package/dist/val/RefVal.d.ts +2 -1
- package/dist/val/RefVal.js +105 -72
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.d.ts +30 -7
- package/dist/val/ReferFuncVal.js +395 -94
- package/dist/val/ReferFuncVal.js.map +1 -1
- package/dist/val/ScalarKindVal.d.ts +4 -2
- package/dist/val/ScalarKindVal.js +12 -1
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/SuperFuncVal.d.ts +4 -2
- package/dist/val/SuperFuncVal.js +118 -14
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.d.ts +1 -1
- package/dist/val/Val.d.ts +2 -3
- package/dist/val/Val.js +39 -20
- package/dist/val/Val.js.map +1 -1
- package/dist/val/arith.js +4 -1
- package/dist/val/arith.js.map +1 -1
- package/dist/vet.d.ts +1 -0
- package/dist/vet.js +32 -1
- package/dist/vet.js.map +1 -1
- package/dist/view.d.ts +90 -0
- package/dist/view.js +2168 -0
- package/dist/view.js.map +1 -0
- package/grammar/aontu.gbnf +18 -10
- package/grammar/aontu.lark +15 -10
- package/grammar/aontu.tmLanguage.json +184 -0
- package/package.json +10 -3
- package/skill/grammar-card.md +1 -2
- package/src/aontu.ts +37 -7
- package/src/cli.ts +553 -8
- package/src/ctx.ts +20 -0
- package/src/diff.ts +4 -2
- package/src/err.ts +8 -1
- package/src/graph.ts +125 -75
- package/src/hcanon.ts +9 -11
- package/src/hints.ts +112 -29
- package/src/jsonschema.ts +41 -0
- package/src/lang.ts +642 -203
- package/src/lsp.ts +75 -6
- package/src/mcp.ts +164 -6
- package/src/mod-tool.ts +48 -9
- package/src/mod.ts +110 -1
- package/src/patch.ts +31 -27
- package/src/provenance.ts +8 -1
- package/src/query.ts +4 -2
- package/src/reach.ts +52 -23
- package/src/relation.ts +139 -236
- package/src/sig.ts +345 -0
- package/src/sigdecl.ts +11 -0
- package/src/siggate.ts +144 -0
- package/src/std.ts +77 -16
- package/src/subsume.ts +59 -10
- package/src/unify.ts +102 -125
- package/src/utility.ts +7 -67
- package/src/val/AggFuncVal.ts +231 -4
- package/src/val/BagVal.ts +58 -9
- package/src/val/ConstraintVal.ts +34 -5
- package/src/val/ContainerKindVal.ts +158 -0
- package/src/val/CopyFuncVal.ts +0 -7
- package/src/val/DisjunctVal.ts +152 -40
- package/src/val/ExpectVal.ts +39 -4
- package/src/val/FuncBaseVal.ts +21 -8
- package/src/val/GraphAtomVal.ts +264 -0
- package/src/val/JunctionVal.ts +23 -6
- package/src/val/ListVal.ts +30 -37
- package/src/val/MapVal.ts +87 -39
- package/src/val/PathFuncVal.ts +107 -19
- package/src/val/PathVal.ts +221 -0
- package/src/val/PlusOpVal.ts +56 -37
- package/src/val/PrefVal.ts +186 -38
- package/src/val/RecurseVal.ts +285 -0
- package/src/val/RefVal.ts +105 -83
- package/src/val/ReferFuncVal.ts +445 -100
- package/src/val/ScalarKindVal.ts +12 -0
- package/src/val/SuperFuncVal.ts +137 -13
- package/src/val/TopVal.ts +1 -1
- package/src/val/Val.ts +44 -35
- package/src/val/arith.ts +4 -1
- package/src/vet.ts +41 -4
- package/src/view.ts +2882 -0
- package/dist/val/IdFuncVal.d.ts +0 -13
- package/dist/val/IdFuncVal.js +0 -54
- package/dist/val/IdFuncVal.js.map +0 -1
- package/src/val/IdFuncVal.ts +0 -91
package/src/cli.ts
CHANGED
|
@@ -40,6 +40,11 @@ import type { TrimReport, TrimVerdict } from './trim'
|
|
|
40
40
|
import type { RelationReport, RelationVerdict } from './relation'
|
|
41
41
|
import { reachCheck } from './reach'
|
|
42
42
|
import type { ReachReport, ReachVerdict } from './reach'
|
|
43
|
+
import { view, viewSet, viewDefaultProfile } from './view'
|
|
44
|
+
import type {
|
|
45
|
+
ViewEdges, ViewFigure, ViewKind, ViewLoss, ViewOptions, ViewProfile,
|
|
46
|
+
ViewReport, ViewSetReport, ViewStyle, ViewVerdict,
|
|
47
|
+
} from './view'
|
|
43
48
|
import type { QueryView } from './query'
|
|
44
49
|
import type { WhyRecord } from './provenance'
|
|
45
50
|
import { agentsMdSplice } from './agentsmd'
|
|
@@ -55,6 +60,8 @@ const HELP = `Usage: aontu [options] [file]
|
|
|
55
60
|
aontu trim --check [options] <file>
|
|
56
61
|
aontu relations [options] <file>
|
|
57
62
|
aontu reaches <from> <to> [--relation <name>] [options] <file>
|
|
63
|
+
aontu view <kind> [options] <file>...
|
|
64
|
+
aontu view --views <path> [--check] [options] <file>
|
|
58
65
|
aontu jsonschema [--at <path>] [--strict] [options] <file>
|
|
59
66
|
aontu hash [options] <file>
|
|
60
67
|
aontu mod tidy|verify|vendor|manifest [options] [dir]
|
|
@@ -175,6 +182,72 @@ Why options:
|
|
|
175
182
|
Why exit codes mirror get's: 0 explained, 1 the path names nothing,
|
|
176
183
|
2 usage, 4 the document does not stand up on its own.
|
|
177
184
|
|
|
185
|
+
View kinds: tree, matrix, graph, layer, sets, layers, ladder, poset
|
|
186
|
+
(the poset takes several files). The figure goes to stdout, the loss
|
|
187
|
+
report to stderr. With --views it draws every figure a document
|
|
188
|
+
declares as data, from one evaluation: each declaration names its own
|
|
189
|
+
kind and out file, nothing is written unless every figure rendered,
|
|
190
|
+
and --check gates the committed set.
|
|
191
|
+
|
|
192
|
+
View options:
|
|
193
|
+
--as <profile> text | mermaid | dot | er | svg, per kind: doc,
|
|
194
|
+
tree, matrix, sets and layers draw text (default)
|
|
195
|
+
or svg; graph draws mermaid (default), dot or er;
|
|
196
|
+
layer draws text (default), mermaid or svg; ladder
|
|
197
|
+
and poset draw mermaid (default) or dot
|
|
198
|
+
--at <path> Restrict the figure to nodes under this path; the
|
|
199
|
+
subtree doc draws; the path the ladder draws;
|
|
200
|
+
where the poset compares
|
|
201
|
+
--views <path> Draw every figure the document declares at this
|
|
202
|
+
path, one evaluation, all or nothing; each
|
|
203
|
+
declaration names its own kind and out file
|
|
204
|
+
-o, --out <file> Write the figure here instead of stdout
|
|
205
|
+
--check Exit 1 if --out differs from what would be drawn;
|
|
206
|
+
nothing is written
|
|
207
|
+
--strict Exit 1 when the loss report holds anything beyond
|
|
208
|
+
edges_deduped, inverse_suppressed and crossings
|
|
209
|
+
--depth <n> doc: how many levels of key to draw (default 3)
|
|
210
|
+
--max-rows <n> Refuse a figure above this many rows (default 60)
|
|
211
|
+
--style <s> auto (default), none, ansi or css. A figure's
|
|
212
|
+
marks carry their meaning -- a direct cell, a
|
|
213
|
+
closure cell, an upward edge -- and each profile
|
|
214
|
+
has one way to show it: SGR escapes for text, CSS
|
|
215
|
+
classes for svg. auto picks that mechanism where
|
|
216
|
+
the destination can carry it: escapes only on a
|
|
217
|
+
terminal (NO_COLOR is honoured), and an svg keeps
|
|
218
|
+
the stylesheet that makes it standalone. none
|
|
219
|
+
drops both; on svg the classes stay and only the
|
|
220
|
+
stylesheet goes, for a host page that has already
|
|
221
|
+
bound --av-ink and its kin. Escapes are never
|
|
222
|
+
written to a file
|
|
223
|
+
--format <f> text (default) or json, the whole report
|
|
224
|
+
--relation <n> tree, matrix, layer: draw over this relation only;
|
|
225
|
+
graph: keep this predicate (repeatable)
|
|
226
|
+
--root <path> tree: draw only the subtree under this node;
|
|
227
|
+
repeatable
|
|
228
|
+
--order <o> matrix: canon (default) or partition
|
|
229
|
+
--closure matrix: mark transitively reachable cells +
|
|
230
|
+
--group-by <k> graph: one subgraph per distinct value of field k;
|
|
231
|
+
layer: one band per value (required)
|
|
232
|
+
--layers <a,b> layer: the bands in this order, top first; without
|
|
233
|
+
it the order is derived from the relation
|
|
234
|
+
--edges <e> layer: which of the relation's edges to draw over
|
|
235
|
+
the bands -- upward (the violations, the default
|
|
236
|
+
for text and svg), all (mermaid's default) or none
|
|
237
|
+
--label <k> graph: label each node with field k
|
|
238
|
+
--sets <path> sets: the map whose keys are the sets
|
|
239
|
+
--member <k> sets: the field holding each set's members
|
|
240
|
+
--universe <p> sets: the full element domain, so the empty
|
|
241
|
+
column exists
|
|
242
|
+
--min-degree <n> sets: drop intersections below this degree
|
|
243
|
+
--min-size <n> layers: drop intersections below this many paths
|
|
244
|
+
--max-cols <n> sets, layers: elide columns beyond this many
|
|
245
|
+
--profile <p> poset: values | defaults (default) | gen
|
|
246
|
+
|
|
247
|
+
View exit codes: 0 rendered, 1 --check mismatch or lossy under
|
|
248
|
+
--strict, 2 usage or --max-rows exceeded, 4 the document does not stand
|
|
249
|
+
up on its own, or a relation, root or path that names nothing.
|
|
250
|
+
|
|
178
251
|
Set options:
|
|
179
252
|
--entry <file> The document the change is checked against
|
|
180
253
|
--overlay <file> The file the change is appended to (created if
|
|
@@ -1711,6 +1784,69 @@ const REACHES_EXIT: Record<ReachVerdict, number> = {
|
|
|
1711
1784
|
error: 4,
|
|
1712
1785
|
}
|
|
1713
1786
|
|
|
1787
|
+
const VIEW_HELP =
|
|
1788
|
+
'aontu view <kind> [options] <file>... (try --help)'
|
|
1789
|
+
|
|
1790
|
+
const VIEW_KINDS: ViewKind[] =
|
|
1791
|
+
['doc', 'tree', 'matrix', 'graph', 'layer', 'sets', 'layers', 'ladder',
|
|
1792
|
+
'poset']
|
|
1793
|
+
|
|
1794
|
+
const VIEW_PROFILES: ViewProfile[] = ['text', 'mermaid', 'dot', 'er', 'svg']
|
|
1795
|
+
|
|
1796
|
+
const VIEW_EDGES: ViewEdges[] = ['upward', 'all', 'none']
|
|
1797
|
+
|
|
1798
|
+
// The styles the CLI accepts (VIEWS.0.md, "7. Styling"). `auto` is
|
|
1799
|
+
// here and NOT in ViewStyle: resolving it means knowing whether stdout
|
|
1800
|
+
// is a terminal, which is the CLI's to know and the library's never --
|
|
1801
|
+
// the same division err.ts already draws for the error frames.
|
|
1802
|
+
const VIEW_STYLES = ['auto', 'none', 'ansi', 'css']
|
|
1803
|
+
|
|
1804
|
+
// `--style auto` resolved, which only the CLI can do. The mechanism is
|
|
1805
|
+
// the PROFILE's and the library knows it -- an SVG carries its
|
|
1806
|
+
// stylesheet unless told not to, which is what makes a figure stand
|
|
1807
|
+
// alone. What the library cannot know is whether the DESTINATION is a
|
|
1808
|
+
// terminal, so that is the only thing decided here: escapes on the
|
|
1809
|
+
// text profile when stdout is a terminal and NO_COLOR is unset, the
|
|
1810
|
+
// same two conditions the error frames use. `undefined` leaves the
|
|
1811
|
+
// profile's own default in place.
|
|
1812
|
+
function viewStyleOf(
|
|
1813
|
+
asked: string | undefined, as: ViewProfile | undefined
|
|
1814
|
+
): ViewStyle | undefined {
|
|
1815
|
+
if (undefined !== asked && 'auto' !== asked) {
|
|
1816
|
+
return asked as ViewStyle
|
|
1817
|
+
}
|
|
1818
|
+
// STDOUT'S OWN TERMINAL-NESS, and NO_COLOR read here rather than
|
|
1819
|
+
// through colorActive(). The figure goes to STDOUT and the error
|
|
1820
|
+
// frames go to STDERR, and they are not the same destination: main()
|
|
1821
|
+
// has already called setColor for stderr, so asking colorActive()
|
|
1822
|
+
// would answer the wrong question twice --- no escapes for
|
|
1823
|
+
// `aontu view tree m.aon 2>/dev/null` at a terminal, and escapes
|
|
1824
|
+
// into the pipe for `aontu view tree m.aon | less`. The NO_COLOR
|
|
1825
|
+
// rule is the one no-color.org states and err.ts implements:
|
|
1826
|
+
// set, to anything but empty, means no colour.
|
|
1827
|
+
const no = process.env.NO_COLOR
|
|
1828
|
+
return 'text' === as && true === process.stdout.isTTY
|
|
1829
|
+
&& (null == no || '' === no) ? 'ansi' : undefined
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// The figure was drawn (0, `lossy` included: the loss report says
|
|
1833
|
+
// what it could not draw, and --strict is the gate on that), or the
|
|
1834
|
+
// document could not be drawn (4). An EMPTY figure is a drawing, not
|
|
1835
|
+
// a failure: a model with no links has nothing to draw, honestly.
|
|
1836
|
+
const VIEW_EXIT: Record<ViewVerdict, number> = {
|
|
1837
|
+
rendered: 0,
|
|
1838
|
+
lossy: 0,
|
|
1839
|
+
error: 4,
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
// The refusals that are USAGE, not the document's fault: exit 2, as
|
|
1843
|
+
// every other verb's usage errors do.
|
|
1844
|
+
const VIEW_USAGE_CODES = [
|
|
1845
|
+
'view_kind_unknown', 'view_profile_unknown', 'view_rows_exceeded',
|
|
1846
|
+
'view_at_required', 'view_sets_required', 'view_group_required',
|
|
1847
|
+
'view_document_shape', 'view_style_profile', 'view_style_unknown',
|
|
1848
|
+
]
|
|
1849
|
+
|
|
1714
1850
|
const MOD_HELP = 'aontu mod tidy|verify|vendor|manifest [dir] (try --help)'
|
|
1715
1851
|
|
|
1716
1852
|
// The module tooling (G6 phase 3, ts/src/mod-tool.ts). All LOCAL:
|
|
@@ -1773,7 +1909,8 @@ function runMod(argv: string[]): number {
|
|
|
1773
1909
|
if ('get' === sub || 'publish' === sub) {
|
|
1774
1910
|
process.stderr.write(
|
|
1775
1911
|
'aontu: mod ' + sub + ' needs a registry client, which this build ' +
|
|
1776
|
-
'does not ship
|
|
1912
|
+
'does not ship; vendor the module by hand and run ' +
|
|
1913
|
+
"'aontu mod tidy'\n")
|
|
1777
1914
|
return 2
|
|
1778
1915
|
}
|
|
1779
1916
|
|
|
@@ -2026,7 +2163,7 @@ function runReaches(argv: string[]): number {
|
|
|
2026
2163
|
|
|
2027
2164
|
if (3 !== rest.length) {
|
|
2028
2165
|
process.stderr.write(
|
|
2029
|
-
`aontu: reaches needs two
|
|
2166
|
+
`aontu: reaches needs two node paths and one file\n${REACHES_HELP}\n`)
|
|
2030
2167
|
return 2
|
|
2031
2168
|
}
|
|
2032
2169
|
|
|
@@ -2074,6 +2211,412 @@ function renderReachesJson(report: ReachReport): string {
|
|
|
2074
2211
|
}, 2)
|
|
2075
2212
|
}
|
|
2076
2213
|
|
|
2214
|
+
// ---------------------------------------------------------------------
|
|
2215
|
+
// The tree view (docs/design/VIEWS.0.md, ts/src/view.ts): the drawn
|
|
2216
|
+
// edge set, as text a golden diff can check.
|
|
2217
|
+
|
|
2218
|
+
function runView(argv: string[]): number {
|
|
2219
|
+
const trusted = takeTrust(argv)
|
|
2220
|
+
if (null == trusted) {
|
|
2221
|
+
return 2
|
|
2222
|
+
}
|
|
2223
|
+
argv = trusted.argv
|
|
2224
|
+
const trust = trusted.trust
|
|
2225
|
+
const rest: string[] = []
|
|
2226
|
+
let format: SubsumeFormat = 'text'
|
|
2227
|
+
let out: string | undefined = undefined
|
|
2228
|
+
let check = false
|
|
2229
|
+
let strict = false
|
|
2230
|
+
const relations: string[] = []
|
|
2231
|
+
const roots: string[] = []
|
|
2232
|
+
const opts: ViewOptions = {}
|
|
2233
|
+
// The style ASKED FOR, which may be `auto` -- a word ViewStyle does
|
|
2234
|
+
// not have, because resolving it is the CLI's job.
|
|
2235
|
+
let style: string | undefined = undefined
|
|
2236
|
+
|
|
2237
|
+
// A flag that takes a value, read into `opts` by name.
|
|
2238
|
+
const valued: Record<string, keyof ViewOptions> = {
|
|
2239
|
+
'--as': 'as', '--at': 'at', '--order': 'order', '--group-by': 'groupBy',
|
|
2240
|
+
'--label': 'label', '--sets': 'sets', '--member': 'member',
|
|
2241
|
+
'--universe': 'universe', '--profile': 'profile', '--views': 'views',
|
|
2242
|
+
'--edges': 'edges',
|
|
2243
|
+
}
|
|
2244
|
+
const counted: Record<string, keyof ViewOptions> = {
|
|
2245
|
+
'--max-rows': 'maxRows', '--max-cols': 'maxCols',
|
|
2246
|
+
'--min-degree': 'minDegree', '--min-size': 'minSize',
|
|
2247
|
+
'--depth': 'depth',
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
for (let i = 0; i < argv.length; i++) {
|
|
2251
|
+
const arg = argv[i]
|
|
2252
|
+
if ('-h' === arg || '--help' === arg) {
|
|
2253
|
+
process.stdout.write(HELP)
|
|
2254
|
+
return 0
|
|
2255
|
+
}
|
|
2256
|
+
if ('--format' === arg) {
|
|
2257
|
+
const f = argv[++i]
|
|
2258
|
+
if ('text' !== f && 'json' !== f) {
|
|
2259
|
+
process.stderr.write('aontu: --format needs text or json\n')
|
|
2260
|
+
return 2
|
|
2261
|
+
}
|
|
2262
|
+
format = f
|
|
2263
|
+
}
|
|
2264
|
+
else if ('--relation' === arg) {
|
|
2265
|
+
const relation = argv[++i]
|
|
2266
|
+
if (null == relation || '' === relation) {
|
|
2267
|
+
process.stderr.write('aontu: --relation needs a name\n')
|
|
2268
|
+
return 2
|
|
2269
|
+
}
|
|
2270
|
+
relations.push(relation)
|
|
2271
|
+
}
|
|
2272
|
+
else if ('--root' === arg) {
|
|
2273
|
+
const root = argv[++i]
|
|
2274
|
+
if (null == root) {
|
|
2275
|
+
process.stderr.write('aontu: --root needs a node path\n')
|
|
2276
|
+
return 2
|
|
2277
|
+
}
|
|
2278
|
+
roots.push(root)
|
|
2279
|
+
}
|
|
2280
|
+
else if ('-o' === arg || '--out' === arg) {
|
|
2281
|
+
out = argv[++i]
|
|
2282
|
+
if (null == out) {
|
|
2283
|
+
process.stderr.write('aontu: --out needs a file\n')
|
|
2284
|
+
return 2
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
else if ('--style' === arg) {
|
|
2288
|
+
style = argv[++i]
|
|
2289
|
+
if (null == style || !VIEW_STYLES.includes(style)) {
|
|
2290
|
+
process.stderr.write(
|
|
2291
|
+
`aontu: --style needs one of ${VIEW_STYLES.join(', ')}\n`)
|
|
2292
|
+
return 2
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
else if ('--check' === arg) {
|
|
2296
|
+
check = true
|
|
2297
|
+
}
|
|
2298
|
+
else if ('--strict' === arg) {
|
|
2299
|
+
strict = true
|
|
2300
|
+
}
|
|
2301
|
+
else if ('--closure' === arg) {
|
|
2302
|
+
opts.closure = true
|
|
2303
|
+
}
|
|
2304
|
+
else if ('--layers' === arg) {
|
|
2305
|
+
const v = argv[++i]
|
|
2306
|
+
if (null == v || '' === v) {
|
|
2307
|
+
process.stderr.write('aontu: --layers needs a comma-separated list\n')
|
|
2308
|
+
return 2
|
|
2309
|
+
}
|
|
2310
|
+
opts.layers = v.split(',')
|
|
2311
|
+
}
|
|
2312
|
+
else if (undefined !== valued[arg]) {
|
|
2313
|
+
const v = argv[++i]
|
|
2314
|
+
if (null == v || '' === v) {
|
|
2315
|
+
process.stderr.write(`aontu: ${arg} needs a value\n`)
|
|
2316
|
+
return 2
|
|
2317
|
+
}
|
|
2318
|
+
(opts as any)[valued[arg]] = v
|
|
2319
|
+
}
|
|
2320
|
+
else if (undefined !== counted[arg]) {
|
|
2321
|
+
const v = argv[++i]
|
|
2322
|
+
if (null == v || !/^[0-9]+$/.test(v)) {
|
|
2323
|
+
process.stderr.write(`aontu: ${arg} needs a count\n`)
|
|
2324
|
+
return 2
|
|
2325
|
+
}
|
|
2326
|
+
(opts as any)[counted[arg]] = parseInt(v, 10)
|
|
2327
|
+
}
|
|
2328
|
+
else if (arg.startsWith('-')) {
|
|
2329
|
+
process.stderr.write(
|
|
2330
|
+
`aontu: unknown view option ${arg} (try --help)\n`)
|
|
2331
|
+
return 2
|
|
2332
|
+
}
|
|
2333
|
+
else {
|
|
2334
|
+
rest.push(arg)
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
// ESCAPES NEVER GO INTO A FILE. A pinned golden holding terminal
|
|
2339
|
+
// control codes is not a golden anybody can read, and a byte
|
|
2340
|
+
// comparison against one would fail on the reader's terminal
|
|
2341
|
+
// settings. `auto` resolves to `none` there on its own; asking for
|
|
2342
|
+
// `ansi` explicitly is a usage error rather than a silent downgrade,
|
|
2343
|
+
// so a script that wanted colour is told where it went.
|
|
2344
|
+
if ('ansi' === style && (undefined !== out || undefined !== opts.views)) {
|
|
2345
|
+
process.stderr.write(
|
|
2346
|
+
'aontu: --style ansi writes to a terminal, not to a file\n')
|
|
2347
|
+
return 2
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// THE VIEW DOCUMENT draws every figure a document declares, so it
|
|
2351
|
+
// names no kind: the declarations do, one each.
|
|
2352
|
+
if (undefined !== opts.views) {
|
|
2353
|
+
// A declaration names its own profile, so the style is left to
|
|
2354
|
+
// each figure's own default; `--style none` still reaches every
|
|
2355
|
+
// one of them, which is how a host page that binds the CSS
|
|
2356
|
+
// variables asks for eight figures without eight stylesheets.
|
|
2357
|
+
opts.style = viewStyleOf(style, undefined)
|
|
2358
|
+
return runViewSet(rest, opts, trust, { format, check, strict, out })
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
if (2 > rest.length) {
|
|
2362
|
+
process.stderr.write(
|
|
2363
|
+
`aontu: view needs a kind and a file\n${VIEW_HELP}\n`)
|
|
2364
|
+
return 2
|
|
2365
|
+
}
|
|
2366
|
+
const kind = rest[0] as ViewKind
|
|
2367
|
+
if (!VIEW_KINDS.includes(kind)) {
|
|
2368
|
+
process.stderr.write(
|
|
2369
|
+
`aontu: unknown view kind ${kind} (the kinds are: ${VIEW_KINDS.join(', ')})\n`)
|
|
2370
|
+
return 2
|
|
2371
|
+
}
|
|
2372
|
+
if (undefined !== opts.as && !VIEW_PROFILES.includes(opts.as)) {
|
|
2373
|
+
process.stderr.write(
|
|
2374
|
+
`aontu: --as needs one of ${VIEW_PROFILES.join(', ')}\n`)
|
|
2375
|
+
return 2
|
|
2376
|
+
}
|
|
2377
|
+
if (undefined !== opts.order && 'canon' !== opts.order && 'partition' !== opts.order) {
|
|
2378
|
+
process.stderr.write('aontu: --order needs canon or partition\n')
|
|
2379
|
+
return 2
|
|
2380
|
+
}
|
|
2381
|
+
if (undefined !== opts.edges && !VIEW_EDGES.includes(opts.edges)) {
|
|
2382
|
+
process.stderr.write(
|
|
2383
|
+
`aontu: --edges needs one of ${VIEW_EDGES.join(', ')}\n`)
|
|
2384
|
+
return 2
|
|
2385
|
+
}
|
|
2386
|
+
if (undefined !== opts.profile && !['values', 'defaults', 'gen'].includes(opts.profile)) {
|
|
2387
|
+
process.stderr.write('aontu: --profile needs values, defaults or gen\n')
|
|
2388
|
+
return 2
|
|
2389
|
+
}
|
|
2390
|
+
if ('poset' !== kind && 2 !== rest.length) {
|
|
2391
|
+
process.stderr.write(`aontu: view ${kind} takes one file\n`)
|
|
2392
|
+
return 2
|
|
2393
|
+
}
|
|
2394
|
+
if ('graph' === kind) {
|
|
2395
|
+
opts.relations = relations
|
|
2396
|
+
}
|
|
2397
|
+
else if (1 < relations.length) {
|
|
2398
|
+
process.stderr.write(`aontu: view ${kind} takes one --relation\n`)
|
|
2399
|
+
return 2
|
|
2400
|
+
}
|
|
2401
|
+
else {
|
|
2402
|
+
opts.relation = relations[0]
|
|
2403
|
+
}
|
|
2404
|
+
if (check && undefined === out) {
|
|
2405
|
+
process.stderr.write('aontu: --check needs --out\n')
|
|
2406
|
+
return 2
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
const files = rest.slice(1)
|
|
2410
|
+
const srcs: string[] = []
|
|
2411
|
+
for (const file of files) {
|
|
2412
|
+
try {
|
|
2413
|
+
srcs.push(readFileSync(file, 'utf8'))
|
|
2414
|
+
}
|
|
2415
|
+
catch (err: any) {
|
|
2416
|
+
process.stderr.write(`aontu: cannot read ${err.path}: ${err.message}\n`)
|
|
2417
|
+
return 2
|
|
2418
|
+
}
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
const report = view(srcs[0], {
|
|
2422
|
+
...opts,
|
|
2423
|
+
style: viewStyleOf(style, opts.as ?? viewDefaultProfile(kind)),
|
|
2424
|
+
kind,
|
|
2425
|
+
path: files[0],
|
|
2426
|
+
roots,
|
|
2427
|
+
trust: verbTrust(trust, entryRootOf(files[0])),
|
|
2428
|
+
docs: files.slice(1).map((path, i) => ({ src: srcs[i + 1], path })),
|
|
2429
|
+
})
|
|
2430
|
+
|
|
2431
|
+
if ('json' === format) {
|
|
2432
|
+
process.stdout.write(renderViewJson(report) + '\n')
|
|
2433
|
+
}
|
|
2434
|
+
else if ('error' === report.verdict) {
|
|
2435
|
+
process.stderr.write(
|
|
2436
|
+
(report.errors as VetFinding[]).map(renderFinding).join('\n') + '\n')
|
|
2437
|
+
}
|
|
2438
|
+
else {
|
|
2439
|
+
// THE FIGURE AND NOTHING ELSE on stdout (or in the file): stdout is
|
|
2440
|
+
// what a golden diff reads, and a verdict line would be part of
|
|
2441
|
+
// every drawing. The loss report goes to stderr, so a figure
|
|
2442
|
+
// written to a file still tells the reader what it could not draw.
|
|
2443
|
+
const text = report.text + '\n'
|
|
2444
|
+
if (undefined === out) {
|
|
2445
|
+
process.stdout.write(text)
|
|
2446
|
+
}
|
|
2447
|
+
else if (check) {
|
|
2448
|
+
let have: string | undefined = undefined
|
|
2449
|
+
try {
|
|
2450
|
+
have = readFileSync(out, 'utf8')
|
|
2451
|
+
}
|
|
2452
|
+
catch (_err: any) {
|
|
2453
|
+
// Absent is a mismatch.
|
|
2454
|
+
}
|
|
2455
|
+
if (have !== text) {
|
|
2456
|
+
process.stderr.write(`aontu: ${out} differs from the ${kind} figure\n`)
|
|
2457
|
+
return 1
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
else {
|
|
2461
|
+
writeFileSync(out, text, 'utf8')
|
|
2462
|
+
}
|
|
2463
|
+
if (0 < report.loss.length) {
|
|
2464
|
+
process.stderr.write(renderViewLoss(report.loss) + '\n')
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
if ('error' === report.verdict) {
|
|
2469
|
+
const code = (report.errors as VetFinding[])[0]?.code
|
|
2470
|
+
return VIEW_USAGE_CODES.includes(code) ? 2 : VIEW_EXIT.error
|
|
2471
|
+
}
|
|
2472
|
+
return strict && 'lossy' === report.verdict ? 1 : VIEW_EXIT[report.verdict]
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
// `aontu view --views <path> <file>`: every figure the document
|
|
2476
|
+
// declares, from one evaluation, all or nothing.
|
|
2477
|
+
//
|
|
2478
|
+
// A declared `out` is resolved against the DOCUMENT's own directory,
|
|
2479
|
+
// not the caller's: a view document is committed beside the figures it
|
|
2480
|
+
// gates, and a gate that only passes from one working directory is not
|
|
2481
|
+
// a gate.
|
|
2482
|
+
function runViewSet(
|
|
2483
|
+
rest: string[], opts: ViewOptions, trust: TrustArg,
|
|
2484
|
+
how: { format: SubsumeFormat, check: boolean, strict: boolean, out?: string }
|
|
2485
|
+
): number {
|
|
2486
|
+
if (1 !== rest.length) {
|
|
2487
|
+
process.stderr.write('aontu: view --views takes one file\n')
|
|
2488
|
+
return 2
|
|
2489
|
+
}
|
|
2490
|
+
if (undefined !== how.out) {
|
|
2491
|
+
process.stderr.write(
|
|
2492
|
+
'aontu: --out is per figure in a view document; each declares its own\n')
|
|
2493
|
+
return 2
|
|
2494
|
+
}
|
|
2495
|
+
const file = rest[0]
|
|
2496
|
+
let src: string
|
|
2497
|
+
try {
|
|
2498
|
+
src = readFileSync(file, 'utf8')
|
|
2499
|
+
}
|
|
2500
|
+
catch (err: any) {
|
|
2501
|
+
process.stderr.write(`aontu: cannot read ${err.path}: ${err.message}\n`)
|
|
2502
|
+
return 2
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
const report = viewSet(src, {
|
|
2506
|
+
...opts, path: file, trust: verbTrust(trust, entryRootOf(file)),
|
|
2507
|
+
})
|
|
2508
|
+
|
|
2509
|
+
if ('json' === how.format) {
|
|
2510
|
+
process.stdout.write(renderViewSetJson(report) + '\n')
|
|
2511
|
+
}
|
|
2512
|
+
else if (undefined !== report.errors) {
|
|
2513
|
+
process.stderr.write(report.errors.map(renderFinding).join('\n') + '\n')
|
|
2514
|
+
}
|
|
2515
|
+
else {
|
|
2516
|
+
for (const fig of report.views) {
|
|
2517
|
+
if (undefined !== fig.errors) {
|
|
2518
|
+
process.stderr.write(`${fig.name} (${fig.kind}):\n` +
|
|
2519
|
+
fig.errors.map(renderFinding).join('\n') + '\n')
|
|
2520
|
+
}
|
|
2521
|
+
else if (0 < fig.loss.length) {
|
|
2522
|
+
process.stderr.write(renderViewLoss(fig.loss)
|
|
2523
|
+
.split('\n').map((l) => `${fig.name} ${l}`).join('\n') + '\n')
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
if ('error' === report.verdict) {
|
|
2528
|
+
return setExit(report)
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
// EVERY FIGURE RENDERED, so the whole set is written -- or, under
|
|
2532
|
+
// --check, the whole set is compared and every difference named.
|
|
2533
|
+
const dir = dirname(resolve(file))
|
|
2534
|
+
let differ = 0
|
|
2535
|
+
for (const fig of report.views) {
|
|
2536
|
+
const path = resolve(dir, fig.out)
|
|
2537
|
+
const text = fig.text + '\n'
|
|
2538
|
+
if (how.check) {
|
|
2539
|
+
let have: string | undefined = undefined
|
|
2540
|
+
try {
|
|
2541
|
+
have = readFileSync(path, 'utf8')
|
|
2542
|
+
}
|
|
2543
|
+
catch (_err: any) {
|
|
2544
|
+
// Absent is a mismatch.
|
|
2545
|
+
}
|
|
2546
|
+
if (have !== text) {
|
|
2547
|
+
differ++
|
|
2548
|
+
process.stderr.write(
|
|
2549
|
+
`aontu: ${fig.out} differs from the ${fig.name} figure\n`)
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
else {
|
|
2553
|
+
try {
|
|
2554
|
+
writeFileSync(path, text, 'utf8')
|
|
2555
|
+
}
|
|
2556
|
+
catch (err: any) {
|
|
2557
|
+
process.stderr.write(`aontu: cannot write ${err.path}: ${err.message}\n`)
|
|
2558
|
+
return 2
|
|
2559
|
+
}
|
|
2560
|
+
if ('json' !== how.format) {
|
|
2561
|
+
process.stderr.write(`wrote ${fig.out} ${fig.name} (${fig.kind})\n`)
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
if (0 < differ) {
|
|
2566
|
+
return 1
|
|
2567
|
+
}
|
|
2568
|
+
return how.strict && 'lossy' === report.verdict ? 1 : VIEW_EXIT[report.verdict]
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
|
|
2572
|
+
// A set's exit code is the worst of its figures': a usage refusal
|
|
2573
|
+
// anywhere is usage, and any other refusal is the document's fault.
|
|
2574
|
+
function setExit(report: ViewSetReport): number {
|
|
2575
|
+
const codes = [
|
|
2576
|
+
...(report.errors ?? []),
|
|
2577
|
+
...report.views.flatMap((v) => v.errors ?? []),
|
|
2578
|
+
].map((e) => e.code)
|
|
2579
|
+
return codes.some((c) => VIEW_USAGE_CODES.includes(c))
|
|
2580
|
+
? 2 : VIEW_EXIT.error
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
|
|
2584
|
+
function renderViewSetJson(report: ViewSetReport): string {
|
|
2585
|
+
return exactJSON({
|
|
2586
|
+
aontu: { version: version(), verb: 'view' },
|
|
2587
|
+
verdict: report.verdict,
|
|
2588
|
+
views: report.views.map((v: ViewFigure) => ({
|
|
2589
|
+
name: v.name,
|
|
2590
|
+
kind: v.kind,
|
|
2591
|
+
out: v.out,
|
|
2592
|
+
verdict: v.verdict,
|
|
2593
|
+
...(null == v.text ? {} : { text: v.text }),
|
|
2594
|
+
loss: v.loss,
|
|
2595
|
+
...(null == v.errors ? {} : { errors: v.errors }),
|
|
2596
|
+
})),
|
|
2597
|
+
...(null == report.errors ? {} : { errors: report.errors }),
|
|
2598
|
+
}, 2)
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
|
|
2602
|
+
// One line per code: the code, the count, and the detail if any.
|
|
2603
|
+
function renderViewLoss(loss: ViewLoss[]): string {
|
|
2604
|
+
return loss.map((l) =>
|
|
2605
|
+
`${l.code} ${l.count}` +
|
|
2606
|
+
(undefined === l.detail ? '' : ' ' + l.detail.join(' '))).join('\n')
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
function renderViewJson(report: ViewReport): string {
|
|
2610
|
+
return exactJSON({
|
|
2611
|
+
aontu: { version: version(), verb: 'view' },
|
|
2612
|
+
kind: report.kind,
|
|
2613
|
+
verdict: report.verdict,
|
|
2614
|
+
...(null == report.text ? {} : { text: report.text }),
|
|
2615
|
+
loss: report.loss,
|
|
2616
|
+
...(null == report.errors ? {} : { errors: report.errors }),
|
|
2617
|
+
}, 2)
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2077
2620
|
function renderRelationsText(report: RelationReport): string {
|
|
2078
2621
|
const head = `verdict: ${report.verdict}`
|
|
2079
2622
|
// WHY, when the document could not be evaluated at all: rendered as
|
|
@@ -2088,11 +2631,8 @@ function renderRelationsText(report: RelationReport): string {
|
|
|
2088
2631
|
const lines = report.findings.map((f) =>
|
|
2089
2632
|
'relation_cycle' === f.code
|
|
2090
2633
|
? `${f.at} ${f.relation}: cycle ${f.detail.join(' -> ')}`
|
|
2091
|
-
:
|
|
2092
|
-
|
|
2093
|
-
`${f.relation} targets (${f.detail[2]})`
|
|
2094
|
-
: `${f.at} ${f.relation}: ${f.detail[1]} does not list ` +
|
|
2095
|
-
`${f.detail[0]} under ${f.detail[2]}`)
|
|
2634
|
+
: `${f.at} ${f.relation}: ${f.detail[1]} does not list ` +
|
|
2635
|
+
`${f.detail[0]} under ${f.detail[2]}`)
|
|
2096
2636
|
return [head, ''].concat(lines).join('\n')
|
|
2097
2637
|
}
|
|
2098
2638
|
|
|
@@ -2906,6 +3446,10 @@ function main(argv: string[]): void {
|
|
|
2906
3446
|
return finish(runReaches(argv.slice(3)))
|
|
2907
3447
|
}
|
|
2908
3448
|
|
|
3449
|
+
if ('view' === argv[2]) {
|
|
3450
|
+
return finish(runView(argv.slice(3)))
|
|
3451
|
+
}
|
|
3452
|
+
|
|
2909
3453
|
if ('trim' === argv[2]) {
|
|
2910
3454
|
return finish(runTrim(argv.slice(3)))
|
|
2911
3455
|
}
|
|
@@ -2989,7 +3533,7 @@ function main(argv: string[]): void {
|
|
|
2989
3533
|
else {
|
|
2990
3534
|
runStdin(mode, trust).then((code) => finish(code))
|
|
2991
3535
|
}
|
|
2992
|
-
} /* node:coverage ignore next
|
|
3536
|
+
} /* node:coverage ignore next 16 */
|
|
2993
3537
|
|
|
2994
3538
|
|
|
2995
3539
|
// No require.main guard here: bin/aontu.js is the executable entry and
|
|
@@ -2999,6 +3543,7 @@ function main(argv: string[]): void {
|
|
|
2999
3543
|
export {
|
|
3000
3544
|
evalSource, main, runVet, runSubsume, runBreaking, runTrim, runRelations,
|
|
3001
3545
|
runReaches,
|
|
3546
|
+
runView,
|
|
3002
3547
|
runJsonSchema,
|
|
3003
3548
|
runMod,
|
|
3004
3549
|
runHash, runGet,
|
package/src/ctx.ts
CHANGED
|
@@ -123,6 +123,25 @@ class AontuContext {
|
|
|
123
123
|
// directly on its Ctx pointer (go/unify.go, maxUniteDepth).
|
|
124
124
|
_depth: { n: number }
|
|
125
125
|
|
|
126
|
+
// The relation declarations this evaluation accumulates (RELATIONS
|
|
127
|
+
// P2): predicate -> what its graph atoms said. One Map per
|
|
128
|
+
// evaluation, created here and inherited by reference through
|
|
129
|
+
// clone()'s prototype chain, exactly as _depth's box is -- a clone
|
|
130
|
+
// made before the first registration must still share the registry.
|
|
131
|
+
_reldecls: Map<string, { acyclic?: boolean, inverses: Set<string> }>
|
|
132
|
+
|
|
133
|
+
// The tree a recursive residual's target resolves against when the
|
|
134
|
+
// meet's own root does not contain it (RECURSION.0.md). Normally
|
|
135
|
+
// undefined: a residual expands by walking ctx.root, and the root
|
|
136
|
+
// holds the definition. An ANCHORED vet run meets a subtree LIFTED
|
|
137
|
+
// out of the settled schema, so `$.spec.Step` names nothing in the
|
|
138
|
+
// meet's root -- the residual held its peer forever and the data
|
|
139
|
+
// under it vetted VALID unchecked. Vet sets this to the settled
|
|
140
|
+
// schema root for anchored runs; RecurseVal.body falls back to it
|
|
141
|
+
// only when the root walk finds nothing. Inherited by clone()
|
|
142
|
+
// through the prototype chain.
|
|
143
|
+
_fixroot: any
|
|
144
|
+
|
|
126
145
|
// The evaluation budgets (G5 trust profile, docs/trust.md): integer
|
|
127
146
|
// counts of engine events, never wall-clock. Always present, defaults
|
|
128
147
|
// from the shared spec-visible constants (test/spec/budget.tsv), so
|
|
@@ -185,6 +204,7 @@ class AontuContext {
|
|
|
185
204
|
this._pathTrie = new Map()
|
|
186
205
|
this._pathidxNext = { n: 1 } // 0 reserved for the root path
|
|
187
206
|
this._depth = { n: 0 }
|
|
207
|
+
this._reldecls = new Map()
|
|
188
208
|
this._pathidx = 0
|
|
189
209
|
|
|
190
210
|
this.manifest = []
|
package/src/diff.ts
CHANGED
|
@@ -56,8 +56,10 @@ export type DiffOptions = {
|
|
|
56
56
|
// The trust profile this run evaluates under (G5, docs/trust.md).
|
|
57
57
|
// The source arrives from a caller, so the caller must be able to
|
|
58
58
|
// say what it may reach: without this the include chain is the
|
|
59
|
-
// default one, and `@"
|
|
60
|
-
//
|
|
59
|
+
// default one, and `@"../../etc/passwd.aon"` reads whatever the
|
|
60
|
+
// process can. (`@"x.js"` no longer executes -- ADR-012 refuses the
|
|
61
|
+
// extension -- but reading is enough.) A server passes
|
|
62
|
+
// `{include:'none'}`.
|
|
61
63
|
trust?: TrustOptions
|
|
62
64
|
}
|
|
63
65
|
|