Skip to content

feat(skillkit,doctor): GitHub Copilot CLI target + doctor probes#491

Draft
elefthei wants to merge 4 commits intoAgent-Field:mainfrom
elefthei:copilot-cli-skillkit
Draft

feat(skillkit,doctor): GitHub Copilot CLI target + doctor probes#491
elefthei wants to merge 4 commits intoAgent-Field:mainfrom
elefthei:copilot-cli-skillkit

Conversation

@elefthei
Copy link
Copy Markdown

@elefthei elefthei commented Apr 20, 2026

Summary

Adds GitHub Copilot CLI as a first-class skill-install target plus af doctor probes, so af skill install covers Copilot the same way it covers Claude Code.

Track B of the two-PR Copilot integration (Track A is #492, the example agent — independent of this PR).

What this PR lands:

  • control-plane/internal/skillkit/target_copilot.go — new copilotTarget that symlinks <canonical current>/ into ~/.copilot/skills/<skill>/. Auto-registers via init(), mirrors target_claude_code.go exactly. Detects the target when ~/.copilot/ exists or the copilot binary is on PATH. Warns on stderr if the same skill is also symlinked into ~/.claude/skills/ (Copilot reads both and dedupes by name).
  • control-plane/internal/cli/doctor.go — new CopilotStatus block in the doctor report. Reports: copilot binary + version, ~/.copilot config-dir presence, last logged-in user, detected auth env-source names (COPILOT_GITHUB_TOKEN, GH_TOKEN, GITHUB_TOKEN — names only, never values), and whether gh auth status exits 0. Ships with an explicit disclaimer that "sources present" ≠ "authenticated" — Copilot rejects classic ghp_* PATs and requires a fine-grained PAT with the "Copilot Requests" permission.
  • README.md — lists "GitHub Copilot CLI" in the Quick Start skill-install target list.
  • research/docs/2026-04-20-*.md — four research docs recording the integration and SDK findings (including the PyPI/repo drift where v0.2.2 doesn't expose AssistantMessageData etc.).

No behaviour change for existing targets; no SDK/server wire changes; no dependencies added.

Testing

  • ./scripts/test-all.sh — skipped (no Go/Python SDK surface changed). Ran the scoped tests instead:
  • Additional verification:
    • go test ./control-plane/internal/skillkit/... — pass (includes new TestCopilotTarget covering detect / install / uninstall / status / symlink redirection).
    • go test ./control-plane/internal/cli/ -run 'Doctor|Helper' — pass.
    • af doctor --json | jq .copilot smoke-tested on dev machine; reports binary + config-dir state correctly.

Checklist

  • I updated documentation where applicable. (README Quick Start + four research/docs/2026-04-20-*.md docs.)
  • I added or updated tests. (control-plane/internal/skillkit/target_copilot_test.go + copilot added to the detected/registered lists in skillkit_test.go.)
  • I updated CHANGELOG.md — new [Unreleased] entry under ### Added.

Screenshots (if UI-related)

Not UI-related.

Related issues

Pairs with #492 (Copilot example agent, independent — merge in either order).

Lef Ioannidis and others added 2 commits April 20, 2026 23:20
Research for adding GitHub Copilot CLI support to AgentField via the
official github/copilot-sdk (Python + Go JSON-RPC clients).

Documents:
- 2026-04-20-copilot-cli-support.md (synthesis + integration design)
- 2026-04-20-sdk-patterns.md (AgentField Python/Go SDK agent shape)
- 2026-04-20-auth-model.md (auth layering + no-secrets-store invariant)
- 2026-04-20-copilot-cli-external-research.md (Copilot CLI v1.0.34 surface)

No code changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Track B of copilot-cli-support plan:

- New skillkit target 'copilot' that symlinks installed skills into
  ~/.copilot/skills/<name>/, mirroring the existing claude-code target.
  Auto-registers in init(). Detected via ~/.copilot/ or 'copilot' on PATH.
- Warns (stderr) when the same skill is already symlinked into
  ~/.claude/skills/ — Copilot CLI reads both locations and dedupes by name,
  but the overlap is surfaced for user visibility.
- 'af doctor' learns a new 'copilot' section reporting:
  * binary presence + version
  * ~/.copilot config dir + last-logged-in user (best-effort parse)
  * auth env *sources* present (COPILOT_GITHUB_TOKEN / GH_TOKEN / GITHUB_TOKEN)
  * gh CLI auth source (gh auth status exit code)
  Intentionally reports 'sources present', not 'authenticated' — Copilot
  rejects classic ghp_ PATs and requires a fine-grained PAT with the
  'Copilot Requests' permission. Disclaimer included in output.
- Unit tests for install/uninstall idempotence, regular-dir replacement,
  and Detected() behavior.

Plan: session workspace plan.md
Rubber-duck findings addressed: Agent-Field#4 (dedup warning), Agent-Field#7 (source-present wording).

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

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Lef Ioannidis seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

PR Agent-Field#491 adds the `copilot` skillkit target that installs
agentfield-multi-reasoner-builder into ~/.copilot/skills/. Advertise it
alongside Claude Code / Codex / Gemini / OpenCode / Aider / Windsurf /
Cursor in the Quick Start so users know `af skill install --all-targets`
(invoked by install.sh) now covers Copilot CLI too.

Docs only; no behaviour change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
elefthei pushed a commit to elefthei/agentfield that referenced this pull request Apr 20, 2026
Tidies six small warts surfaced during self-review. No behaviour change;
all 21 unit tests still pass.

- pyproject.toml: drop unused pydantic>=2.0 dependency
- copilot_session.py: rename _deny_all_handler -> deny_all_handler so it
  can be imported without crossing the leading-underscore boundary; lift
  the nonlocal error_msg declaration out of the SESSION_ERROR branch to
  the top of _on_event and drop the incorrect noqa: PLW0603 (PLW0603 is
  the code for global-statement, not nonlocal); default final_event = None
  before the try block so the post-session read is well-typed even on an
  early error path
- reasoners.py: update import + call sites for the public handler name
- tests/test_copilot_session.py: drop unused monkeypatch fixture in
  test_ask_happy_path; follow handler rename
- README.md: rewrite See-also to reference PR Agent-Field#491 rather than paths that
  only exist on the skillkit branch

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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