aontu 0.60.0 → 0.62.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 (113) hide show
  1. package/README.md +3 -3
  2. package/dist/agentsmd.d.ts +1 -0
  3. package/dist/agentsmd.js +7 -1
  4. package/dist/agentsmd.js.map +1 -1
  5. package/dist/allow.d.ts +23 -0
  6. package/dist/allow.js +230 -0
  7. package/dist/allow.js.map +1 -0
  8. package/dist/aontu.d.ts +4 -2
  9. package/dist/aontu.js +4 -2
  10. package/dist/aontu.js.map +1 -1
  11. package/dist/cli.d.ts +10 -1
  12. package/dist/cli.js +1000 -47
  13. package/dist/cli.js.map +1 -1
  14. package/dist/format.d.ts +1 -0
  15. package/dist/format.js +154 -12
  16. package/dist/format.js.map +1 -1
  17. package/dist/helpdoc.d.ts +16 -0
  18. package/dist/helpdoc.js +59 -0
  19. package/dist/helpdoc.js.map +1 -0
  20. package/dist/hints.js +15 -2
  21. package/dist/hints.js.map +1 -1
  22. package/dist/lang.js +93 -40
  23. package/dist/lang.js.map +1 -1
  24. package/dist/lower.d.ts +3 -0
  25. package/dist/lower.js +3 -0
  26. package/dist/lower.js.map +1 -1
  27. package/dist/lsp.d.ts +1 -1
  28. package/dist/lsp.js +1 -1
  29. package/dist/lsp.js.map +1 -1
  30. package/dist/relation.d.ts +2 -0
  31. package/dist/relation.js +7 -1
  32. package/dist/relation.js.map +1 -1
  33. package/dist/render.js +26 -21
  34. package/dist/render.js.map +1 -1
  35. package/dist/sigdecl.js +1 -1
  36. package/dist/sigdecl.js.map +1 -1
  37. package/dist/std.js +112 -69
  38. package/dist/std.js.map +1 -1
  39. package/dist/template.d.ts +2 -1
  40. package/dist/template.js +51 -15
  41. package/dist/template.js.map +1 -1
  42. package/dist/tsconfig.tsbuildinfo +1 -1
  43. package/dist/val/AggFuncVal.js +2 -2
  44. package/dist/val/AggFuncVal.js.map +1 -1
  45. package/dist/val/CmpFuncVal.d.ts +20 -0
  46. package/dist/val/CmpFuncVal.js +245 -0
  47. package/dist/val/CmpFuncVal.js.map +1 -0
  48. package/dist/val/EachFuncVal.d.ts +1 -2
  49. package/dist/val/EachFuncVal.js +15 -29
  50. package/dist/val/EachFuncVal.js.map +1 -1
  51. package/dist/val/FormFuncVal.js.map +1 -1
  52. package/dist/val/LowerFuncVal.js +17 -1
  53. package/dist/val/LowerFuncVal.js.map +1 -1
  54. package/dist/val/NamerFuncVal.d.ts +12 -0
  55. package/dist/val/NamerFuncVal.js +176 -0
  56. package/dist/val/NamerFuncVal.js.map +1 -0
  57. package/dist/val/NilVal.js +29 -3
  58. package/dist/val/NilVal.js.map +1 -1
  59. package/dist/val/NomFuncVal.d.ts +12 -0
  60. package/dist/val/NomFuncVal.js +187 -0
  61. package/dist/val/NomFuncVal.js.map +1 -0
  62. package/dist/val/PackFuncVal.js +3 -3
  63. package/dist/val/PackFuncVal.js.map +1 -1
  64. package/dist/val/RefVal.js +1 -1
  65. package/dist/val/TranslateFuncVal.d.ts +12 -0
  66. package/dist/val/TranslateFuncVal.js +101 -0
  67. package/dist/val/TranslateFuncVal.js.map +1 -0
  68. package/dist/val/UpperFuncVal.js +17 -1
  69. package/dist/val/UpperFuncVal.js.map +1 -1
  70. package/dist/val/caserange.d.ts +3 -0
  71. package/dist/val/caserange.js +110 -0
  72. package/dist/val/caserange.js.map +1 -0
  73. package/dist/vet.d.ts +12 -0
  74. package/dist/vet.js +209 -1
  75. package/dist/vet.js.map +1 -1
  76. package/grammar/aontu.abnf +1 -1
  77. package/grammar/aontu.gbnf +1 -1
  78. package/grammar/aontu.lark +1 -1
  79. package/grammar/aontu.tmLanguage.json +1 -1
  80. package/package.json +1 -1
  81. package/skill/SKILL.md +8 -0
  82. package/skill/init/check.sh +28 -0
  83. package/skill/init/data.aon +12 -0
  84. package/skill/init/model.aon +19 -0
  85. package/skill/tasks.md +151 -0
  86. package/src/agentsmd.ts +13 -2
  87. package/src/allow.ts +316 -0
  88. package/src/aontu.ts +10 -1
  89. package/src/cli.ts +1131 -53
  90. package/src/format.ts +191 -14
  91. package/src/helpdoc.ts +77 -0
  92. package/src/hints.ts +16 -2
  93. package/src/lang.ts +98 -42
  94. package/src/lower.ts +3 -3
  95. package/src/lsp.ts +1 -1
  96. package/src/relation.ts +21 -1
  97. package/src/render.ts +26 -21
  98. package/src/sigdecl.ts +1 -1
  99. package/src/std.ts +112 -69
  100. package/src/template.ts +55 -15
  101. package/src/val/AggFuncVal.ts +2 -2
  102. package/src/val/CmpFuncVal.ts +411 -0
  103. package/src/val/EachFuncVal.ts +49 -50
  104. package/src/val/LowerFuncVal.ts +18 -1
  105. package/src/val/NilVal.ts +29 -3
  106. package/src/val/NomFuncVal.ts +287 -0
  107. package/src/val/PackFuncVal.ts +3 -3
  108. package/src/val/RefVal.ts +1 -1
  109. package/src/val/TranslateFuncVal.ts +182 -0
  110. package/src/val/UpperFuncVal.ts +18 -1
  111. package/src/val/caserange.ts +115 -0
  112. package/src/vet.ts +287 -1
  113. package/src/val/FormFuncVal.ts +0 -119
package/src/vet.ts CHANGED
@@ -46,6 +46,7 @@ import { subsumeNode, effectiveDefault } from './subsume'
46
46
  // (query imports anchorAt from here), and a benign one: both sides
47
47
  // use the other only from inside a function body, never at load time.
48
48
  import { noPathFinding } from './query'
49
+ import { cmpCodePoint } from './keyorder'
49
50
 
50
51
 
51
52
  export type VetVerdict = 'valid' | 'invalid' | 'incomplete' | 'error'
@@ -118,10 +119,52 @@ export type VetFinding = {
118
119
  note?: string
119
120
  }
120
121
 
122
+ // WHAT THE CHECK ACTUALLY EXAMINED (G11 phase 5,
123
+ // docs/capability-review/g11-agent-onramp.md).
124
+ //
125
+ // The defect this exists for: a schema written with the wildcard every
126
+ // neighbouring tool uses -- `{"*": {...}}`, which in aontu is a key
127
+ // NAMED `*` and not a template -- constrains nothing, and vet answers
128
+ // `valid` over data that violates it. aontu is not wrong there; it was
129
+ // asked about a document declaring an entity called `*`. The defect is
130
+ // that a check that examined NOTHING and a check that PASSED are the
131
+ // same bytes and the same exit code, so an unattended caller reports
132
+ // success.
133
+ //
134
+ // Absent unless asked for (`VetOptions.coverage`), so no existing
135
+ // report changes shape and the accounting costs nothing by default --
136
+ // `render --coverage` sets both precedents.
137
+ export type VetCoverage = {
138
+ // Data LEAVES a schema declaration constrained. Leaves, not paths:
139
+ // a leaf is where a value lives, and matching a CONTAINER constrains
140
+ // no value. A schema that says only "there is a key called entity"
141
+ // has checked nothing, and this is the number that says so.
142
+ checked: number
143
+ // Declarations the schema makes under the anchor. A declaration is a
144
+ // map key, a list index, or a template (spelled `&` in the path),
145
+ // at every depth.
146
+ declared: number
147
+ // Data leaves in all, under `coverageAt` when it is given. `checked`
148
+ // over this is the ratio a reader wants.
149
+ leaves: number
150
+ // The SHALLOWEST data paths no declaration constrained. Shallowest,
151
+ // as `render --coverage`'s `dead` is: a path whose subtree is wholly
152
+ // unconstrained is named once instead of every leaf beneath it.
153
+ unchecked: string[]
154
+ // The SHALLOWEST declarations no data path met.
155
+ unused: string[]
156
+ // NO data leaf was constrained, over a document that has leaves.
157
+ // The exact condition of the `"*"` failure, and what
158
+ // `--strict-coverage` exits 1 on.
159
+ vacuous: boolean
160
+ }
161
+
121
162
  export type VetReport = {
122
163
  verdict: VetVerdict
123
164
  truncated: boolean
124
165
  findings: VetFinding[]
166
+ // Absent unless the run asked for it.
167
+ coverage?: VetCoverage
125
168
  }
126
169
 
127
170
  export type VetOptions = {
@@ -129,6 +172,16 @@ export type VetOptions = {
129
172
  closed?: boolean // close() the anchor for this run
130
173
  partial?: boolean // residue is not a failure
131
174
  maxErrors?: number // cap the finding list (default 20)
175
+
176
+ // Account for what the check examined (G11 phase 5). Off by default:
177
+ // the report gains a `coverage` object only when this is set, so no
178
+ // existing caller's report changes shape.
179
+ coverage?: boolean
180
+ // Measure under this path of the DATA only, instead of the whole
181
+ // document -- `render --coverage`'s `--coverage-at`, for the same
182
+ // reason: a caller gating one subtree should not be answered about
183
+ // the rest. Ignored unless `coverage` is set.
184
+ coverageAt?: string
132
185
  schemaUrl?: string // provenance label for schema sites
133
186
  dataUrl?: string // provenance label for data sites
134
187
 
@@ -596,6 +649,215 @@ export function throughResidue(v: any): any {
596
649
  // are unusable — which is why an unusable schema is a verdict (`error`)
597
650
  // rather than an exception too: "the schema is broken" is a fact the
598
651
  // agent loop needs to branch on, not an exceptional condition.
652
+ // THE COVERAGE ACCOUNTING (G11 phase 5). Structural, over the two
653
+ // trees vet already holds, and deliberately NOT provenance-based: the
654
+ // question is what the SCHEMA DECLARES about the data, which is a
655
+ // property of the two documents rather than of the meet that ran. A
656
+ // meet-based reading would also count a value the data supplied to
657
+ // itself as "covered", which is the opposite of the thing being asked.
658
+ //
659
+ // A map's template lives on `spread.cj` rather than in `peg`, so a
660
+ // declaration path spells it `&` -- the same character the language
661
+ // spells it with, and one no map key can collide with, since a bare
662
+ // `&` cannot be a key.
663
+ const COVER_TEMPLATE = '&'
664
+
665
+
666
+ // Is this value a bag with children to walk?
667
+ function coverKids(v: any): { key: string, val: any }[] {
668
+ // NO KIND GUARD: the two tests below already reject anything that is
669
+ // not a bag, exactly as the Go twin's type switch does, so a guard
670
+ // above them is dead code (ADR-002).
671
+ const out: { key: string, val: any }[] = []
672
+ if (true === v.isMap && null != v.peg) {
673
+ for (const k of Object.keys(v.peg).sort(cmpCodePoint)) {
674
+ out.push({ key: k, val: v.peg[k] })
675
+ }
676
+ }
677
+ else if (true === v.isList && Array.isArray(v.peg)) {
678
+ v.peg.forEach((m: any, i: number) => out.push({ key: String(i), val: m }))
679
+ }
680
+ return out
681
+ }
682
+
683
+
684
+ // The template a bag applies to every child, when it has one. A spread
685
+ // with no conjunct is not a declaration: `{"*":{...}}` carries the
686
+ // empty spread every map carries, and reading that as a template is
687
+ // precisely the confusion this phase exists to end.
688
+ function coverTemplate(v: any): any {
689
+ const cj = v?.spread?.cj
690
+ return null != cj && true === cj.isVal && true !== cj.isTop ? cj : undefined
691
+ }
692
+
693
+
694
+ // Every declaration the schema makes, as a path, with the node at it.
695
+ // Named keys and templates alike, at every depth.
696
+ //
697
+ // NO IDENTITY GUARD, and that is a decision rather than an omission.
698
+ // `walkVals` (ts/src/walk.ts) carries one because it walks values the
699
+ // unification MINTED -- findings, conjunct operands, disjunct trials --
700
+ // where a node really is reached twice. These two walks descend a
701
+ // SETTLED bag through `peg` and `spread` alone, and such a tree is a
702
+ // tree: a reference resolves by cloning its target, and an alias, a
703
+ // repeated spread and a recursive residual were each probed and share
704
+ // nothing. The property is already relied on repository-wide, because
705
+ // `canon` walks the same edges with no guard and is computed on every
706
+ // one of these values. A guard here would be a branch nothing can
707
+ // take, which ADR-002 exists to keep out.
708
+ function coverDeclare(
709
+ v: any, path: string[], out: Map<string, any>): void {
710
+ const tpl = coverTemplate(v)
711
+ if (null != tpl) {
712
+ const at = [...path, COVER_TEMPLATE]
713
+ out.set(pathText(at), tpl)
714
+ coverDeclare(tpl, at, out)
715
+ }
716
+ for (const { key, val } of coverKids(v)) {
717
+ const at = [...path, key]
718
+ out.set(pathText(at), val)
719
+ coverDeclare(val, at, out)
720
+ }
721
+ }
722
+
723
+
724
+ // Every path in the data, and whether it is a LEAF -- a node with no
725
+ // children, which is where a value lives.
726
+ function coverDataPaths(
727
+ v: any, path: string[],
728
+ out: { path: string, leaf: boolean }[]): void {
729
+ const kids = coverKids(v)
730
+ if (0 < path.length) {
731
+ out.push({ path: pathText(path), leaf: 0 === kids.length })
732
+ }
733
+ for (const { key, val } of kids) {
734
+ coverDataPaths(val, [...path, key], out)
735
+ }
736
+ }
737
+
738
+
739
+ // Walk one data path down the schema, naming the declaration that
740
+ // constrains it -- the exact key where the schema has one, else the
741
+ // covering template. Undefined when the schema declares nothing there.
742
+ function coverMatch(
743
+ anchor: any, segs: string[]): string | undefined {
744
+ // NO NIL GUARD ON `at`, and none on an empty `segs`: `at` starts as
745
+ // the anchor and is only ever reassigned to a non-nil child or
746
+ // template, and coverDataPaths never emits the root path, so a call
747
+ // with no segments cannot happen. A guard that cannot fire is dead
748
+ // code, and dead code is what ADR-002 exists to keep out.
749
+ let at: any = anchor
750
+ let decl = ''
751
+ for (const seg of segs) {
752
+ const named = true === at.isMap && null != at.peg ? at.peg[seg]
753
+ : true === at.isList && Array.isArray(at.peg) ? at.peg[Number(seg)]
754
+ : undefined
755
+ if (null != named && true === named.isVal) {
756
+ decl = '' === decl ? seg : decl + '.' + seg
757
+ at = named
758
+ continue
759
+ }
760
+ const tpl = coverTemplate(at)
761
+ if (null == tpl) {
762
+ return undefined
763
+ }
764
+ decl = '' === decl ? COVER_TEMPLATE : decl + '.' + COVER_TEMPLATE
765
+ at = tpl
766
+ }
767
+ return '$.' + decl
768
+ }
769
+
770
+
771
+ // The SHALLOWEST members of a set of paths: one whose parent is also in
772
+ // the set is covered by naming the parent, and naming both is noise.
773
+ // `render --coverage`'s `dead` is built on the same rule.
774
+ function coverShallowest(paths: string[]): string[] {
775
+ const held = new Set(paths)
776
+ return paths.filter((p) => {
777
+ for (let at = p; -1 !== at.lastIndexOf('.');) {
778
+ at = at.slice(0, at.lastIndexOf('.'))
779
+ if (held.has(at)) {
780
+ return false
781
+ }
782
+ }
783
+ return true
784
+ }).sort(cmpCodePoint)
785
+ }
786
+
787
+
788
+ // The accounting itself: what the schema declared, what the data holds,
789
+ // and which of each the other met.
790
+ export function vetCoverage(
791
+ anchor: any, dataVal: any, coverageAt?: string): VetCoverage {
792
+ const declarations = new Map<string, any>()
793
+ coverDeclare(anchor, [], declarations)
794
+
795
+ const dataPaths: { path: string, leaf: boolean }[] = []
796
+ coverDataPaths(dataVal, [], dataPaths)
797
+
798
+ // `--coverage-at` narrows the DATA side, which is the side a caller
799
+ // gating one subtree is asking about. The schema side follows from
800
+ // it: a declaration is unused only among the data actually measured.
801
+ const under = null == coverageAt ? undefined
802
+ : coverageAt.replace(/^\$\.?/, '')
803
+ const inScope = (p: string): boolean => {
804
+ if (null == under || '' === under) {
805
+ return true
806
+ }
807
+ const want = '$.' + under
808
+ return p === want || p.startsWith(want + '.')
809
+ }
810
+
811
+ const used = new Set<string>()
812
+ const unchecked: string[] = []
813
+ let checked = 0
814
+ let leaves = 0
815
+ for (const { path, leaf } of dataPaths) {
816
+ if (!inScope(path)) {
817
+ continue
818
+ }
819
+ const segs = path.replace(/^\$\.?/, '').split('.').filter((x) => '' !== x)
820
+ const decl = coverMatch(anchor, segs)
821
+ if (leaf) {
822
+ leaves++
823
+ }
824
+ if (null == decl) {
825
+ unchecked.push(path)
826
+ continue
827
+ }
828
+ used.add(decl)
829
+ if (leaf) {
830
+ checked++
831
+ }
832
+ }
833
+
834
+ // A declaration is met when it constrained a data path, or when a
835
+ // declaration BENEATH it was: `$.a` is used by `$.a.b` meeting
836
+ // `$.a.b`, and reporting the parent as unused would be false.
837
+ const unused: string[] = []
838
+ for (const decl of declarations.keys()) {
839
+ const covered = used.has(decl) ||
840
+ [...used].some((u) => u.startsWith(decl + '.'))
841
+ if (!covered) {
842
+ unused.push(decl)
843
+ }
844
+ }
845
+
846
+ return {
847
+ checked,
848
+ declared: declarations.size,
849
+ leaves,
850
+ unchecked: coverShallowest(unchecked),
851
+ unused: coverShallowest(unused),
852
+ // VACUOUS IS ABOUT LEAVES, and a document with none cannot be
853
+ // vacuously checked: `{}` against any schema examined nothing
854
+ // because there was nothing to examine, which is not the failure
855
+ // this reports.
856
+ vacuous: 0 === checked && 0 < leaves,
857
+ }
858
+ }
859
+
860
+
599
861
  export function vet(
600
862
  schemaSrc: string, dataSrc: string, opts?: VetOptions): VetReport {
601
863
  const options = opts ?? {}
@@ -729,6 +991,27 @@ export function vet(
729
991
  dataUrl, dataPath: options.dataPath,
730
992
  }
731
993
 
994
+ // COVERAGE IS MEASURED BEFORE THE MEET (G11 phase 5), because the
995
+ // meet CONSUMES its operands: parsed trees are single-use, and under
996
+ // `--at` the anchor itself is the left operand. Measuring after would
997
+ // read a tree the fixpoint had already rewritten.
998
+ //
999
+ // The data side is its own evaluation rather than the parse above,
1000
+ // so a document that reaches its values through `@"..."` or a
1001
+ // reference is measured on the paths it actually has. It is one more
1002
+ // evaluation of one document, and it happens only when asked for.
1003
+ let coverage: VetCoverage | undefined
1004
+ if (true === options.coverage) {
1005
+ const coverCtx = aontu.ctx({ collect: true })
1006
+ const settledData: any = aontu.unify(dataSrc, dataOpts, coverCtx)
1007
+ // A data document that does not stand alone is already reported by
1008
+ // the meet below; here it falls back to what was parsed, which is
1009
+ // the same paths minus whatever an include would have added.
1010
+ const measured = 0 === coverCtx.err.length && true !== settledData?.isNil
1011
+ ? settledData : dataVal
1012
+ coverage = vetCoverage(anchor, measured, options.coverageAt)
1013
+ }
1014
+
732
1015
  // Default-validity lint (G3 phase 5, re-examined under ADR-004): for
733
1016
  // every disjunction in the SCHEMA carrying a preference, warn when
734
1017
  // the effective default is not an instance of any REMAINING
@@ -1031,5 +1314,8 @@ export function vet(
1031
1314
  verdict = 'incomplete'
1032
1315
  }
1033
1316
 
1034
- return { verdict, truncated, findings: kept }
1317
+ return {
1318
+ verdict, truncated, findings: kept,
1319
+ ...(null == coverage ? {} : { coverage }),
1320
+ }
1035
1321
  }
@@ -1,119 +0,0 @@
1
- /* Copyright (c) 2025 Richard Rodger, MIT License */
2
-
3
- // TRANSFORMATION: `form(data, tmpl)` (G9 §4; docs/design/RENDER.0.md
4
- // D11 and P6). One element of the result list per child of `data`,
5
- // being `tmpl` instantiated at that position with `_` bound to the
6
- // source child. It REPLACES; it does not meet.
7
- //
8
- // names: [web, auth]
9
- // units: form($.names, {path: _ + ".ts"}) -> [{path: "web.ts"}, {path: "auth.ts"}]
10
- //
11
- // WHY BESIDE `each`. `each($.ports, integer)` is a schema statement
12
- // and is monotone -- more information about the template narrows the
13
- // children -- so it is a lattice citizen, and a constructor is not.
14
- // The language draws this line twice already: `min`/`max` (bounds)
15
- // against `least`/`greatest` (aggregates), and `filter` (select by
16
- // unifiability) against `match` (choose a result). `each` is the
17
- // bound; `form` is the construction. `each` also carries the source
18
- // child's identity (its clone keeps the entity), where `form`'s
19
- // element IS the template.
20
- //
21
- // WHY IT EXISTS AT ALL: ORDER. `pick(pack(d, {f: t}), f)` maps too,
22
- // but it goes through a map and re-sorts to code-point order, and it
23
- // refuses a list of records outright (pack_key). A struct's fields, a
24
- // DDL's columns and a file's imports are lists whose order is the
25
- // model's, and silently alphabetising them is wrong output. `form`
26
- // reads its members through the one ordering helper `each` uses
27
- // (members.ts), so the two can never disagree about order -- source
28
- // order for a list, sorted-key order for a map -- and skips what
29
- // generation would not emit: a hidden child, an unfilled optional.
30
- //
31
- // It joins `boundArgStart` (PlaceVal.ts): a `_` inside its template
32
- // is ITS hole to bind, never an outer generator's. Forgetting that is
33
- // BUGS.md §34's silent failure -- every existing test passes and the
34
- // new combinator captures an outer generator's hole -- which is why
35
- // the shared spec's nesting rows exist.
36
-
37
- import type {
38
- Val,
39
- ValSpec,
40
- } from '../type'
41
-
42
- import {
43
- AontuContext,
44
- } from '../ctx'
45
-
46
- import { makeNilErr } from '../err'
47
- import { ListVal } from './ListVal'
48
- import { FuncBaseVal } from './FuncBaseVal'
49
- import { repathInstance } from './Val'
50
- import { fillPlace } from './PlaceVal'
51
- import { memberVals } from './members'
52
-
53
-
54
- class FormFuncVal extends FuncBaseVal {
55
- isFormFunc = true
56
-
57
- // THE STAGING RULE, for the reason given in PackFuncVal: the data
58
- // is not settled merely by being `done` once.
59
- staged = true
60
-
61
- constructor(
62
- spec: ValSpec,
63
- ctx?: AontuContext
64
- ) {
65
- super(spec, ctx)
66
- }
67
-
68
-
69
- funcname() {
70
- return 'form'
71
- }
72
-
73
-
74
- // The template is not an argument to drive (see PackFuncVal.prepare).
75
- prepare(_ctx: AontuContext, _args: Val[]) {
76
- return null
77
- }
78
-
79
-
80
- unify(peer: Val, ctx: AontuContext): Val {
81
- // ONE argument is driven: the data. The template is not (see
82
- // prepare above).
83
- if (!this.stagedReady(peer, ctx, 1)) {
84
- return this.residuate(peer, ctx)
85
- }
86
-
87
- return super.unify(peer, ctx)
88
- }
89
-
90
-
91
- resolve(ctx: AontuContext, args: Val[]) {
92
- const vals = memberVals(args?.[0], ctx)
93
- if (undefined === vals) {
94
- return makeNilErr(ctx, 'form_data', this)
95
- }
96
-
97
- // Arity is checked at parse (funcArity), so the template is here.
98
- const tmpl: Val = args[1]
99
- const peg: Val[] = []
100
-
101
- for (let i = 0; i < vals.length; i++) {
102
- const elctx = ctx.descend(String(i))
103
- // A FULL INSTANCE per element, to the leaves (`dup`, ADR-005),
104
- // at the element's own position -- see PackFuncVal.resolve --
105
- // with `_` bound to the source child and NOTHING met into it.
106
- const inst = tmpl.clone(elctx, { dup: true })
107
- repathInstance(inst, inst.path)
108
- peg.push(fillPlace(inst, vals[i], elctx))
109
- }
110
-
111
- return new ListVal({ peg }, ctx)
112
- }
113
-
114
- } /* node:coverage ignore next 6 */
115
-
116
-
117
- export {
118
- FormFuncVal,
119
- }