Skip to content

Feat - Add GitHub Copilot target (#149)#154

Open
momostallion wants to merge 7 commits into
LobsterTrap:mainfrom
StateFarmIns:feat/copilot-target
Open

Feat - Add GitHub Copilot target (#149)#154
momostallion wants to merge 7 commits into
LobsterTrap:mainfrom
StateFarmIns:feat/copilot-target

Conversation

@momostallion
Copy link
Copy Markdown

@momostallion momostallion commented May 21, 2026

Summary

  • Add GitHub Copilot as a target assistant, enabling lola install <module> -a copilot
  • Skills install to .github/skills/<name>/SKILL.md (project) or ~/.copilot/skills/ (user) with required name + description frontmatter
  • Commands use .prompt.md, agents use .agent.md, MCP at .github/copilot/mcp.json

Related Issues

Fixes #149

Test Plan

  • 31 unit tests covering path resolution (project/user/default scope), skill generation (basic, applyTo, globs, missing source), removal, commands, agents, and target metadata
  • End-to-end tested with lola install rosa-skills -a copilot -s user — skills load in VS Code Copilot Chat

Checklist

  • Tests pass (pytest)
  • Linting passes (ruff check src tests)
  • Type checking passes (ty check)

AI Disclosure

AI-assisted with GitHub Copilot (Claude Opus 4.6)

Summary by CodeRabbit

  • New Features

    • Added GitHub Copilot support for generating skills, commands/prompts, agents, and project instructions with Copilot-compatible metadata and layout.
  • Documentation

    • Updated assistant reference and generation notes to include Copilot and its frontmatter behavior (name and description handling).
  • Tests

    • Added comprehensive tests covering Copilot path scopes, generation success/failure cases, frontmatter handling, filename conventions, and removal/legacy cleanup behaviors.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe84fe9a-d0be-49f3-9e1a-ed0a5f6c179f

📥 Commits

Reviewing files that changed from the base of the PR and between 978b12d and 2e00b4e.

📒 Files selected for processing (3)
  • AGENTS.md
  • src/lola/targets/copilot.py
  • tests/test_copilot_target.py

📝 Walkthrough

Walkthrough

Adds a CopilotTarget implementing GitHub Copilot on-disk layouts (skills, prompts, agents, global instructions, MCP), wires it into TARGETS and exports, updates AGENTS.md, and adds pytest coverage for generation, removal, and path resolution.

Changes

GitHub Copilot target support

Layer / File(s) Summary
CopilotTarget implementation
src/lola/targets/copilot.py
Defines CopilotTarget with scope-aware path helpers; generates skills (SKILL.md) with Copilot YAML frontmatter (name, description, applyTo from applyTo or globs); generates/removes commands (.prompt.md) and agents (.agent.md); performs legacy cleanup and sets name="copilot", supports_agents=True, INSTRUCTIONS_FILE="copilot-instructions.md".
Target registration and documentation
src/lola/targets/__init__.py, AGENTS.md
Imports and registers CopilotTarget in TARGETS["copilot"], exports it in __all__, and documents Copilot's output paths and frontmatter modifications in AGENTS.md.
Test coverage
tests/test_copilot_target.py
Adds pytest tests for project/user/default path resolution; positive/negative skill generation (including missing description, globs→applyTo); command and agent generation and removal; filename helpers; legacy-file cleanup; and CopilotTarget metadata assertions.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant CopilotTarget
  participant FileSystem
  Caller->>CopilotTarget: generate_skill(source_path, dest_path, skill_name)
  CopilotTarget->>FileSystem: read source SKILL.md
  CopilotTarget->>CopilotTarget: parse frontmatter (name, description, applyTo/globs)
  CopilotTarget->>FileSystem: create skill dest dir
  CopilotTarget->>FileSystem: write SKILL.md (Copilot YAML + body)
  CopilotTarget-->>Caller: return True/False

  Caller->>CopilotTarget: remove_skill(dest_path, skill_name)
  CopilotTarget->>FileSystem: delete skill dir and legacy instructions file if present
  CopilotTarget-->>Caller: return True/False

  Caller->>CopilotTarget: generate_command(...)
  CopilotTarget->>FileSystem: write <cmd>.prompt.md (and remove legacy variant on uninstall)
  CopilotTarget-->>Caller: return True/False

  Caller->>CopilotTarget: generate_agent(...)
  CopilotTarget->>FileSystem: write <agent>.agent.md (and remove legacy variant on uninstall)
  CopilotTarget-->>Caller: return True/False
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • SecKatie

Poem

🐰 A Copilot joins the fold,
Skills nest in .github bright and bold,
Prompts and agents find their place,
Frontmatter tended with gentle grace,
One rabbit hops — new paths unfold.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat - Add GitHub Copilot target (#149)' clearly and concisely describes the main change: adding a new Copilot target to the lola tool.
Linked Issues check ✅ Passed The PR implements all core objectives from issue #149: registers 'copilot' target in TARGETS registry, maps skills/commands/agents to Copilot paths, preserves applyTo frontmatter, requires name+description for skills, and includes comprehensive tests validating all functionality.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the GitHub Copilot target feature: new CopilotTarget implementation, target registration, documentation updates, and comprehensive test coverage. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
tests/test_copilot_target.py (1)

193-214: ⚡ Quick win

Add a regression test for legacy .instructions.md cleanup.

There’s no test that verifies removing .../.github/instructions/<skill>.instructions.md. Adding one would guard backward-compat uninstall behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_copilot_target.py` around lines 193 - 214, Add a regression test
that verifies CopilotTarget.remove_skill removes legacy instruction files:
create a test (e.g., test_remove_skill_removes_legacy_instructions) which sets
up tmp_path / "skills" / "my-skill" with SKILL.md and also creates the legacy
file at dest / ".github" / "instructions" / "my-skill.instructions.md", call
CopilotTarget().remove_skill(dest, "my-skill"), assert it returns True and both
the skill_dir and the legacy instructions file no longer exist; this ensures
CopilotTarget.remove_skill handles legacy `.instructions.md` cleanup.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Around line 148-151: Section heading currently claims "Agent frontmatter is
modified during generation" but the Copilot bullet describes changes to skill
frontmatter; update the documentation to avoid the semantic mismatch by either
renaming the section heading to mention both "agent and skill frontmatter" or
moving the Copilot bullet into the relevant "skill frontmatter" section so the
Copilot note references the correct scope; update any nearby headings or bullets
that refer to "agent" only to ensure consistency with the Copilot bullet and
verify the Claude Code and Cursor bullets remain under the agent-focused
portion.

In `@src/lola/targets/copilot.py`:
- Around line 109-114: The legacy_file path is constructed with a duplicated
".github" segment causing paths like ".../.github/.github/instructions/...";
update the construction of legacy_file (the variable currently set from
dest_path.parent / ".github" / "instructions" / f"{skill_name}.instructions.md")
to avoid adding the extra ".github" segment — e.g., use dest_path.parent /
"instructions" / f"{skill_name}.instructions.md" or otherwise derive the correct
repo root so legacy_file points to the single ".github/instructions" location;
modify the assignment of legacy_file accordingly to remove the duplicate
segment.
- Around line 80-90: The code builds Copilot frontmatter with "name +
description" required but currently proceeds when frontmatter["description"] is
missing; update the validation before constructing copilot_fm (using variables
skill_name and frontmatter) to enforce that frontmatter contains a non-empty
"description" — if missing/empty, raise a clear exception or return an error
(e.g., ValueError or a logged failure) to prevent writing SKILL.md with invalid
frontmatter; ensure copilot_fm always includes the description field when
proceeding.

In `@tests/test_copilot_target.py`:
- Around line 110-126: The test test_generate_skill_basic currently writes a
SKILL.md without required frontmatter; update it so the source SKILL.md includes
YAML frontmatter with both name and description (e.g., add a leading/frontmatter
block containing name: my-skill and description: "..." before the body) so
CopilotTarget.generate_skill is exercising the valid contract, then assert
result is True and check that both name and description appear in the generated
file; alternatively, if you intend to test rejection, change the assertion to
expect False and verify no output file was created, but keep the test name and
references to test_generate_skill_basic and CopilotTarget.generate_skill
consistent.

---

Nitpick comments:
In `@tests/test_copilot_target.py`:
- Around line 193-214: Add a regression test that verifies
CopilotTarget.remove_skill removes legacy instruction files: create a test
(e.g., test_remove_skill_removes_legacy_instructions) which sets up tmp_path /
"skills" / "my-skill" with SKILL.md and also creates the legacy file at dest /
".github" / "instructions" / "my-skill.instructions.md", call
CopilotTarget().remove_skill(dest, "my-skill"), assert it returns True and both
the skill_dir and the legacy instructions file no longer exist; this ensures
CopilotTarget.remove_skill handles legacy `.instructions.md` cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 70a605d0-6d82-4a2a-8a1c-4ab30f3cd9a2

📥 Commits

Reviewing files that changed from the base of the PR and between 560efa3 and ade69d5.

📒 Files selected for processing (4)
  • AGENTS.md
  • src/lola/targets/__init__.py
  • src/lola/targets/copilot.py
  • tests/test_copilot_target.py

Comment thread AGENTS.md
Comment thread src/lola/targets/copilot.py
Comment thread src/lola/targets/copilot.py
Comment thread tests/test_copilot_target.py
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lola/targets/copilot.py (1)

109-120: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid early return so legacy skill artifacts are always cleaned up.

Line 112 returns immediately after removing skill_dir, so legacy *.instructions.md cleanup is skipped when both files exist.

Suggested fix
     skill_dir = dest_path / skill_name
+    removed = False
     if skill_dir.exists():
         shutil.rmtree(skill_dir)
-        return True
+        removed = True
     # Legacy cleanup: old .instructions.md format
     legacy_file = (
             dest_path.parent / "instructions" / f"{skill_name}.instructions.md"
     )
     if legacy_file.exists():
         legacy_file.unlink()
-        return True
-    return False
+        removed = True
+    return removed
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lola/targets/copilot.py` around lines 109 - 120, The cleanup currently
returns immediately after removing skill_dir (using shutil.rmtree), skipping
legacy artifact removal; instead, remove the early return and implement a
boolean flag (e.g., removed = False) that is set to True when skill_dir is
removed and again when legacy_file (dest_path.parent / "instructions" /
f"{skill_name}.instructions.md") is unlinked, so both cleanup steps run and the
function returns True if either artifact was removed and False otherwise.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lola/targets/copilot.py`:
- Around line 109-120: The cleanup currently returns immediately after removing
skill_dir (using shutil.rmtree), skipping legacy artifact removal; instead,
remove the early return and implement a boolean flag (e.g., removed = False)
that is set to True when skill_dir is removed and again when legacy_file
(dest_path.parent / "instructions" / f"{skill_name}.instructions.md") is
unlinked, so both cleanup steps run and the function returns True if either
artifact was removed and False otherwise.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5f901f76-3eca-4c42-933d-cd749b25981b

📥 Commits

Reviewing files that changed from the base of the PR and between ade69d5 and add334b.

📒 Files selected for processing (3)
  • AGENTS.md
  • src/lola/targets/copilot.py
  • tests/test_copilot_target.py

@momostallion momostallion force-pushed the feat/copilot-target branch from 0356849 to 978b12d Compare May 25, 2026 01:57
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Line 142: Docs mismatch: the Copilot section of AGENTS.md omits user-scope
command/agent paths in the table and incorrectly states that agent frontmatter
is modified while the implementation's generate_agent is a passthrough. Update
AGENTS.md to add user-scope paths for commands and agents to the table (include
the same user ~/.copilot/skills and ~/.copilot/agents patterns) and change the
frontmatter text to reflect the actual behavior of generate_agent (either state
that generate_agent is passthrough and does not modify frontmatter, or if you
prefer to change behavior instead, implement frontmatter modification inside the
generate_agent code path so the docs and implementation match). Ensure you
reference generate_agent and the "frontmatter" wording in the updated text so
reviewers can verify consistency.

In `@src/lola/targets/copilot.py`:
- Around line 47-53: Both user-scope paths are wrong: update
get_instructions_path to use the Copilot user folder (Path.home() / ".copilot" /
self.INSTRUCTIONS_FILE) instead of "~/.github/<...>", and update get_mcp_path to
write the user MCP to the Copilot user config (when scope == "user" return
Path.home() / ".copilot" / "mcp.json") instead of "~/.github/copilot/mcp.json";
modify the base calculation in both get_instructions_path and get_mcp_path to
choose these user locations when scope == "user".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 324f5be9-4caf-49e0-b447-63327e35267f

📥 Commits

Reviewing files that changed from the base of the PR and between 0356849 and 978b12d.

📒 Files selected for processing (4)
  • AGENTS.md
  • src/lola/targets/__init__.py
  • src/lola/targets/copilot.py
  • tests/test_copilot_target.py

Comment thread AGENTS.md Outdated
Comment thread src/lola/targets/copilot.py Outdated
@mrbrandao mrbrandao added enhancement New feature or request good first issue Good for newcomers labels May 25, 2026
@mrbrandao mrbrandao requested a review from SecKatie May 25, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] - Add GitHub Copilot target

3 participants