Skip to content

feat: add GitHub Copilot CLI support#396

Open
ridermw wants to merge 15 commits intogarrytan:mainfrom
ridermw:add-copilot-cli-support
Open

feat: add GitHub Copilot CLI support#396
ridermw wants to merge 15 commits intogarrytan:mainfrom
ridermw:add-copilot-cli-support

Conversation

@ridermw
Copy link

@ridermw ridermw commented Mar 23, 2026

Summary

Add first-class GitHub Copilot CLI support to gstack. All 28 skills now work with the standalone Copilot CLI (copilot binary, GA February 2026) alongside the existing Claude Code and Codex support.

This is a purely additive change — no existing Claude Code or Codex functionality is altered.

Related: #289 (host integration contract RFC). This PR follows the existing Codex pattern for pragmatic incremental support. If the adapter abstraction from #289 lands, Copilot support can be migrated onto it — the changes here are scoped and self-contained.

Motivation

The GitHub Copilot CLI went GA in February 2026 as a standalone binary, separate from the old gh copilot extension. It has its own config directory (~/.copilot/), session storage (~/.copilot/session-state/{id}/), and skill discovery. gstack should support it as a first-class host so users on Copilot CLI get the same experience as Claude Code and Codex users.

Architecture decisions

  • Copilot shares .agents/skills/ with Codex. Both are non-Claude hosts using the same skill discovery path. Only --host codex is run during generation; Copilot-specific paths (~/.copilot/skills/gstack) are rewritten at setup --host copilot time via sed.
  • Build only runs --host codex, not --host copilot. Running both would overwrite the same .agents/skills/ directory. This avoids the conflict entirely.
  • Session scanning walks subdirectories. Copilot CLI stores sessions as ~/.copilot/session-state/{session-id}/ directories containing events.jsonl and workspace.yaml, not flat files. scanCopilot() walks these subdirs.
  • E2E runner forwards auth. Spawning copilot -p with a temp HOME loses login state. The runner copies config.json and hosts.json from the real ~/.copilot/ to the temp HOME, and GH_TOKEN passes through via env.

Copilot CLI facts

Aspect Value
Binary copilot (standalone, not gh copilot)
Install npm install -g @github/copilot (also: brew, winget, install script)
Config directory ~/.copilot/ (overridable via COPILOT_HOME)
Session data ~/.copilot/session-state/{session-id}/
Interactive mode copilot
One-shot mode copilot -p "prompt"
Requirements Node.js 22+, npm 10+, GitHub Copilot subscription
Docs https://docs.github.com/copilot/how-tos/set-up/install-copilot-cli

Files changed (14)

Core runtime (3 files)

File What changed
scripts/gen-skill-docs.ts Added 'copilot' to Host type, HOST_PATHS, preamble bash. Broadened host === 'codex' gates to include copilot.
setup Added --host copilot with auto-detection via command -v copilot. Full install section copies .agents/skills/ output and rewrites paths via sed.
bin/gstack-global-discover.ts Added scanCopilot() — walks ~/.copilot/session-state/{id}/ subdirectories for events.jsonl and workspace.yaml.

Build & CI (2 files)

File What changed
package.json Added test:copilot scripts. Build does NOT include --host copilot (Codex output covers both).
.github/workflows/skill-docs.yml No separate --host copilot CI check (Codex check covers shared .agents/skills/).

Documentation (5 files)

File What changed
README.md Added Copilot CLI install section and first-class treatment alongside Claude and Codex.
AGENTS.md Updated gen command reference (Copilot derives from Codex at setup time).
CONTRIBUTING.md Renamed "Dual-host" → "Multi-host". 4-column comparison table (Claude | Codex | Copilot). Copilot generation, testing, and new-skill guidance.
CLAUDE.md Updated prereqs to reference standalone Copilot CLI.
CHANGELOG.md Added 0.11.10.0 entry (user-facing style).

Tests (4 files)

File What changed
test/copilot-e2e.test.ts New. E2E test checking copilot --version availability and spawning with skill context.
test/helpers/copilot-session-runner.ts New. Subprocess runner for copilot -p. Copies auth config from real ~/.copilot/ to temp HOME.
test/gen-skill-docs.test.ts Updated assertions to expect command -v copilot in auto-detect output.
test/global-discover.test.ts Added copilot property expectations to session scan results.

Versioning (1 file)

File What changed
VERSION 0.11.9.0 → 0.11.10.0 (upstream took 0.11.9.0 for Codex skill loading fix).

Testing

bun test   # all copilot-specific assertions included in static tests

Copilot E2E tests (test/copilot-e2e.test.ts) require the copilot binary installed and authenticated. They skip gracefully when unavailable.

How to verify

# Check Copilot is recognized as a host
./setup --host copilot

# Verify auto-detection picks up copilot
./setup --host auto   # should list copilot if binary is installed

# Run static tests
bun test

Matthew Williams and others added 15 commits March 23, 2026 12:22
Add 'copilot' as a recognized host type alongside 'claude' and 'codex'.
Copilot uses the same .agents/skills/ output directory and dynamic
GSTACK_ROOT preamble pattern as codex, with ~/.copilot/skills/gstack
as the default global path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add copilot as a recognized host alongside claude, codex, and kiro.
Auto-detection checks for 'gh copilot --version'. Global install
goes to ~/.copilot/skills/gstack following the same pattern as kiro.
Copies .agents/skills/ output and rewrites paths for copilot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 'copilot' as a tool type alongside claude_code, codex, and gemini.
Scans ~/.config/gh-copilot/ for conversation logs. Includes copilot
in all session counts, repo aggregations, and summary output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a Copilot freshness section alongside the existing Codex check.
Runs gen-skill-docs with --host copilot --dry-run to verify generated
files are up to date.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Build script now generates skill docs for copilot host alongside
claude and codex. Package description mentions Copilot CLI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Verify that gen-skill-docs --host copilot succeeds alongside the
existing claude and codex checks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add copilot alongside codex in the multi-agent install section.
Document --host copilot flag and ~/.copilot/skills/ install path.
Add Copilot to the retro global tool list and AGENTS.md gen command.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create copilot-session-runner.ts paralleling codex-session-runner.ts
- Create copilot-e2e.test.ts paralleling codex-e2e.test.ts
- Update gen-skill-docs tests to expect --host copilot support
- Update global-discover tests to expect copilot session property
- Add test:copilot and test:copilot:all npm scripts
- Include copilot-e2e.test.ts in eval/e2e test suites

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename 'Dual-host' section to 'Multi-host', add copilot generation
commands, update comparison table, and add copilot to new skill
instructions and freshness check commands.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add note about gh CLI + copilot extension requirement for the
copilot-e2e.test.ts E2E tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The GitHub Copilot CLI went GA in February 2026 as a standalone binary
(\copilot\) installed via \
pm install -g @github/copilot\. Update all
references from the old gh extension (\gh copilot\) to the new standalone:

- setup: auto-detect via \command -v copilot\ (not gh copilot --version)
- gstack-global-discover: scan ~/.copilot/session-state/ (not ~/.config/gh-copilot/)
- copilot-e2e.test.ts: check for \copilot\ binary, update skip messages
- copilot-session-runner.ts: spawn \copilot -p\ (not gh copilot suggest)
- gen-skill-docs.test.ts: update auto-detect assertion
- CLAUDE.md: update prereqs note

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add Copilot CLI support changelog entry following the project's
user-facing style: what you can now do, not implementation details.
VERSION: 0.11.7.0 → 0.11.9.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expand the host comparison table in CONTRIBUTING.md from 3 columns
(Claude | Codex / Copilot) to 4 columns (Claude | Codex | Copilot)
so each host has its own column. Replace 'Codex/Copilot' shorthand
with explicit enumeration in README.md, CONTRIBUTING.md, setup, and
gen-skill-docs.ts comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fix three issues found in code review:

1. P1: Remove --host copilot from build pipeline, CI, and skill:check.
   Copilot and Codex share .agents/skills/ — running both overwrites
   codex output with copilot-flavored preambles. Copilot-specific paths
   are rewritten at setup time via sed (same pattern as Kiro).

2. P1: Rewrite scanCopilot() to walk session subdirectories.
   Copilot CLI stores sessions as ~/.copilot/session-state/{id}/ dirs
   containing events.jsonl and workspace.yaml, not top-level files.

3. P2: Copy auth config from real ~/.copilot/ to temp HOME in E2E runner.
   Without this, copilot -p in temp HOME loses login state and fails
   instead of running the test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…codex exclusion reason

- Remove '(same pattern as Kiro)' — Kiro isn't documented in CONTRIBUTING.md,
  so referencing it introduces an unexplained concept. Replaced with 'via sed'.
- Change Copilot /codex skill exclusion from 'self-referential' to 'shares
  Codex output' — Copilot ≠ Codex, so 'self-referential' is technically wrong.
  The real reason is Copilot shares Codex's generated .agents/skills/ directory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ayovev
Copy link

ayovev commented Mar 23, 2026

Ha I was just about to spin up a similar PR but you beat me to it; thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants