Phase 2/13
Phase 2: Structure
Structure complete — 4-SDK mirror pattern, contract-first polyglot architecture.
4
Language SDKs
8
Top-Level Modules
20
CI/CD Workflows
30
Scenario Templates
1. Directory Tree (Top 3–4 levels, annotated)
copilot-sdk/
│
├── justfile # Polyglot task runner: format, lint, test, install, codegen
├── sdk-protocol-version.json # Single source of truth for protocol version (currently 3)
├── README.md / CHANGELOG.md / CONTRIBUTING.md / LICENSE
│
├── nodejs/ # ── TypeScript/Node.js SDK ──
│ ├── package.json # npm: "@github/copilot-sdk"
│ ├── tsconfig.json / vitest.config.ts / eslint.config.js
│ ├── esbuild-copilotsdk-nodejs.ts # Custom esbuild bundler
│ ├── src/
│ │ ├── index.ts # Public API barrel export
│ │ ├── client.ts # CopilotClient (JSON-RPC connection mgmt)
│ │ ├── session.ts # CopilotSession (conversation lifecycle)
│ │ ├── types.ts # Handwritten type definitions
│ │ ├── extension.ts # joinSession() for child-process extensions
│ │ ├── sdkProtocolVersion.ts # [GENERATED] Protocol version constant
│ │ └── generated/
│ │ ├── rpc.ts # [GENERATED] Typed JSON-RPC method stubs
│ │ └── session-events.ts # [GENERATED] Session event type definitions
│ ├── test/e2e/ # End-to-end tests
│ │ └── harness/ # Node.js-specific E2E harness wrappers
│ ├── samples/ / scripts/ / docs/ / examples/
│
├── python/ # ── Python SDK ──
│ ├── pyproject.toml # PyPI: "github-copilot-sdk"
│ ├── copilot/
│ │ ├── __init__.py # Public API exports
│ │ ├── client.py # CopilotClient (subprocess + JSON-RPC)
│ │ ├── session.py # CopilotSession (conversation lifecycle)
│ │ ├── types.py # Handwritten types (Pydantic models)
│ │ ├── tools.py # define_tool() helper
│ │ ├── jsonrpc.py # Custom async JSON-RPC 2.0 client (stdio)
│ │ └── generated/ # [GENERATED] rpc.py, session_events.py
│ ├── e2e/testharness/ # Python-specific E2E harness
│ ├── test_*.py # Unit tests (pytest)
│
├── go/ # ── Go SDK ──
│ ├── go.mod # Module: github.com/github/copilot-sdk/go
│ ├── client.go # CopilotClient (process mgmt + JSON-RPC)
│ ├── session.go # CopilotSession
│ ├── types.go # Handwritten types
│ ├── definetool.go # DefineTool() with JSON Schema generation
│ ├── permissions.go # PermissionHandler.ApproveAll
│ ├── process_windows.go # Platform-specific process mgmt (Windows)
│ ├── process_other.go # Platform-specific process mgmt (Unix)
│ ├── rpc/generated_rpc.go # [GENERATED] Typed RPC method bindings
│ ├── generated_session_events.go # [GENERATED] Session event structs
│ ├── internal/
│ │ ├── jsonrpc2/ # Custom JSON-RPC 2.0 implementation
│ │ ├── embeddedcli/ # Embedded CLI binary management
│ │ ├── flock/ # Cross-platform file locking
│ │ └── e2e/testharness/ # Go-specific E2E harness
│ ├── embeddedcli/ / cmd/bundler/ # Public CLI installer + bundler tool
│
├── dotnet/ # ── .NET (C#) SDK ──
│ ├── GitHub.Copilot.SDK.slnx # Solution file
│ ├── Directory.Build.props / Directory.Packages.props / nuget.config
│ ├── src/
│ │ ├── GitHub.Copilot.SDK.csproj # NuGet: "GitHub.Copilot.SDK"
│ │ ├── Client.cs # CopilotClient (process + StreamJsonRpc)
│ │ ├── Session.cs # CopilotSession
│ │ ├── Types.cs # Handwritten types
│ │ ├── PermissionHandlers.cs # PermissionHandler.ApproveAll
│ │ ├── build/GitHub.Copilot.SDK.targets # MSBuild targets for CLI bundling
│ │ └── Generated/ # [GENERATED] Rpc.cs, SessionEvents.cs
│ └── test/Harness/ # E2E harness (CapiProxy, TestContext, etc.)
│
├── scripts/ # ── Shared Build Infrastructure ──
│ ├── codegen/ # Code generation from JSON Schema → all 4 SDKs
│ │ ├── utils.ts # Schema loading, processing, shared utilities
│ │ ├── typescript.ts / python.ts / go.ts / csharp.ts
│ └── docs-validation/ # Documentation code-example validator
│ ├── extract.ts / validate.ts
│
├── test/ # ── Shared Test Infrastructure ──
│ ├── harness/ # Cross-language E2E test harness (TypeScript)
│ │ ├── replayingCapiProxy.ts # Record/replay CAPI HTTP proxy
│ │ ├── capturingHttpProxy.ts # Low-level HTTP interception
│ │ ├── server.ts # Proxy server entry point
│ │ └── test-mcp-server.mjs # Mock MCP server for tool tests
│ ├── scenarios/ # Cross-language E2E scenario tests
│ │ ├── auth/ bundling/ callbacks/ modes/ prompts/ sessions/ tools/ transport/
│ └── snapshots/ # Recorded YAML test replay data
│
├── docs/ # ── Documentation ──
│ ├── setup/ auth/ features/ hooks/ integrations/ observability/ troubleshooting/
│
└── .github/ # ── CI/CD & GitHub Configuration ──
├── workflows/ (20 files) # Per-SDK tests, codegen check, publish, agentic workflows
├── actions/setup-copilot/ # Composite action: install deps + expose CLI path
├── agents/ # Copilot agent definitions (.agent.md)
└── aw/ # Agentic workflow definitions + schemas
2. Module Map
| Directory | Role |
|---|---|
| nodejs/ | Primary SDK — houses @github/copilot dependency providing CLI binary + JSON Schemas all SDKs consume. Published to npm. |
| python/ | Python SDK — async client using asyncio + subprocess stdio. Own JSON-RPC impl (jsonrpc.py). Published to PyPI. |
| go/ | Go SDK — pure Go with custom JSON-RPC 2.0. Platform-specific process code. CLI bundler tool. Published as Go module. |
| dotnet/ | C#/.NET SDK — uses StreamJsonRpc. MSBuild targets for auto CLI bundling. Published to NuGet. |
| scripts/ | Shared codegen — TypeScript-based, reads JSON Schemas from @github/copilot, emits typed code into all 4 SDKs. |
| test/ | Shared test infra — Replaying HTTP proxy, 30 cross-language scenario templates, YAML snapshots. |
| docs/ | Unified docs — polyglot guides with machine-validated code examples. |
| .github/ | CI/CD — per-language tests, codegen verification, multi-registry publish, agentic workflows. |
3. SDK Mirror Pattern
The four SDKs follow a rigorous structural mirror with idiomatic naming:
Core Source Files
Core Source Files — 4-SDK Mirror
flowchart LR
subgraph Concepts[" "]
direction TB
C1["Client"]
C2["Session"]
C3["Types"]
C4["Public API"]
C5["Protocol ver."]
C6["Tool helper"]
C7["Permissions"]
end
subgraph TS["TypeScript"]
direction TB
T1["src/client.ts"]
T2["src/session.ts"]
T3["src/types.ts"]
T4["src/index.ts"]
T5["sdkProtocolVersion.ts"]
T6["types.ts defineTool"]
T7["types.ts approveAll"]
end
subgraph PY["Python"]
direction TB
P1["copilot/client.py"]
P2["copilot/session.py"]
P3["copilot/types.py"]
P4["copilot/__init__.py"]
P5["sdk_protocol_version.py"]
P6["tools.py define_tool"]
P7["types.py"]
end
subgraph GO["Go"]
direction TB
G1["client.go"]
G2["session.go"]
G3["types.go"]
G4["package-level"]
G5["sdk_protocol_version.go"]
G6["definetool.go DefineTool"]
G7["permissions.go"]
end
subgraph CS["C#"]
direction TB
S1["src/Client.cs"]
S2["src/Session.cs"]
S3["src/Types.cs"]
S4["namespace"]
S5["SdkProtocolVersion.cs"]
S6["inline Types.cs"]
S7["PermissionHandlers.cs"]
end
C1 --- T1 & P1 & G1 & S1
C2 --- T2 & P2 & G2 & S2
C3 --- T3 & P3 & G3 & S3
C4 --- T4 & P4 & G4 & S4
C5 --- T5 & P5 & G5 & S5
C6 --- T6 & P6 & G6 & S6
C7 --- T7 & P7 & G7 & S7
Generated Files (all from same JSON Schemas via scripts/codegen/)
Generated Artifacts — Schema-Driven Code Generation
flowchart TD
Schema["JSON Schemas<br/>scripts/codegen/"] --> TS & PY & GO & CS
subgraph TS["TypeScript"]
T1["generated/rpc.ts"]
T2["generated/session-events.ts"]
end
subgraph PY["Python"]
P1["generated/rpc.py"]
P2["generated/session_events.py"]
end
subgraph GO["Go"]
G1["rpc/generated_rpc.go"]
G2["generated_session_events.go"]
end
subgraph CS["C#"]
S1["Generated/Rpc.cs"]
S2["Generated/SessionEvents.cs"]
end
E2E Test Harness (per SDK wrapping shared test/harness/)
| Component | TypeScript | Python | Go | C# |
|---|---|---|---|---|
| E2E dir | test/e2e/ | e2e/ | internal/e2e/ | test/ |
| Harness | test/e2e/harness/ | e2e/testharness/ | internal/e2e/testharness/ | test/Harness/ |
Scenario Mirror (each scenario has up to 4 language subdirs)
test/scenarios/tools/custom-agents/
├── typescript/ (package.json + src/index.ts)
├── python/ (main.py + requirements.txt)
├── go/ (go.mod + main.go)
├── csharp/ (csharp.csproj + Program.cs)
├── verify.sh # Language-agnostic verification
└── README.md
4. Dependency Graph Between Modules
Module Dependency Flow
flowchart TD
A["sdk-protocol-version.json"] --> B["scripts/codegen/utils.ts"]
B --> C1["typescript.ts"]
B --> C2["python.ts"]
B --> C3["go.ts"]
B --> C4["csharp.ts"]
C1 --> D1["nodejs/generated/"]
C2 --> D2["python/generated/"]
C3 --> D3["go/rpc/"]
C4 --> D4["dotnet/Generated/"]
D1 --> E1["nodejs/src/\nclient.ts, session.ts"]
D2 --> E2["python/copilot/\nclient.py, session.py"]
D3 --> E3["go/\nclient.go, session.go"]
D4 --> E4["dotnet/src/\nClient.cs, Session.cs"]
E1 & E2 & E3 & E4 --> F1["@github/copilot\nCLI binary + JSON Schemas"]
E1 & E2 & E3 & E4 --> F2["test/harness/\nreplayingCapiProxy"]
F1 --> G1["Copilot CLI Server\n(runtime)"]
F2 --> G2["test/scenarios/\n(all 4 languages)"]
G2 --> H["test/snapshots/"]
Key relationships
- @github/copilot is the root — provides CLI binary + JSON Schema definitions
- scripts/codegen/ depends on nodejs/ (schemas live in nodejs/node_modules/@github/copilot/schemas/)
- All 4 SDKs consume codegen output in their generated/ directories
- test/harness/ is language-independent — each SDK launches it as a subprocess
- publish.yml orchestrates all SDKs — shared version, parallel publish to 4 registries
5. Architecture Pattern Detection
Primary: Contract-First Polyglot SDK with Facade Pattern
Architecture Layer Stack
flowchart TD
L1["Facade: Public API\nindex.ts / __init__.py / package-level"]
L2["Connection Manager: CopilotClient\nConnection lifecycle, process spawning"]
L3["Session Manager: CopilotSession\nConversation lifecycle, event handling"]
L4a["Generated RPC\nMethod Stubs"]
L4b["Generated Events\nType Definitions"]
L5["Transport: JSON-RPC 2.0\nvscode-jsonrpc / custom / StreamJsonRpc"]
L6["Runtime: Copilot CLI Server Process\nSpawned subprocess or TCP connection"]
L1 --> L2 --> L3
L3 --> L4a & L4b
L4a & L4b --> L5 --> L6
Secondary Patterns
- Schema-Driven Code Generation (Contract-First Design) — JSON Schemas are single source of truth
- Observer Pattern — Sessions use event-based subscription across all SDKs
- Proxy Pattern (testing) —
ReplayingCapiProxytransparently intercepts HTTP for record/replay - Monorepo with Independent Publishing — one repo, 4 independent registry publishes
What this is NOT
- Not Hexagonal Architecture (no explicit ports/adapters)
- Not Plugin Architecture (extensible via tools/MCP, but SDK itself isn’t plugin-based)
- Not Layered Architecture (Client manages both process lifecycle and RPC)
Best Characterization
Contract-First Polyglot SDK using Facade + Schema-Driven Code Generation to maintain protocol conformance across 4 language implementations.
6. Key Structural Files
justfile (root)
The developer’s single entry point for all cross-cutting operations:
just format/lint/test— aggregate across all languagesjust install— all deps across all SDKsjust scenario-build— build-verify all scenario samplesjust validate-docs— machine-verify documentation code examples
sdk-protocol-version.json
Contains {"version": 3}. Propagated to all 4 SDKs via codegen. Checked during client init to ensure SDK/CLI compatibility (e.g., nodejs/src/client.ts:56 — MIN_PROTOCOL_VERSION = 2).
.github/workflows/ (20 files)
- 4 per-SDK test workflows — lint + test on Linux/macOS/Windows matrix
- 3 cross-cutting workflows — codegen check, docs validation, scenario builds
- 1 publish workflow — multi-registry publish + GitHub Release
- 4 agentic workflows — AI-powered PR review, issue triage, changelog generation
- Others — dependency updates, Copilot setup