@useinsider/guido 3.3.0-beta.c1e1d7e → 3.3.0-beta.d5c796a

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.
@@ -12,7 +12,7 @@ var t = function() {
12
12
  n,
13
13
  !1,
14
14
  null,
15
- "1a4e7084"
15
+ "cdee3452"
16
16
  );
17
17
  const l = s.exports;
18
18
  export {
@@ -1,38 +1,40 @@
1
- import { defineComponent as J, defineAsyncComponent as I, ref as W, computed as B, watch as Q, onMounted as X, onUnmounted as Y } from "vue";
2
- import { provideGuidoActions as Z } from "../composables/useGuidoActions.js";
3
- import { usePartner as ee } from "../composables/usePartner.js";
4
- import { useStripo as oe } from "../composables/useStripo.js";
5
- import { useTimerClone as te } from "../composables/useTimerClone.js";
6
- import { migrate as H } from "../config/migrator/index.js";
7
- import { ModuleFolderDefaults as x } from "../enums/defaults.js";
8
- import { RIBBON_SELECTOR as ne } from "../enums/onboarding.js";
9
- import re from "./organisms/AutoSaveController.vue.js";
10
- import se from "./organisms/base/Toaster.vue.js";
11
- import ce from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
12
- import ae from "./organisms/header/HeaderWrapper.vue.js";
13
- import ie from "./organisms/LoadingWrapper.vue.js";
14
- import me from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
15
- import de from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
16
- import { useStripoApi as le } from "../services/stripoApi.js";
17
- import { useConfigStore as ue } from "../stores/config.js";
18
- import { useDynamicContentStore as pe } from "../stores/dynamic-content.js";
19
- import { useEditorStore as fe } from "../stores/editor.js";
20
- import { usePreviewStore as ve } from "../stores/preview.js";
21
- import { useUnsubscribeStore as ye } from "../stores/unsubscribe.js";
22
- const We = /* @__PURE__ */ J({
1
+ import { defineComponent as J, defineAsyncComponent as R, ref as I, computed as W, watch as Q, onMounted as X, onUnmounted as Y } from "vue";
2
+ import { useCortexBlueprintBridge as Z } from "../composables/useCortexBlueprintBridge.js";
3
+ import { provideGuidoActions as ee } from "../composables/useGuidoActions.js";
4
+ import { useGuidoStateBridge as oe } from "../composables/useGuidoStateBridge.js";
5
+ import { usePartner as te } from "../composables/usePartner.js";
6
+ import { useStripo as ne } from "../composables/useStripo.js";
7
+ import { useTimerClone as re } from "../composables/useTimerClone.js";
8
+ import { migrate as x } from "../config/migrator/index.js";
9
+ import { ModuleFolderDefaults as G } from "../enums/defaults.js";
10
+ import { RIBBON_SELECTOR as se } from "../enums/onboarding.js";
11
+ import ce from "./organisms/AutoSaveController.vue.js";
12
+ import ae from "./organisms/base/Toaster.vue.js";
13
+ import ie from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
14
+ import me from "./organisms/header/HeaderWrapper.vue.js";
15
+ import de from "./organisms/LoadingWrapper.vue.js";
16
+ import le from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
17
+ import ue from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
18
+ import { useStripoApi as pe } from "../services/stripoApi.js";
19
+ import { useConfigStore as fe } from "../stores/config.js";
20
+ import { useDynamicContentStore as ve } from "../stores/dynamic-content.js";
21
+ import { useEditorStore as ye } from "../stores/editor.js";
22
+ import { usePreviewStore as he } from "../stores/preview.js";
23
+ import { useUnsubscribeStore as Se } from "../stores/unsubscribe.js";
24
+ const He = /* @__PURE__ */ J({
23
25
  __name: "Guido",
24
26
  props: {
25
27
  config: null
26
28
  },
27
29
  emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
28
- setup(G, { expose: z, emit: n }) {
29
- const g = G, q = I(
30
+ setup(H, { expose: z, emit: n }) {
31
+ const g = H, q = R(
30
32
  () => import("./organisms/email-preview/PreviewContainer.vue.js")
31
- ), K = I(
33
+ ), K = R(
32
34
  () => import("./organisms/onboarding/OnboardingWrapper.vue.js")
33
- ), w = W(), u = W(), p = pe(), E = ye(), i = ue();
35
+ ), w = I(), u = I(), p = ve(), E = Se(), i = fe();
34
36
  i.init(g.config);
35
- const f = fe(), V = ve(), m = B(() => f.hasChanges), { isTestPartner: $ } = ee(), D = () => {
37
+ const f = ye(), V = he(), m = W(() => f.hasChanges), { isTestPartner: $ } = te(), D = () => {
36
38
  var e;
37
39
  return (e = w.value) == null ? void 0 : e.handleSave(!0);
38
40
  }, {
@@ -42,8 +44,8 @@ const We = /* @__PURE__ */ J({
42
44
  username: k,
43
45
  template: o,
44
46
  editor: s
45
- } = i, d = (o == null ? void 0 : o.html) || "", F = (o == null ? void 0 : o.css) || "", y = (o == null ? void 0 : o.preselectedDynamicContent) || [], L = (s == null ? void 0 : s.savedModulesFolderName) || x.SAVED_MODULES, U = (s == null ? void 0 : s.defaultModulesFolderName) || x.DEFAULT_MODULES;
46
- f.templateId = v;
47
+ } = i, d = (o == null ? void 0 : o.html) || "", F = (o == null ? void 0 : o.css) || "", y = (o == null ? void 0 : o.preselectedDynamicContent) || [], L = (s == null ? void 0 : s.savedModulesFolderName) || G.SAVED_MODULES, U = (s == null ? void 0 : s.defaultModulesFolderName) || G.DEFAULT_MODULES;
48
+ f.templateId = v, Z(), oe();
47
49
  const h = {
48
50
  emailId: v,
49
51
  userId: C,
@@ -56,11 +58,11 @@ const We = /* @__PURE__ */ J({
56
58
  onReady: () => {
57
59
  console.debug("guido:ready"), n("ready");
58
60
  }
59
- }, { initPlugin: M } = oe(h, _), { getDefaultTemplate: O } = le(), { cloneTimersOnSave: P, hasTimerBlocks: A } = te(), j = B(() => {
61
+ }, { initPlugin: M } = ne(h, _), { getDefaultTemplate: O } = pe(), { cloneTimersOnSave: P, hasTimerBlocks: A } = re(), j = W(() => {
60
62
  var e;
61
63
  return !((e = i.ui) != null && e.showHeader);
62
64
  });
63
- Z({
65
+ ee({
64
66
  onBack: () => {
65
67
  console.debug("guido:back"), n("back");
66
68
  },
@@ -75,9 +77,9 @@ const We = /* @__PURE__ */ J({
75
77
  console.debug("guido:test-email:click"), n("test-email:click");
76
78
  }
77
79
  });
78
- const N = (e) => {
80
+ const B = (e) => {
79
81
  console.debug("dynamic-content:close", e), p.setSelectedDynamicContent(e), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: e }));
80
- }, R = () => {
82
+ }, N = () => {
81
83
  console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
82
84
  };
83
85
  Q(() => m.value, () => {
@@ -90,7 +92,7 @@ const We = /* @__PURE__ */ J({
90
92
  let c = null;
91
93
  const b = () => {
92
94
  var t;
93
- const e = document.querySelector(ne);
95
+ const e = document.querySelector(se);
94
96
  (t = u.value) == null || t.style.setProperty("--ribbon-offset", `${(e == null ? void 0 : e.offsetHeight) ?? 0}px`);
95
97
  };
96
98
  return X(async () => {
@@ -102,10 +104,10 @@ const We = /* @__PURE__ */ J({
102
104
  E.selectedUnsubscribePages = (o == null ? void 0 : o.selectedUnsubscribePages) || [];
103
105
  const a = ((l = o == null ? void 0 : o.migration) == null ? void 0 : l.recommendationConfigs) ?? {};
104
106
  let r = {
105
- html: d && await H(d, a),
107
+ html: d && await x(d, a),
106
108
  css: F
107
109
  };
108
- r.html || (r = await O(), r.html = await H(r.html, a)), A(r.html) && (r.html = await P(r.html)), await M(r), p.selectedDynamicContentList = y;
110
+ r.html || (r = await O(), r.html = await x(r.html, a)), A(r.html) && (r.html = await P(r.html)), await M(r), p.selectedDynamicContentList = y;
109
111
  } catch (a) {
110
112
  console.error("Failed to initialize Stripo editor:", a);
111
113
  }
@@ -120,14 +122,14 @@ const We = /* @__PURE__ */ J({
120
122
  i.reset();
121
123
  }), z({
122
124
  dynamicContent: {
123
- insert: N,
124
- close: R
125
+ insert: B,
126
+ close: N
125
127
  },
126
128
  hasChanges: m,
127
129
  saveSilent: D
128
- }), { __sfc: !0, PreviewContainer: q, OnboardingWrapper: K, headerWrapperRef: w, wrapperRef: u, dynamicContentStore: p, unsubscribeStore: E, props: g, configStore: i, editorStore: f, previewStore: V, hasChanges: m, isTestPartner: $, saveSilent: D, templateId: v, userId: C, partnerName: T, username: k, templateConfig: o, editorConfig: s, html: d, css: F, preselectedDynamicContentList: y, savedModulesFolderName: L, defaultModulesFolderName: U, emit: n, metadata: h, options: _, initPlugin: M, getDefaultTemplate: O, cloneTimersOnSave: P, hasTimerBlocks: A, noHeader: j, insertDynamicContent: N, closeDynamicContent: R, handleDynamicContentOpen: S, ribbonObserver: c, updateRibbonOffset: b, AutoSaveController: re, Toaster: se, FilterSelectionDrawer: ce, HeaderWrapper: ae, LoadingWrapper: ie, SaveAsTemplateDrawer: me, UnsubscribeWrapper: de };
130
+ }), { __sfc: !0, PreviewContainer: q, OnboardingWrapper: K, headerWrapperRef: w, wrapperRef: u, dynamicContentStore: p, unsubscribeStore: E, props: g, configStore: i, editorStore: f, previewStore: V, hasChanges: m, isTestPartner: $, saveSilent: D, templateId: v, userId: C, partnerName: T, username: k, templateConfig: o, editorConfig: s, html: d, css: F, preselectedDynamicContentList: y, savedModulesFolderName: L, defaultModulesFolderName: U, emit: n, metadata: h, options: _, initPlugin: M, getDefaultTemplate: O, cloneTimersOnSave: P, hasTimerBlocks: A, noHeader: j, insertDynamicContent: B, closeDynamicContent: N, handleDynamicContentOpen: S, ribbonObserver: c, updateRibbonOffset: b, AutoSaveController: ce, Toaster: ae, FilterSelectionDrawer: ie, HeaderWrapper: me, LoadingWrapper: de, SaveAsTemplateDrawer: le, UnsubscribeWrapper: ue };
129
131
  }
130
132
  });
131
133
  export {
132
- We as default
134
+ He as default
133
135
  };
@@ -0,0 +1,18 @@
1
+ import l from "./AiStatusPill.vue2.js";
2
+ /* empty css */
3
+ import e from "../../../_virtual/_plugin-vue2_normalizer.js";
4
+ var i = function() {
5
+ var s = this, t = s._self._c, a = s._self._setupProxy;
6
+ return a.showStatusPill ? t("div", { staticClass: "ai-status-pill", attrs: { "aria-live": "polite", role: "status" } }, [t("span", { staticClass: "ai-status-pill__dot" }), t("span", { staticClass: "ai-status-pill__label" }, [s._v(s._s(a.statusLabel))])]) : s._e();
7
+ }, _ = [], r = /* @__PURE__ */ e(
8
+ l,
9
+ i,
10
+ _,
11
+ !1,
12
+ null,
13
+ "dea97ab5"
14
+ );
15
+ const c = r.exports;
16
+ export {
17
+ c as default
18
+ };
@@ -0,0 +1,13 @@
1
+ import { defineComponent as e } from "vue";
2
+ import { useAiStatusStore as r } from "../../../stores/ai-status.js";
3
+ import { storeToRefs as a } from "pinia";
4
+ const f = /* @__PURE__ */ e({
5
+ __name: "AiStatusPill",
6
+ setup(i) {
7
+ const t = r(), { showStatusPill: s, statusLabel: o } = a(t);
8
+ return { __sfc: !0, aiStatus: t, showStatusPill: s, statusLabel: o };
9
+ }
10
+ });
11
+ export {
12
+ f as default
13
+ };
@@ -1,17 +1,17 @@
1
- import i from "./MiddleSlot.vue2.js";
1
+ import r from "./MiddleSlot.vue2.js";
2
2
  import s from "../../../_virtual/_plugin-vue2_normalizer.js";
3
3
  var t = function() {
4
- var r = this, e = r._self._c, o = r._self._setupProxy;
5
- return e("div", [o.editorStore.isVersionHistoryOpen ? e("div", { staticClass: "d-f" }, [e(o.VersionHistory), e(o.VersionHistoryViewOptions)], 1) : o.editorStore.isPreviewModeOpen ? e("div", { staticClass: "d-f" }, [e(o.EmailSizeIndicator), e(o.AmpToggle)], 1) : r._e(), e(o.EditorToolbar, { directives: [{ name: "show", rawName: "v-show", value: o.editorStore.isEditorToolbarVisible, expression: "editorStore.isEditorToolbarVisible" }] })], 1);
6
- }, n = [], a = /* @__PURE__ */ s(
7
- i,
4
+ var o = this, e = o._self._c, i = o._self._setupProxy;
5
+ return e("div", { staticClass: "d-f a-i-c" }, [i.editorStore.isVersionHistoryOpen ? e("div", { staticClass: "d-f" }, [e(i.VersionHistory), e(i.VersionHistoryViewOptions)], 1) : i.editorStore.isPreviewModeOpen ? e("div", { staticClass: "d-f" }, [e(i.EmailSizeIndicator), e(i.AmpToggle)], 1) : o._e(), e(i.EditorToolbar, { directives: [{ name: "show", rawName: "v-show", value: i.editorStore.isEditorToolbarVisible, expression: "editorStore.isEditorToolbarVisible" }] }), e(i.AiStatusPill)], 1);
6
+ }, a = [], n = /* @__PURE__ */ s(
7
+ r,
8
8
  t,
9
- n,
9
+ a,
10
10
  !1,
11
11
  null,
12
12
  null
13
13
  );
14
- const c = a.exports;
14
+ const c = n.exports;
15
15
  export {
16
16
  c as default
17
17
  };
@@ -2,15 +2,16 @@ import { defineComponent as o } from "vue";
2
2
  import r from "../email-preview/amp/AmpToggle.vue.js";
3
3
  import t from "../email-preview/desktop-preview/EmailSizeIndicator.vue.js";
4
4
  import { useEditorStore as i } from "../../../stores/editor.js";
5
- import e from "./EditorToolbar.vue.js";
6
- import m from "./version-history/VersionHistory.vue.js";
7
- import p from "./version-history/ViewOptions.vue.js";
8
- const S = /* @__PURE__ */ o({
5
+ import e from "./AiStatusPill.vue.js";
6
+ import m from "./EditorToolbar.vue.js";
7
+ import p from "./version-history/VersionHistory.vue.js";
8
+ import s from "./version-history/ViewOptions.vue.js";
9
+ const V = /* @__PURE__ */ o({
9
10
  __name: "MiddleSlot",
10
- setup(s) {
11
- return { __sfc: !0, editorStore: i(), AmpToggle: r, EmailSizeIndicator: t, EditorToolbar: e, VersionHistory: m, VersionHistoryViewOptions: p };
11
+ setup(f) {
12
+ return { __sfc: !0, editorStore: i(), AmpToggle: r, EmailSizeIndicator: t, AiStatusPill: e, EditorToolbar: m, VersionHistory: p, VersionHistoryViewOptions: s };
12
13
  }
13
14
  });
14
15
  export {
15
- S as default
16
+ V as default
16
17
  };
@@ -0,0 +1,91 @@
1
+ import { useEmailTemplateApplier as _, resetEmailTemplateApplier as k } from "./useEmailTemplateApplier.js";
2
+ import { useToaster as g } from "./useToaster.js";
3
+ import { useTranslations as I } from "./useTranslations.js";
4
+ import { ToasterTypeOptions as T } from "../enums/toaster.js";
5
+ import { useAiStatusStore as P } from "../stores/ai-status.js";
6
+ import { getActivePinia as W } from "pinia";
7
+ import { watch as B, onUnmounted as D } from "vue";
8
+ const v = "email_template", x = "chat", L = "guido:debug:ai", M = () => {
9
+ if (typeof window > "u")
10
+ return !1;
11
+ try {
12
+ return window.localStorage.getItem(L) === "1";
13
+ } catch {
14
+ return !1;
15
+ }
16
+ }, F = () => {
17
+ const u = W();
18
+ if (!u)
19
+ return;
20
+ const c = u._s, p = c == null ? void 0 : c.get(x);
21
+ if (!p)
22
+ return;
23
+ const { applyTemplate: E, applyTemplateDebounced: A } = _(), i = P(), { showToaster: f } = g(), y = I(), d = (t, r) => {
24
+ const e = y(t);
25
+ return e === t ? r : e;
26
+ }, l = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), h = M(), b = (t, r) => {
27
+ h && console.debug(`[guido:cortex] msg=${t ?? "?"} type=${(r == null ? void 0 : r.type) ?? "?"}`, r);
28
+ }, m = (t) => {
29
+ if (t.blueprintType !== v)
30
+ return;
31
+ const r = t.blueprintId, e = t.blueprintData;
32
+ if (!r || !(e != null && e.html))
33
+ return;
34
+ const n = l.get(r);
35
+ n === void 0 ? (l.set(r, e.html), E(r, e)) : n !== e.html && (l.set(r, e.html), A(r, e));
36
+ }, S = (t) => {
37
+ const r = t.toolCallId ?? "?", e = t.isRunning ? "run" : "done", n = t.error ? "err" : "ok", o = `tool:${r}:${e}:${n}`;
38
+ if (!s.has(o)) {
39
+ if (s.add(o), t.error === !0) {
40
+ i.$patch({ isWorking: !1, currentTool: "", lastError: "tool_error" });
41
+ return;
42
+ }
43
+ t.isRunning === !0 ? i.$patch({
44
+ isWorking: !0,
45
+ currentTool: t.name ?? "",
46
+ lastError: ""
47
+ }) : i.$patch({ isWorking: !1, currentTool: "" });
48
+ }
49
+ }, w = (t, r) => {
50
+ r && a.has(r) || (r && a.add(r), i.$patch({ isWorking: !1, currentTool: "", lastError: t.content ?? "error" }), f({
51
+ type: T.Alert,
52
+ message: d("newsletter.ai-template-failed", "AI couldn't generate the template. Please try again.")
53
+ }));
54
+ }, $ = B(
55
+ () => p.messages,
56
+ (t) => {
57
+ Array.isArray(t) && t.forEach((r) => {
58
+ const e = r == null ? void 0 : r.id;
59
+ (r == null ? void 0 : r.isError) === !0 && e && !a.has(e) && (a.add(e), i.$patch({ isWorking: !1, currentTool: "", lastError: "message_error" }), f({
60
+ type: T.Alert,
61
+ message: d(
62
+ "newsletter.ai-template-failed",
63
+ "AI couldn't generate the template. Please try again."
64
+ )
65
+ }), h && console.debug(`[guido:cortex] message-level error id=${e}`, r));
66
+ const n = r == null ? void 0 : r.segments;
67
+ Array.isArray(n) && n.forEach((o) => {
68
+ if (o)
69
+ switch (b(e, o), o.type) {
70
+ case "blueprint":
71
+ m(o);
72
+ break;
73
+ case "tool":
74
+ S(o);
75
+ break;
76
+ case "error":
77
+ w(o, e);
78
+ break;
79
+ }
80
+ });
81
+ });
82
+ },
83
+ { deep: !0, immediate: !0 }
84
+ );
85
+ D(() => {
86
+ $(), l.clear(), s.clear(), a.clear(), i.$patch({ isWorking: !1, currentTool: "", lastError: "" }), k();
87
+ });
88
+ };
89
+ export {
90
+ F as useCortexBlueprintBridge
91
+ };
@@ -4,20 +4,21 @@ import e from "../static/styles/components/amp-block.css.js";
4
4
  import i from "../static/styles/components/base-input.css.js";
5
5
  import p from "../static/styles/components/button-group.css.js";
6
6
  import n from "../static/styles/components/button.css.js";
7
- import s from "../static/styles/components/combobox.css.js";
8
- import C from "../static/styles/components/counter.css.js";
7
+ import C from "../static/styles/components/combobox.css.js";
8
+ import s from "../static/styles/components/counter.css.js";
9
9
  import f from "../static/styles/components/dropdown-menu.css.js";
10
10
  import a from "../static/styles/components/loader.css.js";
11
11
  import u from "../static/styles/components/narrow-panel.css.js";
12
- import c from "../static/styles/components/popup.css.js";
13
- import d from "../static/styles/components/switcher.css.js";
14
- import l from "../static/styles/components/tabs.css.js";
15
- import h from "../static/styles/components/tools.css.js";
16
- import w from "../static/styles/components/version-history.css.js";
17
- import y from "../static/styles/components/wide-panel.css.js";
18
- import B from "../static/styles/variables.css.js";
19
- const b = [
20
- B,
12
+ import c from "../static/styles/components/notification.css.js";
13
+ import d from "../static/styles/components/popup.css.js";
14
+ import l from "../static/styles/components/switcher.css.js";
15
+ import h from "../static/styles/components/tabs.css.js";
16
+ import w from "../static/styles/components/tools.css.js";
17
+ import y from "../static/styles/components/version-history.css.js";
18
+ import B from "../static/styles/components/wide-panel.css.js";
19
+ import b from "../static/styles/variables.css.js";
20
+ const A = [
21
+ b,
21
22
  // Must be on top
22
23
  S,
23
24
  // Must be on top
@@ -26,8 +27,8 @@ const b = [
26
27
  i,
27
28
  p,
28
29
  n,
29
- s,
30
30
  C,
31
+ s,
31
32
  f,
32
33
  a,
33
34
  u,
@@ -36,12 +37,13 @@ const b = [
36
37
  l,
37
38
  h,
38
39
  w,
39
- y
40
+ y,
41
+ B
40
42
  ].join(`
41
43
 
42
- `), v = () => ({ importCss: () => {
44
+ `), F = () => ({ importCss: () => {
43
45
  const o = new CSSStyleSheet();
44
- o.replaceSync(b);
46
+ o.replaceSync(A);
45
47
  const r = document.querySelector("ui-editor");
46
48
  if (!r)
47
49
  return;
@@ -49,5 +51,5 @@ const b = [
49
51
  t && (t.adoptedStyleSheets = [o]);
50
52
  } });
51
53
  export {
52
- v as useCustomInterfaceAppearance
54
+ F as useCustomInterfaceAppearance
53
55
  };
@@ -0,0 +1,41 @@
1
+ import { useActionsApi as u } from "./useActionsApi.js";
2
+ import { useToaster as T } from "./useToaster.js";
3
+ import { useTranslations as f } from "./useTranslations.js";
4
+ import { ToasterTypeOptions as n } from "../enums/toaster.js";
5
+ import { ref as y } from "vue";
6
+ const h = 250, s = y({}), o = {}, j = () => {
7
+ const { updateHtmlAndCss: l } = u(), { showToaster: r } = T(), i = f(), c = (e, t, p) => {
8
+ s.value = { ...s.value, [e]: "applying" };
9
+ try {
10
+ l(t, p), s.value = { ...s.value, [e]: "applied" }, r({
11
+ type: n.Success,
12
+ message: i("newsletter.ai-template-applied")
13
+ });
14
+ } catch (a) {
15
+ s.value = { ...s.value, [e]: "failed" }, r({
16
+ type: n.Alert,
17
+ message: a instanceof Error ? a.message : "Failed to apply template"
18
+ });
19
+ }
20
+ }, m = (e) => {
21
+ const t = o[e];
22
+ t && (clearTimeout(t), delete o[e]);
23
+ };
24
+ return { applyStatus: s, applyTemplate: (e, t) => {
25
+ t.html && (m(e), c(e, t.html, t.css ?? ""));
26
+ }, applyTemplateDebounced: (e, t) => {
27
+ if (!t.html)
28
+ return;
29
+ m(e);
30
+ const { html: p } = t, a = t.css ?? "";
31
+ o[e] = setTimeout(() => {
32
+ delete o[e], c(e, p, a);
33
+ }, h);
34
+ } };
35
+ }, w = () => {
36
+ Object.values(o).forEach(clearTimeout), Object.keys(o).forEach((l) => delete o[l]), s.value = {};
37
+ };
38
+ export {
39
+ w as resetEmailTemplateApplier,
40
+ j as useEmailTemplateApplier
41
+ };
@@ -0,0 +1,48 @@
1
+ import { useActionsApi as g } from "./useActionsApi.js";
2
+ import { useConfigStore as I } from "../stores/config.js";
3
+ import { useEditorStore as b } from "../stores/editor.js";
4
+ import { useGuidoEmailEditorStore as E } from "../stores/guido-email-editor.js";
5
+ import { watch as c, onUnmounted as T } from "vue";
6
+ const w = 500, z = () => {
7
+ const i = b(), a = E(), l = I(), { getTemplateData: m } = g();
8
+ let e = null, n = !1;
9
+ const r = () => {
10
+ e && (clearTimeout(e), e = null);
11
+ }, s = async () => {
12
+ var t, o;
13
+ if (!(n || !i.isStripoInitialized))
14
+ try {
15
+ const { html: f, css: h } = await m(), S = ((o = (t = l.config) == null ? void 0 : t.identity) == null ? void 0 : o.templateId) ?? "";
16
+ if (n)
17
+ return;
18
+ a.$patch({
19
+ html: f ?? "",
20
+ css: h ?? "",
21
+ templateId: S,
22
+ lastUpdatedAt: Date.now()
23
+ });
24
+ } catch {
25
+ }
26
+ }, u = () => {
27
+ r(), e = setTimeout(() => {
28
+ e = null, s();
29
+ }, w);
30
+ }, d = c(
31
+ () => i.isStripoInitialized,
32
+ (t) => {
33
+ t && s();
34
+ },
35
+ { immediate: !0 }
36
+ ), p = c(
37
+ () => i.hasChanges,
38
+ (t, o) => {
39
+ i.isStripoInitialized && (t ? u() : o && (r(), s()));
40
+ }
41
+ );
42
+ T(() => {
43
+ n = !0, r(), d(), p();
44
+ });
45
+ };
46
+ export {
47
+ z as useGuidoStateBridge
48
+ };
@@ -1,28 +1,27 @@
1
- import { useActionsApi as I } from "./useActionsApi.js";
2
- import { useBlocksConfig as P } from "./useBlocksConfig.js";
3
- import { useConfig as U } from "./useConfig.js";
4
- import { useCustomInterfaceAppearance as R } from "./useCustomInterfaceAppearance.js";
5
- import { useFullStoryBridge as q } from "./useFullStoryBridge.js";
6
- import { useStripoEventHandler as x } from "./useStripoEventHandler.js";
7
- import { useStripoNotifications as H } from "./useStripoNotifications.js";
8
- import { useToaster as N } from "./useToaster.js";
9
- import { localePatch as O } from "../config/i18n/index.js";
10
- import { useStripoApi as j } from "../services/stripoApi.js";
11
- import L from "../static/styles/customEditorStyle.css.js";
1
+ import { useActionsApi as D } from "./useActionsApi.js";
2
+ import { useBlocksConfig as I } from "./useBlocksConfig.js";
3
+ import { useConfig as P } from "./useConfig.js";
4
+ import { useCustomInterfaceAppearance as U } from "./useCustomInterfaceAppearance.js";
5
+ import { useFullStoryBridge as R } from "./useFullStoryBridge.js";
6
+ import { useStripoEventHandler as q } from "./useStripoEventHandler.js";
7
+ import { useToaster as x } from "./useToaster.js";
8
+ import { localePatch as H } from "../config/i18n/index.js";
9
+ import { useStripoApi as O } from "../services/stripoApi.js";
10
+ import j from "../static/styles/customEditorStyle.css.js";
12
11
  import { useEditorStore as E } from "../stores/editor.js";
13
- import { dynamicContentToMergeTags as $ } from "../utils/genericUtil.js";
14
- import z from "../package.json.js";
15
- const dt = (C, c) => {
16
- const { features: l, template: h, isFeatureEnabled: u } = U(), { handleError: m } = N(), { getToken: w, getCustomFonts: b, getSyncModulesStatus: k } = j(), { handleEvent: B } = x(), { getStripoNotifications: T } = H(), { getStripoBlocksConfig: V } = P(), _ = async (i, r = [], s = !1) => {
12
+ import { dynamicContentToMergeTags as L } from "../utils/genericUtil.js";
13
+ import $ from "../package.json.js";
14
+ const se = (C, l) => {
15
+ const { features: c, template: h, isFeatureEnabled: u } = P(), { handleError: m } = x(), { getToken: w, getCustomFonts: b, getSyncModulesStatus: k } = O(), { handleEvent: B } = q(), { getStripoBlocksConfig: T } = I(), V = async (i, r = [], s = !1) => {
17
16
  var g, S, y;
18
- const t = E(), { html: p, css: a } = i, { baseBlocks: o, extensions: d } = await V(), f = ((g = l.value) == null ? void 0 : g.displayConditions) ?? !0, v = ((S = l.value) == null ? void 0 : S.modulesDisabled) ?? !1, M = ((y = h.value) == null ? void 0 : y.forceRecreate) ?? !1;
17
+ const e = E(), { html: p, css: a } = i, { baseBlocks: o, extensions: d } = await T(), f = ((g = c.value) == null ? void 0 : g.displayConditions) ?? !0, F = ((S = c.value) == null ? void 0 : S.modulesDisabled) ?? !1, v = ((y = h.value) == null ? void 0 : y.forceRecreate) ?? !1;
19
18
  window.UIEditor.initEditor(
20
19
  document.querySelector("#guido-editor"),
21
20
  {
22
21
  metadata: C,
23
22
  html: p,
24
23
  css: a,
25
- forceRecreate: M,
24
+ forceRecreate: v,
26
25
  locale: "en",
27
26
  undoButtonSelector: "#guido__undo-button",
28
27
  redoButtonSelector: "#guido__redo-button",
@@ -32,11 +31,11 @@ const dt = (C, c) => {
32
31
  customAppearanceMergetags: !u("liquidSyntax"),
33
32
  customAppearanceMergetagsBorderColor: "#f1f3fe",
34
33
  customAppearanceMergetagsBackgroundColor: "#f1f3fe",
35
- customViewStyles: L,
34
+ customViewStyles: j,
36
35
  conditionsEnabled: f,
37
36
  customConditionsEnabled: f,
38
37
  enableXSSSecurity: !0,
39
- modulesDisabled: v,
38
+ modulesDisabled: F,
40
39
  syncModulesEnabled: s,
41
40
  messageSettingsEnabled: !0,
42
41
  displayGmailAnnotations: !0,
@@ -53,60 +52,59 @@ const dt = (C, c) => {
53
52
  },
54
53
  mergeTags: [
55
54
  {
56
- entries: $(
57
- c.preselectedDynamicContentList,
55
+ entries: L(
56
+ l.preselectedDynamicContentList,
58
57
  u("liquidSyntax")
59
58
  )
60
59
  }
61
60
  ],
62
- async onTokenRefreshRequest(e) {
61
+ async onTokenRefreshRequest(t) {
63
62
  try {
64
63
  const n = await w();
65
- e(n);
64
+ t(n);
66
65
  } catch (n) {
67
66
  m(n, "Failed to refresh token");
68
67
  }
69
68
  },
70
69
  onTemplateLoaded() {
71
70
  try {
72
- const { importCss: e } = R(), { activateCustomViewStyles: n, updateTimerInClonedTemplate: A } = I(), { injectFullStory: D } = q();
73
- e(), n(), D(), A(), c.onReady(), t.isStripoInitialized = !0, t.loadingStatus = !1, setTimeout(() => {
74
- t.hasChanges = !1;
71
+ const { importCss: t } = U(), { activateCustomViewStyles: n, updateTimerInClonedTemplate: M } = D(), { injectFullStory: A } = R();
72
+ t(), n(), A(), M(), l.onReady(), e.isStripoInitialized = !0, e.loadingStatus = !1, setTimeout(() => {
73
+ e.hasChanges = !1;
75
74
  }, 1e3);
76
- } catch (e) {
77
- m(e, "Failed to load custom interface appearance");
75
+ } catch (t) {
76
+ m(t, "Failed to load custom interface appearance");
78
77
  }
79
78
  },
80
- onCodeEditorVisibilityChanged(e) {
81
- t.isCodeEditorOpen = e;
79
+ onCodeEditorVisibilityChanged(t) {
80
+ e.isCodeEditorOpen = t;
82
81
  },
83
- onEditorVisualModeChanged(e) {
84
- t.editorVisualMode = e.toLowerCase();
82
+ onEditorVisualModeChanged(t) {
83
+ e.editorVisualMode = t.toLowerCase();
85
84
  },
86
- onVersionHistoryVisibilityChanged(e) {
87
- t.isVersionHistoryOpen = e;
85
+ onVersionHistoryVisibilityChanged(t) {
86
+ e.isVersionHistoryOpen = t;
88
87
  },
89
88
  onDataChanged() {
90
- t.hasChanges = !0;
89
+ e.hasChanges = !0;
91
90
  },
92
91
  onEvent: B,
93
- notifications: T(),
94
92
  ignoreClickOutsideSelectors: [
95
93
  "#guido-dynamic-content-modal",
96
94
  ".in-on-board-wrapper",
97
95
  ".in-drawer__container"
98
96
  ],
99
97
  extensions: d,
100
- localePatch: O
98
+ localePatch: H
101
99
  }
102
100
  );
103
- }, F = (i) => new Promise((r, s) => {
101
+ }, _ = (i) => new Promise((r, s) => {
104
102
  var d;
105
103
  if (document.getElementById("UiEditorScript")) {
106
104
  i(), r();
107
105
  return;
108
106
  }
109
- const t = z.guido, a = `https://email-static.useinsider.com/guido/${(d = t == null ? void 0 : t.stripo) == null ? void 0 : d.version}/UIEditor.js`, o = document.createElement("script");
107
+ const e = $.guido, a = `https://email-static.useinsider.com/guido/${(d = e == null ? void 0 : e.stripo) == null ? void 0 : d.version}/UIEditor.js`, o = document.createElement("script");
110
108
  o.id = "UiEditorScript", o.type = "module", o.src = a, o.onload = () => {
111
109
  i(), r();
112
110
  }, o.onerror = () => {
@@ -114,15 +112,15 @@ const dt = (C, c) => {
114
112
  }, document.body.appendChild(o);
115
113
  });
116
114
  return { initPlugin: async (i) => {
117
- await F(async () => {
118
- const r = E(), [s, t] = await Promise.all([
115
+ await _(async () => {
116
+ const r = E(), [s, e] = await Promise.all([
119
117
  b(),
120
118
  k()
121
119
  ]);
122
- r.syncModulesEnabled = t, await _(i, s, t);
120
+ r.syncModulesEnabled = e, await V(i, s, e);
123
121
  });
124
122
  } };
125
123
  };
126
124
  export {
127
- dt as useStripo
125
+ se as useStripo
128
126
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-3b53a736],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-4e2a4adb]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-1a4e7084]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-1a4e7084]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-1a4e7084]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-df672485]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-df672485]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-df672485]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-df672485]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-df672485]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-7419ae06] .vueperslides__bullets,[data-v-796d193b] .vueperslides__bullets{pointer-events:none!important}[data-v-796d193b] .vueperslides__parallax-wrapper{height:110px!important}[data-v-cadfc82d] .vueperslides__bullets{pointer-events:none!important}[data-v-cadfc82d] .vueperslides__parallax-wrapper{height:110px!important}
1
+ .gap-16[data-v-3b53a736],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-cd76c125] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.ai-status-pill[data-v-dea97ab5]{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;margin:0 8px;border-radius:12px;background:#3c5af014;color:#2c5282;font-size:12px;font-weight:500;line-height:1.2;-webkit-user-select:none;user-select:none}.ai-status-pill__dot[data-v-dea97ab5]{width:6px;height:6px;border-radius:50%;background:#3c5af0;animation:ai-pulse-dea97ab5 1.4s ease-in-out infinite}.ai-status-pill__label[data-v-dea97ab5]{white-space:nowrap}@keyframes ai-pulse-dea97ab5{0%,to{opacity:.4;transform:scale(1)}50%{opacity:1;transform:scale(1.15)}}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-64c52560]{gap:8px}.version-history__toolbar[data-v-64c52560]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-4e2a4adb]{gap:4px}.header-wrapper[data-v-5c02dcc7]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-cdee3452]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-cdee3452]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-cdee3452]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-df672485]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-df672485]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-df672485]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-df672485]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-df672485]{object-fit:cover;transform:scale(1)}[data-v-43c617a7] .guido__verion-history-view-option-selection-desktop svg,[data-v-43c617a7] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-43c617a7] .in-segments-wrapper__button_selected,[data-v-43c617a7] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-988f8da6]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-988f8da6]{min-height:504px}.iframe-wrapper[data-v-e0424e99]{width:258px}.iframe-scaled[data-v-e0424e99]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-7419ae06] .vueperslides__bullets,[data-v-796d193b] .vueperslides__bullets{pointer-events:none!important}[data-v-796d193b] .vueperslides__parallax-wrapper{height:110px!important}[data-v-cadfc82d] .vueperslides__bullets{pointer-events:none!important}[data-v-cadfc82d] .vueperslides__parallax-wrapper{height:110px!important}
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue/types/v3-component-options.js").ComponentOptionsMixin, import("vue/types/v3-component-options.js").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2
+ export default _default;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Bridges cortex-fe's chat store to Guido's Stripo editor.
3
+ *
4
+ * cortex-fe is a Module Federation MFE that registers `defineStore('chat', …)`
5
+ * on the host's shared (singleton) Pinia. Guido — bundled inside MFE consumers
6
+ * that also share that pinia — reads the same store at runtime via
7
+ * `getActivePinia()._s.get('chat')`. No build-time dep on cortex-fe.
8
+ *
9
+ * The bridge handles three segment shapes:
10
+ *
11
+ * - `blueprint` segments with `blueprintType === 'email_template'` are
12
+ * applied to the Stripo editor (immediate on first sighting, debounced on
13
+ * update, identical-html no-ops).
14
+ * - `tool` segments toggle the AI status pill via `useAiStatusStore`. The
15
+ * pill goes up when `isRunning: true` and clears on `isRunning: false`,
16
+ * `error: true`, or any `error` segment / message-level `isError` flag.
17
+ * - `error` segments (and message-level `isError` / `isCancelled`) trigger
18
+ * a localized toaster and clear the status pill.
19
+ *
20
+ * In dev (`import.meta.env.DEV`) every observed segment + message-level flag
21
+ * change is also `console.debug`-logged with the prefix `[guido:cortex]` so a
22
+ * developer can watch the agent stream in real time. In production this is
23
+ * gated behind `localStorage.guido:debug:ai === '1'`.
24
+ *
25
+ * If cortex-fe isn't loaded the chat store is undefined and the bridge is a
26
+ * no-op (intentional — Guido must still work standalone).
27
+ */
28
+ export declare const useCortexBlueprintBridge: () => void;
@@ -0,0 +1,21 @@
1
+ type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
2
+ /**
3
+ * Applies email_template blueprints from the chat agent to the Stripo editor.
4
+ *
5
+ * - blueprint_create + manual Apply click: immediate.
6
+ * - blueprint_update: debounced 250 ms trailing so rapid mid-stream updates
7
+ * don't thrash updateHtmlAndCss.
8
+ */
9
+ export declare const useEmailTemplateApplier: () => {
10
+ applyStatus: import("vue").Ref<Record<string, ApplyStatus>>;
11
+ applyTemplate: (blueprintId: string, data: {
12
+ html?: string;
13
+ css?: string;
14
+ }) => void;
15
+ applyTemplateDebounced: (blueprintId: string, data: {
16
+ html?: string;
17
+ css?: string;
18
+ }) => void;
19
+ };
20
+ export declare const resetEmailTemplateApplier: () => void;
21
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Outbound bridge — publishes the current editor's html/css to the shared
3
+ * Pinia store `guidoEmailEditor` so cortex-fe can read it at chat-stream
4
+ * submit time and forward it as `clientState.editor`. This is what enables
5
+ * sub-case 1.3 (refine an already-loaded template via the email-agent).
6
+ *
7
+ * The bridge writes on three triggers:
8
+ *
9
+ * 1. Stripo finishes initializing — first snapshot.
10
+ * 2. Editor `hasChanges` flips to true — debounced 500 ms so a streaming
11
+ * Stripo edit doesn't thrash the store.
12
+ * 3. Editor `hasChanges` flips back to false (post-save / autosave) —
13
+ * immediate, since this is the canonical "saved" snapshot.
14
+ *
15
+ * `getTemplateData()` is a Stripo iframe call; it must not run before
16
+ * `isStripoInitialized` is true. The bridge guards against that.
17
+ *
18
+ * If cortex-fe isn't loaded the store still gets written — that's fine;
19
+ * the store has zero overhead and any future reader will find consistent
20
+ * state. The bridge is a one-way pipe with no consumer dependency.
21
+ */
22
+ export declare const useGuidoStateBridge: () => void;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Lightweight read-only store the cortex-fe blueprint bridge writes into and
3
+ * the editor toolbar reads from to show the "AI is generating…" pill while a
4
+ * tool call is in flight. State + getters only — per architecture invariant
5
+ * the bridge mutates state directly via `$patch`, no actions live here.
6
+ */
7
+ export declare const useAiStatusStore: import("pinia").StoreDefinition<"guidoAiStatus", {
8
+ /** A tool is currently running on the agent side. */
9
+ isWorking: boolean;
10
+ /** Tool name the agent is currently invoking, e.g. `tool__qmechanics__compile_template`. */
11
+ currentTool: string;
12
+ /** Last user-facing error message from the stream, cleared on the next tool_call. */
13
+ lastError: string;
14
+ }, {
15
+ /** Show the toolbar pill iff a tool is running AND no error overrides it. */
16
+ showStatusPill: (state: {
17
+ isWorking: boolean;
18
+ currentTool: string;
19
+ lastError: string;
20
+ } & import("pinia").PiniaCustomStateProperties<{
21
+ /** A tool is currently running on the agent side. */
22
+ isWorking: boolean;
23
+ /** Tool name the agent is currently invoking, e.g. `tool__qmechanics__compile_template`. */
24
+ currentTool: string;
25
+ /** Last user-facing error message from the stream, cleared on the next tool_call. */
26
+ lastError: string;
27
+ }>) => boolean;
28
+ /** Display label for the pill — short, suitable for inline UI. */
29
+ statusLabel: (state: {
30
+ isWorking: boolean;
31
+ currentTool: string;
32
+ lastError: string;
33
+ } & import("pinia").PiniaCustomStateProperties<{
34
+ /** A tool is currently running on the agent side. */
35
+ isWorking: boolean;
36
+ /** Tool name the agent is currently invoking, e.g. `tool__qmechanics__compile_template`. */
37
+ currentTool: string;
38
+ /** Last user-facing error message from the stream, cleared on the next tool_call. */
39
+ lastError: string;
40
+ }>) => string;
41
+ }, {}>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Outbound contract Guido publishes to the host's shared Pinia singleton so
3
+ * cortex-fe can pick up the current editor state and forward it as
4
+ * `clientState.editor` on the next chat-stream POST.
5
+ *
6
+ * State + getters only — `useGuidoStateBridge` writes via `$patch`, no actions
7
+ * live here (architecture invariant).
8
+ *
9
+ * Store id `guidoEmailEditor` is cross-MFE: cortex-fe reads it via
10
+ * `pinia._s.get('guidoEmailEditor')` at runtime. The internal Guido editor
11
+ * store keeps id `guidoEditor` — these are intentionally separate. The
12
+ * internal store carries UI state that cortex-fe should not see; this public
13
+ * store carries the contract Guido is willing to share.
14
+ */
15
+ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", {
16
+ /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
17
+ html: string;
18
+ /** Current Stripo CSS — es-p* utility classes used by the html. */
19
+ css: string;
20
+ /** Wall-clock ms when html/css were last written by the bridge. */
21
+ lastUpdatedAt: number;
22
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
23
+ templateId: string;
24
+ }, {
25
+ /** True once the bridge has published at least one snapshot. */
26
+ hasSnapshot: (state: {
27
+ html: string;
28
+ css: string;
29
+ lastUpdatedAt: number;
30
+ templateId: string;
31
+ } & import("pinia").PiniaCustomStateProperties<{
32
+ /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
33
+ html: string;
34
+ /** Current Stripo CSS — es-p* utility classes used by the html. */
35
+ css: string;
36
+ /** Wall-clock ms when html/css were last written by the bridge. */
37
+ lastUpdatedAt: number;
38
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
39
+ templateId: string;
40
+ }>) => boolean;
41
+ }, {}>;
@@ -0,0 +1,74 @@
1
+ const n = `ue-notifications-container {
2
+ left: 96px;
3
+ margin: 0;
4
+ bottom: 32px;
5
+ top: unset;
6
+ width: unset;
7
+ position: fixed;
8
+ }
9
+
10
+ ue-notifications-container ue-message + ue-message {
11
+ margin-bottom: 24px;
12
+ }
13
+
14
+ ue-notifications-container .alert-message-wrapper {
15
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
16
+ border: none;
17
+ padding: 16px 24px;
18
+ }
19
+
20
+ ue-notifications-container .alert-message-wrapper.info,
21
+ ue-notifications-container .alert-message-wrapper.loader {
22
+ background-color: var(--guido-color-background-toaster-info) !important;
23
+ color: inherit;
24
+ }
25
+
26
+ .alert-message-wrapper .alert-message-main {
27
+ align-items: center;
28
+ }
29
+
30
+ ue-notifications-container ue-caption .caption {
31
+ color: var(--guido-color-white) !important;
32
+ }
33
+
34
+ ue-block-thumb-hint {
35
+ text-align: left;
36
+ }
37
+
38
+ ue-notifications-container .alert-message-wrapper .alert-message-main .alert-message-content {
39
+ width: calc(100% - 64px);
40
+ }
41
+
42
+ ue-notifications-container .alert-message-wrapper .alert-message-main .alert-message-text {
43
+ font-size: 15px;
44
+ font-weight: 600;
45
+ }
46
+
47
+ ue-notifications-container .alert-message-text,
48
+ ue-notifications-container .alert-message-wrapper ue-icon-component.icon,
49
+ ue-notifications-container .alert-message-wrapper ue-icon-component.icon-button {
50
+ color: var(--guido-color-white);
51
+ }
52
+
53
+ ue-notifications-container ue-message ue-button.close {
54
+ margin: 0 0 0 16px;
55
+ }
56
+
57
+ ue-notifications-container .alert-message-wrapper.success {
58
+ background: var(--guido-color-background-toaster-success);
59
+ color: inherit;
60
+ }
61
+
62
+ ue-notifications-container .alert-message-wrapper.error {
63
+ background: var(--guido-color-background-toaster-error);
64
+ color: inherit;
65
+ }
66
+
67
+ ue-notifications-container .alert-message-wrapper.warn {
68
+ background: var(--guido-color-background-toaster-warn);
69
+ color: inherit;
70
+ }
71
+ `;
72
+ export {
73
+ n as default
74
+ };
@@ -0,0 +1,25 @@
1
+ import { defineStore as o } from "pinia";
2
+ const i = o("guidoAiStatus", {
3
+ state: () => ({
4
+ /** A tool is currently running on the agent side. */
5
+ isWorking: !1,
6
+ /** Tool name the agent is currently invoking, e.g. `tool__qmechanics__compile_template`. */
7
+ currentTool: "",
8
+ /** Last user-facing error message from the stream, cleared on the next tool_call. */
9
+ lastError: ""
10
+ }),
11
+ getters: {
12
+ /** Show the toolbar pill iff a tool is running AND no error overrides it. */
13
+ showStatusPill: (r) => r.isWorking && r.lastError === "",
14
+ /** Display label for the pill — short, suitable for inline UI. */
15
+ statusLabel: (r) => {
16
+ if (!r.isWorking)
17
+ return "";
18
+ const t = r.currentTool.replace(/^tool__[^_]+__/, "");
19
+ return t ? `AI: ${t}…` : "AI is generating…";
20
+ }
21
+ }
22
+ });
23
+ export {
24
+ i as useAiStatusStore
25
+ };
@@ -0,0 +1,20 @@
1
+ import { defineStore as e } from "pinia";
2
+ const d = e("guidoEmailEditor", {
3
+ state: () => ({
4
+ /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
5
+ html: "",
6
+ /** Current Stripo CSS — es-p* utility classes used by the html. */
7
+ css: "",
8
+ /** Wall-clock ms when html/css were last written by the bridge. */
9
+ lastUpdatedAt: 0,
10
+ /** Template id from the editor config, for cortex-fe to scope per-template. */
11
+ templateId: ""
12
+ }),
13
+ getters: {
14
+ /** True once the bridge has published at least one snapshot. */
15
+ hasSnapshot: (t) => t.lastUpdatedAt > 0 && t.html !== ""
16
+ }
17
+ });
18
+ export {
19
+ d as useGuidoEmailEditorStore
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.3.0-beta.c1e1d7e",
3
+ "version": "3.3.0-beta.d5c796a",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -1,30 +0,0 @@
1
- import { useToaster as a } from "./useToaster.js";
2
- import { ToasterTypeOptions as r } from "../enums/toaster.js";
3
- const h = () => {
4
- const { showToaster: l, hideToaster: u } = a();
5
- let e = null, s = null;
6
- const c = (t, o, i, n) => {
7
- if (e === i && s === o)
8
- return;
9
- e = i, s = o;
10
- const f = n != null && n.action ? { text: n.action.label, onClick: n.action.func } : void 0;
11
- l({ type: t, message: o, actionButton: f });
12
- };
13
- return { getStripoNotifications: () => ({
14
- info: (t, o, i) => c(r.Success, t, o, i),
15
- success: (t, o, i) => c(r.Success, t, o, i),
16
- warn: (t, o, i) => c(r.Warning, t, o, i),
17
- error: (t, o, i) => c(r.Alert, t, o, i),
18
- // Stripo emits `loader` for in-progress operations expected to persist until
19
- // explicit hide(id). Available toaster types auto-dismiss at 6s, so showing
20
- // anything here would lie about completion. Skip until a persistent type exists.
21
- loader: () => {
22
- },
23
- hide: (t) => {
24
- e === t && (u(), e = null, s = null);
25
- }
26
- }) };
27
- };
28
- export {
29
- h as useStripoNotifications
30
- };
@@ -1,4 +0,0 @@
1
- import type { StripoNotifications } from '@@/Types/stripo';
2
- export declare const useStripoNotifications: () => {
3
- getStripoNotifications: () => StripoNotifications;
4
- };