From 0384371a00d04e4fed98990565d980776071dc4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:42:27 +0000 Subject: [PATCH 1/4] Initial plan From ea0d00a7517937cfff44af2cf333151126195e65 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:52:20 +0000 Subject: [PATCH 2/4] Print all gateway-related files in parse_mcp_gateway_log.cjs - Added printAllGatewayFiles() function to list and print all files in /tmp/gh-aw/mcp-logs and /tmp/gh-aw/mcp-config - Function prints directory structure, file sizes, and file contents (up to 1MB) - Updated main() to call printAllGatewayFiles() at the start for comprehensive debugging - Added comprehensive tests for the new function - Properly handles TypeScript error types with unknown type annotations - All tests passing and code formatted Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/parse_mcp_gateway_log.cjs | 77 +++++++ .../setup/js/parse_mcp_gateway_log.test.cjs | 196 +++++++++++++++++- 2 files changed, 272 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/parse_mcp_gateway_log.cjs b/actions/setup/js/parse_mcp_gateway_log.cjs index f08c77aee4..ff99b7fc54 100644 --- a/actions/setup/js/parse_mcp_gateway_log.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.cjs @@ -12,11 +12,87 @@ const { getErrorMessage } = require("./error_helpers.cjs"); * - /tmp/gh-aw/mcp-logs/stderr.log (stderr output, fallback) */ +/** + * Prints all gateway-related files to core.info for debugging + */ +function printAllGatewayFiles() { + core.info("=== Listing All Gateway-Related Files ==="); + core.info(""); + + const gatewayDirs = ["/tmp/gh-aw/mcp-logs", "/tmp/gh-aw/mcp-config"]; + + for (const dir of gatewayDirs) { + if (!fs.existsSync(dir)) { + core.info(`Directory does not exist: ${dir}`); + core.info(""); + continue; + } + + core.info(`Directory: ${dir}`); + try { + const files = fs.readdirSync(dir); + if (files.length === 0) { + core.info(" (empty directory)"); + core.info(""); + continue; + } + + for (const file of files) { + const filePath = `${dir}/${file}`; + try { + const stats = fs.statSync(filePath); + + if (stats.isDirectory()) { + core.info(` ${file}/ (directory)`); + } else { + core.info(` ${file} (${stats.size} bytes)`); + + // Print file content if it's a text file and not too large + if (stats.size > 0 && stats.size < 1024 * 1024) { + // Max 1MB + try { + const content = fs.readFileSync(filePath, "utf8"); + core.info(` --- Content of ${file} ---`); + // Split content into lines and prefix each line for readability + const lines = content.split("\n"); + for (const line of lines) { + core.info(` ${line}`); + } + core.info(` --- End of ${file} ---`); + } catch (/** @type {unknown} */ readError) { + const errorMessage = readError instanceof Error ? readError.message : String(readError); + core.info(` (could not read file as text: ${errorMessage})`); + } + } else if (stats.size === 0) { + core.info(` (empty file)`); + } else { + core.info(` (file too large to display, ${stats.size} bytes)`); + } + } + } catch (/** @type {unknown} */ statError) { + const errorMessage = statError instanceof Error ? statError.message : String(statError); + core.info(` ${file} (error reading file info: ${errorMessage})`); + } + } + } catch (/** @type {unknown} */ readError) { + const errorMessage = readError instanceof Error ? readError.message : String(readError); + core.info(` Error reading directory: ${errorMessage}`); + } + core.info(""); + } + + core.info("=== End of Gateway-Related Files ==="); + core.info(""); +} + /** * Main function to parse and display MCP gateway logs */ async function main() { try { + // First, print all gateway-related files for debugging + printAllGatewayFiles(); + const gatewayMdPath = "/tmp/gh-aw/mcp-logs/gateway.md"; const gatewayLogPath = "/tmp/gh-aw/mcp-logs/gateway.log"; const stderrLogPath = "/tmp/gh-aw/mcp-logs/stderr.log"; @@ -197,6 +273,7 @@ if (typeof module !== "undefined" && module.exports) { generateGatewayLogSummary, generatePlainTextGatewaySummary, generatePlainTextLegacySummary, + printAllGatewayFiles, }; } diff --git a/actions/setup/js/parse_mcp_gateway_log.test.cjs b/actions/setup/js/parse_mcp_gateway_log.test.cjs index c5c6dceb02..4562af09e2 100644 --- a/actions/setup/js/parse_mcp_gateway_log.test.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.test.cjs @@ -1,7 +1,7 @@ // @ts-check /// -const { generateGatewayLogSummary, generatePlainTextGatewaySummary, generatePlainTextLegacySummary } = require("./parse_mcp_gateway_log.cjs"); +const { generateGatewayLogSummary, generatePlainTextGatewaySummary, generatePlainTextLegacySummary, printAllGatewayFiles } = require("./parse_mcp_gateway_log.cjs"); describe("parse_mcp_gateway_log", () => { // Note: The main() function now checks for gateway.md first before falling back to log files. @@ -322,4 +322,198 @@ Some content here.`; } }); }); + + describe("printAllGatewayFiles", () => { + const fs = require("fs"); + const path = require("path"); + const os = require("os"); + + test("prints all files in gateway directories with content", () => { + // Create a temporary directory structure + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-")); + const logsDir = path.join(tmpDir, "mcp-logs"); + const configDir = path.join(tmpDir, "mcp-config"); + + try { + // Create directory structure + fs.mkdirSync(logsDir, { recursive: true }); + fs.mkdirSync(configDir, { recursive: true }); + + // Create test files + fs.writeFileSync(path.join(logsDir, "gateway.log"), "Gateway log content\nLine 2"); + fs.writeFileSync(path.join(logsDir, "stderr.log"), "Error message"); + fs.writeFileSync(path.join(logsDir, "gateway.md"), "# Gateway Summary"); + fs.writeFileSync(path.join(configDir, "gateway-output.json"), '{"status": "ok"}'); + fs.writeFileSync(path.join(configDir, "config.toml"), "[gateway]\nport = 8080"); + + // Mock core + const mockCore = { info: vi.fn() }; + global.core = mockCore; + + // Mock fs to redirect to our test directories + const originalExistsSync = fs.existsSync; + const originalReaddirSync = fs.readdirSync; + const originalStatSync = fs.statSync; + const originalReadFileSync = fs.readFileSync; + + fs.existsSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return true; + if (filepath === "/tmp/gh-aw/mcp-config") return true; + return originalExistsSync(filepath); + }); + + fs.readdirSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return originalReaddirSync(logsDir); + if (filepath === "/tmp/gh-aw/mcp-config") return originalReaddirSync(configDir); + return originalReaddirSync(filepath); + }); + + fs.statSync = vi.fn(filepath => { + if (filepath.startsWith("/tmp/gh-aw/mcp-logs/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); + return originalStatSync(path.join(logsDir, filename)); + } + if (filepath.startsWith("/tmp/gh-aw/mcp-config/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-config/", ""); + return originalStatSync(path.join(configDir, filename)); + } + return originalStatSync(filepath); + }); + + fs.readFileSync = vi.fn((filepath, encoding) => { + if (filepath.startsWith("/tmp/gh-aw/mcp-logs/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); + return originalReadFileSync(path.join(logsDir, filename), encoding); + } + if (filepath.startsWith("/tmp/gh-aw/mcp-config/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-config/", ""); + return originalReadFileSync(path.join(configDir, filename), encoding); + } + return originalReadFileSync(filepath, encoding); + }); + + // Call the function + printAllGatewayFiles(); + + // Verify the output + const infoMessages = mockCore.info.mock.calls.map(call => call[0]); + const allOutput = infoMessages.join("\n"); + + // Check header + expect(allOutput).toContain("=== Listing All Gateway-Related Files ==="); + expect(allOutput).toContain("=== End of Gateway-Related Files ==="); + + // Check directories are listed + expect(allOutput).toContain("Directory: /tmp/gh-aw/mcp-logs"); + expect(allOutput).toContain("Directory: /tmp/gh-aw/mcp-config"); + + // Check files are listed + expect(allOutput).toContain("gateway.log"); + expect(allOutput).toContain("stderr.log"); + expect(allOutput).toContain("gateway.md"); + expect(allOutput).toContain("gateway-output.json"); + expect(allOutput).toContain("config.toml"); + + // Check file contents are printed + expect(allOutput).toContain("Gateway log content"); + expect(allOutput).toContain("Error message"); + expect(allOutput).toContain("# Gateway Summary"); + expect(allOutput).toContain('{"status": "ok"}'); + expect(allOutput).toContain("port = 8080"); + + // Restore original functions + fs.existsSync = originalExistsSync; + fs.readdirSync = originalReaddirSync; + fs.statSync = originalStatSync; + fs.readFileSync = originalReadFileSync; + delete global.core; + } finally { + // Clean up test files + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + + test("handles missing directories gracefully", () => { + // Mock core + const mockCore = { info: vi.fn() }; + global.core = mockCore; + + // Mock fs to return false for directory existence + const fs = require("fs"); + const originalExistsSync = fs.existsSync; + + fs.existsSync = vi.fn(() => false); + + try { + // Call the function + printAllGatewayFiles(); + + // Verify the output + const infoMessages = mockCore.info.mock.calls.map(call => call[0]); + const allOutput = infoMessages.join("\n"); + + // Check that it reports missing directories + expect(allOutput).toContain("Directory does not exist: /tmp/gh-aw/mcp-logs"); + expect(allOutput).toContain("Directory does not exist: /tmp/gh-aw/mcp-config"); + } finally { + // Restore original functions + fs.existsSync = originalExistsSync; + delete global.core; + } + }); + + test("handles empty directories", () => { + const fs = require("fs"); + const path = require("path"); + const os = require("os"); + + // Create empty directories + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-")); + const logsDir = path.join(tmpDir, "mcp-logs"); + const configDir = path.join(tmpDir, "mcp-config"); + + try { + fs.mkdirSync(logsDir, { recursive: true }); + fs.mkdirSync(configDir, { recursive: true }); + + // Mock core + const mockCore = { info: vi.fn() }; + global.core = mockCore; + + // Mock fs to use our test directories + const originalExistsSync = fs.existsSync; + const originalReaddirSync = fs.readdirSync; + + fs.existsSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return true; + if (filepath === "/tmp/gh-aw/mcp-config") return true; + return originalExistsSync(filepath); + }); + + fs.readdirSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return originalReaddirSync(logsDir); + if (filepath === "/tmp/gh-aw/mcp-config") return originalReaddirSync(configDir); + return originalReaddirSync(filepath); + }); + + // Call the function + printAllGatewayFiles(); + + // Verify the output + const infoMessages = mockCore.info.mock.calls.map(call => call[0]); + const allOutput = infoMessages.join("\n"); + + // Check that it reports empty directories + expect(allOutput).toContain("(empty directory)"); + + // Restore original functions + fs.existsSync = originalExistsSync; + fs.readdirSync = originalReaddirSync; + delete global.core; + } finally { + // Clean up + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); + }); }); From 804c8fd33db53ca6d51872c9dac0216d7ad8f930 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:04:33 +0000 Subject: [PATCH 3/4] Exclude config directory from gateway files output - Modified printAllGatewayFiles() to only scan /tmp/gh-aw/mcp-logs - Removed /tmp/gh-aw/mcp-config from scanned directories - Updated tests to reflect that only logs directory is rendered - All 19 tests passing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/parse_mcp_gateway_log.cjs | 2 +- .../setup/js/parse_mcp_gateway_log.test.cjs | 24 ------------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/actions/setup/js/parse_mcp_gateway_log.cjs b/actions/setup/js/parse_mcp_gateway_log.cjs index ff99b7fc54..925c81ad44 100644 --- a/actions/setup/js/parse_mcp_gateway_log.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.cjs @@ -19,7 +19,7 @@ function printAllGatewayFiles() { core.info("=== Listing All Gateway-Related Files ==="); core.info(""); - const gatewayDirs = ["/tmp/gh-aw/mcp-logs", "/tmp/gh-aw/mcp-config"]; + const gatewayDirs = ["/tmp/gh-aw/mcp-logs"]; for (const dir of gatewayDirs) { if (!fs.existsSync(dir)) { diff --git a/actions/setup/js/parse_mcp_gateway_log.test.cjs b/actions/setup/js/parse_mcp_gateway_log.test.cjs index 4562af09e2..c412738f4c 100644 --- a/actions/setup/js/parse_mcp_gateway_log.test.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.test.cjs @@ -332,19 +332,15 @@ Some content here.`; // Create a temporary directory structure const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-")); const logsDir = path.join(tmpDir, "mcp-logs"); - const configDir = path.join(tmpDir, "mcp-config"); try { // Create directory structure fs.mkdirSync(logsDir, { recursive: true }); - fs.mkdirSync(configDir, { recursive: true }); // Create test files fs.writeFileSync(path.join(logsDir, "gateway.log"), "Gateway log content\nLine 2"); fs.writeFileSync(path.join(logsDir, "stderr.log"), "Error message"); fs.writeFileSync(path.join(logsDir, "gateway.md"), "# Gateway Summary"); - fs.writeFileSync(path.join(configDir, "gateway-output.json"), '{"status": "ok"}'); - fs.writeFileSync(path.join(configDir, "config.toml"), "[gateway]\nport = 8080"); // Mock core const mockCore = { info: vi.fn() }; @@ -358,13 +354,11 @@ Some content here.`; fs.existsSync = vi.fn(filepath => { if (filepath === "/tmp/gh-aw/mcp-logs") return true; - if (filepath === "/tmp/gh-aw/mcp-config") return true; return originalExistsSync(filepath); }); fs.readdirSync = vi.fn(filepath => { if (filepath === "/tmp/gh-aw/mcp-logs") return originalReaddirSync(logsDir); - if (filepath === "/tmp/gh-aw/mcp-config") return originalReaddirSync(configDir); return originalReaddirSync(filepath); }); @@ -373,10 +367,6 @@ Some content here.`; const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); return originalStatSync(path.join(logsDir, filename)); } - if (filepath.startsWith("/tmp/gh-aw/mcp-config/")) { - const filename = filepath.replace("/tmp/gh-aw/mcp-config/", ""); - return originalStatSync(path.join(configDir, filename)); - } return originalStatSync(filepath); }); @@ -385,10 +375,6 @@ Some content here.`; const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); return originalReadFileSync(path.join(logsDir, filename), encoding); } - if (filepath.startsWith("/tmp/gh-aw/mcp-config/")) { - const filename = filepath.replace("/tmp/gh-aw/mcp-config/", ""); - return originalReadFileSync(path.join(configDir, filename), encoding); - } return originalReadFileSync(filepath, encoding); }); @@ -405,21 +391,16 @@ Some content here.`; // Check directories are listed expect(allOutput).toContain("Directory: /tmp/gh-aw/mcp-logs"); - expect(allOutput).toContain("Directory: /tmp/gh-aw/mcp-config"); // Check files are listed expect(allOutput).toContain("gateway.log"); expect(allOutput).toContain("stderr.log"); expect(allOutput).toContain("gateway.md"); - expect(allOutput).toContain("gateway-output.json"); - expect(allOutput).toContain("config.toml"); // Check file contents are printed expect(allOutput).toContain("Gateway log content"); expect(allOutput).toContain("Error message"); expect(allOutput).toContain("# Gateway Summary"); - expect(allOutput).toContain('{"status": "ok"}'); - expect(allOutput).toContain("port = 8080"); // Restore original functions fs.existsSync = originalExistsSync; @@ -454,7 +435,6 @@ Some content here.`; // Check that it reports missing directories expect(allOutput).toContain("Directory does not exist: /tmp/gh-aw/mcp-logs"); - expect(allOutput).toContain("Directory does not exist: /tmp/gh-aw/mcp-config"); } finally { // Restore original functions fs.existsSync = originalExistsSync; @@ -470,11 +450,9 @@ Some content here.`; // Create empty directories const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-")); const logsDir = path.join(tmpDir, "mcp-logs"); - const configDir = path.join(tmpDir, "mcp-config"); try { fs.mkdirSync(logsDir, { recursive: true }); - fs.mkdirSync(configDir, { recursive: true }); // Mock core const mockCore = { info: vi.fn() }; @@ -486,13 +464,11 @@ Some content here.`; fs.existsSync = vi.fn(filepath => { if (filepath === "/tmp/gh-aw/mcp-logs") return true; - if (filepath === "/tmp/gh-aw/mcp-config") return true; return originalExistsSync(filepath); }); fs.readdirSync = vi.fn(filepath => { if (filepath === "/tmp/gh-aw/mcp-logs") return originalReaddirSync(logsDir); - if (filepath === "/tmp/gh-aw/mcp-config") return originalReaddirSync(configDir); return originalReaddirSync(filepath); }); From 5e7ce3b7a418b5becc929cac8fde4b2327165150 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:12:02 +0000 Subject: [PATCH 4/4] Limit file content output to 10KB per file - Modified printAllGatewayFiles() to truncate file content at 10KB - Files larger than 10KB now show first 10KB followed by "..." and truncation message - Added test for truncation behavior with 15KB file - Config directory already excluded (no change needed) - All 20 tests passing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/js/parse_mcp_gateway_log.cjs | 10 ++- .../setup/js/parse_mcp_gateway_log.test.cjs | 77 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/actions/setup/js/parse_mcp_gateway_log.cjs b/actions/setup/js/parse_mcp_gateway_log.cjs index 925c81ad44..91e9de17b0 100644 --- a/actions/setup/js/parse_mcp_gateway_log.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.cjs @@ -52,12 +52,20 @@ function printAllGatewayFiles() { // Max 1MB try { const content = fs.readFileSync(filePath, "utf8"); + const maxOutputBytes = 10 * 1024; // 10KB limit per file + const contentToDisplay = content.length > maxOutputBytes ? content.substring(0, maxOutputBytes) : content; + const wasTruncated = content.length > maxOutputBytes; + core.info(` --- Content of ${file} ---`); // Split content into lines and prefix each line for readability - const lines = content.split("\n"); + const lines = contentToDisplay.split("\n"); for (const line of lines) { core.info(` ${line}`); } + if (wasTruncated) { + core.info(` ...`); + core.info(` (truncated, showing first ${maxOutputBytes} bytes of ${content.length} total)`); + } core.info(` --- End of ${file} ---`); } catch (/** @type {unknown} */ readError) { const errorMessage = readError instanceof Error ? readError.message : String(readError); diff --git a/actions/setup/js/parse_mcp_gateway_log.test.cjs b/actions/setup/js/parse_mcp_gateway_log.test.cjs index c412738f4c..e3b3480386 100644 --- a/actions/setup/js/parse_mcp_gateway_log.test.cjs +++ b/actions/setup/js/parse_mcp_gateway_log.test.cjs @@ -491,5 +491,82 @@ Some content here.`; fs.rmSync(tmpDir, { recursive: true, force: true }); } }); + + test("truncates files larger than 10KB", () => { + const fs = require("fs"); + const path = require("path"); + const os = require("os"); + + // Create test directory + const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-test-")); + const logsDir = path.join(tmpDir, "mcp-logs"); + + try { + fs.mkdirSync(logsDir, { recursive: true }); + + // Create a large file (15KB) + const largeContent = "A".repeat(15 * 1024); + fs.writeFileSync(path.join(logsDir, "large.log"), largeContent); + + // Mock core + const mockCore = { info: vi.fn() }; + global.core = mockCore; + + // Mock fs to use our test directories + const originalExistsSync = fs.existsSync; + const originalReaddirSync = fs.readdirSync; + const originalStatSync = fs.statSync; + const originalReadFileSync = fs.readFileSync; + + fs.existsSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return true; + return originalExistsSync(filepath); + }); + + fs.readdirSync = vi.fn(filepath => { + if (filepath === "/tmp/gh-aw/mcp-logs") return originalReaddirSync(logsDir); + return originalReaddirSync(filepath); + }); + + fs.statSync = vi.fn(filepath => { + if (filepath.startsWith("/tmp/gh-aw/mcp-logs/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); + return originalStatSync(path.join(logsDir, filename)); + } + return originalStatSync(filepath); + }); + + fs.readFileSync = vi.fn((filepath, encoding) => { + if (filepath.startsWith("/tmp/gh-aw/mcp-logs/")) { + const filename = filepath.replace("/tmp/gh-aw/mcp-logs/", ""); + return originalReadFileSync(path.join(logsDir, filename), encoding); + } + return originalReadFileSync(filepath, encoding); + }); + + // Call the function + printAllGatewayFiles(); + + // Verify the output + const infoMessages = mockCore.info.mock.calls.map(call => call[0]); + const allOutput = infoMessages.join("\n"); + + // Check that file was truncated + expect(allOutput).toContain("..."); + expect(allOutput).toContain("truncated"); + expect(allOutput).toContain("10240 bytes"); + expect(allOutput).toContain("15360 total"); + + // Restore original functions + fs.existsSync = originalExistsSync; + fs.readdirSync = originalReaddirSync; + fs.statSync = originalStatSync; + fs.readFileSync = originalReadFileSync; + delete global.core; + } finally { + // Clean up + fs.rmSync(tmpDir, { recursive: true, force: true }); + } + }); }); });