@designcrowd/library.brand-page 6.2.14 → 6.2.16

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 (46) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-Deoc6s8r.js → CreatedOnBrandCrowd-de-de-B_-PPZBi.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-BxDzsLl-.js → CreatedOnBrandCrowd-en-us-BO1Kj3iA.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-B-5VS2MV.js → CreatedOnBrandCrowd-es-es-BoDJWRn2.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-C6h05sUZ.js → CreatedOnBrandCrowd-fr-ca-DUJZmdAy.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-C6h05sUZ.js → CreatedOnBrandCrowd-fr-fr-DUJZmdAy.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-BC6XU3ev.js → CreatedOnBrandCrowd-pt-br-pIlAG13E.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-BC6XU3ev.js → CreatedOnBrandCrowd-pt-pt-pIlAG13E.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-dUTedh8v.js → CreatedOnDcom-de-de-BNJtDtvi.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DY0jkOeW.js → CreatedOnDcom-en-us-uL6WU_1S.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-DRioej2A.js → CreatedOnDcom-es-es-DGZQISoF.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-CcglfcUU.js → CreatedOnDcom-fr-ca-CvYWKqNh.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-B7v_e6HI.js → CreatedOnDcom-fr-fr-CpohVgCR.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-5XGcKJb7.js → CreatedOnDcom-pt-br-CaKS-48n.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-DepC53tO.js → CreatedOnDcom-pt-pt-D4g-iecQ.js} +1 -1
  15. package/lib/src/brand-page/utils/migration/migration-22.d.ts +10 -4
  16. package/lib/src/brand-page/utils/migration/migration-22.js +59 -5
  17. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.d.ts +1 -1
  18. package/lib/src/brand-page-maker/composables/ai-chat/aiErrorCopy.js +2 -2
  19. package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +2 -2
  20. package/lib/src/clients/websocket-gateway-client.d.ts +1 -5
  21. package/lib/src/index.mjs +1 -1
  22. package/lib/src/{lib-CidddZOL.js → lib-DwDFHSzX.js} +8863 -8819
  23. package/lib/src/metadata-builder/builders/section-field-maps.d.ts +1 -1
  24. package/lib/src/metadata-builder/builders/section-field-maps.js +1 -1
  25. package/lib/src/metadata-builder/builders/undo-builder.d.ts +2 -2
  26. package/lib/src/metadata-builder/builders/undo-builder.js +2 -2
  27. package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +2 -2
  28. package/lib/src/metadata-builder/parsers/section-tool-arguments.js +1 -1
  29. package/package.json +1 -1
  30. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +1 -0
  31. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/edited-brandsite-sections.v22.json +6 -3
  32. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandcontact-every-section.v22.json +26 -13
  33. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandpage-every-section.v22.json +24 -12
  34. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/new-brandsite-every-section.v22.json +24 -12
  35. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandcontact.v22.json +8 -4
  36. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-general-link.v22.json +6 -3
  37. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandpage-links.v22.json +6 -3
  38. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-header-banner.v22.json +2 -1
  39. package/src/brand-page/utils/migration/__snapshots__/migration-22-output/real-brandsite-sections.v22.json +6 -3
  40. package/src/brand-page/utils/migration/migration-22.ts +103 -4
  41. package/src/brand-page-maker/composables/ai-chat/aiErrorCopy.ts +2 -2
  42. package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +2 -2
  43. package/src/clients/websocket-gateway-client.ts +0 -5
  44. package/src/metadata-builder/builders/section-field-maps.ts +1 -1
  45. package/src/metadata-builder/builders/undo-builder.ts +2 -2
  46. package/src/metadata-builder/parsers/section-tool-arguments.ts +4 -4
@@ -745,6 +745,66 @@ const captureNoRoleTextStyles = (
745
745
  return locations;
746
746
  };
747
747
 
748
+ type ButtonLabelRole = {
749
+ holder: Record<string, unknown>;
750
+ key: string;
751
+ role: string | undefined;
752
+ };
753
+
754
+ /**
755
+ * A button label drew its own colour, else its role's colour, else inherited
756
+ * `buttonStyles.style.color` — never the base coat or a container default. B moves every label to
757
+ * Button text whatever role it was on, so record the role each colourless label drew before B;
758
+ * D bakes that colour onto the label (E hasn't cleared it yet).
759
+ */
760
+ const captureButtonLabelRoles = (
761
+ brandPageModel: BrandPageModel,
762
+ ): ButtonLabelRole[] => {
763
+ const labels: ButtonLabelRole[] = [];
764
+ const record = (
765
+ holder: Record<string, unknown>,
766
+ key: string,
767
+ style: RawStyleObject | undefined,
768
+ ): void => {
769
+ if (style && isBlankColorValue(style.color)) {
770
+ labels.push({ holder, key, role: style.textStyleType });
771
+ }
772
+ };
773
+
774
+ for (const page of brandPageModel.pages ?? []) {
775
+ for (const content of page.contents ?? []) {
776
+ const fields = content as unknown as Record<string, unknown>;
777
+
778
+ for (const key of Object.keys(
779
+ CONTENT_TEXT_STYLE_PROPERTY_KEYS,
780
+ ) as ContentTextStylePropertyKey[]) {
781
+ if (key === 'buttonTextStyle' || isButtonLabelField(content, key)) {
782
+ record(fields, key, fields[key] as RawStyleObject | undefined);
783
+ }
784
+ }
785
+ }
786
+ }
787
+
788
+ for (const header of [
789
+ brandPageModel.pageHeaderDesktop,
790
+ brandPageModel.pageHeaderMobile,
791
+ ]) {
792
+ const headerButton = header?.headerButton;
793
+
794
+ if (headerButton) {
795
+ record(
796
+ headerButton as unknown as Record<string, unknown>,
797
+ 'buttonTextStyle',
798
+ (headerButton.buttonTextStyle as RawStyleObject | undefined) ?? {
799
+ textStyleType: TEXT_STYLE_TYPES.buttons,
800
+ },
801
+ );
802
+ }
803
+ }
804
+
805
+ return labels;
806
+ };
807
+
748
808
  /**
749
809
  * An RTE-eligible field that is a plain string, not a Tiptap doc. On an old site nothing
750
810
  * converts plain text → doc (migration-20 only converts HTML), so such a field renders via
@@ -777,14 +837,16 @@ const roleColour = (
777
837
  * and the role colour (E) changes no pixels. migration-21 already baked element→frame→role
778
838
  * colour into RTE runs, so the only uncoloured runs reaching here inherit the base coat;
779
839
  * non-RTE fields (21 left them alone) resolve element→container-default→role→base coat.
780
- * `buttonTextStyle` and a link button's `titleStyle` are excluded — the button label takes its
781
- * colour from `buttonStyles`, never the base coat. A social-links section's unset icon fill is
782
- * frozen here too.
840
+ * A button label (`buttonTextStyle`, a link button's `titleStyle`, the header button, Save
841
+ * Contact) never takes the base coat: it bakes the colour of the role it drew before B
842
+ * (`captureButtonLabelRoles`), else `buttonStyles.style.color`. A social-links section's unset
843
+ * icon fill is frozen here too.
783
844
  */
784
845
  export const bakeElementColours = (
785
846
  brandPageModel: BrandPageModel,
786
847
  options: TextStyleOptions,
787
848
  noRoleTextStyles: NoRoleTextStyles = new WeakMap(),
849
+ buttonLabelRoles: ButtonLabelRole[] = [],
788
850
  ): void => {
789
851
  const baseCoat = roleColour(options, 'paragraph1');
790
852
 
@@ -916,6 +978,37 @@ export const bakeElementColours = (
916
978
  }
917
979
  }
918
980
 
981
+ const buttonStyleColour = brandPageModel.styles?.buttonStyles?.style?.color;
982
+ const bakeLabel = (
983
+ style: RawStyleObject | undefined,
984
+ roleColourValue: string | undefined,
985
+ ): void => {
986
+ const colour = !isBlankColorValue(roleColourValue)
987
+ ? roleColourValue
988
+ : buttonStyleColour;
989
+
990
+ if (style && isBlankColorValue(style.color) && !isBlankColorValue(colour)) {
991
+ style.color = colour;
992
+ }
993
+ };
994
+
995
+ for (const { holder, key, role } of buttonLabelRoles) {
996
+ bakeLabel(
997
+ holder[key] as RawStyleObject | undefined,
998
+ roleColour(options, role),
999
+ );
1000
+ }
1001
+
1002
+ // Save Contact drew the Buttons role's colour whatever its stored style held.
1003
+ if (brandPageModel.brandPageType === BRAND_PAGE_TYPES.brandContact) {
1004
+ bakeLabel(
1005
+ brandPageModel.saveContactSettings?.buttonTextStyle as
1006
+ | RawStyleObject
1007
+ | undefined,
1008
+ roleColour(options, TEXT_STYLE_TYPES.buttons),
1009
+ );
1010
+ }
1011
+
919
1012
  // Footer copyright is non-RTE text that resolved through role → base coat, but lives
920
1013
  // OUTSIDE `pages[].contents`, so freeze it here too — else it loses its colour when E
921
1014
  // clears the role and F removes the base coat (the copyright-on-dark-footer regression).
@@ -1328,11 +1421,17 @@ export const migration22 = async (
1328
1421
  seedRoleFonts(brandPageModel, options); // A2 — count the site's fonts onto each role family
1329
1422
 
1330
1423
  const noRoleTextStyles = captureNoRoleTextStyles(brandPageModel);
1424
+ const buttonLabelRoles = captureButtonLabelRoles(brandPageModel);
1331
1425
 
1332
1426
  reconnectContentRoles(brandPageModel, targets, options); // B — seed button styles, reconnect every text field
1333
1427
  stripLiftContentRte(brandPageModel, options); // C — RTE baked → override
1334
1428
  await convertPlainRteFields(brandPageModel, options); // B1 — plain text → Tiptap doc (after C)
1335
- bakeElementColours(brandPageModel, options, noRoleTextStyles); // D — freeze resolved colour
1429
+ bakeElementColours(
1430
+ brandPageModel,
1431
+ options,
1432
+ noRoleTextStyles,
1433
+ buttonLabelRoles,
1434
+ ); // D — freeze resolved colour
1336
1435
  clearRoleColours(options); // E — retire role colour
1337
1436
  stripRteStyleColours(brandPageModel); // G — colour-decouple RTE style objects
1338
1437
  }
@@ -1,7 +1,7 @@
1
1
  // REL 1 Phase 1 / 1.5 — friendly chat copy keyed by the backend `code` field.
2
2
  //
3
3
  // Backend returns `{ error, code, message }` for known failure paths
4
- // (both HTTP responses and WebSocket build_error / server_error frames).
4
+ // (both HTTP responses and WebSocket build_error frames).
5
5
  // We look up the code first, then fall back to message → error → generic.
6
6
  // English-only for now; Phase 2 promotes this to proper i18n keys.
7
7
 
@@ -50,7 +50,7 @@ export function pickErrorMessage(error: unknown): string {
50
50
  * Pick a friendly chat message from a WebSocket error frame.
51
51
  *
52
52
  * Reads `msg.{code, message, error}` directly — the shape pushed by the
53
- * ai-pipelines build_error / server_error WebSocket frames.
53
+ * ai-pipelines build_error WebSocket frames.
54
54
  */
55
55
  export function pickWsErrorMessage(
56
56
  msg: ErrorPayload | undefined | null,
@@ -886,7 +886,7 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
886
886
  return;
887
887
  }
888
888
 
889
- if (msg.type === 'server_error' || msg.type === 'build_error') {
889
+ if (msg.type === 'build_error') {
890
890
  handleBuildError(msg);
891
891
 
892
892
  return;
@@ -999,7 +999,7 @@ export function useAiWebsiteBuilderChat(): UseAiChatResult {
999
999
  threadItems.value[messageIndex].isTyping = false;
1000
1000
 
1001
1001
  // Honour the isError flag set by error paths in callApiBuildAsync
1002
- // (apply-failure catch, server_error / build_error WS frames).
1002
+ // (apply-failure catch, build_error WS frames).
1003
1003
  // Without this, error text would render as a normal AI reply.
1004
1004
  if (result.isError) {
1005
1005
  threadItems.value[messageIndex].isError = true;
@@ -16,17 +16,12 @@ export interface WebSocketMessage {
16
16
  type:
17
17
  | 'connected'
18
18
  | 'server_response'
19
- | 'server_error'
20
19
  | 'build_error'
21
20
  | 'chat_started'
22
21
  | 'plan_announced'
23
22
  | 'item_complete';
24
23
  buildId?: string;
25
24
  connectionId?: string;
26
- pageId?: string;
27
- order?: number;
28
- sectionType?: string;
29
- mode?: string;
30
25
  toolCalls?: unknown[];
31
26
  message?: string;
32
27
  error?: string;
@@ -2,7 +2,7 @@
2
2
  * Maps AI tool call argument names → BrandPageModel content field names
3
3
  * per section type.
4
4
  *
5
- * Reference: service.ai-pipelines/src/agents/website/section_schemas.py
5
+ * Reference: service.ai-pipelines/src/agents/websiteV2/platform/tool_schemas/
6
6
  * Reference: library.brand-page/src/brand-page/models/index.ts
7
7
  */
8
8
 
@@ -43,10 +43,10 @@ export interface UndoPayload {
43
43
  * can observe that an undo was executed (useful for telemetry, UI messaging,
44
44
  * and audit logs).
45
45
  *
46
- * Contract guarantee from the AI pipeline (Website Planner WL9): the `undo`
46
+ * Contract guarantee from the AI pipeline (WebsiteV2 main agent): the `undo`
47
47
  * tool call is exclusive — it never co-occurs with build/update/delete tool
48
48
  * calls in the same response. If that contract is ever violated upstream,
49
- * fix the planner — do not add defensive ordering here. The sequential
49
+ * fix the agent — do not add defensive ordering here. The sequential
50
50
  * MetadataExecutor will apply any subsequent builders on top of the restored
51
51
  * snapshot, which is the semantically correct "undo-then-apply" ordering.
52
52
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Typed interfaces for website builder section tool arguments.
3
3
  *
4
- * Canonical reference: service.ai-pipelines/src/agents/website/section_schemas.py
4
+ * Canonical reference: service.ai-pipelines/src/agents/websiteV2/platform/tool_schemas/
5
5
  * Every field defined there has a corresponding TS field here.
6
6
  */
7
7
 
@@ -25,7 +25,7 @@ type UnsupportedContentType =
25
25
  export type SectionType = Exclude<ContentType, UnsupportedContentType>;
26
26
 
27
27
  // ---------------------------------------------------------------------------
28
- // Shared style type (matches TEXT_STYLE_SCHEMA in section_schemas.py)
28
+ // Shared style type (matches TEXT_STYLE_SCHEMA in websiteV2/platform/tools/section_types_tool.py)
29
29
  // ---------------------------------------------------------------------------
30
30
 
31
31
  // ---------------------------------------------------------------------------
@@ -91,7 +91,7 @@ export const isTiptapDocument = (value: unknown): value is TiptapDocument =>
91
91
  Array.isArray((value as TiptapDocument).content);
92
92
 
93
93
  // ---------------------------------------------------------------------------
94
- // Shared style type (matches TEXT_STYLE_SCHEMA in section_schemas.py)
94
+ // Shared style type (matches TEXT_STYLE_SCHEMA in websiteV2/platform/tools/section_types_tool.py)
95
95
  // ---------------------------------------------------------------------------
96
96
 
97
97
  export interface TextStyleArguments {
@@ -127,7 +127,7 @@ export interface TextStyleArguments {
127
127
  * the APPLICATION is per-section: every section's tool call writes the
128
128
  * same site-decided hex into this field.
129
129
  *
130
- * See `ai-pipelines/src/agents/website/tools/section_types_tool.py`
130
+ * See `ai-pipelines/src/agents/websiteV2/platform/tools/section_types_tool.py`
131
131
  * (`_button_text_style_field`) for the AI-side mirror.
132
132
  */
133
133
  export interface ButtonTextStyleArguments {