@useinsider/guido 3.18.2-beta.a5a0a11 → 3.18.2-beta.ac0d92e

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 (49) hide show
  1. package/dist/components/Guido.vue.js +1 -1
  2. package/dist/components/Guido.vue2.js +60 -54
  3. package/dist/components/organisms/base/Toaster.vue2.js +12 -13
  4. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue.js +11 -13
  5. package/dist/components/organisms/extensions/recommendation/AssignStrategyDrawer.vue2.js +57 -74
  6. package/dist/components/organisms/extensions/recommendation/RemoveStrategyModal.vue2.js +37 -23
  7. package/dist/components/organisms/onboarding/OnboardingWrapper.vue2.js +18 -20
  8. package/dist/composables/useActionsApi.js +24 -20
  9. package/dist/composables/useCortexBlueprintBridge.js +115 -54
  10. package/dist/composables/useCustomInterfaceAppearance.js +46 -56
  11. package/dist/composables/useEmailTemplateApplier.js +93 -50
  12. package/dist/composables/useHtmlValidator.js +82 -87
  13. package/dist/composables/useRecommendation.js +35 -40
  14. package/dist/composables/useStripo.js +30 -30
  15. package/dist/composables/useToaster.js +20 -14
  16. package/dist/enums/extensions/recommendationBlock.js +31 -38
  17. package/dist/extensions/Blocks/Recommendation/block.js +42 -61
  18. package/dist/extensions/Blocks/Recommendation/constants/defaultConfig.js +20 -21
  19. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +35 -40
  20. package/dist/extensions/Blocks/Recommendation/controls/main/strategy.js +52 -84
  21. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -74
  22. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +140 -260
  23. package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +16 -26
  24. package/dist/extensions/Blocks/Recommendation/validation/requiredFields.js +12 -21
  25. package/dist/guido.css +1 -1
  26. package/dist/src/composables/useCortexBlueprintBridge.d.ts +4 -3
  27. package/dist/src/composables/useEmailTemplateApplier.d.ts +22 -2
  28. package/dist/src/enums/extensions/recommendationBlock.d.ts +0 -2
  29. package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -10
  30. package/dist/src/extensions/Blocks/Recommendation/constants/defaultConfig.d.ts +0 -1
  31. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  32. package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +0 -2
  33. package/dist/src/extensions/Blocks/Recommendation/controls/main/strategy.d.ts +0 -9
  34. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +2 -7
  35. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -86
  36. package/dist/src/extensions/Blocks/Recommendation/validation/requiredFields.d.ts +0 -4
  37. package/dist/src/stores/guido-email-editor.d.ts +29 -7
  38. package/dist/src/stores/onboarding.d.ts +0 -377
  39. package/dist/static/styles/components/recommendation-strategy.css.js +4 -34
  40. package/dist/stores/guido-email-editor.js +5 -1
  41. package/dist/stores/onboarding.js +36 -41
  42. package/dist/utils/templatePreparation.js +55 -55
  43. package/package.json +1 -1
  44. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.js +0 -21
  45. package/dist/components/organisms/onboarding/RecommendationStrategyOnboarding.vue2.js +0 -47
  46. package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +0 -24
  47. package/dist/src/components/organisms/onboarding/RecommendationStrategyOnboarding.vue.d.ts +0 -2
  48. package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +0 -14
  49. package/dist/static/styles/components/skeleton.css.js +0 -23
@@ -1,32 +1,22 @@
1
- import { ModificationDescription as g } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { RECOMMENDATION_ID_ATTR as s } from "../constants/selectors.js";
3
- import { isPartnerManagedBlock as p, updateProductContentInPlace as C, regenerateProductRowsWithStyles as N } from "../controls/main/utils.js";
4
- import { RecommendationConfigService as m } from "../services/configService.js";
5
- let o = null;
6
- function D(n) {
7
- o = n;
1
+ import { ModificationDescription as f } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { RECOMMENDATION_ID_ATTR as m } from "../constants/selectors.js";
3
+ import { isPartnerManagedBlock as a, updateProductContentInPlace as d, regenerateProductRowsWithStyles as l } from "../controls/main/utils.js";
4
+ import { RecommendationConfigService as s } from "../services/configService.js";
5
+ let e = null;
6
+ function N(r) {
7
+ e = r;
8
8
  }
9
- function P(n, r, c, l) {
10
- const i = o == null ? void 0 : o.getDocumentRootHtmlNode();
11
- if (!o || !i || !("querySelector" in i))
9
+ function D(r, c, i, u) {
10
+ const n = e == null ? void 0 : e.getDocumentRootHtmlNode();
11
+ if (!e || !n || !("querySelector" in n))
12
12
  return !1;
13
- const e = i.querySelector(`[${s}="${n}"]`);
14
- if (!e)
13
+ const t = n.querySelector(`[${m}="${r}"]`);
14
+ if (!t)
15
15
  return !1;
16
- const t = o.getDocumentModifier(), a = m.getConfig(e), d = Object.keys(r).some((u) => JSON.stringify(a[u]) !== JSON.stringify(r[u]));
17
- if (m.stageConfig(t, e, r), p(e))
18
- return t.apply(new g(l)), !0;
19
- let f = !1;
20
- return C({
21
- currentNode: e,
22
- documentModifier: t,
23
- products: c,
24
- onApplied: () => {
25
- f = !0;
26
- }
27
- }) || (f = N({ currentNode: e, documentModifier: t, products: c })), !f && d && t.apply(new g(l)), !0;
16
+ const o = e.getDocumentModifier();
17
+ return s.stageConfig(o, t, c), a(t) ? (o.apply(new f(u)), !0) : (d({ currentNode: t, documentModifier: o, products: i }) || l({ currentNode: t, documentModifier: o, products: i }), !0);
28
18
  }
29
19
  export {
30
- P as commitBlockChangeOutsidePanel,
31
- D as registerNodeConfigWriter
20
+ D as commitBlockChangeOutsidePanel,
21
+ N as registerNodeConfigWriter
32
22
  };
@@ -1,43 +1,34 @@
1
- const o = "strategy", u = [
1
+ const l = [
2
2
  {
3
3
  key: "locale",
4
4
  getValue: (e) => e.language,
5
5
  getAvailableOptions: (e) => Object.keys(e.languages)
6
6
  },
7
- {
8
- // A block feeds from either an assigned strategy (RRS) or an algorithm (legacy).
9
- // Only a fresh RRS block has neither, and its feed URL would otherwise be built
10
- // from an empty algorithm path.
11
- key: o,
12
- getValue: (e) => e.strategyId || e.strategy
13
- },
14
7
  {
15
8
  key: "currency",
16
9
  getValue: (e) => e.currencySettings.value,
17
10
  getAvailableOptions: (e) => e.currencyList.map((n) => n.text),
18
11
  canBeEmpty: !0
19
12
  }
20
- ], l = "newsletter.recommendation-fill-required-fields", g = "newsletter.recommendation-assign-strategy";
21
- function c(e, n, i = u) {
13
+ ], o = "newsletter.recommendation-fill-required-fields";
14
+ function c(e, n, i = l) {
22
15
  return i.filter((t) => {
23
- var s;
16
+ var u;
24
17
  if (t.condition && !t.condition(e))
25
18
  return !1;
26
- const a = (s = t.getAvailableOptions) == null ? void 0 : s.call(t, n);
27
- if (t.canBeEmpty && (a == null ? void 0 : a.length) === 0)
19
+ const r = (u = t.getAvailableOptions) == null ? void 0 : u.call(t, n);
20
+ if (t.canBeEmpty && (r == null ? void 0 : r.length) === 0)
28
21
  return !1;
29
- const r = t.getValue(e);
30
- return r ? a !== void 0 && !a.includes(r) : !0;
22
+ const a = t.getValue(e);
23
+ return a ? r !== void 0 && !r.includes(a) : !0;
31
24
  }).map((t) => t.key);
32
25
  }
33
- function y(e, n) {
26
+ function s(e, n) {
34
27
  return c(e, n).length === 0;
35
28
  }
36
29
  export {
37
- u as REQUIRED_RECOMMENDATION_FIELDS,
38
- g as RecommendationAssignStrategyKey,
39
- l as RecommendationRequiredFieldsKey,
40
- o as STRATEGY_FIELD_KEY,
30
+ l as REQUIRED_RECOMMENDATION_FIELDS,
31
+ o as RecommendationRequiredFieldsKey,
41
32
  c as getInvalidFields,
42
- y as isConfigValid
33
+ s as isConfigValid
43
34
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__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-1ca6baf0]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-cc5ee925]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-cc5ee925]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-cc5ee925]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .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-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{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-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-7f9442a6]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-7f9442a6] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-7f9442a6] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}
1
+ @charset "UTF-8";.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__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-1ca6baf0]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-7674b645]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-7674b645]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-7674b645]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .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-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{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-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-2580a7d9] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}
@@ -17,12 +17,13 @@
17
17
  * - `error` segments (and message-level `isError` / `isCancelled`) trigger
18
18
  * a localized toaster.
19
19
  *
20
+ * Every apply settles into a terminal `applyAcks` entry on the public store, so
21
+ * cortex can move its Apply button on the truth of the editor write rather than
22
+ * on the click.
23
+ *
20
24
  * In dev (`import.meta.env.DEV`) every observed segment + message-level flag
21
25
  * change is also `console.debug`-logged with the prefix `[guido:cortex]` so a
22
26
  * developer can watch the agent stream in real time. In production this is
23
27
  * 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
  */
28
29
  export declare const useCortexBlueprintBridge: () => void;
@@ -1,4 +1,20 @@
1
1
  type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
2
+ /**
3
+ * Terminal outcome of an apply. Every promise this composable hands out settles
4
+ * with exactly one of these — callers (the cortex bridge) ack on it, so a
5
+ * never-settling promise would strand cortex's Apply button forever.
6
+ *
7
+ * `superseded` means a newer payload for the same blueprint replaced this one:
8
+ * not a success, not a failure, and deliberately never acked.
9
+ */
10
+ export type ApplyOutcome = {
11
+ status: 'applied';
12
+ } | {
13
+ status: 'failed';
14
+ error: unknown;
15
+ } | {
16
+ status: 'superseded';
17
+ };
2
18
  /**
3
19
  * Applies email_template blueprints from the chat agent to the Stripo editor.
4
20
  *
@@ -9,6 +25,10 @@ type ApplyStatus = 'pending' | 'applying' | 'applied' | 'failed';
9
25
  * - manual Apply click (first apply): immediate.
10
26
  * - blueprint_update after the user has applied once: debounced 250 ms trailing
11
27
  * so rapid mid-stream updates don't thrash updateHtmlAndCss.
28
+ *
29
+ * A click that lands before Stripo finished initializing is queued rather than
30
+ * dropped, and flushed when `isStripoInitialized` flips — the user does not
31
+ * have to click again.
12
32
  */
13
33
  export declare const useEmailTemplateApplier: () => {
14
34
  applyStatus: import("vue").Ref<Record<string, ApplyStatus>>;
@@ -16,11 +36,11 @@ export declare const useEmailTemplateApplier: () => {
16
36
  applyTemplate: (blueprintId: string, data: {
17
37
  html?: string;
18
38
  css?: string;
19
- }) => void;
39
+ }) => Promise<ApplyOutcome>;
20
40
  applyTemplateDebounced: (blueprintId: string, data: {
21
41
  html?: string;
22
42
  css?: string;
23
- }) => void;
43
+ }) => Promise<ApplyOutcome>;
24
44
  };
25
45
  export declare const resetEmailTemplateApplier: () => void;
26
46
  export {};
@@ -5,9 +5,7 @@ export declare const URLS: {
5
5
  PRODUCT_ATTRIBUTES_PATH: string;
6
6
  RECOMMENDATION_STRATEGIES_PATH: string;
7
7
  RECOMMENDATION_STRATEGIES_PANEL_PATH: string;
8
- RECOMMENDATION_STRATEGY_CREATE_PATH: string;
9
8
  };
10
- export declare const strategyEditPath: (strategyId: string | number) => string;
11
9
  export declare const QUERY_PARAMS: {
12
10
  CLIENT_ID: string;
13
11
  };
@@ -15,8 +15,6 @@ export declare class RecommendationBlock extends Block {
15
15
  * This avoids generating a new (different) ID in onCreated().
16
16
  */
17
17
  private _pendingBlockId;
18
- /** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
19
- private _resetSourceIds;
20
18
  constructor();
21
19
  getId(): string;
22
20
  getIcon(): string;
@@ -75,14 +73,6 @@ export declare class RecommendationBlock extends Block {
75
73
  * in the document and finding the maximum existing ID + 1.
76
74
  */
77
75
  private _generateNextId;
78
- /**
79
- * Drops the "already fetched" claims of a block that arrived holding a baked id
80
- * (saved module, paste, duplicate), so the settings panel reads its strategy again.
81
- *
82
- * Deferred a tick: the collision handlers rename a sibling first, and either sibling can be
83
- * the renamed one depending on where the module was dropped (SD-149916).
84
- */
85
- private _scheduleArrivalReset;
86
76
  /**
87
77
  * Heals a duplicate that slipped past the create-time `_detectDuplicate`
88
78
  * scan (or that was persisted by an older template before SD-142352).
@@ -10,7 +10,6 @@
10
10
  import type { RecommendationNodeConfig, CurrencyConfig, OmnibusTextConfig } from '../types/nodeConfig';
11
11
  export declare const PRE_RRS_CONFIG_VERSION = 1;
12
12
  export declare const CURRENT_CONFIG_VERSION = 2;
13
- export declare const RRS_CONFIG_VERSION = 2;
14
13
  /**
15
14
  * Default currency configuration
16
15
  * Uses USD as the base currency with standard formatting
@@ -10,4 +10,4 @@ export { RecommendationBlockId } from './blockIds';
10
10
  export { RecommendationControlId } from './controlIds';
11
11
  export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CSS_CLASS_SKIP_COMPILE, RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_RECOMMENDATION_TITLE, SELECTOR_TITLE_CELL, ATTR_CUSTOM_PREFIX, ATTR_DATA_CARD_COMPOSITION, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, CSS_CLASS_ATTRIBUTE_ROW, CSS_CLASS_SPACER, SELECTOR_ATTRIBUTE_ROW, ATTR_DATA_ATTRIBUTE_TYPE, ATTR_DATA_VISIBILITY, PRODUCT_ATTRIBUTE_PREFIX, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
12
12
  export { LAYOUT_VALUES, LAYOUT_OPTIONS, DEFAULT_PRODUCTS_PER_ROW, DEFAULT_CARDS_IN_ROW, DEFAULT_MOBILE_CARDS_IN_ROW, MAX_PRODUCT_COUNT, MIN_PRODUCT_COUNT, MAX_PRODUCTS_PER_ROW, MIN_PRODUCTS_PER_ROW, MAX_MOBILE_PRODUCTS_PER_ROW, MIN_MOBILE_PRODUCTS_PER_ROW, DEFAULT_COLUMN_SPACING, DEFAULT_ROW_SPACING, DEFAULT_MOBILE_COLUMN_SPACING, DEFAULT_MOBILE_ROW_SPACING, MIN_SPACING, MAX_SPACING, SPACING_STEP, } from './layout';
13
- export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, PRE_RRS_CONFIG_VERSION, RRS_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
13
+ export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, PRE_RRS_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
@@ -70,8 +70,6 @@ export declare class RecommendationBlockControl extends CommonControl {
70
70
  * state was rebuilt with (SD-150347).
71
71
  */
72
72
  private _syncNodeConfigIfChanged;
73
- /** Whether the deferred write would move the node's strategyId — see the caller (SD-149916). */
74
- private _isPendingStrategyIdChange;
75
73
  private _capturePendingNodeConfigWrite;
76
74
  /**
77
75
  * Accumulates the pending write into `documentModifier` without applying, so the
@@ -2,7 +2,6 @@ import { CommonControl } from '../../../common-control';
2
2
  export declare const STRATEGY_CONTROL_ID = "recommendation-strategy-control";
3
3
  export declare class StrategyControl extends CommonControl {
4
4
  private store;
5
- private onboardingStore;
6
5
  private storeUnsubscription;
7
6
  private listeners;
8
7
  private lastPaintedState;
@@ -10,14 +9,6 @@ export declare class StrategyControl extends CommonControl {
10
9
  getTemplate(): string;
11
10
  private _strategyAction;
12
11
  onRender(): void;
13
- /**
14
- * Whether the document itself says this block has no strategy.
15
- *
16
- * Read the node, not the store: when the main control cannot resolve the block id off the
17
- * node it never syncs the persisted config, so the store still holds defaults (empty
18
- * strategyId) for an assigned block.
19
- */
20
- private _isNodeUnassigned;
21
12
  onDestroy(): void;
22
13
  private _teardown;
23
14
  private _setupButtonListeners;
@@ -107,7 +107,7 @@ export interface RegenerateWithStylesOptions extends Omit<RegenerateProductRowsO
107
107
  * HTML removes the need for any post-rebuild reapply pass.
108
108
  * @param options - Configuration options for regeneration
109
109
  */
110
- export declare function regenerateProductRowsWithStyles(options: RegenerateWithStylesOptions): boolean;
110
+ export declare function regenerateProductRowsWithStyles(options: RegenerateWithStylesOptions): void;
111
111
  /**
112
112
  * Adjusts a products array to a target size.
113
113
  * Used by ProductLayoutControl to synchronously match products to the new size
@@ -151,11 +151,6 @@ export interface UpdateProductContentInPlaceOptions {
151
151
  currentNode: ImmutableHtmlNode | null | undefined;
152
152
  documentModifier: DocumentModifier;
153
153
  products: RecommendationProduct[];
154
- /**
155
- * Called when the batch was actually committed. Identical products commit nothing, which
156
- * leaves anything a caller staged into the same batch unwritten unless it applies itself.
157
- */
158
- onApplied?: () => void;
159
154
  }
160
155
  /**
161
156
  * Updates product content in-place without regenerating HTML structure.
@@ -166,7 +161,7 @@ export interface UpdateProductContentInPlaceOptions {
166
161
  * After updating desktop, also updates mobile container to keep them in sync.
167
162
  *
168
163
  * Falls back to false when product count changed (need to add/remove elements).
169
- * @param options - Configuration options; `onApplied` fires only when a batch was committed
164
+ * @param options - Configuration options
170
165
  * @returns true if in-place update was successful, false to fall back to full regeneration
171
166
  */
172
167
  export declare function updateProductContentInPlace(options: UpdateProductContentInPlaceOptions): boolean;
@@ -83,11 +83,8 @@ interface StoreState {
83
83
  strategies: RrsStrategy[];
84
84
  strategiesLoading: boolean;
85
85
  strategyUrlTemplates: Record<string, string>;
86
- strategiesFetched: boolean;
87
- strategiesSettled: boolean;
88
86
  blockStates: Record<number, PerBlockState>;
89
87
  currentRecommendationId: number | null;
90
- strategyPanelOpen: boolean;
91
88
  configVersion: number;
92
89
  }
93
90
  export declare const useRecommendationExtensionStore: import("pinia").StoreDefinition<"guidoRecommendationExtension", StoreState, {
@@ -114,11 +111,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
114
111
  }[];
115
112
  strategiesLoading: boolean;
116
113
  strategyUrlTemplates: Record<string, string>;
117
- strategiesFetched: boolean;
118
- strategiesSettled: boolean;
119
114
  blockStates: Record<number, PerBlockState>;
120
115
  currentRecommendationId: number | null;
121
- strategyPanelOpen: boolean;
122
116
  configVersion: number;
123
117
  } & import("pinia").PiniaCustomStateProperties<StoreState>): PerBlockConfigs;
124
118
  /**
@@ -143,11 +137,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
143
137
  }[];
144
138
  strategiesLoading: boolean;
145
139
  strategyUrlTemplates: Record<string, string>;
146
- strategiesFetched: boolean;
147
- strategiesSettled: boolean;
148
140
  blockStates: Record<number, PerBlockState>;
149
141
  currentRecommendationId: number | null;
150
- strategyPanelOpen: boolean;
151
142
  configVersion: number;
152
143
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RecommendationProduct[];
153
144
  /**
@@ -172,11 +163,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
172
163
  }[];
173
164
  strategiesLoading: boolean;
174
165
  strategyUrlTemplates: Record<string, string>;
175
- strategiesFetched: boolean;
176
- strategiesSettled: boolean;
177
166
  blockStates: Record<number, PerBlockState>;
178
167
  currentRecommendationId: number | null;
179
- strategyPanelOpen: boolean;
180
168
  configVersion: number;
181
169
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
182
170
  assignStrategyDrawerStatus(state: {
@@ -198,11 +186,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
198
186
  }[];
199
187
  strategiesLoading: boolean;
200
188
  strategyUrlTemplates: Record<string, string>;
201
- strategiesFetched: boolean;
202
- strategiesSettled: boolean;
203
189
  blockStates: Record<number, PerBlockState>;
204
190
  currentRecommendationId: number | null;
205
- strategyPanelOpen: boolean;
206
191
  configVersion: number;
207
192
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
208
193
  removeStrategyModalStatus(state: {
@@ -224,11 +209,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
224
209
  }[];
225
210
  strategiesLoading: boolean;
226
211
  strategyUrlTemplates: Record<string, string>;
227
- strategiesFetched: boolean;
228
- strategiesSettled: boolean;
229
212
  blockStates: Record<number, PerBlockState>;
230
213
  currentRecommendationId: number | null;
231
- strategyPanelOpen: boolean;
232
214
  configVersion: number;
233
215
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
234
216
  assignedStrategy(state: {
@@ -250,11 +232,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
250
232
  }[];
251
233
  strategiesLoading: boolean;
252
234
  strategyUrlTemplates: Record<string, string>;
253
- strategiesFetched: boolean;
254
- strategiesSettled: boolean;
255
235
  blockStates: Record<number, PerBlockState>;
256
236
  currentRecommendationId: number | null;
257
- strategyPanelOpen: boolean;
258
237
  configVersion: number;
259
238
  } & import("pinia").PiniaCustomStateProperties<StoreState>): RrsStrategy | null;
260
239
  /**
@@ -279,11 +258,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
279
258
  }[];
280
259
  strategiesLoading: boolean;
281
260
  strategyUrlTemplates: Record<string, string>;
282
- strategiesFetched: boolean;
283
- strategiesSettled: boolean;
284
261
  blockStates: Record<number, PerBlockState>;
285
262
  currentRecommendationId: number | null;
286
- strategyPanelOpen: boolean;
287
263
  configVersion: number;
288
264
  } & import("pinia").PiniaCustomStateProperties<StoreState>): boolean;
289
265
  /**
@@ -308,11 +284,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
308
284
  }[];
309
285
  strategiesLoading: boolean;
310
286
  strategyUrlTemplates: Record<string, string>;
311
- strategiesFetched: boolean;
312
- strategiesSettled: boolean;
313
287
  blockStates: Record<number, PerBlockState>;
314
288
  currentRecommendationId: number | null;
315
- strategyPanelOpen: boolean;
316
289
  configVersion: number;
317
290
  } & import("pinia").PiniaCustomStateProperties<StoreState>): number;
318
291
  hasFilters(): boolean;
@@ -338,11 +311,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
338
311
  }[];
339
312
  strategiesLoading: boolean;
340
313
  strategyUrlTemplates: Record<string, string>;
341
- strategiesFetched: boolean;
342
- strategiesSettled: boolean;
343
314
  blockStates: Record<number, PerBlockState>;
344
315
  currentRecommendationId: number | null;
345
- strategyPanelOpen: boolean;
346
316
  configVersion: number;
347
317
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
348
318
  text: string;
@@ -367,11 +337,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
367
337
  }[];
368
338
  strategiesLoading: boolean;
369
339
  strategyUrlTemplates: Record<string, string>;
370
- strategiesFetched: boolean;
371
- strategiesSettled: boolean;
372
340
  blockStates: Record<number, PerBlockState>;
373
341
  currentRecommendationId: number | null;
374
- strategyPanelOpen: boolean;
375
342
  configVersion: number;
376
343
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
377
344
  text: string;
@@ -396,11 +363,8 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
396
363
  }[];
397
364
  strategiesLoading: boolean;
398
365
  strategyUrlTemplates: Record<string, string>;
399
- strategiesFetched: boolean;
400
- strategiesSettled: boolean;
401
366
  blockStates: Record<number, PerBlockState>;
402
367
  currentRecommendationId: number | null;
403
- strategyPanelOpen: boolean;
404
368
  configVersion: number;
405
369
  } & import("pinia").PiniaCustomStateProperties<StoreState>) => {
406
370
  text: string;
@@ -426,10 +390,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
426
390
  /**
427
391
  * Deep-clones a block's state and mirrors its campaign URL under a new id.
428
392
  * Invoked from `onCreated` when a duplicate is detected (SD-142352).
429
- *
430
- * The clone keeps the source's data but drops its "already fetched / already
431
- * synced" claims for strategy blocks, so it fetches again like a fresh drop
432
- * (SD-149916).
433
393
  */
434
394
  cloneBlockState(sourceId: number, newId: number): void;
435
395
  /**
@@ -485,47 +445,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
485
445
  openRemoveStrategyModal(): void;
486
446
  closeRemoveStrategyModal(): void;
487
447
  fetchStrategies(): Promise<void>;
488
- /**
489
- * Clears what a block inherited from the id it arrived holding, so the panel fetches for it.
490
- * A re-dropped saved module can keep the source's id — and its "already fetched" entry —
491
- * while the strategy's product count has moved on (SD-149916).
492
- */
493
- resetArrivedBlock(id: number): void;
494
- invalidateStrategies(): void;
495
- /**
496
- * Opens a Smart Recommender strategy page in a new tab and refreshes the list every time
497
- * the user comes back. `visibilitychange` only: a `focus` listener would also fire when
498
- * focus merely returns from the Stripo canvas iframe to the panel, refetching and
499
- * regenerating the canvas while the user never left the editor (SD-149916).
500
- *
501
- * Deliberately NOT one-shot: the strategy tab stays open, so a user can create a second
502
- * strategy in it and come back again — a listener that disarmed on the first return would
503
- * leave that one missing from the list. It disarms on the first return AFTER that tab is
504
- * closed instead, so an ordinary alt-tab later in the session costs nothing. Armed only
505
- * once the user actually opens a strategy page, so anyone who never does pays nothing.
506
- * @returns whether a tab actually opened, so callers can skip work that assumes one did
507
- */
508
- _armStrategyPageReturn(url: string): boolean;
509
- /**
510
- * Reloads the products of the block the user is on, so an edit made in the strategy tab
511
- * lands on the canvas instead of waiting for the assign drawer to be reopened.
512
- *
513
- * Only the selected block: the canvas regeneration is driven off the active block's
514
- * product array, so refreshing an unselected block would fetch without redrawing it.
515
- */
516
- _refreshAssignedStrategyProducts(): Promise<void>;
517
- /** Lets the editor tear the return listeners down when it unmounts. */
518
- disposeStrategyPageReturn(): void;
519
- /**
520
- * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
521
- * new strategy is offered; the user picks it themselves.
522
- */
523
- openStrategyCreation(): boolean;
524
- /**
525
- * Opens the strategy's edit page. Every return refreshes the list so the block reflects the
526
- * edited configuration.
527
- */
528
- openStrategyEdit(strategyId: string | number): boolean;
529
448
  resolveStrategyUrlTemplate(strategy: RrsStrategy, currency: string): Promise<string>;
530
449
  assignStrategy(strategy: RrsStrategy): void;
531
450
  removeStrategy(): void;
@@ -543,11 +462,6 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
543
462
  * every block's recommendationConfigs across user edits.
544
463
  */
545
464
  hasInvalidBlock(): boolean;
546
- /**
547
- * Which required fields are missing across the design's blocks, so the save
548
- * toaster can name the cause instead of always showing the generic message.
549
- */
550
- invalidBlockFields(): string[];
551
465
  fetchRecommendationProducts(): Promise<void>;
552
466
  _doFetchProducts(): Promise<void>;
553
467
  _doFetchStrategyProducts(blockId: number): Promise<void>;
@@ -15,11 +15,7 @@ export interface RequiredField {
15
15
  getAvailableOptions?: (store: ExtensionStoreSlice) => string[];
16
16
  condition?: (config: PerBlockConfigs) => boolean;
17
17
  }
18
- /** Field key of the strategy/algorithm descriptor, used to pick the toaster message. */
19
- export declare const STRATEGY_FIELD_KEY = "strategy";
20
18
  export declare const REQUIRED_RECOMMENDATION_FIELDS: RequiredField[];
21
19
  export declare const RecommendationRequiredFieldsKey = "newsletter.recommendation-fill-required-fields";
22
- /** Shown instead of the generic message when the only thing missing is the strategy. */
23
- export declare const RecommendationAssignStrategyKey = "newsletter.recommendation-assign-strategy";
24
20
  export declare function getInvalidFields(config: PerBlockConfigs, store: ExtensionStoreSlice, fields?: RequiredField[]): string[];
25
21
  export declare function isConfigValid(config: PerBlockConfigs, store: ExtensionStoreSlice): boolean;
@@ -1,16 +1,28 @@
1
+ /** Terminal outcome of an editor write, keyed by `${blueprintId}:${version}`. */
2
+ export interface ApplyAck {
3
+ status: 'applied' | 'failed';
4
+ /** The `applyRequestedAt` of the click this ack answers — lets cortex drop stale acks. */
5
+ requestedAt: number;
6
+ /** Strictly increasing per key, so two acks in the same millisecond still order. */
7
+ ackAt: number;
8
+ /** Stringified — cortex JSON-clones store-derived payloads, an Error would not survive. */
9
+ error?: string;
10
+ }
1
11
  /**
2
12
  * Outbound contract Guido publishes to the host's shared Pinia singleton so
3
13
  * cortex-fe can pick up the current editor state and forward it as
4
14
  * `clientState.editor` on the next chat-stream POST.
5
15
  *
6
- * State + getters only — `useGuidoStateBridge` writes via `$patch`, no actions
7
- * live here (architecture invariant).
16
+ * This store is **state-only, by contract**. It declares no actions and no
17
+ * non-trivial getters, so `pinia.state.value['guidoEmailEditor']` is a complete
18
+ * view of it. cortex-fe reads it through that public path; adding an action or
19
+ * a getter that cortex needs would silently break that read. Keep it
20
+ * state-only. (`hasSnapshot` stays — cortex does not read it.)
8
21
  *
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.
22
+ * Store id `guidoEmailEditor` is cross-MFE. The internal Guido editor store
23
+ * keeps id `guidoEditor` — these are intentionally separate. The internal store
24
+ * carries UI state that cortex-fe should not see; this public store carries the
25
+ * contract Guido is willing to share.
14
26
  */
15
27
  export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"guidoEmailEditor", {
16
28
  /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
@@ -21,6 +33,10 @@ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"
21
33
  lastUpdatedAt: number;
22
34
  /** Template id from the editor config, for cortex-fe to scope per-template. */
23
35
  templateId: string;
36
+ /** True while a mounted Guido bridge is consuming the chat store. Gates cortex's Apply button. */
37
+ bridgeActive: boolean;
38
+ /** `${blueprintId}:${version}` → terminal outcome of the editor write, written only after it settles. */
39
+ applyAcks: Record<string, ApplyAck>;
24
40
  }, {
25
41
  /** True once the bridge has published at least one snapshot. */
26
42
  hasSnapshot: (state: {
@@ -28,6 +44,8 @@ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"
28
44
  css: string;
29
45
  lastUpdatedAt: number;
30
46
  templateId: string;
47
+ bridgeActive: boolean;
48
+ applyAcks: Record<string, ApplyAck>;
31
49
  } & import("pinia").PiniaCustomStateProperties<{
32
50
  /** Current Stripo HTML — stripe tables only, no DOCTYPE/wrapper. */
33
51
  html: string;
@@ -37,5 +55,9 @@ export declare const useGuidoEmailEditorStore: import("pinia").StoreDefinition<"
37
55
  lastUpdatedAt: number;
38
56
  /** Template id from the editor config, for cortex-fe to scope per-template. */
39
57
  templateId: string;
58
+ /** True while a mounted Guido bridge is consuming the chat store. Gates cortex's Apply button. */
59
+ bridgeActive: boolean;
60
+ /** `${blueprintId}:${version}` → terminal outcome of the editor write, written only after it settles. */
61
+ applyAcks: Record<string, ApplyAck>;
40
62
  }>) => boolean;
41
63
  }, {}>;