Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .copilot-schema-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.57
1.0.61
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,51 @@ All notable changes to this project will be documented in this file. This change

## [Unreleased]

### Added (v1.0.1 sync)
- **`open-canvases` snapshot** — port of upstream PR #1604. A new
`github.copilot-sdk/open-canvases` (also `github.copilot-sdk.session/open-canvases`)
returns the per-session vector of currently-open canvases. The snapshot is
initialized from the `session.resume` response (`session.create` does NOT
populate it, matching upstream Node.js client) and updated by the
`:copilot/session.canvas.opened` and `:copilot/session.canvas.closed`
events. Missing/blank `:instance-id` payloads log a warning and no-op.
- **`:copilot/session.canvas.closed` event type** — newly added in upstream
PR #1604. Fires when a canvas is closed; the SDK removes the matching
entry from the open-canvases snapshot before publishing the event so
observers see consistent state.
- **New optional event-data fields** (upstream schema 1.0.57 → 1.0.61):
- `:copilot/session.resume` and `:copilot/session.shutdown`:
`:events-file-size-bytes` (`nat-int?`).
- `:copilot/assistant.message`: `:api-call-id`.
- `:copilot/hook.progress`: `:temporary` (`boolean?`).
- `:copilot/session.schedule_created`: `:at`, `:cron`, `:tz` (with
`:interval-ms` relaxed to optional — schedules can now use
cron / fixed-time variants instead of intervals).

### Changed (v1.0.1 sync)
- Bumped pinned `@github/copilot` schema 1.0.57 → 1.0.61, regenerating
`generated/event_specs.clj` and `generated/coerce.clj`.

### Added (v1.0.1 sync follow-up)
- **`:open-canvases` accepted in `resume-session` / `join-session` config**
(upstream `ResumeSessionConfig.openCanvases`). Lets callers seed the
open-canvases snapshot when reconnecting to a session.

### Changed (v1.0.1 sync follow-up)
- **Strict validation on `session.canvas.opened` upserts** — payloads missing
any of `:instance-id`, `:extension-id`, `:canvas-id`, `:reopen` (boolean),
or `:availability` (`"ready"` / `"stale"`) are now no-ops with a warn log,
matching upstream `isOpenCanvasInstance`.
- **`:input` map keys preserved verbatim** on `session.canvas.opened` events,
on `openCanvases` returned by `session.resume`, and when sent outbound via
the `:open-canvases` resume config. Caller-defined opaque keys (e.g.
`:user_id`, nested or non-camelCase) are NOT re-cased by wire conversion.

### Fixed (v1.0.1 sync follow-up)
- `:github.copilot-sdk.specs/at` now requires `pos-int?` (was lax `number?`).
`at` represents an epoch-ms timestamp, so non-integer or non-positive
values are invalid by construction.

## [1.0.0.0] - 2026-06-04
### Highlights
First generally available (GA) release, at full API/wire/schema parity with
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Add to your `deps.edn`:

```clojure
;; From Maven Central
io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.0.0"}
io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.0"}

;; Or git dependency
io.github.copilot-community-sdk/copilot-sdk-clojure {:git/url "https://github.com/copilot-community-sdk/copilot-sdk-clojure.git"
Expand Down
2 changes: 1 addition & 1 deletion build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
(:import [java.io File]))

(def lib 'io.github.copilot-community-sdk/copilot-sdk-clojure)
(def version "1.0.0.0")
(def version "1.0.1.0")
(def class-dir "target/classes")

(defn- try-sh
Expand Down
2 changes: 1 addition & 1 deletion doc/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ copilot --version
Add to your `deps.edn`:

```clojure
{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.0.0"}}}
{:deps {io.github.copilot-community-sdk/copilot-sdk-clojure {:mvn/version "1.0.1.0"}}}
```

Or use as a Git dependency:
Expand Down
46 changes: 46 additions & 0 deletions doc/reference/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ Create a client and session together, ensuring both are cleaned up on exit.
| `:custom-agents-local-only` | boolean | Restrict custom-agent loading to caller-supplied configs only (no on-disk discovery). Forwarded via `session.options.update`. Defaulted to `true` in `:empty` mode. (upstream PR #1428) |
| `:coauthor-enabled` | boolean | Add a Copilot Co-authored-by trailer to commits made by the CLI. Forwarded via `session.options.update`. Defaulted to `false` in `:empty` mode. (upstream PR #1428) |
| `:manage-schedule-enabled` | boolean | Enable the built-in schedule-management tools. Forwarded via `session.options.update`. Defaulted to `false` in `:empty` mode. (upstream PR #1428) |
| `:open-canvases` | vector | (resume-session / join-session only) Seed the open-canvases snapshot when reconnecting. Each entry: `{:instance-id ... :extension-id ... :canvas-id ... :reopen bool :availability "ready"\|"stale" :extension-name? ... :title? ... :status? ... :url? ... :input? {...}}`. Caller-defined `:input` keys are preserved verbatim through wire conversion (no kebab→camel re-casing). See [`open-canvases`](#open-canvases). (upstream PR #1604) |

#### `resume-session`

Expand Down Expand Up @@ -1276,6 +1277,48 @@ Request structured user input via interactive dialogs. Check host support before

Get the host capabilities map reported when the session was created or resumed.

### `open-canvases`

```clojure
(copilot/open-canvases session)
;; => [{:instance-id "i1" :canvas-id "diff" :extension-id "ext.x"
;; :reopen false :availability "ready"}]
```

Get the current open-canvases snapshot for `session`. Returns a vector of
canvas-instance maps. The snapshot is initialized from `session.resume` and
updated by `:copilot/session.canvas.opened` / `:copilot/session.canvas.closed`
events. `session.create` does NOT populate it (matches upstream Node.js).

Each entry has required keys `:instance-id`, `:extension-id`, `:canvas-id`,
`:reopen`, `:availability` and optional `:extension-name`, `:title`,
`:status`, `:url`, `:input`. Closing an instance that's not in the snapshot is a
silent no-op (idempotent); malformed payloads (missing required field, wrong
type, or invalid `:availability`) log a warning and leave the snapshot
unchanged — matches upstream `isOpenCanvasInstance` strictness.

The `:input` map (caller-defined opaque data on each canvas) is preserved
verbatim through wire conversion. Keys you receive (e.g. via the canvas
opened event or after a resume) round-trip back to the CLI without
camelCasing — including `snake_case` and nested keys.

#### Seeding `open-canvases` on resume

To restore canvases after reconnecting, pass `:open-canvases` to
[`resume-session`](#resume-session) or [`join-session`](#join-session). The
shape mirrors what `(open-canvases session)` returned previously:

```clojure
(let [snap (copilot/open-canvases old-session)]
(copilot/resume-session client session-id
{:on-permission-request copilot/approve-all
:open-canvases snap}))
```

The SDK preserves caller-defined `:input` keys verbatim on the wire (they are
sent as JSON object fields with the original key names, unchanged by Clojure's
kebab-case conversion).

### `elicitation-supported?`

```clojure
Expand Down Expand Up @@ -1488,6 +1531,9 @@ Convert an unqualified event keyword to a namespace-qualified `:copilot/` keywor
| `:copilot/session.remote_steerable_changed` | Session remote steering capability changed; data: `{:remote-steerable true/false}` |
| `:copilot/capabilities.changed` | Session capabilities dynamically changed (e.g., elicitation support); ephemeral. Data: `{:ui {:elicitation true/false}}` |
| `:copilot/mcp_app.tool_call_complete` | An MCP App tool call completed (upstream schema 1.0.52-4, SEP-1865); ephemeral. Data: `{:server-name ... :tool-name ... :duration-ms ... :success bool :arguments {...} :result {...}}` — `:arguments` and `:result` are opaque source-defined maps whose keys are preserved verbatim (not kebab-cased). |
| `:copilot/session.canvas.opened` | A canvas (auxiliary UI surface) was opened in the session; ephemeral. Data: `{:instance-id ... :canvas-id ... :extension-id ... :reopen bool :availability "ready"|"stale" :extension-name? ... :title? ... :status? ... :url? ... :input? {...}}`. The SDK upserts the entry into the [`open-canvases`](#open-canvases) snapshot before publishing. |
| `:copilot/session.canvas.closed` | A canvas was closed; ephemeral. Data: `{:instance-id ... :canvas-id ... :extension-id ...}`. The SDK removes the matching entry from the [`open-canvases`](#open-canvases) snapshot before publishing. (upstream PR #1604) |
| `:copilot/session.canvas.registry_changed` | The set of canvases the host can offer changed; ephemeral. |

### Example: Handling Events

Expand Down
2 changes: 1 addition & 1 deletion schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ These files are fetched verbatim from the `@github/copilot` npm package at the v

**Do not edit by hand.** To update, run `bb schemas:fetch` after bumping `.copilot-schema-version`.

Currently pinned version: `1.0.57`
Currently pinned version: `1.0.61`
Loading
Loading