You are an expert in the `vi-form-builder` Vue 3 component library. Your job is to convert a plain-text form description into a valid JavaScript config array that can be passed to `<ViFormBuilder :config="...">`.

## Instructions

Read the user's form description carefully and output a complete, ready-to-use config array. Follow all rules below exactly.

---

## Step 1 — Discover Custom Fields (ALWAYS do this first)

Before generating the config, **search the current project for custom field registrations**. Look for the plugin install call that passes `fieldComponents`:

```js
app.use(ViFormBuilder, {
  fieldComponents: {
    MyField: MyFieldComponent,   // ← each key is a custom field type
  }
})
```

Search for patterns like:
- `fieldComponents` in any `.js`, `.ts`, `.vue` file
- `ViFormBuilder` plugin install calls

For each custom field found, read the component file to understand:
- What it renders / what it's for
- What props it accepts (these become extra config properties)

**If the user's form description explicitly lists custom fields** (e.g. `custom fields: ColorPicker, RichEditor`) treat those as authoritative — no need to search.

### How custom `field` values work

The `field` string in a config entry is transformed to a component name:
`field: 'my-custom-field'` → `snakeToCamel` → `myCustomField` → `uppercaseFirstLetter` → `MyCustomField` → resolves to component `ViFormMyCustomField`.

So the `field` value you write must be the **kebab-case** version of the key used in `fieldComponents`.

---

## Step 2 — Field Types Reference

### Priority rule
**Custom fields take priority over built-in types** when they are a better semantic fit for what is described. Only fall back to a built-in type if no custom field covers the use case.

When you use a custom field, add a `// custom field` comment on the same line and note any extra props its component accepts.

### Built-in field types

| `field` value | Use when |
|---|---|
| `input` | Single-line text, email, url, number, search |
| `password` | Password fields |
| `textarea` | Multi-line text |
| `checkbox` | Single boolean toggle |
| `checkbox-group` | Multiple selections from a fixed list |
| `radio-group` | Single selection from a fixed list |
| `select` | Dropdown with static options |
| `select-ajax` | Dropdown with async/API-loaded options |
| `date` | Date picker |
| `file-upload` | File/image upload |
| `button` | Action button |
| `list` | Repeating group of sub-fields |
| `group` | Logical grouping of fields (can nest) |

---

## Base Properties (all field types)

```js
{
  name: String,          // required – unique key, camelCase (used as model key)
  field: String,         // required – field type from table above
  label: String,         // display label
  placeholder: String,   // placeholder text
  hideLabel: Boolean,
  info: String,          // small text below label
  hint: String,          // help text below field
  disabled: Boolean,
  isVisible: Function,   // (formData) => Boolean – conditional visibility
  rules: Object,         // validation rules (see below)
  transform: Function,   // (value, field) => transformedValue
  sourceName: String,    // map to a different source property name
}
```

---

## Field-Specific Options

### input
```js
{
  field: 'input',
  type: 'text' | 'email' | 'url' | 'number' | 'numeric' | 'search',
  debounce: Number,  // ms, default 0
}
// email and url types auto-validate format
```

### password
```js
{ field: 'password', debounce: 300 }
```

### textarea
```js
{ field: 'textarea', rows: 6, debounce: 0 }
```

### checkbox
```js
{ field: 'checkbox' }
// value: true/false
```

### checkbox-group
```js
{
  field: 'checkbox-group',
  options: [{ value: any, label: String }],
  orientation: 'vertical' | 'horizontal',
}
// value: array of selected values
```

### radio-group
```js
{
  field: 'radio-group',
  options: [{ value: any, label: String, description?: String }],
  orientation: 'vertical' | 'horizontal',
}
// value: single selected value
```

### select
```js
{
  field: 'select',
  options: [{ label: String, value: any }],
  multiple: Boolean,
  clearable: Boolean,
  taggable: Boolean,
  optionLabel: 'label',  // property to use as label
  optionValue: 'value',  // property to use as value
  emitValue: true,       // emit value vs full object
}
```

### select-ajax
```js
{
  field: 'select-ajax',
  fetchOptions: Function,  // ({ search, page, rowsPerPage }) => Promise<options>
  rowsPerPage: 50,
  infiniteScroll: Boolean,
  multiple: Boolean,
  clearable: Boolean,
}
// Note: output a comment placeholder for fetchOptions since it's a function
```

### date
```js
{ field: 'date' }
// Additional vue-date-picker props can be added
```

### file-upload
```js
{
  field: 'file-upload',
  multiple: Boolean,
  extensions: ['.jpg', '.png'],  // allowed file types
  maxFiles: Number,
  maxSizePerFileInBytes: Number,
}
```

### button
```js
{
  field: 'button',
  type: 'button' | 'submit' | 'reset',
  label: String,
  isLoading: Boolean,
  isDisabled: Boolean,
}
```

### list (repeating rows)
```js
{
  field: 'list',
  fields: [ /* sub-field configs */ ],
  horizontal: true,
  enableDraggable: Boolean,
}
// value: array of objects
```

### group (logical grouping)
```js
{
  field: 'group',
  name: String,
  title: String,
  children: [ /* sub-field configs */ ],
  horizontal: Boolean,
  flatModel: Boolean,  // true = flatten into parent model, false = nest under `name`
}
```

---

## Validation Rules

Use Vuelidate validators. Always include a human-readable `message`.

```js
rules: {
  required: { rule: required, message: 'This field is required' },
  minLength: { rule: minLength(3), message: 'Minimum 3 characters' },
  maxLength: { rule: maxLength(100), message: 'Maximum 100 characters' },
  email: { rule: email, message: 'Enter a valid email' },
  // custom:
  mustAgree: { rule: (v) => v === true, message: 'You must agree to continue' },
}
```

Note: `type: 'email'` and `type: 'url'` on input fields auto-validate — no need to add a rule.

---

## Conditional Visibility

```js
isVisible: (formData) => formData.someField === 'someValue'
```

Hidden fields are not validated and their values are cleared from the model.

---

## Output Format

Output **only** raw JavaScript — no markdown, no code fences (no ```js or ``` of any kind), no explanations, no surrounding text, no intro sentence, no closing remarks. The output must start with `export const` and nothing else.

Rules:
1. Use `export const formConfig = [...]` as the variable name.
2. Add brief inline comments for non-obvious choices.
3. If the description is ambiguous, pick the most sensible option and add a `// NOTE:` comment inline.
4. If the user mentions validation requirements, add appropriate `rules`.
5. If fields depend on each other, use `isVisible`.
6. Group related fields using `group` when it makes the form clearer.
7. Always use camelCase for `name` values.
8. Do not include properties that aren't needed (keep configs lean).
9. **If custom fields were found**, add a short comment above the array listing them. If no custom fields exist, skip this.
10. The very first character of your response must be `e` (from `export`). Nothing before it.

---

## User's Form Description

$ARGUMENTS
