aontu 0.52.1 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/bin/aontu-mcp.js +4 -0
- package/dist/agentsmd.d.ts +16 -0
- package/dist/agentsmd.js +107 -0
- package/dist/agentsmd.js.map +1 -0
- package/dist/aontu.d.ts +15 -3
- package/dist/aontu.js +126 -5
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +45 -1
- package/dist/cli.js +2845 -69
- package/dist/cli.js.map +1 -1
- package/dist/ctx.d.ts +18 -0
- package/dist/ctx.js +44 -0
- package/dist/ctx.js.map +1 -1
- package/dist/diff.d.ts +22 -0
- package/dist/diff.js +141 -0
- package/dist/diff.js.map +1 -0
- package/dist/err.d.ts +3 -1
- package/dist/err.js +45 -8
- package/dist/err.js.map +1 -1
- package/dist/graph.d.ts +13 -0
- package/dist/graph.js +110 -0
- package/dist/graph.js.map +1 -0
- package/dist/hcanon.d.ts +3 -0
- package/dist/hcanon.js +145 -0
- package/dist/hcanon.js.map +1 -0
- package/dist/hints.js +235 -8
- package/dist/hints.js.map +1 -1
- package/dist/jsonschema.d.ts +20 -0
- package/dist/jsonschema.js +425 -0
- package/dist/jsonschema.js.map +1 -0
- package/dist/lang.js +955 -110
- package/dist/lang.js.map +1 -1
- package/dist/lsp.d.ts +9 -2
- package/dist/lsp.js +343 -48
- package/dist/lsp.js.map +1 -1
- package/dist/mcp-server.d.ts +20 -0
- package/dist/mcp-server.js +147 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp.d.ts +42 -0
- package/dist/mcp.js +941 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mod-tool.d.ts +58 -0
- package/dist/mod-tool.js +532 -0
- package/dist/mod-tool.js.map +1 -0
- package/dist/mod.d.ts +35 -0
- package/dist/mod.js +345 -0
- package/dist/mod.js.map +1 -0
- package/dist/patch.d.ts +49 -0
- package/dist/patch.js +506 -0
- package/dist/patch.js.map +1 -0
- package/dist/provenance.d.ts +41 -0
- package/dist/provenance.js +336 -0
- package/dist/provenance.js.map +1 -0
- package/dist/query.d.ts +27 -0
- package/dist/query.js +294 -0
- package/dist/query.js.map +1 -0
- package/dist/reach.d.ts +15 -0
- package/dist/reach.js +168 -0
- package/dist/reach.js.map +1 -0
- package/dist/relation.d.ts +23 -0
- package/dist/relation.js +230 -0
- package/dist/relation.js.map +1 -0
- package/dist/report-sarif.d.ts +14 -0
- package/dist/report-sarif.js +102 -0
- package/dist/report-sarif.js.map +1 -0
- 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/site.d.ts +4 -0
- package/dist/site.js +31 -0
- package/dist/site.js.map +1 -1
- package/dist/std.d.ts +1 -0
- package/dist/std.js +129 -0
- package/dist/std.js.map +1 -0
- package/dist/subsume.d.ts +39 -0
- package/dist/subsume.js +573 -0
- package/dist/subsume.js.map +1 -0
- package/dist/trim.d.ts +19 -0
- package/dist/trim.js +155 -0
- package/dist/trim.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/type.d.ts +17 -1
- package/dist/type.js.map +1 -1
- package/dist/unify.d.ts +2 -1
- package/dist/unify.js +234 -38
- package/dist/unify.js.map +1 -1
- package/dist/utility.d.ts +8 -1
- package/dist/utility.js +68 -1
- package/dist/utility.js.map +1 -1
- package/dist/val/AggFuncVal.d.ts +44 -0
- package/dist/val/AggFuncVal.js +364 -0
- package/dist/val/AggFuncVal.js.map +1 -0
- package/dist/val/ArithFuncVal.d.ts +31 -0
- package/dist/val/ArithFuncVal.js +62 -0
- package/dist/val/ArithFuncVal.js.map +1 -0
- package/dist/val/BagVal.d.ts +7 -0
- package/dist/val/BagVal.js +150 -11
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +9 -1
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.d.ts +1 -1
- package/dist/val/ConjunctVal.js +19 -0
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.d.ts +7 -1
- package/dist/val/ConstraintVal.js +523 -45
- 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.d.ts +1 -2
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.d.ts +1 -0
- package/dist/val/Decimal.js +13 -0
- package/dist/val/Decimal.js.map +1 -1
- package/dist/val/DeprecateFuncVal.d.ts +11 -0
- package/dist/val/DeprecateFuncVal.js +47 -0
- package/dist/val/DeprecateFuncVal.js.map +1 -0
- package/dist/val/DisjunctVal.d.ts +1 -2
- package/dist/val/DisjunctVal.js +269 -53
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/EachFuncVal.d.ts +15 -0
- package/dist/val/EachFuncVal.js +75 -0
- package/dist/val/EachFuncVal.js.map +1 -0
- package/dist/val/ExpectVal.js +62 -4
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FeatureVal.js +1 -1
- package/dist/val/FeatureVal.js.map +1 -1
- package/dist/val/FilterFuncVal.d.ts +15 -0
- package/dist/val/FilterFuncVal.js +91 -0
- package/dist/val/FilterFuncVal.js.map +1 -0
- package/dist/val/FuncBaseVal.d.ts +7 -1
- package/dist/val/FuncBaseVal.js +183 -2
- 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/HideFuncVal.js.map +1 -1
- package/dist/val/JunctionVal.js +24 -1
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.d.ts +1 -1
- package/dist/val/KeyFuncVal.js +38 -30
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +94 -14
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.d.ts +1 -0
- package/dist/val/MapVal.js +146 -14
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MatchFuncVal.d.ts +15 -0
- package/dist/val/MatchFuncVal.js +107 -0
- package/dist/val/MatchFuncVal.js.map +1 -0
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.js +24 -0
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/OpBaseVal.d.ts +1 -1
- package/dist/val/OpBaseVal.js +19 -1
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/OpenFuncVal.js +4 -1
- package/dist/val/OpenFuncVal.js.map +1 -1
- package/dist/val/PackFuncVal.d.ts +15 -0
- package/dist/val/PackFuncVal.js +108 -0
- package/dist/val/PackFuncVal.js.map +1 -0
- 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/PlaceVal.d.ts +13 -0
- package/dist/val/PlaceVal.js +131 -0
- package/dist/val/PlaceVal.js.map +1 -0
- package/dist/val/PlusOpVal.d.ts +2 -1
- package/dist/val/PlusOpVal.js +61 -37
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +4 -2
- package/dist/val/PrefVal.js +223 -41
- 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 +3 -2
- package/dist/val/RefVal.js +181 -66
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ReferFuncVal.d.ts +59 -0
- package/dist/val/ReferFuncVal.js +604 -0
- package/dist/val/ReferFuncVal.js.map +1 -0
- package/dist/val/ScalarKindVal.d.ts +4 -3
- package/dist/val/ScalarKindVal.js +12 -12
- 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/TopVal.js.map +1 -1
- package/dist/val/TypeFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +7 -1
- package/dist/val/Val.js +170 -2
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/arith.d.ts +6 -0
- package/dist/val/arith.js +173 -0
- package/dist/val/arith.js.map +1 -0
- package/dist/vet.d.ts +45 -0
- package/dist/vet.js +802 -0
- package/dist/vet.js.map +1 -0
- package/dist/view.d.ts +85 -0
- package/dist/view.js +1948 -0
- package/dist/view.js.map +1 -0
- package/dist/walk.d.ts +2 -0
- package/dist/walk.js +91 -0
- package/dist/walk.js.map +1 -0
- package/grammar/aontu.gbnf +138 -0
- package/grammar/aontu.lark +118 -0
- package/grammar/aontu.tmLanguage.json +184 -0
- package/package.json +30 -8
- package/skill/SKILL.md +37 -0
- package/skill/error-codes.md +62 -0
- package/skill/examples.md +99 -0
- package/skill/grammar-card.md +56 -0
- package/src/agentsmd.ts +135 -0
- package/src/aontu.ts +166 -5
- package/src/cli.ts +3324 -72
- package/src/ctx.ts +93 -1
- package/src/diff.ts +198 -0
- package/src/err.ts +50 -8
- package/src/graph.ts +185 -0
- package/src/hcanon.ts +167 -0
- package/src/hints.ts +291 -8
- package/src/jsonschema.ts +552 -0
- package/src/lang.ts +1049 -110
- package/src/lsp.ts +351 -49
- package/src/mcp-server.ts +187 -0
- package/src/mcp.ts +1130 -0
- package/src/mod-tool.ts +718 -0
- package/src/mod.ts +453 -0
- package/src/patch.ts +628 -0
- package/src/provenance.ts +437 -0
- package/src/query.ts +381 -0
- package/src/reach.ts +213 -0
- package/src/relation.ts +298 -0
- package/src/report-sarif.ts +137 -0
- package/src/sig.ts +345 -0
- package/src/sigdecl.ts +11 -0
- package/src/siggate.ts +144 -0
- package/src/site.ts +36 -1
- package/src/std.ts +131 -0
- package/src/subsume.ts +739 -0
- package/src/trim.ts +195 -0
- package/src/tsconfig.json +10 -4
- package/src/type.ts +51 -2
- package/src/unify.ts +253 -38
- package/src/utility.ts +79 -1
- package/src/val/AggFuncVal.ts +546 -0
- package/src/val/ArithFuncVal.ts +108 -0
- package/src/val/BagVal.ts +158 -12
- package/src/val/CloseFuncVal.ts +9 -1
- package/src/val/ConjunctVal.ts +20 -0
- package/src/val/ConstraintVal.ts +576 -48
- package/src/val/ContainerKindVal.ts +158 -0
- package/src/val/CopyFuncVal.ts +0 -1
- package/src/val/Decimal.ts +15 -0
- package/src/val/DeprecateFuncVal.ts +84 -0
- package/src/val/DisjunctVal.ts +282 -59
- package/src/val/EachFuncVal.ts +133 -0
- package/src/val/ExpectVal.ts +65 -8
- package/src/val/FeatureVal.ts +1 -1
- package/src/val/FilterFuncVal.ts +154 -0
- package/src/val/FuncBaseVal.ts +206 -2
- package/src/val/GraphAtomVal.ts +264 -0
- package/src/val/HideFuncVal.ts +0 -2
- package/src/val/JunctionVal.ts +24 -1
- package/src/val/KeyFuncVal.ts +39 -35
- package/src/val/ListVal.ts +101 -15
- package/src/val/LowerFuncVal.ts +0 -1
- package/src/val/MapVal.ts +153 -14
- package/src/val/MatchFuncVal.ts +176 -0
- package/src/val/MoveFuncVal.ts +0 -2
- package/src/val/NilVal.ts +25 -0
- package/src/val/OpBaseVal.ts +20 -1
- package/src/val/OpenFuncVal.ts +4 -2
- package/src/val/PackFuncVal.ts +175 -0
- package/src/val/PathFuncVal.ts +107 -20
- package/src/val/PathVal.ts +221 -0
- package/src/val/PlaceVal.ts +193 -0
- package/src/val/PlusOpVal.ts +67 -39
- package/src/val/PrefFuncVal.ts +0 -1
- package/src/val/PrefVal.ts +251 -60
- package/src/val/RecurseVal.ts +285 -0
- package/src/val/RefVal.ts +183 -78
- package/src/val/ReferFuncVal.ts +732 -0
- package/src/val/ScalarKindVal.ts +12 -13
- package/src/val/SuperFuncVal.ts +137 -13
- package/src/val/TopVal.ts +1 -2
- package/src/val/TypeFuncVal.ts +0 -2
- package/src/val/UpperFuncVal.ts +0 -1
- package/src/val/Val.ts +216 -4
- package/src/val/VarVal.ts +0 -1
- package/src/val/arith.ts +319 -0
- package/src/vet.ts +1025 -0
- package/src/view.ts +2563 -0
- package/src/walk.ts +99 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
{
|
|
2
|
+
"information_for_contributors": [
|
|
3
|
+
"Aontu — published grammar (TextMate), for SYNTAX HIGHLIGHTING.",
|
|
4
|
+
"",
|
|
5
|
+
"The third consumer of the published surface, beside grammar/aontu.gbnf",
|
|
6
|
+
"and grammar/aontu.lark: those two constrain a decoder, this one colours",
|
|
7
|
+
"a reader. One file serves every TextMate host — the VS Code extension",
|
|
8
|
+
"(editors/vscode), Shiki on aontu.dev, and GitHub's Linguist if and when",
|
|
9
|
+
"`.aon` clears its usage bar — so a scope added here reaches all of them.",
|
|
10
|
+
"",
|
|
11
|
+
"It is a HIGHLIGHTER, not a parser: it accepts more than the language",
|
|
12
|
+
"does, and is meant to. A file mid-edit must still colour, so nothing",
|
|
13
|
+
"here refuses. What it must never do is colour a spelling the engine",
|
|
14
|
+
"rejects AS THOUGH it were valid, which is why the builtin list below is",
|
|
15
|
+
"the engine's own set and not a hand-picked sample of it.",
|
|
16
|
+
"",
|
|
17
|
+
"THE BUILTIN LIST IS A COPY, AND A COPY DRIFTS. aontu.lark carried",
|
|
18
|
+
"`same` — never a builtin — and was missing `acyclic`, `inverse` and",
|
|
19
|
+
"`rel` for two releases, with every test green. So the same guard the",
|
|
20
|
+
"other two grammars have covers this file: ts/test/grammar.test.ts,",
|
|
21
|
+
"`the-textmate-grammar-names-exactly-the-engine-builtins`, asserts this",
|
|
22
|
+
"list against BUILTIN_FUNCS in BOTH directions. Add a builtin to the",
|
|
23
|
+
"engine without adding it here and that test fails.",
|
|
24
|
+
"",
|
|
25
|
+
"No `|>`: ADR-018 removed the pipe from the language, and all three",
|
|
26
|
+
"published grammars now agree about that."
|
|
27
|
+
],
|
|
28
|
+
"name": "aontu",
|
|
29
|
+
"displayName": "Aontu",
|
|
30
|
+
"scopeName": "source.aontu",
|
|
31
|
+
"aliases": ["aon"],
|
|
32
|
+
"fileTypes": ["aon", "aontu"],
|
|
33
|
+
"patterns": [
|
|
34
|
+
{ "include": "#comment" },
|
|
35
|
+
{ "include": "#include-directive" },
|
|
36
|
+
{ "include": "#key" },
|
|
37
|
+
{ "include": "#string" },
|
|
38
|
+
{ "include": "#spread" },
|
|
39
|
+
{ "include": "#builtin" },
|
|
40
|
+
{ "include": "#kind" },
|
|
41
|
+
{ "include": "#constant" },
|
|
42
|
+
{ "include": "#reference" },
|
|
43
|
+
{ "include": "#number" },
|
|
44
|
+
{ "include": "#operator" },
|
|
45
|
+
{ "include": "#punctuation" }
|
|
46
|
+
],
|
|
47
|
+
"repository": {
|
|
48
|
+
"comment": {
|
|
49
|
+
"name": "comment.line.number-sign.aontu",
|
|
50
|
+
"match": "#.*$"
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
"include-directive": {
|
|
54
|
+
"comment": "@\"path\" pulls in another source. The engine's only import.",
|
|
55
|
+
"match": "(@)(?=\\s*\")",
|
|
56
|
+
"captures": {
|
|
57
|
+
"1": { "name": "keyword.control.import.aontu" }
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
"key": {
|
|
62
|
+
"comment": "A map entry's key, bare or quoted, with the optional marker. Listed BEFORE #string so a quoted key does not read as a string, and before #kind so `string: 1` colours `string` as the key it is. Chained keys (`a: b: c: 1`) each match in turn.",
|
|
63
|
+
"patterns": [
|
|
64
|
+
{
|
|
65
|
+
"match": "(\"(?:[^\"\\\\]|\\\\.)*\")\\s*(\\?)?(?=\\s*:)",
|
|
66
|
+
"captures": {
|
|
67
|
+
"1": { "name": "entity.name.tag.quoted.aontu" },
|
|
68
|
+
"2": { "name": "keyword.operator.optional.aontu" }
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"comment": "No `-`: not a bare-text character (test/spec/op-chars.tsv).",
|
|
73
|
+
"match": "([A-Za-z_][A-Za-z0-9_]*)\\s*(\\?)?(?=\\s*:)",
|
|
74
|
+
"captures": {
|
|
75
|
+
"1": { "name": "entity.name.tag.aontu" },
|
|
76
|
+
"2": { "name": "keyword.operator.optional.aontu" }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
"string": {
|
|
83
|
+
"name": "string.quoted.double.aontu",
|
|
84
|
+
"begin": "\"",
|
|
85
|
+
"beginCaptures": {
|
|
86
|
+
"0": { "name": "punctuation.definition.string.begin.aontu" }
|
|
87
|
+
},
|
|
88
|
+
"end": "\"",
|
|
89
|
+
"endCaptures": {
|
|
90
|
+
"0": { "name": "punctuation.definition.string.end.aontu" }
|
|
91
|
+
},
|
|
92
|
+
"patterns": [
|
|
93
|
+
{
|
|
94
|
+
"name": "constant.character.escape.aontu",
|
|
95
|
+
"match": "\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F]{4})"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "invalid.illegal.unknown-escape.aontu",
|
|
99
|
+
"match": "\\\\."
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
"spread": {
|
|
105
|
+
"comment": "`&: value` — the map-wide template, distinct from `&` the conjunct.",
|
|
106
|
+
"match": "(&)(?=\\s*:)",
|
|
107
|
+
"captures": {
|
|
108
|
+
"1": { "name": "keyword.control.spread.aontu" }
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
"builtin": {
|
|
113
|
+
"comment": "The engine's function registry. `func: name \"(\" ...` in aontu.lark — only these names can be called, so a call to anything else is deliberately left uncoloured rather than dressed up as valid. The prefix family is spelled longest-first (refer|rel|rem|re) to keep the intent legible; the trailing \\b already makes the order immaterial, since a short alternative that swallowed the stem fails the boundary and backtracks.",
|
|
114
|
+
"match": "\\b(above|acyclic|add|below|close|copy|deprecate|div|each|filter|greatest|hide|inverse|join|key|least|length|list|lower|map|match|max|min|mod|move|mul|must|neq|open|pack|path|pick|pref|refer|rel|rem|re|sub|sum|super|type|unique|upper)\\b(?=\\s*\\()",
|
|
115
|
+
"captures": {
|
|
116
|
+
"1": { "name": "support.function.builtin.aontu" }
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
"kind": {
|
|
121
|
+
"comment": "Scalar kinds. `number` is the numeric supertype; the rest of the numerics are its leaves.",
|
|
122
|
+
"name": "support.type.builtin.aontu",
|
|
123
|
+
"match": "\\b(bigdecimal|biginteger|boolean|float|integer|nil|number|string|top)\\b"
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
"constant": {
|
|
127
|
+
"patterns": [
|
|
128
|
+
{
|
|
129
|
+
"name": "constant.language.aontu",
|
|
130
|
+
"match": "\\b(true|false|null)\\b"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"comment": "`_` is a literal of the language as of G8 phase 3, not text.",
|
|
134
|
+
"name": "constant.language.placeholder.aontu",
|
|
135
|
+
"match": "(?<![A-Za-z0-9_])_(?![A-Za-z0-9_])"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
"reference": {
|
|
141
|
+
"comment": "`$.a.b` resolves from the document root; `.a.b` names a sibling, resolved against the enclosing map. Canon emits the relative form wherever a spread template survives unresolved, so both are real. No conflict with a number: a numeric literal always starts with a digit or `-`, so it matches at an earlier offset and wins there.",
|
|
142
|
+
"patterns": [
|
|
143
|
+
{
|
|
144
|
+
"name": "variable.other.reference.absolute.aontu",
|
|
145
|
+
"match": "\\$(?:\\.[A-Za-z0-9_]+)*"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "variable.other.reference.relative.aontu",
|
|
149
|
+
"match": "(?<![A-Za-z0-9_$.])(?:\\.[A-Za-z0-9_]+)+"
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
"number": {
|
|
155
|
+
"patterns": [
|
|
156
|
+
{
|
|
157
|
+
"comment": "The exact decimal — `0d19.99`. MUST precede the ordinary number: both start at the same `0`, and at equal offsets the first listed pattern wins, so the other order colours the `0` alone and leaves `d19.99` bare.",
|
|
158
|
+
"name": "constant.numeric.exact.aontu",
|
|
159
|
+
"match": "-?\\b0d[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?\\b"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "constant.numeric.aontu",
|
|
163
|
+
"match": "-?\\b[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?\\b"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
"operator": {
|
|
169
|
+
"comment": "`&` unify, `|` alternate, `*` prefer, `+` sum.",
|
|
170
|
+
"name": "keyword.operator.aontu",
|
|
171
|
+
"match": "[&|*+]"
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
"punctuation": {
|
|
175
|
+
"patterns": [
|
|
176
|
+
{ "name": "punctuation.definition.map.aontu", "match": "[{}]" },
|
|
177
|
+
{ "name": "punctuation.definition.list.aontu", "match": "[\\[\\]]" },
|
|
178
|
+
{ "name": "punctuation.section.group.aontu", "match": "[()]" },
|
|
179
|
+
{ "name": "punctuation.separator.key-value.aontu", "match": ":" },
|
|
180
|
+
{ "name": "punctuation.separator.comma.aontu", "match": "," }
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
package/package.json
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aontu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"main": "dist/aontu.js",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"types": "dist/aontu.d.ts",
|
|
7
7
|
"bin": {
|
|
8
8
|
"aontu": "bin/aontu.js",
|
|
9
|
-
"aontu-lsp": "bin/aontu-lsp.js"
|
|
9
|
+
"aontu-lsp": "bin/aontu-lsp.js",
|
|
10
|
+
"aontu-mcp": "bin/aontu-mcp.js"
|
|
10
11
|
},
|
|
11
|
-
"description": "
|
|
12
|
-
"homepage": "https://github.com/
|
|
12
|
+
"description": "JSON-superset unification language and validation gate for AI-agent ground truth - evaluate, vet, diff, query, and evolution-check structured models.",
|
|
13
|
+
"homepage": "https://github.com/aontu-lang/aontu",
|
|
13
14
|
"keywords": [
|
|
14
|
-
"unify"
|
|
15
|
+
"unify",
|
|
16
|
+
"unification",
|
|
17
|
+
"json",
|
|
18
|
+
"schema",
|
|
19
|
+
"validation",
|
|
20
|
+
"vet",
|
|
21
|
+
"lattice",
|
|
22
|
+
"config",
|
|
23
|
+
"cue",
|
|
24
|
+
"agent",
|
|
25
|
+
"mcp",
|
|
26
|
+
"ground-truth"
|
|
15
27
|
],
|
|
16
28
|
"author": "Richard Rodger (http://richardrodger.com)",
|
|
17
29
|
"repository": {
|
|
18
30
|
"type": "git",
|
|
19
|
-
"url": "git://github.com/
|
|
31
|
+
"url": "git+https://github.com/aontu-lang/aontu.git"
|
|
20
32
|
},
|
|
21
33
|
"scripts": {
|
|
22
34
|
"test": "node --enable-source-maps --test \"dist-test/**/*.test.js\"",
|
|
@@ -25,6 +37,7 @@
|
|
|
25
37
|
"test-some": "node --enable-source-maps --test-name-pattern=\"$TEST_PATTERN\" --test \"dist-test/**/*.test.js\"",
|
|
26
38
|
"watch": "tsc --build src test -w",
|
|
27
39
|
"build": "tsc --build src test",
|
|
40
|
+
"prepack": "node scripts/prepack.js",
|
|
28
41
|
"clean": "rm -rf dist dist-test node_modules yarn.lock package-lock.json",
|
|
29
42
|
"reset": "npm run clean && npm i && npm run build && npm test",
|
|
30
43
|
"version": "node -e \"const fs=require('fs');const v=require('./package.json').version;const f='./src/aontu.ts';const s=fs.readFileSync(f,'utf8');const re=/^const VERSION = '.*?'/m;if(!re.test(s)){console.error('version: no VERSION constant in '+f);process.exit(1)}const n=s.replace(re,'const VERSION = \\''+v+'\\'');if(n!==s){fs.writeFileSync(f,n);console.log('version: src/aontu.ts VERSION -> '+v)}\"",
|
|
@@ -46,16 +59,24 @@
|
|
|
46
59
|
"bin",
|
|
47
60
|
"src",
|
|
48
61
|
"dist",
|
|
62
|
+
"grammar",
|
|
63
|
+
"skill",
|
|
49
64
|
"LICENSE"
|
|
50
65
|
],
|
|
51
66
|
"dependencies": {
|
|
52
67
|
"@tabnas/debug": "0.3.2",
|
|
53
68
|
"@tabnas/directive": "0.5.2",
|
|
54
69
|
"@tabnas/expr": "0.5.5",
|
|
70
|
+
"@tabnas/ini": "0.5.7",
|
|
71
|
+
"@tabnas/json": "0.5.7",
|
|
72
|
+
"@tabnas/json5": "0.5.7",
|
|
73
|
+
"@tabnas/jsonc": "0.5.6",
|
|
55
74
|
"@tabnas/jsonic": "0.6.2",
|
|
56
75
|
"@tabnas/multisource": "0.5.2",
|
|
57
76
|
"@tabnas/parser": "0.8.7",
|
|
58
|
-
"@tabnas/path": "0.3.2"
|
|
77
|
+
"@tabnas/path": "0.3.2",
|
|
78
|
+
"@tabnas/toml": "0.5.7",
|
|
79
|
+
"@tabnas/yaml": "0.5.7"
|
|
59
80
|
},
|
|
60
81
|
"devDependencies": {
|
|
61
82
|
"@types/node": "26.2.0",
|
|
@@ -66,7 +87,8 @@
|
|
|
66
87
|
"aliases": {
|
|
67
88
|
"@tabnas/multisource/resolver/file": "@tabnas/multisource/dist/resolver/file.js",
|
|
68
89
|
"@tabnas/multisource/resolver/pkg": "@tabnas/multisource/dist/resolver/pkg.js",
|
|
69
|
-
"@tabnas/multisource/resolver/mem": "@tabnas/multisource/dist/resolver/mem.js"
|
|
90
|
+
"@tabnas/multisource/resolver/mem": "@tabnas/multisource/dist/resolver/mem.js",
|
|
91
|
+
"@tabnas/multisource/processor/jsonic": "@tabnas/multisource/dist/processor/jsonic.js"
|
|
70
92
|
}
|
|
71
93
|
}
|
|
72
94
|
}
|
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aontu
|
|
3
|
+
description: >-
|
|
4
|
+
Write, check and query Aontu definitions — a JSON superset where
|
|
5
|
+
documents UNIFY instead of overwriting. Use when a repository holds
|
|
6
|
+
`.aon` files, when configuration must satisfy a schema rather than
|
|
7
|
+
merely parse, or when you need to ask what a configuration says at a
|
|
8
|
+
path and why it says it.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Aontu
|
|
12
|
+
|
|
13
|
+
Aontu is JSON plus a lattice. Two documents do not override each
|
|
14
|
+
other, they **unify**: the result is the most specific value that
|
|
15
|
+
satisfies both, or an error naming the contradiction. That makes a
|
|
16
|
+
definition checkable, queryable and safe to change.
|
|
17
|
+
|
|
18
|
+
Start here:
|
|
19
|
+
|
|
20
|
+
- Every JSON document is an Aontu document. Write JSON, then add
|
|
21
|
+
what JSON cannot say.
|
|
22
|
+
- [`grammar-card.md`](grammar-card.md) — the whole surface on one
|
|
23
|
+
page.
|
|
24
|
+
- [`examples.md`](examples.md) — the JSON-superset ladder: plain
|
|
25
|
+
JSON, then kinds, defaults, templates, constraints.
|
|
26
|
+
- [`error-codes.md`](error-codes.md) — what a refusal means and what
|
|
27
|
+
to do about it.
|
|
28
|
+
|
|
29
|
+
The verbs, all of which answer as JSON with `--format json`:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
aontu vet schema.aon data.aon # does this data satisfy that truth?
|
|
33
|
+
aontu get $.a.b file.aon # what does it say at a path?
|
|
34
|
+
aontu why $.a.b file.aon # why does that value hold?
|
|
35
|
+
aontu set $.a.b=1 --entry file.aon --overlay over.aon
|
|
36
|
+
aontu hash file.aon # a pin that survives reformatting
|
|
37
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# What a refusal means
|
|
2
|
+
|
|
3
|
+
Every Aontu error carries a **code**, and every code has a **class**.
|
|
4
|
+
The class says what kind of thing went wrong, which is what decides
|
|
5
|
+
your next move. The full registry — every code, its class, and the
|
|
6
|
+
version it appeared in — is
|
|
7
|
+
[`test/spec/errcodes.tsv`](https://github.com/aontu-lang/aontu/blob/main/test/spec/errcodes.tsv), which the
|
|
8
|
+
test suite holds to the engine in both implementations.
|
|
9
|
+
|
|
10
|
+
| Class | Meaning | What to do |
|
|
11
|
+
|-------|---------|------------|
|
|
12
|
+
| `parse` | the text is not a document | fix the syntax at the site the frame points at |
|
|
13
|
+
| `conflict` | two values cannot both hold | one of them is wrong: `aontu why <path>` names both and where they were written |
|
|
14
|
+
| `incomplete` | nothing contradicts, but the value is not concrete | supply what is missing, or accept it with `--partial` |
|
|
15
|
+
| `reference` | a path names nothing | check the spelling; `aontu get $ --keys` lists what is there |
|
|
16
|
+
| `compat` | a change breaks an earlier version | that is `aontu subsume` / `aontu breaking` talking: widen the change or version it |
|
|
17
|
+
| `budget` | evaluation hit a deterministic limit | usually a cycle; simplify, or raise the budget deliberately |
|
|
18
|
+
| `internal` | the engine surprised itself | a bug worth reporting |
|
|
19
|
+
|
|
20
|
+
## The repair loop
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
aontu vet schema.aon mine.aon --format json
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The exit code branches for you: `0` valid, `1` invalid (fix the
|
|
27
|
+
data), `3` incomplete (supply more), `4` the schema itself is
|
|
28
|
+
unusable (fix the truth, not the data). Every finding carries
|
|
29
|
+
`path`, `code`, and the sites on both sides — the data site first,
|
|
30
|
+
because that is the one to edit. A site names **the file whose text
|
|
31
|
+
it excerpts**, so its row and column are safe to edit at even when
|
|
32
|
+
the document loads others.
|
|
33
|
+
|
|
34
|
+
Read `hint` before guessing. `message` is the one-line headline;
|
|
35
|
+
`hint` is the engine's own explanation of the failure class with the
|
|
36
|
+
offending values filled in, and for several codes it names the fix
|
|
37
|
+
outright — `lossy_integer_literal` tells you to write the literal as
|
|
38
|
+
`0d…`. It is absent for codes that have no hint text.
|
|
39
|
+
|
|
40
|
+
For a conflict, `aontu why <path> mine.aon` lists every contribution
|
|
41
|
+
to that path with its role and source line, which turns "these
|
|
42
|
+
disagree" into "these two lines disagree".
|
|
43
|
+
|
|
44
|
+
Then fix it:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
aontu set '$.replicas=5' --entry schema.aon --overlay mine.aon --in-place
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`--in-place` rewrites the pinned literal **where it was written**, so
|
|
51
|
+
comments and layout survive. Without it, `set` APPENDS — which is the
|
|
52
|
+
right thing when the document left a hole, and cannot work when it
|
|
53
|
+
pinned the wrong value, because unification only narrows.
|
|
54
|
+
|
|
55
|
+
The edit is verified before a byte is written: a site carries the
|
|
56
|
+
source text it covers, and the text at the span must match it. Where
|
|
57
|
+
that cannot be established — the value comes from a `&:` template or a
|
|
58
|
+
`$ref`, two statements pin the path, the site names the opening token
|
|
59
|
+
of a compound like `min(1)`, or the overlay `@"includes"` another
|
|
60
|
+
document — the assignment is appended as usual and a **warning** says
|
|
61
|
+
which case it hit. A warning never changes the verdict, so asking for
|
|
62
|
+
`--in-place` cannot make a run fail that would have succeeded.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Aontu by example
|
|
2
|
+
|
|
3
|
+
The ladder: start with the JSON you already know, add one thing at a
|
|
4
|
+
time. Every rung is a valid document.
|
|
5
|
+
|
|
6
|
+
## 1. It is JSON
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
{"service": {"name": "auth", "port": 8080}}
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Bare keys and no commas also parse, so this is the same document:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
service: {
|
|
16
|
+
name: "auth"
|
|
17
|
+
port: 8080
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 2. Say what a value MAY be
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
service: {
|
|
25
|
+
name: string
|
|
26
|
+
port: integer
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Nothing generates yet — this is a truth, not a value. `aontu vet
|
|
31
|
+
service.aon deploy.aon` says whether a deployment satisfies it.
|
|
32
|
+
|
|
33
|
+
## 3. Say what it SHOULD be
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
service: {
|
|
37
|
+
name: string
|
|
38
|
+
port: *8080 | integer # 8080 unless told otherwise
|
|
39
|
+
replicas: *1 | integer
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Now it generates: `{"service":{"name":…,"port":8080,"replicas":1}}` —
|
|
44
|
+
except `name`, which nothing has supplied. Defaults are picked at
|
|
45
|
+
generation; they do not stop a caller from choosing something else.
|
|
46
|
+
|
|
47
|
+
`*8080 | integer` means what it reads as: a caller's `9090` overrides
|
|
48
|
+
it, and a caller's `1.5` is refused, because the branch admits only the
|
|
49
|
+
kind it names. Write `*8080 | number` if any numeric value should be
|
|
50
|
+
allowed to win.
|
|
51
|
+
|
|
52
|
+
## 4. Say it once, for every key
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
services: {
|
|
56
|
+
&: { port: integer, replicas: *1 | integer }
|
|
57
|
+
auth: { port: 8080 }
|
|
58
|
+
db: { port: 5432, replicas: 3 }
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The `&:` template meets EVERY key. `aontu why $.services.db.replicas`
|
|
63
|
+
reports both contributions — the template's `*1|integer` and the
|
|
64
|
+
literal `3` — with the line each was written on.
|
|
65
|
+
|
|
66
|
+
## 5. Bound it
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
services: {
|
|
70
|
+
&: {
|
|
71
|
+
port: integer & min(1) & max(65535)
|
|
72
|
+
name: string & re("^[a-z][a-z0-9-]*$")
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
A port of `0` is now an error with a path, not a runtime surprise.
|
|
78
|
+
|
|
79
|
+
## 6. Layer it
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
# base.aon
|
|
83
|
+
service: { image: string, replicas: *1 | integer }
|
|
84
|
+
|
|
85
|
+
# prod.aon
|
|
86
|
+
@"base.aon"
|
|
87
|
+
service: { image: "auth:v2.3", replicas: 5 }
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Unification is order-independent: `base & prod` is `prod & base`. To
|
|
91
|
+
change a value without editing the file, append to an overlay:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
aontu set '$.service.replicas=7' --entry prod.aon --overlay local.aon
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If the value is PINNED rather than open, that command refuses and
|
|
98
|
+
names the pinning site — which is the honest answer, and where
|
|
99
|
+
`aontu why` takes you next.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Aontu grammar card
|
|
2
|
+
|
|
3
|
+
Everything the language spells, on one page. The published machine
|
|
4
|
+
grammar is [`grammar/aontu.gbnf`](../grammar/aontu.gbnf) (and
|
|
5
|
+
`aontu.lark`); this is its human twin.
|
|
6
|
+
|
|
7
|
+
## Values
|
|
8
|
+
|
|
9
|
+
| Write | Means |
|
|
10
|
+
|-------|-------|
|
|
11
|
+
| `{"a":1}`, `a: 1` | a map; keys may be bare or quoted |
|
|
12
|
+
| `[1,2]` | a list |
|
|
13
|
+
| `"s"`, `1`, `1.5`, `true`, `null` | scalars, as JSON |
|
|
14
|
+
| `0d9007199254740993` | an EXACT number, at any magnitude |
|
|
15
|
+
| `string integer number float boolean null` | kinds: any value of that kind |
|
|
16
|
+
| `top` | anything at all; `nil` is the failure |
|
|
17
|
+
|
|
18
|
+
## Combining
|
|
19
|
+
|
|
20
|
+
| Write | Means |
|
|
21
|
+
|-------|-------|
|
|
22
|
+
| `a & b` | both must hold — the meet |
|
|
23
|
+
| `a \| b` | either may hold — the join |
|
|
24
|
+
| `*1 \| integer` | either, with `1` the DEFAULT a generation picks |
|
|
25
|
+
| | the branch keeps its kind: a later `1.5` is refused, not admitted |
|
|
26
|
+
| `x: 1` twice | the two meet; `1 & 2` is an error, `1 & integer` is `1` |
|
|
27
|
+
| `$.a.b` | the value at that path of this document |
|
|
28
|
+
| `1 + 2` | arithmetic on concrete numbers |
|
|
29
|
+
|
|
30
|
+
## Maps that say more
|
|
31
|
+
|
|
32
|
+
| Write | Means |
|
|
33
|
+
|-------|-------|
|
|
34
|
+
| `{&: {k: integer}}` | a TEMPLATE every key must satisfy |
|
|
35
|
+
| `close({a:1})` | no key beyond those named |
|
|
36
|
+
| `{a?: 1}` | optional: dropped if unresolved |
|
|
37
|
+
| `hide(x)` | evaluated, then dropped from the output |
|
|
38
|
+
| `type(x)` | a definition, not a value: it generates nothing |
|
|
39
|
+
| `deprecate(x, {msg:"…"})` | still works, and says so |
|
|
40
|
+
| `refer(t) & path($.a.b)` | a checked LINK: the tree address must resolve, and `t` flows into it |
|
|
41
|
+
|
|
42
|
+
## Constraints
|
|
43
|
+
|
|
44
|
+
`min(n) max(n) above(n) below(n)` bound a number;
|
|
45
|
+
`length(n)` and `unique()` bound a list or string;
|
|
46
|
+
`re("^…$")` matches a string; `neq(v)` refuses one value;
|
|
47
|
+
`must(cond, "why")` is the escape hatch.
|
|
48
|
+
|
|
49
|
+
Bounds compose: `integer & min(1) & max(10)` is a range, and two
|
|
50
|
+
ranges meet to their overlap.
|
|
51
|
+
|
|
52
|
+
## Files
|
|
53
|
+
|
|
54
|
+
`@"other.aon"` includes another document — it unifies in, it does not
|
|
55
|
+
concatenate. (A constrained decoder is not given this: generated
|
|
56
|
+
documents describe values, they do not load files.)
|
package/src/agentsmd.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
// THE AGENTS.md STANZA (G7 phase 6,
|
|
4
|
+
// docs/capability-review/g7-machine-access.md): generated FROM the
|
|
5
|
+
// definition, so the prose entrypoint cannot drift from the formal
|
|
6
|
+
// source it points at.
|
|
7
|
+
//
|
|
8
|
+
// A hand-written "here is where the config lives" paragraph is stale
|
|
9
|
+
// the first time a key is renamed. This one is derived: the root keys
|
|
10
|
+
// come from the document, the pin comes from G6's canon-hash, and the
|
|
11
|
+
// commands are spelled with paths that exist. Re-running the verb
|
|
12
|
+
// after an edit produces the stanza that edit implies.
|
|
13
|
+
|
|
14
|
+
import { Aontu } from './aontu'
|
|
15
|
+
import type { TrustOptions } from './type'
|
|
16
|
+
import { canonHash } from './hcanon'
|
|
17
|
+
import { get } from './query'
|
|
18
|
+
import { evalFailure } from './query'
|
|
19
|
+
import type { VetFinding } from './vet'
|
|
20
|
+
import { cmpCodePoint } from './keyorder'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
// The markers an update rewrites between. A stanza outside them is
|
|
24
|
+
// prose someone wrote, and is left alone.
|
|
25
|
+
export const AGENTSMD_BEGIN = '<!-- aontu:begin -->'
|
|
26
|
+
export const AGENTSMD_END = '<!-- aontu:end -->'
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export type AgentsMdReport = {
|
|
30
|
+
findings: VetFinding[]
|
|
31
|
+
ok: boolean
|
|
32
|
+
stanza: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type AgentsMdOptions = {
|
|
36
|
+
// The name the stanza should call the document. The engine never
|
|
37
|
+
// reads a file; the CLI passes what the author typed.
|
|
38
|
+
name?: string
|
|
39
|
+
path?: string
|
|
40
|
+
// The include capability this document evaluates under
|
|
41
|
+
// (G5, docs/trust.md); vet's precedent.
|
|
42
|
+
trust?: TrustOptions
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// The stanza for one document.
|
|
47
|
+
export function agentsMd(
|
|
48
|
+
src: string, opts?: AgentsMdOptions): AgentsMdReport {
|
|
49
|
+
const options = opts ?? {}
|
|
50
|
+
const name = options.name ?? 'the definition'
|
|
51
|
+
|
|
52
|
+
const aontu = new Aontu(
|
|
53
|
+
null == options.trust ? undefined : { trust: options.trust })
|
|
54
|
+
const ctx = aontu.ctx({ collect: true })
|
|
55
|
+
const parseOpts = null == options.path ? undefined : { path: options.path }
|
|
56
|
+
const v: any = aontu.unify(src, parseOpts, ctx)
|
|
57
|
+
if (0 < ctx.err.length) {
|
|
58
|
+
return { findings: [evalFailure(ctx)], ok: false, stanza: '' }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const keys = true === v.isMap ? Object.keys(v.peg).sort(cmpCodePoint) : []
|
|
62
|
+
const shape = get(src, '$', { view: 'types', depth: 2, path: options.path })
|
|
63
|
+
|
|
64
|
+
// A REAL path, so the example command works as written: the first
|
|
65
|
+
// root key when there is one, the root itself when there is not.
|
|
66
|
+
const example = 0 < keys.length ? '$.' + keys[0] : '$'
|
|
67
|
+
|
|
68
|
+
const lines = [
|
|
69
|
+
AGENTSMD_BEGIN,
|
|
70
|
+
'## Ground truth: `' + name + '`',
|
|
71
|
+
'',
|
|
72
|
+
'The values below are DERIVED from `' + name + '`, an Aontu',
|
|
73
|
+
'definition. Do not restate them here — read them from the source,',
|
|
74
|
+
'which is the only copy that cannot go stale.',
|
|
75
|
+
'',
|
|
76
|
+
'- Pin: `' + canonHash(v) + '`',
|
|
77
|
+
' (the canon-hash: it survives reformatting and moves on any',
|
|
78
|
+
' change of meaning — `aontu hash ' + name + '` re-derives it)',
|
|
79
|
+
'- Top-level keys: ' +
|
|
80
|
+
(0 === keys.length ? '_none_' : keys.map((k) => '`' + k + '`').join(', ')),
|
|
81
|
+
'- Shape: `' + shape.out + '`',
|
|
82
|
+
'',
|
|
83
|
+
'How to work with it:',
|
|
84
|
+
'',
|
|
85
|
+
'```',
|
|
86
|
+
'# what does it say at a path?',
|
|
87
|
+
'aontu get ' + example + ' ' + name,
|
|
88
|
+
'',
|
|
89
|
+
'# why does that value hold?',
|
|
90
|
+
'aontu why ' + example + ' ' + name,
|
|
91
|
+
'',
|
|
92
|
+
'# does my document satisfy it?',
|
|
93
|
+
'aontu vet ' + name + ' mine.aon',
|
|
94
|
+
'',
|
|
95
|
+
'# change it without editing it',
|
|
96
|
+
'aontu set ' + example + '=<value> --entry ' + name +
|
|
97
|
+
' --overlay overlay.aon',
|
|
98
|
+
'```',
|
|
99
|
+
'',
|
|
100
|
+
'Regenerate this section with `aontu agentsmd ' + name + '`.',
|
|
101
|
+
AGENTSMD_END,
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
return { findings: [], ok: true, stanza: lines.join('\n') + '\n' }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// Splice the stanza into an existing document: replace what stands
|
|
109
|
+
// between the markers, or append when there is nothing to replace. A
|
|
110
|
+
// document is otherwise LEFT ALONE — the rest of an AGENTS.md is
|
|
111
|
+
// someone's prose, and a generator that rewrote it would be a
|
|
112
|
+
// generator nobody dared run twice.
|
|
113
|
+
export function agentsMdSplice(existing: string, stanza: string): string {
|
|
114
|
+
const from = existing.indexOf(AGENTSMD_BEGIN)
|
|
115
|
+
const to = existing.indexOf(AGENTSMD_END)
|
|
116
|
+
if (from < 0 || to < from) {
|
|
117
|
+
const head = '' === existing || existing.endsWith('\n')
|
|
118
|
+
? existing : existing + '\n'
|
|
119
|
+
return head + ('' === existing ? '' : '\n') + stanza
|
|
120
|
+
}
|
|
121
|
+
// Skip the end marker's line terminator, whatever it is, and only if
|
|
122
|
+
// it is there. The full note is on the Go twin (go/agentsmd.go): `+1`
|
|
123
|
+
// assumed one byte and got the CR of a CRLF document, leaving the LF
|
|
124
|
+
// to become a blank line on every regeneration -- and past the end of
|
|
125
|
+
// a document whose marker is its last content, where Go panicked and
|
|
126
|
+
// this side quietly did not.
|
|
127
|
+
let end = to + AGENTSMD_END.length
|
|
128
|
+
if ('\r' === existing[end]) {
|
|
129
|
+
end++
|
|
130
|
+
}
|
|
131
|
+
if ('\n' === existing[end]) {
|
|
132
|
+
end++
|
|
133
|
+
}
|
|
134
|
+
return existing.slice(0, from) + stanza + existing.slice(end)
|
|
135
|
+
}
|