diff --git a/CHANGELOG.md b/CHANGELOG.md index 05a7a37..8752f52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/). ## [Unreleased] +### Added (v0.1.32 sync) +- `:skip-permission?` option on tool definitions — when `true`, the tool executes without triggering a permission prompt. Sent as `skipPermission: true` in the wire protocol (upstream PR #808). + +### Changed (v0.1.32 sync) +- `join-session` now makes `:on-permission-request` **optional**. When omitted, a default handler returns `{:kind :no-result}`, leaving any pending permission request unanswered. This matches the upstream `JoinSessionConfig` where `onPermissionRequest` is optional (upstream PR #802). +- `:auto-restart?` client option is **deprecated** and has no effect. The auto-restart 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). + ### Added - `:no-result` permission outcome — extensions can attach to sessions without actively answering permission requests by returning `{:kind :no-result}` from their `:on-permission-request` handler. On v3 protocol, the `handlePendingPermissionRequest` RPC is skipped; on v2, an error is propagated to the CLI (upstream PR #802). diff --git a/src/github/copilot_sdk/client.clj b/src/github/copilot_sdk/client.clj index 2bf0aec..a72f717 100644 --- a/src/github/copilot_sdk/client.clj +++ b/src/github/copilot_sdk/client.clj @@ -47,7 +47,7 @@ :use-stdio? true :log-level :info :auto-start? true - :auto-restart? true + :auto-restart? false :notification-queue-size 4096 :router-queue-size 4096 :tool-timeout-ms 120000 @@ -113,7 +113,7 @@ - :use-stdio? - Use stdio transport (default: true) - :log-level - :none :error :warning :info :debug :all - :auto-start? - Auto-start on first use (default: true) - - :auto-restart? - Auto-restart on crash (default: true) + - :auto-restart? - **DEPRECATED**: This option has no effect and will be removed in a future release. - :notification-queue-size - Max queued protocol notifications (default: 4096) - :router-queue-size - Max queued non-session notifications (default: 4096) - :tool-timeout-ms - Timeout for tool calls that return a channel (default: 120000) @@ -420,22 +420,9 @@ (recur))))))) (defn- maybe-reconnect! - "Attempt a stop/start cycle when auto-restart is enabled." - [client reason] - (let [state @(:state client)] - (when (and (:auto-restart? (:options client)) - (= :connected (:status state)) - (not (:stopping? state))) - (when (mark-restarting! client) - (log/warn "Auto-restart triggered:" reason) - (async/thread - (try - (stop! client) - (start! client) - (catch Exception e - (log/error "Auto-restart failed: " (ex-message e))) - (finally - (swap! (:state client) assoc :restarting? false)))))))) + "No-op: auto-restart is deprecated and has no effect." + [_client _reason] + nil) (defn- watch-process-exit! "Trigger auto-restart when the managed CLI process exits." @@ -683,8 +670,8 @@ Blocks until connected or throws on error. Thread safety: do not call start! and stop! concurrently from different - threads. The :stopping? and :restarting? flags guard against concurrent - auto-restart, but explicit concurrent calls are unsupported." + threads. The :stopping? flag guards against concurrent calls, but explicit + concurrent calls are unsupported." [client] (when-not (= :connected (:status @(:state client))) (log/info "Starting Copilot client...") @@ -1111,7 +1098,9 @@ :description (:tool-description t) :parameters (:tool-parameters t)} (some? (:overrides-built-in-tool t)) - (assoc :overridesBuiltInTool (:overrides-built-in-tool t)))) + (assoc :overridesBuiltInTool (:overrides-built-in-tool t)) + (:skip-permission? t) + (assoc :skipPermission true))) (:tools config))) wire-sys-msg (when-let [sm (:system-message config)] (cond @@ -1163,7 +1152,9 @@ :description (:tool-description t) :parameters (:tool-parameters t)} (some? (:overrides-built-in-tool t)) - (assoc :overridesBuiltInTool (:overrides-built-in-tool t)))) + (assoc :overridesBuiltInTool (:overrides-built-in-tool t)) + (:skip-permission? t) + (assoc :skipPermission true))) (:tools config))) wire-sys-msg (when-let [sm (:system-message config)] (cond @@ -1423,7 +1414,10 @@ Reads the SESSION_ID environment variable and connects to the parent CLI process via stdio. This is intended for extensions spawned by the Copilot CLI. - Config is the same as resume-session (`:on-permission-request` is **required**). + Config is the same as resume-session. `:on-permission-request` is **optional**; + when omitted, a default handler is used that returns `:no-result`, leaving any + pending permission request unanswered (appropriate for most extensions that use + `:skip-permission?` on their tools or do not require permission handling). The `:disable-resume?` option defaults to true. Returns a map with :client and :session keys. The caller is responsible for @@ -1438,6 +1432,8 @@ {}))) (let [c (client {:is-child-process? true}) merged-config (cond-> config + (not (contains? config :on-permission-request)) + (assoc :on-permission-request (constantly {:kind :no-result})) (not (contains? config :disable-resume?)) (assoc :disable-resume? true))] (try diff --git a/src/github/copilot_sdk/instrument.clj b/src/github/copilot_sdk/instrument.clj index fc0b84a..b976074 100644 --- a/src/github/copilot_sdk/instrument.clj +++ b/src/github/copilot_sdk/instrument.clj @@ -69,7 +69,7 @@ :ret ::specs/events-ch) (s/fdef github.copilot-sdk.client/join-session - :args (s/cat :config ::specs/resume-session-config) + :args (s/cat :config ::specs/join-session-config) :ret (s/keys :req-un [::specs/client ::specs/session])) (s/fdef github.copilot-sdk.client/list-sessions diff --git a/src/github/copilot_sdk/specs.clj b/src/github/copilot_sdk/specs.clj index c4fb320..28b6ba7 100644 --- a/src/github/copilot_sdk/specs.clj +++ b/src/github/copilot_sdk/specs.clj @@ -78,10 +78,11 @@ (s/def ::tool-parameters (s/nilable ::json-schema)) (s/def ::tool-handler fn?) (s/def ::overrides-built-in-tool boolean?) +(s/def ::skip-permission? boolean?) (s/def ::tool (s/keys :req-un [::tool-name ::tool-handler] - :opt-un [::tool-description ::tool-parameters ::overrides-built-in-tool])) + :opt-un [::tool-description ::tool-parameters ::overrides-built-in-tool ::skip-permission?])) (s/def ::tools (s/coll-of ::tool)) @@ -250,6 +251,19 @@ ::on-event]) resume-session-config-keys)) +;; join-session config: same as resume-session-config but :on-permission-request is optional. +;; When omitted, join-session defaults to a handler that returns {:kind :no-result}. +(s/def ::join-session-config + (closed-keys + (s/keys :opt-un [::on-permission-request + ::client-name ::model ::tools ::system-message ::available-tools ::excluded-tools + ::provider ::streaming? + ::mcp-servers ::custom-agents ::config-dir ::skill-directories + ::disabled-skills ::infinite-sessions ::reasoning-effort + ::on-user-input-request ::hooks ::working-directory ::disable-resume? ::agent + ::on-event]) + resume-session-config-keys)) + ;; ----------------------------------------------------------------------------- ;; Message options ;; -----------------------------------------------------------------------------