cocopilot

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 8, 2025 License: MIT Imports: 11 Imported by: 0

README

cocopilot 💩🧑‍✈️

fetches API tokens to use GitHub Copilot with any tool

GitHub Issues GitHub Pull Requests

Codecov License


📝 Table of Contents

🧐 About

Once upon a time, some "CISO wizards" (believe me, self-entitled) in a bureaucratic company decided to allow GitHub Copilot - but only through Visual Studio Code. Such bullshit decision smelled so bad that an engineer set out to find a way to get Copilot tokens to use with other tools such as aichat. This is the end result.

cocopilot is a CLI that does one thing, and does it well: retrieves and refreshes GitHub Copilot tokens for tools to interact with its inference APIs. This allows you to feed any tool that supports GitHub Copilot, from CLIs to agents and anything in-between.

The name means two things: first, that it is a co-copilot, as in a third-tier pilot. Second, "cocô" means "poop" in Portuguese, which perfectly represents such bullshit policy that made me create this unnecessary tool in the first place. I bet such "security decision" is for the greater good.

🏁 Getting Started

Using nix: nix run github:wwmoraes/cocopilot. Its also available in my NUR.

🎈 Usage

Run cocopilot, it'll automagically retrieve and return a valid token on the standard output; this may be an existing token, a refreshed token or a new one after asking you to authenticate.

The command is save to use directly as an assignment to environment variables, such as COPILOT_API_KEY for aichat:

env COPILOT_API_KEY=$(cocopilot) aichat --model copilot:gpt-4.1 hi

[!NOTE] aichat in specific requires an openai-compatible client configuration for GitHub Copilot to make the example command above work ;)

Documentation

Overview

Package cocopilot provides bindings to retrieve a GitHub Copilot token to interact with their LLM models. It uses the same public client as Visual Studio Code to authenticate using OAuth to retrieve a device token, and then use that token to get the Copilot one.

Index

Constants

View Source
const (
	// ClientID contains the VSCode client ID, as we need to impersonate it to get
	// a token
	ClientID = "01ab8ac9400c4e429b23"
)

Variables

View Source
var ErrInvalidAPIToken = errors.New("invalid API token")

ErrInvalidAPIToken occurs if the API returns an empty access token

Functions

func NewRequest

func NewRequest(ctx context.Context, token *oauth2.Token) (*http.Request, error)

NewRequest generates a HTTP request that when sent gets a response that contains a session token usable by the Copilot APIs.

Headers are as per VSCode, minus browser-only Sec-Fetch-* ones. It is not clear whether Origin and User-Agent make a functional difference; for the sake of work's "security wizards" BS we send them anyway.

Types

type APIError

type APIError struct {
	URL            string `json:"url,omitempty"`
	Message        string `json:"message,omitempty"`
	Title          string `json:"title,omitempty"`
	NotificationID string `json:"notification_id,omitempty"`
}

APIError contains details about an error response.

func (*APIError) Error

func (err *APIError) Error() string

type AuthorizationResponse

type AuthorizationResponse struct {
	Code             string
	State            string
	ErrorCode        string
	ErrorDescription string
	ErrorURI         string
}

AuthorizationResponse contains the parameters set by the authorization server on the request back to the redirect URI. This includes both the success and error cases, as both are sent over a HTTP 302 Found request.

See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2

func (*AuthorizationResponse) Error

func (response *AuthorizationResponse) Error() error

Error formats the response error if any, otherwise returns nil.

type Code

type Code = string

Code The authorization code generated by the authorization server. See https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2

type GithubDeviceAuthGrantFlowHandler

type GithubDeviceAuthGrantFlowHandler struct {
	context.Context
	// contains filtered or unexported fields
}

GithubDeviceAuthGrantFlowHandler implements an OAuth 2.0 Device Authorization Grant flow handler with GitHub-flavored specifics. It creates a listener and HTTP server to handle the callback.

func (*GithubDeviceAuthGrantFlowHandler) AuthorizationHandler

func (handler *GithubDeviceAuthGrantFlowHandler) AuthorizationHandler(
	authCodeURL string,
) (Code, State, error)

AuthorizationHandler initiates an authorization flow by running a HTTP server and waiting for a callback request.

type Response

type Response struct {
	ErrorDetails *APIError `json:"error_details,omitempty"`
	Message      string    `json:"message,omitempty"`
	Token
}

Response contains the properties of the non-standard token response that Copilot uses.

func (*Response) Parse

func (res *Response) Parse() (*Token, error)

Parse extracts a Copilot token and error from a response.

type State

type State = string

State opaque value used by the client to maintain state between the request and callback. See https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1

type Token

type Token struct {
	// AccessToken contains a session/cookie string, where it sports key-values
	// that looks like this:
	//   tid=...;exp=...;sku=...;...
	//
	// Copilot APIs require this whole value as-is to work.
	AccessToken string `json:"token,omitempty"`
	ExpiresAt   int64  `json:"expires_at,omitempty"`
	RefreshIn   int64  `json:"refresh_in,omitempty"`
}

Token contains a custom token representation from GitHub. It falls short of fitting in a regular oauth2.Token by using a distinct property name for the access token, hence why it is a custom type.

type TokenSource

type TokenSource struct {
	Context         context.Context
	Config          *oauth2.Config
	Handler         authhandler.AuthorizationHandler
	AuthCodeOptions []oauth2.AuthCodeOption
}

TokenSource implements an oauth2.TokenSource to refresh Github API tokens. It uses a device authorization code flow to retrieve the first one.

func NewTokenSource

func NewTokenSource(ctx context.Context) *TokenSource

NewTokenSource initializes a GitHub token source to retrieve/renew its core API token. It uses scopes and redirect URLs as per the upstream Visual Studio Code implementation.

func (*TokenSource) Token

func (source *TokenSource) Token() (*oauth2.Token, error)

Token initializes and handles a device authorization code flow, polling the server to exchange the code for a token.

Directories

Path Synopsis
cmd
cocopilot command
Binary cocopilot uses the homonymous package to retrieve Copilot tokens.
Binary cocopilot uses the homonymous package to retrieve Copilot tokens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL