Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tilakpatell/copilot-sdk-cpp
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2afbf06
Choose a base ref
...
head repository: 0xeb/copilot-sdk-cpp
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d7e8267
Choose a head ref
  • 17 commits
  • 20 files changed
  • 2 contributors

Commits on May 16, 2026

  1. feat(protocol): bump SDK_PROTOCOL_VERSION 2 -> 3, add range check

    Aligns with upstream nodejs SDK (reference/copilot-sdk d0eb531e) which moved
    SDK_PROTOCOL_VERSION to 3. Introduces:
    
    - kMinProtocolVersion = 2 (mirror of nodejs/Rust port's range support)
    - verify_protocol_version() accepts servers in [kMinProtocolVersion .. kSdkProtocolVersion]
    - new Client::negotiated_protocol_version() accessor (std::optional<int>)
      populated after successful start()
    
    Test updates:
    - TypesTest.PingResponse uses protocolVersion 3
    - TypesTest.ProtocolVersion asserts kSdkProtocolVersion == 3 and the
      min<=max invariant
    
    All 297 non-E2E ctest cases pass.
    
    Part of sync/upstream-1.0.49-1 (Phase 2 bucket 1 of full-parity sync).
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    6344069 View commit details
    Browse the repository at this point in the history
  2. feat(client): add ClientOptions parity for upstream v0.1.49

    Adds the ClientOptions fields introduced upstream (nodejs SDK at
    reference/copilot-sdk d0eb531e) and wires them through to the spawned
    CLI server:
    
    - tcp_connection_token (std::optional<string>) -> COPILOT_CONNECTION_TOKEN
      env var. Validated to be non-empty and rejected with use_stdio=true.
      Auto-generated as a UUID v4 when SDK spawns its own CLI in TCP mode
      and the caller did not set one (matches nodejs effectiveConnectionToken
      semantics so loopback listeners are safe by default).
    - copilot_home (std::optional<string>) -> COPILOT_HOME env var (configurable
      data directory).
    - session_idle_timeout_seconds (std::optional<int>) -> --session-idle-timeout
      CLI flag (only emitted when value > 0).
    - remote (bool) -> --remote CLI flag (Mission Control integration).
    
    Deprecates auto_restart:
    - Marked [[deprecated]] with no-op semantics. Default flipped from true
      to false (the field was never actually consulted by the C++ port, and
      upstream nodejs SDK marked it deprecated/no-op as well).
    - Tests opt-in to the deprecation warning suppression to keep building
      clean.
    
    ClientOptionsTest.DefaultValues extended with the new field defaults.
    
    All 297 non-E2E ctest cases continue to pass.
    
    Part of sync/upstream-1.0.49-1 (Phase 2 bucket 3 of full-parity sync).
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    e823266 View commit details
    Browse the repository at this point in the history
  3. feat(lifecycle): SessionListFilter, SessionContext, getSessionMetadata

    Adds the session lifecycle API additions introduced upstream (nodejs SDK
    at reference/copilot-sdk d0eb531e):
    
    Types
    - SessionContext: cwd / git_root / repository / branch (working directory
      context from session creation).
    - SessionListFilter: optional filter (cwd / git_root / repository / branch)
      for narrowing list_sessions results.
    - SessionMetadata gains an optional 'context' field (parsed from the
      'context' JSON object when present).
    
    Client API
    - Client::list_sessions(SessionListFilter) overload mirrors upstream
      CopilotClient.listSessions(filter). The no-arg list_sessions() now
      delegates to the filtered overload with an empty filter, and both use
      the SessionMetadata from_json (so startTime, modifiedTime, isRemote,
      summary, and context are all populated -- previously only sessionId and
      summary were read).
    - Client::get_session_metadata(session_id) calls 'session.getMetadata'
      and returns std::optional<SessionMetadata> (nullopt when the server
      returns no session).
    
    Tests (test_types.cpp, +5 cases, total 302/302 ctest pass)
    - SessionListFilterTest.EmptyFilterSerializesToEmptyObject
    - SessionListFilterTest.AllFieldsSerialize
    - SessionContextTest.RoundTrip
    - SessionMetadataTest.ParsesContextField
    - SessionMetadataTest.ContextAbsentIsNullopt
    
    Part of sync/upstream-1.0.49-1 (Phase 2 bucket 4 of full-parity sync).
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    dc9fafe View commit details
    Browse the repository at this point in the history
  4. feat(tools): add ToolResultType::Timeout + Tool.skip_permission/overr…

    …ides_built_in_tool
    
    
    Adds the tool-handling additions from upstream nodejs SDK at d0eb531e:
    
    - ToolResultType::Timeout enum value (serializes as "timeout").
    - Tool::overrides_built_in_tool bool default false; serialized as
      overridesBuiltInTool only when true.
    - Tool::skip_permission bool default false; serialized as skipPermission
      only when true.
    
    Both new flags wired into build_session_create_request and
    build_session_resume_request alongside existing name/description/parameters.
    
    Tests added:
    - ToolResultTypeTest.TimeoutEnumRoundTrip
    - ToolTest.DefaultFlagsFalse
    
    304/304 ctest pass (E2E skipped).
    
    Part of sync/upstream-1.0.49-1 Phase 2 bucket 6 partial: tools/permissions
    core flags. Commands, elicitations, userInput callbacks remain TODO.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    af070f6 View commit details
    Browse the repository at this point in the history
  5. feat(byok): Client::set_on_list_models for custom model providers

    Adds the BYOK list_models handler from upstream nodejs SDK
    CopilotClientOptions.onListModels (PR #730, present at d0eb531e).
    
    Design note: in C++ this is exposed as a setter on Client rather than
    a field on ClientOptions, because std::function<std::vector<ModelInfo>()>
    requires ModelInfo to be complete and ClientOptions is declared earlier
    in types.hpp than ModelInfo.
    
    - Client::set_on_list_models(handler) registers a custom callback used in
      place of the CLI models.list RPC. Passing nullptr reverts to RPC-based
      behavior.
    - Client::list_models() now:
      1) Returns the cached models if present (both BYOK and RPC paths share
         the same cache).
      2) If a BYOK handler is registered, calls it (does NOT require an active
         CLI connection), caches the result, returns it.
      3) Otherwise falls through to the existing models.list RPC path.
    - set_on_list_models() invalidates the cache so the next list_models()
      observes the new source.
    
    304/304 ctest pass (E2E skipped). Existing tests cover the RPC path.
    
    Part of sync/upstream-1.0.49-1 Phase 2 bucket 8 BYOK/models.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    82dd2e8 View commit details
    Browse the repository at this point in the history
  6. feat(session): SessionConfig+ResumeSessionConfig v0.1.49 additive fields

    Adds the additive SessionConfig / ResumeSessionConfig fields landed
    upstream (nodejs SDK at reference/copilot-sdk d0eb531e):
    
    - client_name (#510, optional string)
    - enable_session_telemetry (#1224, optional bool)
    - include_sub_agent_streaming_events (#1108, optional bool)
    - enable_config_discovery (#1044, optional bool)
    - instruction_directories (#1190, optional vector<string>)
    - remote_session (#1295, optional RemoteSessionMode)
    
    Types
    - New RemoteSessionMode enum class (Off / Export / On) with
      NLOHMANN_JSON_SERIALIZE_ENUM mapping (off/export/on) matching the
      upstream nodejs type union.
    
    Serialization (no behavior change when omitted)
    - build_session_create_request: emits clientName / enableSessionTelemetry
      / includeSubAgentStreamingEvents / enableConfigDiscovery /
      instructionDirectories / remoteSession only when the corresponding
      optional is set.
    - build_session_resume_request: same set of fields mirrored.
    
    Tests (test_types.cpp, +4 cases, total 308/308 ctest pass)
    - RemoteSessionModeTest.RoundTrip
    - SessionConfigTest.V0149FieldsOmittedByDefault
    - SessionConfigTest.V0149FieldsSerialize
    - ResumeSessionConfigTest.V0149FieldsSerialize
    
    Not yet covered in this commit (remain on the bucket TODO list):
    - sessionFs / SessionFsConfig
    - modelCapabilities override
    - per-agent skills + defaultAgent.excludedTools
    - CustomAgentConfig.model
    - MCP config refactor (MCPStdioServerConfig / MCPHTTPServerConfig)
    - systemMessage transform callbacks
    - session idle timeout (already covered by ClientOptions bucket)
    
    Part of sync/upstream-1.0.49-1 Phase 2 bucket 5 partial.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    8735dc8 View commit details
    Browse the repository at this point in the history
  7. feat(session): add Session::set_model + set_mode + getters (v3 RPC)

    Adds the v0.1.49 mode/model APIs that upstream exposed via the v3 RPC
    namespace (session.model.*, session.mode.*):
    
    - Session::set_model(model_id, SetModelOptions) calls session.model.switchTo
      with {sessionId, modelId, reasoningEffort?}. Mirrors upstream
      CopilotSession.setModel.
    - Session::SetModelOptions struct with optional reasoning_effort.
    - Session::get_current_model() calls session.model.getCurrent and returns
      std::optional<string> (nullopt when server reports no modelId).
    - Session::Mode enum (Interactive / Plan / Autopilot) mirrors the upstream
      "interactive" | "plan" | "autopilot" SessionMode union.
    - Session::set_mode(mode) calls session.mode.set.
    - Session::get_mode() calls session.mode.get and parses the wire string;
      defaults to Interactive on unknown values to keep the SDK forward-compatible.
    
    Tests added (test_types.cpp, +2 cases):
    - SessionModeTest.EnumValuesExist
    - SessionSetModelOptionsTest.DefaultsEmpty
    
    310/310 ctest pass (E2E skipped).
    
    Not yet covered in this commit (still on bucket TODO):
    - ModelCapabilitiesOverride passthrough on set_model
    - agent.select / agent.switch APIs
    - session compaction RPCs (session.compact / compact.start / compact.complete)
      beyond the existing compaction event hooks
    
    Part of sync/upstream-1.0.49-1 Phase 2 bucket 7 partial.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    f633f81 View commit details
    Browse the repository at this point in the history
  8. feat(rpc): mirror v3 generated RPC namespace and add typed structs

    Adds two new public headers that centralize the JSON-RPC method-name
    surface published by the upstream nodejs reference at
    reference/copilot-sdk/nodejs/src/generated/rpc.ts:
    
    - include/copilot/rpc_methods.hpp exposes one
      inline constexpr const char* per wire string under
      copilot::rpc::methods (e.g. kSessionModelSwitchTo,
      kSessionPlanRead, kSessionsFork, kSessionFsReadFile).
      Also ships RpcRequestDispatcher, a thin facade that demuxes
      JsonRpcClient::set_request_handler by method name and mirrors
      the shape of upstream registerClientSessionApiHandlers.
    
    - include/copilot/rpc_types.hpp provides nlohmann::json-friendly
      request/result structs for the most commonly used new families:
      session.name, session.mode, session.model.switchTo,
      session.plan.{read,update}, session.history.{compact,truncate},
      sessions.fork, session.shell.{exec,kill},
      session.commands.{list,invoke,handlePendingCommand},
      session.permissions.setApproveAll and the full sessionFs.*
      server-to-client request set with a SessionFsHandlers bundle
      and register_session_fs_handlers helper.
    
    - Switches the existing 21 hard-coded method strings in
      src/client.cpp and src/session.cpp over to the new constants.
    
    - Adds tests/test_rpc_methods.cpp (37 cases) covering wire-string
      parity for every catalog entry, round-trip JSON for the new typed
      structs, and RpcRequestDispatcher routing.
    
    Does NOT touch event parsing (events.hpp/events.cpp) - that
    surface is owned by the parallel p2-cpp-events work.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    13f06e6 View commit details
    Browse the repository at this point in the history
  9. feat(events): add v0.1.49 event variants for full parity

    Adds 43 new SessionEvent variants to bring events.hpp to schema parity
    with reference/copilot-sdk@d0eb531e (nodejs/src/generated/session-events.ts).
    
    New event types:
    - Session lifecycle: remote_steerable_changed, title_changed,
      schedule_created/cancelled, warning, mode_changed, plan_changed,
      workspace_file_changed, context_changed, task_complete,
      custom_notification, tools_updated, background_tasks_changed,
      skills_loaded, custom_agents_updated, mcp_servers_loaded,
      mcp_server_status_changed, extensions_loaded
    - Streaming: assistant.streaming_delta, assistant.message_start
    - Telemetry: model.call_failure
    - Subagent: subagent.deselected
    - Interactivity: permission.requested/completed, user_input.requested/completed,
      elicitation.requested/completed, sampling.requested/completed,
      mcp.oauth_required/completed, external_tool.requested/completed,
      command.queued/execute/completed, auto_mode_switch.requested/completed,
      commands.changed, capabilities.changed, exit_plan_mode.requested/completed,
      system.notification
    
    Also:
    - Adds optional `agent_id` to SessionEvent envelope (sub-agent
      identifier present on every upstream event).
    - Adds WorkingDirectoryContext shared type used by session.context_changed.
    - Permission/elicitation/system-notification payloads keep their
      discriminated-union sub-fields (permissionRequest, promptRequest,
      result, kind, content, requestedSchema) as raw json so callers can
      branch on inner `kind`/`type` discriminators without forcing a
      large struct hierarchy.
    - Unknown-event fallback to `json` is preserved.
    
    Tests: 30 new EventsTest cases in tests/test_types.cpp covering at least
    one parse case per new event family plus agent_id parsing and the
    unknown-event fallback.
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    cc7629a View commit details
    Browse the repository at this point in the history
  10. test(v0149): add focused unit tests + examples for v0.1.49 features

    Augments the existing test/example suites with offline-only coverage
    for surfaces added during the v0.1.49 sync cycle. No existing tests
    were modified or removed; all 377 prior ctest cases continue to pass.
    
    New tests (tests/test_v0149_features.cpp, 26 cases):
    
    * ClientOptions::tcp_connection_token validation
      - empty string rejected
      - stdio + explicit token rejected
      - auto-UUID generated path does not throw in TCP mode
      - explicit token accepted in TCP mode
      - external server (cli_url) bypasses token requirement
      - RFC-4122 v4 shape regex sanity
    
    * Tool flag wiring through build_session_create_request /
      build_session_resume_request:
      - skipPermission + overridesBuiltInTool serialize per-tool when set
      - flags are omitted when false
    
    * ResumeSessionConfig v0.1.49 fields:
      - omitted from resume payload by default
      - clientName / enableSessionTelemetry / includeSubAgentStreamingEvents
        / enableConfigDiscovery / instructionDirectories / remoteSession
        all serialize when set
    
    * RemoteSessionMode edge cases:
      - all three known values round-trip via session.create payload
      - unknown wire value falls back to first-listed enumerator
    
    * Session::dispatch_event end-to-end typed-variant routing:
      - session.title_changed routes to SessionTitleChangedData
      - session.warning + model.call_failure both route to typed variants
      - multiple handlers fire in registration order
      - Subscription destructor removes handler
      - handler exception does not break other subscribers
      - SessionWarningData carries warning_type / message after dispatch
    
    * Typed RPC struct round-trips (gaps left by test_rpc_methods.cpp):
      - ModeSetRequest / ModeGetResult
      - ModelSwitchToResult nullable modelId
      - HistoryCompactResult
      - PermissionsSetApproveAllRequest / Result
      - PlanUpdateRequest
    
    * SessionStartData baseline parse + WorkingDirectoryContext all-fields
      parse (used by session.start and session.context_changed).
    
    New examples (compile-only demos, no live CLI required):
    
    * examples/instruction_directories.cpp -- mirrors upstream PR #1190.
      Builds a SessionConfig populated with per-session instruction
      directories and dumps the resulting session.create payload via the
      public build_session_create_request helper.
    
    * examples/remote_session.cpp -- mirrors upstream PR #1295. Walks
      through the three RemoteSessionMode values (off / export / on) and
      prints the resulting session.create payload for each.
    
    Both examples are registered in examples/CMakeLists.txt and link
    against copilot_sdk_cpp.
    
    Final ctest: 403 passed / 0 failed (was 377).
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    c2208e1 View commit details
    Browse the repository at this point in the history
  11. test(conformance): add offline conformance suite closing E2E gap

    Adds tests/test_conformance.cpp with 24 offline ctest cases that exercise
    wire-level behavior without requiring the real Copilot CLI. Closes the
    coverage gap left by E2E tests skipped via COPILOT_SDK_CPP_SKIP_E2E.
    
    Test sections:
      * Section A - CLI argv / env mapping (8 tests). Asserts COPILOT_HOME,
        COPILOT_CONNECTION_TOKEN, COPILOT_SDK_AUTH_TOKEN env passthrough plus
        --session-idle-timeout, --remote, --log-level, --port / --stdio CLI
        flag emission. NODE_DEBUG stripping is also verified.
      * Section B - v0.1.49 session.create / session.resume payload (3 tests).
        Verifies all v0.1.49 fields are omitted by default and that, when set,
        they serialize with the upstream camelCase names (clientName,
        enableSessionTelemetry, includeSubAgentStreamingEvents,
        enableConfigDiscovery, instructionDirectories, remoteSession).
      * Section C - Pending lifecycle (4 tests). Drives an in-process JSON-RPC
        peer that connects to the SDK over loopback TCP and injects server-to
        -client tool.call / permission.request / userInput.request requests.
        Asserts the registered handler is invoked and the SDK's reply payload
        matches the expected wire shape.
      * Section D - Session-event fixture parsing (7 tests). Feeds representative
        JSON envelopes for major event families (session.idle, assistant.message,
        tool.execution_start/complete, permission.requested, user_input.requested,
        unknown) through the event router and asserts the variant is correctly
        typed.
      * Section E - Async lifetime (2 tests). Registers a slow tool handler,
        drives a server-side tool.call, then calls Session::destroy() /
        Client::stop() while the handler is mid-flight. Asserts no crash, no
        UAF; completion happens or is gracefully cancelled.
      * Section F - TODO(conformance) marker documenting that real-CLI subprocess
        lifecycle remains gated behind the E2E tier (test_e2e.cpp), per
        p2-cpp-buildsys-ci.
    
    Supporting changes:
      * include/copilot/client.hpp + src/client.cpp - extract build_cli_command_args
        and build_cli_environment as free functions in the copilot:: namespace so
        they can be unit-tested directly. Client::start_cli_server() now delegates
        to them; behavior is unchanged.
      * tests/CMakeLists.txt - register the new test_conformance executable next
        to the existing focused test targets.
    
    The in-process JSON-RPC peer mirrors the SnapshotRpcServer pattern from
    tests/snapshot_tests/snapshot_replay.cpp - opens a loopback listener, accepts
    one connection, runs a reader + writer thread, and exposes inject_request()
    for tests to push server-to-client requests and capture the SDK's reply.
    
    ctest summary:
      Before: 403 tests, 100% passing.
      After:  427 tests, 100% passing (+24 conformance).
    0xeb committed May 16, 2026
    Configuration menu
    Copy the full SHA
    b73cdcb View commit details
    Browse the repository at this point in the history

Commits on Jun 8, 2026

  1. feat(types): add skills and model fields to CustomAgentConfig

    Port upstream d0eb531e (add model field to CustomAgentConfig) and
    backfill the pre-existing skills field gap. Both fields are optional
    and omitted from JSON when unset.
    
    - Add skills (vector<string>) and model (string) to CustomAgentConfig
    - Update to_json/from_json serialization
    - Add round-trip and omission tests
    0xeb committed Jun 8, 2026
    Configuration menu
    Copy the full SHA
    8e43019 View commit details
    Browse the repository at this point in the history

Commits on Jun 9, 2026

  1. feat(types): close type-surface parity gaps with upstream .NET SDK

    Add missing enums, types, and fields to match upstream Types.cs:
    - SectionOverrideAction enum (5 variants)
    - SectionOverride struct (action + content)
    - McpHttpServerConfigOauthGrantType enum (2 variants)
    - SystemMessageMode::Customize variant
    - DefaultAgentConfig struct (excludedTools)
    - SystemMessageConfig.sections field
    - ProviderConfig: headers, modelId, wireModel, maxPromptTokens, maxOutputTokens
    - SessionConfig: commands, defaultAgent, agent, modelCapabilities, githubToken
    - ResumeSessionConfig: commands, defaultAgent, agent, modelCapabilities
    - MessageOptions: requestHeaders
    
    Callback handlers (OnElicitationRequest, OnExitPlanMode, etc.) deferred.
    
    Tests: 437/437 passing (8 new parity tests added)
    0xeb committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    a7d699e View commit details
    Browse the repository at this point in the history
  2. feat: add elicitation, exit-plan-mode, auto-mode-switch handlers and …

    …conformance tests
    
    
    Add callback handler types (ElicitationContext/Result, ExitPlanModeRequest/Result,
    AutoModeSwitchRequest/Response) with registration, dispatch, and default behaviors.
    Wire up new handlers in Client request dispatch and SessionConfig.
    Add comprehensive conformance tests for all new handler types and parity types.
    0xeb committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    083664f View commit details
    Browse the repository at this point in the history
  3. feat: add fluent setters for Tool skip_permission and overrides_built…

    …_in_tool
    
    
    Add ref-qualified with_skip_permission() and with_overrides_built_in_tool()
    fluent setters enabling chaining on make_tool() and ToolBuilder results.
    
    Closes 0xeb#11
    
    Co-authored-by: Tilak Patel <tilakny@gmail.com>
    0xeb and tilakpatell committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    4cf7c40 View commit details
    Browse the repository at this point in the history
  4. Merge: sync/upstream-d0eb531e — full v0.1.49 parity

    feat: upstream parity sync (d0eb531e) — types, handlers, fluent setters
    0xeb authored Jun 9, 2026
    Configuration menu
    Copy the full SHA
    bb49682 View commit details
    Browse the repository at this point in the history
  5. chore: bump version to 0.2.0

    0xeb committed Jun 9, 2026
    Configuration menu
    Copy the full SHA
    d7e8267 View commit details
    Browse the repository at this point in the history
Loading