Skip to content

Add 5 critical MCP tools: capabilities, back, key, gesture, batch#115

Merged
jfversluis merged 3 commits into
mainfrom
feat/mcp-critical-tools
Apr 24, 2026
Merged

Add 5 critical MCP tools: capabilities, back, key, gesture, batch#115
jfversluis merged 3 commits into
mainfrom
feat/mcp-critical-tools

Conversation

@rmarinho
Copy link
Copy Markdown
Member

Summary

Closes the critical gap between DevFlow's AgentClient API and the MCP tool surface. After the v1 spec alignment (2c05e68), several new AgentClient methods had no MCP tools.

New MCP Tools

Tool File AgentClient Method Description
maui_capabilities AgentTools.cs GetCapabilitiesAsync Discover agent-supported features before using other tools
maui_back NavigationTools.cs BackAsync System back navigation
maui_key InteractionTools.cs KeyAsync Keyboard input (enter, backspace, text typing)
maui_gesture InteractionTools.cs GestureAsync Touch gestures (swipe, tap, longpress) with validation
maui_batch BatchTools.cs (new) BatchAsync Atomic multi-action sequences with JSON validation

Design Decisions

  • maui_gesture validates types to the supported backend set (swipe, tap, longpress) and requires direction for swipes — fails fast instead of silently succeeding
  • maui_key documents actual backend behavior (enter/backspace work on Entry/Editor/SearchBar; other keys may be no-ops)
  • maui_batch accepts a JSON string with strict validation (array check, object check, action field check) with descriptive error messages
  • maui_capabilities placed in AgentTools since it's agent metadata, not UI interaction

Remaining Gaps (tracked in issues)

Testing

  • ✅ Build passes (dotnet build src/Cli/Microsoft.Maui.Cli/)
  • ✅ Existing 260 unit tests unaffected (12 pre-existing failures unchanged)
  • Manual testing: use maui devflow mcp with a running MAUI app, or the equivalent CLI commands

Add maui_capabilities to AgentTools — discover agent-supported features.
Add maui_back to NavigationTools — system back button navigation.
Add maui_key to InteractionTools — keyboard input (enter, backspace, text).
Add maui_gesture to InteractionTools — swipe, tap, longpress gestures
  with input validation for supported types and required parameters.
Create BatchTools with maui_batch — atomic multi-action sequences
  with strict JSON validation and descriptive error messages.

Profiler tools tracked in #112, WebView tools tracked in #113.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 21, 2026 17:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds missing Model Context Protocol (MCP) tools to the maui devflow mcp surface so AI agents can access newer DevFlow AgentClient capabilities.

Changes:

  • Added new MCP tools: maui_capabilities, maui_back, maui_key, maui_gesture.
  • Introduced maui_batch tool (new BatchTools.cs) and registered it in McpServerHost.
  • Implemented basic validation + JSON output formatting for new tool responses.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/NavigationTools.cs Adds maui_back tool wrapping AgentClient.BackAsync().
src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/InteractionTools.cs Adds maui_key and maui_gesture tools for keyboard and gesture actions.
src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/BatchTools.cs New tool maui_batch that parses action JSON and calls AgentClient.BatchAsync().
src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/AgentTools.cs Adds maui_capabilities tool wrapping AgentClient.GetCapabilitiesAsync().
src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/McpServerHost.cs Registers BatchTools with the MCP server host.

Comment thread src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/BatchTools.cs Outdated
Comment on lines +14 to +26
The 'actionsJson' parameter must be a JSON array of action objects.
Each action object must have an "action" field specifying the operation.

Supported actions and their fields:
- {"action":"tap", "elementId":"<id>"}
- {"action":"fill", "elementId":"<id>", "text":"<value>"}
- {"action":"clear", "elementId":"<id>"}
- {"action":"key", "key":"enter", "elementId":"<id>"}
- {"action":"focus", "elementId":"<id>"}
- {"action":"scroll", "elementId":"<id>", "deltaX":0, "deltaY":200}
- {"action":"gesture", "type":"swipe", "elementId":"<id>", "direction":"up"}
- {"action":"navigate", "route":"//page"}
- {"action":"back"}
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tool description and validation messaging say each action must have an "action" field, but the backend and existing tests accept either action or type (and AgentClient’s BatchAsync examples use type). This mismatch will confuse callers and can lead to sending objects with only action that may not behave as expected for some operations (e.g., gesture). Please align the schema documentation and error message with the actual accepted field(s) (e.g., require type or explicitly document action/type aliases and when each is needed).

Copilot uses AI. Check for mistakes.
Comment thread src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/BatchTools.cs Outdated
Comment thread src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/AgentTools.cs
Comment thread src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/InteractionTools.cs Outdated
Comment thread src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/InteractionTools.cs Outdated
- Fix BatchTools: use pattern match instead of AsArray() to avoid
  InvalidOperationException on non-array JSON (e.g., {})
- Fix BatchTools: remove misleading 'atomic' wording, clarify sequential
  non-transactional behavior
- Fix BatchTools: document 'action'/'type' field aliases and when each
  is needed (gesture actions use both)
- Fix AgentTools: guard GetCapabilitiesAsync against Undefined JsonElement
  when agent is unreachable
- Fix InteractionTools: clarify maui_key description — omitting elementId
  may result in no action; update success message accordingly
- Fix InteractionTools: normalize gesture type (accept 'long-press' alias),
  validate swipe direction against supported set (up/down/left/right)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

return $"Invalid action at index {i}: expected a JSON object, got {parsed[i]?.GetValueKind().ToString() ?? "null"}.";

if (obj["action"] == null && obj["type"] == null)
return $"Invalid action at index {i}: must have an 'action' field (e.g., 'tap', 'fill', 'navigate').";
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The validation allows an action object to have either an action or type field, but this error message says only action is required. Update the message (or the validation) so it matches the accepted schema.

Suggested change
return $"Invalid action at index {i}: must have an 'action' field (e.g., 'tap', 'fill', 'navigate').";
return $"Invalid action at index {i}: must have an 'action' or 'type' field (e.g., 'tap', 'fill', 'navigate').";

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +15
[McpServerTool(Name = "maui_batch"), Description("""
Execute multiple UI actions in a single request. Actions run sequentially and are not transactional.
Earlier actions are applied even if a later action fails.
The 'actionsJson' parameter must be a JSON array of action objects.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description calls maui_batch “atomic”, but the tool description explicitly says actions are not transactional and earlier actions may be applied even if later ones fail. Please align the PR description and tool behavior/description so “atomic” isn’t misleading.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +54
[McpServerTool(Name = "maui_key"), Description("Send a key press to an element. Supported keys for Entry/Editor/SearchBar: 'enter' (submit or newline), 'backspace' (delete last character). Use 'text' parameter to type characters. For reliable behavior, provide an element ID; omitting it may have no effect depending on the agent/platform implementation.")]
public static async Task<string> Key(
McpAgentSession session,
[Description("Key to press: 'enter', 'return', 'backspace', 'delete'")] string key,
[Description("Target element ID. Optional, but omitting it may result in no action; provide an element ID for reliable behavior.")] string? elementId = null,
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maui_key requires a non-empty key, but the agent endpoint supports either key or text. With the current signature, “type-only” input isn’t possible without a dummy/empty key, and passing both key and text can result in text being ignored for keys like enter/return. Consider making key nullable/optional and validating that at least one of key or text is provided (and ideally reject conflicting combinations).

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +71
[McpServerTool(Name = "maui_gesture"), Description("Perform a touch gesture on the app. Supported gesture types: 'swipe' (requires direction), 'tap', 'longpress', and 'long-press'. Use maui_tap for simple taps — this tool is for advanced gestures like swiping.")]
public static async Task<string> Gesture(
McpAgentSession session,
[Description("Gesture type: 'swipe', 'tap', 'longpress', or 'long-press'")] string type,
[Description("Target element ID (optional)")] string? elementId = null,
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For maui_gesture, elementId is typed/described as optional, but tap/longpress are implemented by delegating to the tap action, which requires elementId. Consider failing fast when type is tap/longpress and elementId is missing, or update the parameter description to clarify it’s required for those gesture types.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +75
[Description("Swipe direction: 'up', 'down', 'left', or 'right' (required for swipe)")] string? direction = null,
[Description("Swipe distance in pixels (optional, uses default if omitted)")] double? distance = null,
[Description("Gesture duration in milliseconds (optional)")] int? durationMs = null,
[Description("Agent HTTP port (optional if only one agent connected)")] int? agentPort = null)
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

distance/durationMs default to null, but the agent request model uses non-nullable double Distance/int DurationMs with defaults. Sending JSON null for these fields can cause deserialization to fail on the agent. Consider passing explicit defaults when omitted (matching the agent defaults), or ensure null values aren’t serialized/sent.

Copilot uses AI. Check for mistakes.
Comment on lines +67 to +70
[McpServerTool(Name = "maui_gesture"), Description("Perform a touch gesture on the app. Supported gesture types: 'swipe' (requires direction), 'tap', 'longpress', and 'long-press'. Use maui_tap for simple taps — this tool is for advanced gestures like swiping.")]
public static async Task<string> Gesture(
McpAgentSession session,
[Description("Gesture type: 'swipe', 'tap', 'longpress', or 'long-press'")] string type,
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maui_gesture description implies longpress is a distinct gesture, but the agent currently handles longpress by delegating to the tap action. Consider clarifying in the tool description (or restricting supported types) so agents don’t assume a true long-press interaction is performed.

Suggested change
[McpServerTool(Name = "maui_gesture"), Description("Perform a touch gesture on the app. Supported gesture types: 'swipe' (requires direction), 'tap', 'longpress', and 'long-press'. Use maui_tap for simple taps — this tool is for advanced gestures like swiping.")]
public static async Task<string> Gesture(
McpAgentSession session,
[Description("Gesture type: 'swipe', 'tap', 'longpress', or 'long-press'")] string type,
[McpServerTool(Name = "maui_gesture"), Description("Perform a touch gesture on the app. Supported gesture types: 'swipe' (requires direction) and 'tap'. 'longpress' and 'long-press' are accepted for compatibility but currently use tap behavior rather than performing a true long-press interaction. Use maui_tap for simple taps — this tool is primarily for advanced gestures like swiping.")]
public static async Task<string> Gesture(
McpAgentSession session,
[Description("Gesture type: 'swipe' or 'tap'. 'longpress' and 'long-press' are accepted aliases but currently behave the same as 'tap', not a true long press.")] string type,

Copilot uses AI. Check for mistakes.
@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Expert Code Review — Adversarial Consensus

Methodology: 3 independent reviewers with adversarial consensus. Disputed findings were cross-examined by the other reviewers. Only findings with ≥2/3 agreement are included.

CI Status: ✅ All 7 checks passed (macOS build, Windows build, CLA, agent tests, etc.)


🟡 MODERATE — maui_batch: Unhandled exceptions when agent is unreachable (2/3 reviewers)

File: src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/BatchTools.cs, lines 65–67

Scenario: AI agent calls maui_batch while the MAUI app is not running or the agent crashes mid-request. agent.BatchAsync() propagates HttpRequestException, TaskCanceledException, or JsonException unhandled into the MCP framework — unlike every other new tool in this PR. maui_back/maui_key/maui_gesture use PostActionAsync (which catches internally), maui_capabilities uses GetJsonAsync (which catches internally). maui_batch calls BatchAsync which uses raw PostAsync + DriverJson.ParseElement with no error handling.

Recommendation: Wrap the BatchAsync call:

try
{
    var result = await agent.BatchAsync(actions, continueOnError);
    return CliJson.SerializeUntyped(result, indented: false);
}
catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException or JsonException)
{
    return $"Batch request failed: {ex.Message}. Is the app running?";
}

🟡 MODERATE — maui_gesture: Nullable parameters serialize as JSON null, causing agent-side deserialization failure (3/3 reviewers after cross-examination)

File: src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/InteractionTools.cs, line ~101 → AgentClient.GestureAsync

Scenario: AI agent calls maui_gesture(type="swipe", direction="up") without specifying distance or durationMs (the common case — using defaults). GestureAsync builds a JsonObject with ["distance"] = null, ["durationMs"] = null, which serializes as "distance":null,"durationMs":null. The agent-side GestureActionRequest DTO has non-nullable properties (double Distance { get; set; } = 120; int DurationMs { get; set; } = 200). System.Text.Json throws JsonException on null → non-nullable value type. The agent returns HTTP 500, PostActionAsync returns false, and the MCP tool reports "Failed to perform swipe gesture" for a completely valid call.

Recommendation: Apply defaults before constructing the JsonObject in AgentClient.GestureAsync, or conditionally omit null keys:

// Option A: omit nulls from the JsonObject
if (distance.HasValue) payload["distance"] = distance.Value;
if (durationMs.HasValue) payload["durationMs"] = durationMs.Value;

Note: This bug exists in the pre-existing AgentClient.GestureAsync — the PR exposes it via the new MCP tool. The fix belongs in the driver.


🟡 MODERATE — maui_key: Required key parameter conflicts with text-only usage (2/3 reviewers)

File: src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/InteractionTools.cs, line ~54

Scenario: AI agent wants to type text into an element (e.g., text="hello") without pressing a named key. The key parameter is a required non-nullable string, so the agent must always provide it — but there's no guidance for what to pass in text-only mode. The agent will likely guess "enter" or "", causing an unwanted enter keypress alongside the text, or an empty string that may be silently rejected.

Recommendation: Make key optional (string? key = null) and validate that at least one of key or text is provided:

if (string.IsNullOrEmpty(key) && string.IsNullOrEmpty(text))
    return "Must provide at least one of 'key' or 'text'.";

🟢 MINOR — maui_capabilities: Error message misleading for older agents (2/3 reviewers)

File: src/Cli/Microsoft.Maui.Cli/DevFlow/Mcp/Tools/AgentTools.cs, line ~96

Scenario: AI connects to an older agent that doesn't implement /api/v1/agent/capabilities. If GetJsonAsync returns default(JsonElement) (Undefined), the message "Agent not responding. Is the app running?" is misleading — the app is running, the endpoint just doesn't exist.

Recommendation: Use a more diagnostic message: "Unable to retrieve capabilities. The agent may not support this feature or may be an older version."


Discarded Findings (single reviewer only — not confirmed by cross-examination)

Finding Flagged By Verdict
Batch validation should enforce semantic rules per action type Reviewer 3 Discarded — Reviewers 1 & 2 confirmed this follows the established lightweight-validation pattern; backend returns structured per-action errors
maui_key success message omits text parameter feedback Reviewer 1 Discarded — single reviewer
maui_key success message "may have had no effect" is misleading Reviewer 2 Discarded — single reviewer
maui_gesture description lists long-press as distinct type Reviewer 1 Discarded — single reviewer
Batch error message casing inconsistency ("Null" vs "null") Reviewer 2 Discarded — single reviewer

Summary

Severity Count Key Theme
🟡 MODERATE 3 Exception safety, serialization bug, API design
🟢 MINOR 1 Error message accuracy

Overall: Clean, well-structured PR that follows established MCP tool patterns. The most impactful issue is the gesture serialization bug (nullable → non-nullable deserialization failure) which causes valid default-parameter calls to fail silently. The batch exception handling gap is straightforward to fix. The key parameter design could benefit from making key optional to support text-only scenarios.

Test coverage: No new unit tests added for the 5 new tools. The PR notes 260 existing tests are unaffected. Consider adding tests for the batch JSON validation logic (valid/invalid arrays, edge cases) and gesture parameter handling in a follow-up.

Note

🔒 Integrity filter blocked 1 item

The following item were blocked because they don't meet the GitHub integrity level.

  • #100 list_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Expert Code Review · ● 15.4M ·

…' fields

The validation logic accepts either 'action' or 'type' on each action object,
but the error message only mentioned 'action', which would confuse AI agents.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jfversluis
Copy link
Copy Markdown
Member

'action' or 'type').

Follow-up items for @rmarinho (non-blocking, from the expert review):

  1. Batch exception agent.BatchAsync() doesn't catch HttpRequestException/TaskCanceledException like other tools. Consider wrapping with a try/catch that returns a friendly error.handling
  2. Gesture nullable distance/durationMs serialize as JSON null which can fail on the agent's non-nullable DTO. Pre-existing in AgentClient.GestureAsync, but this PR exposes it. Fix belongs in the driver (omit nulls from JsonObject).params
  3. maui_key required key consider making key optional for text-only input scenarios.param

None of these are the tools follow established patterns and CI is green.blocking

Copy link
Copy Markdown
Member

@jfversluis jfversluis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed with multi-model consensus (Opus 4.5 + Sonnet 4) cross-referenced with the expert adversarial review. Pushed fix for the batch error message. Remaining items noted as non-blocking follow-ups. CI green, tools follow MCP conventions, descriptions are AI-agent-friendly.

@jfversluis jfversluis merged commit 64690b1 into main Apr 24, 2026
2 of 3 checks passed
@jfversluis jfversluis deleted the feat/mcp-critical-tools branch April 24, 2026 10:44
rmarinho pushed a commit that referenced this pull request Apr 24, 2026
… message (#144)

* Harden MCP tools: batch exception handling, gesture null params, capabilities message

- Wrap BatchAsync in try/catch for HttpRequestException, TaskCanceledException,
  and JsonException so batch tool returns a friendly error instead of crashing
- Omit null distance/durationMs from gesture JsonObject to prevent agent-side
  deserialization failure on non-nullable DTO properties
- Improve capabilities error message to distinguish unreachable agents from
  older agents that lack the capabilities endpoint

Follow-up to #115.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review feedback: ScrollAsync nulls, OperationCanceledException, error messages

- Fix ScrollAsync to omit null itemIndex/groupIndex/scrollToPosition/elementId
  from JsonObject (same pattern as the GestureAsync fix)
- Widen batch catch filter from TaskCanceledException to
  OperationCanceledException (the base class)
- Improve batch and capabilities error messages to mention both
  connectivity and version/feature support

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PureWeen added a commit to dotnet/maui that referenced this pull request Apr 27, 2026
…sus (#35111)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

Adds a `/review` slash command that triggers a 3-model adversarial code
review on any PR.

## How It Works

1. A maintainer comments `/review` on a PR
2. The orchestrator (Opus) dispatches 3 parallel sub-agents (Opus,
Sonnet, Codex) to independently review the PR
3. Findings go through adversarial consensus — 3/3 include, 2/3 include,
1/3 gets challenged by the other 2 models
4. Results posted as inline review comments on diff lines + a COMMENT
review summary

## Files

| File | Purpose |
|------|---------|
| `.github/workflows/review.agent.md` | `/review` slash command trigger
+ workflow_dispatch for testing |
| `.github/workflows/shared/review-shared.md` | Shared orchestration
(multi-model dispatch, consensus, posting) |
| `.github/workflows/review.agent.lock.yml` | Auto-generated compiled
workflow |
| `.github/aw/actions-lock.json` | Pinned action versions (adds v0.71.0,
preserves existing entries) |

## Design Decisions

- **`/review` only** — no auto-review-on-open to avoid cost on every PR
in a large repo
- **COMMENT-only reviews** — `allowed-events: [COMMENT]` prevents stale
blocking reviews that cannot be dismissed
([gh-aw#27655](github/gh-aw#27655))
- **Inline + summary** — `create_pull_request_review_comment` for
diff-line annotations, `submit_pull_request_review` for summary,
`add_comment` as fallback
- **Gated to write+ roles** — `roles: [admin, maintainer, write]`
- **Token-optimized** — orchestrator delegates file reading to
sub-agents, caps follow-ups at 2 models and 3 disputed findings
- **Sub-agents use `.github/skills/code-review/SKILL.md`** — existing
MAUI code review skill with 345 lines of maintainer-sourced review rules

## Trial Run

Validated end-to-end via `gh aw trial`:
- [PureWeen/gh-aw-trial
run](https://github.com/PureWeen/gh-aw-trial/actions/runs/24992602411) —
all 6 jobs passed (pre_activation, activation, agent, detection,
safe_outputs, conclusion)
- Compiled with 0 errors, 0 warnings at gh-aw v0.71.0

## Provenance

Ported from [dotnet/maui-labs PR
#118](dotnet/maui-labs#118), iteratively tested
and refined across:
- [dotnet/maui-labs PR
#115](dotnet/maui-labs#115 (comment))
(add_comment path verified)
- [PureWeen/PolyPilot PR
#656](PureWeen/PolyPilot#656) (inline review
comments verified)
- [dotnet/maui-labs PR
#123](dotnet/maui-labs#123) (inline + summary
verified)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
devanathan-vaithiyanathan pushed a commit to devanathan-vaithiyanathan/maui that referenced this pull request Jun 1, 2026
…sus (dotnet#35111)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Summary

Adds a `/review` slash command that triggers a 3-model adversarial code
review on any PR.

## How It Works

1. A maintainer comments `/review` on a PR
2. The orchestrator (Opus) dispatches 3 parallel sub-agents (Opus,
Sonnet, Codex) to independently review the PR
3. Findings go through adversarial consensus — 3/3 include, 2/3 include,
1/3 gets challenged by the other 2 models
4. Results posted as inline review comments on diff lines + a COMMENT
review summary

## Files

| File | Purpose |
|------|---------|
| `.github/workflows/review.agent.md` | `/review` slash command trigger
+ workflow_dispatch for testing |
| `.github/workflows/shared/review-shared.md` | Shared orchestration
(multi-model dispatch, consensus, posting) |
| `.github/workflows/review.agent.lock.yml` | Auto-generated compiled
workflow |
| `.github/aw/actions-lock.json` | Pinned action versions (adds v0.71.0,
preserves existing entries) |

## Design Decisions

- **`/review` only** — no auto-review-on-open to avoid cost on every PR
in a large repo
- **COMMENT-only reviews** — `allowed-events: [COMMENT]` prevents stale
blocking reviews that cannot be dismissed
([gh-aw#27655](github/gh-aw#27655))
- **Inline + summary** — `create_pull_request_review_comment` for
diff-line annotations, `submit_pull_request_review` for summary,
`add_comment` as fallback
- **Gated to write+ roles** — `roles: [admin, maintainer, write]`
- **Token-optimized** — orchestrator delegates file reading to
sub-agents, caps follow-ups at 2 models and 3 disputed findings
- **Sub-agents use `.github/skills/code-review/SKILL.md`** — existing
MAUI code review skill with 345 lines of maintainer-sourced review rules

## Trial Run

Validated end-to-end via `gh aw trial`:
- [PureWeen/gh-aw-trial
run](https://github.com/PureWeen/gh-aw-trial/actions/runs/24992602411) —
all 6 jobs passed (pre_activation, activation, agent, detection,
safe_outputs, conclusion)
- Compiled with 0 errors, 0 warnings at gh-aw v0.71.0

## Provenance

Ported from [dotnet/maui-labs PR
dotnet#118](dotnet/maui-labs#118), iteratively tested
and refined across:
- [dotnet/maui-labs PR
dotnet#115](dotnet/maui-labs#115 (comment))
(add_comment path verified)
- [PureWeen/PolyPilot PR
dotnet#656](PureWeen/PolyPilot#656) (inline review
comments verified)
- [dotnet/maui-labs PR
dotnet#123](dotnet/maui-labs#123) (inline + summary
verified)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants