copillm 0.2.7 → 0.2.8

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.
@@ -384,18 +384,67 @@ export default function activate(pi: PiApi): void {
384
384
  }
385
385
  }
386
386
  `;
387
- // ─── Copilot CLI (stub) ───────────────────────────────────────────────────
388
- export function renderCopilot(_input) {
387
+ // ─── Copilot CLI ──────────────────────────────────────────────────────────
388
+ export function renderCopilot(input) {
389
+ const writes = [];
390
+ const notes = [];
391
+ const cliArgs = [];
392
+ const mcpConfigPath = path.join(getCopillmHome(), "copilot", "mcp-config.json");
393
+ const serverCount = Object.keys(input.resolved.mcpServers).length;
394
+ if (serverCount > 0) {
395
+ const content = renderCopilotMcp(input.resolved.mcpServers);
396
+ const existing = fs.existsSync(mcpConfigPath) ? fs.readFileSync(mcpConfigPath, "utf8") : null;
397
+ if (existing !== content) {
398
+ writes.push({
399
+ path: mcpConfigPath,
400
+ content,
401
+ mode: 0o600,
402
+ description: "Copilot CLI MCP config (copillm-managed)"
403
+ });
404
+ }
405
+ cliArgs.push("--additional-mcp-config", `@${mcpConfigPath}`);
406
+ }
407
+ else if (fs.existsSync(mcpConfigPath)) {
408
+ fs.rmSync(mcpConfigPath, { force: true });
409
+ notes.push(`Removed stale ${mcpConfigPath} (no MCP servers in active profile).`);
410
+ }
389
411
  return {
390
- writes: [],
412
+ writes,
391
413
  envOverlay: {},
392
- cliArgs: [],
393
- notes: [
394
- "Copilot CLI: native MCP config format is not yet documented publicly. " +
395
- "Skipping fan-out. Track upstream and remove this stub when the path is known."
396
- ]
414
+ cliArgs,
415
+ notes
397
416
  };
398
417
  }
418
+ function renderCopilotMcp(servers) {
419
+ const out = {};
420
+ for (const [name, server] of Object.entries(servers)) {
421
+ if (server.transport === "stdio") {
422
+ const entry = {
423
+ type: "local",
424
+ command: server.command,
425
+ tools: ["*"]
426
+ };
427
+ if (server.args)
428
+ entry.args = server.args;
429
+ if (server.env)
430
+ entry.env = server.env;
431
+ if (server.cwd)
432
+ entry.cwd = server.cwd;
433
+ out[name] = entry;
434
+ }
435
+ else {
436
+ const entry = {
437
+ type: server.transport,
438
+ url: server.url,
439
+ tools: ["*"]
440
+ };
441
+ if (server.headers)
442
+ entry.headers = server.headers;
443
+ out[name] = entry;
444
+ }
445
+ }
446
+ return `${JSON.stringify({ mcpServers: out }, null, 2)}\n`;
447
+ }
399
448
  export function planRender(opts, load) {
400
449
  const baseInput = { resolved: load.resolved, cwd: opts.cwd };
401
450
  switch (opts.agent) {
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
2
  const FALLBACK_PACKAGE_INFO = {
3
3
  name: "copillm",
4
- version: "0.2.7"
4
+ version: "0.2.8"
5
5
  };
6
6
  export function getPackageInfo() {
7
7
  const envName = cleanPackageValue(process.env.COPILLM_PACKAGE_NAME);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "copillm",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Local Copilot proxy CLI (OpenAI/Anthropic-compatible)",
5
5
  "license": "MIT",
6
6
  "type": "module",