allagents 1.6.1 → 1.7.1

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 +417 -207
  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
7476
  ## Repository 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>
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 [];
@@ -28434,13 +28435,14 @@ async function discoverRepoSkills(repoPath, options2) {
28434
28435
  async function discoverWorkspaceSkills(workspacePath, repositories, clientNames) {
28435
28436
  const skillsByName = new Map;
28436
28437
  for (const repo of repositories) {
28437
- if (repo.skills === false)
28438
+ if (repo.skills === false || repo.skills === undefined)
28438
28439
  continue;
28439
28440
  const repoAbsPath = resolve8(workspacePath, repo.path);
28440
28441
  const discoverOpts = Array.isArray(repo.skills) ? { skillPaths: repo.skills } : { clients: clientNames };
28441
28442
  const repoSkills = await discoverRepoSkills(repoAbsPath, discoverOpts);
28442
28443
  for (const skill of repoSkills) {
28443
- const location = `${repo.path}/${skill.relativePath}`.replace(/\\/g, "/");
28444
+ const base = repo.path.replace(/[/\\]+$/, "");
28445
+ const location = `${base}/${skill.relativePath}`.replace(/\\/g, "/");
28444
28446
  const candidate = {
28445
28447
  repoPath: repo.path,
28446
28448
  name: skill.name,
@@ -28464,6 +28466,73 @@ async function discoverWorkspaceSkills(workspacePath, repositories, clientNames)
28464
28466
  }
28465
28467
  return [...skillsByName.values()].map(({ fileSize: _, ...entry }) => entry);
28466
28468
  }
28469
+ function writeSkillsIndex(workspacePath, skillsByRepo) {
28470
+ if (skillsByRepo.size === 0)
28471
+ return { writtenFiles: [], refs: [] };
28472
+ const indexDir = join12(workspacePath, ".allagents", "skills-index");
28473
+ mkdirSync(indexDir, { recursive: true });
28474
+ const writtenFiles = [];
28475
+ const refs = [];
28476
+ for (const [, { repoName, skills }] of skillsByRepo) {
28477
+ const skillEntries = skills.map((s) => `<skill>
28478
+ <name>${s.name}</name>
28479
+ <description>${s.description}</description>
28480
+ <location>${s.location}</location>
28481
+ </skill>`).join(`
28482
+ `);
28483
+ const content = `# Skills: ${repoName}
28484
+
28485
+ <available_skills>
28486
+ ${skillEntries}
28487
+ </available_skills>
28488
+ `;
28489
+ const filePath = `skills-index/${repoName}.md`;
28490
+ writeFileSync(join12(indexDir, `${repoName}.md`), content, "utf-8");
28491
+ writtenFiles.push(filePath);
28492
+ refs.push({ repoName, indexPath: `.allagents/${filePath}` });
28493
+ }
28494
+ return { writtenFiles, refs };
28495
+ }
28496
+ function cleanupSkillsIndex(workspacePath, currentFiles) {
28497
+ const indexDir = join12(workspacePath, ".allagents", "skills-index");
28498
+ if (!existsSync9(indexDir))
28499
+ return;
28500
+ const currentSet = new Set(currentFiles.map((f) => f.replace("skills-index/", "")));
28501
+ let entries;
28502
+ try {
28503
+ entries = readdirSync(indexDir);
28504
+ } catch {
28505
+ return;
28506
+ }
28507
+ for (const entry of entries) {
28508
+ if (!currentSet.has(entry)) {
28509
+ rmSync(join12(indexDir, entry), { force: true });
28510
+ }
28511
+ }
28512
+ try {
28513
+ const remaining = readdirSync(indexDir);
28514
+ if (remaining.length === 0) {
28515
+ rmSync(indexDir, { recursive: true, force: true });
28516
+ }
28517
+ } catch {}
28518
+ }
28519
+ function groupSkillsByRepo(skills, repositories) {
28520
+ const repoNameMap = new Map;
28521
+ for (const repo of repositories) {
28522
+ repoNameMap.set(repo.path, repo.name ?? basename5(repo.path));
28523
+ }
28524
+ const grouped = new Map;
28525
+ for (const skill of skills) {
28526
+ const repoName = repoNameMap.get(skill.repoPath) ?? basename5(skill.repoPath);
28527
+ const existing = grouped.get(skill.repoPath);
28528
+ if (existing) {
28529
+ existing.skills.push(skill);
28530
+ } else {
28531
+ grouped.set(skill.repoPath, { repoName, skills: [skill] });
28532
+ }
28533
+ }
28534
+ return grouped;
28535
+ }
28467
28536
  var init_repo_skills = __esm(() => {
28468
28537
  init_skill();
28469
28538
  init_client_mapping();
@@ -28585,6 +28654,9 @@ async function updateAgentFiles(workspacePath = process.cwd()) {
28585
28654
  return;
28586
28655
  const clientNames = resolveClientNames(config.clients);
28587
28656
  const allSkills = await discoverWorkspaceSkills(workspacePath, config.repositories, clientNames);
28657
+ const grouped = groupSkillsByRepo(allSkills, config.repositories);
28658
+ const { writtenFiles, refs: skillsIndexRefs } = writeSkillsIndex(workspacePath, grouped);
28659
+ cleanupSkillsIndex(workspacePath, writtenFiles);
28588
28660
  const agentFiles = new Set;
28589
28661
  for (const client of config.clients ?? []) {
28590
28662
  const clientName = typeof client === "string" ? client : client.name;
@@ -28594,7 +28666,7 @@ async function updateAgentFiles(workspacePath = process.cwd()) {
28594
28666
  }
28595
28667
  agentFiles.add("AGENTS.md");
28596
28668
  for (const agentFile of agentFiles) {
28597
- await ensureWorkspaceRules(join13(workspacePath, agentFile), config.repositories, allSkills);
28669
+ await ensureWorkspaceRules(join13(workspacePath, agentFile), config.repositories, skillsIndexRefs);
28598
28670
  }
28599
28671
  }
28600
28672
  var init_workspace_repo = __esm(() => {
@@ -28765,7 +28837,8 @@ var init_sync_state = __esm(() => {
28765
28837
  mcpServers: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
28766
28838
  nativePlugins: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())).optional(),
28767
28839
  vscodeWorkspaceHash: exports_external.string().optional(),
28768
- vscodeWorkspaceRepos: exports_external.array(exports_external.string()).optional()
28840
+ vscodeWorkspaceRepos: exports_external.array(exports_external.string()).optional(),
28841
+ skillsIndex: exports_external.array(exports_external.string()).optional()
28769
28842
  });
28770
28843
  });
28771
28844
 
@@ -28831,7 +28904,8 @@ async function saveSyncState(workspacePath, data) {
28831
28904
  ...normalizedData.mcpServers && { mcpServers: normalizedData.mcpServers },
28832
28905
  ...normalizedData.nativePlugins && { nativePlugins: normalizedData.nativePlugins },
28833
28906
  ...normalizedData.vscodeWorkspaceHash && { vscodeWorkspaceHash: normalizedData.vscodeWorkspaceHash },
28834
- ...normalizedData.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: normalizedData.vscodeWorkspaceRepos }
28907
+ ...normalizedData.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: normalizedData.vscodeWorkspaceRepos },
28908
+ ...normalizedData.skillsIndex && normalizedData.skillsIndex.length > 0 && { skillsIndex: normalizedData.skillsIndex }
28835
28909
  };
28836
28910
  await mkdir7(dirname6(statePath), { recursive: true });
28837
28911
  await ensureConfigGitignore(workspacePath);
@@ -28862,7 +28936,7 @@ var init_sync_state2 = __esm(() => {
28862
28936
 
28863
28937
  // src/core/vscode-workspace.ts
28864
28938
  import { createHash as createHash2 } from "node:crypto";
28865
- import { resolve as resolve9, basename as basename5, isAbsolute as isAbsolute3, relative as relative4 } from "node:path";
28939
+ import { resolve as resolve9, basename as basename6, isAbsolute as isAbsolute3, relative as relative4 } from "node:path";
28866
28940
  function buildPathPlaceholderMap(repositories, workspacePath) {
28867
28941
  const map2 = new Map;
28868
28942
  for (const repo of repositories) {
@@ -28945,7 +29019,7 @@ function getWorkspaceOutputPath(workspacePath, vscodeConfig) {
28945
29019
  const filename = name.endsWith(".code-workspace") ? name : `${name}.code-workspace`;
28946
29020
  return resolve9(workspacePath, filename);
28947
29021
  }
28948
- const dirName = basename5(resolve9(workspacePath));
29022
+ const dirName = basename6(resolve9(workspacePath));
28949
29023
  return resolve9(workspacePath, `${dirName}.code-workspace`);
28950
29024
  }
28951
29025
  function computeWorkspaceHash(content) {
@@ -29017,7 +29091,7 @@ var init_vscode_workspace = __esm(() => {
29017
29091
  });
29018
29092
 
29019
29093
  // src/core/vscode-mcp.ts
29020
- import { existsSync as existsSync13, readFileSync, writeFileSync, mkdirSync } from "node:fs";
29094
+ import { existsSync as existsSync13, readFileSync, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
29021
29095
  import { join as join16, dirname as dirname7 } from "node:path";
29022
29096
  function deepEqual(a, b) {
29023
29097
  if (a === b)
@@ -29097,7 +29171,7 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29097
29171
  const configPath = options2?.configPath ?? getVscodeMcpConfigPath();
29098
29172
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29099
29173
  const hasTracking = options2?.trackedServers !== undefined;
29100
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29174
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29101
29175
  const result = {
29102
29176
  added: 0,
29103
29177
  skipped: 0,
@@ -29163,9 +29237,9 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29163
29237
  existingConfig.servers = existingServers;
29164
29238
  const dir = dirname7(configPath);
29165
29239
  if (!existsSync13(dir)) {
29166
- mkdirSync(dir, { recursive: true });
29240
+ mkdirSync2(dir, { recursive: true });
29167
29241
  }
29168
- writeFileSync(configPath, `${JSON.stringify(existingConfig, null, 2)}
29242
+ writeFileSync2(configPath, `${JSON.stringify(existingConfig, null, 2)}
29169
29243
  `, "utf-8");
29170
29244
  result.configPath = configPath;
29171
29245
  }
@@ -29181,9 +29255,9 @@ function syncVscodeMcpConfig(validatedPlugins, options2) {
29181
29255
  existingConfig.servers = existingServers;
29182
29256
  const dir = dirname7(configPath);
29183
29257
  if (!existsSync13(dir)) {
29184
- mkdirSync(dir, { recursive: true });
29258
+ mkdirSync2(dir, { recursive: true });
29185
29259
  }
29186
- writeFileSync(configPath, `${JSON.stringify(existingConfig, null, 2)}
29260
+ writeFileSync2(configPath, `${JSON.stringify(existingConfig, null, 2)}
29187
29261
  `, "utf-8");
29188
29262
  result.configPath = configPath;
29189
29263
  }
@@ -29196,6 +29270,60 @@ var init_vscode_mcp = __esm(() => {
29196
29270
  import_json5 = __toESM(require_lib(), 1);
29197
29271
  });
29198
29272
 
29273
+ // src/core/mcp-proxy.ts
29274
+ import { existsSync as existsSync14, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
29275
+ import { join as join17, dirname as dirname8 } from "node:path";
29276
+ function getProxyMetadataPath() {
29277
+ return join17(getHomeDir(), ".allagents", "mcp-remote", "mcp-metadata-settings.json");
29278
+ }
29279
+ function shouldProxy(serverName, client, config) {
29280
+ if (config.clients.includes(client)) {
29281
+ return true;
29282
+ }
29283
+ const serverOverride = config.servers?.[serverName];
29284
+ if (serverOverride?.proxy.includes(client)) {
29285
+ return true;
29286
+ }
29287
+ return false;
29288
+ }
29289
+ function isHttpServer(config) {
29290
+ return typeof config === "object" && config !== null && "url" in config && typeof config.url === "string";
29291
+ }
29292
+ function toProxiedConfig(url, metadataPath) {
29293
+ return {
29294
+ command: "npx",
29295
+ args: [
29296
+ "mcp-remote",
29297
+ url,
29298
+ "--http",
29299
+ "--static-oauth-client-metadata",
29300
+ `@${metadataPath}`
29301
+ ]
29302
+ };
29303
+ }
29304
+ function applyMcpProxy(servers, client, config, metadataPath) {
29305
+ const result = new Map;
29306
+ for (const [name, serverConfig] of servers) {
29307
+ if (isHttpServer(serverConfig) && shouldProxy(name, client, config)) {
29308
+ result.set(name, toProxiedConfig(serverConfig.url, metadataPath));
29309
+ } else {
29310
+ result.set(name, serverConfig);
29311
+ }
29312
+ }
29313
+ return result;
29314
+ }
29315
+ function ensureProxyMetadata(metadataPath) {
29316
+ const path = metadataPath ?? getProxyMetadataPath();
29317
+ if (existsSync14(path)) {
29318
+ return;
29319
+ }
29320
+ mkdirSync3(dirname8(path), { recursive: true });
29321
+ writeFileSync3(path, JSON.stringify({ client_uri: "http://localhost" }, null, 2), "utf-8");
29322
+ }
29323
+ var init_mcp_proxy = __esm(() => {
29324
+ init_constants();
29325
+ });
29326
+
29199
29327
  // src/core/native/types.ts
29200
29328
  import { spawn as spawn2 } from "node:child_process";
29201
29329
  function executeCommand(binary2, args, options2 = {}) {
@@ -29249,8 +29377,8 @@ function mergeNativeSyncResults(results) {
29249
29377
  var init_types2 = () => {};
29250
29378
 
29251
29379
  // src/core/codex-mcp.ts
29252
- import { existsSync as existsSync14, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
29253
- import { dirname as dirname8 } from "node:path";
29380
+ import { existsSync as existsSync15, readFileSync as readFileSync2, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "node:fs";
29381
+ import { dirname as dirname9 } from "node:path";
29254
29382
  function buildCodexMcpAddArgs(name, config) {
29255
29383
  if (typeof config.url === "string") {
29256
29384
  return ["mcp", "add", name, "--url", config.url];
@@ -29275,7 +29403,7 @@ async function syncCodexMcpServers(validatedPlugins, options2) {
29275
29403
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29276
29404
  const hasTracking = options2?.trackedServers !== undefined;
29277
29405
  const exec = options2?._mockExecute ?? ((binary2, args) => executeCommand(binary2, args));
29278
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29406
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29279
29407
  const result = {
29280
29408
  added: 0,
29281
29409
  skipped: 0,
@@ -29446,7 +29574,7 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29446
29574
  }
29447
29575
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29448
29576
  const hasTracking = options2?.trackedServers !== undefined;
29449
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29577
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29450
29578
  const result = {
29451
29579
  added: 0,
29452
29580
  skipped: 0,
@@ -29460,7 +29588,7 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29460
29588
  trackedServers: []
29461
29589
  };
29462
29590
  let existingContent = "";
29463
- if (existsSync14(configPath)) {
29591
+ if (existsSync15(configPath)) {
29464
29592
  try {
29465
29593
  existingContent = readFileSync2(configPath, "utf-8");
29466
29594
  } catch {
@@ -29515,11 +29643,11 @@ function syncCodexProjectMcpConfig(validatedPlugins, options2) {
29515
29643
 
29516
29644
  `)}
29517
29645
  `;
29518
- const dir = dirname8(configPath);
29519
- if (!existsSync14(dir)) {
29520
- mkdirSync2(dir, { recursive: true });
29646
+ const dir = dirname9(configPath);
29647
+ if (!existsSync15(dir)) {
29648
+ mkdirSync4(dir, { recursive: true });
29521
29649
  }
29522
- writeFileSync2(configPath, output, "utf-8");
29650
+ writeFileSync4(configPath, output, "utf-8");
29523
29651
  result.configPath = configPath;
29524
29652
  }
29525
29653
  return result;
@@ -29530,8 +29658,8 @@ var init_codex_mcp = __esm(() => {
29530
29658
  });
29531
29659
 
29532
29660
  // src/core/claude-mcp.ts
29533
- import { existsSync as existsSync15, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
29534
- import { dirname as dirname9 } from "node:path";
29661
+ import { existsSync as existsSync16, readFileSync as readFileSync3, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5 } from "node:fs";
29662
+ import { dirname as dirname10 } from "node:path";
29535
29663
  function deepEqual2(a, b) {
29536
29664
  if (a === b)
29537
29665
  return true;
@@ -29584,7 +29712,7 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29584
29712
  }
29585
29713
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29586
29714
  const hasTracking = options2?.trackedServers !== undefined;
29587
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29715
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29588
29716
  const result = {
29589
29717
  added: 0,
29590
29718
  skipped: 0,
@@ -29598,7 +29726,7 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29598
29726
  trackedServers: []
29599
29727
  };
29600
29728
  let existingConfig = {};
29601
- if (existsSync15(configPath)) {
29729
+ if (existsSync16(configPath)) {
29602
29730
  try {
29603
29731
  const content = readFileSync3(configPath, "utf-8");
29604
29732
  existingConfig = import_json52.default.parse(content);
@@ -29648,11 +29776,11 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29648
29776
  const hasChanges = result.added > 0 || result.overwritten > 0 || result.removed > 0;
29649
29777
  if (hasChanges && !dryRun) {
29650
29778
  existingConfig.mcpServers = existingServers;
29651
- const dir = dirname9(configPath);
29652
- if (!existsSync15(dir)) {
29653
- mkdirSync3(dir, { recursive: true });
29779
+ const dir = dirname10(configPath);
29780
+ if (!existsSync16(dir)) {
29781
+ mkdirSync5(dir, { recursive: true });
29654
29782
  }
29655
- writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29783
+ writeFileSync5(configPath, `${JSON.stringify(existingConfig, null, 2)}
29656
29784
  `, "utf-8");
29657
29785
  result.configPath = configPath;
29658
29786
  }
@@ -29666,11 +29794,11 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29666
29794
  }
29667
29795
  if (result.removed > 0 && !dryRun) {
29668
29796
  existingConfig.mcpServers = existingServers;
29669
- const dir = dirname9(configPath);
29670
- if (!existsSync15(dir)) {
29671
- mkdirSync3(dir, { recursive: true });
29797
+ const dir = dirname10(configPath);
29798
+ if (!existsSync16(dir)) {
29799
+ mkdirSync5(dir, { recursive: true });
29672
29800
  }
29673
- writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29801
+ writeFileSync5(configPath, `${JSON.stringify(existingConfig, null, 2)}
29674
29802
  `, "utf-8");
29675
29803
  result.configPath = configPath;
29676
29804
  }
@@ -29682,7 +29810,7 @@ async function syncClaudeMcpServersViaCli(validatedPlugins, options2) {
29682
29810
  const previouslyTracked = new Set(options2?.trackedServers ?? []);
29683
29811
  const hasTracking = options2?.trackedServers !== undefined;
29684
29812
  const exec = options2?._mockExecute ?? ((binary2, args) => executeCommand(binary2, args));
29685
- const { servers: pluginServers, warnings } = collectMcpServers(validatedPlugins);
29813
+ const { servers: pluginServers, warnings } = options2?.serverOverrides ? { servers: options2.serverOverrides, warnings: [] } : collectMcpServers(validatedPlugins);
29686
29814
  const result = {
29687
29815
  added: 0,
29688
29816
  skipped: 0,
@@ -29766,9 +29894,9 @@ var init_claude_mcp = __esm(() => {
29766
29894
  });
29767
29895
 
29768
29896
  // src/core/copilot-mcp.ts
29769
- import { join as join17 } from "node:path";
29897
+ import { join as join18 } from "node:path";
29770
29898
  function getCopilotMcpConfigPath() {
29771
- return join17(getHomeDir(), ".copilot", "mcp-config.json");
29899
+ return join18(getHomeDir(), ".copilot", "mcp-config.json");
29772
29900
  }
29773
29901
  var init_copilot_mcp = __esm(() => {
29774
29902
  init_constants();
@@ -30066,9 +30194,9 @@ function padStart2(str3, len) {
30066
30194
  }
30067
30195
 
30068
30196
  // src/core/sync.ts
30069
- import { existsSync as existsSync16, readFileSync as readFileSync4, writeFileSync as writeFileSync4, lstatSync as lstatSync2 } from "node:fs";
30197
+ import { existsSync as existsSync17, readFileSync as readFileSync4, writeFileSync as writeFileSync6, lstatSync as lstatSync2 } from "node:fs";
30070
30198
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
30071
- import { join as join18, resolve as resolve10, dirname as dirname10, relative as relative5 } from "node:path";
30199
+ import { join as join19, resolve as resolve10, dirname as dirname11, relative as relative5 } from "node:path";
30072
30200
  function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
30073
30201
  const pathToClients = new Map;
30074
30202
  for (const client of clients) {
@@ -30182,7 +30310,7 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
30182
30310
  const previousFiles = getPreviouslySyncedFiles(state, client);
30183
30311
  const purgedPaths = [];
30184
30312
  for (const filePath of previousFiles) {
30185
- const fullPath = join18(workspacePath, filePath);
30313
+ const fullPath = join19(workspacePath, filePath);
30186
30314
  const cleanPath = fullPath.replace(/\/$/, "");
30187
30315
  let stats;
30188
30316
  try {
@@ -30209,16 +30337,16 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
30209
30337
  return result;
30210
30338
  }
30211
30339
  async function cleanupEmptyParents(workspacePath, filePath) {
30212
- let parentPath = dirname10(filePath);
30340
+ let parentPath = dirname11(filePath);
30213
30341
  while (parentPath && parentPath !== "." && parentPath !== "/") {
30214
- const fullParentPath = join18(workspacePath, parentPath);
30215
- if (!existsSync16(fullParentPath)) {
30216
- parentPath = dirname10(parentPath);
30342
+ const fullParentPath = join19(workspacePath, parentPath);
30343
+ if (!existsSync17(fullParentPath)) {
30344
+ parentPath = dirname11(parentPath);
30217
30345
  continue;
30218
30346
  }
30219
30347
  try {
30220
30348
  await rmdir(fullParentPath);
30221
- parentPath = dirname10(parentPath);
30349
+ parentPath = dirname11(parentPath);
30222
30350
  } catch {
30223
30351
  break;
30224
30352
  }
@@ -30297,8 +30425,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30297
30425
  errors2.push(`Cannot resolve file '${file}' - no workspace.source configured`);
30298
30426
  continue;
30299
30427
  }
30300
- const fullPath = join18(defaultSourcePath, file);
30301
- if (!existsSync16(fullPath)) {
30428
+ const fullPath = join19(defaultSourcePath, file);
30429
+ if (!existsSync17(fullPath)) {
30302
30430
  errors2.push(`File source not found: ${fullPath}`);
30303
30431
  }
30304
30432
  continue;
@@ -30316,8 +30444,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30316
30444
  errors2.push(`GitHub cache not found for ${cacheKey}`);
30317
30445
  continue;
30318
30446
  }
30319
- const fullPath = join18(cachePath, parsed.filePath);
30320
- if (!existsSync16(fullPath)) {
30447
+ const fullPath = join19(cachePath, parsed.filePath);
30448
+ if (!existsSync17(fullPath)) {
30321
30449
  errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
30322
30450
  }
30323
30451
  } else {
@@ -30327,11 +30455,11 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30327
30455
  } else if (file.source.startsWith("../")) {
30328
30456
  fullPath = resolve10(file.source);
30329
30457
  } else if (defaultSourcePath) {
30330
- fullPath = join18(defaultSourcePath, file.source);
30458
+ fullPath = join19(defaultSourcePath, file.source);
30331
30459
  } else {
30332
30460
  fullPath = resolve10(file.source);
30333
30461
  }
30334
- if (!existsSync16(fullPath)) {
30462
+ if (!existsSync17(fullPath)) {
30335
30463
  errors2.push(`File source not found: ${fullPath}`);
30336
30464
  }
30337
30465
  }
@@ -30340,8 +30468,8 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30340
30468
  errors2.push(`Cannot resolve file '${file.dest}' - no workspace.source configured and no explicit source provided`);
30341
30469
  continue;
30342
30470
  }
30343
- const fullPath = join18(defaultSourcePath, file.dest ?? "");
30344
- if (!existsSync16(fullPath)) {
30471
+ const fullPath = join19(defaultSourcePath, file.dest ?? "");
30472
+ if (!existsSync17(fullPath)) {
30345
30473
  errors2.push(`File source not found: ${fullPath}`);
30346
30474
  }
30347
30475
  }
@@ -30487,7 +30615,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30487
30615
  ...fetchResult.error && { error: fetchResult.error }
30488
30616
  };
30489
30617
  }
30490
- const resolvedPath2 = parsed?.subpath ? join18(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30618
+ const resolvedPath2 = parsed?.subpath ? join19(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30491
30619
  return {
30492
30620
  plugin: pluginSource,
30493
30621
  resolved: resolvedPath2,
@@ -30497,7 +30625,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30497
30625
  };
30498
30626
  }
30499
30627
  const resolvedPath = resolve10(workspacePath, pluginSource);
30500
- if (!existsSync16(resolvedPath)) {
30628
+ if (!existsSync17(resolvedPath)) {
30501
30629
  return {
30502
30630
  plugin: pluginSource,
30503
30631
  resolved: resolvedPath,
@@ -30658,10 +30786,10 @@ function buildPluginSkillNameMaps(allSkills) {
30658
30786
  return pluginMaps;
30659
30787
  }
30660
30788
  function generateVscodeWorkspaceFile(workspacePath, config) {
30661
- const configDir = join18(workspacePath, CONFIG_DIR);
30662
- const templatePath = join18(configDir, VSCODE_TEMPLATE_FILE);
30789
+ const configDir = join19(workspacePath, CONFIG_DIR);
30790
+ const templatePath = join19(configDir, VSCODE_TEMPLATE_FILE);
30663
30791
  let template;
30664
- if (existsSync16(templatePath)) {
30792
+ if (existsSync17(templatePath)) {
30665
30793
  try {
30666
30794
  template = import_json53.default.parse(readFileSync4(templatePath, "utf-8"));
30667
30795
  } catch (error) {
@@ -30676,7 +30804,7 @@ function generateVscodeWorkspaceFile(workspacePath, config) {
30676
30804
  const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
30677
30805
  const contentStr = `${JSON.stringify(content, null, "\t")}
30678
30806
  `;
30679
- writeFileSync4(outputPath, contentStr, "utf-8");
30807
+ writeFileSync6(outputPath, contentStr, "utf-8");
30680
30808
  return contentStr;
30681
30809
  }
30682
30810
  function failedSyncResult(error, overrides) {
@@ -30808,7 +30936,7 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
30808
30936
  let updatedConfig = config;
30809
30937
  if (previousState?.vscodeWorkspaceHash && previousState?.vscodeWorkspaceRepos) {
30810
30938
  const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
30811
- if (existsSync16(outputPath)) {
30939
+ if (existsSync17(outputPath)) {
30812
30940
  const existingContent = readFileSync4(outputPath, "utf-8");
30813
30941
  const currentHash = computeWorkspaceHash(existingContent);
30814
30942
  if (currentHash !== previousState.vscodeWorkspaceHash) {
@@ -30865,16 +30993,17 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
30865
30993
  ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState },
30866
30994
  ...extra?.vscodeState?.hash && { vscodeWorkspaceHash: extra.vscodeState.hash },
30867
30995
  ...extra?.vscodeState?.repos && { vscodeWorkspaceRepos: extra.vscodeState.repos },
30868
- ...extra?.mcpTrackedServers && { mcpServers: extra.mcpTrackedServers }
30996
+ ...extra?.mcpTrackedServers && { mcpServers: extra.mcpTrackedServers },
30997
+ ...extra?.skillsIndex && extra.skillsIndex.length > 0 && { skillsIndex: extra.skillsIndex }
30869
30998
  });
30870
30999
  }
30871
31000
  async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
30872
31001
  await migrateWorkspaceSkillsV1toV2(workspacePath);
30873
31002
  const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
30874
31003
  const sw = new Stopwatch;
30875
- const configDir = join18(workspacePath, CONFIG_DIR);
30876
- const configPath = join18(configDir, WORKSPACE_CONFIG_FILE);
30877
- if (!existsSync16(configPath)) {
31004
+ const configDir = join19(workspacePath, CONFIG_DIR);
31005
+ const configPath = join19(configDir, WORKSPACE_CONFIG_FILE);
31006
+ if (!existsSync17(configPath)) {
30878
31007
  return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
30879
31008
  Run 'allagents workspace init <path>' to create a new workspace`);
30880
31009
  }
@@ -30956,6 +31085,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30956
31085
  })), `${validPlugins.length} plugin(s)`);
30957
31086
  const nativeResult = await sw.measure("native-plugin-sync", () => syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages));
30958
31087
  let workspaceFileResults = [];
31088
+ let writtenSkillsIndexFiles = [];
30959
31089
  const skipWorkspaceFiles = !!config.workspace?.source && !validatedWorkspaceSource;
30960
31090
  if (config.workspace && !skipWorkspaceFiles) {
30961
31091
  sw.start("workspace-files");
@@ -30963,8 +31093,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30963
31093
  const filesToCopy = [...config.workspace.files];
30964
31094
  if (hasRepositories && sourcePath) {
30965
31095
  for (const agentFile of AGENT_FILES) {
30966
- const agentPath = join18(sourcePath, agentFile);
30967
- if (existsSync16(agentPath) && !filesToCopy.includes(agentFile)) {
31096
+ const agentPath = join19(sourcePath, agentFile);
31097
+ if (existsSync17(agentPath) && !filesToCopy.includes(agentFile)) {
30968
31098
  filesToCopy.push(agentFile);
30969
31099
  }
30970
31100
  }
@@ -30987,12 +31117,22 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30987
31117
  `)}`, { pluginResults, totalFailed: fileValidationErrors.length });
30988
31118
  }
30989
31119
  const repoSkills = hasRepositories && !dryRun ? await discoverWorkspaceSkills(workspacePath, config.repositories, syncClients) : [];
30990
- workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories, skills: repoSkills });
31120
+ let skillsIndexRefs = [];
31121
+ if (!dryRun) {
31122
+ if (repoSkills.length > 0) {
31123
+ const grouped = groupSkillsByRepo(repoSkills, config.repositories);
31124
+ const result = writeSkillsIndex(workspacePath, grouped);
31125
+ writtenSkillsIndexFiles = result.writtenFiles;
31126
+ skillsIndexRefs = result.refs;
31127
+ }
31128
+ cleanupSkillsIndex(workspacePath, writtenSkillsIndexFiles);
31129
+ }
31130
+ workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories, skillsIndexRefs });
30991
31131
  if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
30992
- const claudePath = join18(workspacePath, "CLAUDE.md");
30993
- const agentsPath = join18(workspacePath, "AGENTS.md");
30994
- const claudeExistsInSource = existsSync16(join18(sourcePath, "CLAUDE.md"));
30995
- if (!claudeExistsInSource && existsSync16(agentsPath) && !existsSync16(claudePath)) {
31132
+ const claudePath = join19(workspacePath, "CLAUDE.md");
31133
+ const agentsPath = join19(workspacePath, "AGENTS.md");
31134
+ const claudeExistsInSource = existsSync17(join19(sourcePath, "CLAUDE.md"));
31135
+ if (!claudeExistsInSource && existsSync17(agentsPath) && !existsSync17(claudePath)) {
30996
31136
  await copyFile(agentsPath, claudePath);
30997
31137
  }
30998
31138
  }
@@ -31009,16 +31149,39 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31009
31149
  vscodeState = { hash: result.hash, repos: result.repos };
31010
31150
  }
31011
31151
  }
31152
+ const mcpProxyConfig = config.mcpProxy;
31153
+ let proxyMetadataPath;
31154
+ let proxyBaseServers;
31155
+ if (mcpProxyConfig) {
31156
+ if (!dryRun) {
31157
+ ensureProxyMetadata();
31158
+ }
31159
+ proxyMetadataPath = getProxyMetadataPath();
31160
+ const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
31161
+ if (proxyWarnings.length > 0) {
31162
+ warnings.push(...proxyWarnings);
31163
+ }
31164
+ if (servers.size > 0) {
31165
+ proxyBaseServers = servers;
31166
+ }
31167
+ }
31168
+ function getServersForClient(client) {
31169
+ if (!mcpProxyConfig || !proxyMetadataPath || !proxyBaseServers)
31170
+ return;
31171
+ return applyMcpProxy(proxyBaseServers, client, mcpProxyConfig, proxyMetadataPath);
31172
+ }
31012
31173
  sw.start("mcp-sync");
31013
31174
  const mcpResults = {};
31014
31175
  if (syncClients.includes("vscode")) {
31015
31176
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
31016
- const projectMcpPath = join18(workspacePath, ".vscode", "mcp.json");
31177
+ const projectMcpPath = join19(workspacePath, ".vscode", "mcp.json");
31178
+ const vscodeMcpOverrides = getServersForClient("vscode");
31017
31179
  const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
31018
31180
  dryRun,
31019
31181
  force: false,
31020
31182
  configPath: projectMcpPath,
31021
- trackedServers: trackedMcpServers
31183
+ trackedServers: trackedMcpServers,
31184
+ ...vscodeMcpOverrides && { serverOverrides: vscodeMcpOverrides }
31022
31185
  });
31023
31186
  if (vscodeMcp.warnings.length > 0) {
31024
31187
  warnings.push(...vscodeMcp.warnings);
@@ -31027,12 +31190,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31027
31190
  }
31028
31191
  if (syncClients.includes("claude")) {
31029
31192
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
31030
- const projectMcpJsonPath = join18(workspacePath, ".mcp.json");
31193
+ const projectMcpJsonPath = join19(workspacePath, ".mcp.json");
31194
+ const claudeMcpOverrides = getServersForClient("claude");
31031
31195
  const claudeMcp = syncClaudeMcpConfig(validPlugins, {
31032
31196
  dryRun,
31033
31197
  force: false,
31034
31198
  configPath: projectMcpJsonPath,
31035
- trackedServers: trackedMcpServers
31199
+ trackedServers: trackedMcpServers,
31200
+ ...claudeMcpOverrides && { serverOverrides: claudeMcpOverrides }
31036
31201
  });
31037
31202
  if (claudeMcp.warnings.length > 0) {
31038
31203
  warnings.push(...claudeMcp.warnings);
@@ -31041,12 +31206,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31041
31206
  }
31042
31207
  if (syncClients.includes("codex")) {
31043
31208
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
31044
- const projectCodexConfigPath = join18(workspacePath, ".codex", "config.toml");
31209
+ const projectCodexConfigPath = join19(workspacePath, ".codex", "config.toml");
31210
+ const codexMcpOverrides = getServersForClient("codex");
31045
31211
  const codexMcp = syncCodexProjectMcpConfig(validPlugins, {
31046
31212
  dryRun,
31047
31213
  force: false,
31048
31214
  configPath: projectCodexConfigPath,
31049
- trackedServers: trackedMcpServers
31215
+ trackedServers: trackedMcpServers,
31216
+ ...codexMcpOverrides && { serverOverrides: codexMcpOverrides }
31050
31217
  });
31051
31218
  if (codexMcp.warnings.length > 0) {
31052
31219
  warnings.push(...codexMcp.warnings);
@@ -31055,12 +31222,14 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31055
31222
  }
31056
31223
  if (syncClients.includes("copilot")) {
31057
31224
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
31058
- const projectCopilotMcpPath = join18(workspacePath, ".copilot", "mcp-config.json");
31225
+ const projectCopilotMcpPath = join19(workspacePath, ".copilot", "mcp-config.json");
31226
+ const copilotMcpOverrides = getServersForClient("copilot");
31059
31227
  const copilotMcp = syncClaudeMcpConfig(validPlugins, {
31060
31228
  dryRun,
31061
31229
  force: false,
31062
31230
  configPath: projectCopilotMcpPath,
31063
- trackedServers: trackedMcpServers
31231
+ trackedServers: trackedMcpServers,
31232
+ ...copilotMcpOverrides && { serverOverrides: copilotMcpOverrides }
31064
31233
  });
31065
31234
  if (copilotMcp.warnings.length > 0) {
31066
31235
  warnings.push(...copilotMcp.warnings);
@@ -31069,7 +31238,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31069
31238
  }
31070
31239
  sw.stop("mcp-sync");
31071
31240
  const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
31072
- const { servers: allMcpServers } = collectMcpServers(validPlugins);
31241
+ const allMcpServers = proxyBaseServers ?? collectMcpServers(validPlugins).servers;
31073
31242
  if (allMcpServers.size > 0) {
31074
31243
  for (const client of syncClients) {
31075
31244
  if (!PROJECT_MCP_CLIENTS.has(client)) {
@@ -31090,7 +31259,8 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31090
31259
  ...vscodeState && { vscodeState },
31091
31260
  ...Object.keys(mcpResults).length > 0 && {
31092
31261
  mcpTrackedServers: Object.fromEntries(Object.entries(mcpResults).map(([scope, r]) => [scope, r.trackedServers]))
31093
- }
31262
+ },
31263
+ ...writtenSkillsIndexFiles.length > 0 && { skillsIndex: writtenSkillsIndexFiles }
31094
31264
  }));
31095
31265
  }
31096
31266
  return {
@@ -31125,7 +31295,7 @@ async function seedFetchCacheFromMarketplaces(results) {
31125
31295
  }
31126
31296
  function readGitBranch(repoPath) {
31127
31297
  try {
31128
- const head = readFileSync4(join18(repoPath, ".git", "HEAD"), "utf-8").trim();
31298
+ const head = readFileSync4(join19(repoPath, ".git", "HEAD"), "utf-8").trim();
31129
31299
  const prefix = "ref: refs/heads/";
31130
31300
  return head.startsWith(prefix) ? head.slice(prefix.length) : null;
31131
31301
  } catch {
@@ -31184,11 +31354,38 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31184
31354
  return { ...result, scope: "user" };
31185
31355
  })), `${validPlugins.length} plugin(s)`);
31186
31356
  const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
31357
+ const userMcpProxyConfig = config.mcpProxy;
31358
+ let userProxyMetadataPath;
31359
+ let userProxyBaseServers;
31360
+ if (userMcpProxyConfig) {
31361
+ if (!dryRun) {
31362
+ ensureProxyMetadata();
31363
+ }
31364
+ userProxyMetadataPath = getProxyMetadataPath();
31365
+ const { servers, warnings: proxyWarnings } = collectMcpServers(validPlugins);
31366
+ if (proxyWarnings.length > 0) {
31367
+ warnings.push(...proxyWarnings);
31368
+ }
31369
+ if (servers.size > 0) {
31370
+ userProxyBaseServers = servers;
31371
+ }
31372
+ }
31373
+ function getUserServersForClient(client) {
31374
+ if (!userMcpProxyConfig || !userProxyMetadataPath || !userProxyBaseServers)
31375
+ return;
31376
+ return applyMcpProxy(userProxyBaseServers, client, userMcpProxyConfig, userProxyMetadataPath);
31377
+ }
31187
31378
  sw.start("mcp-sync");
31188
31379
  const mcpResults = {};
31189
31380
  if (syncClients.includes("vscode")) {
31190
31381
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
31191
- const vscodeMcp = syncVscodeMcpConfig(validPlugins, { dryRun, force, trackedServers: trackedMcpServers });
31382
+ const vscodeMcpOverrides = getUserServersForClient("vscode");
31383
+ const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
31384
+ dryRun,
31385
+ force,
31386
+ trackedServers: trackedMcpServers,
31387
+ ...vscodeMcpOverrides && { serverOverrides: vscodeMcpOverrides }
31388
+ });
31192
31389
  if (vscodeMcp.warnings.length > 0) {
31193
31390
  warnings.push(...vscodeMcp.warnings);
31194
31391
  }
@@ -31196,7 +31393,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31196
31393
  }
31197
31394
  if (syncClients.includes("codex")) {
31198
31395
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
31199
- const codexMcp = await syncCodexMcpServers(validPlugins, { dryRun, trackedServers: trackedMcpServers });
31396
+ const codexMcpOverrides = getUserServersForClient("codex");
31397
+ const codexMcp = await syncCodexMcpServers(validPlugins, {
31398
+ dryRun,
31399
+ trackedServers: trackedMcpServers,
31400
+ ...codexMcpOverrides && { serverOverrides: codexMcpOverrides }
31401
+ });
31200
31402
  if (codexMcp.warnings.length > 0) {
31201
31403
  warnings.push(...codexMcp.warnings);
31202
31404
  }
@@ -31204,7 +31406,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31204
31406
  }
31205
31407
  if (syncClients.includes("claude")) {
31206
31408
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
31207
- const claudeMcp = await syncClaudeMcpServersViaCli(validPlugins, { dryRun, trackedServers: trackedMcpServers });
31409
+ const claudeMcpOverrides = getUserServersForClient("claude");
31410
+ const claudeMcp = await syncClaudeMcpServersViaCli(validPlugins, {
31411
+ dryRun,
31412
+ trackedServers: trackedMcpServers,
31413
+ ...claudeMcpOverrides && { serverOverrides: claudeMcpOverrides }
31414
+ });
31208
31415
  if (claudeMcp.warnings.length > 0) {
31209
31416
  warnings.push(...claudeMcp.warnings);
31210
31417
  }
@@ -31213,11 +31420,13 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31213
31420
  if (syncClients.includes("copilot")) {
31214
31421
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
31215
31422
  const copilotMcpPath = getCopilotMcpConfigPath();
31423
+ const copilotMcpOverrides = getUserServersForClient("copilot");
31216
31424
  const copilotMcp = syncClaudeMcpConfig(validPlugins, {
31217
31425
  dryRun,
31218
31426
  force,
31219
31427
  configPath: copilotMcpPath,
31220
- trackedServers: trackedMcpServers
31428
+ trackedServers: trackedMcpServers,
31429
+ ...copilotMcpOverrides && { serverOverrides: copilotMcpOverrides }
31221
31430
  });
31222
31431
  if (copilotMcp.warnings.length > 0) {
31223
31432
  warnings.push(...copilotMcp.warnings);
@@ -31226,7 +31435,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31226
31435
  }
31227
31436
  sw.stop("mcp-sync");
31228
31437
  const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
31229
- const { servers: allUserMcpServers } = collectMcpServers(validPlugins);
31438
+ const allUserMcpServers = userProxyBaseServers ?? collectMcpServers(validPlugins).servers;
31230
31439
  if (allUserMcpServers.size > 0) {
31231
31440
  for (const client of syncClients) {
31232
31441
  if (!USER_MCP_CLIENTS.has(client)) {
@@ -31282,6 +31491,7 @@ var init_sync = __esm(() => {
31282
31491
  init_vscode_workspace();
31283
31492
  init_workspace_modify();
31284
31493
  init_vscode_mcp();
31494
+ init_mcp_proxy();
31285
31495
  init_codex_mcp();
31286
31496
  init_claude_mcp();
31287
31497
  init_copilot_mcp();
@@ -31290,11 +31500,11 @@ var init_sync = __esm(() => {
31290
31500
  });
31291
31501
 
31292
31502
  // src/core/github-fetch.ts
31293
- import { existsSync as existsSync17, readFileSync as readFileSync5 } from "node:fs";
31294
- import { join as join19 } from "node:path";
31503
+ import { existsSync as existsSync18, readFileSync as readFileSync5 } from "node:fs";
31504
+ import { join as join20 } from "node:path";
31295
31505
  function readFileFromClone(tempDir, filePath) {
31296
- const fullPath = join19(tempDir, filePath);
31297
- if (existsSync17(fullPath)) {
31506
+ const fullPath = join20(tempDir, filePath);
31507
+ if (existsSync18(fullPath)) {
31298
31508
  return readFileSync5(fullPath, "utf-8");
31299
31509
  }
31300
31510
  return null;
@@ -31394,14 +31604,14 @@ var init_github_fetch = __esm(() => {
31394
31604
 
31395
31605
  // src/core/workspace.ts
31396
31606
  import { cp as cp2, mkdir as mkdir8, readFile as readFile12, writeFile as writeFile8, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
31397
- import { existsSync as existsSync18 } from "node:fs";
31398
- import { join as join20, resolve as resolve11, dirname as dirname11, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31607
+ import { existsSync as existsSync19 } from "node:fs";
31608
+ import { join as join21, resolve as resolve11, dirname as dirname12, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31399
31609
  import { fileURLToPath } from "node:url";
31400
31610
  async function initWorkspace(targetPath = ".", options2 = {}) {
31401
31611
  const absoluteTarget = resolve11(targetPath);
31402
- const configDir = join20(absoluteTarget, CONFIG_DIR);
31403
- const configPath = join20(configDir, WORKSPACE_CONFIG_FILE);
31404
- if (existsSync18(configPath)) {
31612
+ const configDir = join21(absoluteTarget, CONFIG_DIR);
31613
+ const configPath = join21(configDir, WORKSPACE_CONFIG_FILE);
31614
+ if (existsSync19(configPath)) {
31405
31615
  if (options2.force) {
31406
31616
  await unlink3(configPath);
31407
31617
  } else {
@@ -31410,9 +31620,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31410
31620
  }
31411
31621
  }
31412
31622
  const currentFilePath = fileURLToPath(import.meta.url);
31413
- const currentFileDir = dirname11(currentFilePath);
31623
+ const currentFileDir = dirname12(currentFilePath);
31414
31624
  const isProduction = currentFilePath.includes(`${sep2}dist${sep2}`);
31415
- const defaultTemplatePath = isProduction ? join20(currentFileDir, "templates", "default") : join20(currentFileDir, "..", "templates", "default");
31625
+ const defaultTemplatePath = isProduction ? join21(currentFileDir, "templates", "default") : join21(currentFileDir, "..", "templates", "default");
31416
31626
  let githubTempDir;
31417
31627
  let parsedFromUrl;
31418
31628
  let githubBasePath = "";
@@ -31452,19 +31662,19 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31452
31662
  console.log(`✓ Using workspace.yaml from: ${options2.from}`);
31453
31663
  } else {
31454
31664
  const fromPath = resolve11(options2.from);
31455
- if (!existsSync18(fromPath)) {
31665
+ if (!existsSync19(fromPath)) {
31456
31666
  throw new Error(`Template not found: ${fromPath}`);
31457
31667
  }
31458
31668
  const { stat: stat2 } = await import("node:fs/promises");
31459
31669
  const fromStat = await stat2(fromPath);
31460
31670
  let sourceYamlPath;
31461
31671
  if (fromStat.isDirectory()) {
31462
- const nestedPath = join20(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31463
- const rootPath = join20(fromPath, WORKSPACE_CONFIG_FILE);
31464
- if (existsSync18(nestedPath)) {
31672
+ const nestedPath = join21(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31673
+ const rootPath = join21(fromPath, WORKSPACE_CONFIG_FILE);
31674
+ if (existsSync19(nestedPath)) {
31465
31675
  sourceYamlPath = nestedPath;
31466
31676
  sourceDir = fromPath;
31467
- } else if (existsSync18(rootPath)) {
31677
+ } else if (existsSync19(rootPath)) {
31468
31678
  sourceYamlPath = rootPath;
31469
31679
  sourceDir = fromPath;
31470
31680
  } else {
@@ -31473,9 +31683,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31473
31683
  }
31474
31684
  } else {
31475
31685
  sourceYamlPath = fromPath;
31476
- const parentDir = dirname11(fromPath);
31686
+ const parentDir = dirname12(fromPath);
31477
31687
  if (parentDir.endsWith(CONFIG_DIR)) {
31478
- sourceDir = dirname11(parentDir);
31688
+ sourceDir = dirname12(parentDir);
31479
31689
  } else {
31480
31690
  sourceDir = parentDir;
31481
31691
  }
@@ -31495,8 +31705,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31495
31705
  console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
31496
31706
  }
31497
31707
  } else {
31498
- const defaultYamlPath = join20(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31499
- if (!existsSync18(defaultYamlPath)) {
31708
+ const defaultYamlPath = join21(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31709
+ if (!existsSync19(defaultYamlPath)) {
31500
31710
  throw new Error(`Default template not found at: ${defaultTemplatePath}`);
31501
31711
  }
31502
31712
  workspaceYamlContent = await readFile12(defaultYamlPath, "utf-8");
@@ -31512,8 +31722,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31512
31722
  const clientNames = getClientTypes(clients);
31513
31723
  const VSCODE_TEMPLATE_FILE2 = "template.code-workspace";
31514
31724
  if (clientNames.includes("vscode") && options2.from) {
31515
- const targetTemplatePath = join20(configDir, VSCODE_TEMPLATE_FILE2);
31516
- if (!existsSync18(targetTemplatePath)) {
31725
+ const targetTemplatePath = join21(configDir, VSCODE_TEMPLATE_FILE2);
31726
+ if (!existsSync19(targetTemplatePath)) {
31517
31727
  if (isGitHubUrl(options2.from) && githubTempDir) {
31518
31728
  if (parsedFromUrl) {
31519
31729
  const templatePath = githubBasePath ? `${githubBasePath}/${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}` : `${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}`;
@@ -31523,8 +31733,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31523
31733
  }
31524
31734
  }
31525
31735
  } else if (sourceDir) {
31526
- const sourceTemplatePath = join20(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31527
- if (existsSync18(sourceTemplatePath)) {
31736
+ const sourceTemplatePath = join21(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31737
+ if (existsSync19(sourceTemplatePath)) {
31528
31738
  await copyFile2(sourceTemplatePath, targetTemplatePath);
31529
31739
  }
31530
31740
  }
@@ -31537,8 +31747,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31537
31747
  if (options2.from && isGitHubUrl(options2.from) && githubTempDir) {
31538
31748
  if (parsedFromUrl) {
31539
31749
  for (const agentFile of AGENT_FILES) {
31540
- const targetFilePath = join20(absoluteTarget, agentFile);
31541
- if (existsSync18(targetFilePath)) {
31750
+ const targetFilePath = join21(absoluteTarget, agentFile);
31751
+ if (existsSync19(targetFilePath)) {
31542
31752
  copiedAgentFiles.push(agentFile);
31543
31753
  continue;
31544
31754
  }
@@ -31553,13 +31763,13 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31553
31763
  } else {
31554
31764
  const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
31555
31765
  for (const agentFile of AGENT_FILES) {
31556
- const targetFilePath = join20(absoluteTarget, agentFile);
31557
- if (existsSync18(targetFilePath)) {
31766
+ const targetFilePath = join21(absoluteTarget, agentFile);
31767
+ if (existsSync19(targetFilePath)) {
31558
31768
  copiedAgentFiles.push(agentFile);
31559
31769
  continue;
31560
31770
  }
31561
- const sourcePath = join20(effectiveSourceDir, agentFile);
31562
- if (existsSync18(sourcePath)) {
31771
+ const sourcePath = join21(effectiveSourceDir, agentFile);
31772
+ if (existsSync19(sourcePath)) {
31563
31773
  const content = await readFile12(sourcePath, "utf-8");
31564
31774
  await writeFile8(targetFilePath, content, "utf-8");
31565
31775
  copiedAgentFiles.push(agentFile);
@@ -31567,16 +31777,16 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31567
31777
  }
31568
31778
  }
31569
31779
  if (copiedAgentFiles.length === 0) {
31570
- await ensureWorkspaceRules(join20(absoluteTarget, "AGENTS.md"), repositories);
31780
+ await ensureWorkspaceRules(join21(absoluteTarget, "AGENTS.md"), repositories);
31571
31781
  copiedAgentFiles.push("AGENTS.md");
31572
31782
  } else {
31573
31783
  for (const agentFile of copiedAgentFiles) {
31574
- await ensureWorkspaceRules(join20(absoluteTarget, agentFile), repositories);
31784
+ await ensureWorkspaceRules(join21(absoluteTarget, agentFile), repositories);
31575
31785
  }
31576
31786
  }
31577
31787
  if (clientNames.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
31578
- const agentsPath = join20(absoluteTarget, "AGENTS.md");
31579
- const claudePath = join20(absoluteTarget, "CLAUDE.md");
31788
+ const agentsPath = join21(absoluteTarget, "AGENTS.md");
31789
+ const claudePath = join21(absoluteTarget, "CLAUDE.md");
31580
31790
  await copyFile2(agentsPath, claudePath);
31581
31791
  }
31582
31792
  }
@@ -31621,14 +31831,14 @@ Next steps:`);
31621
31831
  async function seedCacheFromClone(tempDir, owner, repo, branch) {
31622
31832
  const cachePaths = [
31623
31833
  getPluginCachePath(owner, repo, branch),
31624
- join20(getMarketplacesDir(), repo)
31834
+ join21(getMarketplacesDir(), repo)
31625
31835
  ];
31626
31836
  for (const cachePath of cachePaths) {
31627
- if (existsSync18(cachePath))
31837
+ if (existsSync19(cachePath))
31628
31838
  continue;
31629
31839
  try {
31630
- const parentDir = dirname11(cachePath);
31631
- if (!existsSync18(parentDir)) {
31840
+ const parentDir = dirname12(cachePath);
31841
+ if (!existsSync19(parentDir)) {
31632
31842
  await mkdir8(parentDir, { recursive: true });
31633
31843
  }
31634
31844
  await cp2(tempDir, cachePath, { recursive: true });
@@ -31649,11 +31859,11 @@ var init_workspace = __esm(() => {
31649
31859
  });
31650
31860
 
31651
31861
  // src/core/status.ts
31652
- import { existsSync as existsSync19 } from "node:fs";
31653
- import { join as join21 } from "node:path";
31862
+ import { existsSync as existsSync20 } from "node:fs";
31863
+ import { join as join22 } from "node:path";
31654
31864
  async function getWorkspaceStatus(workspacePath = process.cwd()) {
31655
- const configPath = join21(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31656
- if (!existsSync19(configPath) || isUserConfigPath(workspacePath)) {
31865
+ const configPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31866
+ if (!existsSync20(configPath) || isUserConfigPath(workspacePath)) {
31657
31867
  const userPlugins = await getUserPluginStatuses();
31658
31868
  return {
31659
31869
  success: true,
@@ -31695,7 +31905,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
31695
31905
  function getPluginStatus(parsed) {
31696
31906
  if (parsed.type === "github") {
31697
31907
  const cachePath = parsed.owner && parsed.repo ? getPluginCachePath(parsed.owner, parsed.repo) : "";
31698
- const available2 = cachePath ? existsSync19(cachePath) : false;
31908
+ const available2 = cachePath ? existsSync20(cachePath) : false;
31699
31909
  return {
31700
31910
  source: parsed.original,
31701
31911
  type: "github",
@@ -31705,7 +31915,7 @@ function getPluginStatus(parsed) {
31705
31915
  ...parsed.repo && { repo: parsed.repo }
31706
31916
  };
31707
31917
  }
31708
- const available = existsSync19(parsed.normalized);
31918
+ const available = existsSync20(parsed.normalized);
31709
31919
  return {
31710
31920
  source: parsed.original,
31711
31921
  type: "local",
@@ -33842,9 +34052,9 @@ var init_prompt_clients = __esm(() => {
33842
34052
  });
33843
34053
 
33844
34054
  // src/core/skills.ts
33845
- import { existsSync as existsSync22 } from "node:fs";
34055
+ import { existsSync as existsSync23 } from "node:fs";
33846
34056
  import { readFile as readFile14, readdir as readdir5 } from "node:fs/promises";
33847
- import { join as join24, basename as basename6, resolve as resolve13 } from "node:path";
34057
+ import { join as join25, basename as basename7, resolve as resolve13 } from "node:path";
33848
34058
  async function resolvePluginPath(pluginSource, workspacePath) {
33849
34059
  if (isPluginSpec(pluginSource)) {
33850
34060
  const resolved2 = await resolvePluginSpecWithAutoRegister(pluginSource, {
@@ -33865,15 +34075,15 @@ async function resolvePluginPath(pluginSource, workspacePath) {
33865
34075
  });
33866
34076
  if (!result.success)
33867
34077
  return null;
33868
- const path = parsed?.subpath ? join24(result.cachePath, parsed.subpath) : result.cachePath;
34078
+ const path = parsed?.subpath ? join25(result.cachePath, parsed.subpath) : result.cachePath;
33869
34079
  return { path };
33870
34080
  }
33871
34081
  const resolved = resolve13(workspacePath, pluginSource);
33872
- return existsSync22(resolved) ? { path: resolved } : null;
34082
+ return existsSync23(resolved) ? { path: resolved } : null;
33873
34083
  }
33874
34084
  async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33875
- const configPath = join24(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
33876
- if (!existsSync22(configPath)) {
34085
+ const configPath = join25(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34086
+ if (!existsSync23(configPath)) {
33877
34087
  return [];
33878
34088
  }
33879
34089
  const content = await readFile14(configPath, "utf-8");
@@ -33889,32 +34099,32 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33889
34099
  continue;
33890
34100
  const pluginPath = resolved.path;
33891
34101
  const pluginName = resolved.pluginName ?? getPluginName(pluginPath);
33892
- const skillsDir = join24(pluginPath, "skills");
34102
+ const skillsDir = join25(pluginPath, "skills");
33893
34103
  const pluginSkillsConfig = typeof pluginEntry === "string" ? undefined : pluginEntry.skills;
33894
34104
  const hasEnabledEntries = !pluginSkillsConfig && enabledSkills && [...enabledSkills].some((s) => s.startsWith(`${pluginName}`));
33895
34105
  let skillEntries;
33896
- if (existsSync22(skillsDir)) {
34106
+ if (existsSync23(skillsDir)) {
33897
34107
  const entries = await readdir5(skillsDir, { withFileTypes: true });
33898
- skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join24(skillsDir, e.name) }));
34108
+ skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join25(skillsDir, e.name) }));
33899
34109
  } else {
33900
34110
  const entries = await readdir5(pluginPath, { withFileTypes: true });
33901
34111
  const flatSkills = [];
33902
34112
  for (const entry of entries) {
33903
34113
  if (!entry.isDirectory())
33904
34114
  continue;
33905
- const skillMdPath = join24(pluginPath, entry.name, "SKILL.md");
33906
- if (existsSync22(skillMdPath)) {
33907
- flatSkills.push({ name: entry.name, skillPath: join24(pluginPath, entry.name) });
34115
+ const skillMdPath = join25(pluginPath, entry.name, "SKILL.md");
34116
+ if (existsSync23(skillMdPath)) {
34117
+ flatSkills.push({ name: entry.name, skillPath: join25(pluginPath, entry.name) });
33908
34118
  }
33909
34119
  }
33910
34120
  if (flatSkills.length > 0) {
33911
34121
  skillEntries = flatSkills;
33912
34122
  } else {
33913
- const rootSkillMd = join24(pluginPath, "SKILL.md");
33914
- if (existsSync22(rootSkillMd)) {
34123
+ const rootSkillMd = join25(pluginPath, "SKILL.md");
34124
+ if (existsSync23(rootSkillMd)) {
33915
34125
  const skillContent = await readFile14(rootSkillMd, "utf-8");
33916
34126
  const metadata = parseSkillMetadata(skillContent);
33917
- const skillName = metadata?.name ?? basename6(pluginPath);
34127
+ const skillName = metadata?.name ?? basename7(pluginPath);
33918
34128
  skillEntries = [{ name: skillName, skillPath: pluginPath }];
33919
34129
  } else {
33920
34130
  skillEntries = [];
@@ -33953,10 +34163,10 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
33953
34163
  return allSkills.filter((s) => s.name === skillName);
33954
34164
  }
33955
34165
  async function discoverSkillNames(pluginPath) {
33956
- if (!existsSync22(pluginPath))
34166
+ if (!existsSync23(pluginPath))
33957
34167
  return [];
33958
- const skillsDir = join24(pluginPath, "skills");
33959
- if (existsSync22(skillsDir)) {
34168
+ const skillsDir = join25(pluginPath, "skills");
34169
+ if (existsSync23(skillsDir)) {
33960
34170
  const entries2 = await readdir5(skillsDir, { withFileTypes: true });
33961
34171
  return entries2.filter((e) => e.isDirectory()).map((e) => e.name);
33962
34172
  }
@@ -33965,21 +34175,21 @@ async function discoverSkillNames(pluginPath) {
33965
34175
  for (const entry of entries) {
33966
34176
  if (!entry.isDirectory())
33967
34177
  continue;
33968
- if (existsSync22(join24(pluginPath, entry.name, "SKILL.md"))) {
34178
+ if (existsSync23(join25(pluginPath, entry.name, "SKILL.md"))) {
33969
34179
  flatSkills.push(entry.name);
33970
34180
  }
33971
34181
  }
33972
34182
  if (flatSkills.length > 0)
33973
34183
  return flatSkills;
33974
- const rootSkillMd = join24(pluginPath, "SKILL.md");
33975
- if (existsSync22(rootSkillMd)) {
34184
+ const rootSkillMd = join25(pluginPath, "SKILL.md");
34185
+ if (existsSync23(rootSkillMd)) {
33976
34186
  try {
33977
34187
  const content = await readFile14(rootSkillMd, "utf-8");
33978
34188
  const { parseSkillMetadata: parseSkillMetadata2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
33979
34189
  const metadata = parseSkillMetadata2(content);
33980
- return [metadata?.name ?? basename6(pluginPath)];
34190
+ return [metadata?.name ?? basename7(pluginPath)];
33981
34191
  } catch {
33982
- return [basename6(pluginPath)];
34192
+ return [basename7(pluginPath)];
33983
34193
  }
33984
34194
  }
33985
34195
  return [];
@@ -34492,7 +34702,7 @@ var package_default;
34492
34702
  var init_package = __esm(() => {
34493
34703
  package_default = {
34494
34704
  name: "allagents",
34495
- version: "1.6.1",
34705
+ version: "1.7.1",
34496
34706
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
34497
34707
  type: "module",
34498
34708
  bin: {
@@ -34573,10 +34783,10 @@ var init_package = __esm(() => {
34573
34783
 
34574
34784
  // src/cli/update-check.ts
34575
34785
  import { readFile as readFile17 } from "node:fs/promises";
34576
- import { join as join27 } from "node:path";
34786
+ import { join as join28 } from "node:path";
34577
34787
  import { spawn as spawn3 } from "node:child_process";
34578
34788
  async function getCachedUpdateInfo(path3) {
34579
- const filePath = path3 ?? join27(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34789
+ const filePath = path3 ?? join28(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34580
34790
  try {
34581
34791
  const raw = await readFile17(filePath, "utf-8");
34582
34792
  const data = JSON.parse(raw);
@@ -34614,8 +34824,8 @@ function buildNotice(currentVersion, latestVersion) {
34614
34824
  Run \`allagents self update\` to upgrade.`);
34615
34825
  }
34616
34826
  function backgroundUpdateCheck() {
34617
- const dir = join27(getHomeDir(), CONFIG_DIR);
34618
- const filePath = join27(dir, CACHE_FILE);
34827
+ const dir = join28(getHomeDir(), CONFIG_DIR);
34828
+ const filePath = join28(dir, CACHE_FILE);
34619
34829
  const script = `
34620
34830
  const https = require('https');
34621
34831
  const fs = require('fs');
@@ -34702,15 +34912,15 @@ class TuiCache {
34702
34912
  }
34703
34913
 
34704
34914
  // src/cli/tui/context.ts
34705
- import { existsSync as existsSync25 } from "node:fs";
34706
- import { join as join28 } from "node:path";
34915
+ import { existsSync as existsSync26 } from "node:fs";
34916
+ import { join as join29 } from "node:path";
34707
34917
  async function getTuiContext(cwd = process.cwd(), cache2) {
34708
34918
  const cachedContext = cache2?.getContext();
34709
34919
  if (cachedContext) {
34710
34920
  return cachedContext;
34711
34921
  }
34712
- const configPath = join28(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34713
- const hasWorkspace = existsSync25(configPath) && !isUserConfigPath(cwd);
34922
+ const configPath = join29(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34923
+ const hasWorkspace = existsSync26(configPath) && !isUserConfigPath(cwd);
34714
34924
  let projectPluginCount = 0;
34715
34925
  if (hasWorkspace) {
34716
34926
  try {
@@ -36126,8 +36336,8 @@ init_workspace();
36126
36336
  init_sync();
36127
36337
  init_status2();
36128
36338
  var import_cmd_ts2 = __toESM(require_cjs(), 1);
36129
- import { existsSync as existsSync21 } from "node:fs";
36130
- import { join as join23, resolve as resolve12 } from "node:path";
36339
+ import { existsSync as existsSync22 } from "node:fs";
36340
+ import { join as join24, resolve as resolve12 } from "node:path";
36131
36341
 
36132
36342
  // src/core/prune.ts
36133
36343
  init_js_yaml();
@@ -36136,8 +36346,8 @@ init_marketplace();
36136
36346
  init_user_workspace();
36137
36347
  init_workspace_config();
36138
36348
  import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
36139
- import { existsSync as existsSync20 } from "node:fs";
36140
- import { join as join22 } from "node:path";
36349
+ import { existsSync as existsSync21 } from "node:fs";
36350
+ import { join as join23 } from "node:path";
36141
36351
  async function isOrphanedPlugin(pluginSpec) {
36142
36352
  if (!isPluginSpec(pluginSpec))
36143
36353
  return false;
@@ -36164,8 +36374,8 @@ async function prunePlugins(plugins) {
36164
36374
  }
36165
36375
  async function pruneOrphanedPlugins(workspacePath) {
36166
36376
  let projectResult = { removed: [], kept: [], keptEntries: [] };
36167
- const projectConfigPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
36168
- if (existsSync20(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36377
+ const projectConfigPath = join23(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
36378
+ if (existsSync21(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36169
36379
  const content = await readFile13(projectConfigPath, "utf-8");
36170
36380
  const config = load(content);
36171
36381
  projectResult = await prunePlugins(config.plugins);
@@ -36457,8 +36667,8 @@ var syncCmd = import_cmd_ts2.command({
36457
36667
  `);
36458
36668
  }
36459
36669
  const userConfigExists = !!await getUserWorkspaceConfig();
36460
- const projectConfigPath = join23(process.cwd(), ".allagents", "workspace.yaml");
36461
- const projectConfigExists = existsSync21(projectConfigPath);
36670
+ const projectConfigPath = join24(process.cwd(), ".allagents", "workspace.yaml");
36671
+ const projectConfigExists = existsSync22(projectConfigPath);
36462
36672
  if (!userConfigExists && !projectConfigExists) {
36463
36673
  await ensureUserWorkspace();
36464
36674
  if (isJsonMode()) {
@@ -37126,9 +37336,9 @@ init_workspace_modify();
37126
37336
  init_user_workspace();
37127
37337
  init_skills();
37128
37338
  var import_cmd_ts3 = __toESM(require_cjs(), 1);
37129
- import { existsSync as existsSync23 } from "node:fs";
37339
+ import { existsSync as existsSync24 } from "node:fs";
37130
37340
  import { readFile as readFile15 } from "node:fs/promises";
37131
- import { join as join25 } from "node:path";
37341
+ import { join as join26 } from "node:path";
37132
37342
 
37133
37343
  // src/cli/metadata/plugin-skills.ts
37134
37344
  var skillsListMeta = {
@@ -37219,7 +37429,7 @@ init_skill();
37219
37429
  init_marketplace();
37220
37430
  init_marketplace_manifest_parser();
37221
37431
  function hasProjectConfig(dir) {
37222
- return existsSync23(join25(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37432
+ return existsSync24(join26(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37223
37433
  }
37224
37434
  function resolveScope(cwd) {
37225
37435
  if (isUserConfigPath(cwd))
@@ -37250,7 +37460,7 @@ async function resolveSkillNameFromRepo(url, parsed, fallbackName, fetchFn = fet
37250
37460
  if (!fetchResult.success)
37251
37461
  return fallbackName;
37252
37462
  try {
37253
- const skillMd = await readFile15(join25(fetchResult.cachePath, "SKILL.md"), "utf-8");
37463
+ const skillMd = await readFile15(join26(fetchResult.cachePath, "SKILL.md"), "utf-8");
37254
37464
  const metadata = parseSkillMetadata(skillMd);
37255
37465
  return metadata?.name ?? fallbackName;
37256
37466
  } catch {
@@ -37808,8 +38018,8 @@ init_workspace_config();
37808
38018
  init_constants();
37809
38019
  init_js_yaml();
37810
38020
  import { readFile as readFile16 } from "node:fs/promises";
37811
- import { existsSync as existsSync24 } from "node:fs";
37812
- import { join as join26 } from "node:path";
38021
+ import { existsSync as existsSync25 } from "node:fs";
38022
+ import { join as join27 } from "node:path";
37813
38023
  async function runSyncAndPrint(options2) {
37814
38024
  if (!isJsonMode()) {
37815
38025
  console.log(`
@@ -38054,7 +38264,7 @@ var marketplaceAddCmd = import_cmd_ts4.command({
38054
38264
  process.exit(1);
38055
38265
  }
38056
38266
  if (effectiveScope === "project") {
38057
- if (!existsSync24(join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38267
+ if (!existsSync25(join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38058
38268
  const msg = 'No workspace found in current directory. Run "allagents workspace init" first.';
38059
38269
  if (isJsonMode()) {
38060
38270
  jsonOutput({ success: false, command: "plugin marketplace add", error: msg });
@@ -38361,7 +38571,7 @@ var pluginListCmd = import_cmd_ts4.command({
38361
38571
  };
38362
38572
  const pluginClients = new Map;
38363
38573
  async function loadConfigClients(configPath, scope) {
38364
- if (!existsSync24(configPath))
38574
+ if (!existsSync25(configPath))
38365
38575
  return;
38366
38576
  try {
38367
38577
  const content = await readFile16(configPath, "utf-8");
@@ -38376,8 +38586,8 @@ var pluginListCmd = import_cmd_ts4.command({
38376
38586
  }
38377
38587
  } catch {}
38378
38588
  }
38379
- const userConfigPath = join26(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
38380
- const projectConfigPath = join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38589
+ const userConfigPath = join27(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
38590
+ const projectConfigPath = join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38381
38591
  const cwdIsHome = isUserConfigPath(process.cwd());
38382
38592
  await loadConfigClients(userConfigPath, "user");
38383
38593
  if (!cwdIsHome) {
@@ -38519,7 +38729,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
38519
38729
  const isUser = scope === "user" || !scope && isUserConfigPath(process.cwd());
38520
38730
  if (isUser) {
38521
38731
  const userConfigPath = getUserWorkspaceConfigPath();
38522
- if (!existsSync24(userConfigPath)) {
38732
+ if (!existsSync25(userConfigPath)) {
38523
38733
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38524
38734
  const clients = await promptForClients2();
38525
38735
  if (clients === null) {
@@ -38531,8 +38741,8 @@ var pluginInstallCmd = import_cmd_ts4.command({
38531
38741
  await ensureUserWorkspace(clients);
38532
38742
  }
38533
38743
  } else {
38534
- const configPath = join26(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38535
- if (!existsSync24(configPath)) {
38744
+ const configPath = join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38745
+ if (!existsSync25(configPath)) {
38536
38746
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38537
38747
  const clients = await promptForClients2();
38538
38748
  if (clients === null) {
@@ -38809,13 +39019,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
38809
39019
  }
38810
39020
  }
38811
39021
  if (updateProject && !isUserConfigPath(process.cwd())) {
38812
- const { existsSync: existsSync25 } = await import("node:fs");
39022
+ const { existsSync: existsSync26 } = await import("node:fs");
38813
39023
  const { readFile: readFile17 } = await import("node:fs/promises");
38814
- const { join: join27 } = await import("node:path");
39024
+ const { join: join28 } = await import("node:path");
38815
39025
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
38816
39026
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
38817
- const configPath = join27(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
38818
- if (existsSync25(configPath)) {
39027
+ const configPath = join28(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
39028
+ if (existsSync26(configPath)) {
38819
39029
  const content = await readFile17(configPath, "utf-8");
38820
39030
  const config = load2(content);
38821
39031
  for (const entry of config.plugins ?? []) {