aontu 0.62.0 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/README.md +7 -7
  2. package/dist/agentsmd.js +0 -27
  3. package/dist/agentsmd.js.map +1 -1
  4. package/dist/alias.js.map +1 -1
  5. package/dist/allow.js +0 -92
  6. package/dist/allow.js.map +1 -1
  7. package/dist/aontu.d.ts +3 -3
  8. package/dist/aontu.js +4 -84
  9. package/dist/aontu.js.map +1 -1
  10. package/dist/aontumodel.d.ts +4 -0
  11. package/dist/aontumodel.js +27 -0
  12. package/dist/aontumodel.js.map +1 -0
  13. package/dist/casing.d.ts +5 -0
  14. package/dist/casing.js +90 -0
  15. package/dist/casing.js.map +1 -0
  16. package/dist/cli.d.ts +2 -2
  17. package/dist/cli.js +228 -935
  18. package/dist/cli.js.map +1 -1
  19. package/dist/ctx.js +0 -48
  20. package/dist/ctx.js.map +1 -1
  21. package/dist/diff.js +0 -32
  22. package/dist/diff.js.map +1 -1
  23. package/dist/err.js +0 -40
  24. package/dist/err.js.map +1 -1
  25. package/dist/escape.js +0 -45
  26. package/dist/escape.js.map +1 -1
  27. package/dist/exactjson.d.ts +0 -35
  28. package/dist/exactjson.js +0 -131
  29. package/dist/exactjson.js.map +1 -1
  30. package/dist/format.js +13 -203
  31. package/dist/format.js.map +1 -1
  32. package/dist/grammar.d.ts +9 -0
  33. package/dist/grammar.js +54 -0
  34. package/dist/grammar.js.map +1 -0
  35. package/dist/graph.js +0 -26
  36. package/dist/graph.js.map +1 -1
  37. package/dist/hcanon.js +0 -82
  38. package/dist/hcanon.js.map +1 -1
  39. package/dist/helpdoc.js +2 -2
  40. package/dist/helpdoc.js.map +1 -1
  41. package/dist/hints.d.ts +0 -6
  42. package/dist/hints.js +57 -55
  43. package/dist/hints.js.map +1 -1
  44. package/dist/jsonschema.js +0 -114
  45. package/dist/jsonschema.js.map +1 -1
  46. package/dist/keyorder.d.ts +0 -7
  47. package/dist/keyorder.js +0 -41
  48. package/dist/keyorder.js.map +1 -1
  49. package/dist/lang.js +17 -915
  50. package/dist/lang.js.map +1 -1
  51. package/dist/lsp-server.js +0 -16
  52. package/dist/lsp-server.js.map +1 -1
  53. package/dist/lsp.d.ts +1 -1
  54. package/dist/lsp.js +12 -159
  55. package/dist/lsp.js.map +1 -1
  56. package/dist/mcp-server.js +0 -26
  57. package/dist/mcp-server.js.map +1 -1
  58. package/dist/mcp.js +0 -149
  59. package/dist/mcp.js.map +1 -1
  60. package/dist/mod-tool.js +16 -131
  61. package/dist/mod-tool.js.map +1 -1
  62. package/dist/mod.js +0 -162
  63. package/dist/mod.js.map +1 -1
  64. package/dist/patch.js +0 -217
  65. package/dist/patch.js.map +1 -1
  66. package/dist/profile.d.ts +9 -0
  67. package/dist/profile.js +28 -0
  68. package/dist/profile.js.map +1 -0
  69. package/dist/provenance.js +0 -140
  70. package/dist/provenance.js.map +1 -1
  71. package/dist/query.js +0 -75
  72. package/dist/query.js.map +1 -1
  73. package/dist/reach.js +0 -43
  74. package/dist/reach.js.map +1 -1
  75. package/dist/relation.js +0 -61
  76. package/dist/relation.js.map +1 -1
  77. package/dist/report-sarif.d.ts +0 -11
  78. package/dist/report-sarif.js +0 -28
  79. package/dist/report-sarif.js.map +1 -1
  80. package/dist/sig.js +0 -35
  81. package/dist/sig.js.map +1 -1
  82. package/dist/sigdecl.js +1 -1
  83. package/dist/sigdecl.js.map +1 -1
  84. package/dist/siggate.js +0 -4
  85. package/dist/siggate.js.map +1 -1
  86. package/dist/site.js +3 -29
  87. package/dist/site.js.map +1 -1
  88. package/dist/subsume.d.ts +0 -10
  89. package/dist/subsume.js +0 -137
  90. package/dist/subsume.js.map +1 -1
  91. package/dist/template.d.ts +2 -1
  92. package/dist/template.js +58 -138
  93. package/dist/template.js.map +1 -1
  94. package/dist/trace.d.ts +21 -0
  95. package/dist/trace.js +107 -0
  96. package/dist/trace.js.map +1 -0
  97. package/dist/trim.js +0 -41
  98. package/dist/trim.js.map +1 -1
  99. package/dist/tsconfig.tsbuildinfo +1 -1
  100. package/dist/type.js.map +1 -1
  101. package/dist/unify.js +13 -248
  102. package/dist/unify.js.map +1 -1
  103. package/dist/utility.js +0 -22
  104. package/dist/utility.js.map +1 -1
  105. package/dist/val/AbnfFuncVal.d.ts +18 -0
  106. package/dist/val/AbnfFuncVal.js +132 -0
  107. package/dist/val/AbnfFuncVal.js.map +1 -0
  108. package/dist/val/AbsentVal.d.ts +11 -0
  109. package/dist/val/AbsentVal.js +30 -0
  110. package/dist/val/AbsentVal.js.map +1 -0
  111. package/dist/val/AggFuncVal.d.ts +10 -1
  112. package/dist/val/AggFuncVal.js +104 -116
  113. package/dist/val/AggFuncVal.js.map +1 -1
  114. package/dist/val/ArithFuncVal.js +0 -12
  115. package/dist/val/ArithFuncVal.js.map +1 -1
  116. package/dist/val/BagVal.js +1 -78
  117. package/dist/val/BagVal.js.map +1 -1
  118. package/dist/val/BigDecimalVal.js +0 -16
  119. package/dist/val/BigDecimalVal.js.map +1 -1
  120. package/dist/val/BigIntegerVal.js +0 -16
  121. package/dist/val/BigIntegerVal.js.map +1 -1
  122. package/dist/val/CloseFuncVal.js +0 -9
  123. package/dist/val/CloseFuncVal.js.map +1 -1
  124. package/dist/val/CmpFuncVal.d.ts +2 -0
  125. package/dist/val/CmpFuncVal.js +49 -72
  126. package/dist/val/CmpFuncVal.js.map +1 -1
  127. package/dist/val/ConjunctVal.js +0 -29
  128. package/dist/val/ConjunctVal.js.map +1 -1
  129. package/dist/val/ConstraintVal.js +0 -500
  130. package/dist/val/ConstraintVal.js.map +1 -1
  131. package/dist/val/ContainerKindVal.js +0 -2
  132. package/dist/val/ContainerKindVal.js.map +1 -1
  133. package/dist/val/CopyFuncVal.js +0 -3
  134. package/dist/val/CopyFuncVal.js.map +1 -1
  135. package/dist/val/Decimal.js +0 -179
  136. package/dist/val/Decimal.js.map +1 -1
  137. package/dist/val/DeprecateFuncVal.js.map +1 -1
  138. package/dist/val/DisjunctVal.js +0 -152
  139. package/dist/val/DisjunctVal.js.map +1 -1
  140. package/dist/val/EachFuncVal.js +0 -3
  141. package/dist/val/EachFuncVal.js.map +1 -1
  142. package/dist/val/EmitFuncVal.d.ts +1 -1
  143. package/dist/val/EmitFuncVal.js +6 -119
  144. package/dist/val/EmitFuncVal.js.map +1 -1
  145. package/dist/val/ExpectVal.js +0 -62
  146. package/dist/val/ExpectVal.js.map +1 -1
  147. package/dist/val/FilterFuncVal.js +0 -25
  148. package/dist/val/FilterFuncVal.js.map +1 -1
  149. package/dist/val/FuncBaseVal.d.ts +1 -0
  150. package/dist/val/FuncBaseVal.js +7 -127
  151. package/dist/val/FuncBaseVal.js.map +1 -1
  152. package/dist/val/GraphAtomVal.js +0 -15
  153. package/dist/val/GraphAtomVal.js.map +1 -1
  154. package/dist/val/HideFuncVal.js +0 -13
  155. package/dist/val/HideFuncVal.js.map +1 -1
  156. package/dist/val/IntegerVal.js +0 -61
  157. package/dist/val/IntegerVal.js.map +1 -1
  158. package/dist/val/JunctionVal.js +0 -20
  159. package/dist/val/JunctionVal.js.map +1 -1
  160. package/dist/val/KeyFuncVal.js +0 -46
  161. package/dist/val/KeyFuncVal.js.map +1 -1
  162. package/dist/val/ListVal.js +0 -57
  163. package/dist/val/ListVal.js.map +1 -1
  164. package/dist/val/LowerFuncVal.js +0 -11
  165. package/dist/val/LowerFuncVal.js.map +1 -1
  166. package/dist/val/MapVal.js +0 -151
  167. package/dist/val/MapVal.js.map +1 -1
  168. package/dist/val/MatchFuncVal.js +0 -27
  169. package/dist/val/MatchFuncVal.js.map +1 -1
  170. package/dist/val/{FormFuncVal.d.ts → MaybeFuncVal.d.ts} +5 -5
  171. package/dist/val/MaybeFuncVal.js +50 -0
  172. package/dist/val/MaybeFuncVal.js.map +1 -0
  173. package/dist/val/MoveFuncVal.js +0 -18
  174. package/dist/val/MoveFuncVal.js.map +1 -1
  175. package/dist/val/NilVal.js +0 -60
  176. package/dist/val/NilVal.js.map +1 -1
  177. package/dist/val/NomFuncVal.js +18 -54
  178. package/dist/val/NomFuncVal.js.map +1 -1
  179. package/dist/val/NumberVal.js +0 -15
  180. package/dist/val/NumberVal.js.map +1 -1
  181. package/dist/val/OpBaseVal.d.ts +1 -0
  182. package/dist/val/OpBaseVal.js +3 -15
  183. package/dist/val/OpBaseVal.js.map +1 -1
  184. package/dist/val/PackFuncVal.js +0 -34
  185. package/dist/val/PackFuncVal.js.map +1 -1
  186. package/dist/val/PathFuncVal.js +0 -6
  187. package/dist/val/PathFuncVal.js.map +1 -1
  188. package/dist/val/PathVal.js +0 -41
  189. package/dist/val/PathVal.js.map +1 -1
  190. package/dist/val/PlaceVal.js +0 -25
  191. package/dist/val/PlaceVal.js.map +1 -1
  192. package/dist/val/PlusOpVal.d.ts +1 -7
  193. package/dist/val/PlusOpVal.js +13 -74
  194. package/dist/val/PlusOpVal.js.map +1 -1
  195. package/dist/val/PrefFuncVal.js +0 -1
  196. package/dist/val/PrefFuncVal.js.map +1 -1
  197. package/dist/val/PrefVal.js +0 -167
  198. package/dist/val/PrefVal.js.map +1 -1
  199. package/dist/val/RecurseVal.js +0 -55
  200. package/dist/val/RecurseVal.js.map +1 -1
  201. package/dist/val/RefVal.js +0 -282
  202. package/dist/val/RefVal.js.map +1 -1
  203. package/dist/val/ReferFuncVal.js +3 -232
  204. package/dist/val/ReferFuncVal.js.map +1 -1
  205. package/dist/val/ScalarKindVal.js +0 -49
  206. package/dist/val/ScalarKindVal.js.map +1 -1
  207. package/dist/val/ScalarVal.js +0 -11
  208. package/dist/val/ScalarVal.js.map +1 -1
  209. package/dist/val/StrFuncVal.js +0 -18
  210. package/dist/val/StrFuncVal.js.map +1 -1
  211. package/dist/val/SuperFuncVal.js +0 -32
  212. package/dist/val/SuperFuncVal.js.map +1 -1
  213. package/dist/val/TopVal.js +0 -1
  214. package/dist/val/TopVal.js.map +1 -1
  215. package/dist/val/TranslateFuncVal.js +1 -3
  216. package/dist/val/TranslateFuncVal.js.map +1 -1
  217. package/dist/val/UpperFuncVal.js +0 -11
  218. package/dist/val/UpperFuncVal.js.map +1 -1
  219. package/dist/val/Val.d.ts +1 -0
  220. package/dist/val/Val.js +2 -133
  221. package/dist/val/Val.js.map +1 -1
  222. package/dist/val/VarVal.js +0 -12
  223. package/dist/val/VarVal.js.map +1 -1
  224. package/dist/val/arith.js +0 -37
  225. package/dist/val/arith.js.map +1 -1
  226. package/dist/val/caserange.js +0 -61
  227. package/dist/val/caserange.js.map +1 -1
  228. package/dist/val/members.js +0 -6
  229. package/dist/val/members.js.map +1 -1
  230. package/dist/val/numcmp.js +0 -11
  231. package/dist/val/numcmp.js.map +1 -1
  232. package/dist/val/numkind.js +0 -145
  233. package/dist/val/numkind.js.map +1 -1
  234. package/dist/val/valutil.js +0 -16
  235. package/dist/val/valutil.js.map +1 -1
  236. package/dist/vet.js +0 -461
  237. package/dist/vet.js.map +1 -1
  238. package/dist/view.js +0 -414
  239. package/dist/view.js.map +1 -1
  240. package/dist/walk.js +0 -41
  241. package/dist/walk.js.map +1 -1
  242. package/grammar/aontu.abnf +8 -6
  243. package/grammar/aontu.gbnf +4 -4
  244. package/grammar/aontu.lark +4 -4
  245. package/grammar/aontu.tmLanguage.json +1 -1
  246. package/package.json +4 -2
  247. package/skill/tasks.md +9 -7
  248. package/src/agentsmd.ts +0 -35
  249. package/src/alias.ts +0 -39
  250. package/src/allow.ts +1 -96
  251. package/src/aontu.ts +4 -116
  252. package/src/aontumodel.ts +26 -0
  253. package/src/casing.ts +95 -0
  254. package/src/cli.ts +258 -1024
  255. package/src/ctx.ts +0 -103
  256. package/src/diff.ts +0 -40
  257. package/src/err.ts +0 -40
  258. package/src/escape.ts +0 -46
  259. package/src/exactjson.ts +0 -131
  260. package/src/format.ts +14 -257
  261. package/src/grammar.ts +72 -0
  262. package/src/graph.ts +0 -61
  263. package/src/hcanon.ts +0 -82
  264. package/src/helpdoc.ts +2 -2
  265. package/src/hints.ts +69 -57
  266. package/src/jsonschema.ts +0 -123
  267. package/src/keyorder.ts +0 -42
  268. package/src/lang.ts +19 -931
  269. package/src/lsp-server.ts +0 -16
  270. package/src/lsp.ts +12 -180
  271. package/src/mcp-server.ts +0 -31
  272. package/src/mcp.ts +0 -169
  273. package/src/mod-tool.ts +18 -159
  274. package/src/mod.ts +0 -178
  275. package/src/patch.ts +0 -232
  276. package/src/profile.ts +42 -0
  277. package/src/provenance.ts +0 -183
  278. package/src/query.ts +0 -84
  279. package/src/reach.ts +0 -53
  280. package/src/relation.ts +0 -84
  281. package/src/report-sarif.ts +0 -48
  282. package/src/sig.ts +0 -35
  283. package/src/sigdecl.ts +1 -1
  284. package/src/siggate.ts +0 -30
  285. package/src/site.ts +3 -29
  286. package/src/subsume.ts +1 -161
  287. package/src/template.ts +69 -140
  288. package/src/trace.ts +157 -0
  289. package/src/trim.ts +0 -53
  290. package/src/type.ts +2 -45
  291. package/src/unify.ts +14 -257
  292. package/src/utility.ts +0 -31
  293. package/src/val/AbnfFuncVal.ts +181 -0
  294. package/src/val/AbsentVal.ts +54 -0
  295. package/src/val/AggFuncVal.ts +152 -188
  296. package/src/val/ArithFuncVal.ts +0 -20
  297. package/src/val/BagVal.ts +1 -78
  298. package/src/val/BigDecimalVal.ts +0 -16
  299. package/src/val/BigIntegerVal.ts +0 -16
  300. package/src/val/CloseFuncVal.ts +0 -9
  301. package/src/val/CmpFuncVal.ts +68 -184
  302. package/src/val/ConjunctVal.ts +0 -33
  303. package/src/val/ConstraintVal.ts +2 -537
  304. package/src/val/ContainerKindVal.ts +0 -18
  305. package/src/val/CopyFuncVal.ts +0 -5
  306. package/src/val/Decimal.ts +1 -185
  307. package/src/val/DeprecateFuncVal.ts +0 -10
  308. package/src/val/DisjunctVal.ts +0 -157
  309. package/src/val/EachFuncVal.ts +0 -40
  310. package/src/val/EmitFuncVal.ts +8 -208
  311. package/src/val/ExpectVal.ts +0 -62
  312. package/src/val/FilterFuncVal.ts +0 -55
  313. package/src/val/FuncBaseVal.ts +9 -130
  314. package/src/val/GraphAtomVal.ts +0 -42
  315. package/src/val/HideFuncVal.ts +0 -15
  316. package/src/val/IntegerVal.ts +0 -61
  317. package/src/val/JunctionVal.ts +0 -20
  318. package/src/val/KeyFuncVal.ts +0 -48
  319. package/src/val/ListVal.ts +0 -59
  320. package/src/val/LowerFuncVal.ts +0 -12
  321. package/src/val/MapVal.ts +0 -151
  322. package/src/val/MatchFuncVal.ts +0 -59
  323. package/src/val/MaybeFuncVal.ts +86 -0
  324. package/src/val/MoveFuncVal.ts +0 -20
  325. package/src/val/NilVal.ts +0 -60
  326. package/src/val/NomFuncVal.ts +10 -99
  327. package/src/val/NumberVal.ts +0 -16
  328. package/src/val/OpBaseVal.ts +4 -17
  329. package/src/val/PackFuncVal.ts +0 -63
  330. package/src/val/PathFuncVal.ts +0 -32
  331. package/src/val/PathVal.ts +0 -66
  332. package/src/val/PlaceVal.ts +0 -45
  333. package/src/val/PlusOpVal.ts +18 -75
  334. package/src/val/PrefFuncVal.ts +0 -1
  335. package/src/val/PrefVal.ts +0 -179
  336. package/src/val/RecurseVal.ts +0 -81
  337. package/src/val/RefVal.ts +1 -285
  338. package/src/val/ReferFuncVal.ts +4 -255
  339. package/src/val/ScalarKindVal.ts +0 -50
  340. package/src/val/ScalarVal.ts +0 -12
  341. package/src/val/StrFuncVal.ts +0 -44
  342. package/src/val/SuperFuncVal.ts +0 -42
  343. package/src/val/TopVal.ts +0 -1
  344. package/src/val/TranslateFuncVal.ts +1 -51
  345. package/src/val/UpperFuncVal.ts +0 -12
  346. package/src/val/Val.ts +3 -192
  347. package/src/val/VarVal.ts +0 -15
  348. package/src/val/arith.ts +0 -92
  349. package/src/val/caserange.ts +0 -62
  350. package/src/val/members.ts +0 -23
  351. package/src/val/numcmp.ts +1 -27
  352. package/src/val/numkind.ts +0 -149
  353. package/src/val/valutil.ts +0 -16
  354. package/src/vet.ts +1 -582
  355. package/src/view.ts +0 -507
  356. package/src/walk.ts +0 -41
  357. package/dist/lower.d.ts +0 -23
  358. package/dist/lower.js +0 -578
  359. package/dist/lower.js.map +0 -1
  360. package/dist/render.d.ts +0 -53
  361. package/dist/render.js +0 -547
  362. package/dist/render.js.map +0 -1
  363. package/dist/std.d.ts +0 -3
  364. package/dist/std.js +0 -672
  365. package/dist/std.js.map +0 -1
  366. package/dist/val/FormFuncVal.js +0 -55
  367. package/dist/val/FormFuncVal.js.map +0 -1
  368. package/dist/val/NamerFuncVal.d.ts +0 -12
  369. package/dist/val/NamerFuncVal.js +0 -176
  370. package/dist/val/NamerFuncVal.js.map +0 -1
  371. package/src/lower.ts +0 -636
  372. package/src/render.ts +0 -732
  373. package/src/std.ts +0 -683
@@ -0,0 +1,181 @@
1
+ /* Copyright (c) 2026 Richard Rodger, MIT License */
2
+
3
+ // The grammar pair, ADR-033. Twin of go/abnf.go.
4
+
5
+ import type { Val, ValSpec } from '../type'
6
+ import { DONE } from '../type'
7
+ import { AontuContext } from '../ctx'
8
+ import { FuncBaseVal } from './FuncBaseVal'
9
+ import { StringVal } from './StringVal'
10
+ import { MapVal } from './MapVal'
11
+ import { ListVal } from './ListVal'
12
+ import { ConjunctVal } from './ConjunctVal'
13
+ import { makeNilErr } from '../err'
14
+ import { compileGrammar, parseWith } from '../grammar'
15
+
16
+
17
+ class AbnfFuncVal extends FuncBaseVal {
18
+ isAbnfFunc = true
19
+
20
+ constructor(spec: ValSpec, ctx?: AontuContext) {
21
+ super(spec, ctx)
22
+ }
23
+
24
+ funcname() {
25
+ return 'abnf'
26
+ }
27
+
28
+ resolve(ctx: AontuContext, args: Val[]): Val {
29
+ const a: any = args[0]
30
+
31
+ // Not an arity check: the arity and signature gates run first, so
32
+ // what reaches here is a nil argument, which both pass over.
33
+ if ('string' !== typeof a?.peg) {
34
+ return this.place(makeNilErr(ctx, 'abnf_grammar', this, undefined,
35
+ 'abnf'))
36
+ }
37
+
38
+ const [, why] = compileGrammar(a.peg)
39
+ if (undefined !== why) {
40
+ return this.place(makeNilErr(ctx, 'abnf_grammar', this, undefined,
41
+ 'abnf', { reason: why }))
42
+ }
43
+
44
+ return this.place(new StringVal({ peg: a.peg }, ctx))
45
+ }
46
+ }
47
+
48
+
49
+ // A tree node is just the map {rule, src, kids}, so it needs no case of
50
+ // its own. Keys are sorted so both ports build the same member order.
51
+ function astVal(node: any, ctx: AontuContext): Val {
52
+ if ('string' === typeof node) {
53
+ return new StringVal({ peg: node }, ctx)
54
+ }
55
+
56
+ if (Array.isArray(node)) {
57
+ return new ListVal({
58
+ peg: node.map(
59
+ (e: any, i: number) => astVal(e, ctx.descend(String(i)))),
60
+ }, ctx)
61
+ }
62
+
63
+ const peg: Record<string, Val> = {}
64
+ for (const k of Object.keys(node).sort()) {
65
+ peg[k] = astVal(node[k], ctx.descend(k))
66
+ }
67
+ return new MapVal({ peg }, ctx)
68
+ }
69
+
70
+
71
+ class ParseFuncVal extends FuncBaseVal {
72
+ isParseFunc = true
73
+
74
+ constructor(spec: ValSpec, ctx?: AontuContext) {
75
+ super(spec, ctx)
76
+ }
77
+
78
+ funcname() {
79
+ return 'parse'
80
+ }
81
+
82
+
83
+ // Meets its peer instead of resolving, so it must see the peer
84
+ // before the base drives to resolve().
85
+ unify(peer: Val, ctx: AontuContext): Val {
86
+ if (1 !== this.peg.length) {
87
+ return super.unify(peer, ctx)
88
+ }
89
+
90
+ this.driveStagedArgs(ctx, 1)
91
+
92
+ const g: any = this.peg[0]
93
+ if ('string' !== typeof g?.peg) {
94
+ return this.residuate(peer, ctx)
95
+ }
96
+
97
+ // A settled constraint is stable, as a residual constraint atom is.
98
+ // Without this a `type()` holding one never resolves.
99
+ this.dc = DONE
100
+
101
+ const p: any = peer
102
+ if (true !== p?.isString || 'string' !== typeof p?.peg) {
103
+ return this.hold(peer, ctx)
104
+ }
105
+
106
+ const [grammar, why] = compileGrammar(g.peg)
107
+ if (undefined !== why) {
108
+ return makeNilErr(ctx, 'abnf_grammar', this, peer, 'parse',
109
+ { reason: why })
110
+ }
111
+ if ('' === p.peg) {
112
+ return makeNilErr(ctx, 'parse_failed', this, peer, 'parse',
113
+ { reason: 'the empty string parses under no grammar' })
114
+ }
115
+ const [, err] = parseWith(grammar, p.peg, ctx)
116
+ if (undefined !== err) {
117
+ return makeNilErr(ctx, 'parse_failed', this, peer, 'parse',
118
+ { reason: err })
119
+ }
120
+
121
+ return peer
122
+ }
123
+
124
+
125
+ // The stable twin of residuate: no `notdone()`, because a settled
126
+ // constraint stays done while it waits for a value.
127
+ hold(peer: Val, ctx: AontuContext): Val {
128
+ if (peer.isTop || peer.id === this.id) {
129
+ // Cloned, or a driver meeting it twice reports `unify_cycle`.
130
+ const out: Val = this.clone(ctx)
131
+ out.dc = DONE
132
+ return out
133
+ }
134
+
135
+ if (peer.isFunc
136
+ && (peer as any).funcname() === this.funcname()
137
+ && peer.path.join('.') === this.path.join('.')
138
+ && peer.canon === this.canon) {
139
+ return this
140
+ }
141
+
142
+ return new ConjunctVal({ peg: [this, peer] }, ctx)
143
+ }
144
+
145
+
146
+ resolve(ctx: AontuContext, args: Val[]): Val {
147
+ const g: any = args[0]
148
+ const v: any = args[1]
149
+
150
+ // Not an arity check: see the abnf twin above.
151
+ if ('string' !== typeof g?.peg || 'string' !== typeof v?.peg) {
152
+ return this.place(makeNilErr(ctx, 'parse_arg', this, undefined, 'parse'))
153
+ }
154
+
155
+ const [grammar, why] = compileGrammar(g.peg)
156
+ if (undefined !== why) {
157
+ return this.place(makeNilErr(ctx, 'abnf_grammar', this, undefined,
158
+ 'parse', { reason: why }))
159
+ }
160
+
161
+ // The host answers an empty tree for empty input.
162
+ if ('' === v.peg) {
163
+ return this.place(makeNilErr(ctx, 'parse_failed', this, undefined,
164
+ 'parse', { reason: 'the empty string parses under no grammar' }))
165
+ }
166
+
167
+ const [node, err] = parseWith(grammar, v.peg, ctx)
168
+ if (undefined !== err) {
169
+ return this.place(makeNilErr(ctx, 'parse_failed', this, undefined,
170
+ 'parse', { reason: err }))
171
+ }
172
+
173
+ return this.place(astVal(node, ctx))
174
+ }
175
+ } /* node:coverage ignore next 6 */
176
+
177
+
178
+ export {
179
+ AbnfFuncVal,
180
+ ParseFuncVal,
181
+ }
@@ -0,0 +1,54 @@
1
+ /* Copyright (c) 2026 Richard Rodger, MIT License */
2
+
3
+
4
+ import type {
5
+ Val,
6
+ ValSpec,
7
+ } from '../type'
8
+
9
+ import {
10
+ DONE,
11
+ } from '../type'
12
+
13
+ import {
14
+ AontuContext,
15
+ } from '../ctx'
16
+
17
+ import { FeatureVal } from './FeatureVal'
18
+
19
+
20
+ // Top with one difference (ADR-034): absence is GENERABLE, and
21
+ // generates nothing, so a bag drops it at a required key too.
22
+ class AbsentVal extends FeatureVal {
23
+ isAbsent = true
24
+
25
+ constructor(
26
+ spec: ValSpec,
27
+ ctx?: AontuContext
28
+ ) {
29
+ super(spec, ctx)
30
+ this.dc = DONE
31
+ this.mark.type = false
32
+ this.mark.hide = false
33
+ }
34
+
35
+ // The unit of the meet, called for EITHER operand so `&` commutes.
36
+ // Nothing here meets an absence with TOP, so there is no top arm;
37
+ // Go has one because it MEETS an op's result where this port places
38
+ // it. edge-plus-list-absent guards the day that changes.
39
+ unify(peer: Val, _ctx: AontuContext): Val {
40
+ return peer
41
+ }
42
+
43
+ get canon() { return 'maybe()' }
44
+
45
+ gen(_ctx?: AontuContext) {
46
+ return undefined
47
+ }
48
+
49
+ } /* node:coverage ignore next 6 */
50
+
51
+
52
+ export {
53
+ AbsentVal,
54
+ }
@@ -1,47 +1,5 @@
1
1
  /* Copyright (c) 2025 Richard Rodger, MIT License */
2
2
 
3
- // AGGREGATION, PROJECTION AND THE STRING FOLD: `sum(d)`, `least(d)`,
4
- // `greatest(d)`, `pick(d, k)` and `join(d, sep?)`.
5
- //
6
- // The review's finding I: "No aggregation. `length()` counts but
7
- // nothing sums: an invoice total, a fleet-wide resource budget, a quota
8
- // roll-up -- all inexpressible." Use case 10 had to write totals by
9
- // hand and spot-check them with `must()`, which is a model asserting
10
- // what it should be able to COMPUTE.
11
- //
12
- // total: sum($.lines) # an invoice total
13
- // cheapest: least($.quotes) # ... and the extremes
14
- // peak: greatest($.hourly)
15
- //
16
- // A FOLD OVER A FINITE, SETTLED BAG IS AS TOTAL AS `each`. There is no
17
- // recursion here and no user-supplied step: the bag is the one the
18
- // model already holds, the operation is fixed, and the walk visits each
19
- // child exactly once. That is the whole reason these are built-ins
20
- // rather than a `fold` combinator -- a fold takes a function, and a
21
- // language with no user functions has none to take.
22
- //
23
- // THE NAMES ARE `least` AND `greatest`, NOT `min` AND `max`, because
24
- // those two are already the constraint atoms for a LOWER and UPPER
25
- // BOUND (`min(3)` means "at least 3"). An aggregate over a bag and a
26
- // bound on a value are different things and must not share a spelling;
27
- // least and greatest are the lattice's own words for the extremes of a
28
- // set, which is exactly what these compute.
29
- //
30
- // `sum` FOLDS WITH `add`, so the number tower's whole law comes with it
31
- // (arith.ts): the exact ladder, R5 contagion, the refusal to mix a
32
- // binary float with an exact leaf, and the refusal to store a result
33
- // that will not fit. A bag of integers sums to an integer; one integer
34
- // float among them makes the total a float; `0d` operands keep it
35
- // exact. And `sum([])` is `0` -- addition has an identity, which is
36
- // what makes the empty case answerable.
37
- //
38
- // `least`/`greatest` have NO identity to answer an empty bag with: the
39
- // least element of nothing is not a value, it is a question with no
40
- // answer, so an empty bag is a located `aggregate_empty` rather than an
41
- // invented zero or infinity. They compare with the tower's EXACT
42
- // comparator (numcmp), so an integer and a bigdecimal in one bag order
43
- // correctly rather than through binary64, and the winner is returned
44
- // with its own kind intact.
45
3
 
46
4
  import type {
47
5
  Val,
@@ -59,6 +17,7 @@ import { StringVal } from './StringVal'
59
17
  import { FuncBaseVal } from './FuncBaseVal'
60
18
  import { arith } from './arith'
61
19
  import { cmpNumeric } from './numcmp'
20
+ import { cmpCodePoint } from '../keyorder'
62
21
  import { memberVals } from './members'
63
22
  import { plusText } from './PlusOpVal'
64
23
 
@@ -66,12 +25,6 @@ import { plusText } from './PlusOpVal'
66
25
  type AggOp = 'sum' | 'least' | 'greatest'
67
26
 
68
27
 
69
- // The children of a bag, in the order the aggregate sees them: source
70
- // order for a list, sorted-key order for a map -- `each`'s order, and
71
- // for the same reason (a map has no order of its own, so the language
72
- // picks one and states it).
73
- // The members of the bag a fold reads: what generation would emit
74
- // (./members.ts, BUGS.md §79), in the one map-key order (BUGS.md §62).
75
28
  function bagChildren(data: any, ctx: AontuContext): Val[] | undefined {
76
29
  return memberVals(data, ctx)
77
30
  }
@@ -80,9 +33,6 @@ function bagChildren(data: any, ctx: AontuContext): Val[] | undefined {
80
33
  class AggFuncVal extends FuncBaseVal {
81
34
  isAggFunc = true
82
35
 
83
- // THE STAGING RULE (G8 phase 0). A total over a bag that is still
84
- // being merged into is a total of the wrong bag -- the same reason
85
- // `filter` and `each` wait.
86
36
  staged = true
87
37
 
88
38
  op: AggOp
@@ -97,21 +47,11 @@ class AggFuncVal extends FuncBaseVal {
97
47
  }
98
48
 
99
49
 
100
- // NO `make` OVERRIDE, matching the other STAGED funcs (pack, each,
101
- // filter, match): a staged call returns `residuate` before `unify`
102
- // ever reaches the rebuild branch, so an override there would be
103
- // unreachable code pretending to be a contract. The base's `make`
104
- // raises `func:<name>` if that ever stops being true, which is the
105
- // loud answer rather than a value that silently lost its operation.
106
-
107
50
  funcname() {
108
51
  return this.op
109
52
  }
110
53
 
111
54
 
112
- // The base does not drive the argument: `unify` drives it by hand,
113
- // because a staged func must advance what it is waiting on every
114
- // pass rather than only on the pass it fires.
115
55
  prepare(_ctx: AontuContext, _args: Val[]) {
116
56
  return null
117
57
  }
@@ -137,9 +77,6 @@ class AggFuncVal extends FuncBaseVal {
137
77
  }
138
78
 
139
79
  if ('sum' === this.op) {
140
- // Zero is addition's identity, so an empty bag has an answer and
141
- // it is an integer -- the narrowest kind, which the first real
142
- // operand then widens under R5 exactly as `add(0, x)` would.
143
80
  let total: Val = new IntegerVal({ peg: 0 })
144
81
  for (const child of children) {
145
82
  total = arith(ctx, 'add', this, total, child, this.op)
@@ -192,28 +129,6 @@ function unpref(v: any): any {
192
129
  }
193
130
 
194
131
 
195
- // PROJECTION: `pick(d, k)` -- one element per child of `d`, being that
196
- // child's `k`.
197
- //
198
- // The other half of the review's finding I: "`_.field` is unspellable,
199
- // `filter` cannot see into lists, `unique()`-by-field is reserved but
200
- // absent -- so 'no two services share a port' and 'unique event ids'
201
- // cannot be said." Without it the aggregates above cannot reach the
202
- // case that motivated them, because `sum` needs a bag of NUMBERS and a
203
- // model holds a bag of RECORDS:
204
- //
205
- // total: sum(pick($.lines, amountCents))
206
- //
207
- // IT IS NOT `each` WITH A CLEVER TEMPLATE. `each(d, _ & t)` MEETS each
208
- // child with `t`, and a meet cannot select: `each($.lines, _ & _.amount)`
209
- // asks for a child that is simultaneously the whole record and one of
210
- // its fields, which is why every spelling of it answers `no_path`.
211
- // Selection is a different operation and gets its own verb.
212
- //
213
- // A CHILD MISSING THE KEY IS AN ERROR, not a silently shorter list.
214
- // Skipping would make `sum(pick(...))` quietly total the wrong set of
215
- // records -- the failure mode an aggregate exists to prevent -- so the
216
- // refusal names the child (`pick_key`).
217
132
  class PickFuncVal extends FuncBaseVal {
218
133
  isPickFunc = true
219
134
 
@@ -293,56 +208,159 @@ class PickFuncVal extends FuncBaseVal {
293
208
  }
294
209
 
295
210
 
211
+ // `pick`'s rule, plus: the empty string is the member itself, which is
212
+ // how a keyless descending sort is spelled.
213
+ function projectorName(key: any): [string, boolean] {
214
+ if (null == key || null == key.peg) {
215
+ return ['', true]
216
+ }
217
+ if ('string' === typeof key.peg) {
218
+ return [key.peg, true]
219
+ }
220
+ if ('number' === typeof key.peg && key.isInteger) {
221
+ return [String(key.peg), true]
222
+ }
223
+ return ['', false]
224
+ }
225
+
226
+
227
+ function fieldOf(child: any, name: string): Val | undefined {
228
+ return true === child?.isMap ? child.peg[name] :
229
+ true === child?.isList ? child.peg[Number(name)] :
230
+ undefined
231
+ }
232
+
233
+
234
+ const SORT_DIRECTIONS: Record<string, number> = { asc: 1, desc: -1 }
235
+
236
+
237
+ function directionOf(v: any): number | undefined {
238
+ if (null == v || null == v.peg) {
239
+ return 1
240
+ }
241
+ return 'string' === typeof v.peg ? SORT_DIRECTIONS[v.peg] : undefined
242
+ }
243
+
244
+
245
+ // Text by code point, numbers by the exact comparator, nothing else.
246
+ function sortDomain(u: any): 'text' | 'number' | undefined {
247
+ if (true !== u?.isVal || true !== u.isScalar || true === u.isNull) {
248
+ return undefined
249
+ }
250
+ if ('string' === typeof u.peg) {
251
+ return 'text'
252
+ }
253
+ return 'boolean' === typeof u.peg ? undefined : 'number'
254
+ }
255
+
256
+
257
+ type SortRow = { idx: number, val: Val, key: any }
258
+
259
+
260
+ class SortFuncVal extends FuncBaseVal {
261
+ isSortFunc = true
262
+
263
+ // The bag must settle before it is ordered, exactly as it must
264
+ // before it is projected.
265
+ staged = true
266
+
267
+ constructor(
268
+ spec: ValSpec,
269
+ ctx?: AontuContext
270
+ ) {
271
+ super(spec, ctx)
272
+ }
273
+
274
+
275
+ funcname() {
276
+ return 'sort'
277
+ }
278
+
279
+
280
+ // The base drives no argument: the DATA is driven by hand below, and
281
+ // the projector is a bare word the parser has already made a string.
282
+ prepare(_ctx: AontuContext, _args: Val[]) {
283
+ return null
284
+ }
285
+
286
+
287
+ unify(peer: Val, ctx: AontuContext): Val {
288
+ const ready = this.driveStagedArgs(ctx, 1)
289
+
290
+ if (!ready || !ctx.settle) {
291
+ return this.residuate(peer, ctx)
292
+ }
293
+
294
+ return super.unify(peer, ctx)
295
+ }
296
+
297
+
298
+ resolve(ctx: AontuContext, args: Val[]) {
299
+ const children = bagChildren(args?.[0], ctx)
300
+
301
+ if (undefined === children) {
302
+ return this.place(makeNilErr(ctx, 'aggregate_data', this, undefined,
303
+ 'sort'))
304
+ }
305
+
306
+ const [name, nameok] = projectorName(args?.[1])
307
+
308
+ if (!nameok) {
309
+ return this.place(makeNilErr(ctx, 'invalid-arg', this, undefined,
310
+ 'sort'))
311
+ }
312
+
313
+ const dir = directionOf(args?.[2])
314
+
315
+ if (undefined === dir) {
316
+ return this.place(makeNilErr(ctx, 'sort_dir', this, undefined, 'sort',
317
+ { dir: (args[2] as any).canon }))
318
+ }
319
+
320
+ const rows: SortRow[] = []
321
+ let domain: 'text' | 'number' | undefined = undefined
322
+
323
+ for (const child of children) {
324
+ const at: any = '' === name ? child : fieldOf(child, name)
325
+
326
+ if (null == at) {
327
+ return this.place(makeNilErr(ctx, 'sort_key', this, undefined, 'sort',
328
+ { key: name }))
329
+ }
330
+
331
+ const u = unpref(at)
332
+ const found = sortDomain(u)
333
+
334
+ if (undefined === found ||
335
+ (undefined !== domain && found !== domain)) {
336
+ return this.place(makeNilErr(ctx, 'sort_domain', this, undefined,
337
+ 'sort', { member: u.canon }))
338
+ }
339
+
340
+ domain = found
341
+ rows.push({ idx: rows.length, val: child, key: u })
342
+ }
343
+
344
+ // The source index breaks every tie, so the order is TOTAL and
345
+ // neither port's sort algorithm can reorder equals.
346
+ rows.sort((a, b) => {
347
+ const c = 'text' === domain ?
348
+ cmpCodePoint(a.key.peg as string, b.key.peg as string) :
349
+ cmpNumeric(a.key, b.key)
350
+ return 0 === c ? a.idx - b.idx : dir * c
351
+ })
352
+
353
+ const peg: Val[] = rows.map(
354
+ (r, i) => r.val.clone(ctx.descend(String(i))))
355
+
356
+ return this.place(new ListVal({ peg }, ctx))
357
+ }
358
+ }
359
+
296
360
 
297
- // THE FOLD TO A STRING: `join(coll, sep?)` -- G9 phase 2.
298
- //
299
- // The one primitive between a model and a generated file. A spread can
300
- // put a separator AFTER each element; putting one BETWEEN N elements is
301
- // a reduction over strings, and the language had none: `sum` is numeric,
302
- // `+` does not reduce a list, and indexed concatenation needs the arity
303
- // known in advance. So a generated SQL column list carried a trailing
304
- // comma and did not parse (use-cases/15-code-generation).
305
- //
306
- // IT FOLDS WITH `+` SEEDED WITH `""`, exactly as `sum` folds with `add`
307
- // seeded with `0`. That is not a figure of speech: the members are
308
- // rendered by `plusText`, which IS the function `+`'s string branch
309
- // calls, so the language keeps exactly one answer to "how does a number
310
- // become text" and the two cannot drift. `join(coll)` is therefore
311
- // concatenation and no `concat` is needed; `join(coll, "\n")` is lines
312
- // and no `lines` is needed. ONE BUILTIN, NOT A FAMILY.
313
- //
314
- // `split`/`words` is the inverse -- an input-PARSING operation with no
315
- // generation use -- and is deliberately absent.
316
- //
317
- // EMPTY IS `""`, concatenation's identity, the exact parallel of
318
- // `sum([]) == 0` and the opposite of `least([])`: a fold with an
319
- // identity can answer the empty bag, and one without has to refuse it.
320
- //
321
- // MEMBERS ARE VALIDATED BEFORE THE FOLD, which is the whole reason this
322
- // is not three lines. `+` with a string on the left RESIDUATES on a
323
- // container or a null rather than refusing (`"" + {b:1}` and `"x" +
324
- // null` both reach generation as `mapval_no_gen`), so folding blindly
325
- // would turn a bad member into a useless late error pointing at the
326
- // wrong thing. The three verdicts below are that check.
327
361
  type MemberVerdict = 'text' | 'never' | 'notyet'
328
362
 
329
363
 
330
- // Which of the three a value is.
331
- //
332
- // `text` -- `+` would take it, so the fold can.
333
- //
334
- // `never` -- a SETTLED value that will never become text: a map, a
335
- // list, a null. This is `join_member`, class `conflict`, and it names
336
- // the member rather than the call, because "one of these is not a
337
- // string" is only actionable if you are told which.
338
- //
339
- // `notyet` -- an unresolved kind, a top, a stable residue. NOT a join
340
- // failure at all: the call stays residual and generation reports
341
- // `mapval_no_gen`, class `incomplete`, exactly as docs/trust.md
342
- // requires ("a stable residue ... is ordinary incompleteness"). Getting
343
- // this split wrong in either direction is the defect that matters here:
344
- // refusing a residue makes `join` unusable inside a schema, and
345
- // deferring on a map makes a real error arrive as a shrug.
346
364
  function memberVerdict(v: any): MemberVerdict {
347
365
  const u = unpref(v)
348
366
  if (undefined !== plusText(u)) {
@@ -355,15 +373,6 @@ function memberVerdict(v: any): MemberVerdict {
355
373
  }
356
374
 
357
375
 
358
- // The separator is a STRING or it is nothing.
359
- //
360
- // A number would render perfectly well through `+`, and is still
361
- // refused: the separator is not a member of the fold, it is the
362
- // parameter naming the text between members, and `join(x, 5)` is far
363
- // likelier a mistake than an intent to separate with "5". `pick`'s key
364
- // argument draws the same line for the same reason. This is the
365
- // direction that can be loosened later without breaking a document;
366
- // the other direction cannot.
367
376
  function sepVerdict(v: any): MemberVerdict {
368
377
  const u = unpref(v)
369
378
  if (u?.isVal && u.isScalar) {
@@ -391,22 +400,6 @@ class JoinFuncVal extends FuncBaseVal {
391
400
  }
392
401
 
393
402
 
394
- // A `make` OVERRIDE, WHERE ITS AggFuncVal SIBLINGS HAVE NONE, and the
395
- // difference is worth stating because it is not arbitrary. `sum`,
396
- // `pick` and the rest are staged and nothing more: they residuate
397
- // before `unify` reaches the rebuild branch, so a `make` there would
398
- // be unreachable code pretending to be a contract, and the base's
399
- // `func:<name>` refusal is the loud answer if that ever changes.
400
- //
401
- // `join` is the first builtin that is BOTH staged AND defers its
402
- // resolution (see `deferResolve`). A deferred call has settled
403
- // arguments, so it does reach the rebuild branch, and without this it
404
- // raised `func:join` on the first document with an unresolved member
405
- // — where the Go port residuated and reported `mapval_no_gen`.
406
- // Opposite answers on `join($.m, ",")` with `m: [string]`, caught by
407
- // running both engines rather than by either test suite. `super` and
408
- // bare `id`, the two other deferring calls, each carry the same
409
- // override for the same reason.
410
403
  make(_ctx: AontuContext, spec: ValSpec): Val {
411
404
  return new JoinFuncVal(spec)
412
405
  }
@@ -426,10 +419,6 @@ class JoinFuncVal extends FuncBaseVal {
426
419
 
427
420
 
428
421
  unify(peer: Val, ctx: AontuContext): Val {
429
- // BOTH arguments, unlike `pick`, which drives only its bag: `pick`'s
430
- // key is a bare word the parser has already made a string, while a
431
- // separator is an ordinary expression and `join($.rows, $.sep)` has
432
- // to wait for it.
433
422
  const ready = this.driveStagedArgs(ctx, 2)
434
423
 
435
424
  if (!ready || !ctx.settle) {
@@ -440,10 +429,6 @@ class JoinFuncVal extends FuncBaseVal {
440
429
  }
441
430
 
442
431
 
443
- // The `notyet` half of the verdict, taken before `resolve` runs: with
444
- // arguments settled but a member still a kind, the call rides the
445
- // ordinary args-not-done path and residuates, which is what makes an
446
- // unresolved member ordinary incompleteness rather than a refusal.
447
432
  deferResolve(ctx: AontuContext, args?: Val[]): boolean {
448
433
  const children = bagChildren(args?.[0], ctx)
449
434
  if (undefined === children) {
@@ -467,28 +452,11 @@ class JoinFuncVal extends FuncBaseVal {
467
452
  'join'))
468
453
  }
469
454
 
470
- // Arity is [1,2], so a second argument is present or the separator
471
- // is the empty string -- which makes `join(coll)` concatenation.
472
- // The separator's SHAPE is settled before resolve runs: the
473
- // signature gate refuses every concrete non-string
474
- // (docs/design/SIGNATURES.0.md; join(d: map|list, sep?: string)),
475
- // and deferResolve holds the call while sepVerdict answers notyet
476
- // -- so a present separator here is text.
477
455
  let sep = ''
478
456
  if (1 < args.length) {
479
457
  sep = unpref(args[1]).peg
480
458
  }
481
459
 
482
- // NO NIL-MEMBER GUARD, WHERE `sum` HAS ONE, and the difference is
483
- // the fold's shape rather than an oversight. `sum` folds with
484
- // `arith`, which MINTS a nil part-way through — a non-numeric child
485
- // or an overflow — so it has to stop and return it. `join` folds
486
- // already-unified values, and a nil among a list's elements
487
- // collapses the list before this call resolves: `join([least([])],
488
- // ",")` reports `aggregate_empty` at the member's own path,
489
- // `$.o.0`, and never reaches here. A guard was written, the
490
- // ADR-002 gate found it unexecuted, and probing confirmed no
491
- // spelling reaches it, so it is removed rather than excused.
492
460
  const parts: string[] = []
493
461
  for (const child of children) {
494
462
  const u: any = unpref(child)
@@ -500,16 +468,11 @@ class JoinFuncVal extends FuncBaseVal {
500
468
  parts.push(text)
501
469
  }
502
470
 
503
- // Every part is already a string, so this IS the `+` fold seeded
504
- // with `""` -- written as one concatenation because a loop of `+`
505
- // over settled strings cannot differ from it, and because the Go
506
- // twin's strings.Join must produce the same bytes.
507
471
  return this.place(new StringVal({ peg: parts.join(sep) }))
508
472
  }
509
473
  }
510
474
 
511
475
 
512
- // The three the registry names. Each is its operation and nothing else.
513
476
  class SumFuncVal extends AggFuncVal {
514
477
  constructor(spec: ValSpec, ctx?: AontuContext) { super(spec, ctx, 'sum') }
515
478
  }
@@ -522,13 +485,14 @@ class GreatestFuncVal extends AggFuncVal {
522
485
  constructor(spec: ValSpec, ctx?: AontuContext) {
523
486
  super(spec, ctx, 'greatest')
524
487
  }
525
- } /* node:coverage ignore next 10 */
488
+ } /* node:coverage ignore next 11 */
526
489
 
527
490
 
528
491
  export {
529
492
  AggFuncVal,
530
493
  JoinFuncVal,
531
494
  PickFuncVal,
495
+ SortFuncVal,
532
496
  SumFuncVal,
533
497
  LeastFuncVal,
534
498
  GreatestFuncVal,