@ng-forge/dynamic-form-mcp 1.0.0-rc.4 → 1.0.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/src/index.js CHANGED
@@ -648,9 +648,9 @@ var FIELD_TYPES = [
648
648
  minimalExample: `{ key: 'submit', type: 'submit', label: 'Submit' }`
649
649
  },
650
650
  {
651
- type: "addArrayItem",
651
+ type: "add-array-item",
652
652
  category: "button",
653
- description: "Button to add a new item to an array field. Must be placed within or near the array container.",
653
+ description: "Button to append a new item to the end of an array field. Must be placed within or near the array container. (Legacy alias: addArrayItem.)",
654
654
  valueType: void 0,
655
655
  baseInterface: "FieldDef",
656
656
  props: {},
@@ -659,15 +659,50 @@ var FIELD_TYPES = [
659
659
  allowedIn: ["array", "row", "group"],
660
660
  example: `{
661
661
  key: 'addContact',
662
- type: 'addArrayItem',
662
+ type: 'add-array-item',
663
663
  label: 'Add Contact'
664
664
  }`,
665
- minimalExample: `{ key: 'add', type: 'addArrayItem', label: 'Add Item' }`
665
+ minimalExample: `{ key: 'add', type: 'add-array-item', label: 'Add Item' }`
666
666
  },
667
667
  {
668
- type: "removeArrayItem",
668
+ type: "prepend-array-item",
669
669
  category: "button",
670
- description: "Button to remove the current item from an array field. Typically placed within each array item template.",
670
+ description: "Button to add a new item to the beginning of an array field. (Legacy alias: prependArrayItem.)",
671
+ valueType: void 0,
672
+ baseInterface: "FieldDef",
673
+ props: {},
674
+ validationSupported: false,
675
+ source: "adapter",
676
+ allowedIn: ["array", "row", "group"],
677
+ example: `{
678
+ key: 'prependContact',
679
+ type: 'prepend-array-item',
680
+ label: 'Add to Top'
681
+ }`,
682
+ minimalExample: `{ key: 'prepend', type: 'prepend-array-item', label: 'Add First' }`
683
+ },
684
+ {
685
+ type: "insert-array-item",
686
+ category: "button",
687
+ description: "Button to insert a new item at a specific index in an array field (set via the index property). (Legacy alias: insertArrayItem.)",
688
+ valueType: void 0,
689
+ baseInterface: "FieldDef",
690
+ props: {},
691
+ validationSupported: false,
692
+ source: "adapter",
693
+ allowedIn: ["array", "row", "group"],
694
+ example: `{
695
+ key: 'insertContact',
696
+ type: 'insert-array-item',
697
+ label: 'Insert',
698
+ index: 1
699
+ }`,
700
+ minimalExample: `{ key: 'insert', type: 'insert-array-item', label: 'Insert', index: 0 }`
701
+ },
702
+ {
703
+ type: "remove-array-item",
704
+ category: "button",
705
+ description: "Button to remove the current item from an array field. Typically placed within each array item template. (Legacy alias: removeArrayItem.)",
671
706
  valueType: void 0,
672
707
  baseInterface: "FieldDef",
673
708
  props: {},
@@ -676,10 +711,46 @@ var FIELD_TYPES = [
676
711
  allowedIn: ["array", "row", "group"],
677
712
  example: `{
678
713
  key: 'removeContact',
679
- type: 'removeArrayItem',
714
+ type: 'remove-array-item',
680
715
  label: 'Remove'
681
716
  }`,
682
- minimalExample: `{ key: 'remove', type: 'removeArrayItem', label: 'Remove' }`
717
+ minimalExample: `{ key: 'remove', type: 'remove-array-item', label: 'Remove' }`
718
+ },
719
+ {
720
+ type: "pop-array-item",
721
+ category: "button",
722
+ description: "Button to remove the last item from an array field. (Legacy alias: popArrayItem.)",
723
+ valueType: void 0,
724
+ baseInterface: "FieldDef",
725
+ props: {},
726
+ validationSupported: false,
727
+ source: "adapter",
728
+ allowedIn: ["array", "row", "group"],
729
+ example: `{
730
+ key: 'popContact',
731
+ type: 'pop-array-item',
732
+ label: 'Remove Last',
733
+ arrayKey: 'contacts'
734
+ }`,
735
+ minimalExample: `{ key: 'pop', type: 'pop-array-item', label: 'Remove Last', arrayKey: 'items' }`
736
+ },
737
+ {
738
+ type: "shift-array-item",
739
+ category: "button",
740
+ description: "Button to remove the first item from an array field. (Legacy alias: shiftArrayItem.)",
741
+ valueType: void 0,
742
+ baseInterface: "FieldDef",
743
+ props: {},
744
+ validationSupported: false,
745
+ source: "adapter",
746
+ allowedIn: ["array", "row", "group"],
747
+ example: `{
748
+ key: 'shiftContact',
749
+ type: 'shift-array-item',
750
+ label: 'Remove First',
751
+ arrayKey: 'contacts'
752
+ }`,
753
+ minimalExample: `{ key: 'shift', type: 'shift-array-item', label: 'Remove First', arrayKey: 'items' }`
683
754
  }
684
755
  ];
685
756
 
@@ -1470,7 +1541,7 @@ var WRAPPERS = [
1470
1541
  category: "demo",
1471
1542
  availability: "demo-only",
1472
1543
  package: "@internal/examples-shared-ui",
1473
- description: 'Demo wrapper used by the docs sandbox. Wraps an array field in a titled card whose header contains an "Add" button \u2014 the wrapper owns the append behaviour, dispatching `arrayEvent(key).append(itemTemplate)` on click via the `EventBus`. Lets the consumer config drop the separate `addArrayItem` button field. NOT a shipping primitive; copy the component out of `internal/examples-shared-ui/src/lib/demo-wrappers/` or author your own if you want this pattern in production.',
1544
+ description: 'Demo wrapper used by the docs sandbox. Wraps an array field in a titled card whose header contains an "Add" button \u2014 the wrapper owns the append behaviour, dispatching `arrayEvent(key).append(itemTemplate)` on click via the `EventBus`. Lets the consumer config drop the separate `add-array-item` button field. NOT a shipping primitive; copy the component out of `internal/examples-shared-ui/src/lib/demo-wrappers/` or author your own if you want this pattern in production.',
1474
1545
  props: {
1475
1546
  title: {
1476
1547
  name: "title",
@@ -3037,7 +3108,7 @@ All features are exported from \`@ng-forge/dynamic-forms\`.
3037
3108
 
3038
3109
  ## CRITICAL: UI Library Differences
3039
3110
 
3040
- Different UI libraries support different properties. Always validate against the correct library using \`ngforge_validate_form_config\` with the appropriate \`uiIntegration\` parameter.
3111
+ Different UI libraries support different properties. Always validate against the correct library using \`ngforge_validate\` with the appropriate \`uiIntegration\` parameter.
3041
3112
 
3042
3113
  ### Property Differences by Library
3043
3114
 
@@ -3080,24 +3151,24 @@ Container fields (\`page\`, \`group\`, \`row\`) do NOT support these properties:
3080
3151
  { key: 'volume', type: 'slider', label: 'Volume', min: 0, max: 100 }
3081
3152
  \`\`\`
3082
3153
 
3083
- 5. **Using unsupported field types** - Each UI library supports specific field types. Use \`ngforge_get_field_schema\` to see available types.
3154
+ 5. **Using unsupported field types** - Each UI library supports specific field types. Use \`ngforge_lookup\` with \`depth: "schema"\` to see available types.
3084
3155
 
3085
3156
  ## Validation Before Use
3086
3157
 
3087
- Always validate your FormConfig using the \`ngforge_validate_form_config\` tool before using it. This tool uses the actual TypeScript/Zod schemas, so if validation passes, the config will work correctly at runtime.
3158
+ Always validate your FormConfig using the \`ngforge_validate\` tool before using it. This tool uses the actual TypeScript/Zod schemas, so if validation passes, the config will work correctly at runtime.
3088
3159
 
3089
3160
  \`\`\`typescript
3090
3161
  // Always specify the UI integration you're using
3091
- ngforge_validate_form_config({
3162
+ ngforge_validate({
3092
3163
  uiIntegration: 'material', // or 'bootstrap', 'primeng', 'ionic'
3093
3164
  config: { fields: [...] }
3094
3165
  })
3095
3166
  \`\`\`
3096
3167
 
3097
- To understand what properties are supported for each field type, use \`ngforge_get_field_schema\`:
3168
+ To understand what properties are supported for each field type, use \`ngforge_lookup\` with \`depth: "schema"\`:
3098
3169
 
3099
3170
  \`\`\`typescript
3100
- ngforge_get_field_schema({ uiIntegration: 'material' })
3171
+ ngforge_lookup({ topic: 'input', depth: 'schema', uiIntegration: 'material' })
3101
3172
  \`\`\`
3102
3173
  `;
3103
3174
 
@@ -5213,7 +5284,7 @@ var MatPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
5213
5284
  props: MatButtonPropsSchema.optional()
5214
5285
  });
5215
5286
  var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5216
- type: z33.literal("addArrayItem"),
5287
+ type: z33.literal("add-array-item"),
5217
5288
  /**
5218
5289
  * Key of the array field to add items to.
5219
5290
  * If omitted, uses the parent array context.
@@ -5222,7 +5293,7 @@ var MatAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5222
5293
  props: MatButtonPropsSchema.optional()
5223
5294
  });
5224
5295
  var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5225
- type: z33.literal("removeArrayItem"),
5296
+ type: z33.literal("remove-array-item"),
5226
5297
  /**
5227
5298
  * Key of the array field to remove items from.
5228
5299
  * If omitted, uses the parent array context.
@@ -5230,6 +5301,44 @@ var MatRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5230
5301
  arrayKey: z33.string().optional(),
5231
5302
  props: MatButtonPropsSchema.optional()
5232
5303
  });
5304
+ var MatPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5305
+ type: z33.literal("prepend-array-item"),
5306
+ /**
5307
+ * Key of the array field to prepend items to.
5308
+ * If omitted, uses the parent array context.
5309
+ */
5310
+ arrayKey: z33.string().optional(),
5311
+ props: MatButtonPropsSchema.optional()
5312
+ });
5313
+ var MatInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5314
+ type: z33.literal("insert-array-item"),
5315
+ /**
5316
+ * Key of the array field to insert items into.
5317
+ * If omitted, uses the parent array context.
5318
+ */
5319
+ arrayKey: z33.string().optional(),
5320
+ /**
5321
+ * Index at which to insert the new item.
5322
+ */
5323
+ index: z33.number(),
5324
+ props: MatButtonPropsSchema.optional()
5325
+ });
5326
+ var MatPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5327
+ type: z33.literal("pop-array-item"),
5328
+ /**
5329
+ * Key of the array field to pop items from.
5330
+ */
5331
+ arrayKey: z33.string(),
5332
+ props: MatButtonPropsSchema.optional()
5333
+ });
5334
+ var MatShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5335
+ type: z33.literal("shift-array-item"),
5336
+ /**
5337
+ * Key of the array field to shift items from.
5338
+ */
5339
+ arrayKey: z33.string(),
5340
+ props: MatButtonPropsSchema.optional()
5341
+ });
5233
5342
 
5234
5343
  // internal/dynamic-forms-zod/material/src/mat-leaf-field.schema.ts
5235
5344
  import { z as z36 } from "zod";
@@ -5305,7 +5414,11 @@ var MatLeafFieldSchema = z36.discriminatedUnion("type", [
5305
5414
  MatNextButtonFieldSchema,
5306
5415
  MatPreviousButtonFieldSchema,
5307
5416
  MatAddArrayItemButtonFieldSchema,
5308
- MatRemoveArrayItemButtonFieldSchema
5417
+ MatRemoveArrayItemButtonFieldSchema,
5418
+ MatPrependArrayItemButtonFieldSchema,
5419
+ MatInsertArrayItemButtonFieldSchema,
5420
+ MatPopArrayItemButtonFieldSchema,
5421
+ MatShiftArrayItemButtonFieldSchema
5309
5422
  ]).superRefine(nullableValueRefine);
5310
5423
 
5311
5424
  // internal/dynamic-forms-zod/src/lib/schemas/containers/factories.ts
@@ -5773,13 +5886,34 @@ var BsPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
5773
5886
  props: BsButtonPropsSchema.optional()
5774
5887
  });
5775
5888
  var BsAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5776
- type: z44.literal("addArrayItem"),
5889
+ type: z44.literal("add-array-item"),
5777
5890
  arrayKey: z44.string().optional(),
5778
5891
  props: BsButtonPropsSchema.optional()
5779
5892
  });
5780
5893
  var BsRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5781
- type: z44.literal("removeArrayItem"),
5894
+ type: z44.literal("remove-array-item"),
5895
+ arrayKey: z44.string().optional(),
5896
+ props: BsButtonPropsSchema.optional()
5897
+ });
5898
+ var BsPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5899
+ type: z44.literal("prepend-array-item"),
5900
+ arrayKey: z44.string().optional(),
5901
+ props: BsButtonPropsSchema.optional()
5902
+ });
5903
+ var BsInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5904
+ type: z44.literal("insert-array-item"),
5782
5905
  arrayKey: z44.string().optional(),
5906
+ index: z44.number(),
5907
+ props: BsButtonPropsSchema.optional()
5908
+ });
5909
+ var BsPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5910
+ type: z44.literal("pop-array-item"),
5911
+ arrayKey: z44.string(),
5912
+ props: BsButtonPropsSchema.optional()
5913
+ });
5914
+ var BsShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5915
+ type: z44.literal("shift-array-item"),
5916
+ arrayKey: z44.string(),
5783
5917
  props: BsButtonPropsSchema.optional()
5784
5918
  });
5785
5919
 
@@ -5802,7 +5936,11 @@ var BsLeafFieldSchema = z45.discriminatedUnion("type", [
5802
5936
  BsNextButtonFieldSchema,
5803
5937
  BsPreviousButtonFieldSchema,
5804
5938
  BsAddArrayItemButtonFieldSchema,
5805
- BsRemoveArrayItemButtonFieldSchema
5939
+ BsRemoveArrayItemButtonFieldSchema,
5940
+ BsPrependArrayItemButtonFieldSchema,
5941
+ BsInsertArrayItemButtonFieldSchema,
5942
+ BsPopArrayItemButtonFieldSchema,
5943
+ BsShiftArrayItemButtonFieldSchema
5806
5944
  ]).superRefine(nullableValueRefine);
5807
5945
 
5808
5946
  // internal/dynamic-forms-zod/bootstrap/src/bs-form-config.schema.ts
@@ -5985,15 +6123,36 @@ var PrimePreviousButtonFieldSchema = BaseFieldDefSchema.extend({
5985
6123
  props: PrimeButtonPropsSchema.optional()
5986
6124
  });
5987
6125
  var PrimeAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5988
- type: z48.literal("addArrayItem"),
6126
+ type: z48.literal("add-array-item"),
5989
6127
  arrayKey: z48.string().optional(),
5990
6128
  props: PrimeButtonPropsSchema.optional()
5991
6129
  });
5992
6130
  var PrimeRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
5993
- type: z48.literal("removeArrayItem"),
6131
+ type: z48.literal("remove-array-item"),
5994
6132
  arrayKey: z48.string().optional(),
5995
6133
  props: PrimeButtonPropsSchema.optional()
5996
6134
  });
6135
+ var PrimePrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6136
+ type: z48.literal("prepend-array-item"),
6137
+ arrayKey: z48.string().optional(),
6138
+ props: PrimeButtonPropsSchema.optional()
6139
+ });
6140
+ var PrimeInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6141
+ type: z48.literal("insert-array-item"),
6142
+ arrayKey: z48.string().optional(),
6143
+ index: z48.number(),
6144
+ props: PrimeButtonPropsSchema.optional()
6145
+ });
6146
+ var PrimePopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6147
+ type: z48.literal("pop-array-item"),
6148
+ arrayKey: z48.string(),
6149
+ props: PrimeButtonPropsSchema.optional()
6150
+ });
6151
+ var PrimeShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6152
+ type: z48.literal("shift-array-item"),
6153
+ arrayKey: z48.string(),
6154
+ props: PrimeButtonPropsSchema.optional()
6155
+ });
5997
6156
 
5998
6157
  // internal/dynamic-forms-zod/primeng/src/prime-leaf-field.schema.ts
5999
6158
  import { z as z49 } from "zod";
@@ -6014,7 +6173,11 @@ var PrimeLeafFieldSchema = z49.discriminatedUnion("type", [
6014
6173
  PrimeNextButtonFieldSchema,
6015
6174
  PrimePreviousButtonFieldSchema,
6016
6175
  PrimeAddArrayItemButtonFieldSchema,
6017
- PrimeRemoveArrayItemButtonFieldSchema
6176
+ PrimeRemoveArrayItemButtonFieldSchema,
6177
+ PrimePrependArrayItemButtonFieldSchema,
6178
+ PrimeInsertArrayItemButtonFieldSchema,
6179
+ PrimePopArrayItemButtonFieldSchema,
6180
+ PrimeShiftArrayItemButtonFieldSchema
6018
6181
  ]).superRefine(nullableValueRefine);
6019
6182
 
6020
6183
  // internal/dynamic-forms-zod/primeng/src/prime-form-config.schema.ts
@@ -6239,15 +6402,36 @@ var IonicPreviousButtonFieldSchema = BaseFieldDefSchema.extend({
6239
6402
  props: IonicButtonPropsSchema.optional()
6240
6403
  });
6241
6404
  var IonicAddArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6242
- type: z52.literal("addArrayItem"),
6405
+ type: z52.literal("add-array-item"),
6243
6406
  arrayKey: z52.string().optional(),
6244
6407
  props: IonicButtonPropsSchema.optional()
6245
6408
  });
6246
6409
  var IonicRemoveArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6247
- type: z52.literal("removeArrayItem"),
6410
+ type: z52.literal("remove-array-item"),
6411
+ arrayKey: z52.string().optional(),
6412
+ props: IonicButtonPropsSchema.optional()
6413
+ });
6414
+ var IonicPrependArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6415
+ type: z52.literal("prepend-array-item"),
6248
6416
  arrayKey: z52.string().optional(),
6249
6417
  props: IonicButtonPropsSchema.optional()
6250
6418
  });
6419
+ var IonicInsertArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6420
+ type: z52.literal("insert-array-item"),
6421
+ arrayKey: z52.string().optional(),
6422
+ index: z52.number(),
6423
+ props: IonicButtonPropsSchema.optional()
6424
+ });
6425
+ var IonicPopArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6426
+ type: z52.literal("pop-array-item"),
6427
+ arrayKey: z52.string(),
6428
+ props: IonicButtonPropsSchema.optional()
6429
+ });
6430
+ var IonicShiftArrayItemButtonFieldSchema = BaseFieldDefSchema.extend({
6431
+ type: z52.literal("shift-array-item"),
6432
+ arrayKey: z52.string(),
6433
+ props: IonicButtonPropsSchema.optional()
6434
+ });
6251
6435
 
6252
6436
  // internal/dynamic-forms-zod/ionic/src/ionic-leaf-field.schema.ts
6253
6437
  import { z as z53 } from "zod";
@@ -6268,7 +6452,11 @@ var IonicLeafFieldSchema = z53.discriminatedUnion("type", [
6268
6452
  IonicNextButtonFieldSchema,
6269
6453
  IonicPreviousButtonFieldSchema,
6270
6454
  IonicAddArrayItemButtonFieldSchema,
6271
- IonicRemoveArrayItemButtonFieldSchema
6455
+ IonicRemoveArrayItemButtonFieldSchema,
6456
+ IonicPrependArrayItemButtonFieldSchema,
6457
+ IonicInsertArrayItemButtonFieldSchema,
6458
+ IonicPopArrayItemButtonFieldSchema,
6459
+ IonicShiftArrayItemButtonFieldSchema
6272
6460
  ]).superRefine(nullableValueRefine);
6273
6461
 
6274
6462
  // internal/dynamic-forms-zod/ionic/src/ionic-form-config.schema.ts
@@ -6654,8 +6842,12 @@ var NESTING_RULES = {
6654
6842
  "submit",
6655
6843
  "next",
6656
6844
  "previous",
6657
- "addArrayItem",
6658
- "removeArrayItem"
6845
+ "add-array-item",
6846
+ "prepend-array-item",
6847
+ "insert-array-item",
6848
+ "remove-array-item",
6849
+ "pop-array-item",
6850
+ "shift-array-item"
6659
6851
  ],
6660
6852
  forbidden: ["page"],
6661
6853
  message: "Pages cannot be nested inside other containers. ALL top-level fields must be pages if using multi-page mode."
@@ -6678,8 +6870,12 @@ var NESTING_RULES = {
6678
6870
  "submit",
6679
6871
  "next",
6680
6872
  "previous",
6681
- "addArrayItem",
6682
- "removeArrayItem"
6873
+ "add-array-item",
6874
+ "prepend-array-item",
6875
+ "insert-array-item",
6876
+ "remove-array-item",
6877
+ "pop-array-item",
6878
+ "shift-array-item"
6683
6879
  ],
6684
6880
  forbidden: ["page", "row", "hidden"],
6685
6881
  message: "Rows cannot contain pages, other rows, or hidden fields. Hidden fields should be at page or form level."
@@ -6702,8 +6898,12 @@ var NESTING_RULES = {
6702
6898
  "submit",
6703
6899
  "next",
6704
6900
  "previous",
6705
- "addArrayItem",
6706
- "removeArrayItem"
6901
+ "add-array-item",
6902
+ "prepend-array-item",
6903
+ "insert-array-item",
6904
+ "remove-array-item",
6905
+ "pop-array-item",
6906
+ "shift-array-item"
6707
6907
  ],
6708
6908
  forbidden: ["page", "group"],
6709
6909
  message: "Groups cannot contain pages or other groups (no nested groups)."
@@ -6727,8 +6927,12 @@ var NESTING_RULES = {
6727
6927
  "submit",
6728
6928
  "next",
6729
6929
  "previous",
6730
- "addArrayItem",
6731
- "removeArrayItem"
6930
+ "add-array-item",
6931
+ "prepend-array-item",
6932
+ "insert-array-item",
6933
+ "remove-array-item",
6934
+ "pop-array-item",
6935
+ "shift-array-item"
6732
6936
  ],
6733
6937
  forbidden: ["page", "array"],
6734
6938
  message: "Arrays cannot contain pages or other arrays (no nested arrays)."
@@ -6974,6 +7178,27 @@ function preValidateConfig(config) {
6974
7178
  });
6975
7179
  return errors;
6976
7180
  }
7181
+ var LEGACY_ARRAY_ACTION_TYPES = {
7182
+ addArrayItem: "add-array-item",
7183
+ prependArrayItem: "prepend-array-item",
7184
+ insertArrayItem: "insert-array-item",
7185
+ removeArrayItem: "remove-array-item",
7186
+ popArrayItem: "pop-array-item",
7187
+ shiftArrayItem: "shift-array-item"
7188
+ };
7189
+ function normalizeLegacyArrayActionTypes(value) {
7190
+ if (Array.isArray(value)) {
7191
+ return value.map(normalizeLegacyArrayActionTypes);
7192
+ }
7193
+ if (value && typeof value === "object") {
7194
+ const out = {};
7195
+ for (const [key, val] of Object.entries(value)) {
7196
+ out[key] = key === "type" && typeof val === "string" && LEGACY_ARRAY_ACTION_TYPES[val] ? LEGACY_ARRAY_ACTION_TYPES[val] : normalizeLegacyArrayActionTypes(val);
7197
+ }
7198
+ return out;
7199
+ }
7200
+ return value;
7201
+ }
6977
7202
  function validateFormConfig(uiIntegration, config) {
6978
7203
  const schema = formConfigSchemas2[uiIntegration];
6979
7204
  if (!schema) {
@@ -6988,15 +7213,16 @@ function validateFormConfig(uiIntegration, config) {
6988
7213
  errorSummary: `Unknown UI integration: ${uiIntegration}`
6989
7214
  };
6990
7215
  }
6991
- const preErrors = preValidateConfig(config);
6992
- const result = schema.safeParse(config);
7216
+ const normalizedConfig = normalizeLegacyArrayActionTypes(config);
7217
+ const preErrors = preValidateConfig(normalizedConfig);
7218
+ const result = schema.safeParse(normalizedConfig);
6993
7219
  if (result.success && preErrors.length === 0) {
6994
7220
  return {
6995
7221
  valid: true,
6996
7222
  data: result.data
6997
7223
  };
6998
7224
  }
6999
- const zodErrors = result.success ? [] : formatZodError(result.error, config);
7225
+ const zodErrors = result.success ? [] : formatZodError(result.error, normalizedConfig);
7000
7226
  const allErrors = [...preErrors, ...zodErrors];
7001
7227
  return {
7002
7228
  valid: false,
@@ -7026,29 +7252,32 @@ ${UI_INTEGRATIONS.map((ui) => `- ${ui}`).join("\n")}
7026
7252
  ## Field Types
7027
7253
  ${fieldTypes.map((ft) => `- ${ft}`).join("\n")}
7028
7254
 
7029
- ## Tools (4 total - consolidated)
7255
+ ## Tools (5 total - consolidated)
7030
7256
 
7031
- **1. START HERE - One-shot reference:**
7032
- \`ngforge_get_cheatsheet(uiIntegration?)\`
7257
+ **1. START HERE - Documentation lookup:**
7258
+ \`ngforge_lookup(topic, depth?, uiIntegration?)\`
7259
+ - topic="workflow" for the recommended tool-usage guide
7033
7260
  - Property placement rules, condition syntax, copy-paste patterns, common errors
7034
- - Component API (template binding, event names)
7035
- - **Use this first** - it has 90% of what you need in one call
7261
+ - depth="brief|full|schema" (default full); uiIntegration filters schema output
7036
7262
 
7037
- **2. Validation:**
7038
- \`ngforge_validate_form_config(uiIntegration, config)\`
7263
+ **2. Search:**
7264
+ \`ngforge_search(query)\`
7265
+ - Free-text keyword search across all topics and examples
7266
+ - Use when you don't know the exact topic name
7267
+
7268
+ **3. Validation:**
7269
+ \`ngforge_validate(config, uiIntegration?)\`
7039
7270
  - Validates config against actual TypeScript types
7040
7271
  - Catches errors before runtime
7041
7272
 
7042
- **3. Field info + schema:**
7043
- \`ngforge_get_field_info(fieldType?, uiIntegration?, includeSchema?)\`
7044
- - Properties, validators, and examples for a specific field type
7045
- - Set includeSchema=true for JSON Schema (machine-readable)
7046
-
7047
- **4. Examples + deep explanations:**
7048
- \`ngforge_get_example(pattern?, depth?)\`
7273
+ **4. Examples:**
7274
+ \`ngforge_examples(pattern, depth?)\`
7049
7275
  - Patterns: complete, derivation, conditional, multi-page, validation
7050
- - depth="example" (default) = working code
7051
- - depth="deep" = conceptual explanation + code + edge cases
7276
+ - depth controls how much detail (working code vs. deep explanation)
7277
+
7278
+ **5. Scaffold:**
7279
+ \`ngforge_scaffold(fields?, pages?, arrays?, groups?, hidden?, uiIntegration?)\`
7280
+ - Generates a compilable FormConfig skeleton
7052
7281
  `
7053
7282
  }
7054
7283
  ]
@@ -7708,8 +7937,8 @@ interface SimplifiedArrayField {
7708
7937
 
7709
7938
  The simplified API is normalized into the full API at runtime:
7710
7939
  1. Each \`value\` element creates an item using the \`template\` structure
7711
- 2. An \`addArrayItem\` button is auto-generated after the array (unless \`addButton: false\`)
7712
- 3. A \`removeArrayItem\` button is added to each item (unless \`removeButton: false\`)
7940
+ 2. An \`add-array-item\` button is auto-generated after the array (unless \`addButton: false\`)
7941
+ 3. A \`remove-array-item\` button is added to each item (unless \`removeButton: false\`)
7713
7942
 
7714
7943
  ## Conditional Visibility
7715
7944
 
@@ -9464,19 +9693,19 @@ const config = { fields: [...] } as const satisfies FormConfig;
9464
9693
  - Together they give you: type safety + exact type inference`
9465
9694
  },
9466
9695
  "array-buttons": {
9467
- brief: `**Add:** \`{ type: 'addArrayItem', key: 'add', label: 'Add', arrayKey: 'contacts' }\`
9468
- **Remove:** \`{ type: 'removeArrayItem', key: 'remove', label: 'Remove' }\` (inside array template)
9696
+ brief: `**Add:** \`{ type: 'add-array-item', key: 'add', label: 'Add', arrayKey: 'contacts' }\`
9697
+ **Remove:** \`{ type: 'remove-array-item', key: 'remove', label: 'Remove' }\` (inside array template)
9469
9698
  \u26A0\uFE0F arrayKey at FIELD level, NOT in props!`,
9470
9699
  full: `# Array Buttons (Add/Remove Items)
9471
9700
 
9472
- **UI libraries provide \`addArrayItem\` and \`removeArrayItem\` button types.**
9701
+ **UI libraries provide \`add-array-item\` and \`remove-array-item\` button types.**
9473
9702
 
9474
9703
  ## Add Item Button
9475
9704
 
9476
9705
  \`\`\`typescript
9477
9706
  {
9478
9707
  key: 'addPhone',
9479
- type: 'addArrayItem',
9708
+ type: 'add-array-item',
9480
9709
  label: 'Add Phone',
9481
9710
  arrayKey: 'phones', // \u26A0\uFE0F AT FIELD LEVEL, NOT IN PROPS!
9482
9711
  props: {
@@ -9498,7 +9727,7 @@ const config = { fields: [...] } as const satisfies FormConfig;
9498
9727
  { key: 'number', type: 'input', label: 'Phone Number' },
9499
9728
  {
9500
9729
  key: 'removePhone',
9501
- type: 'removeArrayItem',
9730
+ type: 'remove-array-item',
9502
9731
  label: 'Remove',
9503
9732
  // arrayKey not needed - inferred from parent array
9504
9733
  props: { color: 'warn' }
@@ -9513,13 +9742,13 @@ const config = { fields: [...] } as const satisfies FormConfig;
9513
9742
  \`\`\`typescript
9514
9743
  // WRONG - arrayKey in props
9515
9744
  {
9516
- type: 'addArrayItem',
9745
+ type: 'add-array-item',
9517
9746
  props: { arrayKey: 'phones' } // \u274C WRONG LOCATION
9518
9747
  }
9519
9748
 
9520
9749
  // CORRECT - arrayKey at field level
9521
9750
  {
9522
- type: 'addArrayItem',
9751
+ type: 'add-array-item',
9523
9752
  arrayKey: 'phones', // \u2705 CORRECT
9524
9753
  props: { color: 'primary' }
9525
9754
  }
@@ -9788,8 +10017,19 @@ var TOPIC_ALIASES = {
9788
10017
  valueof: "context-api",
9789
10018
  "add-array": "array-buttons",
9790
10019
  "remove-array": "array-buttons",
10020
+ // Array-action field types: kebab-case canonical + camelCase legacy aliases
10021
+ "add-array-item": "array-buttons",
10022
+ "prepend-array-item": "array-buttons",
10023
+ "insert-array-item": "array-buttons",
10024
+ "remove-array-item": "array-buttons",
10025
+ "pop-array-item": "array-buttons",
10026
+ "shift-array-item": "array-buttons",
9791
10027
  addarrayitem: "array-buttons",
10028
+ prependarrayitem: "array-buttons",
10029
+ insertarrayitem: "array-buttons",
9792
10030
  removearrayitem: "array-buttons",
10031
+ poparrayitem: "array-buttons",
10032
+ shiftarrayitem: "array-buttons",
9793
10033
  "custom-validator": "custom-validators",
9794
10034
  customvalidator: "custom-validators",
9795
10035
  mistakes: "pitfalls",
@@ -10834,7 +11074,7 @@ For full control, use the \`fields\`-based API with explicit add/remove buttons:
10834
11074
  ]
10835
11075
  ]
10836
11076
  }
10837
- // + separate addArrayItem button with arrayKey
11077
+ // + separate add-array-item button with arrayKey
10838
11078
  \`\`\``,
10839
11079
  explained: `# Array Fields - Complete Explanation
10840
11080
 
@@ -10906,7 +11146,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
10906
11146
  // ADD button - place OUTSIDE the array
10907
11147
  {
10908
11148
  key: 'addContact',
10909
- type: 'addArrayItem',
11149
+ type: 'add-array-item',
10910
11150
  label: 'Add Contact',
10911
11151
  arrayKey: 'contacts', // \u26A0\uFE0F AT FIELD LEVEL!
10912
11152
  }
@@ -10918,7 +11158,7 @@ For full control, use \`fields\` with explicit item definitions and manual add/r
10918
11158
  fields: [
10919
11159
  [
10920
11160
  { key: 'name', type: 'input', label: 'Name' },
10921
- { key: 'remove', type: 'removeArrayItem', label: 'Remove' }
11161
+ { key: 'remove', type: 'remove-array-item', label: 'Remove' }
10922
11162
  ]
10923
11163
  ]
10924
11164
  }
@@ -10952,8 +11192,8 @@ expression: '(formValue.items || []).reduce((sum, item) => sum + (item.price ||
10952
11192
 
10953
11193
  \u274C Putting \`arrayKey\` in props (full API):
10954
11194
  \`\`\`typescript
10955
- { type: 'addArrayItem', props: { arrayKey: 'x' } } // WRONG
10956
- { type: 'addArrayItem', arrayKey: 'x' } // CORRECT
11195
+ { type: 'add-array-item', props: { arrayKey: 'x' } } // WRONG
11196
+ { type: 'add-array-item', arrayKey: 'x' } // CORRECT
10957
11197
  \`\`\``
10958
11198
  },
10959
11199
  "minimal-simplified-array": {
@@ -1,4 +1,5 @@
1
1
  /** Addon Registry Data */
2
+ import type { UiIntegration } from '@ng-forge/dynamic-forms-zod/mcp';
2
3
  import type { PropertyInfo } from './index.js';
3
4
  export interface AddonTypeInfo {
4
5
  /** Discriminant matching `addon.type` in form configs. */
@@ -8,7 +9,7 @@ export interface AddonTypeInfo {
8
9
  /** Provider package; `'core'` means @ng-forge/dynamic-forms. */
9
10
  package: string;
10
11
  /** Adapter that ships this type, or `null` for core types. */
11
- adapter: 'material' | 'primeng' | 'bootstrap' | 'ionic' | null;
12
+ adapter: UiIntegration | null;
12
13
  /** One-line description of what this type renders. */
13
14
  description: string;
14
15
  /**
@@ -33,7 +34,7 @@ export interface FieldAddonSupportInfo {
33
34
  /** Field type discriminant (matches `FieldDef.type`). */
34
35
  fieldType: string;
35
36
  /** Adapter shipping the field — null for core fields. */
36
- adapter: 'material' | 'primeng' | 'bootstrap' | 'ionic' | null;
37
+ adapter: UiIntegration | null;
37
38
  /** Slots this field accepts. */
38
39
  slots: ('prefix' | 'suffix' | string)[];
39
40
  /** Whitelist of allowed types (omitted = any registered type). */