diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 5a7adeeee00..30cf2f511b5 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"be57566a84f0e8ad718579e92de26e7263b7e450fec93a61c1a3813cfbef56df","body_hash":"30d40738b32791caae633af85d6d2bb8aac971f646c1bab499220afd3c17b8a2","agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"be57566a84f0e8ad718579e92de26e7263b7e450fec93a61c1a3813cfbef56df","body_hash":"30d40738b32791caae633af85d6d2bb8aac971f646c1bab499220afd3c17b8a2","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_issue"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -162,7 +162,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_FRONTMATTER_EMOJI: "โœ๏ธ" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | @@ -172,11 +172,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/blog-auditor.lock.yml b/.github/workflows/blog-auditor.lock.yml index acfa084e8b3..53a9c8e95f1 100644 --- a/.github/workflows/blog-auditor.lock.yml +++ b/.github/workflows/blog-auditor.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"867031d54f72663135c068879eb9696cce12d8c0b079bbbbf11b14df59b91bc4","body_hash":"c218bd9f70b366d3252594a8ad1ba62bea5be8799b839bf6ac1b55840af391fe","agent_id":"claude","engine_versions":{"claude":"2.1.237"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"867031d54f72663135c068879eb9696cce12d8c0b079bbbbf11b14df59b91bc4","body_hash":"c218bd9f70b366d3252594a8ad1ba62bea5be8799b839bf6ac1b55840af391fe","strict":true,"agent_id":"claude","engine_versions":{"claude":"2.1.237"}} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -159,7 +159,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ“" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -170,11 +170,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/cli-consistency-checker.lock.yml b/.github/workflows/cli-consistency-checker.lock.yml index 6896a9e5211..395390dbc2c 100644 --- a/.github/workflows/cli-consistency-checker.lock.yml +++ b/.github/workflows/cli-consistency-checker.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5622d03f61e8ab47358e2caf9339fb0678da4593b665b7c6e8bafbbc09229a0c","body_hash":"c3e994dad61c9d825aa7f7c1b745793e15d10fd48c2ccc419e3b15d819c2b430","agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5622d03f61e8ab47358e2caf9339fb0678da4593b665b7c6e8bafbbc09229a0c","body_hash":"c3e994dad61c9d825aa7f7c1b745793e15d10fd48c2ccc419e3b15d819c2b430","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_issue","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -152,7 +152,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_FRONTMATTER_EMOJI: "โœ…" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -163,11 +163,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index 7b5110678c9..17ba4b74f8c 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"c30ac91d1d0c402bc4e262f0b3d5b334ec35381a1acb3df78833b9e42f5c1d8c","body_hash":"e806f8a1ca149e0e38ec6000ffe8856c8dfbc37126c9a108bf4a6afab11b89b5","agent_id":"claude","engine_versions":{"claude":"2.1.237"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"c30ac91d1d0c402bc4e262f0b3d5b334ec35381a1acb3df78833b9e42f5c1d8c","body_hash":"e806f8a1ca149e0e38ec6000ffe8856c8dfbc37126c9a108bf4a6afab11b89b5","strict":true,"agent_id":"claude","engine_versions":{"claude":"2.1.237"}} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_issue","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -157,7 +157,7 @@ jobs: GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ”ข" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -168,11 +168,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index 972ab4c78c1..07dc7b56fb8 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"47dbb72084b5abad6ec5293337db252d600f80f6e9fa090e91ea099b5a0d0cb2","body_hash":"cfe64a75cb6f86e82204447143976d2ff91a4820b1e6108a5cdb43dd3e7d15c3","agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"47dbb72084b5abad6ec5293337db252d600f80f6e9fa090e91ea099b5a0d0cb2","body_hash":"cfe64a75cb6f86e82204447143976d2ff91a4820b1e6108a5cdb43dd3e7d15c3","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"}],"mcp_servers":[{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -156,7 +156,7 @@ jobs: GH_AW_INFO_AGENT_RUNTIME: "" GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ“Š" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -167,11 +167,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/daily-team-evolution-insights.lock.yml b/.github/workflows/daily-team-evolution-insights.lock.yml index 167ae42554d..4205a3e2b7f 100644 --- a/.github/workflows/daily-team-evolution-insights.lock.yml +++ b/.github/workflows/daily-team-evolution-insights.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2d0f779aaf8f7164d73363bd00b226c0ffb9138298fa71e22f4d4f95107f0bf0","body_hash":"1572e54b8a5340cd1eca0454a579e520b856fac10d8826f3eadd3cc63d1fb376","agent_id":"goose","agent_model":"copilot/claude-sonnet-4.5","engine_versions":{"goose":"1.45.0"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"2d0f779aaf8f7164d73363bd00b226c0ffb9138298fa71e22f4d4f95107f0bf0","body_hash":"1572e54b8a5340cd1eca0454a579e520b856fac10d8826f3eadd3cc63d1fb376","strict":true,"agent_id":"goose","agent_model":"copilot/claude-sonnet-4.5","engine_versions":{"goose":"1.45.0"}} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -154,7 +154,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ“Š" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -165,11 +165,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 5127621d6fa..457eec01f12 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9ea4a7e6f815b72e623c13c8c0d8840935f80821a068d5cf412cae622c611d58","body_hash":"8a03ac2d1f92d6410a68f2e84d24acc9baa720ebd5309d2732f5da0239339f83","agent_id":"codex","agent_model":"gpt-5.4","engine_versions":{"codex":"0.148.0"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9ea4a7e6f815b72e623c13c8c0d8840935f80821a068d5cf412cae622c611d58","body_hash":"8a03ac2d1f92d6410a68f2e84d24acc9baa720ebd5309d2732f5da0239339f83","strict":true,"agent_id":"codex","agent_model":"gpt-5.4","engine_versions":{"codex":"0.148.0"}} # gh-aw-manifest: {"version":1,"secrets":["CODEX_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.4","digest":"sha256:7ad9113203642c5b12303b97e221fc6b5dd0fb0655c09a2eba9d5c6fa3201a3b","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.28.4@sha256:7ad9113203642c5b12303b97e221fc6b5dd0fb0655c09a2eba9d5c6fa3201a3b"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"safeoutputs","tools":["create_issue","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -175,7 +175,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ’ป" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | @@ -185,11 +185,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/example-permissions-warning.lock.yml b/.github/workflows/example-permissions-warning.lock.yml index 3486a1dc031..5214d1df396 100644 --- a/.github/workflows/example-permissions-warning.lock.yml +++ b/.github/workflows/example-permissions-warning.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"3081a53a364f2fe6eda3086c877ca6046d453e0092c0eb1374703ffd56ece777","body_hash":"e1998198345ea79225db083490d051afef427544d6528377b8556a3cb4638d22","agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"3081a53a364f2fe6eda3086c877ca6046d453e0092c0eb1374703ffd56ece777","body_hash":"e1998198345ea79225db083490d051afef427544d6528377b8556a3cb4638d22","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_issue"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -150,7 +150,7 @@ jobs: GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_FRONTMATTER_EMOJI: "โš ๏ธ" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | @@ -160,11 +160,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/gpclean.lock.yml b/.github/workflows/gpclean.lock.yml index 2a1f2220563..1fdbfb5d815 100644 --- a/.github/workflows/gpclean.lock.yml +++ b/.github/workflows/gpclean.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e4c3e81303647b24ae34d57155b8443abb752d176842d02cd3b3479853406b02","body_hash":"9a319e8c129ca199af41fd0816dc41f10994ae38a6a37c2c2cf0a82f9d9ebf54","agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e4c3e81303647b24ae34d57155b8443abb752d176842d02cd3b3479853406b02","body_hash":"9a319e8c129ca199af41fd0816dc41f10994ae38a6a37c2c2cf0a82f9d9ebf54","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["create_issue","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -157,7 +157,7 @@ jobs: GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿงน" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | @@ -167,11 +167,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 7e745c8e8d9..13adbeb2cde 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e0997d32f92614ebb3575495f8e36f304de2c7421545a79f0cfab26c5891380a","body_hash":"42daae928c8295891472e702ddec1ad8479ca526a291e5a9db7f7f89037a8b94","agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e0997d32f92614ebb3575495f8e36f304de2c7421545a79f0cfab26c5891380a","body_hash":"42daae928c8295891472e702ddec1ad8479ca526a291e5a9db7f7f89037a8b94","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.80","copilot-sdk":"1.0.11"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","DD_API_KEY","DD_APPLICATION_KEY","DD_APP_KEY","DD_SITE","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN","SENTRY_ACCESS_TOKEN","SENTRY_OPENAI_API_KEY","SLACK_BOT_TOKEN","TAVILY_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/setup-buildx-action","sha":"37fe631027851001ddb9b187196cc803df7f5f0e","version":"v4.3.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4","digest":"sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.4@sha256:8f18587981eff7e6291784200a88a7191d23bfd8f5723db848c640d6b4e88e46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4","digest":"sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.4@sha256:64e668297d1b9d83ee102626e104c054ac2cf5cfd7225bf6e144f86962229882"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4","digest":"sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.4@sha256:35953d0beac18f642aa0bc98bb726a85288539b1fc630c16e94da33300058258"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0d9f1fb5fd6610c0ac1f5194a38e45a8a1e81f8a390d5142d8e4e6f26a4b3196"},{"image":"ghcr.io/github/github-mcp-server:v1.10.0","digest":"sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c","pinned_image":"ghcr.io/github/github-mcp-server:v1.10.0@sha256:097512ddf58af80a620c177ae9cad93448f9a2a55c70ee8fde5cec6714522a8c"},{"image":"ghcr.io/oraios/serena:latest","digest":"sha256:0944b2ffe66dbcddeed531694b6819d7f9efd8125b442b282a1cc863f570a03e","pinned_image":"ghcr.io/oraios/serena:latest@sha256:0944b2ffe66dbcddeed531694b6819d7f9efd8125b442b282a1cc863f570a03e"},{"image":"node:lts-alpine","digest":"sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43","pinned_image":"node:lts-alpine@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43"}],"mcp_servers":[{"name":"agenticworkflows","tools":["*"]},{"name":"ast-grep","tools":["*"]},{"name":"datadog","tools":["get_datadog_metric","get_datadog_trace","search_datadog_dashboards","search_datadog_metrics","search_datadog_slos","search_datadog_spans"]},{"name":"deepwiki","tools":["ask_question","read_wiki_contents","read_wiki_structure"]},{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"microsoftdocs","tools":["*"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop","post_to_slack_channel"]},{"name":"sentry","tools":["analyze_issue_with_seer","find_dsns","find_organizations","find_projects","find_releases","find_teams","get_doc","get_event_attachment","get_issue_details","get_trace_details","list_events","list_issue_events","search_docs","search_events","search_issues","whoami"]},{"name":"serena","tools":["*"]},{"name":"tavily","tools":["*"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -179,7 +179,7 @@ jobs: GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" GH_AW_INFO_CACHE_MEMORY: "true" GH_AW_INFO_FRONTMATTER_EMOJI: "๐Ÿ”" - GH_AW_COMPILED_STRICT: "false" + GH_AW_COMPILED_STRICT: "true" GH_AW_INFO_FEATURES: '{"gh-aw-detection":true}' uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -190,11 +190,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'generate_aw_info.cjs')); await main(core, context); - - name: Enforce strict mode policy - if: ${{ vars.GH_AW_POLICY_STRICT == 'true' }} - run: | - echo "::error::GH_AW_POLICY_STRICT=true but this workflow was not compiled in strict mode. Recompile with --strict or strict: true." - exit 1 - name: Restore daily AIC usage cache id: restore-daily-aic-cache if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }} diff --git a/pkg/parser/inline_skill_extractor.go b/pkg/parser/inline_skill_extractor.go index 5895e1a5585..f5bc144d85f 100644 --- a/pkg/parser/inline_skill_extractor.go +++ b/pkg/parser/inline_skill_extractor.go @@ -90,7 +90,7 @@ func ExtractInlineSkills(markdown string) (mainMarkdown string, skills []InlineS allStarts := inlineSkillSeparatorRegex.FindAllStringSubmatchIndex(markdown, -1) if len(allStarts) == 0 { if err := validateNoInlineSectionEndMarkers(markdown, inlineSkillEndRegex); err != nil { - return "", nil, fmt.Errorf("invalid inline skill end marker: %w", err) + return "", nil, fmt.Errorf("inline skill end marker should reference a valid skill name: %w", err) } inlineSkillLog.Print("No inline skill markers found") return markdown, nil, nil @@ -106,7 +106,7 @@ func ExtractInlineSkills(markdown string) (mainMarkdown string, skills []InlineS return InlineSkill{Name: name, Content: content} }) if err != nil { - return "", nil, fmt.Errorf("invalid inline skill end marker: %w", err) + return "", nil, fmt.Errorf("inline skill end marker should reference a valid skill name: %w", err) } inlineSkillLog.Printf("Extraction complete: %d skill(s), main markdown length: %d", len(skills), len(mainMarkdown)) return mainMarkdown, skills, nil @@ -115,6 +115,11 @@ func ExtractInlineSkills(markdown string) (mainMarkdown string, skills []InlineS func validateUniqueInlineSkillNames(markdown string, allStarts [][]int) error { return validateUniqueInlineSectionNames(markdown, allStarts, func(name string) error { inlineSkillLog.Printf("Duplicate inline skill name: %q", name) - return fmt.Errorf("duplicate inline skill name %q", name) + return NewValidationError( + "skills", + name, + "duplicate name already defined", + fmt.Sprintf("Rename one of the duplicate skills or remove the extra `%s` definition.", name), + ) }) } diff --git a/pkg/parser/inline_skill_extractor_test.go b/pkg/parser/inline_skill_extractor_test.go index 17cff2e77de..acfda60f6a2 100644 --- a/pkg/parser/inline_skill_extractor_test.go +++ b/pkg/parser/inline_skill_extractor_test.go @@ -177,7 +177,10 @@ func TestExtractInlineSkills_DuplicateNameError(t *testing.T) { _, _, err := ExtractInlineSkills(markdown) require.Error(t, err, "duplicate skill name should produce an error") - require.ErrorContains(t, err, "duplicate", "error should mention duplicate") + require.ErrorContains(t, err, "Validation failed for field 'skills'") + require.ErrorContains(t, err, "Value: planner") + require.ErrorContains(t, err, "Reason: duplicate name already defined") + require.ErrorContains(t, err, "Suggestion: Rename one of the duplicate skills or remove the extra `planner` definition.") require.ErrorContains(t, err, "planner", "error should include the duplicate name") } diff --git a/pkg/parser/sub_agent_extractor.go b/pkg/parser/sub_agent_extractor.go index 362cf290b8d..f4f8501d818 100644 --- a/pkg/parser/sub_agent_extractor.go +++ b/pkg/parser/sub_agent_extractor.go @@ -210,7 +210,7 @@ func ExtractInlineSubAgents(markdown string) (mainMarkdown string, agents []Inli allStarts := subAgentSeparatorRegex.FindAllStringSubmatchIndex(markdown, -1) if len(allStarts) == 0 { if err := validateNoInlineSectionEndMarkers(markdown, subAgentEndRegex); err != nil { - return "", nil, fmt.Errorf("invalid inline sub-agent end marker: %w", err) + return "", nil, fmt.Errorf("inline sub-agent end marker should reference a valid sub-agent name: %w", err) } subAgentLog.Print("No inline sub-agent markers found") return markdown, nil, nil @@ -226,7 +226,7 @@ func ExtractInlineSubAgents(markdown string) (mainMarkdown string, agents []Inli return InlineSubAgent{Name: name, Content: content} }) if err != nil { - return "", nil, fmt.Errorf("invalid inline sub-agent end marker: %w", err) + return "", nil, fmt.Errorf("inline sub-agent end marker should reference a valid sub-agent name: %w", err) } subAgentLog.Printf("Extraction complete: %d sub-agent(s), main markdown length: %d", len(agents), len(mainMarkdown)) return mainMarkdown, agents, nil @@ -235,6 +235,11 @@ func ExtractInlineSubAgents(markdown string) (mainMarkdown string, agents []Inli func validateUniqueSubAgentNames(markdown string, allStarts [][]int) error { return validateUniqueInlineSectionNames(markdown, allStarts, func(name string) error { subAgentLog.Printf("Duplicate sub-agent name: %q", name) - return fmt.Errorf("duplicate inline sub-agent name %q", name) + return NewValidationError( + "sub-agents", + name, + "duplicate name already defined", + fmt.Sprintf("Rename one of the duplicate sub-agents or remove the extra `%s` definition.", name), + ) }) } diff --git a/pkg/parser/sub_agent_extractor_test.go b/pkg/parser/sub_agent_extractor_test.go index a579bd7458e..b24975e9b94 100644 --- a/pkg/parser/sub_agent_extractor_test.go +++ b/pkg/parser/sub_agent_extractor_test.go @@ -214,7 +214,10 @@ func TestExtractInlineSubAgents_DuplicateNameError(t *testing.T) { _, _, err := ExtractInlineSubAgents(markdown) require.Error(t, err, "duplicate agent name should produce an error") - require.ErrorContains(t, err, "duplicate", "error should mention duplicate") + require.ErrorContains(t, err, "Validation failed for field 'sub-agents'") + require.ErrorContains(t, err, "Value: planner") + require.ErrorContains(t, err, "Reason: duplicate name already defined") + require.ErrorContains(t, err, "Suggestion: Rename one of the duplicate sub-agents or remove the extra `planner` definition.") require.ErrorContains(t, err, "planner", "error should include the duplicate name") } diff --git a/pkg/parser/validation_error.go b/pkg/parser/validation_error.go new file mode 100644 index 00000000000..162626a4c4a --- /dev/null +++ b/pkg/parser/validation_error.go @@ -0,0 +1,32 @@ +package parser + +import ( + "fmt" + + "github.com/github/gh-aw/pkg/validationerror" +) + +// ValidationError represents an input validation error in parser package checks. +// It embeds validationerror.Payload so callers can uniformly detect structured +// validation errors from any package via errors.As(err, &validationerror.ValidationError). +type ValidationError struct { + validationerror.Payload +} + +// Error implements the error interface. +func (e *ValidationError) Error() string { + header := fmt.Sprintf("Validation failed for field '%s'", e.Field) + return validationerror.Format(header, e.Payload, false) +} + +// NewValidationError creates a new parser validation error with context. +func NewValidationError(field, value, reason, suggestion string) *ValidationError { + return &ValidationError{ + Payload: validationerror.Payload{ + Field: field, + Value: value, + Reason: reason, + Suggestion: suggestion, + }, + } +} diff --git a/pkg/validationerror/validationerror.go b/pkg/validationerror/validationerror.go new file mode 100644 index 00000000000..612dccc2777 --- /dev/null +++ b/pkg/validationerror/validationerror.go @@ -0,0 +1,79 @@ +// Package validationerror provides a shared, dependency-neutral payload and +// message formatting for structured field/value/reason/suggestion validation +// errors. Packages such as parser and workflow embed Payload in their own +// error types so that: +// - the message formatting logic (including value truncation) lives in one +// place and future fixes don't need to be duplicated per package, and +// - callers can uniformly detect any structured validation error with +// errors.As(err, &validationerror.ValidationError) regardless of which +// package produced it. +package validationerror + +import ( + "fmt" + "strings" + + "github.com/github/gh-aw/pkg/stringutil" +) + +// MaxValueLength is the maximum number of characters kept for the Value field +// when formatting a message with value truncation enabled. +const MaxValueLength = 100 + +// Payload holds the common field/value/reason/suggestion data shared by +// structured validation errors across packages. +type Payload struct { + Field string + Value string + Reason string + Suggestion string +} + +// ValidationField returns the name of the field that failed validation. +func (p Payload) ValidationField() string { return p.Field } + +// ValidationValue returns the offending value, if any. +func (p Payload) ValidationValue() string { return p.Value } + +// ValidationReason returns the reason validation failed. +func (p Payload) ValidationReason() string { return p.Reason } + +// ValidationSuggestion returns actionable remediation guidance, if any. +func (p Payload) ValidationSuggestion() string { return p.Suggestion } + +// ValidationError is the common interface implemented by structured +// field/value/reason/suggestion validation errors across packages (for +// example parser.ValidationError and workflow.WorkflowValidationError). +// Use errors.As(err, &target) with a variable of this interface type to +// uniformly extract validation details regardless of the concrete type. +type ValidationError interface { + error + ValidationField() string + ValidationValue() string + ValidationReason() string + ValidationSuggestion() string +} + +// Format renders header followed by the payload's value/reason/suggestion in +// a deterministic multi-line shape. When truncateValue is true, Value is +// truncated to MaxValueLength before being included. +func Format(header string, p Payload, truncateValue bool) string { + var b strings.Builder + b.WriteString(header) + + if p.Value != "" { + value := p.Value + if truncateValue { + value = stringutil.Truncate(value, MaxValueLength) + } + fmt.Fprintf(&b, "\n\nValue: %s", value) + } + + fmt.Fprintf(&b, "\nReason: %s", p.Reason) + + if p.Suggestion != "" { + fmt.Fprintf(&b, "\nSuggestion: %s", p.Suggestion) + } + + return b.String() +} diff --git a/pkg/validationerror/validationerror_test.go b/pkg/validationerror/validationerror_test.go new file mode 100644 index 00000000000..548439aa1e2 --- /dev/null +++ b/pkg/validationerror/validationerror_test.go @@ -0,0 +1,90 @@ +//go:build !integration + +package validationerror_test + +import ( + "errors" + "fmt" + "strings" + "testing" + + "github.com/github/gh-aw/pkg/validationerror" +) + +// exampleError is a minimal concrete type embedding validationerror.Payload, +// mirroring how parser.ValidationError and workflow.WorkflowValidationError +// each embed the shared payload. +type exampleError struct { + validationerror.Payload +} + +func (e *exampleError) Error() string { + return validationerror.Format(fmt.Sprintf("Validation failed for field '%s'", e.Field), e.Payload, false) +} + +func TestFormat_IncludesValueReasonAndSuggestion(t *testing.T) { + msg := validationerror.Format("Validation failed for field 'skills'", validationerror.Payload{ + Field: "skills", + Value: "docs", + Reason: "duplicate name already defined", + Suggestion: "Rename one of the duplicate skills or remove the extra `docs` definition.", + }, false) + + for _, want := range []string{ + "Validation failed for field 'skills'", + "Value: docs", + "Reason: duplicate name already defined", + "Suggestion: Rename one of the duplicate skills", + } { + if !strings.Contains(msg, want) { + t.Errorf("expected formatted message to contain %q, got: %s", want, msg) + } + } +} + +func TestFormat_TruncatesValueWhenRequested(t *testing.T) { + longValue := strings.Repeat("x", 200) + msg := validationerror.Format("header", validationerror.Payload{Value: longValue, Reason: "reason"}, true) + + if strings.Contains(msg, longValue) { + t.Errorf("expected long value to be truncated, got: %s", msg) + } +} + +func TestFormat_OmitsEmptyValueAndSuggestion(t *testing.T) { + msg := validationerror.Format("header", validationerror.Payload{Reason: "reason only"}, false) + + if strings.Contains(msg, "Value:") { + t.Errorf("expected no Value section for empty value, got: %s", msg) + } + if strings.Contains(msg, "Suggestion:") { + t.Errorf("expected no Suggestion section for empty suggestion, got: %s", msg) + } +} + +func TestValidationError_ErrorsAsWorksAcrossConcreteTypes(t *testing.T) { + err := error(&exampleError{Payload: validationerror.Payload{ + Field: "skills", + Value: "docs", + Reason: "duplicate name already defined", + Suggestion: "Rename one of the duplicate skills.", + }}) + + var ve validationerror.ValidationError + if !errors.As(err, &ve) { + t.Fatalf("expected errors.As to match validationerror.ValidationError interface") + } + + if ve.ValidationField() != "skills" { + t.Errorf("expected field 'skills', got %q", ve.ValidationField()) + } + if ve.ValidationValue() != "docs" { + t.Errorf("expected value 'docs', got %q", ve.ValidationValue()) + } + if ve.ValidationReason() != "duplicate name already defined" { + t.Errorf("expected reason 'duplicate name already defined', got %q", ve.ValidationReason()) + } + if ve.ValidationSuggestion() == "" { + t.Error("expected non-empty suggestion") + } +} diff --git a/pkg/workflow/compiler_error_formatting_test.go b/pkg/workflow/compiler_error_formatting_test.go index 1bbf75fd723..7c321e20a3a 100644 --- a/pkg/workflow/compiler_error_formatting_test.go +++ b/pkg/workflow/compiler_error_formatting_test.go @@ -9,6 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/github/gh-aw/pkg/validationerror" ) // TestFormatCompilerError tests the formatCompilerError helper function @@ -242,7 +244,7 @@ func TestFormatCompilerError_NilCause(t *testing.T) { // to 1:1. func TestFormatCompilerError_UsesLocationFromValidationError(t *testing.T) { t.Run("uses line and column from validation error", func(t *testing.T) { - vErr := &WorkflowValidationError{Field: "engine", Value: "copiliot", Reason: "not a valid engine", Suggestion: "Did you mean 'copilot'?", File: "workflow.md", Line: 15, Column: 3} + vErr := &WorkflowValidationError{Payload: validationerror.Payload{Field: "engine", Value: "copiliot", Reason: "not a valid engine", Suggestion: "Did you mean 'copilot'?"}, File: "workflow.md", Line: 15, Column: 3} wrapped := formatCompilerError("workflow.md", "error", vErr.Error(), vErr) require.Error(t, wrapped) @@ -256,7 +258,7 @@ func TestFormatCompilerError_UsesLocationFromValidationError(t *testing.T) { }) t.Run("uses file from validation error when different from filePath", func(t *testing.T) { - vErr := &WorkflowValidationError{Field: "concurrency", Value: "invalid", Reason: "reason", File: "actual-source.md", Line: 7, Column: 1} + vErr := &WorkflowValidationError{Payload: validationerror.Payload{Field: "concurrency", Value: "invalid", Reason: "reason"}, File: "actual-source.md", Line: 7, Column: 1} wrapped := formatCompilerError("other.md", "error", vErr.Error(), vErr) require.Error(t, wrapped) diff --git a/pkg/workflow/error_recovery_test.go b/pkg/workflow/error_recovery_test.go index 50b76aa3f7d..0944adeac60 100644 --- a/pkg/workflow/error_recovery_test.go +++ b/pkg/workflow/error_recovery_test.go @@ -8,6 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/github/gh-aw/pkg/parser" + "github.com/github/gh-aw/pkg/validationerror" ) func TestExpandErrorMessages_UnwrapsJoinedErrors(t *testing.T) { @@ -90,6 +93,22 @@ func TestNewValidationError_ClassifiesSeverity(t *testing.T) { assert.Equal(t, "permissions", err.Category, "Network strict-mode errors should be categorized as permissions") } +// TestValidationError_UniformAcrossPackages verifies that workflow.WorkflowValidationError +// and parser.ValidationError can both be detected uniformly via +// errors.As(err, &validationerror.ValidationError), since both embed +// validationerror.Payload. +func TestValidationError_UniformAcrossPackages(t *testing.T) { + workflowErr := error(NewValidationError("engine", "copiliot", "not a valid engine", "Did you mean 'copilot'?")) + parserErr := error(parser.NewValidationError("skills", "docs", "duplicate name already defined", "Rename one of the duplicate skills.")) + + for _, err := range []error{workflowErr, parserErr} { + var ve validationerror.ValidationError + require.ErrorAs(t, err, &ve, "expected errors.As to match validationerror.ValidationError for %T", err) + assert.NotEmpty(t, ve.ValidationField()) + assert.NotEmpty(t, ve.ValidationReason()) + } +} + func TestBuildPrioritizedErrorReportFromMessages_DuplicateKeyErrorsGetSpecificSuggestion(t *testing.T) { message := `/tmp/smoke-gemini-duplicate-engine.md:10:1: error: mapping key "engine" already defined at [7:1] 7 | engine: diff --git a/pkg/workflow/workflow_errors.go b/pkg/workflow/workflow_errors.go index bf951fff4ed..259fcd0974c 100644 --- a/pkg/workflow/workflow_errors.go +++ b/pkg/workflow/workflow_errors.go @@ -26,6 +26,7 @@ import ( "github.com/github/gh-aw/pkg/console" "github.com/github/gh-aw/pkg/logger" "github.com/github/gh-aw/pkg/stringutil" + "github.com/github/gh-aw/pkg/validationerror" ) var errorHelpersLog = logger.New("workflow:error_helpers") @@ -34,15 +35,14 @@ var errorHelpersLog = logger.New("workflow:error_helpers") // File and Line are optional; zero values mean "location unknown". type FieldLocation = console.ErrorPosition -// WorkflowValidationError represents an error that occurred during input validation +// WorkflowValidationError represents an error that occurred during input validation. +// It embeds validationerror.Payload so callers can uniformly detect structured +// validation errors from any package via errors.As(err, &validationerror.ValidationError). type WorkflowValidationError struct { - Field string - Value string - Reason string - Suggestion string - Severity ErrorSeverity - Category string - Timestamp time.Time + validationerror.Payload + Severity ErrorSeverity + Category string + Timestamp time.Time // Location context (optional โ€” zero values mean location unknown) File string Line int @@ -51,30 +51,16 @@ type WorkflowValidationError struct { // Error implements the error interface func (e *WorkflowValidationError) Error() string { - var b strings.Builder - + var header string if e.Line > 0 { // When a source location is known, omit the timestamp so the compiler's // file:line:col: prefix is not cluttered with a redundant timestamp. - fmt.Fprintf(&b, "Validation failed for field '%s'", e.Field) + header = fmt.Sprintf("Validation failed for field '%s'", e.Field) } else { - fmt.Fprintf(&b, "[%s] Validation failed for field '%s'", + header = fmt.Sprintf("[%s] Validation failed for field '%s'", e.Timestamp.Format(time.RFC3339), e.Field) } - - if e.Value != "" { - // Truncate long values - truncatedValue := stringutil.Truncate(e.Value, 100) - fmt.Fprintf(&b, "\n\nValue: %s", truncatedValue) - } - - fmt.Fprintf(&b, "\nReason: %s", e.Reason) - - if e.Suggestion != "" { - fmt.Fprintf(&b, "\nSuggestion: %s", e.Suggestion) - } - - return b.String() + return validationerror.Format(header, e.Payload, true) } // NewValidationError creates a new validation error with context @@ -84,13 +70,15 @@ func NewValidationError(field, value, reason, suggestion string) *WorkflowValida } severity, category := classifyValidationSeverity(field, reason) return &WorkflowValidationError{ - Field: field, - Value: value, - Reason: reason, - Suggestion: suggestion, - Severity: severity, - Category: category, - Timestamp: time.Now(), + Payload: validationerror.Payload{ + Field: field, + Value: value, + Reason: reason, + Suggestion: suggestion, + }, + Severity: severity, + Category: category, + Timestamp: time.Now(), } }