All notable changes to this project will be documented in this file. This change log follows the conventions of keepachangelog.com.
- Per-session GitHub authentication —
:github-tokenis now accepted increate-session,<create-session,resume-session,<resume-session, andjoin-sessionconfigs and is forwarded asgitHubTokenon session create/resume RPCs. This enables one client to manage sessions authenticated as different GitHub users. (upstream PR #1124) - Stable v0.3.0 permission decision kinds —
::permission-kindnow includes:hook, and::permission-result-kindaccepts upstream decision kinds:approve-once,:approve-for-session,:approve-for-location,:reject, and:user-not-availablein addition to:no-result. Legacy Clojure denial aliases remain accepted and are normalized before the SDK sends decisions to the CLI. (upstream PR #1124)
approve-allparity —copilot/approve-allnow returns{:kind :approve-once}, matching the upstream Node.js SDKapproveAllhelper. Existing legacy:approvedpermission results are still accepted from custom handlers and normalized to:approve-once. (upstream PR #1124)
- Schema-driven codegen pipeline — new
bb codegentask generatessrc/github/copilot_sdk/generated/event_specs.cljfrom the upstream@github/copilot/schemas/session-events.schema.json. Produces ~190 spec forms (one leaf spec per unique property, one*-dataspec per event variant, one envelope spec per variant, and an aggregate::eventspec). - Schema fetch task — new
bb schemas:fetchdownloads the upstream npm package at the version pinned in.copilot-schema-versionand extracts schema JSON files intoschemas/(committed for reproducibility). - CI codegen-check workflow —
.github/workflows/codegen-check.ymlregenerates on every PR touching schemas, generator, generated files, or the pinned version, and fails on drift between committed and regenerated output. - Developer documentation — new
doc/codegen.mdexplains the pipeline, workflows for local development, and the JSON Schema →clojure.spectranslation rules. - Phase 3.5: three-tier wire/coerce/idiom architecture — new
script/codegen/coercions.edn(hand-curated event-scoped coercion table) and generatedsrc/github/copilot_sdk/generated/coerce.clj(event-wire->idiomandevent-idiom->wire). The runtime event dispatcher inclient.cljnow applies idiomatic coercion (e.g. ISO-8601 strings →java.time.Instant) before delivering events to user handlers. Coercion is fail-open: parse failures log a warning and deliver the uncoerced-but-normalized event so a malformed payload cannot kill the notification go-loop. Thehand-written-specs-agree-with-generateddrift audit now runs against coerced data with an emptyknown-driftsset, and three new invariants are enforced by tests (every coercion is exercised, converters are idempotent, round-trip is semantically lossless). - Historical event coercion —
session/get-messagesnow applies the same wire→idiom coercion pipeline as the live notification path, so:start-timeonsession.startevents fetched from history is also delivered as ajava.time.Instant. New integration testtest-get-messages-applies-coercionenforces this.
- Phase 6: instrument deduplication —
src/github/copilot_sdk/instrument.cljno longer maintains three parallel symbol lists (ones/fdefper public API fn, one symbol list passed toinstrument-all!, one tounstrument-all!). A new privateregister-fdef!macro both delegates tos/fdefand records the fully-qualified symbol in a singleregistered-fdefsregistry; bothinstrument-all!andunstrument-all!now derive their target list from that registry. The macro fail-fast rejects unqualified symbols at macroexpansion time, so a stale or alias-qualified entry is caught immediately rather than silently leaving an instrumentation gap. Net effect: ~162 lines removed frominstrument.clj, no behavior change, and adding a new public API fn now requires a single edit instead of three.
session.startevent delivery —:selected-modelwas being read with the wrong (camelCase) key:selectedModelin the runtime dispatcher; fixed to:selected-modelto match the kebab-case keys produced byutil/wire->clj.
- Mock server validates injected event types —
mock/send-session-event!now rejects unknown event types instead of silently emitting an unrecognised notification. Validation uses the SDK's canonical publicevent-typesregistry as the source of truth, so any event the SDK recognises can still be injected. A dedicatedmock/send-v3-broadcast-event!helper restricts injection to the five protocol v3 broadcast events (kept in sync withclient/handle-v3-broadcast-event!); the four v3 integration tests have migrated to it. Surfaces typos like"session.startt"immediately rather than as a confusing missing-event test failure.
0.3.0.0-SNAPSHOT - 2026-04-23
defaultAgent.excludedToolssession option — new:default-agent {:excluded-tools [...]}config for create, resume, and join session paths. This hides selected tools from the built-in/default agent while preserving tool availability for custom agents. (upstream commitb1b0df5c)- Session FS provider adapter — new
create-session-fs-adapterhelper adapts provider-style filesystem functions into structuredsessionFs.*RPC results. Session factories now also auto-adapt provider-style maps while preserving the existing low-level one-arg handler contract. (upstream commita3e273c9) - Generated event data specs — added explicit specs for assistant reasoning/message/usage fields, MCP server status/load events, skills loaded events, and extension loaded events from the upstream generated schema.
- Integration tests for
defaultAgentwire params, session FS adapter behavior, session FS factory auto-adaptation, extension status values, and event data specs.
- Extension status enum parity —
session.extensions_loadednow accepts upstream statuses"running","starting","disabled", and"failed"and rejects obsolete"enabled". - Message content specs — assistant/user message and reasoning event content remains string-only while elicitation result content accepts maps, matching upstream generated schemas.
0.2.2.0 - 2026-04-20
includeSubAgentStreamingEventssession option — new boolean:include-sub-agent-streaming-events?on::session-config,::resume-session-config, and::join-session-config. Whentrue(default), sub-agent streaming events are forwarded to the parent session's event stream. (upstream PR #1108)- Per-request HTTP headers on
send!— new:request-headersoption (map of string→string) on::send-options. Forwarded as wirerequestHeadersand merged with provider-level headers by the CLI. (upstream PR #1094) - Provider-level HTTP headers — new
:headersfield (map of string→string) on::providerconfig. Sent with each model request to BYOK endpoints. (upstream PR #1094) ::can-offer-session-approvalspec — boolean field present onpermission.requestedevents of kindwriteFile, indicating the CLI can offer a "trust this session" choice. (CLI 1.0.28, upstream PR #1089)::reasoning-tokensspec — non-negative integer field onassistant.usageandsession.usage_infoevents tracking tokens used for reasoning content. (CLI 1.0.32, upstream PR #1105)::agent-idspec — optional string field on::base-event, identifying which (sub-)agent emitted the event. (upstream PR #1108)- Integration tests for all new wire fields and specs (6 new
deftests covering sync/async wire forwarding and the 3 new spec additions).
convert-mcp-call-tool-result— new public function intoolsnamespace that converts MCPCallToolResultformat into the SDK'sToolResultObject. Handles text, image, and resource content types. (upstream PR #1049)default-join-session-permission-handler— new permission handler forresume-sessionthat returns{:kind :no-result}, signaling the CLI to handle permissions itself. SendsrequestPermission: falseon the wire. (upstream PR #1056)- MCP config spec aliases —
::mcp-stdio-serverand::mcp-http-serveras aliases for::mcp-local-serverand::mcp-remote-serverrespectively, matching upstream rename from Local→Stdio, Remote→HTTP. Old names kept for backward compatibility. (upstream PR #1051) - Per-agent skills field —
::agent-skills(vector of strings) on::custom-agentspec, allowing skill injection per custom agent. (upstream PR #995) - Memory permission event specs —
::memory-action,::memory-direction,::memory-reasonspecs for enriched memory permission request events. (CLI 1.0.22, upstream PR #1055) - New RPC wrappers in
sessionnamespace (all experimental):session-name-get,session-name-set!— get/set session display name (CLI 1.0.26, upstream PR #1076)workspace-get-workspace— get current workspace metadata (CLI 1.0.26, upstream PR #1076)mcp-discover— discover MCP servers in a working directory (CLI 1.0.22, upstream PR #1055)usage-get-metrics— get session usage metrics (CLI 1.0.22, upstream PR #1055)
- Integration tests for all new features (18 tests covering convert-mcp-call-tool-result, spec renames, agent skills, requestPermission behavior, new RPCs, and memory specs)
requestPermissionon resume —resume-sessionnow sendsrequestPermission: falsewhen usingdefault-join-session-permission-handler, andtruewhen using any other handler (e.g.,approve-all). Previously always senttrue. (upstream PR #1056)
enableConfigDiscoverysession option — new boolean:enable-config-discoveryon session and resume configs. Auto-discovers.mcp.json,.vscode/mcp.json, skills, etc. Instruction files are always loaded regardless. (upstream PR #1044)modelCapabilitiesoverride — new:model-capabilitiesoption on session config, resume config, andswitch-model!/set-model!. Pass a partial capabilities map (e.g.{:model-supports {:supports-vision true}}) to override model capabilities for the session. (upstream PR #1029)history-truncate!— new experimental function to trigger manual truncation of session context (upstream PR #1039)sessions-fork!— new experimental function to fork the current session (upstream PR #1039)- Integration tests for all new features (wire param verification, RPC routing)
compaction-compact!RPC renamed — underlying JSON-RPC method changed fromsession.compaction.compacttosession.history.compact(upstream PR #1039). The Clojure function name is unchanged for backward compatibility.
0.2.1.1 - 2026-04-04
- Session RPC wrappers — new experimental functions for session-level RPCs previously only accessible via
proto/send-request!:mode-get,mode-set!— get/set agent mode (interactive/plan/autopilot)plan-read,plan-update!,plan-delete!— read/update/delete session plan fileworkspace-list-files,workspace-read-file,workspace-create-file!— session workspace file operationsagent-list,agent-get-current,agent-select!,agent-deselect!,agent-reload!— custom agent managementfleet-start!— start parallel sub-sessions
- MCP config wrappers — new experimental server-level functions in
client:mcp-config-list,mcp-config-add!,mcp-config-update!,mcp-config-remove!— MCP server configuration management
- Hooks integration tests — 6 tests covering all hook types (preToolUse, postToolUse, sessionStart, unknownType, handler exceptions, no-hooks)
- User input handler tests — 2 tests for
userInput.requestserver→client RPC - System message transform tests — 3 tests for
systemMessage.transformcallback invocation, error fallback, and passthrough - Tool result normalization tests — 3 tests for string, nil, and structured ToolResultObject results via v3 broadcast
- Session RPC wrapper tests — 18 integration tests for all new RPC wrapper functions
- Mock server enhancements —
send-rpc-request!for testing server→client RPCs, response routing in server loop, 30+ new method stubs - Full
s/fdefinstrumentation for all 19 new public functions
session.errorevent data spec enriched — optional:status-code(int),:provider-call-id(string), and:url(string) fields added to::session.error-dataspec. These fields carry HTTP status codes, GitHub request tracing IDs, and actionable URLs from upstream error events (upstream PR #999, runtime 1.0.17).
0.2.1.0 - 2026-04-04
resolvedByHookguard onpermission.requested— when the runtime resolves a permission request via apermissionRequesthook, the broadcast event includesresolvedByHook: true. The SDK now skips the client's:on-permission-requesthandler and does not send thehandlePendingPermissionRequestRPC, preventing duplicate responses. Event subscribers still observe the event (upstream PR #999, runtime 1.0.17).- New permission result kinds —
:denied-by-content-exclusion-policyand:denied-by-permission-request-hookadded to::permission-result-kindspec (upstream PR #999). - MCP fields on
tool.execution_startevents — optional:mcp-server-nameand:mcp-tool-namefields added to::tool.execution_start-dataspec indicating the MCP server and original tool name for MCP-originated tool calls (upstream runtime 1.0.17). ::resolved-by-hookspec — boolean spec for theresolvedByHookfield onpermission.requestedevent data.- Commands example — new
examples/commands.cljdemonstrating slash command registration and handling. - Integration tests for
resolvedByHookguard (both true and false cases), new permission result kind specs, and MCP tool event fields.
- Public preview branding — README updated from "technical preview" to "public preview" with link to the announcement.
- BREAKING: Elicitation handler signature changed from 2-arg
(fn [request ctx])to single-arg(fn [context]). TheElicitationContextmap now includes:session-idalongside request fields (:message,:requested-schema,:mode,:elicitation-source,:url). Matches upstream cross-SDK consistency change (upstream PR #960).::elicitation-requestspec renamed to::elicitation-context.
remote-steerable?field onsession.startandsession.resumeevents — event data now includes optional:remote-steerable?boolean field indicating whether the session supports remote steering via Mission Control. Replaces previous:steerable?(upstream PRs #927, #908).get-session-metadata— new function on client for efficient O(1) session lookup by ID. Returns session metadata map if found, ornilif not found. Sendssession.getMetadataJSON-RPC call. Sharedwire->session-metadatahelper extracted fromlist-sessionsto eliminate duplication (upstream PR #899).- Elicitation provider support — new
:on-elicitation-requesthandler onSessionConfigandResumeSessionConfig. When provided, sendsrequestElicitation: truein the session create/resume RPC. The runtime routeselicitation.requestedbroadcast events to the handler, and results are sent back viasession.ui.handlePendingElicitationRPC. Handler errors automatically send a cancel response. New::elicitation-requestand::on-elicitation-requestspecs (upstream PR #908). capabilities.changedevent handling — session capabilities are dynamically updated whencapabilities.changedbroadcast events are received, e.g. when another client joins with elicitation support (upstream PR #908).- New event types —
sampling.requested,sampling.completed,session.remote_steerable_changed,capabilities.changedadded to event type enum and event sets (upstream PRs #908, #916). - Subagent event data fields —
subagent.started,subagent.completed,subagent.failedevents now include optional:model,:total-tool-calls,:total-tokens,:duration-msfields. New::subagent.started-data,::subagent.completed-data,::subagent.failed-dataspecs (upstream PR #916). skill.invokedevent:descriptionfield — optional:descriptionfrom SKILL.md frontmatter (upstream PR #916).session.custom_agents_updatedpayload spec — full::session.custom_agents_updated-dataspec with:agents(array of agent metadata),:warnings,:errors. New::custom-agent-infospec (upstream PR #916).- SessionFs virtual filesystem — new
:session-fsclient option with:initial-cwd,:session-state-path,:conventions. Client callssessionFs.setProviderRPC on connect. New:create-session-fs-handleron session config provides a per-session FS handler factory. The SDK dispatches incomingsessionFs.*RPC requests (10 operations:readFile,writeFile,appendFile,exists,stat,mkdir,readdir,readdirWithTypes,rm,rename) to the session's handler. Enables custom session storage backends (upstream PR #917). aborted?onsession.task_complete— optional boolean indicating the preceding agentic loop was cancelled via abort signal. New::aborted?spec (upstream PR #917).timeouttool result type —::result-typenow accepts:timeout/"timeout"for tool calls that timed out (upstream PR #970).- Integration tests for elicitation provider routing, handler error→cancel fallback, capabilities.changed updates, and requestElicitation wire flag.
- BREAKING:
::steerable?renamed to::remote-steerable?onsession.startandsession.resumeevent data, matching upstream wire field rename fromsteerabletoremoteSteerable(upstream PR #908). session.idleis now ephemeral — the runtime no longer persistssession.idleevents in session history.get-messageswill no longer returnsession.idleevents. Live event listeners (used bysend-and-wait!andsend!) are unaffected and still receive it (upstream PR #927).
0.2.1.1-SNAPSHOT - 2026-03-26
- Commands support — register slash commands per-session via
:commandsoption in session config. Each command definition has:name, optional:description, and a:command-handlerfunction. Commands are sent on the wire (name + description) and executed viacommand.executebroadcast events withsession.commands.handlePendingCommandRPC callback (upstream PR #906). - UI Elicitation convenience API — new public functions
confirm!,select!,input!wrap the existingui-elicitation!with typed schemas.capabilitiesaccessor returns host capabilities from session create/resume response.elicitation-supported?predicate checks if the host supports elicitation dialogs. All convenience methods throw with a clear error when elicitation is unsupported (upstream PR #906). COPILOT_CLI_PATHenv var fallback — client constructor now checksCOPILOT_CLI_PATHenvironment variable before defaulting to"copilot"when no explicit:cli-pathor:cli-urlis provided (upstream PR #906).- New event type
session.custom_agents_updatedadded to event type enum. :hostfield onsession.handoffevents — event data now includes optional:hostfield with the GitHub host URL. New::session.handoff-dataspec documents the shape (upstream PR #900).- New specs:
::command-definition,::commands,::session-capabilities,::elicitation-params,::elicitation-result,::input-options. - Function specs and instrumentation for
capabilities,elicitation-supported?,confirm!,select!,input!. - Integration tests for command wire format, command.execute routing, unknown command errors, handler errors, capabilities storage, and elicitation guards.
ui-elicitation!no longer marked^:experimental— now asserts elicitation support before calling. Updated fdef to use::elicitation-paramsspec.- Mock server
handle-requestnow supportssession.commands.handlePendingCommandRPC and allows request hooks to merge additional data into responses.
0.2.0.0 - 2026-03-23
- System message customize mode — new
:customizemode for:system-messageenables section-level overrides of the Copilot system prompt. Ten configurable sections::identity,:tone,:tool-efficiency,:environment-context,:code-change-rules,:guidelines,:safety,:tool-instructions,:custom-instructions,:last-instructions. Each section supports static actions (:replace,:remove,:append,:prepend) and transform callbacks (1-arity functions receiving current content, returning modified text). Newsystem-prompt-sectionsconstant exported from main namespace (upstream PR #816). - New experimental RPC methods — thin wrapper functions in
sessionnamespace for emerging CLI APIs (upstream PR #900):- Skills:
skills-list,skills-enable!,skills-disable!,skills-reload! - MCP servers:
mcp-list,mcp-enable!,mcp-disable!,mcp-reload! - Extensions:
extensions-list,extensions-enable!,extensions-disable!,extensions-reload! - Plugins:
plugins-list - Compaction:
compaction-compact! - Shell:
shell-exec!,shell-kill! - UI:
ui-elicitation!
- Skills:
- 15 new event types added to the event type enum:
command.completed,command.execute,command.queued,commands.changed,exit_plan_mode.requested,exit_plan_mode.completed,external_tool.completed,mcp.oauth_required,mcp.oauth_completed,session.tools_updated,session.background_tasks_changed,session.skills_loaded,session.mcp_servers_loaded,session.mcp_server_status_changed,session.extensions_loaded. - Experimental API annotations (
^:experimentalmetadata) on all new RPC method wrappers. - Function specs (
s/fdef) and instrumentation for all new RPC methods.
- Version bump to
0.2.0.0-SNAPSHOTtracking upstream copilot-sdk v0.2.0. - Updated
interaction-eventsset to include new event types (commands, MCP OAuth, exit plan mode).
0.1.33.0-SNAPSHOT - 2026-03-19
:no-resultpermission outcome — extensions can attach to sessions without actively answering permission requests by returning{:kind :no-result}from their:on-permission-requesthandler. On v3 protocol, thehandlePendingPermissionRequestRPC is skipped; on v2, an error is propagated to the CLI (upstream PR #802).:blobattachment type for outbound messages — send inline base64-encoded data (e.g. images) via{:type :blob :data "..." :mime-type "image/png"}in:attachments. Previously blob attachments were only supported in inbound events (upstream PR #731).
:skip-permission?option on tool definitions — whentrue, the tool executes without triggering a permission prompt. Sent asskipPermission: truein the wire protocol (upstream PR #808).- OpenTelemetry support: new
:telemetryclient option (map with:otlp-endpoint,:file-path,:exporter-type,:source-name,:capture-content?) configures OTel environment variables on the spawned CLI process. New:on-get-trace-contextclient option (0-arity fn returning{:traceparent ... :tracestate ...}) enables W3C Trace Context propagation intosession.create,session.resume, andsession.sendRPCs (upstream PR #785). - Tool invocations now receive
:traceparentand:tracestatefields in the invocation context map when the CLI provides them (upstream PR #785). - Optional
:reasoning-effortparameter inswitch-model!andset-model!— pass{:reasoning-effort "high"}as a third argument to set reasoning effort when switching models (upstream PR #712). - New event data fields from upstream codegen update (upstream PR #796):
session.startevent::reasoning-effort,:already-in-use?,:host-type,:head-commit,:base-commitoptional fieldssession.resumeevent: new::session.resume-dataspec with:event-count,:selected-model,:reasoning-effort,:already-in-use?,:host-type,:head-commit,:base-commitsession.model_changeevent: new::session.model_change-dataspec with:new-model,:previous-model,:reasoning-effort,:previous-reasoning-effortuser.messageevent: new:blobattachment type with:data(base64),:mime-type, optional:display-name
join-sessionnow makes:on-permission-requestoptional. When omitted, a default handler returns{:kind :no-result}, leaving any pending permission request unanswered. This matches the upstreamJoinSessionConfigwhereonPermissionRequestis optional (upstream PR #802).:auto-restart?client option is deprecated and has no effect. The auto-restart/reconnect behavior has been removed across all official SDKs. The option is retained for backward compatibility but will be removed in a future release (upstream PR #803).
- "Permission Handling" section in README.md — covers deny-by-default model,
approve-all, custom handlers, and links to API reference (upstream PR #879).
0.1.32.0 - 2026-03-12
- Session pre-registration: sessions are now created and registered in client state before the RPC call, preventing early events (e.g.
session.start) from being dropped. Session IDs are generated client-side viajava.util.UUID/randomUUIDwhen not explicitly provided. On RPC failure, sessions are automatically cleaned up (upstream PR #664). :on-eventoptional handler increate-sessionandresume-sessionconfigs — a 1-arity function receiving event maps, registered before the RPC call so no events are missed. Equivalent to callingsubscribe-eventsimmediately after creation, but executes earlier in the lifecycle (upstream PR #664).join-sessionfunction — convenience for extensions running as child processes of the Copilot CLI. ReadsSESSION_IDfrom environment, creates a child-process client, and resumes the session with:disable-resume? true. Returns{:client ... :session ...}(upstream PR #737).:copilot/system.notificationevent type — structured notification events with:kinddiscriminator (agent_completed,shell_completed,shell_detached_completed) (upstream PR #737).
CopilotSessionrecord no longer includesworkspace-pathas a field. Use(workspace-path session)accessor which reads from mutable session state. This enables the pre-registration flow where workspace-path is set after the RPC response.
0.1.32.0 - 2026-03-10
:agentoptional string parameter increate-sessionandresume-sessionconfigs — pre-selects a custom agent by name when the session starts. Must match a name in:custom-agents. Equivalent to callingagent.selectafter creation (upstream PR #722).:on-list-modelsoptional handler in client options — zero-arg function returning model info maps. Bypasses themodels.listRPC call and does not requirestart!. Results use the same promise-based cache (upstream PR #730).log!session method — logs a message to the session timeline via"session.log"RPC. Accepts optional:level("info","warning","error") and:ephemeral?(transient, not persisted) options. Returns the event ID string (upstream PR #737).:is-child-process?client option — whentrue, the SDK connects via its own stdio to a parent Copilot CLI process instead of spawning a new one. Mutually exclusive with:cli-url; requires:use-stdio?to betrue(or unset) (upstream PR #737).
0.1.30.1 - 2026-03-07
disconnect!function as the preferred API for closing sessions, matching upstream SDK'sdisconnect()(upstream PR #599).destroy!is deprecated but still works as an alias.- 6 new broadcast event types from CLI protocol 0.0.421 (upstream PR #684):
:copilot/permission.requested,:copilot/permission.completed,:copilot/user_input.requested,:copilot/user_input.completed,:copilot/elicitation.requested,:copilot/elicitation.completed - New
interaction-eventscategory set for permission, user input, and elicitation flow events :memorypermission kind added to::permission-kindspec (upstream PR #684)- Protocol v3 support with backwards compatibility (supports v2 and v3). The SDK negotiates the protocol version with the CLI server at startup using a supported range
[2, 3]. Version 3 replacestool.callandpermission.requestRPC callbacks with broadcast events (external_tool.requested,permission.requested) and new RPC response methods (session.tools.handlePendingToolCall,session.permissions.handlePendingPermissionRequest). - Custom agents & sub-agent orchestration guide (
doc/guides/custom-agents.md)
stop!now usesdisconnect!internally instead ofdestroy!delete-session!docstring clarified to contrast withdisconnect!- Version negotiation now validates the CLI-reported protocol version is within the supported range
[2, 3]instead of requiring exact match on version 2
destroy!— usedisconnect!instead.destroy!delegates todisconnect!and will be removed in a future release.
0.1.30.0 - 2026-03-04
- Support overriding built-in tools via
:overrides-built-in-tooloption indefine-tool(upstream PR #636). Tools with this flag set totruecan override built-in tools likegreporedit_file. Without the flag, name clashes cause an error. set-model!function as alias forswitch-model!, matching the upstream SDK'ssetModel()API (upstream PR #621).
- Updated
switch-model!andget-current-modeldocstrings — removed stale "not yet implemented as of CLI 0.0.412" notes. These RPC methods are now supported.
0.1.29.0 - 2026-03-03
:copilot/subagent.deselectedevent type added to::event-typespec,event-typesvar, and API reference table (upstream PR #605 / CLI 0.0.420).:github-referenceattachment type: represents a GitHub issue, PR, or discussion attached to a user message. Added to::attachment-typespec and::attachmentspec. Data fields:number,title,reference-type("issue"/"pr"/"discussion"),state,url(upstream PR #605).::assistant.turn_start-dataspec withturn-id(required) andinteraction-id(optional).:interaction-idoptional field added to::user.message-data,::assistant.turn_start-data,::assistant.message_delta-data, and::tool.execution_complete-dataspecs (upstream PR #605).:modeloptional field added to::tool.execution_complete-dataspec — model used for the tool execution (upstream PR #605).:plugin-nameand:plugin-versionoptional fields added to::skill.invoked-dataspec (upstream PR #605).
- Azure Managed Identity BYOK guide (
doc/auth/azure-managed-identity.md): shows how to useDefaultAzureCredentialwith short-lived bearer tokens for Azure AI Foundry, with Clojure examples for basic usage and token refresh (upstream PR #498). - Updated BYOK limitations to link to the Managed Identity workaround instead of listing it as fully unsupported.
- Added Azure Managed Identity guide to
doc/auth/index.mdanddoc/index.md.
examples/file_attachments.clj— Demonstrates sending file attachments with prompts using:attachmentsin message options.examples/session_resume.clj— Demonstrates session resume: create session, send secret word, resume by ID, verify context preserved.examples/infinite_sessions.clj— Demonstrates infinite sessions with context compaction thresholds for long conversations.examples/lifecycle_hooks.clj— Demonstrates all 6 lifecycle hooks: session start/end, pre/post tool use, user prompt submitted, error occurred.examples/reasoning_effort.clj— Demonstrates the:reasoning-effortsession config option.
0.1.28.0 - 2026-02-27
- BREAKING:
:on-permission-requestis now required when callingcreate-session,resume-session,<create-session, and<resume-session. Calls without a handler throwExceptionInfowith a descriptive message. This matches upstream Node.js SDK whereonPermissionRequestis required inSessionConfigandResumeSessionConfig(upstream PR #554). create-sessionand<create-sessionno longer accept a 0-arity (no config) form — a config map with:on-permission-requestmust always be provided.resume-sessionand<resume-sessionno longer accept a 2-arity (no config) form — a config map with:on-permission-requestmust always be provided.- All examples, tests, and documentation updated to always pass
:on-permission-request.
:custom-toolpermission kind —::permission-kindspec now includes:custom-tool, matching the upstreamPermissionRequest.kindunion type. Permission handlers will receive{:permission-kind :custom-tool ...}for SDK-registered custom tool invocations (upstream PR #555).
:copilot/session.task_completeevent type added to::event-typespec andevent-typesvar. Previously it was in the spec but missing from the publicevent-typesset (upstream PR #544).:copilot/assistant.streaming_deltanew event type: emitted when the total response size changes during streaming. Data:{:total-response-size-bytes N}. Added to::event-typespec,event-typesvar, andassistant-eventsvar (upstream PR #544).:copilot/session.mode_changedevent type: emitted when the session agent mode changes. Data:{:previous-mode "...", :new-mode "..."}. Added to::event-typespec,event-typesvar, andsession-eventsvar.:copilot/session.plan_changedevent type: emitted when the session plan changes. Data:{:operation "create"|"update"|"delete"}. Added to::event-typespec,event-typesvar, andsession-eventsvar.:copilot/session.workspace_file_changedevent type: emitted when a workspace file is created or updated. Data:{:path "...", :operation "create"|"update"}. Added to::event-typespec,event-typesvar, andsession-eventsvar.- Data specs for new events:
::session.mode_changed-data,::session.plan_changed-data,::session.workspace_file_changed-data,::session.task_complete-data,::assistant.streaming_delta-data.
::assistant.message_delta-dataspec: removed::total-response-size-bytesfrom optional keys. The response size is now delivered via the separateassistant.streaming_deltaevent (upstream PR #544).
- Microsoft Foundry Local BYOK provider guide in
doc/auth/byok.md: quick start example, installation instructions, and connection troubleshooting (upstream PR #461). doc/reference/API.md: added:copilot/session.task_completeto the Event Reference table (from upstream PR #544 sync).doc/reference/API.md: added permission kind reference table (:shell,:write,:mcp,:read,:url,:custom-tool) in the Permission Handling section.
- Windows console window hiding: CLI process is spawned with explicit PIPE redirects ensuring the JVM sets
CREATE_NO_WINDOWon Windows — no console window appears in GUI applications. Equivalent to upstreamwindowsHide: true(upstream PR #329).
- Recommended default model for non-streaming examples is
claude-haiku-4.5instead ofgpt-5.2for faster response times
0.1.26.0-SNAPSHOT - 2026-02-20
:client-nameoption forcreate-sessionandresume-session— identifies the application using the SDK, included in the User-Agent header for API requests. Forwarded asclientNameon the wire (upstream PR #510).
- BREAKING: Deny all permissions by default —
requestPermissionis now alwaystrueon the wire, and permission requests are denied when no:on-permission-requesthandler is configured. Previously, omitting the handler meant the CLI never asked for permission. To restore the old behavior, pass:on-permission-request copilot/approve-allin your session config.
approve-all— convenience permission handler that approves all requests (copilot/approve-all). Equivalent to the upstream Node.js SDKapproveAllexport. Use as:on-permission-request copilot/approve-allin session config.- Integration tests for deny-by-default permission model: wire format assertions,
approve-allbehavior, handler dispatch with/without handler, custom selective handler
- MCP local server example now passes
:on-permission-request copilot/approve-all(required for MCP tool execution under deny-by-default)
- Permission denial result
:kindnow consistently uses keywords (not strings) in default handler responses, matching specs andapprove-allbehavior
0.1.25.1 - 2026-02-18
- Release pipeline: GPG signing now fails fast with a clear error when no key is available, instead of silently producing unsigned artifacts that Maven Central rejects
- Release pipeline:
stamp-changelogno longer throws when[Unreleased]is empty — prints a warning and exits cleanly
- Metadata API example: suppressed SDK INFO log noise, improved session display (short IDs, summaries, timestamps), clearer messaging for unsupported CLI methods
0.1.25.0 - 2026-02-18
- Core.async native async architecture — eliminates all blocking operations from the async API path:
<create-session/<resume-session— async session lifecycle functions that return channels deliveringCopilotSession, safe for use insidegoblocks- Protocol layer now uses core.async channels instead of Java promises for RPC responses
- Session send-lock replaced
java.util.concurrent.Semaphorewith a channel-based lock <send-async*— fully non-blocking send pipeline using parking channel operations- The idiomatic pattern is now
(go (let [s (<! (<create-session client opts))] (<! (<send! s {:prompt "..."}))))— no thread pool starvation
- Wire parity: always send
requestPermission,requestUserInput, andhooksfields (asfalsewhen not configured) to match upstream Node.js SDK — fixes 400 errors when creating sessions without specifying a model - MCP server environment variables now passed correctly as literal values to subprocesses — sends
envValueMode: "direct"on session create/resume wire payloads (upstream PR #484) - Fix potential semaphore deadlock in
send-and-wait!andsend-async*—tapon a closed mult could leave the send-lock permanently held; movedtapinside thetry/finallyblock that releases the lock - Multi-agent example parallelism: sessions and sends now run concurrently in
goblocks instead of sequentially blocking
- CLI stderr is now captured and forwarded to debug logging; included in error messages on startup failure for better diagnostics (inspired by upstream PR #492)
verify-protocol-version!now races the initial ping against process exit to detect early CLI failures instead of blocking for 60 seconds on timeoutlist-sessionsnow accepts optional filter map{:cwd :git-root :repository :branch}to narrow results by session context (upstream PR #427)- Session metadata from
list-sessionsnow includes:contextmap with working directory info ({:cwd :git-root :repository :branch}) when available (upstream PR #427) list-tools— list available tools with metadata; accepts optional model param for model-specific overrides (upstream PR #464)get-quota— get account quota information (entitlements, usage, overage) (upstream PR #464)get-current-model— get the current model for a session (session-scoped) (upstream PR #464)switch-model!— switch the model for a session (session-scoped) (upstream PR #464)- New event types:
session.context_changed,session.title_changed,session.warning(upstream PRs #396, #427) line-rangeoptional field on file/directory attachment specs (upstream session-events schema update)agent-modeoptional field onuser.messageevent data — one of:interactive,:plan,:autopilot,:shell(upstream session-events schema update)
- BREAKING: Namespace prefix renamed from
krukow.copilot-sdktogithub.copilot-sdk. All requires must be updated (e.g.,github.copilot-sdk.client,github.copilot-sdk.helpers). - Repository moved to
copilot-community-sdk/copilot-sdk-clojureon GitHub. Maven artifact unchanged:io.github.copilot-community-sdk/copilot-sdk-clojure. - Git dependency URL in README fixed to point to new org
- Selection attachment type support (
:selectionwith:file-path,:display-name,:selection-range,:text) - Session lifecycle event subscription via
on-lifecycle-event(:session.created,:session.deleted,:session.updated,:session.foreground,:session.background) - Enhanced model info with full capabilities (
:model-capabilities), billing (:model-billing), and policy (:model-policy) structures session.shutdownandskill.invokedevent types"xhigh"reasoning effort level
- GitHub Actions CI workflow: runs
bb ci(unit/integration tests, doc validation, jar build) on PRs andmainpushes - Daily documentation updater agentic workflow: automatically scans for merged PRs and updates docs
.github/instructions/documentation.instructions.md: guidelines for AI agents updating documentation- GitHub Actions Release workflow: manual dispatch with version management inputs (
sync-upstream,bump-clj-patch,set-version), GPG signing, Maven Central deploy, and SLSA build provenance attestation bb citask: runs tests, doc validation, and jar build (no copilot CLI required)bb ci:fulltask: full pipeline including E2E tests and examples (requires copilot CLI)- Cross-platform
build.clj:md5-hashandsha1-hashhelpers with macOS/Linux fallback - Idempotent
update-readme-sha: succeeds when README already has current SHA stamp-changelogbuild task: automatically moves[Unreleased]entries to a versioned section with today's date and updates comparison links; integrated into the release workflow
- Release workflow now creates a PR with auto-merge instead of pushing directly to
main, compatible with branch protection rules requiring PRs and status checks - Release workflow creates a
vX.Y.Z.Ntag after successful deploy
doc/index.md— Documentation hub / table of contentsdoc/style.md— Documentation authoring style guidedoc/reference/API.md— API reference (moved fromdoc/API.md)PUBLISHING.md— Maven Central publishing guidescript/validate_docs.clj— Documentation validation script (bb validate-docs).github/skills/update-docs/SKILL.md— Update-docs skill for regenerating docs after source changes
- BREAKING: Version scheme changed to 4-segment format
UPSTREAM.CLJ_PATCH(e.g.,0.1.22.0) to track upstream copilot-sdk releases. See PUBLISHING.md for details. - New build tasks:
sync-version(align to upstream),bump-version(increment clj-patch) - Replaced
cheshire/cheshire(Clojars) withorg.clojure/data.json(Maven Central) for JSON processing — eliminates Clojars and Jackson transitive dependencies - Deprecated Clojars publishing (
net.clojars.krukow/copilot-sdk). Use Maven Central (io.github.copilot-community-sdk/copilot-sdk-clojure) going forward.
- Java API (
java_api.clj), Java examples, and AOT compilation. For Java/JVM usage, see copilot-sdk-java. doc/intro.mdanddoc/java-async-api.md(replaced by reorganized documentation)
- Resume session config parity with create-session (upstream PR #376):
resume-sessionnow accepts:model,:system-message,:available-tools,:excluded-tools,:config-dir, and:infinite-sessionsoptions
- API parity with official Node.js SDK (
@github/copilot-sdk)::working-directoryoption forcreate-sessionandresume-session:disable-resume?option forresume-sessionget-foreground-session-idandset-foreground-session-id!client methods (TUI+server mode):large-outputmarked as experimental (CLI protocol feature, not in official SDK)
- New metadata APIs (upstream PR #77):
get-status- Get CLI version and protocol informationget-auth-status- Get current authentication statuslist-models- List available models with metadata
- New event type
:copilot/tool.execution_progressfor progress updates during long-running tool executions - Infinite sessions support (upstream PR #76):
:infinite-sessionsconfig option forcreate-session- Automatic context compaction when approaching context window limits
- New event types:
:copilot/session.compaction_start,:copilot/session.compaction_complete
- Session workspace path accessors for Clojure and Java APIs
- New event type
:copilot/session.snapshot_rewindfor session state rollback (upstream PR #208) - Exported event type constants:
event-types- All valid event typessession-events- Session lifecycle and state eventsassistant-events- Assistant response eventstool-events- Tool execution events
- New example:
session_events.clj- demonstrates monitoring session state events - Authentication options for client (upstream PR #237):
:github-token- GitHub token for authentication (setsCOPILOT_SDK_AUTH_TOKENenv var):use-logged-in-user?- Whether to use logged-in user auth (default: true, false when token provided)
- Hooks and user input handlers (upstream PR #269):
:on-user-input-request- Handler forask_usertool invocations:hooks- Lifecycle hooks map with callbacks::on-pre-tool-use- Called before tool execution:on-post-tool-use- Called after tool execution:on-user-prompt-submitted- Called when user sends a prompt:on-session-start- Called when session starts:on-session-end- Called when session ends:on-error-occurred- Called on errors
- Reasoning effort support (upstream PR #302):
:reasoning-effortsession config option ("low", "medium", "high", "xhigh")- Model info now includes
:supports-reasoning-effort,:supported-reasoning-efforts,:default-reasoning-effort
- Documentation:
doc/getting-started.md— Comprehensive tutorialdoc/auth/index.md— Authentication guide (all methods, priority order)doc/auth/byok.md— BYOK (Bring Your Own Key) guide with examples for OpenAI, Azure, Anthropic, Ollamadoc/mcp/overview.md— MCP server configuration guidedoc/mcp/debugging.md— MCP debugging and troubleshooting guide
- New examples:
examples/byok_provider.clj— BYOK provider configurationexamples/mcp_local_server.clj— MCP local server integration
- BYOK validation:
create-sessionandresume-sessionnow throw when:provideris specified without:model
- BREAKING: Event types are now namespaced keywords (e.g.,
:copilot/session.idleinstead of:session.idle)- Migration: Add
copilot/prefix to all event type keywords in your code
- Migration: Add
- FIX: MCP server config wire format now correctly strips
:mcp-prefix before sending to CLI. Previously:mcp-command,:mcp-args,:mcp-tools, etc. were sent asmcpCommand,mcpArgs,mcpToolson the wire; they are now correctly sent ascommand,args,toolsto match the upstream Node.js SDK. The Clojure API keys (:mcp-command,:mcp-args, etc.) are unchanged. - Protocol version bumped from 1 to 2 (requires CLI 0.0.389+)
- Removed
helpers/query-seqin favor ofhelpers/query-seq!andhelpers/query-chan list-modelsnow caches results per client connection to prevent 429 rate limiting under concurrency (upstream PR #300)- Cache is cleared on
stop!andforce-stop!
- Cache is cleared on
0.1.0 - 2026-01-18
- Initial release of copilot-sdk-clojure
- Full port of JavaScript Copilot SDK to idiomatic Clojure
- JSON-RPC protocol layer with Content-Length framing
- CopilotClient for managing CLI server lifecycle
- stdio and TCP transport support
- Auto-start and auto-restart capabilities
- CopilotSession for conversation management
send!,send-and-wait!,send-asyncmessage methods- Event handling via core.async mult channels
- Tool registration and invocation
- Permission request handling
- Tool definition helpers with result builders
- System message configuration (append/replace modes)
- MCP server configuration support
- Custom agent configuration support
- Provider configuration (BYOK - Bring Your Own Key)
- Streaming support for assistant messages
- Comprehensive clojure.spec definitions
- Example applications:
- Basic Q&A conversation
- Custom tool integration
- Multi-agent orchestration with core.async
- org.clojure/clojure 1.12.4
- org.clojure/core.async 1.6.681
- org.clojure/spec.alpha 0.5.238
- cheshire/cheshire 5.13.0