Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
51f6a68
CopilotService: catch StartAsync failures and set NeedsConfiguration;…
PureWeen Feb 16, 2026
75f6fa6
Fix: dispose failed client and null reference after StartAsync failure
PureWeen Feb 16, 2026
165f607
Add test proving StartAsync throws on unreachable server
PureWeen Feb 16, 2026
5ada2f3
Extract interfaces for CopilotService dependencies and add integratio…
PureWeen Feb 16, 2026
658f1c0
Add missing debug log in ReconnectAsync, suppress CS0067 warnings in …
PureWeen Feb 16, 2026
b30c5e7
Remove stray TestSdk project and null.dll
PureWeen Feb 16, 2026
069868c
Fix session loss during mode switches (Embedded↔Persistent)
PureWeen Feb 16, 2026
c486675
Fix mode persistence, add fallback notice, and bug report button
PureWeen Feb 16, 2026
31ffddd
Add CLI source/mode persistence tests, scenarios, and update repo docs
PureWeen Feb 16, 2026
ce2b047
Split sidebar footer into Report Bug and Fix/Feature buttons
PureWeen Feb 16, 2026
7c640ad
Add settings resilience instruction to copilot prompt
PureWeen Feb 16, 2026
58e11c2
Fix terminal launch: write scripts to temp files to avoid shell quoti…
PureWeen Feb 16, 2026
a22134d
Fix terminal launch: use 'open -a Terminal' to avoid sandbox inheritance
PureWeen Feb 16, 2026
d806553
Add --yolo flag to copilot launch for non-interactive permission grants
PureWeen Feb 16, 2026
e001226
Add inline 'Reconnect Now' hint when transport mode changes
PureWeen Feb 16, 2026
dc67f99
Make fix-it copilot launch interactive with --resume
PureWeen Feb 16, 2026
592783a
Use -i (interactive) flag instead of -p for copilot launch
PureWeen Feb 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,31 @@ This is a .NET MAUI Blazor Hybrid app targeting Mac Catalyst, Android, and iOS.
3. **SDK** — `GitHub.Copilot.SDK` (`CopilotClient`/`CopilotSession`) communicates with the Copilot CLI process via ACP (Agent Control Protocol) over stdio or TCP.

### Connection Modes
- **Embedded** (default on desktop): SDK spawns copilot via stdio, dies with app.
- **Persistent**: App spawns a detached `copilot --headless` server tracked via PID file; survives restarts.
- **Embedded** (fallback): SDK spawns copilot via stdio, dies with app.
- **Persistent** (default on desktop): App spawns a detached `copilot --headless` server tracked via PID file; survives restarts.
- **Remote**: Connects to a remote server URL (e.g., DevTunnel). Only mode available on mobile.
- **Demo**: Local mock responses for testing without a network connection.

Mode and CLI source selections persist immediately to `~/.polypilot/settings.json` when the user clicks the corresponding card — no "Save & Reconnect" needed for the choice itself. "Save & Reconnect" is only needed to actually reconnect with the new settings.

### Mode Switching & Session Persistence
When switching between Embedded and Persistent modes (via Settings → Save & Reconnect), `ReconnectAsync` tears down the existing client and restores sessions from disk. Key safety mechanisms:

1. **Merge-based `SaveActiveSessionsToDisk()`** — reads the existing `active-sessions.json` and preserves entries whose session directory still exists on disk, even if not currently in memory. This prevents partial restores from clobbering the full list. The merge logic is in `CopilotService.Persistence.cs` → `MergeSessionEntries()` (static, testable).

2. **`_closedSessionIds`** — tracks sessions explicitly closed by the user so the merge doesn't re-add them. Cleared on `ReconnectAsync`.

3. **`IsRestoring` flag** — set during `RestorePreviousSessionsAsync`. Guards per-session `SaveActiveSessionsToDisk()` and `ReconcileOrganization()` calls to avoid unnecessary disk I/O and race conditions during bulk restore.

4. **Persistent fallback notice** — if `InitializeAsync` can't start the persistent server, it falls back to Embedded and sets `FallbackNotice` with a visible warning banner on the Dashboard.

### WebSocket Bridge (Remote Viewer Protocol)
`WsBridgeServer` runs on the desktop app and exposes session state over WebSocket. `WsBridgeClient` runs on mobile apps to receive live updates and send commands. The protocol is defined in `Models/BridgeMessages.cs` with typed payloads and message type constants in `BridgeMessageTypes`.

`DevTunnelService` manages a `devtunnel host` process to expose the bridge over the internet, with QR code scanning for easy mobile setup (`QrScannerPage.xaml`).

### Platform Differences
`Models/PlatformHelper.cs` exposes `IsDesktop`/`IsMobile` and controls which `ConnectionMode`s are available. Mobile can only use Remote mode. Desktop defaults to Embedded.
`Models/PlatformHelper.cs` exposes `IsDesktop`/`IsMobile` and controls which `ConnectionMode`s are available. Mobile can only use Remote mode. Desktop defaults to Persistent.

## Critical Conventions

Expand Down Expand Up @@ -183,9 +197,20 @@ Test files in `PolyPilot.Tests/`:
- `AgentSessionInfoTests.cs` — Session info properties, history, queue
- `SessionOrganizationTests.cs` — Groups, sorting, metadata
- `ConnectionSettingsTests.cs` — Settings persistence
- `CopilotServiceInitializationTests.cs` — Initialization error handling, mode switching, fallback notices, CLI source persistence
- `SessionPersistenceTests.cs` — Merge-based `SaveActiveSessionsToDisk()`, closed session exclusion, directory checks
- `ScenarioReferenceTests.cs` — Validates UI scenario JSON + cross-references with unit tests
- `EventsJsonlParsingTests.cs` — SDK event log parsing
- `PlatformHelperTests.cs` — Platform detection
- `ToolResultFormattingTests.cs` — Tool output formatting
- `UiStatePersistenceTests.cs` — UI state save/load

UI scenario definitions live in `PolyPilot.Tests/Scenarios/mode-switch-scenarios.json` — executable via MauiDevFlow CDP commands against a running app.

Tests include source files via `<Compile Include>` links in the csproj. When adding new model classes, add a corresponding link entry.

### Test Safety
- Tests must **NEVER** call `ConnectionSettings.Save()` or `ConnectionSettings.Load()` — these read/write `~/.polypilot/settings.json` which is shared with the running app.
- All tests use `ReconnectAsync(settings)` with an in-memory settings object.
- Never use `ConnectionMode.Embedded` in tests — it spawns real copilot processes. Use `ConnectionMode.Persistent` with port 19999 for deterministic failures, or `ConnectionMode.Demo` for success paths.
- CopilotService dependencies are injected via interfaces: `IChatDatabase`, `IServerManager`, `IWsBridgeClient`, `IDemoService`. Test stubs live in `TestStubs.cs`.
Loading