@plitzi/sdk-server 0.32.5 → 0.32.7

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 (175) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/core/services/mcp.js +1 -1
  3. package/dist/helpers/buildServerInfo.js +3 -9
  4. package/dist/index.js +2 -1
  5. package/dist/modules/ai/toolkit.js +1 -0
  6. package/dist/modules/mcp/catalogs/builtinCallbacks.js +204 -0
  7. package/dist/modules/mcp/catalogs/builtinComponents.js +170 -0
  8. package/dist/modules/mcp/catalogs/builtinElementCallbacks.js +50 -0
  9. package/dist/modules/mcp/catalogs/builtinTransformers.js +148 -0
  10. package/dist/modules/mcp/catalogs/builtinUtilities.js +90 -0
  11. package/dist/modules/mcp/{tools/operations/style → catalogs}/cssCatalog.js +75 -2
  12. package/dist/modules/mcp/catalogs/observed.js +90 -0
  13. package/dist/modules/mcp/catalogs/paramSpec.js +69 -0
  14. package/dist/modules/mcp/catalogs/registry.js +89 -0
  15. package/dist/modules/mcp/handler.js +41 -13
  16. package/dist/modules/mcp/helpers/agentPrompt.js +104 -0
  17. package/dist/modules/mcp/helpers/guide.js +334 -15
  18. package/dist/modules/mcp/helpers/interactions.js +123 -0
  19. package/dist/modules/mcp/helpers/log.js +54 -0
  20. package/dist/modules/mcp/helpers/space.js +184 -33
  21. package/dist/modules/mcp/helpers/uris.js +44 -0
  22. package/dist/modules/mcp/resources/canonical.js +6 -21
  23. package/dist/modules/mcp/resources/core.js +4 -3
  24. package/dist/modules/mcp/resources/primer.js +13 -8
  25. package/dist/modules/mcp/resources/register.js +37 -5
  26. package/dist/modules/mcp/resources/schema.js +30 -20
  27. package/dist/modules/mcp/resources/style.js +18 -11
  28. package/dist/modules/mcp/server.js +29 -8
  29. package/dist/modules/mcp/tools/apply/dispatch.js +38 -18
  30. package/dist/modules/mcp/tools/apply/index.js +19 -4
  31. package/dist/modules/mcp/tools/apply/writeResult.js +2 -1
  32. package/dist/modules/mcp/tools/index.js +3 -1
  33. package/dist/modules/mcp/tools/operations/index.js +13 -2
  34. package/dist/modules/mcp/tools/operations/schema/bindings/deleteBinding.js +32 -0
  35. package/dist/modules/mcp/tools/operations/schema/bindings/patchBinding.js +36 -0
  36. package/dist/modules/mcp/tools/operations/schema/bindings/upsertBinding.js +47 -0
  37. package/dist/modules/mcp/tools/operations/schema/{deleteElement.js → elements/deleteElement.js} +10 -6
  38. package/dist/modules/mcp/tools/operations/schema/{moveElement.js → elements/moveElement.js} +8 -6
  39. package/dist/modules/mcp/tools/operations/schema/{patchElement.js → elements/patchElement.js} +19 -7
  40. package/dist/modules/mcp/tools/operations/schema/{upsertElement.js → elements/upsertElement.js} +11 -5
  41. package/dist/modules/mcp/tools/operations/schema/{deleteFolder.js → folders/deleteFolder.js} +4 -4
  42. package/dist/modules/mcp/tools/operations/schema/{upsertFolder.js → folders/upsertFolder.js} +4 -4
  43. package/dist/modules/mcp/tools/operations/schema/interactions/deleteInteraction.js +52 -0
  44. package/dist/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.js +47 -0
  45. package/dist/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.js +43 -0
  46. package/dist/modules/mcp/tools/operations/schema/operations.js +25 -11
  47. package/dist/modules/mcp/tools/operations/schema/{deletePage.js → pages/deletePage.js} +8 -5
  48. package/dist/modules/mcp/tools/operations/schema/pages/upsertPage.js +75 -0
  49. package/dist/modules/mcp/tools/operations/schema/settings/patchSettings.js +45 -0
  50. package/dist/modules/mcp/tools/operations/schema/shared.js +94 -2
  51. package/dist/modules/mcp/tools/operations/schema/translator.js +77 -10
  52. package/dist/modules/mcp/tools/operations/schema/{deleteVariable.js → variables/deleteVariable.js} +3 -3
  53. package/dist/modules/mcp/tools/operations/schema/{upsertVariable.js → variables/upsertVariable.js} +4 -4
  54. package/dist/modules/mcp/tools/operations/schema/write.js +78 -13
  55. package/dist/modules/mcp/tools/operations/style/{deleteDefinition.js → definitions/deleteDefinition.js} +4 -3
  56. package/dist/modules/mcp/tools/operations/style/{patchDefinition.js → definitions/patchDefinition.js} +6 -5
  57. package/dist/modules/mcp/tools/operations/style/{upsertDefinition.js → definitions/upsertDefinition.js} +5 -4
  58. package/dist/modules/mcp/tools/operations/style/{deleteGlobalStyle.js → globalStyles/deleteGlobalStyle.js} +4 -3
  59. package/dist/modules/mcp/tools/operations/style/{patchGlobalStyle.js → globalStyles/patchGlobalStyle.js} +6 -5
  60. package/dist/modules/mcp/tools/operations/style/{upsertGlobalStyle.js → globalStyles/upsertGlobalStyle.js} +5 -4
  61. package/dist/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.js +21 -0
  62. package/dist/modules/mcp/tools/operations/style/idStyles/patchIdStyle.js +28 -0
  63. package/dist/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.js +24 -0
  64. package/dist/modules/mcp/tools/operations/style/operations.js +14 -8
  65. package/dist/modules/mcp/tools/operations/style/translator.js +25 -1
  66. package/dist/modules/mcp/tools/operations/style/{deleteStyleVariable.js → variables/deleteStyleVariable.js} +4 -4
  67. package/dist/modules/mcp/tools/operations/style/{upsertStyleVariable.js → variables/upsertStyleVariable.js} +4 -4
  68. package/dist/modules/mcp/tools/operations/style/write.js +19 -11
  69. package/dist/modules/mcp/tools/read.js +1 -1
  70. package/dist/modules/mcp/tools/render.js +114 -0
  71. package/dist/modules/mcp/tools/search.js +34 -27
  72. package/dist/modules/mcp/tools/shared/tool.js +1 -0
  73. package/dist/modules/mcp/tools/shared/validator/audit.js +124 -0
  74. package/dist/modules/mcp/tools/shared/validator/batch.js +30 -0
  75. package/dist/modules/mcp/tools/shared/validator/bindings.js +70 -0
  76. package/dist/modules/mcp/tools/shared/validator/context.js +35 -0
  77. package/dist/modules/mcp/tools/shared/validator/css.js +47 -0
  78. package/dist/modules/mcp/tools/shared/validator/elements.js +55 -0
  79. package/dist/modules/mcp/tools/shared/validator/index.js +226 -0
  80. package/dist/modules/mcp/tools/shared/validator/interactions.js +106 -0
  81. package/dist/modules/mcp/tools/shared/validator/refs.js +28 -0
  82. package/dist/modules/mcp/tools/validate.js +23 -3
  83. package/dist/modules/ssr/preview.js +1 -1
  84. package/dist/modules/ssr/views/template.ejs +2 -0
  85. package/dist/src/index.d.ts +1 -1
  86. package/dist/src/modules/mcp/catalogs/builtinCallbacks.d.ts +23 -0
  87. package/dist/src/modules/mcp/catalogs/builtinComponents.d.ts +4 -0
  88. package/dist/src/modules/mcp/catalogs/builtinElementCallbacks.d.ts +20 -0
  89. package/dist/src/modules/mcp/catalogs/builtinTransformers.d.ts +28 -0
  90. package/dist/src/modules/mcp/catalogs/builtinTransformers.test.d.ts +1 -0
  91. package/dist/src/modules/mcp/catalogs/builtinUtilities.d.ts +18 -0
  92. package/dist/src/modules/mcp/{tools/operations/style → catalogs}/cssCatalog.d.ts +5 -1
  93. package/dist/src/modules/mcp/catalogs/index.d.ts +9 -0
  94. package/dist/src/modules/mcp/catalogs/observed.d.ts +48 -0
  95. package/dist/src/modules/mcp/catalogs/paramSpec.d.ts +42 -0
  96. package/dist/src/modules/mcp/catalogs/registry.d.ts +35 -0
  97. package/dist/src/modules/mcp/handler.d.ts +2 -2
  98. package/dist/src/modules/mcp/helpers/agentPrompt.d.ts +4 -0
  99. package/dist/src/modules/mcp/helpers/guide.d.ts +2 -1
  100. package/dist/src/modules/mcp/helpers/index.d.ts +4 -0
  101. package/dist/src/modules/mcp/helpers/interactions.d.ts +30 -0
  102. package/dist/src/modules/mcp/helpers/log.d.ts +8 -0
  103. package/dist/src/modules/mcp/helpers/log.test.d.ts +1 -0
  104. package/dist/src/modules/mcp/helpers/space.d.ts +68 -11
  105. package/dist/src/modules/mcp/helpers/uris.d.ts +28 -0
  106. package/dist/src/modules/mcp/index.d.ts +1 -1
  107. package/dist/src/modules/mcp/mcp.bench.d.ts +1 -0
  108. package/dist/src/modules/mcp/resources/canonical.d.ts +0 -1
  109. package/dist/src/modules/mcp/resources/index.d.ts +2 -3
  110. package/dist/src/modules/mcp/resources/primer.d.ts +2 -1
  111. package/dist/src/modules/mcp/resources/register.d.ts +2 -2
  112. package/dist/src/modules/mcp/server.d.ts +5 -2
  113. package/dist/src/modules/mcp/tools/apply/index.d.ts +191 -2
  114. package/dist/src/modules/mcp/tools/index.d.ts +1 -0
  115. package/dist/src/modules/mcp/tools/operations/index.d.ts +383 -4
  116. package/dist/src/modules/mcp/tools/operations/schema/bindings/deleteBinding.d.ts +17 -0
  117. package/dist/src/modules/mcp/tools/operations/schema/bindings/patchBinding.d.ts +25 -0
  118. package/dist/src/modules/mcp/tools/operations/schema/bindings/upsertBinding.d.ts +27 -0
  119. package/dist/src/modules/mcp/tools/operations/schema/{deleteElement.d.ts → elements/deleteElement.d.ts} +2 -2
  120. package/dist/src/modules/mcp/tools/operations/schema/{moveElement.d.ts → elements/moveElement.d.ts} +2 -2
  121. package/dist/src/modules/mcp/tools/operations/schema/{patchElement.d.ts → elements/patchElement.d.ts} +7 -2
  122. package/dist/src/modules/mcp/tools/operations/schema/{upsertElement.d.ts → elements/upsertElement.d.ts} +3 -3
  123. package/dist/src/modules/mcp/tools/operations/schema/{deleteFolder.d.ts → folders/deleteFolder.d.ts} +2 -2
  124. package/dist/src/modules/mcp/tools/operations/schema/{upsertFolder.d.ts → folders/upsertFolder.d.ts} +2 -2
  125. package/dist/src/modules/mcp/tools/operations/schema/index.d.ts +17 -11
  126. package/dist/src/modules/mcp/tools/operations/schema/interactions/deleteInteraction.d.ts +12 -0
  127. package/dist/src/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.d.ts +18 -0
  128. package/dist/src/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.d.ts +27 -0
  129. package/dist/src/modules/mcp/tools/operations/schema/operations.d.ts +131 -0
  130. package/dist/src/modules/mcp/tools/operations/schema/{deletePage.d.ts → pages/deletePage.d.ts} +2 -2
  131. package/dist/src/modules/mcp/tools/operations/schema/{upsertPage.d.ts → pages/upsertPage.d.ts} +3 -2
  132. package/dist/src/modules/mcp/tools/operations/schema/settings/patchSettings.d.ts +34 -0
  133. package/dist/src/modules/mcp/tools/operations/schema/shared.d.ts +53 -0
  134. package/dist/src/modules/mcp/tools/operations/schema/translator.d.ts +5 -2
  135. package/dist/src/modules/mcp/tools/operations/schema/{deleteVariable.d.ts → variables/deleteVariable.d.ts} +2 -2
  136. package/dist/src/modules/mcp/tools/operations/schema/{upsertVariable.d.ts → variables/upsertVariable.d.ts} +2 -2
  137. package/dist/src/modules/mcp/tools/operations/schema/write.d.ts +38 -8
  138. package/dist/src/modules/mcp/tools/operations/style/{deleteDefinition.d.ts → definitions/deleteDefinition.d.ts} +2 -2
  139. package/dist/src/modules/mcp/tools/operations/style/{patchDefinition.d.ts → definitions/patchDefinition.d.ts} +2 -2
  140. package/dist/src/modules/mcp/tools/operations/style/{upsertDefinition.d.ts → definitions/upsertDefinition.d.ts} +2 -2
  141. package/dist/src/modules/mcp/tools/operations/style/{deleteGlobalStyle.d.ts → globalStyles/deleteGlobalStyle.d.ts} +2 -2
  142. package/dist/src/modules/mcp/tools/operations/style/{patchGlobalStyle.d.ts → globalStyles/patchGlobalStyle.d.ts} +2 -2
  143. package/dist/src/modules/mcp/tools/operations/style/{upsertGlobalStyle.d.ts → globalStyles/upsertGlobalStyle.d.ts} +2 -2
  144. package/dist/src/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.d.ts +9 -0
  145. package/dist/src/modules/mcp/tools/operations/style/idStyles/patchIdStyle.d.ts +37 -0
  146. package/dist/src/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.d.ts +37 -0
  147. package/dist/src/modules/mcp/tools/operations/style/index.d.ts +11 -9
  148. package/dist/src/modules/mcp/tools/operations/style/operations.d.ts +70 -2
  149. package/dist/src/modules/mcp/tools/operations/style/shared.d.ts +1 -1
  150. package/dist/src/modules/mcp/tools/operations/style/translator.d.ts +4 -1
  151. package/dist/src/modules/mcp/tools/operations/style/{deleteStyleVariable.d.ts → variables/deleteStyleVariable.d.ts} +3 -3
  152. package/dist/src/modules/mcp/tools/operations/style/{upsertStyleVariable.d.ts → variables/upsertStyleVariable.d.ts} +3 -3
  153. package/dist/src/modules/mcp/tools/operations/style/write.d.ts +2 -7
  154. package/dist/src/modules/mcp/tools/preview.d.ts +191 -2
  155. package/dist/src/modules/mcp/tools/render.d.ts +434 -0
  156. package/dist/src/modules/mcp/tools/render.test.d.ts +1 -0
  157. package/dist/src/modules/mcp/tools/screenshot.d.ts +191 -2
  158. package/dist/src/modules/mcp/tools/shared/tool.d.ts +4 -0
  159. package/dist/src/modules/mcp/tools/shared/validator/audit.d.ts +4 -0
  160. package/dist/src/modules/mcp/tools/shared/validator/batch.d.ts +5 -0
  161. package/dist/src/modules/mcp/tools/shared/validator/bindings.d.ts +6 -0
  162. package/dist/src/modules/mcp/tools/shared/validator/context.d.ts +34 -0
  163. package/dist/src/modules/mcp/tools/shared/validator/css.d.ts +4 -0
  164. package/dist/src/modules/mcp/tools/shared/validator/elements.d.ts +6 -0
  165. package/dist/src/modules/mcp/tools/shared/validator/index.d.ts +8 -0
  166. package/dist/src/modules/mcp/tools/shared/validator/interactions.d.ts +3 -0
  167. package/dist/src/modules/mcp/tools/shared/validator/refs.d.ts +4 -0
  168. package/dist/src/modules/mcp/tools/validate.d.ts +191 -2
  169. package/dist/src/modules/mcp/types/aiSchema.d.ts +93 -1
  170. package/package.json +12 -10
  171. package/dist/modules/mcp/tools/operations/schema/registry.js +0 -55
  172. package/dist/modules/mcp/tools/operations/schema/upsertPage.js +0 -64
  173. package/dist/modules/mcp/tools/shared/validator.js +0 -262
  174. package/dist/src/modules/mcp/tools/operations/schema/registry.d.ts +0 -22
  175. package/dist/src/modules/mcp/tools/shared/validator.d.ts +0 -4
@@ -0,0 +1,90 @@
1
+ import { reconcileParams } from "./paramSpec.js";
2
+ //#region src/modules/mcp/catalogs/builtinUtilities.ts
3
+ var BUILTIN_UTILITIES = {
4
+ delayTime: {
5
+ title: "Delay Time",
6
+ strictParams: true,
7
+ params: { time: {
8
+ type: "number",
9
+ description: "Milliseconds to wait before the next step runs. The key is \"time\" (not \"delay\")."
10
+ } }
11
+ },
12
+ twigTemplate: {
13
+ title: "Twig Template",
14
+ strictParams: true,
15
+ params: {
16
+ returnMode: {
17
+ type: "select",
18
+ description: "How the rendered template is returned.",
19
+ default: "text",
20
+ options: [
21
+ "text",
22
+ "json",
23
+ "jsonObject"
24
+ ]
25
+ },
26
+ template: {
27
+ type: "textarea",
28
+ description: "The Twig template string to render against the flow/global params."
29
+ }
30
+ }
31
+ },
32
+ webHook: {
33
+ title: "Webhook",
34
+ strictParams: true,
35
+ params: {
36
+ url: {
37
+ type: "text",
38
+ description: "The URL to call."
39
+ },
40
+ method: {
41
+ type: "select",
42
+ description: "HTTP method.",
43
+ default: "get",
44
+ options: [
45
+ "get",
46
+ "post",
47
+ "put",
48
+ "delete",
49
+ "patch",
50
+ "head"
51
+ ]
52
+ },
53
+ body: {
54
+ type: "textarea",
55
+ description: "Request body."
56
+ },
57
+ authorizationToken: {
58
+ type: "text",
59
+ description: "Value sent as the Authorization header."
60
+ },
61
+ credentials: {
62
+ type: "select",
63
+ description: "fetch credentials mode.",
64
+ default: "same-origin",
65
+ options: [
66
+ "include",
67
+ "omit",
68
+ "same-origin"
69
+ ]
70
+ }
71
+ }
72
+ }
73
+ };
74
+ /** The built-in utility for an action, or undefined when the action is not a known built-in utility. */
75
+ var getUtility = (action) => Object.hasOwn(BUILTIN_UTILITIES, action) ? BUILTIN_UTILITIES[action] : void 0;
76
+ /** Reconcile a `utility` action against the utility catalog: unknown keys dropped for a closed utility, then missing
77
+ * defaults filled. An unknown action yields unchanged params. */
78
+ var applyUtility = (action, params) => {
79
+ const utility = getUtility(action);
80
+ if (!utility) return {
81
+ known: false,
82
+ params
83
+ };
84
+ return {
85
+ known: true,
86
+ params: reconcileParams(params, utility.params, utility.strictParams)
87
+ };
88
+ };
89
+ //#endregion
90
+ export { BUILTIN_UTILITIES, applyUtility, getUtility };
@@ -1,5 +1,5 @@
1
1
  import styleConstants from "@plitzi/sdk-shared/style/styleConstants";
2
- //#region src/modules/mcp/tools/operations/style/cssCatalog.ts
2
+ //#region src/modules/mcp/catalogs/cssCatalog.ts
3
3
  /** Every kebab-case CSS property Plitzi's style engine understands. Values written to a definition
4
4
  * must use these exact keys — camelCase or unknown keys are rejected by the validator. */
5
5
  var cssProperties = Array.from(new Set(Object.values(styleConstants))).sort();
@@ -28,6 +28,79 @@ var splitTokens = (value) => {
28
28
  if (current) tokens.push(current);
29
29
  return tokens;
30
30
  };
31
+ var COMPOUND_SHORTHANDS = {
32
+ flex: [
33
+ "flex-grow",
34
+ "flex-shrink",
35
+ "flex-basis"
36
+ ],
37
+ "flex-flow": ["flex-direction", "flex-wrap"],
38
+ background: [
39
+ "background-color",
40
+ "background-image",
41
+ "background-position",
42
+ "background-size",
43
+ "background-repeat"
44
+ ],
45
+ font: [
46
+ "font-family",
47
+ "font-size",
48
+ "font-weight",
49
+ "line-height"
50
+ ],
51
+ transition: [
52
+ "transition-property",
53
+ "transition-duration",
54
+ "transition-timing-function",
55
+ "transition-delay"
56
+ ],
57
+ animation: [
58
+ "animation-name",
59
+ "animation-duration",
60
+ "animation-timing-function",
61
+ "animation-delay",
62
+ "animation-iteration-count"
63
+ ],
64
+ grid: [
65
+ "grid-template-columns",
66
+ "grid-template-rows",
67
+ "grid-template-areas"
68
+ ],
69
+ "grid-template": [
70
+ "grid-template-columns",
71
+ "grid-template-rows",
72
+ "grid-template-areas"
73
+ ],
74
+ "grid-area": [
75
+ "grid-row-start",
76
+ "grid-column-start",
77
+ "grid-row-end",
78
+ "grid-column-end"
79
+ ],
80
+ "place-content": ["align-content", "justify-content"],
81
+ "place-items": ["align-items", "justify-items"],
82
+ "place-self": ["align-self", "justify-self"],
83
+ "list-style": [
84
+ "list-style-type",
85
+ "list-style-position",
86
+ "list-style-image"
87
+ ],
88
+ "text-decoration": [
89
+ "text-decoration-line",
90
+ "text-decoration-color",
91
+ "text-decoration-style"
92
+ ],
93
+ outline: [
94
+ "outline-width",
95
+ "outline-style",
96
+ "outline-color"
97
+ ],
98
+ columns: ["column-width", "column-count"],
99
+ overflow: ["overflow-x", "overflow-y"]
100
+ };
101
+ /** The atomic longhands to write instead of a compound shorthand, or undefined when the key is not a compound
102
+ * shorthand. `flex` layout in particular is NOT `display` + `flex-direction` (those are their own properties). */
103
+ var compoundLonghands = (key) => Object.hasOwn(COMPOUND_SHORTHANDS, key) ? COMPOUND_SHORTHANDS[key] : void 0;
31
104
  var SIDES = [
32
105
  "top",
33
106
  "right",
@@ -129,4 +202,4 @@ var expandShorthand = (css) => {
129
202
  };
130
203
  };
131
204
  //#endregion
132
- export { cssProperties, expandShorthand, isCssProperty, suggestCssProperty };
205
+ export { COMPOUND_SHORTHANDS, compoundLonghands, cssProperties, expandShorthand, isCssProperty, suggestCssProperty };
@@ -0,0 +1,90 @@
1
+ import { BUILTIN_GLOBAL_CALLBACKS } from "./builtinCallbacks.js";
2
+ import { BUILTIN_ELEMENT_CALLBACKS } from "./builtinElementCallbacks.js";
3
+ import { BUILTIN_UTILITIES } from "./builtinUtilities.js";
4
+ import { transformerCatalog } from "./builtinTransformers.js";
5
+ //#region src/modules/mcp/catalogs/observed.ts
6
+ var INTERACTION_NOTE = "Interaction actions observed on this space, grouped by node type. A flow is a trigger followed by ordered callbacks/utilities; write one with upsertInteractionFlow. Names not listed may still be valid plugin actions.";
7
+ var GLOBAL_CALLBACKS_NOTE = "Built-in global callbacks always available in every space. A globalCallback is registered on its SOURCE MODULE, so its node `elementId` is the listed `source` (e.g. \"space\" for addNotification) — NOT the element that hosts the flow. Omit `elementId` and the MCP sets the right source and fills the param defaults for you. Use ONLY the params listed under each callback (with the exact spelling shown) — for addNotification the visible text goes in `content`; there is no title/message/type param. When strictParams is true, any other key is rejected.";
8
+ var ELEMENT_CALLBACKS_NOTE = "Built-in `callback`-type actions every element registers on ITSELF. Unlike a globalCallback, an element callback runs against a real element, so its node `elementId` is that element (the flow host by default, or another element to act on) and its nodeType is \"callback\". `setState` here changes the element's own attribute/state (params category/key/value/revertOnFinish) — NOT the global state setState (which is a globalCallback on source \"state\" with params key/type/value). Set revertOnFinish:true for a TEMPORARY change (e.g. a \"loading…\" label): it is undone automatically when the flow finishes, so you do NOT add manual restore steps. A specific element type may register more callbacks beyond these defaults.";
9
+ var UTILITIES_NOTE = "Built-in `utility`-type actions (no element/source module). Use nodeType \"utility\". Use the EXACT param names — e.g. delayTime waits `time` milliseconds (not `delay`).";
10
+ var toParamInfo = (params) => Object.entries(params).map(([name, spec]) => ({
11
+ name,
12
+ type: spec.type,
13
+ description: spec.description,
14
+ ...spec.default !== void 0 ? { default: spec.default } : {},
15
+ ...spec.options ? { options: spec.options } : {},
16
+ ...spec.when ? { conditional: true } : {}
17
+ }));
18
+ var builtinGlobalCallbacks = () => Object.entries(BUILTIN_GLOBAL_CALLBACKS).map(([action, { source, title, strictParams, params }]) => ({
19
+ action,
20
+ source,
21
+ title,
22
+ strictParams,
23
+ params: toParamInfo(params)
24
+ }));
25
+ var builtinElementCallbacks = () => Object.entries(BUILTIN_ELEMENT_CALLBACKS).map(([action, { title, strictParams, params }]) => ({
26
+ action,
27
+ title,
28
+ strictParams,
29
+ params: toParamInfo(params)
30
+ }));
31
+ var builtinUtilities = () => Object.entries(BUILTIN_UTILITIES).map(([action, { title, strictParams, params }]) => ({
32
+ action,
33
+ title,
34
+ strictParams,
35
+ params: toParamInfo(params)
36
+ }));
37
+ var DATA_SOURCE_NOTE = "Data-source paths and binding targets observed on this space. Bind a source to an element field with upsertBinding (category attributes|style|initialState). Paths not listed may still be valid. A binding may post-process its value through `transformers` (see below) and be gated by a `when` QueryBuilder guard.";
38
+ var DATA_SOURCE_SCOPE_NOTE = "SCOPE: an element source named `<type>_<idRef>` (e.g. `apiContainer_products`, `list_food-list`) is provided by that element to its DESCENDANTS ONLY — the provider wraps its subtree in the source’s scope, so only elements INSIDE the provider can bind to it. Binding a sibling or unrelated element to it is schema-valid but broken at runtime (the source is not in scope), and validate/apply REJECT it as an error. To consume `apiContainer_x.data`, the bound element must live under that apiContainer. Module sources (no `<type>_<idRef>` head — e.g. state/space/navigation/auth/collection) are global and bindable anywhere.";
39
+ var TRANSFORMERS_NOTE = "Built-in transformers that post-process a binding value before it reaches the field: `source → t₁ → t₂ → field`. Set them on a binding as `transformers: [{ action, params }]` (params are strings). The runtime resolves each by its `action` alone, so an UNKNOWN action is silently skipped (the value passes through unchanged) — use the exact action names below. Common formatting is `twigTemplate` (the value is the {{source}} token, not {{value}}).";
40
+ var buildInteractionCatalog = (schema) => {
41
+ const actions = {};
42
+ const flows = /* @__PURE__ */ new Set();
43
+ for (const el of Object.values(schema.flat)) for (const node of Object.values(el.definition.interactions ?? {})) {
44
+ (actions[node.type] ??= /* @__PURE__ */ new Set()).add(node.action);
45
+ flows.add(node.flowId || node.id);
46
+ }
47
+ const grouped = {};
48
+ for (const [nodeType, set] of Object.entries(actions)) grouped[nodeType] = [...set].sort();
49
+ return {
50
+ note: INTERACTION_NOTE,
51
+ actions: grouped,
52
+ globalCallbacksNote: GLOBAL_CALLBACKS_NOTE,
53
+ globalCallbacks: builtinGlobalCallbacks(),
54
+ elementCallbacksNote: ELEMENT_CALLBACKS_NOTE,
55
+ elementCallbacks: builtinElementCallbacks(),
56
+ utilitiesNote: UTILITIES_NOTE,
57
+ utilities: builtinUtilities(),
58
+ flowCount: flows.size
59
+ };
60
+ };
61
+ var buildDataSourceCatalog = (schema) => {
62
+ const sources = /* @__PURE__ */ new Set();
63
+ const targets = {};
64
+ for (const el of Object.values(schema.flat)) for (const [category, list] of Object.entries(el.definition.bindings ?? {})) for (const binding of list) {
65
+ sources.add(binding.source);
66
+ (targets[category] ??= /* @__PURE__ */ new Set()).add(binding.to);
67
+ }
68
+ const groupedTargets = {};
69
+ for (const [category, set] of Object.entries(targets)) groupedTargets[category] = [...set].sort();
70
+ return {
71
+ note: DATA_SOURCE_NOTE,
72
+ scopeNote: DATA_SOURCE_SCOPE_NOTE,
73
+ sources: [...sources].sort(),
74
+ targets: groupedTargets,
75
+ transformersNote: TRANSFORMERS_NOTE,
76
+ transformers: transformerCatalog()
77
+ };
78
+ };
79
+ var observedInteractionActions = (schema) => {
80
+ const actions = /* @__PURE__ */ new Set();
81
+ for (const el of Object.values(schema.flat)) for (const node of Object.values(el.definition.interactions ?? {})) actions.add(node.action);
82
+ return actions;
83
+ };
84
+ var observedDataSources = (schema) => {
85
+ const sources = /* @__PURE__ */ new Set();
86
+ for (const el of Object.values(schema.flat)) for (const list of Object.values(el.definition.bindings ?? {})) for (const binding of list) sources.add(binding.source);
87
+ return sources;
88
+ };
89
+ //#endregion
90
+ export { buildDataSourceCatalog, buildInteractionCatalog, observedDataSources, observedInteractionActions };
@@ -0,0 +1,69 @@
1
+ import { hasValidToken } from "@plitzi/sdk-shared/helpers/twigWrapper";
2
+ //#region src/modules/mcp/catalogs/paramSpec.ts
3
+ /** Declared params the agent supplied that end up HIDDEN because their own `when` guard is false against the
4
+ * effective params — they are silently ignored (e.g. a global setState `value` with no `type`, or an
5
+ * addNotification `autoDismissTimeout` with autoDismiss:false). Evaluated against the effective params so a param
6
+ * the default fills in (e.g. category:"attribute") does not false-report a value as hidden. */
7
+ var hiddenParams = (provided, effective, spec) => {
8
+ const hidden = [];
9
+ for (const [key, param] of Object.entries(spec)) if (param.when && provided[key] !== void 0 && !param.when(effective)) hidden.push(key);
10
+ return hidden;
11
+ };
12
+ /** Declared params marked `required` that the agent did NOT supply, and whose `when` guard holds against the
13
+ * effective params (so they are actually in play). Evaluated against the effective params so a required param
14
+ * gated by a companion (e.g. setState `value`, shown only once `category` is set) is not reported when its guard
15
+ * is not met. */
16
+ var missingRequiredParams = (provided, effective, spec) => {
17
+ const missing = [];
18
+ for (const [key, param] of Object.entries(spec)) if (param.required && provided[key] === void 0 && (!param.when || param.when(effective))) missing.push(key);
19
+ return missing;
20
+ };
21
+ var isNumeric = (value) => value.trim() !== "" && Number.isFinite(Number(value));
22
+ var isBindingToken = (value) => typeof value === "string" && hasValidToken(value);
23
+ var matchesType = (value, param) => {
24
+ switch (param.type) {
25
+ case "boolean": return typeof value === "boolean";
26
+ case "number": return typeof value === "number" || typeof value === "string" && isNumeric(value);
27
+ case "select": return typeof value === "string" && (!param.options || param.options.includes(value));
28
+ case "scalar": return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
29
+ case "text":
30
+ case "textarea": return typeof value === "string";
31
+ default: return true;
32
+ }
33
+ };
34
+ /** Declared params the agent supplied whose value is the WRONG type for the catalog — the check that catches a
35
+ * malformed node the unknown/missing/hidden checks miss (a boolean stored as a string, a select value not in its
36
+ * options, a leftover `null`). Only params actually in play are checked: undefined values (the param is absent) and
37
+ * params hidden by their own `when` guard against the effective params are skipped, so this never fires on a param
38
+ * that is not really used. Callers gate this to CLOSED (strict) catalogs, whose types we own authoritatively. */
39
+ var invalidParams = (provided, effective, spec) => {
40
+ const invalid = [];
41
+ for (const [key, param] of Object.entries(spec)) {
42
+ const value = provided[key];
43
+ if (value === void 0 || isBindingToken(value) || param.when && !param.when(effective)) continue;
44
+ if (!matchesType(value, param)) invalid.push({
45
+ key,
46
+ expected: param.type,
47
+ got: value === null ? "null" : typeof value,
48
+ ...param.options ? { options: param.options } : {}
49
+ });
50
+ }
51
+ return invalid;
52
+ };
53
+ /** Reconcile supplied params to a catalog schema: drop unknown keys when the set is CLOSED (strict), then fill the
54
+ * builder's defaults for any declared param the agent omitted whose `when` guard holds. Mirrors what the builder
55
+ * stores, so the persisted node round-trips cleanly. */
56
+ var reconcileParams = (params, spec, strict) => {
57
+ const next = {};
58
+ for (const [key, value] of Object.entries(params)) {
59
+ if (strict && !(key in spec)) continue;
60
+ next[key] = value;
61
+ }
62
+ for (const [key, param] of Object.entries(spec)) {
63
+ if (param.default === void 0 || next[key] !== void 0 || param.when && !param.when(next)) continue;
64
+ next[key] = param.default;
65
+ }
66
+ return next;
67
+ };
68
+ //#endregion
69
+ export { hiddenParams, invalidParams, missingRequiredParams, reconcileParams };
@@ -0,0 +1,89 @@
1
+ import { BUILTIN_COMPONENTS } from "./builtinComponents.js";
2
+ import { cssProperties } from "./cssCatalog.js";
3
+ //#region src/modules/mcp/catalogs/registry.ts
4
+ var enrichType = (typeName, info, catalog) => {
5
+ const entry = catalog?.[typeName];
6
+ if (entry) {
7
+ info.label = entry.label ?? info.label;
8
+ if (entry.description !== void 0) info.description = entry.description;
9
+ if (entry.category !== void 0) info.category = entry.category;
10
+ info.source = entry.custom ? "plugin" : "builtin";
11
+ if (entry.defaultStyle && Object.keys(entry.defaultStyle).length > 0) info.defaultStyle = entry.defaultStyle;
12
+ for (const attr of entry.attributes ?? []) info.props[attr] ??= {
13
+ valueTypes: [],
14
+ examples: []
15
+ };
16
+ for (const slot of entry.styleSelectors ?? []) if (!info.slots.includes(slot)) info.slots.push(slot);
17
+ return;
18
+ }
19
+ const builtin = BUILTIN_COMPONENTS[typeName];
20
+ if (builtin) {
21
+ info.label = builtin.label;
22
+ info.description = builtin.description;
23
+ info.category = builtin.category;
24
+ info.source = "builtin";
25
+ }
26
+ };
27
+ var EXAMPLE_MAX_LENGTH = 80;
28
+ var isCompactExample = (value) => {
29
+ if (typeof value === "string") return value.length <= EXAMPLE_MAX_LENGTH;
30
+ return typeof value === "number" || typeof value === "boolean";
31
+ };
32
+ var NOTE = "Element types and their props/slots are observed from the elements that already exist in this space — they are ground truth, never inferred. Each type also carries a `label`, `description` (what it is FOR) and `category`, plus a `source`: \"builtin\" (a Plitzi element), \"plugin\" (a custom element added via a plugin), or \"unknown\" (observed but undescribed — label only). Use the description to pick the right type (e.g. apiContainer fetches backend data, link navigates between pages). Props list the attribute keys seen on each type with example values. Slots are the styleSelectors keys seen on each type (target them via element.style.slots). `defaultStyle` (when present) is the intrinsic base CSS of the type BEFORE any class is attached — the real starting point, so account for it and never assume `display: block` (e.g. `text` is `display: inline`; wrap or override it explicitly if you need block/flex layout). CSS in definitions must use the kebab-case keys in cssProperties. Reference schema variables in props via {{name}} and style variables in CSS via var(--name).";
33
+ var buildTypeRegistry = (schema, catalog) => {
34
+ const types = {};
35
+ for (const el of Object.values(schema.flat)) {
36
+ const typeName = el.definition.type;
37
+ const info = types[typeName] ??= {
38
+ count: 0,
39
+ source: "unknown",
40
+ subTypes: [],
41
+ slots: [],
42
+ props: {}
43
+ };
44
+ info.count += 1;
45
+ if (!info.label && typeof el.definition.label === "string" && el.definition.label !== "") info.label = el.definition.label;
46
+ const subType = el.attributes.subType;
47
+ if (typeof subType === "string" && !info.subTypes.includes(subType)) info.subTypes.push(subType);
48
+ for (const slot of Object.keys(el.definition.styleSelectors)) if (!info.slots.includes(slot)) info.slots.push(slot);
49
+ for (const [key, value] of Object.entries(el.attributes)) {
50
+ if (key === "subType") continue;
51
+ const prop = info.props[key] ??= {
52
+ valueTypes: [],
53
+ examples: []
54
+ };
55
+ const valueType = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
56
+ if (!prop.valueTypes.includes(valueType)) prop.valueTypes.push(valueType);
57
+ if (prop.examples.length < 3 && isCompactExample(value) && value !== "" && !prop.examples.includes(value)) prop.examples.push(value);
58
+ }
59
+ }
60
+ for (const typeName of Object.keys(catalog ?? {})) types[typeName] ??= {
61
+ count: 0,
62
+ source: "unknown",
63
+ subTypes: [],
64
+ slots: [],
65
+ props: {}
66
+ };
67
+ for (const [typeName, info] of Object.entries(types)) {
68
+ enrichType(typeName, info, catalog);
69
+ info.subTypes.sort();
70
+ info.slots.sort();
71
+ }
72
+ return {
73
+ note: NOTE,
74
+ cssProperties,
75
+ styleVariableCategories: [
76
+ "color",
77
+ "spacing",
78
+ "shadow",
79
+ "custom"
80
+ ],
81
+ templateSyntax: {
82
+ schemaVariable: "{{name}}",
83
+ styleVariable: "var(--name)"
84
+ },
85
+ types
86
+ };
87
+ };
88
+ //#endregion
89
+ export { buildTypeRegistry };
@@ -16,32 +16,60 @@ var readMcpBody = (req) => new Promise((resolve, reject) => {
16
16
  req.on("error", reject);
17
17
  });
18
18
  var serveMcp = async (raw, res, server) => {
19
+ res.setHeader("Access-Control-Allow-Origin", "*");
20
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
21
+ res.setHeader("Access-Control-Allow-Headers", "*");
22
+ res.setHeader("Access-Control-Max-Age", "86400");
23
+ if (raw.method === "OPTIONS") {
24
+ res.writeHead(204);
25
+ res.end();
26
+ return;
27
+ }
28
+ if (raw.url?.startsWith("/.well-known/")) {
29
+ res.writeHead(404);
30
+ res.end();
31
+ return;
32
+ }
33
+ if (raw.method !== "POST") {
34
+ res.writeHead(405, {
35
+ "Content-Type": "application/json",
36
+ Allow: "POST, OPTIONS"
37
+ });
38
+ res.end(JSON.stringify({
39
+ jsonrpc: "2.0",
40
+ error: {
41
+ code: -32e3,
42
+ message: "Method not allowed; this MCP endpoint accepts JSON-RPC over POST only."
43
+ },
44
+ id: null
45
+ }));
46
+ return;
47
+ }
19
48
  const transport = new StreamableHTTPServerTransport({
20
49
  sessionIdGenerator: void 0,
21
50
  enableJsonResponse: true
22
51
  });
23
52
  await server.connect(transport);
24
53
  try {
25
- if (raw.method === "POST") {
26
- let body = raw.body;
27
- if (body === void 0) try {
28
- body = await readMcpBody(raw);
29
- } catch {
30
- res.writeHead(400, { "Content-Type": "application/json" });
31
- res.end(JSON.stringify({ error: "Invalid JSON body" }));
32
- return;
33
- }
34
- await transport.handleRequest(raw, res, body);
35
- } else await transport.handleRequest(raw, res);
54
+ let body = raw.body;
55
+ if (body === void 0) try {
56
+ body = await readMcpBody(raw);
57
+ } catch {
58
+ res.writeHead(400, { "Content-Type": "application/json" });
59
+ res.end(JSON.stringify({ error: "Invalid JSON body" }));
60
+ return;
61
+ }
62
+ await transport.handleRequest(raw, res, body);
36
63
  } finally {
37
64
  await transport.close();
38
65
  }
39
66
  };
40
- var handleMcp = (raw, res, req, adapters, preview, screenshot) => serveMcp(raw, res, createMcpServer({
67
+ var handleMcp = (raw, res, req, adapters, preview, screenshot, logger) => serveMcp(raw, res, createMcpServer({
41
68
  adapters,
42
69
  getSpaceId: () => adapters.getSpaceId?.(req) ?? Promise.resolve(void 0),
43
70
  preview,
44
- screenshot
71
+ screenshot,
72
+ logger
45
73
  }));
46
74
  //#endregion
47
75
  export { createMcpServer, handleMcp, readMcpBody, serveMcp };
@@ -0,0 +1,104 @@
1
+ import { BUILTIN_GLOBAL_CALLBACKS } from "../catalogs/builtinCallbacks.js";
2
+ import { BUILTIN_ELEMENT_CALLBACKS } from "../catalogs/builtinElementCallbacks.js";
3
+ import { BUILTIN_UTILITIES } from "../catalogs/builtinUtilities.js";
4
+ //#region src/modules/mcp/helpers/agentPrompt.ts
5
+ var EDITING_MODEL = [
6
+ "━━ PLITZI MCP — EDITING MODEL ━━",
7
+ "A Plitzi space is TWO schemas you edit together in one atomic plitzi_apply batch:",
8
+ "• Element schema — the tree of pages/elements (type, label, props, and which style classes each uses).",
9
+ "• Style schema — reusable definitions (CSS classes), design tokens (variables), theme.",
10
+ "To style an element: write a definition AND attach it via the element’s style.base in the same batch.",
11
+ "style.base is a LIST — an element can attach several classes (plus non-base slots); ALL of them apply together",
12
+ "(they cascade), so when a style looks wrong inspect EVERY attached class + its global/id styles, not just one.",
13
+ "Refs accept a semantic idRef ([A-Za-z0-9_-] starting with a letter, unique, chosen by you) or the raw id; the",
14
+ "idRef is ALSO the runtime wiring key (a provider source is `<type>_<idRef>.<field>` — a dot is not allowed in the",
15
+ "idRef, an underscore is). CSS is kebab-case; style vars are var(--name), schema",
16
+ "vars are {{name}}. Use patchElement/patchDefinition to change SOME props/CSS; the upsert variants replace them all.",
17
+ "Reads are cheap by design — list to navigate, read one item for detail; never fetch a whole tree you do not need."
18
+ ].join("\n");
19
+ var TOOLS = [
20
+ "━━ MCP TOOLS ━━",
21
+ "• plitzi_search — find refs by label/type/attribute (include:\"detail\" also returns each hit’s style + versions).",
22
+ "• plitzi_read — batch-read one or more resource URIs you already hold (from search or a write response).",
23
+ "• plitzi_validate — check a batch of operations without executing; returns teachable errors and warnings.",
24
+ "• plitzi_apply — persist a batch of operations. Pass dryRun to preview the full diff without writing, and",
25
+ " expectedResourceVersions to guard against concurrent edits (apply and search hand back the versions you need).",
26
+ "• plitzi_preview / plitzi_screenshot — render an element/page already in the schema (HTML / image).",
27
+ "Discover → browse resources. Find a ref → plitzi_search. Fetch known URIs → plitzi_read. Do not confuse them."
28
+ ].join("\n");
29
+ var RESOURCES = [
30
+ "━━ MCP RESOURCES (read) ━━",
31
+ "Read plitzi://primer/{env} FIRST — a cold-start bundle: guide + types + css-properties + page/definition/variable",
32
+ "summaries in one call. Then, on demand:",
33
+ "• plitzi://guide — full usage reference.",
34
+ "• plitzi://types — element types observed in this space (props, slots, subTypes, label/description/category).",
35
+ "• plitzi://css-properties — valid kebab-case CSS property keys.",
36
+ "• plitzi://schema/{env}/pages , /{ref} — page summaries, then one page as a skeleton tree.",
37
+ "• plitzi://folders/{env} — page folders (the sidebar tree).",
38
+ "• plitzi://definitions/{env} , plitzi://style-variables/{env} — style classes and design tokens.",
39
+ "• plitzi://interactions/{env} — interaction actions + built-in globalCallbacks with their source + param schema.",
40
+ "• plitzi://data-sources/{env} — data-source paths and binding targets (vocabulary for upsertBinding).",
41
+ "• plitzi://settings/{env} — space-level settings."
42
+ ].join("\n");
43
+ var NAVIGATION = [
44
+ "━━ NAVIGATION & DYNAMIC PAGES ━━",
45
+ "To move between pages, PREFER the Link element over an interaction — it is a CONTAINER that wraps any children and",
46
+ "navigates on click. mode \"page\" links to another space page (href = the target page); mode \"internal\" takes a",
47
+ "path inside the space and resolves {{token}} templates in it (e.g. /posts/{{postId}}); mode \"external\" is a full",
48
+ "URL. Reach for the navigate globalCallback only when navigation must be one step inside a larger flow.",
49
+ "A page slug is RELATIVE — never start it with \"/\" (the runtime prepends it). Folder slugs PREPEND to the page",
50
+ "slug, so a page at slug \"post\" inside folders \"blog\" > \"2024\" resolves to /blog/2024/post.",
51
+ "A slug segment \":name\" (e.g. \"posts/:postId\") declares a ROUTE PARAM, react-router style. It is readable on that",
52
+ "page as {{name}} in props AND as the binding source navigation.routeParams.name — so a dynamic detail page is a",
53
+ "\"posts/:postId\" page whose apiContainer query binds navigation.routeParams.postId."
54
+ ].join("\n");
55
+ var paramList = (params) => {
56
+ const names = Object.keys(params);
57
+ return names.length > 0 ? names.join(", ") : "(no params)";
58
+ };
59
+ var globalCallbackLines = () => Object.entries(BUILTIN_GLOBAL_CALLBACKS).map(([action, { source, params }]) => ` • ${action} → source "${source}"; params: ${paramList(params)}`);
60
+ var elementCallbackLines = () => Object.entries(BUILTIN_ELEMENT_CALLBACKS).map(([action, { params }]) => ` • ${action}; params: ${paramList(params)}`);
61
+ var utilityLines = () => Object.entries(BUILTIN_UTILITIES).map(([action, { params }]) => ` • ${action}; params: ${paramList(params)}`);
62
+ var INTERACTIONS = () => [
63
+ "━━ INTERACTIONS ━━",
64
+ "A flow is a trigger (onClick, onPageLoad…) followed by ordered callbacks/utilities; each step has an enabled",
65
+ "flag. Write one with upsertInteractionFlow (first node MUST be a trigger); change one step with",
66
+ "patchInteractionNode; remove a step (nodeId) or a whole flow (flowId) with deleteInteraction.",
67
+ "Disable ≠ delete: to turn a step off without removing it use patchInteractionNode { enabled: false }.",
68
+ "deleteInteraction is destructive — confirm with the user first.",
69
+ "Pick the RIGHT node type for an action: the wrong type resolves against nothing and the step silently no-ops.",
70
+ "Any param VALUE can be a data-binding token {{ source }} — e.g. addNotification content",
71
+ "\"{{ list_<idRef>.item.name }}\" shows the clicked row’s field; it resolves at runtime just like a prop binding.",
72
+ "",
73
+ "globalCallback (nodeType \"globalCallback\") — provided by a SOURCE MODULE, not the host element: OMIT elementId",
74
+ "and the MCP pins the right source and fills the builder’s param defaults. Use ONLY each callback’s declared",
75
+ "params (exact spelling) — for addNotification the text goes in `content` (NO title/message/type). Built-ins:",
76
+ ...globalCallbackLines(),
77
+ "",
78
+ "callback (nodeType \"callback\") — a callback ON an element; elementId is that element (host by default). Every",
79
+ "element has a built-in `setState` that changes ITS OWN attribute/state (category/key/value/revertOnFinish). Set",
80
+ "revertOnFinish:true for a TEMPORARY change (e.g. a \"loading…\" label) so it auto-reverts at flow end — do NOT add",
81
+ "manual restore steps. This element setState has NO `type` param (that is the global state setState). Built-ins:",
82
+ ...elementCallbackLines(),
83
+ "",
84
+ "utility (nodeType \"utility\") — no element/source. Use the EXACT param names (delayTime waits `time` ms, not",
85
+ "`delay`). Built-ins:",
86
+ ...utilityLines(),
87
+ "The full param schema (types, options, defaults) for each is in plitzi://interactions/{env}."
88
+ ].join("\n");
89
+ /** The MCP-owned guidance block a consumer concatenates into its system prompt. Covers what the MCP is
90
+ * authoritative about: its editing model, tools, resources and interaction vocabulary. It intentionally does NOT
91
+ * cover a consumer’s own tools (previews, design helpers) or product framing (modes, identity, security). */
92
+ var buildAgentGuide = () => [
93
+ EDITING_MODEL,
94
+ "",
95
+ TOOLS,
96
+ "",
97
+ RESOURCES,
98
+ "",
99
+ NAVIGATION,
100
+ "",
101
+ INTERACTIONS()
102
+ ].join("\n");
103
+ //#endregion
104
+ export { buildAgentGuide };