How to Contribute to the GitHub Copilot SDK Project: A Complete Developer Guide
Contributing to the GitHub Copilot SDK requires pre-approval for all changes, local setup of the Node.js test harness, and passing both language-specific unit tests and shared integration tests before submitting a pull request.
The GitHub Copilot SDK is a multi-language framework that enables developers to embed the GitHub Copilot agent into custom tools and applications. If you want to contribute to the GitHub Copilot SDK project, you will work with a core Go architecture exposed through language-specific packages for Node.js/TypeScript, Python, Go, .NET, Java, and Rust. Understanding the core types defined in go/types.go and the mandatory testing workflow is essential for successful contribution.
Prerequisites and Repository Setup
Before writing code, you must fork the repository and install dependencies for each language you plan to modify. The SDK uses a shared test harness written in Node.js that validates behavior across all language implementations.
Forking and Local Installation
Clone your fork and install the required language SDKs:
# Node.js/TypeScript SDK
cd nodejs && npm ci
# Python SDK
cd python && uv pip install -e ".[dev]"
# Go SDK
cd go && go mod download
Source: [CONTRIBUTING.md](https://github.com/github/copilot-sdk/blob/main/CONTRIBUTING.md#prerequisites-for-running-and-testing-code)
You must also install the shared test harness before running any language-specific tests:
cd test/harness && npm ci
Understanding the Copilot SDK Architecture
The SDK centers on several core abstractions defined in the Go source that propagate to all language bindings. Understanding these types helps you write consistent code across the multi-language codebase.
Core Types in go/types.go
The file go/types.go defines the fundamental structures that drive every language SDK:
RuntimeConnection– An interface describing how clients communicate with the Copilot runtime viaStdioConnection,TCPConnection,URIConnection, orInProcessConnection(lines 21-84).ClientOptions– A configuration struct aggregating connection settings, authentication, environment variables, and feature flags (lines 15-99).SessionConfig– Per-session customization including model selection, skills, tools, and telemetry settings (lines 33-100).SessionHooks– Programmable callbacks intercepting the agent lifecycle, includingonPreToolUse,onPostToolUse, and error handlers (lines 57-68).
The Hooks System and Session Lifecycle
Hooks allow developers to intercept agent operations programmatically. When implementing features involving hook customization, you will modify or extend the SessionHooks struct and its associated input/output types. These hooks are exposed identically across all language SDKs, ensuring behavioral parity between Go, Python, and Node.js implementations.
The Testing Requirements
All contributions must pass two layers of validation: language-specific unit tests and the shared cross-language harness. The CI pipeline automatically rejects pull requests lacking adequate test coverage.
Running the Shared Test Harness
The Node.js test harness in test/harness drives end-to-end tests for every language. You must install and verify this harness before submitting changes:
cd test/harness && npm ci
This harness ensures that changes to core types in go/types.go propagate correctly to all language bindings.
Language-Specific Test Commands
After setting up the harness, run the appropriate tests for your modified languages:
# Node.js
cd nodejs && npm test && npm run lint
# Python
cd python && uv run pytest && uv run ruff check .
# Go
cd go && go test ./... && golangci-lint run ./...
Source: [CONTRIBUTING.md](https://github.com/github/copilot-sdk/blob/main/CONTRIBUTING.md#running-tests-and-linters)
Contribution Workflow
The GitHub Copilot SDK project maintains strict contribution policies to ensure code quality and architectural consistency across multiple languages.
Pre-Approval Requirements
According to the [CONTRIBUTING.md](https://github.com/github/copilot-sdk/blob/main/CONTRIBUTING.md#before-you-submit-a-pr) policy, the project only accepts work that has been pre-approved. This includes feature discussions, bug reports, and documentation updates. Before writing significant code, browse open issues, label the one you intend to work on, or start a discussion for new features. Documentation improvements and bug fixes typically require less upfront coordination than new features.
Submitting Your Pull Request
Once you have pre-approval and passing tests:
- Create a focused branch with a clear naming convention
- Write comprehensive tests for any new behavior
- Commit with descriptive messages referencing the issue number
- Push to your fork and open a pull request linking the associated issue
- Respond to maintainer feedback and ensure all CI checks pass
Implementation Examples
When contributing new features, reference these patterns from the existing codebase to ensure consistency with the core Go types.
Go Client Setup
This example demonstrates creating a client using ClientOptions and starting a session with SessionConfig:
import (
"context"
"github.com/github/copilot-sdk/go"
)
func main() {
// Connect via stdio (default)
client, _ := copilot.NewClient(context.Background(), &copilot.ClientOptions{
LogLevel: "debug",
})
defer client.Close()
// Start a session with a custom system message
sess, _ := client.StartSession(context.Background(), &copilot.SessionConfig{
Model: "gpt-4o",
SystemMessage: &copilot.SystemMessageConfig{
Mode: "append",
Content: "You are an expert Go consultant.",
},
})
// Use the session …
_ = sess
}
Source: Go SDK API – built on ClientOptions and SessionConfig in [go/types.go](https://github.com/github/copilot-sdk/blob/main/go/types.go).
Python Session Configuration
The Python SDK mirrors the Go struct patterns:
from copilot import CopilotClient, SessionConfig
client = CopilotClient()
session = client.start_session(
SessionConfig(
model="gpt-4o",
system_message={"mode": "append", "content": "You are a helpful Python assistant."},
)
)
response = session.run("Write a function that returns the factorial of n.")
print(response)
Node.js Hooks Implementation
When extending hook functionality, implement the SessionHooks interface as defined in the core types:
import { CopilotClient, StdioConnection, PreToolUseHookInput } from '@github/copilot-sdk';
const client = new CopilotClient({
connection: new StdioConnection({ path: 'copilot-runtime' }),
hooks: {
onPreToolUse: async (input: PreToolUseHookInput) => {
// Example: deny any `rm` tool calls
if (input.toolName === 'rm') {
return { permissionDecision: 'deny', permissionDecisionReason: 'Safety policy' };
}
return {};
},
},
});
(async () => {
const session = await client.startSession({ model: 'gpt-4o' });
const result = await session.run('List files in the current directory.');
console.log(result);
})();
Source: The hook mechanism is defined in SessionHooks (go/types.go) and exposed in each language's SDK.
Summary
- Pre-approval is mandatory for all contributions to the GitHub Copilot SDK project according to the official policy.
- Install the shared Node.js test harness before running language-specific tests, as it validates cross-language compatibility.
- Core types defined in
go/types.go(includingRuntimeConnection,ClientOptions, andSessionConfig) drive the architecture for all six language SDKs. - All PRs require tests for new behavior, and must pass both unit tests and the shared harness validation.
- Hooks and SessionConfig provide the primary extension points for customizing agent behavior across languages.
Frequently Asked Questions
Do I need prior approval before submitting a PR?
Yes. The GitHub Copilot SDK project only accepts pre-approved work. You must either pick an existing labeled issue or start a discussion for new features before submitting code. This policy is strictly enforced to maintain architectural consistency across the multi-language codebase.
Which languages can I contribute to?
You can contribute to any of the six supported language SDKs: Go (the core implementation), Node.js/TypeScript, Python, .NET, Java, or Rust. All languages must maintain parity with the core types defined in go/types.go and pass the shared Node.js test harness.
What is the test harness and why is it required?
The test harness is a Node.js-based integration testing framework located in test/harness that drives end-to-end tests across all language SDKs. It is required because the Copilot SDK is a multi-process framework where Go types must serialize correctly to other languages. The harness ensures behavioral consistency between the core Go implementation and all language bindings.
How do I handle cross-language changes?
When modifying core types in go/types.go, you must update the corresponding type definitions in all language SDKs (Node.js, Python, .NET, Java, Rust) to maintain API parity. Run the shared test harness after changes to verify that serialization and deserialization work correctly across language boundaries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →