diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0e707e5..cf28b7a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -174,11 +174,14 @@ This project emphasizes **rigor and correctness**, particularly for: ## Project Structure ``` +src/github/copilot_sdk.clj # Top-level public API namespace (github.copilot-sdk): + # re-exports + curated public `event-types` / `session-events` sets src/github/copilot_sdk/ ├── client.clj # Main client API (create-client, create-session, etc.) ├── session.clj # Session operations (send!, send-and-wait!, etc.) ├── helpers.clj # Convenience functions (query, query-seq!, query-chan, etc.) ├── tools.clj # Helper functions for defining tools (define-tool, result-success, etc.) +├── tool_set.clj # Source-qualified tool filter patterns (:available-tools/:excluded-tools) ├── specs.clj # clojure.spec definitions for all data shapes ├── instrument.clj # Function specs (fdefs) and instrumentation ├── util.clj # Wire conversion (camelCase ↔ kebab-case), MCP helpers diff --git a/.github/skills/update-upstream/SKILL.md b/.github/skills/update-upstream/SKILL.md index e1eeec5..d540d68 100644 --- a/.github/skills/update-upstream/SKILL.md +++ b/.github/skills/update-upstream/SKILL.md @@ -172,4 +172,6 @@ Real recurring traps when porting upstream changes: 4. **Test fixtures: match the shape the layer actually produces.** Mock server responses use wire shape; client-side assertions use idiomatic shape. Production conversion (`util/wire->clj`) only transforms keyword keys — string-keyed fixtures silently bypass it and produce tests that pass for the wrong reason. +5. **Outbound optional fields: match upstream's omit-vs-null behavior per RPC.** Don't reflexively gate an optional wire field on `contains?` and emit JSON `null`. Some patch RPCs (e.g. `session.options.update`) genuinely accept `null` to clear a value; others (e.g. `session.model.switchTo`) have no null variant in the schema — upstream spreads `...options`, dropping `undefined`. Check the upstream call site and the request schema: if the field has no null union, compute the wire value first and gate on `(some? v)` so a `nil` option omits the key instead of sending `null`. + For the mechanics of camelCase ↔ kebab-case conversion (including the `?`-suffix rule), see the cheat sheet in `references/PROJECT.md`. diff --git a/.github/skills/update-upstream/references/PROJECT.md b/.github/skills/update-upstream/references/PROJECT.md index b208fd2..7593057 100644 --- a/.github/skills/update-upstream/references/PROJECT.md +++ b/.github/skills/update-upstream/references/PROJECT.md @@ -18,6 +18,7 @@ When syncing, map upstream changes to the corresponding Clojure files: | `nodejs/src/index.ts` | Public exports (defines the public API surface) | | `nodejs/src/generated/session-events.ts` | All event types and data shapes | | `nodejs/src/generated/rpc.ts` | RPC method signatures | +| `nodejs/src/toolSet.ts` | `ToolSet` / `BuiltInTools` tool-filter helpers | ### Clojure Counterparts @@ -26,9 +27,11 @@ When syncing, map upstream changes to the corresponding Clojure files: | Types / config | `specs.clj` | Session config, event data, permissions, tools | | Client methods | `client.clj` | Broadcast handlers, create-client, create-session | | Session methods | `session.clj` | send/receive, UI convenience methods | -| Event types | `client.clj` | `event-types` set, `subscribe-events!` | +| Curated public event sets | `copilot_sdk.clj` | Top-level `github.copilot-sdk` ns: hand-curated public `event-types` / `session-events` sets | +| Generated event specs | `generated/event_specs.clj` | AUTO-GENERATED full `event-types` set + wire specs (`bb codegen`) | | RPC methods | `protocol.clj` | JSON-RPC protocol layer | -| Public exports | `client.clj`, `helpers.clj`, `tools.clj` | Public API surface | +| Tool-filter helpers | `tool_set.clj` | Source-qualified `:available-tools` / `:excluded-tools` patterns | +| Public exports | `copilot_sdk.clj`, `client.clj`, `helpers.clj`, `tools.clj` | Public API surface | | Function specs | `instrument.clj` | fdefs for all public functions | ## Wire Conversion Cheat Sheet