Commit Graph
215 Commits
Author SHA1 Message Date
David KayaandCopilot cf41279ff5 fix: clamp auto-approval pill count to known tools
The auto-approval pill displayed effectiveAutoApproved.size as the
numerator, which could include tool names not present in the approval
tool list (e.g. names added via 'Always approve' for tools that aren't
in runtimeTools yet). This caused impossible counts like '17/14'.

Compute the count by intersecting effectiveAutoApproved with the actual
approvalTools list, so the numerator never exceeds the denominator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 20:40:30 +01:00
David KayaandCopilot c02589f4c0 fix: only probe OAuth for newly enabled MCP servers
Previously, every tooling update re-probed all enabled HTTP MCP servers
for OAuth requirements. Now it compares the new selection against the
previous one and only probes servers that were just enabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 20:31:29 +01:00
David KayaandCopilot 73595039fc fix: support provider-specific MCP OAuth settings
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>
2026-03-27 20:23:26 +01:00
David KayaandCopilot 81bddcbd63 fix: align MCP OAuth flow with Copilot client ID requirements
- Use vscode.dev/redirect as redirect URI when using the Copilot client
  ID, with the local callback URL encoded in the state parameter
- Use PRM resource scopes (e.g. api://icmmcpapi-prod/mcp.tools) instead
  of generic OIDC scopes, always include offline_access
- Listen on root path instead of /callback to match vscode.dev/redirect
  behavior
- Extract PRM scopes from protected resource metadata discovery

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 20:15:25 +01:00
David KayaandCopilot 53f1167681 feat: use GitHub Copilot client ID as default for MCP OAuth
Use the well-known Copilot client ID (aebc6443-996d-45c2-90f0-388ff96faa56)
when no static client config is provided and the auth server doesn't
support dynamic client registration. This matches how VS Code authenticates
with Entra ID-backed MCP servers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 20:08:40 +01:00
David KayaandCopilot 4f7b479996 fix: fall back to openid-configuration for auth server metadata discovery
Microsoft Entra ID and other OIDC providers expose metadata at
.well-known/openid-configuration rather than RFC 8414's
.well-known/oauth-authorization-server. Now tries both suffixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 20:06:02 +01:00
David KayaandCopilot 0fd7a04a51 fix: try both RFC 9728 and appended well-known URL paths for MCP OAuth discovery
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>
2026-03-27 20:00:50 +01:00
David KayaandCopilot 6c6b49fde4 fix: probe PRM directly instead of GET-ing the MCP server URL
MCP servers use POST/SSE, not GET. A plain GET to the server URL can
return 405, 404, or other codes unrelated to authentication. Instead,
go directly to the .well-known/oauth-protected-resource endpoint and
check whether it returns valid metadata with authorization_servers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 19:48:49 +01:00
David KayaandCopilot d73eaae30b fix: correct well-known URL construction per RFC 9728
The .well-known/{suffix} segment was being appended to the full URL
path instead of inserted after the origin. For example:

  Wrong:   https://api.example.com/mcp/.well-known/oauth-protected-resource
  Correct: https://api.example.com/.well-known/oauth-protected-resource/mcp/

- Extract buildWellKnownUrl() helper in mcpTokenStore (Electron-free)
- Fix all 3 call sites: requiresOAuth probe, PRM discovery, auth
  server metadata
- Add 6 unit tests for URL construction with various path shapes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 19:46:25 +01:00
David KayaandCopilot 1868a79d9a feat: add 'Always approve' button for tool-call approvals
When a tool-call approval banner appears, users can now click 'Always
approve' to both approve the current call AND add the tool to the
session's autoApprovedToolNames. Future calls to that tool are then
auto-approved without showing the banner.

- Add alwaysApprove?: boolean to ResolveSessionApprovalInput
- In resolveSessionApproval, atomically append tool to session
  approvalSettings when alwaysApprove is true (avoids running guard)
- Add 'Always approve' button in ApprovalBanner (tool-call kind only)
- Wire through ChatPane and App.tsx with updated callback signatures

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 19:34:50 +01:00
David KayaandCopilot 4f1ae86021 fix: add diagnostic logging to MCP OAuth probing
Add [aryx oauth] log messages throughout the proactive auth flow so
failures are visible in the Electron main process console (DevTools →
Main Process or terminal output). Logs cover: probe start, HTTP status,
PRM discovery, token skip, flow start, and success/failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 19:31:03 +01:00
David KayaandCopilot f0c2b4982b feat: proactive OAuth when enabling HTTP MCP servers
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>
2026-03-27 19:26:59 +01:00
David KayaandCopilot ac48aa58e0 feat: implement MCP OAuth 2.1 flow, token storage, and injection
- 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>
2026-03-27 19:15:37 +01:00
David KayaandCopilot f9757d5ce2 feat: add MCP OAuth authentication frontend wiring and banner
- 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>
2026-03-27 19:09:11 +01:00
David KayaandCopilot 192c28f721 feat: surface MCP OAuth sidecar events
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-27 19:01:46 +01:00
David KayaandCopilot b670680a7d refactor: improve plan mode UX with composer-integrated toggle and guidance text
- Move plan mode toggle from pills row to composer send button area
- Plan toggle sits next to the send button as a mode switch icon
- Send button turns emerald when plan mode is active
- Add mode indicator strip below composer when plan mode is on
- Replace 'Implement this plan' auto-send button with instructional
  guidance text that tells the user to send a follow-up message
- Keep Dismiss button to clear the plan review banner

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 23:46:04 +01:00
David KayaandCopilot 231be36e6c feat: add plan mode frontend support with mode toggle and plan review UI
- 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>
2026-03-26 23:39:48 +01:00
David KayaandCopilot 380e402512 feat: add backend plan mode checkpoints
Add backend support for plan-mode turn shaping and exit-plan review
checkpoints. Run-turn commands now accept an interaction mode,
plan-mode prompt guidance tells agents to produce a plan and call
exit_plan_mode, and the sidecar emits a structured
exit-plan-mode-requested event when the SDK raises that session event.

For now the backend intentionally treats exit_plan_mode as a turn
boundary and graceful-degradation review checkpoint. The current
Agent Framework GitHubCopilotAgent wrapper does not expose a clean way
to bridge the live CopilotSession back into same-turn exit-plan
resolution, so that follow-up remains documented for the frontend and a
future backend slice.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 23:29:32 +01:00
David KayaandCopilot c069b86add docs: add website update guideline to AGENTS.md
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 23:24:37 +01:00
David KayaandCopilot 912677fba0 feat: add tool metadata registry with human-readable labels
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>
2026-03-26 19:27:36 +01:00
David KayaandCopilot a1a044e7ca fix: filter internal runtime tools
Exclude internal runtime tools from sidecar capability discovery so they do not surface in the approval tool catalog.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 19:23:48 +01:00
David KayaandCopilot f15b1aedb1 feat: add ask_user interactive user input to frontend
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>
2026-03-26 17:45:27 +01:00
David KayaandCopilot 2ae4bd01b4 feat: add ask_user support to sidecar
Implement the Copilot SDK user input round-trip in the backend:
- add user-input-requested and resolve-user-input protocol DTOs
- add a CopilotUserInputCoordinator that mirrors approval flow with
  pending TaskCompletionSource state and explicit resolution
- wire SessionConfig.OnUserInputRequest through CopilotAgentBundle
  and CopilotWorkflowRunner
- extend SidecarProtocolHost to emit user input events, accept
  resolve-user-input commands, and filter ask_user from runtime
  approval tools
- add regression tests for the new coordinator and protocol flow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 17:34:49 +01:00
David KayaandCopilot 4c01d8b1a7 feat: surface structured permission details in approval UI
Wire the sidecar's new permissionDetail payload through the frontend:
- Add PermissionDetail interface to sidecar contract
- Add permissionDetail field to PendingApprovalRecord and thread
  through normalization and AryxAppService mapping
- Create PermissionDetailView component with kind-specific rendering:
  shell (command block + warning), write (filename + diff), read (path),
  mcp (server badge + args), url (prominent URL), memory (subject/fact),
  custom-tool (description + args), hook (message + args)
- ApprovalBanner shows structured detail when available, falls back to
  generic text for backward compatibility
- QueuedApprovalsList shows brief kind-specific summaries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 16:59:15 +01:00
David KayaandCopilot 13c543e2fd feat: add structured tool approval details to sidecar protocol
Expose SDK permission request details on approval-requested events via a
new permissionDetail payload. This preserves the existing title/detail
summary while carrying the command, URL, diff, args, and other
kind-specific data needed for richer approval UI in the renderer.

Also adds sidecar coverage for all supported permission request kinds and
verifies the new payload serializes over the protocol.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 16:40:41 +01:00
David KayaandCopilot 69562c19f3 fix: fix Inno Setup preprocessor defines via environment variables
ISCC's /D command-line flag combined with Node.js spawn on Windows
produces broken ISPP defines due to argument quoting conflicts.
Switch to environment variables read via GetEnv() — robust and
avoids all quoting issues. Product name and publisher are now
hardcoded in the ISS (they never change).

Verified: installer shows 'Aryx' and correct version in metadata.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 16:14:14 +01:00
David KayaandCopilot 7c1852f79f refactor: replace NSIS with Inno Setup for Windows installer
Switch from NSIS (early 2000s) to Inno Setup 6 — the modern standard
used by VS Code and most Electron apps. Features:

- Modern wizard UI (WizardStyle=modern)
- LZMA2/ultra64 solid compression (138.9 MB, down from 143 MB with NSIS)
- Per-user install to %LOCALAPPDATA%\Programs\Aryx (no admin needed)
- Optional desktop shortcut, Start Menu group
- Auto-closes running instance before install/uninstall
- Proper Add/Remove Programs integration via AppId
- Launch-after-install option

CI updated to install Inno Setup via Chocolatey on windows-latest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
v0.0.5
2026-03-26 14:47:11 +01:00
David KayaandCopilot d7d1b33a53 fix: fix CI installer creation for all platforms
- Windows: add NSIS installation step via Chocolatey in CI workflow
- macOS: fix create-dmg CLI invocation to match sindresorhus package
  API (--overwrite, --no-version-in-filename, --no-code-sign) and
  rename output to expected asset name
- Add rename import to create-installer.ts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
v0.0.4
2026-03-26 13:35:20 +01:00
David KayaandCopilot f838d2ac15 feat: add native platform installers for Windows, macOS, and Linux
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>
v0.0.3
2026-03-26 13:06:50 +01:00
David KayaandCopilot da7aa5cdd2 perf: enable .NET sidecar trimming and single-file publish
- Enable PublishTrimmed with TrimMode=partial to remove unused
  framework assemblies while preserving app/SDK code safety
- Enable PublishSingleFile to bundle all managed assemblies into
  one executable (sidecar goes from 254 files to 2 files)

Sidecar shrinks from 191 MB / 254 files to 134 MB / 2 files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
v0.0.2
2026-03-26 12:22:30 +01:00
David KayaandCopilot d1cc3c2e6d perf: optimize release artifact size and file count
- Move 15 renderer-only dependencies to devDependencies since they are
  already bundled by Vite (197 → 37 runtime deps)
- Pack app resources into asar archive with native addon unpacking
- Strip unused Electron locale files, keeping only en-US
- Remove non-essential Electron files (LICENSES.chromium.html, LICENSE)
- Remove default_app.asar from Electron distribution
- Strip .NET sidecar localization satellite assemblies (en only)

Release artifact shrinks from 607 MB / 10,525 files to 478 MB / 235 files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 12:19:46 +01:00
David KayaandCopilot cb05148231 fix: require child_process in gitService
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>
v0.0.1
2026-03-26 00:37:24 +01:00
David KayaandCopilot 66c129f8b9 fix: handle bun child_process interop
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>
2026-03-26 00:34:44 +01:00
David KayaandCopilot d9f3f5302a fix: resolve macos bun interop
Use Bun-safe Electron and child_process import patterns for macOS GitHub Actions tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:30:41 +01:00
David Kaya 40ef1c07b5 fix: failing macos test 2026-03-26 00:22:28 +01:00
David KayaandCopilot 88030eb48d refactor: finish Aryx rebrand sweep
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:17:14 +01:00
David KayaandCopilot 1edd3aed55 refactor: rename sidecar host to Aryx
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:14:12 +01:00
David KayaandCopilot 4e3c74497f feat: add macOS arm64 release build
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:06:07 +01:00
David KayaandCopilot 90cc32e737 fix: update macOS GitHub Actions runner
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 00:04:25 +01:00
David Kaya d02ccf22a2 feat: website changes 2026-03-26 00:01:32 +01:00
David KayaandCopilot d88d00df0d fix: make copilot CLI path resolution cross-platform
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 23:44:49 +01:00
David Kaya f94c3232b4 fix: screenshot 2026-03-25 23:36:50 +01:00
David KayaandCopilot 5ed2b8bcd4 feat: add product website for Cloudflare Pages
Single-page marketing site built with Astro 5 and Tailwind CSS v4.
Produces static HTML with zero client-side JS — ideal for Cloudflare
Pages deployment.

Sections: hero with screenshot placeholder, 6 feature cards,
5 orchestration patterns showcase, 4-step getting started guide,
tech banner, and footer.

Dark theme (zinc-950/indigo accents) matches the app aesthetic.
Responsive design with mobile navigation.

Build: cd website && bun install && bun run build
Output: website/dist/

To add a real screenshot, replace
website/public/images/screenshot-placeholder.svg with
website/public/images/screenshot.png and update the img src
in website/src/pages/index.astro.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:57:00 +01:00
David KayaandCopilot 968ae37279 feat: allow model selection in all single-agent sessions
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>
2026-03-25 22:41:46 +01:00
David Kaya 46b5de472e tests: some additional tests 2026-03-25 22:28:36 +01:00
David KayaandCopilot 628fdff29e fix: clear live agent status on cancel
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>
2026-03-25 22:20:57 +01:00
David KayaandCopilot c9cc2fd8e7 fix: clear stale agent activity on cancel
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>
2026-03-25 22:17:33 +01:00
David KayaandCopilot 82fdadb312 feat: add turn cancellation UI and main process wiring
Adds cancel-turn IPC channel, SidecarClient.cancelTurn(), TurnCancelledError,
EryxAppService.cancelSessionTurn(), finalizeCancelledTurn(), stop button in
ChatPane, and cancelled run status throughout the run timeline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:17:15 +01:00
David KayaandCopilot d84b3021f2 feat: add sidecar turn cancellation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 22:04:14 +01:00
David KayaandCopilot c8bb9d6f59 fix: align chat MCP tooling with session project
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>
2026-03-25 21:57:30 +01:00