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.
Files changed (310) hide show
  1. package/README.md +88 -0
  2. package/bin/aontu-mcp.js +4 -0
  3. package/dist/agentsmd.d.ts +16 -0
  4. package/dist/agentsmd.js +107 -0
  5. package/dist/agentsmd.js.map +1 -0
  6. package/dist/aontu.d.ts +15 -3
  7. package/dist/aontu.js +126 -5
  8. package/dist/aontu.js.map +1 -1
  9. package/dist/cli.d.ts +45 -1
  10. package/dist/cli.js +2845 -69
  11. package/dist/cli.js.map +1 -1
  12. package/dist/ctx.d.ts +18 -0
  13. package/dist/ctx.js +44 -0
  14. package/dist/ctx.js.map +1 -1
  15. package/dist/diff.d.ts +22 -0
  16. package/dist/diff.js +141 -0
  17. package/dist/diff.js.map +1 -0
  18. package/dist/err.d.ts +3 -1
  19. package/dist/err.js +45 -8
  20. package/dist/err.js.map +1 -1
  21. package/dist/graph.d.ts +13 -0
  22. package/dist/graph.js +110 -0
  23. package/dist/graph.js.map +1 -0
  24. package/dist/hcanon.d.ts +3 -0
  25. package/dist/hcanon.js +145 -0
  26. package/dist/hcanon.js.map +1 -0
  27. package/dist/hints.js +235 -8
  28. package/dist/hints.js.map +1 -1
  29. package/dist/jsonschema.d.ts +20 -0
  30. package/dist/jsonschema.js +425 -0
  31. package/dist/jsonschema.js.map +1 -0
  32. package/dist/lang.js +955 -110
  33. package/dist/lang.js.map +1 -1
  34. package/dist/lsp.d.ts +9 -2
  35. package/dist/lsp.js +343 -48
  36. package/dist/lsp.js.map +1 -1
  37. package/dist/mcp-server.d.ts +20 -0
  38. package/dist/mcp-server.js +147 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/mcp.d.ts +42 -0
  41. package/dist/mcp.js +941 -0
  42. package/dist/mcp.js.map +1 -0
  43. package/dist/mod-tool.d.ts +58 -0
  44. package/dist/mod-tool.js +532 -0
  45. package/dist/mod-tool.js.map +1 -0
  46. package/dist/mod.d.ts +35 -0
  47. package/dist/mod.js +345 -0
  48. package/dist/mod.js.map +1 -0
  49. package/dist/patch.d.ts +49 -0
  50. package/dist/patch.js +506 -0
  51. package/dist/patch.js.map +1 -0
  52. package/dist/provenance.d.ts +41 -0
  53. package/dist/provenance.js +336 -0
  54. package/dist/provenance.js.map +1 -0
  55. package/dist/query.d.ts +27 -0
  56. package/dist/query.js +294 -0
  57. package/dist/query.js.map +1 -0
  58. package/dist/reach.d.ts +15 -0
  59. package/dist/reach.js +168 -0
  60. package/dist/reach.js.map +1 -0
  61. package/dist/relation.d.ts +23 -0
  62. package/dist/relation.js +230 -0
  63. package/dist/relation.js.map +1 -0
  64. package/dist/report-sarif.d.ts +14 -0
  65. package/dist/report-sarif.js +102 -0
  66. package/dist/report-sarif.js.map +1 -0
  67. package/dist/sig.d.ts +25 -0
  68. package/dist/sig.js +277 -0
  69. package/dist/sig.js.map +1 -0
  70. package/dist/sigdecl.d.ts +2 -0
  71. package/dist/sigdecl.js +11 -0
  72. package/dist/sigdecl.js.map +1 -0
  73. package/dist/siggate.d.ts +4 -0
  74. package/dist/siggate.js +90 -0
  75. package/dist/siggate.js.map +1 -0
  76. package/dist/site.d.ts +4 -0
  77. package/dist/site.js +31 -0
  78. package/dist/site.js.map +1 -1
  79. package/dist/std.d.ts +1 -0
  80. package/dist/std.js +129 -0
  81. package/dist/std.js.map +1 -0
  82. package/dist/subsume.d.ts +39 -0
  83. package/dist/subsume.js +573 -0
  84. package/dist/subsume.js.map +1 -0
  85. package/dist/trim.d.ts +19 -0
  86. package/dist/trim.js +155 -0
  87. package/dist/trim.js.map +1 -0
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/dist/type.d.ts +17 -1
  90. package/dist/type.js.map +1 -1
  91. package/dist/unify.d.ts +2 -1
  92. package/dist/unify.js +234 -38
  93. package/dist/unify.js.map +1 -1
  94. package/dist/utility.d.ts +8 -1
  95. package/dist/utility.js +68 -1
  96. package/dist/utility.js.map +1 -1
  97. package/dist/val/AggFuncVal.d.ts +44 -0
  98. package/dist/val/AggFuncVal.js +364 -0
  99. package/dist/val/AggFuncVal.js.map +1 -0
  100. package/dist/val/ArithFuncVal.d.ts +31 -0
  101. package/dist/val/ArithFuncVal.js +62 -0
  102. package/dist/val/ArithFuncVal.js.map +1 -0
  103. package/dist/val/BagVal.d.ts +7 -0
  104. package/dist/val/BagVal.js +150 -11
  105. package/dist/val/BagVal.js.map +1 -1
  106. package/dist/val/CloseFuncVal.js +9 -1
  107. package/dist/val/CloseFuncVal.js.map +1 -1
  108. package/dist/val/ConjunctVal.d.ts +1 -1
  109. package/dist/val/ConjunctVal.js +19 -0
  110. package/dist/val/ConjunctVal.js.map +1 -1
  111. package/dist/val/ConstraintVal.d.ts +7 -1
  112. package/dist/val/ConstraintVal.js +523 -45
  113. package/dist/val/ConstraintVal.js.map +1 -1
  114. package/dist/val/ContainerKindVal.d.ts +35 -0
  115. package/dist/val/ContainerKindVal.js +99 -0
  116. package/dist/val/ContainerKindVal.js.map +1 -0
  117. package/dist/val/CopyFuncVal.d.ts +1 -2
  118. package/dist/val/CopyFuncVal.js.map +1 -1
  119. package/dist/val/Decimal.d.ts +1 -0
  120. package/dist/val/Decimal.js +13 -0
  121. package/dist/val/Decimal.js.map +1 -1
  122. package/dist/val/DeprecateFuncVal.d.ts +11 -0
  123. package/dist/val/DeprecateFuncVal.js +47 -0
  124. package/dist/val/DeprecateFuncVal.js.map +1 -0
  125. package/dist/val/DisjunctVal.d.ts +1 -2
  126. package/dist/val/DisjunctVal.js +269 -53
  127. package/dist/val/DisjunctVal.js.map +1 -1
  128. package/dist/val/EachFuncVal.d.ts +15 -0
  129. package/dist/val/EachFuncVal.js +75 -0
  130. package/dist/val/EachFuncVal.js.map +1 -0
  131. package/dist/val/ExpectVal.js +62 -4
  132. package/dist/val/ExpectVal.js.map +1 -1
  133. package/dist/val/FeatureVal.js +1 -1
  134. package/dist/val/FeatureVal.js.map +1 -1
  135. package/dist/val/FilterFuncVal.d.ts +15 -0
  136. package/dist/val/FilterFuncVal.js +91 -0
  137. package/dist/val/FilterFuncVal.js.map +1 -0
  138. package/dist/val/FuncBaseVal.d.ts +7 -1
  139. package/dist/val/FuncBaseVal.js +183 -2
  140. package/dist/val/FuncBaseVal.js.map +1 -1
  141. package/dist/val/GraphAtomVal.d.ts +39 -0
  142. package/dist/val/GraphAtomVal.js +184 -0
  143. package/dist/val/GraphAtomVal.js.map +1 -0
  144. package/dist/val/HideFuncVal.js.map +1 -1
  145. package/dist/val/JunctionVal.js +24 -1
  146. package/dist/val/JunctionVal.js.map +1 -1
  147. package/dist/val/KeyFuncVal.d.ts +1 -1
  148. package/dist/val/KeyFuncVal.js +38 -30
  149. package/dist/val/KeyFuncVal.js.map +1 -1
  150. package/dist/val/ListVal.js +94 -14
  151. package/dist/val/ListVal.js.map +1 -1
  152. package/dist/val/LowerFuncVal.js.map +1 -1
  153. package/dist/val/MapVal.d.ts +1 -0
  154. package/dist/val/MapVal.js +146 -14
  155. package/dist/val/MapVal.js.map +1 -1
  156. package/dist/val/MatchFuncVal.d.ts +15 -0
  157. package/dist/val/MatchFuncVal.js +107 -0
  158. package/dist/val/MatchFuncVal.js.map +1 -0
  159. package/dist/val/MoveFuncVal.js.map +1 -1
  160. package/dist/val/NilVal.js +24 -0
  161. package/dist/val/NilVal.js.map +1 -1
  162. package/dist/val/OpBaseVal.d.ts +1 -1
  163. package/dist/val/OpBaseVal.js +19 -1
  164. package/dist/val/OpBaseVal.js.map +1 -1
  165. package/dist/val/OpenFuncVal.js +4 -1
  166. package/dist/val/OpenFuncVal.js.map +1 -1
  167. package/dist/val/PackFuncVal.d.ts +15 -0
  168. package/dist/val/PackFuncVal.js +108 -0
  169. package/dist/val/PackFuncVal.js.map +1 -0
  170. package/dist/val/PathFuncVal.d.ts +2 -2
  171. package/dist/val/PathFuncVal.js +75 -16
  172. package/dist/val/PathFuncVal.js.map +1 -1
  173. package/dist/val/PathVal.d.ts +25 -0
  174. package/dist/val/PathVal.js +150 -0
  175. package/dist/val/PathVal.js.map +1 -0
  176. package/dist/val/PlaceVal.d.ts +13 -0
  177. package/dist/val/PlaceVal.js +131 -0
  178. package/dist/val/PlaceVal.js.map +1 -0
  179. package/dist/val/PlusOpVal.d.ts +2 -1
  180. package/dist/val/PlusOpVal.js +61 -37
  181. package/dist/val/PlusOpVal.js.map +1 -1
  182. package/dist/val/PrefFuncVal.js.map +1 -1
  183. package/dist/val/PrefVal.d.ts +4 -2
  184. package/dist/val/PrefVal.js +223 -41
  185. package/dist/val/PrefVal.js.map +1 -1
  186. package/dist/val/RecurseVal.d.ts +19 -0
  187. package/dist/val/RecurseVal.js +217 -0
  188. package/dist/val/RecurseVal.js.map +1 -0
  189. package/dist/val/RefVal.d.ts +3 -2
  190. package/dist/val/RefVal.js +181 -66
  191. package/dist/val/RefVal.js.map +1 -1
  192. package/dist/val/ReferFuncVal.d.ts +59 -0
  193. package/dist/val/ReferFuncVal.js +604 -0
  194. package/dist/val/ReferFuncVal.js.map +1 -0
  195. package/dist/val/ScalarKindVal.d.ts +4 -3
  196. package/dist/val/ScalarKindVal.js +12 -12
  197. package/dist/val/ScalarKindVal.js.map +1 -1
  198. package/dist/val/SuperFuncVal.d.ts +4 -2
  199. package/dist/val/SuperFuncVal.js +118 -14
  200. package/dist/val/SuperFuncVal.js.map +1 -1
  201. package/dist/val/TopVal.d.ts +1 -1
  202. package/dist/val/TopVal.js.map +1 -1
  203. package/dist/val/TypeFuncVal.js.map +1 -1
  204. package/dist/val/UpperFuncVal.js.map +1 -1
  205. package/dist/val/Val.d.ts +7 -1
  206. package/dist/val/Val.js +170 -2
  207. package/dist/val/Val.js.map +1 -1
  208. package/dist/val/VarVal.js.map +1 -1
  209. package/dist/val/arith.d.ts +6 -0
  210. package/dist/val/arith.js +173 -0
  211. package/dist/val/arith.js.map +1 -0
  212. package/dist/vet.d.ts +45 -0
  213. package/dist/vet.js +802 -0
  214. package/dist/vet.js.map +1 -0
  215. package/dist/view.d.ts +85 -0
  216. package/dist/view.js +1948 -0
  217. package/dist/view.js.map +1 -0
  218. package/dist/walk.d.ts +2 -0
  219. package/dist/walk.js +91 -0
  220. package/dist/walk.js.map +1 -0
  221. package/grammar/aontu.gbnf +138 -0
  222. package/grammar/aontu.lark +118 -0
  223. package/grammar/aontu.tmLanguage.json +184 -0
  224. package/package.json +30 -8
  225. package/skill/SKILL.md +37 -0
  226. package/skill/error-codes.md +62 -0
  227. package/skill/examples.md +99 -0
  228. package/skill/grammar-card.md +56 -0
  229. package/src/agentsmd.ts +135 -0
  230. package/src/aontu.ts +166 -5
  231. package/src/cli.ts +3324 -72
  232. package/src/ctx.ts +93 -1
  233. package/src/diff.ts +198 -0
  234. package/src/err.ts +50 -8
  235. package/src/graph.ts +185 -0
  236. package/src/hcanon.ts +167 -0
  237. package/src/hints.ts +291 -8
  238. package/src/jsonschema.ts +552 -0
  239. package/src/lang.ts +1049 -110
  240. package/src/lsp.ts +351 -49
  241. package/src/mcp-server.ts +187 -0
  242. package/src/mcp.ts +1130 -0
  243. package/src/mod-tool.ts +718 -0
  244. package/src/mod.ts +453 -0
  245. package/src/patch.ts +628 -0
  246. package/src/provenance.ts +437 -0
  247. package/src/query.ts +381 -0
  248. package/src/reach.ts +213 -0
  249. package/src/relation.ts +298 -0
  250. package/src/report-sarif.ts +137 -0
  251. package/src/sig.ts +345 -0
  252. package/src/sigdecl.ts +11 -0
  253. package/src/siggate.ts +144 -0
  254. package/src/site.ts +36 -1
  255. package/src/std.ts +131 -0
  256. package/src/subsume.ts +739 -0
  257. package/src/trim.ts +195 -0
  258. package/src/tsconfig.json +10 -4
  259. package/src/type.ts +51 -2
  260. package/src/unify.ts +253 -38
  261. package/src/utility.ts +79 -1
  262. package/src/val/AggFuncVal.ts +546 -0
  263. package/src/val/ArithFuncVal.ts +108 -0
  264. package/src/val/BagVal.ts +158 -12
  265. package/src/val/CloseFuncVal.ts +9 -1
  266. package/src/val/ConjunctVal.ts +20 -0
  267. package/src/val/ConstraintVal.ts +576 -48
  268. package/src/val/ContainerKindVal.ts +158 -0
  269. package/src/val/CopyFuncVal.ts +0 -1
  270. package/src/val/Decimal.ts +15 -0
  271. package/src/val/DeprecateFuncVal.ts +84 -0
  272. package/src/val/DisjunctVal.ts +282 -59
  273. package/src/val/EachFuncVal.ts +133 -0
  274. package/src/val/ExpectVal.ts +65 -8
  275. package/src/val/FeatureVal.ts +1 -1
  276. package/src/val/FilterFuncVal.ts +154 -0
  277. package/src/val/FuncBaseVal.ts +206 -2
  278. package/src/val/GraphAtomVal.ts +264 -0
  279. package/src/val/HideFuncVal.ts +0 -2
  280. package/src/val/JunctionVal.ts +24 -1
  281. package/src/val/KeyFuncVal.ts +39 -35
  282. package/src/val/ListVal.ts +101 -15
  283. package/src/val/LowerFuncVal.ts +0 -1
  284. package/src/val/MapVal.ts +153 -14
  285. package/src/val/MatchFuncVal.ts +176 -0
  286. package/src/val/MoveFuncVal.ts +0 -2
  287. package/src/val/NilVal.ts +25 -0
  288. package/src/val/OpBaseVal.ts +20 -1
  289. package/src/val/OpenFuncVal.ts +4 -2
  290. package/src/val/PackFuncVal.ts +175 -0
  291. package/src/val/PathFuncVal.ts +107 -20
  292. package/src/val/PathVal.ts +221 -0
  293. package/src/val/PlaceVal.ts +193 -0
  294. package/src/val/PlusOpVal.ts +67 -39
  295. package/src/val/PrefFuncVal.ts +0 -1
  296. package/src/val/PrefVal.ts +251 -60
  297. package/src/val/RecurseVal.ts +285 -0
  298. package/src/val/RefVal.ts +183 -78
  299. package/src/val/ReferFuncVal.ts +732 -0
  300. package/src/val/ScalarKindVal.ts +12 -13
  301. package/src/val/SuperFuncVal.ts +137 -13
  302. package/src/val/TopVal.ts +1 -2
  303. package/src/val/TypeFuncVal.ts +0 -2
  304. package/src/val/UpperFuncVal.ts +0 -1
  305. package/src/val/Val.ts +216 -4
  306. package/src/val/VarVal.ts +0 -1
  307. package/src/val/arith.ts +319 -0
  308. package/src/vet.ts +1025 -0
  309. package/src/view.ts +2563 -0
  310. package/src/walk.ts +99 -0
package/src/sig.ts ADDED
@@ -0,0 +1,345 @@
1
+ /* Copyright (c) 2021-2026 Richard Rodger, MIT License */
2
+
3
+ // THE SIGNATURE REGISTRY (docs/design/SIGNATURES.0.md). The call
4
+ // surface of the built-in functions is DECLARED, in the signature
5
+ // syntax itself, in test/spec/signature.tsv; this module is the
6
+ // TypeScript half of the pair that reads it. The declaration text is
7
+ // inlined at build time (ts/src/sigdecl.ts, `make sig`) and parsed at
8
+ // initialisation by the signature grammar -- a custom tabnas grammar,
9
+ // the same engine the aontu grammar itself is built on -- into the
10
+ // registry the runtime signature checker, the error-message builder,
11
+ // the docs table and the LSP all consume. Neither port authors a
12
+ // table: go/sig.go parses the same text with the same grammar, and
13
+ // the shared suite round-trips every line (render(parse(line)) is the
14
+ // line) so the two parsers cannot drift.
15
+ //
16
+ // line = name '(' [ arg {',' arg} ] ')' ':' type
17
+ // arg = [mode] name ['?'] ':' type
18
+ // | '...' name ':' ( type | '(' [mode] type {',' [mode] type} ')' )
19
+ // type = word {'|' word}
20
+ // mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'
21
+ //
22
+ // `value` mode is unmarked; the five marked modes are the vocabulary
23
+ // plain pseudo-TypeScript cannot say (a captured spelling is not a
24
+ // string value). The grammar is line-oriented: the loader strips
25
+ // comment and blank lines and parses each declaration line alone, so
26
+ // the grammar never sees line structure.
27
+
28
+ import { Tabnas } from '@tabnas/parser'
29
+
30
+ import { SIGDECL } from './sigdecl'
31
+
32
+
33
+ type ArgMode = 'value' | 'capture' | 'template' | 'trial' | 'projector' | 'text'
34
+
35
+ // One group member of a rest-group argument (match's pattern/result
36
+ // pair): a mode and a type, no name -- the group repeats.
37
+ type GroupSig = {
38
+ mode: ArgMode
39
+ type: string
40
+ }
41
+
42
+ type ArgSig = {
43
+ name: string
44
+ mode: ArgMode
45
+ type: string
46
+ opt?: boolean
47
+ rest?: boolean
48
+ group?: GroupSig[]
49
+ }
50
+
51
+ type FuncSig = {
52
+ name: string
53
+ args: ArgSig[]
54
+ out: string
55
+ }
56
+
57
+ const ARG_MODES: Record<string, boolean> = {
58
+ capture: true, template: true, trial: true, projector: true, text: true,
59
+ }
60
+
61
+
62
+ // The signature grammar, as a tabnas grammar plugin. Rules: sig (the
63
+ // line) -> args -> arg -> argtype -> type | group -> gmember. Alts
64
+ // match at most two tokens, the engine's shape; lists loop the
65
+ // json-grammar way (the element rule replaces itself on ',' and
66
+ // backtracks the closer for its parent to consume).
67
+ function sigGrammar(tn: any) {
68
+ tn.options({
69
+ fixed: {
70
+ token: {
71
+ '#OP': '(',
72
+ '#CP': ')',
73
+ '#QM': '?',
74
+ '#PI': '|',
75
+ '#DD': '...',
76
+ },
77
+ },
78
+ rule: { start: 'sig' },
79
+ })
80
+
81
+ // Parse-level validation errors, collected by the actions: the
82
+ // engine's own errors cover token shape, these cover word choice (a
83
+ // mode that is not a mode). Read after parse by parseSigLine.
84
+ const errs: string[] = []
85
+ tn.sigErrs = errs
86
+
87
+ const mode = (word: string): ArgMode => {
88
+ if (true !== ARG_MODES[word]) {
89
+ errs.push('mode:' + word)
90
+ return 'value'
91
+ }
92
+ return word as ArgMode
93
+ }
94
+
95
+ tn.grammar({
96
+ ref: {
97
+ '@sig-bo': (r: any) => {
98
+ r.node = { name: '', args: [], out: '' }
99
+ r.u.words = []
100
+ },
101
+ '@signame': (r: any) => {
102
+ r.node.name = String(r.o0.val)
103
+ },
104
+ '@sigargs': (r: any) => {
105
+ r.node.args = r.child.node
106
+ },
107
+ '@sigout': (r: any) => {
108
+ r.node.out = r.u.words.join('|')
109
+ },
110
+
111
+ '@args-bo': (r: any) => {
112
+ r.node = []
113
+ },
114
+
115
+ '@arg-bo': (r: any) => {
116
+ r.u.sig = { name: '', mode: 'value', type: '' }
117
+ },
118
+ '@arg-rest': (r: any) => {
119
+ r.u.sig.rest = true
120
+ r.u.sig.name = String(r.o1.val)
121
+ },
122
+ '@arg-modename': (r: any) => {
123
+ r.u.sig.mode = mode(String(r.o0.val))
124
+ r.u.sig.name = String(r.o1.val)
125
+ },
126
+ '@arg-name': (r: any) => {
127
+ r.u.sig.name = String(r.o0.val)
128
+ },
129
+ '@arg-opt': (r: any) => {
130
+ r.u.sig.opt = true
131
+ },
132
+ '@arg-done': (r: any) => {
133
+ const sig = r.u.sig
134
+ const at = r.child.node
135
+ if (Array.isArray(at)) {
136
+ sig.group = at
137
+ sig.type = ''
138
+ }
139
+ else {
140
+ sig.type = String(at)
141
+ }
142
+ r.node.push(sig)
143
+ },
144
+
145
+ '@argtype-bo': (r: any) => {
146
+ r.u.words = []
147
+ },
148
+ '@argtype-bc': (r: any) => {
149
+ r.node = 0 < r.u.words.length ?
150
+ r.u.words.join('|') : r.child.node
151
+ },
152
+
153
+ '@type-word': (r: any) => {
154
+ r.parent.u.words.push(String(r.o0.val))
155
+ },
156
+
157
+ '@group-bo': (r: any) => {
158
+ r.node = []
159
+ },
160
+ '@gm-two': (r: any) => {
161
+ r.u.gm = { mode: mode(String(r.o0.val)), type: String(r.o1.val) }
162
+ },
163
+ '@gm-one': (r: any) => {
164
+ r.u.gm = { mode: 'value', type: String(r.o0.val) }
165
+ },
166
+ '@gm-done': (r: any) => {
167
+ r.node.push(r.u.gm)
168
+ },
169
+ },
170
+
171
+ rule: {
172
+ sig: {
173
+ open: [
174
+ { s: '#TX #OP', a: '@signame', p: 'args' },
175
+ ],
176
+ close: [
177
+ { s: '#CL', p: 'type', a: '@sigargs' },
178
+ { s: '#ZZ', a: '@sigout' },
179
+ ],
180
+ },
181
+
182
+ args: {
183
+ open: [
184
+ { s: '#CP', b: 1 },
185
+ { p: 'arg' },
186
+ ],
187
+ close: [
188
+ { s: '#CP' },
189
+ ],
190
+ },
191
+
192
+ arg: {
193
+ open: [
194
+ { s: '#DD #TX', a: '@arg-rest' },
195
+ { s: '#TX #TX', a: '@arg-modename' },
196
+ { s: '#TX', a: '@arg-name' },
197
+ ],
198
+ close: [
199
+ { s: '#QM #CL', a: '@arg-opt', p: 'argtype' },
200
+ { s: '#CL', p: 'argtype' },
201
+ { s: '#CA', a: '@arg-done', r: 'arg' },
202
+ { s: '#CP', a: '@arg-done', b: 1 },
203
+ ],
204
+ },
205
+
206
+ argtype: {
207
+ open: [
208
+ { s: '#OP', p: 'group' },
209
+ { p: 'type' },
210
+ ],
211
+ close: [
212
+ {},
213
+ ],
214
+ },
215
+
216
+ type: {
217
+ open: [
218
+ { s: '#TX', a: '@type-word' },
219
+ ],
220
+ close: [
221
+ { s: '#PI', r: 'type' },
222
+ {},
223
+ ],
224
+ },
225
+
226
+ group: {
227
+ open: [
228
+ { p: 'gmember' },
229
+ ],
230
+ close: [
231
+ { s: '#CP' },
232
+ ],
233
+ },
234
+
235
+ gmember: {
236
+ open: [
237
+ { s: '#TX #TX', a: '@gm-two' },
238
+ { s: '#TX', a: '@gm-one' },
239
+ ],
240
+ close: [
241
+ { s: '#CA', a: '@gm-done', r: 'gmember' },
242
+ { s: '#CP', a: '@gm-done', b: 1 },
243
+ ],
244
+ },
245
+ },
246
+ })
247
+ }
248
+
249
+
250
+ let sigParser: any = undefined
251
+
252
+ function makeSigParser(): any {
253
+ if (undefined === sigParser) {
254
+ sigParser = new Tabnas({ plugins: [sigGrammar] })
255
+ }
256
+ return sigParser
257
+ }
258
+
259
+
260
+ // Parse ONE declaration line. A malformed line is an Error: the
261
+ // declaration is repository content, read at build and test time, so
262
+ // failing loudly is the right shape (the round-trip suite holds the
263
+ // gate).
264
+ function parseSigLine(line: string): FuncSig {
265
+ const tn = makeSigParser()
266
+ tn.sigErrs.length = 0
267
+ const out = tn.parse(line)
268
+ if (0 < tn.sigErrs.length) {
269
+ throw new Error('signature: bad declaration ' +
270
+ tn.sigErrs.join(',') + ': ' + line)
271
+ }
272
+ if (null == out || '' === out.name || '' === out.out) {
273
+ throw new Error('signature: incomplete declaration: ' + line)
274
+ }
275
+ return out as FuncSig
276
+ }
277
+
278
+
279
+ // Render one argument of a signature -- the piece the LSP's
280
+ // signatureHelp parameters share with the whole-line renderer.
281
+ function renderSigArg(a: ArgSig): string {
282
+ const type = undefined === a.group ? a.type :
283
+ '(' + a.group.map((g: GroupSig) =>
284
+ ('value' === g.mode ? '' : g.mode + ' ') + g.type).join(', ') + ')'
285
+ return (true === a.rest ? '...' : '') +
286
+ ('value' === a.mode || true === a.rest ? '' : a.mode + ' ') +
287
+ a.name +
288
+ (true === a.opt ? '?' : '') +
289
+ ': ' + type
290
+ }
291
+
292
+
293
+ // Render the canonical line for a parsed signature -- the round-trip
294
+ // twin of parseSigLine, and the one renderer every consumer (hints,
295
+ // docs, LSP) uses.
296
+ function renderSig(sig: FuncSig): string {
297
+ return sig.name + '(' +
298
+ sig.args.map(renderSigArg).join(', ') + ') : ' + sig.out
299
+ }
300
+
301
+
302
+ // Parse the whole declaration text: comment (#) and blank lines are
303
+ // the loader's to skip, one FuncSig per remaining line, name-keyed.
304
+ // A duplicate name is an error for the same reason a bad line is.
305
+ function parseSigText(text: string): Record<string, FuncSig> {
306
+ const reg: Record<string, FuncSig> = {}
307
+ for (const rawline of text.split('\n')) {
308
+ const line = rawline.trim()
309
+ if ('' === line || line.startsWith('#')) {
310
+ continue
311
+ }
312
+ const sig = parseSigLine(line)
313
+ if (undefined !== reg[sig.name]) {
314
+ throw new Error('signature: duplicate declaration: ' + sig.name)
315
+ }
316
+ reg[sig.name] = sig
317
+ }
318
+ return reg
319
+ }
320
+
321
+
322
+ export type {
323
+ ArgMode,
324
+ ArgSig,
325
+ GroupSig,
326
+ FuncSig,
327
+ }
328
+
329
+ // The parsed registry, built once from the inlined declaration -- the
330
+ // one source every consumer (the arity tables, the runtime gate, the
331
+ // hints, the docs table, the LSP) reads. A parse failure here throws
332
+ // at module load: the inlined text is repository content whose parse
333
+ // the round-trip suite gates, so a failure is a build defect, not a
334
+ // runtime condition. Twin: funcSig in go/sig.go.
335
+ const funcSig: Record<string, FuncSig> =
336
+ parseSigText(SIGDECL) /* node:coverage ignore next 9 */
337
+
338
+
339
+ export {
340
+ funcSig,
341
+ parseSigLine,
342
+ parseSigText,
343
+ renderSig,
344
+ renderSigArg,
345
+ }
package/src/sigdecl.ts ADDED
@@ -0,0 +1,11 @@
1
+ /* Copyright (c) 2021-2026 Richard Rodger, MIT License */
2
+
3
+ // GENERATED by ts/scripts/sigdecl.cjs (`make sig`) from
4
+ // test/spec/signature.tsv — DO NOT EDIT. The declaration is the
5
+ // source (docs/design/SIGNATURES.0.md); ts/test/sig.test.ts asserts
6
+ // this copy is identical with the shared file.
7
+
8
+ const SIGDECL: string =
9
+ "# The call surface: one declaration line per built-in function\n# (docs/design/SIGNATURES.0.md). THIS FILE IS THE SOURCE — both ports\n# carry a build-time-inlined copy (ts/src/sigdecl.ts, go/sigdecl.txt;\n# `make sig` regenerates both, and each port's suite asserts its copy\n# is byte-identical with this file) and parse it at initialisation\n# with the signature grammar, a tabnas grammar (ts/src/sig.ts,\n# go/sig.go). The suites also round-trip every line:\n# render(parse(line)) must be the line exactly, in both ports.\n#\n# The syntax (rendered TypeScript-ish, honest about argument MODES):\n# line = name '(' [ arg {',' arg} ] ')' ':' type\n# arg = [mode] name ['?'] ':' type\n# | '...' name ':' '(' [mode] type {',' [mode] type} ')'\n# type = word {'|' word}\n# mode = 'capture' | 'template' | 'trial' | 'projector' | 'text'\n# `value` mode is unmarked. `constraint` is the result word for\n# residuals whose meet depends on the peer; `any` is the honest type\n# where a function is a wrapper.\nupper(s: string|number) : string\nlower(s: string|number) : string\ncopy(v: any) : any\npref(v: any) : any\nsuper(t: any) : any\ntype(t: any) : any\nhide(v: any) : any\nclose(m: any) : any\nopen(m: any) : any\nmove(v: any) : any\npath(capture p?: path) : path\nmap() : map\nlist() : list\nmin(n: number|string) : constraint\nmax(n: number|string) : constraint\nabove(n: number|string) : constraint\nbelow(n: number|string) : constraint\nre(text p: string) : constraint\nlength(n: number|constraint) : constraint\nkey(up?: integer|biginteger) : string\nunique(projector k?: string) : constraint\nneq(...vals: number|string) : constraint\nmust(trial c: any, text msg: string) : constraint\ndeprecate(v: any, r?: map) : any\nacyclic() : constraint\ninverse(projector k: string) : constraint\nrefer(template t?: any) : constraint\nrel(template t?: any) : constraint\npack(d: map|list, template t: any) : map\neach(d: map|list, template t?: any) : list\nfilter(d: map|list, trial c: any) : map|list\nmatch(s: any, ...pr: (trial any, any), dflt?: any) : any\nadd(a: number, b: number) : number\nsub(a: number, b: number) : number\nmul(a: number, b: number) : number\ndiv(a: number, b: number) : number\nmod(a: number, b: number) : number\nrem(a: number, b: number) : number\nsum(d: map|list) : number\nleast(d: map|list) : number\ngreatest(d: map|list) : number\npick(d: map|list, projector k: string|integer) : any\njoin(d: map|list, sep?: string) : string\n"
10
+
11
+ export { SIGDECL }
package/src/siggate.ts ADDED
@@ -0,0 +1,144 @@
1
+ /* Copyright (c) 2021-2026 Richard Rodger, MIT License */
2
+
3
+ // THE RUNTIME SIGNATURE CHECKER (docs/design/SIGNATURES.0.md). One
4
+ // argument gate, run by the shared function machinery
5
+ // (FuncBaseVal.unify) just before a call resolves, when its arguments
6
+ // are driven: for each VALUE-mode argument whose declared type is
7
+ // scalar-kind words, the driven Val must be a concrete scalar of an
8
+ // admitted kind. A failure refuses as `func_arg`, whose hint renders
9
+ // the signature line and names the offending argument -- the
10
+ // error-message builder the registry exists for.
11
+ //
12
+ // The gate owns exactly the argument-shape refusals that were bare
13
+ // `invalid-arg` at the call: the case family's operand, the
14
+ // arithmetic operands, join's separator, pick's key. Everything with
15
+ // more meaning than a shape mismatch keeps its own code: the bag
16
+ // arguments (`pack_data`, `each_data`, `filter_data`,
17
+ // `aggregate_data` -- container words are not gate words), the
18
+ // constraint atoms (not on this path at all -- their refusals ride
19
+ // the residual), `key()` (whose level meaning `key_level` names, and
20
+ // which is skipped here for that reason), and the capture, template,
21
+ // trial, projector and text modes, none of which are read as values.
22
+ //
23
+ // What the gate refuses it must POSITIVELY identify: a concrete
24
+ // scalar of a wrong kind, a map, a list, or a scalar KIND marker
25
+ // where a value belongs. Anything else -- a preference, a residual, a
26
+ // disjunct -- passes through to the builtin's own logic, which is
27
+ // what keeps arith's unpref reading and join's deferral working.
28
+ // Twin: sigRefuse in go/siggate.go.
29
+
30
+ import type { Val } from './type'
31
+ import { AontuContext } from './ctx'
32
+ import { makeNilErr } from './err'
33
+
34
+ import { funcSig, renderSig } from './sig'
35
+ import type { FuncSig, ArgSig } from './sig'
36
+
37
+ import {
38
+ BigDecimal,
39
+ BigInteger,
40
+ Float,
41
+ Integer,
42
+ Path,
43
+ kindSubsumes,
44
+ } from './val/ScalarKindVal'
45
+
46
+
47
+ // The scalar-kind words the gate enforces, each to its lattice
48
+ // marker. A declared type is gate-checkable only when EVERY union
49
+ // word is here: `any`, `constraint`, and the container words leave
50
+ // the argument to the builtin.
51
+ const SIG_KIND = new Map<string, any>([
52
+ ['string', String],
53
+ ['number', Number],
54
+ ['integer', Integer],
55
+ ['float', Float],
56
+ ['biginteger', BigInteger],
57
+ ['bigdecimal', BigDecimal],
58
+ ['boolean', Boolean],
59
+ ['path', Path],
60
+ ])
61
+
62
+
63
+ function gateWords(type: string): any[] | undefined {
64
+ const out: any[] = []
65
+ for (const word of type.split('|')) {
66
+ const marker = SIG_KIND.get(word)
67
+ if (undefined === marker) {
68
+ return undefined
69
+ }
70
+ out.push(marker)
71
+ }
72
+ return out
73
+ }
74
+
75
+
76
+ // The declared type admits a driven Val when the Val is a concrete
77
+ // scalar whose leaf kind is, or sits below, one of the declared
78
+ // words -- the same walk subsumption makes, so `number` admits every
79
+ // numeric leaf and `string` admits a path value.
80
+ function admits(markers: any[], arg: any): boolean {
81
+ const leaf: any = arg.superior?.()
82
+ if (true !== arg.isScalar || true !== leaf?.isScalarKind) {
83
+ return false
84
+ }
85
+ for (const marker of markers) {
86
+ if (marker === leaf.peg || kindSubsumes(marker, leaf.peg)) {
87
+ return true
88
+ }
89
+ }
90
+ return false
91
+ }
92
+
93
+
94
+ // The gate. Answers the func_arg refusal, or undefined to let the
95
+ // call resolve.
96
+ function sigRefuse(
97
+ ctx: AontuContext, fn: any, args: Val[]
98
+ ): Val | undefined {
99
+ const sig: FuncSig | undefined = funcSig[fn.funcname()]
100
+
101
+ // key() reads its level off the written peg and `key_level` names
102
+ // what is wrong with a bad one; the gate leaves the meaning where
103
+ // it lives.
104
+ if (undefined === sig || 'key' === sig.name) {
105
+ return undefined
106
+ }
107
+
108
+ for (let i = 0; i < sig.args.length; i++) {
109
+ const a: ArgSig = sig.args[i]
110
+ if (true === a.rest) {
111
+ break
112
+ }
113
+ if ('value' !== a.mode) {
114
+ continue
115
+ }
116
+ const markers = gateWords(a.type)
117
+ if (undefined === markers) {
118
+ continue
119
+ }
120
+ const arg: any = args[i]
121
+ if (undefined === arg || true === arg.isNil || true !== arg.done) {
122
+ continue
123
+ }
124
+ const shaped = (true === arg.isScalar) ||
125
+ (true === arg.isMap) || (true === arg.isList) ||
126
+ (true === arg.isScalarKind)
127
+ if (shaped && !admits(markers, arg)) {
128
+ return makeNilErr(ctx, 'func_arg', fn, arg, undefined, {
129
+ func: sig.name,
130
+ sig: renderSig(sig),
131
+ arg: a.name,
132
+ argn: '' + (i + 1),
133
+ got: arg.canon,
134
+ })
135
+ }
136
+ }
137
+
138
+ return undefined
139
+ } /* node:coverage ignore next 5 */
140
+
141
+
142
+ export {
143
+ sigRefuse,
144
+ }
package/src/site.ts CHANGED
@@ -6,12 +6,45 @@ import type {
6
6
  } from './type'
7
7
 
8
8
 
9
- type SiteSpec = { row?: number, col?: number, url?: string }
9
+ type SiteSpec = {
10
+ row?: number, col?: number, url?: string, len?: number, src?: string,
11
+ }
10
12
 
13
+ // Site locates a value in the text that produced it: where it starts
14
+ // (row, col), HOW FAR IT RUNS (len), and the source text itself (src).
15
+ //
16
+ // THE EXTENT IS NOT OPTIONAL DETAIL — it is what makes a site safe to
17
+ // edit. Without it the only length available is the CANON, and canon is
18
+ // not source text: `port: 0x1F` has canon `31`, so replacing
19
+ // `(col, canon.length)` writes `port: 5x1F` and corrupts the document.
20
+ // The parser knew the extent all along — the token carries `len` and
21
+ // `src` beside the `rI`/`cI` this already read — and dropping it was
22
+ // the whole defect (status report 2026-08-21, §5).
23
+ //
24
+ // WHAT THE EXTENT COVERS is the TOKEN THE SITE POINTS AT, which is the
25
+ // same thing row and col have always pointed at:
26
+ //
27
+ // 0x1F a scalar literal len 4 the whole literal
28
+ // "hi there" a string len 10 quotes included
29
+ // {x:1} a map len 1 the opening brace
30
+ // min(3) a constraint len 3 the name, not the call
31
+ //
32
+ // So for a SCALAR — which is what a repair edits, and what `set` and
33
+ // the manual fallback rewrite — `(col, len)` is exactly the span to
34
+ // replace. For a container it under-reaches to the opening delimiter,
35
+ // which is safe in the direction that matters: a highlight that is too
36
+ // short is a cosmetic flaw, while canon.length on a map over-reaches
37
+ // across lines into text the value never occupied.
38
+ //
39
+ // -1 and '' mean UNKNOWN, the same convention row and col already use:
40
+ // a value minted by unification rather than written by a document has
41
+ // no site, and must not be edited as though it had one.
11
42
  class Site {
12
43
  row: number
13
44
  col: number
14
45
  url: string
46
+ len: number
47
+ src: string
15
48
 
16
49
  constructor(val?: Val | SiteSpec) {
17
50
  const site = ((val as any)?.site ?? val) as SiteSpec
@@ -19,6 +52,8 @@ class Site {
19
52
  this.row = site?.row ?? -1
20
53
  this.col = site?.col ?? -1
21
54
  this.url = site?.url ?? ''
55
+ this.len = site?.len ?? -1
56
+ this.src = site?.src ?? ''
22
57
  }
23
58
  } /* node:coverage ignore next 6 */
24
59
 
package/src/std.ts ADDED
@@ -0,0 +1,131 @@
1
+ /* Copyright (c) 2025 Richard Rodger, MIT License */
2
+
3
+ // THE BUNDLED VOCABULARY (G4 phase 4,
4
+ // docs/capability-review/g4-identity-relations.md): `@"std/system"` is
5
+ // served from the engine itself — no filesystem, no package resolution
6
+ // — so a document may use it under every include capability except
7
+ // `none`, and the hermeticity posture is not widened by a source that
8
+ // never leaves the process.
9
+ //
10
+ // The TEXT is the shared artifact: go/std.go carries the same bytes,
11
+ // and test/spec/std-system.tsv pins its canon and its canon-hash in
12
+ // both engines, so the two copies cannot drift without a red suite.
13
+ // It carries no backtick for that reason: one string literal per port,
14
+ // and Go's raw string has no escape.
15
+
16
+ const STD_SYSTEM = `# std/system --- the SYSTEM VOCABULARY (G4 phase 4). Ports, components
17
+ # and relations need no syntax: they are schemas. Everything here is
18
+ # ordinary unification --- conjunction, spreads, marks, defaults ---
19
+ # so the vocabulary costs the language nothing, and an author who wants
20
+ # a different one writes it the same way.
21
+ #
22
+ # EXPERIMENTAL until the distribution layer can version it by
23
+ # canon-hash. Entity ids deliberately do NOT embed versions: fusing
24
+ # identity and version makes "v1 and v2 describe the same entity"
25
+ # inexpressible.
26
+
27
+ std: {
28
+
29
+ # One end of a connection.
30
+ Port: type({
31
+ direction: *in | out | inout
32
+ protocol?: string
33
+ })
34
+
35
+ # A node with ports. Where a Component sits in the tree is what it
36
+ # is a component OF -- containment is the document's own structure
37
+ # and needs no mark of its own.
38
+ Component: type({
39
+ ports?: {&: $.std.Port}
40
+ })
41
+
42
+ # A component that is a service. Written out rather than as
43
+ # $.std.Component & {kind: service}: a reference from one member of
44
+ # this file to another does not survive being INCLUDED into a
45
+ # document (the marks the include carries make the referring member
46
+ # unusable), so the vocabulary states each schema on its own.
47
+ Service: type({
48
+ kind: service
49
+ ports?: {&: $.std.Port}
50
+ })
51
+
52
+ # (The Relation schema that used to sit here is retired with the
53
+ # relations: magic key, RELATIONS.0.md P2: a relation is declared
54
+ # by the graph atoms at its field -- rel(t) & acyclic() &
55
+ # inverse(name) -- and the target half is rel(t)'s flow.)
56
+ }
57
+ `
58
+
59
+
60
+ const STD_VIEW = `# std/view --- the FIGURE VOCABULARY (VIEWS.0.md, "6. The view
61
+ # document"). A view document declares its figures as data, and a
62
+ # declaration is just a map: this is the schema for one, so a typo is
63
+ # refused where every other mistake in an Aontu document is refused --
64
+ # at evaluation, by unification -- rather than by the verb that reads
65
+ # it afterwards.
66
+ #
67
+ # @"std/view"
68
+ # @"./system.aon"
69
+ #
70
+ # views: {&: $.view.Figure} & {
71
+ # arch: {kind: matrix, order: partition, out: "docs/arch.dsm.txt"}
72
+ # }
73
+ #
74
+ # The keys ARE the view options: the command-line flags without the
75
+ # dashes, one vocabulary for the CLI, the library and the file. The
76
+ # poset is not among the kinds, because a view document declares
77
+ # figures of the ONE document it includes and the poset compares
78
+ # several.
79
+ #
80
+ # EXPERIMENTAL until the distribution layer can version it by
81
+ # canon-hash. This file carries no backtick: it is one string literal
82
+ # per port, and Go raw strings have no escape.
83
+
84
+ view: {
85
+
86
+ # One declared figure. The kind says what to draw and out says where
87
+ # it belongs; everything else narrows the drawing, and each option
88
+ # belongs to the kinds that read it.
89
+ Figure: type({
90
+ kind: tree | matrix | graph | layer | sets | layers | ladder
91
+ out: string
92
+
93
+ # Every kind.
94
+ as?: text | mermaid | dot | er | svg
95
+ at?: string
96
+ maxRows?: integer & min(0)
97
+
98
+ # tree, matrix, layer: the relation drawn. graph: the predicates
99
+ # kept. tree: the subtrees drawn.
100
+ relation?: string
101
+ relations?: [&: string]
102
+ roots?: [&: string]
103
+
104
+ # matrix.
105
+ order?: canon | partition
106
+ closure?: boolean
107
+
108
+ # graph, layer.
109
+ groupBy?: string
110
+ label?: string
111
+ layers?: [&: string]
112
+ edges?: upward | all | none
113
+
114
+ # sets, layers.
115
+ sets?: string
116
+ member?: string
117
+ universe?: string
118
+ minDegree?: integer & min(0)
119
+ maxCols?: integer & min(0)
120
+ minSize?: integer & min(0)
121
+ })
122
+ }
123
+ `
124
+
125
+
126
+ export const STD_SOURCES: Record<string, string> = {
127
+ 'std/system': STD_SYSTEM,
128
+ 'std/system.aon': STD_SYSTEM,
129
+ 'std/view': STD_VIEW,
130
+ 'std/view.aon': STD_VIEW,
131
+ }