diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml
index 53bb61070b1..346734b5c41 100644
--- a/.github/workflows/pdf-summary.lock.yml
+++ b/.github/workflows/pdf-summary.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"f17bccc0ed91e64b7c3cff907b5a513092549fd7d00d1d990492e24515bdf6f1","strict":true,"agent_id":"copilot"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9545894780070d11ad24d202421b7fdb4a8ddddbd3ff48bc964aeebfc7e48932","strict":true,"agent_id":"copilot"}
# 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":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"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":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.46"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.9","digest":"sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4"},{"image":"mcp/markitdown","digest":"sha256:1cef3bf502503310ed0884441874ccf6cdaac20136dc1179797fa048269dc4cb","pinned_image":"mcp/markitdown@sha256:1cef3bf502503310ed0884441874ccf6cdaac20136dc1179797fa048269dc4cb"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
@@ -75,7 +75,7 @@ on:
type: string
url:
description: URL(s) to resource(s) to analyze (comma-separated for multiple URLs)
- required: true
+ required: false
type: string
permissions: {}
@@ -263,21 +263,21 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_13803584a5c506a8_EOF'
+ cat << 'GH_AW_PROMPT_83a82e91f64ea609_EOF'
- GH_AW_PROMPT_13803584a5c506a8_EOF
+ GH_AW_PROMPT_83a82e91f64ea609_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_13803584a5c506a8_EOF'
+ cat << 'GH_AW_PROMPT_83a82e91f64ea609_EOF'
Tools: add_comment, create_discussion, missing_tool, missing_data, noop
- GH_AW_PROMPT_13803584a5c506a8_EOF
+ GH_AW_PROMPT_83a82e91f64ea609_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_13803584a5c506a8_EOF'
+ cat << 'GH_AW_PROMPT_83a82e91f64ea609_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -306,19 +306,19 @@ jobs:
{{/if}}
- GH_AW_PROMPT_13803584a5c506a8_EOF
+ GH_AW_PROMPT_83a82e91f64ea609_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
fi
- cat << 'GH_AW_PROMPT_13803584a5c506a8_EOF'
+ cat << 'GH_AW_PROMPT_83a82e91f64ea609_EOF'
{{#runtime-import .github/workflows/shared/mcp/markitdown.md}}
{{#runtime-import .github/workflows/shared/reporting.md}}
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/shared/noop-reminder.md}}
{{#runtime-import .github/workflows/pdf-summary.md}}
- GH_AW_PROMPT_13803584a5c506a8_EOF
+ GH_AW_PROMPT_83a82e91f64ea609_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -570,9 +570,9 @@ jobs:
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_7ec836cbd3f34cbd_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_515ba76f1bd04a4c_EOF'
{"add_comment":{"max":1},"create_discussion":{"expires":24,"fallback_to_issue":true,"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_7ec836cbd3f34cbd_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_515ba76f1bd04a4c_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -795,7 +795,7 @@ jobs:
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_7b16283d2c428515_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_9ed7043b688a3489_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
@@ -855,7 +855,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_7b16283d2c428515_EOF
+ GH_AW_MCP_CONFIG_9ed7043b688a3489_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
diff --git a/.github/workflows/pdf-summary.md b/.github/workflows/pdf-summary.md
index cf3697cce14..bfcc9e8d471 100644
--- a/.github/workflows/pdf-summary.md
+++ b/.github/workflows/pdf-summary.md
@@ -13,7 +13,7 @@ on:
inputs:
url:
description: 'URL(s) to resource(s) to analyze (comma-separated for multiple URLs)'
- required: true
+ required: false
type: string
query:
description: 'Query or question to answer about the resource(s)'
diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml
index 8c984eb2964..6df3e0c645a 100644
--- a/.github/workflows/scout.lock.yml
+++ b/.github/workflows/scout.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"876ad3e3f5e72fe3ce92cf6800bad55f24d826e36fab9fa74b974d26ce2806b5","strict":true,"agent_id":"claude"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"d762596476e9ee11c5f0546bd2148f1b314544476475aa8103dfbd0cccc4a89b","strict":true,"agent_id":"claude"}
# gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","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","TAVILY_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"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":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.46"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.9","digest":"sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4"},{"image":"mcp/arxiv-mcp-server","digest":"sha256:6dc6bba6dfed97f4ad6eb8d23a5c98ef5b7fa6184937d54b2d675801cd9dd29e","pinned_image":"mcp/arxiv-mcp-server@sha256:6dc6bba6dfed97f4ad6eb8d23a5c98ef5b7fa6184937d54b2d675801cd9dd29e"},{"image":"mcp/markitdown","digest":"sha256:1cef3bf502503310ed0884441874ccf6cdaac20136dc1179797fa048269dc4cb","pinned_image":"mcp/markitdown@sha256:1cef3bf502503310ed0884441874ccf6cdaac20136dc1179797fa048269dc4cb"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
@@ -89,7 +89,7 @@ on:
type: choice
topic:
description: Research topic or question
- required: true
+ required: false
permissions: {}
@@ -277,21 +277,21 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_3f97b0be61723276_EOF'
+ cat << 'GH_AW_PROMPT_10305b34369706b3_EOF'
- GH_AW_PROMPT_3f97b0be61723276_EOF
+ GH_AW_PROMPT_10305b34369706b3_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_3f97b0be61723276_EOF'
+ cat << 'GH_AW_PROMPT_10305b34369706b3_EOF'
Tools: add_comment, add_labels, missing_tool, missing_data, noop
- GH_AW_PROMPT_3f97b0be61723276_EOF
+ GH_AW_PROMPT_10305b34369706b3_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_3f97b0be61723276_EOF'
+ cat << 'GH_AW_PROMPT_10305b34369706b3_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -320,12 +320,12 @@ jobs:
{{/if}}
- GH_AW_PROMPT_3f97b0be61723276_EOF
+ GH_AW_PROMPT_10305b34369706b3_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md"
if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
fi
- cat << 'GH_AW_PROMPT_3f97b0be61723276_EOF'
+ cat << 'GH_AW_PROMPT_10305b34369706b3_EOF'
{{#runtime-import .github/workflows/shared/reporting.md}}
{{#runtime-import .github/workflows/shared/mcp/arxiv.md}}
@@ -337,7 +337,7 @@ jobs:
{{#runtime-import .github/workflows/shared/observability-otlp.md}}
{{#runtime-import .github/workflows/shared/noop-reminder.md}}
{{#runtime-import .github/workflows/scout.md}}
- GH_AW_PROMPT_3f97b0be61723276_EOF
+ GH_AW_PROMPT_10305b34369706b3_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -590,9 +590,9 @@ jobs:
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_7f1bdfc34579045a_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_3a67a53bc13a95ff_EOF'
{"add_comment":{"max":1},"add_labels":{"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_7f1bdfc34579045a_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_3a67a53bc13a95ff_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -805,7 +805,7 @@ jobs:
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -e TAVILY_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.9'
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_5ffea96d0f666af9_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_ce395a5651924577_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"arxiv": {
@@ -915,7 +915,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_5ffea96d0f666af9_EOF
+ GH_AW_MCP_CONFIG_ce395a5651924577_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
diff --git a/.github/workflows/scout.md b/.github/workflows/scout.md
index 32535679ea3..473060fc22f 100644
--- a/.github/workflows/scout.md
+++ b/.github/workflows/scout.md
@@ -12,7 +12,7 @@ on:
inputs:
topic:
description: 'Research topic or question'
- required: true
+ required: false
history:
description: "Git history to fetch: shallow (default) or full"
required: false
diff --git a/pkg/workflow/command_dispatch_validation.go b/pkg/workflow/command_dispatch_validation.go
new file mode 100644
index 00000000000..26099191279
--- /dev/null
+++ b/pkg/workflow/command_dispatch_validation.go
@@ -0,0 +1,62 @@
+package workflow
+
+import (
+ "fmt"
+ "strings"
+)
+
+// validateCommandWorkflowDispatchInputs rejects required workflow_dispatch inputs when
+// slash_command or label_command triggers are configured.
+// Returns an error if any workflow_dispatch input has required: true.
+func validateCommandWorkflowDispatchInputs(workflowData *WorkflowData) error {
+ if workflowData == nil || workflowData.RawFrontmatter == nil {
+ return nil
+ }
+
+ hasSlashCommand := len(workflowData.Command) > 0
+ hasLabelCommand := len(workflowData.LabelCommand) > 0
+ if !hasSlashCommand && !hasLabelCommand {
+ return nil
+ }
+
+ onMap, ok := workflowData.RawFrontmatter["on"].(map[string]any)
+ if !ok {
+ return nil
+ }
+
+ workflowDispatchMap, ok := onMap["workflow_dispatch"].(map[string]any)
+ if !ok {
+ return nil
+ }
+
+ inputsMap, ok := workflowDispatchMap["inputs"].(map[string]any)
+ if !ok {
+ return nil
+ }
+
+ for inputName, inputDef := range inputsMap {
+ inputDefMap, ok := inputDef.(map[string]any)
+ if !ok {
+ continue
+ }
+
+ required, ok := inputDefMap["required"].(bool)
+ if ok && required {
+ var triggerNames []string
+ if hasSlashCommand {
+ triggerNames = append(triggerNames, "slash_command")
+ }
+ if hasLabelCommand {
+ triggerNames = append(triggerNames, "label_command")
+ }
+ triggerNamesPhrase := strings.Join(triggerNames, " and ")
+
+ return fmt.Errorf(
+ "on.workflow_dispatch.inputs.%s.required: true is not allowed when using %s; these triggers are dispatched automatically and cannot enforce required manual inputs; set required: false in workflow_dispatch.inputs",
+ inputName, triggerNamesPhrase,
+ )
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/workflow/compiler_validators.go b/pkg/workflow/compiler_validators.go
index 0c23b600ed8..0b5511335fc 100644
--- a/pkg/workflow/compiler_validators.go
+++ b/pkg/workflow/compiler_validators.go
@@ -185,6 +185,12 @@ func (c *Compiler) validateToolConfiguration(workflowData *WorkflowData, markdow
return formatCompilerError(markdownPath, "error", err.Error(), err)
}
+ // Validate workflow_dispatch required inputs with slash/label command triggers.
+ log.Printf("Validating workflow_dispatch input requirements for command triggers")
+ if err := validateCommandWorkflowDispatchInputs(workflowData); err != nil {
+ return formatCompilerError(markdownPath, "error", err.Error(), err)
+ }
+
// Validate workflow-level concurrency group expression
log.Printf("Validating workflow-level concurrency configuration")
if workflowData.Concurrency != "" {
diff --git a/pkg/workflow/slash_command_centralized_compile_test.go b/pkg/workflow/slash_command_centralized_compile_test.go
index a442854bc2e..694197dddae 100644
--- a/pkg/workflow/slash_command_centralized_compile_test.go
+++ b/pkg/workflow/slash_command_centralized_compile_test.go
@@ -84,3 +84,72 @@ tools:
require.Contains(t, compiled, "fromJSON(github.event.inputs.aw_context || '{}').trigger_label == 'triage'")
require.Contains(t, compiled, "fromJSON(github.event.inputs.aw_context || '{}').event_type == 'issues'")
}
+
+func TestCompileWorkflow_SlashCommandRejectsRequiredDispatchInputs(t *testing.T) {
+ tmpDir := testutil.TempDir(t, "workflow-centralized-slash-dispatch-inputs-test")
+
+ markdownPath := filepath.Join(tmpDir, "scout.md")
+ content := `---
+on:
+ slash_command:
+ name: scout
+ strategy: centralized
+ workflow_dispatch:
+ inputs:
+ topic:
+ description: "Research topic"
+ required: true
+ type: string
+tools:
+ github:
+ allowed: [list_issues]
+---
+
+# Scout
+`
+ require.NoError(t, os.WriteFile(markdownPath, []byte(content), 0644))
+
+ compiler := NewCompiler()
+ err := compiler.CompileWorkflow(markdownPath)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "on.workflow_dispatch.inputs.topic.required: true is not allowed when using slash_command")
+
+ lockPath := stringutil.MarkdownToLockFile(markdownPath)
+ _, statErr := os.Stat(lockPath)
+ require.Error(t, statErr)
+ require.True(t, os.IsNotExist(statErr))
+}
+
+func TestCompileWorkflow_LabelCommandRejectsRequiredDispatchInputs(t *testing.T) {
+ tmpDir := testutil.TempDir(t, "workflow-label-dispatch-inputs-test")
+
+ markdownPath := filepath.Join(tmpDir, "triage.md")
+ content := `---
+on:
+ label_command:
+ name: triage
+ workflow_dispatch:
+ inputs:
+ topic:
+ description: "Research topic"
+ required: true
+ type: string
+tools:
+ github:
+ allowed: [list_issues]
+---
+
+# Triage
+`
+ require.NoError(t, os.WriteFile(markdownPath, []byte(content), 0644))
+
+ compiler := NewCompiler()
+ err := compiler.CompileWorkflow(markdownPath)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "on.workflow_dispatch.inputs.topic.required: true is not allowed when using label_command")
+
+ lockPath := stringutil.MarkdownToLockFile(markdownPath)
+ _, statErr := os.Stat(lockPath)
+ require.Error(t, statErr)
+ require.True(t, os.IsNotExist(statErr))
+}