diff --git a/.github/skills/gh-agent-task/SKILL.md b/.github/skills/gh-agent-task/SKILL.md index fc8c91f1cad..da8ae97302b 100644 --- a/.github/skills/gh-agent-task/SKILL.md +++ b/.github/skills/gh-agent-task/SKILL.md @@ -129,13 +129,13 @@ Fix auth ## Integration with GitHub Agentic Workflows -The `gh agent-task` extension is used by the `create-agent-task` safe output feature in GitHub Agentic Workflows (gh-aw). +The `gh agent-task` extension is used by the `create-agent-session` safe output feature in GitHub Agentic Workflows (gh-aw). ### Safe Output Configuration ```yaml safe-outputs: - create-agent-task: + create-agent-session: base: main # Base branch for agent task PR target-repo: "owner/target-repo" # Cross-repository task creation ``` @@ -151,7 +151,7 @@ permissions: actions: read engine: claude safe-outputs: - create-agent-task: + create-agent-session: base: main # Code Task Delegator @@ -163,7 +163,7 @@ When an issue is labeled with "code-task", analyze the requirements and create a The safe output processor: 1. Reads agent output from the workflow execution -2. Extracts `create_agent_task` items from the structured output +2. Extracts `create_agent_session` items from the structured output 3. Writes task descriptions to temporary files 4. Executes `gh agent-task create --from-file --base ` 5. Captures the created task URL and number @@ -239,7 +239,7 @@ When `safe-outputs.staged: true`, agent tasks are previewed without creation: ```yaml safe-outputs: staged: true - create-agent-task: + create-agent-session: ``` **Staged Output:** @@ -268,7 +268,7 @@ on: types: [labeled] engine: claude safe-outputs: - create-agent-task: + create-agent-session: When issue is labeled with "needs-implementation", create an agent task with implementation instructions. ``` @@ -281,7 +281,7 @@ on: - cron: "0 9 * * 1" # Monday 9AM engine: copilot safe-outputs: - create-agent-task: + create-agent-session: base: develop Analyze codebase for improvement opportunities and create agent tasks for top 3 improvements. @@ -293,7 +293,7 @@ Analyze codebase for improvement opportunities and create agent tasks for top 3 on: workflow_dispatch engine: claude safe-outputs: - create-agent-task: + create-agent-session: target-repo: "organization/backend-repo" base: main @@ -359,23 +359,23 @@ Create agent task in backend repository to implement the API changes described i ## Output Structure -When used via safe outputs, the create-agent-task job provides outputs: +When used via safe outputs, the create-agent-session job provides outputs: ```yaml outputs: - task_number: "123" - task_url: "https://github.com/owner/repo/issues/123" + session_number: "123" + session_url: "https://github.com/owner/repo/issues/123" ``` **Usage in Dependent Jobs:** ```yaml jobs: follow_up: - needs: create_agent_task + needs: create_agent_session steps: - name: Notify team run: | - echo "Agent task created: ${{ needs.create_agent_task.outputs.task_url }}" + echo "Agent session created: ${{ needs.create_agent_session.outputs.session_url }}" ``` ## References diff --git a/docs/public/editor/autocomplete-data.json b/docs/public/editor/autocomplete-data.json index ff7e9dade79..dd9ce37e890 100644 --- a/docs/public/editor/autocomplete-data.json +++ b/docs/public/editor/autocomplete-data.json @@ -2143,11 +2143,6 @@ "desc": "Enable AI agents to create GitHub issues from workflow output.", "leaf": true }, - "create-agent-task": { - "type": "object|null", - "desc": "Enable creation of GitHub Copilot coding agent tasks from workflow output.", - "leaf": true - }, "create-agent-session": { "type": "object|null", "desc": "Enable creation of GitHub Copilot coding agent sessions from workflow output.", diff --git a/docs/src/content/docs/reference/frontmatter-full.md b/docs/src/content/docs/reference/frontmatter-full.md index 255990eb254..55278ecdce0 100644 --- a/docs/src/content/docs/reference/frontmatter-full.md +++ b/docs/src/content/docs/reference/frontmatter-full.md @@ -4722,287 +4722,14 @@ safe-outputs: # Format 2: Enable issue creation with default configuration create-issue: null - # Enable creation of GitHub Copilot coding agent tasks from workflow output. - # Allows workflows to spawn new agent sessions for follow-up work. - # (optional) - # Accepted formats: - - # Format 1: DEPRECATED: Use 'create-agent-session' instead. Configuration for - # creating GitHub Copilot coding agent sessions from agentic workflow output using - # gh agent-task CLI. The main job does not need write permissions. - create-agent-task: - # Base branch for the agent session pull request. Defaults to the current branch - # or repository default branch. - # (optional) - base: "example-value" - - # Maximum number of agent sessions to create (default: 1) Supports integer or - # GitHub Actions expression (e.g. '${{ inputs.max }}'). - # (optional) - # Accepted formats: - - # Format 1: integer - max: 1 - - # Format 2: GitHub Actions expression that resolves to an integer at runtime - max: "example-value" - - # Target repository in format 'owner/repo' for cross-repository agent session - # creation. Takes precedence over trial target repo settings. - # (optional) - target-repo: "example-value" - - # List of additional repositories in format 'owner/repo' that agent sessions can - # be created in. When specified, the agent can use a 'repo' field in the output to - # specify which repository to create the agent session in. The target repository - # (current or target-repo) is always implicitly allowed. - # (optional) - allowed-repos: [] - # Array of strings - - # GitHub token to use for this specific output type. Overrides global github-token - # if specified. - # (optional) - github-token: "${{ secrets.GITHUB_TOKEN }}" - - # When true, emit step summary messages instead of making GitHub API calls for - # this specific output type (preview mode) - # (optional) - # Accepted formats: - - # Format 1: boolean - staged: true - - # Format 2: GitHub Actions expression that resolves to a boolean at runtime - staged: "example-value" - - # Enable issue-intent metadata support (rationale/confidence/suggest) for this - # output type. - # (optional) - issue-intent: true - - # Internal hidden feature. Optional list of declarative sample payloads that - # exercise this safe-output handler. Used by the hidden `gh aw compile - # --use-samples` flag to replace the agentic step with a deterministic replay - # through the safe-outputs MCP server. Each entry should conform to the - # corresponding MCP tool inputSchema; recognized sidecar keys (currently `patch` - # for create-pull-request and push-to-pull-request-branch) are stripped before - # schema validation and consumed by the replay driver. - # (optional) - # Accepted formats: - - # Format 1: array - samples: [] - # Array items: object - - # Format 2: object - samples: - {} - - # GitHub App authentication. Mints a short-lived installation access token via - # actions/create-github-app-token. Mutually exclusive with github-token. - # (optional) - github-app: - # Deprecated alias for client-id. GitHub App ID/client ID (e.g., '${{ vars.APP_ID - # }}'). - # (optional) - app-id: "example-value" - - # GitHub App client ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App - # token. - # (optional) - client-id: "example-value" - - # GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to - # mint a GitHub App token. - # (optional) - private-key: "example-value" - - # If true, skip token minting when client-id/private-key resolve to empty strings - # at runtime. Defaults to false. - # (optional) - ignore-if-missing: true - - # Optional owner of the GitHub App installation (defaults to current repository - # owner if not specified) - # (optional) - owner: "example-value" - - # Optional list of repositories to grant access to (defaults to current repository - # if not specified) - # (optional) - repositories: [] - # Array of strings - - # Optional extra GitHub App-only permissions to merge into the minted token. Takes - # effect for tools.github.github-app and safe-outputs.github-app; ignored in - # on.github-app and the top-level github-app fallback. Use to add GitHub App-only - # scopes (e.g. members, organization-administration) not expressible via standard - # handler declarations. - # (optional) - permissions: - # Permission level for repository administration (read/none; "write" is rejected - # by the compiler). GitHub App-only permission for repository administration. - # (optional) - administration: "read" - - # Permission level for Codespaces (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - codespaces: "read" - - # Permission level for Codespaces lifecycle administration (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - codespaces-lifecycle-admin: "read" - - # Permission level for Codespaces metadata (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - codespaces-metadata: "read" - - # Permission level for user email addresses (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - email-addresses: "read" - - # Permission level for repository environments (read/none; "write" is rejected by - # the compiler). GitHub App-only permission. - # (optional) - environments: "read" - - # Permission level for git signing (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - git-signing: "read" - - # Permission level for organization members (read/none; "write" is rejected by the - # compiler). Required for org team membership API calls. - # (optional) - members: "read" - - # Permission level for organization administration (read/none; "write" is rejected - # by the compiler). GitHub App-only permission. - # (optional) - organization-administration: "read" - - # Permission level for organization announcement banners (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-announcement-banners: "read" - - # Permission level for organization Codespaces (read/none; "write" is rejected by - # the compiler). GitHub App-only permission. - # (optional) - organization-codespaces: "read" - - # Permission level for organization Copilot (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - organization-copilot: "read" - - # Permission level for organization custom org roles (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-custom-org-roles: "read" - - # Permission level for organization custom properties (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-custom-properties: "read" - - # Permission level for organization custom repository roles (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-custom-repository-roles: "read" - - # Permission level for organization events (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - organization-events: "read" - - # Permission level for organization webhooks (read/none; "write" is rejected by - # the compiler). GitHub App-only permission. - # (optional) - organization-hooks: "read" - - # Permission level for organization members management (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-members: "read" - - # Permission level for organization packages (read/none; "write" is rejected by - # the compiler). GitHub App-only permission. - # (optional) - organization-packages: "read" - - # Permission level for organization personal access token requests (read/none; - # "write" is rejected by the compiler). GitHub App-only permission. - # (optional) - organization-personal-access-token-requests: "read" - - # Permission level for organization personal access tokens (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-personal-access-tokens: "read" - - # Permission level for organization plan (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - organization-plan: "read" - - # Permission level for organization self-hosted runners (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - organization-self-hosted-runners: "read" - - # Permission level for organization user blocking (read/none; "write" is rejected - # by the compiler). GitHub App-only permission. - # (optional) - organization-user-blocking: "read" - - # Permission level for repository custom properties (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - repository-custom-properties: "read" - - # Permission level for repository webhooks (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - repository-hooks: "read" - - # Permission level for single file access (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - single-file: "read" - - # Permission level for team discussions (read/none; "write" is rejected by the - # compiler). GitHub App-only permission. - # (optional) - team-discussions: "read" - - # Permission level for Dependabot vulnerability alerts (read/none; "write" is - # rejected by the compiler). Also available as a GITHUB_TOKEN scope. When used - # with a GitHub App, forwarded as permission-vulnerability-alerts input. - # (optional) - vulnerability-alerts: "read" - - # Permission level for GitHub Actions workflow files (read/none; "write" is - # rejected by the compiler). GitHub App-only permission. - # (optional) - workflows: "read" - - # Format 2: Enable agent session creation with default configuration - create-agent-task: null - # Enable creation of GitHub Copilot coding agent sessions from workflow output. # Allows workflows to start interactive agent conversations. # (optional) # Accepted formats: # Format 1: Configuration for creating GitHub Copilot coding agent sessions from - # agentic workflow output using gh agent-task CLI. The main job does not need - # write permissions. + # agentic workflow output using the GitHub CLI `gh agent-task create` command. + # The main job does not need write permissions. create-agent-session: # Base branch for the agent session pull request. Defaults to the current branch # or repository default branch. diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 0ebab39bedf..e4c00586a6c 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -5406,7 +5406,7 @@ }, "safe-outputs": { "type": "object", - "$comment": "Required if workflow creates or modifies GitHub resources. Operations requiring safe-outputs: approve-workflow-run, autofix-code-scanning-alert, add-comment, add-labels, add-reviewer, assign-milestone, assign-to-agent, assign-to-user, close-discussion, close-issue, close-pull-request, create-agent-session, create-agent-task (deprecated, use create-agent-session), create-check-run, create-code-scanning-alert, create-discussion, create-issue, create-project, create-project-status-update, create-pull-request, create-pull-request-review-comment, dispatch-workflow, hide-comment, link-sub-issue, mark-pull-request-as-ready-for-review, merge-pull-request, missing-data, missing-tool, noop, push-to-pull-request-branch, remove-labels, reply-to-pull-request-review-comment, resolve-pull-request-review-thread, set-issue-field, set-issue-type, submit-pull-request-review, threat-detection, unassign-from-user, update-discussion, update-issue, update-project, update-pull-request, update-release, upload-artifact, upload-asset. See documentation for complete details.", + "$comment": "Required if workflow creates or modifies GitHub resources. Operations requiring safe-outputs: approve-workflow-run, autofix-code-scanning-alert, add-comment, add-labels, add-reviewer, assign-milestone, assign-to-agent, assign-to-user, close-discussion, close-issue, close-pull-request, create-agent-session, create-check-run, create-code-scanning-alert, create-discussion, create-issue, create-project, create-project-status-update, create-pull-request, create-pull-request-review-comment, dispatch-workflow, hide-comment, link-sub-issue, mark-pull-request-as-ready-for-review, merge-pull-request, missing-data, missing-tool, noop, push-to-pull-request-branch, remove-labels, reply-to-pull-request-review-comment, resolve-pull-request-review-thread, set-issue-field, set-issue-type, submit-pull-request-review, threat-detection, unassign-from-user, update-discussion, update-issue, update-project, update-pull-request, update-release, upload-artifact, upload-asset. See documentation for complete details.", "description": "Safe output processing configuration that automatically creates GitHub issues, comments, and pull requests from AI workflow output without requiring write permissions in the main job", "examples": [ { @@ -5664,92 +5664,12 @@ ], "description": "Enable AI agents to create GitHub issues from workflow output. Supports title prefixes, automatic labeling, assignees, and cross-repository creation. Does not require 'issues: write' permission." }, - "create-agent-task": { - "oneOf": [ - { - "type": "object", - "description": "DEPRECATED: Use 'create-agent-session' instead. Configuration for creating GitHub Copilot coding agent sessions from agentic workflow output using gh agent-task CLI. The main job does not need write permissions.", - "deprecated": true, - "x-deprecation-message": "'create-agent-task' is deprecated. Use 'create-agent-session' instead.", - "properties": { - "base": { - "type": "string", - "description": "Base branch for the agent session pull request. Defaults to the current branch or repository default branch." - }, - "max": { - "description": "Maximum number of agent sessions to create (default: 1) Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').", - "oneOf": [ - { - "type": "integer", - "minimum": 1, - "maximum": 1 - }, - { - "type": "string", - "pattern": "^\\$\\{\\{.*\\}\\}$", - "description": "GitHub Actions expression that resolves to an integer at runtime" - } - ] - }, - "target-repo": { - "type": "string", - "description": "Target repository in format 'owner/repo' for cross-repository agent session creation. Takes precedence over trial target repo settings." - }, - "allowed-repos": { - "type": "array", - "items": { - "type": "string" - }, - "description": "List of additional repositories in format 'owner/repo' that agent sessions can be created in. When specified, the agent can use a 'repo' field in the output to specify which repository to create the agent session in. The target repository (current or target-repo) is always implicitly allowed." - }, - "github-token": { - "$ref": "#/$defs/github_token_same_job", - "description": "GitHub token to use for this specific output type. Overrides global github-token if specified." - }, - "staged": { - "$ref": "#/$defs/templatable_boolean", - "description": "When true, emit step summary messages instead of making GitHub API calls for this specific output type (preview mode)", - "examples": [true, false] - }, - "issue-intent": { - "type": "boolean", - "description": "Enable issue-intent metadata support (rationale/confidence/suggest) for this output type." - }, - "samples": { - "description": "Internal hidden feature. Optional list of declarative sample payloads that exercise this safe-output handler. Used by the hidden `gh aw compile --use-samples` flag to replace the agentic step with a deterministic replay through the safe-outputs MCP server. Each entry should conform to the corresponding MCP tool inputSchema; recognized sidecar keys (currently `patch` for create-pull-request and push-to-pull-request-branch) are stripped before schema validation and consumed by the replay driver.", - "oneOf": [ - { - "type": "array", - "items": { - "type": "object", - "additionalProperties": true - } - }, - { - "type": "object", - "additionalProperties": true - } - ] - }, - "github-app": { - "$ref": "#/$defs/github_app", - "description": "GitHub App authentication. Mints a short-lived installation access token via actions/create-github-app-token. Mutually exclusive with github-token." - } - }, - "additionalProperties": false - }, - { - "type": "null", - "description": "Enable agent session creation with default configuration" - } - ], - "description": "Enable creation of GitHub Copilot coding agent tasks from workflow output. Allows workflows to spawn new agent sessions for follow-up work." - }, "create-agent-session": { + "x-synonyms": ["create-agent-task"], "oneOf": [ { "type": "object", - "description": "Configuration for creating GitHub Copilot coding agent sessions from agentic workflow output using gh agent-task CLI. The main job does not need write permissions.", + "description": "Configuration for creating GitHub Copilot coding agent sessions from agentic workflow output using the GitHub CLI `gh agent-task create` command. The main job does not need write permissions.", "properties": { "base": { "type": "string", diff --git a/pkg/workflow/create_agent_session.go b/pkg/workflow/create_agent_session.go index df54858d347..cdf228a801d 100644 --- a/pkg/workflow/create_agent_session.go +++ b/pkg/workflow/create_agent_session.go @@ -19,64 +19,37 @@ func (c *Compiler) parseAgentSessionConfig(outputMap map[string]any) *CreateAgen // Try new key first if configData, exists := outputMap["create-agent-session"]; exists { createAgentSessionLog.Print("Parsing create-agent-session configuration") - agentSessionConfig := &CreateAgentSessionConfig{} - - if configMap, ok := configData.(map[string]any); ok { - // Parse base branch - if base, exists := configMap["base"]; exists { - if baseStr, ok := base.(string); ok { - agentSessionConfig.Base = baseStr - } - } - - // Parse target-repo using shared helper with validation - targetRepoSlug, isInvalid := parseTargetRepoWithValidation(configMap) - if isInvalid { - return nil // Invalid configuration, return nil to cause validation error - } - agentSessionConfig.TargetRepoSlug = targetRepoSlug - - // Parse common base fields with default max of 1 - c.parseBaseSafeOutputConfig(configMap, &agentSessionConfig.BaseSafeOutputConfig, 1) - } else { - // If configData is nil or not a map (e.g., "create-agent-session:" with no value), - // still set the default max - agentSessionConfig.Max = defaultIntStr(1) - } - - return agentSessionConfig + return c.parseAgentSessionConfigMap(configData) } - // Fall back to deprecated key for backward compatibility - if configData, exists := outputMap["create-agent-task"]; exists { - createAgentSessionLog.Print("WARNING: Using deprecated 'create-agent-task' configuration. Please migrate to 'create-agent-session' using 'gh aw fix'") - agentSessionConfig := &CreateAgentSessionConfig{} + return nil +} - if configMap, ok := configData.(map[string]any); ok { - // Parse base branch - if base, exists := configMap["base"]; exists { - if baseStr, ok := base.(string); ok { - agentSessionConfig.Base = baseStr - } - } +func (c *Compiler) parseAgentSessionConfigMap(configData any) *CreateAgentSessionConfig { + agentSessionConfig := &CreateAgentSessionConfig{} - // Parse target-repo using shared helper with validation - targetRepoSlug, isInvalid := parseTargetRepoWithValidation(configMap) - if isInvalid { - return nil // Invalid configuration, return nil to cause validation error + if configMap, ok := configData.(map[string]any); ok { + // Parse base branch + if base, exists := configMap["base"]; exists { + if baseStr, ok := base.(string); ok { + agentSessionConfig.Base = baseStr } - agentSessionConfig.TargetRepoSlug = targetRepoSlug - - // Parse common base fields with default max of 1 - c.parseBaseSafeOutputConfig(configMap, &agentSessionConfig.BaseSafeOutputConfig, 1) - } else { - // If configData is nil or not a map (e.g., "create-agent-task:" with no value), - // still set the default max - agentSessionConfig.Max = defaultIntStr(1) } - return agentSessionConfig + // Parse target-repo using shared helper with validation + targetRepoSlug, isInvalid := parseTargetRepoWithValidation(configMap) + if isInvalid { + return nil // Invalid configuration, return nil to cause validation error + } + agentSessionConfig.TargetRepoSlug = targetRepoSlug + + // Parse common base fields with default max of 1 + c.parseBaseSafeOutputConfig(configMap, &agentSessionConfig.BaseSafeOutputConfig, 1) + } else { + // If configData is nil or not a map (e.g., "create-agent-session:" with no value), + // still set the default max + agentSessionConfig.Max = defaultIntStr(1) } - return nil + return agentSessionConfig } diff --git a/pkg/workflow/create_agent_session_test.go b/pkg/workflow/create_agent_session_test.go index e8dcf90a53e..936d014ae74 100644 --- a/pkg/workflow/create_agent_session_test.go +++ b/pkg/workflow/create_agent_session_test.go @@ -138,3 +138,18 @@ func TestHasSafeOutputsEnabledWithAgentTask(t *testing.T) { t.Error("HasSafeOutputsEnabled() = true, want false when no safe outputs are configured") } } + +func TestParseAgentSessionConfigWithDeprecatedKey(t *testing.T) { + compiler := NewCompiler() + config := compiler.parseAgentSessionConfig(map[string]any{ + "create-agent-task": map[string]any{ + "base": "develop", + "target-repo": "owner/repo", + "max": 1, + }, + }) + + if config != nil { + t.Fatal("parseAgentSessionConfig() should ignore deprecated create-agent-task key") + } +} diff --git a/pkg/workflow/safe_output_handlers.go b/pkg/workflow/safe_output_handlers.go index 79cf3cc97e7..06e81743344 100644 --- a/pkg/workflow/safe_output_handlers.go +++ b/pkg/workflow/safe_output_handlers.go @@ -34,7 +34,6 @@ var safeOutputHandlers = []safeOutputHandlerDescriptor{ }, { Key: "create-agent-session", - Aliases: []string{"create-agent-task"}, StructField: "CreateAgentSessions", ToolName: "create_agent_session", NewConfig: func() any { return &CreateAgentSessionConfig{} }, diff --git a/pkg/workflow/safe_outputs_fix_test.go b/pkg/workflow/safe_outputs_fix_test.go index 658c8bade9a..b29629295b4 100644 --- a/pkg/workflow/safe_outputs_fix_test.go +++ b/pkg/workflow/safe_outputs_fix_test.go @@ -44,7 +44,6 @@ func TestHasSafeOutputTypeNewKeys(t *testing.T) { "upload-artifact", "update-release", "create-agent-session", - "create-agent-task", "update-project", "update-discussion", "mark-pull-request-as-ready-for-review",