GitHub Copilot setup
Why Github Copilot?
- Currently the
ai@1task supports only one provider. More providers to come in future. - So every
ai@1task runs using Github Copilot SDK which in turn needs Copilot Cli
Prerequisites for GHCP
- Run
npm install -g @github/copilot - Run
Get-ChildItem "$env:APPDATA\npm\node_modules\@github" -Recurse -Filter copilot.exe -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName - Run
[Environment]::SetEnvironmentVariable("COPILOT_CLI_PATH", "PASTE_THE_PATH_HERE", "User")
Why it is not bundled
The CLI is roughly 340 MB per platform, across eight platforms.
Pointing at a copy you already have
If the CLI is somewhere that is not on PATH, name it:
tasks:
draft:
uses: ai@1
env:
COPILOT_CLI_PATH: D:\tools\copilot\copilot.exe
args:
prompt: Summarise the commits since the last tag.
COPILOT_CLI_PATH is honoured wherever an environment variable can be
set — the task’s env:, your shell, or the machine. A copy installed
beside the SDK is found automatically, so most people never set it.
Point it at the executable, not at a .js file. Inside VS Code a
.js entry point gets launched through Code.exe, the CLI’s argument
parser mistakes that for Electron, and the run dies with
error: too many arguments. Expected 0 arguments but got 1.
What you do not need
The GitHub Copilot VS Code extension. Nothing here calls it. A machine with it installed and signed in still needs the CLI; a machine without it works fine with the CLI.
Copilot is also deliberately not declared as an extension dependency — that field force-installs it, and you should not get Copilot pushed onto you for tasks you may never write.
What ai@1 hands to ghcp
Every setting on the task is passed straight through. ghcp adds no
settings of its own, which is what makes swapping a vendor one line.
| On the task | What ghcp does with it |
|---|---|
model: |
the model the session runs on. auto lets the provider pick |
attachments: |
files handed over by absolute path, with name as what the agent sees them called - build one from ${{ home }} or ${{ workspaceDir }} |
env: |
layered over the environment the CLI child gets — see below |
the task’s cwd |
the session’s working directory. One client per session, so two tasks can work in different folders at once |
| anything else | handed to the runtime as written, under its own name — systemMessage:, availableTools:, excludedTools:, and whatever it grows next |
The one exception is mcpServers: — the engine removes it. MCP servers
are declared in ai.mcpServers in
.local-workflows/settings.json,
alongside the Copilot CLI’s own discovery files
(~/.copilot/mcp-config.json, .mcp.json, .github/mcp.json) — never
in a workflow file; see
MCP servers.
That last row is the whole shape of this plugin. ai@1 declares only
what the engine does with a session; the rest is the runtime’s own
vocabulary, so a session option shipped last month is usable today
without a new build here.
Full arg table and the MCP guidance:
ai@1.
Model names
They are the provider’s vocabulary, not this extension’s. ai@1
passes the string through and never validates it. model: auto is the
sane default — a pinned name goes stale.
The environment the CLI child gets
Three layers, in this order:
- The whole of the editor’s environment. Merged, never replaced —
handing the child only the task’s declared
env:left it with noPATHand noAPPDATA, so it could not even find your Copilot sign-in. - The task’s own
env:, layered on top. The same order arun:task gets. COPILOT_CLI_PATHresolved to the native binary, andELECTRON_RUN_AS_NODE=1. Both are set for you.
Next
- Your first spec — the first thing that needs all of the above.
ai@1— the args the engine declares, and what happens to the ones it does not.- SDD config — setting
provider:andmodel:once for every phase.