@plitzi/sdk-mcp 0.38.7 → 0.38.9

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 (66) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +9 -9
  3. package/dist/index.d.ts +2 -2
  4. package/dist/index.js +2 -3
  5. package/dist/modules/mcp/helpers/guide.js +37 -21
  6. package/dist/modules/mcp/index.d.ts +2 -2
  7. package/dist/modules/mcp/server.d.ts +4 -4
  8. package/dist/modules/mcp/server.js +10 -5
  9. package/dist/modules/mcp/tests/cheapMistakes.test.d.ts +1 -0
  10. package/dist/modules/mcp/tests/helpers.d.ts +9 -2
  11. package/dist/modules/mcp/tests/intents.test.d.ts +1 -0
  12. package/dist/modules/mcp/tests/look.test.d.ts +1 -0
  13. package/dist/modules/mcp/tools/apply/index.d.ts +64 -50
  14. package/dist/modules/mcp/tools/apply/index.js +70 -20
  15. package/dist/modules/mcp/tools/describeOperation.d.ts +11 -0
  16. package/dist/modules/mcp/tools/describeOperation.js +40 -0
  17. package/dist/modules/mcp/tools/describeOperation.test.d.ts +1 -0
  18. package/dist/modules/mcp/tools/index.d.ts +1 -6
  19. package/dist/modules/mcp/tools/index.js +12 -9
  20. package/dist/modules/mcp/tools/intents.d.ts +5 -0
  21. package/dist/modules/mcp/tools/intents.js +201 -0
  22. package/dist/modules/mcp/tools/look.d.ts +17 -0
  23. package/dist/modules/mcp/tools/look.js +32 -0
  24. package/dist/modules/mcp/tools/operations/closed.d.ts +7 -0
  25. package/dist/modules/mcp/tools/operations/closed.js +29 -0
  26. package/dist/modules/mcp/tools/operations/index.d.ts +229 -180
  27. package/dist/modules/mcp/tools/operations/index.js +72 -51
  28. package/dist/modules/mcp/tools/operations/schema/bindings/upsertBinding.d.ts +1 -1
  29. package/dist/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.d.ts +1 -1
  30. package/dist/modules/mcp/tools/operations/schema/operations.d.ts +2 -2
  31. package/dist/modules/mcp/tools/operations/schema/shared.d.ts +2 -2
  32. package/dist/modules/mcp/tools/operations/schema/shared.js +7 -6
  33. package/dist/modules/mcp/tools/operations/schemaIds.js +4 -4
  34. package/dist/modules/mcp/tools/render.d.ts +40 -40
  35. package/dist/modules/mcp/tools/render.js +5 -1
  36. package/dist/modules/mcp/tools/shared/draftBatch.d.ts +3 -2
  37. package/dist/modules/mcp/tools/shared/draftBatch.js +16 -5
  38. package/dist/modules/mcp/tools/shared/effects.d.ts +2 -0
  39. package/dist/modules/mcp/tools/shared/effects.js +155 -0
  40. package/dist/modules/mcp/tools/shared/effects.test.d.ts +1 -0
  41. package/dist/modules/mcp/tools/shared/look.d.ts +32 -0
  42. package/dist/modules/mcp/tools/shared/look.js +128 -0
  43. package/dist/modules/mcp/tools/shared/normalizeOperations.d.ts +6 -0
  44. package/dist/modules/mcp/tools/shared/normalizeOperations.js +37 -0
  45. package/dist/modules/mcp/tools/shared/repeats.d.ts +13 -0
  46. package/dist/modules/mcp/tools/shared/repeats.js +38 -0
  47. package/dist/modules/mcp/tools/shared/tool.d.ts +9 -6
  48. package/dist/modules/mcp/tools/shared/tool.js +2 -1
  49. package/dist/modules/mcp/tools/shared/validator/context.d.ts +0 -1
  50. package/dist/modules/mcp/tools/shared/validator/elements.js +0 -1
  51. package/dist/modules/mcp/tools/shared/validator/index.js +25 -2
  52. package/dist/modules/mcp/types/screenshotTypes.d.ts +3 -3
  53. package/dist/modules/mcp/types/toolTypes.d.ts +2 -4
  54. package/dist/options.d.ts +4 -5
  55. package/dist/preview/createPreview.js +9 -18
  56. package/package.json +7 -7
  57. package/skills/plitzi-render/SKILL.md +8 -184
  58. package/skills/plitzi-render/reference/good-call.md +88 -0
  59. package/skills/plitzi-render/reference/interactive.md +64 -0
  60. package/skills/plitzi-render/reference/looks.md +29 -0
  61. package/dist/modules/mcp/tools/preview.d.ts +0 -1423
  62. package/dist/modules/mcp/tools/preview.js +0 -37
  63. package/dist/modules/mcp/tools/screenshot.d.ts +0 -1708
  64. package/dist/modules/mcp/tools/screenshot.js +0 -127
  65. package/dist/modules/mcp/tools/validate.d.ts +0 -1699
  66. package/dist/modules/mcp/tools/validate.js +0 -32
@@ -1,66 +1,78 @@
1
1
  import { actionOps } from "./actions/index.js";
2
+ import { closed, typeOf } from "./closed.js";
2
3
  import { connectorOps } from "./connectors/index.js";
3
4
  import { dataOps } from "./data/index.js";
4
5
  import { functionOps } from "./functions/index.js";
5
6
  import { elementOps } from "./schema/operations.js";
6
7
  import { registerSharedSchemaIds } from "./schemaIds.js";
7
8
  import { styleOps } from "./style/operations.js";
9
+ import { closest } from "@plitzi/sdk-authoring";
8
10
  import { z } from "zod";
9
11
  //#region src/modules/mcp/tools/operations/index.ts
10
12
  registerSharedSchemaIds();
13
+ /** A batch's operations, each read by its `type` — and a type none of them has answered with the nearest one. */
14
+ var union = (options) => {
15
+ const types = options.map(typeOf);
16
+ return z.discriminatedUnion("type", options, { error: (issue) => {
17
+ const { input } = issue;
18
+ const type = typeof input === "object" && input !== null && "type" in input ? String(input.type) : "";
19
+ const nearest = closest(type, types);
20
+ return type === "" ? "An operation needs its `type`: plitzi_describe_operation lists every one" : `There is no "${type}" operation${nearest ? ` — did you mean "${nearest}"?` : ""}: plitzi_describe_operation lists every type`;
21
+ } });
22
+ };
11
23
  var documentOps = [
12
- elementOps.upsertElement,
13
- elementOps.repeatElement,
14
- elementOps.patchElement,
15
- elementOps.deleteElement,
16
- elementOps.moveElement,
17
- elementOps.upsertPage,
18
- elementOps.deletePage,
19
- elementOps.upsertLayout,
20
- elementOps.deleteLayout,
21
- elementOps.upsertFolder,
22
- elementOps.deleteFolder,
23
- elementOps.upsertVariable,
24
- elementOps.deleteVariable,
25
- elementOps.upsertFlag,
26
- elementOps.deleteFlag,
27
- elementOps.upsertBinding,
28
- elementOps.patchBinding,
29
- elementOps.deleteBinding,
30
- elementOps.upsertInteractionFlow,
31
- elementOps.patchInteractionNode,
32
- elementOps.deleteInteraction,
33
- elementOps.patchSettings,
34
- elementOps.upsertComponent,
35
- elementOps.deleteComponent,
36
- styleOps.upsertDefinition,
37
- styleOps.upsertDefinitions,
38
- styleOps.patchDefinition,
39
- styleOps.deleteDefinition,
40
- styleOps.upsertGlobalStyle,
41
- styleOps.patchGlobalStyle,
42
- styleOps.deleteGlobalStyle,
43
- styleOps.upsertIdStyle,
44
- styleOps.patchIdStyle,
45
- styleOps.deleteIdStyle,
46
- styleOps.upsertStyleVariable,
47
- styleOps.deleteStyleVariable,
48
- styleOps.upsertFont,
49
- styleOps.deleteFont
24
+ closed(elementOps.upsertElement),
25
+ closed(elementOps.repeatElement),
26
+ closed(elementOps.patchElement),
27
+ closed(elementOps.deleteElement),
28
+ closed(elementOps.moveElement),
29
+ closed(elementOps.upsertPage),
30
+ closed(elementOps.deletePage),
31
+ closed(elementOps.upsertLayout),
32
+ closed(elementOps.deleteLayout),
33
+ closed(elementOps.upsertFolder),
34
+ closed(elementOps.deleteFolder),
35
+ closed(elementOps.upsertVariable),
36
+ closed(elementOps.deleteVariable),
37
+ closed(elementOps.upsertFlag),
38
+ closed(elementOps.deleteFlag),
39
+ closed(elementOps.upsertBinding),
40
+ closed(elementOps.patchBinding),
41
+ closed(elementOps.deleteBinding),
42
+ closed(elementOps.upsertInteractionFlow),
43
+ closed(elementOps.patchInteractionNode),
44
+ closed(elementOps.deleteInteraction),
45
+ closed(elementOps.patchSettings),
46
+ closed(elementOps.upsertComponent),
47
+ closed(elementOps.deleteComponent),
48
+ closed(styleOps.upsertDefinition),
49
+ closed(styleOps.upsertDefinitions),
50
+ closed(styleOps.patchDefinition),
51
+ closed(styleOps.deleteDefinition),
52
+ closed(styleOps.upsertGlobalStyle),
53
+ closed(styleOps.patchGlobalStyle),
54
+ closed(styleOps.deleteGlobalStyle),
55
+ closed(styleOps.upsertIdStyle),
56
+ closed(styleOps.patchIdStyle),
57
+ closed(styleOps.deleteIdStyle),
58
+ closed(styleOps.upsertStyleVariable),
59
+ closed(styleOps.deleteStyleVariable),
60
+ closed(styleOps.upsertFont),
61
+ closed(styleOps.deleteFont)
50
62
  ];
51
- var documentOperation = z.discriminatedUnion("type", documentOps);
52
- var operation = z.discriminatedUnion("type", [
63
+ var documentOperation = union(documentOps);
64
+ var operation = union([
53
65
  ...documentOps,
54
- connectorOps.upsertConnector,
55
- connectorOps.patchConnector,
56
- connectorOps.deleteConnector,
57
- actionOps.upsertAction,
58
- actionOps.patchAction,
59
- actionOps.deleteAction,
60
- functionOps.upsertFunctionFile,
61
- functionOps.deleteFunctionFile,
62
- dataOps.upsertDataFile,
63
- dataOps.deleteDataFile
66
+ closed(connectorOps.upsertConnector),
67
+ closed(connectorOps.patchConnector),
68
+ closed(connectorOps.deleteConnector),
69
+ closed(actionOps.upsertAction),
70
+ closed(actionOps.patchAction),
71
+ closed(actionOps.deleteAction),
72
+ closed(functionOps.upsertFunctionFile),
73
+ closed(functionOps.deleteFunctionFile),
74
+ closed(dataOps.upsertDataFile),
75
+ closed(dataOps.deleteDataFile)
64
76
  ]);
65
77
  var STYLE_OP_TYPES = new Set(Object.keys(styleOps));
66
78
  var isStyleOp = (type) => STYLE_OP_TYPES.has(type);
@@ -68,5 +80,14 @@ var MAX_OPS = 1e3;
68
80
  var environment = z.string().optional().describe("Environment; default main");
69
81
  var operations = z.array(operation).max(MAX_OPS).describe(`Operations applied atomically, in order (max ${MAX_OPS})`);
70
82
  var documentOperations = z.array(documentOperation).max(MAX_OPS).describe(`Operations applied atomically, in order (max ${MAX_OPS})`);
83
+ /** Every operation by its type — the closed vocabulary an agent picks from, and what `plitzi_describe_operation` reads. */
84
+ var OPERATIONS_BY_TYPE = new Map(operation.options.map((variant) => [variant.shape.type.value, variant]));
85
+ var DOCUMENT_OPERATION_TYPES = documentOperation.options.map((variant) => variant.shape.type.value);
86
+ /**
87
+ * `documentOperations` as advertised beside a tool that already carries the whole vocabulary (`plitzi_apply`): each
88
+ * operation's type from the closed list, its fields left to the schema the agent already has. One copy of a ~14k-token
89
+ * schema per connection instead of two; what runs is still parsed against the full one.
90
+ */
91
+ var compactDocumentOperations = z.array(z.looseObject({ type: z.enum(DOCUMENT_OPERATION_TYPES) })).max(MAX_OPS).describe(`Operations applied atomically, in order (max ${MAX_OPS}) — the document operations of plitzi_apply, with the same fields; plitzi_describe_operation gives any one of them`);
71
92
  //#endregion
72
- export { MAX_OPS, documentOperation, documentOperations, environment, isStyleOp, operation, operations };
93
+ export { MAX_OPS, OPERATIONS_BY_TYPE, compactDocumentOperations, documentOperation, documentOperations, environment, isStyleOp, operation, operations };
@@ -21,7 +21,7 @@ export declare const upsertBindingOp: z.ZodObject<{
21
21
  }, z.core.$strip>>>;
22
22
  when: z.ZodOptional<z.ZodType<import('@plitzi/sdk-shared').RuleGroup, unknown, z.core.$ZodTypeInternals<import('@plitzi/sdk-shared').RuleGroup, unknown>>>;
23
23
  enabled: z.ZodOptional<z.ZodBoolean>;
24
- }, z.core.$strip>;
24
+ }, z.core.$strict>;
25
25
  }, z.core.$strip>;
26
26
  export type UpsertBinding = z.infer<typeof upsertBindingOp>;
27
27
  export declare const upsertBinding: (space: Space, env: Env, op: UpsertBinding) => OpResult;
@@ -27,7 +27,7 @@ export declare const upsertInteractionFlowOp: z.ZodObject<{
27
27
  }>>;
28
28
  elementId: z.ZodOptional<z.ZodString>;
29
29
  preview: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
- }, z.core.$strip>>;
30
+ }, z.core.$strict>>;
31
31
  }, z.core.$strip>;
32
32
  export type UpsertInteractionFlow = z.infer<typeof upsertInteractionFlowOp>;
33
33
  export declare const upsertInteractionFlow: (space: Space, env: Env, op: UpsertInteractionFlow) => OpResult;
@@ -168,7 +168,7 @@ export declare const elementOps: {
168
168
  }, import('zod/v4/core').$strip>>>;
169
169
  when: import('zod').ZodOptional<import('zod').ZodType<import('@plitzi/sdk-shared').RuleGroup, unknown, import('zod/v4/core').$ZodTypeInternals<import('@plitzi/sdk-shared').RuleGroup, unknown>>>;
170
170
  enabled: import('zod').ZodOptional<import('zod').ZodBoolean>;
171
- }, import('zod/v4/core').$strip>;
171
+ }, import('zod/v4/core').$strict>;
172
172
  }, import('zod/v4/core').$strip>;
173
173
  patchBinding: import('zod').ZodObject<{
174
174
  type: import('zod').ZodLiteral<"patchBinding">;
@@ -228,7 +228,7 @@ export declare const elementOps: {
228
228
  }>>;
229
229
  elementId: import('zod').ZodOptional<import('zod').ZodString>;
230
230
  preview: import('zod').ZodOptional<import('zod').ZodRecord<import('zod').ZodString, import('zod').ZodUnknown>>;
231
- }, import('zod/v4/core').$strip>>;
231
+ }, import('zod/v4/core').$strict>>;
232
232
  }, import('zod/v4/core').$strip>;
233
233
  patchInteractionNode: import('zod').ZodObject<{
234
234
  type: import('zod').ZodLiteral<"patchInteractionNode">;
@@ -104,7 +104,7 @@ export declare const bindingInput: z.ZodObject<{
104
104
  }, z.core.$strip>>>;
105
105
  when: z.ZodOptional<z.ZodType<RuleGroup, unknown, z.core.$ZodTypeInternals<RuleGroup, unknown>>>;
106
106
  enabled: z.ZodOptional<z.ZodBoolean>;
107
- }, z.core.$strip>;
107
+ }, z.core.$strict>;
108
108
  export declare const interactionNodeType: z.ZodEnum<{
109
109
  trigger: "trigger";
110
110
  globalCallback: "globalCallback";
@@ -132,7 +132,7 @@ export declare const interactionNode: z.ZodObject<{
132
132
  }>>;
133
133
  elementId: z.ZodOptional<z.ZodString>;
134
134
  preview: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
135
- }, z.core.$strip>;
135
+ }, z.core.$strict>;
136
136
  /** What the validator checks: an authored node, or one read back from storage — which may carry a `task` type the
137
137
  * write vocabulary above does not offer. Checking the stored shape is the point; refusing it is the validator's. */
138
138
  export type InteractionNodeInput = Omit<z.infer<typeof interactionNode>, 'nodeType'> & {
@@ -1,3 +1,4 @@
1
+ import { closedObject } from "../closed.js";
1
2
  import { isSuggestionCode } from "@plitzi/sdk-authoring";
2
3
  import { z } from "zod";
3
4
  import { FLAG_GATE_PATTERN } from "@plitzi/sdk-shared/flags";
@@ -111,10 +112,10 @@ var elementShape = {
111
112
  motion: elementMotion.optional(),
112
113
  quiet: elementQuiet.optional()
113
114
  };
114
- var elementInput = z.lazy(() => z.object({
115
+ var elementInput = z.lazy(() => closedObject("An element", {
115
116
  ...elementShape,
116
117
  children: z.array(elementInput).optional()
117
- }));
118
+ }, "plitzi_describe_operation { type: \"upsertElement\" }"));
118
119
  var position = z.enum([
119
120
  "inside",
120
121
  "before",
@@ -135,21 +136,21 @@ var bindingTransformer = z.object({
135
136
  params: z.record(z.string(), z.string()),
136
137
  enabled: z.boolean().optional().describe("Set false to keep the transformer in the chain but skip it at runtime (defaults to true)")
137
138
  });
138
- var bindingInput = z.object({
139
+ var bindingInput = closedObject("A binding", {
139
140
  to: z.string().describe("Target field the value feeds (a prop key, style value, or initialState key)"),
140
141
  source: z.string().describe("Data source path, e.g. \"apiContainer_x.data\" — see plitzi://data-sources"),
141
142
  id: z.string().optional().describe("Stable binding id; generated when omitted"),
142
143
  transformers: z.array(bindingTransformer).optional(),
143
144
  when: ruleGroup.optional().describe("QueryBuilder RuleGroup gating the binding (validated structurally)"),
144
145
  enabled: z.boolean().optional()
145
- });
146
+ }, "plitzi_describe_operation { type: \"upsertBinding\" }");
146
147
  var interactionNodeType = z.enum([
147
148
  "trigger",
148
149
  "globalCallback",
149
150
  "callback",
150
151
  "utility"
151
152
  ]).describe("trigger starts a flow (must be first); the rest run in order after it");
152
- var interactionNode = z.object({
153
+ var interactionNode = closedObject("A flow step", {
153
154
  id: z.string().optional().describe("Existing node id to preserve; generated when omitted"),
154
155
  title: z.string().describe("Human label for the step"),
155
156
  nodeType: interactionNodeType,
@@ -160,6 +161,6 @@ var interactionNode = z.object({
160
161
  whileRunning: z.enum(WHILE_RUNNING_MODES).optional().describe("Trigger only: a refiring while this flow runs"),
161
162
  elementId: z.string().optional().describe("Element whose callback this step invokes, by name; defaults to this element"),
162
163
  preview: z.record(z.string(), z.unknown()).optional()
163
- });
164
+ }, "plitzi_describe_operation { type: \"upsertInteractionFlow\" }");
164
165
  //#endregion
165
166
  export { bindingCategory, bindingInput, elementAnchor, elementFlag, elementInput, elementMotion, elementQuiet, elementRuntime, elementShape, initialStateInput, interactionNode, interactionNodeType, position, ruleGroup, scalar, styleRefs, styleVariantInput };
@@ -4,10 +4,10 @@ import { bindingInput, elementAnchor, elementFlag, elementInput, elementMotion,
4
4
  import { ancestors, ancestorsPatch, conditions, conditionsPatch, cssMap, cssPatchMap, definitionSlot, definitionSlotPatch, displayModeCss, displayModeCssPatch, pseudos, pseudosPatch, themeValue, variantPart, variantPartPatch } from "./style/shared.js";
5
5
  import { z } from "zod";
6
6
  //#region src/modules/mcp/tools/operations/schemaIds.ts
7
- /** The op union is the tool input of plitzi_apply, plitzi_validate, plitzi_render AND plitzi_preview, and every
8
- * host reads it as JSON Schema on tools/list — four copies of the same 30 operations in the model's context, on
9
- * EVERY request of every conversation the server is connected to. It measured ~25k tokens PER TOOL (~100k in
10
- * total), which dwarfs anything a widget payload ever costs.
7
+ /** The op union is the tool input of plitzi_apply (and of plitzi_render where apply is not listed), and every host
8
+ * reads it as JSON Schema on tools/list — on EVERY request of every conversation the server is connected to. It
9
+ * measured ~25k tokens a copy, which dwarfs anything a widget payload ever costs; one copy per connection is what
10
+ * `compactInputShape` keeps it to, and this keeps that copy small.
11
11
  *
12
12
  * Most of that weight is one subschema pasted over and over: an element tree appears in upsertElement,
13
13
  * patchElement and both repeat templates; a breakpoint CSS block in every style op; a rule group in every binding
@@ -13,7 +13,7 @@ export declare const renderShape: {
13
13
  after: "after";
14
14
  inside: "inside";
15
15
  }>>;
16
- }, z.core.$strip>, z.ZodObject<{
16
+ }, z.core.$strict>, z.ZodObject<{
17
17
  type: z.ZodLiteral<"repeatElement">;
18
18
  pageRef: z.ZodString;
19
19
  ref: z.ZodString;
@@ -31,7 +31,7 @@ export declare const renderShape: {
31
31
  }>>;
32
32
  template: z.ZodType<import('./operations/schema').TemplateElement, unknown, z.core.$ZodTypeInternals<import('./operations/schema').TemplateElement, unknown>>;
33
33
  items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
34
- }, z.core.$strip>, z.ZodObject<{
34
+ }, z.core.$strict>, z.ZodObject<{
35
35
  type: z.ZodLiteral<"patchElement">;
36
36
  pageRef: z.ZodString;
37
37
  ref: z.ZodString;
@@ -56,11 +56,11 @@ export declare const renderShape: {
56
56
  anchor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
57
57
  motion: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
58
58
  quiet: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
59
- }, z.core.$strip>, z.ZodObject<{
59
+ }, z.core.$strict>, z.ZodObject<{
60
60
  type: z.ZodLiteral<"deleteElement">;
61
61
  pageRef: z.ZodString;
62
62
  ref: z.ZodString;
63
- }, z.core.$strip>, z.ZodObject<{
63
+ }, z.core.$strict>, z.ZodObject<{
64
64
  type: z.ZodLiteral<"moveElement">;
65
65
  pageRef: z.ZodString;
66
66
  ref: z.ZodString;
@@ -70,7 +70,7 @@ export declare const renderShape: {
70
70
  after: "after";
71
71
  inside: "inside";
72
72
  }>;
73
- }, z.core.$strip>, z.ZodObject<{
73
+ }, z.core.$strict>, z.ZodObject<{
74
74
  type: z.ZodLiteral<"upsertPage">;
75
75
  ref: z.ZodString;
76
76
  label: z.ZodOptional<z.ZodString>;
@@ -81,10 +81,10 @@ export declare const renderShape: {
81
81
  layoutContainer: z.ZodOptional<z.ZodNullable<z.ZodString>>;
82
82
  enabled: z.ZodOptional<z.ZodBoolean>;
83
83
  flag: z.ZodOptional<z.ZodNullable<z.ZodString>>;
84
- }, z.core.$strip>, z.ZodObject<{
84
+ }, z.core.$strict>, z.ZodObject<{
85
85
  type: z.ZodLiteral<"deletePage">;
86
86
  ref: z.ZodString;
87
- }, z.core.$strip>, z.ZodObject<{
87
+ }, z.core.$strict>, z.ZodObject<{
88
88
  type: z.ZodLiteral<"upsertLayout">;
89
89
  ref: z.ZodString;
90
90
  label: z.ZodOptional<z.ZodString>;
@@ -100,19 +100,19 @@ export declare const renderShape: {
100
100
  address: "address";
101
101
  figure: "figure";
102
102
  }>>;
103
- }, z.core.$strip>, z.ZodObject<{
103
+ }, z.core.$strict>, z.ZodObject<{
104
104
  type: z.ZodLiteral<"deleteLayout">;
105
105
  ref: z.ZodString;
106
- }, z.core.$strip>, z.ZodObject<{
106
+ }, z.core.$strict>, z.ZodObject<{
107
107
  type: z.ZodLiteral<"upsertFolder">;
108
108
  ref: z.ZodString;
109
109
  name: z.ZodOptional<z.ZodString>;
110
110
  slug: z.ZodOptional<z.ZodString>;
111
111
  parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
112
- }, z.core.$strip>, z.ZodObject<{
112
+ }, z.core.$strict>, z.ZodObject<{
113
113
  type: z.ZodLiteral<"deleteFolder">;
114
114
  ref: z.ZodString;
115
- }, z.core.$strip>, z.ZodObject<{
115
+ }, z.core.$strict>, z.ZodObject<{
116
116
  type: z.ZodLiteral<"upsertVariable">;
117
117
  name: z.ZodString;
118
118
  variableType: z.ZodString;
@@ -122,10 +122,10 @@ export declare const renderShape: {
122
122
  when: z.ZodUnknown;
123
123
  value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
124
124
  }, z.core.$strip>>>;
125
- }, z.core.$strip>, z.ZodObject<{
125
+ }, z.core.$strict>, z.ZodObject<{
126
126
  type: z.ZodLiteral<"deleteVariable">;
127
127
  name: z.ZodString;
128
- }, z.core.$strip>, z.ZodObject<{
128
+ }, z.core.$strict>, z.ZodObject<{
129
129
  type: z.ZodLiteral<"upsertFlag">;
130
130
  name: z.ZodString;
131
131
  description: z.ZodOptional<z.ZodString>;
@@ -134,10 +134,10 @@ export declare const renderShape: {
134
134
  when: z.ZodType<import('@plitzi/sdk-shared').RuleGroup, unknown, z.core.$ZodTypeInternals<import('@plitzi/sdk-shared').RuleGroup, unknown>>;
135
135
  value: z.ZodBoolean;
136
136
  }, z.core.$strip>>>;
137
- }, z.core.$strip>, z.ZodObject<{
137
+ }, z.core.$strict>, z.ZodObject<{
138
138
  type: z.ZodLiteral<"deleteFlag">;
139
139
  name: z.ZodString;
140
- }, z.core.$strip>, z.ZodObject<{
140
+ }, z.core.$strict>, z.ZodObject<{
141
141
  type: z.ZodLiteral<"upsertBinding">;
142
142
  pageRef: z.ZodString;
143
143
  ref: z.ZodString;
@@ -157,8 +157,8 @@ export declare const renderShape: {
157
157
  }, z.core.$strip>>>;
158
158
  when: z.ZodOptional<z.ZodType<import('@plitzi/sdk-shared').RuleGroup, unknown, z.core.$ZodTypeInternals<import('@plitzi/sdk-shared').RuleGroup, unknown>>>;
159
159
  enabled: z.ZodOptional<z.ZodBoolean>;
160
- }, z.core.$strip>;
161
- }, z.core.$strip>, z.ZodObject<{
160
+ }, z.core.$strict>;
161
+ }, z.core.$strict>, z.ZodObject<{
162
162
  type: z.ZodLiteral<"patchBinding">;
163
163
  pageRef: z.ZodString;
164
164
  ref: z.ZodString;
@@ -177,7 +177,7 @@ export declare const renderShape: {
177
177
  }, z.core.$strip>>>;
178
178
  when: z.ZodOptional<z.ZodType<import('@plitzi/sdk-shared').RuleGroup, unknown, z.core.$ZodTypeInternals<import('@plitzi/sdk-shared').RuleGroup, unknown>>>;
179
179
  enabled: z.ZodOptional<z.ZodBoolean>;
180
- }, z.core.$strip>, z.ZodObject<{
180
+ }, z.core.$strict>, z.ZodObject<{
181
181
  type: z.ZodLiteral<"deleteBinding">;
182
182
  pageRef: z.ZodString;
183
183
  ref: z.ZodString;
@@ -188,7 +188,7 @@ export declare const renderShape: {
188
188
  }>;
189
189
  to: z.ZodString;
190
190
  id: z.ZodOptional<z.ZodString>;
191
- }, z.core.$strip>, z.ZodObject<{
191
+ }, z.core.$strict>, z.ZodObject<{
192
192
  type: z.ZodLiteral<"upsertInteractionFlow">;
193
193
  pageRef: z.ZodString;
194
194
  ref: z.ZodString;
@@ -214,8 +214,8 @@ export declare const renderShape: {
214
214
  }>>;
215
215
  elementId: z.ZodOptional<z.ZodString>;
216
216
  preview: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
217
- }, z.core.$strip>>;
218
- }, z.core.$strip>, z.ZodObject<{
217
+ }, z.core.$strict>>;
218
+ }, z.core.$strict>, z.ZodObject<{
219
219
  type: z.ZodLiteral<"patchInteractionNode">;
220
220
  pageRef: z.ZodString;
221
221
  ref: z.ZodString;
@@ -233,13 +233,13 @@ export declare const renderShape: {
233
233
  }>>;
234
234
  elementId: z.ZodOptional<z.ZodString>;
235
235
  preview: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
236
- }, z.core.$strip>, z.ZodObject<{
236
+ }, z.core.$strict>, z.ZodObject<{
237
237
  type: z.ZodLiteral<"deleteInteraction">;
238
238
  pageRef: z.ZodString;
239
239
  ref: z.ZodString;
240
240
  flowId: z.ZodOptional<z.ZodString>;
241
241
  nodeId: z.ZodOptional<z.ZodString>;
242
- }, z.core.$strip>, z.ZodObject<{
242
+ }, z.core.$strict>, z.ZodObject<{
243
243
  type: z.ZodLiteral<"patchSettings">;
244
244
  customCss: z.ZodOptional<z.ZodString>;
245
245
  notifications: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodString>>>;
@@ -287,7 +287,7 @@ export declare const renderShape: {
287
287
  }>>;
288
288
  presence: z.ZodOptional<z.ZodBoolean>;
289
289
  }, z.core.$strip>>>>;
290
- }, z.core.$strip>, z.ZodObject<{
290
+ }, z.core.$strict>, z.ZodObject<{
291
291
  type: z.ZodLiteral<"upsertComponent">;
292
292
  ref: z.ZodString;
293
293
  label: z.ZodOptional<z.ZodString>;
@@ -295,10 +295,10 @@ export declare const renderShape: {
295
295
  slots: z.ZodOptional<z.ZodArray<z.ZodString>>;
296
296
  fromRef: z.ZodOptional<z.ZodString>;
297
297
  instanceRef: z.ZodOptional<z.ZodString>;
298
- }, z.core.$strip>, z.ZodObject<{
298
+ }, z.core.$strict>, z.ZodObject<{
299
299
  type: z.ZodLiteral<"deleteComponent">;
300
300
  ref: z.ZodString;
301
- }, z.core.$strip>, z.ZodObject<{
301
+ }, z.core.$strict>, z.ZodObject<{
302
302
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
303
303
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
304
304
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
@@ -449,7 +449,7 @@ export declare const renderShape: {
449
449
  }, z.core.$strip>>>;
450
450
  type: z.ZodLiteral<"upsertDefinition">;
451
451
  ref: z.ZodString;
452
- }, z.core.$strip>, z.ZodObject<{
452
+ }, z.core.$strict>, z.ZodObject<{
453
453
  type: z.ZodLiteral<"upsertDefinitions">;
454
454
  definitions: z.ZodRecord<z.ZodString, z.ZodObject<{
455
455
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
@@ -601,7 +601,7 @@ export declare const renderShape: {
601
601
  }, z.core.$strip>>>;
602
602
  }, z.core.$strip>>>;
603
603
  }, z.core.$strip>>;
604
- }, z.core.$strip>, z.ZodObject<{
604
+ }, z.core.$strict>, z.ZodObject<{
605
605
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
606
606
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
607
607
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
@@ -752,10 +752,10 @@ export declare const renderShape: {
752
752
  }, z.core.$strip>>>;
753
753
  type: z.ZodLiteral<"patchDefinition">;
754
754
  ref: z.ZodString;
755
- }, z.core.$strip>, z.ZodObject<{
755
+ }, z.core.$strict>, z.ZodObject<{
756
756
  type: z.ZodLiteral<"deleteDefinition">;
757
757
  ref: z.ZodString;
758
- }, z.core.$strip>, z.ZodObject<{
758
+ }, z.core.$strict>, z.ZodObject<{
759
759
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
760
760
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
761
761
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
@@ -906,7 +906,7 @@ export declare const renderShape: {
906
906
  }, z.core.$strip>>>;
907
907
  type: z.ZodLiteral<"upsertGlobalStyle">;
908
908
  componentType: z.ZodString;
909
- }, z.core.$strip>, z.ZodObject<{
909
+ }, z.core.$strict>, z.ZodObject<{
910
910
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
911
911
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
912
912
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
@@ -1057,10 +1057,10 @@ export declare const renderShape: {
1057
1057
  }, z.core.$strip>>>;
1058
1058
  type: z.ZodLiteral<"patchGlobalStyle">;
1059
1059
  componentType: z.ZodString;
1060
- }, z.core.$strip>, z.ZodObject<{
1060
+ }, z.core.$strict>, z.ZodObject<{
1061
1061
  type: z.ZodLiteral<"deleteGlobalStyle">;
1062
1062
  componentType: z.ZodString;
1063
- }, z.core.$strip>, z.ZodObject<{
1063
+ }, z.core.$strict>, z.ZodObject<{
1064
1064
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
1065
1065
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
1066
1066
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
@@ -1211,7 +1211,7 @@ export declare const renderShape: {
1211
1211
  }, z.core.$strip>>>;
1212
1212
  type: z.ZodLiteral<"upsertIdStyle">;
1213
1213
  targetId: z.ZodString;
1214
- }, z.core.$strip>, z.ZodObject<{
1214
+ }, z.core.$strict>, z.ZodObject<{
1215
1215
  desktop: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
1216
1216
  tablet: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
1217
1217
  mobile: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>>>;
@@ -1362,10 +1362,10 @@ export declare const renderShape: {
1362
1362
  }, z.core.$strip>>>;
1363
1363
  type: z.ZodLiteral<"patchIdStyle">;
1364
1364
  targetId: z.ZodString;
1365
- }, z.core.$strip>, z.ZodObject<{
1365
+ }, z.core.$strict>, z.ZodObject<{
1366
1366
  type: z.ZodLiteral<"deleteIdStyle">;
1367
1367
  targetId: z.ZodString;
1368
- }, z.core.$strip>, z.ZodObject<{
1368
+ }, z.core.$strict>, z.ZodObject<{
1369
1369
  type: z.ZodLiteral<"upsertStyleVariable">;
1370
1370
  category: z.ZodEnum<{
1371
1371
  color: "color";
@@ -1379,7 +1379,7 @@ export declare const renderShape: {
1379
1379
  dark: z.ZodOptional<z.ZodString>;
1380
1380
  default: z.ZodOptional<z.ZodString>;
1381
1381
  }, z.core.$strip>]>;
1382
- }, z.core.$strip>, z.ZodObject<{
1382
+ }, z.core.$strict>, z.ZodObject<{
1383
1383
  type: z.ZodLiteral<"deleteStyleVariable">;
1384
1384
  category: z.ZodEnum<{
1385
1385
  color: "color";
@@ -1388,7 +1388,7 @@ export declare const renderShape: {
1388
1388
  custom: "custom";
1389
1389
  }>;
1390
1390
  name: z.ZodString;
1391
- }, z.core.$strip>, z.ZodObject<{
1391
+ }, z.core.$strict>, z.ZodObject<{
1392
1392
  type: z.ZodLiteral<"upsertFont">;
1393
1393
  family: z.ZodString;
1394
1394
  source: z.ZodEnum<{
@@ -1417,10 +1417,10 @@ export declare const renderShape: {
1417
1417
  url: z.ZodOptional<z.ZodString>;
1418
1418
  path: z.ZodOptional<z.ZodString>;
1419
1419
  }, z.core.$strip>>>;
1420
- }, z.core.$strip>, z.ZodObject<{
1420
+ }, z.core.$strict>, z.ZodObject<{
1421
1421
  type: z.ZodLiteral<"deleteFont">;
1422
1422
  family: z.ZodString;
1423
- }, z.core.$strip>], "type">>;
1423
+ }, z.core.$strict>], "type">>;
1424
1424
  patch: z.ZodOptional<z.ZodBoolean>;
1425
1425
  renderId: z.ZodOptional<z.ZodString>;
1426
1426
  };
@@ -2,7 +2,7 @@ import { iconFontCss } from "../apps/render/styles.js";
2
2
  import { RENDER_APP_URI } from "../apps/render/index.js";
3
3
  import { emptySpace } from "../helpers/space.js";
4
4
  import { proxifyResources } from "../proxy/rewrite.js";
5
- import { documentOperations } from "./operations/index.js";
5
+ import { compactDocumentOperations, documentOperations } from "./operations/index.js";
6
6
  import { draftBatch } from "./shared/draftBatch.js";
7
7
  import { defineTool } from "./shared/tool.js";
8
8
  import { interactionReport } from "./shared/interactionReport.js";
@@ -146,6 +146,10 @@ var renderTool = defineTool({
146
146
  title: "Render widget",
147
147
  description: "Show the user a real, rendered UI widget instead of describing one — cards, hero sections, pricing tables, forms, menus, checklists, profiles, galleries. It runs the Plitzi SDK fully offline: no backend, account, or setup. Reach for it whenever a visual layout beats prose: the user asks you to design/build/show something, OR your answer is naturally visual (a recipe → a card, a comparison → a table, steps → a checklist). Prefer showing over telling.\n\nAuthor the widget as an ordered list of `operations` that build an element tree under the pre-seeded root page \"render\". Three rules:\n1. STRUCTURE — one upsertElement builds the whole tree: set pageRef:\"render\" and give element a nested `children` array. Each element is { ref (unique), type, subType?, props?, style?, children? }; children render in order. (To attach to something you already made, use a top-level parentRef:\"<existing ref>\" instead.)\n1b. REPEATS — the moment two siblings share a shape and differ only in data (list, steps, cards, table, timeline), do NOT copy-paste them: use repeatElement { pageRef, ref (wrapper), style, template, items }. The template is written once with {{item.field}} placeholders and rendered per row; refs come out numbered (\"step-1\", \"step-2\"…). A list INSIDE each row (days with their own steps) is the same op: give the wrapping node repeat:{ items:\"{{item.<list>}}\", template:… } and put the sub-rows in the row data.\n2. STYLE — declare ALL the classes in ONE upsertDefinitions { definitions: { \"<class>\": { desktop:{ …CSS in kebab-case… } }, … } }, then attach via the element style:{ base:[\"<class ref>\"] }. Lay containers out with flex/grid. Keep the call small: one class per look, not per property.\n2a. GRAPHICS — a logo, a sparkline, a badge, a decorative shape: draw it as an INLINE <svg> in a blockHtml element (props.content), keeping a viewBox with width/height \"100%\" so its class sizes it, and fill/stroke \"currentColor\" so it follows the host theme. Budget it: a handful of paths, drawn once and reused, never a data: URI and never a full illustration — a photo-real scene costs more than the whole widget, so use an https image, a flat colour or a gradient for that. Markup only: scripts and on* handlers are rejected.\n2b. LAYOUT — it renders in a side panel, so width is free and HEIGHT is scarce. Plain containers stack children vertically, which is the tall half-empty default to avoid: put peers (metrics, plans, options, image + text) in a wrapping row — display:flex, flex-direction:row, flex-wrap:wrap, children flex-grow:\"1\" + flex-basis:\"0%\" + min-width — or a grid with grid-template-columns:\"repeat(auto-fit, minmax(160px, 1fr))\". Keep padding 12-16px and gap 8-12px, and let the outer container fill the panel. Stack only what reads in order (heading over paragraph, forms, steps, prose). Nothing carries a minimum size, so an element with no content and no size takes none — give a spacer or a rail its own height/width — while heading/paragraph do keep the margins the browser gives them (zero them, space with the parent gap).\n2c. THEME — it is embedded in the host UI, which MAY BE DARK, so never hardcode a light palette. Take colours from the host variables with a light-dark() fallback — background-color:\"var(--color-background-secondary, light-dark(#ffffff, #1f2430))\", color:\"var(--color-text-primary, light-dark(#0f172a, #e8eaed))\", border-color:\"var(--color-border-primary, light-dark(#e2e8f0, #333a48))\" — and always set `color` wherever you set `background-color` (a brand accent states its own text colour too).\n3. CONTENT — visible copy goes in props.content (text, heading, paragraph, button); heading level is the element subType (\"h1\"..\"h6\"); image/video take props.src. Write real https URLs: everything the widget loads from outside (images, media, fonts, an apiContainer endpoint) is fetched for it by the render server, so redirects and hotlink rules are handled and there is nothing to configure. It must still point at the actual file — use a URL you have seen work, and when you have none, draw the block with a gradient or an inline SVG instead of guessing one. An unknown prop comes back as a warning naming the right one.\n\nCommon types: container, heading, paragraph, text, button, link, image, video, list, listItem, markdown (plitzi://render/types lists every built-in type with descriptions). Widgets can also be data-driven and interactive — an apiContainer fetches at runtime, upsertBinding wires data into elements, and upsertInteractionFlow makes them react to clicks (see the guide).\nREAD the resource plitzi://render/guide first — it has the element/prop table, the style model and a full worked example, and following it is the difference between a widget that renders and repeated failed calls.\nITERATING — to change a widget you already rendered, do NOT rebuild it: call again with patch:true, the `renderId` that render answered with, and ONLY the operations that differ (patchDefinition, patchElement, deleteElement…). The widget merges them and reports back what it applied; address rows by the refs you already know. Patch ONLY to modify that widget: a different subject or a different kind of widget is a fresh render, without patch — a patch is merged into the previous batch, so patching a new idea leaves you with both.\nReturns a compact summary including the renderId (the widget itself is shown to the user), plus — when the widget has interaction flows — an `interactions` line per flow naming what got wired to what. That reports the WIRING, not that a click was performed: say what you connected, never that you verified it at runtime. On failure it returns teachable errors (path + hint) — read them and retry.",
148
148
  inputShape: renderShape,
149
+ compactInputShape: {
150
+ ...renderShape,
151
+ operations: compactDocumentOperations
152
+ },
149
153
  access: "read",
150
154
  spaceless: true,
151
155
  ui: { resourceUri: RENDER_APP_URI },
@@ -17,9 +17,10 @@ export type DraftResult = {
17
17
  };
18
18
  /**
19
19
  * A batch run on a copy of the space and read back — the one way every tool that takes operations handles them, so
20
- * `plitzi_validate` answers exactly what `plitzi_apply` would, and `plitzi_render` holds a widget to the same rules.
20
+ * a `dryRun` answers exactly what `plitzi_apply` would save, and `plitzi_render` holds a widget to the same rules.
21
21
  *
22
- * In order: the sugar ops expanded; what was already wrong with the elements the batch touches fixed where it has one
22
+ * In order: the sugar ops expanded; what has one reading read that way (`normalizeOperations`, said in `warnings`);
23
+ * what was already wrong with the elements the batch touches fixed where it has one
23
24
  * reading (`fixTouched`, each fix said in `warnings`); each op checked against the input it takes; the batch applied to
24
25
  * the copy; and the copy read by `lintDraft` — structure and meaning, the same reading every other writer gets. The
25
26
  * first stage to refuse ends it; the space handed in is never touched.