From 11be488b4cd88aadb32df184580f57d3e56dfe92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:12:15 +0000 Subject: [PATCH 1/5] Initial plan From 2099bb5a1c3b8814827a4ffc589dd8bf7ed2e516 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:19:00 +0000 Subject: [PATCH 2/5] Initial analysis of agent identifier extraction issue Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/release.lock.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index a73e0604740..160a26701ef 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6119,19 +6119,19 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 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.20.10 + uses: anchore/sbom-action@fbfd9c6c189226748411491745178e0c2017392d # v0 with: artifact-name: sbom.cdx.json format: cyclonedx-json output-file: sbom.cdx.json - name: Upload SBOM artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: sbom-artifacts path: | From 1e7e608a325e1fdd66def7e374ef80d8c8a3e440 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:21:57 +0000 Subject: [PATCH 3/5] Fix agent identifier extraction to handle .agent.md files Update ExtractAgentIdentifier to strip both .agent.md and .md extensions. This fixes the issue where custom agent files like "speckit-dispatcher.agent.md" were being converted to "speckit-dispatcher.agent" instead of "speckit-dispatcher" when passed to Copilot CLI's --agent flag. - Updated ExtractAgentIdentifier to try .agent.md first, then .md - Added 4 test cases for .agent.md filename pattern - All tests pass including agent import tests - Manually verified speckit-dispatcher workflow compiles correctly Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/speckit-dispatcher.lock.yml | 2 +- pkg/workflow/engine_helpers.go | 9 +++++++-- pkg/workflow/engine_helpers_test.go | 20 +++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/speckit-dispatcher.lock.yml b/.github/workflows/speckit-dispatcher.lock.yml index f231b12e9bd..71d9aba9439 100644 --- a/.github/workflows/speckit-dispatcher.lock.yml +++ b/.github/workflows/speckit-dispatcher.lock.yml @@ -4309,7 +4309,7 @@ jobs: run: | set -o pipefail sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount /tmp:/tmp:rw --mount "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw" --mount /usr/bin/date:/usr/bin/date:ro --mount /usr/bin/gh:/usr/bin/gh:ro --mount /usr/bin/yq:/usr/bin/yq:ro --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,github.com,raw.githubusercontent.com,registry.npmjs.org --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs \ - -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent speckit-dispatcher.agent --allow-tool github --allow-tool safeoutputs --allow-tool 'shell(cat .specify/memory/constitution.md)' --allow-tool 'shell(cat)' --allow-tool 'shell(date)' --allow-tool 'shell(echo)' --allow-tool 'shell(find specs -name '\''plan.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -name '\''spec.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -name '\''tasks.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -type f -name '\''*.md'\'')' --allow-tool 'shell(git branch)' --allow-tool 'shell(git status)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(ls -la .specify/)' --allow-tool 'shell(ls -la specs/)' --allow-tool 'shell(ls)' --allow-tool 'shell(pwd)' --allow-tool 'shell(sort)' --allow-tool 'shell(tail)' --allow-tool 'shell(uniq)' --allow-tool 'shell(wc)' --allow-tool 'shell(yq)' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ + -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent speckit-dispatcher --allow-tool github --allow-tool safeoutputs --allow-tool 'shell(cat .specify/memory/constitution.md)' --allow-tool 'shell(cat)' --allow-tool 'shell(date)' --allow-tool 'shell(echo)' --allow-tool 'shell(find specs -name '\''plan.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -name '\''spec.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -name '\''tasks.md'\'' -exec cat {} \;)' --allow-tool 'shell(find specs -type f -name '\''*.md'\'')' --allow-tool 'shell(git branch)' --allow-tool 'shell(git status)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(ls -la .specify/)' --allow-tool 'shell(ls -la specs/)' --allow-tool 'shell(ls)' --allow-tool 'shell(pwd)' --allow-tool 'shell(sort)' --allow-tool 'shell(tail)' --allow-tool 'shell(uniq)' --allow-tool 'shell(wc)' --allow-tool 'shell(yq)' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ 2>&1 | tee /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE diff --git a/pkg/workflow/engine_helpers.go b/pkg/workflow/engine_helpers.go index 821389e68d1..de87ae3cd99 100644 --- a/pkg/workflow/engine_helpers.go +++ b/pkg/workflow/engine_helpers.go @@ -76,7 +76,7 @@ func GetBaseInstallationSteps(config EngineInstallConfig, workflowData *Workflow // This is used by the Copilot CLI which expects agent identifiers, not full paths. // // Parameters: -// - agentFile: The relative path to the agent file (e.g., ".github/agents/test-agent.md") +// - agentFile: The relative path to the agent file (e.g., ".github/agents/test-agent.md" or ".github/agents/test-agent.agent.md") // // Returns: // - string: The agent identifier (e.g., "test-agent") @@ -85,6 +85,9 @@ func GetBaseInstallationSteps(config EngineInstallConfig, workflowData *Workflow // // identifier := ExtractAgentIdentifier(".github/agents/my-agent.md") // // Returns: "my-agent" +// +// identifier := ExtractAgentIdentifier(".github/agents/my-agent.agent.md") +// // Returns: "my-agent" func ExtractAgentIdentifier(agentFile string) string { engineHelpersLog.Printf("Extracting agent identifier from: %s", agentFile) // Extract the base filename from the path @@ -94,7 +97,9 @@ func ExtractAgentIdentifier(agentFile string) string { filename = agentFile[lastSlash+1:] } - // Remove the .md extension using TrimSuffix (unconditionally safe) + // Remove the .agent.md extension first (for custom agent files), then fall back to .md + // This handles both ".agent.md" and ".md" extensions correctly + filename = strings.TrimSuffix(filename, ".agent.md") filename = strings.TrimSuffix(filename, ".md") return filename diff --git a/pkg/workflow/engine_helpers_test.go b/pkg/workflow/engine_helpers_test.go index baef67c61e7..17f834c4646 100644 --- a/pkg/workflow/engine_helpers_test.go +++ b/pkg/workflow/engine_helpers_test.go @@ -249,6 +249,26 @@ func TestExtractAgentIdentifier(t *testing.T) { input: ".github/agents/test-agent", expected: "test-agent", }, + { + name: "custom agent file with .agent.md extension", + input: ".github/agents/speckit-dispatcher.agent.md", + expected: "speckit-dispatcher", + }, + { + name: "custom agent file simple path", + input: ".github/agents/test-agent.agent.md", + expected: "test-agent", + }, + { + name: "custom agent file with path", + input: "../agents/technical-doc-writer.agent.md", + expected: "technical-doc-writer", + }, + { + name: "custom agent file with underscores", + input: ".github/agents/my_custom_agent.agent.md", + expected: "my_custom_agent", + }, } for _, tt := range tests { From 68d45fe83b4db488a7ca028fc5a493412f93cb16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:31:48 +0000 Subject: [PATCH 4/5] Recompile workflows with corrected agent identifiers Recompiled all workflows to apply the agent identifier fix. Agent identifiers in compiled workflows now correctly use: - speckit-dispatcher (was speckit-dispatcher.agent) - technical-doc-writer (was technical-doc-writer.agent) All tests pass and make agent-finish completes successfully. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/glossary-maintainer.lock.yml | 2 +- .github/workflows/technical-doc-writer.lock.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index e831baa1831..112b7d800d0 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -3462,7 +3462,7 @@ jobs: run: | set -o pipefail sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount /tmp:/tmp:rw --mount "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw" --mount /usr/bin/date:/usr/bin/date:ro --mount /usr/bin/gh:/usr/bin/gh:ro --mount /usr/bin/yq:/usr/bin/yq:ro --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs \ - -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent technical-doc-writer.agent --allow-tool github --allow-tool safeoutputs --allow-tool 'shell(cat)' --allow-tool 'shell(date)' --allow-tool 'shell(echo)' --allow-tool 'shell(find docs -name '\''*.md'\'')' --allow-tool 'shell(git add:*)' --allow-tool 'shell(git branch:*)' --allow-tool 'shell(git checkout:*)' --allow-tool 'shell(git commit:*)' --allow-tool 'shell(git log --since='\''24 hours ago'\'' --oneline)' --allow-tool 'shell(git log --since='\''7 days ago'\'' --oneline)' --allow-tool 'shell(git merge:*)' --allow-tool 'shell(git rm:*)' --allow-tool 'shell(git status)' --allow-tool 'shell(git switch:*)' --allow-tool 'shell(grep -r '\''*'\'' docs)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(ls)' --allow-tool 'shell(pwd)' --allow-tool 'shell(sort)' --allow-tool 'shell(tail)' --allow-tool 'shell(uniq)' --allow-tool 'shell(wc)' --allow-tool 'shell(yq)' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ + -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent technical-doc-writer --allow-tool github --allow-tool safeoutputs --allow-tool 'shell(cat)' --allow-tool 'shell(date)' --allow-tool 'shell(echo)' --allow-tool 'shell(find docs -name '\''*.md'\'')' --allow-tool 'shell(git add:*)' --allow-tool 'shell(git branch:*)' --allow-tool 'shell(git checkout:*)' --allow-tool 'shell(git commit:*)' --allow-tool 'shell(git log --since='\''24 hours ago'\'' --oneline)' --allow-tool 'shell(git log --since='\''7 days ago'\'' --oneline)' --allow-tool 'shell(git merge:*)' --allow-tool 'shell(git rm:*)' --allow-tool 'shell(git status)' --allow-tool 'shell(git switch:*)' --allow-tool 'shell(grep -r '\''*'\'' docs)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(ls)' --allow-tool 'shell(pwd)' --allow-tool 'shell(sort)' --allow-tool 'shell(tail)' --allow-tool 'shell(uniq)' --allow-tool 'shell(wc)' --allow-tool 'shell(yq)' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ 2>&1 | tee /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 0cf7d7c535b..2ce9cc1cf77 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -3647,7 +3647,7 @@ jobs: run: | set -o pipefail sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount /tmp:/tmp:rw --mount "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw" --mount /usr/bin/date:/usr/bin/date:ro --mount /usr/bin/gh:/usr/bin/gh:ro --mount /usr/bin/yq:/usr/bin/yq:ro --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.com,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs \ - -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent technical-doc-writer.agent --allow-tool github --allow-tool safeoutputs --allow-tool shell --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ + -- npx -y @github/copilot@0.0.367 --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --agent technical-doc-writer --allow-tool github --allow-tool safeoutputs --allow-tool shell --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"} \ 2>&1 | tee /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE From 478a25259f4e55b1140edf6e2ad7a75ed4f6cbcf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 21:42:04 +0000 Subject: [PATCH 5/5] Add support for trimming .agent extension from agent names Extended ExtractAgentIdentifier to also trim .agent extension (without .md). This makes the function more robust and handles edge cases where agent files might use .agent extension alone. - Added trimming of .agent suffix after .agent.md and .md - Added 2 test cases for .agent extension handling - All tests pass including agent import tests Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/engine_helpers.go | 5 +++-- pkg/workflow/engine_helpers_test.go | 10 ++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pkg/workflow/engine_helpers.go b/pkg/workflow/engine_helpers.go index de87ae3cd99..bf3acaccb7b 100644 --- a/pkg/workflow/engine_helpers.go +++ b/pkg/workflow/engine_helpers.go @@ -97,10 +97,11 @@ func ExtractAgentIdentifier(agentFile string) string { filename = agentFile[lastSlash+1:] } - // Remove the .agent.md extension first (for custom agent files), then fall back to .md - // This handles both ".agent.md" and ".md" extensions correctly + // Remove extensions in order: .agent.md, then .md, then .agent + // This handles all possible agent file naming conventions filename = strings.TrimSuffix(filename, ".agent.md") filename = strings.TrimSuffix(filename, ".md") + filename = strings.TrimSuffix(filename, ".agent") return filename } diff --git a/pkg/workflow/engine_helpers_test.go b/pkg/workflow/engine_helpers_test.go index 17f834c4646..e5bebe6f916 100644 --- a/pkg/workflow/engine_helpers_test.go +++ b/pkg/workflow/engine_helpers_test.go @@ -269,6 +269,16 @@ func TestExtractAgentIdentifier(t *testing.T) { input: ".github/agents/my_custom_agent.agent.md", expected: "my_custom_agent", }, + { + name: "agent file with only .agent extension", + input: ".github/agents/test-agent.agent", + expected: "test-agent", + }, + { + name: "agent file with .agent extension in path", + input: "../agents/my-agent.agent", + expected: "my-agent", + }, } for _, tt := range tests {