Form definition diff
form-definition-diff · version 1.0.0 · Forms · free, no key needed
Diff two form definitions by stable field id, including choice lists and field order.
Use when you need to: diff form fields · form structure diff.
Supported
- diff form fields
- form structure diff
Not supported
- filled answer diff
- fuzzy field matching
- html extraction
- pdf or ocr
Behavior
- Match fields by exact id. Do not infer renames. NFC and NFD ids are different.
- Duplicate field ids are rejected. Unknown keys are rejected. U+0000 is rejected.
- Field order is not equality. A shared-id sequence change sets order_changed and returns both sequences.
- changed.changes lists label, type, required, and choices in that order, and only the ones that differ.
- Choice order is part of the definition. choice_added and choice_removed keep the source order. choice_reordered compares the shared choice sequence.
- Unchanged fields are counted and not copied. Counts match the arrays. Over-budget output is rejected.
Input
left(object, required)right(object, required)
Output
added(array of any, required)removed(array of any, required)changed(array of any, required)order_changed(boolean, required)common_order_left(array of string, optional)common_order_right(array of string, optional)counts(object, required)
Limits
- max input bytes: 262144
- max output bytes: 262144
- max input depth: 16
- max input nodes: 20000
- max fields: 100
- max choices: 50
- max respondents: 100
- max id bytes: 128
- max label bytes: 256
- max choice bytes: 128
- max answer string bytes: 4096
- max answer depth: 6
- max answer nodes: 50
- max changes: 500
- max mapping: 100
Example
Request input:
{
"left": {
"fields": [
{
"id": "email",
"label": "Email",
"type": "string",
"required": true
},
{
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"free",
"pro"
]
}
]
},
"right": {
"fields": [
{
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"pro",
"team"
]
},
{
"id": "seats",
"label": "Seats",
"type": "integer",
"required": false
}
]
}
}
Response:
{
"result": {
"added": [
{
"id": "seats",
"field": {
"id": "seats",
"label": "Seats",
"type": "integer",
"required": false
}
}
],
"removed": [
{
"id": "email",
"field": {
"id": "email",
"label": "Email",
"type": "string",
"required": true
}
}
],
"changed": [
{
"id": "plan",
"changes": [
"choices"
],
"left": {
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"free",
"pro"
]
},
"right": {
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"pro",
"team"
]
},
"choice_added": [
"team"
],
"choice_removed": [
"free"
],
"choice_reordered": false
}
],
"order_changed": false,
"counts": {
"added": 1,
"removed": 1,
"changed": 1,
"unchanged": 0,
"reordered": 0
}
}
}
How to call it
MCP
Connect https://computefirst.net/mcp (setup), then call execute with:
{
"id": "form-definition-diff",
"version": "1.0.0",
"input": {
"left": {
"fields": [
{
"id": "email",
"label": "Email",
"type": "string",
"required": true
},
{
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"free",
"pro"
]
}
]
},
"right": {
"fields": [
{
"id": "plan",
"label": "Plan",
"type": "choice",
"required": true,
"choices": [
"pro",
"team"
]
},
{
"id": "seats",
"label": "Seats",
"type": "integer",
"required": false
}
]
}
}
}
HTTP (no key)
curl -X POST https://computefirst.net/v1/tools/form-definition-diff/versions/1.0.0/execute \
-H "Content-Type: application/json" \
-d '{"left":{"fields":[{"id":"email","label":"Email","type":"string","required":true},{"id":"plan","label":"Plan","type":"choice","required":true,"choices":["free","pro"]}]},"right":{"fields":[{"id":"plan","label":"Plan","type":"choice","required":true,"choices":["pro","team"]},{"id":"seats","label":"Seats","type":"integer","required":false}]}}'
The machine-readable contract is at /v1/tools/form-definition-diff/versions/1.0.0.
CLI
node cli.mjs run form-definition-diff 1.0.0 --input input.json --base-url https://computefirst.net
Get the client at /clients/cli/.
Related tools
- Form answer diff: Diff two answer maps against one shared form definition.
- Form compare: Compare two filled form snapshots and return compact field and answer changes.
- Form field map: Rename form fields with an explicit id map and reject collisions.
- Form response diff: Reconcile two form response sets by exact respondent id.
- Form response check: Report missing required answers, nulls, type failures, and choice failures.