mergeDiscoveredToolingState now carries over probedTools from existing
servers when the config fingerprint is unchanged. The equality check in
syncProjectDiscoveredTooling also strips probedTools before comparing,
so runtime-only probe data never triggers a spurious state replacement.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Some MCP servers (e.g., eschat.microsoft.com/mcp) serve their
OAuth Protected Resource Metadata at the origin without the path
suffix. Add a third candidate URL that strips the path, matching
VS Code's discovery behavior.
Tried in order:
1. RFC 9728: {origin}/.well-known/{suffix}{path}
2. Appended: {origin}{path}/.well-known/{suffix}
3. Origin-only: {origin}/.well-known/{suffix}
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When multiple MCP servers expose the same tool names (e.g., several
kusto-mcp instances), each server's group now shows its tools instead
of only the first server getting the tools and others showing 0/0.
Deduplicate the effectiveAutoApprovedCount to avoid double-counting
shared tools in the pill header.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When MCP server configs declare wildcard tools (empty tools array),
the Copilot SDK has no API to list individual tool names. Add direct
MCP protocol probing using @modelcontextprotocol/sdk to discover
available tools from each accepted server.
- Add McpToolProber service supporting stdio/SSE/HTTP transports
- Probe accepted MCP servers on project load, acceptance, and rescan
- Store probed tools on DiscoveredMcpServer and McpServerDefinition
- Use probed tools in listApprovalToolDefinitions when declared tools
are empty, so the approval pill shows individual tool toggles
- Remove unused isMcpServerApprovalKey helper
- Fix effectiveAutoApprovedCount Math.max workaround in ChatPane
- Add comprehensive tests for probed tool behavior
- Update ARCHITECTURE.md tooling integration section
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
MCP servers configured with empty tools arrays (wildcard) now appear in the
auto-approval pill with a server-level toggle. When toggled, a server-level
approval key (mcp_server:<name>) is added to autoApprovedToolNames. The
sidecar matches this key against PermissionRequestMcp.ServerName to auto-
approve all tools from that server without needing individual tool names.
- Add buildMcpServerApprovalKey/isMcpServerApprovalKey helpers
- Create approval groups for all MCP servers including empty-tools ones
- Add serverApprovalKey to ApprovalToolGroup for server-level toggles
- Update sidecar RequiresToolCallApproval to check server-level keys
- Include server-level keys in listApprovalToolNames for pruning safety
- Add tests for both shared domain and sidecar approval matching
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Group MCP tools by server and LSP tools by profile in the approval popover
instead of showing a flat list. Each server/profile group gets a collapsible
header with a batch toggle to approve/unapprove all tools at once. Add a
search filter (visible when >10 tools) and partial-state indicators for
groups with mixed approval. Add groupApprovalToolsByProvider shared helper
with tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Give each scratchpad session its own working directory, migrate existing scratchpad sessions on workspace load, and route sidecar turns through the session-specific cwd. Add regression coverage for create, duplicate, delete, and migration flows, and document the new persistence model.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the old disconnected-node addAgentNodeToGraph with the
mode-aware addAgentToGraph so new agents are automatically wired
into the graph topology. Replace the graph-nuking removeAgent
path with removeAgentFromGraph for surgical node removal. Split
emitChange into graph-preserving and mode-change paths so editing
agent properties no longer discards custom positions and edges.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add mode-aware graph mutation helpers for pattern topology so backend
code can add and remove agents without forcing a full graph rebuild.
Also preserve an existing pattern graph in savePattern instead of
re-syncing it from defaults, and cover the new behavior with shared
and main-process tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use provider-aware OAuth handling instead of a single hardcoded client ID.
GitHub now follows VS Code's GitHub auth setup with the GitHub client ID,
GitHub authorize/token endpoints, prompt=select_account, vscode.dev/redirect,
and JSON-compatible token exchange. Entra keeps the Copilot client ID via a
known provider match, while unknown providers still fall back to metadata
and dynamic registration.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Some MCP servers place .well-known metadata at the appended path
(e.g. /v1/.well-known/oauth-protected-resource) instead of the
RFC 9728 compliant inserted path. Now tries the RFC-compliant URL
first and falls back to the appended form.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When a user enables an HTTP MCP server for a session, proactively probe
the server URL. If it returns 401 and has discoverable OAuth metadata
(RFC 9728), automatically trigger the full OAuth 2.1 + PKCE flow and
open the browser for consent — matching VS Code's behavior.
- Add requiresOAuth() probe: GET server URL → check 401 → check PRM
- Add probeAndAuthenticateHttpMcpServers() in AryxAppService
- Call proactive probe from updateSessionTooling (fire-and-forget)
- Skip servers that already have stored tokens
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create mcpTokenStore: in-memory token storage keyed by normalized server URL
with automatic expiry checking
- Create mcpOAuthService: full OAuth 2.1 + PKCE flow implementation
- Protected Resource Metadata discovery (RFC 9728)
- Authorization Server Metadata fetch (RFC 8414)
- Dynamic Client Registration (RFC 7591) when no static client ID
- PKCE S256 code challenge generation
- Local HTTP callback server for auth code receipt
- Browser-based consent via Electron shell.openExternal
- Authorization code to token exchange
- Add startSessionMcpAuth IPC channel and handler to trigger OAuth flow
- Inject stored OAuth tokens as Authorization headers in buildRunTurnToolingConfig
- Update McpAuthBanner with 'Authenticate in browser' button and loading state
- Add tests for token store (7 tests) and token injection (3 tests)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add McpOauthRequiredEvent and McpOauthStaticClientConfigEvent to sidecar contracts
- Add PendingMcpAuthRecord domain type with status tracking (pending/authenticating/failed/done)
- Add pendingMcpAuth field to SessionRecord for session-level auth state
- Wire onMcpOAuthRequired callback through sidecarProcess, runTurnPending, and AryxAppService
- Handle mcp-oauth-required events: set session pendingMcpAuth, clear on turn finalize/cancel
- Add dismissSessionMcpAuth IPC channel with preload binding and handler registration
- Create McpAuthBanner component (amber-themed, shows server name/URL, dismiss button)
- Integrate McpAuthBanner into ChatPane with placeholder text and App.tsx callback
- Update test fixtures for new RunTurnPendingCommand.onMcpOAuthRequired field
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add InteractionMode type and ExitPlanModeRequestedEvent to sidecar contracts
- Add PendingPlanReviewRecord domain type and interactionMode to SessionRecord
- Wire onExitPlanMode callback through SidecarClient and RunTurnPendingCommand
- Pass session interaction mode to RunTurnCommand for sidecar consumption
- Handle exit-plan-mode-requested events in AryxAppService
- Add setSessionInteractionMode and dismissSessionPlanReview IPC methods
- Create PlanReviewBanner component with summary, markdown content, and actions
- Add plan mode toggle pill in ChatPane composer area
- Wire implement action as follow-up message (graceful degradation)
- Clear pending plan review on new turn, turn completion, and cancellation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a builtin tool label registry mapping all ~30 official SDK tool IDs
to human-readable display names. Update listApprovalToolDefinitions to
resolve labels from the registry instead of showing raw tool IDs like
read_bash or fetch_copilot_cli_documentation. Expand the fallback
runtime tool catalog from 6 to 23 non-internal standard tools.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wire the sidecar user-input-requested protocol event through the main
process, IPC layer, and renderer UI so agents can ask the user
interactive questions with choices and freeform input.
- Add UserInputRequestedEvent and ResolveUserInputCommand to sidecar
protocol types
- Add resolveUserInput method to SidecarClient and onUserInput callback
to runTurn
- Create PendingUserInputRecord domain type and add pendingUserInput to
SessionRecord
- Add handleUserInputRequested and resolveSessionUserInput to
AryxAppService with handle management
- Register sessions:resolve-user-input IPC channel with preload bridge
- Create UserInputBanner component with choice buttons and freeform
input
- Integrate UserInputBanner into ChatPane with header indicator
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace zip/tar archive distribution with platform-native installers:
- Windows: NSIS installer (.exe) with per-user install to
%LOCALAPPDATA%\Programs\Aryx, Start Menu and Desktop shortcuts,
Add/Remove Programs registration, and silent install support
- macOS: DMG disk image (.dmg) with drag-to-Applications experience
via create-dmg
- Linux: Debian package (.deb) with /opt/aryx installation,
/usr/bin/aryx symlink, desktop entry, hicolor icons, and
libsecret-1-0 dependency declaration
Add scripts/create-installer.ts as the platform-dispatching entry
point. Update CI workflow to produce native installers instead of
archives. Add installerAssetName to ReleaseTarget interface.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use createRequire for node:child_process so Bun on macOS can load gitService without ESM export-shape issues.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve execFile from named or default child_process exports so macOS Bun can load gitService in tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generalize the scratchpad-only model/reasoning-effort selector to work
in any session whose pattern has exactly one agent. This enables model
switching above the chat input for project 1-on-1 chats, not just
scratchpads.
- Rename ScratchpadSessionConfig -> SessionModelConfig across domain,
contracts, IPC, preload, and renderer
- Replace isScratchpadProject guard with agents.length === 1 check in
EryxAppService.updateSessionModelConfig and ChatPane pills gate
- Apply session model config in buildEffectivePattern whenever present,
regardless of project type
- Seed sessionModelConfig on session creation for any single-agent
pattern
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Clear only active agent statuses when a session reaches idle, and keep the terminal cancelled/error run cleanup in place. Add regression coverage for idle cleanup after cancellation-like flows.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Clear only still-active side-panel agent states when a run ends as cancelled or error, while preserving completed agent statuses. Add a renderer regression test for cancelled runs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve chat tooling from the selected session's project instead of the
separately tracked selectedProjectId so project-scoped discovered MCPs do
not appear for the wrong session. Also synchronize selectedProjectId when
a session is selected and add regression tests for both behaviors.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a Troubleshooting section under a Support nav group in Settings:
- Open App Data Folder: reveals the user-data directory in the OS file
explorer via shell.openPath.
- Reset Local Workspace: destructive action that deletes workspace.json
and scratchpad contents, clears the in-memory cache, and reseeds
defaults. Auth secrets are preserved. Requires two-step confirmation.
New IPC channels, ElectronApi methods, and preload bridge added for
openAppDataFolder and resetLocalWorkspace. Existing electron mock in
tests updated to include shell.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add CSS styling for selected edges (indigo highlight with glow)
- Enable orchestrator↔agent connections in group-chat mode
- Downgrade disconnected-agent validation from error to warning
- Rename addHandoffEdge to addEdge (generic for all modes)
- Add tests for group-chat connection rules
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend edge deletion to group-chat orchestrator↔agent edges in addition
to handoff agent↔agent edges. Structural edges (user-input/output,
distributor/collector) remain non-deletable across all modes.
Sequential, concurrent, and single modes keep fully structural topologies
with no user-deletable edges.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Color-code edges by semantic role: structural edges (system↔node) in
muted zinc, agent-to-agent edges in indigo for clear visual separation
- Switch from smoothstep to bezier curves for smoother, more natural
edge routing that reduces right-angle overlaps
- Stagger agent nodes at alternating X offsets in concurrent, handoff,
and group-chat layouts so parallel fan-out/fan-in edges take distinct
bezier paths instead of stacking
- Increase spacing in all layouts to give edges more room
- Add dagre-powered auto-layout button (top-right of canvas) that
computes optimal left-to-right hierarchical node positions
- Add 2 new tests for auto-layout across all orchestration modes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add ArrowClosed markers to all graph edges for clear directional flow
- Replace generic Bot icon with AI provider logos (OpenAI, Anthropic,
Google) on agent nodes, inferred from the agent's model id
- Show model display name as subtitle on agent nodes (e.g. 'GPT-5.4',
'Claude Opus 4.5')
- Thread availableModels catalog from PatternEditor through canvas to
resolve friendly model names; falls back to raw model id
- Add 3 new tests for arrow markers, provider icons, and model labels
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Hide input handle on User Input nodes and output handle on User Output
nodes (separate userInputNode/userOutputNode node types)
- Enable edge deletion in handoff mode only (Delete key or React Flow UI);
only agent-to-agent edges are deletable, structural edges are protected
- Block all edge mutations (add/delete) in concurrent and group chat modes
- Add agent as disconnected node without auto-rebuilding the graph
- Add sequential reorder controls (↑↓) in the inspector panel with
position/order swap and automatic edge rebuilding
- Replace circular group chat layout with vertical column to prevent
bidirectional edge crossings
- Tighten handoff layout spacing so edges between triage and specialists
don't overlap nodes
- Use smoothstep edge type for cleaner edge routing across all modes
- Add 6 new tests covering reorder, disconnected add, edge deletion rules,
and node type assertions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the flat agent list and static flow diagrams in PatternEditor with
an interactive React Flow canvas backed by the authoritative PatternGraph
model. Users can now see and manipulate orchestration topology visually.
Changes:
- Add @xyflow/react (React Flow) as a canvas library
- Create patternGraph view-model layer for graph-to-canvas projection
- Create GraphNodes with custom system/agent node components
- Create PatternGraphCanvas with drag, connect, and selection support
- Create PatternGraphInspector for selected node/agent details
- Rewrite PatternEditor with split layout: canvas + inspector sidebar
- Add dark theme CSS overrides for React Flow
- Add 11 tests covering view-model projection, connection rules, and
graph mutation helpers
- Update ARCHITECTURE.md to reflect the new renderer graph boundary
The canvas projects PatternGraph into React Flow nodes/edges. Handoff mode
supports drawing new agent-to-agent edges interactively. Node positions
persist to the graph on drag completion. Agent editing moves from inline
forms to the inspector panel on node selection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>