@useinsider/guido 3.13.0-beta.4a55a9f → 3.13.0-beta.ba65053

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -134,7 +134,7 @@ const config: GuidoConfigInput = {
134
134
  // Optional: Editor settings
135
135
  editor?: {
136
136
  locale?: string, // Default: 'en'
137
- translationsPath?: string, // Default: first locale registered on window.trans
137
+ translationsPath?: string, // Default: 'window.trans.en'
138
138
  migrationDate?: number, // Stripo migration timestamp
139
139
  emailHeader?: {
140
140
  senderName?: string,
@@ -1,7 +1,4 @@
1
1
  import { ProductType as a, MessageType as o } from "./schemas.js";
2
- const i = {
3
- translationsPath: "window.trans[Object.keys(window.trans)[0]]"
4
- };
5
2
  a.EMAIL;
6
3
  o.PROMOTIONAL;
7
4
  const e = [
@@ -36,13 +33,12 @@ const e = [
36
33
  "vikingsankara",
37
34
  "stripoeditorlivetest"
38
35
  ];
39
- function s(t) {
36
+ function n(t) {
40
37
  return e.includes(t);
41
38
  }
42
39
  export {
43
- i as DEFAULT_EDITOR,
44
40
  o as MessageType,
45
41
  a as ProductType,
46
42
  e as TEST_PARTNERS,
47
- s as isTestPartner
43
+ n as isTestPartner
48
44
  };
@@ -0,0 +1,17 @@
1
+ import a from "./AiStatusPill.vue2.js";
2
+ import r from "../../../_virtual/_plugin-vue2_normalizer.js";
3
+ var n = function() {
4
+ var t = this, e = t._self._c, s = t._self._setupProxy;
5
+ return s.isGenerating ? e(s.InStatusText, { staticClass: "mr-2", attrs: { "data-testid": "guido-ai-status-pill", size: "small", status: "smart", text: s.label } }) : t._e();
6
+ }, l = [], _ = /* @__PURE__ */ r(
7
+ a,
8
+ n,
9
+ l,
10
+ !1,
11
+ null,
12
+ null
13
+ );
14
+ const u = _.exports;
15
+ export {
16
+ u as default
17
+ };
@@ -0,0 +1,17 @@
1
+ import { defineComponent as i, computed as a } from "vue";
2
+ import { useAiStatus as m } from "../../../composables/useAiStatus.js";
3
+ import { useTranslations as u } from "../../../composables/useTranslations.js";
4
+ import { InStatusText as c } from "@useinsider/design-system-vue";
5
+ const L = /* @__PURE__ */ i({
6
+ __name: "AiStatusPill",
7
+ setup(p) {
8
+ const t = "newsletter.ai-generating", e = "AI is generating...", { isGenerating: r } = m(), n = u(), o = a(() => {
9
+ const s = n(t);
10
+ return s === t ? e : s;
11
+ });
12
+ return { __sfc: !0, LABEL_KEY: t, LABEL_FALLBACK: e, isGenerating: r, trans: n, label: o, InStatusText: c };
13
+ }
14
+ });
15
+ export {
16
+ L as default
17
+ };
@@ -2,7 +2,7 @@ import r from "./MiddleSlot.vue2.js";
2
2
  import s from "../../../_virtual/_plugin-vue2_normalizer.js";
3
3
  var t = function() {
4
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" }] })], 1);
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
6
  }, a = [], n = /* @__PURE__ */ s(
7
7
  r,
8
8
  t,
@@ -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,14 @@
1
+ import { useAiStatusStore as r } from "../stores/ai-status.js";
2
+ import { computed as i } from "vue";
3
+ const s = () => {
4
+ const t = r();
5
+ return {
6
+ isGenerating: i(() => t.isGenerating),
7
+ setGenerating: (e) => {
8
+ t.isGenerating !== e && t.$patch({ isGenerating: e });
9
+ }
10
+ };
11
+ };
12
+ export {
13
+ s as useAiStatus
14
+ };
@@ -1,70 +1,77 @@
1
- import { useEmailTemplateApplier as w, resetEmailTemplateApplier as _ } from "./useEmailTemplateApplier.js";
2
- import { useToaster as I } from "./useToaster.js";
3
- import { useTranslations as P } from "./useTranslations.js";
4
- import { ToasterTypeOptions as S } from "../enums/toaster.js";
5
- import { getActivePinia as v } from "pinia";
6
- import { watch as B, onUnmounted as D } from "vue";
7
- const x = "email_template", L = "chat", M = "guido:debug:ai", R = () => {
1
+ import { useAiStatus as I } from "./useAiStatus.js";
2
+ import { useEmailTemplateApplier as P, resetEmailTemplateApplier as v } from "./useEmailTemplateApplier.js";
3
+ import { useToaster as B } from "./useToaster.js";
4
+ import { useTranslations as D } from "./useTranslations.js";
5
+ import { ToasterTypeOptions as R } from "../enums/toaster.js";
6
+ import { getActivePinia as x } from "pinia";
7
+ import { watch as G, onUnmounted as L } from "vue";
8
+ const M = "email_template", k = "chat", C = "guido:debug:ai", U = () => {
8
9
  if (typeof window > "u")
9
10
  return !1;
10
11
  try {
11
- return window.localStorage.getItem(M) === "1";
12
+ return window.localStorage.getItem(C) === "1";
12
13
  } catch {
13
14
  return !1;
14
15
  }
15
- }, H = () => {
16
- const c = v();
17
- if (!c)
16
+ }, K = () => {
17
+ const a = x();
18
+ if (!a)
18
19
  return;
19
- const l = c._s, p = l == null ? void 0 : l.get(L);
20
- if (!p)
20
+ const l = a._s, c = l == null ? void 0 : l.get(k);
21
+ if (!c)
21
22
  return;
22
- const { markPending: d, applyTemplate: f, applyTemplateDebounced: T } = w(), { showToaster: E } = I(), h = P(), y = (r, t) => {
23
- const e = h(r);
24
- return e === r ? t : e;
25
- }, i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), u = R(), A = (r, t) => {
26
- u && console.debug(`[guido:cortex] msg=${r ?? "?"} type=${(t == null ? void 0 : t.type) ?? "?"}`, t);
27
- }, b = (r) => {
28
- if (r.blueprintType !== x)
23
+ const { markPending: T, applyTemplate: E, applyTemplateDebounced: h } = P(), { showToaster: y } = B(), { setGenerating: p } = I(), A = D(), b = (r, e) => {
24
+ const t = A(r);
25
+ return t === r ? e : t;
26
+ }, n = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Set(), s = U(), m = (r, e) => {
27
+ s && console.debug(`[guido:cortex] msg=${r ?? "?"} type=${(e == null ? void 0 : e.type) ?? "?"}`, e);
28
+ }, w = (r) => {
29
+ if (r.blueprintType !== M)
29
30
  return;
30
- const t = r.blueprintId, e = r.blueprintData;
31
- if (!t || !(e != null && e.html))
31
+ const e = r.blueprintId, t = r.blueprintData;
32
+ if (!e || !(t != null && t.html))
32
33
  return;
33
34
  if (!r.applyRequested) {
34
- d(t);
35
+ T(e);
35
36
  return;
36
37
  }
37
- const o = i.get(t);
38
- o === void 0 ? (i.set(t, e.html), f(t, e)) : o !== e.html && (i.set(t, e.html), T(t, e));
39
- }, s = (r) => r === void 0 || a.has(r) ? !1 : (a.add(r), E({
40
- type: S.Error,
41
- message: y("newsletter.ai-template-failed", "AI couldn't generate the template. Please try again.")
42
- }), !0), m = B(
43
- () => p.messages,
38
+ const o = n.get(e);
39
+ o === void 0 ? (n.set(e, t.html), E(e, t)) : o !== t.html && (n.set(e, t.html), h(e, t));
40
+ }, S = (r, e) => e.isRunning === !0 && r.isStreaming === !0 && r.isError !== !0 && r.isCancelled !== !0, f = (r) => r === void 0 || u.has(r) ? !1 : (u.add(r), y({
41
+ type: R.Error,
42
+ message: b("newsletter.ai-template-failed", "AI couldn't generate the template. Please try again.")
43
+ }), !0), _ = G(
44
+ () => c.messages,
44
45
  (r) => {
45
- Array.isArray(r) && r.forEach((t) => {
46
- const e = t == null ? void 0 : t.id;
47
- (t == null ? void 0 : t.isError) === !0 && s(e) && u && console.debug(`[guido:cortex] message-level error id=${e}`, t);
48
- const o = t == null ? void 0 : t.segments;
49
- Array.isArray(o) && o.forEach((n) => {
50
- if (n)
51
- switch (A(e, n), n.type) {
46
+ if (!Array.isArray(r))
47
+ return;
48
+ let e = !1;
49
+ r.forEach((t) => {
50
+ const o = t == null ? void 0 : t.id;
51
+ (t == null ? void 0 : t.isError) === !0 && f(o) && s && console.debug(`[guido:cortex] message-level error id=${o}`, t);
52
+ const d = t == null ? void 0 : t.segments;
53
+ Array.isArray(d) && d.forEach((i) => {
54
+ if (i)
55
+ switch (m(o, i), i.type) {
52
56
  case "blueprint":
53
- b(n);
57
+ w(i);
58
+ break;
59
+ case "tool":
60
+ e = e || S(t, i);
54
61
  break;
55
62
  case "error":
56
- s(e);
63
+ f(o);
57
64
  break;
58
65
  }
59
66
  });
60
- });
67
+ }), p(e);
61
68
  },
62
69
  { deep: !0, immediate: !0 }
63
70
  );
64
- D(() => {
65
- m(), i.clear(), a.clear(), _();
71
+ L(() => {
72
+ _(), n.clear(), u.clear(), p(!1), v();
66
73
  });
67
74
  };
68
75
  export {
69
- H as useCortexBlueprintBridge
76
+ K as useCortexBlueprintBridge
70
77
  };
@@ -1,20 +1,18 @@
1
- import "../@types/config/schemas.js";
2
- import { DEFAULT_EDITOR } from "../@types/config/defaults.js";
3
1
  import memoize from "../node_modules/lodash-es/memoize.js";
4
2
  import { ref } from "vue";
5
3
  import { useConfig } from "./useConfig.js";
6
4
  const useTranslations = () => {
7
5
  var o, e;
8
- const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || DEFAULT_EDITOR.translationsPath, translations = ref(eval(translationsPath)), trans = (t, n) => {
9
- const r = translations.value[t];
10
- return r ? n ? Object.entries(n).reduce(
6
+ const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || "window.trans.en", translations = ref(eval(translationsPath)), trans = (n, t) => {
7
+ const r = translations.value[n];
8
+ return r ? t ? Object.entries(t).reduce(
11
9
  (s, [i, a]) => s.replace(new RegExp(`{${i}}`, "g"), String(a)),
12
10
  r
13
- ) : r : (console.warn(`Translation key not found: ${t}`), t);
11
+ ) : r : (console.warn(`Translation key not found: ${n}`), n);
14
12
  };
15
13
  return memoize(
16
14
  trans,
17
- (t, n) => !n || Object.keys(n).length === 0 ? t : JSON.stringify({ key: t, params: n })
15
+ (n, t) => !t || Object.keys(t).length === 0 ? n : JSON.stringify({ key: n, params: t })
18
16
  );
19
17
  };
20
18
  export {
@@ -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,16 @@
1
+ import type { ComputedRef } from 'vue';
2
+ interface AiStatus {
3
+ /** True while a cortex-fe agent turn is running a tool. */
4
+ isGenerating: ComputedRef<boolean>;
5
+ /** Idempotent writer — the bridge recomputes this on every stream chunk. */
6
+ setGenerating: (isGenerating: boolean) => void;
7
+ }
8
+ /**
9
+ * Read/write access to the AI status the header pill renders.
10
+ *
11
+ * The setter is deliberately idempotent: the cortex bridge watcher re-derives
12
+ * the status on every streamed chunk, so writing an unchanged value would
13
+ * re-trigger every subscriber several times per second.
14
+ */
15
+ export declare const useAiStatus: () => AiStatus;
16
+ export {};
@@ -6,8 +6,10 @@
6
6
  * that also share that pinia — reads the same store at runtime via
7
7
  * `getActivePinia()._s.get('chat')`. No build-time dep on cortex-fe.
8
8
  *
9
- * The bridge handles two segment shapes:
9
+ * The bridge handles three segment shapes:
10
10
  *
11
+ * - `tool` segments drive the header's "AI is generating…" pill while the
12
+ * owning message is still streaming.
11
13
  * - `blueprint` segments with `blueprintType === 'email_template'` are
12
14
  * applied to the Stripo editor, but ONLY after the user clicks
13
15
  * "Apply to editor" in cortex-fe (which sets `applyRequested` on the
@@ -1,4 +1,9 @@
1
1
  import type { ModuleAddData, ModuleModifier } from '@@/Types/stripo';
2
+ /**
3
+ * Host-registered translation key for the "some attributes could not be
4
+ * converted" toaster. Guido resolves it against the host's `window.trans.en`;
5
+ * the copy is registered host-side.
6
+ */
2
7
  export declare const UNRESOLVED_DYNAMIC_CONTENT_ON_DROP_KEY = "dynamic-content.unresolved-attributes-on-drop";
3
8
  /**
4
9
  * Repairs label-form dynamic-content tokens in saved modules as they are dropped
@@ -0,0 +1,12 @@
1
+ /**
2
+ * AI generation status Guido surfaces in the header while a cortex-fe agent
3
+ * turn is running a tool. Written by `useAiStatus` (via `$patch`) from the
4
+ * inbound cortex bridge; read by the header pill.
5
+ *
6
+ * Store id `guidoAiStatus` is asserted in the local dev smoke checklist
7
+ * (`pinia._s.has('guidoAiStatus')`) — keep it stable.
8
+ */
9
+ export declare const useAiStatusStore: import("pinia").StoreDefinition<"guidoAiStatus", {
10
+ /** True while a cortex-fe tool segment is running inside a live message. */
11
+ isGenerating: boolean;
12
+ }, {}, {}>;
@@ -0,0 +1,10 @@
1
+ import { defineStore as t } from "pinia";
2
+ const i = t("guidoAiStatus", {
3
+ state: () => ({
4
+ /** True while a cortex-fe tool segment is running inside a live message. */
5
+ isGenerating: !1
6
+ })
7
+ });
8
+ export {
9
+ i as useAiStatusStore
10
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.13.0-beta.4a55a9f",
3
+ "version": "3.13.0-beta.ba65053",
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",