@clipform/mcp-server 1.44.4 → 1.46.0

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
@@ -59,7 +59,7 @@ You can also pass the key as a CLI flag: `npx -y @clipform/mcp-server --api-key=
59
59
 
60
60
  ## Tools
61
61
 
62
- Your MCP client lists these automatically on connect (via `tools/list`). Full reference - arguments, schemas, and examples - is in the [docs](https://clipform.io/docs/guides/mcp).
62
+ Your MCP client lists these automatically on connect (via `tools/list`). Full reference - arguments, schemas, and examples - is in the [docs](https://clipform.io/docs/api/mcp).
63
63
 
64
64
  | Tool | Description |
65
65
  |------|-------------|
@@ -107,6 +107,6 @@ Forms are created with a start node and end screen automatically - you just add
107
107
  ## Links
108
108
 
109
109
  - [Clipform](https://clipform.io) - Create interactive video forms
110
- - [Documentation](https://clipform.io/docs/guides/mcp) - Full guide with node types and more
110
+ - [Documentation](https://clipform.io/docs/api/mcp) - Full guide with node types and more
111
111
 
112
112
  > Craft guides (`clipform://guides/*`, `clipform_get_guide`) are fetched from the Clipform API at runtime, so the server needs a reachable `API_URL` and valid `CLIPFORM_API_KEY` to serve them.
@@ -36,6 +36,14 @@ var FEATURES = {
36
36
  branching: {
37
37
  name: "Conditional branching",
38
38
  description: "Choice nodes route to different destinations based on which option is picked",
39
+ enabled: true,
40
+ status: "live",
41
+ wentLiveAt: "2026-06-25",
42
+ category: "builder"
43
+ },
44
+ funnel: {
45
+ name: "Lead qualification funnels",
46
+ description: "Multi-step funnels with conditional routing built on branching",
39
47
  enabled: false,
40
48
  status: "planned",
41
49
  category: "builder"
@@ -54,6 +62,13 @@ var FEATURES = {
54
62
  status: "planned",
55
63
  category: "builder"
56
64
  },
65
+ multi_select: {
66
+ name: "Multi-select choices",
67
+ description: "Pick-all-that-apply choice questions (checkbox-style selection)",
68
+ enabled: false,
69
+ status: "planned",
70
+ category: "builder"
71
+ },
57
72
  custom_fonts: {
58
73
  name: "Custom fonts",
59
74
  description: "Upload and use custom fonts in forms",
@@ -85,7 +100,7 @@ var FEATURES = {
85
100
  },
86
101
  node_choice: {
87
102
  name: "Multiple choice",
88
- description: "Single or multi-select questions with configurable options",
103
+ description: "Single-select questions with configurable options (multi-select is gated by the multi_select feature)",
89
104
  enabled: true,
90
105
  status: "live",
91
106
  category: "node-types"
@@ -146,6 +161,16 @@ var FEATURES = {
146
161
  status: "planned",
147
162
  category: "node-types"
148
163
  },
164
+ node_draw: {
165
+ name: "Drawing",
166
+ description: "Drawing canvas; respondents draw and it is saved as a PNG image",
167
+ // Live (#1012): builder picker shows it, the API accepts it, the viewer renders
168
+ // the canvas, and dashboard results render the saved PNG (#1012 results pass).
169
+ enabled: true,
170
+ status: "live",
171
+ wentLiveAt: "2026-06-27",
172
+ category: "node-types"
173
+ },
149
174
  node_payment: {
150
175
  name: "Payment",
151
176
  description: "Collect payments via Stripe or Paddle inline",
@@ -237,6 +262,7 @@ var FEATURES = {
237
262
  description: "Export response data to CSV, including transcriptions and media links",
238
263
  enabled: true,
239
264
  status: "live",
265
+ wentLiveAt: "2026-06-07",
240
266
  category: "analytics"
241
267
  },
242
268
  tracked_links: {
@@ -266,6 +292,7 @@ var FEATURES = {
266
292
  description: "Embed forms on external websites via script tag or JavaScript API",
267
293
  enabled: true,
268
294
  status: "live",
295
+ wentLiveAt: "2026-05-27",
269
296
  category: "sharing"
270
297
  },
271
298
  embed_widget: {
@@ -315,16 +342,18 @@ var FEATURES = {
315
342
  api_keys: {
316
343
  name: "API key management",
317
344
  description: "Self-service API key creation in the dashboard",
318
- enabled: false,
319
- status: "planned",
345
+ enabled: true,
346
+ status: "live",
347
+ wentLiveAt: "2026-06-22",
320
348
  category: "api"
321
349
  },
322
350
  // -- Integrations --
323
351
  webhooks: {
324
352
  name: "Webhooks",
325
353
  description: "Send response data to external URLs on form completion",
326
- enabled: false,
327
- status: "planned",
354
+ enabled: true,
355
+ status: "live",
356
+ wentLiveAt: "2026-06-24",
328
357
  category: "integrations"
329
358
  },
330
359
  // Per-integration lifecycle (split from the old coarse `integrations` flag so
@@ -375,15 +404,25 @@ var FEATURES = {
375
404
  integration_zapier: {
376
405
  name: "Zapier",
377
406
  description: "Connect to 5,000+ apps and automate workflows",
378
- enabled: false,
379
- status: "planned",
407
+ enabled: true,
408
+ status: "live",
409
+ wentLiveAt: "2026-06-21",
380
410
  category: "integrations"
381
411
  },
382
412
  integration_make: {
383
413
  name: "Make",
384
414
  description: "Advanced automation and integrations",
385
- enabled: false,
386
- status: "planned",
415
+ enabled: true,
416
+ status: "live",
417
+ wentLiveAt: "2026-06-22",
418
+ category: "integrations"
419
+ },
420
+ integration_n8n: {
421
+ name: "n8n",
422
+ description: "Open-source workflow automation - trigger flows on form responses",
423
+ enabled: true,
424
+ status: "live",
425
+ wentLiveAt: "2026-06-26",
387
426
  category: "integrations"
388
427
  },
389
428
  integration_hubspot: {
@@ -414,6 +453,13 @@ var FEATURES = {
414
453
  status: "planned",
415
454
  category: "integrations"
416
455
  },
456
+ integration_google_sheets: {
457
+ name: "Google Sheets",
458
+ description: "Sync form responses to a Google Sheet, one row per submission",
459
+ enabled: false,
460
+ status: "planned",
461
+ category: "integrations"
462
+ },
417
463
  notifications: {
418
464
  name: "Response notifications",
419
465
  description: "Email or webhook alerts when new responses arrive",
@@ -436,6 +482,22 @@ var FEATURES = {
436
482
  category: "integrations"
437
483
  }
438
484
  };
485
+ for (const [key, f] of Object.entries(FEATURES)) {
486
+ if (f.status === "live" && !f.enabled) {
487
+ throw new Error(`FEATURES.${key}: status 'live' requires enabled:true (shipped features must be exposed)`);
488
+ }
489
+ if (f.status === "planned" && f.enabled) {
490
+ throw new Error(`FEATURES.${key}: status 'planned' requires enabled:false (planned features must not be exposed)`);
491
+ }
492
+ if (f.wentLiveAt !== void 0) {
493
+ if (f.status === "planned") {
494
+ throw new Error(`FEATURES.${key}: wentLiveAt set but status is 'planned' (only shipped features have a go-live date)`);
495
+ }
496
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(f.wentLiveAt)) {
497
+ throw new Error(`FEATURES.${key}: wentLiveAt must be 'YYYY-MM-DD' (got ${JSON.stringify(f.wentLiveAt)})`);
498
+ }
499
+ }
500
+ }
439
501
 
440
502
  // ../config/node-types.js
441
503
  var RESPONSE_FORMATS = ["text", "audio", "video"];
@@ -483,9 +545,10 @@ var NODE_TYPES = {
483
545
  show_in_results: true,
484
546
  default_config: {
485
547
  selection_mode: "single",
486
- choice: { enable_branching: true, record_scores: false },
548
+ choice: { enable_branching: false, record_scores: false },
487
549
  randomise_options: false,
488
550
  show_option_count: false,
551
+ option_display: "list",
489
552
  options: [
490
553
  { content: "Option 1" },
491
554
  { content: "Option 2" }
@@ -522,13 +585,13 @@ var NODE_TYPES = {
522
585
  type: "string",
523
586
  label: "Selection mode",
524
587
  default: "single",
525
- description: "Allow single or multiple selections"
588
+ description: 'Allow single or multiple selections. "multiple" is gated by the multi_select feature - while it is off, the API coerces it to "single" (the viewer renders single-select only).'
526
589
  },
527
590
  allow_text_response: {
528
591
  type: "boolean",
529
592
  label: "Allow text response",
530
593
  default: false,
531
- description: "Allow free-text response in addition to options (single choice only)"
594
+ description: "Allow free-text response in addition to options (single choice only). Gated by the text_response feature - while it is off, the API coerces it to false (the viewer renders no free-text field yet)."
532
595
  },
533
596
  randomise_options: {
534
597
  type: "boolean",
@@ -542,6 +605,13 @@ var NODE_TYPES = {
542
605
  default: false,
543
606
  description: "Display number of options"
544
607
  },
608
+ option_display: {
609
+ enum: ["list", "letters"],
610
+ type: "string",
611
+ label: "Option display",
612
+ default: "list",
613
+ description: "How options render: full text rows (list), or compact A/B/C/D chips (letters) when the media already shows the labelled options - e.g. a Grid background"
614
+ },
545
615
  content_media_type: {
546
616
  enum: ["upload", "recorded"],
547
617
  type: "string",
@@ -556,9 +626,9 @@ var NODE_TYPES = {
556
626
  },
557
627
  output_schema: {
558
628
  type: "object",
559
- required: ["type", "label", "option_id"],
629
+ required: ["node_type", "label", "option_id"],
560
630
  properties: {
561
- type: { type: "string", const: "choice" },
631
+ node_type: { type: "string", const: "choice" },
562
632
  label: { type: "string", description: "Human-readable option label" },
563
633
  option_id: { type: "string", format: "uuid", description: "Selected option UUID" }
564
634
  }
@@ -654,32 +724,36 @@ var NODE_TYPES = {
654
724
  },
655
725
  output_schema: {
656
726
  type: "object",
657
- required: ["type"],
727
+ required: ["node_type"],
658
728
  properties: {
659
- type: { type: "string", const: "text" },
729
+ node_type: { type: "string", const: "open" },
660
730
  text: { type: "string", description: "Text response or transcription" },
661
731
  media: {
662
732
  type: "object",
663
733
  properties: {
664
734
  type: { enum: ["audio", "video"], type: "string" },
665
- storage_path: { type: "string" },
666
- facing_mode: { enum: ["user", "environment"], type: "string" },
667
- preview_crop: {
668
- type: "object",
669
- properties: {
670
- stream_width: { type: "number" },
671
- stream_height: { type: "number" },
672
- preview_width: { type: "number" },
673
- preview_height: { type: "number" }
674
- }
675
- }
735
+ // Direct, time-limited signed URL to the recording (~48h, supports
736
+ // HTTP range); minted per delivery, never the internal storage path.
737
+ url: { type: "string", format: "uri" }
676
738
  }
677
739
  },
678
740
  transcription: {
679
741
  type: "object",
680
742
  properties: {
681
743
  text: { type: "string" },
682
- language: { type: "string" }
744
+ language: { type: "string" },
745
+ segments: {
746
+ type: "array",
747
+ description: "Timestamped segments (seconds) for captions/seeking.",
748
+ items: {
749
+ type: "object",
750
+ properties: {
751
+ start: { type: "number" },
752
+ end: { type: "number" },
753
+ text: { type: "string" }
754
+ }
755
+ }
756
+ }
683
757
  }
684
758
  }
685
759
  }
@@ -809,6 +883,10 @@ var NODE_TYPES = {
809
883
  supports_media: false,
810
884
  is_system: false,
811
885
  show_in_results: false,
886
+ // Excluded from the aggregate Results charts (a list of emails can't be
887
+ // charted) but DOES show in the per-response Responses table, where each
888
+ // lead's contact fields are actionable (#746).
889
+ show_in_responses: true,
812
890
  default_config: {
813
891
  fields: [
814
892
  { id: "first_name", type: "first_name", label: "First Name", enabled: true, required: true },
@@ -892,9 +970,9 @@ var NODE_TYPES = {
892
970
  },
893
971
  output_schema: {
894
972
  type: "object",
895
- required: ["type", "fields"],
973
+ required: ["node_type", "fields"],
896
974
  properties: {
897
- type: { type: "string", const: "contact" },
975
+ node_type: { type: "string", const: "contact" },
898
976
  fields: {
899
977
  type: "array",
900
978
  items: {
@@ -972,6 +1050,74 @@ var NODE_TYPES = {
972
1050
  },
973
1051
  output_schema: null
974
1052
  },
1053
+ draw: {
1054
+ label: "Drawing",
1055
+ shorthand: "Draw",
1056
+ icon: "Pencil",
1057
+ color: "#FEF3C7",
1058
+ description: "Drawing canvas; respondents draw and it is saved as a PNG image",
1059
+ category: "input",
1060
+ sort_order: 6.5,
1061
+ has_options: false,
1062
+ is_terminal: false,
1063
+ show_nav_bar: true,
1064
+ loading: "lazy",
1065
+ supports_prompt: false,
1066
+ supports_media: false,
1067
+ is_system: false,
1068
+ show_in_results: true,
1069
+ default_config: {
1070
+ paper_color: "#FAF9F6",
1071
+ stroke_colors: ["#1F2937", "#EF4444", "#3B82F6", "#22C55E", "#FACC15"],
1072
+ stroke_widths: [3, 6, 12]
1073
+ },
1074
+ config_schema: {
1075
+ type: "object",
1076
+ properties: {
1077
+ paper_color: { type: "string", label: "Paper colour", default: "#FAF9F6", description: "Canvas background colour (off-white paper by default)" },
1078
+ stroke_colors: {
1079
+ type: "array",
1080
+ items: { type: "string" },
1081
+ minItems: 1,
1082
+ maxItems: 8,
1083
+ label: "Pen colours",
1084
+ default: ["#1F2937", "#EF4444", "#3B82F6", "#22C55E", "#FACC15"],
1085
+ description: "Colour swatches the respondent can draw with"
1086
+ },
1087
+ stroke_widths: {
1088
+ type: "array",
1089
+ items: { type: "number", minimum: 1, maximum: 60 },
1090
+ minItems: 1,
1091
+ maxItems: 5,
1092
+ label: "Pen thicknesses",
1093
+ default: [3, 6, 12],
1094
+ description: "Stroke widths (px) the respondent can choose"
1095
+ }
1096
+ }
1097
+ },
1098
+ response_schema: {
1099
+ // Mirrors the live `open` node's media response shape (the only complete
1100
+ // media path): the sketch image is uploaded to the `media-responses`
1101
+ // bucket via the same upload-client pipeline and referenced by
1102
+ // storage_path. Exported as PNG (crisp line art); the off-white paper
1103
+ // background is composited in before export so it is baked into the file.
1104
+ type: "object",
1105
+ required: ["media"],
1106
+ properties: {
1107
+ media: {
1108
+ type: "object",
1109
+ required: ["storage_path", "type"],
1110
+ properties: {
1111
+ type: { enum: ["image"], type: "string", description: 'Always "image" for a sketch' },
1112
+ storage_path: { type: "string", description: "Path in the media-responses bucket: bucket/workspace_id/.../uuid.png" },
1113
+ mime_type: { type: "string", description: "Image MIME type (image/png)" }
1114
+ },
1115
+ description: "The exported sketch, stored as a single image in media-responses"
1116
+ }
1117
+ }
1118
+ },
1119
+ output_schema: null
1120
+ },
975
1121
  payment: {
976
1122
  label: "Payment",
977
1123
  shorthand: "Payment",
@@ -1073,7 +1219,7 @@ var NODE_TYPES = {
1073
1219
  is_system: false,
1074
1220
  show_in_results: true,
1075
1221
  default_config: {
1076
- choice: { enable_branching: true },
1222
+ choice: { enable_branching: false },
1077
1223
  options: [
1078
1224
  { content: "Yes" },
1079
1225
  { content: "No" }
@@ -1107,9 +1253,9 @@ var NODE_TYPES = {
1107
1253
  },
1108
1254
  output_schema: {
1109
1255
  type: "object",
1110
- required: ["type", "label", "option_id"],
1256
+ required: ["node_type", "label", "option_id"],
1111
1257
  properties: {
1112
- type: { type: "string", const: "binary" },
1258
+ node_type: { type: "string", const: "binary" },
1113
1259
  label: { type: "string", description: "Human-readable option label" },
1114
1260
  option_id: { type: "string", format: "uuid", description: "Selected option UUID" }
1115
1261
  }
@@ -1148,9 +1294,9 @@ var NODE_TYPES = {
1148
1294
  },
1149
1295
  output_schema: {
1150
1296
  type: "object",
1151
- required: ["type", "label", "option_id"],
1297
+ required: ["node_type", "label", "option_id"],
1152
1298
  properties: {
1153
- type: { type: "string", const: "button" },
1299
+ node_type: { type: "string", const: "button" },
1154
1300
  label: { type: "string", description: "Human-readable option label" },
1155
1301
  option_id: { type: "string", format: "uuid", description: "Selected option UUID" }
1156
1302
  }
@@ -1430,6 +1576,7 @@ for (const [type, def] of Object.entries(NODE_TYPES)) {
1430
1576
  def.is_active = feature.enabled;
1431
1577
  }
1432
1578
  var NODE_TYPES_LIST = Object.entries(NODE_TYPES).map(([type, def]) => ({ type, ...def })).sort((a, b) => a.sort_order - b.sort_order);
1579
+ var ACTIVE_NODE_TYPES = Object.entries(NODE_TYPES).filter(([, def]) => def.is_active && !def.is_system).map(([type]) => type);
1433
1580
  var NODE_TYPE_KEYS = Object.keys(NODE_TYPES);
1434
1581
  var RESPONSE_SCHEMAS = Object.fromEntries(
1435
1582
  Object.entries(NODE_TYPES).map(([k, v]) => [k, v.response_schema])
@@ -1454,6 +1601,9 @@ var TERMINAL_TYPES = Object.entries(NODE_TYPES).filter(([, v]) => v.is_terminal)
1454
1601
  var NON_COUNTABLE_TYPES = Object.entries(NODE_TYPES).filter(([, v]) => v.is_system || v.is_terminal).map(([k]) => k);
1455
1602
  var NON_COUNTABLE_FILTER = `(${NON_COUNTABLE_TYPES.map((t) => `"${t}"`).join(",")})`;
1456
1603
  var RESULTS_EXCLUDED_TYPES = Object.entries(NODE_TYPES).filter(([, v]) => !v.show_in_results).map(([k]) => k);
1604
+ var NON_STEP_TYPES = /* @__PURE__ */ new Set(["button"]);
1605
+ var STEP_COUNTED_TYPES = Object.entries(NODE_TYPES).filter(([k, v]) => v.show_nav_bar && !NON_STEP_TYPES.has(k)).map(([k]) => k);
1606
+ var RESPONSES_EXCLUDED_TYPES = Object.entries(NODE_TYPES).filter(([, v]) => !(v.show_in_responses ?? v.show_in_results)).map(([k]) => k);
1457
1607
 
1458
1608
  // ../config/form-types.js
1459
1609
  var FORM_TYPES = {
@@ -1552,7 +1702,7 @@ var FORM_TYPES = {
1552
1702
  category: "qualification",
1553
1703
  aliases: ["lead-gen", "qualification", "lead-magnet"],
1554
1704
  variants: [],
1555
- required_features: ["branching"],
1705
+ required_features: ["branching", "funnel"],
1556
1706
  required_node_types: ["choice", "contact", "end_screen"],
1557
1707
  default_media_style: "text",
1558
1708
  guide_uri: "clipform://guides/funnel",
@@ -1666,11 +1816,11 @@ function getDiscoveryParams(formType, variant, mode = "full") {
1666
1816
 
1667
1817
  // ../config/help-links.js
1668
1818
  var HELP_TOPICS = {
1669
- goLive: { path: "/guides/sharing", anchor: "go-live" },
1670
- cantGoLive: { path: "/guides/sharing", anchor: "cant-go-live" },
1671
- liveAndDraft: { path: "/guides/managing-forms", anchor: "live-and-draft" },
1672
- publishingChanges: { path: "/guides/managing-forms", anchor: "publishing-changes" },
1673
- embedding: { path: "/guides/embed", anchor: null }
1819
+ goLive: { path: "/help/sharing", anchor: "go-live" },
1820
+ cantGoLive: { path: "/help/sharing", anchor: "cant-go-live" },
1821
+ liveAndDraft: { path: "/help/managing-forms", anchor: "live-and-draft" },
1822
+ publishingChanges: { path: "/help/managing-forms", anchor: "publishing-changes" },
1823
+ embedding: { path: "/help/embed", anchor: null }
1674
1824
  };
1675
1825
  function buildHelpLinks(docsBaseUrl) {
1676
1826
  const links = {};
@@ -1693,10 +1843,27 @@ var ENV = {
1693
1843
  };
1694
1844
  var COOKIE_DOMAIN = ENV.isDevelopment ? void 0 : ".clipform.io";
1695
1845
  var isTunnelBrowser = isBrowser && window.location.hostname.endsWith(".smith-forge.com");
1846
+ var PROD_URLS = {
1847
+ marketing: "https://www.clipform.io",
1848
+ // Dedicated CDN host for the embed SDK, decoupled from the marketing deploy
1849
+ // (ships in seconds via packages/embed-sdk `deploy:cf`). www.clipform.io/embed.js
1850
+ // stays as the legacy bridge until all installs migrate here.
1851
+ embed: "https://js.clipform.io",
1852
+ dashboard: "https://app.clipform.io",
1853
+ viewer: "https://clipform.io",
1854
+ api: "https://api.clipform.io",
1855
+ // Dedicated subdomain for the remote MCP server. Same Render service
1856
+ // as `api`, just routed by Host header. Token audience is bound here.
1857
+ mcp: "https://mcp.clipform.io",
1858
+ docs: "https://clipform.io/docs"
1859
+ };
1696
1860
  function getUrls() {
1697
1861
  if (isTunnelBrowser) {
1698
1862
  return {
1699
1863
  marketing: "https://marketing-dev.smith-forge.com",
1864
+ // Dev/tunnel: the marketing dev server 308-redirects /embed.js to js.clipform.io
1865
+ // (public/embed.js was retired in #1288), so embeds load the live SDK.
1866
+ embed: "https://marketing-dev.smith-forge.com",
1700
1867
  dashboard: "https://dashboard-dev.smith-forge.com",
1701
1868
  viewer: "https://viewer-dev.smith-forge.com",
1702
1869
  api: "https://api-dev.smith-forge.com",
@@ -1708,6 +1875,9 @@ function getUrls() {
1708
1875
  const api = process.env.NEXT_PUBLIC_API_URL || "http://localhost:3003";
1709
1876
  return {
1710
1877
  marketing: process.env.NEXT_PUBLIC_MARKETING_URL || "http://localhost:3002",
1878
+ // Local: the marketing dev server redirects /embed.js to js.clipform.io
1879
+ // (public/embed.js was retired in #1288), so embeds load the live SDK.
1880
+ embed: process.env.NEXT_PUBLIC_MARKETING_URL || "http://localhost:3002",
1711
1881
  dashboard: process.env.NEXT_PUBLIC_DASHBOARD_URL || "http://localhost:3000",
1712
1882
  viewer: process.env.NEXT_PUBLIC_VIEWER_URL || "http://localhost:3001",
1713
1883
  api,
@@ -1718,16 +1888,7 @@ function getUrls() {
1718
1888
  docs: process.env.NEXT_PUBLIC_DOCS_URL || "http://localhost:3004/docs"
1719
1889
  };
1720
1890
  }
1721
- return {
1722
- marketing: "https://www.clipform.io",
1723
- dashboard: "https://app.clipform.io",
1724
- viewer: "https://clipform.io",
1725
- api: "https://api.clipform.io",
1726
- // Dedicated subdomain for the remote MCP server. Same Render service
1727
- // as `api`, just routed by Host header. Token audience is bound here.
1728
- mcp: "https://mcp.clipform.io",
1729
- docs: "https://clipform.io/docs"
1730
- };
1891
+ return { ...PROD_URLS };
1731
1892
  }
1732
1893
  var BUSINESS = {
1733
1894
  name: "Clipform",
@@ -1742,6 +1903,7 @@ var BUSINESS = {
1742
1903
  },
1743
1904
  urls: getUrls()
1744
1905
  };
1906
+ var MEDIA_DIRECT_MAX_BYTES = 10 * 1024 * 1024;
1745
1907
  var HELP_LINKS = buildHelpLinks(BUSINESS.urls.docs);
1746
1908
  var CONTACT_FIELDS = [
1747
1909
  { id: "first_name", label: "First Name", type: "text", placeholder: "Enter first name", order: 1 },
@@ -1804,11 +1966,7 @@ var COMPOSITION_REGISTRY = [
1804
1966
  { id: "NumberLine", tier: "public", kind: "bed" },
1805
1967
  { id: "CountdownRing", tier: "public", kind: "bed" },
1806
1968
  { id: "CountrySilhouetteClip", tier: "public", kind: "bed", scene_layer: true },
1807
- // TODO(consolidation): collapse to one FlagReveal { country } - these three
1808
- // are the same component with hardcoded flag paths (a recipe, not a tool).
1809
- { id: "FlagRevealGB", tier: "public", kind: "bed" },
1810
- { id: "FlagRevealJP", tier: "public", kind: "bed" },
1811
- { id: "FlagRevealBR", tier: "public", kind: "bed" },
1969
+ { id: "FlagReveal", tier: "public", kind: "bed" },
1812
1970
  { id: "ColorCards", tier: "public", kind: "bed", scene_layer: true },
1813
1971
  { id: "TitleCard", tier: "public", kind: "bed" },
1814
1972
  { id: "ParallaxImage", tier: "public", kind: "bed" },
@@ -2036,6 +2194,7 @@ async function getSessionContext() {
2036
2194
 
2037
2195
  export {
2038
2196
  NODE_TYPES,
2197
+ ACTIVE_NODE_TYPES,
2039
2198
  NON_COUNTABLE_TYPES,
2040
2199
  FORM_TYPE_KEYS,
2041
2200
  WORKFLOW_TYPES,
@@ -2060,4 +2219,4 @@ export {
2060
2219
  getSessionContextWithAuth,
2061
2220
  getSessionContext
2062
2221
  };
2063
- //# sourceMappingURL=chunk-PCCTN3T7.js.map
2222
+ //# sourceMappingURL=chunk-AHWMH66L.js.map