diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index c27a98d3a77..b388c44ddb2 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -4524,7 +4524,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/ai-triage-campaign.lock.yml b/.github/workflows/ai-triage-campaign.lock.yml index 9d841a472f3..65ff697881c 100644 --- a/.github/workflows/ai-triage-campaign.lock.yml +++ b/.github/workflows/ai-triage-campaign.lock.yml @@ -3429,7 +3429,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 4da5ec52a05..c4719f4c766 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -5090,7 +5090,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml index 473d35dfdcd..517a610d916 100644 --- a/.github/workflows/artifacts-summary.lock.yml +++ b/.github/workflows/artifacts-summary.lock.yml @@ -3587,7 +3587,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index bf7d5a9419c..b2a39e2db44 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -5144,7 +5144,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml index 7b1acc4d92b..b1e681ba393 100644 --- a/.github/workflows/blog-auditor.lock.yml +++ b/.github/workflows/blog-auditor.lock.yml @@ -4206,7 +4206,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index ca8481870bd..aed59794d88 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -4880,7 +4880,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/breaking-change-checker.lock.yml b/.github/workflows/breaking-change-checker.lock.yml index 3f275d52bba..45d20196ce7 100644 --- a/.github/workflows/breaking-change-checker.lock.yml +++ b/.github/workflows/breaking-change-checker.lock.yml @@ -3671,7 +3671,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index 2d921a104f6..f241d803228 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -4557,7 +4557,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 44d26c23eb2..eb423527a84 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -4366,7 +4366,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml index 176193dbb3a..9cf90b9f5de 100644 --- a/.github/workflows/cli-consistency-checker.lock.yml +++ b/.github/workflows/cli-consistency-checker.lock.yml @@ -3668,7 +3668,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index d1e80a3919d..5db9452d396 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -4155,7 +4155,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 2482aa5b0db..bfbeda05264 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -5622,7 +5622,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/close-old-discussions.lock.yml b/.github/workflows/close-old-discussions.lock.yml index 55cf450dbd1..7a328a307da 100644 --- a/.github/workflows/close-old-discussions.lock.yml +++ b/.github/workflows/close-old-discussions.lock.yml @@ -3762,7 +3762,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/commit-changes-analyzer.lock.yml b/.github/workflows/commit-changes-analyzer.lock.yml index d268f0fd1d7..fe7b1703949 100644 --- a/.github/workflows/commit-changes-analyzer.lock.yml +++ b/.github/workflows/commit-changes-analyzer.lock.yml @@ -4087,7 +4087,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/copilot-agent-analysis.lock.yml b/.github/workflows/copilot-agent-analysis.lock.yml index aa3d0d71095..7c4d5466cd2 100644 --- a/.github/workflows/copilot-agent-analysis.lock.yml +++ b/.github/workflows/copilot-agent-analysis.lock.yml @@ -4831,7 +4831,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index 1d7fab51637..e856ac38ef3 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -5109,7 +5109,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/copilot-pr-nlp-analysis.lock.yml b/.github/workflows/copilot-pr-nlp-analysis.lock.yml index 2282a243b92..5a31e4a7778 100644 --- a/.github/workflows/copilot-pr-nlp-analysis.lock.yml +++ b/.github/workflows/copilot-pr-nlp-analysis.lock.yml @@ -5208,7 +5208,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/copilot-pr-prompt-analysis.lock.yml b/.github/workflows/copilot-pr-prompt-analysis.lock.yml index a2668e3bb9a..25746c80ecc 100644 --- a/.github/workflows/copilot-pr-prompt-analysis.lock.yml +++ b/.github/workflows/copilot-pr-prompt-analysis.lock.yml @@ -4230,7 +4230,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/copilot-session-insights.lock.yml b/.github/workflows/copilot-session-insights.lock.yml index 583a9ef314a..9d05d312fca 100644 --- a/.github/workflows/copilot-session-insights.lock.yml +++ b/.github/workflows/copilot-session-insights.lock.yml @@ -6241,7 +6241,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 90258a87b8e..4ed08f29a7d 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -5224,7 +5224,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-assign-issue-to-user.lock.yml b/.github/workflows/daily-assign-issue-to-user.lock.yml index b772d8c2a09..30058bdf76d 100644 --- a/.github/workflows/daily-assign-issue-to-user.lock.yml +++ b/.github/workflows/daily-assign-issue-to-user.lock.yml @@ -3865,7 +3865,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-code-metrics.lock.yml b/.github/workflows/daily-code-metrics.lock.yml index ad209e43054..b1ed60659ad 100644 --- a/.github/workflows/daily-code-metrics.lock.yml +++ b/.github/workflows/daily-code-metrics.lock.yml @@ -5282,7 +5282,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index 0a004415659..d838fdec466 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -5373,7 +5373,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-doc-updater.lock.yml b/.github/workflows/daily-doc-updater.lock.yml index 5c6d9e80184..1153e8d58be 100644 --- a/.github/workflows/daily-doc-updater.lock.yml +++ b/.github/workflows/daily-doc-updater.lock.yml @@ -3878,7 +3878,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 53d43b1f082..6cc3b928fa9 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -3957,7 +3957,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index 0801d6f9ea3..19c99f956dd 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -3911,7 +3911,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml index 84ff7a3e60a..204b13b2c4d 100644 --- a/.github/workflows/daily-firewall-report.lock.yml +++ b/.github/workflows/daily-firewall-report.lock.yml @@ -4655,7 +4655,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-issues-report.lock.yml b/.github/workflows/daily-issues-report.lock.yml index 0dd48c06a6f..0318efd59d6 100644 --- a/.github/workflows/daily-issues-report.lock.yml +++ b/.github/workflows/daily-issues-report.lock.yml @@ -5494,7 +5494,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-malicious-code-scan.lock.yml b/.github/workflows/daily-malicious-code-scan.lock.yml index 35a5643dda3..c13fa134d64 100644 --- a/.github/workflows/daily-malicious-code-scan.lock.yml +++ b/.github/workflows/daily-malicious-code-scan.lock.yml @@ -3901,7 +3901,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-multi-device-docs-tester.lock.yml b/.github/workflows/daily-multi-device-docs-tester.lock.yml index a6fb17abf14..59b949417a5 100644 --- a/.github/workflows/daily-multi-device-docs-tester.lock.yml +++ b/.github/workflows/daily-multi-device-docs-tester.lock.yml @@ -3789,7 +3789,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index c4bea86a6f4..9634088aa93 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -5132,7 +5132,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml index d3bf9bd47f0..f765c489ecd 100644 --- a/.github/workflows/daily-performance-summary.lock.yml +++ b/.github/workflows/daily-performance-summary.lock.yml @@ -6725,7 +6725,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-repo-chronicle.lock.yml b/.github/workflows/daily-repo-chronicle.lock.yml index 84da0bd3f61..cdcdb92a199 100644 --- a/.github/workflows/daily-repo-chronicle.lock.yml +++ b/.github/workflows/daily-repo-chronicle.lock.yml @@ -4806,7 +4806,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/daily-workflow-updater.lock.yml b/.github/workflows/daily-workflow-updater.lock.yml index 53327a16df9..98e3526c939 100644 --- a/.github/workflows/daily-workflow-updater.lock.yml +++ b/.github/workflows/daily-workflow-updater.lock.yml @@ -3593,7 +3593,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 467be715950..66564fb1773 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -4373,7 +4373,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/dependabot-go-checker.lock.yml b/.github/workflows/dependabot-go-checker.lock.yml index d1687bce3a1..d305f786e16 100644 --- a/.github/workflows/dependabot-go-checker.lock.yml +++ b/.github/workflows/dependabot-go-checker.lock.yml @@ -4201,7 +4201,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 6cdb809562c..0795adab4cf 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -4134,7 +4134,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index d1cc63e5d73..583a04ebeda 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -4378,7 +4378,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 37bfe5773b0..1ce62618f0e 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -5033,7 +5033,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/dictation-prompt.lock.yml b/.github/workflows/dictation-prompt.lock.yml index 83c7ed57a47..f3a89dc41f7 100644 --- a/.github/workflows/dictation-prompt.lock.yml +++ b/.github/workflows/dictation-prompt.lock.yml @@ -3541,7 +3541,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/docs-noob-tester.lock.yml b/.github/workflows/docs-noob-tester.lock.yml index 76e4261b730..97a3d1f36bc 100644 --- a/.github/workflows/docs-noob-tester.lock.yml +++ b/.github/workflows/docs-noob-tester.lock.yml @@ -3679,7 +3679,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 1cb480bed3c..53d051b7662 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -3746,7 +3746,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml index 6176aaa4b3c..bdc1b802166 100644 --- a/.github/workflows/example-workflow-analyzer.lock.yml +++ b/.github/workflows/example-workflow-analyzer.lock.yml @@ -3594,7 +3594,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/github-mcp-structural-analysis.lock.yml b/.github/workflows/github-mcp-structural-analysis.lock.yml index 467e4d19843..e654ee32ed6 100644 --- a/.github/workflows/github-mcp-structural-analysis.lock.yml +++ b/.github/workflows/github-mcp-structural-analysis.lock.yml @@ -4960,7 +4960,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/github-mcp-tools-report.lock.yml b/.github/workflows/github-mcp-tools-report.lock.yml index c226488822e..4bf7dc54ef8 100644 --- a/.github/workflows/github-mcp-tools-report.lock.yml +++ b/.github/workflows/github-mcp-tools-report.lock.yml @@ -4736,7 +4736,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 85b0645f486..3d7d604ee04 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -4699,7 +4699,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml index ea2fad7b92a..8e5168d159c 100644 --- a/.github/workflows/go-fan.lock.yml +++ b/.github/workflows/go-fan.lock.yml @@ -4277,7 +4277,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/go-logger.lock.yml b/.github/workflows/go-logger.lock.yml index c5d38a0d7b7..2ecc4f77ede 100644 --- a/.github/workflows/go-logger.lock.yml +++ b/.github/workflows/go-logger.lock.yml @@ -4042,7 +4042,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/go-pattern-detector.lock.yml b/.github/workflows/go-pattern-detector.lock.yml index 18c9fa1428c..2763d2bdfae 100644 --- a/.github/workflows/go-pattern-detector.lock.yml +++ b/.github/workflows/go-pattern-detector.lock.yml @@ -3793,7 +3793,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 60ae919770b..484717d03f9 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -5029,7 +5029,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/instructions-janitor.lock.yml b/.github/workflows/instructions-janitor.lock.yml index c33350cc920..3fc8fbe4418 100644 --- a/.github/workflows/instructions-janitor.lock.yml +++ b/.github/workflows/instructions-janitor.lock.yml @@ -3807,7 +3807,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/issue-arborist.lock.yml b/.github/workflows/issue-arborist.lock.yml index bcb02ee42fb..ed696ef3a94 100644 --- a/.github/workflows/issue-arborist.lock.yml +++ b/.github/workflows/issue-arborist.lock.yml @@ -3755,7 +3755,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index bb23081b4f2..b23c531d207 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -4605,7 +4605,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 6c952ac7dfe..e64769c98db 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -4301,7 +4301,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml index ca383732bb6..5c48dc39aaf 100644 --- a/.github/workflows/issue-triage-agent.lock.yml +++ b/.github/workflows/issue-triage-agent.lock.yml @@ -3773,7 +3773,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/layout-spec-maintainer.lock.yml b/.github/workflows/layout-spec-maintainer.lock.yml index ec1c77aa228..feb6ef4b8ed 100644 --- a/.github/workflows/layout-spec-maintainer.lock.yml +++ b/.github/workflows/layout-spec-maintainer.lock.yml @@ -498,6 +498,8 @@ jobs: env: GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs GH_AW_SAFE_OUTPUTS: /tmp/gh-aw/safeoutputs/outputs.jsonl + GH_AW_SAFE_OUTPUTS_CONFIG_PATH: /tmp/gh-aw/safeoutputs/config.json + GH_AW_SAFE_OUTPUTS_TOOLS_PATH: /tmp/gh-aw/safeoutputs/tools.json outputs: has_patch: ${{ steps.collect_output.outputs.has_patch }} model: ${{ steps.generate_aw_info.outputs.model }} @@ -616,6 +618,7 @@ jobs: - name: Write Safe Outputs Config run: | mkdir -p /tmp/gh-aw/safeoutputs + mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs cat > /tmp/gh-aw/safeoutputs/config.json << 'EOF' {"create_pull_request":{},"missing_tool":{"max":0},"noop":{"max":1}} EOF @@ -767,50 +770,347 @@ jobs: EOF - name: Write Safe Outputs JavaScript Files run: | - cat > /tmp/gh-aw/safeoutputs/mcp-server.cjs << 'EOF' + cat > /tmp/gh-aw/safeoutputs/estimate_tokens.cjs << 'EOF_ESTIMATE_TOKENS' + function estimateTokens(text) { + if (!text) return 0; + return Math.ceil(text.length / 4); + } + module.exports = { + estimateTokens, + }; + EOF_ESTIMATE_TOKENS + cat > /tmp/gh-aw/safeoutputs/generate_compact_schema.cjs << 'EOF_GENERATE_COMPACT_SCHEMA' + function generateCompactSchema(content) { + try { + const parsed = JSON.parse(content); + if (Array.isArray(parsed)) { + if (parsed.length === 0) { + return "[]"; + } + const firstItem = parsed[0]; + if (typeof firstItem === "object" && firstItem !== null) { + const keys = Object.keys(firstItem); + return `[{${keys.join(", ")}}] (${parsed.length} items)`; + } + return `[${typeof firstItem}] (${parsed.length} items)`; + } else if (typeof parsed === "object" && parsed !== null) { + const keys = Object.keys(parsed); + if (keys.length > 10) { + return `{${keys.slice(0, 10).join(", ")}, ...} (${keys.length} keys)`; + } + return `{${keys.join(", ")}}`; + } + return `${typeof parsed}`; + } catch { + return "text content"; + } + } + module.exports = { + generateCompactSchema, + }; + EOF_GENERATE_COMPACT_SCHEMA + cat > /tmp/gh-aw/safeoutputs/generate_git_patch.cjs << 'EOF_GENERATE_GIT_PATCH' const fs = require("fs"); const path = require("path"); - const { execFile, execSync } = require("child_process"); - const os = require("os"); - const crypto = require("crypto"); - class ReadBuffer { - constructor() { - this._buffer = null; - } - append(chunk) { - this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk; + const { execSync } = require("child_process"); + const { getBaseBranch } = require("./get_base_branch.cjs"); + function generateGitPatch(branchName) { + const patchPath = "/tmp/gh-aw/aw.patch"; + const cwd = process.env.GITHUB_WORKSPACE || process.cwd(); + const defaultBranch = process.env.DEFAULT_BRANCH || getBaseBranch(); + const githubSha = process.env.GITHUB_SHA; + const patchDir = path.dirname(patchPath); + if (!fs.existsSync(patchDir)) { + fs.mkdirSync(patchDir, { recursive: true }); } - readMessage() { - if (!this._buffer) { - return null; - } - const index = this._buffer.indexOf("\n"); - if (index === -1) { - return null; + let patchGenerated = false; + let errorMessage = null; + try { + if (branchName) { + try { + execSync(`git show-ref --verify --quiet refs/heads/${branchName}`, { cwd, encoding: "utf8" }); + let baseRef; + try { + execSync(`git show-ref --verify --quiet refs/remotes/origin/${branchName}`, { cwd, encoding: "utf8" }); + baseRef = `origin/${branchName}`; + } catch { + execSync(`git fetch origin ${defaultBranch}`, { cwd, encoding: "utf8" }); + baseRef = execSync(`git merge-base origin/${defaultBranch} ${branchName}`, { cwd, encoding: "utf8" }).trim(); + } + const commitCount = parseInt(execSync(`git rev-list --count ${baseRef}..${branchName}`, { cwd, encoding: "utf8" }).trim(), 10); + if (commitCount > 0) { + const patchContent = execSync(`git format-patch ${baseRef}..${branchName} --stdout`, { + cwd, + encoding: "utf8", + }); + if (patchContent && patchContent.trim()) { + fs.writeFileSync(patchPath, patchContent, "utf8"); + patchGenerated = true; + } + } + } catch (branchError) { + } } - const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, ""); - this._buffer = this._buffer.subarray(index + 1); - if (line.trim() === "") { - return this.readMessage(); + if (!patchGenerated) { + const currentHead = execSync("git rev-parse HEAD", { cwd, encoding: "utf8" }).trim(); + if (!githubSha) { + errorMessage = "GITHUB_SHA environment variable is not set"; + } else if (currentHead === githubSha) { + } else { + try { + execSync(`git merge-base --is-ancestor ${githubSha} HEAD`, { cwd, encoding: "utf8" }); + const commitCount = parseInt(execSync(`git rev-list --count ${githubSha}..HEAD`, { cwd, encoding: "utf8" }).trim(), 10); + if (commitCount > 0) { + const patchContent = execSync(`git format-patch ${githubSha}..HEAD --stdout`, { + cwd, + encoding: "utf8", + }); + if (patchContent && patchContent.trim()) { + fs.writeFileSync(patchPath, patchContent, "utf8"); + patchGenerated = true; + } + } + } catch { + } + } } - try { - return JSON.parse(line); - } catch (error) { - throw new Error(`Parse error: ${error instanceof Error ? error.message : String(error)}`); + } catch (error) { + errorMessage = `Failed to generate patch: ${error instanceof Error ? error.message : String(error)}`; + } + if (patchGenerated && fs.existsSync(patchPath)) { + const patchContent = fs.readFileSync(patchPath, "utf8"); + const patchSize = Buffer.byteLength(patchContent, "utf8"); + const patchLines = patchContent.split("\n").length; + if (!patchContent.trim()) { + return { + success: false, + error: "No changes to commit - patch is empty", + patchPath: patchPath, + patchSize: 0, + patchLines: 0, + }; } + return { + success: true, + patchPath: patchPath, + patchSize: patchSize, + patchLines: patchLines, + }; } + return { + success: false, + error: errorMessage || "No changes to commit - no commits found", + patchPath: patchPath, + }; } - function validateRequiredFields(args, inputSchema) { - const requiredFields = inputSchema && Array.isArray(inputSchema.required) ? inputSchema.required : []; - if (!requiredFields.length) { - return []; + module.exports = { + generateGitPatch, + }; + EOF_GENERATE_GIT_PATCH + cat > /tmp/gh-aw/safeoutputs/get_base_branch.cjs << 'EOF_GET_BASE_BRANCH' + function getBaseBranch() { + return process.env.GH_AW_BASE_BRANCH || "main"; + } + module.exports = { + getBaseBranch, + }; + EOF_GET_BASE_BRANCH + cat > /tmp/gh-aw/safeoutputs/get_current_branch.cjs << 'EOF_GET_CURRENT_BRANCH' + const { execSync } = require("child_process"); + function getCurrentBranch() { + const cwd = process.env.GITHUB_WORKSPACE || process.cwd(); + try { + const branch = execSync("git rev-parse --abbrev-ref HEAD", { + encoding: "utf8", + cwd: cwd, + }).trim(); + return branch; + } catch (error) { } - const missing = requiredFields.filter(f => { - const value = args[f]; - return value === undefined || value === null || (typeof value === "string" && value.trim() === ""); - }); - return missing; + const ghHeadRef = process.env.GITHUB_HEAD_REF; + const ghRefName = process.env.GITHUB_REF_NAME; + if (ghHeadRef) { + return ghHeadRef; + } + if (ghRefName) { + return ghRefName; + } + throw new Error("Failed to determine current branch: git command failed and no GitHub environment variables available"); + } + module.exports = { + getCurrentBranch, + }; + EOF_GET_CURRENT_BRANCH + cat > /tmp/gh-aw/safeoutputs/mcp_handler_python.cjs << 'EOF_MCP_HANDLER_PYTHON' + const { execFile } = require("child_process"); + function createPythonHandler(server, toolName, scriptPath, timeoutSeconds = 60) { + return async args => { + server.debug(` [${toolName}] Invoking Python handler: ${scriptPath}`); + server.debug(` [${toolName}] Python handler args: ${JSON.stringify(args)}`); + server.debug(` [${toolName}] Timeout: ${timeoutSeconds}s`); + const inputJson = JSON.stringify(args || {}); + server.debug( + ` [${toolName}] Input JSON (${inputJson.length} bytes): ${inputJson.substring(0, 200)}${inputJson.length > 200 ? "..." : ""}` + ); + return new Promise((resolve, reject) => { + server.debug(` [${toolName}] Executing Python script...`); + const child = execFile( + "python3", + [scriptPath], + { + env: process.env, + timeout: timeoutSeconds * 1000, + maxBuffer: 10 * 1024 * 1024, + }, + (error, stdout, stderr) => { + if (stdout) { + server.debug(` [${toolName}] stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`); + } + if (stderr) { + server.debug(` [${toolName}] stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`); + } + if (error) { + server.debugError(` [${toolName}] Python script error: `, error); + reject(error); + return; + } + let result; + try { + if (stdout && stdout.trim()) { + result = JSON.parse(stdout.trim()); + } else { + result = { stdout: stdout || "", stderr: stderr || "" }; + } + } catch (parseError) { + server.debug(` [${toolName}] Output is not JSON, returning as text`); + result = { stdout: stdout || "", stderr: stderr || "" }; + } + server.debug(` [${toolName}] Python handler completed successfully`); + resolve({ + content: [ + { + type: "text", + text: JSON.stringify(result), + }, + ], + }); + } + ); + if (child.stdin) { + child.stdin.write(inputJson); + child.stdin.end(); + } + }); + }; + } + module.exports = { + createPythonHandler, + }; + EOF_MCP_HANDLER_PYTHON + cat > /tmp/gh-aw/safeoutputs/mcp_handler_shell.cjs << 'EOF_MCP_HANDLER_SHELL' + const fs = require("fs"); + const path = require("path"); + const { execFile } = require("child_process"); + const os = require("os"); + function createShellHandler(server, toolName, scriptPath, timeoutSeconds = 60) { + return async args => { + server.debug(` [${toolName}] Invoking shell handler: ${scriptPath}`); + server.debug(` [${toolName}] Shell handler args: ${JSON.stringify(args)}`); + server.debug(` [${toolName}] Timeout: ${timeoutSeconds}s`); + const env = { ...process.env }; + for (const [key, value] of Object.entries(args || {})) { + const envKey = `INPUT_${key.toUpperCase().replace(/-/g, "_")}`; + env[envKey] = String(value); + server.debug(` [${toolName}] Set env: ${envKey}=${String(value).substring(0, 100)}${String(value).length > 100 ? "..." : ""}`); + } + const outputFile = path.join(os.tmpdir(), `mcp-shell-output-${Date.now()}-${Math.random().toString(36).substring(2)}.txt`); + env.GITHUB_OUTPUT = outputFile; + server.debug(` [${toolName}] Output file: ${outputFile}`); + fs.writeFileSync(outputFile, ""); + return new Promise((resolve, reject) => { + server.debug(` [${toolName}] Executing shell script...`); + execFile( + scriptPath, + [], + { + env, + timeout: timeoutSeconds * 1000, + maxBuffer: 10 * 1024 * 1024, + }, + (error, stdout, stderr) => { + if (stdout) { + server.debug(` [${toolName}] stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`); + } + if (stderr) { + server.debug(` [${toolName}] stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`); + } + if (error) { + server.debugError(` [${toolName}] Shell script error: `, error); + try { + if (fs.existsSync(outputFile)) { + fs.unlinkSync(outputFile); + } + } catch { + } + reject(error); + return; + } + const outputs = {}; + try { + if (fs.existsSync(outputFile)) { + const outputContent = fs.readFileSync(outputFile, "utf-8"); + server.debug( + ` [${toolName}] Output file content: ${outputContent.substring(0, 500)}${outputContent.length > 500 ? "..." : ""}` + ); + const lines = outputContent.split("\n"); + for (const line of lines) { + const trimmed = line.trim(); + if (trimmed && trimmed.includes("=")) { + const eqIndex = trimmed.indexOf("="); + const key = trimmed.substring(0, eqIndex); + const value = trimmed.substring(eqIndex + 1); + outputs[key] = value; + server.debug(` [${toolName}] Parsed output: ${key}=${value.substring(0, 100)}${value.length > 100 ? "..." : ""}`); + } + } + } + } catch (readError) { + server.debugError(` [${toolName}] Error reading output file: `, readError); + } + try { + if (fs.existsSync(outputFile)) { + fs.unlinkSync(outputFile); + } + } catch { + } + const result = { + stdout: stdout || "", + stderr: stderr || "", + outputs, + }; + server.debug(` [${toolName}] Shell handler completed, outputs: ${Object.keys(outputs).join(", ") || "(none)"}`); + resolve({ + content: [ + { + type: "text", + text: JSON.stringify(result), + }, + ], + }); + } + ); + }); + }; } + module.exports = { + createShellHandler, + }; + EOF_MCP_HANDLER_SHELL + cat > /tmp/gh-aw/safeoutputs/mcp_server_core.cjs << 'EOF_MCP_SERVER_CORE' + const fs = require("fs"); + const path = require("path"); + const { ReadBuffer } = require("./read_buffer.cjs"); + const { validateRequiredFields } = require("./safe_inputs_validation.cjs"); const encoder = new TextEncoder(); function initLogFile(server) { if (server.logFileInitialized || !server.logDir || !server.logFilePath) return; @@ -993,96 +1293,7 @@ jobs: server.debugError(` [${toolName}] Warning: Could not make shell script executable: `, chmodError); } } - function createShellHandler(server, toolName, scriptPath, timeoutSeconds = 60) { - return async args => { - server.debug(` [${toolName}] Invoking shell handler: ${scriptPath}`); - server.debug(` [${toolName}] Shell handler args: ${JSON.stringify(args)}`); - server.debug(` [${toolName}] Timeout: ${timeoutSeconds}s`); - const env = { ...process.env }; - for (const [key, value] of Object.entries(args || {})) { - const envKey = `INPUT_${key.toUpperCase().replace(/-/g, "_")}`; - env[envKey] = String(value); - server.debug(` [${toolName}] Set env: ${envKey}=${String(value).substring(0, 100)}${String(value).length > 100 ? "..." : ""}`); - } - const outputFile = path.join(os.tmpdir(), `mcp-shell-output-${Date.now()}-${Math.random().toString(36).substring(2)}.txt`); - env.GITHUB_OUTPUT = outputFile; - server.debug(` [${toolName}] Output file: ${outputFile}`); - fs.writeFileSync(outputFile, ""); - return new Promise((resolve, reject) => { - server.debug(` [${toolName}] Executing shell script...`); - execFile( - scriptPath, - [], - { - env, - timeout: timeoutSeconds * 1000, - maxBuffer: 10 * 1024 * 1024, - }, - (error, stdout, stderr) => { - if (stdout) { - server.debug(` [${toolName}] stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`); - } - if (stderr) { - server.debug(` [${toolName}] stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`); - } - if (error) { - server.debugError(` [${toolName}] Shell script error: `, error); - try { - if (fs.existsSync(outputFile)) { - fs.unlinkSync(outputFile); - } - } catch { - } - reject(error); - return; - } - const outputs = {}; - try { - if (fs.existsSync(outputFile)) { - const outputContent = fs.readFileSync(outputFile, "utf-8"); - server.debug( - ` [${toolName}] Output file content: ${outputContent.substring(0, 500)}${outputContent.length > 500 ? "..." : ""}` - ); - const lines = outputContent.split("\n"); - for (const line of lines) { - const trimmed = line.trim(); - if (trimmed && trimmed.includes("=")) { - const eqIndex = trimmed.indexOf("="); - const key = trimmed.substring(0, eqIndex); - const value = trimmed.substring(eqIndex + 1); - outputs[key] = value; - server.debug(` [${toolName}] Parsed output: ${key}=${value.substring(0, 100)}${value.length > 100 ? "..." : ""}`); - } - } - } - } catch (readError) { - server.debugError(` [${toolName}] Error reading output file: `, readError); - } - try { - if (fs.existsSync(outputFile)) { - fs.unlinkSync(outputFile); - } - } catch { - } - const result = { - stdout: stdout || "", - stderr: stderr || "", - outputs, - }; - server.debug(` [${toolName}] Shell handler completed, outputs: ${Object.keys(outputs).join(", ") || "(none)"}`); - resolve({ - content: [ - { - type: "text", - text: JSON.stringify(result), - }, - ], - }); - } - ); - }); - }; - } + const { createShellHandler } = require("./mcp_handler_shell.cjs"); const timeout = tool.timeout || 60; tool.handler = createShellHandler(server, toolName, resolvedPath, timeout); loadedCount++; @@ -1100,66 +1311,7 @@ jobs: server.debugError(` [${toolName}] Warning: Could not make Python script executable: `, chmodError); } } - function createPythonHandler(server, toolName, scriptPath, timeoutSeconds = 60) { - return async args => { - server.debug(` [${toolName}] Invoking Python handler: ${scriptPath}`); - server.debug(` [${toolName}] Python handler args: ${JSON.stringify(args)}`); - server.debug(` [${toolName}] Timeout: ${timeoutSeconds}s`); - const inputJson = JSON.stringify(args || {}); - server.debug( - ` [${toolName}] Input JSON (${inputJson.length} bytes): ${inputJson.substring(0, 200)}${inputJson.length > 200 ? "..." : ""}` - ); - return new Promise((resolve, reject) => { - server.debug(` [${toolName}] Executing Python script...`); - const child = execFile( - "python3", - [scriptPath], - { - env: process.env, - timeout: timeoutSeconds * 1000, - maxBuffer: 10 * 1024 * 1024, - }, - (error, stdout, stderr) => { - if (stdout) { - server.debug(` [${toolName}] stdout: ${stdout.substring(0, 500)}${stdout.length > 500 ? "..." : ""}`); - } - if (stderr) { - server.debug(` [${toolName}] stderr: ${stderr.substring(0, 500)}${stderr.length > 500 ? "..." : ""}`); - } - if (error) { - server.debugError(` [${toolName}] Python script error: `, error); - reject(error); - return; - } - let result; - try { - if (stdout && stdout.trim()) { - result = JSON.parse(stdout.trim()); - } else { - result = { stdout: stdout || "", stderr: stderr || "" }; - } - } catch (parseError) { - server.debug(` [${toolName}] Output is not JSON, returning as text`); - result = { stdout: stdout || "", stderr: stderr || "" }; - } - server.debug(` [${toolName}] Python handler completed successfully`); - resolve({ - content: [ - { - type: "text", - text: JSON.stringify(result), - }, - ], - }); - } - ); - if (child.stdin) { - child.stdin.write(inputJson); - child.stdin.end(); - } - }); - }; - } + const { createPythonHandler } = require("./mcp_handler_python.cjs"); const timeout = tool.timeout || 60; tool.handler = createPythonHandler(server, toolName, resolvedPath, timeout); loadedCount++; @@ -1378,33 +1530,157 @@ jobs: async function processReadBuffer(server, defaultHandler) { while (true) { try { - const message = server.readBuffer.readMessage(); - if (!message) { - break; - } - server.debug(`recv: ${JSON.stringify(message)}`); - await handleMessage(server, message, defaultHandler); + const message = server.readBuffer.readMessage(); + if (!message) { + break; + } + server.debug(`recv: ${JSON.stringify(message)}`); + await handleMessage(server, message, defaultHandler); + } catch (error) { + server.debug(`Parse error: ${error instanceof Error ? error.message : String(error)}`); + } + } + } + function start(server, options = {}) { + const { defaultHandler } = options; + server.debug(`v${server.serverInfo.version} ready on stdio`); + server.debug(` tools: ${Object.keys(server.tools).join(", ")}`); + if (!Object.keys(server.tools).length) { + throw new Error("No tools registered"); + } + const onData = async chunk => { + server.readBuffer.append(chunk); + await processReadBuffer(server, defaultHandler); + }; + process.stdin.on("data", onData); + process.stdin.on("error", err => server.debug(`stdin error: ${err}`)); + process.stdin.resume(); + server.debug(`listening...`); + } + module.exports = { + createServer, + registerTool, + normalizeTool, + handleRequest, + handleMessage, + processReadBuffer, + start, + loadToolHandlers, + }; + EOF_MCP_SERVER_CORE + cat > /tmp/gh-aw/safeoutputs/normalize_branch_name.cjs << 'EOF_NORMALIZE_BRANCH_NAME' + function normalizeBranchName(branchName) { + if (!branchName || typeof branchName !== "string" || branchName.trim() === "") { + return branchName; + } + let normalized = branchName.replace(/[^a-zA-Z0-9\-_/.]+/g, "-"); + normalized = normalized.replace(/-+/g, "-"); + normalized = normalized.replace(/^-+|-+$/g, ""); + if (normalized.length > 128) { + normalized = normalized.substring(0, 128); + } + normalized = normalized.replace(/-+$/, ""); + normalized = normalized.toLowerCase(); + return normalized; + } + module.exports = { + normalizeBranchName, + }; + EOF_NORMALIZE_BRANCH_NAME + cat > /tmp/gh-aw/safeoutputs/read_buffer.cjs << 'EOF_READ_BUFFER' + class ReadBuffer { + constructor() { + this._buffer = null; + } + append(chunk) { + this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk; + } + readMessage() { + if (!this._buffer) { + return null; + } + const index = this._buffer.indexOf("\n"); + if (index === -1) { + return null; + } + const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, ""); + this._buffer = this._buffer.subarray(index + 1); + if (line.trim() === "") { + return this.readMessage(); + } + try { + return JSON.parse(line); + } catch (error) { + throw new Error(`Parse error: ${error instanceof Error ? error.message : String(error)}`); + } + } + } + module.exports = { + ReadBuffer, + }; + EOF_READ_BUFFER + cat > /tmp/gh-aw/safeoutputs/safe_inputs_validation.cjs << 'EOF_SAFE_INPUTS_VALIDATION' + function validateRequiredFields(args, inputSchema) { + const requiredFields = inputSchema && Array.isArray(inputSchema.required) ? inputSchema.required : []; + if (!requiredFields.length) { + return []; + } + const missing = requiredFields.filter(f => { + const value = args[f]; + return value === undefined || value === null || (typeof value === "string" && value.trim() === ""); + }); + return missing; + } + module.exports = { + validateRequiredFields, + }; + EOF_SAFE_INPUTS_VALIDATION + cat > /tmp/gh-aw/safeoutputs/safe_outputs_append.cjs << 'EOF_SAFE_OUTPUTS_APPEND' + const fs = require("fs"); + function createAppendFunction(outputFile) { + return function appendSafeOutput(entry) { + if (!outputFile) throw new Error("No output file configured"); + entry.type = entry.type.replace(/-/g, "_"); + const jsonLine = JSON.stringify(entry) + "\n"; + try { + fs.appendFileSync(outputFile, jsonLine); } catch (error) { - server.debug(`Parse error: ${error instanceof Error ? error.message : String(error)}`); + throw new Error(`Failed to write to output file: ${error instanceof Error ? error.message : String(error)}`); } - } + }; } - function start(server, options = {}) { - const { defaultHandler } = options; - server.debug(`v${server.serverInfo.version} ready on stdio`); - server.debug(` tools: ${Object.keys(server.tools).join(", ")}`); - if (!Object.keys(server.tools).length) { - throw new Error("No tools registered"); + module.exports = { createAppendFunction }; + EOF_SAFE_OUTPUTS_APPEND + cat > /tmp/gh-aw/safeoutputs/safe_outputs_bootstrap.cjs << 'EOF_SAFE_OUTPUTS_BOOTSTRAP' + const fs = require("fs"); + const { loadConfig } = require("./safe_outputs_config.cjs"); + const { loadTools } = require("./safe_outputs_tools_loader.cjs"); + function bootstrapSafeOutputsServer(logger) { + logger.debug("Loading safe-outputs configuration"); + const { config, outputFile } = loadConfig(logger); + logger.debug("Loading safe-outputs tools"); + const tools = loadTools(logger); + return { config, outputFile, tools }; + } + function cleanupConfigFile(logger) { + const configPath = process.env.GH_AW_SAFE_OUTPUTS_CONFIG_PATH || "/tmp/gh-aw/safeoutputs/config.json"; + 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); } - const onData = async chunk => { - server.readBuffer.append(chunk); - await processReadBuffer(server, defaultHandler); - }; - process.stdin.on("data", onData); - process.stdin.on("error", err => server.debug(`stdin error: ${err}`)); - process.stdin.resume(); - server.debug(`listening...`); } + module.exports = { + bootstrapSafeOutputsServer, + cleanupConfigFile, + }; + EOF_SAFE_OUTPUTS_BOOTSTRAP + cat > /tmp/gh-aw/safeoutputs/safe_outputs_config.cjs << 'EOF_SAFE_OUTPUTS_CONFIG' + const fs = require("fs"); + const path = require("path"); function loadConfig(server) { const configPath = process.env.GH_AW_SAFE_OUTPUTS_CONFIG_PATH || "/tmp/gh-aw/safeoutputs/config.json"; let safeOutputsConfigRaw; @@ -1443,188 +1719,18 @@ jobs: outputFile: outputFile, }; } - function createAppendFunction(outputFile) { - return function appendSafeOutput(entry) { - if (!outputFile) throw new Error("No output file configured"); - entry.type = entry.type.replace(/-/g, "_"); - const jsonLine = JSON.stringify(entry) + "\n"; - try { - fs.appendFileSync(outputFile, jsonLine); - } catch (error) { - throw new Error(`Failed to write to output file: ${error instanceof Error ? error.message : String(error)}`); - } - }; - } - function normalizeBranchName(branchName) { - if (!branchName || typeof branchName !== "string" || branchName.trim() === "") { - return branchName; - } - let normalized = branchName.replace(/[^a-zA-Z0-9\-_/.]+/g, "-"); - normalized = normalized.replace(/-+/g, "-"); - normalized = normalized.replace(/^-+|-+$/g, ""); - if (normalized.length > 128) { - normalized = normalized.substring(0, 128); - } - normalized = normalized.replace(/-+$/, ""); - normalized = normalized.toLowerCase(); - return normalized; - } - function estimateTokens(text) { - if (!text) return 0; - return Math.ceil(text.length / 4); - } - function generateCompactSchema(content) { - try { - const parsed = JSON.parse(content); - if (Array.isArray(parsed)) { - if (parsed.length === 0) { - return "[]"; - } - const firstItem = parsed[0]; - if (typeof firstItem === "object" && firstItem !== null) { - const keys = Object.keys(firstItem); - return `[{${keys.join(", ")}}] (${parsed.length} items)`; - } - return `[${typeof firstItem}] (${parsed.length} items)`; - } else if (typeof parsed === "object" && parsed !== null) { - const keys = Object.keys(parsed); - if (keys.length > 10) { - return `{${keys.slice(0, 10).join(", ")}, ...} (${keys.length} keys)`; - } - return `{${keys.join(", ")}}`; - } - return `${typeof parsed}`; - } catch { - return "text content"; - } - } - function writeLargeContentToFile(content) { - const logsDir = "/tmp/gh-aw/safeoutputs"; - if (!fs.existsSync(logsDir)) { - fs.mkdirSync(logsDir, { recursive: true }); - } - const hash = crypto.createHash("sha256").update(content).digest("hex"); - const filename = `${hash}.json`; - const filepath = path.join(logsDir, filename); - fs.writeFileSync(filepath, content, "utf8"); - const description = generateCompactSchema(content); - return { - filename: filename, - description: description, - }; - } - function getCurrentBranch() { - const cwd = process.env.GITHUB_WORKSPACE || process.cwd(); - try { - const branch = execSync("git rev-parse --abbrev-ref HEAD", { - encoding: "utf8", - cwd: cwd, - }).trim(); - return branch; - } catch (error) { - } - const ghHeadRef = process.env.GITHUB_HEAD_REF; - const ghRefName = process.env.GITHUB_REF_NAME; - if (ghHeadRef) { - return ghHeadRef; - } - if (ghRefName) { - return ghRefName; - } - throw new Error("Failed to determine current branch: git command failed and no GitHub environment variables available"); - } - function getBaseBranch() { - return process.env.GH_AW_BASE_BRANCH || "main"; - } - function generateGitPatch(branchName) { - const patchPath = "/tmp/gh-aw/aw.patch"; - const cwd = process.env.GITHUB_WORKSPACE || process.cwd(); - const defaultBranch = process.env.DEFAULT_BRANCH || getBaseBranch(); - const githubSha = process.env.GITHUB_SHA; - const patchDir = path.dirname(patchPath); - if (!fs.existsSync(patchDir)) { - fs.mkdirSync(patchDir, { recursive: true }); - } - let patchGenerated = false; - let errorMessage = null; - try { - if (branchName) { - try { - execSync(`git show-ref --verify --quiet refs/heads/${branchName}`, { cwd, encoding: "utf8" }); - let baseRef; - try { - execSync(`git show-ref --verify --quiet refs/remotes/origin/${branchName}`, { cwd, encoding: "utf8" }); - baseRef = `origin/${branchName}`; - } catch { - execSync(`git fetch origin ${defaultBranch}`, { cwd, encoding: "utf8" }); - baseRef = execSync(`git merge-base origin/${defaultBranch} ${branchName}`, { cwd, encoding: "utf8" }).trim(); - } - const commitCount = parseInt(execSync(`git rev-list --count ${baseRef}..${branchName}`, { cwd, encoding: "utf8" }).trim(), 10); - if (commitCount > 0) { - const patchContent = execSync(`git format-patch ${baseRef}..${branchName} --stdout`, { - cwd, - encoding: "utf8", - }); - if (patchContent && patchContent.trim()) { - fs.writeFileSync(patchPath, patchContent, "utf8"); - patchGenerated = true; - } - } - } catch (branchError) { - } - } - if (!patchGenerated) { - const currentHead = execSync("git rev-parse HEAD", { cwd, encoding: "utf8" }).trim(); - if (!githubSha) { - errorMessage = "GITHUB_SHA environment variable is not set"; - } else if (currentHead === githubSha) { - } else { - try { - execSync(`git merge-base --is-ancestor ${githubSha} HEAD`, { cwd, encoding: "utf8" }); - const commitCount = parseInt(execSync(`git rev-list --count ${githubSha}..HEAD`, { cwd, encoding: "utf8" }).trim(), 10); - if (commitCount > 0) { - const patchContent = execSync(`git format-patch ${githubSha}..HEAD --stdout`, { - cwd, - encoding: "utf8", - }); - if (patchContent && patchContent.trim()) { - fs.writeFileSync(patchPath, patchContent, "utf8"); - patchGenerated = true; - } - } - } catch { - } - } - } - } catch (error) { - errorMessage = `Failed to generate patch: ${error instanceof Error ? error.message : String(error)}`; - } - if (patchGenerated && fs.existsSync(patchPath)) { - const patchContent = fs.readFileSync(patchPath, "utf8"); - const patchSize = Buffer.byteLength(patchContent, "utf8"); - const patchLines = patchContent.split("\n").length; - if (!patchContent.trim()) { - return { - success: false, - error: "No changes to commit - patch is empty", - patchPath: patchPath, - patchSize: 0, - patchLines: 0, - }; - } - return { - success: true, - patchPath: patchPath, - patchSize: patchSize, - patchLines: patchLines, - }; - } - return { - success: false, - error: errorMessage || "No changes to commit - no commits found", - patchPath: patchPath, - }; - } + module.exports = { loadConfig }; + EOF_SAFE_OUTPUTS_CONFIG + cat > /tmp/gh-aw/safeoutputs/safe_outputs_handlers.cjs << 'EOF_SAFE_OUTPUTS_HANDLERS' + const fs = require("fs"); + const path = require("path"); + const crypto = require("crypto"); + const { normalizeBranchName } = require("./normalize_branch_name.cjs"); + const { estimateTokens } = require("./estimate_tokens.cjs"); + const { writeLargeContentToFile } = require("./write_large_content_to_file.cjs"); + const { getCurrentBranch } = require("./get_current_branch.cjs"); + const { getBaseBranch } = require("./get_base_branch.cjs"); + const { generateGitPatch } = require("./generate_git_patch.cjs"); function createHandlers(server, appendSafeOutput) { const defaultHandler = type => args => { const entry = { ...(args || {}), type }; @@ -1816,6 +1922,45 @@ jobs: pushToPullRequestBranchHandler, }; } + module.exports = { createHandlers }; + EOF_SAFE_OUTPUTS_HANDLERS + cat > /tmp/gh-aw/safeoutputs/safe_outputs_mcp_server.cjs << 'EOF_SAFE_OUTPUTS_MCP_SERVER' + const { createServer, registerTool, normalizeTool, start } = require("./mcp_server_core.cjs"); + const { createAppendFunction } = require("./safe_outputs_append.cjs"); + const { createHandlers } = require("./safe_outputs_handlers.cjs"); + const { attachHandlers, registerPredefinedTools, registerDynamicTools } = require("./safe_outputs_tools_loader.cjs"); + const { bootstrapSafeOutputsServer, cleanupConfigFile } = require("./safe_outputs_bootstrap.cjs"); + function startSafeOutputsServer(options = {}) { + const SERVER_INFO = { name: "safeoutputs", version: "1.0.0" }; + const MCP_LOG_DIR = options.logDir || process.env.GH_AW_MCP_LOG_DIR; + const server = createServer(SERVER_INFO, { logDir: MCP_LOG_DIR }); + const { config: safeOutputsConfig, outputFile, tools: ALL_TOOLS } = bootstrapSafeOutputsServer(server); + const appendSafeOutput = createAppendFunction(outputFile); + const handlers = createHandlers(server, appendSafeOutput); + const { defaultHandler } = handlers; + const toolsWithHandlers = attachHandlers(ALL_TOOLS, handlers); + server.debug(` output file: ${outputFile}`); + server.debug(` config: ${JSON.stringify(safeOutputsConfig)}`); + registerPredefinedTools(server, toolsWithHandlers, safeOutputsConfig, registerTool, normalizeTool); + registerDynamicTools(server, toolsWithHandlers, safeOutputsConfig, outputFile, registerTool, normalizeTool); + server.debug(` tools: ${Object.keys(server.tools).join(", ")}`); + if (!Object.keys(server.tools).length) throw new Error("No tools enabled in configuration"); + start(server, { defaultHandler }); + } + if (require.main === module) { + try { + startSafeOutputsServer(); + } catch (error) { + console.error(`Error starting safe-outputs server: ${error instanceof Error ? error.message : String(error)}`); + process.exit(1); + } + } + module.exports = { + startSafeOutputsServer, + }; + EOF_SAFE_OUTPUTS_MCP_SERVER + cat > /tmp/gh-aw/safeoutputs/safe_outputs_tools_loader.cjs << 'EOF_SAFE_OUTPUTS_TOOLS_LOADER' + const fs = require("fs"); function loadTools(server) { const toolsPath = process.env.GH_AW_SAFE_OUTPUTS_TOOLS_PATH || "/tmp/gh-aw/safeoutputs/tools.json"; let ALL_TOOLS = []; @@ -1918,22 +2063,48 @@ jobs: } }); } - const SERVER_INFO = { name: "safeoutputs", version: "1.0.0" }; - const MCP_LOG_DIR = process.env.GH_AW_MCP_LOG_DIR; - const server = createServer(SERVER_INFO, { logDir: MCP_LOG_DIR }); - const { config: safeOutputsConfig, outputFile } = loadConfig(server); - const appendSafeOutput = createAppendFunction(outputFile); - const handlers = createHandlers(server, appendSafeOutput); - const { defaultHandler } = handlers; - let ALL_TOOLS = loadTools(server); - ALL_TOOLS = attachHandlers(ALL_TOOLS, handlers); - server.debug(` output file: ${outputFile}`); - server.debug(` config: ${JSON.stringify(safeOutputsConfig)}`); - registerPredefinedTools(server, ALL_TOOLS, safeOutputsConfig, registerTool, normalizeTool); - registerDynamicTools(server, ALL_TOOLS, safeOutputsConfig, outputFile, registerTool, normalizeTool); - server.debug(` tools: ${Object.keys(server.tools).join(", ")}`); - if (!Object.keys(server.tools).length) throw new Error("No tools enabled in configuration"); - start(server, { defaultHandler }); + module.exports = { + loadTools, + attachHandlers, + registerPredefinedTools, + registerDynamicTools, + }; + EOF_SAFE_OUTPUTS_TOOLS_LOADER + cat > /tmp/gh-aw/safeoutputs/write_large_content_to_file.cjs << 'EOF_WRITE_LARGE_CONTENT_TO_FILE' + const fs = require("fs"); + const path = require("path"); + const crypto = require("crypto"); + const { generateCompactSchema } = require("./generate_compact_schema.cjs"); + function writeLargeContentToFile(content) { + const logsDir = "/tmp/gh-aw/safeoutputs"; + if (!fs.existsSync(logsDir)) { + fs.mkdirSync(logsDir, { recursive: true }); + } + const hash = crypto.createHash("sha256").update(content).digest("hex"); + const filename = `${hash}.json`; + const filepath = path.join(logsDir, filename); + fs.writeFileSync(filepath, content, "utf8"); + const description = generateCompactSchema(content); + return { + filename: filename, + description: description, + }; + } + module.exports = { + writeLargeContentToFile, + }; + EOF_WRITE_LARGE_CONTENT_TO_FILE + cat > /tmp/gh-aw/safeoutputs/mcp-server.cjs << 'EOF' + const { startSafeOutputsServer } = require("./safe_outputs_mcp_server.cjs"); + if (require.main === module) { + try { + startSafeOutputsServer(); + } catch (error) { + console.error(`Error starting safe-outputs server: ${error instanceof Error ? error.message : String(error)}`); + process.exit(1); + } + } + module.exports = { startSafeOutputsServer }; EOF chmod +x /tmp/gh-aw/safeoutputs/mcp-server.cjs @@ -1973,7 +2144,10 @@ jobs: "args": ["/tmp/gh-aw/safeoutputs/mcp-server.cjs"], "tools": ["*"], "env": { + "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}", "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}", + "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}", + "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}", "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}", "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}", "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}", @@ -3594,14 +3768,20 @@ jobs: const outputFile = process.env.GH_AW_SAFE_OUTPUTS; const configPath = process.env.GH_AW_SAFE_OUTPUTS_CONFIG_PATH || "/tmp/gh-aw/safeoutputs/config.json"; let safeOutputsConfig; + core.info(`[INGESTION] Reading config from: ${configPath}`); try { if (fs.existsSync(configPath)) { const configFileContent = fs.readFileSync(configPath, "utf8"); + core.info(`[INGESTION] Raw config content: ${configFileContent}`); safeOutputsConfig = JSON.parse(configFileContent); + core.info(`[INGESTION] Parsed config keys: ${JSON.stringify(Object.keys(safeOutputsConfig))}`); + } else { + core.info(`[INGESTION] Config file does not exist at: ${configPath}`); } } catch (error) { core.warning(`Failed to read config file from ${configPath}: ${error instanceof Error ? error.message : String(error)}`); } + core.info(`[INGESTION] Output file path: ${outputFile}`); if (!outputFile) { core.info("GH_AW_SAFE_OUTPUTS not set, no output to collect"); core.setOutput("output", ""); @@ -3617,11 +3797,14 @@ jobs: core.info("Output file is empty"); } core.info(`Raw output content length: ${outputContent.length}`); + core.info(`[INGESTION] First 500 chars of output: ${outputContent.substring(0, 500)}`); let expectedOutputTypes = {}; if (safeOutputsConfig) { try { + core.info(`[INGESTION] Normalizing config keys (dash -> underscore)`); expectedOutputTypes = Object.fromEntries(Object.entries(safeOutputsConfig).map(([key, value]) => [key.replace(/-/g, "_"), value])); - core.info(`Expected output types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.info(`[INGESTION] Expected output types after normalization: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.info(`[INGESTION] Expected output types full config: ${JSON.stringify(expectedOutputTypes)}`); } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); core.info(`Warning: Could not parse safe-outputs config: ${errorMsg}`); @@ -3633,6 +3816,7 @@ jobs: for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line === "") continue; + core.info(`[INGESTION] Processing line ${i + 1}: ${line.substring(0, 200)}...`); try { const item = parseJsonWithRepair(line); if (item === undefined) { @@ -3643,9 +3827,14 @@ jobs: errors.push(`Line ${i + 1}: Missing required 'type' field`); continue; } + const originalType = item.type; const itemType = item.type.replace(/-/g, "_"); + core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/lockfile-stats.lock.yml b/.github/workflows/lockfile-stats.lock.yml index 16b3963edcc..1f697095aaf 100644 --- a/.github/workflows/lockfile-stats.lock.yml +++ b/.github/workflows/lockfile-stats.lock.yml @@ -4319,7 +4319,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index bef3a8028be..ce0b43c5c8c 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -4209,7 +4209,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 7b62b07f76a..42b57ab5de5 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -4374,7 +4374,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/notion-issue-summary.lock.yml b/.github/workflows/notion-issue-summary.lock.yml index 9cc8011e4b1..ca685210590 100644 --- a/.github/workflows/notion-issue-summary.lock.yml +++ b/.github/workflows/notion-issue-summary.lock.yml @@ -3276,7 +3276,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/org-health-report.lock.yml b/.github/workflows/org-health-report.lock.yml index 49ae51709ca..1736b21b375 100644 --- a/.github/workflows/org-health-report.lock.yml +++ b/.github/workflows/org-health-report.lock.yml @@ -5070,7 +5070,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index dd26b1ace70..83b35f703e5 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -5054,7 +5054,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index decf62d8c1e..7ed4d7691dd 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -4388,7 +4388,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index db2de3c2a5e..8fba116a177 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -6106,7 +6106,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 8c5423a49f3..98750394d8f 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -5374,7 +5374,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index 5f858d733ef..b19f11b8fd4 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -5595,7 +5595,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml index fbf38242927..b036c6a7481 100644 --- a/.github/workflows/python-data-charts.lock.yml +++ b/.github/workflows/python-data-charts.lock.yml @@ -5438,7 +5438,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 0b5bc4872ed..d9fe0dd234d 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -5636,7 +5636,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 918161b16a6..1618a8d9ef2 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -3734,7 +3734,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } @@ -6459,13 +6461,13 @@ 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 diff --git a/.github/workflows/repo-tree-map.lock.yml b/.github/workflows/repo-tree-map.lock.yml index 0561c73a585..8df97744af1 100644 --- a/.github/workflows/repo-tree-map.lock.yml +++ b/.github/workflows/repo-tree-map.lock.yml @@ -3614,7 +3614,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index 710b2f6ba99..560c3862c22 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -4652,7 +4652,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/research.lock.yml b/.github/workflows/research.lock.yml index 95f512fa12d..e04b1f890ed 100644 --- a/.github/workflows/research.lock.yml +++ b/.github/workflows/research.lock.yml @@ -3529,7 +3529,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml index 10a70a5a01b..5717c9f0771 100644 --- a/.github/workflows/safe-output-health.lock.yml +++ b/.github/workflows/safe-output-health.lock.yml @@ -4616,7 +4616,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/schema-consistency-checker.lock.yml b/.github/workflows/schema-consistency-checker.lock.yml index e302e5e508e..d53e4ab5aa6 100644 --- a/.github/workflows/schema-consistency-checker.lock.yml +++ b/.github/workflows/schema-consistency-checker.lock.yml @@ -4264,7 +4264,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 4491a52d1d8..967a4d4d1ce 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -5670,7 +5670,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/security-fix-pr.lock.yml b/.github/workflows/security-fix-pr.lock.yml index 33774dd11bf..4eece6ede67 100644 --- a/.github/workflows/security-fix-pr.lock.yml +++ b/.github/workflows/security-fix-pr.lock.yml @@ -3814,7 +3814,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/semantic-function-refactor.lock.yml b/.github/workflows/semantic-function-refactor.lock.yml index 3067f2dd1d8..000c14b3156 100644 --- a/.github/workflows/semantic-function-refactor.lock.yml +++ b/.github/workflows/semantic-function-refactor.lock.yml @@ -4652,7 +4652,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 09721ad594d..8b613270ed5 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -5551,7 +5551,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index a04d26a3b82..b2c543a5464 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -5121,7 +5121,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-copilot-no-firewall.lock.yml b/.github/workflows/smoke-copilot-no-firewall.lock.yml index 206fb4ed3d5..8fcd04c3ef8 100644 --- a/.github/workflows/smoke-copilot-no-firewall.lock.yml +++ b/.github/workflows/smoke-copilot-no-firewall.lock.yml @@ -6542,7 +6542,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-copilot-playwright.lock.yml b/.github/workflows/smoke-copilot-playwright.lock.yml index 70c4ab28685..8ef2aaf9791 100644 --- a/.github/workflows/smoke-copilot-playwright.lock.yml +++ b/.github/workflows/smoke-copilot-playwright.lock.yml @@ -6522,7 +6522,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-copilot-safe-inputs.lock.yml b/.github/workflows/smoke-copilot-safe-inputs.lock.yml index 89c7443be6e..400a226ac30 100644 --- a/.github/workflows/smoke-copilot-safe-inputs.lock.yml +++ b/.github/workflows/smoke-copilot-safe-inputs.lock.yml @@ -6247,7 +6247,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index c1addd70ae7..0b0f52da14d 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -5072,7 +5072,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-detector.lock.yml b/.github/workflows/smoke-detector.lock.yml index fe96b00dd31..67f0b43e48a 100644 --- a/.github/workflows/smoke-detector.lock.yml +++ b/.github/workflows/smoke-detector.lock.yml @@ -5294,7 +5294,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/smoke-srt.lock.yml b/.github/workflows/smoke-srt.lock.yml index f94fe412ee7..21bf6c36740 100644 --- a/.github/workflows/smoke-srt.lock.yml +++ b/.github/workflows/smoke-srt.lock.yml @@ -3422,7 +3422,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/spec-kit-execute.lock.yml b/.github/workflows/spec-kit-execute.lock.yml index 35932996b81..e92dfc8696c 100644 --- a/.github/workflows/spec-kit-execute.lock.yml +++ b/.github/workflows/spec-kit-execute.lock.yml @@ -4143,7 +4143,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/spec-kit-executor.lock.yml b/.github/workflows/spec-kit-executor.lock.yml index 68046abcf33..ce55799aebd 100644 --- a/.github/workflows/spec-kit-executor.lock.yml +++ b/.github/workflows/spec-kit-executor.lock.yml @@ -3833,7 +3833,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/speckit-dispatcher.lock.yml b/.github/workflows/speckit-dispatcher.lock.yml index 470addd66b6..2792a757b67 100644 --- a/.github/workflows/speckit-dispatcher.lock.yml +++ b/.github/workflows/speckit-dispatcher.lock.yml @@ -5549,7 +5549,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index a367aed850c..62897999232 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -5306,7 +5306,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml index a7ef3edd8e3..b4ce2a77847 100644 --- a/.github/workflows/static-analysis-report.lock.yml +++ b/.github/workflows/static-analysis-report.lock.yml @@ -4355,7 +4355,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index 55f2e5375c1..bf10d71f8fe 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -3830,7 +3830,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 4f511ad7c1e..d767cc2026d 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -4887,7 +4887,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/test-discussion-expires.lock.yml b/.github/workflows/test-discussion-expires.lock.yml index 4db09dec3e5..885902a8992 100644 --- a/.github/workflows/test-discussion-expires.lock.yml +++ b/.github/workflows/test-discussion-expires.lock.yml @@ -3208,7 +3208,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/test-python-safe-input.lock.yml b/.github/workflows/test-python-safe-input.lock.yml index cd32d770876..76ed1e6c002 100644 --- a/.github/workflows/test-python-safe-input.lock.yml +++ b/.github/workflows/test-python-safe-input.lock.yml @@ -4825,7 +4825,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 492219cebcb..867de576ce7 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -3947,7 +3947,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml index 6fe7ca5c19f..3e35971fbbf 100644 --- a/.github/workflows/typist.lock.yml +++ b/.github/workflows/typist.lock.yml @@ -4683,7 +4683,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index f31c72d10d9..7486425f237 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -5416,7 +5416,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/video-analyzer.lock.yml b/.github/workflows/video-analyzer.lock.yml index 9297bac3d5f..b1cbb3b6279 100644 --- a/.github/workflows/video-analyzer.lock.yml +++ b/.github/workflows/video-analyzer.lock.yml @@ -3871,7 +3871,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/.github/workflows/weekly-issue-summary.lock.yml b/.github/workflows/weekly-issue-summary.lock.yml index c93a2c3df7b..f7fc954572c 100644 --- a/.github/workflows/weekly-issue-summary.lock.yml +++ b/.github/workflows/weekly-issue-summary.lock.yml @@ -4663,7 +4663,9 @@ jobs: core.info(`[INGESTION] Line ${i + 1}: Original type='${originalType}', Normalized type='${itemType}'`); item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; } diff --git a/pkg/workflow/bundler.go b/pkg/workflow/bundler.go index 8118bbad3f7..9bf420dd9ac 100644 --- a/pkg/workflow/bundler.go +++ b/pkg/workflow/bundler.go @@ -110,6 +110,12 @@ func BundleJavaScriptWithMode(mainContent string, sources map[string]string, bas bundlerLog.Printf("Bundling JavaScript: source_count=%d, base_path=%s, main_content_size=%d bytes, runtime_mode=%s", len(sources), basePath, len(mainContent), mode) + // Validate that no runtime mode mixing occurs + if err := validateNoRuntimeMixing(mainContent, sources, mode); err != nil { + bundlerLog.Printf("Runtime mode validation failed: %v", err) + return "", err + } + // Track already processed files to avoid circular dependencies processed := make(map[string]bool) diff --git a/pkg/workflow/bundler_runtime_mode_test.go b/pkg/workflow/bundler_runtime_mode_test.go index 69e1b7afb1c..9f2273662f8 100644 --- a/pkg/workflow/bundler_runtime_mode_test.go +++ b/pkg/workflow/bundler_runtime_mode_test.go @@ -310,3 +310,207 @@ module.exports = { main }; t.Errorf("Node.js mode: expected 3 module.exports statements, got %d", count) } } + +func TestValidateNoRuntimeMixing_GitHubScriptWithNodeJsHelper(t *testing.T) { + // Create a Node.js-only helper that uses child_process + helperContent := `const { execSync } = require('child_process'); + +function runCommand(cmd) { + return execSync(cmd).toString(); +} + +module.exports = { runCommand }; +` + + // Create a main script that tries to use this helper in GitHub Script mode + mainContent := `const { runCommand } = require('./helper.cjs'); + +function main() { + const result = runCommand('ls'); + console.log(result); +} + +main(); +` + + sources := map[string]string{ + "helper.cjs": helperContent, + } + + // This should fail because GitHub Script mode cannot use Node.js-only APIs + _, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeGitHubScript) + if err == nil { + t.Error("Expected error when bundling Node.js script in GitHub Script mode, but got nil") + } + + // Check error message mentions runtime conflict + if !strings.Contains(err.Error(), "runtime mode conflict") { + t.Errorf("Error should mention runtime mode conflict, got: %v", err) + } +} + +func TestValidateNoRuntimeMixing_NodeJsWithNodeJsHelper(t *testing.T) { + // Create a Node.js-only helper that uses child_process + helperContent := `const { execSync } = require('child_process'); + +function runCommand(cmd) { + return execSync(cmd).toString(); +} + +module.exports = { runCommand }; +` + + // Create a main script that uses this helper in Node.js mode + mainContent := `const { runCommand } = require('./helper.cjs'); + +function main() { + const result = runCommand('ls'); + console.log(result); +} + +module.exports = { main }; +` + + sources := map[string]string{ + "helper.cjs": helperContent, + } + + // This should succeed because both are Node.js mode + bundled, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeNodeJS) + if err != nil { + t.Errorf("Expected no error when bundling Node.js script in Node.js mode, but got: %v", err) + } + + // Verify the helper is included + if !strings.Contains(bundled, "function runCommand") { + t.Error("Bundled output does not contain runCommand function") + } +} + +func TestValidateNoRuntimeMixing_GitHubScriptWithCompatibleHelper(t *testing.T) { + // Create a helper that's compatible with both modes (no runtime-specific APIs) + helperContent := `function add(a, b) { + return a + b; +} + +module.exports = { add }; +` + + // Create a main script for GitHub Script mode + mainContent := `const { add } = require('./helper.cjs'); + +function main() { + console.log(add(1, 2)); +} + +main(); +` + + sources := map[string]string{ + "helper.cjs": helperContent, + } + + // This should succeed because the helper is compatible with GitHub Script mode + bundled, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeGitHubScript) + if err != nil { + t.Errorf("Expected no error when bundling compatible helper in GitHub Script mode, but got: %v", err) + } + + // Verify the helper is included + if !strings.Contains(bundled, "function add") { + t.Error("Bundled output does not contain add function") + } + + // Verify module.exports is removed in GitHub Script mode + if strings.Contains(bundled, "module.exports") { + t.Error("GitHub Script mode should remove module.exports") + } +} + +func TestValidateNoRuntimeMixing_GitHubScriptWithGitHubScriptAPIs(t *testing.T) { + // Create a helper that uses GitHub Script APIs + helperContent := `async function createIssue(title) { + await github.rest.issues.create({ + owner: github.context.repo.owner, + repo: github.context.repo.repo, + title: title + }); +} + +module.exports = { createIssue }; +` + + // Create a main script for GitHub Script mode + mainContent := `const { createIssue } = require('./helper.cjs'); + +async function main() { + await createIssue('Test Issue'); + core.info('Issue created'); +} + +main(); +` + + sources := map[string]string{ + "helper.cjs": helperContent, + } + + // This should succeed because both use GitHub Script APIs + bundled, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeGitHubScript) + if err != nil { + t.Errorf("Expected no error when bundling GitHub Script helper in GitHub Script mode, but got: %v", err) + } + + // Verify the helper is included + if !strings.Contains(bundled, "function createIssue") { + t.Error("Bundled output does not contain createIssue function") + } +} + +func TestValidateNoRuntimeMixing_TransitiveDependency(t *testing.T) { + // Create a Node.js-only utility + utilContent := `const { execSync } = require('child_process'); + +function exec(cmd) { + return execSync(cmd).toString(); +} + +module.exports = { exec }; +` + + // Create a helper that uses the utility + helperContent := `const { exec } = require('./util.cjs'); + +function runTest() { + return exec('echo test'); +} + +module.exports = { runTest }; +` + + // Create a main script in GitHub Script mode + mainContent := `const { runTest } = require('./helper.cjs'); + +function main() { + core.info(runTest()); +} + +main(); +` + + sources := map[string]string{ + "util.cjs": utilContent, + "helper.cjs": helperContent, + } + + // This should fail because of transitive Node.js dependency + _, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeGitHubScript) + if err == nil { + t.Error("Expected error when bundling script with transitive Node.js dependency in GitHub Script mode") + } + + // Check error message mentions runtime conflict + if !strings.Contains(err.Error(), "runtime mode conflict") { + t.Errorf("Error should mention runtime mode conflict, got: %v", err) + } +} diff --git a/pkg/workflow/bundler_test.go b/pkg/workflow/bundler_test.go index dece601de03..7fdc285d4d0 100644 --- a/pkg/workflow/bundler_test.go +++ b/pkg/workflow/bundler_test.go @@ -653,9 +653,9 @@ main(); "file2.cjs": file2, } - bundled, err := BundleJavaScriptFromSources(mainContent, sources, "") + bundled, err := BundleJavaScriptWithMode(mainContent, sources, "", RuntimeModeNodeJS) if err != nil { - t.Fatalf("BundleJavaScriptFromSources failed: %v", err) + t.Fatalf("BundleJavaScriptWithMode failed: %v", err) } // Check that the bundled code contains a merged require statement diff --git a/pkg/workflow/bundler_validation.go b/pkg/workflow/bundler_validation.go index 67c8a0de2e7..edcfdf8dc88 100644 --- a/pkg/workflow/bundler_validation.go +++ b/pkg/workflow/bundler_validation.go @@ -314,6 +314,127 @@ func validateNoGitHubScriptGlobals(scriptName string, content string, mode Runti return nil } +// validateNoRuntimeMixing checks that all files being bundled are compatible with the target runtime mode +// This prevents mixing nodejs-only scripts (that use child_process) with github-script scripts +// Returns an error if incompatible runtime modes are detected +func validateNoRuntimeMixing(mainScript string, sources map[string]string, targetMode RuntimeMode) error { + bundlerValidationLog.Printf("Validating runtime mode compatibility: target_mode=%s", targetMode) + + // Track which files have been checked to avoid redundant checks + checked := make(map[string]bool) + + // Recursively validate the main script and its dependencies + return validateRuntimeModeRecursive(mainScript, "", sources, targetMode, checked) +} + +// validateRuntimeModeRecursive recursively validates that all required files are compatible with the target runtime mode +func validateRuntimeModeRecursive(content string, currentPath string, sources map[string]string, targetMode RuntimeMode, checked map[string]bool) error { + // Extract all local require statements + requireRegex := regexp.MustCompile(`require\(['"](\.\.?/[^'"]+)['"]\)`) + matches := requireRegex.FindAllStringSubmatch(content, -1) + + for _, match := range matches { + if len(match) <= 1 { + continue + } + + requirePath := match[1] + + // Resolve the full path + var fullPath string + if currentPath == "" { + fullPath = requirePath + } else { + fullPath = currentPath + "/" + requirePath + } + + // Ensure .cjs extension + if !strings.HasSuffix(fullPath, ".cjs") && !strings.HasSuffix(fullPath, ".js") { + fullPath += ".cjs" + } + + // Normalize the path + fullPath = normalizePath(fullPath) + + // Skip if already checked + if checked[fullPath] { + continue + } + checked[fullPath] = true + + // Get the required file content + requiredContent, ok := sources[fullPath] + if !ok { + // File not found - this will be caught by other validation + continue + } + + // Detect the runtime mode of the required file + detectedMode := detectRuntimeMode(requiredContent) + + // Check for incompatibility + if detectedMode != RuntimeModeGitHubScript && targetMode != detectedMode { + return fmt.Errorf("runtime mode conflict: script requires '%s' which is a %s script, but the main script is compiled for %s mode.\n\nNode.js scripts cannot be bundled with GitHub Script mode scripts because they use incompatible APIs (e.g., child_process, fs).\n\nTo fix this:\n- Use only GitHub Script compatible scripts (core.*, exec.*, github.*) for GitHub Script mode\n- Or change the main script to Node.js mode if it needs Node.js APIs", + fullPath, detectedMode, targetMode) + } + + // Recursively check the required file's dependencies + requiredDir := "" + if strings.Contains(fullPath, "/") { + parts := strings.Split(fullPath, "/") + requiredDir = strings.Join(parts[:len(parts)-1], "/") + } + + if err := validateRuntimeModeRecursive(requiredContent, requiredDir, sources, targetMode, checked); err != nil { + return err + } + } + + return nil +} + +// detectRuntimeMode attempts to detect the intended runtime mode of a JavaScript file +// by analyzing its content for runtime-specific patterns. +// This is used to detect if a LOCAL file being bundled is incompatible with the target mode. +func detectRuntimeMode(content string) RuntimeMode { + // Check for Node.js-specific APIs that are CALLED in the code + // These indicate the script uses Node.js-only functionality + // Note: We only check for APIs that are fundamentally incompatible with github-script, + // specifically child_process APIs like execSync/spawnSync + nodeOnlyPatterns := []string{ + `\bexecSync\s*\(`, // execSync function call + `\bspawnSync\s*\(`, // spawnSync function call + } + + for _, pattern := range nodeOnlyPatterns { + matched, _ := regexp.MatchString(pattern, content) + if matched { + bundlerValidationLog.Printf("Detected Node.js mode: pattern '%s' found", pattern) + return RuntimeModeNodeJS + } + } + + // Check for github-script specific APIs + // These indicate the script is intended for GitHub Script mode + githubScriptPatterns := []string{ + `\bcore\.\w+`, // @actions/core + `\bgithub\.\w+`, // github context + } + + for _, pattern := range githubScriptPatterns { + matched, _ := regexp.MatchString(pattern, content) + if matched { + bundlerValidationLog.Printf("Detected GitHub Script mode: pattern '%s' found", pattern) + return RuntimeModeGitHubScript + } + } + + // If no specific patterns found, assume it's compatible with both (utility/helper functions) + // and return GitHub Script mode as the default/most restrictive + bundlerValidationLog.Print("No runtime-specific patterns found, assuming GitHub Script compatible") + return RuntimeModeGitHubScript +} + // normalizePath normalizes a file path by resolving . and .. components func normalizePath(path string) string { // Split path into parts diff --git a/pkg/workflow/js/collect_ndjson_output.cjs b/pkg/workflow/js/collect_ndjson_output.cjs index 02be002e107..95e74c66104 100644 --- a/pkg/workflow/js/collect_ndjson_output.cjs +++ b/pkg/workflow/js/collect_ndjson_output.cjs @@ -247,7 +247,9 @@ async function main() { // Update item.type to normalized value item.type = itemType; if (!expectedOutputTypes[itemType]) { - core.warning(`[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}`); + core.warning( + `[INGESTION] Line ${i + 1}: Type '${itemType}' not found in expected types: ${JSON.stringify(Object.keys(expectedOutputTypes))}` + ); errors.push(`Line ${i + 1}: Unexpected output type '${itemType}'. Expected one of: ${Object.keys(expectedOutputTypes).join(", ")}`); continue; }