feat: add GitHub Copilot CLI provider#6
Conversation
Adds `copilot_cli` as a new provider that discovers sessions from
~/.copilot/session-state/{uuid}/events.jsonl and integrates them
under the existing Copilot section in the UI.
Changes:
- New copilot_cli discovery, JSONL stream adapter, and event parser
- Registered across all provider registries, IPC contracts, and search
- UI: grouped under Copilot chip, independent Settings toggle with >_ icon
- styles.css: copilot_cli accent color tokens
Bug fixes:
- events.jsonl was read in full (8.4 MB+); now reads ≤16 KB via readFirstJsonlObject
- outputTokens from assistant.message events now stored as tokenOutput
- Missing data.result on tool.execution_complete no longer produces spurious "{}" DB row
- Path splitting with lastIndexOf replaced with dirname/basename from node:path
- Inline EMPTY_PROVIDER_COUNTS in useLiveWatchController replaced with import from app/constants
Tests: 929 passing (36 new) — parseWorkspaceYaml (9), parseCopilotCliEvent (12), providerGroups (13), integration fixture counts updated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Copilot CLI (copilot_cli) provider to Code Trail, discovering sessions from Copilot CLI’s events.jsonl stream under ~/.copilot/session-state/, indexing them as a distinct provider, and grouping them under the existing Copilot UI chip.
Changes:
- Core: introduce
copilot_clidiscovery + parsing + adapter/registry wiring, and include it in provider enums and search facet counts. - Desktop: add UI grouping helpers so Copilot CLI is shown under the Copilot chip while remaining independently toggleable in Settings.
- Tests/fixtures: add Copilot CLI fixture sessions and expand existing integration/unit tests for discovery, parsing, and grouping behavior.
Reviewed changes
Copilot reviewed 43 out of 44 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/contracts/canonical.ts | Adds copilot_cli to canonical provider enum. |
| packages/core/src/contracts/providerMetadata.ts | Adds Copilot CLI provider metadata + discovery path key. |
| packages/core/src/discovery/types.ts | Extends DiscoveryConfig with copilotCliRoot. |
| packages/core/src/discovery/shared.ts | Extends typed getDiscoveryPath overloads to include Copilot CLI. |
| packages/core/src/discovery/platformDiscoveryDefaults.ts | Adds default Copilot CLI root path under ~/.copilot/session-state. |
| packages/core/src/discovery/providers/copilotCli.ts | New Copilot CLI session discovery + lightweight workspace metadata parsing. |
| packages/core/src/providers/adapters/copilotCli.ts | New provider adapter hooking discovery + parsing into the ingestion pipeline. |
| packages/core/src/providers/registry.ts | Registers the new copilot_cli adapter. |
| packages/core/src/parsing/providerParsers.ts | Adds parseCopilotCliEvent and registers it for event parsing. |
| packages/core/src/search/searchMessages.ts | Adds copilot_cli facet counting to search aggregation results. |
| packages/core/src/testing/settingsInfoFixture.ts | Adds copilotCliRoot to test settings fixture paths. |
| packages/core/test-fixtures/providers/copilot-cli/session-state/session-001/workspace.yaml | New Copilot CLI workspace metadata fixture. |
| packages/core/test-fixtures/providers/copilot-cli/session-state/session-001/events.jsonl | New Copilot CLI JSONL event stream fixture. |
| packages/core/src/discovery/providers/copilotCli.test.ts | Unit tests for workspace.yaml parsing. |
| packages/core/src/parsing/providerParsers.test.ts | Unit tests for parseCopilotCliEvent. |
| packages/core/src/indexing/providerFixtures.integration.test.ts | Updates fixture indexing expectations to include Copilot CLI. |
| packages/core/src/discovery/discoverSessionFiles.pythonFixtures.test.ts | Updates provider discovery expectations for fixtures to include Copilot CLI. |
| packages/core/src/indexing/systemMessageRules.test.ts | Adds copilot_cli to default rules shape expectations. |
| packages/core/src/search/searchMessages.integration.test.ts | Adds copilotCliRoot to integration test discovery config. |
| apps/desktop/src/renderer/lib/providerGroups.ts | New UI-side grouping utilities (Copilot CLI under Copilot). |
| apps/desktop/src/renderer/lib/providerGroups.test.ts | Tests for provider grouping/toggling helpers. |
| apps/desktop/src/renderer/features/SearchView.tsx | Renders grouped provider chips + combined counts; group-toggle behavior. |
| apps/desktop/src/renderer/features/HistoryLayout.tsx | Uses grouped provider toggling for the project pane provider filters. |
| apps/desktop/src/renderer/components/history/ProjectPane.tsx | Displays grouped provider tags and combined counts in project pane. |
| apps/desktop/src/renderer/components/SettingsView.tsx | Adds Copilot CLI settings row/icon + “child provider” UX. |
| apps/desktop/src/renderer/styles.css | Adds Copilot CLI tag/chip styling tokens. |
| apps/desktop/src/renderer/features/useLiveWatchController.ts | Replaces local empty provider counts with canonical constant import. |
| .gitignore | Ignores .copilot/ and .squad/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove unused toggleGroupProviders import in ProjectPane.tsx - Set unresolvedProject dynamically based on projectPath presence - Use 'unresolved' resolutionSource (not null) when cwd is absent - Set repositoryUrl: null, store raw slug in sessionMetadata instead - Strip surrounding quotes from parsed YAML values - Add discovery integration tests (discoverCopilotCliFiles x6, discoverSingleCopilotCliFile x3) - Fix TypeScript strict-mode array access in tests with non-null assertions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 44 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Improve tool.execution_complete result handling: use content key when present (non-empty string), fall back to serializeUnknown only when result has keys other than 'content'; this prevents spurious messages for empty objects, empty-content wrappers, and similar edge cases - Fix getProviderWithChildren JSDoc to accurately describe that the given provider itself is included only when present in allProviders - Add tests: empty-content result, non-content structured result, and fix misleading test name in providerGroups.test.ts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 44 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- suffix Copilot CLI tool_result message ids with :result when a toolCallId is present so tool_use and tool_result source ids stay distinct - preserve the original toolCallId inside the serialized tool_use payload for correlation - add regression coverage for distinct tool_use/tool_result ids and update parser expectations accordingly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The copilot review was directionally correct, not a pure false positive. The indexer did not crash because duplicate source IDs were being rewritten to ~dupN, but that still produced unstable message identity and noisy duplicate-rewrite notices. The parser now emits a distinct tool_result source ID ({toolCallId}:result) while preserving the original toolCallId inside the serialized tool-use payload for correlation. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 43 out of 44 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Adds GitHub Copilot CLI (
~/.copilot/session-state/) as a new provider to Code Trail. Discovers sessions from theevents.jsonlJSONL event stream format and integrates Copilot CLI history under the existing Copilot section in the UI — no separate top-level chip.Copilot CLI not installed → no errors, provider simply returns no sessions.
Changes
37 modified files · 5 new source files · 2 new fixture files · +557 lines / −58 lines
Core
copilot_cliprovider: session discovery (copilotCli.ts), JSONL stream adapter, event parser (parseCopilotCliEvent), registered across all provider registries and IPC contractsplatformDiscoveryDefaults.ts: addedcopilot_clidefault path (~/.copilot/session-state/)canonical.ts/providerMetadata.ts:copilot_cliadded to all provider enumerationssearchMessages.ts:copilot_cliincluded in full-text search scopeDesktop
SettingsView.tsx: Copilot CLI row with>_icon and independent-toggle tooltipSearchView.tsx/HistoryLayout.tsx: Copilot CLI grouped under the Copilot chip (not a separate top-level entry)ProjectPane.tsx: provider tag display handles Copilot CLI groupingstyles.css:copilot_cliaccent color tokensuseLiveWatchController.ts: replaced inlineEMPTY_PROVIDER_COUNTSwith import fromapp/constantsBug Fixes Included
events.jsonlwas being read in full (8.4 MB for active sessions)readFirstJsonlObjectoutputTokensfromassistant.messageevents was discardedtokenOutputdata.resultontool.execution_completeproduced a spurious"{}"DB rowserializeUnknownlastIndexOf("/")instead ofnode:pathAPIsdirname/basenameEMPTY_PROVIDER_COUNTSinuseLiveWatchControllercould diverge from canonical sourceapp/constantsUI
>_terminal icon and a tooltip clarifying it can be toggled independently from VS Code CopilotTesting
copilotCli.test.ts(new)parseWorkspaceYaml— 9 cases: colons in values, CRLF, empty, whitespace, unknown keysproviderParsers.test.tsparseCopilotCliEvent— 12 cases: all event types, fallback IDs, token counts, empty result preventionproviderGroups.test.ts(new)getChipProviders/getProviderWithChildren/toggleGroupProviders— 13 edge-case testsproviderFixtures.integration.test.tscopilot_clidiscoverSessionFiles.pythonFixtures.test.tsnpx biome checkclean on all modified files.Implementation Notes
jsonl_streamadapter — same pattern as other streaming providers; no new adapter introducedworkspace.yamlfallback: if the file is missing, session metadata is extracted from the firstsession.startJSONL eventcopilot_clias a distinct provider value; the UI maps it undercopilotfor chips and search filtersScreenshots