allagents 1.6.0 → 1.7.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.
Files changed (3) hide show
  1. package/README.md +77 -401
  2. package/dist/index.js +436 -213
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7465,24 +7465,17 @@ __export(exports_constants, {
7465
7465
  function getHomeDir() {
7466
7466
  return process.env.HOME || process.env.USERPROFILE || "~";
7467
7467
  }
7468
- function generateWorkspaceRules(repositories, skills = []) {
7468
+ function generateWorkspaceRules(repositories, skillsIndexRefs = []) {
7469
7469
  const repoList = repositories.map((r) => `- ${r.path}${r.description ? ` - ${r.description}` : ""}`).join(`
7470
7470
  `);
7471
7471
  let skillsBlock = "";
7472
- if (skills.length > 0) {
7473
- const skillEntries = skills.map((s) => `<skill>
7474
- <name>${s.name}</name>
7475
- <description>${s.description}</description>
7476
- <location>${s.location}</location>
7477
- </skill>`).join(`
7472
+ if (skillsIndexRefs.length > 0) {
7473
+ const refLines = skillsIndexRefs.map((r) => `- ${r.repoName}: ${r.indexPath}`).join(`
7478
7474
  `);
7479
7475
  skillsBlock = `
7480
- ## Workspace Skills
7481
- When a task matches a skill description, fetch the full instructions from its location.
7482
-
7483
- <available_skills>
7484
- ${skillEntries}
7485
- </available_skills>
7476
+ ## Repository Skills
7477
+ If the skills from the following repositories are not already available in your context, read the corresponding index file:
7478
+ ${refLines}
7486
7479
  `;
7487
7480
  }
7488
7481
  return `
@@ -11497,7 +11490,7 @@ function resolveInstallMode(pluginEntry, clientEntry) {
11497
11490
  return pluginMode;
11498
11491
  return clientEntry.install;
11499
11492
  }
11500
- var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, WorkspaceConfigSchema;
11493
+ var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, McpProxyServerSchema, McpProxyConfigSchema, WorkspaceConfigSchema;
11501
11494
  var init_workspace_config = __esm(() => {
11502
11495
  init_zod();
11503
11496
  RepositorySchema = exports_external.object({
@@ -11602,6 +11595,13 @@ var init_workspace_config = __esm(() => {
11602
11595
  output: exports_external.string().optional()
11603
11596
  });
11604
11597
  SyncModeSchema = exports_external.enum(["symlink", "copy"]);
11598
+ McpProxyServerSchema = exports_external.object({
11599
+ proxy: exports_external.array(exports_external.string())
11600
+ });
11601
+ McpProxyConfigSchema = exports_external.object({
11602
+ clients: exports_external.array(exports_external.string()),
11603
+ servers: exports_external.record(McpProxyServerSchema).optional()
11604
+ });
11605
11605
  WorkspaceConfigSchema = exports_external.object({
11606
11606
  version: exports_external.number().optional(),
11607
11607
  workspace: WorkspaceSchema.optional(),
@@ -11610,6 +11610,7 @@ var init_workspace_config = __esm(() => {
11610
11610
  clients: exports_external.array(ClientEntrySchema),
11611
11611
  vscode: VscodeConfigSchema.optional(),
11612
11612
  syncMode: SyncModeSchema.optional(),
11613
+ mcpProxy: McpProxyConfigSchema.optional(),
11613
11614
  disabledSkills: exports_external.array(exports_external.string()).optional(),
11614
11615
  enabledSkills: exports_external.array(exports_external.string()).optional()
11615
11616
  });
@@ -25500,8 +25501,8 @@ var init_skill = __esm(() => {
25500
25501
  import { readFile as readFile3, writeFile, mkdir as mkdir3, cp, readdir as readdir2 } from "node:fs/promises";
25501
25502
  import { existsSync as existsSync4 } from "node:fs";
25502
25503
  import { join as join7, basename as basename2, dirname as dirname4, relative as relative2 } from "node:path";
25503
- async function ensureWorkspaceRules(filePath, repositories, skills = []) {
25504
- const rulesContent = generateWorkspaceRules(repositories, skills);
25504
+ async function ensureWorkspaceRules(filePath, repositories, skillsIndexRefs = []) {
25505
+ const rulesContent = generateWorkspaceRules(repositories, skillsIndexRefs);
25505
25506
  const startMarker = "<!-- WORKSPACE-RULES:START -->";
25506
25507
  const endMarker = "<!-- WORKSPACE-RULES:END -->";
25507
25508
  if (!existsSync4(filePath)) {
@@ -25934,7 +25935,7 @@ function resolveFileSourcePath(source, defaultSourcePath, githubCache) {
25934
25935
  return null;
25935
25936
  }
25936
25937
  async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {}) {
25937
- const { dryRun = false, githubCache, repositories = [], skills = [] } = options2;
25938
+ const { dryRun = false, githubCache, repositories = [], skillsIndexRefs = [] } = options2;
25938
25939
  const results = [];
25939
25940
  const stringPatterns = [];
25940
25941
  const objectEntries = [];
@@ -26087,7 +26088,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
26087
26088
  for (const agentFile of copiedAgentFiles) {
26088
26089
  const targetPath = join7(workspacePath, agentFile);
26089
26090
  try {
26090
- await ensureWorkspaceRules(targetPath, repositories, skills);
26091
+ await ensureWorkspaceRules(targetPath, repositories, skillsIndexRefs);
26091
26092
  } catch (error) {
26092
26093
  results.push({
26093
26094
  source: "WORKSPACE-RULES",
@@ -28366,9 +28367,9 @@ var init_workspace_modify = __esm(() => {
28366
28367
  });
28367
28368
 
28368
28369
  // src/core/repo-skills.ts
28369
- import { existsSync as existsSync9, lstatSync } from "node:fs";
28370
+ import { existsSync as existsSync9, lstatSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs";
28370
28371
  import { readdir as readdir4, readFile as readFile8 } from "node:fs/promises";
28371
- import { join as join12, relative as relative3, resolve as resolve8 } from "node:path";
28372
+ import { basename as basename5, join as join12, relative as relative3, resolve as resolve8 } from "node:path";
28372
28373
  async function discoverRepoSkills(repoPath, options2) {
28373
28374
  if (options2.disabled)
28374
28375
  return [];
@@ -28423,7 +28424,8 @@ async function discoverRepoSkills(repoPath, options2) {
28423
28424
  results.push({
28424
28425
  name: metadata.name,
28425
28426
  description: metadata.description,
28426
- relativePath: relPath
28427
+ relativePath: relPath,
28428
+ fileSize: content.length
28427
28429
  });
28428
28430
  } catch {}
28429
28431
  }
@@ -28431,24 +28433,104 @@ async function discoverRepoSkills(repoPath, options2) {
28431
28433
  return results;
28432
28434
  }
28433
28435
  async function discoverWorkspaceSkills(workspacePath, repositories, clientNames) {
28434
- const allSkills = [];
28436
+ const skillsByName = new Map;
28435
28437
  for (const repo of repositories) {
28436
- if (repo.skills === false)
28438
+ if (repo.skills === false || repo.skills === undefined)
28437
28439
  continue;
28438
28440
  const repoAbsPath = resolve8(workspacePath, repo.path);
28439
28441
  const discoverOpts = Array.isArray(repo.skills) ? { skillPaths: repo.skills } : { clients: clientNames };
28440
28442
  const repoSkills = await discoverRepoSkills(repoAbsPath, discoverOpts);
28441
28443
  for (const skill of repoSkills) {
28442
28444
  const location = `${repo.path}/${skill.relativePath}`.replace(/\\/g, "/");
28443
- allSkills.push({
28445
+ const candidate = {
28444
28446
  repoPath: repo.path,
28445
28447
  name: skill.name,
28446
28448
  description: skill.description,
28447
- location
28448
- });
28449
+ location,
28450
+ fileSize: skill.fileSize
28451
+ };
28452
+ const existing = skillsByName.get(skill.name);
28453
+ if (!existing) {
28454
+ skillsByName.set(skill.name, candidate);
28455
+ continue;
28456
+ }
28457
+ const existingIsAgents = existing.location.includes(".agents/");
28458
+ const candidateIsAgents = candidate.location.includes(".agents/");
28459
+ if (candidateIsAgents && !existingIsAgents) {
28460
+ skillsByName.set(skill.name, candidate);
28461
+ } else if (!candidateIsAgents && existingIsAgents) {} else if (candidate.fileSize > existing.fileSize) {
28462
+ skillsByName.set(skill.name, candidate);
28463
+ }
28449
28464
  }
28450
28465
  }
28451
- return allSkills;
28466
+ return [...skillsByName.values()].map(({ fileSize: _, ...entry }) => entry);
28467
+ }
28468
+ function writeSkillsIndex(workspacePath, skillsByRepo) {
28469
+ if (skillsByRepo.size === 0)
28470
+ return { writtenFiles: [], refs: [] };
28471
+ const indexDir = join12(workspacePath, ".allagents", "skills-index");
28472
+ mkdirSync(indexDir, { recursive: true });
28473
+ const writtenFiles = [];
28474
+ const refs = [];
28475
+ for (const [, { repoName, skills }] of skillsByRepo) {
28476
+ const skillEntries = skills.map((s) => `<skill>
28477
+ <name>${s.name}</name>
28478
+ <description>${s.description}</description>
28479
+ <location>${s.location}</location>
28480
+ </skill>`).join(`
28481
+ `);
28482
+ const content = `# Skills: ${repoName}
28483
+
28484
+ <available_skills>
28485
+ ${skillEntries}
28486
+ </available_skills>
28487
+ `;
28488
+ const filePath = `skills-index/${repoName}.md`;
28489
+ writeFileSync(join12(indexDir, `${repoName}.md`), content, "utf-8");
28490
+ writtenFiles.push(filePath);
28491
+ refs.push({ repoName, indexPath: `.allagents/${filePath}` });
28492
+ }
28493
+ return { writtenFiles, refs };
28494
+ }
28495
+ function cleanupSkillsIndex(workspacePath, currentFiles) {
28496
+ const indexDir = join12(workspacePath, ".allagents", "skills-index");
28497
+ if (!existsSync9(indexDir))
28498
+ return;
28499
+ const currentSet = new Set(currentFiles.map((f) => f.replace("skills-index/", "")));
28500
+ let entries;
28501
+ try {
28502
+ entries = readdirSync(indexDir);
28503
+ } catch {
28504
+ return;
28505
+ }
28506
+ for (const entry of entries) {
28507
+ if (!currentSet.has(entry)) {
28508
+ rmSync(join12(indexDir, entry), { force: true });
28509
+ }
28510
+ }
28511
+ try {
28512
+ const remaining = readdirSync(indexDir);
28513
+ if (remaining.length === 0) {
28514
+ rmSync(indexDir, { recursive: true, force: true });
28515
+ }
28516
+ } catch {}
28517
+ }
28518
+ function groupSkillsByRepo(skills, repositories) {
28519
+ const repoNameMap = new Map;
28520
+ for (const repo of repositories) {
28521
+ repoNameMap.set(repo.path, repo.name ?? basename5(repo.path));
28522
+ }
28523
+ const grouped = new Map;
28524
+ for (const skill of skills) {
28525
+ const repoName = repoNameMap.get(skill.repoPath) ?? basename5(skill.repoPath);
28526
+ const existing = grouped.get(skill.repoPath);
28527
+ if (existing) {
28528
+ existing.skills.push(skill);
28529
+ } else {
28530
+ grouped.set(skill.repoPath, { repoName, skills: [skill] });
28531
+ }
28532
+ }
28533
+ return grouped;
28452
28534
  }
28453
28535
  var init_repo_skills = __esm(() => {
28454
28536
  init_skill();
@@ -28571,6 +28653,9 @@ async function updateAgentFiles(workspacePath = process.cwd()) {
28571
28653
  return;
28572
28654
  const clientNames = resolveClientNames(config.clients);
28573
28655
  const allSkills = await discoverWorkspaceSkills(workspacePath, config.repositories, clientNames);
28656
+ const grouped = groupSkillsByRepo(allSkills, config.repositories);
28657
+ const { writtenFiles, refs: skillsIndexRefs } = writeSkillsIndex(workspacePath, grouped);
28658
+ cleanupSkillsIndex(workspacePath, writtenFiles);
28574
28659
  const agentFiles = new Set;
28575
28660
  for (const client of config.clients ?? []) {
28576
28661
  const clientName = typeof client === "string" ? client : client.name;
@@ -28580,7 +28665,7 @@ async function updateAgentFiles(workspacePath = process.cwd()) {
28580
28665
  }
28581
28666
  agentFiles.add("AGENTS.md");
28582
28667
  for (const agentFile of agentFiles) {
28583
- await ensureWorkspaceRules(join13(workspacePath, agentFile), config.repositories, allSkills);
28668
+ await ensureWorkspaceRules(join13(workspacePath, agentFile), config.repositories, skillsIndexRefs);
28584
28669
  }
28585
28670
  }
28586
28671
  var init_workspace_repo = __esm(() => {
@@ -28751,7 +28836,8 @@ var init_sync_state = __esm(() => {
28751
28836
  mcpServers: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
28752
28837
  nativePlugins: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())).optional(),
28753
28838
  vscodeWorkspaceHash: exports_external.string().optional(),
28754
- vscodeWorkspaceRepos: exports_external.array(exports_external.string()).optional()
28839
+ vscodeWorkspaceRepos: exports_external.array(exports_external.string()).optional(),
28840
+ skillsIndex: exports_external.array(exports_external.string()).optional()
28755
28841
  });
28756
28842
  });
28757
28843
 
@@ -28817,7 +28903,8 @@ async function saveSyncState(workspacePath, data) {
28817
28903
  ...normalizedData.mcpServers && { mcpServers: normalizedData.mcpServers },
28818
28904
  ...normalizedData.nativePlugins && { nativePlugins: normalizedData.nativePlugins },
28819
28905
  ...normalizedData.vscodeWorkspaceHash && { vscodeWorkspaceHash: normalizedData.vscodeWorkspaceHash },
28820
- ...normalizedData.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: normalizedData.vscodeWorkspaceRepos }
28906
+ ...normalizedData.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: normalizedData.vscodeWorkspaceRepos },
28907
+ ...normalizedData.skillsIndex && normalizedData.skillsIndex.length > 0 && { skillsIndex: normalizedData.skillsIndex }
28821
28908
  };
28822
28909
  await mkdir7(dirname6(statePath), { recursive: true });
28823
28910
  await ensureConfigGitignore(workspacePath);
@@ -28848,7 +28935,7 @@ var init_sync_state2 = __esm(() => {
28848
28935
 
28849
28936
  // src/core/vscode-workspace.ts
28850
28937
  import { createHash as createHash2 } from "node:crypto";
28851
- import { resolve as resolve9, basename as basename5, isAbsolute as isAbsolute3, relative as relative4 } from "node:path";
28938
+ import { resolve as resolve9, basename as basename6, isAbsolute as isAbsolute3, relative as relative4 } from "node:path";
28852
28939
  function buildPathPlaceholderMap(repositories, workspacePath) {
28853
28940
  const map2 = new Map;
28854
28941
  for (const repo of repositories) {
@@ -28931,7 +29018,7 @@ function getWorkspaceOutputPath(workspacePath, vscodeConfig) {
28931
29018
  const filename = name.endsWith(".code-workspace") ? name : `${name}.code-workspace`;
28932
29019
  return resolve9(workspacePath, filename);
28933
29020
  }
28934
- const dirName = basename5(resolve9(workspacePath));
29021
+ const dirName = basename6(resolve9(workspacePath));
28935
29022
  return resolve9(workspacePath, `${dirName}.code-workspace`);
28936
29023
  }
28937
29024
  function computeWorkspaceHash(content) {
@@ -29003,7 +29090,7 @@ var init_vscode_workspace = __esm(() => {
29003
29090
  });
29004
29091
 
29005
29092
  // src/core/vscode-mcp.ts
29006
- import { existsSync as existsSync13, readFileSync, writeFileSync, mkdirSync } from "node:fs";
29093
+ import { existsSync as existsSync13, readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
29007
29094
  import { join as join16, dirname as dirname7 } from "node:path";
29008
29095
  function deepEqual(a, b) {
29009
29096
  if (a === b)
@@ -29083,7 +29170,7 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29083
29170
  const configPath = options2?.configPath ?? getVscodeMcpConfigPath();
29084
29171
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29085
29172
  const hasTracking = options2?.trackedServers !== undefined;
29086
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29173
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29087
29174
  const result = {
29088
29175
  added: 0,
29089
29176
  skipped: 0,
@@ -29149,9 +29236,9 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29149
29236
  existingConfig.servers = existingServers;
29150
29237
  const dir = dirname7(configPath);
29151
29238
  if (!existsSync13(dir)) {
29152
- mkdirSync(dir, { recursive: true });
29239
+ mkdirSync2(dir, { recursive: true });
29153
29240
  }
29154
- writeFileSync(configPath, `${JSON.stringify(existingConfig, null, 2)}
29241
+ writeFileSync2(configPath, `${JSON.stringify(existingConfig, null, 2)}
29155
29242
  `, "utf-8");
29156
29243
  result.configPath = configPath;
29157
29244
  }
@@ -29167,9 +29254,9 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29167
29254
  existingConfig.servers = existingServers;
29168
29255
  const dir = dirname7(configPath);
29169
29256
  if (!existsSync13(dir)) {
29170
- mkdirSync(dir, { recursive: true });
29257
+ mkdirSync2(dir, { recursive: true });
29171
29258
  }
29172
- writeFileSync(configPath, `${JSON.stringify(existingConfig, null, 2)}
29259
+ writeFileSync2(configPath, `${JSON.stringify(existingConfig, null, 2)}
29173
29260
  `, "utf-8");
29174
29261
  result.configPath = configPath;
29175
29262
  }
@@ -29182,6 +29269,60 @@ var init_vscode_mcp = __esm(() => {
29182
29269
  import_json5 = __toESM(require_lib(), 1);
29183
29270
  });
29184
29271
 
29272
+ // src/core/mcp-proxy.ts
29273
+ import { existsSync as existsSync14, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
29274
+ import { join as join17, dirname as dirname8 } from "node:path";
29275
+ function getProxyMetadataPath() {
29276
+ return join17(getHomeDir(), ".allagents", "mcp-remote", "mcp-metadata-settings.json");
29277
+ }
29278
+ function shouldProxy(serverName, client, config) {
29279
+ if (config.clients.includes(client)) {
29280
+ return true;
29281
+ }
29282
+ const serverOverride = config.servers?.[serverName];
29283
+ if (serverOverride?.proxy.includes(client)) {
29284
+ return true;
29285
+ }
29286
+ return false;
29287
+ }
29288
+ function isHttpServer(config) {
29289
+ return typeof config === "object" && config !== null && "url" in config && typeof config.url === "string";
29290
+ }
29291
+ function toProxiedConfig(url, metadataPath) {
29292
+ return {
29293
+ command: "npx",
29294
+ args: [
29295
+ "mcp-remote",
29296
+ url,
29297
+ "--http",
29298
+ "--static-oauth-client-metadata",
29299
+ `@${metadataPath}`
29300
+ ]
29301
+ };
29302
+ }
29303
+ function applyMcpProxy(servers, client, config, metadataPath) {
29304
+ const result = new Map;
29305
+ for (const [name, serverConfig] of servers) {
29306
+ if (isHttpServer(serverConfig) && shouldProxy(name, client, config)) {
29307
+ result.set(name, toProxiedConfig(serverConfig.url, metadataPath));
29308
+ } else {
29309
+ result.set(name, serverConfig);
29310
+ }
29311
+ }
29312
+ return result;
29313
+ }
29314
+ function ensureProxyMetadata(metadataPath) {
29315
+ const path = metadataPath ?? getProxyMetadataPath();
29316
+ if (existsSync14(path)) {
29317
+ return;
29318
+ }
29319
+ mkdirSync3(dirname8(path), { recursive: true });
29320
+ writeFileSync3(path, JSON.stringify({ client_uri: "http://localhost" }, null, 2), "utf-8");
29321
+ }
29322
+ var init_mcp_proxy = __esm(() => {
29323
+ init_constants();
29324
+ });
29325
+
29185
29326
  // src/core/native/types.ts
29186
29327
  import { spawn as spawn2 } from "node:child_process";
29187
29328
  function executeCommand(binary2, args, options2 = {}) {
@@ -29235,8 +29376,8 @@ function mergeNativeSyncResults(results) {
29235
29376
  var init_types2 = () => {};
29236
29377
 
29237
29378
  // src/core/codex-mcp.ts
29238
- import { existsSync as existsSync14, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
29239
- import { dirname as dirname8 } from "node:path";
29379
+ import { existsSync as existsSync15, readFileSync as readFileSync2, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "node:fs";
29380
+ import { dirname as dirname9 } from "node:path";
29240
29381
  function buildCodexMcpAddArgs(name, config) {
29241
29382
  if (typeof config.url === "string") {
29242
29383
  return ["mcp", "add", name, "--url", config.url];
@@ -29261,7 +29402,7 @@ async function syncCodexMcpServers(validatedPlugins, options2) {
29261
29402
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29262
29403
  const hasTracking = options2?.trackedServers !== undefined;
29263
29404
  const exec = options2?._mockExecute ?? ((binary2, args) => executeCommand(binary2, args));
29264
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29405
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29265
29406
  const result = {
29266
29407
  added: 0,
29267
29408
  skipped: 0,
@@ -29432,7 +29573,7 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29432
29573
  }
29433
29574
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29434
29575
  const hasTracking = options2?.trackedServers !== undefined;
29435
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29576
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29436
29577
  const result = {
29437
29578
  added: 0,
29438
29579
  skipped: 0,
@@ -29446,7 +29587,7 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29446
29587
  trackedServers: []
29447
29588
  };
29448
29589
  let existingContent = "";
29449
- if (existsSync14(configPath)) {
29590
+ if (existsSync15(configPath)) {
29450
29591
  try {
29451
29592
  existingContent = readFileSync2(configPath, "utf-8");
29452
29593
  } catch {
@@ -29501,11 +29642,11 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29501
29642
 
29502
29643
  `)}
29503
29644
  `;
29504
- const dir = dirname8(configPath);
29505
- if (!existsSync14(dir)) {
29506
- mkdirSync2(dir, { recursive: true });
29645
+ const dir = dirname9(configPath);
29646
+ if (!existsSync15(dir)) {
29647
+ mkdirSync4(dir, { recursive: true });
29507
29648
  }
29508
- writeFileSync2(configPath, output, "utf-8");
29649
+ writeFileSync4(configPath, output, "utf-8");
29509
29650
  result.configPath = configPath;
29510
29651
  }
29511
29652
  return result;
@@ -29516,8 +29657,8 @@ var init_codex_mcp = __esm(() => {
29516
29657
  });
29517
29658
 
29518
29659
  // src/core/claude-mcp.ts
29519
- import { existsSync as existsSync15, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
29520
- import { dirname as dirname9 } from "node:path";
29660
+ import { existsSync as existsSync16, readFileSync as readFileSync3, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "node:fs";
29661
+ import { dirname as dirname10 } from "node:path";
29521
29662
  function deepEqual2(a, b) {
29522
29663
  if (a === b)
29523
29664
  return true;
@@ -29570,7 +29711,7 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29570
29711
  }
29571
29712
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29572
29713
  const hasTracking = options2?.trackedServers !== undefined;
29573
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29714
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29574
29715
  const result = {
29575
29716
  added: 0,
29576
29717
  skipped: 0,
@@ -29584,7 +29725,7 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29584
29725
  trackedServers: []
29585
29726
  };
29586
29727
  let existingConfig = {};
29587
- if (existsSync15(configPath)) {
29728
+ if (existsSync16(configPath)) {
29588
29729
  try {
29589
29730
  const content = readFileSync3(configPath, "utf-8");
29590
29731
  existingConfig = import_json52.default.parse(content);
@@ -29634,11 +29775,11 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29634
29775
  const hasChanges = result.added > 0 || result.overwritten > 0 || result.removed > 0;
29635
29776
  if (hasChanges && !dryRun) {
29636
29777
  existingConfig.mcpServers = existingServers;
29637
- const dir = dirname9(configPath);
29638
- if (!existsSync15(dir)) {
29639
- mkdirSync3(dir, { recursive: true });
29778
+ const dir = dirname10(configPath);
29779
+ if (!existsSync16(dir)) {
29780
+ mkdirSync5(dir, { recursive: true });
29640
29781
  }
29641
- writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29782
+ writeFileSync5(configPath, `${JSON.stringify(existingConfig, null, 2)}
29642
29783
  `, "utf-8");
29643
29784
  result.configPath = configPath;
29644
29785
  }
@@ -29652,11 +29793,11 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29652
29793
  }
29653
29794
  if (result.removed > 0 && !dryRun) {
29654
29795
  existingConfig.mcpServers = existingServers;
29655
- const dir = dirname9(configPath);
29656
- if (!existsSync15(dir)) {
29657
- mkdirSync3(dir, { recursive: true });
29796
+ const dir = dirname10(configPath);
29797
+ if (!existsSync16(dir)) {
29798
+ mkdirSync5(dir, { recursive: true });
29658
29799
  }
29659
- writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29800
+ writeFileSync5(configPath, `${JSON.stringify(existingConfig, null, 2)}
29660
29801
  `, "utf-8");
29661
29802
  result.configPath = configPath;
29662
29803
  }
@@ -29668,7 +29809,7 @@ async function syncClaudeMcpServersViaCli(validatedPlugins, options2) {
29668
29809
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29669
29810
  const hasTracking = options2?.trackedServers !== undefined;
29670
29811
  const exec = options2?._mockExecute ?? ((binary2, args) => executeCommand(binary2, args));
29671
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29812
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29672
29813
  const result = {
29673
29814
  added: 0,
29674
29815
  skipped: 0,
@@ -29752,9 +29893,9 @@ var init_claude_mcp = __esm(() => {
29752
29893
  });
29753
29894
 
29754
29895
  // src/core/copilot-mcp.ts
29755
- import { join as join17 } from "node:path";
29896
+ import { join as join18 } from "node:path";
29756
29897
  function getCopilotMcpConfigPath() {
29757
- return join17(getHomeDir(), ".copilot", "mcp-config.json");
29898
+ return join18(getHomeDir(), ".copilot", "mcp-config.json");
29758
29899
  }
29759
29900
  var init_copilot_mcp = __esm(() => {
29760
29901
  init_constants();
@@ -30052,9 +30193,9 @@ function padStart2(str3, len) {
30052
30193
  }
30053
30194
 
30054
30195
  // src/core/sync.ts
30055
- import { existsSync as existsSync16, readFileSync as readFileSync4, writeFileSync as writeFileSync4, lstatSync as lstatSync2 } from "node:fs";
30196
+ import { existsSync as existsSync17, readFileSync as readFileSync4, writeFileSync as writeFileSync6, lstatSync as lstatSync2 } from "node:fs";
30056
30197
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
30057
- import { join as join18, resolve as resolve10, dirname as dirname10, relative as relative5 } from "node:path";
30198
+ import { join as join19, resolve as resolve10, dirname as dirname11, relative as relative5 } from "node:path";
30058
30199
  function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
30059
30200
  const pathToClients = new Map;
30060
30201
  for (const client of clients) {
@@ -30168,7 +30309,7 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
30168
30309
  const previousFiles = getPreviouslySyncedFiles(state, client);
30169
30310
  const purgedPaths = [];
30170
30311
  for (const filePath of previousFiles) {
30171
- const fullPath = join18(workspacePath, filePath);
30312
+ const fullPath = join19(workspacePath, filePath);
30172
30313
  const cleanPath = fullPath.replace(/\/$/, "");
30173
30314
  let stats;
30174
30315
  try {
@@ -30195,16 +30336,16 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
30195
30336
  return result;
30196
30337
  }
30197
30338
  async function cleanupEmptyParents(workspacePath, filePath) {
30198
- let parentPath = dirname10(filePath);
30339
+ let parentPath = dirname11(filePath);
30199
30340
  while (parentPath && parentPath !== "." && parentPath !== "/") {
30200
- const fullParentPath = join18(workspacePath, parentPath);
30201
- if (!existsSync16(fullParentPath)) {
30202
- parentPath = dirname10(parentPath);
30341
+ const fullParentPath = join19(workspacePath, parentPath);
30342
+ if (!existsSync17(fullParentPath)) {
30343
+ parentPath = dirname11(parentPath);
30203
30344
  continue;
30204
30345
  }
30205
30346
  try {
30206
30347
  await rmdir(fullParentPath);
30207
- parentPath = dirname10(parentPath);
30348
+ parentPath = dirname11(parentPath);
30208
30349
  } catch {
30209
30350
  break;
30210
30351
  }
@@ -30283,8 +30424,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30283
30424
  errors2.push(`Cannot resolve file '${file}' - no workspace.source configured`);
30284
30425
  continue;
30285
30426
  }
30286
- const fullPath = join18(defaultSourcePath, file);
30287
- if (!existsSync16(fullPath)) {
30427
+ const fullPath = join19(defaultSourcePath, file);
30428
+ if (!existsSync17(fullPath)) {
30288
30429
  errors2.push(`File source not found: ${fullPath}`);
30289
30430
  }
30290
30431
  continue;
@@ -30302,8 +30443,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30302
30443
  errors2.push(`GitHub cache not found for ${cacheKey}`);
30303
30444
  continue;
30304
30445
  }
30305
- const fullPath = join18(cachePath, parsed.filePath);
30306
- if (!existsSync16(fullPath)) {
30446
+ const fullPath = join19(cachePath, parsed.filePath);
30447
+ if (!existsSync17(fullPath)) {
30307
30448
  errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
30308
30449
  }
30309
30450
  } else {
@@ -30313,11 +30454,11 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30313
30454
  } else if (file.source.startsWith("../")) {
30314
30455
  fullPath = resolve10(file.source);
30315
30456
  } else if (defaultSourcePath) {
30316
- fullPath = join18(defaultSourcePath, file.source);
30457
+ fullPath = join19(defaultSourcePath, file.source);
30317
30458
  } else {
30318
30459
  fullPath = resolve10(file.source);
30319
30460
  }
30320
- if (!existsSync16(fullPath)) {
30461
+ if (!existsSync17(fullPath)) {
30321
30462
  errors2.push(`File source not found: ${fullPath}`);
30322
30463
  }
30323
30464
  }
@@ -30326,8 +30467,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30326
30467
  errors2.push(`Cannot resolve file '${file.dest}' - no workspace.source configured and no explicit source provided`);
30327
30468
  continue;
30328
30469
  }
30329
- const fullPath = join18(defaultSourcePath, file.dest ?? "");
30330
- if (!existsSync16(fullPath)) {
30470
+ const fullPath = join19(defaultSourcePath, file.dest ?? "");
30471
+ if (!existsSync17(fullPath)) {
30331
30472
  errors2.push(`File source not found: ${fullPath}`);
30332
30473
  }
30333
30474
  }
@@ -30473,7 +30614,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30473
30614
  ...fetchResult.error && { error: fetchResult.error }
30474
30615
  };
30475
30616
  }
30476
- const resolvedPath2 = parsed?.subpath ? join18(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30617
+ const resolvedPath2 = parsed?.subpath ? join19(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30477
30618
  return {
30478
30619
  plugin: pluginSource,
30479
30620
  resolved: resolvedPath2,
@@ -30483,7 +30624,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30483
30624
  };
30484
30625
  }
30485
30626
  const resolvedPath = resolve10(workspacePath, pluginSource);
30486
- if (!existsSync16(resolvedPath)) {
30627
+ if (!existsSync17(resolvedPath)) {
30487
30628
  return {
30488
30629
  plugin: pluginSource,
30489
30630
  resolved: resolvedPath,
@@ -30644,10 +30785,10 @@ function buildPluginSkillNameMaps(allSkills) {
30644
30785
  return pluginMaps;
30645
30786
  }
30646
30787
  function generateVscodeWorkspaceFile(workspacePath, config) {
30647
- const configDir = join18(workspacePath, CONFIG_DIR);
30648
- const templatePath = join18(configDir, VSCODE_TEMPLATE_FILE);
30788
+ const configDir = join19(workspacePath, CONFIG_DIR);
30789
+ const templatePath = join19(configDir, VSCODE_TEMPLATE_FILE);
30649
30790
  let template;
30650
- if (existsSync16(templatePath)) {
30791
+ if (existsSync17(templatePath)) {
30651
30792
  try {
30652
30793
  template = import_json53.default.parse(readFileSync4(templatePath, "utf-8"));
30653
30794
  } catch (error) {
@@ -30662,7 +30803,7 @@ function generateVscodeWorkspaceFile(workspacePath, config) {
30662
30803
  const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
30663
30804
  const contentStr = `${JSON.stringify(content, null, "\t")}
30664
30805
  `;
30665
- writeFileSync4(outputPath, contentStr, "utf-8");
30806
+ writeFileSync6(outputPath, contentStr, "utf-8");
30666
30807
  return contentStr;
30667
30808
  }
30668
30809
  function failedSyncResult(error, overrides) {
@@ -30794,7 +30935,7 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
30794
30935
  let updatedConfig = config;
30795
30936
  if (previousState?.vscodeWorkspaceHash && previousState?.vscodeWorkspaceRepos) {
30796
30937
  const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
30797
- if (existsSync16(outputPath)) {
30938
+ if (existsSync17(outputPath)) {
30798
30939
  const existingContent = readFileSync4(outputPath, "utf-8");
30799
30940
  const currentHash = computeWorkspaceHash(existingContent);
30800
30941
  if (currentHash !== previousState.vscodeWorkspaceHash) {
@@ -30851,16 +30992,17 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
30851
30992
  ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState },
30852
30993
  ...extra?.vscodeState?.hash && { vscodeWorkspaceHash: extra.vscodeState.hash },
30853
30994
  ...extra?.vscodeState?.repos && { vscodeWorkspaceRepos: extra.vscodeState.repos },
30854
- ...extra?.mcpTrackedServers && { mcpServers: extra.mcpTrackedServers }
30995
+ ...extra?.mcpTrackedServers && { mcpServers: extra.mcpTrackedServers },
30996
+ ...extra?.skillsIndex && extra.skillsIndex.length > 0 && { skillsIndex: extra.skillsIndex }
30855
30997
  });
30856
30998
  }
30857
30999
  async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
30858
31000
  await migrateWorkspaceSkillsV1toV2(workspacePath);
30859
31001
  const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
30860
31002
  const sw = new Stopwatch;
30861
- const configDir = join18(workspacePath, CONFIG_DIR);
30862
- const configPath = join18(configDir, WORKSPACE_CONFIG_FILE);
30863
- if (!existsSync16(configPath)) {
31003
+ const configDir = join19(workspacePath, CONFIG_DIR);
31004
+ const configPath = join19(configDir, WORKSPACE_CONFIG_FILE);
31005
+ if (!existsSync17(configPath)) {
30864
31006
  return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
30865
31007
  Run 'allagents workspace init <path>' to create a new workspace`);
30866
31008
  }
@@ -30942,6 +31084,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30942
31084
  })), `${validPlugins.length} plugin(s)`);
30943
31085
  const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages));
30944
31086
  let workspaceFileResults = [];
31087
+ let writtenSkillsIndexFiles = [];
30945
31088
  const skipWorkspaceFiles = !!config.workspace?.source && !validatedWorkspaceSource;
30946
31089
  if (config.workspace && !skipWorkspaceFiles) {
30947
31090
  sw.start("workspace-files");
@@ -30949,8 +31092,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30949
31092
  const filesToCopy = [...config.workspace.files];
30950
31093
  if (hasRepositories && sourcePath) {
30951
31094
  for (const agentFile of AGENT_FILES) {
30952
- const agentPath = join18(sourcePath, agentFile);
30953
- if (existsSync16(agentPath) && !filesToCopy.includes(agentFile)) {
31095
+ const agentPath = join19(sourcePath, agentFile);
31096
+ if (existsSync17(agentPath) && !filesToCopy.includes(agentFile)) {
30954
31097
  filesToCopy.push(agentFile);
30955
31098
  }
30956
31099
  }
@@ -30973,12 +31116,22 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30973
31116
  `)}`, { pluginResults, totalFailed: fileValidationErrors.length });
30974
31117
  }
30975
31118
  const repoSkills = hasRepositories && !dryRun ? await discoverWorkspaceSkills(workspacePath, config.repositories, syncClients) : [];
30976
- workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories, skills: repoSkills });
31119
+ let skillsIndexRefs = [];
31120
+ if (!dryRun) {
31121
+ if (repoSkills.length > 0) {
31122
+ const grouped = groupSkillsByRepo(repoSkills, config.repositories);
31123
+ const result = writeSkillsIndex(workspacePath, grouped);
31124
+ writtenSkillsIndexFiles = result.writtenFiles;
31125
+ skillsIndexRefs = result.refs;
31126
+ }
31127
+ cleanupSkillsIndex(workspacePath, writtenSkillsIndexFiles);
31128
+ }
31129
+ workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories, skillsIndexRefs });
30977
31130
  if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
30978
- const claudePath = join18(workspacePath, "CLAUDE.md");
30979
- const agentsPath = join18(workspacePath, "AGENTS.md");
30980
- const claudeExistsInSource = existsSync16(join18(sourcePath, "CLAUDE.md"));
30981
- if (!claudeExistsInSource && existsSync16(agentsPath) && !existsSync16(claudePath)) {
31131
+ const claudePath = join19(workspacePath, "CLAUDE.md");
31132
+ const agentsPath = join19(workspacePath, "AGENTS.md");
31133
+ const claudeExistsInSource = existsSync17(join19(sourcePath, "CLAUDE.md"));
31134
+ if (!claudeExistsInSource && existsSync17(agentsPath) && !existsSync17(claudePath)) {
30982
31135
  await copyFile(agentsPath, claudePath);
30983
31136
  }
30984
31137
  }
@@ -30995,16 +31148,39 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30995
31148
  vscodeState = { hash: result.hash, repos: result.repos };
30996
31149
  }
30997
31150
  }
31151
+ const mcpProxyConfig = config.mcpProxy;
31152
+ let proxyMetadataPath;
31153
+ let proxyBaseServers;
31154
+ if (mcpProxyConfig) {
31155
+ if (!dryRun) {
31156
+ ensureProxyMetadata();
31157
+ }
31158
+ proxyMetadataPath = getProxyMetadataPath();
31159
+ const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
31160
+ if (proxyWarnings.length > 0) {
31161
+ warnings.push(...proxyWarnings);
31162
+ }
31163
+ if (servers.size > 0) {
31164
+ proxyBaseServers = servers;
31165
+ }
31166
+ }
31167
+ function getServersForClient(client) {
31168
+ if (!mcpProxyConfig || !proxyMetadataPath || !proxyBaseServers)
31169
+ return;
31170
+ return applyMcpProxy(proxyBaseServers, client, mcpProxyConfig, proxyMetadataPath);
31171
+ }
30998
31172
  sw.start("mcp-sync");
30999
31173
  const mcpResults = {};
31000
31174
  if (syncClients.includes("vscode")) {
31001
31175
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
31002
- const projectMcpPath = join18(workspacePath, ".vscode", "mcp.json");
31176
+ const projectMcpPath = join19(workspacePath, ".vscode", "mcp.json");
31177
+ const vscodeMcpOverrides = getServersForClient("vscode");
31003
31178
  const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
31004
31179
  dryRun,
31005
31180
  force: false,
31006
31181
  configPath: projectMcpPath,
31007
- trackedServers: trackedMcpServers
31182
+ trackedServers: trackedMcpServers,
31183
+ ...vscodeMcpOverrides && { serverOverrides: vscodeMcpOverrides }
31008
31184
  });
31009
31185
  if (vscodeMcp.warnings.length > 0) {
31010
31186
  warnings.push(...vscodeMcp.warnings);
@@ -31013,12 +31189,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31013
31189
  }
31014
31190
  if (syncClients.includes("claude")) {
31015
31191
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
31016
- const projectMcpJsonPath = join18(workspacePath, ".mcp.json");
31192
+ const projectMcpJsonPath = join19(workspacePath, ".mcp.json");
31193
+ const claudeMcpOverrides = getServersForClient("claude");
31017
31194
  const claudeMcp = syncClaudeMcpConfig(validPlugins, {
31018
31195
  dryRun,
31019
31196
  force: false,
31020
31197
  configPath: projectMcpJsonPath,
31021
- trackedServers: trackedMcpServers
31198
+ trackedServers: trackedMcpServers,
31199
+ ...claudeMcpOverrides && { serverOverrides: claudeMcpOverrides }
31022
31200
  });
31023
31201
  if (claudeMcp.warnings.length > 0) {
31024
31202
  warnings.push(...claudeMcp.warnings);
@@ -31027,12 +31205,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31027
31205
  }
31028
31206
  if (syncClients.includes("codex")) {
31029
31207
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
31030
- const projectCodexConfigPath = join18(workspacePath, ".codex", "config.toml");
31208
+ const projectCodexConfigPath = join19(workspacePath, ".codex", "config.toml");
31209
+ const codexMcpOverrides = getServersForClient("codex");
31031
31210
  const codexMcp = syncCodexProjectMcpConfig(validPlugins, {
31032
31211
  dryRun,
31033
31212
  force: false,
31034
31213
  configPath: projectCodexConfigPath,
31035
- trackedServers: trackedMcpServers
31214
+ trackedServers: trackedMcpServers,
31215
+ ...codexMcpOverrides && { serverOverrides: codexMcpOverrides }
31036
31216
  });
31037
31217
  if (codexMcp.warnings.length > 0) {
31038
31218
  warnings.push(...codexMcp.warnings);
@@ -31041,12 +31221,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31041
31221
  }
31042
31222
  if (syncClients.includes("copilot")) {
31043
31223
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
31044
- const projectCopilotMcpPath = join18(workspacePath, ".copilot", "mcp-config.json");
31224
+ const projectCopilotMcpPath = join19(workspacePath, ".copilot", "mcp-config.json");
31225
+ const copilotMcpOverrides = getServersForClient("copilot");
31045
31226
  const copilotMcp = syncClaudeMcpConfig(validPlugins, {
31046
31227
  dryRun,
31047
31228
  force: false,
31048
31229
  configPath: projectCopilotMcpPath,
31049
- trackedServers: trackedMcpServers
31230
+ trackedServers: trackedMcpServers,
31231
+ ...copilotMcpOverrides && { serverOverrides: copilotMcpOverrides }
31050
31232
  });
31051
31233
  if (copilotMcp.warnings.length > 0) {
31052
31234
  warnings.push(...copilotMcp.warnings);
@@ -31055,7 +31237,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31055
31237
  }
31056
31238
  sw.stop("mcp-sync");
31057
31239
  const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
31058
- const { servers: allMcpServers } = collectMcpServers(validPlugins);
31240
+ const allMcpServers = proxyBaseServers ?? collectMcpServers(validPlugins).servers;
31059
31241
  if (allMcpServers.size > 0) {
31060
31242
  for (const client of syncClients) {
31061
31243
  if (!PROJECT_MCP_CLIENTS.has(client)) {
@@ -31076,7 +31258,8 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31076
31258
  ...vscodeState && { vscodeState },
31077
31259
  ...Object.keys(mcpResults).length > 0 && {
31078
31260
  mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
31079
- }
31261
+ },
31262
+ ...writtenSkillsIndexFiles.length > 0 && { skillsIndex: writtenSkillsIndexFiles }
31080
31263
  }));
31081
31264
  }
31082
31265
  return {
@@ -31111,7 +31294,7 @@ async function seedFetchCacheFromMarketplaces(results) {
31111
31294
  }
31112
31295
  function readGitBranch(repoPath) {
31113
31296
  try {
31114
- const head = readFileSync4(join18(repoPath, ".git", "HEAD"), "utf-8").trim();
31297
+ const head = readFileSync4(join19(repoPath, ".git", "HEAD"), "utf-8").trim();
31115
31298
  const prefix = "ref: refs/heads/";
31116
31299
  return head.startsWith(prefix) ? head.slice(prefix.length) : null;
31117
31300
  } catch {
@@ -31170,11 +31353,38 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31170
31353
  return { ...result, scope: "user" };
31171
31354
  })), `${validPlugins.length} plugin(s)`);
31172
31355
  const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
31356
+ const userMcpProxyConfig = config.mcpProxy;
31357
+ let userProxyMetadataPath;
31358
+ let userProxyBaseServers;
31359
+ if (userMcpProxyConfig) {
31360
+ if (!dryRun) {
31361
+ ensureProxyMetadata();
31362
+ }
31363
+ userProxyMetadataPath = getProxyMetadataPath();
31364
+ const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
31365
+ if (proxyWarnings.length > 0) {
31366
+ warnings.push(...proxyWarnings);
31367
+ }
31368
+ if (servers.size > 0) {
31369
+ userProxyBaseServers = servers;
31370
+ }
31371
+ }
31372
+ function getUserServersForClient(client) {
31373
+ if (!userMcpProxyConfig || !userProxyMetadataPath || !userProxyBaseServers)
31374
+ return;
31375
+ return applyMcpProxy(userProxyBaseServers, client, userMcpProxyConfig, userProxyMetadataPath);
31376
+ }
31173
31377
  sw.start("mcp-sync");
31174
31378
  const mcpResults = {};
31175
31379
  if (syncClients.includes("vscode")) {
31176
31380
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
31177
- const vscodeMcp = syncVscodeMcpConfig(validPlugins, { dryRun, force, trackedServers: trackedMcpServers });
31381
+ const vscodeMcpOverrides = getUserServersForClient("vscode");
31382
+ const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
31383
+ dryRun,
31384
+ force,
31385
+ trackedServers: trackedMcpServers,
31386
+ ...vscodeMcpOverrides && { serverOverrides: vscodeMcpOverrides }
31387
+ });
31178
31388
  if (vscodeMcp.warnings.length > 0) {
31179
31389
  warnings.push(...vscodeMcp.warnings);
31180
31390
  }
@@ -31182,7 +31392,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31182
31392
  }
31183
31393
  if (syncClients.includes("codex")) {
31184
31394
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
31185
- const codexMcp = await syncCodexMcpServers(validPlugins, { dryRun, trackedServers: trackedMcpServers });
31395
+ const codexMcpOverrides = getUserServersForClient("codex");
31396
+ const codexMcp = await syncCodexMcpServers(validPlugins, {
31397
+ dryRun,
31398
+ trackedServers: trackedMcpServers,
31399
+ ...codexMcpOverrides && { serverOverrides: codexMcpOverrides }
31400
+ });
31186
31401
  if (codexMcp.warnings.length > 0) {
31187
31402
  warnings.push(...codexMcp.warnings);
31188
31403
  }
@@ -31190,7 +31405,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31190
31405
  }
31191
31406
  if (syncClients.includes("claude")) {
31192
31407
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
31193
- const claudeMcp = await syncClaudeMcpServersViaCli(validPlugins, { dryRun, trackedServers: trackedMcpServers });
31408
+ const claudeMcpOverrides = getUserServersForClient("claude");
31409
+ const claudeMcp = await syncClaudeMcpServersViaCli(validPlugins, {
31410
+ dryRun,
31411
+ trackedServers: trackedMcpServers,
31412
+ ...claudeMcpOverrides && { serverOverrides: claudeMcpOverrides }
31413
+ });
31194
31414
  if (claudeMcp.warnings.length > 0) {
31195
31415
  warnings.push(...claudeMcp.warnings);
31196
31416
  }
@@ -31199,11 +31419,13 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31199
31419
  if (syncClients.includes("copilot")) {
31200
31420
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
31201
31421
  const copilotMcpPath = getCopilotMcpConfigPath();
31422
+ const copilotMcpOverrides = getUserServersForClient("copilot");
31202
31423
  const copilotMcp = syncClaudeMcpConfig(validPlugins, {
31203
31424
  dryRun,
31204
31425
  force,
31205
31426
  configPath: copilotMcpPath,
31206
- trackedServers: trackedMcpServers
31427
+ trackedServers: trackedMcpServers,
31428
+ ...copilotMcpOverrides && { serverOverrides: copilotMcpOverrides }
31207
31429
  });
31208
31430
  if (copilotMcp.warnings.length > 0) {
31209
31431
  warnings.push(...copilotMcp.warnings);
@@ -31212,7 +31434,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31212
31434
  }
31213
31435
  sw.stop("mcp-sync");
31214
31436
  const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
31215
- const { servers: allUserMcpServers } = collectMcpServers(validPlugins);
31437
+ const allUserMcpServers = userProxyBaseServers ?? collectMcpServers(validPlugins).servers;
31216
31438
  if (allUserMcpServers.size > 0) {
31217
31439
  for (const client of syncClients) {
31218
31440
  if (!USER_MCP_CLIENTS.has(client)) {
@@ -31268,6 +31490,7 @@ var init_sync = __esm(() => {
31268
31490
  init_vscode_workspace();
31269
31491
  init_workspace_modify();
31270
31492
  init_vscode_mcp();
31493
+ init_mcp_proxy();
31271
31494
  init_codex_mcp();
31272
31495
  init_claude_mcp();
31273
31496
  init_copilot_mcp();
@@ -31276,11 +31499,11 @@ var init_sync = __esm(() => {
31276
31499
  });
31277
31500
 
31278
31501
  // src/core/github-fetch.ts
31279
- import { existsSync as existsSync17, readFileSync as readFileSync5 } from "node:fs";
31280
- import { join as join19 } from "node:path";
31502
+ import { existsSync as existsSync18, readFileSync as readFileSync5 } from "node:fs";
31503
+ import { join as join20 } from "node:path";
31281
31504
  function readFileFromClone(tempDir, filePath) {
31282
- const fullPath = join19(tempDir, filePath);
31283
- if (existsSync17(fullPath)) {
31505
+ const fullPath = join20(tempDir, filePath);
31506
+ if (existsSync18(fullPath)) {
31284
31507
  return readFileSync5(fullPath, "utf-8");
31285
31508
  }
31286
31509
  return null;
@@ -31380,14 +31603,14 @@ var init_github_fetch = __esm(() => {
31380
31603
 
31381
31604
  // src/core/workspace.ts
31382
31605
  import { cp as cp2, mkdir as mkdir8, readFile as readFile12, writeFile as writeFile8, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
31383
- import { existsSync as existsSync18 } from "node:fs";
31384
- import { join as join20, resolve as resolve11, dirname as dirname11, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31606
+ import { existsSync as existsSync19 } from "node:fs";
31607
+ import { join as join21, resolve as resolve11, dirname as dirname12, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31385
31608
  import { fileURLToPath } from "node:url";
31386
31609
  async function initWorkspace(targetPath = ".", options2 = {}) {
31387
31610
  const absoluteTarget = resolve11(targetPath);
31388
- const configDir = join20(absoluteTarget, CONFIG_DIR);
31389
- const configPath = join20(configDir, WORKSPACE_CONFIG_FILE);
31390
- if (existsSync18(configPath)) {
31611
+ const configDir = join21(absoluteTarget, CONFIG_DIR);
31612
+ const configPath = join21(configDir, WORKSPACE_CONFIG_FILE);
31613
+ if (existsSync19(configPath)) {
31391
31614
  if (options2.force) {
31392
31615
  await unlink3(configPath);
31393
31616
  } else {
@@ -31396,9 +31619,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31396
31619
  }
31397
31620
  }
31398
31621
  const currentFilePath = fileURLToPath(import.meta.url);
31399
- const currentFileDir = dirname11(currentFilePath);
31622
+ const currentFileDir = dirname12(currentFilePath);
31400
31623
  const isProduction = currentFilePath.includes(`${sep2}dist${sep2}`);
31401
- const defaultTemplatePath = isProduction ? join20(currentFileDir, "templates", "default") : join20(currentFileDir, "..", "templates", "default");
31624
+ const defaultTemplatePath = isProduction ? join21(currentFileDir, "templates", "default") : join21(currentFileDir, "..", "templates", "default");
31402
31625
  let githubTempDir;
31403
31626
  let parsedFromUrl;
31404
31627
  let githubBasePath = "";
@@ -31438,19 +31661,19 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31438
31661
  console.log(`✓ Using workspace.yaml from: ${options2.from}`);
31439
31662
  } else {
31440
31663
  const fromPath = resolve11(options2.from);
31441
- if (!existsSync18(fromPath)) {
31664
+ if (!existsSync19(fromPath)) {
31442
31665
  throw new Error(`Template not found: ${fromPath}`);
31443
31666
  }
31444
31667
  const { stat: stat2 } = await import("node:fs/promises");
31445
31668
  const fromStat = await stat2(fromPath);
31446
31669
  let sourceYamlPath;
31447
31670
  if (fromStat.isDirectory()) {
31448
- const nestedPath = join20(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31449
- const rootPath = join20(fromPath, WORKSPACE_CONFIG_FILE);
31450
- if (existsSync18(nestedPath)) {
31671
+ const nestedPath = join21(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31672
+ const rootPath = join21(fromPath, WORKSPACE_CONFIG_FILE);
31673
+ if (existsSync19(nestedPath)) {
31451
31674
  sourceYamlPath = nestedPath;
31452
31675
  sourceDir = fromPath;
31453
- } else if (existsSync18(rootPath)) {
31676
+ } else if (existsSync19(rootPath)) {
31454
31677
  sourceYamlPath = rootPath;
31455
31678
  sourceDir = fromPath;
31456
31679
  } else {
@@ -31459,9 +31682,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31459
31682
  }
31460
31683
  } else {
31461
31684
  sourceYamlPath = fromPath;
31462
- const parentDir = dirname11(fromPath);
31685
+ const parentDir = dirname12(fromPath);
31463
31686
  if (parentDir.endsWith(CONFIG_DIR)) {
31464
- sourceDir = dirname11(parentDir);
31687
+ sourceDir = dirname12(parentDir);
31465
31688
  } else {
31466
31689
  sourceDir = parentDir;
31467
31690
  }
@@ -31481,8 +31704,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31481
31704
  console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
31482
31705
  }
31483
31706
  } else {
31484
- const defaultYamlPath = join20(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31485
- if (!existsSync18(defaultYamlPath)) {
31707
+ const defaultYamlPath = join21(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31708
+ if (!existsSync19(defaultYamlPath)) {
31486
31709
  throw new Error(`Default template not found at: ${defaultTemplatePath}`);
31487
31710
  }
31488
31711
  workspaceYamlContent = await readFile12(defaultYamlPath, "utf-8");
@@ -31498,8 +31721,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31498
31721
  const clientNames = getClientTypes(clients);
31499
31722
  const VSCODE_TEMPLATE_FILE2 = "template.code-workspace";
31500
31723
  if (clientNames.includes("vscode") && options2.from) {
31501
- const targetTemplatePath = join20(configDir, VSCODE_TEMPLATE_FILE2);
31502
- if (!existsSync18(targetTemplatePath)) {
31724
+ const targetTemplatePath = join21(configDir, VSCODE_TEMPLATE_FILE2);
31725
+ if (!existsSync19(targetTemplatePath)) {
31503
31726
  if (isGitHubUrl(options2.from) && githubTempDir) {
31504
31727
  if (parsedFromUrl) {
31505
31728
  const templatePath = githubBasePath ? `${githubBasePath}/${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}` : `${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}`;
@@ -31509,8 +31732,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31509
31732
  }
31510
31733
  }
31511
31734
  } else if (sourceDir) {
31512
- const sourceTemplatePath = join20(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31513
- if (existsSync18(sourceTemplatePath)) {
31735
+ const sourceTemplatePath = join21(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31736
+ if (existsSync19(sourceTemplatePath)) {
31514
31737
  await copyFile2(sourceTemplatePath, targetTemplatePath);
31515
31738
  }
31516
31739
  }
@@ -31523,8 +31746,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31523
31746
  if (options2.from && isGitHubUrl(options2.from) && githubTempDir) {
31524
31747
  if (parsedFromUrl) {
31525
31748
  for (const agentFile of AGENT_FILES) {
31526
- const targetFilePath = join20(absoluteTarget, agentFile);
31527
- if (existsSync18(targetFilePath)) {
31749
+ const targetFilePath = join21(absoluteTarget, agentFile);
31750
+ if (existsSync19(targetFilePath)) {
31528
31751
  copiedAgentFiles.push(agentFile);
31529
31752
  continue;
31530
31753
  }
@@ -31539,13 +31762,13 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31539
31762
  } else {
31540
31763
  const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
31541
31764
  for (const agentFile of AGENT_FILES) {
31542
- const targetFilePath = join20(absoluteTarget, agentFile);
31543
- if (existsSync18(targetFilePath)) {
31765
+ const targetFilePath = join21(absoluteTarget, agentFile);
31766
+ if (existsSync19(targetFilePath)) {
31544
31767
  copiedAgentFiles.push(agentFile);
31545
31768
  continue;
31546
31769
  }
31547
- const sourcePath = join20(effectiveSourceDir, agentFile);
31548
- if (existsSync18(sourcePath)) {
31770
+ const sourcePath = join21(effectiveSourceDir, agentFile);
31771
+ if (existsSync19(sourcePath)) {
31549
31772
  const content = await readFile12(sourcePath, "utf-8");
31550
31773
  await writeFile8(targetFilePath, content, "utf-8");
31551
31774
  copiedAgentFiles.push(agentFile);
@@ -31553,16 +31776,16 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31553
31776
  }
31554
31777
  }
31555
31778
  if (copiedAgentFiles.length === 0) {
31556
- await ensureWorkspaceRules(join20(absoluteTarget, "AGENTS.md"), repositories);
31779
+ await ensureWorkspaceRules(join21(absoluteTarget, "AGENTS.md"), repositories);
31557
31780
  copiedAgentFiles.push("AGENTS.md");
31558
31781
  } else {
31559
31782
  for (const agentFile of copiedAgentFiles) {
31560
- await ensureWorkspaceRules(join20(absoluteTarget, agentFile), repositories);
31783
+ await ensureWorkspaceRules(join21(absoluteTarget, agentFile), repositories);
31561
31784
  }
31562
31785
  }
31563
31786
  if (clientNames.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
31564
- const agentsPath = join20(absoluteTarget, "AGENTS.md");
31565
- const claudePath = join20(absoluteTarget, "CLAUDE.md");
31787
+ const agentsPath = join21(absoluteTarget, "AGENTS.md");
31788
+ const claudePath = join21(absoluteTarget, "CLAUDE.md");
31566
31789
  await copyFile2(agentsPath, claudePath);
31567
31790
  }
31568
31791
  }
@@ -31607,14 +31830,14 @@ Next steps:`);
31607
31830
  async function seedCacheFromClone(tempDir, owner, repo, branch) {
31608
31831
  const cachePaths = [
31609
31832
  getPluginCachePath(owner, repo, branch),
31610
- join20(getMarketplacesDir(), repo)
31833
+ join21(getMarketplacesDir(), repo)
31611
31834
  ];
31612
31835
  for (const cachePath of cachePaths) {
31613
- if (existsSync18(cachePath))
31836
+ if (existsSync19(cachePath))
31614
31837
  continue;
31615
31838
  try {
31616
- const parentDir = dirname11(cachePath);
31617
- if (!existsSync18(parentDir)) {
31839
+ const parentDir = dirname12(cachePath);
31840
+ if (!existsSync19(parentDir)) {
31618
31841
  await mkdir8(parentDir, { recursive: true });
31619
31842
  }
31620
31843
  await cp2(tempDir, cachePath, { recursive: true });
@@ -31635,11 +31858,11 @@ var init_workspace = __esm(() => {
31635
31858
  });
31636
31859
 
31637
31860
  // src/core/status.ts
31638
- import { existsSync as existsSync19 } from "node:fs";
31639
- import { join as join21 } from "node:path";
31861
+ import { existsSync as existsSync20 } from "node:fs";
31862
+ import { join as join22 } from "node:path";
31640
31863
  async function getWorkspaceStatus(workspacePath = process.cwd()) {
31641
- const configPath = join21(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31642
- if (!existsSync19(configPath) || isUserConfigPath(workspacePath)) {
31864
+ const configPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31865
+ if (!existsSync20(configPath) || isUserConfigPath(workspacePath)) {
31643
31866
  const userPlugins = await getUserPluginStatuses();
31644
31867
  return {
31645
31868
  success: true,
@@ -31681,7 +31904,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
31681
31904
  function getPluginStatus(parsed) {
31682
31905
  if (parsed.type === "github") {
31683
31906
  const cachePath = parsed.owner && parsed.repo ? getPluginCachePath(parsed.owner, parsed.repo) : "";
31684
- const available2 = cachePath ? existsSync19(cachePath) : false;
31907
+ const available2 = cachePath ? existsSync20(cachePath) : false;
31685
31908
  return {
31686
31909
  source: parsed.original,
31687
31910
  type: "github",
@@ -31691,7 +31914,7 @@ function getPluginStatus(parsed) {
31691
31914
  ...parsed.repo && { repo: parsed.repo }
31692
31915
  };
31693
31916
  }
31694
- const available = existsSync19(parsed.normalized);
31917
+ const available = existsSync20(parsed.normalized);
31695
31918
  return {
31696
31919
  source: parsed.original,
31697
31920
  type: "local",
@@ -33828,9 +34051,9 @@ var init_prompt_clients = __esm(() => {
33828
34051
  });
33829
34052
 
33830
34053
  // src/core/skills.ts
33831
- import { existsSync as existsSync22 } from "node:fs";
34054
+ import { existsSync as existsSync23 } from "node:fs";
33832
34055
  import { readFile as readFile14, readdir as readdir5 } from "node:fs/promises";
33833
- import { join as join24, basename as basename6, resolve as resolve13 } from "node:path";
34056
+ import { join as join25, basename as basename7, resolve as resolve13 } from "node:path";
33834
34057
  async function resolvePluginPath(pluginSource, workspacePath) {
33835
34058
  if (isPluginSpec(pluginSource)) {
33836
34059
  const resolved2 = await resolvePluginSpecWithAutoRegister(pluginSource, {
@@ -33851,15 +34074,15 @@ async function resolvePluginPath(pluginSource, workspacePath) {
33851
34074
  });
33852
34075
  if (!result.success)
33853
34076
  return null;
33854
- const path = parsed?.subpath ? join24(result.cachePath, parsed.subpath) : result.cachePath;
34077
+ const path = parsed?.subpath ? join25(result.cachePath, parsed.subpath) : result.cachePath;
33855
34078
  return { path };
33856
34079
  }
33857
34080
  const resolved = resolve13(workspacePath, pluginSource);
33858
- return existsSync22(resolved) ? { path: resolved } : null;
34081
+ return existsSync23(resolved) ? { path: resolved } : null;
33859
34082
  }
33860
34083
  async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33861
- const configPath = join24(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
33862
- if (!existsSync22(configPath)) {
34084
+ const configPath = join25(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34085
+ if (!existsSync23(configPath)) {
33863
34086
  return [];
33864
34087
  }
33865
34088
  const content = await readFile14(configPath, "utf-8");
@@ -33875,32 +34098,32 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33875
34098
  continue;
33876
34099
  const pluginPath = resolved.path;
33877
34100
  const pluginName = resolved.pluginName ?? getPluginName(pluginPath);
33878
- const skillsDir = join24(pluginPath, "skills");
34101
+ const skillsDir = join25(pluginPath, "skills");
33879
34102
  const pluginSkillsConfig = typeof pluginEntry === "string" ? undefined : pluginEntry.skills;
33880
34103
  const hasEnabledEntries = !pluginSkillsConfig && enabledSkills && [...enabledSkills].some((s) => s.startsWith(`${pluginName}`));
33881
34104
  let skillEntries;
33882
- if (existsSync22(skillsDir)) {
34105
+ if (existsSync23(skillsDir)) {
33883
34106
  const entries = await readdir5(skillsDir, { withFileTypes: true });
33884
- skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join24(skillsDir, e.name) }));
34107
+ skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join25(skillsDir, e.name) }));
33885
34108
  } else {
33886
34109
  const entries = await readdir5(pluginPath, { withFileTypes: true });
33887
34110
  const flatSkills = [];
33888
34111
  for (const entry of entries) {
33889
34112
  if (!entry.isDirectory())
33890
34113
  continue;
33891
- const skillMdPath = join24(pluginPath, entry.name, "SKILL.md");
33892
- if (existsSync22(skillMdPath)) {
33893
- flatSkills.push({ name: entry.name, skillPath: join24(pluginPath, entry.name) });
34114
+ const skillMdPath = join25(pluginPath, entry.name, "SKILL.md");
34115
+ if (existsSync23(skillMdPath)) {
34116
+ flatSkills.push({ name: entry.name, skillPath: join25(pluginPath, entry.name) });
33894
34117
  }
33895
34118
  }
33896
34119
  if (flatSkills.length > 0) {
33897
34120
  skillEntries = flatSkills;
33898
34121
  } else {
33899
- const rootSkillMd = join24(pluginPath, "SKILL.md");
33900
- if (existsSync22(rootSkillMd)) {
34122
+ const rootSkillMd = join25(pluginPath, "SKILL.md");
34123
+ if (existsSync23(rootSkillMd)) {
33901
34124
  const skillContent = await readFile14(rootSkillMd, "utf-8");
33902
34125
  const metadata = parseSkillMetadata(skillContent);
33903
- const skillName = metadata?.name ?? basename6(pluginPath);
34126
+ const skillName = metadata?.name ?? basename7(pluginPath);
33904
34127
  skillEntries = [{ name: skillName, skillPath: pluginPath }];
33905
34128
  } else {
33906
34129
  skillEntries = [];
@@ -33939,10 +34162,10 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
33939
34162
  return allSkills.filter((s) => s.name === skillName);
33940
34163
  }
33941
34164
  async function discoverSkillNames(pluginPath) {
33942
- if (!existsSync22(pluginPath))
34165
+ if (!existsSync23(pluginPath))
33943
34166
  return [];
33944
- const skillsDir = join24(pluginPath, "skills");
33945
- if (existsSync22(skillsDir)) {
34167
+ const skillsDir = join25(pluginPath, "skills");
34168
+ if (existsSync23(skillsDir)) {
33946
34169
  const entries2 = await readdir5(skillsDir, { withFileTypes: true });
33947
34170
  return entries2.filter((e) => e.isDirectory()).map((e) => e.name);
33948
34171
  }
@@ -33951,21 +34174,21 @@ async function discoverSkillNames(pluginPath) {
33951
34174
  for (const entry of entries) {
33952
34175
  if (!entry.isDirectory())
33953
34176
  continue;
33954
- if (existsSync22(join24(pluginPath, entry.name, "SKILL.md"))) {
34177
+ if (existsSync23(join25(pluginPath, entry.name, "SKILL.md"))) {
33955
34178
  flatSkills.push(entry.name);
33956
34179
  }
33957
34180
  }
33958
34181
  if (flatSkills.length > 0)
33959
34182
  return flatSkills;
33960
- const rootSkillMd = join24(pluginPath, "SKILL.md");
33961
- if (existsSync22(rootSkillMd)) {
34183
+ const rootSkillMd = join25(pluginPath, "SKILL.md");
34184
+ if (existsSync23(rootSkillMd)) {
33962
34185
  try {
33963
34186
  const content = await readFile14(rootSkillMd, "utf-8");
33964
34187
  const { parseSkillMetadata: parseSkillMetadata2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
33965
34188
  const metadata = parseSkillMetadata2(content);
33966
- return [metadata?.name ?? basename6(pluginPath)];
34189
+ return [metadata?.name ?? basename7(pluginPath)];
33967
34190
  } catch {
33968
- return [basename6(pluginPath)];
34191
+ return [basename7(pluginPath)];
33969
34192
  }
33970
34193
  }
33971
34194
  return [];
@@ -34478,7 +34701,7 @@ var package_default;
34478
34701
  var init_package = __esm(() => {
34479
34702
  package_default = {
34480
34703
  name: "allagents",
34481
- version: "1.6.0",
34704
+ version: "1.7.0",
34482
34705
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
34483
34706
  type: "module",
34484
34707
  bin: {
@@ -34559,10 +34782,10 @@ var init_package = __esm(() => {
34559
34782
 
34560
34783
  // src/cli/update-check.ts
34561
34784
  import { readFile as readFile17 } from "node:fs/promises";
34562
- import { join as join27 } from "node:path";
34785
+ import { join as join28 } from "node:path";
34563
34786
  import { spawn as spawn3 } from "node:child_process";
34564
34787
  async function getCachedUpdateInfo(path3) {
34565
- const filePath = path3 ?? join27(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34788
+ const filePath = path3 ?? join28(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34566
34789
  try {
34567
34790
  const raw = await readFile17(filePath, "utf-8");
34568
34791
  const data = JSON.parse(raw);
@@ -34600,8 +34823,8 @@ function buildNotice(currentVersion, latestVersion) {
34600
34823
  Run \`allagents self update\` to upgrade.`);
34601
34824
  }
34602
34825
  function backgroundUpdateCheck() {
34603
- const dir = join27(getHomeDir(), CONFIG_DIR);
34604
- const filePath = join27(dir, CACHE_FILE);
34826
+ const dir = join28(getHomeDir(), CONFIG_DIR);
34827
+ const filePath = join28(dir, CACHE_FILE);
34605
34828
  const script = `
34606
34829
  const https = require('https');
34607
34830
  const fs = require('fs');
@@ -34688,15 +34911,15 @@ class TuiCache {
34688
34911
  }
34689
34912
 
34690
34913
  // src/cli/tui/context.ts
34691
- import { existsSync as existsSync25 } from "node:fs";
34692
- import { join as join28 } from "node:path";
34914
+ import { existsSync as existsSync26 } from "node:fs";
34915
+ import { join as join29 } from "node:path";
34693
34916
  async function getTuiContext(cwd = process.cwd(), cache2) {
34694
34917
  const cachedContext = cache2?.getContext();
34695
34918
  if (cachedContext) {
34696
34919
  return cachedContext;
34697
34920
  }
34698
- const configPath = join28(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34699
- const hasWorkspace = existsSync25(configPath) && !isUserConfigPath(cwd);
34921
+ const configPath = join29(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34922
+ const hasWorkspace = existsSync26(configPath) && !isUserConfigPath(cwd);
34700
34923
  let projectPluginCount = 0;
34701
34924
  if (hasWorkspace) {
34702
34925
  try {
@@ -36112,8 +36335,8 @@ init_workspace();
36112
36335
  init_sync();
36113
36336
  init_status2();
36114
36337
  var import_cmd_ts2 = __toESM(require_cjs(), 1);
36115
- import { existsSync as existsSync21 } from "node:fs";
36116
- import { join as join23, resolve as resolve12 } from "node:path";
36338
+ import { existsSync as existsSync22 } from "node:fs";
36339
+ import { join as join24, resolve as resolve12 } from "node:path";
36117
36340
 
36118
36341
  // src/core/prune.ts
36119
36342
  init_js_yaml();
@@ -36122,8 +36345,8 @@ init_marketplace();
36122
36345
  init_user_workspace();
36123
36346
  init_workspace_config();
36124
36347
  import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
36125
- import { existsSync as existsSync20 } from "node:fs";
36126
- import { join as join22 } from "node:path";
36348
+ import { existsSync as existsSync21 } from "node:fs";
36349
+ import { join as join23 } from "node:path";
36127
36350
  async function isOrphanedPlugin(pluginSpec) {
36128
36351
  if (!isPluginSpec(pluginSpec))
36129
36352
  return false;
@@ -36150,8 +36373,8 @@ async function prunePlugins(plugins) {
36150
36373
  }
36151
36374
  async function pruneOrphanedPlugins(workspacePath) {
36152
36375
  let projectResult = { removed: [], kept: [], keptEntries: [] };
36153
- const projectConfigPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
36154
- if (existsSync20(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36376
+ const projectConfigPath = join23(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
36377
+ if (existsSync21(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36155
36378
  const content = await readFile13(projectConfigPath, "utf-8");
36156
36379
  const config = load(content);
36157
36380
  projectResult = await prunePlugins(config.plugins);
@@ -36443,8 +36666,8 @@ var syncCmd = import_cmd_ts2.command({
36443
36666
  `);
36444
36667
  }
36445
36668
  const userConfigExists = !!await getUserWorkspaceConfig();
36446
- const projectConfigPath = join23(process.cwd(), ".allagents", "workspace.yaml");
36447
- const projectConfigExists = existsSync21(projectConfigPath);
36669
+ const projectConfigPath = join24(process.cwd(), ".allagents", "workspace.yaml");
36670
+ const projectConfigExists = existsSync22(projectConfigPath);
36448
36671
  if (!userConfigExists && !projectConfigExists) {
36449
36672
  await ensureUserWorkspace();
36450
36673
  if (isJsonMode()) {
@@ -37112,9 +37335,9 @@ init_workspace_modify();
37112
37335
  init_user_workspace();
37113
37336
  init_skills();
37114
37337
  var import_cmd_ts3 = __toESM(require_cjs(), 1);
37115
- import { existsSync as existsSync23 } from "node:fs";
37338
+ import { existsSync as existsSync24 } from "node:fs";
37116
37339
  import { readFile as readFile15 } from "node:fs/promises";
37117
- import { join as join25 } from "node:path";
37340
+ import { join as join26 } from "node:path";
37118
37341
 
37119
37342
  // src/cli/metadata/plugin-skills.ts
37120
37343
  var skillsListMeta = {
@@ -37205,7 +37428,7 @@ init_skill();
37205
37428
  init_marketplace();
37206
37429
  init_marketplace_manifest_parser();
37207
37430
  function hasProjectConfig(dir) {
37208
- return existsSync23(join25(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37431
+ return existsSync24(join26(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37209
37432
  }
37210
37433
  function resolveScope(cwd) {
37211
37434
  if (isUserConfigPath(cwd))
@@ -37236,7 +37459,7 @@ async function resolveSkillNameFromRepo(url, parsed, fallbackName, fetchFn = fet
37236
37459
  if (!fetchResult.success)
37237
37460
  return fallbackName;
37238
37461
  try {
37239
- const skillMd = await readFile15(join25(fetchResult.cachePath, "SKILL.md"), "utf-8");
37462
+ const skillMd = await readFile15(join26(fetchResult.cachePath, "SKILL.md"), "utf-8");
37240
37463
  const metadata = parseSkillMetadata(skillMd);
37241
37464
  return metadata?.name ?? fallbackName;
37242
37465
  } catch {
@@ -37794,8 +38017,8 @@ init_workspace_config();
37794
38017
  init_constants();
37795
38018
  init_js_yaml();
37796
38019
  import { readFile as readFile16 } from "node:fs/promises";
37797
- import { existsSync as existsSync24 } from "node:fs";
37798
- import { join as join26 } from "node:path";
38020
+ import { existsSync as existsSync25 } from "node:fs";
38021
+ import { join as join27 } from "node:path";
37799
38022
  async function runSyncAndPrint(options2) {
37800
38023
  if (!isJsonMode()) {
37801
38024
  console.log(`
@@ -38040,7 +38263,7 @@ var marketplaceAddCmd = import_cmd_ts4.command({
38040
38263
  process.exit(1);
38041
38264
  }
38042
38265
  if (effectiveScope === "project") {
38043
- if (!existsSync24(join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38266
+ if (!existsSync25(join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38044
38267
  const msg = 'No workspace found in current directory. Run "allagents workspace init" first.';
38045
38268
  if (isJsonMode()) {
38046
38269
  jsonOutput({ success: false, command: "plugin marketplace add", error: msg });
@@ -38347,7 +38570,7 @@ var pluginListCmd = import_cmd_ts4.command({
38347
38570
  };
38348
38571
  const pluginClients = new Map;
38349
38572
  async function loadConfigClients(configPath, scope) {
38350
- if (!existsSync24(configPath))
38573
+ if (!existsSync25(configPath))
38351
38574
  return;
38352
38575
  try {
38353
38576
  const content = await readFile16(configPath, "utf-8");
@@ -38362,8 +38585,8 @@ var pluginListCmd = import_cmd_ts4.command({
38362
38585
  }
38363
38586
  } catch {}
38364
38587
  }
38365
- const userConfigPath = join26(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
38366
- const projectConfigPath = join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38588
+ const userConfigPath = join27(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
38589
+ const projectConfigPath = join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38367
38590
  const cwdIsHome = isUserConfigPath(process.cwd());
38368
38591
  await loadConfigClients(userConfigPath, "user");
38369
38592
  if (!cwdIsHome) {
@@ -38505,7 +38728,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
38505
38728
  const isUser = scope === "user" || !scope && isUserConfigPath(process.cwd());
38506
38729
  if (isUser) {
38507
38730
  const userConfigPath = getUserWorkspaceConfigPath();
38508
- if (!existsSync24(userConfigPath)) {
38731
+ if (!existsSync25(userConfigPath)) {
38509
38732
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38510
38733
  const clients = await promptForClients2();
38511
38734
  if (clients === null) {
@@ -38517,8 +38740,8 @@ var pluginInstallCmd = import_cmd_ts4.command({
38517
38740
  await ensureUserWorkspace(clients);
38518
38741
  }
38519
38742
  } else {
38520
- const configPath = join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38521
- if (!existsSync24(configPath)) {
38743
+ const configPath = join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38744
+ if (!existsSync25(configPath)) {
38522
38745
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38523
38746
  const clients = await promptForClients2();
38524
38747
  if (clients === null) {
@@ -38795,13 +39018,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
38795
39018
  }
38796
39019
  }
38797
39020
  if (updateProject && !isUserConfigPath(process.cwd())) {
38798
- const { existsSync: existsSync25 } = await import("node:fs");
39021
+ const { existsSync: existsSync26 } = await import("node:fs");
38799
39022
  const { readFile: readFile17 } = await import("node:fs/promises");
38800
- const { join: join27 } = await import("node:path");
39023
+ const { join: join28 } = await import("node:path");
38801
39024
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
38802
39025
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
38803
- const configPath = join27(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
38804
- if (existsSync25(configPath)) {
39026
+ const configPath = join28(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
39027
+ if (existsSync26(configPath)) {
38805
39028
  const content = await readFile17(configPath, "utf-8");
38806
39029
  const config = load2(content);
38807
39030
  for (const entry of config.plugins ?? []) {