mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-14 12:15:29 +02:00
GitHub Copilot CLI discovers SKILL.md skills from .github/skills/ and custom agents from .github/agents/, so ECC's catalog can be installed there without a conversion step. This adds a managed-project install target that places both. Scope is deliberately limited to agents and skills. ECC hooks are written against Claude Code's event model, and commands rely on slash-command argument substitution Copilot does not provide, so neither is installed. Agent frontmatter goes through an allowlist transform rather than a passthrough: Copilot resolves the session model from user configuration, so a Claude model id makes it warn and fall back on every invocation; Claude tool names are not Copilot tool names, and Copilot governs tool access per session via --allow-tool/--deny-tool. Unknown keys added to ECC agents later therefore cannot leak into the Copilot copy. Target selection stays permissive in supportsModule so dependency-anchor modules still resolve; planOperations is what narrows the install, matching the convention used by the other adapters. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
71 lines
2.7 KiB
JavaScript
71 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
// GitHub Copilot CLI custom agents are markdown files with `name` and
|
|
// `description` frontmatter. Claude Code's agent files additionally carry
|
|
// `model`, `tools`, and `color`, none of which transfer cleanly:
|
|
//
|
|
// model Copilot CLI resolves the session model from user configuration and
|
|
// plan entitlement. Carrying a Claude model id ("opus", "sonnet")
|
|
// makes Copilot emit "specifies model ... which is not available" on
|
|
// every invocation and silently fall back. Dropping the key selects
|
|
// the session default with no warning.
|
|
// tools Claude tool names (Read, Grep, Bash, ...) are not Copilot CLI tool
|
|
// names. Copilot governs tool access at the session level through
|
|
// --allow-tool/--deny-tool, so carrying the Claude list would assert
|
|
// a restriction Copilot does not actually apply.
|
|
// color Claude Code presentation only.
|
|
//
|
|
// The transform is therefore an allowlist rather than a denylist: unknown keys
|
|
// added to ECC agents later cannot silently leak into the Copilot copy.
|
|
const SUPPORTED_FRONTMATTER_KEYS = Object.freeze(['name', 'description']);
|
|
|
|
const REQUIRED_FRONTMATTER_KEYS = Object.freeze(['name', 'description']);
|
|
|
|
function splitFrontmatter(source, label) {
|
|
const match = String(source || '').match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/);
|
|
if (!match) {
|
|
throw new Error(`Cannot adapt Copilot agent ${label}: missing YAML frontmatter`);
|
|
}
|
|
|
|
// Keep YAML loading behind the transform boundary. Public help commands load
|
|
// the installer graph without executing a transform, including in hermetic
|
|
// packed-artifact checks where runtime dependencies are intentionally absent.
|
|
const frontmatter = require('js-yaml').load(match[1]);
|
|
if (!frontmatter || typeof frontmatter !== 'object' || Array.isArray(frontmatter)) {
|
|
throw new Error(`Cannot adapt Copilot agent ${label}: frontmatter must be an object`);
|
|
}
|
|
|
|
return {
|
|
frontmatter,
|
|
body: source.slice(match[0].length),
|
|
};
|
|
}
|
|
|
|
function adaptCopilotAgent(source, label = '<unknown>') {
|
|
const { frontmatter, body } = splitFrontmatter(source, label);
|
|
|
|
for (const key of REQUIRED_FRONTMATTER_KEYS) {
|
|
const value = frontmatter[key];
|
|
if (typeof value !== 'string' || value.trim() === '') {
|
|
throw new Error(`Cannot adapt Copilot agent ${label}: missing required frontmatter "${key}"`);
|
|
}
|
|
}
|
|
|
|
const adapted = {};
|
|
for (const key of SUPPORTED_FRONTMATTER_KEYS) {
|
|
if (Object.hasOwn(frontmatter, key)) {
|
|
adapted[key] = frontmatter[key];
|
|
}
|
|
}
|
|
|
|
const serialized = require('js-yaml')
|
|
.dump(adapted, { lineWidth: -1, noRefs: true })
|
|
.trimEnd();
|
|
return `---\n${serialized}\n---\n${body}`;
|
|
}
|
|
|
|
module.exports = {
|
|
adaptCopilotAgent,
|
|
SUPPORTED_FRONTMATTER_KEYS,
|
|
};
|