@json-layout/core 2.8.2 → 2.9.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 (64) hide show
  1. package/package.json +4 -2
  2. package/src/compile/index.js +3 -1
  3. package/src/compile/skeleton-node.js +46 -5
  4. package/src/compile/types.ts +1 -0
  5. package/src/compile/utils/resolve-refs.js +5 -8
  6. package/src/compile/utils/x-i18n.js +15 -6
  7. package/src/state/index.js +18 -1
  8. package/src/state/state-node.js +11 -2
  9. package/src/state/utils/urls.js +2 -0
  10. package/src/utils/json-pointer.js +29 -0
  11. package/src/webmcp/README.md +144 -0
  12. package/src/webmcp/index.js +88 -82
  13. package/src/webmcp/project.js +479 -111
  14. package/src/webmcp/resolve.js +37 -1
  15. package/src/webmcp/schema.js +169 -0
  16. package/src/webmcp/suggestions-store.js +121 -0
  17. package/src/webmcp/tools/describe-state.js +20 -64
  18. package/src/webmcp/tools/edit-array.js +51 -28
  19. package/src/webmcp/tools/fill-form-skill.js +17 -41
  20. package/src/webmcp/tools/get-data.js +66 -13
  21. package/src/webmcp/tools/get-field-suggestions.js +12 -23
  22. package/src/webmcp/tools/set-data.js +79 -28
  23. package/src/webmcp/tools/set-field-value.js +49 -39
  24. package/src/webmcp/variants-memo.js +53 -0
  25. package/types/compile/index.d.ts.map +1 -1
  26. package/types/compile/skeleton-node.d.ts +9 -2
  27. package/types/compile/skeleton-node.d.ts.map +1 -1
  28. package/types/compile/types.d.ts +1 -0
  29. package/types/compile/types.d.ts.map +1 -1
  30. package/types/compile/utils/resolve-refs.d.ts.map +1 -1
  31. package/types/compile/utils/x-i18n.d.ts +1 -1
  32. package/types/compile/utils/x-i18n.d.ts.map +1 -1
  33. package/types/state/index.d.ts +10 -0
  34. package/types/state/index.d.ts.map +1 -1
  35. package/types/state/state-node.d.ts.map +1 -1
  36. package/types/state/utils/urls.d.ts.map +1 -1
  37. package/types/utils/json-pointer.d.ts +22 -0
  38. package/types/utils/json-pointer.d.ts.map +1 -0
  39. package/types/webmcp/index.d.ts +23 -15
  40. package/types/webmcp/index.d.ts.map +1 -1
  41. package/types/webmcp/project.d.ts +159 -57
  42. package/types/webmcp/project.d.ts.map +1 -1
  43. package/types/webmcp/resolve.d.ts +7 -3
  44. package/types/webmcp/resolve.d.ts.map +1 -1
  45. package/types/webmcp/schema.d.ts +44 -0
  46. package/types/webmcp/schema.d.ts.map +1 -0
  47. package/types/webmcp/suggestions-store.d.ts +82 -0
  48. package/types/webmcp/suggestions-store.d.ts.map +1 -0
  49. package/types/webmcp/tools/describe-state.d.ts +5 -57
  50. package/types/webmcp/tools/describe-state.d.ts.map +1 -1
  51. package/types/webmcp/tools/edit-array.d.ts +8 -37
  52. package/types/webmcp/tools/edit-array.d.ts.map +1 -1
  53. package/types/webmcp/tools/fill-form-skill.d.ts +10 -13
  54. package/types/webmcp/tools/fill-form-skill.d.ts.map +1 -1
  55. package/types/webmcp/tools/get-data.d.ts +17 -15
  56. package/types/webmcp/tools/get-data.d.ts.map +1 -1
  57. package/types/webmcp/tools/get-field-suggestions.d.ts +4 -30
  58. package/types/webmcp/tools/get-field-suggestions.d.ts.map +1 -1
  59. package/types/webmcp/tools/set-data.d.ts +17 -34
  60. package/types/webmcp/tools/set-data.d.ts.map +1 -1
  61. package/types/webmcp/tools/set-field-value.d.ts +20 -57
  62. package/types/webmcp/tools/set-field-value.d.ts.map +1 -1
  63. package/types/webmcp/variants-memo.d.ts +42 -0
  64. package/types/webmcp/variants-memo.d.ts.map +1 -0
@@ -2,16 +2,39 @@
2
2
  * @file getData tool
3
3
  */
4
4
 
5
- export const inputSchema = {
6
- type: 'object',
7
- properties: {}
5
+ import { resolveNode } from '../resolve.js'
6
+
7
+ /** Most field paths named in a refusal before the rest are counted instead. */
8
+ export const NAMED_FIELDS_MAX = 12
9
+
10
+ /**
11
+ * The paths under a layout section that do own a place in the data.
12
+ *
13
+ * A section may nest more sections — an allOf inside a oneOf branch — so this walks past
14
+ * every wrapper until it reaches nodes whose value is their own, which are the paths the
15
+ * agent can actually read. Naming them is the difference between a refusal that redirects
16
+ * and one that just says no: calendar's agent gave up after being refused, charts had to
17
+ * guess its next path.
18
+ * @param {import('../../state/types.js').StateNode} node
19
+ * @param {string[]} [into]
20
+ * @returns {string[]}
21
+ */
22
+ function dataOwningFields (node, into = []) {
23
+ for (const child of node.children ?? []) {
24
+ if (into.length > NAMED_FIELDS_MAX) return into
25
+ if (child.dataPath === node.dataPath) dataOwningFields(child, into)
26
+ else into.push(child.fullKey)
27
+ }
28
+ return into
8
29
  }
9
30
 
10
- export const outputSchema = {
31
+ export const inputSchema = {
11
32
  type: 'object',
12
33
  properties: {
13
- data: {},
14
- valid: { type: 'boolean' }
34
+ path: {
35
+ type: 'string',
36
+ description: 'Node path as returned by describeState (e.g. "/address/city"). Omit for the whole document.'
37
+ }
15
38
  }
16
39
  }
17
40
 
@@ -20,17 +43,47 @@ export const outputSchema = {
20
43
  * @returns {string}
21
44
  */
22
45
  export function getDescription (dataTitle) {
23
- return `Get the current "${dataTitle}" data and validity status.`
46
+ return `Get the current "${dataTitle}" data and validity status. The data is always returned whole and unmodified, so on a large form pass "path" to read one part of it rather than the entire document.`
24
47
  }
25
48
 
26
49
  /**
50
+ * Read the data, whole or at a path. Whatever it returns is the real value: an agent may
51
+ * forward it to an API, so nothing here is ever abbreviated. `path` exists so that
52
+ * wanting one field is not a reason to pull a document that can run to tens of kilobytes.
27
53
  * @param {import('../../state/index.js').StatefulLayout} statefulLayout
28
- * @param {{}} _args
29
- * @returns {{ data: unknown, valid: boolean }}
54
+ * @param {{ path?: string }} args
55
+ * @returns {{ data?: unknown, unset?: boolean, valid: boolean }}
30
56
  */
31
- export function execute (statefulLayout, _args) {
32
- return {
33
- data: statefulLayout.data,
34
- valid: statefulLayout.valid
57
+ export function execute (statefulLayout, args) {
58
+ if (!args?.path) {
59
+ return { data: statefulLayout.data, valid: statefulLayout.valid }
60
+ }
61
+ const node = resolveNode(statefulLayout.stateTree.root, args.path)
62
+ if (!node) {
63
+ throw new Error(`node not found at path: ${args.path}`)
64
+ }
65
+ // A section a `$allOf`, `$oneOf` or `$comp-` wrapper introduces holds no data of its
66
+ // own: its value IS its parent's, so asking for it returns the document the `path`
67
+ // argument exists to avoid. charts asked for "/$allOf-1" and got the whole thing back,
68
+ // 29% of that run's bytes, with nothing in the answer to say the path had bought
69
+ // nothing. Refusing costs one short line and names where to go instead.
70
+ if (node.dataPath === node.parentDataPath) {
71
+ const owner = node.parentDataPath === '' ? 'the whole document' : `"${node.parentDataPath}"`
72
+ const fields = dataOwningFields(node)
73
+ const named = fields.length > NAMED_FIELDS_MAX
74
+ ? `${fields.slice(0, NAMED_FIELDS_MAX).join(', ')} and ${fields.length - NAMED_FIELDS_MAX} more`
75
+ : fields.join(', ')
76
+ const instead = fields.length
77
+ ? ` Read one of its fields instead: ${named}.`
78
+ : ''
79
+ throw new Error(`"${args.path}" is a layout section, it holds no data of its own — its value is the data of ${owner}.${instead} Omit "path" to read the document.`)
80
+ }
81
+ // JSON.stringify drops an undefined value, so an unset field would come back as a
82
+ // response with no "data" key at all — indistinguishable from a malformed answer.
83
+ if (node.data === undefined) {
84
+ return { unset: true, valid: statefulLayout.valid }
35
85
  }
86
+ // The form's validity, not the node's: it is what an agent is deciding on, and a
87
+ // subtree that validates inside a form that does not would read as done.
88
+ return { data: node.data, valid: statefulLayout.valid }
36
89
  }
@@ -9,7 +9,7 @@ export const inputSchema = {
9
9
  properties: {
10
10
  path: {
11
11
  type: 'string',
12
- description: 'Path to the field'
12
+ description: 'Node path as returned by describeState (e.g. "/address/city").'
13
13
  },
14
14
  query: {
15
15
  type: 'string',
@@ -19,37 +19,26 @@ export const inputSchema = {
19
19
  required: ['path']
20
20
  }
21
21
 
22
- export const outputSchema = {
23
- type: 'object',
24
- properties: {
25
- items: {
26
- type: 'array',
27
- items: {
28
- type: 'object',
29
- properties: {
30
- value: {},
31
- title: { type: 'string' },
32
- key: { type: 'string' }
33
- }
34
- }
35
- }
36
- }
37
- }
38
-
39
22
  /**
40
23
  * @param {string} dataTitle
41
24
  * @returns {string}
42
25
  */
43
26
  export function getDescription (dataTitle) {
44
- return `Get available options for a select/autocomplete/combobox field of form "${dataTitle}". Supports query-based filtering.`
27
+ // The one statement of the suggestion protocol. It used to be said here, again in
28
+ // setFieldValue's description, a third time in that tool's suggestionIndex parameter and
29
+ // a fourth in the guide — 1114 bytes of the 5941 the model is sent, and four copies that
30
+ // had to agree. The trigger moved in from the guide so that the whole contract sits in
31
+ // the description of the tool it belongs to.
32
+ return `Get the accepted values of a field of "${dataTitle}" that describeState marked "suggestions", optionally filtered by a query. A field whose values describeState already stated on its line as values=[...] needs no call — write one of them. Each option comes back with an index and a title; one whose value is not a short scalar is listed by title alone, exactly as a user sees it. To choose one, call setFieldValue with the same path and "suggestionIndex" set to its index, and the full original value is applied.`
45
33
  }
46
34
 
47
35
  /**
48
36
  * @param {import('../../state/index.js').StatefulLayout} statefulLayout
49
37
  * @param {{ path: string, query?: string }} args
50
- * @returns {Promise<{items: Array<{value: unknown, title: string, key?: string}>}>}
38
+ * @param {import('../suggestions-store.js').SuggestionsStore} [store] - memorizes the full items so that setFieldValue can apply one by index
39
+ * @returns {Promise<{items: Array<{value: unknown, title: string, key?: string}>, baseIndex: number}>}
51
40
  */
52
- export async function execute (statefulLayout, args) {
41
+ export async function execute (statefulLayout, args, store) {
53
42
  const node = resolveNode(statefulLayout.stateTree.root, args.path)
54
43
  if (!node) {
55
44
  throw new Error(`node not found at path: ${args.path}`)
@@ -61,7 +50,7 @@ export async function execute (statefulLayout, args) {
61
50
  const items = (oneOfItems || [])
62
51
  .filter((item) => !item.header)
63
52
  .map((item) => ({ value: item.key, title: item.title }))
64
- return { items }
53
+ return { items, baseIndex: store?.add(args.path, items, node.itemsCacheKey) ?? 0 }
65
54
  }
66
55
 
67
56
  const rawItems = await statefulLayout.getItems(node, args.query)
@@ -80,5 +69,5 @@ export async function execute (statefulLayout, args) {
80
69
  return result
81
70
  })
82
71
 
83
- return { items }
72
+ return { items, baseIndex: store?.add(args.path, items, node.itemsCacheKey) ?? 0 }
84
73
  }
@@ -2,57 +2,108 @@
2
2
  * @file setData tool
3
3
  */
4
4
 
5
- import { collectErrors } from '../project.js'
5
+ import { collectErrors, visibilitySnapshot, diffVisibility } from '../project.js'
6
6
 
7
7
  export const inputSchema = {
8
8
  type: 'object',
9
9
  properties: {
10
10
  data: {
11
11
  description: 'The form data object to set'
12
+ },
13
+ merge: {
14
+ type: 'boolean',
15
+ description: 'Merge the given keys into the existing data (default). Set false to replace the whole object, which removes every key you do not pass.'
12
16
  }
13
17
  },
14
18
  required: ['data']
15
19
  }
16
20
 
17
- export const outputSchema = {
18
- type: 'object',
19
- properties: {
20
- valid: { type: 'boolean' },
21
- errors: {
22
- type: 'array',
23
- items: {
24
- type: 'object',
25
- properties: {
26
- path: { type: 'string' },
27
- message: { type: 'string' }
28
- }
29
- }
30
- }
31
- }
32
- }
33
-
34
21
  /**
35
22
  * @param {string} dataTitle
36
- * @param {"small"|"medium"|"large"} [complexity]
37
23
  * @returns {string}
38
24
  */
39
- export function getDescription (dataTitle, complexity) {
40
- if (complexity === 'large') {
41
- return `Set all "${dataTitle}" data at once. For complex forms, prefer setFieldValue for incremental changes.`
42
- }
43
- return `Set all "${dataTitle}" data at once. Best for simple forms. Check errors in the response, use describeState if you need the full form structure.`
25
+ export function getDescription (dataTitle) {
26
+ return `Set all "${dataTitle}" data at once, for when you already know every value. Prefer setFieldValue to change one field. Check the errors in the response.`
27
+ }
28
+
29
+ /**
30
+ * Root-level data keys the form actually carries.
31
+ *
32
+ * Read from each node's dataPath rather than from the root's children, because the
33
+ * children of a composed schema are synthetic ($allOf-1, $comp-1) and carry no data
34
+ * key of their own — the real property sits below them.
35
+ * @param {import('../../state/types.js').StateNode} node
36
+ * @param {Set<string>} [keys]
37
+ * @returns {Set<string>}
38
+ */
39
+ function collectRootDataKeys (node, keys = new Set()) {
40
+ const segments = (node.dataPath ?? '').split('/').filter(Boolean)
41
+ if (segments.length === 1) keys.add(segments[0])
42
+ for (const child of node.children ?? []) collectRootDataKeys(child, keys)
43
+ return keys
44
+ }
45
+
46
+ /**
47
+ * @param {unknown} value
48
+ * @returns {boolean}
49
+ */
50
+ function isPlainObject (value) {
51
+ return !!value && typeof value === 'object' && !Array.isArray(value)
44
52
  }
45
53
 
46
54
  /**
47
55
  * @param {import('../../state/index.js').StatefulLayout} statefulLayout
48
- * @param {{ data: unknown }} args
49
- * @returns {{ valid: boolean, errors: Array<{path: string, message: string}> }}
56
+ * @param {{ data: unknown, merge?: boolean }} args
57
+ * @returns {{ valid: boolean, written: string[], removed: string[], unknownKeys: string[], visibility?: { revealed: string[], hidden: string[] }, errors: Array<{path: string, message: string}> }}
50
58
  */
51
59
  export function execute (statefulLayout, args) {
52
- statefulLayout.data = args.data
60
+ const current = statefulLayout.data
61
+ const mergeable = isPlainObject(current) && isPlainObject(args.data)
62
+
63
+ /** @type {string[]} */
64
+ let removed = []
65
+ let next = args.data
66
+
67
+ if (mergeable) {
68
+ if (args.merge === false) {
69
+ // Replacement stays available, but never silently: a model that means "update the
70
+ // sections" and wipes the dataset, the title and every setting must at least be
71
+ // told what it removed. The form can be valid without those keys, so validity
72
+ // alone would report the amputation as a success.
73
+ removed = Object.keys(/** @type {Record<string, unknown>} */(current))
74
+ .filter((key) => !(key in /** @type {Record<string, unknown>} */(args.data)))
75
+ } else {
76
+ // Merging is the default because an agent asking to set some keys means to set
77
+ // those keys, not to delete everything else.
78
+ next = { ...(/** @type {Record<string, unknown>} */(current)), ...(/** @type {Record<string, unknown>} */(args.data)) }
79
+ }
80
+ }
81
+
82
+ // Same reason as setFieldValue: a written key can turn a condition true and unhide a
83
+ // section that nothing else in the answer would mention.
84
+ const visibleBefore = visibilitySnapshot(statefulLayout.stateTree.root)
85
+ statefulLayout.data = next
86
+
87
+ // Computed after applying the data so the tree reflects it: a key that activates a
88
+ // oneOf branch is only hydrated once written, and flagging it before would cry wolf.
89
+ // A warning rather than a rejection — ajv accepts the key because the schema does not
90
+ // close additionalProperties, and the form stays valid, so nothing else would say so.
91
+ const knownKeys = collectRootDataKeys(statefulLayout.stateTree.root)
92
+ const unknownKeys = isPlainObject(args.data)
93
+ ? Object.keys(/** @type {Record<string, unknown>} */(args.data)).filter((key) => !knownKeys.has(key))
94
+ : []
95
+
96
+ const visibility = diffVisibility(visibleBefore, visibilitySnapshot(statefulLayout.stateTree.root))
53
97
 
54
98
  return {
55
99
  valid: statefulLayout.valid,
56
- errors: collectErrors(statefulLayout.stateTree.root)
100
+ // Which keys landed. "valid, no errors" says the form is happy but nothing about what
101
+ // was stored, and contact's agent read that as a reason to spend a call on getData
102
+ // to see its own write. Keys only: the values can be a 12 KB dataset object.
103
+ written: isPlainObject(args.data) ? Object.keys(/** @type {Record<string, unknown>} */(args.data)) : [],
104
+ removed,
105
+ unknownKeys,
106
+ ...(visibility.revealed.length || visibility.hidden.length ? { visibility } : {}),
107
+ errors: collectErrors(statefulLayout)
57
108
  }
58
109
  }
@@ -2,7 +2,7 @@
2
2
  * @file setFieldValue tool
3
3
  */
4
4
 
5
- import { projectFieldResult, collectErrors } from '../project.js'
5
+ import { projectFieldResult, collectScopedErrors, projectNodeToMarkdown, visibilitySnapshot, diffVisibility } from '../project.js'
6
6
  import { resolveNode } from '../resolve.js'
7
7
 
8
8
  export const inputSchema = {
@@ -10,39 +10,17 @@ export const inputSchema = {
10
10
  properties: {
11
11
  path: {
12
12
  type: 'string',
13
- description: 'Path to the field (e.g. "/name", "/items/0/quantity")'
13
+ description: 'Node path as returned by describeState (e.g. "/address/city").'
14
14
  },
15
15
  value: {
16
- description: 'The value to set. For variant-selector fields, pass the variant index to switch variants.'
17
- }
18
- },
19
- required: ['path', 'value']
20
- }
21
-
22
- export const outputSchema = {
23
- type: 'object',
24
- properties: {
25
- valid: { type: 'boolean' },
26
- field: {
27
- type: 'object',
28
- properties: {
29
- path: { type: 'string' },
30
- type: { type: 'string' },
31
- data: {},
32
- error: { type: 'string' }
33
- }
16
+ description: 'The value to set. For variant-selector fields, pass the variant index to switch variants. Exclusive with "suggestionIndex".'
34
17
  },
35
- errors: {
36
- type: 'array',
37
- items: {
38
- type: 'object',
39
- properties: {
40
- path: { type: 'string' },
41
- message: { type: 'string' }
42
- }
43
- }
18
+ suggestionIndex: {
19
+ type: 'number',
20
+ description: 'Index from the last getFieldSuggestions call on this same path. Exclusive with "value".'
44
21
  }
45
- }
22
+ },
23
+ required: ['path']
46
24
  }
47
25
 
48
26
  /**
@@ -50,34 +28,66 @@ export const outputSchema = {
50
28
  * @returns {string}
51
29
  */
52
30
  export function getDescription (dataTitle) {
53
- return `Set the value of a specific field of "${dataTitle}" by path. For fields with suggestions, use the value returned by getFieldSuggestions. To switch a variant selector, set value to the desired variant index (shown in describeState).`
31
+ return `Set the value of a specific field of "${dataTitle}" by path. To switch a variant selector, set value to the desired variant index (shown in describeState); the answer then lists the fields of the branch it activated. The returned errors are scoped to the modified field.`
54
32
  }
55
33
 
56
34
  /**
57
35
  * @param {import('../../state/index.js').StatefulLayout} statefulLayout
58
- * @param {{ path: string, value: unknown }} args
59
- * @returns {{ valid: boolean, field: ReturnType<typeof projectFieldResult>, errors: Array<{path: string, message: string}> }}
36
+ * @param {{ path: string, value?: unknown, suggestionIndex?: number }} args
37
+ * @param {import('../suggestions-store.js').SuggestionsStore} [store]
38
+ * @param {import('../variants-memo.js').VariantsMemo} [variantsMemo] - the activated branch
39
+ * may nest the same union again; the memo keeps the response from printing it twice
40
+ * @returns {{ valid: boolean, field: ReturnType<typeof projectFieldResult>, errors: Array<{path: string, message: string}>, otherErrors: number, activatedMarkdown?: string, visibility?: { revealed: string[], hidden: string[] } }}
60
41
  */
61
- export function execute (statefulLayout, args) {
42
+ export function execute (statefulLayout, args, store, variantsMemo) {
62
43
  const node = resolveNode(statefulLayout.stateTree.root, args.path)
63
44
  if (!node) {
64
45
  throw new Error(`node not found at path: ${args.path}`)
65
46
  }
66
47
 
67
- if (node.key === '$oneOf' && typeof args.value === 'number') {
68
- statefulLayout.activateItem(node, args.value)
48
+ let value = args.value
49
+ if (args.suggestionIndex !== undefined) {
50
+ if (args.value !== undefined) {
51
+ throw new Error('value and suggestionIndex are exclusive, use only one of them')
52
+ }
53
+ if (!store) {
54
+ throw new Error('no suggestion memorized, call getFieldSuggestions first')
55
+ }
56
+ value = store.getValue(args.path, args.suggestionIndex)
57
+ } else if (args.value === undefined && !('value' in args)) {
58
+ throw new Error('value or suggestionIndex is required')
59
+ }
60
+
61
+ // A write can turn a condition true and unhide a whole section. Nothing else in the
62
+ // answer would say so: the node written reports itself, and the form goes on being
63
+ // valid, so an agent is left believing it is finished.
64
+ const visibleBefore = visibilitySnapshot(statefulLayout.stateTree.root)
65
+
66
+ let activating = false
67
+ if (node.key === '$oneOf' && typeof value === 'number') {
68
+ activating = true
69
+ statefulLayout.activateItem(node, value)
69
70
  } else {
70
- statefulLayout.input(node, args.value)
71
+ statefulLayout.input(node, value)
71
72
  statefulLayout.blur(node)
72
73
  }
73
74
 
74
75
  // Re-resolve node from updated state tree
75
76
  const updatedNode = resolveNode(statefulLayout.stateTree.root, args.path)
76
- const errors = collectErrors(statefulLayout.stateTree.root)
77
+ const { errors, otherErrors } = collectScopedErrors(statefulLayout, updatedNode || node)
78
+
79
+ // Switching a variant replaces a whole subtree, so answering with only the value that
80
+ // was written leaves the agent knowing a branch appeared but not what is in it. This
81
+ // mirrors what editArray already does for an item it activates.
82
+ const activated = activating ? (updatedNode || node).children?.[0] : undefined
83
+ const visibility = diffVisibility(visibleBefore, visibilitySnapshot(statefulLayout.stateTree.root))
77
84
 
78
85
  return {
79
86
  valid: statefulLayout.valid,
80
87
  field: projectFieldResult(updatedNode || node, statefulLayout),
81
- errors
88
+ errors,
89
+ otherErrors,
90
+ ...(visibility.revealed.length || visibility.hidden.length ? { visibility } : {}),
91
+ ...(activated ? { activatedMarkdown: projectNodeToMarkdown(activated, statefulLayout, 0, undefined, variantsMemo) } : {})
82
92
  }
83
93
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file Remembers which variant lists have already been sent to the agent.
3
+ *
4
+ * A discriminated union is a constant: the 39 branches of a portal page element are the
5
+ * same 39 whether they are reached at /elements/0 or at /elements/0/.../children2/0. The
6
+ * markdown projection used to print all of them every time one of those nodes appeared,
7
+ * and on a recursive schema that is most of the response — measured on the portal-page
8
+ * eval case, three emissions of one list were 4.45 KB of a 10.8 KB session, and the agent
9
+ * read it once and used it once.
10
+ *
11
+ * The memo is keyed on the SKELETON POINTER rather than the data path, which is what makes
12
+ * it catch recursion: every one of those nodes resolves to
13
+ * `page-config-simple#/$defs/element/oneOf`. It records where the list was first printed so
14
+ * a later response can point the agent back at it in its own transcript.
15
+ *
16
+ * It is never cleared on a write: unlike memorized suggestions, a schema's branches cannot
17
+ * be invalidated by editing the data. `describeState` projects into a fresh memo and merges
18
+ * it in afterwards, so a full read always prints every list once and stays authoritative.
19
+ */
20
+ export class VariantsMemo {
21
+ /**
22
+ * first path each pointer's variant list was printed at
23
+ * @type {Map<string, string>}
24
+ */
25
+ _listedAt = new Map()
26
+
27
+ /**
28
+ * @param {string} pointer - skeleton pointer of the one-of-select node
29
+ * @returns {string | undefined} the path it was first listed at, or undefined if never
30
+ */
31
+ listedAt (pointer) {
32
+ return this._listedAt.get(pointer)
33
+ }
34
+
35
+ /**
36
+ * @param {string} pointer
37
+ * @param {string} path
38
+ */
39
+ record (pointer, path) {
40
+ if (!this._listedAt.has(pointer)) this._listedAt.set(pointer, path)
41
+ }
42
+
43
+ /**
44
+ * @param {VariantsMemo} other
45
+ */
46
+ merge (other) {
47
+ for (const [pointer, path] of other._listedAt) this.record(pointer, path)
48
+ }
49
+
50
+ clear () {
51
+ this._listedAt.clear()
52
+ }
53
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,iCAJW,MAAM,mBACN,qBAAqB,GACnB,cAAc,CAuH1B;;;;2BAvIY,OAAO,YAAY,EAAE,YAAY;2BACjC,OAAO,YAAY,EAAE,YAAY;6BACjC,OAAO,YAAY,EAAE,cAAc;6BACnC,OAAO,YAAY,EAAE,cAAc;oCACnC,OAAO,YAAY,EAAE,qBAAqB;iCAC1C,OAAO,YAAY,EAAE,kBAAkB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compile/index.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,iCAJW,MAAM,mBACN,qBAAqB,GACnB,cAAc,CAyH1B;;;;2BAzIY,OAAO,YAAY,EAAE,YAAY;2BACjC,OAAO,YAAY,EAAE,YAAY;6BACjC,OAAO,YAAY,EAAE,cAAc;6BACnC,OAAO,YAAY,EAAE,cAAc;oCACnC,OAAO,YAAY,EAAE,qBAAqB;iCAC1C,OAAO,YAAY,EAAE,kBAAkB"}
@@ -11,11 +11,18 @@
11
11
  * @param {import('@json-layout/vocabulary').Expression[]} expressions
12
12
  * @param {string | number} key
13
13
  * @param {string} pointer
14
- * @param {boolean} required
14
+ * @param {boolean} required - the schema makes this node's value mandatory: omitting it is
15
+ * a validation error. This is what `node.required` reports and what a UI marks with an
16
+ * asterisk, so it must never be true for a node the schema is happy to see absent.
15
17
  * @param {string} [condition]
16
18
  * @param {boolean} [dependent]
17
19
  * @param {string} [knownType]
20
+ * @param {boolean} [alwaysPresent] - the node's value is materialized whether or not the
21
+ * schema requires it, because its parent renders it as a fixed slot. Drives default and
22
+ * empty-container application only. Defaults to `required`, which is the same thing for
23
+ * every parent that builds its children from what the schema demands; tuple entries are
24
+ * the exception, always present but only required up to `minItems`.
18
25
  * @returns {import('./types.js').SkeletonNode}
19
26
  */
20
- export function makeSkeletonNode(rawSchema: any, sourceSchemaId: string, options: import("./index.js").CompileOptions, getJSONRef: (schemaId: string, ref: string) => [any, string, string], skeletonTrees: Record<string, import("./types.js").SkeletonTree>, skeletonNodes: Record<string, import("./types.js").SkeletonNode>, validatePointers: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import("@json-layout/vocabulary").NormalizedLayout>, expressions: import("@json-layout/vocabulary").Expression[], key: string | number, pointer: string, required: boolean, condition?: string, dependent?: boolean, knownType?: string): import("./types.js").SkeletonNode;
27
+ export function makeSkeletonNode(rawSchema: any, sourceSchemaId: string, options: import("./index.js").CompileOptions, getJSONRef: (schemaId: string, ref: string) => [any, string, string], skeletonTrees: Record<string, import("./types.js").SkeletonTree>, skeletonNodes: Record<string, import("./types.js").SkeletonNode>, validatePointers: string[], validationErrors: Record<string, string[]>, normalizedLayouts: Record<string, import("@json-layout/vocabulary").NormalizedLayout>, expressions: import("@json-layout/vocabulary").Expression[], key: string | number, pointer: string, required: boolean, condition?: string, dependent?: boolean, knownType?: string, alwaysPresent?: boolean): import("./types.js").SkeletonNode;
21
28
  //# sourceMappingURL=skeleton-node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skeleton-node.d.ts","sourceRoot":"","sources":["../../src/compile/skeleton-node.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;GAkBG;AACH,4CAlBW,GAAG,kBACH,MAAM,WACN,OAAO,YAAY,EAAE,cAAc,cACnC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,iBACxD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,iBACjD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,oBACjD,MAAM,EAAE,oBACR,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,qBACxB,MAAM,CAAC,MAAM,EAAE,OAAO,yBAAyB,EAAE,gBAAgB,CAAC,eAClE,OAAO,yBAAyB,EAAE,UAAU,EAAE,OAC9C,MAAM,GAAG,MAAM,WACf,MAAM,YACN,OAAO,cACP,MAAM,cACN,OAAO,cACP,MAAM,GACJ,OAAO,YAAY,EAAE,YAAY,CA6jB7C"}
1
+ {"version":3,"file":"skeleton-node.d.ts","sourceRoot":"","sources":["../../src/compile/skeleton-node.js"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,4CAzBW,GAAG,kBACH,MAAM,WACN,OAAO,YAAY,EAAE,cAAc,cACnC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,iBACxD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,iBACjD,MAAM,CAAC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC,oBACjD,MAAM,EAAE,oBACR,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,qBACxB,MAAM,CAAC,MAAM,EAAE,OAAO,yBAAyB,EAAE,gBAAgB,CAAC,eAClE,OAAO,yBAAyB,EAAE,UAAU,EAAE,OAC9C,MAAM,GAAG,MAAM,WACf,MAAM,YACN,OAAO,cAGP,MAAM,cACN,OAAO,cACP,MAAM,kBACN,OAAO,GAKL,OAAO,YAAY,EAAE,YAAY,CAukB7C"}
@@ -57,5 +57,6 @@ export interface SkeletonNode {
57
57
  discriminator?: string;
58
58
  required?: boolean;
59
59
  nullable?: boolean;
60
+ constraints?: Record<string, unknown>;
60
61
  }
61
62
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compile/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compile/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-refs.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/resolve-refs.js"],"names":[],"mappings":"AAyBA;;;;;;;GAOG;AACH,0CANW,OAAO,KAAK,EAAE,YAAY,OAC1B,OAAO,kBAAkB,EAAE,OAAO,WAClC,MAAM,kBACN,MAAM,GACJ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CASpE;AAuCD;;;;;GAKG;AACH,2CAJW,OAAO,KAAK,EAAE,YAAY,YAC1B,MAAM,cACN,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,OA+ClE"}
1
+ {"version":3,"file":"resolve-refs.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/resolve-refs.js"],"names":[],"mappings":"AAsBA;;;;;;;GAOG;AACH,0CANW,OAAO,KAAK,EAAE,YAAY,OAC1B,OAAO,kBAAkB,EAAE,OAAO,WAClC,MAAM,kBACN,MAAM,GACJ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CASpE;AAuCD;;;;;GAKG;AACH,2CAJW,OAAO,KAAK,EAAE,YAAY,YAC1B,MAAM,cACN,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,OA+ClE"}
@@ -1,2 +1,2 @@
1
- export function resolveXI18n(schema: Record<string, any>, locale: string, defaultLocale?: string): void;
1
+ export function resolveXI18n(schema: Record<string, any>, locale: string, defaultLocale?: string, apply?: boolean): void;
2
2
  //# sourceMappingURL=x-i18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"x-i18n.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/x-i18n.js"],"names":[],"mappings":"AAOO,qCAJI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UACnB,MAAM,kBACN,MAAM,QAkBhB"}
1
+ {"version":3,"file":"x-i18n.d.ts","sourceRoot":"","sources":["../../../src/compile/utils/x-i18n.js"],"names":[],"mappings":"AAQO,qCALI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UACnB,MAAM,kBACN,MAAM,UACN,OAAO,QA0BjB"}
@@ -129,6 +129,16 @@ export class StatefulLayout {
129
129
  * @type {CreateStateTreeContext}
130
130
  */
131
131
  private _lastCreateStateTreeContext;
132
+ /**
133
+ * The raw validation errors of the last state update, each carrying the data pointer
134
+ * (instancePath) it applies to.
135
+ *
136
+ * A node only carries an error when it is hydrated, so an error below an unhydrated
137
+ * subtree — a list item shown in summary mode, say — has no node to attach to and
138
+ * collapses onto the nearest ancestor. These keep the precise location.
139
+ * @returns {import('ajv').ErrorObject[]}
140
+ */
141
+ get validationErrors(): import("ajv").ErrorObject[];
132
142
  /**
133
143
  * @private
134
144
  * @type {string | null}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/state/index.js"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"state-node.d.ts","sourceRoot":"","sources":["../../src/state/state-node.js"],"names":[],"mappings":"AAkRA;;;;;;;;;;;GAWG;AACH,4CAXW,OAAO,aAAa,EAAE,kBAAkB,EAAE,cAC1C,OAAO,yBAAyB,EAAE,UAAU,QAC5C,GAAG,WACH,OAAO,YAAY,EAAE,gBAAgB,WACrC,OAAO,oBAAoB,EAAE,OAAO,UACpC,OAAO,yBAAyB,EAAE,cAAc,aAChD,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,gBAAgB,CAAC,YAC9C,OAAO,iBACP,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,GAC1D,GAAG,CAsBf;AAiCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,yCAlBW,OAAO,YAAY,EAAE,sBAAsB,iBAC3C,OAAO,YAAY,EAAE,gBAAgB,kBACrC,OAAO,aAAa,EAAE,cAAc,OACpC,MAAM,GAAG,MAAM,WACf,MAAM,iBACN,MAAM,GAAG,IAAI,YACb,MAAM,kBACN,MAAM,GAAG,IAAI,YACb,OAAO,aAAa,EAAE,YAAY,mBAClC,OAAO,yBAAyB,EAAE,KAAK,GAAG,IAAI,iBAC9C,OAAO,oBAAoB,EAAE,OAAO,QACpC,GAAG,iBACH,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,mBAC5D,OAAO,YAAY,EAAE,eAAe,cACpC,MAAM,eACN,OAAO,YAAY,EAAE,SAAS,GAC5B,OAAO,YAAY,EAAE,SAAS,CAipB1C;AAx9BM,qCALI,OAAO,UACP,OAAO,yBAAyB,EAAE,cAAc,WAChD,OAAO,YAAY,EAAE,gBAAgB,GACnC,OAAO,CAMnB;AAs9BD,uFAAuF;AACvF,iCADW,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,KAAK,GAAG,CAgBjF;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,8BAFU,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO,KAAK,GAAG,CAkC5M"}
1
+ {"version":3,"file":"state-node.d.ts","sourceRoot":"","sources":["../../src/state/state-node.js"],"names":[],"mappings":"AAkRA;;;;;;;;;;;GAWG;AACH,4CAXW,OAAO,aAAa,EAAE,kBAAkB,EAAE,cAC1C,OAAO,yBAAyB,EAAE,UAAU,QAC5C,GAAG,WACH,OAAO,YAAY,EAAE,gBAAgB,WACrC,OAAO,oBAAoB,EAAE,OAAO,UACpC,OAAO,yBAAyB,EAAE,cAAc,aAChD,MAAM,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,gBAAgB,CAAC,YAC9C,OAAO,iBACP,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,GAC1D,GAAG,CAsBf;AA0CD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,yCAlBW,OAAO,YAAY,EAAE,sBAAsB,iBAC3C,OAAO,YAAY,EAAE,gBAAgB,kBACrC,OAAO,aAAa,EAAE,cAAc,OACpC,MAAM,GAAG,MAAM,WACf,MAAM,iBACN,MAAM,GAAG,IAAI,YACb,MAAM,kBACN,MAAM,GAAG,IAAI,YACb,OAAO,aAAa,EAAE,YAAY,mBAClC,OAAO,yBAAyB,EAAE,KAAK,GAAG,IAAI,iBAC9C,OAAO,oBAAoB,EAAE,OAAO,QACpC,GAAG,iBACH,OAAO,qBAAqB,EAAE,uBAAuB,GAAG,IAAI,mBAC5D,OAAO,YAAY,EAAE,eAAe,cACpC,MAAM,eACN,OAAO,YAAY,EAAE,SAAS,GAC5B,OAAO,YAAY,EAAE,SAAS,CAipB1C;AAj+BM,qCALI,OAAO,UACP,OAAO,yBAAyB,EAAE,cAAc,WAChD,OAAO,YAAY,EAAE,gBAAgB,GACnC,OAAO,CAMnB;AA+9BD,uFAAuF;AACvF,iCADW,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,KAAK,GAAG,CAgBjF;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,8BAFU,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,aAAa,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,yBAAyB,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,OAAO,KAAK,GAAG,CAkC5M"}
@@ -1 +1 @@
1
- {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../../src/state/utils/urls.js"],"names":[],"mappings":"AAEO,6BAA4B,MAAM,WAAoB,MAAM,OAIlE"}
1
+ {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../../src/state/utils/urls.js"],"names":[],"mappings":"AAEO,6BAA4B,MAAM,WAAoB,MAAM,OAMlE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @file JSON pointer traversal, shared by the compilation step and the webmcp tools
3
+ * @description Pointers are produced by concatenation in the compilation step
4
+ * (`${refPointerPrefix}/properties/${propertyKey}` and similar), their segments are
5
+ * therefore consumed raw: they are deliberately not unescaped as RFC 6901 would
6
+ * prescribe, so that resolution stays symmetric with the way pointers are built.
7
+ */
8
+ /**
9
+ * Resolve the fragment part of a JSON pointer (what follows the '#') in a schema or any object.
10
+ * @param {unknown} root
11
+ * @param {string} fragment - e.g. '/properties/address/items', leading and empty segments are ignored
12
+ * @returns {{found: true, value: unknown} | {found: false, path: string[]}} - the resolved value, or
13
+ * the segments consumed up to and including the missing one, to report where the resolution failed
14
+ */
15
+ export function resolvePointerFragment(root: unknown, fragment: string): {
16
+ found: true;
17
+ value: unknown;
18
+ } | {
19
+ found: false;
20
+ path: string[];
21
+ };
22
+ //# sourceMappingURL=json-pointer.d.ts.map