Node.js client for GitHub Copilot CLI with both a raw ACP transport wrapper and a higher-level structured session/turn API.
npm install @raylin01/copilot-client- Node.js 18+
- GitHub Copilot CLI installed and authenticated, or runnable through
npx @github/copilot
import { CopilotClient } from '@raylin01/copilot-client';
const client = await CopilotClient.init({
cwd: process.cwd(),
model: 'gpt-5-mini'
});
const turn = client.send('Hello Copilot. Give me a short intro.');
for await (const update of turn.updates()) {
if (update.kind === 'output' && update.snapshot.currentOutputKind === 'text') {
process.stdout.write(`\r${update.snapshot.text}`);
}
if (update.kind === 'request') {
await client.approveRequest(update.snapshot.openRequests.at(-1)!.id);
}
}
const finalSnapshot = await turn.done;
process.stdout.write(`\n\nStop reason: ${finalSnapshot.result?.stopReason || 'unknown'}\n`);
await client.close();If Copilot CLI is not on your PATH, you can use npx instead:
const client = await CopilotClient.init({
cwd: process.cwd(),
model: 'gpt-5-mini',
executable: 'npx',
executableArgs: ['-y'],
copilotPath: '@github/copilot'
});CopilotClient.init(options)starts Copilot CLI in ACP mode and returns aStructuredCopilotClientclient.send(input, options?)returns a turn handle immediatelyturn.current(),turn.history(),turn.updates(), andturn.doneexpose normalized turn stateclient.getOpenRequests()returns pending permission requestsclient.approveRequest(...),client.denyRequest(...), andclient.cancelRequest(...)resolve Copilot approval prompts
The structured permission helper prefers actual ACP shapes over invented scopes:
- use
scope: 'once' | 'always'when you want the coarse helper - inspect
request.optionswhen you need the underlying provider-native option kinds directly
The sessions subpath reads persisted Copilot CLI session state and normalizes it into a provider-neutral transcript.
import {
listCopilotSessionSummaries,
readCopilotSessionRecord
} from '@raylin01/copilot-client/sessions';
const summaries = await listCopilotSessionSummaries({
projectPath: process.cwd()
});
const latest = summaries[0];
if (latest) {
const record = await readCopilotSessionRecord(latest.id, {
projectPath: process.cwd()
});
console.log('Session:', record.summary.id);
console.log('Workspace summary:', record.rawSession.summary);
for (const message of record.transcript) {
console.log(message.role, message.content.map((block) => block.type));
}
}These helpers inspect the persisted Copilot state under ~/.copilot/session-state, while still returning rawSession, rawMessages, and normalized transcript data together.
If you need direct access to Copilot CLI over ACP, the original new CopilotClient(...) API is unchanged.
ready: ACP session established withsessionIdsession_update: raw ACP session updaterequest_permission: Copilot requested approval for a tool callstderr,error,exit
See /examples:
basic.ts
- This package uses Copilot CLI's public preview ACP server rather than scraping terminal output.
- The default testing model used in examples is
gpt-5-mini.
ISC