@github/copilot-sdk 1.0.29-preview.7 → 1.0.29-preview.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
- import { existsSync } from "node:fs";
3
+ import { accessSync, constants, existsSync, statSync } from "node:fs";
4
4
  import { isIPv6, Socket } from "node:net";
5
- import { dirname, isAbsolute, join, resolve } from "node:path";
5
+ import { dirname, isAbsolute, join, resolve, win32 } from "node:path";
6
6
  import {
7
7
  createMessageConnection as createRpcMessageConnection,
8
8
  ErrorCodes,
@@ -283,6 +283,10 @@ function getNodeExecPath() {
283
283
  function getBundledRuntimePath() {
284
284
  return ensureRuntimeBundle(COPILOT_CLI_VERSION);
285
285
  }
286
+ async function getSpawnableBundledRuntimePath() {
287
+ const runtimePath = await getBundledRuntimePath();
288
+ return process.platform === "win32" ? win32.toNamespacedPath(runtimePath) : runtimePath;
289
+ }
286
290
  class TeardownResilientStreamMessageWriter extends StreamMessageWriter {
287
291
  suppressWriteErrors = false;
288
292
  constructor(writable) {
@@ -448,19 +452,22 @@ class CopilotClient {
448
452
  */
449
453
  constructor(options = {}) {
450
454
  const conn = options._internalConnection ?? options.connection ?? CopilotClient.resolveDefaultConnection();
455
+ if ((conn.kind === "uri" || conn.kind === "parent-process") && options.internalTestOptions !== void 0) {
456
+ throw new Error("internalTestOptions requires a runtime owned by this client");
457
+ }
451
458
  if (conn.kind === "uri" && (options.gitHubToken !== void 0 || options.useLoggedInUser !== void 0)) {
452
459
  throw new Error(
453
460
  "gitHubToken and useLoggedInUser cannot be used with RuntimeConnection.forUri (external server manages its own auth)"
454
461
  );
455
462
  }
456
- if (conn.kind === "inprocess" && options.workingDirectory !== void 0) {
463
+ if (conn.kind === "inprocess" && options.env !== void 0) {
457
464
  throw new Error(
458
- "workingDirectory is not supported with RuntimeConnection.forInProcess(): the in-process transport hosts the runtime in this process, so honoring it would require mutating the shared process-global cwd. Change the host process's working directory before constructing the client instead."
465
+ "env is not supported with RuntimeConnection.forInProcess(): environment variables belong to the shared host process. Use typed client/session options or a child-process transport."
459
466
  );
460
467
  }
461
- if (conn.kind === "inprocess" && options.env !== void 0) {
468
+ if (conn.kind === "inprocess" && options.workingDirectory !== void 0) {
462
469
  throw new Error(
463
- "env is not supported with RuntimeConnection.forInProcess(): the in-process transport loads the native runtime into the shared host process, whose single environment block cannot carry per-client values. Set the variables on the host process environment instead."
470
+ "workingDirectory is not supported with RuntimeConnection.forInProcess(): the in-process transport hosts the runtime in this process, so honoring it would require mutating the shared process-global cwd. Set SessionConfig.workingDirectory instead."
464
471
  );
465
472
  }
466
473
  if (conn.kind === "inprocess" && options.telemetry !== void 0) {
@@ -526,6 +533,7 @@ class CopilotClient {
526
533
  const connArgs = conn.kind === "stdio" || conn.kind === "tcp" ? conn.args ?? [] : [];
527
534
  this.connectionExtraArgs = [...connArgs];
528
535
  this.options = {
536
+ internalTestOptions: options.internalTestOptions,
529
537
  entra: options.entra ? { ...options.entra, tokenProvider: options.entra.tokenProvider } : void 0,
530
538
  workingDirectory: options.workingDirectory ?? process.cwd(),
531
539
  logLevel: options.logLevel,
@@ -797,12 +805,17 @@ class CopilotClient {
797
805
  * Stops the CLI server and closes all active sessions.
798
806
  *
799
807
  * This method performs graceful cleanup:
800
- * 1. Closes all active sessions (releases in-memory resources)
808
+ * 1. Closes all active sessions (releases in-memory resources); detach
809
+ * requests share one shutdown timeout
801
810
  * 2. Requests runtime shutdown for SDK-owned CLI processes
802
811
  * 3. Closes the JSON-RPC connection
803
812
  * 4. Signals EOF to an owned stdio process and waits for host cleanup, then
804
813
  * terminates the process if it does not exit within the shutdown timeout
805
814
  *
815
+ * In-process connections first abort active turns without a timeout. That
816
+ * step is outside the detach deadline, so in-process stop() can still wait
817
+ * indefinitely if the runtime stops answering abort requests.
818
+ *
806
819
  * Note: session data on disk is preserved, so sessions can be resumed later.
807
820
  * To permanently remove session data before stopping, call
808
821
  * {@link deleteSession} for each session first.
@@ -824,16 +837,31 @@ class CopilotClient {
824
837
  if (this.connectionConfig.kind === "inprocess") {
825
838
  await Promise.allSettled(activeSessions.map((session) => session.abort()));
826
839
  }
840
+ let detachDeadlineTimer;
841
+ const detachDeadline = new Promise((resolve2) => {
842
+ detachDeadlineTimer = setTimeout(() => resolve2("timeout"), RUNTIME_SHUTDOWN_TIMEOUT_MS);
843
+ });
827
844
  for (const session of activeSessions) {
828
845
  const sessionId = session.sessionId;
829
846
  let lastError = null;
847
+ let attempts = 0;
830
848
  for (let attempt = 1; attempt <= 3; attempt++) {
831
849
  if (this.connectionClosed) {
832
850
  lastError = null;
833
851
  break;
834
852
  }
853
+ attempts = attempt;
835
854
  try {
836
- await session.disconnect();
855
+ const outcome = await Promise.race([
856
+ session.disconnect().then(() => "disconnected"),
857
+ detachDeadline
858
+ ]);
859
+ if (outcome === "timeout") {
860
+ lastError = new Error(
861
+ `session.detach did not complete within the ${RUNTIME_SHUTDOWN_TIMEOUT_MS}ms shutdown timeout`
862
+ );
863
+ break;
864
+ }
837
865
  lastError = null;
838
866
  break;
839
867
  } catch (error) {
@@ -851,11 +879,12 @@ class CopilotClient {
851
879
  if (lastError) {
852
880
  errors.push(
853
881
  new Error(
854
- `Failed to disconnect session ${sessionId} after 3 attempts: ${lastError.message}`
882
+ `Failed to disconnect session ${sessionId} after ${attempts} ${attempts === 1 ? "attempt" : "attempts"}: ${lastError.message}`
855
883
  )
856
884
  );
857
885
  }
858
886
  }
887
+ clearTimeout(detachDeadlineTimer);
859
888
  for (const session of activeSessions) {
860
889
  session._markDisconnected();
861
890
  }
@@ -1125,7 +1154,7 @@ class CopilotClient {
1125
1154
  * // Session with model and tools
1126
1155
  * const session = await client.createSession({
1127
1156
  * onPermissionRequest: approveAll,
1128
- * model: "gpt-4",
1157
+ * model: "gpt-5.4",
1129
1158
  * tools: [{
1130
1159
  * name: "get_weather",
1131
1160
  * description: "Get weather for a location",
@@ -2390,15 +2419,40 @@ class CopilotClient {
2390
2419
  };
2391
2420
  }
2392
2421
  /**
2393
- * Builds the environment for the spawned runtime child process (stdio/TCP): applies
2394
- * the auth token, connection token, `COPILOT_HOME`, keychain setting, and telemetry
2395
- * variables on top of the effective env. Not used by the in-process (FFI) transport,
2396
- * whose worker inherits the host process's ambient environment
2397
- * (see {@link CopilotClient.startInProcessFfi}).
2422
+ * Builds runtime configuration for child processes and the per-host FFI snapshot.
2423
+ * Typed auth, home, keychain, and telemetry options override the effective env.
2398
2424
  */
2399
2425
  buildRuntimeEnv() {
2400
- const env = { ...this.resolvedEnv };
2426
+ const env = process.platform === "win32" ? Object.fromEntries(
2427
+ Object.entries(this.resolvedEnv).map(([key, value]) => [
2428
+ key.toUpperCase(),
2429
+ value
2430
+ ])
2431
+ ) : { ...this.resolvedEnv };
2401
2432
  delete env.NODE_DEBUG;
2433
+ const test = this.options.internalTestOptions;
2434
+ if (test) {
2435
+ const overrides = {
2436
+ COPILOT_API_URL: test.copilotApiUrl,
2437
+ COPILOT_DEBUG_GITHUB_API_URL: test.githubApiUrl,
2438
+ HTTP_PROXY: test.proxyUrl,
2439
+ HTTPS_PROXY: test.proxyUrl,
2440
+ http_proxy: test.proxyUrl,
2441
+ https_proxy: test.proxyUrl,
2442
+ NO_PROXY: test.noProxy,
2443
+ no_proxy: test.noProxy,
2444
+ NODE_EXTRA_CA_CERTS: test.caCertificatePath,
2445
+ SSL_CERT_FILE: test.caCertificatePath,
2446
+ REQUESTS_CA_BUNDLE: test.caCertificatePath,
2447
+ CURL_CA_BUNDLE: test.caCertificatePath,
2448
+ GIT_SSL_CAINFO: test.caCertificatePath
2449
+ };
2450
+ for (const [key, value] of Object.entries(overrides)) {
2451
+ if (value !== void 0) {
2452
+ env[process.platform === "win32" ? key.toUpperCase() : key] = value;
2453
+ }
2454
+ }
2455
+ }
2402
2456
  if (this.options.gitHubToken) {
2403
2457
  env.COPILOT_SDK_AUTH_TOKEN = this.options.gitHubToken;
2404
2458
  }
@@ -2407,6 +2461,9 @@ class CopilotClient {
2407
2461
  }
2408
2462
  if (this.options.baseDirectory) {
2409
2463
  env.COPILOT_HOME = this.options.baseDirectory;
2464
+ if (this.connectionConfig.kind === "inprocess") {
2465
+ env.COPILOT_CACHE_HOME = join(this.options.baseDirectory, "cache");
2466
+ }
2410
2467
  }
2411
2468
  if (this.options.mode === "empty") {
2412
2469
  env.COPILOT_DISABLE_KEYTAR = "1";
@@ -2433,7 +2490,7 @@ class CopilotClient {
2433
2490
  * Start the CLI server process
2434
2491
  */
2435
2492
  async startCLIServer() {
2436
- this.resolvedCliPath ??= await getBundledRuntimePath();
2493
+ this.resolvedCliPath ??= await getSpawnableBundledRuntimePath();
2437
2494
  return new Promise((resolve2, reject) => {
2438
2495
  this.stderrBuffer = "";
2439
2496
  const args = [...this.connectionExtraArgs, "--headless", "--no-auto-update"];
@@ -2471,6 +2528,22 @@ class CopilotClient {
2471
2528
  `Copilot CLI not found at ${this.resolvedCliPath}. Set COPILOT_CLI_PATH to use a custom installation.`
2472
2529
  );
2473
2530
  }
2531
+ const workingDirectory = this.options.workingDirectory;
2532
+ let workingDirectoryProblem;
2533
+ try {
2534
+ workingDirectoryProblem = statSync(workingDirectory).isDirectory() ? void 0 : "does not exist or is not a directory";
2535
+ if (!workingDirectoryProblem) {
2536
+ accessSync(workingDirectory, constants.X_OK);
2537
+ }
2538
+ } catch (error) {
2539
+ const code = error.code;
2540
+ workingDirectoryProblem = code === "ENOENT" || code === "ENOTDIR" ? "does not exist or is not a directory" : `cannot be entered: ${error instanceof Error ? error.message : String(error)}`;
2541
+ }
2542
+ if (workingDirectoryProblem) {
2543
+ throw new Error(
2544
+ `Working directory ${workingDirectory} ${workingDirectoryProblem}.`
2545
+ );
2546
+ }
2474
2547
  const stdioConfig = this.connectionConfig.kind === "stdio" ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
2475
2548
  const isJsFile = this.resolvedCliPath.endsWith(".js");
2476
2549
  if (isJsFile) {
@@ -2622,16 +2695,7 @@ stderr: ${this.stderrBuffer.trim().slice(-8192) || "(empty)"}`
2622
2695
  runtimeLibrary = join(dirname(bundledRuntimePath), "runtime.node");
2623
2696
  }
2624
2697
  const { FfiRuntimeHost } = await import("./ffiRuntimeHost.js");
2625
- const environment = {};
2626
- if (this.options.gitHubToken) {
2627
- environment.COPILOT_SDK_AUTH_TOKEN = this.options.gitHubToken;
2628
- }
2629
- if (this.options.baseDirectory) {
2630
- environment.COPILOT_HOME = this.options.baseDirectory;
2631
- }
2632
- if (this.options.mode === "empty") {
2633
- environment.COPILOT_DISABLE_KEYTAR = "1";
2634
- }
2698
+ const environment = this.buildRuntimeEnv();
2635
2699
  const args = [];
2636
2700
  if (this.options.logLevel) {
2637
2701
  args.push("--log-level", this.options.logLevel);
@@ -116,6 +116,10 @@ export interface RuntimeLifecycleProgressStateDiagnosticEvent {
116
116
  * Experimental, observational-only state of runtime progress and the lifecycle operations that block it. Observation and delivery never control runtime or model behavior. Process death, diagnostic projection loss, transport loss, or serialization failure can prevent external delivery.
117
117
  */
118
118
  export interface RuntimeLifecycleProgressStateData {
119
+ /**
120
+ * Agent that owns this progress. Absent for the primary agent and progress without an agent owner.
121
+ */
122
+ agentId?: string;
119
123
  /**
120
124
  * Complete dependency blocker set after this progress change.
121
125
  */
@@ -130,7 +130,7 @@ export type AuthEnumerateQuery = {
130
130
  */
131
131
  /** @experimental */
132
132
  export type LoginProviderKind =
133
- /** OAuth github.com sign-in via the browser (web loopback + PKCE). */
133
+ /** OAuth github.com sign-in, in the browser (web loopback + PKCE) or by device code — see the login method. */
134
134
  "githubDotCom"
135
135
  /** A GitHub Enterprise Cloud account — a GitHub account on a non-github.com host, e.g. *.ghe.com; the host is supplied interactively through the neutral input-required step. */
136
136
  | "proxima"
@@ -438,6 +438,18 @@ export type AuthEnumerateValue = {
438
438
  */
439
439
  kind: "loginAccounts";
440
440
  };
441
+ /**
442
+ * How an interactive GitHub login is authorized.
443
+ *
444
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
445
+ * via the `definition` "AuthLoginMethod".
446
+ */
447
+ /** @experimental */
448
+ export type AuthLoginMethod =
449
+ /** Browser authorization with a loopback callback; the flow surfaces an `open-url` step. */
450
+ "web"
451
+ /** OAuth device authorization; the flow surfaces a `device-code` step with a one-time code, for terminals whose browser cannot reach a loopback callback. */
452
+ | "device-code";
441
453
  /**
442
454
  * How an interactive provider login should choose its base identity.
443
455
  *
@@ -451,7 +463,7 @@ export type AuthLoginMode =
451
463
  /** Explicitly ask the provider to present its account-selection UI instead of serving from a retained identity. */
452
464
  | "selectAccount";
453
465
  /**
454
- * One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra).
466
+ * One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra). A device-code flow surfaces its one-time code as `device-code`; the consumer shows the code, may open the verification URI, and calls advance, which resolves once the user has authorized the device.
455
467
  *
456
468
  * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
457
469
  * via the `definition` "AuthLoginStep".
@@ -503,6 +515,27 @@ export type AuthLoginStep = {
503
515
  * Login flow step variant discriminator.
504
516
  */
505
517
  kind: "error";
518
+ } | {
519
+ /**
520
+ * One-time code the user enters at the verification URI.
521
+ */
522
+ userCode: string;
523
+ /**
524
+ * Page where the user enters the one-time code (consumer-driven browser-open).
525
+ */
526
+ verificationUri: string;
527
+ /**
528
+ * Seconds until the one-time code expires, measured from when this step was produced. Consumers can show a countdown or pick their own timeout instead of blocking until the provider rejects the code.
529
+ */
530
+ expiresIn: number;
531
+ /**
532
+ * Minimum seconds between authorization polls required by the provider. The runtime performs the polling itself for the duration of the single `advance` call, so this is informational (for example to drive a progress indicator); repeating `advance` is rejected as already advancing.
533
+ */
534
+ interval: number;
535
+ /**
536
+ * Login flow step variant discriminator.
537
+ */
538
+ kind: "device-code";
506
539
  };
507
540
  /**
508
541
  * Disposition of a login attempt, including pending user decisions.
@@ -8248,6 +8281,10 @@ export interface AgentGetCurrentResult {
8248
8281
  */
8249
8282
  /** @experimental */
8250
8283
  export interface AgentInfo {
8284
+ /**
8285
+ * Opaque identity of the plugin owning this agent. Matches plugins.list().plugins[].id on the same runtime host. Compare the complete value without parsing it. Omitted for non-plugin agents.
8286
+ */
8287
+ pluginId?: string;
8251
8288
  /**
8252
8289
  * Name of the agent. Use `id` as the stable selection identifier.
8253
8290
  */
@@ -8971,6 +9008,10 @@ export interface AuthLoginBeginRequest {
8971
9008
  * The provider kind to sign in with.
8972
9009
  */
8973
9010
  kind: LoginProviderKind;
9011
+ /**
9012
+ * How to authorize: `web` (default) or `device-code`. Device code is offered for `githubDotCom` and `proxima`; `proxima` still asks for its host through `input-required` first.
9013
+ */
9014
+ method?: AuthLoginMethod;
8974
9015
  /**
8975
9016
  * Neutral identity-selection intent. Omitted is equivalent to default.
8976
9017
  */
@@ -10293,6 +10334,23 @@ export interface CanvasProviderUnregisterRequest {
10293
10334
  */
10294
10335
  connectionId: string;
10295
10336
  }
10337
+ /**
10338
+ * Closes a canvas through its original owned or attached session namespace.
10339
+ *
10340
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
10341
+ * via the `definition` "CanvasSourceCloseRequest".
10342
+ */
10343
+ /** @experimental */
10344
+ export interface CanvasSourceCloseRequest {
10345
+ /**
10346
+ * Open canvas instance identifier
10347
+ */
10348
+ instanceId: string;
10349
+ /**
10350
+ * Exact authenticated local attachment identifier. Omit for the SDK connection's owned session.
10351
+ */
10352
+ attachId?: number | null;
10353
+ }
10296
10354
  /**
10297
10355
  * Options scoped to the built-in CAPI (Copilot API) provider.
10298
10356
  *
@@ -13810,6 +13868,10 @@ export interface DiscoveredExtension {
13810
13868
  */
13811
13869
  /** @experimental */
13812
13870
  export interface DiscoveredExtensionPlugin {
13871
+ /**
13872
+ * Opaque identity of the owning plugin. Matches plugins.list().plugins[].id on the same runtime host. Compare the complete value without parsing it. May be absent on older runtimes.
13873
+ */
13874
+ id?: string;
13813
13875
  /**
13814
13876
  * Installed plugin name
13815
13877
  */
@@ -13894,6 +13956,14 @@ export interface DiscoveredHook {
13894
13956
  * Durable content hash used by hook enablement. Identical actions may intentionally share this key. Omitted when changing the user's disabled-hooks setting cannot change the action's current server-discovered state, including managed-policy hooks, session-start prompt actions, actions suppressed by disable-all settings, and projectless plugin actions that require project-directory expansion.
13895
13957
  */
13896
13958
  disableKey?: string;
13959
+ /**
13960
+ * File URI of the document defining this action on the selected runtime host, not the command or script it executes. Inline hooks point to their containing settings document or plugin manifest. Omitted for sources without a backing file, such as registry policy.
13961
+ */
13962
+ definitionFileUri?: string;
13963
+ /**
13964
+ * Opaque identity of the plugin owning this action. Matches plugins.list().plugins[].id and MCP effectiveSource.plugin.id on the same runtime host. Compare the complete value without parsing it. Omitted for non-plugin hooks.
13965
+ */
13966
+ pluginId?: string;
13897
13967
  }
13898
13968
  /**
13899
13969
  * MCP server discovered by `mcp.discover`, with config source, optional plugin source, transport type, and enabled state.
@@ -15796,6 +15866,39 @@ export interface HistorySkippedFileRestore {
15796
15866
  */
15797
15867
  reason: HistoryFileRestoreSkipReason;
15798
15868
  }
15869
+ /**
15870
+ * Compaction settings for this session. Each call replaces the previous settings: an omitted field returns to its default. Settings live in memory until the session ends; re-apply them after resuming a session in a new process.
15871
+ *
15872
+ * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema
15873
+ * via the `definition` "HistorySetCompactionConfigRequest".
15874
+ */
15875
+ /** @experimental */
15876
+ export interface HistorySetCompactionConfigRequest {
15877
+ /**
15878
+ * Model that summarizes this session's conversation when it compacts,
15879
+ * instead of the session's own model. Applies only when both are Copilot
15880
+ * models the session may use; for a BYOK or provider session, or a model
15881
+ * the session's catalog or allowed-model policy rejects, compaction
15882
+ * summarizes on the session's model. Takes precedence over any runtime
15883
+ * experiment that picks a compaction model. Blank values are ignored.
15884
+ */
15885
+ model?: string;
15886
+ /**
15887
+ * Summarization instruction sent as the final user message of a
15888
+ * compaction request, replacing the built-in prompt entirely; the caller
15889
+ * owns the summary's format. `/compact` focus instructions and a note that
15890
+ * tools are unavailable are appended to it. Blank values are ignored.
15891
+ */
15892
+ prompt?: string;
15893
+ /**
15894
+ * Reasoning effort for compaction requests: one of `none`, `minimal`,
15895
+ * `low`, `medium`, `high`, `xhigh` or `max`. Applies when the model that
15896
+ * summarizes supports it; otherwise the request keeps its usual effort.
15897
+ * Takes precedence over any runtime experiment that adjusts compaction
15898
+ * reasoning effort. Any other value is rejected.
15899
+ */
15900
+ reasoningEffort?: string;
15901
+ }
15799
15902
  /**
15800
15903
  * Markdown summary of the conversation context (empty when not available).
15801
15904
  *
@@ -17048,6 +17151,10 @@ export interface InstalledPluginInfo {
17048
17151
  * Whether the plugin is currently enabled for new sessions
17049
17152
  */
17050
17153
  enabled: boolean;
17154
+ /**
17155
+ * Absolute local directory containing this plugin's installed content, including disabled installations. Absent when the runtime has no resolved content directory. This is the plugin root, not its marketplace directory; clients must not forward it back as an additional plugin.
17156
+ */
17157
+ rootPath?: string;
17051
17158
  /**
17052
17159
  * Absolute path of the marketplace directory a live plugin was resolved from. Present only on live, never-persisted records — a plugin belonging to a directory/local marketplace, which is loaded from its real directory on every pass instead of a copy under the installed-plugins cache. Its presence is what marks a listed plugin as live: such a plugin is always present on disk, so `enabled` is its only meaningful state and it is never "not installed".
17053
17160
  */
@@ -17080,6 +17187,10 @@ export interface InstalledPluginInfo {
17080
17187
  * HTTPS URL of the plugin's icon on raw.githubusercontent.com, retained from the catalogue entry it was installed from. Untrusted external content: load it without credentials. Present only for a direct install pinned to one GitHub commit whose catalogue entry had an icon.
17081
17188
  */
17082
17189
  iconUrl?: string;
17190
+ /**
17191
+ * Opaque plugin identity in this runtime's inventory. Matches MCP effectiveSource.plugin.id for the same plugin. Stable across enablement changes, updates and restarts while the installation source is unchanged; not a cross-host identifier or a mutation argument. Compare the complete value without parsing it. May be absent on older runtimes.
17192
+ */
17193
+ id?: string;
17083
17194
  }
17084
17195
  /**
17085
17196
  * The GitHub repository and commit an installed plugin is pinned to.
@@ -17203,6 +17314,10 @@ export interface InstructionsGetSourcesResult {
17203
17314
  */
17204
17315
  /** @experimental */
17205
17316
  export interface InstructionSource {
17317
+ /**
17318
+ * Opaque identity of the plugin owning this instruction source. Matches plugins.list().plugins[].id on the same runtime host. Compare the complete value without parsing it. Omitted for non-plugin sources.
17319
+ */
17320
+ pluginId?: string;
17206
17321
  /**
17207
17322
  * Unique identifier for this source (used for toggling)
17208
17323
  */
@@ -24205,7 +24320,7 @@ export interface PermissionsConfigureParams {
24205
24320
  */
24206
24321
  authenticatedAuthority?: AuthenticatedAuthorityUpdate;
24207
24322
  /**
24208
- * Declares whether this connection's registered permission handler applies non-human host policy to the tools this connection registered. When true, unattended Assisted Autopilot sends permission requests for those tools to the handler before runtime Assisted Approval or unattended fallback can settle them. All other requests, including shell commands, file access, URLs, and tools registered by other connections or extensions, keep runtime settlement. Managed policy and other runtime enforcement still take precedence. Only the session's owning non-extension connection may set this field. The declaration ends when that connection detaches or the session is resumed, so hosts must reapply it after resume. Omit to leave unchanged; false clears it. Without a declaration, registered handlers are not consulted during unattended Assisted Autopilot. Remote sessions are not supported.
24323
+ * Declares whether this connection's registered permission handler applies non-human host policy to the tools and canvases this connection registered. When true, unattended Assisted Autopilot sends permission requests for those tools, and `open_canvas` and `invoke_canvas_action` requests whose target canvas this connection registered, to the handler before runtime Assisted Approval or unattended fallback can settle them. All other requests, including shell commands, file access, URLs, and tools or canvases registered by other connections or extensions, keep runtime settlement. Managed policy and other runtime enforcement still take precedence. Only the session's owning non-extension connection may set this field. The declaration ends when that connection detaches or the session is resumed, so hosts must reapply it after resume. Omit to leave unchanged; false clears it. Without a declaration, registered handlers are not consulted during unattended Assisted Autopilot. Remote sessions are not supported.
24209
24324
  */
24210
24325
  hostPolicyPermissionHandler?: boolean;
24211
24326
  }
@@ -24759,6 +24874,10 @@ export interface Plugin {
24759
24874
  * Opaque stable identity for a direct plugin source.
24760
24875
  */
24761
24876
  directSourceId?: string;
24877
+ /**
24878
+ * Absolute local directory containing this plugin's resolved content, including disabled installations. Absent when no content directory is resolved. This is the plugin root, not its marketplace directory; clients must not forward it back as an additional plugin.
24879
+ */
24880
+ rootPath?: string;
24762
24881
  /**
24763
24882
  * Absolute marketplace directory for a live plugin.
24764
24883
  */
@@ -24779,6 +24898,10 @@ export interface Plugin {
24779
24898
  * Whether this managed desired plugin has an installed or live record.
24780
24899
  */
24781
24900
  installed?: boolean;
24901
+ /**
24902
+ * Opaque plugin identity in this runtime's inventory. Matches global inventory id and MCP effectiveSource.plugin.id for the same plugin. Stable across enablement changes, updates and restarts while the source is unchanged. Session-only plugin identities are scoped to their session; not a cross-host identifier or a mutation argument. Compare the complete value without parsing it. May be absent on older runtimes.
24903
+ */
24904
+ id?: string;
24782
24905
  }
24783
24906
  /**
24784
24907
  * Applies exactly one retained verified Agent Plugin installation plan.
@@ -24942,7 +25065,7 @@ export interface PluginsBuiltinSetRequest {
24942
25065
  /** @experimental */
24943
25066
  export interface PluginsDisableRequest {
24944
25067
  /**
24945
- * Plugin names or "plugin@marketplace" specs to disable. Unknown names are ignored. Non-marketplace direct installs cannot be disabled via this API; uninstall them instead. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins.
25068
+ * Plugin names, "plugin@marketplace" specs, or opaque directSourceId values from inventory to disable. Use directSourceId to distinguish same-named direct installations. Unknown targets and session-only plugin-directory mounts are ignored. Direct-install decisions persist on the installation record. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins.
24946
25069
  */
24947
25070
  names: string[];
24948
25071
  /**
@@ -24959,7 +25082,7 @@ export interface PluginsDisableRequest {
24959
25082
  /** @experimental */
24960
25083
  export interface PluginsEnableRequest {
24961
25084
  /**
24962
- * Plugin names or "plugin@marketplace" specs to enable. Unknown names are ignored. Non-marketplace direct installs are always enabled and cannot be toggled via this API.
25085
+ * Plugin names, "plugin@marketplace" specs, or opaque directSourceId values from inventory to enable. Use directSourceId to distinguish same-named direct installations. Unknown targets and session-only plugin-directory mounts are ignored. Direct-install decisions persist on the installation record; active sessions must reload plugins to load newly enabled contributions.
24963
25086
  */
24964
25087
  names: string[];
24965
25088
  /**
@@ -28079,6 +28202,10 @@ export interface ServerInstructionSourceList {
28079
28202
  */
28080
28203
  /** @experimental */
28081
28204
  export interface ServerSkill {
28205
+ /**
28206
+ * Opaque identity of the plugin owning this skill. Matches plugins.list().plugins[].id on the same runtime host. Compare the complete value without parsing it. Omitted for non-plugin skills.
28207
+ */
28208
+ pluginId?: string;
28082
28209
  /**
28083
28210
  * Unique identifier for the skill
28084
28211
  */
@@ -30388,7 +30515,7 @@ export interface SessionsOpenProgress {
30388
30515
  /** @experimental */
30389
30516
  export interface SessionPluginsDisableRequest {
30390
30517
  /**
30391
- * Plugin names or "plugin@marketplace" specs to disable. Unknown names are ignored. Non-marketplace direct installs cannot be disabled via this API; uninstall them instead. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins.
30518
+ * Plugin names, "plugin@marketplace" specs, or opaque directSourceId values from inventory to disable. Use directSourceId to distinguish same-named direct installations. This persists user-level enablement, not a session-only override. Unknown targets and session-only plugin-directory mounts are ignored. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins.
30392
30519
  */
30393
30520
  names: string[];
30394
30521
  }
@@ -30401,7 +30528,7 @@ export interface SessionPluginsDisableRequest {
30401
30528
  /** @experimental */
30402
30529
  export interface SessionPluginsEnableRequest {
30403
30530
  /**
30404
- * Plugin names or "plugin@marketplace" specs to enable. Unknown names are ignored. Non-marketplace direct installs are always enabled and cannot be toggled via this API.
30531
+ * Plugin names, "plugin@marketplace" specs, or opaque directSourceId values from inventory to enable. Use directSourceId to distinguish same-named direct installations. This persists user-level enablement, not a session-only override. Unknown targets and session-only plugin-directory mounts are ignored; active sessions must reload plugins to load newly enabled contributions.
30405
30532
  */
30406
30533
  names: string[];
30407
30534
  }
@@ -32109,6 +32236,10 @@ export interface ShutdownRequest {
32109
32236
  */
32110
32237
  /** @experimental */
32111
32238
  export interface Skill {
32239
+ /**
32240
+ * Opaque identity of the plugin owning this skill. Matches plugins.list().plugins[].id on the same runtime host. Compare the complete value without parsing it. Omitted for non-plugin skills.
32241
+ */
32242
+ pluginId?: string;
32112
32243
  /**
32113
32244
  * Unique identifier for the skill
32114
32245
  */
@@ -39489,7 +39620,7 @@ export declare function createSessionRpc(connection: MessageConnection, sessionI
39489
39620
  /** @experimental */
39490
39621
  login: {
39491
39622
  /**
39492
- * Begin an interactive login flow for a provider kind (dispatch is kind-only) and return its opaque flow id and first step.
39623
+ * Begin an interactive login flow for a provider kind, optionally selecting how to authorize (`method`: `web` by default, or `device-code`), and return its opaque flow id and first step.
39493
39624
  *
39494
39625
  * @param params Begin an interactive login flow for a provider kind, optionally reusing a cached base identity or explicitly requesting provider account selection.
39495
39626
  *
@@ -39501,7 +39632,7 @@ export declare function createSessionRpc(connection: MessageConnection, sessionI
39501
39632
  *
39502
39633
  * @param params Advance an in-flight login flow, optionally fulfilling an input-required step.
39503
39634
  *
39504
- * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra).
39635
+ * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra). A device-code flow surfaces its one-time code as `device-code`; the consumer shows the code, may open the verification URI, and calls advance, which resolves once the user has authorized the device.
39505
39636
  */
39506
39637
  advance: (params: AuthLoginAdvanceRequest) => Promise<AuthLoginStep>;
39507
39638
  /**
@@ -41361,6 +41492,12 @@ export declare function createSessionRpc(connection: MessageConnection, sessionI
41361
41492
  * @returns Indicates whether an in-progress background compaction was cancelled.
41362
41493
  */
41363
41494
  cancelBackgroundCompaction: () => Promise<HistoryCancelBackgroundCompactionResult>;
41495
+ /**
41496
+ * Replaces this local session's compaction settings: the model, prompt and reasoning effort its automatic and manual compactions use. Each call replaces all three: an omitted field returns to its default. Settings are held in memory only, so re-apply them after resuming the session in a new process. A change applies to compactions that start afterwards, except that automatic compactions keep the model the running turn already chose for them until that turn ends; a compaction already in progress may still pick up a new reasoning effort. Rejects on a remote session.
41497
+ *
41498
+ * @param params Compaction settings for this session. Each call replaces the previous settings: an omitted field returns to its default. Settings live in memory until the session ends; re-apply them after resuming a session in a new process.
41499
+ */
41500
+ setCompactionConfig: (params: HistorySetCompactionConfigRequest) => Promise<void>;
41364
41501
  /**
41365
41502
  * Aborts any in-progress manual compaction on a local session.
41366
41503
  *
@@ -2600,7 +2600,7 @@ function createSessionRpc(connection, sessionId) {
2600
2600
  /** @experimental */
2601
2601
  login: {
2602
2602
  /**
2603
- * Begin an interactive login flow for a provider kind (dispatch is kind-only) and return its opaque flow id and first step.
2603
+ * Begin an interactive login flow for a provider kind, optionally selecting how to authorize (`method`: `web` by default, or `device-code`), and return its opaque flow id and first step.
2604
2604
  *
2605
2605
  * @param params Begin an interactive login flow for a provider kind, optionally reusing a cached base identity or explicitly requesting provider account selection.
2606
2606
  *
@@ -2612,7 +2612,7 @@ function createSessionRpc(connection, sessionId) {
2612
2612
  *
2613
2613
  * @param params Advance an in-flight login flow, optionally fulfilling an input-required step.
2614
2614
  *
2615
- * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra).
2615
+ * @returns One step in an interactive login flow. The consumer acts on the step and calls advance to proceed. Browser-open is encoded as two distinct steps by design: `open-url` is CONSUMER-driven (the provider surfaces the authorize URL and the consumer opens it — github.com/GHEC web), while `needs-interaction` is PROVIDER-driven (the provider opens the browser or broker UI itself and does not surface a URL — Entra). A device-code flow surfaces its one-time code as `device-code`; the consumer shows the code, may open the verification URI, and calls advance, which resolves once the user has authorized the device.
2616
2616
  */
2617
2617
  advance: async (params) => connection.sendRequest("session.accounts.login.advance", { ...params, sessionId }),
2618
2618
  /**
@@ -4472,6 +4472,12 @@ function createSessionRpc(connection, sessionId) {
4472
4472
  * @returns Indicates whether an in-progress background compaction was cancelled.
4473
4473
  */
4474
4474
  cancelBackgroundCompaction: async () => connection.sendRequest("session.history.cancelBackgroundCompaction", { sessionId }),
4475
+ /**
4476
+ * Replaces this local session's compaction settings: the model, prompt and reasoning effort its automatic and manual compactions use. Each call replaces all three: an omitted field returns to its default. Settings are held in memory only, so re-apply them after resuming the session in a new process. A change applies to compactions that start afterwards, except that automatic compactions keep the model the running turn already chose for them until that turn ends; a compaction already in progress may still pick up a new reasoning effort. Rejects on a remote session.
4477
+ *
4478
+ * @param params Compaction settings for this session. Each call replaces the previous settings: an omitted field returns to its default. Settings live in memory until the session ends; re-apply them after resuming a session in a new process.
4479
+ */
4480
+ setCompactionConfig: async (params) => connection.sendRequest("session.history.setCompactionConfig", { ...params, sessionId }),
4475
4481
  /**
4476
4482
  * Aborts any in-progress manual compaction on a local session.
4477
4483
  *
@@ -4809,6 +4815,15 @@ function createInternalSessionRpc(connection, sessionId) {
4809
4815
  }
4810
4816
  },
4811
4817
  /** @experimental */
4818
+ canvasSource: {
4819
+ /**
4820
+ * Closes a canvas through its original session source. Requires the privately admitted in-process CLI host.
4821
+ *
4822
+ * @param params Closes a canvas through its original owned or attached session namespace.
4823
+ */
4824
+ close: async (params) => connection.sendRequest("session.canvasSource.close", { ...params, sessionId })
4825
+ },
4826
+ /** @experimental */
4812
4827
  workflow: {
4813
4828
  /**
4814
4829
  * Internal tool-originated dynamic workflow invocation.
@@ -253,7 +253,15 @@ export type IndexedSearchDisabledReason =
253
253
  /** The Windows cloud-sync safety check failed. */
254
254
  | "cloud_sync_detection_failed"
255
255
  /** The workspace is not available on the runtime's local filesystem. */
256
- | "workspace_not_local";
256
+ | "workspace_not_local"
257
+ /** Another process holds the machine-wide indexed-search server slot. */
258
+ | "server_limit"
259
+ /** The workspace is a filesystem or network-share root. */
260
+ | "filesystem_root"
261
+ /** The workspace is the user's home directory. */
262
+ | "home_directory"
263
+ /** The user's home directory could not be determined. */
264
+ | "home_directory_detection_failed";
257
265
  /**
258
266
  * Result of an indexed-search startup attempt.
259
267
  */
@@ -14202,6 +14210,10 @@ export interface CommandQueuedData {
14202
14210
  * Unique identifier for this request; used to respond via session.respondToQueuedCommand()
14203
14211
  */
14204
14212
  requestId: string;
14213
+ /**
14214
+ * Whether a schedule dispatched this command. Consumers must reject commands marked as not schedulable before executing a scheduled request. Absent for ordinary queued commands.
14215
+ */
14216
+ scheduled?: boolean;
14205
14217
  }
14206
14218
  /**
14207
14219
  * Session event "command.execute". Registered command dispatch request routed to the owning client