Skip to content

Commit 74cd8e4

Browse files
Copilotbrunoborges
andcommitted
Add tests, documentation, and CHANGELOG for session context feature
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
1 parent 37d7f37 commit 74cd8e4

3 files changed

Lines changed: 162 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,49 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
88
99
## [Unreleased]
1010

11-
> **Upstream sync:** [`github/copilot-sdk@05e3c46`](https://github.com/github/copilot-sdk/commit/05e3c46c8c23130c9c064dc43d00ec78f7a75eab)
11+
> **Upstream sync:** [`github/copilot-sdk@e40d57c`](https://github.com/github/copilot-sdk/commit/e40d57c86e18b495722adbf42045288c03924342)
12+
13+
### Added
14+
15+
#### Session Context and Filtering
16+
17+
Added session context tracking and filtering capabilities to help manage multiple Copilot sessions across different repositories and working directories.
18+
19+
**New Classes:**
20+
- `SessionContext` - Represents working directory context (cwd, gitRoot, repository, branch) with fluent setters
21+
- `SessionListFilter` - Filter sessions by context fields (extends SessionContext)
22+
- `SessionContextChangedEvent` - Event fired when working directory context changes between turns
23+
24+
**Updated APIs:**
25+
- `SessionMetadata.getContext()` - Returns optional context information for persisted sessions
26+
- `CopilotClient.listSessions(SessionListFilter)` - New overload to filter sessions by context criteria
27+
28+
**Example:**
29+
```java
30+
// List sessions for a specific repository
31+
var filter = new SessionListFilter()
32+
.setRepository("owner/repo")
33+
.setBranch("main");
34+
var sessions = client.listSessions(filter).get();
35+
36+
// Access context information
37+
for (var session : sessions) {
38+
var ctx = session.getContext();
39+
if (ctx != null) {
40+
System.out.println("CWD: " + ctx.getCwd());
41+
System.out.println("Repo: " + ctx.getRepository());
42+
}
43+
}
44+
45+
// Listen for context changes
46+
session.on(SessionContextChangedEvent.class, event -> {
47+
SessionContext newContext = event.getData();
48+
System.out.println("Working directory changed to: " + newContext.getCwd());
49+
});
50+
```
51+
52+
**Requirements:**
53+
- GitHub Copilot CLI 0.0.409 or later
1254

1355
## [1.0.8] - 2026-02-08
1456

src/site/markdown/advanced.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ This guide covers advanced scenarios for extending and customizing your Copilot
2424
- [Permission Handling](#Permission_Handling)
2525
- [Session Hooks](#Session_Hooks)
2626
- [Manual Server Control](#Manual_Server_Control)
27+
- [Session Context and Filtering](#Session_Context_and_Filtering)
28+
- [Listing Sessions with Context](#Listing_Sessions_with_Context)
29+
- [Filtering Sessions by Context](#Filtering_Sessions_by_Context)
30+
- [Context Changed Events](#Context_Changed_Events)
2731
- [Session Lifecycle Events](#Session_Lifecycle_Events)
2832
- [Subscribing to All Lifecycle Events](#Subscribing_to_All_Lifecycle_Events)
2933
- [Subscribing to Specific Event Types](#Subscribing_to_Specific_Event_Types)
@@ -500,6 +504,65 @@ client.forceStop().get();
500504
501505
---
502506

507+
## Session Context and Filtering
508+
509+
Track and filter sessions by their working directory context including the current directory, git repository, and branch information.
510+
511+
### Listing Sessions with Context
512+
513+
Session metadata may include context information for persisted sessions:
514+
515+
```java
516+
var sessions = client.listSessions().get();
517+
for (var session : sessions) {
518+
var context = session.getContext();
519+
if (context != null) {
520+
System.out.println("Session: " + session.getSessionId());
521+
System.out.println(" Working dir: " + context.getCwd());
522+
System.out.println(" Repository: " + context.getRepository());
523+
System.out.println(" Branch: " + context.getBranch());
524+
System.out.println(" Git root: " + context.getGitRoot());
525+
}
526+
}
527+
```
528+
529+
### Filtering Sessions by Context
530+
531+
Use `SessionListFilter` to filter sessions by context fields:
532+
533+
```java
534+
// Find sessions for a specific repository
535+
var filter = new SessionListFilter()
536+
.setRepository("owner/myproject")
537+
.setBranch("main");
538+
539+
var sessions = client.listSessions(filter).get();
540+
```
541+
542+
Filter options:
543+
- `setCwd(String)` - Filter by exact working directory match
544+
- `setGitRoot(String)` - Filter by git repository root
545+
- `setRepository(String)` - Filter by repository in "owner/repo" format
546+
- `setBranch(String)` - Filter by git branch name
547+
548+
### Context Changed Events
549+
550+
Listen for changes to the working directory context:
551+
552+
```java
553+
session.on(SessionContextChangedEvent.class, event -> {
554+
var newContext = event.getData();
555+
System.out.println("Context changed:");
556+
System.out.println(" New CWD: " + newContext.getCwd());
557+
System.out.println(" Repository: " + newContext.getRepository());
558+
System.out.println(" Branch: " + newContext.getBranch());
559+
});
560+
```
561+
562+
The `session.context_changed` event fires when the working directory context changes between conversation turns.
563+
564+
---
565+
503566
## Session Lifecycle Events
504567

505568
Subscribe to lifecycle events to be notified when sessions are created, deleted, updated, or change foreground/background state.

src/test/java/com/github/copilot/sdk/CopilotSessionTest.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,4 +762,60 @@ void testShouldPassStreamingOptionToSessionCreation() throws Exception {
762762
session.close();
763763
}
764764
}
765+
766+
/**
767+
* Verifies that listSessions returns metadata with optional context
768+
* information.
769+
*
770+
* @see Snapshot: session/should_list_sessions
771+
*/
772+
@Test
773+
void testListSessionsIncludesContextWhenAvailable() throws Exception {
774+
ctx.configureForTest("session", "should_list_sessions");
775+
776+
try (CopilotClient client = ctx.createClient()) {
777+
var session = client.createSession().get();
778+
779+
var sessions = client.listSessions().get(30, TimeUnit.SECONDS);
780+
assertNotNull(sessions);
781+
782+
// List may be empty or contain sessions depending on test environment
783+
// The main goal is to verify the API works and context field is accessible
784+
for (var s : sessions) {
785+
assertNotNull(s.getSessionId());
786+
// Context field is optional
787+
if (s.getContext() != null) {
788+
// When context is present, cwd should be non-null
789+
assertNotNull(s.getContext().getCwd());
790+
}
791+
}
792+
793+
session.close();
794+
}
795+
}
796+
797+
/**
798+
* Verifies that SessionListFilter works with fluent setters.
799+
*/
800+
@Test
801+
void testSessionListFilterFluentAPI() throws Exception {
802+
ctx.configureForTest("session", "should_list_sessions");
803+
804+
try (CopilotClient client = ctx.createClient()) {
805+
var session = client.createSession().get();
806+
807+
var filter = new com.github.copilot.sdk.json.SessionListFilter().setCwd("/test/path")
808+
.setRepository("owner/repo").setBranch("main").setGitRoot("/test");
809+
810+
assertEquals("/test/path", filter.getCwd());
811+
assertEquals("owner/repo", filter.getRepository());
812+
assertEquals("main", filter.getBranch());
813+
assertEquals("/test", filter.getGitRoot());
814+
815+
var filteredSessions = client.listSessions(filter).get(30, TimeUnit.SECONDS);
816+
assertNotNull(filteredSessions);
817+
818+
session.close();
819+
}
820+
}
765821
}

0 commit comments

Comments
 (0)