@michaelfromyeg/loom-adapter-copilot 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,11 +16,11 @@ function readJson(path) {
16
16
  }
17
17
  }
18
18
  function subdirsWith(dir, marker) {
19
- if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];
19
+ if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];
20
20
  return readdirSync(dir).filter((n) => statSync(join(dir, n)).isDirectory() && existsSync(join(dir, n, marker))).sort();
21
21
  }
22
22
  function filesWithExt(dir, ext) {
23
- if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];
23
+ if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];
24
24
  return readdirSync(dir).filter((n) => n.endsWith(ext) && statSync(join(dir, n)).isFile()).sort();
25
25
  }
26
26
  function copyTree(srcDir, destPrefix, kind) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/import.ts","../src/mcp.ts","../src/index.ts"],"names":["author","json","artifact","join"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type ImportedMarketplace,\n type ImportedPlugin,\n type ImportOptions,\n type ImportResult,\n} from \"@michaelfromyeg/loom-adapter-kit\";\nimport type { Component, Marketplace, Plugin } from \"@michaelfromyeg/loom-schema\";\nimport type { McpServerConfig } from \"./mcp\";\n\nconst MCP_SCHEMA = \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction readJson(path: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\n/** Subdirectories of `dir` that contain `marker`. */\nfunction subdirsWith(dir: string, marker: string): string[] {\n if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];\n return readdirSync(dir)\n .filter((n) => statSync(join(dir, n)).isDirectory() && existsSync(join(dir, n, marker)))\n .sort();\n}\n\nfunction filesWithExt(dir: string, ext: string): string[] {\n if (!existsSync(dir) || !statSync(dir).isDirectory()) return [];\n return readdirSync(dir)\n .filter((n) => n.endsWith(ext) && statSync(join(dir, n)).isFile())\n .sort();\n}\n\nfunction copyTree(\n srcDir: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const out: CompiledArtifact[] = [];\n const walk = (d: string) => {\n for (const n of readdirSync(d).sort()) {\n const abs = join(d, n);\n if (statSync(abs).isDirectory()) walk(abs);\n else\n out.push(artifact(`${destPrefix}/${relative(srcDir, abs)}`, readFileSync(abs), { kind }));\n }\n };\n walk(srcDir);\n return out;\n}\n\n/** A Loom source string from a Copilot marketplace `source` (string or object). */\nfunction sourceToString(source: unknown): string {\n if (typeof source === \"string\") return source;\n const s = source as Record<string, unknown>;\n switch (s?.source) {\n case \"github\":\n return `github:${s.repo}${s.ref ? `#${s.ref}` : \"\"}`;\n case \"url\":\n case \"git-subdir\":\n return String(s.url);\n case \"npm\":\n return `npm:${s.package}${s.version ? `@${s.version}` : \"\"}`;\n default:\n return String(source);\n }\n}\n\n/**\n * Reconstruct an MCP-standard server.json from a Copilot `mcpServers` run config\n * (lossy but functional). Only used when there is NO verbatim mcp/<leaf>/server.json\n * to copy. Copilot's per-server shape: `type` local|stdio|http|sse; command/args/env\n * for local|stdio; url/headers for http|sse.\n */\nfunction synthesizeServerJson(namespace: string, name: string, cfg: McpServerConfig): unknown {\n const base = {\n $schema: MCP_SCHEMA,\n name: `${namespace}/${name}`,\n description: `Imported ${name} MCP server.`,\n version: \"0.0.0\",\n };\n // Remote transport (http|sse + url).\n if (cfg.url) {\n const type = cfg.type === \"sse\" ? \"sse\" : \"streamable-http\";\n const headers =\n cfg.headers && Object.keys(cfg.headers).length\n ? Object.entries(cfg.headers).map(([n, value]) => ({ name: n, value }))\n : undefined;\n return {\n ...base,\n remotes: [{ type, url: cfg.url, ...(headers ? { headers } : {}) }],\n };\n }\n // npm-style local: command npx + a bare package identifier in args.\n if (cfg.command === \"npx\" && Array.isArray(cfg.args)) {\n const ident = cfg.args.find((a) => a !== \"-y\" && !a.startsWith(\"-\"));\n if (ident) {\n const at = ident.lastIndexOf(\"@\");\n const id = at > 0 ? ident.slice(0, at) : ident;\n const version = at > 0 ? ident.slice(at + 1) : undefined;\n return {\n ...base,\n packages: [\n {\n registryType: \"npm\",\n identifier: id,\n ...(version ? { version } : {}),\n transport: { type: \"stdio\" },\n },\n ],\n };\n }\n }\n // Bare local command.\n return {\n ...base,\n ...(cfg.command ? { command: cfg.command } : {}),\n ...(cfg.args ? { args: cfg.args } : {}),\n ...(cfg.env ? { env: cfg.env } : {}),\n };\n}\n\nfunction importPlugin(\n dir: string,\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedPlugin {\n const components: Component[] = [];\n const files: CompiledArtifact[] = [];\n\n for (const sk of subdirsWith(join(dir, \"skills\"), \"SKILL.md\")) {\n components.push({ skill: `skills/${sk}` });\n files.push(...copyTree(join(dir, \"skills\", sk), `skills/${sk}`, \"skill\"));\n }\n // Copilot agents are agents/<name>.agent.md.\n for (const f of filesWithExt(join(dir, \"agents\"), \".agent.md\")) {\n components.push({ agent: `agents/${f}` });\n files.push(artifact(`agents/${f}`, readFileSync(join(dir, \"agents\", f)), { kind: \"agent\" }));\n }\n for (const f of filesWithExt(join(dir, \"commands\"), \".md\")) {\n components.push({ command: `commands/${f}` });\n files.push(\n artifact(`commands/${f}`, readFileSync(join(dir, \"commands\", f)), { kind: \"command\" }),\n );\n }\n\n // MCP: prefer a verbatim mcp/<leaf>/server.json (a Loom-built plugin carries one);\n // only reconstruct from the native run config when there is no mcp/ dir.\n if (existsSync(join(dir, \"mcp\"))) {\n for (const leaf of subdirsWith(join(dir, \"mcp\"), \"server.json\")) {\n components.push({ mcp: `mcp/${leaf}` });\n files.push(\n artifact(`mcp/${leaf}/server.json`, readFileSync(join(dir, \"mcp\", leaf, \"server.json\")), {\n kind: \"mcp\",\n }),\n );\n }\n } else {\n const mcpServers =\n (manifest.mcpServers as Record<string, McpServerConfig> | undefined) ??\n (readJson(join(dir, \"mcp-config.json\"))?.mcpServers as Record<string, McpServerConfig>) ??\n {};\n for (const [serverName, cfg] of Object.entries(mcpServers)) {\n components.push({ mcp: `mcp/${serverName}` });\n files.push(\n artifact(\n `mcp/${serverName}/server.json`,\n json(synthesizeServerJson(namespace, serverName, cfg)),\n { kind: \"mcp\" },\n ),\n );\n }\n }\n\n const authorRaw = manifest.author;\n const author =\n typeof authorRaw === \"string\"\n ? { name: authorRaw }\n : (authorRaw as { name?: string; email?: string } | undefined);\n const plugin: Plugin = {\n name: String(manifest.name),\n version: String(manifest.version ?? \"0.1.0\"),\n owner: {\n name: author?.name ?? String(manifest.name),\n namespace,\n ...(author?.email ? { email: author.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n components,\n };\n return { kind: \"plugin\", plugin, files };\n}\n\nfunction importMarketplace(\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedMarketplace {\n const ownerRaw = manifest.owner;\n const owner =\n typeof ownerRaw === \"string\"\n ? { name: ownerRaw }\n : (ownerRaw as { name?: string; email?: string } | undefined);\n const plugins = ((manifest.plugins as Array<Record<string, unknown>>) ?? []).map((p) => ({\n plugin: sourceToString(p.source),\n ...(p.version ? { version: String(p.version) } : {}),\n ...(p.category ? { category: String(p.category) } : {}),\n ...(Array.isArray(p.tags) ? { tags: p.tags as string[] } : {}),\n }));\n const marketplace: Marketplace = {\n name: String(manifest.name),\n owner: {\n name: owner?.name ?? String(manifest.name),\n namespace,\n ...(owner?.email ? { email: owner.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n plugins,\n };\n return { kind: \"marketplace\", marketplace };\n}\n\n/** Copilot's four plugin.json search locations (research §Copilot). */\nconst MANIFEST_PATHS = [\n [\"plugin.json\"],\n [\".plugin\", \"plugin.json\"],\n [\".github\", \"plugin\", \"plugin.json\"],\n [\".claude-plugin\", \"plugin.json\"],\n];\n\n/** Reverse-compile a GitHub Copilot plugin or marketplace dir into the Loom model. */\nexport function importCopilot(dir: string, opts?: ImportOptions): ImportResult | null {\n const namespace = opts?.namespace ?? \"com.imported\";\n const marketplace = readJson(join(dir, \".copilot-plugin\", \"marketplace.json\"));\n if (marketplace) return importMarketplace(marketplace, namespace);\n\n for (const segs of MANIFEST_PATHS) {\n const manifest = readJson(join(dir, ...segs));\n if (manifest) return importPlugin(dir, manifest, namespace);\n }\n\n // No manifest, but a bare plugin layout (skills/ etc.) is still importable.\n if (existsSync(join(dir, \"skills\"))) {\n return importPlugin(dir, { name: \"imported-plugin\" }, namespace);\n }\n return null;\n}\n","/**\n * Derives a runnable Copilot `mcpServers` entry from an MCP-standard `server.json`\n * (the registry's ServerJSON shape: packages[] / remotes[] / a bare command).\n * Stored standards stay verbatim in the plugin; this is the tool-specific view.\n *\n * Copilot's per-server shape (verified, research §Copilot): `type` is one of\n * `local|stdio|http|sse`; `command`+`args`+`env` for local/stdio; `url`+`headers`\n * for http/sse; `tools` is `\"*\"` or an explicit list.\n */\n\nexport interface McpServerConfig {\n type: \"local\" | \"stdio\" | \"http\" | \"sse\";\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n tools?: string[] | \"*\";\n}\n\ninterface McpPackage {\n registryType?: string;\n identifier?: string;\n version?: string;\n transport?: { type?: string };\n}\ninterface McpRemote {\n type?: string;\n url?: string;\n headers?: Array<{ name: string; value: string }>;\n}\ninterface ServerJson {\n name?: string;\n packages?: McpPackage[];\n remotes?: McpRemote[];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** The short server key Copilot uses (the part after the reverse-DNS namespace). */\nexport function mcpServerName(server: ServerJson): string {\n const raw = server.name ?? \"server\";\n const afterSlash = raw.includes(\"/\") ? raw.slice(raw.lastIndexOf(\"/\") + 1) : raw;\n return afterSlash || \"server\";\n}\n\nconst RUNNERS: Record<string, string> = { npm: \"npx\", pypi: \"uvx\" };\n\nexport function mcpRunConfig(server: ServerJson): McpServerConfig {\n const pkg = server.packages?.[0];\n if (pkg?.identifier) {\n if (pkg.registryType === \"oci\") {\n return {\n type: \"local\",\n command: \"docker\",\n args: [\"run\", \"-i\", \"--rm\", pkg.identifier],\n tools: [\"*\"],\n };\n }\n const runner = RUNNERS[pkg.registryType ?? \"npm\"] ?? \"npx\";\n const ident = pkg.version ? `${pkg.identifier}@${pkg.version}` : pkg.identifier;\n const args = runner === \"npx\" ? [\"-y\", ident] : [ident];\n return { type: \"local\", command: runner, args, tools: [\"*\"] };\n }\n\n const remote = server.remotes?.[0];\n if (remote?.url) {\n // Copilot uses http|sse for remote transports; the MCP registry's\n // \"streamable-http\" maps to \"http\".\n const type = remote.type === \"sse\" ? \"sse\" : \"http\";\n const config: McpServerConfig = { type, url: remote.url, tools: [\"*\"] };\n if (remote.headers?.length) {\n config.headers = Object.fromEntries(remote.headers.map((h) => [h.name, h.value]));\n }\n return config;\n }\n\n if (server.command) {\n const config: McpServerConfig = { type: \"local\", command: server.command, tools: [\"*\"] };\n if (server.args) config.args = server.args;\n if (server.env) config.env = server.env;\n return config;\n }\n\n return {\n type: \"local\",\n command: \"echo\",\n args: [\"server.json declares no runnable transport\"],\n tools: [\"*\"],\n };\n}\n","import { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type HarnessAdapter,\n type InstallPaths,\n type PluginCtx,\n type ResolvedMarketplace,\n} from \"@michaelfromyeg/loom-adapter-kit\";\nimport {\n type Component,\n kindOf,\n leafNameOf,\n type Plugin,\n refOf,\n type Scope,\n} from \"@michaelfromyeg/loom-schema\";\nimport { importCopilot } from \"./import\";\nimport { type McpServerConfig, mcpRunConfig, mcpServerName } from \"./mcp\";\n\n/**\n * Bump on any change to Copilot's plugin/marketplace manifest shape (spec §5).\n *\n * NOTE for the future driver: Copilot has NO structured headless trace. `copilot -p`\n * only emits a markdown transcript via `--share`/`--share-gist`; `--output-format`/\n * `--json` exist only on `copilot mcp` subcommands. A driver must degrade `trace`\n * assertions to `output` assertions (research §Copilot).\n */\nconst TARGET_SCHEMA = \"copilot-plugin/1\";\n\ninterface CopilotAuthor {\n name: string;\n email?: string;\n}\ninterface CopilotPluginManifest {\n name: string;\n description?: string;\n version?: string;\n author?: CopilotAuthor;\n mcpServers?: Record<string, McpServerConfig>;\n}\ninterface CopilotMarketplacePlugin {\n name: string;\n source: string;\n description?: string;\n version?: string;\n category?: string;\n tags?: string[];\n}\ninterface CopilotMarketplace {\n name: string;\n owner: CopilotAuthor;\n description?: string;\n plugins: CopilotMarketplacePlugin[];\n}\n\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction author(name: string, email?: string): CopilotAuthor {\n return email ? { name, email } : { name };\n}\n\n/** Copy every file under a plugin dir into `destPrefix/`, preserving structure. */\nfunction copyDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n return ctx.list(ref).map((file) => {\n const within = file.startsWith(`${ref}/`) ? file.slice(ref.length + 1) : basename(file);\n return artifact(`${destPrefix}/${within}`, ctx.read(file), { kind });\n });\n}\n\n/** Place a component that may be a single Markdown file or a directory. */\nfunction copyFileOrDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n ext: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const files = ctx.list(ref);\n if (files.length === 0) {\n // ref is a single file (e.g. agents/code-review.md). Use the harness-required\n // extension (e.g. .agent.md), not the source file's -- `destPrefix` already\n // ends in the extension-stripped leaf name.\n return [artifact(`${destPrefix}${ext}`, ctx.read(ref), { kind })];\n }\n return copyDir(ctx, ref, destPrefix, kind);\n}\n\nexport const copilotAdapter: HarnessAdapter = {\n target: \"copilot\",\n version: \"0.1.0\",\n targetSchema: TARGET_SCHEMA,\n\n detect(scope: Scope, cwd: string): InstallPaths {\n // Real Copilot keys its config dir off COPILOT_HOME (default ~/.copilot) and\n // has no official project scope. We honor COPILOT_HOME for user scope and treat\n // project scope as <cwd>/.copilot best-effort.\n // TODO(verify): project-scoped <cwd>/.copilot is unconfirmed -- Copilot only\n // documents COPILOT_HOME (no per-project config dir and no --config-dir flag).\n const userRoot = process.env.COPILOT_HOME ?? join(homedir(), \".copilot\");\n const root = scope === \"user\" ? userRoot : join(cwd, \".copilot\");\n return {\n root,\n plugins: join(root, \"installed-plugins\"),\n skills: join(root, \"skills\"),\n // mcp-config.json lives at the config-dir root, so `mcp` points at root.\n mcp: root,\n agents: join(root, \"agents\"),\n // TODO(verify): commands/ dir is best-effort; Copilot docs list skills/agents/\n // hooks/mcp-config.json but do not confirm a top-level commands/ directory.\n commands: join(root, \"commands\"),\n hooks: join(root, \"hooks\"),\n catalog: root,\n };\n },\n\n transform(component: Component, ctx: PluginCtx): CompiledArtifact[] {\n const ref = refOf(component);\n const leaf = leafNameOf(component);\n switch (kindOf(component)) {\n case \"skill\":\n // skills/<name>/SKILL.md (+ any sibling assets), copied verbatim.\n return copyDir(ctx, ref, `skills/${leaf}`, \"skill\");\n case \"agent\":\n // CONFIRMED extension: agents/<name>.agent.md.\n return copyFileOrDir(ctx, ref, `agents/${leaf}`, \".agent.md\", \"agent\");\n case \"command\":\n // TODO(verify): commands/<leaf>.md placement is best-effort (see detect()).\n return copyFileOrDir(ctx, ref, `commands/${leaf}`, \".md\", \"command\");\n case \"hook\":\n return copyFileOrDir(ctx, ref, `hooks/${leaf}`, \".md\", \"hook\");\n case \"mcp\":\n // Verbatim provenance copy; the runnable config goes inline in plugin.json.\n return copyDir(ctx, ref, `mcp/${leaf}`, \"mcp\");\n case \"passthrough\":\n return [\n artifact(`hooks/${basename(ref)}`, ctx.read(ref), { kind: \"hook\", executable: true }),\n ];\n default:\n return [];\n }\n },\n\n emitManifest(plugin: Plugin, ctx: PluginCtx): CompiledArtifact[] {\n const manifest: CopilotPluginManifest = {\n name: plugin.name,\n version: plugin.version,\n author: author(plugin.owner.name, plugin.owner.email),\n };\n if (plugin.description) manifest.description = plugin.description;\n\n const mcpServers: Record<string, McpServerConfig> = {};\n for (const c of plugin.components) {\n if (kindOf(c) !== \"mcp\") continue;\n try {\n const server = JSON.parse(ctx.read(`${refOf(c)}/server.json`).toString(\"utf8\"));\n mcpServers[mcpServerName(server)] = mcpRunConfig(server);\n } catch {\n // validate.ts already surfaced an error for an unparsable server.json.\n }\n }\n if (Object.keys(mcpServers).length > 0) manifest.mcpServers = mcpServers;\n\n // plugin.json AT PLUGIN ROOT -- one of Copilot's four search locations\n // (.plugin/, root, .github/plugin/, .claude-plugin/).\n return [artifact(\"plugin.json\", json(manifest), { kind: \"manifest\" })];\n },\n\n emitCatalog(marketplace: ResolvedMarketplace): CompiledArtifact[] {\n const plugins: CopilotMarketplacePlugin[] = marketplace.entries.map((entry) => {\n const entryPlugin: CopilotMarketplacePlugin = {\n name: entry.name,\n source: entry.source.startsWith(\"./\") ? entry.source : `./${entry.source}`,\n };\n if (entry.description) entryPlugin.description = entry.description;\n if (entry.version) entryPlugin.version = entry.version;\n if (entry.category) entryPlugin.category = entry.category;\n if (entry.tags) entryPlugin.tags = entry.tags;\n return entryPlugin;\n });\n\n const catalog: CopilotMarketplace = {\n name: marketplace.name,\n owner: author(marketplace.owner.name, marketplace.owner.email),\n plugins,\n };\n if (marketplace.description) catalog.description = marketplace.description;\n\n // TODO(verify): Copilot's marketplace.json shape is NOT documented. This is a\n // best-effort manifest mirroring Claude's { name, owner, plugins[] }. The exact\n // field names and file location (.copilot-plugin/ vs root) are unconfirmed.\n return [artifact(\".copilot-plugin/marketplace.json\", json(catalog), { kind: \"catalog\" })];\n },\n\n importNative: importCopilot,\n};\n\nexport default copilotAdapter;\n"]}
1
+ {"version":3,"sources":["../src/import.ts","../src/mcp.ts","../src/index.ts"],"names":["author","json","artifact","join"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type ImportedMarketplace,\n type ImportedPlugin,\n type ImportOptions,\n type ImportResult,\n} from \"@michaelfromyeg/loom-adapter-kit\";\nimport type { Component, Marketplace, Plugin } from \"@michaelfromyeg/loom-schema\";\nimport type { McpServerConfig } from \"./mcp\";\n\nconst MCP_SCHEMA = \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction readJson(path: string): Record<string, unknown> | null {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\n/** Subdirectories of `dir` that contain `marker`. */\nfunction subdirsWith(dir: string, marker: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => statSync(join(dir, n)).isDirectory() && existsSync(join(dir, n, marker)))\n .sort();\n}\n\nfunction filesWithExt(dir: string, ext: string): string[] {\n if (!(existsSync(dir) && statSync(dir).isDirectory())) return [];\n return readdirSync(dir)\n .filter((n) => n.endsWith(ext) && statSync(join(dir, n)).isFile())\n .sort();\n}\n\nfunction copyTree(\n srcDir: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const out: CompiledArtifact[] = [];\n const walk = (d: string) => {\n for (const n of readdirSync(d).sort()) {\n const abs = join(d, n);\n if (statSync(abs).isDirectory()) walk(abs);\n else\n out.push(artifact(`${destPrefix}/${relative(srcDir, abs)}`, readFileSync(abs), { kind }));\n }\n };\n walk(srcDir);\n return out;\n}\n\n/** A Loom source string from a Copilot marketplace `source` (string or object). */\nfunction sourceToString(source: unknown): string {\n if (typeof source === \"string\") return source;\n const s = source as Record<string, unknown>;\n switch (s?.source) {\n case \"github\":\n return `github:${s.repo}${s.ref ? `#${s.ref}` : \"\"}`;\n case \"url\":\n case \"git-subdir\":\n return String(s.url);\n case \"npm\":\n return `npm:${s.package}${s.version ? `@${s.version}` : \"\"}`;\n default:\n return String(source);\n }\n}\n\n/**\n * Reconstruct an MCP-standard server.json from a Copilot `mcpServers` run config\n * (lossy but functional). Only used when there is NO verbatim mcp/<leaf>/server.json\n * to copy. Copilot's per-server shape: `type` local|stdio|http|sse; command/args/env\n * for local|stdio; url/headers for http|sse.\n */\nfunction synthesizeServerJson(namespace: string, name: string, cfg: McpServerConfig): unknown {\n const base = {\n $schema: MCP_SCHEMA,\n name: `${namespace}/${name}`,\n description: `Imported ${name} MCP server.`,\n version: \"0.0.0\",\n };\n // Remote transport (http|sse + url).\n if (cfg.url) {\n const type = cfg.type === \"sse\" ? \"sse\" : \"streamable-http\";\n const headers =\n cfg.headers && Object.keys(cfg.headers).length\n ? Object.entries(cfg.headers).map(([n, value]) => ({ name: n, value }))\n : undefined;\n return {\n ...base,\n remotes: [{ type, url: cfg.url, ...(headers ? { headers } : {}) }],\n };\n }\n // npm-style local: command npx + a bare package identifier in args.\n if (cfg.command === \"npx\" && Array.isArray(cfg.args)) {\n const ident = cfg.args.find((a) => a !== \"-y\" && !a.startsWith(\"-\"));\n if (ident) {\n const at = ident.lastIndexOf(\"@\");\n const id = at > 0 ? ident.slice(0, at) : ident;\n const version = at > 0 ? ident.slice(at + 1) : undefined;\n return {\n ...base,\n packages: [\n {\n registryType: \"npm\",\n identifier: id,\n ...(version ? { version } : {}),\n transport: { type: \"stdio\" },\n },\n ],\n };\n }\n }\n // Bare local command.\n return {\n ...base,\n ...(cfg.command ? { command: cfg.command } : {}),\n ...(cfg.args ? { args: cfg.args } : {}),\n ...(cfg.env ? { env: cfg.env } : {}),\n };\n}\n\nfunction importPlugin(\n dir: string,\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedPlugin {\n const components: Component[] = [];\n const files: CompiledArtifact[] = [];\n\n for (const sk of subdirsWith(join(dir, \"skills\"), \"SKILL.md\")) {\n components.push({ skill: `skills/${sk}` });\n files.push(...copyTree(join(dir, \"skills\", sk), `skills/${sk}`, \"skill\"));\n }\n // Copilot agents are agents/<name>.agent.md.\n for (const f of filesWithExt(join(dir, \"agents\"), \".agent.md\")) {\n components.push({ agent: `agents/${f}` });\n files.push(artifact(`agents/${f}`, readFileSync(join(dir, \"agents\", f)), { kind: \"agent\" }));\n }\n for (const f of filesWithExt(join(dir, \"commands\"), \".md\")) {\n components.push({ command: `commands/${f}` });\n files.push(\n artifact(`commands/${f}`, readFileSync(join(dir, \"commands\", f)), { kind: \"command\" }),\n );\n }\n\n // MCP: prefer a verbatim mcp/<leaf>/server.json (a Loom-built plugin carries one);\n // only reconstruct from the native run config when there is no mcp/ dir.\n if (existsSync(join(dir, \"mcp\"))) {\n for (const leaf of subdirsWith(join(dir, \"mcp\"), \"server.json\")) {\n components.push({ mcp: `mcp/${leaf}` });\n files.push(\n artifact(`mcp/${leaf}/server.json`, readFileSync(join(dir, \"mcp\", leaf, \"server.json\")), {\n kind: \"mcp\",\n }),\n );\n }\n } else {\n const mcpServers =\n (manifest.mcpServers as Record<string, McpServerConfig> | undefined) ??\n (readJson(join(dir, \"mcp-config.json\"))?.mcpServers as Record<string, McpServerConfig>) ??\n {};\n for (const [serverName, cfg] of Object.entries(mcpServers)) {\n components.push({ mcp: `mcp/${serverName}` });\n files.push(\n artifact(\n `mcp/${serverName}/server.json`,\n json(synthesizeServerJson(namespace, serverName, cfg)),\n { kind: \"mcp\" },\n ),\n );\n }\n }\n\n const authorRaw = manifest.author;\n const author =\n typeof authorRaw === \"string\"\n ? { name: authorRaw }\n : (authorRaw as { name?: string; email?: string } | undefined);\n const plugin: Plugin = {\n name: String(manifest.name),\n version: String(manifest.version ?? \"0.1.0\"),\n owner: {\n name: author?.name ?? String(manifest.name),\n namespace,\n ...(author?.email ? { email: author.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n components,\n };\n return { kind: \"plugin\", plugin, files };\n}\n\nfunction importMarketplace(\n manifest: Record<string, unknown>,\n namespace: string,\n): ImportedMarketplace {\n const ownerRaw = manifest.owner;\n const owner =\n typeof ownerRaw === \"string\"\n ? { name: ownerRaw }\n : (ownerRaw as { name?: string; email?: string } | undefined);\n const plugins = ((manifest.plugins as Record<string, unknown>[]) ?? []).map((p) => ({\n plugin: sourceToString(p.source),\n ...(p.version ? { version: String(p.version) } : {}),\n ...(p.category ? { category: String(p.category) } : {}),\n ...(Array.isArray(p.tags) ? { tags: p.tags as string[] } : {}),\n }));\n const marketplace: Marketplace = {\n name: String(manifest.name),\n owner: {\n name: owner?.name ?? String(manifest.name),\n namespace,\n ...(owner?.email ? { email: owner.email } : {}),\n },\n ...(manifest.description ? { description: String(manifest.description) } : {}),\n plugins,\n };\n return { kind: \"marketplace\", marketplace };\n}\n\n/** Copilot's four plugin.json search locations (research §Copilot). */\nconst MANIFEST_PATHS = [\n [\"plugin.json\"],\n [\".plugin\", \"plugin.json\"],\n [\".github\", \"plugin\", \"plugin.json\"],\n [\".claude-plugin\", \"plugin.json\"],\n];\n\n/** Reverse-compile a GitHub Copilot plugin or marketplace dir into the Loom model. */\nexport function importCopilot(dir: string, opts?: ImportOptions): ImportResult | null {\n const namespace = opts?.namespace ?? \"com.imported\";\n const marketplace = readJson(join(dir, \".copilot-plugin\", \"marketplace.json\"));\n if (marketplace) return importMarketplace(marketplace, namespace);\n\n for (const segs of MANIFEST_PATHS) {\n const manifest = readJson(join(dir, ...segs));\n if (manifest) return importPlugin(dir, manifest, namespace);\n }\n\n // No manifest, but a bare plugin layout (skills/ etc.) is still importable.\n if (existsSync(join(dir, \"skills\"))) {\n return importPlugin(dir, { name: \"imported-plugin\" }, namespace);\n }\n return null;\n}\n","/**\n * Derives a runnable Copilot `mcpServers` entry from an MCP-standard `server.json`\n * (the registry's ServerJSON shape: packages[] / remotes[] / a bare command).\n * Stored standards stay verbatim in the plugin; this is the tool-specific view.\n *\n * Copilot's per-server shape (verified, research §Copilot): `type` is one of\n * `local|stdio|http|sse`; `command`+`args`+`env` for local/stdio; `url`+`headers`\n * for http/sse; `tools` is `\"*\"` or an explicit list.\n */\n\nexport interface McpServerConfig {\n type: \"local\" | \"stdio\" | \"http\" | \"sse\";\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n tools?: string[] | \"*\";\n}\n\ninterface McpPackage {\n registryType?: string;\n identifier?: string;\n version?: string;\n transport?: { type?: string };\n}\ninterface McpRemote {\n type?: string;\n url?: string;\n headers?: Array<{ name: string; value: string }>;\n}\ninterface ServerJson {\n name?: string;\n packages?: McpPackage[];\n remotes?: McpRemote[];\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** The short server key Copilot uses (the part after the reverse-DNS namespace). */\nexport function mcpServerName(server: ServerJson): string {\n const raw = server.name ?? \"server\";\n const afterSlash = raw.includes(\"/\") ? raw.slice(raw.lastIndexOf(\"/\") + 1) : raw;\n return afterSlash || \"server\";\n}\n\nconst RUNNERS: Record<string, string> = { npm: \"npx\", pypi: \"uvx\" };\n\nexport function mcpRunConfig(server: ServerJson): McpServerConfig {\n const pkg = server.packages?.[0];\n if (pkg?.identifier) {\n if (pkg.registryType === \"oci\") {\n return {\n type: \"local\",\n command: \"docker\",\n args: [\"run\", \"-i\", \"--rm\", pkg.identifier],\n tools: [\"*\"],\n };\n }\n const runner = RUNNERS[pkg.registryType ?? \"npm\"] ?? \"npx\";\n const ident = pkg.version ? `${pkg.identifier}@${pkg.version}` : pkg.identifier;\n const args = runner === \"npx\" ? [\"-y\", ident] : [ident];\n return { type: \"local\", command: runner, args, tools: [\"*\"] };\n }\n\n const remote = server.remotes?.[0];\n if (remote?.url) {\n // Copilot uses http|sse for remote transports; the MCP registry's\n // \"streamable-http\" maps to \"http\".\n const type = remote.type === \"sse\" ? \"sse\" : \"http\";\n const config: McpServerConfig = { type, url: remote.url, tools: [\"*\"] };\n if (remote.headers?.length) {\n config.headers = Object.fromEntries(remote.headers.map((h) => [h.name, h.value]));\n }\n return config;\n }\n\n if (server.command) {\n const config: McpServerConfig = { type: \"local\", command: server.command, tools: [\"*\"] };\n if (server.args) config.args = server.args;\n if (server.env) config.env = server.env;\n return config;\n }\n\n return {\n type: \"local\",\n command: \"echo\",\n args: [\"server.json declares no runnable transport\"],\n tools: [\"*\"],\n };\n}\n","import { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\nimport {\n artifact,\n type CompiledArtifact,\n type HarnessAdapter,\n type InstallPaths,\n type PluginCtx,\n type ResolvedMarketplace,\n} from \"@michaelfromyeg/loom-adapter-kit\";\nimport {\n type Component,\n kindOf,\n leafNameOf,\n type Plugin,\n refOf,\n type Scope,\n} from \"@michaelfromyeg/loom-schema\";\nimport { importCopilot } from \"./import\";\nimport { type McpServerConfig, mcpRunConfig, mcpServerName } from \"./mcp\";\n\n/**\n * Bump on any change to Copilot's plugin/marketplace manifest shape (spec §5).\n *\n * NOTE for the future driver: Copilot has NO structured headless trace. `copilot -p`\n * only emits a markdown transcript via `--share`/`--share-gist`; `--output-format`/\n * `--json` exist only on `copilot mcp` subcommands. A driver must degrade `trace`\n * assertions to `output` assertions (research §Copilot).\n */\nconst TARGET_SCHEMA = \"copilot-plugin/1\";\n\ninterface CopilotAuthor {\n name: string;\n email?: string;\n}\ninterface CopilotPluginManifest {\n name: string;\n description?: string;\n version?: string;\n author?: CopilotAuthor;\n mcpServers?: Record<string, McpServerConfig>;\n}\ninterface CopilotMarketplacePlugin {\n name: string;\n source: string;\n description?: string;\n version?: string;\n category?: string;\n tags?: string[];\n}\ninterface CopilotMarketplace {\n name: string;\n owner: CopilotAuthor;\n description?: string;\n plugins: CopilotMarketplacePlugin[];\n}\n\nconst json = (o: unknown): string => `${JSON.stringify(o, null, 2)}\\n`;\n\nfunction author(name: string, email?: string): CopilotAuthor {\n return email ? { name, email } : { name };\n}\n\n/** Copy every file under a plugin dir into `destPrefix/`, preserving structure. */\nfunction copyDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n return ctx.list(ref).map((file) => {\n const within = file.startsWith(`${ref}/`) ? file.slice(ref.length + 1) : basename(file);\n return artifact(`${destPrefix}/${within}`, ctx.read(file), { kind });\n });\n}\n\n/** Place a component that may be a single Markdown file or a directory. */\nfunction copyFileOrDir(\n ctx: PluginCtx,\n ref: string,\n destPrefix: string,\n ext: string,\n kind: CompiledArtifact[\"kind\"],\n): CompiledArtifact[] {\n const files = ctx.list(ref);\n if (files.length === 0) {\n // ref is a single file (e.g. agents/code-review.md). Use the harness-required\n // extension (e.g. .agent.md), not the source file's -- `destPrefix` already\n // ends in the extension-stripped leaf name.\n return [artifact(`${destPrefix}${ext}`, ctx.read(ref), { kind })];\n }\n return copyDir(ctx, ref, destPrefix, kind);\n}\n\nexport const copilotAdapter: HarnessAdapter = {\n target: \"copilot\",\n version: \"0.1.0\",\n targetSchema: TARGET_SCHEMA,\n\n detect(scope: Scope, cwd: string): InstallPaths {\n // Real Copilot keys its config dir off COPILOT_HOME (default ~/.copilot) and\n // has no official project scope. We honor COPILOT_HOME for user scope and treat\n // project scope as <cwd>/.copilot best-effort.\n // TODO(verify): project-scoped <cwd>/.copilot is unconfirmed -- Copilot only\n // documents COPILOT_HOME (no per-project config dir and no --config-dir flag).\n const userRoot = process.env.COPILOT_HOME ?? join(homedir(), \".copilot\");\n const root = scope === \"user\" ? userRoot : join(cwd, \".copilot\");\n return {\n root,\n plugins: join(root, \"installed-plugins\"),\n skills: join(root, \"skills\"),\n // mcp-config.json lives at the config-dir root, so `mcp` points at root.\n mcp: root,\n agents: join(root, \"agents\"),\n // TODO(verify): commands/ dir is best-effort; Copilot docs list skills/agents/\n // hooks/mcp-config.json but do not confirm a top-level commands/ directory.\n commands: join(root, \"commands\"),\n hooks: join(root, \"hooks\"),\n catalog: root,\n };\n },\n\n transform(component: Component, ctx: PluginCtx): CompiledArtifact[] {\n const ref = refOf(component);\n const leaf = leafNameOf(component);\n switch (kindOf(component)) {\n case \"skill\":\n // skills/<name>/SKILL.md (+ any sibling assets), copied verbatim.\n return copyDir(ctx, ref, `skills/${leaf}`, \"skill\");\n case \"agent\":\n // CONFIRMED extension: agents/<name>.agent.md.\n return copyFileOrDir(ctx, ref, `agents/${leaf}`, \".agent.md\", \"agent\");\n case \"command\":\n // TODO(verify): commands/<leaf>.md placement is best-effort (see detect()).\n return copyFileOrDir(ctx, ref, `commands/${leaf}`, \".md\", \"command\");\n case \"hook\":\n return copyFileOrDir(ctx, ref, `hooks/${leaf}`, \".md\", \"hook\");\n case \"mcp\":\n // Verbatim provenance copy; the runnable config goes inline in plugin.json.\n return copyDir(ctx, ref, `mcp/${leaf}`, \"mcp\");\n case \"passthrough\":\n return [\n artifact(`hooks/${basename(ref)}`, ctx.read(ref), { kind: \"hook\", executable: true }),\n ];\n default:\n return [];\n }\n },\n\n emitManifest(plugin: Plugin, ctx: PluginCtx): CompiledArtifact[] {\n const manifest: CopilotPluginManifest = {\n name: plugin.name,\n version: plugin.version,\n author: author(plugin.owner.name, plugin.owner.email),\n };\n if (plugin.description) manifest.description = plugin.description;\n\n const mcpServers: Record<string, McpServerConfig> = {};\n for (const c of plugin.components) {\n if (kindOf(c) !== \"mcp\") continue;\n try {\n const server = JSON.parse(ctx.read(`${refOf(c)}/server.json`).toString(\"utf8\"));\n mcpServers[mcpServerName(server)] = mcpRunConfig(server);\n } catch {\n // validate.ts already surfaced an error for an unparsable server.json.\n }\n }\n if (Object.keys(mcpServers).length > 0) manifest.mcpServers = mcpServers;\n\n // plugin.json AT PLUGIN ROOT -- one of Copilot's four search locations\n // (.plugin/, root, .github/plugin/, .claude-plugin/).\n return [artifact(\"plugin.json\", json(manifest), { kind: \"manifest\" })];\n },\n\n emitCatalog(marketplace: ResolvedMarketplace): CompiledArtifact[] {\n const plugins: CopilotMarketplacePlugin[] = marketplace.entries.map((entry) => {\n const entryPlugin: CopilotMarketplacePlugin = {\n name: entry.name,\n source: entry.source.startsWith(\"./\") ? entry.source : `./${entry.source}`,\n };\n if (entry.description) entryPlugin.description = entry.description;\n if (entry.version) entryPlugin.version = entry.version;\n if (entry.category) entryPlugin.category = entry.category;\n if (entry.tags) entryPlugin.tags = entry.tags;\n return entryPlugin;\n });\n\n const catalog: CopilotMarketplace = {\n name: marketplace.name,\n owner: author(marketplace.owner.name, marketplace.owner.email),\n plugins,\n };\n if (marketplace.description) catalog.description = marketplace.description;\n\n // TODO(verify): Copilot's marketplace.json shape is NOT documented. This is a\n // best-effort manifest mirroring Claude's { name, owner, plugins[] }. The exact\n // field names and file location (.copilot-plugin/ vs root) are unconfirmed.\n return [artifact(\".copilot-plugin/marketplace.json\", json(catalog), { kind: \"catalog\" })];\n },\n\n importNative: importCopilot,\n};\n\nexport default copilotAdapter;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michaelfromyeg/loom-adapter-copilot",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Loom adapter for GitHub Copilot CLI: plugin.json + mcp-config + component placement.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -16,11 +16,11 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@michaelfromyeg/loom-adapter-kit": "0.1.0",
20
- "@michaelfromyeg/loom-schema": "0.1.0"
19
+ "@michaelfromyeg/loom-adapter-kit": "0.2.0",
20
+ "@michaelfromyeg/loom-schema": "0.2.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@michaelfromyeg/loom-core": "0.1.0"
23
+ "@michaelfromyeg/loom-core": "0.2.0"
24
24
  },
25
25
  "license": "MIT",
26
26
  "author": "Michael DeMarco",