From cb9db72362e4f14023da8f7a65e579daa6e30b0c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 01:50:26 +0000 Subject: [PATCH 1/3] Initial plan From b4535db7fcd850d31a7635b04a2f0ea6258c4a23 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 02:18:16 +0000 Subject: [PATCH 2/3] Add GetSafeInputsBootstrapScript and write safe_inputs_bootstrap.cjs file - Add GetSafeInputsBootstrapScript() function in pkg/workflow/js.go to return the embedded bootstrap script - Add file writing step for safe_inputs_bootstrap.cjs in pkg/workflow/mcp_servers.go - Recompile all workflow files to include the missing bootstrap file - Fixes "Cannot find module './safe_inputs_bootstrap.cjs'" error in safe-inputs workflows Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../copilot-pr-merged-report.lock.yml | 29 +++++++++++++++++++ .../daily-performance-summary.lock.yml | 29 +++++++++++++++++++ .github/workflows/dev.lock.yml | 29 +++++++++++++++++++ .github/workflows/release.lock.yml | 6 ++-- .../smoke-copilot-no-firewall.lock.yml | 29 +++++++++++++++++++ .../smoke-copilot-playwright.lock.yml | 29 +++++++++++++++++++ .../smoke-copilot-safe-inputs.lock.yml | 29 +++++++++++++++++++ .github/workflows/smoke-copilot.lock.yml | 29 +++++++++++++++++++ .../workflows/test-python-safe-input.lock.yml | 29 +++++++++++++++++++ pkg/workflow/js.go | 5 ++++ pkg/workflow/mcp_servers.go | 6 ++++ 11 files changed, 246 insertions(+), 3 deletions(-) diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index a5e07a7c05..07e7b163c2 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -2890,6 +2890,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml index c444aeafe8..bf1b549168 100644 --- a/.github/workflows/daily-performance-summary.lock.yml +++ b/.github/workflows/daily-performance-summary.lock.yml @@ -3464,6 +3464,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 5b8d5f427b..7a1f4b23d2 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -1385,6 +1385,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 25f1d66a81..adc2239097 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6209,19 +6209,19 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 with: artifact-name: sbom.cdx.json format: cyclonedx-json output-file: sbom.cdx.json - name: Upload SBOM artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: sbom-artifacts path: | diff --git a/.github/workflows/smoke-copilot-no-firewall.lock.yml b/.github/workflows/smoke-copilot-no-firewall.lock.yml index 9cfdf4a7b2..b6230463ed 100644 --- a/.github/workflows/smoke-copilot-no-firewall.lock.yml +++ b/.github/workflows/smoke-copilot-no-firewall.lock.yml @@ -4394,6 +4394,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/smoke-copilot-playwright.lock.yml b/.github/workflows/smoke-copilot-playwright.lock.yml index 78c5b4f3a1..ed9313add4 100644 --- a/.github/workflows/smoke-copilot-playwright.lock.yml +++ b/.github/workflows/smoke-copilot-playwright.lock.yml @@ -4393,6 +4393,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/smoke-copilot-safe-inputs.lock.yml b/.github/workflows/smoke-copilot-safe-inputs.lock.yml index 6bbd01b8f3..52b6856904 100644 --- a/.github/workflows/smoke-copilot-safe-inputs.lock.yml +++ b/.github/workflows/smoke-copilot-safe-inputs.lock.yml @@ -4293,6 +4293,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 813fb7eec7..fd1727fe13 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -4308,6 +4308,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/.github/workflows/test-python-safe-input.lock.yml b/.github/workflows/test-python-safe-input.lock.yml index 94d411cff7..f568fbf947 100644 --- a/.github/workflows/test-python-safe-input.lock.yml +++ b/.github/workflows/test-python-safe-input.lock.yml @@ -2646,6 +2646,35 @@ jobs: validateRequiredFields, }; EOF_VALIDATION + cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP' + const path = require("path"); + const fs = require("fs"); + const { loadConfig } = require("./safe_inputs_config_loader.cjs"); + const { loadToolHandlers } = require("./mcp_server_core.cjs"); + function bootstrapSafeInputsServer(configPath, logger) { + logger.debug(`Loading safe-inputs configuration from: ${configPath}`); + const config = loadConfig(configPath); + const basePath = path.dirname(configPath); + logger.debug(`Base path for handlers: ${basePath}`); + logger.debug(`Tools to load: ${config.tools.length}`); + const tools = loadToolHandlers(logger, config.tools, basePath); + return { config, basePath, tools }; + } + function cleanupConfigFile(configPath, logger) { + try { + if (fs.existsSync(configPath)) { + fs.unlinkSync(configPath); + logger.debug(`Deleted configuration file: ${configPath}`); + } + } catch (error) { + logger.debugError(`Warning: Could not delete configuration file: `, error); + } + } + module.exports = { + bootstrapSafeInputsServer, + cleanupConfigFile, + }; + EOF_BOOTSTRAP cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER' const { createServer, registerTool, start } = require("./mcp_server_core.cjs"); const { loadConfig } = require("./safe_inputs_config_loader.cjs"); diff --git a/pkg/workflow/js.go b/pkg/workflow/js.go index 0785c452a2..6427e0be8c 100644 --- a/pkg/workflow/js.go +++ b/pkg/workflow/js.go @@ -826,6 +826,11 @@ func GetSafeInputsToolFactoryScript() string { return safeInputsToolFactoryScript } +// GetSafeInputsBootstrapScript returns the embedded safe_inputs_bootstrap.cjs script +func GetSafeInputsBootstrapScript() string { + return safeInputsBootstrapScript +} + // GetSafeInputsValidationScript returns the embedded safe_inputs_validation.cjs script func GetSafeInputsValidationScript() string { return safeInputsValidationScript diff --git a/pkg/workflow/mcp_servers.go b/pkg/workflow/mcp_servers.go index d6b91c6ed7..38edb0a696 100644 --- a/pkg/workflow/mcp_servers.go +++ b/pkg/workflow/mcp_servers.go @@ -339,6 +339,12 @@ func (c *Compiler) generateMCPSetup(yaml *strings.Builder, tools map[string]any, } yaml.WriteString(" EOF_VALIDATION\n") + yaml.WriteString(" cat > /tmp/gh-aw/safe-inputs/safe_inputs_bootstrap.cjs << 'EOF_BOOTSTRAP'\n") + for _, line := range FormatJavaScriptForYAML(GetSafeInputsBootstrapScript()) { + yaml.WriteString(line) + } + yaml.WriteString(" EOF_BOOTSTRAP\n") + // Write safe-inputs MCP server main module yaml.WriteString(" cat > /tmp/gh-aw/safe-inputs/safe_inputs_mcp_server.cjs << 'EOF_SAFE_INPUTS_SERVER'\n") for _, line := range FormatJavaScriptForYAML(GetSafeInputsMCPServerScript()) { From 35bc323746a7d352947f2ec72de8d7e5cea92f12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 8 Dec 2025 02:24:49 +0000 Subject: [PATCH 3/3] Add changeset: fix missing safe-inputs bootstrap [skip-ci] --- .../patch-fix-missing-safe-inputs-bootstrap.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .changeset/patch-fix-missing-safe-inputs-bootstrap.md diff --git a/.changeset/patch-fix-missing-safe-inputs-bootstrap.md b/.changeset/patch-fix-missing-safe-inputs-bootstrap.md new file mode 100644 index 0000000000..0ff7d64a82 --- /dev/null +++ b/.changeset/patch-fix-missing-safe-inputs-bootstrap.md @@ -0,0 +1,12 @@ +--- +"gh-aw": patch +--- + +Add missing agent bootstrap `safe_inputs_bootstrap.cjs` support. + +The pull request fixes a bug where the embedded safe inputs bootstrap script +was not exposed via a getter and therefore not written to the +`/tmp/gh-aw/safe-inputs/` directory. This change adds the getter and the +file-writing step so workflows depending on `safe_inputs_bootstrap.cjs` can +load it correctly. +