From 88a37e8e9c5eee3deafee42682b1bf63e90cf8b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 23:11:14 +0000 Subject: [PATCH 1/4] Initial plan From 737869041f55029b12291b0da373bee4999a869e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 23:28:52 +0000 Subject: [PATCH 2/4] Port copilotHome, tcpConnectionToken, instructionDirectories, continuePendingWork, and MCP OAuth fields from reference implementation Co-authored-by: edburns <75821+edburns@users.noreply.github.com> --- .../github/copilot/sdk/CliServerManager.java | 13 +++ .../com/github/copilot/sdk/CopilotClient.java | 13 ++- .../copilot/sdk/SessionRequestBuilder.java | 3 + .../sdk/json/CopilotClientOptions.java | 61 ++++++++++++++ .../sdk/json/CreateSessionRequest.java | 15 ++++ .../copilot/sdk/json/McpHttpServerConfig.java | 82 +++++++++++++++++++ .../copilot/sdk/json/ResumeSessionConfig.java | 63 ++++++++++++++ .../sdk/json/ResumeSessionRequest.java | 28 +++++++ .../copilot/sdk/json/SessionConfig.java | 27 ++++++ .../github/copilot/sdk/CopilotClientTest.java | 16 ++++ 10 files changed, 320 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/copilot/sdk/CliServerManager.java b/src/main/java/com/github/copilot/sdk/CliServerManager.java index 07b5eefec..a6e808e1e 100644 --- a/src/main/java/com/github/copilot/sdk/CliServerManager.java +++ b/src/main/java/com/github/copilot/sdk/CliServerManager.java @@ -115,6 +115,19 @@ ProcessInfo startCliServer() throws IOException, InterruptedException { pb.environment().put("COPILOT_SDK_AUTH_TOKEN", options.getGitHubToken()); } + // Set COPILOT_HOME if configured + if (options.getCopilotHome() != null && !options.getCopilotHome().isEmpty()) { + pb.environment().put("COPILOT_HOME", options.getCopilotHome()); + } + + // Set connection token for TCP mode + if (options.getTcpConnectionToken() != null && !options.getTcpConnectionToken().isEmpty()) { + pb.environment().put("COPILOT_CONNECTION_TOKEN", options.getTcpConnectionToken()); + } else if (!options.isUseStdio() && (options.getCliUrl() == null || options.getCliUrl().isEmpty())) { + // Auto-generate connection token for SDK-spawned TCP mode + pb.environment().put("COPILOT_CONNECTION_TOKEN", java.util.UUID.randomUUID().toString()); + } + // Set telemetry environment variables if configured if (options.getTelemetry() != null) { var telemetry = options.getTelemetry(); diff --git a/src/main/java/com/github/copilot/sdk/CopilotClient.java b/src/main/java/com/github/copilot/sdk/CopilotClient.java index ebe995bd7..85e541183 100644 --- a/src/main/java/com/github/copilot/sdk/CopilotClient.java +++ b/src/main/java/com/github/copilot/sdk/CopilotClient.java @@ -104,7 +104,8 @@ public CopilotClient() { public CopilotClient(CopilotClientOptions options) { this.options = options != null ? options : new CopilotClientOptions(); - // When cliUrl is set, auto-correct useStdio since we're connecting via TCP + // When cliUrl is set, force TCP mode (we connect to an external server, not + // spawn one) if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()) { this.options.setUseStdio(false); } @@ -115,6 +116,16 @@ public CopilotClient(CopilotClientOptions options) { throw new IllegalArgumentException("CliUrl is mutually exclusive with CliPath"); } + // Validate TcpConnectionToken + if (this.options.getTcpConnectionToken() != null) { + if (this.options.getTcpConnectionToken().isEmpty()) { + throw new IllegalArgumentException("TcpConnectionToken must be a non-empty string"); + } + if (this.options.isUseStdio()) { + throw new IllegalArgumentException("TcpConnectionToken cannot be used with UseStdio = true"); + } + } + // Validate auth options with external server if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty() && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser() != null)) { diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java index de6977ea8..ffac14312 100644 --- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java +++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java @@ -122,6 +122,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess request.setAgent(config.getAgent()); request.setInfiniteSessions(config.getInfiniteSessions()); request.setSkillDirectories(config.getSkillDirectories()); + request.setInstructionDirectories(config.getInstructionDirectories()); request.setDisabledSkills(config.getDisabledSkills()); request.setConfigDir(config.getConfigDir()); request.setEnableConfigDiscovery(config.getEnableConfigDiscovery()); @@ -192,6 +193,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo request.setConfigDir(config.getConfigDir()); request.setEnableConfigDiscovery(config.getEnableConfigDiscovery()); request.setDisableResume(config.isDisableResume() ? true : null); + request.setContinuePendingWork(config.getContinuePendingWork()); request.setStreaming(config.isStreaming() ? true : null); request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents()); request.setMcpServers(config.getMcpServers()); @@ -199,6 +201,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo request.setDefaultAgent(config.getDefaultAgent()); request.setAgent(config.getAgent()); request.setSkillDirectories(config.getSkillDirectories()); + request.setInstructionDirectories(config.getInstructionDirectories()); request.setDisabledSkills(config.getDisabledSkills()); request.setInfiniteSessions(config.getInfiniteSessions()); request.setModelCapabilities(config.getModelCapabilities()); diff --git a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java index 3a14d1733..6a800a389 100644 --- a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java +++ b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java @@ -44,6 +44,7 @@ public class CopilotClientOptions { private String[] cliArgs; private String cliPath; private String cliUrl; + private String copilotHome; private String cwd; private Map environment; private Executor executor; @@ -51,6 +52,7 @@ public class CopilotClientOptions { private String logLevel = "info"; private Supplier>> onListModels; private int port; + private String tcpConnectionToken; private TelemetryConfig telemetry; private Integer sessionIdleTimeoutSeconds; private Boolean useLoggedInUser; @@ -214,6 +216,36 @@ public CopilotClientOptions setCwd(String cwd) { return this; } + /** + * Gets the base directory for Copilot data (session state, config, etc.). + * + * @return the Copilot home directory path, or {@code null} to use the CLI + * default ({@code ~/.copilot}) + * @since 1.4.0 + */ + public String getCopilotHome() { + return copilotHome; + } + + /** + * Sets the base directory for Copilot data (session state, config, etc.). + *

+ * Sets the {@code COPILOT_HOME} environment variable on the spawned CLI + * process. When {@code null}, the CLI defaults to {@code ~/.copilot}. + *

+ * This option is only used when the SDK spawns the CLI process; it is ignored + * when connecting to an external server via {@link #setCliUrl(String)}. + * + * @param copilotHome + * the Copilot home directory path (must not be {@code null}) + * @return this options instance for method chaining + * @since 1.4.0 + */ + public CopilotClientOptions setCopilotHome(String copilotHome) { + this.copilotHome = Objects.requireNonNull(copilotHome, "copilotHome must not be null"); + return this; + } + /** * Gets the environment variables for the CLI process. *

@@ -405,6 +437,33 @@ public CopilotClientOptions setPort(int port) { return this; } + /** + * Gets the connection token for the headless CLI server (TCP only). + * + * @return the connection token, or {@code null} if not set + * @since 1.4.0 + */ + public String getTcpConnectionToken() { + return tcpConnectionToken; + } + + /** + * Sets the connection token for the headless CLI server (TCP only). + *

+ * When the SDK spawns its own CLI in TCP mode and this is omitted, a UUID is + * generated automatically so the loopback listener is safe by default. Cannot + * be combined with {@link #setUseStdio(boolean)} set to {@code true}. + * + * @param tcpConnectionToken + * the connection token (must not be {@code null} or empty) + * @return this options instance for method chaining + * @since 1.4.0 + */ + public CopilotClientOptions setTcpConnectionToken(String tcpConnectionToken) { + this.tcpConnectionToken = Objects.requireNonNull(tcpConnectionToken, "tcpConnectionToken must not be null"); + return this; + } + /** * Gets the OpenTelemetry configuration for the CLI server. * @@ -533,6 +592,7 @@ public CopilotClientOptions clone() { copy.cliArgs = this.cliArgs != null ? this.cliArgs.clone() : null; copy.cliPath = this.cliPath; copy.cliUrl = this.cliUrl; + copy.copilotHome = this.copilotHome; copy.cwd = this.cwd; copy.environment = this.environment != null ? new java.util.HashMap<>(this.environment) : null; copy.executor = this.executor; @@ -541,6 +601,7 @@ public CopilotClientOptions clone() { copy.onListModels = this.onListModels; copy.port = this.port; copy.sessionIdleTimeoutSeconds = this.sessionIdleTimeoutSeconds; + copy.tcpConnectionToken = this.tcpConnectionToken; copy.telemetry = this.telemetry; copy.useLoggedInUser = this.useLoggedInUser; copy.useStdio = this.useStdio; diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java index ef8d5fda2..b94608caf 100644 --- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java +++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java @@ -91,6 +91,9 @@ public final class CreateSessionRequest { @JsonProperty("skillDirectories") private List skillDirectories; + @JsonProperty("instructionDirectories") + private List instructionDirectories; + @JsonProperty("disabledSkills") private List disabledSkills; @@ -326,6 +329,18 @@ public void setSkillDirectories(List skillDirectories) { this.skillDirectories = skillDirectories; } + /** Gets instruction directories. @return the instruction directory paths */ + public List getInstructionDirectories() { + return instructionDirectories == null ? null : Collections.unmodifiableList(instructionDirectories); + } + + /** + * Sets instruction directories. @param instructionDirectories the directories + */ + public void setInstructionDirectories(List instructionDirectories) { + this.instructionDirectories = instructionDirectories; + } + /** Gets disabled skills. @return the disabled skill names */ public List getDisabledSkills() { return disabledSkills == null ? null : Collections.unmodifiableList(disabledSkills); diff --git a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java index 7017db3d2..904dabf15 100644 --- a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java +++ b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java @@ -41,6 +41,15 @@ public final class McpHttpServerConfig extends McpServerConfig { @JsonProperty("headers") private Map headers; + @JsonProperty("oauthClientId") + private String oauthClientId; + + @JsonProperty("oauthPublicClient") + private Boolean oauthPublicClient; + + @JsonProperty("oauthGrantType") + private String oauthGrantType; + /** * Gets the server type discriminator. * @@ -92,6 +101,79 @@ public McpHttpServerConfig setHeaders(Map headers) { return this; } + /** + * Gets the optional OAuth client ID for the remote server. + * + * @return the OAuth client ID, or {@code null} + * @since 1.4.0 + */ + public String getOauthClientId() { + return oauthClientId; + } + + /** + * Sets the optional OAuth client ID for the remote server. + * + * @param oauthClientId + * the OAuth client ID + * @return this config for method chaining + * @since 1.4.0 + */ + public McpHttpServerConfig setOauthClientId(String oauthClientId) { + this.oauthClientId = oauthClientId; + return this; + } + + /** + * Gets whether this is a public OAuth client. + * + * @return {@code true} if public, {@code null} if not set + * @since 1.4.0 + */ + public Boolean getOauthPublicClient() { + return oauthPublicClient; + } + + /** + * Sets whether this is a public OAuth client. + * + * @param oauthPublicClient + * {@code true} if public + * @return this config for method chaining + * @since 1.4.0 + */ + public McpHttpServerConfig setOauthPublicClient(Boolean oauthPublicClient) { + this.oauthPublicClient = oauthPublicClient; + return this; + } + + /** + * Gets the optional OAuth grant type for the remote server. + *

+ * Valid values: {@code "authorization_code"}, {@code "client_credentials"}. + * + * @return the OAuth grant type, or {@code null} + * @since 1.4.0 + */ + public String getOauthGrantType() { + return oauthGrantType; + } + + /** + * Sets the optional OAuth grant type for the remote server. + *

+ * Valid values: {@code "authorization_code"}, {@code "client_credentials"}. + * + * @param oauthGrantType + * the OAuth grant type + * @return this config for method chaining + * @since 1.4.0 + */ + public McpHttpServerConfig setOauthGrantType(String oauthGrantType) { + this.oauthGrantType = oauthGrantType; + return this; + } + @Override public McpHttpServerConfig setTools(List tools) { super.setTools(tools); diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java index b4dacf370..f0a5f6b49 100644 --- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java +++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java @@ -51,6 +51,7 @@ public class ResumeSessionConfig { private String workingDirectory; private String configDir; private Boolean enableConfigDiscovery; + private Boolean continuePendingWork; private boolean disableResume; private boolean streaming; private Boolean includeSubAgentStreamingEvents; @@ -59,6 +60,7 @@ public class ResumeSessionConfig { private DefaultAgentConfig defaultAgent; private String agent; private List skillDirectories; + private List instructionDirectories; private List disabledSkills; private InfiniteSessionConfig infiniteSessions; private Consumer onEvent; @@ -458,6 +460,40 @@ public ResumeSessionConfig setDisableResume(boolean disableResume) { return this; } + /** + * Returns whether to continue pending work on resume. + *

+ * When {@code true}, instructs the runtime to continue any tool calls or + * permission prompts that were still pending when the session was last + * suspended. When {@code false} (the default), the runtime treats pending work + * as interrupted on resume. + * + * @return {@code true} to continue pending work, {@code false} or {@code null} + * to treat as interrupted + * @since 1.4.0 + */ + public Boolean getContinuePendingWork() { + return continuePendingWork; + } + + /** + * Sets whether to continue pending work on resume. + *

+ * When {@code true}, instructs the runtime to continue any tool calls or + * permission prompts that were still pending when the session was last + * suspended. When {@code false} (the default), the runtime treats pending work + * as interrupted on resume. + * + * @param continuePendingWork + * {@code true} to continue pending work + * @return this config for method chaining + * @since 1.4.0 + */ + public ResumeSessionConfig setContinuePendingWork(Boolean continuePendingWork) { + this.continuePendingWork = continuePendingWork; + return this; + } + /** * Returns whether streaming is enabled. * @@ -591,6 +627,29 @@ public ResumeSessionConfig setSkillDirectories(List skillDirectories) { return this; } + /** + * Gets the additional directories to search for custom instruction files. + * + * @return the list of instruction directory paths + * @since 1.4.0 + */ + public List getInstructionDirectories() { + return instructionDirectories == null ? null : Collections.unmodifiableList(instructionDirectories); + } + + /** + * Sets additional directories to search for custom instruction files. + * + * @param instructionDirectories + * the list of instruction directory paths + * @return this config for method chaining + * @since 1.4.0 + */ + public ResumeSessionConfig setInstructionDirectories(List instructionDirectories) { + this.instructionDirectories = instructionDirectories; + return this; + } + /** * Gets the disabled skills. * @@ -767,6 +826,7 @@ public ResumeSessionConfig clone() { copy.workingDirectory = this.workingDirectory; copy.configDir = this.configDir; copy.enableConfigDiscovery = this.enableConfigDiscovery; + copy.continuePendingWork = this.continuePendingWork; copy.disableResume = this.disableResume; copy.streaming = this.streaming; copy.includeSubAgentStreamingEvents = this.includeSubAgentStreamingEvents; @@ -775,6 +835,9 @@ public ResumeSessionConfig clone() { copy.defaultAgent = this.defaultAgent; copy.agent = this.agent; copy.skillDirectories = this.skillDirectories != null ? new ArrayList<>(this.skillDirectories) : null; + copy.instructionDirectories = this.instructionDirectories != null + ? new ArrayList<>(this.instructionDirectories) + : null; copy.disabledSkills = this.disabledSkills != null ? new ArrayList<>(this.disabledSkills) : null; copy.infiniteSessions = this.infiniteSessions; copy.onEvent = this.onEvent; diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java index e36e90b67..460f4cd90 100644 --- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java +++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java @@ -74,6 +74,9 @@ public final class ResumeSessionRequest { @JsonProperty("disableResume") private Boolean disableResume; + @JsonProperty("continuePendingWork") + private Boolean continuePendingWork; + @JsonProperty("streaming") private Boolean streaming; @@ -98,6 +101,9 @@ public final class ResumeSessionRequest { @JsonProperty("skillDirectories") private List skillDirectories; + @JsonProperty("instructionDirectories") + private List instructionDirectories; + @JsonProperty("disabledSkills") private List disabledSkills; @@ -281,6 +287,16 @@ public void setDisableResume(Boolean disableResume) { this.disableResume = disableResume; } + /** Gets continue pending work flag. @return the flag */ + public Boolean getContinuePendingWork() { + return continuePendingWork; + } + + /** Sets continue pending work flag. @param continuePendingWork the flag */ + public void setContinuePendingWork(Boolean continuePendingWork) { + this.continuePendingWork = continuePendingWork; + } + /** Gets streaming flag. @return the flag */ public Boolean getStreaming() { return streaming; @@ -366,6 +382,18 @@ public void setSkillDirectories(List skillDirectories) { this.skillDirectories = skillDirectories; } + /** Gets instruction directories. @return the instruction directory paths */ + public List getInstructionDirectories() { + return instructionDirectories == null ? null : Collections.unmodifiableList(instructionDirectories); + } + + /** + * Sets instruction directories. @param instructionDirectories the directories + */ + public void setInstructionDirectories(List instructionDirectories) { + this.instructionDirectories = instructionDirectories; + } + /** Gets disabled skills. @return the disabled skill names */ public List getDisabledSkills() { return disabledSkills == null ? null : Collections.unmodifiableList(disabledSkills); diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java index 09661346a..578bb92fd 100644 --- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java +++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java @@ -57,6 +57,7 @@ public class SessionConfig { private String agent; private InfiniteSessionConfig infiniteSessions; private List skillDirectories; + private List instructionDirectories; private List disabledSkills; private String configDir; private Boolean enableConfigDiscovery; @@ -550,6 +551,29 @@ public SessionConfig setSkillDirectories(List skillDirectories) { return this; } + /** + * Gets the additional directories to search for custom instruction files. + * + * @return the list of instruction directory paths + * @since 1.4.0 + */ + public List getInstructionDirectories() { + return instructionDirectories == null ? null : Collections.unmodifiableList(instructionDirectories); + } + + /** + * Sets additional directories to search for custom instruction files. + * + * @param instructionDirectories + * the list of instruction directory paths + * @return this config instance for method chaining + * @since 1.4.0 + */ + public SessionConfig setInstructionDirectories(List instructionDirectories) { + this.instructionDirectories = instructionDirectories; + return this; + } + /** * Gets the disabled skill names. * @@ -825,6 +849,9 @@ public SessionConfig clone() { copy.agent = this.agent; copy.infiniteSessions = this.infiniteSessions; copy.skillDirectories = this.skillDirectories != null ? new ArrayList<>(this.skillDirectories) : null; + copy.instructionDirectories = this.instructionDirectories != null + ? new ArrayList<>(this.instructionDirectories) + : null; copy.disabledSkills = this.disabledSkills != null ? new ArrayList<>(this.disabledSkills) : null; copy.configDir = this.configDir; copy.enableConfigDiscovery = this.enableConfigDiscovery; diff --git a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java index 1cc067587..611799792 100644 --- a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java +++ b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java @@ -81,6 +81,22 @@ void testCliUrlMutualExclusionWithCliPath() { assertThrows(IllegalArgumentException.class, () -> new CopilotClient(options)); } + @Test + void testTcpConnectionTokenWithStdioThrows() { + var options = new CopilotClientOptions().setTcpConnectionToken("my-token").setUseStdio(true); + + assertThrows(IllegalArgumentException.class, () -> new CopilotClient(options)); + } + + @Test + void testTcpConnectionTokenWithTcpMode() { + var options = new CopilotClientOptions().setTcpConnectionToken("my-token").setUseStdio(false); + + // Should NOT throw + var client = new CopilotClient(options); + client.close(); + } + @Test void testStartAndConnectUsingStdio() throws Exception { assertNotNull(cliPath, "Copilot CLI not found in PATH or COPILOT_CLI_PATH"); From aa73ab08a0f03cee1a13da889528907e0d159e33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 23:32:05 +0000 Subject: [PATCH 3/4] Update documentation for new features: copilotHome, tcpConnectionToken, instructionDirectories, continuePendingWork Co-authored-by: edburns <75821+edburns@users.noreply.github.com> --- src/site/markdown/advanced.md | 52 ++++++++++++++++++++++++++++++ src/site/markdown/documentation.md | 2 ++ 2 files changed, 54 insertions(+) diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md index a4c4d830a..bd2b5e9f3 100644 --- a/src/site/markdown/advanced.md +++ b/src/site/markdown/advanced.md @@ -25,6 +25,7 @@ This guide covers advanced scenarios for extending and customizing your Copilot - [Skills Configuration](#Skills_Configuration) - [Loading Skills](#Loading_Skills) - [Disabling Skills](#Disabling_Skills) +- [Instruction Directories](#Instruction_Directories) - [Custom Configuration Directory](#Custom_Configuration_Directory) - [Session Logging](#Session_Logging) - [Early Event Registration](#Early_Event_Registration) @@ -32,6 +33,8 @@ This guide covers advanced scenarios for extending and customizing your Copilot - [Permission Handling](#Permission_Handling) - [Session Hooks](#Session_Hooks) - [Manual Server Control](#Manual_Server_Control) +- [Copilot Home Directory](#Copilot_Home_Directory) +- [TCP Connection Token](#TCP_Connection_Token) - [Session Context and Filtering](#Session_Context_and_Filtering) - [Listing Sessions with Context](#Listing_Sessions_with_Context) - [Filtering Sessions by Context](#Filtering_Sessions_by_Context) @@ -626,6 +629,28 @@ var session = client.createSession( --- +## Instruction Directories + +Specify additional directories to search for custom instruction files. Instruction files (`.instructions.md`) placed in `.github/instructions/` subdirectories of the specified paths will be included in the session's system message: + +```java +var session = client.createSession( + new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL) + .setInstructionDirectories(List.of("/path/to/extra/instructions")) +).get(); +``` + +This works with both `createSession` and `resumeSession`: + +```java +var resumed = client.resumeSession(sessionId, + new ResumeSessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL) + .setInstructionDirectories(List.of("/path/to/instructions")) +).get(); +``` + +--- + ## Custom Configuration Directory Use a custom configuration directory for session settings: @@ -830,6 +855,33 @@ client.forceStop().get(); --- +## Copilot Home Directory + +Configure a custom base directory for Copilot data (session state, config, etc.). This sets the `COPILOT_HOME` environment variable on the spawned CLI process: + +```java +var options = new CopilotClientOptions() + .setCopilotHome("/custom/data/dir"); +``` + +When not set, the CLI defaults to `~/.copilot`. This option is only used when the SDK spawns the CLI process; it is ignored when connecting to an external server via `setCliUrl()`. + +--- + +## TCP Connection Token + +When the SDK spawns the CLI in TCP mode, a connection token is generated automatically to secure the loopback listener. You can provide your own token: + +```java +var options = new CopilotClientOptions() + .setUseStdio(false) + .setTcpConnectionToken("my-secret-token"); +``` + +This cannot be combined with `setUseStdio(true)`. When omitted in TCP mode, the SDK auto-generates a UUID token. + +--- + ## Session Context and Filtering Track and filter sessions by their working directory context including the current directory, git repository, and branch information. diff --git a/src/site/markdown/documentation.md b/src/site/markdown/documentation.md index 7b0c958e3..595d8815e 100644 --- a/src/site/markdown/documentation.md +++ b/src/site/markdown/documentation.md @@ -644,11 +644,13 @@ When resuming a session, you can optionally reconfigure many settings. This is u | `customAgents` | Configure custom agents | | `agent` | Pre-select a custom agent at session start | | `skillDirectories` | Directories to load skills from | +| `instructionDirectories` | Additional directories to search for custom instruction files | | `disabledSkills` | Skills to disable | | `infiniteSessions` | Configure infinite session behavior | | `commands` | Slash command definitions for the resumed session | | `onElicitationRequest` | Handler for incoming elicitation requests | | `disableResume` | When `true`, resumes without emitting a `session.resume` event | +| `continuePendingWork` | When `true`, continues pending tool calls/permissions from prior suspend | | `onEvent` | Event handler registered before session resumption | **Example: Changing Model on Resume** From e66e215ac24cd7544df73b21aaa8652a5539b0cb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 4 May 2026 23:32:55 +0000 Subject: [PATCH 4/4] Update .lastmerge to c063458ecc3d606766f04cf203b11b08de672cc8, sync pom.xml CLI version, and update scripts/codegen @github/copilot version Co-authored-by: edburns <75821+edburns@users.noreply.github.com> --- .lastmerge | 2 +- pom.xml | 2 +- scripts/codegen/package-lock.json | 56 +++++++++++++++---------------- scripts/codegen/package.json | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/.lastmerge b/.lastmerge index d40c7b3af..4a35fe8da 100644 --- a/.lastmerge +++ b/.lastmerge @@ -1 +1 @@ -e42b726ca42bd1b2e099a956c9287ba9435ba3e5 +c063458ecc3d606766f04cf203b11b08de672cc8 diff --git a/pom.xml b/pom.xml index b0b442b61..e25102036 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ reference-impl-sync workflow and deal with the subsequent PR. --> - ^1.0.40-0 + ^1.0.41-0 diff --git a/scripts/codegen/package-lock.json b/scripts/codegen/package-lock.json index 73aa2cdc7..b45b9c668 100644 --- a/scripts/codegen/package-lock.json +++ b/scripts/codegen/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "copilot-sdk-java-codegen", "dependencies": { - "@github/copilot": "^1.0.40-0", + "@github/copilot": "^1.0.41-0", "json-schema": "^0.4.0", "tsx": "^4.20.6" } @@ -428,26 +428,26 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.40-0.tgz", - "integrity": "sha512-KIrRqPOCGPcYUq09wvi66qUi5YMFTH5z9fOEzo1BuyLFVQqUen0TtRk0mpbhG6TxArLPqosBY8nDXOdc+NqKKw==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.41-0.tgz", + "integrity": "sha512-gLyCadBZdJeJtHJI3XdN8wAmLMEUdXfCa3EcVnbdbV1NHZDAJhr7h41l7a49pqRAmJyLUKlk1Lokk7U+OD3tgw==", "license": "SEE LICENSE IN LICENSE.md", "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.40-0", - "@github/copilot-darwin-x64": "1.0.40-0", - "@github/copilot-linux-arm64": "1.0.40-0", - "@github/copilot-linux-x64": "1.0.40-0", - "@github/copilot-win32-arm64": "1.0.40-0", - "@github/copilot-win32-x64": "1.0.40-0" + "@github/copilot-darwin-arm64": "1.0.41-0", + "@github/copilot-darwin-x64": "1.0.41-0", + "@github/copilot-linux-arm64": "1.0.41-0", + "@github/copilot-linux-x64": "1.0.41-0", + "@github/copilot-win32-arm64": "1.0.41-0", + "@github/copilot-win32-x64": "1.0.41-0" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.40-0.tgz", - "integrity": "sha512-l905DiMvOB7Jn5MAkS+iEQcM99hmJHQ5yrKaGJ9OteVWBCcxPEO5ctnRYFdeq4NHL+9OnAzJzNc0kwScOAUCzg==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.41-0.tgz", + "integrity": "sha512-lrrH1oMbTOF1W/YxH6rvoEHOymxmXaMx4aDzm190hU0Yh6Cuu0BJGFvgG8nE9bqcv5O8W7eEBr26jDlGtnZiwg==", "cpu": [ "arm64" ], @@ -461,9 +461,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.40-0.tgz", - "integrity": "sha512-e/Dtc1CjZ5SpNLdtY7vHxzH3hhNKfiMJdyp/2UY/6rzXsSPfbw9xZL01nUBbZt0aYj2FbPBDMTyfqoh5weUSww==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.41-0.tgz", + "integrity": "sha512-4418VtSSkEgn4BcwCFg+0UDhGCfQgGTx16r/PiWbuUOgIBzts3FfVzWMWTuXyxk7kl2Ib8k7KSd/7rNpjcrzBw==", "cpu": [ "x64" ], @@ -477,9 +477,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.40-0.tgz", - "integrity": "sha512-fR/gVUXFpjwojNf3Pg5lH2vrb8q0Gghv6RK6xx1QS6pEBdPTMGeoPxQVqSSB6dZCR/X3dkK1tIZ5IGnuABDHbA==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.41-0.tgz", + "integrity": "sha512-5xjgp3Ak5QJ68byNbsgBpdK1V6T5t8EGu0pUwEJMNMMXxqvL9f7gPcnCGdTtV2DS4Q3adkziV/gpBSSQ5HY8hg==", "cpu": [ "arm64" ], @@ -493,9 +493,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.40-0.tgz", - "integrity": "sha512-vDfE5Cxgg+BealbxBjqa0MUrLGJF+zT+XygMFgWXi/4ESVpRvvAet8rUoLeL+7Lgg6QRlS+UMPWfWL6ZAoSp5w==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.41-0.tgz", + "integrity": "sha512-oWPkj0bSjBjtAqonMEZD7EuSByBNXwtceMw8y7uGOfs6jQXfhDGzCCB6NGb+lcftVNtWDKFCUtx+x8Fbt4O37w==", "cpu": [ "x64" ], @@ -509,9 +509,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.40-0.tgz", - "integrity": "sha512-7aEo1CZ5476lWRtfcym0TX1DhH5l9+PKENHPOr8vfziHKeNlWYkXHVTo7OGIUnCAwIetbCQRyf92nnaFhG/8Jw==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.41-0.tgz", + "integrity": "sha512-MaPg4tFWTiRuyv+j0ymJbZp8UPK+RIXNMpekR7FRf8/Uz+NiJgTTxTDjFi4ytRJU5UNrUezkVAk5Xduq/CaIew==", "cpu": [ "arm64" ], @@ -525,9 +525,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.40-0", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.40-0.tgz", - "integrity": "sha512-egnoilEO6TS0qSexe+A26GUSyfeinaqXJRTYL4Qr6eVgAfFhCEpCJtK/gHIZmlDXnq2ex3jGrVvz9+ZIp+JSoA==", + "version": "1.0.41-0", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.41-0.tgz", + "integrity": "sha512-ykRuDWjJEgSywMFJl1yaefssaklCVSVhprx2NcSVh6tIGupvvzVAM6nL6Mj6nyKpG6FKGHanedBeL6SJc935cw==", "cpu": [ "x64" ], diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json index b2af72d6f..d146fd945 100644 --- a/scripts/codegen/package.json +++ b/scripts/codegen/package.json @@ -7,7 +7,7 @@ "generate:java": "tsx java.ts" }, "dependencies": { - "@github/copilot": "^1.0.40-0", + "@github/copilot": "^1.0.41-0", "json-schema": "^0.4.0", "tsx": "^4.20.6" }