From fcbdc6f9f529fea11470dcecc93555b1fdc7e235 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:14:49 +0000 Subject: [PATCH 1/6] Initial plan From 62ca8af76773d91b733e607f990f63b54731ddb5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:35:15 +0000 Subject: [PATCH 2/6] test: add regression coverage for update_issue MCP body length handling Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../setup/js/mcp_scripts_validation.test.cjs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/actions/setup/js/mcp_scripts_validation.test.cjs b/actions/setup/js/mcp_scripts_validation.test.cjs index dea289beb7f..f1be85482a1 100644 --- a/actions/setup/js/mcp_scripts_validation.test.cjs +++ b/actions/setup/js/mcp_scripts_validation.test.cjs @@ -1,4 +1,6 @@ import { describe, it, expect } from "vitest"; +import fs from "fs"; +import path from "path"; describe("mcp_scripts_validation.cjs", () => { describe("validateRequiredFields", () => { @@ -331,6 +333,32 @@ describe("mcp_scripts_validation.cjs", () => { const violations = validateStringInputLengths(args, schema); expect(violations).toEqual([]); }); + + it("should allow update_issue body above 10KB when schema declares maxLength", async () => { + const { validateStringInputLengths, MAX_STRING_INPUT_BYTES } = await import("./mcp_scripts_validation.cjs"); + const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); + const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); + const updateIssueTool = tools.find(tool => tool.name === "update_issue"); + + expect(updateIssueTool).toBeDefined(); + expect(updateIssueTool.inputSchema.properties.body.maxLength).toBe(65536); + + const args = { body: "a".repeat(MAX_STRING_INPUT_BYTES + 1) }; + const violations = validateStringInputLengths(args, updateIssueTool.inputSchema); + expect(violations).toEqual([]); + }); + + it("should enforce update_issue body schema maxLength boundary", async () => { + const { validateStringInputLengths } = await import("./mcp_scripts_validation.cjs"); + const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); + const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); + const updateIssueTool = tools.find(tool => tool.name === "update_issue"); + + const args = { body: "a".repeat(65537) }; + const violations = validateStringInputLengths(args, updateIssueTool.inputSchema); + expect(violations).toHaveLength(1); + expect(violations[0]).toMatchObject({ field: "body", limit: 65536, unit: "characters" }); + }); }); describe("validateStringMinLengths", () => { From 47bfba3a49e3f7917906937a40176c351a5d726e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:42:02 +0000 Subject: [PATCH 3/6] test: harden update_issue body length regression assertions Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../setup/js/mcp_scripts_validation.test.cjs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/actions/setup/js/mcp_scripts_validation.test.cjs b/actions/setup/js/mcp_scripts_validation.test.cjs index f1be85482a1..dfbd5ea8209 100644 --- a/actions/setup/js/mcp_scripts_validation.test.cjs +++ b/actions/setup/js/mcp_scripts_validation.test.cjs @@ -3,6 +3,18 @@ import fs from "fs"; import path from "path"; describe("mcp_scripts_validation.cjs", () => { + function loadUpdateIssueToolSchema() { + const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); + try { + const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); + const updateIssueTool = tools.find(tool => tool.name === "update_issue"); + expect(updateIssueTool, "update_issue tool should exist in safe_outputs_tools.json").toBeDefined(); + return updateIssueTool.inputSchema; + } catch (error) { + throw new Error(`Failed to load or parse safe outputs tool schema at ${toolsPath}: ${error.message}`); + } + } + describe("validateRequiredFields", () => { it("should return empty array when no required fields", async () => { const { validateRequiredFields } = await import("./mcp_scripts_validation.cjs"); @@ -336,26 +348,21 @@ describe("mcp_scripts_validation.cjs", () => { it("should allow update_issue body above 10KB when schema declares maxLength", async () => { const { validateStringInputLengths, MAX_STRING_INPUT_BYTES } = await import("./mcp_scripts_validation.cjs"); - const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); - const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); - const updateIssueTool = tools.find(tool => tool.name === "update_issue"); + const updateIssueSchema = loadUpdateIssueToolSchema(); - expect(updateIssueTool).toBeDefined(); - expect(updateIssueTool.inputSchema.properties.body.maxLength).toBe(65536); + expect(updateIssueSchema.properties.body.maxLength).toBe(65536); const args = { body: "a".repeat(MAX_STRING_INPUT_BYTES + 1) }; - const violations = validateStringInputLengths(args, updateIssueTool.inputSchema); + const violations = validateStringInputLengths(args, updateIssueSchema); expect(violations).toEqual([]); }); it("should enforce update_issue body schema maxLength boundary", async () => { const { validateStringInputLengths } = await import("./mcp_scripts_validation.cjs"); - const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); - const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); - const updateIssueTool = tools.find(tool => tool.name === "update_issue"); + const updateIssueSchema = loadUpdateIssueToolSchema(); const args = { body: "a".repeat(65537) }; - const violations = validateStringInputLengths(args, updateIssueTool.inputSchema); + const violations = validateStringInputLengths(args, updateIssueSchema); expect(violations).toHaveLength(1); expect(violations[0]).toMatchObject({ field: "body", limit: 65536, unit: "characters" }); }); From 5c60a16ec142c16c1ddbaa53bc59bc912083419d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:48:43 +0000 Subject: [PATCH 4/6] test: improve update_issue schema fixture loading diagnostics Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/mcp_scripts_validation.test.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/mcp_scripts_validation.test.cjs b/actions/setup/js/mcp_scripts_validation.test.cjs index dfbd5ea8209..1737c4c0590 100644 --- a/actions/setup/js/mcp_scripts_validation.test.cjs +++ b/actions/setup/js/mcp_scripts_validation.test.cjs @@ -4,6 +4,7 @@ import path from "path"; describe("mcp_scripts_validation.cjs", () => { function loadUpdateIssueToolSchema() { + // This suite runs from actions/setup/js where safe_outputs_tools.json is mirrored. const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); try { const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); @@ -11,7 +12,7 @@ describe("mcp_scripts_validation.cjs", () => { expect(updateIssueTool, "update_issue tool should exist in safe_outputs_tools.json").toBeDefined(); return updateIssueTool.inputSchema; } catch (error) { - throw new Error(`Failed to load or parse safe outputs tool schema at ${toolsPath}: ${error.message}`); + throw new Error(`Failed to load or parse safe outputs tool schema at ${toolsPath}. Expected a JSON array containing an 'update_issue' tool definition. Cause: ${error.message}`); } } From b8d2fb085d43e6a4daf0f2c97ca31f6c7ce2235a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 09:55:20 +0000 Subject: [PATCH 5/6] test: simplify update_issue schema assertion messaging Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/mcp_scripts_validation.test.cjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/mcp_scripts_validation.test.cjs b/actions/setup/js/mcp_scripts_validation.test.cjs index 1737c4c0590..1d20df1b526 100644 --- a/actions/setup/js/mcp_scripts_validation.test.cjs +++ b/actions/setup/js/mcp_scripts_validation.test.cjs @@ -9,7 +9,9 @@ describe("mcp_scripts_validation.cjs", () => { try { const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); const updateIssueTool = tools.find(tool => tool.name === "update_issue"); - expect(updateIssueTool, "update_issue tool should exist in safe_outputs_tools.json").toBeDefined(); + if (!updateIssueTool) { + throw new Error("Expected a tool definition named 'update_issue' in safe_outputs_tools.json"); + } return updateIssueTool.inputSchema; } catch (error) { throw new Error(`Failed to load or parse safe outputs tool schema at ${toolsPath}. Expected a JSON array containing an 'update_issue' tool definition. Cause: ${error.message}`); From d381390d967d26af2212eb1bb7a963836fb1f65b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:02:05 +0000 Subject: [PATCH 6/6] test: make update_issue schema fixture loading more robust Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/mcp_scripts_validation.test.cjs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/actions/setup/js/mcp_scripts_validation.test.cjs b/actions/setup/js/mcp_scripts_validation.test.cjs index 1d20df1b526..5bf94fff525 100644 --- a/actions/setup/js/mcp_scripts_validation.test.cjs +++ b/actions/setup/js/mcp_scripts_validation.test.cjs @@ -1,16 +1,19 @@ import { describe, it, expect } from "vitest"; import fs from "fs"; -import path from "path"; +import { fileURLToPath } from "url"; describe("mcp_scripts_validation.cjs", () => { function loadUpdateIssueToolSchema() { - // This suite runs from actions/setup/js where safe_outputs_tools.json is mirrored. - const toolsPath = path.join(process.cwd(), "safe_outputs_tools.json"); + const toolsPath = fileURLToPath(new URL("./safe_outputs_tools.json", import.meta.url)); try { const tools = JSON.parse(fs.readFileSync(toolsPath, "utf8")); + if (!Array.isArray(tools)) { + throw new Error("Expected tools schema to be a JSON array"); + } const updateIssueTool = tools.find(tool => tool.name === "update_issue"); if (!updateIssueTool) { - throw new Error("Expected a tool definition named 'update_issue' in safe_outputs_tools.json"); + const availableNames = tools.map(tool => tool?.name).filter(Boolean); + throw new Error(`Expected a tool definition named 'update_issue' in safe_outputs_tools.json. Found tools: ${availableNames.join(", ")}`); } return updateIssueTool.inputSchema; } catch (error) {