copilotcli

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package copilotcli is the GitHub Copilot CLI provider: CopilotCLIExecutor drives the Copilot command line as a turn executor for one session CSF owns. Each turn is one Copilot process, started through the ipc/proc capability on the session's identifier, which Copilot creates on the first turn and resumes with its history on every later one.

Every non-ephemeral record Copilot writes is reported to a structured log under the turn's trace, in the record shape the Claude Code turn executor writes. The two records the harness reads back are reported in Claude Code's stream-json shape, with Copilot's own record kept under "copilot": an assistant message becomes an "assistant" event whose tool calls carry the Claude Code tool names, and the turn's result becomes a "result" event carrying the token and cache usage Copilot wrote to its usage file. So a run's log reads the same whichever executor ran the turn.

It is unrelated to ipc/model/copilot, the Copilot Workbench client.

Index

Constants

View Source
const (

	// EventTypeAssistant is an assistant message, in Claude Code's shape.
	EventTypeAssistant = "assistant"
	// EventTypeResult is the event that ends a turn.
	EventTypeResult = "result"
	// EventTypeUser names the prompt the executor was given, in the report
	// only, and a tool's result, both in Claude Code's stream-json user
	// message shape.
	EventTypeUser = "user"
)

Copilot record types the executor reads, and the Claude Code stream-json types and fields it reports them as.

View Source
const DefaultExecutable = "copilot"

DefaultExecutable is the Copilot command line, resolved on PATH.

View Source
const PinnedVersion = "1.0.90"

PinnedVersion is the Copilot CLI version the harness's Copilot sessions were measured on: its flags, record shapes, hook payloads and usage file.

View Source
const ProviderName = "copilotcli"

ProviderName names the Copilot CLI provider in turn reports and proposals.

Variables

View Source
var (
	// ErrNoLauncher reports an executor constructed without the process
	// capability.
	ErrNoLauncher = errors.New("copilotcli executor: a process launcher is required")
	// ErrNoSession reports an executor constructed without a session
	// identifier.
	ErrNoSession = errors.New("copilotcli executor: a nonzero session identifier is required")
	// ErrInvalidOption reports a nil option or an option value the executor
	// cannot use.
	ErrInvalidOption = errors.New("copilotcli executor: invalid option")
	// ErrNoPrompt reports a nil turn or a turn with an empty prompt.
	ErrNoPrompt = errors.New("copilotcli executor: a turn needs a prompt")
	// ErrMalformedEvent reports an output line that is not a Copilot JSON
	// record.
	ErrMalformedEvent = errors.New("copilotcli executor: Copilot wrote a line that is not a JSON record")
	// ErrTurnIncomplete reports a Copilot process that exited without the
	// result record that ends a turn.
	ErrTurnIncomplete = errors.New("copilotcli executor: Copilot exited before reporting the turn's result")
	// ErrTurnFailed reports a result record with a nonzero exit code.
	ErrTurnFailed = errors.New("copilotcli executor: Copilot reported a failed turn")
	// ErrSessionMismatch reports a result for another session than the one
	// the executor runs.
	ErrSessionMismatch = errors.New("copilotcli executor: Copilot reported another session")
	// ErrInterrupted reports a turn whose process Interrupt stopped.
	ErrInterrupted = errors.New("copilotcli executor: the turn was interrupted")
	// ErrClosed reports a turn or an interrupt on a closed executor, and a
	// turn Close stopped.
	ErrClosed = errors.New("copilotcli executor: the executor is closed")
)
View Source
var ErrUntranslatableTool = errors.New("copilotcli executor: the tool rule has no Copilot equivalent")

ErrUntranslatableTool reports a Claude Code tool rule that has no Copilot equivalent. A recipe carrying one cannot run on Copilot: dropping the rule would narrow the session and widening it would break the allowlist.

Functions

This section is empty.

Types

type CopilotCLIExecutor

type CopilotCLIExecutor struct {
	// contains filtered or unexported fields
}

CopilotCLIExecutor runs the turns of one Copilot session, one process per turn. Turns never overlap: Propose waits for the previous turn to finish. Interrupt stops the running turn's process; Close stops it, waits for the turn to return and refuses every later one. The executor starts no goroutine of its own: each turn's process runs, and is reaped, inside the Propose that started it.

func NewCopilotCLIExecutor

func NewCopilotCLIExecutor(launcher proc.ILauncher, session uuid.UUID, options ...CopilotCLIExecutorOption) (*CopilotCLIExecutor, error)

NewCopilotCLIExecutor builds the Copilot turn executor for session. The launcher is the process capability every turn's Copilot process is started through; the caller owns it.

func (*CopilotCLIExecutor) Close

func (executor *CopilotCLIExecutor) Close(ctx context.Context) error

Close stops the running turn, if any, waits for it to return and refuses every later turn. ctx bounds the wait. It is idempotent.

func (*CopilotCLIExecutor) Interrupt

func (executor *CopilotCLIExecutor) Interrupt(ctx context.Context) error

Interrupt stops the running turn's process; the turn returns ErrInterrupted. Between turns there is nothing to stop.

func (*CopilotCLIExecutor) Propose

func (executor *CopilotCLIExecutor) Propose(ctx context.Context, turn *Turn) (*model.Proposal[Event], error)

Propose runs one turn: it starts Copilot on the session with the prompt and returns every record reported for it, in order, ending with the result. ctx bounds the turn's process. A turn that does not reach a successful result returns a *TurnError carrying the records reported before the failure.

func (*CopilotCLIExecutor) Session

func (executor *CopilotCLIExecutor) Session() uuid.UUID

Session is the session identifier CSF gave this executor.

type CopilotCLIExecutorOption

type CopilotCLIExecutorOption func(executor *CopilotCLIExecutor) error

CopilotCLIExecutorOption configures a CopilotCLIExecutor.

func WithArguments

func WithArguments(arguments ...string) CopilotCLIExecutorOption

WithArguments appends arguments to every Copilot invocation, after the flags the executor owns, which may not be repeated.

func WithDirectory

func WithDirectory(directory string) CopilotCLIExecutorOption

WithDirectory runs Copilot in directory instead of the caller's working directory.

func WithEnvironment

func WithEnvironment(variables ...string) CopilotCLIExecutorOption

WithEnvironment appends variables, as NAME=value, to the environment every Copilot process inherits.

func WithExecutable

func WithExecutable(executable string) CopilotCLIExecutorOption

WithExecutable runs Copilot from executable, a path or a name on PATH, instead of DefaultExecutable.

func WithLaunchPrefix

func WithLaunchPrefix(prefix ...string) CopilotCLIExecutorOption

WithLaunchPrefix wraps every Copilot process: the process started is prefix[0], with prefix[1:] ahead of the Copilot executable and its arguments. The session sandbox puts its launcher here.

func WithLogger

func WithLogger(logger *slog.Logger) CopilotCLIExecutorOption

WithLogger reports every turn and record to logger instead of slog.Default().

func WithUsageFile

func WithUsageFile(path string) CopilotCLIExecutorOption

WithUsageFile has every turn write Copilot's usage statistics to path, replaced each turn, and report the tokens and cache usage it holds on the turn's result. Without it the result carries no token counts: Copilot's stream reports none.

type Event

type Event struct {
	Type string
	Raw  json.RawMessage
}

Event is one record the executor reported for a turn: Type is its type and Raw the record as reported.

type ToolGrants

type ToolGrants struct {
	Available []string
	Allowed   []string
	AllPaths  bool
}

ToolGrants is a recipe's tool rules as Copilot takes them: the tools the model is shown (--available-tools) and the permissions it holds without asking (--allow-tool). Nothing else is available, and a permission not granted is denied, since nobody answers a prompt. AllPaths is set when the shell is granted: Copilot also denies a shell command naming a path outside the working directory, which Claude Code's shell rules never do, and a session that may run the shell can reach any path through it anyway.

func TranslateToolRules

func TranslateToolRules(rules []string) (ToolGrants, error)

TranslateToolRules translates Claude Code tool rules into Copilot's grants: "Bash" grants the shell, "Bash(pattern)" the shell for commands matching the pattern, "mcp__server__tool" one MCP tool, and Read, Write, Edit, MultiEdit, Glob and Grep their Copilot tools. Any other rule is ErrUntranslatableTool.

type Turn

type Turn struct {
	Prompt string
}

Turn is what one Copilot turn decides on: the prompt, passed to Copilot unchanged.

type TurnError

type TurnError struct {
	Turn   int
	Events []Event
	Err    error
}

TurnError reports a turn that did not complete. Events holds every record reported before the failure.

func (*TurnError) Error

func (failure *TurnError) Error() string

func (*TurnError) Unwrap

func (failure *TurnError) Unwrap() error

Jump to

Keyboard shortcuts

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