Copilot Cleaner is a local cross-platform desktop app built with C# and Avalonia. It inspects GitHub Copilot session-state folders on disk, lists SDK-visible Copilot sessions, and lets the user decide which session-state folders or SDK sessions to clean up. The project targets net8.0 so it can build and publish for Windows, Linux, and macOS.
Program.cs,App.axaml, andApp.xaml.cs: Avalonia desktop application entry point.MainWindow.axamlandMainWindow.xaml.cs: main UI, grid behavior, aggregation controls, selection handling, folder picking, and cleanup commands.Models/: data models used by the UI.Services/: filesystem scanning, metadata parsing, row comparison, grouping, and cleanup operations.
- The app defaults the source path to
~/.copilot/session-state, the move target to~/.copilot/old_session-state, and the Copilot SDK home to~/.copilot. SessionScannerenumerates each session folder under the source path.- For each session folder, the scanner reads lightweight metadata and top-level filesystem facts into a
SessionRow. - Before a session-state scan,
CopilotSdkSessionServiceasks the official GitHub Copilot SDK for the session list so the grid can show whether each folder exists in the SDK-visible session list. MainWindowstreams rows into the session-stateDataGridas they are scanned so the UI becomes useful before the full scan completes.- The selected session row lazily loads recursive file entries into the bottom file-list grid.
- Move and delete commands operate on checked session-state rows, then remove successfully processed rows from the UI.
- The Copilot SDK Sessions tab loads session metadata with
CopilotClient.ListSessionsAsyncand deletes selected SDK sessions withCopilotClient.DeleteSessionAsync.
The app uses local file parsing for session-state folder details because those cleanup targets are local filesystem artifacts. It uses the official GitHub Copilot SDK for SDK-visible session enumeration and SDK-managed session deletion.
vscode.metadata.jsonis parsed withSystem.Text.Jsonand flattened into display columns.copilotshell.jsonis parsed withSystem.Text.Json, flattened under thecopilotshell.*prefix, and surfaced with a file-existence column for quick filtering.workspace.yamlis parsed with YamlDotNet and flattened into display values. If a session file is malformed, a narrow fallback salvages simple key/value fields and multi-line quoted summaries through end-of-file so fields such asworkspace.summarycan still be displayed.vscode.requests.metadata.jsonis summarized as a request count.events.jsonlis summarized by size during the initial scan. Expensive recursive file enumeration is deferred until a session is selected.- The Copilot SDK integration does not read or write
session-store.dbdirectly; it usesGitHub.Copilot.SDKAPIs.
The main window has three primary areas:
- A Session State tab with path and action controls for source folder, move target, scan, move, and delete.
- A sortable, reorderable session-state grid with row checkboxes and aggregation controls.
- A selected-session details area with lazy file-list loading and full flattened metadata values.
- A Copilot SDK Sessions tab with SDK home selection, SDK session loading, SDK metadata columns, missing-session-state selection, and SDK-backed deletion.
- An About / Licenses tab that displays the embedded
LICENSEtext first, followed by embeddedTHIRD_PARTY_NOTICES.mdtext.
Session State and Copilot SDK sorting is tracked per column and applied according to the visible left-to-right column order. Aggregation is represented by explicit group rows in the session grid, supports multiple ordered grouping levels, and supports group-level checkbox selection across nested groups.
Delete operations ask for confirmation. Move operations create the destination folder when needed and avoid overwriting existing session folders by adding a numeric suffix. Sessions with inuse.*.lock files are surfaced in the grid so active sessions can be avoided. SDK session deletion also asks for confirmation and routes through CopilotClient.DeleteSessionAsync rather than direct database mutation.
The UI uses Avalonia controls and storage-provider folder pickers rather than WPF or Windows Forms APIs. The service and model layers are designed around .NET filesystem and parsing APIs. Release automation publishes self-contained app artifacts for Windows, Linux, and macOS, but runtime behavior still depends on the host having Copilot session-state data and Copilot SDK/CLI support.
GitHub Actions includes a Windows, Linux, and macOS build workflow for pushes and pull requests to main. Release automation runs from v* tags or manual dispatch, publishes self-contained win-x64, win-arm64, linux-x64, osx-x64, and osx-arm64 ZIP files, and creates a GitHub Release. Dependabot tracks NuGet and GitHub Actions updates weekly.
License compliance is checked by Scripts/Check-Licenses.ps1, which restores the project when needed, reads obj/project.assets.json, validates NuGet license metadata for packages with compile/runtime/native assets against the approved policy, requires the main MIT LICENSE, and requires each notice-relevant package/version to appear in THIRD_PARTY_NOTICES.md. LICENSE and THIRD_PARTY_NOTICES.md are embedded into the app for the About / Licenses tab and copied into build and publish output. Build and release workflows also run Scripts/Test-PublishLicenses.ps1 after publish to verify that both license files are present and that any SDK-published copilot-cli runtime retains its LICENSE.md file.