Skip to content

Commit ae1b155

Browse files
mvanhornOrKoN
authored andcommitted
Exclude fill_form from schema validation lint rule per review
- Revert fill_form API changes (src/tools/input.ts, tests/tools/input.test.ts) - Rename rule to enforce-zod-schema per reviewer suggestion - Fix copyright year to 2026 - Add comment explaining .nullable() catches all calls intentionally - Exclude src/tools/input.ts from the lint rule via ignores
1 parent fd1a273 commit ae1b155

6 files changed

Lines changed: 34 additions & 21 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,5 @@ export const scenario: TestScenario = {
145145

146146
## Restrictions on JSON schema
147147

148-
- no .nullable(), no .object() types. Enforced by the `@local/no-zod-nullable-object` ESLint rule.
148+
- no .nullable(), no .object() types. Enforced by the `@local/enforce-zod-schema` ESLint rule.
149149
- represent complex object as a short formatted string.

eslint.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ export default defineConfig([
138138
{
139139
name: 'Tool schema restrictions',
140140
files: ['src/tools/**/*.ts'],
141+
ignores: ['src/tools/input.ts'],
141142
rules: {
142-
'@local/no-zod-nullable-object': 'error',
143+
'@local/enforce-zod-schema': 'error',
143144
},
144145
},
145146
{

scripts/eslint_rules/no-zod-nullable-object-rule.js renamed to scripts/eslint_rules/enforce-zod-schema-rule.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/**
22
* @license
3-
* Copyright 2025 Google LLC
3+
* Copyright 2026 Google LLC
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

77
export default {
8-
name: 'no-zod-nullable-object',
8+
name: 'enforce-zod-schema',
99
meta: {
1010
type: 'problem',
1111
docs: {
@@ -33,6 +33,9 @@ export default {
3333

3434
const methodName = node.callee.property.name;
3535

36+
// We don't validate that .nullable() is called on a ZodObject
37+
// specifically - this intentionally catches all .nullable() calls
38+
// in tool schema files.
3639
if (methodName === 'nullable') {
3740
context.report({
3841
node: node.callee.property,

scripts/eslint_rules/local-plugin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
*/
66

77
import checkLicenseRule from './check-license-rule.js';
8-
import noZodNullableObjectRule from './no-zod-nullable-object-rule.js';
8+
import enforceZodSchemaRule from './enforce-zod-schema-rule.js';
99

1010
export default {
1111
rules: {
1212
'check-license': checkLicenseRule,
13-
'no-zod-nullable-object': noZodNullableObjectRule,
13+
'enforce-zod-schema': enforceZodSchemaRule,
1414
},
1515
};

src/tools/input.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -321,25 +321,25 @@ export const fillForm = definePageTool({
321321
},
322322
schema: {
323323
elements: zod
324-
.array(zod.string())
325-
.describe(
326-
'Elements from snapshot to fill out. Each entry is formatted as "uid=value".',
327-
),
324+
.array(
325+
zod.object({
326+
uid: zod.string().describe('The uid of the element to fill out'),
327+
value: zod.string().describe('Value for the element'),
328+
}),
329+
)
330+
.describe('Elements from snapshot to fill out.'),
328331
includeSnapshot: includeSnapshotSchema,
329332
},
330333
handler: async (request, response, context) => {
331334
const page = request.page;
332-
for (const entry of request.params.elements) {
333-
const separatorIndex = entry.indexOf('=');
334-
if (separatorIndex === -1) {
335-
throw new Error(
336-
`Invalid element format: "${entry}". Expected "uid=value".`,
337-
);
338-
}
339-
const uid = entry.slice(0, separatorIndex);
340-
const value = entry.slice(separatorIndex + 1);
335+
for (const element of request.params.elements) {
341336
await context.waitForEventsAfterAction(async () => {
342-
await fillFormElement(uid, value, context as McpContext, page);
337+
await fillFormElement(
338+
element.uid,
339+
element.value,
340+
context as McpContext,
341+
page,
342+
);
343343
});
344344
}
345345
response.appendResponseLine(`Successfully filled out the form`);

tests/tools/input.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,16 @@ describe('input', () => {
670670
await fillForm.handler(
671671
{
672672
params: {
673-
elements: ['1_2=test', '1_4=test2'],
673+
elements: [
674+
{
675+
uid: '1_2',
676+
value: 'test',
677+
},
678+
{
679+
uid: '1_4',
680+
value: 'test2',
681+
},
682+
],
674683
},
675684
page: context.getSelectedMcpPage(),
676685
},

0 commit comments

Comments
 (0)