@puckeditor/plugin-ai 0.9.0-canary.9c664bf4 → 0.9.0-canary.9ff9b8a5

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 (3) hide show
  1. package/dist/index.js +201 -107
  2. package/dist/index.mjs +144 -50
  3. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -995,7 +995,7 @@ function useChat({
995
995
  // src/components/Chat/index.tsx
996
996
  var import_core5 = require("@puckeditor/core");
997
997
  var import_ai5 = require("ai");
998
- var import_react27 = require("react");
998
+ var import_react28 = require("react");
999
999
  var import_ulid = require("ulid");
1000
1000
 
1001
1001
  // ../utils/lib/get-class-name-factory.ts
@@ -1038,7 +1038,7 @@ var styles_module_default = { "Chat": "_Chat_1ei0a_1", "Chat-header": "_Chat-hea
1038
1038
 
1039
1039
  // src/components/ChatBody/index.tsx
1040
1040
  init_react_import();
1041
- var import_react21 = require("react");
1041
+ var import_react22 = require("react");
1042
1042
  var import_use_stick_to_bottom = require("use-stick-to-bottom");
1043
1043
  var import_react_markdown = __toESM(require("react-markdown"));
1044
1044
 
@@ -1814,6 +1814,42 @@ var matchesAccept = (file, accept) => {
1814
1814
  return file.type === entry;
1815
1815
  });
1816
1816
  };
1817
+ var documentExtensionByMediaType = {
1818
+ "application/msword": "doc",
1819
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
1820
+ "text/markdown": "md",
1821
+ "application/pdf": "pdf",
1822
+ "text/plain": "txt"
1823
+ };
1824
+ var mediaTypeToExtension = (mediaType) => {
1825
+ const mapped = documentExtensionByMediaType[mediaType];
1826
+ if (mapped) {
1827
+ return mapped;
1828
+ }
1829
+ const subtype = mediaType.split("/")[1] ?? "";
1830
+ return subtype.split("+")[0] || "bin";
1831
+ };
1832
+ var getFilesFromClipboard = (data) => {
1833
+ const files = [];
1834
+ for (const item of data.items ? Array.from(data.items) : []) {
1835
+ if (item.kind === "file") {
1836
+ const file = item.getAsFile();
1837
+ if (file) {
1838
+ files.push(file);
1839
+ }
1840
+ }
1841
+ }
1842
+ if (files.length === 0 && data.files) {
1843
+ files.push(...Array.from(data.files));
1844
+ }
1845
+ return files.map(
1846
+ (file, index) => file.name ? file : new File(
1847
+ [file],
1848
+ `pasted-${Date.now()}-${index}.${mediaTypeToExtension(file.type)}`,
1849
+ { type: file.type }
1850
+ )
1851
+ );
1852
+ };
1817
1853
  var getAttachmentIdFromRef = (url) => url.startsWith("attachment://") ? url.slice("attachment://".length) : null;
1818
1854
  var resolveAttachmentUrl = (url, attachmentEndpoint) => {
1819
1855
  if (!attachmentEndpoint) {
@@ -1825,6 +1861,20 @@ var resolveAttachmentUrl = (url, attachmentEndpoint) => {
1825
1861
  }
1826
1862
  return `${attachmentEndpoint.replace(/\/$/, "")}/${attachmentId}`;
1827
1863
  };
1864
+ var fetchAttachmentUrl = async (endpoint, signal) => {
1865
+ const response = await fetch(endpoint, { redirect: "manual", signal });
1866
+ if (response.type === "opaqueredirect" || response.status >= 300 && response.status < 400) {
1867
+ return endpoint;
1868
+ }
1869
+ if (!response.ok) {
1870
+ throw new Error(`Attachment URL request failed with ${response.status}`);
1871
+ }
1872
+ const { url } = await response.json();
1873
+ if (typeof url !== "string" || !url) {
1874
+ throw new Error("Attachment URL response did not include a url");
1875
+ }
1876
+ return url;
1877
+ };
1828
1878
  var isInternalMessage = (text) => text.startsWith(INTERNAL_MESSAGE_PREFIX);
1829
1879
  var truncateFilename = (name, max = 25) => {
1830
1880
  if (name.length <= max) return name;
@@ -1896,6 +1946,16 @@ function PromptForm({
1896
1946
  },
1897
1947
  [canDrop, onFileDrop]
1898
1948
  );
1949
+ const handlePaste = (0, import_react19.useCallback)(
1950
+ (e) => {
1951
+ if (!canDrop) return;
1952
+ const files = getFilesFromClipboard(e.clipboardData);
1953
+ if (files.length === 0) return;
1954
+ e.preventDefault();
1955
+ onFileDrop(files);
1956
+ },
1957
+ [canDrop, onFileDrop]
1958
+ );
1899
1959
  (0, import_react19.useEffect)(() => {
1900
1960
  setPrompt(value);
1901
1961
  }, [setPrompt, value]);
@@ -1997,6 +2057,7 @@ function PromptForm({
1997
2057
  internalRef.current = node;
1998
2058
  },
1999
2059
  onChange: (e) => setPrompt(e.target.value),
2060
+ onPaste: onFileDrop ? handlePaste : void 0,
2000
2061
  onKeyDown: (e) => {
2001
2062
  if (!e.shiftKey && e.key === "Enter") {
2002
2063
  e.preventDefault();
@@ -2064,6 +2125,35 @@ var HostProvider = hostContext.Provider;
2064
2125
  var subagentStateContext = (0, import_react20.createContext)({});
2065
2126
  var SubagentStateProvider = subagentStateContext.Provider;
2066
2127
 
2128
+ // src/lib/use-attachment-url.ts
2129
+ init_react_import();
2130
+ var import_react21 = require("react");
2131
+ function useAttachmentUrl(url, endpoint) {
2132
+ const isRef = getAttachmentIdFromRef(url) !== null;
2133
+ const [fetched, setFetched] = (0, import_react21.useState)();
2134
+ (0, import_react21.useEffect)(() => {
2135
+ if (!isRef) return;
2136
+ const controller = new AbortController();
2137
+ const loadUrl = async () => {
2138
+ try {
2139
+ const resolved = await fetchAttachmentUrl(
2140
+ resolveAttachmentUrl(url, endpoint),
2141
+ controller.signal
2142
+ );
2143
+ setFetched({ ref: url, url: resolved });
2144
+ } catch (error) {
2145
+ if (!controller.signal.aborted) {
2146
+ console.error("Failed to load attachment:", error);
2147
+ }
2148
+ }
2149
+ };
2150
+ loadUrl();
2151
+ return () => controller.abort();
2152
+ }, [isRef, url, endpoint]);
2153
+ if (!isRef) return url;
2154
+ return fetched?.ref === url ? fetched.url : void 0;
2155
+ }
2156
+
2067
2157
  // src/components/ChatBody/index.tsx
2068
2158
  var import_jsx_runtime29 = require("react/jsx-runtime");
2069
2159
  var cx8 = getClassNameFactory2("Chat", styles_module_default7);
@@ -2167,7 +2257,7 @@ function mergeReasoningParts(parts) {
2167
2257
  }
2168
2258
  function ChatMessage({ message }) {
2169
2259
  const { role, parts: rawParts } = message;
2170
- const parts = (0, import_react21.useMemo)(() => mergeReasoningParts(rawParts), [rawParts]);
2260
+ const parts = (0, import_react22.useMemo)(() => mergeReasoningParts(rawParts), [rawParts]);
2171
2261
  if (role === "user") {
2172
2262
  const attachmentParts = parts.filter((part) => part.type === "file");
2173
2263
  const otherParts = parts.filter((part) => part.type !== "file");
@@ -2219,9 +2309,9 @@ function ChatAttachmentThumbnail({
2219
2309
  mediaType,
2220
2310
  url
2221
2311
  }) {
2222
- const host = (0, import_react21.useContext)(hostContext);
2312
+ const host = (0, import_react22.useContext)(hostContext);
2223
2313
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2224
- const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2314
+ const resolvedUrl = useAttachmentUrl(url, endpoint);
2225
2315
  const attachmentId = getAttachmentIdFromRef(url);
2226
2316
  const label = filename || attachmentId || "Attachment";
2227
2317
  const isImage = mediaType.startsWith("image/");
@@ -2235,7 +2325,7 @@ function ChatAttachmentThumbnail({
2235
2325
  target: "_blank",
2236
2326
  title: label,
2237
2327
  children: [
2238
- isImage ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("img", { alt: label, src: resolvedUrl }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(FileText, { size: 20 }),
2328
+ isImage ? resolvedUrl && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("img", { alt: label, src: resolvedUrl }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(FileText, { size: 20 }),
2239
2329
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cxMessage("thumbnailLabel"), children: label })
2240
2330
  ]
2241
2331
  }
@@ -2256,12 +2346,12 @@ function ChatMessageWrapper({
2256
2346
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children });
2257
2347
  }
2258
2348
  function ReasoningBlock({ part }) {
2259
- const startTimeRef = (0, import_react21.useRef)(null);
2260
- const [durationSecs, setDurationSecs] = (0, import_react21.useState)(null);
2349
+ const startTimeRef = (0, import_react22.useRef)(null);
2350
+ const [durationSecs, setDurationSecs] = (0, import_react22.useState)(null);
2261
2351
  if (part.state !== "done" && startTimeRef.current === null) {
2262
2352
  startTimeRef.current = Date.now();
2263
2353
  }
2264
- (0, import_react21.useEffect)(() => {
2354
+ (0, import_react22.useEffect)(() => {
2265
2355
  if (part.state === "done" && startTimeRef.current !== null) {
2266
2356
  setDurationSecs(Math.round((Date.now() - startTimeRef.current) / 1e3));
2267
2357
  }
@@ -2313,13 +2403,13 @@ function ChatAttachment({
2313
2403
  mediaType,
2314
2404
  url
2315
2405
  }) {
2316
- const host = (0, import_react21.useContext)(hostContext);
2406
+ const host = (0, import_react22.useContext)(hostContext);
2317
2407
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2318
- const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2408
+ const resolvedUrl = useAttachmentUrl(url, endpoint);
2319
2409
  const attachmentId = getAttachmentIdFromRef(url);
2320
2410
  const label = filename || attachmentId || "Attachment";
2321
2411
  if (mediaType.startsWith("image/")) {
2322
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cxMessage("attachmentImage"), children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("img", { alt: label, src: resolvedUrl }) }) });
2412
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cxMessage("attachmentImage"), children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: resolvedUrl && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("img", { alt: label, src: resolvedUrl }) }) });
2323
2413
  }
2324
2414
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cxMessage("attachmentFile"), children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: [
2325
2415
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(FileText, { size: 16 }),
@@ -2332,10 +2422,10 @@ function PuckTool({
2332
2422
  defaultLabel = "Thinking...",
2333
2423
  type
2334
2424
  }) {
2335
- const toolStatus = (0, import_react21.useContext)(toolStatusContext)[toolCallId];
2425
+ const toolStatus = (0, import_react22.useContext)(toolStatusContext)[toolCallId];
2336
2426
  const outputObj = output;
2337
2427
  const status = outputObj && "status" in outputObj ? outputObj.status : toolStatus ?? { loading: true, label: defaultLabel };
2338
- let icon = (0, import_react21.useMemo)(() => {
2428
+ let icon = (0, import_react22.useMemo)(() => {
2339
2429
  if (type === "tool-write") {
2340
2430
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Pen, { size: 18 });
2341
2431
  } else if (type === "tool-refreshPageData") {
@@ -2352,16 +2442,16 @@ function PuckTool({
2352
2442
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ChatEvent, { status, icon });
2353
2443
  }
2354
2444
  function SubagentBlock({ toolCallId }) {
2355
- const subagentState = (0, import_react21.useContext)(subagentStateContext);
2445
+ const subagentState = (0, import_react22.useContext)(subagentStateContext);
2356
2446
  const state = subagentState[toolCallId];
2357
- const toolStatusMap = (0, import_react21.useContext)(toolStatusContext);
2447
+ const toolStatusMap = (0, import_react22.useContext)(toolStatusContext);
2358
2448
  const toolStatus = toolStatusMap[toolCallId];
2359
2449
  const fallbackLabel = toolStatus?.label ?? "Running subagent";
2360
2450
  const label = state?.label ? state.state === "done" ? `${state.agentType} subagent complete` : state.label : fallbackLabel;
2361
2451
  const loading = state ? state.state !== "done" : toolStatus?.loading ?? true;
2362
2452
  const hasBody = !!state && state.parts.length > 0;
2363
2453
  const parts = state?.parts ?? [];
2364
- const [isOpen, setIsOpen] = (0, import_react21.useState)(false);
2454
+ const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
2365
2455
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2366
2456
  "details",
2367
2457
  {
@@ -2420,7 +2510,7 @@ function ChatEvent({
2420
2510
  status,
2421
2511
  icon = /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Check, { size: 18 })
2422
2512
  }) {
2423
- const [isOpen, setIsOpen] = (0, import_react21.useState)(false);
2513
+ const [isOpen, setIsOpen] = (0, import_react22.useState)(false);
2424
2514
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2425
2515
  "details",
2426
2516
  {
@@ -2545,7 +2635,7 @@ var import_core4 = require("@puckeditor/core");
2545
2635
  // src/lib/design/component.tsx
2546
2636
  init_react_import();
2547
2637
  var import_core3 = require("@puckeditor/core");
2548
- var import_react24 = require("react");
2638
+ var import_react25 = require("react");
2549
2639
 
2550
2640
  // src/lib/morph-html.ts
2551
2641
  init_react_import();
@@ -3658,7 +3748,7 @@ var wireArrayItemEditing = ({
3658
3748
  // src/lib/design/render-html.tsx
3659
3749
  init_react_import();
3660
3750
  var import_htmlparser22 = require("htmlparser2");
3661
- var import_react22 = require("react");
3751
+ var import_react23 = require("react");
3662
3752
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
3663
3753
  "area",
3664
3754
  "base",
@@ -3721,7 +3811,7 @@ var nodeToReact = (node, slots, key) => {
3721
3811
  if (isEventHandlerAttr2(name)) continue;
3722
3812
  props2[REACT_PROP_NAMES[name] || name] = value;
3723
3813
  }
3724
- return (0, import_react22.createElement)(tag, props2, slots[slotName]);
3814
+ return (0, import_react23.createElement)(tag, props2, slots[slotName]);
3725
3815
  }
3726
3816
  const props = { key };
3727
3817
  for (const [name, value] of Object.entries(attribs)) {
@@ -3733,10 +3823,10 @@ var nodeToReact = (node, slots, key) => {
3733
3823
  }
3734
3824
  }
3735
3825
  if (VOID_ELEMENTS.has(tag)) {
3736
- return (0, import_react22.createElement)(tag, props);
3826
+ return (0, import_react23.createElement)(tag, props);
3737
3827
  }
3738
3828
  const children = el.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
3739
- return (0, import_react22.createElement)(tag, props, ...children);
3829
+ return (0, import_react23.createElement)(tag, props, ...children);
3740
3830
  };
3741
3831
  var htmlToReactTree = (html, slots) => {
3742
3832
  if (!html) return null;
@@ -3744,12 +3834,12 @@ var htmlToReactTree = (html, slots) => {
3744
3834
  const children = doc.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
3745
3835
  if (children.length === 0) return null;
3746
3836
  if (children.length === 1) return children[0];
3747
- return (0, import_react22.createElement)(import_react22.Fragment, null, ...children);
3837
+ return (0, import_react23.createElement)(import_react23.Fragment, null, ...children);
3748
3838
  };
3749
3839
 
3750
3840
  // src/lib/design/slot-portal.tsx
3751
3841
  init_react_import();
3752
- var import_react23 = require("react");
3842
+ var import_react24 = require("react");
3753
3843
  var import_react_dom = require("react-dom");
3754
3844
  var import_jsx_runtime31 = require("react/jsx-runtime");
3755
3845
  var parseInlineStyle = (cssText) => {
@@ -3773,13 +3863,13 @@ var SlotPortal = ({
3773
3863
  slotClassName,
3774
3864
  SlotContent
3775
3865
  }) => {
3776
- const [target, setTarget] = (0, import_react23.useState)(null);
3777
- const lastTarget = (0, import_react23.useRef)(null);
3778
- const style = (0, import_react23.useMemo)(
3866
+ const [target, setTarget] = (0, import_react24.useState)(null);
3867
+ const lastTarget = (0, import_react24.useRef)(null);
3868
+ const style = (0, import_react24.useMemo)(
3779
3869
  () => slotStyle ? parseInlineStyle(slotStyle) : void 0,
3780
3870
  [slotStyle]
3781
3871
  );
3782
- (0, import_react23.useEffect)(() => {
3872
+ (0, import_react24.useEffect)(() => {
3783
3873
  const el = entry.querySelector(`[data-puck-slot="${cssEscape(slotName)}"]`);
3784
3874
  if (el !== lastTarget.current) {
3785
3875
  el?.replaceChildren();
@@ -3900,11 +3990,11 @@ function createDesignComponentConfig(registration) {
3900
3990
  style,
3901
3991
  ...props
3902
3992
  }) {
3903
- const getSnapshot = (0, import_react24.useCallback)(
3993
+ const getSnapshot = (0, import_react25.useCallback)(
3904
3994
  () => registrationStore.get(name) ?? registration,
3905
3995
  []
3906
3996
  );
3907
- const reg = (0, import_react24.useSyncExternalStore)(
3997
+ const reg = (0, import_react25.useSyncExternalStore)(
3908
3998
  registrationStore.subscribe,
3909
3999
  getSnapshot,
3910
4000
  getSnapshot
@@ -3912,10 +4002,10 @@ function createDesignComponentConfig(registration) {
3912
4002
  const html = reg.html ?? "";
3913
4003
  const styles = reg.styles;
3914
4004
  const script = reg.script;
3915
- const [entryEl, setEntryEl] = (0, import_react24.useState)(null);
3916
- const scriptRef = (0, import_react24.useRef)(null);
3917
- const annotations = (0, import_react24.useMemo)(() => getAnnotations(html), [html]);
3918
- const { attrFields, arrayFields, attrSig, arraySig } = (0, import_react24.useMemo)(() => {
4005
+ const [entryEl, setEntryEl] = (0, import_react25.useState)(null);
4006
+ const scriptRef = (0, import_react25.useRef)(null);
4007
+ const annotations = (0, import_react25.useMemo)(() => getAnnotations(html), [html]);
4008
+ const { attrFields, arrayFields, attrSig, arraySig } = (0, import_react25.useMemo)(() => {
3919
4009
  const attr = [];
3920
4010
  const arrays = [];
3921
4011
  for (const field of annotations.fields) {
@@ -3937,11 +4027,11 @@ function createDesignComponentConfig(registration) {
3937
4027
  arraySig: JSON.stringify(arrays)
3938
4028
  };
3939
4029
  }, [props, annotations]);
3940
- const patchedHtml = (0, import_react24.useMemo)(() => {
4030
+ const patchedHtml = (0, import_react25.useMemo)(() => {
3941
4031
  if (puck.isEditing) return html;
3942
4032
  return patchHtmlAnnotations(html, props);
3943
4033
  }, [html, props, puck.isEditing]);
3944
- const fieldValueAttrs = (0, import_react24.useMemo)(() => {
4034
+ const fieldValueAttrs = (0, import_react25.useMemo)(() => {
3945
4035
  const attrs = {};
3946
4036
  attrs["data-puck-design"] = name;
3947
4037
  for (const field of annotations.fields) {
@@ -3952,17 +4042,17 @@ function createDesignComponentConfig(registration) {
3952
4042
  }
3953
4043
  return attrs;
3954
4044
  }, [annotations, props, puck.isEditing]);
3955
- const editorEntryNode = (0, import_react24.useMemo)(
4045
+ const editorEntryNode = (0, import_react25.useMemo)(
3956
4046
  () => puck.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl }) : null,
3957
4047
  [puck.isEditing]
3958
4048
  );
3959
- (0, import_react24.useEffect)(() => {
4049
+ (0, import_react25.useEffect)(() => {
3960
4050
  if (!puck.isEditing || !getPuck) return;
3961
4051
  getPuck().resolveDataById(id, "force");
3962
4052
  }, [reg, puck.isEditing, getPuck, id]);
3963
- const fieldWiring = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
3964
- const morphed = (0, import_react24.useRef)(null);
3965
- (0, import_react24.useLayoutEffect)(() => {
4053
+ const fieldWiring = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
4054
+ const morphed = (0, import_react25.useRef)(null);
4055
+ (0, import_react25.useLayoutEffect)(() => {
3966
4056
  if (!puck.isEditing || !entryEl) return;
3967
4057
  if (morphed.current?.el !== entryEl || morphed.current?.html !== html || morphed.current?.attrSig !== attrSig) {
3968
4058
  morphed.current = { el: entryEl, html, attrSig };
@@ -3979,14 +4069,14 @@ function createDesignComponentConfig(registration) {
3979
4069
  });
3980
4070
  }
3981
4071
  });
3982
- (0, import_react24.useEffect)(
4072
+ (0, import_react25.useEffect)(
3983
4073
  () => () => {
3984
4074
  fieldWiring.current.forEach((cleanup) => cleanup());
3985
4075
  fieldWiring.current.clear();
3986
4076
  },
3987
4077
  []
3988
4078
  );
3989
- (0, import_react24.useEffect)(() => {
4079
+ (0, import_react25.useEffect)(() => {
3990
4080
  if (!entryEl || !puck.isEditing) return;
3991
4081
  for (const attr of Array.from(entryEl.attributes)) {
3992
4082
  if ((attr.name === "data-puck-design" || attr.name.startsWith("data-puck-field-value-")) && !(attr.name in fieldValueAttrs)) {
@@ -3999,10 +4089,10 @@ function createDesignComponentConfig(registration) {
3999
4089
  }
4000
4090
  }
4001
4091
  }, [entryEl, fieldValueAttrs]);
4002
- const appliedArrayHtml = (0, import_react24.useRef)(/* @__PURE__ */ new WeakMap());
4003
- const arrayItemWiring = (0, import_react24.useRef)({});
4004
- const appliedArrays = (0, import_react24.useRef)(null);
4005
- (0, import_react24.useEffect)(() => {
4092
+ const appliedArrayHtml = (0, import_react25.useRef)(/* @__PURE__ */ new WeakMap());
4093
+ const arrayItemWiring = (0, import_react25.useRef)({});
4094
+ const appliedArrays = (0, import_react25.useRef)(null);
4095
+ (0, import_react25.useEffect)(() => {
4006
4096
  if (!puck.isEditing || !entryEl || !getPuck) return;
4007
4097
  if (appliedArrays.current?.el === entryEl && appliedArrays.current?.html === html && appliedArrays.current?.sig === arraySig) {
4008
4098
  return;
@@ -4054,7 +4144,7 @@ function createDesignComponentConfig(registration) {
4054
4144
  id,
4055
4145
  getPuck
4056
4146
  ]);
4057
- (0, import_react24.useEffect)(
4147
+ (0, import_react25.useEffect)(
4058
4148
  () => () => {
4059
4149
  Object.values(arrayItemWiring.current).forEach(
4060
4150
  (wiring) => wiring.forEach(({ cleanup }) => cleanup())
@@ -4062,7 +4152,7 @@ function createDesignComponentConfig(registration) {
4062
4152
  },
4063
4153
  []
4064
4154
  );
4065
- (0, import_react24.useEffect)(() => {
4155
+ (0, import_react25.useEffect)(() => {
4066
4156
  if (!script || !entryEl) return;
4067
4157
  scriptRef.current?.remove();
4068
4158
  const doc = entryEl.ownerDocument;
@@ -4117,7 +4207,7 @@ function createDesignComponentConfig(registration) {
4117
4207
 
4118
4208
  // src/lib/design/globals.tsx
4119
4209
  init_react_import();
4120
- var import_react25 = require("react");
4210
+ var import_react26 = require("react");
4121
4211
  var import_jsx_runtime33 = require("react/jsx-runtime");
4122
4212
  function getDynamicConfigGlobals(dynamicConfig) {
4123
4213
  if (typeof dynamicConfig !== "object" || dynamicConfig === null) return {};
@@ -4133,9 +4223,9 @@ function DesignGlobals({
4133
4223
  script,
4134
4224
  isEditing
4135
4225
  }) {
4136
- const scriptRef = (0, import_react25.useRef)(null);
4137
- const hostRef = (0, import_react25.useRef)(null);
4138
- (0, import_react25.useEffect)(() => {
4226
+ const scriptRef = (0, import_react26.useRef)(null);
4227
+ const hostRef = (0, import_react26.useRef)(null);
4228
+ (0, import_react26.useEffect)(() => {
4139
4229
  if (!script) return;
4140
4230
  scriptRef.current?.remove();
4141
4231
  const doc = hostRef.current?.ownerDocument ?? document;
@@ -4584,7 +4674,7 @@ var q = (0, import_qler.default)();
4584
4674
  var DEFAULT_API_VERSION = "v2";
4585
4675
  var BUILD_OP_DEBOUNCE_MS = 1e3 / 60;
4586
4676
  var CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE = "Unable to verify the page data. Please enable the `/chat/tool` endpoint on the server and try again.";
4587
- var PLUGIN_AI_VERSION = true ? "0.9.0-canary.9c664bf4" : "unknown";
4677
+ var PLUGIN_AI_VERSION = true ? "0.9.0-canary.9ff9b8a5" : "unknown";
4588
4678
  var BENCHMARK = false;
4589
4679
  var prefixedUlid = (prefix = "") => `${prefix ? `${prefix}_` : ""}${(0, import_ulid.ulid)()}`;
4590
4680
  var getClassName18 = getClassNameFactory("Chat", styles_module_default);
@@ -4607,32 +4697,32 @@ function Chat2(props) {
4607
4697
  } = chat ?? {};
4608
4698
  const puckDispatch = usePuck((s) => s.dispatch);
4609
4699
  const getPuck = (0, import_core5.useGetPuck)();
4610
- const localChatId = (0, import_react27.useRef)("");
4611
- const inputRef = (0, import_react27.useRef)(null);
4612
- const pluginRef = (0, import_react27.useRef)(null);
4613
- const [mode, setMode] = (0, import_react27.useState)(defaultMode);
4614
- const modeRef = (0, import_react27.useRef)(mode);
4700
+ const localChatId = (0, import_react28.useRef)("");
4701
+ const inputRef = (0, import_react28.useRef)(null);
4702
+ const pluginRef = (0, import_react28.useRef)(null);
4703
+ const [mode, setMode] = (0, import_react28.useState)(defaultMode);
4704
+ const modeRef = (0, import_react28.useRef)(mode);
4615
4705
  const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
4616
- (0, import_react27.useEffect)(() => {
4706
+ (0, import_react28.useEffect)(() => {
4617
4707
  modeRef.current = mode;
4618
4708
  }, [mode]);
4619
4709
  const puckData = usePuck((s) => s.appState.data);
4620
- (0, import_react27.useEffect)(() => {
4710
+ (0, import_react28.useEffect)(() => {
4621
4711
  syncDesignComponents(getPuck);
4622
4712
  }, [puckData, getPuck]);
4623
- const [error, setError] = (0, import_react27.useState)();
4624
- const [userError, setUserError] = (0, import_react27.useState)();
4625
- const clientToolEndpointUnavailableRef = (0, import_react27.useRef)(false);
4626
- const stopChatRef = (0, import_react27.useRef)(null);
4627
- const [composerAttachments, setComposerAttachments] = (0, import_react27.useState)([]);
4628
- const removedAttachmentClientIdsRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
4629
- const uploadControllersRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
4630
- const pendingBuildOpsRef = (0, import_react27.useRef)([]);
4631
- const lastStreamActivityRef = (0, import_react27.useRef)(0);
4632
- const hiddenSinceRef = (0, import_react27.useRef)(null);
4633
- const [toolStatus, setToolStatus] = (0, import_react27.useState)({});
4634
- const [subagentState, setSubagentState] = (0, import_react27.useState)({});
4635
- const attachmentConfig = (0, import_react27.useMemo)(
4713
+ const [error, setError] = (0, import_react28.useState)();
4714
+ const [userError, setUserError] = (0, import_react28.useState)();
4715
+ const clientToolEndpointUnavailableRef = (0, import_react28.useRef)(false);
4716
+ const stopChatRef = (0, import_react28.useRef)(null);
4717
+ const [composerAttachments, setComposerAttachments] = (0, import_react28.useState)([]);
4718
+ const removedAttachmentClientIdsRef = (0, import_react28.useRef)(/* @__PURE__ */ new Set());
4719
+ const uploadControllersRef = (0, import_react28.useRef)(/* @__PURE__ */ new Map());
4720
+ const pendingBuildOpsRef = (0, import_react28.useRef)([]);
4721
+ const lastStreamActivityRef = (0, import_react28.useRef)(0);
4722
+ const hiddenSinceRef = (0, import_react28.useRef)(null);
4723
+ const [toolStatus, setToolStatus] = (0, import_react28.useState)({});
4724
+ const [subagentState, setSubagentState] = (0, import_react28.useState)({});
4725
+ const attachmentConfig = (0, import_react28.useMemo)(
4636
4726
  () => ({
4637
4727
  accept: attachments?.accept ?? defaultAttachmentAccept,
4638
4728
  enabled: attachments?.enabled ?? true,
@@ -4642,14 +4732,14 @@ function Chat2(props) {
4642
4732
  }),
4643
4733
  [attachments, host]
4644
4734
  );
4645
- (0, import_react27.useEffect)(
4735
+ (0, import_react28.useEffect)(
4646
4736
  () => () => {
4647
4737
  uploadControllersRef.current.forEach((controller) => controller.abort());
4648
4738
  uploadControllersRef.current.clear();
4649
4739
  },
4650
4740
  []
4651
4741
  );
4652
- const deleteAttachment = (0, import_react27.useCallback)(
4742
+ const deleteAttachment = (0, import_react28.useCallback)(
4653
4743
  async (attachmentId) => {
4654
4744
  try {
4655
4745
  await fetch(`${attachmentConfig.endpoint}/${attachmentId}`, {
@@ -4661,7 +4751,7 @@ function Chat2(props) {
4661
4751
  },
4662
4752
  [attachmentConfig.endpoint]
4663
4753
  );
4664
- const uploadScreenshot = (0, import_react27.useCallback)(
4754
+ const uploadScreenshot = (0, import_react28.useCallback)(
4665
4755
  async (width, bucketUrl) => {
4666
4756
  try {
4667
4757
  const iframeDocument = document?.getElementById("preview-frame")?.contentDocument?.documentElement ?? null;
@@ -4716,14 +4806,14 @@ function Chat2(props) {
4716
4806
  BUILD_OP_DEBOUNCE_MS,
4717
4807
  { maxWait: BUILD_OP_DEBOUNCE_MS }
4718
4808
  );
4719
- const queueBuildOp = (0, import_react27.useCallback)(
4809
+ const queueBuildOp = (0, import_react28.useCallback)(
4720
4810
  (operation) => {
4721
4811
  pendingBuildOpsRef.current.push(operation);
4722
4812
  debouncedFlushBuildOps();
4723
4813
  },
4724
4814
  [debouncedFlushBuildOps]
4725
4815
  );
4726
- const handleClientToolEndpointUnavailable = (0, import_react27.useCallback)(() => {
4816
+ const handleClientToolEndpointUnavailable = (0, import_react28.useCallback)(() => {
4727
4817
  if (clientToolEndpointUnavailableRef.current) return;
4728
4818
  clientToolEndpointUnavailableRef.current = true;
4729
4819
  setError(CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE);
@@ -4747,7 +4837,7 @@ function Chat2(props) {
4747
4837
  });
4748
4838
  stopChatRef.current?.();
4749
4839
  }, []);
4750
- const sendClientToolResponse = (0, import_react27.useCallback)(
4840
+ const sendClientToolResponse = (0, import_react28.useCallback)(
4751
4841
  async (body) => {
4752
4842
  try {
4753
4843
  await postClientToolResponse(host, body);
@@ -4757,7 +4847,7 @@ function Chat2(props) {
4757
4847
  },
4758
4848
  [handleClientToolEndpointUnavailable, host]
4759
4849
  );
4760
- const processData = (0, import_react27.useCallback)(
4850
+ const processData = (0, import_react28.useCallback)(
4761
4851
  (dataPart) => {
4762
4852
  lastStreamActivityRef.current = Date.now();
4763
4853
  switch (dataPart.type) {
@@ -4786,12 +4876,14 @@ function Chat2(props) {
4786
4876
  }
4787
4877
  case "data-client-request": {
4788
4878
  const { requestId, action } = dataPart.data;
4879
+ const chatId = localChatId.current || void 0;
4789
4880
  if (action === "getPageData") {
4790
4881
  debouncedFlushBuildOps.flush();
4791
4882
  q.wait().then(() => {
4792
4883
  const { appState } = getPuck();
4793
4884
  return sendClientToolResponse({
4794
4885
  id: requestId,
4886
+ chatId,
4795
4887
  responses: [{ action, output: appState.data }]
4796
4888
  });
4797
4889
  }).catch((e) => {
@@ -4821,12 +4913,14 @@ function Chat2(props) {
4821
4913
  }
4822
4914
  return sendClientToolResponse({
4823
4915
  id: requestId,
4916
+ chatId,
4824
4917
  responses: [{ action, output: { sizeBytes: blob.size } }]
4825
4918
  });
4826
4919
  }).catch((e) => {
4827
4920
  console.error("Failed to respond to client request:", e);
4828
4921
  return sendClientToolResponse({
4829
4922
  id: requestId,
4923
+ chatId,
4830
4924
  responses: [{ action, output: { sizeBytes: 0 } }]
4831
4925
  });
4832
4926
  });
@@ -4964,21 +5058,21 @@ function Chat2(props) {
4964
5058
  });
4965
5059
  }
4966
5060
  });
4967
- (0, import_react27.useEffect)(() => {
5061
+ (0, import_react28.useEffect)(() => {
4968
5062
  stopChatRef.current = stop;
4969
5063
  return () => {
4970
5064
  stopChatRef.current = null;
4971
5065
  stop();
4972
5066
  };
4973
5067
  }, [stop]);
4974
- const statusRef = (0, import_react27.useRef)(status);
4975
- (0, import_react27.useEffect)(() => {
5068
+ const statusRef = (0, import_react28.useRef)(status);
5069
+ (0, import_react28.useEffect)(() => {
4976
5070
  statusRef.current = status;
4977
5071
  }, [status]);
4978
- (0, import_react27.useEffect)(() => {
5072
+ (0, import_react28.useEffect)(() => {
4979
5073
  lastStreamActivityRef.current = Date.now();
4980
5074
  }, [messages]);
4981
- (0, import_react27.useEffect)(() => {
5075
+ (0, import_react28.useEffect)(() => {
4982
5076
  const FROZEN_HIDDEN_MS = 3 * 6e4;
4983
5077
  const RESUME_GRACE_MS = 12e3;
4984
5078
  const isStreaming = () => statusRef.current === "streaming" || statusRef.current === "submitted";
@@ -5021,12 +5115,12 @@ function Chat2(props) {
5021
5115
  if (graceTimer) clearTimeout(graceTimer);
5022
5116
  };
5023
5117
  }, [stop]);
5024
- const [forcedStatus, setForcedStatus] = (0, import_react27.useState)();
5025
- const resolvedStatus = (0, import_react27.useMemo)(
5118
+ const [forcedStatus, setForcedStatus] = (0, import_react28.useState)();
5119
+ const resolvedStatus = (0, import_react28.useMemo)(
5026
5120
  () => forcedStatus ?? status,
5027
5121
  [status, forcedStatus]
5028
5122
  );
5029
- (0, import_react27.useEffect)(() => {
5123
+ (0, import_react28.useEffect)(() => {
5030
5124
  if (!scrollTrackingId) return;
5031
5125
  dispatchScrollTrackingEvent({
5032
5126
  id: scrollTrackingId,
@@ -5039,7 +5133,7 @@ function Chat2(props) {
5039
5133
  });
5040
5134
  };
5041
5135
  }, [resolvedStatus, scrollTrackingId]);
5042
- (0, import_react27.useEffect)(() => {
5136
+ (0, import_react28.useEffect)(() => {
5043
5137
  window.__PUCK_AI = {
5044
5138
  processData,
5045
5139
  setMessages,
@@ -5250,7 +5344,7 @@ function Chat2(props) {
5250
5344
  if (!target?.attachmentId) return;
5251
5345
  await deleteAttachment(target.attachmentId);
5252
5346
  };
5253
- const messagesWithStatuses = (0, import_react27.useMemo)(() => {
5347
+ const messagesWithStatuses = (0, import_react28.useMemo)(() => {
5254
5348
  return messages.map((msg) => {
5255
5349
  return {
5256
5350
  ...msg,
@@ -5435,8 +5529,8 @@ function AttachmentComposer({
5435
5529
  maxFiles,
5436
5530
  onChange
5437
5531
  }) {
5438
- const id = (0, import_react27.useId)();
5439
- const inputId = (0, import_react27.useMemo)(() => `attachment-input-${id}`, []);
5532
+ const id = (0, import_react28.useId)();
5533
+ const inputId = (0, import_react28.useMemo)(() => `attachment-input-${id}`, []);
5440
5534
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: getClassName18("attachmentControls"), children: [
5441
5535
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
5442
5536
  "input",
@@ -5536,7 +5630,7 @@ function isScrolledIntoView(el) {
5536
5630
 
5537
5631
  // src/components/ScrollTracking/ScrollTracking.tsx
5538
5632
  init_react_import();
5539
- var import_react29 = require("react");
5633
+ var import_react30 = require("react");
5540
5634
 
5541
5635
  // src/lib/scroll-into-view-local.ts
5542
5636
  init_react_import();
@@ -5559,9 +5653,9 @@ function scrollIntoViewLocal(el, win, behavior = "smooth") {
5559
5653
 
5560
5654
  // src/lib/use-frame-mutation-observer.ts
5561
5655
  init_react_import();
5562
- var import_react28 = require("react");
5656
+ var import_react29 = require("react");
5563
5657
  function useFrameMutationObserver(callback) {
5564
- return (0, import_react28.useCallback)(() => {
5658
+ return (0, import_react29.useCallback)(() => {
5565
5659
  const frame = document?.getElementById(
5566
5660
  "preview-frame"
5567
5661
  );
@@ -5606,9 +5700,9 @@ var ScrollTracking = ({
5606
5700
  children,
5607
5701
  trackingId
5608
5702
  }) => {
5609
- const followedRefs = (0, import_react29.useRef)([]);
5610
- const enabledRef = (0, import_react29.useRef)(false);
5611
- (0, import_react29.useEffect)(() => {
5703
+ const followedRefs = (0, import_react30.useRef)([]);
5704
+ const enabledRef = (0, import_react30.useRef)(false);
5705
+ (0, import_react30.useEffect)(() => {
5612
5706
  return subscribeToScrollTrackingEvents(({ id, enabled }) => {
5613
5707
  if (id !== trackingId) return;
5614
5708
  enabledRef.current = enabled;
@@ -5627,7 +5721,7 @@ var ScrollTracking = ({
5627
5721
  });
5628
5722
  }
5629
5723
  });
5630
- (0, import_react29.useEffect)(() => {
5724
+ (0, import_react30.useEffect)(() => {
5631
5725
  follow();
5632
5726
  }, [follow]);
5633
5727
  return children;
@@ -5640,7 +5734,7 @@ var import_core7 = require("@puckeditor/core");
5640
5734
  // src/components/ManageComponents/index.tsx
5641
5735
  init_react_import();
5642
5736
  var import_core6 = require("@puckeditor/core");
5643
- var import_react30 = require("react");
5737
+ var import_react31 = require("react");
5644
5738
 
5645
5739
  // css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ManageComponents/styles.module.css#css-module
5646
5740
  init_react_import();
@@ -5649,7 +5743,7 @@ var styles_module_default10 = { "ManageComponents-cta": "_ManageComponents-cta_x
5649
5743
  // src/components/ManageComponents/index.tsx
5650
5744
  var import_jsx_runtime36 = require("react/jsx-runtime");
5651
5745
  var cx10 = getClassNameFactory2("ManageComponents", styles_module_default10);
5652
- var useRegistrations = () => (0, import_react30.useSyncExternalStore)(
5746
+ var useRegistrations = () => (0, import_react31.useSyncExternalStore)(
5653
5747
  registrationStore.subscribe,
5654
5748
  () => registrationStore.getAll(),
5655
5749
  () => registrationStore.getAll()
@@ -5657,9 +5751,9 @@ var useRegistrations = () => (0, import_react30.useSyncExternalStore)(
5657
5751
  function ManageModalContent({ onClose }) {
5658
5752
  const getPuck = (0, import_core6.useGetPuck)();
5659
5753
  const { visible, setVisible } = useModal();
5660
- const [confirmTarget, setConfirmTarget] = (0, import_react30.useState)(null);
5754
+ const [confirmTarget, setConfirmTarget] = (0, import_react31.useState)(null);
5661
5755
  const entries = useRegistrations();
5662
- (0, import_react30.useEffect)(() => {
5756
+ (0, import_react31.useEffect)(() => {
5663
5757
  if (!visible) onClose();
5664
5758
  }, [visible, onClose]);
5665
5759
  const handleDelete = (name) => {
@@ -5714,9 +5808,9 @@ function ManageModalContent({ onClose }) {
5714
5808
  ] }) });
5715
5809
  }
5716
5810
  function ManageComponentsCta() {
5717
- const [open, setOpen] = (0, import_react30.useState)(false);
5811
+ const [open, setOpen] = (0, import_react31.useState)(false);
5718
5812
  const entries = useRegistrations();
5719
- const handleClose = (0, import_react30.useCallback)(() => setOpen(false), []);
5813
+ const handleClose = (0, import_react31.useCallback)(() => setOpen(false), []);
5720
5814
  if (entries.length === 0) return null;
5721
5815
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
5722
5816
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("button", { className: cx10("cta"), onClick: () => setOpen(true), type: "button", children: [
package/dist/index.mjs CHANGED
@@ -999,11 +999,11 @@ import {
999
999
  } from "ai";
1000
1000
  import {
1001
1001
  useCallback as useCallback6,
1002
- useEffect as useEffect13,
1002
+ useEffect as useEffect14,
1003
1003
  useId as useId3,
1004
1004
  useMemo as useMemo6,
1005
1005
  useRef as useRef13,
1006
- useState as useState16
1006
+ useState as useState17
1007
1007
  } from "react";
1008
1008
  import { ulid } from "ulid";
1009
1009
 
@@ -1049,10 +1049,10 @@ var styles_module_default = { "Chat": "_Chat_1ei0a_1", "Chat-header": "_Chat-hea
1049
1049
  init_react_import();
1050
1050
  import {
1051
1051
  useContext as useContext3,
1052
- useEffect as useEffect9,
1052
+ useEffect as useEffect10,
1053
1053
  useMemo as useMemo3,
1054
1054
  useRef as useRef9,
1055
- useState as useState13
1055
+ useState as useState14
1056
1056
  } from "react";
1057
1057
  import { useStickToBottom } from "use-stick-to-bottom";
1058
1058
  import Markdown from "react-markdown";
@@ -1834,6 +1834,42 @@ var matchesAccept = (file, accept) => {
1834
1834
  return file.type === entry;
1835
1835
  });
1836
1836
  };
1837
+ var documentExtensionByMediaType = {
1838
+ "application/msword": "doc",
1839
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
1840
+ "text/markdown": "md",
1841
+ "application/pdf": "pdf",
1842
+ "text/plain": "txt"
1843
+ };
1844
+ var mediaTypeToExtension = (mediaType) => {
1845
+ const mapped = documentExtensionByMediaType[mediaType];
1846
+ if (mapped) {
1847
+ return mapped;
1848
+ }
1849
+ const subtype = mediaType.split("/")[1] ?? "";
1850
+ return subtype.split("+")[0] || "bin";
1851
+ };
1852
+ var getFilesFromClipboard = (data) => {
1853
+ const files = [];
1854
+ for (const item of data.items ? Array.from(data.items) : []) {
1855
+ if (item.kind === "file") {
1856
+ const file = item.getAsFile();
1857
+ if (file) {
1858
+ files.push(file);
1859
+ }
1860
+ }
1861
+ }
1862
+ if (files.length === 0 && data.files) {
1863
+ files.push(...Array.from(data.files));
1864
+ }
1865
+ return files.map(
1866
+ (file, index) => file.name ? file : new File(
1867
+ [file],
1868
+ `pasted-${Date.now()}-${index}.${mediaTypeToExtension(file.type)}`,
1869
+ { type: file.type }
1870
+ )
1871
+ );
1872
+ };
1837
1873
  var getAttachmentIdFromRef = (url) => url.startsWith("attachment://") ? url.slice("attachment://".length) : null;
1838
1874
  var resolveAttachmentUrl = (url, attachmentEndpoint) => {
1839
1875
  if (!attachmentEndpoint) {
@@ -1845,6 +1881,20 @@ var resolveAttachmentUrl = (url, attachmentEndpoint) => {
1845
1881
  }
1846
1882
  return `${attachmentEndpoint.replace(/\/$/, "")}/${attachmentId}`;
1847
1883
  };
1884
+ var fetchAttachmentUrl = async (endpoint, signal) => {
1885
+ const response = await fetch(endpoint, { redirect: "manual", signal });
1886
+ if (response.type === "opaqueredirect" || response.status >= 300 && response.status < 400) {
1887
+ return endpoint;
1888
+ }
1889
+ if (!response.ok) {
1890
+ throw new Error(`Attachment URL request failed with ${response.status}`);
1891
+ }
1892
+ const { url } = await response.json();
1893
+ if (typeof url !== "string" || !url) {
1894
+ throw new Error("Attachment URL response did not include a url");
1895
+ }
1896
+ return url;
1897
+ };
1848
1898
  var isInternalMessage = (text) => text.startsWith(INTERNAL_MESSAGE_PREFIX);
1849
1899
  var truncateFilename = (name, max = 25) => {
1850
1900
  if (name.length <= max) return name;
@@ -1916,6 +1966,16 @@ function PromptForm({
1916
1966
  },
1917
1967
  [canDrop, onFileDrop]
1918
1968
  );
1969
+ const handlePaste = useCallback4(
1970
+ (e) => {
1971
+ if (!canDrop) return;
1972
+ const files = getFilesFromClipboard(e.clipboardData);
1973
+ if (files.length === 0) return;
1974
+ e.preventDefault();
1975
+ onFileDrop(files);
1976
+ },
1977
+ [canDrop, onFileDrop]
1978
+ );
1919
1979
  useEffect8(() => {
1920
1980
  setPrompt(value);
1921
1981
  }, [setPrompt, value]);
@@ -2017,6 +2077,7 @@ function PromptForm({
2017
2077
  internalRef.current = node;
2018
2078
  },
2019
2079
  onChange: (e) => setPrompt(e.target.value),
2080
+ onPaste: onFileDrop ? handlePaste : void 0,
2020
2081
  onKeyDown: (e) => {
2021
2082
  if (!e.shiftKey && e.key === "Enter") {
2022
2083
  e.preventDefault();
@@ -2084,6 +2145,35 @@ var HostProvider = hostContext.Provider;
2084
2145
  var subagentStateContext = createContext3({});
2085
2146
  var SubagentStateProvider = subagentStateContext.Provider;
2086
2147
 
2148
+ // src/lib/use-attachment-url.ts
2149
+ init_react_import();
2150
+ import { useEffect as useEffect9, useState as useState13 } from "react";
2151
+ function useAttachmentUrl(url, endpoint) {
2152
+ const isRef = getAttachmentIdFromRef(url) !== null;
2153
+ const [fetched, setFetched] = useState13();
2154
+ useEffect9(() => {
2155
+ if (!isRef) return;
2156
+ const controller = new AbortController();
2157
+ const loadUrl = async () => {
2158
+ try {
2159
+ const resolved = await fetchAttachmentUrl(
2160
+ resolveAttachmentUrl(url, endpoint),
2161
+ controller.signal
2162
+ );
2163
+ setFetched({ ref: url, url: resolved });
2164
+ } catch (error) {
2165
+ if (!controller.signal.aborted) {
2166
+ console.error("Failed to load attachment:", error);
2167
+ }
2168
+ }
2169
+ };
2170
+ loadUrl();
2171
+ return () => controller.abort();
2172
+ }, [isRef, url, endpoint]);
2173
+ if (!isRef) return url;
2174
+ return fetched?.ref === url ? fetched.url : void 0;
2175
+ }
2176
+
2087
2177
  // src/components/ChatBody/index.tsx
2088
2178
  import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
2089
2179
  var cx8 = getClassNameFactory2("Chat", styles_module_default7);
@@ -2241,7 +2331,7 @@ function ChatAttachmentThumbnail({
2241
2331
  }) {
2242
2332
  const host = useContext3(hostContext);
2243
2333
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2244
- const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2334
+ const resolvedUrl = useAttachmentUrl(url, endpoint);
2245
2335
  const attachmentId = getAttachmentIdFromRef(url);
2246
2336
  const label = filename || attachmentId || "Attachment";
2247
2337
  const isImage = mediaType.startsWith("image/");
@@ -2255,7 +2345,7 @@ function ChatAttachmentThumbnail({
2255
2345
  target: "_blank",
2256
2346
  title: label,
2257
2347
  children: [
2258
- isImage ? /* @__PURE__ */ jsx29("img", { alt: label, src: resolvedUrl }) : /* @__PURE__ */ jsx29(FileText, { size: 20 }),
2348
+ isImage ? resolvedUrl && /* @__PURE__ */ jsx29("img", { alt: label, src: resolvedUrl }) : /* @__PURE__ */ jsx29(FileText, { size: 20 }),
2259
2349
  /* @__PURE__ */ jsx29("span", { className: cxMessage("thumbnailLabel"), children: label })
2260
2350
  ]
2261
2351
  }
@@ -2277,11 +2367,11 @@ function ChatMessageWrapper({
2277
2367
  }
2278
2368
  function ReasoningBlock({ part }) {
2279
2369
  const startTimeRef = useRef9(null);
2280
- const [durationSecs, setDurationSecs] = useState13(null);
2370
+ const [durationSecs, setDurationSecs] = useState14(null);
2281
2371
  if (part.state !== "done" && startTimeRef.current === null) {
2282
2372
  startTimeRef.current = Date.now();
2283
2373
  }
2284
- useEffect9(() => {
2374
+ useEffect10(() => {
2285
2375
  if (part.state === "done" && startTimeRef.current !== null) {
2286
2376
  setDurationSecs(Math.round((Date.now() - startTimeRef.current) / 1e3));
2287
2377
  }
@@ -2335,11 +2425,11 @@ function ChatAttachment({
2335
2425
  }) {
2336
2426
  const host = useContext3(hostContext);
2337
2427
  const endpoint = host ? `${host.replace(/\/$/, "")}/attachments` : "/api/puck/chat/attachments";
2338
- const resolvedUrl = resolveAttachmentUrl(url, endpoint);
2428
+ const resolvedUrl = useAttachmentUrl(url, endpoint);
2339
2429
  const attachmentId = getAttachmentIdFromRef(url);
2340
2430
  const label = filename || attachmentId || "Attachment";
2341
2431
  if (mediaType.startsWith("image/")) {
2342
- return /* @__PURE__ */ jsx29("div", { className: cxMessage("attachmentImage"), children: /* @__PURE__ */ jsx29("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx29("img", { alt: label, src: resolvedUrl }) }) });
2432
+ return /* @__PURE__ */ jsx29("div", { className: cxMessage("attachmentImage"), children: /* @__PURE__ */ jsx29("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: resolvedUrl && /* @__PURE__ */ jsx29("img", { alt: label, src: resolvedUrl }) }) });
2343
2433
  }
2344
2434
  return /* @__PURE__ */ jsx29("div", { className: cxMessage("attachmentFile"), children: /* @__PURE__ */ jsxs16("a", { href: resolvedUrl, target: "_blank", rel: "noreferrer", children: [
2345
2435
  /* @__PURE__ */ jsx29(FileText, { size: 16 }),
@@ -2381,7 +2471,7 @@ function SubagentBlock({ toolCallId }) {
2381
2471
  const loading = state ? state.state !== "done" : toolStatus?.loading ?? true;
2382
2472
  const hasBody = !!state && state.parts.length > 0;
2383
2473
  const parts = state?.parts ?? [];
2384
- const [isOpen, setIsOpen] = useState13(false);
2474
+ const [isOpen, setIsOpen] = useState14(false);
2385
2475
  return /* @__PURE__ */ jsxs16(
2386
2476
  "details",
2387
2477
  {
@@ -2440,7 +2530,7 @@ function ChatEvent({
2440
2530
  status,
2441
2531
  icon = /* @__PURE__ */ jsx29(Check, { size: 18 })
2442
2532
  }) {
2443
- const [isOpen, setIsOpen] = useState13(false);
2533
+ const [isOpen, setIsOpen] = useState14(false);
2444
2534
  return /* @__PURE__ */ jsxs16(
2445
2535
  "details",
2446
2536
  {
@@ -2571,11 +2661,11 @@ import {
2571
2661
  } from "@puckeditor/core";
2572
2662
  import {
2573
2663
  useCallback as useCallback5,
2574
- useEffect as useEffect11,
2664
+ useEffect as useEffect12,
2575
2665
  useLayoutEffect,
2576
2666
  useMemo as useMemo5,
2577
2667
  useRef as useRef11,
2578
- useState as useState15,
2668
+ useState as useState16,
2579
2669
  useSyncExternalStore as useSyncExternalStore2
2580
2670
  } from "react";
2581
2671
 
@@ -3781,7 +3871,7 @@ var htmlToReactTree = (html, slots) => {
3781
3871
 
3782
3872
  // src/lib/design/slot-portal.tsx
3783
3873
  init_react_import();
3784
- import { useEffect as useEffect10, useMemo as useMemo4, useRef as useRef10, useState as useState14 } from "react";
3874
+ import { useEffect as useEffect11, useMemo as useMemo4, useRef as useRef10, useState as useState15 } from "react";
3785
3875
  import { createPortal } from "react-dom";
3786
3876
  import { jsx as jsx31 } from "react/jsx-runtime";
3787
3877
  var parseInlineStyle = (cssText) => {
@@ -3805,13 +3895,13 @@ var SlotPortal = ({
3805
3895
  slotClassName,
3806
3896
  SlotContent
3807
3897
  }) => {
3808
- const [target, setTarget] = useState14(null);
3898
+ const [target, setTarget] = useState15(null);
3809
3899
  const lastTarget = useRef10(null);
3810
3900
  const style = useMemo4(
3811
3901
  () => slotStyle ? parseInlineStyle(slotStyle) : void 0,
3812
3902
  [slotStyle]
3813
3903
  );
3814
- useEffect10(() => {
3904
+ useEffect11(() => {
3815
3905
  const el = entry.querySelector(`[data-puck-slot="${cssEscape(slotName)}"]`);
3816
3906
  if (el !== lastTarget.current) {
3817
3907
  el?.replaceChildren();
@@ -3944,7 +4034,7 @@ function createDesignComponentConfig(registration) {
3944
4034
  const html = reg.html ?? "";
3945
4035
  const styles = reg.styles;
3946
4036
  const script = reg.script;
3947
- const [entryEl, setEntryEl] = useState15(null);
4037
+ const [entryEl, setEntryEl] = useState16(null);
3948
4038
  const scriptRef = useRef11(null);
3949
4039
  const annotations = useMemo5(() => getAnnotations(html), [html]);
3950
4040
  const { attrFields, arrayFields, attrSig, arraySig } = useMemo5(() => {
@@ -3988,7 +4078,7 @@ function createDesignComponentConfig(registration) {
3988
4078
  () => puck.isEditing ? /* @__PURE__ */ jsx32("div", { ref: setEntryEl }) : null,
3989
4079
  [puck.isEditing]
3990
4080
  );
3991
- useEffect11(() => {
4081
+ useEffect12(() => {
3992
4082
  if (!puck.isEditing || !getPuck) return;
3993
4083
  getPuck().resolveDataById(id, "force");
3994
4084
  }, [reg, puck.isEditing, getPuck, id]);
@@ -4011,14 +4101,14 @@ function createDesignComponentConfig(registration) {
4011
4101
  });
4012
4102
  }
4013
4103
  });
4014
- useEffect11(
4104
+ useEffect12(
4015
4105
  () => () => {
4016
4106
  fieldWiring.current.forEach((cleanup) => cleanup());
4017
4107
  fieldWiring.current.clear();
4018
4108
  },
4019
4109
  []
4020
4110
  );
4021
- useEffect11(() => {
4111
+ useEffect12(() => {
4022
4112
  if (!entryEl || !puck.isEditing) return;
4023
4113
  for (const attr of Array.from(entryEl.attributes)) {
4024
4114
  if ((attr.name === "data-puck-design" || attr.name.startsWith("data-puck-field-value-")) && !(attr.name in fieldValueAttrs)) {
@@ -4034,7 +4124,7 @@ function createDesignComponentConfig(registration) {
4034
4124
  const appliedArrayHtml = useRef11(/* @__PURE__ */ new WeakMap());
4035
4125
  const arrayItemWiring = useRef11({});
4036
4126
  const appliedArrays = useRef11(null);
4037
- useEffect11(() => {
4127
+ useEffect12(() => {
4038
4128
  if (!puck.isEditing || !entryEl || !getPuck) return;
4039
4129
  if (appliedArrays.current?.el === entryEl && appliedArrays.current?.html === html && appliedArrays.current?.sig === arraySig) {
4040
4130
  return;
@@ -4086,7 +4176,7 @@ function createDesignComponentConfig(registration) {
4086
4176
  id,
4087
4177
  getPuck
4088
4178
  ]);
4089
- useEffect11(
4179
+ useEffect12(
4090
4180
  () => () => {
4091
4181
  Object.values(arrayItemWiring.current).forEach(
4092
4182
  (wiring) => wiring.forEach(({ cleanup }) => cleanup())
@@ -4094,7 +4184,7 @@ function createDesignComponentConfig(registration) {
4094
4184
  },
4095
4185
  []
4096
4186
  );
4097
- useEffect11(() => {
4187
+ useEffect12(() => {
4098
4188
  if (!script || !entryEl) return;
4099
4189
  scriptRef.current?.remove();
4100
4190
  const doc = entryEl.ownerDocument;
@@ -4149,7 +4239,7 @@ function createDesignComponentConfig(registration) {
4149
4239
 
4150
4240
  // src/lib/design/globals.tsx
4151
4241
  init_react_import();
4152
- import { useEffect as useEffect12, useRef as useRef12 } from "react";
4242
+ import { useEffect as useEffect13, useRef as useRef12 } from "react";
4153
4243
  import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
4154
4244
  function getDynamicConfigGlobals(dynamicConfig) {
4155
4245
  if (typeof dynamicConfig !== "object" || dynamicConfig === null) return {};
@@ -4167,7 +4257,7 @@ function DesignGlobals({
4167
4257
  }) {
4168
4258
  const scriptRef = useRef12(null);
4169
4259
  const hostRef = useRef12(null);
4170
- useEffect12(() => {
4260
+ useEffect13(() => {
4171
4261
  if (!script) return;
4172
4262
  scriptRef.current?.remove();
4173
4263
  const doc = hostRef.current?.ownerDocument ?? document;
@@ -4616,7 +4706,7 @@ var q = qler();
4616
4706
  var DEFAULT_API_VERSION = "v2";
4617
4707
  var BUILD_OP_DEBOUNCE_MS = 1e3 / 60;
4618
4708
  var CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE = "Unable to verify the page data. Please enable the `/chat/tool` endpoint on the server and try again.";
4619
- var PLUGIN_AI_VERSION = true ? "0.9.0-canary.9c664bf4" : "unknown";
4709
+ var PLUGIN_AI_VERSION = true ? "0.9.0-canary.9ff9b8a5" : "unknown";
4620
4710
  var BENCHMARK = false;
4621
4711
  var prefixedUlid = (prefix = "") => `${prefix ? `${prefix}_` : ""}${ulid()}`;
4622
4712
  var getClassName18 = getClassNameFactory("Chat", styles_module_default);
@@ -4642,28 +4732,28 @@ function Chat2(props) {
4642
4732
  const localChatId = useRef13("");
4643
4733
  const inputRef = useRef13(null);
4644
4734
  const pluginRef = useRef13(null);
4645
- const [mode, setMode] = useState16(defaultMode);
4735
+ const [mode, setMode] = useState17(defaultMode);
4646
4736
  const modeRef = useRef13(mode);
4647
4737
  const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
4648
- useEffect13(() => {
4738
+ useEffect14(() => {
4649
4739
  modeRef.current = mode;
4650
4740
  }, [mode]);
4651
4741
  const puckData = usePuck((s) => s.appState.data);
4652
- useEffect13(() => {
4742
+ useEffect14(() => {
4653
4743
  syncDesignComponents(getPuck);
4654
4744
  }, [puckData, getPuck]);
4655
- const [error, setError] = useState16();
4656
- const [userError, setUserError] = useState16();
4745
+ const [error, setError] = useState17();
4746
+ const [userError, setUserError] = useState17();
4657
4747
  const clientToolEndpointUnavailableRef = useRef13(false);
4658
4748
  const stopChatRef = useRef13(null);
4659
- const [composerAttachments, setComposerAttachments] = useState16([]);
4749
+ const [composerAttachments, setComposerAttachments] = useState17([]);
4660
4750
  const removedAttachmentClientIdsRef = useRef13(/* @__PURE__ */ new Set());
4661
4751
  const uploadControllersRef = useRef13(/* @__PURE__ */ new Map());
4662
4752
  const pendingBuildOpsRef = useRef13([]);
4663
4753
  const lastStreamActivityRef = useRef13(0);
4664
4754
  const hiddenSinceRef = useRef13(null);
4665
- const [toolStatus, setToolStatus] = useState16({});
4666
- const [subagentState, setSubagentState] = useState16({});
4755
+ const [toolStatus, setToolStatus] = useState17({});
4756
+ const [subagentState, setSubagentState] = useState17({});
4667
4757
  const attachmentConfig = useMemo6(
4668
4758
  () => ({
4669
4759
  accept: attachments?.accept ?? defaultAttachmentAccept,
@@ -4674,7 +4764,7 @@ function Chat2(props) {
4674
4764
  }),
4675
4765
  [attachments, host]
4676
4766
  );
4677
- useEffect13(
4767
+ useEffect14(
4678
4768
  () => () => {
4679
4769
  uploadControllersRef.current.forEach((controller) => controller.abort());
4680
4770
  uploadControllersRef.current.clear();
@@ -4818,12 +4908,14 @@ function Chat2(props) {
4818
4908
  }
4819
4909
  case "data-client-request": {
4820
4910
  const { requestId, action } = dataPart.data;
4911
+ const chatId = localChatId.current || void 0;
4821
4912
  if (action === "getPageData") {
4822
4913
  debouncedFlushBuildOps.flush();
4823
4914
  q.wait().then(() => {
4824
4915
  const { appState } = getPuck();
4825
4916
  return sendClientToolResponse({
4826
4917
  id: requestId,
4918
+ chatId,
4827
4919
  responses: [{ action, output: appState.data }]
4828
4920
  });
4829
4921
  }).catch((e) => {
@@ -4853,12 +4945,14 @@ function Chat2(props) {
4853
4945
  }
4854
4946
  return sendClientToolResponse({
4855
4947
  id: requestId,
4948
+ chatId,
4856
4949
  responses: [{ action, output: { sizeBytes: blob.size } }]
4857
4950
  });
4858
4951
  }).catch((e) => {
4859
4952
  console.error("Failed to respond to client request:", e);
4860
4953
  return sendClientToolResponse({
4861
4954
  id: requestId,
4955
+ chatId,
4862
4956
  responses: [{ action, output: { sizeBytes: 0 } }]
4863
4957
  });
4864
4958
  });
@@ -4996,7 +5090,7 @@ function Chat2(props) {
4996
5090
  });
4997
5091
  }
4998
5092
  });
4999
- useEffect13(() => {
5093
+ useEffect14(() => {
5000
5094
  stopChatRef.current = stop;
5001
5095
  return () => {
5002
5096
  stopChatRef.current = null;
@@ -5004,13 +5098,13 @@ function Chat2(props) {
5004
5098
  };
5005
5099
  }, [stop]);
5006
5100
  const statusRef = useRef13(status);
5007
- useEffect13(() => {
5101
+ useEffect14(() => {
5008
5102
  statusRef.current = status;
5009
5103
  }, [status]);
5010
- useEffect13(() => {
5104
+ useEffect14(() => {
5011
5105
  lastStreamActivityRef.current = Date.now();
5012
5106
  }, [messages]);
5013
- useEffect13(() => {
5107
+ useEffect14(() => {
5014
5108
  const FROZEN_HIDDEN_MS = 3 * 6e4;
5015
5109
  const RESUME_GRACE_MS = 12e3;
5016
5110
  const isStreaming = () => statusRef.current === "streaming" || statusRef.current === "submitted";
@@ -5053,12 +5147,12 @@ function Chat2(props) {
5053
5147
  if (graceTimer) clearTimeout(graceTimer);
5054
5148
  };
5055
5149
  }, [stop]);
5056
- const [forcedStatus, setForcedStatus] = useState16();
5150
+ const [forcedStatus, setForcedStatus] = useState17();
5057
5151
  const resolvedStatus = useMemo6(
5058
5152
  () => forcedStatus ?? status,
5059
5153
  [status, forcedStatus]
5060
5154
  );
5061
- useEffect13(() => {
5155
+ useEffect14(() => {
5062
5156
  if (!scrollTrackingId) return;
5063
5157
  dispatchScrollTrackingEvent({
5064
5158
  id: scrollTrackingId,
@@ -5071,7 +5165,7 @@ function Chat2(props) {
5071
5165
  });
5072
5166
  };
5073
5167
  }, [resolvedStatus, scrollTrackingId]);
5074
- useEffect13(() => {
5168
+ useEffect14(() => {
5075
5169
  window.__PUCK_AI = {
5076
5170
  processData,
5077
5171
  setMessages,
@@ -5568,7 +5662,7 @@ function isScrolledIntoView(el) {
5568
5662
 
5569
5663
  // src/components/ScrollTracking/ScrollTracking.tsx
5570
5664
  init_react_import();
5571
- import { useEffect as useEffect14, useRef as useRef14 } from "react";
5665
+ import { useEffect as useEffect15, useRef as useRef14 } from "react";
5572
5666
 
5573
5667
  // src/lib/scroll-into-view-local.ts
5574
5668
  init_react_import();
@@ -5640,7 +5734,7 @@ var ScrollTracking = ({
5640
5734
  }) => {
5641
5735
  const followedRefs = useRef14([]);
5642
5736
  const enabledRef = useRef14(false);
5643
- useEffect14(() => {
5737
+ useEffect15(() => {
5644
5738
  return subscribeToScrollTrackingEvents(({ id, enabled }) => {
5645
5739
  if (id !== trackingId) return;
5646
5740
  enabledRef.current = enabled;
@@ -5659,7 +5753,7 @@ var ScrollTracking = ({
5659
5753
  });
5660
5754
  }
5661
5755
  });
5662
- useEffect14(() => {
5756
+ useEffect15(() => {
5663
5757
  follow();
5664
5758
  }, [follow]);
5665
5759
  return children;
@@ -5672,7 +5766,7 @@ import { createUsePuck as createUsePuck2 } from "@puckeditor/core";
5672
5766
  // src/components/ManageComponents/index.tsx
5673
5767
  init_react_import();
5674
5768
  import { useGetPuck as useGetPuck5 } from "@puckeditor/core";
5675
- import { useCallback as useCallback8, useEffect as useEffect15, useState as useState17, useSyncExternalStore as useSyncExternalStore3 } from "react";
5769
+ import { useCallback as useCallback8, useEffect as useEffect16, useState as useState18, useSyncExternalStore as useSyncExternalStore3 } from "react";
5676
5770
 
5677
5771
  // css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ManageComponents/styles.module.css#css-module
5678
5772
  init_react_import();
@@ -5689,9 +5783,9 @@ var useRegistrations = () => useSyncExternalStore3(
5689
5783
  function ManageModalContent({ onClose }) {
5690
5784
  const getPuck = useGetPuck5();
5691
5785
  const { visible, setVisible } = useModal();
5692
- const [confirmTarget, setConfirmTarget] = useState17(null);
5786
+ const [confirmTarget, setConfirmTarget] = useState18(null);
5693
5787
  const entries = useRegistrations();
5694
- useEffect15(() => {
5788
+ useEffect16(() => {
5695
5789
  if (!visible) onClose();
5696
5790
  }, [visible, onClose]);
5697
5791
  const handleDelete = (name) => {
@@ -5746,7 +5840,7 @@ function ManageModalContent({ onClose }) {
5746
5840
  ] }) });
5747
5841
  }
5748
5842
  function ManageComponentsCta() {
5749
- const [open, setOpen] = useState17(false);
5843
+ const [open, setOpen] = useState18(false);
5750
5844
  const entries = useRegistrations();
5751
5845
  const handleClose = useCallback8(() => setOpen(false), []);
5752
5846
  if (entries.length === 0) return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puckeditor/plugin-ai",
3
- "version": "0.9.0-canary.9c664bf4",
3
+ "version": "0.9.0-canary.9ff9b8a5",
4
4
  "author": "Chris Villa <chris@puckeditor.com>",
5
5
  "repository": {
6
6
  "type": "git",
@@ -52,12 +52,12 @@
52
52
  "tsup": "^8.2.4",
53
53
  "typescript": "^5.5.4",
54
54
  "vitest": "^4.1.11",
55
- "@puckeditor/platform-types": "0.9.0-canary.9c664bf4",
56
- "tsup-config": "0.9.0-canary.9c664bf4",
57
- "@puckeditor/ai-types": "0.9.0-canary.9c664bf4",
58
- "tsconfig": "0.9.0-canary.9c664bf4",
59
- "eslint-config-custom": "0.9.0-canary.9c664bf4",
60
- "reducer": "0.9.0-canary.9c664bf4"
55
+ "@puckeditor/platform-types": "0.9.0-canary.9ff9b8a5",
56
+ "eslint-config-custom": "0.9.0-canary.9ff9b8a5",
57
+ "reducer": "0.9.0-canary.9ff9b8a5",
58
+ "tsconfig": "0.9.0-canary.9ff9b8a5",
59
+ "tsup-config": "0.9.0-canary.9ff9b8a5",
60
+ "@puckeditor/ai-types": "0.9.0-canary.9ff9b8a5"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "@puckeditor/core": "^0",