@clipform/mcp-server 4.2.8 → 4.3.2

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.
@@ -142,6 +142,15 @@ var FEATURES = {
142
142
  status: "planned",
143
143
  category: "builder"
144
144
  },
145
+ // Built in #5148 (PR #5155), shipped dark. When off: no builder switch, viewer ignores
146
+ // stored allow_skip, and the MCP hides/drops allow_skip via the config_schema `feature` marker.
147
+ optional_questions: {
148
+ name: "Optional questions",
149
+ description: "Builders can mark a draw or camera question optional so respondents can skip it",
150
+ enabled: false,
151
+ status: "planned",
152
+ category: "builder"
153
+ },
145
154
  draw_target_shape: {
146
155
  name: "Draw target shape",
147
156
  description: "Score a drawing against a builder-drawn target outline (match-to-shape game)",
@@ -1652,6 +1661,7 @@ var NODE_TYPES = {
1652
1661
  // overlay share the same coordinate frame without re-deriving it.
1653
1662
  game: {
1654
1663
  type: "object",
1664
+ feature: "draw_target_shape",
1655
1665
  label: "Match-to-shape game",
1656
1666
  description: "Optional target shape the drawing is scored against on submit",
1657
1667
  properties: {
@@ -1691,6 +1701,13 @@ var NODE_TYPES = {
1691
1701
  description: "Score bands shown in the reveal, ascending by min_score - defaults to a 5-band Scribble to Perfect scale"
1692
1702
  }
1693
1703
  }
1704
+ },
1705
+ allow_skip: {
1706
+ type: "boolean",
1707
+ feature: "optional_questions",
1708
+ default: false,
1709
+ label: "Optional",
1710
+ description: "Respondents can skip this question without drawing"
1694
1711
  }
1695
1712
  }
1696
1713
  },
@@ -1853,6 +1870,13 @@ var NODE_TYPES = {
1853
1870
  label: "Minimum media items",
1854
1871
  shortLabel: "Min",
1855
1872
  description: "Fewest photos or videos a respondent must add before continuing"
1873
+ },
1874
+ allow_skip: {
1875
+ type: "boolean",
1876
+ feature: "optional_questions",
1877
+ default: false,
1878
+ label: "Optional",
1879
+ description: "Respondents can skip this question without adding a photo or video"
1856
1880
  }
1857
1881
  }
1858
1882
  },
@@ -2533,6 +2557,29 @@ for (const [type, def] of Object.entries(NODE_TYPES)) {
2533
2557
  }
2534
2558
  def.is_active = feature.enabled;
2535
2559
  }
2560
+ function validateFeatureMarkers(nodeTypes, features) {
2561
+ for (const [type, def] of Object.entries(nodeTypes)) {
2562
+ for (const [key, prop] of Object.entries(def.config_schema?.properties ?? {})) {
2563
+ if (prop.feature !== void 0 && !features[prop.feature]) {
2564
+ throw new Error(`NODE_TYPES.${type}.config_schema.${key}: feature "${prop.feature}" is not in FEATURES`);
2565
+ }
2566
+ }
2567
+ }
2568
+ }
2569
+ validateFeatureMarkers(NODE_TYPES, FEATURES);
2570
+ function gatedConfigKeys(type) {
2571
+ const props = NODE_TYPES[type]?.config_schema?.properties ?? {};
2572
+ return new Set(
2573
+ Object.entries(props).filter(([, prop]) => prop.feature !== void 0 && !FEATURES[prop.feature]?.enabled).map(([key]) => key)
2574
+ );
2575
+ }
2576
+ function stripGatedConfigKeys(type, config) {
2577
+ if (!config || typeof config !== "object") return { config, dropped: [] };
2578
+ const gated = gatedConfigKeys(type);
2579
+ const dropped = Object.keys(config).filter((k) => gated.has(k));
2580
+ if (dropped.length === 0) return { config, dropped };
2581
+ return { config: Object.fromEntries(Object.entries(config).filter(([k]) => !gated.has(k))), dropped };
2582
+ }
2536
2583
  var NODE_TYPES_LIST = Object.entries(NODE_TYPES).map(([type, def]) => ({ type, ...def })).sort((a, b) => a.sort_order - b.sort_order);
2537
2584
  var ACTIVE_NODE_TYPES = Object.entries(NODE_TYPES).filter(([, def]) => def.is_active && !def.is_system).map(([type]) => type);
2538
2585
  var NODE_TYPE_KEYS = Object.keys(NODE_TYPES);
@@ -3449,6 +3496,8 @@ function structuredResult(text, structuredContent) {
3449
3496
  export {
3450
3497
  FEATURE_FLAGS,
3451
3498
  NODE_TYPES,
3499
+ gatedConfigKeys,
3500
+ stripGatedConfigKeys,
3452
3501
  ACTIVE_NODE_TYPES,
3453
3502
  NON_COUNTABLE_TYPES,
3454
3503
  FORM_TYPES,
@@ -3476,4 +3525,4 @@ export {
3476
3525
  textResult,
3477
3526
  structuredResult
3478
3527
  };
3479
- //# sourceMappingURL=chunk-UMO47NOJ.js.map
3528
+ //# sourceMappingURL=chunk-NCL5EEMF.js.map