allagents 1.2.0 → 1.4.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 (2) hide show
  1. package/dist/index.js +271 -195
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -29246,7 +29246,8 @@ var init_codex_mcp = __esm(() => {
29246
29246
  });
29247
29247
 
29248
29248
  // src/core/claude-mcp.ts
29249
- import { existsSync as existsSync13, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
29249
+ import { existsSync as existsSync13, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
29250
+ import { dirname as dirname9 } from "node:path";
29250
29251
  function deepEqual2(a, b) {
29251
29252
  if (a === b)
29252
29253
  return true;
@@ -29363,6 +29364,10 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29363
29364
  const hasChanges = result.added > 0 || result.overwritten > 0 || result.removed > 0;
29364
29365
  if (hasChanges && !dryRun) {
29365
29366
  existingConfig.mcpServers = existingServers;
29367
+ const dir = dirname9(configPath);
29368
+ if (!existsSync13(dir)) {
29369
+ mkdirSync3(dir, { recursive: true });
29370
+ }
29366
29371
  writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29367
29372
  `, "utf-8");
29368
29373
  result.configPath = configPath;
@@ -29377,6 +29382,10 @@ function syncClaudeMcpConfig(validatedPlugins, options2) {
29377
29382
  }
29378
29383
  if (result.removed > 0 && !dryRun) {
29379
29384
  existingConfig.mcpServers = existingServers;
29385
+ const dir = dirname9(configPath);
29386
+ if (!existsSync13(dir)) {
29387
+ mkdirSync3(dir, { recursive: true });
29388
+ }
29380
29389
  writeFileSync3(configPath, `${JSON.stringify(existingConfig, null, 2)}
29381
29390
  `, "utf-8");
29382
29391
  result.configPath = configPath;
@@ -29472,6 +29481,15 @@ var init_claude_mcp = __esm(() => {
29472
29481
  import_json52 = __toESM(require_lib(), 1);
29473
29482
  });
29474
29483
 
29484
+ // src/core/copilot-mcp.ts
29485
+ import { join as join15 } from "node:path";
29486
+ function getCopilotMcpConfigPath() {
29487
+ return join15(getHomeDir(), ".copilot", "mcp-config.json");
29488
+ }
29489
+ var init_copilot_mcp = __esm(() => {
29490
+ init_constants();
29491
+ });
29492
+
29475
29493
  // src/core/native/claude.ts
29476
29494
  class ClaudeNativeClient {
29477
29495
  async isAvailable() {
@@ -29692,7 +29710,7 @@ var init_native = __esm(() => {
29692
29710
  // src/core/sync.ts
29693
29711
  import { existsSync as existsSync14, readFileSync as readFileSync4, writeFileSync as writeFileSync4, lstatSync } from "node:fs";
29694
29712
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
29695
- import { join as join15, resolve as resolve9, dirname as dirname9, relative as relative4 } from "node:path";
29713
+ import { join as join16, resolve as resolve9, dirname as dirname10, relative as relative4 } from "node:path";
29696
29714
  function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
29697
29715
  const pathToClients = new Map;
29698
29716
  for (const client of clients) {
@@ -29793,7 +29811,7 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
29793
29811
  const previousFiles = getPreviouslySyncedFiles(state, client);
29794
29812
  const purgedPaths = [];
29795
29813
  for (const filePath of previousFiles) {
29796
- const fullPath = join15(workspacePath, filePath);
29814
+ const fullPath = join16(workspacePath, filePath);
29797
29815
  const cleanPath = fullPath.replace(/\/$/, "");
29798
29816
  let stats;
29799
29817
  try {
@@ -29820,16 +29838,16 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
29820
29838
  return result;
29821
29839
  }
29822
29840
  async function cleanupEmptyParents(workspacePath, filePath) {
29823
- let parentPath = dirname9(filePath);
29841
+ let parentPath = dirname10(filePath);
29824
29842
  while (parentPath && parentPath !== "." && parentPath !== "/") {
29825
- const fullParentPath = join15(workspacePath, parentPath);
29843
+ const fullParentPath = join16(workspacePath, parentPath);
29826
29844
  if (!existsSync14(fullParentPath)) {
29827
- parentPath = dirname9(parentPath);
29845
+ parentPath = dirname10(parentPath);
29828
29846
  continue;
29829
29847
  }
29830
29848
  try {
29831
29849
  await rmdir(fullParentPath);
29832
- parentPath = dirname9(parentPath);
29850
+ parentPath = dirname10(parentPath);
29833
29851
  } catch {
29834
29852
  break;
29835
29853
  }
@@ -29908,7 +29926,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
29908
29926
  errors2.push(`Cannot resolve file '${file}' - no workspace.source configured`);
29909
29927
  continue;
29910
29928
  }
29911
- const fullPath = join15(defaultSourcePath, file);
29929
+ const fullPath = join16(defaultSourcePath, file);
29912
29930
  if (!existsSync14(fullPath)) {
29913
29931
  errors2.push(`File source not found: ${fullPath}`);
29914
29932
  }
@@ -29927,7 +29945,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
29927
29945
  errors2.push(`GitHub cache not found for ${cacheKey}`);
29928
29946
  continue;
29929
29947
  }
29930
- const fullPath = join15(cachePath, parsed.filePath);
29948
+ const fullPath = join16(cachePath, parsed.filePath);
29931
29949
  if (!existsSync14(fullPath)) {
29932
29950
  errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
29933
29951
  }
@@ -29938,7 +29956,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
29938
29956
  } else if (file.source.startsWith("../")) {
29939
29957
  fullPath = resolve9(file.source);
29940
29958
  } else if (defaultSourcePath) {
29941
- fullPath = join15(defaultSourcePath, file.source);
29959
+ fullPath = join16(defaultSourcePath, file.source);
29942
29960
  } else {
29943
29961
  fullPath = resolve9(file.source);
29944
29962
  }
@@ -29951,7 +29969,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
29951
29969
  errors2.push(`Cannot resolve file '${file.dest}' - no workspace.source configured and no explicit source provided`);
29952
29970
  continue;
29953
29971
  }
29954
- const fullPath = join15(defaultSourcePath, file.dest ?? "");
29972
+ const fullPath = join16(defaultSourcePath, file.dest ?? "");
29955
29973
  if (!existsSync14(fullPath)) {
29956
29974
  errors2.push(`File source not found: ${fullPath}`);
29957
29975
  }
@@ -30098,7 +30116,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30098
30116
  ...fetchResult.error && { error: fetchResult.error }
30099
30117
  };
30100
30118
  }
30101
- const resolvedPath2 = parsed?.subpath ? join15(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30119
+ const resolvedPath2 = parsed?.subpath ? join16(fetchResult.cachePath, parsed.subpath) : fetchResult.cachePath;
30102
30120
  return {
30103
30121
  plugin: pluginSource,
30104
30122
  resolved: resolvedPath2,
@@ -30269,8 +30287,8 @@ function buildPluginSkillNameMaps(allSkills) {
30269
30287
  return pluginMaps;
30270
30288
  }
30271
30289
  function generateVscodeWorkspaceFile(workspacePath, config) {
30272
- const configDir = join15(workspacePath, CONFIG_DIR);
30273
- const templatePath = join15(configDir, VSCODE_TEMPLATE_FILE);
30290
+ const configDir = join16(workspacePath, CONFIG_DIR);
30291
+ const templatePath = join16(configDir, VSCODE_TEMPLATE_FILE);
30274
30292
  let template;
30275
30293
  if (existsSync14(templatePath)) {
30276
30294
  try {
@@ -30476,8 +30494,8 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
30476
30494
  async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
30477
30495
  await migrateWorkspaceSkillsV1toV2(workspacePath);
30478
30496
  const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
30479
- const configDir = join15(workspacePath, CONFIG_DIR);
30480
- const configPath = join15(configDir, WORKSPACE_CONFIG_FILE);
30497
+ const configDir = join16(workspacePath, CONFIG_DIR);
30498
+ const configPath = join16(configDir, WORKSPACE_CONFIG_FILE);
30481
30499
  if (!existsSync14(configPath)) {
30482
30500
  return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
30483
30501
  Run 'allagents workspace init <path>' to create a new workspace`);
@@ -30558,7 +30576,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30558
30576
  const filesToCopy = [...config.workspace.files];
30559
30577
  if (hasRepositories && sourcePath) {
30560
30578
  for (const agentFile of AGENT_FILES) {
30561
- const agentPath = join15(sourcePath, agentFile);
30579
+ const agentPath = join16(sourcePath, agentFile);
30562
30580
  if (existsSync14(agentPath) && !filesToCopy.includes(agentFile)) {
30563
30581
  filesToCopy.push(agentFile);
30564
30582
  }
@@ -30583,9 +30601,9 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30583
30601
  }
30584
30602
  workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories });
30585
30603
  if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
30586
- const claudePath = join15(workspacePath, "CLAUDE.md");
30587
- const agentsPath = join15(workspacePath, "AGENTS.md");
30588
- const claudeExistsInSource = existsSync14(join15(sourcePath, "CLAUDE.md"));
30604
+ const claudePath = join16(workspacePath, "CLAUDE.md");
30605
+ const agentsPath = join16(workspacePath, "AGENTS.md");
30606
+ const claudeExistsInSource = existsSync14(join16(sourcePath, "CLAUDE.md"));
30589
30607
  if (!claudeExistsInSource && existsSync14(agentsPath) && !existsSync14(claudePath)) {
30590
30608
  await copyFile(agentsPath, claudePath);
30591
30609
  }
@@ -30605,7 +30623,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30605
30623
  const mcpResults = {};
30606
30624
  if (syncClients.includes("vscode")) {
30607
30625
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
30608
- const projectMcpPath = join15(workspacePath, ".vscode", "mcp.json");
30626
+ const projectMcpPath = join16(workspacePath, ".vscode", "mcp.json");
30609
30627
  const vscodeMcp = syncVscodeMcpConfig(validPlugins, {
30610
30628
  dryRun,
30611
30629
  force: false,
@@ -30619,7 +30637,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30619
30637
  }
30620
30638
  if (syncClients.includes("claude")) {
30621
30639
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "claude");
30622
- const projectMcpJsonPath = join15(workspacePath, ".mcp.json");
30640
+ const projectMcpJsonPath = join16(workspacePath, ".mcp.json");
30623
30641
  const claudeMcp = syncClaudeMcpConfig(validPlugins, {
30624
30642
  dryRun,
30625
30643
  force: false,
@@ -30633,7 +30651,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30633
30651
  }
30634
30652
  if (syncClients.includes("codex")) {
30635
30653
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "codex");
30636
- const projectCodexConfigPath = join15(workspacePath, ".codex", "config.toml");
30654
+ const projectCodexConfigPath = join16(workspacePath, ".codex", "config.toml");
30637
30655
  const codexMcp = syncCodexProjectMcpConfig(validPlugins, {
30638
30656
  dryRun,
30639
30657
  force: false,
@@ -30645,7 +30663,21 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
30645
30663
  }
30646
30664
  mcpResults.codex = codexMcp;
30647
30665
  }
30648
- const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "universal"]);
30666
+ if (syncClients.includes("copilot")) {
30667
+ const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
30668
+ const projectCopilotMcpPath = join16(workspacePath, ".copilot", "mcp-config.json");
30669
+ const copilotMcp = syncClaudeMcpConfig(validPlugins, {
30670
+ dryRun,
30671
+ force: false,
30672
+ configPath: projectCopilotMcpPath,
30673
+ trackedServers: trackedMcpServers
30674
+ });
30675
+ if (copilotMcp.warnings.length > 0) {
30676
+ warnings.push(...copilotMcp.warnings);
30677
+ }
30678
+ mcpResults.copilot = copilotMcp;
30679
+ }
30680
+ const PROJECT_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
30649
30681
  const { servers: allMcpServers } = collectMcpServers(validPlugins);
30650
30682
  if (allMcpServers.size > 0) {
30651
30683
  for (const client of syncClients) {
@@ -30760,7 +30792,21 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
30760
30792
  }
30761
30793
  mcpResults.claude = claudeMcp;
30762
30794
  }
30763
- const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "universal"]);
30795
+ if (syncClients.includes("copilot")) {
30796
+ const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "copilot");
30797
+ const copilotMcpPath = getCopilotMcpConfigPath();
30798
+ const copilotMcp = syncClaudeMcpConfig(validPlugins, {
30799
+ dryRun,
30800
+ force,
30801
+ configPath: copilotMcpPath,
30802
+ trackedServers: trackedMcpServers
30803
+ });
30804
+ if (copilotMcp.warnings.length > 0) {
30805
+ warnings.push(...copilotMcp.warnings);
30806
+ }
30807
+ mcpResults.copilot = copilotMcp;
30808
+ }
30809
+ const USER_MCP_CLIENTS = new Set(["claude", "codex", "vscode", "copilot", "universal"]);
30764
30810
  const { servers: allUserMcpServers } = collectMcpServers(validPlugins);
30765
30811
  if (allUserMcpServers.size > 0) {
30766
30812
  for (const client of syncClients) {
@@ -30817,15 +30863,16 @@ var init_sync = __esm(() => {
30817
30863
  init_vscode_mcp();
30818
30864
  init_codex_mcp();
30819
30865
  init_claude_mcp();
30866
+ init_copilot_mcp();
30820
30867
  init_native();
30821
30868
  import_json53 = __toESM(require_lib(), 1);
30822
30869
  });
30823
30870
 
30824
30871
  // src/core/github-fetch.ts
30825
30872
  import { existsSync as existsSync15, readFileSync as readFileSync5 } from "node:fs";
30826
- import { join as join16 } from "node:path";
30873
+ import { join as join17 } from "node:path";
30827
30874
  function readFileFromClone(tempDir, filePath) {
30828
- const fullPath = join16(tempDir, filePath);
30875
+ const fullPath = join17(tempDir, filePath);
30829
30876
  if (existsSync15(fullPath)) {
30830
30877
  return readFileSync5(fullPath, "utf-8");
30831
30878
  }
@@ -30927,12 +30974,12 @@ var init_github_fetch = __esm(() => {
30927
30974
  // src/core/workspace.ts
30928
30975
  import { mkdir as mkdir8, readFile as readFile10, writeFile as writeFile7, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
30929
30976
  import { existsSync as existsSync16 } from "node:fs";
30930
- import { join as join17, resolve as resolve10, dirname as dirname10, relative as relative5, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
30977
+ import { join as join18, resolve as resolve10, dirname as dirname11, relative as relative5, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
30931
30978
  import { fileURLToPath } from "node:url";
30932
30979
  async function initWorkspace(targetPath = ".", options2 = {}) {
30933
30980
  const absoluteTarget = resolve10(targetPath);
30934
- const configDir = join17(absoluteTarget, CONFIG_DIR);
30935
- const configPath = join17(configDir, WORKSPACE_CONFIG_FILE);
30981
+ const configDir = join18(absoluteTarget, CONFIG_DIR);
30982
+ const configPath = join18(configDir, WORKSPACE_CONFIG_FILE);
30936
30983
  if (existsSync16(configPath)) {
30937
30984
  if (options2.force) {
30938
30985
  await unlink3(configPath);
@@ -30942,9 +30989,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
30942
30989
  }
30943
30990
  }
30944
30991
  const currentFilePath = fileURLToPath(import.meta.url);
30945
- const currentFileDir = dirname10(currentFilePath);
30992
+ const currentFileDir = dirname11(currentFilePath);
30946
30993
  const isProduction = currentFilePath.includes(`${sep2}dist${sep2}`);
30947
- const defaultTemplatePath = isProduction ? join17(currentFileDir, "templates", "default") : join17(currentFileDir, "..", "templates", "default");
30994
+ const defaultTemplatePath = isProduction ? join18(currentFileDir, "templates", "default") : join18(currentFileDir, "..", "templates", "default");
30948
30995
  let githubTempDir;
30949
30996
  let parsedFromUrl;
30950
30997
  let githubBasePath = "";
@@ -30990,8 +31037,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
30990
31037
  const fromStat = await stat2(fromPath);
30991
31038
  let sourceYamlPath;
30992
31039
  if (fromStat.isDirectory()) {
30993
- const nestedPath = join17(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
30994
- const rootPath = join17(fromPath, WORKSPACE_CONFIG_FILE);
31040
+ const nestedPath = join18(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31041
+ const rootPath = join18(fromPath, WORKSPACE_CONFIG_FILE);
30995
31042
  if (existsSync16(nestedPath)) {
30996
31043
  sourceYamlPath = nestedPath;
30997
31044
  sourceDir = fromPath;
@@ -31004,9 +31051,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31004
31051
  }
31005
31052
  } else {
31006
31053
  sourceYamlPath = fromPath;
31007
- const parentDir = dirname10(fromPath);
31054
+ const parentDir = dirname11(fromPath);
31008
31055
  if (parentDir.endsWith(CONFIG_DIR)) {
31009
- sourceDir = dirname10(parentDir);
31056
+ sourceDir = dirname11(parentDir);
31010
31057
  } else {
31011
31058
  sourceDir = parentDir;
31012
31059
  }
@@ -31026,7 +31073,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31026
31073
  console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
31027
31074
  }
31028
31075
  } else {
31029
- const defaultYamlPath = join17(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31076
+ const defaultYamlPath = join18(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31030
31077
  if (!existsSync16(defaultYamlPath)) {
31031
31078
  throw new Error(`Default template not found at: ${defaultTemplatePath}`);
31032
31079
  }
@@ -31043,7 +31090,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31043
31090
  const clientNames = getClientTypes(clients);
31044
31091
  const VSCODE_TEMPLATE_FILE2 = "template.code-workspace";
31045
31092
  if (clientNames.includes("vscode") && options2.from) {
31046
- const targetTemplatePath = join17(configDir, VSCODE_TEMPLATE_FILE2);
31093
+ const targetTemplatePath = join18(configDir, VSCODE_TEMPLATE_FILE2);
31047
31094
  if (!existsSync16(targetTemplatePath)) {
31048
31095
  if (isGitHubUrl(options2.from) && githubTempDir) {
31049
31096
  if (parsedFromUrl) {
@@ -31054,7 +31101,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31054
31101
  }
31055
31102
  }
31056
31103
  } else if (sourceDir) {
31057
- const sourceTemplatePath = join17(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31104
+ const sourceTemplatePath = join18(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31058
31105
  if (existsSync16(sourceTemplatePath)) {
31059
31106
  await copyFile2(sourceTemplatePath, targetTemplatePath);
31060
31107
  }
@@ -31068,7 +31115,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31068
31115
  if (options2.from && isGitHubUrl(options2.from) && githubTempDir) {
31069
31116
  if (parsedFromUrl) {
31070
31117
  for (const agentFile of AGENT_FILES) {
31071
- const targetFilePath = join17(absoluteTarget, agentFile);
31118
+ const targetFilePath = join18(absoluteTarget, agentFile);
31072
31119
  if (existsSync16(targetFilePath)) {
31073
31120
  copiedAgentFiles.push(agentFile);
31074
31121
  continue;
@@ -31084,12 +31131,12 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31084
31131
  } else {
31085
31132
  const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
31086
31133
  for (const agentFile of AGENT_FILES) {
31087
- const targetFilePath = join17(absoluteTarget, agentFile);
31134
+ const targetFilePath = join18(absoluteTarget, agentFile);
31088
31135
  if (existsSync16(targetFilePath)) {
31089
31136
  copiedAgentFiles.push(agentFile);
31090
31137
  continue;
31091
31138
  }
31092
- const sourcePath = join17(effectiveSourceDir, agentFile);
31139
+ const sourcePath = join18(effectiveSourceDir, agentFile);
31093
31140
  if (existsSync16(sourcePath)) {
31094
31141
  const content = await readFile10(sourcePath, "utf-8");
31095
31142
  await writeFile7(targetFilePath, content, "utf-8");
@@ -31098,16 +31145,16 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31098
31145
  }
31099
31146
  }
31100
31147
  if (copiedAgentFiles.length === 0) {
31101
- await ensureWorkspaceRules(join17(absoluteTarget, "AGENTS.md"), repositories);
31148
+ await ensureWorkspaceRules(join18(absoluteTarget, "AGENTS.md"), repositories);
31102
31149
  copiedAgentFiles.push("AGENTS.md");
31103
31150
  } else {
31104
31151
  for (const agentFile of copiedAgentFiles) {
31105
- await ensureWorkspaceRules(join17(absoluteTarget, agentFile), repositories);
31152
+ await ensureWorkspaceRules(join18(absoluteTarget, agentFile), repositories);
31106
31153
  }
31107
31154
  }
31108
31155
  if (clientNames.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
31109
- const agentsPath = join17(absoluteTarget, "AGENTS.md");
31110
- const claudePath = join17(absoluteTarget, "CLAUDE.md");
31156
+ const agentsPath = join18(absoluteTarget, "AGENTS.md");
31157
+ const claudePath = join18(absoluteTarget, "CLAUDE.md");
31111
31158
  await copyFile2(agentsPath, claudePath);
31112
31159
  }
31113
31160
  }
@@ -31159,9 +31206,9 @@ var init_workspace = __esm(() => {
31159
31206
 
31160
31207
  // src/core/status.ts
31161
31208
  import { existsSync as existsSync17 } from "node:fs";
31162
- import { join as join18 } from "node:path";
31209
+ import { join as join19 } from "node:path";
31163
31210
  async function getWorkspaceStatus(workspacePath = process.cwd()) {
31164
- const configPath = join18(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31211
+ const configPath = join19(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31165
31212
  if (!existsSync17(configPath) || isUserConfigPath(workspacePath)) {
31166
31213
  const userPlugins = await getUserPluginStatuses();
31167
31214
  return {
@@ -31421,7 +31468,7 @@ function formatMcpResult(mcpResult, scope) {
31421
31468
  parts.push(`${removed} removed`);
31422
31469
  if (skipped > 0)
31423
31470
  parts.push(`${skipped} skipped`);
31424
- const displayScope = scope ? getDisplayName(scope) : undefined;
31471
+ const displayScope = scope;
31425
31472
  const label = displayScope ? `MCP servers (${displayScope})` : "MCP servers";
31426
31473
  lines.push(`${label}: ${parts.join(", ")}`);
31427
31474
  for (const name of mcpResult.addedServers) {
@@ -33259,19 +33306,14 @@ var exports_prompt_clients = {};
33259
33306
  __export(exports_prompt_clients, {
33260
33307
  promptForClients: () => promptForClients,
33261
33308
  isInteractive: () => isInteractive,
33262
- buildClientGroups: () => buildClientGroups
33309
+ buildClientOptions: () => buildClientOptions
33263
33310
  });
33264
- function buildClientGroups() {
33265
- const allClients = ClientTypeSchema.options;
33266
- const universalGroup = allClients.filter((c) => c === "universal").map((c) => ({ value: c, label: c, hint: CLIENT_MAPPINGS[c].skillsPath }));
33267
- const clientSpecificGroup = allClients.filter((c) => c !== "universal").map((c) => ({ value: c, label: c, hint: CLIENT_MAPPINGS[c].skillsPath }));
33268
- return {
33269
- groups: {
33270
- "Universal (.agents/skills)": universalGroup,
33271
- "Client-specific": clientSpecificGroup
33272
- },
33273
- initialValues: ["universal"]
33274
- };
33311
+ function buildClientOptions() {
33312
+ return ClientTypeSchema.options.map((c) => ({
33313
+ value: c,
33314
+ label: c,
33315
+ hint: CLIENT_MAPPINGS[c].skillsPath
33316
+ }));
33275
33317
  }
33276
33318
  function isInteractive() {
33277
33319
  if (ue())
@@ -33282,11 +33324,11 @@ async function promptForClients() {
33282
33324
  if (!isInteractive()) {
33283
33325
  return ["universal"];
33284
33326
  }
33285
- const { groups, initialValues } = buildClientGroups();
33286
- const selected = await groupMultiselect({
33327
+ const options2 = buildClientOptions();
33328
+ const selected = await autocompleteMultiselect({
33287
33329
  message: "Which AI clients do you use?",
33288
- options: groups,
33289
- initialValues,
33330
+ options: options2,
33331
+ initialValues: ["universal"],
33290
33332
  required: false
33291
33333
  });
33292
33334
  if (Ct(selected)) {
@@ -33297,18 +33339,18 @@ async function promptForClients() {
33297
33339
  }
33298
33340
  return selected;
33299
33341
  }
33300
- var groupMultiselect;
33342
+ var autocompleteMultiselect;
33301
33343
  var init_prompt_clients = __esm(() => {
33302
33344
  init_dist2();
33303
33345
  init_workspace_config();
33304
33346
  init_client_mapping();
33305
- ({ groupMultiselect } = exports_dist);
33347
+ ({ autocompleteMultiselect } = exports_dist);
33306
33348
  });
33307
33349
 
33308
33350
  // src/core/skills.ts
33309
33351
  import { existsSync as existsSync20 } from "node:fs";
33310
33352
  import { readFile as readFile12, readdir as readdir4 } from "node:fs/promises";
33311
- import { join as join21, basename as basename6, resolve as resolve12 } from "node:path";
33353
+ import { join as join22, basename as basename6, resolve as resolve12 } from "node:path";
33312
33354
  async function resolvePluginPath(pluginSource, workspacePath) {
33313
33355
  if (isPluginSpec(pluginSource)) {
33314
33356
  const resolved2 = await resolvePluginSpecWithAutoRegister(pluginSource, {
@@ -33329,14 +33371,14 @@ async function resolvePluginPath(pluginSource, workspacePath) {
33329
33371
  });
33330
33372
  if (!result.success)
33331
33373
  return null;
33332
- const path = parsed?.subpath ? join21(result.cachePath, parsed.subpath) : result.cachePath;
33374
+ const path = parsed?.subpath ? join22(result.cachePath, parsed.subpath) : result.cachePath;
33333
33375
  return { path };
33334
33376
  }
33335
33377
  const resolved = resolve12(workspacePath, pluginSource);
33336
33378
  return existsSync20(resolved) ? { path: resolved } : null;
33337
33379
  }
33338
33380
  async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33339
- const configPath = join21(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
33381
+ const configPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
33340
33382
  if (!existsSync20(configPath)) {
33341
33383
  return [];
33342
33384
  }
@@ -33353,28 +33395,28 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
33353
33395
  continue;
33354
33396
  const pluginPath = resolved.path;
33355
33397
  const pluginName = resolved.pluginName ?? getPluginName(pluginPath);
33356
- const skillsDir = join21(pluginPath, "skills");
33398
+ const skillsDir = join22(pluginPath, "skills");
33357
33399
  const pluginSkillsConfig = typeof pluginEntry === "string" ? undefined : pluginEntry.skills;
33358
33400
  const hasEnabledEntries = !pluginSkillsConfig && enabledSkills && [...enabledSkills].some((s) => s.startsWith(`${pluginName}`));
33359
33401
  let skillEntries;
33360
33402
  if (existsSync20(skillsDir)) {
33361
33403
  const entries = await readdir4(skillsDir, { withFileTypes: true });
33362
- skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join21(skillsDir, e.name) }));
33404
+ skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join22(skillsDir, e.name) }));
33363
33405
  } else {
33364
33406
  const entries = await readdir4(pluginPath, { withFileTypes: true });
33365
33407
  const flatSkills = [];
33366
33408
  for (const entry of entries) {
33367
33409
  if (!entry.isDirectory())
33368
33410
  continue;
33369
- const skillMdPath = join21(pluginPath, entry.name, "SKILL.md");
33411
+ const skillMdPath = join22(pluginPath, entry.name, "SKILL.md");
33370
33412
  if (existsSync20(skillMdPath)) {
33371
- flatSkills.push({ name: entry.name, skillPath: join21(pluginPath, entry.name) });
33413
+ flatSkills.push({ name: entry.name, skillPath: join22(pluginPath, entry.name) });
33372
33414
  }
33373
33415
  }
33374
33416
  if (flatSkills.length > 0) {
33375
33417
  skillEntries = flatSkills;
33376
33418
  } else {
33377
- const rootSkillMd = join21(pluginPath, "SKILL.md");
33419
+ const rootSkillMd = join22(pluginPath, "SKILL.md");
33378
33420
  if (existsSync20(rootSkillMd)) {
33379
33421
  const skillContent = await readFile12(rootSkillMd, "utf-8");
33380
33422
  const metadata = parseSkillMetadata(skillContent);
@@ -33419,7 +33461,7 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
33419
33461
  async function discoverSkillNames(pluginPath) {
33420
33462
  if (!existsSync20(pluginPath))
33421
33463
  return [];
33422
- const skillsDir = join21(pluginPath, "skills");
33464
+ const skillsDir = join22(pluginPath, "skills");
33423
33465
  if (existsSync20(skillsDir)) {
33424
33466
  const entries2 = await readdir4(skillsDir, { withFileTypes: true });
33425
33467
  return entries2.filter((e) => e.isDirectory()).map((e) => e.name);
@@ -33429,13 +33471,13 @@ async function discoverSkillNames(pluginPath) {
33429
33471
  for (const entry of entries) {
33430
33472
  if (!entry.isDirectory())
33431
33473
  continue;
33432
- if (existsSync20(join21(pluginPath, entry.name, "SKILL.md"))) {
33474
+ if (existsSync20(join22(pluginPath, entry.name, "SKILL.md"))) {
33433
33475
  flatSkills.push(entry.name);
33434
33476
  }
33435
33477
  }
33436
33478
  if (flatSkills.length > 0)
33437
33479
  return flatSkills;
33438
- const rootSkillMd = join21(pluginPath, "SKILL.md");
33480
+ const rootSkillMd = join22(pluginPath, "SKILL.md");
33439
33481
  if (existsSync20(rootSkillMd)) {
33440
33482
  try {
33441
33483
  const content = await readFile12(rootSkillMd, "utf-8");
@@ -33956,7 +33998,7 @@ var package_default;
33956
33998
  var init_package = __esm(() => {
33957
33999
  package_default = {
33958
34000
  name: "allagents",
33959
- version: "1.2.0",
34001
+ version: "1.4.0",
33960
34002
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
33961
34003
  type: "module",
33962
34004
  bin: {
@@ -34031,10 +34073,10 @@ var init_package = __esm(() => {
34031
34073
 
34032
34074
  // src/cli/update-check.ts
34033
34075
  import { readFile as readFile15 } from "node:fs/promises";
34034
- import { join as join24 } from "node:path";
34076
+ import { join as join25 } from "node:path";
34035
34077
  import { spawn as spawn3 } from "node:child_process";
34036
34078
  async function getCachedUpdateInfo(path3) {
34037
- const filePath = path3 ?? join24(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34079
+ const filePath = path3 ?? join25(getHomeDir(), CONFIG_DIR, CACHE_FILE);
34038
34080
  try {
34039
34081
  const raw = await readFile15(filePath, "utf-8");
34040
34082
  const data = JSON.parse(raw);
@@ -34072,8 +34114,8 @@ function buildNotice(currentVersion, latestVersion) {
34072
34114
  Run \`allagents self update\` to upgrade.`);
34073
34115
  }
34074
34116
  function backgroundUpdateCheck() {
34075
- const dir = join24(getHomeDir(), CONFIG_DIR);
34076
- const filePath = join24(dir, CACHE_FILE);
34117
+ const dir = join25(getHomeDir(), CONFIG_DIR);
34118
+ const filePath = join25(dir, CACHE_FILE);
34077
34119
  const script = `
34078
34120
  const https = require('https');
34079
34121
  const fs = require('fs');
@@ -34161,13 +34203,13 @@ class TuiCache {
34161
34203
 
34162
34204
  // src/cli/tui/context.ts
34163
34205
  import { existsSync as existsSync23 } from "node:fs";
34164
- import { join as join25 } from "node:path";
34206
+ import { join as join26 } from "node:path";
34165
34207
  async function getTuiContext(cwd = process.cwd(), cache2) {
34166
34208
  const cachedContext = cache2?.getContext();
34167
34209
  if (cachedContext) {
34168
34210
  return cachedContext;
34169
34211
  }
34170
- const configPath = join25(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34212
+ const configPath = join26(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34171
34213
  const hasWorkspace = existsSync23(configPath) && !isUserConfigPath(cwd);
34172
34214
  let projectPluginCount = 0;
34173
34215
  if (hasWorkspace) {
@@ -34237,27 +34279,44 @@ var init_context = __esm(() => {
34237
34279
  async function runSync(context) {
34238
34280
  try {
34239
34281
  const s = Ie();
34282
+ let projectLines;
34240
34283
  if (context.hasWorkspace && context.workspacePath) {
34241
34284
  s.start("Syncing project plugins...");
34242
34285
  const result = await syncWorkspace(context.workspacePath);
34243
- s.stop("Project sync complete");
34244
34286
  if (result.error) {
34287
+ if (context.userPluginCount > 0) {
34288
+ s.message("Syncing user plugins...");
34289
+ } else {
34290
+ s.stop("Sync failed");
34291
+ }
34245
34292
  kt2(result.error, "Sync Error");
34246
34293
  } else {
34247
- const lines = result.pluginResults.map((pr) => formatPluginHeader(pr));
34248
- lines.push("");
34249
- lines.push(...formatSyncSummary(result));
34294
+ projectLines = result.pluginResults.map((pr) => formatPluginHeader(pr));
34295
+ projectLines.push("");
34296
+ projectLines.push(...formatSyncSummary(result));
34250
34297
  if (result.nativeResult) {
34251
- lines.push(...formatNativeResult(result.nativeResult));
34298
+ projectLines.push(...formatNativeResult(result.nativeResult));
34252
34299
  }
34253
- kt2(lines.join(`
34300
+ if (context.userPluginCount > 0) {
34301
+ s.message("Syncing user plugins...");
34302
+ } else {
34303
+ s.stop("Sync complete");
34304
+ kt2(projectLines.join(`
34254
34305
  `), "Project Sync");
34306
+ return;
34307
+ }
34255
34308
  }
34256
34309
  }
34257
34310
  if (context.userPluginCount > 0) {
34258
- s.start("Syncing user plugins...");
34311
+ if (!context.hasWorkspace || !context.workspacePath) {
34312
+ s.start("Syncing user plugins...");
34313
+ }
34259
34314
  const userResult = await syncUserWorkspace();
34260
- s.stop("User sync complete");
34315
+ s.stop("Sync complete");
34316
+ if (projectLines) {
34317
+ kt2(projectLines.join(`
34318
+ `), "Project Sync");
34319
+ }
34261
34320
  if (userResult.error) {
34262
34321
  kt2(userResult.error, "User Sync Error");
34263
34322
  } else {
@@ -34403,11 +34462,9 @@ async function installSelectedPlugin(pluginRef, context, cache2) {
34403
34462
  kt2(result.error ?? "Unknown error", "Error");
34404
34463
  return false;
34405
34464
  }
34406
- s.stop("Plugin added");
34407
- const syncS = Ie();
34408
- syncS.start("Syncing...");
34465
+ s.message("Syncing...");
34409
34466
  await syncWorkspace(workspacePath);
34410
- syncS.stop("Sync complete");
34467
+ s.stop("Installed and synced");
34411
34468
  } else {
34412
34469
  const result = await addUserPlugin(pluginRef);
34413
34470
  if (!result.success) {
@@ -34415,11 +34472,9 @@ async function installSelectedPlugin(pluginRef, context, cache2) {
34415
34472
  kt2(result.error ?? "Unknown error", "Error");
34416
34473
  return false;
34417
34474
  }
34418
- s.stop("Plugin added");
34419
- const syncS = Ie();
34420
- syncS.start("Syncing...");
34475
+ s.message("Syncing...");
34421
34476
  await syncUserWorkspace();
34422
- syncS.stop("Sync complete");
34477
+ s.stop("Installed and synced");
34423
34478
  }
34424
34479
  cache2?.invalidate();
34425
34480
  kt2(`Installed: ${pluginRef}`, "Success");
@@ -34434,20 +34489,20 @@ async function runUpdatePlugin(pluginSource, scope, context, cache2) {
34434
34489
  kt2(result.error ?? "Unknown error", "Error");
34435
34490
  return;
34436
34491
  }
34437
- s.stop(result.action === "updated" ? "Plugin updated" : "Already up to date");
34438
- if (result.action === "updated") {
34439
- const syncS = Ie();
34440
- syncS.start("Syncing...");
34441
- if (scope === "project" && context.workspacePath) {
34442
- await syncWorkspace(context.workspacePath);
34443
- } else {
34444
- await syncUserWorkspace();
34445
- }
34446
- syncS.stop("Sync complete");
34447
- cache2?.invalidate();
34492
+ if (result.action !== "updated") {
34493
+ s.stop("Already up to date");
34494
+ kt2(`- ${pluginSource} (${result.action})`, "Update");
34495
+ return;
34496
+ }
34497
+ s.message("Syncing...");
34498
+ if (scope === "project" && context.workspacePath) {
34499
+ await syncWorkspace(context.workspacePath);
34500
+ } else {
34501
+ await syncUserWorkspace();
34448
34502
  }
34449
- const icon = result.action === "updated" ? "✓" : "-";
34450
- kt2(`${icon} ${pluginSource} (${result.action})`, "Update");
34503
+ s.stop("Updated and synced");
34504
+ cache2?.invalidate();
34505
+ kt2(`✓ ${pluginSource} (${result.action})`, "Update");
34451
34506
  }
34452
34507
  async function runUpdateAllPlugins(context, cache2) {
34453
34508
  const s = Ie();
@@ -34469,10 +34524,8 @@ async function runUpdateAllPlugins(context, cache2) {
34469
34524
  s.stop("No plugins to update");
34470
34525
  return;
34471
34526
  }
34472
- s.stop(`Found ${pluginsToUpdate.length} plugin(s)`);
34527
+ s.message(`Updating ${pluginsToUpdate.length} plugin(s)...`);
34473
34528
  const deps = createUpdateDeps();
34474
- const updateS = Ie();
34475
- updateS.start("Updating plugins...");
34476
34529
  const results = [];
34477
34530
  let needsProjectSync = false;
34478
34531
  let needsUserSync = false;
@@ -34493,22 +34546,17 @@ async function runUpdateAllPlugins(context, cache2) {
34493
34546
  needsUserSync = true;
34494
34547
  }
34495
34548
  }
34496
- updateS.stop("Update complete");
34497
- if (needsProjectSync && context.workspacePath) {
34498
- const syncS = Ie();
34499
- syncS.start("Syncing project...");
34500
- await syncWorkspace(context.workspacePath);
34501
- syncS.stop("Project sync complete");
34502
- }
34503
- if (needsUserSync) {
34504
- const syncS = Ie();
34505
- syncS.start("Syncing user...");
34506
- await syncUserWorkspace();
34507
- syncS.stop("User sync complete");
34508
- }
34509
34549
  if (needsProjectSync || needsUserSync) {
34550
+ s.message("Syncing...");
34551
+ if (needsProjectSync && context.workspacePath) {
34552
+ await syncWorkspace(context.workspacePath);
34553
+ }
34554
+ if (needsUserSync) {
34555
+ await syncUserWorkspace();
34556
+ }
34510
34557
  cache2?.invalidate();
34511
34558
  }
34559
+ s.stop("Update complete");
34512
34560
  const updated = results.filter((r) => r.action === "updated").length;
34513
34561
  const skipped = results.filter((r) => r.action === "skipped").length;
34514
34562
  const failed = results.filter((r) => r.action === "failed").length;
@@ -34540,15 +34588,17 @@ async function runPlugins(context, cache2) {
34540
34588
  for (const plugin of status.plugins) {
34541
34589
  const key = `project:${plugin.source}`;
34542
34590
  options2.push({
34543
- label: `${plugin.source} (${plugin.type}) [project]`,
34544
- value: key
34591
+ label: plugin.source,
34592
+ value: key,
34593
+ hint: `${plugin.type} · project`
34545
34594
  });
34546
34595
  }
34547
34596
  for (const plugin of status.userPlugins ?? []) {
34548
34597
  const key = `user:${plugin.source}`;
34549
34598
  options2.push({
34550
- label: `${plugin.source} (${plugin.type}) [user]`,
34551
- value: key
34599
+ label: plugin.source,
34600
+ value: key,
34601
+ hint: `${plugin.type} · user`
34552
34602
  });
34553
34603
  }
34554
34604
  }
@@ -34639,15 +34689,13 @@ async function runPluginDetail(pluginKey, context, cache2) {
34639
34689
  continue;
34640
34690
  }
34641
34691
  }
34642
- s.stop("Mode updated");
34643
- const syncS = Ie();
34644
- syncS.start("Syncing...");
34692
+ s.message("Syncing...");
34645
34693
  if (scope === "project" && context.workspacePath) {
34646
34694
  await syncWorkspace(context.workspacePath);
34647
34695
  } else {
34648
34696
  await syncUserWorkspace();
34649
34697
  }
34650
- syncS.stop("Sync complete");
34698
+ s.stop("Mode updated and synced");
34651
34699
  cache2?.invalidate();
34652
34700
  const newMode = currentMode === "allowlist" ? "ON" : "OFF";
34653
34701
  kt2(`Auto-enable new skills: ${newMode}`, "Updated");
@@ -34673,11 +34721,9 @@ async function runPluginDetail(pluginKey, context, cache2) {
34673
34721
  kt2(result.error ?? "Unknown error", "Error");
34674
34722
  continue;
34675
34723
  }
34676
- s.stop("Plugin removed");
34677
- const syncS = Ie();
34678
- syncS.start("Syncing...");
34724
+ s.message("Syncing...");
34679
34725
  await syncWorkspace(context.workspacePath);
34680
- syncS.stop("Sync complete");
34726
+ s.stop("Removed and synced");
34681
34727
  } else {
34682
34728
  const result = await removeUserPlugin(pluginSource);
34683
34729
  if (!result.success) {
@@ -34685,11 +34731,9 @@ async function runPluginDetail(pluginKey, context, cache2) {
34685
34731
  kt2(result.error ?? "Unknown error", "Error");
34686
34732
  continue;
34687
34733
  }
34688
- s.stop("Plugin removed");
34689
- const syncS = Ie();
34690
- syncS.start("Syncing...");
34734
+ s.message("Syncing...");
34691
34735
  await syncUserWorkspace();
34692
- syncS.stop("Sync complete");
34736
+ s.stop("Removed and synced");
34693
34737
  }
34694
34738
  cache2?.invalidate();
34695
34739
  kt2(`Removed: ${pluginSource} [${scope}]`, "Success");
@@ -34761,15 +34805,13 @@ async function runBrowsePluginSkills(pluginSource, scope, context, cache2) {
34761
34805
  }
34762
34806
  }
34763
34807
  }
34764
- s.stop("Skills updated");
34765
- const syncS = Ie();
34766
- syncS.start("Syncing...");
34808
+ s.message("Syncing...");
34767
34809
  if (scope === "project" && context.workspacePath) {
34768
34810
  await syncWorkspace(context.workspacePath);
34769
34811
  } else if (scope === "user") {
34770
34812
  await syncUserWorkspace();
34771
34813
  }
34772
- syncS.stop("Sync complete");
34814
+ s.stop("Skills updated and synced");
34773
34815
  cache2?.invalidate();
34774
34816
  const changes = [];
34775
34817
  for (const skill of toEnable) {
@@ -34785,6 +34827,12 @@ async function runBrowsePluginSkills(pluginSource, scope, context, cache2) {
34785
34827
  kt2(message, "Error");
34786
34828
  }
34787
34829
  }
34830
+ function truncateList(items, maxVisible = 3) {
34831
+ if (items.length <= maxVisible) {
34832
+ return items.join(", ");
34833
+ }
34834
+ return `${items.slice(0, maxVisible).join(", ")} +${items.length - maxVisible} more`;
34835
+ }
34788
34836
  async function runInstallPlugin(context, cache2) {
34789
34837
  try {
34790
34838
  const marketplaces = await getCachedMarketplaces(cache2);
@@ -34799,12 +34847,14 @@ Use "Manage marketplaces" to add one first.`, "Marketplace");
34799
34847
  for (const plugin of result.plugins) {
34800
34848
  const skillNames = await discoverSkillNames(plugin.path);
34801
34849
  const desc = plugin.description ? ` - ${plugin.description}` : "";
34802
- const skillInfo = skillNames.length > 0 ? `
34803
- Skills: ${skillNames.join(", ")}` : "";
34804
- allPlugins.push({
34805
- label: `${plugin.name}${desc} (${marketplace.name})${skillInfo}`,
34850
+ const entry = {
34851
+ label: `${plugin.name}${desc} (${marketplace.name})`,
34806
34852
  value: `${plugin.name}@${marketplace.name}`
34807
- });
34853
+ };
34854
+ if (skillNames.length > 0) {
34855
+ entry.hint = `${skillNames.length} skills: ${truncateList(skillNames)}`;
34856
+ }
34857
+ allPlugins.push(entry);
34808
34858
  }
34809
34859
  }
34810
34860
  if (allPlugins.length === 0) {
@@ -34812,9 +34862,10 @@ Use "Manage marketplaces" to add one first.`, "Marketplace");
34812
34862
  return;
34813
34863
  }
34814
34864
  allPlugins.push({ label: "Back", value: "__back__" });
34815
- const selected = await select({
34865
+ const selected = await autocomplete({
34816
34866
  message: "Select a plugin to install",
34817
- options: allPlugins
34867
+ options: allPlugins,
34868
+ placeholder: "Type to search..."
34818
34869
  });
34819
34870
  if (Ct(selected) || selected === "__back__") {
34820
34871
  return;
@@ -34896,9 +34947,10 @@ async function runMarketplaceDetail(marketplaceName, context, cache2) {
34896
34947
  return { label, value: plugin.name };
34897
34948
  });
34898
34949
  pluginOptions.push({ label: "Back", value: "__back__" });
34899
- const selectedPlugin = await select({
34950
+ const selectedPlugin = await autocomplete({
34900
34951
  message: "Select a plugin to install",
34901
- options: pluginOptions
34952
+ options: pluginOptions,
34953
+ placeholder: "Type to search..."
34902
34954
  });
34903
34955
  if (Ct(selectedPlugin) || selectedPlugin === "__back__") {
34904
34956
  continue;
@@ -34971,7 +35023,7 @@ What would you like to do with them?`,
34971
35023
  }
34972
35024
  }
34973
35025
  }
34974
- var select, text2, confirm, multiselect;
35026
+ var select, text2, confirm, multiselect, autocomplete;
34975
35027
  var init_plugins = __esm(() => {
34976
35028
  init_dist2();
34977
35029
  init_workspace_modify();
@@ -34983,7 +35035,7 @@ var init_plugins = __esm(() => {
34983
35035
  init_status2();
34984
35036
  init_skills();
34985
35037
  init_constants();
34986
- ({ select, text: text2, confirm, multiselect } = exports_dist);
35038
+ ({ select, text: text2, confirm, multiselect, autocomplete } = exports_dist);
34987
35039
  });
34988
35040
 
34989
35041
  // src/cli/tui/actions/status.ts
@@ -35099,10 +35151,10 @@ async function runManageClients(context, cache2) {
35099
35151
  currentClients = userConfig?.clients ? getClientTypes(userConfig.clients) : [];
35100
35152
  }
35101
35153
  const allClients = ClientTypeSchema.options;
35102
- const { groups } = buildClientGroups();
35103
- const selectedClients = await Ot({
35154
+ const options2 = buildClientOptions();
35155
+ const selectedClients = await autocompleteMultiselect2({
35104
35156
  message: `Select AI clients [${scope}]`,
35105
- options: groups,
35157
+ options: options2,
35106
35158
  initialValues: currentClients.filter((c) => allClients.includes(c)),
35107
35159
  required: false
35108
35160
  });
@@ -35143,7 +35195,7 @@ async function runManageClients(context, cache2) {
35143
35195
  kt2(message, "Error");
35144
35196
  }
35145
35197
  }
35146
- var select3;
35198
+ var select3, autocompleteMultiselect2;
35147
35199
  var init_clients = __esm(() => {
35148
35200
  init_dist2();
35149
35201
  init_workspace_config();
@@ -35152,7 +35204,7 @@ var init_clients = __esm(() => {
35152
35204
  init_sync();
35153
35205
  init_status2();
35154
35206
  init_prompt_clients();
35155
- ({ select: select3 } = exports_dist);
35207
+ ({ select: select3, autocompleteMultiselect: autocompleteMultiselect2 } = exports_dist);
35156
35208
  });
35157
35209
 
35158
35210
  // src/cli/tui/actions/skills.ts
@@ -35249,8 +35301,9 @@ async function runSkills(context, cache2) {
35249
35301
  }
35250
35302
  async function runToggleSkills(skills, context, cache2) {
35251
35303
  const options2 = skills.map((s2) => ({
35252
- label: `${s2.name} (${s2.pluginName}) [${s2.scope}]`,
35253
- value: s2.key
35304
+ label: s2.name,
35305
+ value: s2.key,
35306
+ hint: `${s2.pluginName} · ${s2.scope}`
35254
35307
  }));
35255
35308
  const initialValues = skills.filter((s2) => !s2.disabled).map((s2) => s2.key);
35256
35309
  const selected = await multiselect2({
@@ -35311,16 +35364,14 @@ async function runToggleSkills(skills, context, cache2) {
35311
35364
  else
35312
35365
  changedProject = true;
35313
35366
  }
35314
- s.stop("Skills updated");
35315
- const syncS = Ie();
35316
- syncS.start("Syncing...");
35367
+ s.message("Syncing...");
35317
35368
  if (changedProject && context.workspacePath) {
35318
35369
  await syncWorkspace(context.workspacePath);
35319
35370
  }
35320
35371
  if (changedUser) {
35321
35372
  await syncUserWorkspace();
35322
35373
  }
35323
- syncS.stop("Sync complete");
35374
+ s.stop("Skills updated and synced");
35324
35375
  cache2?.invalidate();
35325
35376
  const changes = [];
35326
35377
  for (const skill of toEnable) {
@@ -35332,6 +35383,12 @@ async function runToggleSkills(skills, context, cache2) {
35332
35383
  kt2(changes.join(`
35333
35384
  `), "Updated");
35334
35385
  }
35386
+ function truncateList2(items, maxVisible = 3) {
35387
+ if (items.length <= maxVisible) {
35388
+ return items.join(", ");
35389
+ }
35390
+ return `${items.slice(0, maxVisible).join(", ")} +${items.length - maxVisible} more`;
35391
+ }
35335
35392
  async function runBrowseMarketplaceSkills(context, cache2) {
35336
35393
  const s = Ie();
35337
35394
  s.start("Loading marketplace skills...");
@@ -35359,18 +35416,18 @@ Use "Manage marketplaces" to add one first.`, "Skills");
35359
35416
  }
35360
35417
  const options2 = [];
35361
35418
  for (const [pluginRef, data] of byPlugin) {
35362
- const skillList = data.skills.join(", ");
35363
35419
  const desc = data.description ? ` - ${data.description}` : "";
35364
35420
  options2.push({
35365
- label: `${pluginRef}${desc}
35366
- Skills: ${skillList}`,
35367
- value: pluginRef
35421
+ label: `${pluginRef}${desc}`,
35422
+ value: pluginRef,
35423
+ hint: `${data.skills.length} skills: ${truncateList2(data.skills)}`
35368
35424
  });
35369
35425
  }
35370
35426
  options2.push({ label: "Back", value: "__back__" });
35371
- const selected = await select4({
35427
+ const selected = await autocomplete2({
35372
35428
  message: "Select a plugin",
35373
- options: options2
35429
+ options: options2,
35430
+ placeholder: "Type to search..."
35374
35431
  });
35375
35432
  if (Ct(selected) || selected === "__back__") {
35376
35433
  return;
@@ -35390,7 +35447,7 @@ Use "Manage marketplaces" to add one first.`, "Skills");
35390
35447
  await runBrowsePluginSkills(selected, scope, context, cache2);
35391
35448
  }
35392
35449
  }
35393
- var multiselect2, select4;
35450
+ var multiselect2, select4, autocomplete2;
35394
35451
  var init_skills2 = __esm(() => {
35395
35452
  init_dist2();
35396
35453
  init_skills();
@@ -35400,7 +35457,7 @@ var init_skills2 = __esm(() => {
35400
35457
  init_marketplace();
35401
35458
  init_constants();
35402
35459
  init_plugins();
35403
- ({ multiselect: multiselect2, select: select4 } = exports_dist);
35460
+ ({ multiselect: multiselect2, select: select4, autocomplete: autocomplete2 } = exports_dist);
35404
35461
  });
35405
35462
 
35406
35463
  // src/cli/tui/wizard.ts
@@ -35423,6 +35480,18 @@ function buildMenuOptions(context) {
35423
35480
  options2.push({ label: "Exit", value: "exit" });
35424
35481
  return options2;
35425
35482
  }
35483
+ function buildCompactSummary(context) {
35484
+ const parts = [];
35485
+ if (context.hasWorkspace) {
35486
+ parts.push(`${context.projectPluginCount} project`);
35487
+ }
35488
+ parts.push(`${context.userPluginCount} user`);
35489
+ parts.push(`${context.marketplaceCount} marketplaces`);
35490
+ if (context.needsSync) {
35491
+ parts.push(source_default.yellow("sync needed"));
35492
+ }
35493
+ return parts.join(", ");
35494
+ }
35426
35495
  function buildSummary(context) {
35427
35496
  const lines = [];
35428
35497
  if (context.hasWorkspace && context.workspacePath) {
@@ -35450,8 +35519,14 @@ async function runWizard() {
35450
35519
  }
35451
35520
  const cache2 = new TuiCache;
35452
35521
  let context = await getTuiContext(process.cwd(), cache2);
35522
+ let isFirstLoop = true;
35453
35523
  while (true) {
35454
- kt2(buildSummary(context), "Workspace");
35524
+ if (isFirstLoop) {
35525
+ kt2(buildSummary(context), "Workspace");
35526
+ isFirstLoop = false;
35527
+ } else {
35528
+ R2.info(source_default.dim(`Workspace: ${buildCompactSummary(context)}`));
35529
+ }
35455
35530
  const action = await select5({
35456
35531
  message: "What would you like to do?",
35457
35532
  options: buildMenuOptions(context)
@@ -35557,7 +35632,7 @@ init_sync();
35557
35632
  init_status2();
35558
35633
  var import_cmd_ts2 = __toESM(require_cjs(), 1);
35559
35634
  import { existsSync as existsSync19 } from "node:fs";
35560
- import { join as join20, resolve as resolve11 } from "node:path";
35635
+ import { join as join21, resolve as resolve11 } from "node:path";
35561
35636
 
35562
35637
  // src/core/prune.ts
35563
35638
  init_js_yaml();
@@ -35567,7 +35642,7 @@ init_user_workspace();
35567
35642
  init_workspace_config();
35568
35643
  import { readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
35569
35644
  import { existsSync as existsSync18 } from "node:fs";
35570
- import { join as join19 } from "node:path";
35645
+ import { join as join20 } from "node:path";
35571
35646
  async function isOrphanedPlugin(pluginSpec) {
35572
35647
  if (!isPluginSpec(pluginSpec))
35573
35648
  return false;
@@ -35594,7 +35669,7 @@ async function prunePlugins(plugins) {
35594
35669
  }
35595
35670
  async function pruneOrphanedPlugins(workspacePath) {
35596
35671
  let projectResult = { removed: [], kept: [], keptEntries: [] };
35597
- const projectConfigPath = join19(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
35672
+ const projectConfigPath = join20(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
35598
35673
  if (existsSync18(projectConfigPath) && !isUserConfigPath(workspacePath)) {
35599
35674
  const content = await readFile11(projectConfigPath, "utf-8");
35600
35675
  const config = load(content);
@@ -35872,6 +35947,7 @@ Plugin sync results:`);
35872
35947
  });
35873
35948
  var syncCmd = import_cmd_ts2.command({
35874
35949
  name: "sync",
35950
+ aliases: ["update"],
35875
35951
  description: buildDescription(syncMeta),
35876
35952
  args: {
35877
35953
  offline: import_cmd_ts2.flag({ long: "offline", description: "Use cached plugins without fetching latest from remote" }),
@@ -35886,7 +35962,7 @@ var syncCmd = import_cmd_ts2.command({
35886
35962
  `);
35887
35963
  }
35888
35964
  const userConfigExists = !!await getUserWorkspaceConfig();
35889
- const projectConfigPath = join20(process.cwd(), ".allagents", "workspace.yaml");
35965
+ const projectConfigPath = join21(process.cwd(), ".allagents", "workspace.yaml");
35890
35966
  const projectConfigExists = existsSync19(projectConfigPath);
35891
35967
  if (!userConfigExists && !projectConfigExists) {
35892
35968
  await ensureUserWorkspace();
@@ -36536,7 +36612,7 @@ init_skills();
36536
36612
  var import_cmd_ts3 = __toESM(require_cjs(), 1);
36537
36613
  import { existsSync as existsSync21 } from "node:fs";
36538
36614
  import { readFile as readFile13 } from "node:fs/promises";
36539
- import { join as join22 } from "node:path";
36615
+ import { join as join23 } from "node:path";
36540
36616
 
36541
36617
  // src/cli/metadata/plugin-skills.ts
36542
36618
  var skillsListMeta = {
@@ -36627,7 +36703,7 @@ init_skill();
36627
36703
  init_marketplace();
36628
36704
  init_marketplace_manifest_parser();
36629
36705
  function hasProjectConfig(dir) {
36630
- return existsSync21(join22(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
36706
+ return existsSync21(join23(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
36631
36707
  }
36632
36708
  function resolveScope(cwd) {
36633
36709
  if (isUserConfigPath(cwd))
@@ -36658,7 +36734,7 @@ async function resolveSkillNameFromRepo(url, parsed, fallbackName, fetchFn = fet
36658
36734
  if (!fetchResult.success)
36659
36735
  return fallbackName;
36660
36736
  try {
36661
- const skillMd = await readFile13(join22(fetchResult.cachePath, "SKILL.md"), "utf-8");
36737
+ const skillMd = await readFile13(join23(fetchResult.cachePath, "SKILL.md"), "utf-8");
36662
36738
  const metadata = parseSkillMetadata(skillMd);
36663
36739
  return metadata?.name ?? fallbackName;
36664
36740
  } catch {
@@ -37217,7 +37293,7 @@ init_constants();
37217
37293
  init_js_yaml();
37218
37294
  import { readFile as readFile14 } from "node:fs/promises";
37219
37295
  import { existsSync as existsSync22 } from "node:fs";
37220
- import { join as join23 } from "node:path";
37296
+ import { join as join24 } from "node:path";
37221
37297
  async function runSyncAndPrint(options2) {
37222
37298
  if (!isJsonMode()) {
37223
37299
  console.log(`
@@ -37462,7 +37538,7 @@ var marketplaceAddCmd = import_cmd_ts4.command({
37462
37538
  process.exit(1);
37463
37539
  }
37464
37540
  if (effectiveScope === "project") {
37465
- if (!existsSync22(join23(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
37541
+ if (!existsSync22(join24(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
37466
37542
  const msg = 'No workspace found in current directory. Run "allagents workspace init" first.';
37467
37543
  if (isJsonMode()) {
37468
37544
  jsonOutput({ success: false, command: "plugin marketplace add", error: msg });
@@ -37784,8 +37860,8 @@ var pluginListCmd = import_cmd_ts4.command({
37784
37860
  }
37785
37861
  } catch {}
37786
37862
  }
37787
- const userConfigPath = join23(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
37788
- const projectConfigPath = join23(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
37863
+ const userConfigPath = join24(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
37864
+ const projectConfigPath = join24(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
37789
37865
  await loadConfigClients(userConfigPath, "user");
37790
37866
  await loadConfigClients(projectConfigPath, "project");
37791
37867
  const userPlugins = await getInstalledUserPlugins();
@@ -37924,7 +38000,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
37924
38000
  try {
37925
38001
  const isUser = scope === "user" || !scope && isUserConfigPath(process.cwd());
37926
38002
  if (!isUser) {
37927
- const configPath = join23(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38003
+ const configPath = join24(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
37928
38004
  if (!existsSync22(configPath)) {
37929
38005
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
37930
38006
  const clients = await promptForClients2();
@@ -38213,10 +38289,10 @@ var pluginUpdateCmd = import_cmd_ts4.command({
38213
38289
  if (updateProject && !isUserConfigPath(process.cwd())) {
38214
38290
  const { existsSync: existsSync23 } = await import("node:fs");
38215
38291
  const { readFile: readFile15 } = await import("node:fs/promises");
38216
- const { join: join24 } = await import("node:path");
38292
+ const { join: join25 } = await import("node:path");
38217
38293
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
38218
38294
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
38219
- const configPath = join24(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
38295
+ const configPath = join25(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
38220
38296
  if (existsSync23(configPath)) {
38221
38297
  const content = await readFile15(configPath, "utf-8");
38222
38298
  const config = load2(content);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
5
5
  "type": "module",
6
6
  "bin": {