@github/copilot-sdk 1.0.0-beta.8 → 1.0.0

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/types.d.ts CHANGED
@@ -3,12 +3,14 @@
3
3
  */
4
4
  import type { Canvas } from "./canvas.js";
5
5
  import type { SessionFsProvider } from "./sessionFsProvider.js";
6
- import type { SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
6
+ import type { ReasoningSummary, SessionEvent as GeneratedSessionEvent } from "./generated/session-events.js";
7
7
  import type { CopilotSession } from "./session.js";
8
8
  import type { RemoteSessionMode } from "./generated/rpc.js";
9
9
  import type { OpenCanvasInstance } from "./generated/rpc.js";
10
+ import type { ToolSet } from "./toolSet.js";
10
11
  export type { RemoteSessionMode } from "./generated/rpc.js";
11
12
  export type SessionEvent = GeneratedSessionEvent;
13
+ export type { ReasoningSummary } from "./generated/session-events.js";
12
14
  export type { SessionFsProvider } from "./sessionFsProvider.js";
13
15
  export { createSessionFsAdapter } from "./sessionFsProvider.js";
14
16
  export type { SessionFsFileInfo } from "./sessionFsProvider.js";
@@ -128,12 +130,38 @@ export declare const RuntimeConnection: {
128
130
  connectionToken?: string;
129
131
  }) => UriRuntimeConnection;
130
132
  };
133
+ /**
134
+ * Controls SDK defaults for ambient features.
135
+ *
136
+ * - `"copilot-cli"` (default): Defaults equivalent to Copilot CLI. Useful when
137
+ * building a coding agent that shares sessions with Copilot CLI. Do not use
138
+ * this mode for server-based multi-user applications — the default coding
139
+ * agent has tools and capabilities that operate across sessions and can
140
+ * access the host OS environment.
141
+ * - `"empty"`: Disables optional features by default. The app must explicitly
142
+ * opt into anything it needs. Required for any scenario where CLI-like
143
+ * ambient behavior is unsafe (e.g. multi-user servers).
144
+ */
145
+ export type CopilotClientMode = "empty" | "copilot-cli";
131
146
  export interface CopilotClientOptions {
132
147
  /**
133
148
  * How to connect to the Copilot runtime. When omitted, defaults to
134
149
  * {@link RuntimeConnection.forStdio} with the bundled runtime.
135
150
  */
136
151
  connection?: RuntimeConnection;
152
+ /**
153
+ * Selects the SDK defaulting strategy. See {@link CopilotClientMode}.
154
+ *
155
+ * When set to `"empty"`, the SDK validates that the app has supplied the
156
+ * required configuration ({@link CopilotClientOptions.baseDirectory} or
157
+ * {@link CopilotClientOptions.sessionFs}, plus
158
+ * {@link SessionConfigBase.availableTools} on each session) and translates
159
+ * session creation requests into runtime options that flip tool filter
160
+ * precedence to deny-wins so exclusions are expressible.
161
+ *
162
+ * @default "copilot-cli"
163
+ */
164
+ mode?: CopilotClientMode;
137
165
  /**
138
166
  * Working directory for the runtime process.
139
167
  * If not set, inherits the current process's working directory.
@@ -391,6 +419,17 @@ export interface SessionCapabilities {
391
419
  ui?: {
392
420
  /** Whether the host supports interactive elicitation dialogs. */
393
421
  elicitation?: boolean;
422
+ /**
423
+ * Whether the runtime has accepted the session's MCP Apps (SEP-1865)
424
+ * opt-in. `true` when the consumer set `enableMcpApps: true` on
425
+ * create/resume **and** the runtime's `MCP_APPS` feature flag (or
426
+ * `COPILOT_MCP_APPS=true` env override) is on. Otherwise absent or
427
+ * `false`, indicating the runtime silently dropped the opt-in.
428
+ *
429
+ * @experimental This property is part of an experimental wire-protocol surface
430
+ * (SEP-1865) and may change or be removed in a future release.
431
+ */
432
+ mcpApps?: boolean;
394
433
  /** Whether the host supports canvas rendering. */
395
434
  canvases?: boolean;
396
435
  };
@@ -849,6 +888,47 @@ export interface PostToolUseHookOutput {
849
888
  export type PostToolUseHandler = (input: PostToolUseHookInput, invocation: {
850
889
  sessionId: string;
851
890
  }) => Promise<PostToolUseHookOutput | void> | PostToolUseHookOutput | void;
891
+ /**
892
+ * Input for post-tool-use-failure hook.
893
+ *
894
+ * Dispatched after a tool execution whose `resultType` is `"failure"`.
895
+ * The input differs from {@link PostToolUseHookInput}: the host CLI does not
896
+ * forward the full `ToolResultObject` to failure hooks — only `error`, the
897
+ * stringified failure message extracted from the tool's result, is provided.
898
+ */
899
+ export interface PostToolUseFailureHookInput extends BaseHookInput {
900
+ toolName: string;
901
+ toolArgs: unknown;
902
+ /**
903
+ * Failure message from the tool's result (the `error` field of the
904
+ * underlying `ToolResultObject`, falling back to its text/log fields).
905
+ */
906
+ error: string;
907
+ }
908
+ /**
909
+ * Output for post-tool-use-failure hook.
910
+ *
911
+ * Only `additionalContext` is consumed by the host CLI — it is appended as
912
+ * hidden guidance to the model alongside the failed tool result. Other fields
913
+ * such as `modifiedResult` or `suppressOutput` are not honored for failure
914
+ * hooks (see {@link PostToolUseHookOutput} for the success-only hook).
915
+ */
916
+ export interface PostToolUseFailureHookOutput {
917
+ additionalContext?: string;
918
+ }
919
+ /**
920
+ * Handler for post-tool-use-failure hook.
921
+ *
922
+ * Fires after a tool execution whose result was `"failure"`. `onPostToolUse`
923
+ * only fires for successful results, so register this handler to observe or
924
+ * react to failed tool outcomes.
925
+ *
926
+ * Note: `"rejected"`, `"denied"`, and `"timeout"` results do not currently
927
+ * trigger this hook either — only `"failure"` does.
928
+ */
929
+ export type PostToolUseFailureHandler = (input: PostToolUseFailureHookInput, invocation: {
930
+ sessionId: string;
931
+ }) => Promise<PostToolUseFailureHookOutput | void> | PostToolUseFailureHookOutput | void;
852
932
  /**
853
933
  * Input for user-prompt-submitted hook
854
934
  */
@@ -947,9 +1027,20 @@ export interface SessionHooks {
947
1027
  */
948
1028
  onPreMcpToolCall?: PreMcpToolCallHandler;
949
1029
  /**
950
- * Called after a tool is executed
1030
+ * Called after a tool is executed with a successful result.
1031
+ *
1032
+ * For failed tool executions, register {@link onPostToolUseFailure} instead;
1033
+ * this handler does not fire for non-success results.
951
1034
  */
952
1035
  onPostToolUse?: PostToolUseHandler;
1036
+ /**
1037
+ * Called after a tool execution whose result was `"failure"`.
1038
+ *
1039
+ * Register this handler alongside {@link onPostToolUse} to observe failed
1040
+ * tool calls — `onPostToolUse` only fires for successful results, so
1041
+ * without this hook failed tool calls are invisible to extensions.
1042
+ */
1043
+ onPostToolUseFailure?: PostToolUseFailureHandler;
953
1044
  /**
954
1045
  * Called when the user submits a prompt
955
1046
  */
@@ -1108,10 +1199,38 @@ export interface InfiniteSessionConfig {
1108
1199
  */
1109
1200
  bufferExhaustionThreshold?: number;
1110
1201
  }
1202
+ /**
1203
+ * Configuration for handling large tool outputs.
1204
+ *
1205
+ * When a tool produces output exceeding the configured size, the output is
1206
+ * written to a temp file and a reference is returned to the model instead of
1207
+ * the full payload.
1208
+ */
1209
+ export interface LargeToolOutputConfig {
1210
+ /**
1211
+ * Whether large output handling is enabled.
1212
+ * @default true
1213
+ */
1214
+ enabled?: boolean;
1215
+ /**
1216
+ * Maximum size in bytes before output is written to a temp file.
1217
+ * @default 51200
1218
+ */
1219
+ maxSizeBytes?: number;
1220
+ /**
1221
+ * Directory to write temp files to. Defaults to the OS temp directory.
1222
+ */
1223
+ outputDirectory?: string;
1224
+ }
1111
1225
  /**
1112
1226
  * Valid reasoning effort levels for models that support it.
1113
1227
  */
1114
1228
  export type ReasoningEffort = "low" | "medium" | "high" | "xhigh";
1229
+ /**
1230
+ * Context window tier for the session. "long_context" pins the session to the
1231
+ * long-context tier when the selected model supports it.
1232
+ */
1233
+ export type ContextTier = "default" | "long_context";
1115
1234
  /**
1116
1235
  * Stable extension identity for session participants that provide canvases.
1117
1236
  */
@@ -1142,13 +1261,30 @@ export interface SessionConfigBase {
1142
1261
  * Use client.listModels() to check supported values for each model.
1143
1262
  */
1144
1263
  reasoningEffort?: ReasoningEffort;
1264
+ /**
1265
+ * Reasoning summary mode for models that support configurable reasoning summaries.
1266
+ * Use "none" to suppress summary output regardless of whether reasoning is enabled.
1267
+ */
1268
+ reasoningSummary?: ReasoningSummary;
1269
+ /**
1270
+ * Context window tier for models that support it. Use "long_context" to pin
1271
+ * the session to the long-context tier; omit or use "default" otherwise.
1272
+ */
1273
+ contextTier?: ContextTier;
1145
1274
  /** Per-property overrides for model capabilities, deep-merged over runtime defaults. */
1146
1275
  modelCapabilities?: ModelCapabilitiesOverride;
1276
+ /**
1277
+ * Configuration for handling large tool outputs. When a tool produces
1278
+ * output exceeding the configured size, the output is written to a temp
1279
+ * file and a reference is returned to the model instead of the full
1280
+ * payload.
1281
+ */
1282
+ largeOutput?: LargeToolOutputConfig;
1147
1283
  /**
1148
1284
  * Override the default configuration directory location.
1149
1285
  * When specified, the session will use this directory for storing config and state.
1150
1286
  */
1151
- configDir?: string;
1287
+ configDirectory?: string;
1152
1288
  /**
1153
1289
  * When true, automatically discovers MCP server configurations (e.g. `.mcp.json`,
1154
1290
  * `.vscode/mcp.json`) and skill directories from the working directory and merges
@@ -1188,6 +1324,19 @@ export interface SessionConfigBase {
1188
1324
  * stay clean.
1189
1325
  */
1190
1326
  requestExtensions?: boolean;
1327
+ /**
1328
+ * Optional override path to a `copilot-sdk/` folder to inject into
1329
+ * extension subprocesses for this session in place of the bundled SDK.
1330
+ * When unset or invalid (missing folder or missing `index.js` /
1331
+ * `extension.js`), the runtime falls back to the bundled SDK without
1332
+ * throwing. Takes precedence over any server-level default.
1333
+ *
1334
+ * Only honored on session create and resume — extensions joining via
1335
+ * `joinSession` cannot override the SDK path, because the extension
1336
+ * subprocess has already been forked by the host with the SDK the host
1337
+ * chose. `JoinSessionConfig` omits this field for that reason.
1338
+ */
1339
+ extensionSdkPath?: string;
1191
1340
  /**
1192
1341
  * Stable extension identity for canvas providers on this connection. When
1193
1342
  * set, the runtime uses `${source}:${name}` as the agent-facing extension
@@ -1207,14 +1356,25 @@ export interface SessionConfigBase {
1207
1356
  systemMessage?: SystemMessageConfig;
1208
1357
  /**
1209
1358
  * List of tool names to allow. When specified, only these tools will be available.
1210
- * Takes precedence over excludedTools.
1359
+ *
1360
+ * Supports source-qualified filter patterns (`builtin:*`, `builtin:<name>`,
1361
+ * `mcp:*`, `mcp:<name>`, `custom:*`, `custom:<name>`) as well as the bare
1362
+ * name form (exact match across any source). Build this list with
1363
+ * {@link ToolSet} for type safety and readable intent.
1364
+ *
1365
+ * Composes with {@link excludedTools}: a tool is enabled when it matches
1366
+ * `availableTools` (or `availableTools` is unset) AND it does not match
1367
+ * `excludedTools`. This lets you express "everything matching X except Y".
1211
1368
  */
1212
- availableTools?: string[];
1369
+ availableTools?: string[] | ToolSet;
1213
1370
  /**
1214
- * List of tool names to disable. All other tools remain available.
1215
- * Ignored if availableTools is specified.
1371
+ * List of tool names to disable. Supports the same pattern syntax as
1372
+ * {@link availableTools}.
1373
+ *
1374
+ * Always takes precedence over {@link availableTools}: a tool listed here
1375
+ * is disabled even if it also matches `availableTools`.
1216
1376
  */
1217
- excludedTools?: string[];
1377
+ excludedTools?: string[] | ToolSet;
1218
1378
  /**
1219
1379
  * Custom provider configuration (BYOK - Bring Your Own Key).
1220
1380
  * When specified, uses the provided API endpoint instead of the Copilot API.
@@ -1229,6 +1389,39 @@ export interface SessionConfigBase {
1229
1389
  * This is independent of the OpenTelemetry configuration in {@link CopilotClientOptions.telemetry}.
1230
1390
  */
1231
1391
  enableSessionTelemetry?: boolean;
1392
+ /**
1393
+ * When true, the runtime skips loading custom-instruction sources
1394
+ * (e.g. `.github/copilot-instructions.md`, `AGENTS.md`, `CLAUDE.md`).
1395
+ *
1396
+ * Defaults to `false` (custom instructions are loaded). Under
1397
+ * {@link CopilotClientOptions.mode} = `"empty"`, defaults to `true`; apps
1398
+ * can pass `false` here to opt back in.
1399
+ */
1400
+ skipCustomInstructions?: boolean;
1401
+ /**
1402
+ * When true, custom agents default to local-only execution and are not
1403
+ * dispatched to remote workers.
1404
+ *
1405
+ * Defaults to `false`. Under {@link CopilotClientOptions.mode} = `"empty"`,
1406
+ * defaults to `true`; apps can pass `false` here to opt back in.
1407
+ */
1408
+ customAgentsLocalOnly?: boolean;
1409
+ /**
1410
+ * When true, the runtime instructs the agent to include a `Co-authored-by`
1411
+ * trailer in commit messages it composes.
1412
+ *
1413
+ * Defaults to `true`. Under {@link CopilotClientOptions.mode} = `"empty"`,
1414
+ * defaults to `false`; apps can pass `true` here to opt back in.
1415
+ */
1416
+ coauthorEnabled?: boolean;
1417
+ /**
1418
+ * When true, the `manage_schedule` tool is exposed to the agent.
1419
+ *
1420
+ * Defaults to whatever the runtime exposes (typically gated to staff
1421
+ * users). Under {@link CopilotClientOptions.mode} = `"empty"`, defaults to
1422
+ * `false`; apps can pass `true` here to opt back in.
1423
+ */
1424
+ manageScheduleEnabled?: boolean;
1232
1425
  /**
1233
1426
  * Optional handler for permission requests from the server.
1234
1427
  * When omitted, permission requests are surfaced as events and left pending for
@@ -1246,6 +1439,33 @@ export interface SessionConfigBase {
1246
1439
  * Also enables the `elicitation` capability on the session.
1247
1440
  */
1248
1441
  onElicitationRequest?: ElicitationHandler;
1442
+ /**
1443
+ * Enable MCP Apps (SEP-1865) UI passthrough on this session.
1444
+ *
1445
+ * When `true` **and** the runtime has MCP Apps enabled (via the
1446
+ * `MCP_APPS` feature flag or `COPILOT_MCP_APPS=true` environment
1447
+ * override), the runtime adds the `mcp-apps` capability to the session,
1448
+ * which causes it to advertise the `extensions.io.modelcontextprotocol/ui`
1449
+ * extension to MCP servers (so they expose `_meta.ui.resourceUri` on
1450
+ * tools) and to expose the `session.rpc.mcp.apps.{listTools,callTool,
1451
+ * readResource,setHostContext,getHostContext,diagnose}` JSON-RPC methods.
1452
+ *
1453
+ * If the runtime gate is off, the opt-in is silently dropped server-side
1454
+ * (the runtime logs a warning); the session is created normally but the
1455
+ * MCP Apps surface is unavailable. Inspect the runtime's
1456
+ * `capabilities.ui.mcpApps` on the create/resume response to detect this.
1457
+ *
1458
+ * SDK consumers MUST set this to `true` only when they have an iframe
1459
+ * renderer that can display `ui://` MCP App bundles. Setting it without a
1460
+ * renderer will cause MCP servers to register UI-enabled tool variants
1461
+ * the consumer cannot display.
1462
+ *
1463
+ * @experimental This option is part of an experimental wire-protocol surface
1464
+ * (SEP-1865) and may change or be removed in a future release.
1465
+ *
1466
+ * @default false
1467
+ */
1468
+ enableMcpApps?: boolean;
1249
1469
  /**
1250
1470
  * Handler for exit-plan-mode requests from the agent.
1251
1471
  * When provided, enables `exitPlanMode.request` callbacks.
@@ -1284,6 +1504,14 @@ export interface SessionConfigBase {
1284
1504
  * @default true
1285
1505
  */
1286
1506
  includeSubAgentStreamingEvents?: boolean;
1507
+ /**
1508
+ * Controls how MCP OAuth tokens are stored for this session.
1509
+ * - `"persistent"` — tokens are stored in the OS keychain (shared across sessions)
1510
+ * - `"in-memory"` — tokens are stored in memory and discarded when the session ends
1511
+ *
1512
+ * @default "in-memory"
1513
+ */
1514
+ mcpOAuthTokenStorage?: "persistent" | "in-memory";
1287
1515
  /**
1288
1516
  * MCP server configurations for the session.
1289
1517
  * Keys are server names, values are server configurations.
@@ -1310,6 +1538,20 @@ export interface SessionConfigBase {
1310
1538
  * Directories to load skills from.
1311
1539
  */
1312
1540
  skillDirectories?: string[];
1541
+ /**
1542
+ * Local filesystem paths to Open Plugins-format directories
1543
+ * (https://open-plugins.com/) to load for this session.
1544
+ *
1545
+ * Relative paths resolve against `workingDirectory` (or the runtime cwd if
1546
+ * unset); absolute paths are recommended. Invalid entries are logged and
1547
+ * skipped.
1548
+ *
1549
+ * Treated as an explicit opt-in: plugin agents and rules load even when
1550
+ * {@link SessionConfigBase.enableConfigDiscovery} is false. Loaded assets
1551
+ * slot between project (cwd) sources and personal/home sources in the
1552
+ * session-wide precedence order.
1553
+ */
1554
+ pluginDirectories?: string[];
1313
1555
  /**
1314
1556
  * Additional directories to search for custom instruction files.
1315
1557
  */
@@ -1335,6 +1577,53 @@ export interface SessionConfigBase {
1335
1577
  * the identity used for content exclusion, model routing, and quota checks.
1336
1578
  */
1337
1579
  gitHubToken?: string;
1580
+ /**
1581
+ * When true, skips embedding-based retrieval for this session.
1582
+ * Use in multitenant deployments to prevent cross-session information leakage
1583
+ * through the shared embedding cache.
1584
+ */
1585
+ skipEmbeddingRetrieval?: boolean;
1586
+ /**
1587
+ * Controls how the embedding cache is stored for this session.
1588
+ * - `"persistent"`: Embeddings are cached on disk and shared across sessions/restarts.
1589
+ * - `"in-memory"`: Embeddings are cached in memory only and discarded when the session ends.
1590
+ */
1591
+ embeddingCacheStorage?: "persistent" | "in-memory";
1592
+ /**
1593
+ * Organization-level custom instructions to include in the system prompt.
1594
+ * Allows hosts to inject organization-specific guidance without relying on
1595
+ * filesystem-based instruction discovery.
1596
+ */
1597
+ organizationCustomInstructions?: string;
1598
+ /**
1599
+ * When true, enables on-demand discovery of instruction files (AGENTS.md,
1600
+ * .github/copilot-instructions.md, etc.) after successful file views.
1601
+ */
1602
+ enableOnDemandInstructionDiscovery?: boolean;
1603
+ /**
1604
+ * When true, enables loading of file-based hooks from `.github/hooks/`.
1605
+ * This is separate from the `hooks` callback parameter which gates SDK
1606
+ * hook event registration.
1607
+ */
1608
+ enableFileHooks?: boolean;
1609
+ /**
1610
+ * When true, enables git operations on the host filesystem (branch detection,
1611
+ * file status, commit history). When false, no git context is surfaced in
1612
+ * the system prompt.
1613
+ */
1614
+ enableHostGitOperations?: boolean;
1615
+ /**
1616
+ * When true, enables the cross-session store for search and retrieval
1617
+ * across sessions. When false, session content is not written to or
1618
+ * read from the shared session store.
1619
+ */
1620
+ enableSessionStore?: boolean;
1621
+ /**
1622
+ * When true, enables skill loading (including builtin skills and discovered
1623
+ * skill directories). When false, no skills are loaded regardless of
1624
+ * `skillDirectories` or `enableConfigDiscovery` settings.
1625
+ */
1626
+ enableSkills?: boolean;
1338
1627
  /**
1339
1628
  * Per-session remote behavior control:
1340
1629
  * - `"off"` — local only, no remote export (default)
@@ -1514,10 +1803,19 @@ export interface MessageOptions {
1514
1803
  * - "immediate": Send immediately
1515
1804
  */
1516
1805
  mode?: "enqueue" | "immediate";
1806
+ /**
1807
+ * The UI mode the agent was in when this message was sent (for example "plan" or "autopilot").
1808
+ * Defaults to the session's current mode when unset.
1809
+ */
1810
+ agentMode?: "interactive" | "plan" | "autopilot" | "shell";
1517
1811
  /**
1518
1812
  * Custom HTTP headers to include in outbound model requests for this turn.
1519
1813
  */
1520
1814
  requestHeaders?: Record<string, string>;
1815
+ /**
1816
+ * If provided, this is shown in the timeline instead of `prompt`.
1817
+ */
1818
+ displayPrompt?: string;
1521
1819
  }
1522
1820
  /**
1523
1821
  * All possible event type strings from SessionEvent
@@ -118,19 +118,20 @@ hooks: {
118
118
  onUserPromptSubmitted: async (input, invocation) => { ... },
119
119
  onPreToolUse: async (input, invocation) => { ... },
120
120
  onPostToolUse: async (input, invocation) => { ... },
121
+ onPostToolUseFailure: async (input, invocation) => { ... },
121
122
  onSessionStart: async (input, invocation) => { ... },
122
123
  onSessionEnd: async (input, invocation) => { ... },
123
124
  onErrorOccurred: async (input, invocation) => { ... },
124
125
  }
125
126
  ```
126
127
 
127
- All hook inputs include `timestamp` (unix ms) and `cwd` (working directory).
128
+ All hook inputs include `timestamp` (`Date`) and `workingDirectory`.
128
129
  All handlers receive `invocation: { sessionId: string }` as the second argument.
129
130
  All handlers may return `void`/`undefined` (no-op) or an output object.
130
131
 
131
132
  ### onUserPromptSubmitted
132
133
 
133
- **Input:** `{ prompt: string, timestamp, cwd }`
134
+ **Input:** `{ prompt: string, timestamp, workingDirectory }`
134
135
 
135
136
  **Output (all fields optional):**
136
137
  | Field | Type | Effect |
@@ -140,7 +141,7 @@ All handlers may return `void`/`undefined` (no-op) or an output object.
140
141
 
141
142
  ### onPreToolUse
142
143
 
143
- **Input:** `{ toolName: string, toolArgs: unknown, timestamp, cwd }`
144
+ **Input:** `{ toolName: string, toolArgs: unknown, timestamp, workingDirectory }`
144
145
 
145
146
  **Output (all fields optional):**
146
147
  | Field | Type | Effect |
@@ -152,7 +153,10 @@ All handlers may return `void`/`undefined` (no-op) or an output object.
152
153
 
153
154
  ### onPostToolUse
154
155
 
155
- **Input:** `{ toolName: string, toolArgs: unknown, toolResult: ToolResultObject, timestamp, cwd }`
156
+ **Input:** `{ toolName: string, toolArgs: unknown, toolResult: ToolResultObject, timestamp, workingDirectory }`
157
+
158
+ Fires only when the tool returned a successful result. To observe non-success
159
+ outcomes, register `onPostToolUseFailure` as well.
156
160
 
157
161
  **Output (all fields optional):**
158
162
  | Field | Type | Effect |
@@ -160,9 +164,29 @@ All handlers may return `void`/`undefined` (no-op) or an output object.
160
164
  | `modifiedResult` | `ToolResultObject` | Replaces the tool result |
161
165
  | `additionalContext` | `string` | Injected into the conversation |
162
166
 
167
+ ### onPostToolUseFailure
168
+
169
+ **Input:** `{ toolName: string, toolArgs: unknown, error: string, timestamp, workingDirectory }`
170
+
171
+ Fires after a tool execution whose result was `"failure"`. `onPostToolUse`
172
+ does **not** fire for these outcomes, so register this handler to observe or
173
+ react to them — useful for telemetry, replay buffers, fault-injection tests,
174
+ or pairing pre/post tool tracking that would otherwise leak when the tool
175
+ fails. Note the input shape differs from `onPostToolUse`: only `error` (the
176
+ stringified failure message) is provided, not the full `toolResult`.
177
+
178
+ **Output (all fields optional):**
179
+ | Field | Type | Effect |
180
+ |-------|------|--------|
181
+ | `additionalContext` | `string` | Appended as hidden guidance the model sees alongside the failed tool result |
182
+
183
+ Note: only `"failure"` results trigger this hook. Other non-success
184
+ `resultType` values (`"rejected"`, `"denied"`, `"timeout"`) do not currently
185
+ fire it.
186
+
163
187
  ### onSessionStart
164
188
 
165
- **Input:** `{ source: "startup" \| "resume" \| "new", initialPrompt?: string, timestamp, cwd }`
189
+ **Input:** `{ source: "startup" \| "resume" \| "new", initialPrompt?: string, timestamp, workingDirectory }`
166
190
 
167
191
  **Output (all fields optional):**
168
192
  | Field | Type | Effect |
@@ -171,7 +195,7 @@ All handlers may return `void`/`undefined` (no-op) or an output object.
171
195
 
172
196
  ### onSessionEnd
173
197
 
174
- **Input:** `{ reason: "complete" \| "error" \| "abort" \| "timeout" \| "user_exit", finalMessage?: string, error?: string, timestamp, cwd }`
198
+ **Input:** `{ reason: "complete" \| "error" \| "abort" \| "timeout" \| "user_exit", finalMessage?: string, error?: string, timestamp, workingDirectory }`
175
199
 
176
200
  **Output (all fields optional):**
177
201
  | Field | Type | Effect |
@@ -181,7 +205,7 @@ All handlers may return `void`/`undefined` (no-op) or an output object.
181
205
 
182
206
  ### onErrorOccurred
183
207
 
184
- **Input:** `{ error: string, errorContext: "model_call" \| "tool_execution" \| "system" \| "user_input", recoverable: boolean, timestamp, cwd }`
208
+ **Input:** `{ error: string, errorContext: "model_call" \| "tool_execution" \| "system" \| "user_input", recoverable: boolean, timestamp, workingDirectory }`
185
209
 
186
210
  **Output (all fields optional):**
187
211
  | Field | Type | Effect |
package/docs/examples.md CHANGED
@@ -152,16 +152,17 @@ Hooks intercept and modify behavior at key lifecycle points. Register them in th
152
152
 
153
153
  ### Available Hooks
154
154
 
155
- | Hook | Fires When | Can Modify |
156
- | ----------------------- | ------------------------- | ------------------------------------------- |
157
- | `onUserPromptSubmitted` | User sends a message | The prompt text, add context |
158
- | `onPreToolUse` | Before a tool executes | Tool args, permission decision, add context |
159
- | `onPostToolUse` | After a tool executes | Tool result, add context |
160
- | `onSessionStart` | Session starts or resumes | Add context, modify config |
161
- | `onSessionEnd` | Session ends | Cleanup actions, summary |
162
- | `onErrorOccurred` | An error occurs | Error handling strategy (retry/skip/abort) |
163
-
164
- All hook inputs include `timestamp` (unix ms) and `cwd` (working directory).
155
+ | Hook | Fires When | Can Modify |
156
+ | ----------------------- | ---------------------------------------- | ------------------------------------------- |
157
+ | `onUserPromptSubmitted` | User sends a message | The prompt text, add context |
158
+ | `onPreToolUse` | Before a tool executes | Tool args, permission decision, add context |
159
+ | `onPostToolUse` | After a tool executes successfully | Tool result, add context |
160
+ | `onPostToolUseFailure` | After a tool execution returns a failure | Add hidden guidance to the model |
161
+ | `onSessionStart` | Session starts or resumes | Add context |
162
+ | `onSessionEnd` | Session ends | Cleanup actions, summary |
163
+ | `onErrorOccurred` | An error occurs | Error handling strategy (retry/skip/abort) |
164
+
165
+ All hook inputs include `timestamp` (`Date`) and `workingDirectory`.
165
166
 
166
167
  ### Modifying the user's message
167
168
 
@@ -267,12 +268,18 @@ hooks: {
267
268
  }
268
269
  ```
269
270
 
270
- ### Augmenting tool results with extra context
271
+ ### Reacting when a tool fails
272
+
273
+ `onPostToolUse` only fires for successful tool executions. To observe or react
274
+ to failures, register `onPostToolUseFailure`. The input includes
275
+ `input.error` (the stringified failure message); only `additionalContext` on
276
+ the return value is consumed by the runtime, and it is appended as hidden
277
+ guidance alongside the failed tool result.
271
278
 
272
279
  ```js
273
280
  hooks: {
274
- onPostToolUse: async (input) => {
275
- if (input.toolName === "bash" && input.toolResult?.resultType === "failure") {
281
+ onPostToolUseFailure: async (input) => {
282
+ if (input.toolName === "bash") {
276
283
  return {
277
284
  additionalContext: "The command failed. Try a different approach.",
278
285
  };
@@ -408,7 +415,7 @@ session.on("assistant.message", (event) => {
408
415
  | Event Type | Description | Key Data Fields |
409
416
  | --------------------------- | ------------------------------------------------ | ------------------------------------------------------ |
410
417
  | `assistant.message` | Agent's final response | `content`, `messageId`, `toolRequests` |
411
- | `assistant.streaming_delta` | Token-by-token streaming (ephemeral) | `totalResponseSizeBytes` |
418
+ | `assistant.message_delta` | Message content chunks (ephemeral) | `deltaContent` |
412
419
  | `tool.execution_start` | A tool is about to run | `toolCallId`, `toolName`, `arguments` |
413
420
  | `tool.execution_complete` | A tool finished running | `toolCallId`, `toolName`, `success`, `result`, `error` |
414
421
  | `user.message` | User sent a message | `content`, `attachments`, `source` |
@@ -622,8 +629,11 @@ const session = await joinSession({
622
629
  onPreToolUse: async (input) => {
623
630
  if (input.toolName === "bash") {
624
631
  const cmd = String(input.toolArgs?.command || "");
625
- if (/rm\\s+-rf\\s+\\/ / i.test(cmd) || /Remove-Item\\s+.*-Recurse/i.test(cmd)) {
626
- return { permissionDecision: "deny" };
632
+ if (/rm\\s+-rf\\s+\//i.test(cmd) || /Remove-Item\\s+.*-Recurse/i.test(cmd)) {
633
+ return {
634
+ permissionDecision: "deny",
635
+ permissionDecisionReason: "Destructive commands are not allowed.",
636
+ };
627
637
  }
628
638
  }
629
639
  },
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "1.0.0-beta.8",
7
+ "version": "1.0.0",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/cjs/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -44,7 +44,7 @@
44
44
  "generate": "cd ../scripts/codegen && npm run generate",
45
45
  "update:protocol-version": "tsx scripts/update-protocol-version.ts",
46
46
  "prepublishOnly": "npm run build",
47
- "package": "npm run clean && npm run build && node scripts/set-version.js && npm pack && npm version 0.1.0 --no-git-tag-version --allow-same-version"
47
+ "package": "npm run clean && npm run build && node scripts/set-version.js && npm pack && npm version 0.0.0-dev --no-git-tag-version --allow-same-version"
48
48
  },
49
49
  "keywords": [
50
50
  "github",
@@ -56,7 +56,7 @@
56
56
  "author": "GitHub",
57
57
  "license": "MIT",
58
58
  "dependencies": {
59
- "@github/copilot": "^1.0.55-1",
59
+ "@github/copilot": "^1.0.57",
60
60
  "vscode-jsonrpc": "^8.2.1",
61
61
  "zod": "^4.3.6"
62
62
  },