@caelo-cms/shared 0.10.58 → 0.10.59

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.
@@ -0,0 +1,49 @@
1
+ /** Comment prefix of an opening marker; the closing marker is `/caelo:f`. */
2
+ export declare const EDIT_MARKER_PREFIX = "caelo:f";
3
+ /** Field shape {@link wrapEditableValues} needs: name + kind. */
4
+ export interface EditableFieldDef {
5
+ readonly name: string;
6
+ readonly kind?: string;
7
+ }
8
+ /**
9
+ * Wrap the editable text of a content instance's values in sentinels.
10
+ * Returns a new object; non-editable values pass through untouched.
11
+ *
12
+ * Paths: `<field>` for a `text` / `url` / `image` field, `<field>.<i>`
13
+ * for a `text-list` item, `<field>.<i>.label` / `<field>.<i>.href` for a
14
+ * `link-list` item's label / target.
15
+ *
16
+ * @example
17
+ * wrapEditableValues({ hero_title: "Hi" }, [{ name: "hero_title", kind: "text" }]);
18
+ * // → { hero_title: "\uE000hero_title\uE001Hi\uE002" }
19
+ */
20
+ export declare function wrapEditableValues(values: Readonly<Record<string, unknown>>, fields: readonly EditableFieldDef[]): Record<string, unknown>;
21
+ /**
22
+ * Turn sentinels in rendered module HTML into marker comments (text
23
+ * content) or drop them (everywhere else). See the file header.
24
+ *
25
+ * A tag whose `href` / `src` / `alt` value is exactly one marked value
26
+ * gets `data-caelo-fields="href=<path> …"` plus the placement
27
+ * (`data-caelo-placement`, `data-caelo-shared`), so the editor can offer
28
+ * "Edit link" / "Replace image" (#918). A value assembled from several
29
+ * parts (`href="/blog/{{slug}}"`) is not editable and is not marked.
30
+ *
31
+ * @param placement The placement key, `<blockName>#<position>`.
32
+ * @param sharedPages 0 for a placement with its own content; for a synced
33
+ * (shared) one, the number of pages that show the same content.
34
+ */
35
+ export declare function finalizeEditMarkers(html: string, placement: string, sharedPages: number): string;
36
+ /** A parsed opening marker. */
37
+ export interface EditMarker {
38
+ readonly blockName: string;
39
+ readonly position: number;
40
+ readonly synced: boolean;
41
+ readonly field: string;
42
+ readonly index?: number;
43
+ }
44
+ /**
45
+ * Parse an opening marker's comment text (without `<!--`/`-->`), or null.
46
+ * Mirrors what the preview runtime does in the browser.
47
+ */
48
+ export declare function parseEditMarker(comment: string): EditMarker | null;
49
+ //# sourceMappingURL=edit-markers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-markers.d.ts","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"AAoCA,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAY5C,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,MAAM,EAAE,SAAS,gBAAgB,EAAE,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB;AAyBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2ChG;AA+BD,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAgBlE"}
@@ -0,0 +1,225 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * #917 — field markers for the Live Edit preview. They let the preview
4
+ * iframe tell which placement + field a piece of visible text came from,
5
+ * so the operator can edit that text in place.
6
+ *
7
+ * Two steps around the normal module render:
8
+ *
9
+ * 1. {@link wrapEditableValues} wraps every plain-text value of a
10
+ * placement's content instance in private-use sentinels that carry
11
+ * the field path. The template engine substitutes the wrapped value
12
+ * like any other string (its escape is the identity), so the
13
+ * sentinels land wherever the module author put `{{field}}`.
14
+ * 2. {@link finalizeEditMarkers} scans the rendered HTML. A sentinel in
15
+ * text content becomes a pair of HTML comments around the value:
16
+ * `<!--caelo:f p=<placement> s=<0|1> f=<path>-->value<!--/caelo:f-->`.
17
+ * Comments do not affect layout or CSS selectors. A sentinel in a
18
+ * comment or a raw-text element (`<script>`, `<style>`, `<title>`,
19
+ * `<textarea>`) is removed and the value stays as it was. In a tag
20
+ * it is removed too; an `href` / `src` / `alt` that is exactly one
21
+ * marked value also gets `data-caelo-fields` on its tag (#918).
22
+ *
23
+ * Only the editor preview runs this. Published output never carries
24
+ * markers: the static generator and every other caller of
25
+ * `pages.render_preview` leave `editMarkers` off.
26
+ *
27
+ * Only values without `<` are wrapped: a value that carries markup cannot
28
+ * be edited as plain text without destroying that markup.
29
+ */
30
+ const START = "\uE000";
31
+ const SEP = "\uE001";
32
+ const END = "\uE002";
33
+ const SENTINELS = /[\uE000-\uE002]/g;
34
+ /** Comment prefix of an opening marker; the closing marker is `/caelo:f`. */
35
+ export const EDIT_MARKER_PREFIX = "caelo:f";
36
+ /**
37
+ * Field kinds the preview marks: text (`text`, `text-list` items,
38
+ * `link-list` labels) and link / image targets (`url`, `image`,
39
+ * `link-list` hrefs, #918) — the latter usually land in `href` / `src`.
40
+ */
41
+ const EDITABLE_KINDS = new Set(["text", "text-list", "link-list", "url", "image"]);
42
+ /** Attributes whose marked value the editor can change (link target, image, alt text). */
43
+ const MARKABLE_ATTRIBUTES = new Set(["href", "src", "alt"]);
44
+ function editable(value) {
45
+ return typeof value === "string" && value.trim().length > 0 && !value.includes("<");
46
+ }
47
+ function wrap(path, value) {
48
+ return `${START}${path}${SEP}${value.replace(SENTINELS, "")}${END}`;
49
+ }
50
+ /**
51
+ * Wrap the editable text of a content instance's values in sentinels.
52
+ * Returns a new object; non-editable values pass through untouched.
53
+ *
54
+ * Paths: `<field>` for a `text` / `url` / `image` field, `<field>.<i>`
55
+ * for a `text-list` item, `<field>.<i>.label` / `<field>.<i>.href` for a
56
+ * `link-list` item's label / target.
57
+ *
58
+ * @example
59
+ * wrapEditableValues({ hero_title: "Hi" }, [{ name: "hero_title", kind: "text" }]);
60
+ * // → { hero_title: "\uE000hero_title\uE001Hi\uE002" }
61
+ */
62
+ export function wrapEditableValues(values, fields) {
63
+ const out = { ...values };
64
+ for (const f of fields) {
65
+ const kind = f.kind ?? "text";
66
+ if (!EDITABLE_KINDS.has(kind))
67
+ continue;
68
+ const v = values[f.name];
69
+ if (kind === "text" || kind === "url" || kind === "image") {
70
+ if (editable(v))
71
+ out[f.name] = wrap(f.name, v);
72
+ }
73
+ else if (kind === "text-list" && Array.isArray(v)) {
74
+ out[f.name] = v.map((item, i) => (editable(item) ? wrap(`${f.name}.${i}`, item) : item));
75
+ }
76
+ else if (kind === "link-list" && Array.isArray(v)) {
77
+ out[f.name] = v.map((item, i) => {
78
+ if (typeof item !== "object" || item === null)
79
+ return item;
80
+ const { label, href } = item;
81
+ return {
82
+ ...item,
83
+ ...(editable(label) ? { label: wrap(`${f.name}.${i}.label`, label) } : {}),
84
+ ...(editable(href) ? { href: wrap(`${f.name}.${i}.href`, href) } : {}),
85
+ };
86
+ });
87
+ }
88
+ }
89
+ return out;
90
+ }
91
+ /** Comment-safe encoding: no `--`, no `>`, no whitespace. */
92
+ function attr(value) {
93
+ return encodeURIComponent(value).replace(/-/g, "%2D");
94
+ }
95
+ const RAW_TEXT_ELEMENTS = new Set(["script", "style", "title", "textarea"]);
96
+ /** End index (exclusive) of the tag starting at `i`, honouring quoted attribute values. */
97
+ function tagEnd(html, i) {
98
+ let quote = null;
99
+ for (let j = i + 1; j < html.length; j += 1) {
100
+ const c = html[j];
101
+ if (quote) {
102
+ if (c === quote)
103
+ quote = null;
104
+ }
105
+ else if (c === '"' || c === "'") {
106
+ quote = c;
107
+ }
108
+ else if (c === ">") {
109
+ return j + 1;
110
+ }
111
+ }
112
+ return html.length;
113
+ }
114
+ /**
115
+ * Turn sentinels in rendered module HTML into marker comments (text
116
+ * content) or drop them (everywhere else). See the file header.
117
+ *
118
+ * A tag whose `href` / `src` / `alt` value is exactly one marked value
119
+ * gets `data-caelo-fields="href=<path> …"` plus the placement
120
+ * (`data-caelo-placement`, `data-caelo-shared`), so the editor can offer
121
+ * "Edit link" / "Replace image" (#918). A value assembled from several
122
+ * parts (`href="/blog/{{slug}}"`) is not editable and is not marked.
123
+ *
124
+ * @param placement The placement key, `<blockName>#<position>`.
125
+ * @param sharedPages 0 for a placement with its own content; for a synced
126
+ * (shared) one, the number of pages that show the same content.
127
+ */
128
+ export function finalizeEditMarkers(html, placement, sharedPages) {
129
+ if (!html.includes(START))
130
+ return html;
131
+ const open = (path) => `<!--${EDIT_MARKER_PREFIX} p=${attr(placement)} s=${sharedPages} f=${attr(path)}-->`;
132
+ const close = `<!--/${EDIT_MARKER_PREFIX}-->`;
133
+ let out = "";
134
+ let i = 0;
135
+ while (i < html.length) {
136
+ const c = html[i];
137
+ if (c === "<" && html.startsWith("<!--", i)) {
138
+ const end = html.indexOf("-->", i + 4);
139
+ const stop = end === -1 ? html.length : end + 3;
140
+ out += stripSentinels(html.slice(i, stop));
141
+ i = stop;
142
+ continue;
143
+ }
144
+ if (c === "<" && /[a-zA-Z/!?]/.test(html[i + 1] ?? "")) {
145
+ const stop = tagEnd(html, i);
146
+ const tag = html.slice(i, stop);
147
+ out += markTag(tag, placement, sharedPages);
148
+ i = stop;
149
+ const name = /^<([a-zA-Z][a-zA-Z0-9-]*)/.exec(tag)?.[1]?.toLowerCase();
150
+ if (name && RAW_TEXT_ELEMENTS.has(name) && !tag.endsWith("/>")) {
151
+ const closeAt = html.toLowerCase().indexOf(`</${name}`, i);
152
+ const rawStop = closeAt === -1 ? html.length : closeAt;
153
+ out += stripSentinels(html.slice(i, rawStop));
154
+ i = rawStop;
155
+ }
156
+ continue;
157
+ }
158
+ if (c === START) {
159
+ const sep = html.indexOf(SEP, i);
160
+ const end = html.indexOf(END, i);
161
+ if (sep !== -1 && end !== -1 && sep < end) {
162
+ out += `${open(html.slice(i + 1, sep))}${html.slice(sep + 1, end)}${close}`;
163
+ i = end + 1;
164
+ continue;
165
+ }
166
+ }
167
+ if (c !== SEP && c !== END && c !== START)
168
+ out += c;
169
+ i += 1;
170
+ }
171
+ return out;
172
+ }
173
+ const ATTRIBUTE = /([^\s"'=<>/]+)(\s*=\s*)(?:"([^"]*)"|'([^']*)')/g;
174
+ const WHOLE_VALUE = /^\uE000([^\uE001]*)\uE001[^\uE002]*\uE002$/;
175
+ /** Strip sentinels from a tag and mark its editable attributes (see finalizeEditMarkers). */
176
+ function markTag(tag, placement, sharedPages) {
177
+ if (!tag.includes(START))
178
+ return tag;
179
+ const marks = [];
180
+ const cleaned = stripSentinels(tag.replace(ATTRIBUTE, (m, name, eq, dq, sq) => {
181
+ const value = dq ?? sq ?? "";
182
+ if (!value.includes(START))
183
+ return m;
184
+ const whole = WHOLE_VALUE.exec(value);
185
+ const lower = name.toLowerCase();
186
+ if (whole?.[1] && MARKABLE_ATTRIBUTES.has(lower))
187
+ marks.push(`${lower}=${attr(whole[1])}`);
188
+ const quote = dq !== undefined ? '"' : "'";
189
+ return `${name}${eq}${quote}${stripSentinels(value)}${quote}`;
190
+ }));
191
+ if (marks.length === 0)
192
+ return cleaned;
193
+ const extra = ` data-caelo-fields="${marks.join(" ")}" data-caelo-placement="${attr(placement)}" data-caelo-shared="${sharedPages}"`;
194
+ const at = cleaned.endsWith("/>") ? cleaned.length - 2 : cleaned.length - 1;
195
+ return `${cleaned.slice(0, at)}${extra}${cleaned.slice(at)}`;
196
+ }
197
+ /** Drop sentinels and the path they carry, keeping the wrapped value. */
198
+ function stripSentinels(s) {
199
+ return s.replace(/\uE000[^\uE001]*\uE001/g, "").replace(SENTINELS, "");
200
+ }
201
+ /**
202
+ * Parse an opening marker's comment text (without `<!--`/`-->`), or null.
203
+ * Mirrors what the preview runtime does in the browser.
204
+ */
205
+ export function parseEditMarker(comment) {
206
+ const m = /^caelo:f p=(\S+) s=([01]) f=(\S+)$/.exec(comment.trim());
207
+ if (!m?.[1] || !m[2] || !m[3])
208
+ return null;
209
+ const placement = decodeURIComponent(m[1]);
210
+ const hash = placement.lastIndexOf("#");
211
+ const position = Number(placement.slice(hash + 1));
212
+ if (hash <= 0 || !Number.isInteger(position))
213
+ return null;
214
+ const [field, index] = decodeURIComponent(m[3]).split(".");
215
+ if (!field)
216
+ return null;
217
+ return {
218
+ blockName: placement.slice(0, hash),
219
+ position,
220
+ synced: m[2] === "1",
221
+ field,
222
+ ...(index !== undefined ? { index: Number(index) } : {}),
223
+ };
224
+ }
225
+ //# sourceMappingURL=edit-markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-markers.js","sourceRoot":"","sources":["../src/edit-markers.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./ai-tools.js";
3
3
  export * from "./auth-forms.js";
4
4
  export * from "./auto-update.js";
5
5
  export * from "./base-css.js";
6
+ export * from "./bug-intake.js";
6
7
  export * from "./build-page.js";
7
8
  export * from "./cap-failures.js";
8
9
  export * from "./cloud-shell-install.js";
@@ -13,6 +14,7 @@ export * from "./css-var-scan.js";
13
14
  export * from "./database-url.js";
14
15
  export * from "./design-draft-shell.js";
15
16
  export * from "./document-language.js";
17
+ export * from "./edit-markers.js";
16
18
  export * from "./font-assets.js";
17
19
  export * from "./font-axis-policy.js";
18
20
  export * from "./font-usage.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,YAAY,EACjB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,YAAY,EACjB,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export * from "./ai-tools.js";
4
4
  export * from "./auth-forms.js";
5
5
  export * from "./auto-update.js";
6
6
  export * from "./base-css.js";
7
+ export * from "./bug-intake.js";
7
8
  export * from "./build-page.js";
8
9
  export * from "./cap-failures.js";
9
10
  export * from "./cloud-shell-install.js";
@@ -14,6 +15,7 @@ export * from "./css-var-scan.js";
14
15
  export * from "./database-url.js";
15
16
  export * from "./design-draft-shell.js";
16
17
  export * from "./document-language.js";
18
+ export * from "./edit-markers.js";
17
19
  export * from "./font-assets.js";
18
20
  export * from "./font-axis-policy.js";
19
21
  export * from "./font-usage.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EAEb,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,aAAa,EACb,aAAa,EAEb,cAAc,EACd,YAAY,GACb,MAAM,cAAc,CAAC"}
@@ -62,8 +62,8 @@ export declare const pageLogEntrySchema: z.ZodObject<{
62
62
  chatSessionId: z.ZodNullable<z.ZodString>;
63
63
  actorKind: z.ZodEnum<{
64
64
  system: "system";
65
- human: "human";
66
65
  ai: "ai";
66
+ human: "human";
67
67
  plugin: "plugin";
68
68
  }>;
69
69
  entryKind: z.ZodEnum<{
package/dist/version.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
20
20
  * follow standard SemVer.
21
21
  */
22
- export declare const CAELO_VERSION = "0.10.58";
22
+ export declare const CAELO_VERSION = "0.10.59";
23
23
  /**
24
24
  * Deprecated alias for back-compat — early P17 work spelled this
25
25
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
@@ -31,7 +31,7 @@ export declare const CAELO_VERSION = "0.10.58";
31
31
  *
32
32
  * @deprecated use CAELO_VERSION
33
33
  */
34
- export declare const CALEO_VERSION = "0.10.58";
34
+ export declare const CALEO_VERSION = "0.10.59";
35
35
  /**
36
36
  * Parsed shape — major/minor/patch + optional pre-release tag.
37
37
  * Stable interface for callers that need to feature-gate (rare —
package/dist/version.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
21
21
  * follow standard SemVer.
22
22
  */
23
- export const CAELO_VERSION = "0.10.58";
23
+ export const CAELO_VERSION = "0.10.59";
24
24
  /**
25
25
  * Deprecated alias for back-compat — early P17 work spelled this
26
26
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caelo-cms/shared",
3
- "version": "0.10.58",
3
+ "version": "0.10.59",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
6
  "description": "Shared Zod schemas + types + the two-pass HTML composer used by every Caelo CMS workspace package. Stable enough for plugin authors and embedders to depend on directly.",
package/src/ai-tools.ts CHANGED
@@ -430,7 +430,10 @@ export const CHAT_MAX_ATTACHMENTS = 4;
430
430
  * module picked from the composer's module dropdown. `selectedText` and
431
431
  * `context` come from a right-click / text selection in the live-edit
432
432
  * preview (#916): what the operator selected and the text of the block
433
- * around it, so the AI knows exactly what was meant.
433
+ * around it, so the AI knows exactly what was meant. `blockName` /
434
+ * `position` / `field` / `index` (#917) name the placement field the text
435
+ * comes from when the preview marked it, so the AI can address it in
436
+ * `set_page_module_content` without inspecting the page first.
434
437
  */
435
438
  export const chatChipSchema = z
436
439
  .object({
@@ -439,6 +442,10 @@ export const chatChipSchema = z
439
442
  label: z.string().min(1).max(200),
440
443
  selectedText: z.string().min(1).max(2000).optional(),
441
444
  context: z.string().min(1).max(500).optional(),
445
+ blockName: z.string().min(1).max(80).optional(),
446
+ position: z.number().int().nonnegative().optional(),
447
+ field: z.string().min(1).max(200).optional(),
448
+ index: z.number().int().nonnegative().optional(),
442
449
  })
443
450
  .strict();
444
451
  export type ChatChip = z.infer<typeof chatChipSchema>;
@@ -0,0 +1,154 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ /**
4
+ * Epic #901 — the install↔intake contract. The fingerprint must merge the
5
+ * same defect across installs and versions while keeping different defects
6
+ * apart; redaction must strip everything personal or secret before a report
7
+ * is queued, without destroying what makes it triageable.
8
+ */
9
+
10
+ import { describe, expect, it } from "bun:test";
11
+ import {
12
+ bugIntakeReport,
13
+ bugIntakeSigningString,
14
+ computeBugFingerprint,
15
+ normalizeBugText,
16
+ redactBugReportFields,
17
+ redactBugText,
18
+ } from "./bug-intake.js";
19
+
20
+ describe("computeBugFingerprint", () => {
21
+ const auto = (whatHappened: string, suspectedTool = "build_page") =>
22
+ computeBugFingerprint({ source: "auto", suspectedTool, title: "x", whatHappened });
23
+
24
+ it("merges the same auto-captured error with different ids and values", async () => {
25
+ const a = await auto(
26
+ 'Page 7f3c2b9e-1d4a-4e8b-9c0f-2a1b3c4d5e6f not found (slug "pricing", 3 modules)',
27
+ );
28
+ const b = await auto(
29
+ 'Page 0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d not found (slug "about-us", 12 modules)',
30
+ );
31
+ expect(a).toBe(b);
32
+ });
33
+
34
+ it("keeps different tools and different quoted field names apart", async () => {
35
+ expect(await auto("boom", "build_page")).not.toBe(await auto("boom", "edit_module"));
36
+ expect(await auto('Invalid input at "page.slug"')).not.toBe(
37
+ await auto('Invalid input at "page.title"'),
38
+ );
39
+ });
40
+
41
+ it("separates AI-filed from auto-captured reports and keys AI reports on the title", async () => {
42
+ const ai = (title: string) =>
43
+ computeBugFingerprint({
44
+ source: "ai",
45
+ suspectedTool: "screenshot_page",
46
+ title,
47
+ whatHappened: "prose",
48
+ });
49
+ expect(await ai("Selector crop ignored")).toBe(await ai("selector crop ignored"));
50
+ expect(await ai("Selector crop ignored")).not.toBe(
51
+ await computeBugFingerprint({
52
+ source: "auto",
53
+ suspectedTool: "screenshot_page",
54
+ title: "Selector crop ignored",
55
+ whatHappened: "Selector crop ignored",
56
+ }),
57
+ );
58
+ });
59
+
60
+ it("is a 64-char hex digest the report schema accepts", async () => {
61
+ expect(await auto("boom")).toMatch(/^[0-9a-f]{64}$/);
62
+ });
63
+ });
64
+
65
+ describe("normalizeBugText", () => {
66
+ it("strips urls, emails, numbers and paths", () => {
67
+ expect(
68
+ normalizeBugText(
69
+ "GET https://acme.com/a?b=1 for jo@acme.com failed after 1500ms at /srv/app/x.ts",
70
+ ),
71
+ ).toBe("get <url> for <email> failed after <n>ms at <path>");
72
+ });
73
+ });
74
+
75
+ describe("redactBugText", () => {
76
+ it("removes contact data, credentials and links", () => {
77
+ const out = redactBugText(
78
+ [
79
+ "Mail max.mustermann@example.de or call +49 30 1234567 / 030 1234567.",
80
+ "Key sk-ant-api03-abcdefghijklmnopqrstuvwxyz and ghp_abcdefghijklmnopqrstuvwxyz0123.",
81
+ "Authorization: Bearer abc.def.ghi-123456",
82
+ 'config {"password": "hunter2", "api_key": "k-123"}',
83
+ "Fetched https://kunde.example.de/preise?id=4 from 10.0.0.12",
84
+ "jwt eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.c2lnbmF0dXJl",
85
+ ].join("\n"),
86
+ );
87
+ for (const leaked of [
88
+ "max.mustermann",
89
+ "1234567",
90
+ "sk-ant",
91
+ "ghp_",
92
+ "abc.def.ghi",
93
+ "hunter2",
94
+ "k-123",
95
+ "kunde.example.de",
96
+ "10.0.0.12",
97
+ "eyJhbGci",
98
+ ]) {
99
+ expect(out).not.toContain(leaked);
100
+ }
101
+ });
102
+
103
+ it("keeps what makes a report triageable", () => {
104
+ const text =
105
+ "build_page failed in packages/admin-core/src/ai/tools/build-page-handler.ts on 2026-10-20 " +
106
+ "with set_page_module_content_many (version 0.10.55, 42 rows)";
107
+ expect(redactBugText(text)).toBe(text);
108
+ });
109
+ });
110
+
111
+ describe("redactBugReportFields", () => {
112
+ it("redacts every free-text field and caps evidence", () => {
113
+ const out = redactBugReportFields({
114
+ title: "Fails for a@b.de",
115
+ whatHappened: "see https://x.y/z",
116
+ expected: "ok",
117
+ evidence: "y".repeat(9000),
118
+ });
119
+ expect(out.title).toBe("Fails for [email]");
120
+ expect(out.whatHappened).toBe("see [url]");
121
+ expect(out.evidence?.length).toBe(4000);
122
+ });
123
+ });
124
+
125
+ describe("bugIntakeSigningString", () => {
126
+ it("binds method, path, timestamp and body", async () => {
127
+ const base = { method: "post", path: "/v1/reports", timestamp: "1", body: "{}" };
128
+ const s = await bugIntakeSigningString(base);
129
+ expect(s.startsWith("POST\n/v1/reports\n1\n")).toBe(true);
130
+ expect(await bugIntakeSigningString({ ...base, body: "{ }" })).not.toBe(s);
131
+ expect(await bugIntakeSigningString({ ...base, path: "/v1/installs" })).not.toBe(s);
132
+ });
133
+ });
134
+
135
+ describe("bugIntakeReport", () => {
136
+ it("rejects unknown fields so nothing unreviewed rides along", () => {
137
+ const parsed = bugIntakeReport.safeParse({
138
+ protocolVersion: 1,
139
+ reportId: "7f3c2b9e-1d4a-4e8b-9c0f-2a1b3c4d5e6f",
140
+ caeloVersion: "0.10.55",
141
+ fingerprint: "a".repeat(64),
142
+ source: "ai",
143
+ severity: "degraded",
144
+ blockedTask: false,
145
+ suspectedTool: null,
146
+ title: "t",
147
+ whatHappened: "w",
148
+ expected: "e",
149
+ evidence: null,
150
+ siteUrl: "https://leak.example",
151
+ });
152
+ expect(parsed.success).toBe(false);
153
+ });
154
+ });