@anvilkit/contracts 0.1.18

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ancyloce
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });
@@ -0,0 +1,244 @@
1
+ /**
2
+ * @file Section-level AI editing contract — the types
3
+ * `@anvilkit/schema/section`, `@anvilkit/validator/section`, and the
4
+ * `regenerateSelection()` flow in `@anvilkit/plugin-ai-copilot` pass
5
+ * between each other when an author asks an LLM to rewrite a selected
6
+ * subtree of an existing page.
7
+ *
8
+ * Section-level AI is the Phase 6 / M9 sibling to Phase 3's whole-page
9
+ * AI flow ({@link AiGenerationContext} in `./ai.ts`). The page-level
10
+ * flow asks the LLM to emit a complete {@link PageIR}; the section-level
11
+ * flow asks it to emit a {@link AiSectionPatch} that atomically replaces
12
+ * just the selected nodes inside one Puck zone.
13
+ *
14
+ * ### Shape of the contract
15
+ *
16
+ * - {@link AiSectionSelection} is the editor's "what did the author
17
+ * click" payload. The plugin builds it from Puck's selection state +
18
+ * the surrounding zone metadata, then hands it to
19
+ * `configToAiSectionContext()`.
20
+ * - {@link AiSectionContext} is the LLM-shaped view of that selection —
21
+ * the available replacement components (already narrowed to whatever
22
+ * the zone allows), the current subtree snapshots, and optional
23
+ * environment hints. `@anvilkit/schema/section` owns the derivation;
24
+ * this package only owns the destination shape.
25
+ * - {@link AiSectionPatch} is the LLM's response shape. Validation
26
+ * lives in `@anvilkit/validator/section`; this package only owns
27
+ * the type.
28
+ *
29
+ * ### Design rules
30
+ *
31
+ * 1. **Types only.** No runtime code.
32
+ * 2. **Single-subtree per call.** Phase 6 ships a single contiguous
33
+ * subtree replacement per call. Batched multi-zone patches are
34
+ * deliberately out of scope — they would need a new contract and
35
+ * are reserved for `1.2` (plan §12 Q1).
36
+ * 3. **Round-trip safe with Phase 3 page-level AI.** The
37
+ * {@link AiSectionContext.availableComponents} reuses the
38
+ * {@link AiComponentSchema} shape so the validator can apply the
39
+ * same field-level rules at both granularities without forking.
40
+ *
41
+ * @see {@link https://github.com/anvilkit/studio/blob/main/docs/plans/phase-6-plan.md | Phase 6 plan §5.1 Section-level AI patch model}
42
+ */
43
+ import type { AiComponentSchema, AiThemeHint } from "./ai.js";
44
+ import type { PageIRNode } from "./ir.js";
45
+ /**
46
+ * The editor's description of which nodes the author selected before
47
+ * asking for a section-level regeneration.
48
+ *
49
+ * Built by the AI copilot plugin from Puck's selection state plus the
50
+ * surrounding zone metadata. Passed verbatim into
51
+ * `configToAiSectionContext()` to derive an LLM-shaped
52
+ * {@link AiSectionContext}.
53
+ *
54
+ * Selection lives inside a single zone — root, a legacy `data.zones`
55
+ * entry, or a modern slot field. The {@link zoneId} discriminates;
56
+ * {@link allow} / {@link disallow} mirror the parent slot's allow-list
57
+ * if the selection is slot-scoped.
58
+ */
59
+ export interface AiSectionSelection {
60
+ /**
61
+ * The Puck zone identifier containing the selection.
62
+ *
63
+ * - For root content: Puck's root zone id (typically `"root-zone"`
64
+ * or the empty string, depending on Puck version).
65
+ * - For legacy `data.zones` entries: the dotted key Puck uses
66
+ * (`${parentId}:${zoneName}`).
67
+ * - For modern slot fields: the slot field's path inside the parent
68
+ * component.
69
+ *
70
+ * Opaque to {@link AiSectionContext} consumers — only the validator
71
+ * compares it against incoming {@link AiSectionPatch.zoneId} values.
72
+ */
73
+ readonly zoneId: string;
74
+ /**
75
+ * Selected node IDs, in author-visible order.
76
+ *
77
+ * Length must be ≥ 1 — selecting zero nodes is the page-level flow,
78
+ * not the section flow. The order is preserved into
79
+ * {@link AiSectionPatch.nodeIds} so the validator can match
80
+ * positions when {@link AiSectionContext.allowResize} is `false`.
81
+ */
82
+ readonly nodeIds: readonly string[];
83
+ /**
84
+ * Optional snapshot of the current node subtrees being replaced.
85
+ *
86
+ * When provided, `configToAiSectionContext()` forwards this onto
87
+ * {@link AiSectionContext.currentNodes} so the prompt builder can
88
+ * include "before" content. Hosts that have already loaded a
89
+ * `PageIR` have this for free; hosts that drive Puck without a
90
+ * normalized IR may omit it.
91
+ */
92
+ readonly currentNodes?: readonly PageIRNode[];
93
+ /**
94
+ * Optional zone-scoped allow-list, mirroring the
95
+ * `allow` array on Puck slot field definitions.
96
+ *
97
+ * When present, `configToAiSectionContext()` narrows
98
+ * {@link AiSectionContext.availableComponents} to this set. Absent
99
+ * means "every registered component is permitted in this zone"
100
+ * (the root-zone default).
101
+ */
102
+ readonly allow?: readonly string[];
103
+ /**
104
+ * Optional zone-scoped disallow-list, mirroring the `disallow` array
105
+ * on Puck slot field definitions. Applied after {@link allow}.
106
+ */
107
+ readonly disallow?: readonly string[];
108
+ /**
109
+ * Optional Puck zone hint — `"slot"` for modern slot fields,
110
+ * `"zone"` for legacy `data.zones` entries, omitted for the root
111
+ * zone. Forwarded to {@link AiSectionContext.zoneKind}; the
112
+ * validator uses it as a sanity check when {@link allow} is empty.
113
+ */
114
+ readonly zoneKind?: "slot" | "zone";
115
+ }
116
+ /**
117
+ * Optional environment hints for `configToAiSectionContext()`.
118
+ *
119
+ * Mirrors the per-call hints on {@link AiGenerationContext} (theme,
120
+ * locale) so a host that already builds a page-level context can reuse
121
+ * the same hint object for both flows.
122
+ */
123
+ export interface ConfigToAiSectionContextOptions {
124
+ /**
125
+ * Optional theme hint (`"light"` | `"dark"`) forwarded onto
126
+ * {@link AiSectionContext.theme}.
127
+ */
128
+ readonly theme?: AiThemeHint;
129
+ /**
130
+ * Optional BCP 47 language tag forwarded onto
131
+ * {@link AiSectionContext.locale}.
132
+ */
133
+ readonly locale?: string;
134
+ /**
135
+ * When `true`, the resulting context's {@link AiSectionContext.allowResize}
136
+ * is set so the LLM (and the validator) accepts a {@link AiSectionPatch}
137
+ * whose `replacement.length` ≠ {@link AiSectionSelection.nodeIds}.length.
138
+ *
139
+ * Defaults to `false` — Phase 6 / M9 ships size-preserving patches
140
+ * only. Hosts wanting "split this hero into three sections" must opt
141
+ * in explicitly.
142
+ */
143
+ readonly allowResize?: boolean;
144
+ }
145
+ /**
146
+ * The LLM-shaped view of a section-level regeneration request.
147
+ *
148
+ * Produced by `@anvilkit/schema/section`'s `configToAiSectionContext()`
149
+ * from a Puck `Config` + an {@link AiSectionSelection}. Passed into the
150
+ * host-supplied `generateSection(ctx, prompt)` callback and again into
151
+ * `validateAiSectionPatch(patch, ctx)` after the LLM responds.
152
+ *
153
+ * Closed shape: every field is intentional. Hosts must not stuff
154
+ * arbitrary metadata onto this object — open extension is reserved for
155
+ * a Phase 7 major bump.
156
+ */
157
+ export interface AiSectionContext {
158
+ /**
159
+ * The zone the selection lives inside. Forwarded from
160
+ * {@link AiSectionSelection.zoneId} so the validator can verify
161
+ * that the LLM's emitted {@link AiSectionPatch.zoneId} matches.
162
+ */
163
+ readonly zoneId: string;
164
+ /**
165
+ * Optional Puck zone discriminator — `"slot"`, `"zone"`, or omitted
166
+ * for the root zone. Forwarded from
167
+ * {@link AiSectionSelection.zoneKind}.
168
+ */
169
+ readonly zoneKind?: "slot" | "zone";
170
+ /**
171
+ * The selected node IDs in author-visible order. Forwarded from
172
+ * {@link AiSectionSelection.nodeIds}; an emitted patch must
173
+ * preserve this order (and length, when
174
+ * {@link allowResize} is `false`).
175
+ */
176
+ readonly nodeIds: readonly string[];
177
+ /**
178
+ * The components the LLM may emit inside this zone, already
179
+ * narrowed by the zone's allow / disallow lists.
180
+ *
181
+ * Each entry has the same shape as
182
+ * {@link AiGenerationContext.availableComponents} so the validator
183
+ * applies identical field-level rules at section and page
184
+ * granularity.
185
+ *
186
+ * The list is sorted by {@link AiComponentSchema.componentName} for
187
+ * deterministic prompts.
188
+ */
189
+ readonly availableComponents: readonly AiComponentSchema[];
190
+ /**
191
+ * Optional snapshot of the subtrees being replaced. Forwarded from
192
+ * {@link AiSectionSelection.currentNodes}. Lets the prompt builder
193
+ * include "rewrite THIS subtree" context.
194
+ */
195
+ readonly currentNodes?: readonly PageIRNode[];
196
+ /**
197
+ * Whether a size-changing replacement is permitted. Driven by
198
+ * {@link ConfigToAiSectionContextOptions.allowResize}; defaults to
199
+ * `false` so single-subtree-replacement is the safe default.
200
+ */
201
+ readonly allowResize: boolean;
202
+ /**
203
+ * Optional theme hint forwarded onto the prompt. Mirrors
204
+ * {@link AiGenerationContext.theme}.
205
+ */
206
+ readonly theme?: AiThemeHint;
207
+ /**
208
+ * Optional BCP 47 locale hint. Mirrors
209
+ * {@link AiGenerationContext.locale}.
210
+ */
211
+ readonly locale?: string;
212
+ }
213
+ /**
214
+ * The LLM's response to a section-level regeneration request.
215
+ *
216
+ * Replaces {@link nodeIds} inside {@link zoneId} with {@link replacement}
217
+ * via `puckApi.dispatch({ type: "setData", data: applyPatch(...) })`,
218
+ * preserving surrounding canvas (selection, sidebar, scroll).
219
+ *
220
+ * Validation lives in `@anvilkit/validator/section`'s
221
+ * `validateAiSectionPatch()`; this package only owns the type.
222
+ */
223
+ export interface AiSectionPatch {
224
+ /**
225
+ * The zone the patch applies to. Must match
226
+ * {@link AiSectionContext.zoneId} — patches that target a different
227
+ * zone are rejected with code `PATCH_SHAPE`.
228
+ */
229
+ readonly zoneId: string;
230
+ /**
231
+ * The node IDs being replaced. Must equal
232
+ * {@link AiSectionContext.nodeIds} (same order, same length unless
233
+ * {@link AiSectionContext.allowResize} is `true`).
234
+ */
235
+ readonly nodeIds: readonly string[];
236
+ /**
237
+ * The new subtrees, in the order they should appear in the zone
238
+ * after the replacement is applied. Each node is fully formed
239
+ * `PageIRNode` shape — the validator runs the same per-node rules
240
+ * as `validateAiOutput`, scoped to this subtree only.
241
+ */
242
+ readonly replacement: readonly PageIRNode[];
243
+ }
244
+ //# sourceMappingURL=ai-section.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-section.d.cts","sourceRoot":"","sources":["../src/ai-section.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9C;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,mBAAmB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC5C"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * @file Section-level AI editing contract — the types
3
+ * `@anvilkit/schema/section`, `@anvilkit/validator/section`, and the
4
+ * `regenerateSelection()` flow in `@anvilkit/plugin-ai-copilot` pass
5
+ * between each other when an author asks an LLM to rewrite a selected
6
+ * subtree of an existing page.
7
+ *
8
+ * Section-level AI is the Phase 6 / M9 sibling to Phase 3's whole-page
9
+ * AI flow ({@link AiGenerationContext} in `./ai.ts`). The page-level
10
+ * flow asks the LLM to emit a complete {@link PageIR}; the section-level
11
+ * flow asks it to emit a {@link AiSectionPatch} that atomically replaces
12
+ * just the selected nodes inside one Puck zone.
13
+ *
14
+ * ### Shape of the contract
15
+ *
16
+ * - {@link AiSectionSelection} is the editor's "what did the author
17
+ * click" payload. The plugin builds it from Puck's selection state +
18
+ * the surrounding zone metadata, then hands it to
19
+ * `configToAiSectionContext()`.
20
+ * - {@link AiSectionContext} is the LLM-shaped view of that selection —
21
+ * the available replacement components (already narrowed to whatever
22
+ * the zone allows), the current subtree snapshots, and optional
23
+ * environment hints. `@anvilkit/schema/section` owns the derivation;
24
+ * this package only owns the destination shape.
25
+ * - {@link AiSectionPatch} is the LLM's response shape. Validation
26
+ * lives in `@anvilkit/validator/section`; this package only owns
27
+ * the type.
28
+ *
29
+ * ### Design rules
30
+ *
31
+ * 1. **Types only.** No runtime code.
32
+ * 2. **Single-subtree per call.** Phase 6 ships a single contiguous
33
+ * subtree replacement per call. Batched multi-zone patches are
34
+ * deliberately out of scope — they would need a new contract and
35
+ * are reserved for `1.2` (plan §12 Q1).
36
+ * 3. **Round-trip safe with Phase 3 page-level AI.** The
37
+ * {@link AiSectionContext.availableComponents} reuses the
38
+ * {@link AiComponentSchema} shape so the validator can apply the
39
+ * same field-level rules at both granularities without forking.
40
+ *
41
+ * @see {@link https://github.com/anvilkit/studio/blob/main/docs/plans/phase-6-plan.md | Phase 6 plan §5.1 Section-level AI patch model}
42
+ */
43
+ import type { AiComponentSchema, AiThemeHint } from "./ai.js";
44
+ import type { PageIRNode } from "./ir.js";
45
+ /**
46
+ * The editor's description of which nodes the author selected before
47
+ * asking for a section-level regeneration.
48
+ *
49
+ * Built by the AI copilot plugin from Puck's selection state plus the
50
+ * surrounding zone metadata. Passed verbatim into
51
+ * `configToAiSectionContext()` to derive an LLM-shaped
52
+ * {@link AiSectionContext}.
53
+ *
54
+ * Selection lives inside a single zone — root, a legacy `data.zones`
55
+ * entry, or a modern slot field. The {@link zoneId} discriminates;
56
+ * {@link allow} / {@link disallow} mirror the parent slot's allow-list
57
+ * if the selection is slot-scoped.
58
+ */
59
+ export interface AiSectionSelection {
60
+ /**
61
+ * The Puck zone identifier containing the selection.
62
+ *
63
+ * - For root content: Puck's root zone id (typically `"root-zone"`
64
+ * or the empty string, depending on Puck version).
65
+ * - For legacy `data.zones` entries: the dotted key Puck uses
66
+ * (`${parentId}:${zoneName}`).
67
+ * - For modern slot fields: the slot field's path inside the parent
68
+ * component.
69
+ *
70
+ * Opaque to {@link AiSectionContext} consumers — only the validator
71
+ * compares it against incoming {@link AiSectionPatch.zoneId} values.
72
+ */
73
+ readonly zoneId: string;
74
+ /**
75
+ * Selected node IDs, in author-visible order.
76
+ *
77
+ * Length must be ≥ 1 — selecting zero nodes is the page-level flow,
78
+ * not the section flow. The order is preserved into
79
+ * {@link AiSectionPatch.nodeIds} so the validator can match
80
+ * positions when {@link AiSectionContext.allowResize} is `false`.
81
+ */
82
+ readonly nodeIds: readonly string[];
83
+ /**
84
+ * Optional snapshot of the current node subtrees being replaced.
85
+ *
86
+ * When provided, `configToAiSectionContext()` forwards this onto
87
+ * {@link AiSectionContext.currentNodes} so the prompt builder can
88
+ * include "before" content. Hosts that have already loaded a
89
+ * `PageIR` have this for free; hosts that drive Puck without a
90
+ * normalized IR may omit it.
91
+ */
92
+ readonly currentNodes?: readonly PageIRNode[];
93
+ /**
94
+ * Optional zone-scoped allow-list, mirroring the
95
+ * `allow` array on Puck slot field definitions.
96
+ *
97
+ * When present, `configToAiSectionContext()` narrows
98
+ * {@link AiSectionContext.availableComponents} to this set. Absent
99
+ * means "every registered component is permitted in this zone"
100
+ * (the root-zone default).
101
+ */
102
+ readonly allow?: readonly string[];
103
+ /**
104
+ * Optional zone-scoped disallow-list, mirroring the `disallow` array
105
+ * on Puck slot field definitions. Applied after {@link allow}.
106
+ */
107
+ readonly disallow?: readonly string[];
108
+ /**
109
+ * Optional Puck zone hint — `"slot"` for modern slot fields,
110
+ * `"zone"` for legacy `data.zones` entries, omitted for the root
111
+ * zone. Forwarded to {@link AiSectionContext.zoneKind}; the
112
+ * validator uses it as a sanity check when {@link allow} is empty.
113
+ */
114
+ readonly zoneKind?: "slot" | "zone";
115
+ }
116
+ /**
117
+ * Optional environment hints for `configToAiSectionContext()`.
118
+ *
119
+ * Mirrors the per-call hints on {@link AiGenerationContext} (theme,
120
+ * locale) so a host that already builds a page-level context can reuse
121
+ * the same hint object for both flows.
122
+ */
123
+ export interface ConfigToAiSectionContextOptions {
124
+ /**
125
+ * Optional theme hint (`"light"` | `"dark"`) forwarded onto
126
+ * {@link AiSectionContext.theme}.
127
+ */
128
+ readonly theme?: AiThemeHint;
129
+ /**
130
+ * Optional BCP 47 language tag forwarded onto
131
+ * {@link AiSectionContext.locale}.
132
+ */
133
+ readonly locale?: string;
134
+ /**
135
+ * When `true`, the resulting context's {@link AiSectionContext.allowResize}
136
+ * is set so the LLM (and the validator) accepts a {@link AiSectionPatch}
137
+ * whose `replacement.length` ≠ {@link AiSectionSelection.nodeIds}.length.
138
+ *
139
+ * Defaults to `false` — Phase 6 / M9 ships size-preserving patches
140
+ * only. Hosts wanting "split this hero into three sections" must opt
141
+ * in explicitly.
142
+ */
143
+ readonly allowResize?: boolean;
144
+ }
145
+ /**
146
+ * The LLM-shaped view of a section-level regeneration request.
147
+ *
148
+ * Produced by `@anvilkit/schema/section`'s `configToAiSectionContext()`
149
+ * from a Puck `Config` + an {@link AiSectionSelection}. Passed into the
150
+ * host-supplied `generateSection(ctx, prompt)` callback and again into
151
+ * `validateAiSectionPatch(patch, ctx)` after the LLM responds.
152
+ *
153
+ * Closed shape: every field is intentional. Hosts must not stuff
154
+ * arbitrary metadata onto this object — open extension is reserved for
155
+ * a Phase 7 major bump.
156
+ */
157
+ export interface AiSectionContext {
158
+ /**
159
+ * The zone the selection lives inside. Forwarded from
160
+ * {@link AiSectionSelection.zoneId} so the validator can verify
161
+ * that the LLM's emitted {@link AiSectionPatch.zoneId} matches.
162
+ */
163
+ readonly zoneId: string;
164
+ /**
165
+ * Optional Puck zone discriminator — `"slot"`, `"zone"`, or omitted
166
+ * for the root zone. Forwarded from
167
+ * {@link AiSectionSelection.zoneKind}.
168
+ */
169
+ readonly zoneKind?: "slot" | "zone";
170
+ /**
171
+ * The selected node IDs in author-visible order. Forwarded from
172
+ * {@link AiSectionSelection.nodeIds}; an emitted patch must
173
+ * preserve this order (and length, when
174
+ * {@link allowResize} is `false`).
175
+ */
176
+ readonly nodeIds: readonly string[];
177
+ /**
178
+ * The components the LLM may emit inside this zone, already
179
+ * narrowed by the zone's allow / disallow lists.
180
+ *
181
+ * Each entry has the same shape as
182
+ * {@link AiGenerationContext.availableComponents} so the validator
183
+ * applies identical field-level rules at section and page
184
+ * granularity.
185
+ *
186
+ * The list is sorted by {@link AiComponentSchema.componentName} for
187
+ * deterministic prompts.
188
+ */
189
+ readonly availableComponents: readonly AiComponentSchema[];
190
+ /**
191
+ * Optional snapshot of the subtrees being replaced. Forwarded from
192
+ * {@link AiSectionSelection.currentNodes}. Lets the prompt builder
193
+ * include "rewrite THIS subtree" context.
194
+ */
195
+ readonly currentNodes?: readonly PageIRNode[];
196
+ /**
197
+ * Whether a size-changing replacement is permitted. Driven by
198
+ * {@link ConfigToAiSectionContextOptions.allowResize}; defaults to
199
+ * `false` so single-subtree-replacement is the safe default.
200
+ */
201
+ readonly allowResize: boolean;
202
+ /**
203
+ * Optional theme hint forwarded onto the prompt. Mirrors
204
+ * {@link AiGenerationContext.theme}.
205
+ */
206
+ readonly theme?: AiThemeHint;
207
+ /**
208
+ * Optional BCP 47 locale hint. Mirrors
209
+ * {@link AiGenerationContext.locale}.
210
+ */
211
+ readonly locale?: string;
212
+ }
213
+ /**
214
+ * The LLM's response to a section-level regeneration request.
215
+ *
216
+ * Replaces {@link nodeIds} inside {@link zoneId} with {@link replacement}
217
+ * via `puckApi.dispatch({ type: "setData", data: applyPatch(...) })`,
218
+ * preserving surrounding canvas (selection, sidebar, scroll).
219
+ *
220
+ * Validation lives in `@anvilkit/validator/section`'s
221
+ * `validateAiSectionPatch()`; this package only owns the type.
222
+ */
223
+ export interface AiSectionPatch {
224
+ /**
225
+ * The zone the patch applies to. Must match
226
+ * {@link AiSectionContext.zoneId} — patches that target a different
227
+ * zone are rejected with code `PATCH_SHAPE`.
228
+ */
229
+ readonly zoneId: string;
230
+ /**
231
+ * The node IDs being replaced. Must equal
232
+ * {@link AiSectionContext.nodeIds} (same order, same length unless
233
+ * {@link AiSectionContext.allowResize} is `true`).
234
+ */
235
+ readonly nodeIds: readonly string[];
236
+ /**
237
+ * The new subtrees, in the order they should appear in the zone
238
+ * after the replacement is applied. Each node is fully formed
239
+ * `PageIRNode` shape — the validator runs the same per-node rules
240
+ * as `validateAiOutput`, scoped to this subtree only.
241
+ */
242
+ readonly replacement: readonly PageIRNode[];
243
+ }
244
+ //# sourceMappingURL=ai-section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-section.d.ts","sourceRoot":"","sources":["../src/ai-section.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9C;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,mBAAmB,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CAC5C"}
@@ -0,0 +1 @@
1
+ export { };
package/dist/ai.cjs ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.r = (exports1)=>{
5
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
6
+ value: 'Module'
7
+ });
8
+ Object.defineProperty(exports1, '__esModule', {
9
+ value: true
10
+ });
11
+ };
12
+ })();
13
+ var __webpack_exports__ = {};
14
+ __webpack_require__.r(__webpack_exports__);
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
+ Object.defineProperty(exports, '__esModule', {
17
+ value: true
18
+ });