flutter-inspector-form
Form debugging specialist. Use for validation and error message inspection
| 항목 | 내용 |
|---|---|
| 모델 | haiku |
| 사용 도구 | Read, Glob, Grep |
| 연계 스킬 | flutter-inspector |
A specialized agent for debugging form state and validation at runtime.
Triggers#
Automatically activated when @flutter-inspector-form is invoked or the following keywords are detected:
- Form, Form, input
- Validation, Validation
- Field value, error message
MCP Tools#
form_list#
Lists all forms on the current screen.
{
"name": "form_list",
"description": "List forms",
"inputSchema": {
"type": "object",
"properties": {}
}
}
Response example:
{
"forms": [
{
"key": "loginForm",
"fieldCount": 3,
"isValid": false,
"isDirty": true,
"fields": ["email", "password", "rememberMe"]
},
{
"key": "profileForm",
"fieldCount": 5,
"isValid": true,
"isDirty": false,
"fields": ["name", "phone", "address", "city", "zipCode"]
}
],
"count": 2
}
form_get_state#
Returns the detailed state of a specific form.
{
"name": "form_get_state",
"description": "Detailed form state query",
"inputSchema": {
"type": "object",
"properties": {
"formKey": {
"type": "string",
"description": "Form key"
}
},
"required": ["formKey"]
}
}
Response example:
{
"formKey": "loginForm",
"state": {
"isValid": false,
"isDirty": true,
"isSubmitting": false,
"submitCount": 2,
"fields": {
"email": {
"value": "user@example",
"isValid": false,
"isTouched": true,
"isDirty": true,
"error": "Invalid email format"
},
"password": {
"value": "***",
"isValid": true,
"isTouched": true,
"isDirty": true,
"error": null
},
"rememberMe": {
"value": true,
"isValid": true,
"isTouched": false,
"isDirty": false,
"error": null
}
}
}
}
form_get_errors#
Returns all errors for a form.
{
"name": "form_get_errors",
"description": "Form error query",
"inputSchema": {
"type": "object",
"properties": {
"formKey": {
"type": "string",
"description": "Form key (omit for all forms)"
}
}
}
}
Response example:
{
"errors": {
"loginForm": {
"email": "Invalid email format",
"password": null
},
"profileForm": {
"phone": "Phone number is required",
"zipCode": "Invalid zip code format"
}
},
"totalErrors": 3
}
form_validate#
Manually validates a form.
{
"name": "form_validate",
"description": "Run form validation",
"inputSchema": {
"type": "object",
"properties": {
"formKey": {
"type": "string",
"description": "Form key"
}
},
"required": ["formKey"]
}
}
Response example:
{
"formKey": "loginForm",
"isValid": false,
"errors": {
"email": "Invalid email format"
},
"validatedAt": "2024-01-01T10:00:00Z"
}
App Integration Code#
// lib/debug/mcp_form_tools.dart
import 'package:mcp_toolkit/mcp_toolkit.dart';
import 'package:flutter/widgets.dart';
class FormTracker {
static final instance = FormTracker._();
FormTracker._();
final Map<String, GlobalKey<FormState>> _forms = {};
final Map<String, Map<String, TextEditingController>> _controllers = {};
final Map<String, Map<String, String?>> _errors = {};
void registerForm(String key, GlobalKey<FormState> formKey) {
_forms[key] = formKey;
}
void registerField(String formKey, String fieldName, TextEditingController controller) {
_controllers[formKey] ??= {};
_controllers[formKey]![fieldName] = controller;
}
void setError(String formKey, String fieldName, String? error) {
_errors[formKey] ??= {};
_errors[formKey]![fieldName] = error;
}
List<Map<String, dynamic>> listForms() {
return _forms.entries.map((e) {
final formState = e.value.currentState;
return {
'key': e.key,
'fieldCount': _controllers[e.key]?.length ?? 0,
'isValid': formState?.validate() ?? false,
'fields': _controllers[e.key]?.keys.toList() ?? [],
};
}).toList();
}
Map<String, dynamic> getFormState(String formKey) {
final formState = _forms[formKey]?.currentState;
final controllers = _controllers[formKey] ?? {};
final errors = _errors[formKey] ?? {};
return {
'formKey': formKey,
'state': {
'isValid': formState?.validate() ?? false,
'fields': controllers.map((name, controller) => MapEntry(name, {
'value': name.contains('password') ? '***' : controller.text,
'error': errors[name],
})),
},
};
}
Map<String, dynamic> getAllErrors() {
return Map.fromEntries(
_errors.entries.where((e) => e.value.values.any((v) => v != null)),
);
}
Map<String, dynamic> validateForm(String formKey) {
final formState = _forms[formKey]?.currentState;
final isValid = formState?.validate() ?? false;
return {
'formKey': formKey,
'isValid': isValid,
'errors': _errors[formKey]?.entries
.where((e) => e.value != null)
.fold<Map<String, String>>({}, (map, e) => map..[e.key] = e.value!),
};
}
}
void registerFormTools() {
if (!kDebugMode) return;
addMcpTool(MCPCallEntry.tool(
handler: (_) => MCPCallResult(
message: 'Form list',
parameters: {'forms': FormTracker.instance.listForms()},
),
definition: MCPToolDefinition(
name: 'form_list',
description: 'List forms',
inputSchema: {'type': 'object', 'properties': {}},
),
));
addMcpTool(MCPCallEntry.tool(
handler: (params) {
final formKey = params['formKey'] as String;
return MCPCallResult(
message: 'Form state',
parameters: FormTracker.instance.getFormState(formKey),
);
},
definition: MCPToolDefinition(
name: 'form_get_state',
description: 'Form state query',
inputSchema: {
'type': 'object',
'properties': {'formKey': {'type': 'string'}},
'required': ['formKey'],
},
),
));
addMcpTool(MCPCallEntry.tool(
handler: (_) => MCPCallResult(
message: 'Form errors',
parameters: {'errors': FormTracker.instance.getAllErrors()},
),
definition: MCPToolDefinition(
name: 'form_get_errors',
description: 'Form error query',
inputSchema: {'type': 'object', 'properties': {}},
),
));
addMcpTool(MCPCallEntry.tool(
handler: (params) {
final formKey = params['formKey'] as String;
return MCPCallResult(
message: 'Validation result',
parameters: FormTracker.instance.validateForm(formKey),
);
},
definition: MCPToolDefinition(
name: 'form_validate',
description: 'Form validation',
inputSchema: {
'type': 'object',
'properties': {'formKey': {'type': 'string'}},
'required': ['formKey'],
},
),
));
}
Usage Examples#
Check form list#
Q: What forms are on the current screen?
A: Run form_list
-> loginForm (3 fields), profileForm (5 fields)
Detailed form state check#
Q: Show me the login form state
A: Run form_get_state formKey="loginForm"
-> email: invalid, password: valid, rememberMe: true
Check errors#
Q: Are there any form errors?
A: Run form_get_errors
-> email: "Invalid email format"
Manual validation#
Q: Validate the profile form
A: Run form_validate formKey="profileForm"
-> isValid: false, errors: {phone: "Required field"}
Common Problem Diagnosis#
Form not submitting#
1. Check current state with form_get_state
2. If isValid: false, check errors
3. Query all errors with form_get_errors
4. Review validation logic
Validation not working#
1. Run manual validation with form_validate
2. Check error messages
3. Review validator function logic
Field values not persisting#
1. Check field values with form_get_state
2. Verify TextEditingController connection
3. Review form state restoration logic
Error messages not showing#
1. Confirm errors exist with form_get_errors
2. Check ErrorText widget rendering
3. Check AutovalidateMode settings
Form Widget Integration#
// Form registration example
class LoginForm extends StatefulWidget {
@override
_LoginFormState createState() => _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
@override
void initState() {
super.initState();
if (kDebugMode) {
FormTracker.instance.registerForm('loginForm', _formKey);
FormTracker.instance.registerField('loginForm', 'email', _emailController);
FormTracker.instance.registerField('loginForm', 'password', _passwordController);
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _emailController,
validator: (value) {
final error = _validateEmail(value);
if (kDebugMode) {
FormTracker.instance.setError('loginForm', 'email', error);
}
return error;
},
),
// ...
],
),
);
}
}
Related Agents#
@flutter-inspector: Master inspector@flutter-inspector-bloc: Form state and BLoC connection@flutter-inspector-ui: Form UI layout inspection