allagents 0.22.3 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +29 -6
  2. package/dist/index.js +290 -90
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -11,7 +11,7 @@ CLI tool for managing multi-repo AI agent workspaces with plugin synchronization
11
11
  | Feature | Claude Code Plugins | AllAgents |
12
12
  |---------|--------------------|-----------|
13
13
  | Scope | Single project | Multi-repo workspace |
14
- | Client support | Claude only | 8 AI clients |
14
+ | Client support | Claude only | 23 AI clients |
15
15
  | File location | Runtime lookup from cache | Copied to workspace (git-versioned) |
16
16
  | Project structure | AI config mixed with code | Separate workspace repo |
17
17
 
@@ -298,19 +298,42 @@ These marketplace names auto-resolve to their GitHub repos:
298
298
 
299
299
  ### Supported Clients
300
300
 
301
+ AllAgents supports 23 AI coding assistants:
302
+
303
+ #### Universal Clients (share `.agents/skills/`)
304
+
301
305
  | Client | Skills | Agent File | Hooks | Commands | GitHub Overrides |
302
306
  |--------|--------|------------|-------|----------|------------------|
303
- | claude | `.claude/skills/` | `CLAUDE.md` | `.claude/hooks/` | `.claude/commands/` | No |
304
307
  | copilot | `.agents/skills/` | `AGENTS.md` | No | No | `.github/` |
305
308
  | codex | `.agents/skills/` | `AGENTS.md` | No | No | No |
306
- | cursor | `.cursor/skills/` | `AGENTS.md` | No | No | No |
307
309
  | opencode | `.agents/skills/` | `AGENTS.md` | No | `.opencode/commands/` | No |
308
310
  | gemini | `.agents/skills/` | `GEMINI.md` | No | No | No |
309
- | factory | `.factory/skills/` | `AGENTS.md` | `.factory/hooks/` | No | No |
310
311
  | ampcode | `.agents/skills/` | `AGENTS.md` | No | No | No |
311
312
  | vscode | `.agents/skills/` | `AGENTS.md` | No | No | `.github/` |
312
-
313
- > **Note:** Clients supporting the universal `.agents/` folder (copilot, codex, opencode, gemini, ampcode, vscode) share the same skills directory. GitHub overrides (`.github/prompts/`, `copilot-instructions.md`) are copied to Copilot/VSCode's `.github/` folder.
313
+ | replit | `.agents/skills/` | `AGENTS.md` | No | No | No |
314
+ | kimi | `.agents/skills/` | `AGENTS.md` | No | No | No |
315
+
316
+ #### Provider-Specific Clients
317
+
318
+ | Client | Skills | Agent File | Hooks | Commands |
319
+ |--------|--------|------------|-------|----------|
320
+ | claude | `.claude/skills/` | `CLAUDE.md` | `.claude/hooks/` | `.claude/commands/` |
321
+ | cursor | `.cursor/skills/` | `AGENTS.md` | No | No |
322
+ | factory | `.factory/skills/` | `AGENTS.md` | `.factory/hooks/` | No |
323
+ | openclaw | `skills/` | `AGENTS.md` | No | No |
324
+ | windsurf | `.windsurf/skills/` | `AGENTS.md` | No | No |
325
+ | cline | `.cline/skills/` | `AGENTS.md` | No | No |
326
+ | continue | `.continue/skills/` | `AGENTS.md` | No | No |
327
+ | roo | `.roo/skills/` | `AGENTS.md` | No | No |
328
+ | kilo | `.kilocode/skills/` | `AGENTS.md` | No | No |
329
+ | trae | `.trae/skills/` | `AGENTS.md` | No | No |
330
+ | augment | `.augment/skills/` | `AGENTS.md` | No | No |
331
+ | zencoder | `.zencoder/skills/` | `AGENTS.md` | No | No |
332
+ | junie | `.junie/skills/` | `AGENTS.md` | No | No |
333
+ | openhands | `.openhands/skills/` | `AGENTS.md` | No | No |
334
+ | kiro | `.kiro/skills/` | `AGENTS.md` | No | No |
335
+
336
+ > **Note:** Universal clients share the same `.agents/skills/` directory. GitHub overrides (`.github/prompts/`, `copilot-instructions.md`) are copied to Copilot/VSCode's `.github/` folder.
314
337
 
315
338
  ## Marketplace Structure
316
339
 
package/dist/index.js CHANGED
@@ -11453,7 +11453,13 @@ var init_zod = __esm(() => {
11453
11453
  });
11454
11454
 
11455
11455
  // src/models/workspace-config.ts
11456
- var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, VscodeConfigSchema, SyncModeSchema, WorkspaceConfigSchema;
11456
+ function getPluginSource(plugin) {
11457
+ return typeof plugin === "string" ? plugin : plugin.source;
11458
+ }
11459
+ function getPluginClients(plugin) {
11460
+ return typeof plugin === "string" ? undefined : plugin.clients;
11461
+ }
11462
+ var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, WorkspaceConfigSchema;
11457
11463
  var init_workspace_config = __esm(() => {
11458
11464
  init_zod();
11459
11465
  RepositorySchema = exports_external.object({
@@ -11483,7 +11489,29 @@ var init_workspace_config = __esm(() => {
11483
11489
  "gemini",
11484
11490
  "factory",
11485
11491
  "ampcode",
11486
- "vscode"
11492
+ "vscode",
11493
+ "openclaw",
11494
+ "windsurf",
11495
+ "cline",
11496
+ "continue",
11497
+ "roo",
11498
+ "kilo",
11499
+ "trae",
11500
+ "augment",
11501
+ "zencoder",
11502
+ "junie",
11503
+ "openhands",
11504
+ "kiro",
11505
+ "replit",
11506
+ "kimi",
11507
+ "universal"
11508
+ ]);
11509
+ PluginEntrySchema = exports_external.union([
11510
+ PluginSourceSchema,
11511
+ exports_external.object({
11512
+ source: PluginSourceSchema,
11513
+ clients: exports_external.array(ClientTypeSchema).optional()
11514
+ })
11487
11515
  ]);
11488
11516
  VscodeConfigSchema = exports_external.object({
11489
11517
  output: exports_external.string().optional()
@@ -11492,7 +11520,7 @@ var init_workspace_config = __esm(() => {
11492
11520
  WorkspaceConfigSchema = exports_external.object({
11493
11521
  workspace: WorkspaceSchema.optional(),
11494
11522
  repositories: exports_external.array(RepositorySchema),
11495
- plugins: exports_external.array(PluginSourceSchema),
11523
+ plugins: exports_external.array(PluginEntrySchema),
11496
11524
  clients: exports_external.array(ClientTypeSchema),
11497
11525
  vscode: VscodeConfigSchema.optional(),
11498
11526
  syncMode: SyncModeSchema.optional(),
@@ -21372,7 +21400,7 @@ var init_glob_patterns = __esm(() => {
21372
21400
 
21373
21401
  // src/models/client-mapping.ts
21374
21402
  function isUniversalClient(client) {
21375
- return CLIENT_MAPPINGS[client].skillsPath === CANONICAL_SKILLS_PATH;
21403
+ return client === "universal";
21376
21404
  }
21377
21405
  var CLIENT_MAPPINGS, CANONICAL_SKILLS_PATH = ".agents/skills/", USER_CLIENT_MAPPINGS;
21378
21406
  var init_client_mapping = __esm(() => {
@@ -21386,12 +21414,12 @@ var init_client_mapping = __esm(() => {
21386
21414
  hooksPath: ".claude/hooks/"
21387
21415
  },
21388
21416
  copilot: {
21389
- skillsPath: ".agents/skills/",
21417
+ skillsPath: ".github/skills/",
21390
21418
  agentFile: "AGENTS.md",
21391
21419
  githubPath: ".github/"
21392
21420
  },
21393
21421
  codex: {
21394
- skillsPath: ".agents/skills/",
21422
+ skillsPath: ".codex/skills/",
21395
21423
  agentFile: "AGENTS.md"
21396
21424
  },
21397
21425
  cursor: {
@@ -21400,11 +21428,11 @@ var init_client_mapping = __esm(() => {
21400
21428
  },
21401
21429
  opencode: {
21402
21430
  commandsPath: ".opencode/commands/",
21403
- skillsPath: ".agents/skills/",
21431
+ skillsPath: ".opencode/skills/",
21404
21432
  agentFile: "AGENTS.md"
21405
21433
  },
21406
21434
  gemini: {
21407
- skillsPath: ".agents/skills/",
21435
+ skillsPath: ".gemini/skills/",
21408
21436
  agentFile: "GEMINI.md",
21409
21437
  agentFileFallback: "AGENTS.md"
21410
21438
  },
@@ -21414,13 +21442,73 @@ var init_client_mapping = __esm(() => {
21414
21442
  hooksPath: ".factory/hooks/"
21415
21443
  },
21416
21444
  ampcode: {
21417
- skillsPath: ".agents/skills/",
21445
+ skillsPath: ".ampcode/skills/",
21418
21446
  agentFile: "AGENTS.md"
21419
21447
  },
21420
21448
  vscode: {
21421
- skillsPath: ".agents/skills/",
21449
+ skillsPath: ".github/skills/",
21422
21450
  agentFile: "AGENTS.md",
21423
21451
  githubPath: ".github/"
21452
+ },
21453
+ openclaw: {
21454
+ skillsPath: "skills/",
21455
+ agentFile: "AGENTS.md"
21456
+ },
21457
+ windsurf: {
21458
+ skillsPath: ".windsurf/skills/",
21459
+ agentFile: "AGENTS.md"
21460
+ },
21461
+ cline: {
21462
+ skillsPath: ".cline/skills/",
21463
+ agentFile: "AGENTS.md"
21464
+ },
21465
+ continue: {
21466
+ skillsPath: ".continue/skills/",
21467
+ agentFile: "AGENTS.md"
21468
+ },
21469
+ roo: {
21470
+ skillsPath: ".roo/skills/",
21471
+ agentFile: "AGENTS.md"
21472
+ },
21473
+ kilo: {
21474
+ skillsPath: ".kilocode/skills/",
21475
+ agentFile: "AGENTS.md"
21476
+ },
21477
+ trae: {
21478
+ skillsPath: ".trae/skills/",
21479
+ agentFile: "AGENTS.md"
21480
+ },
21481
+ augment: {
21482
+ skillsPath: ".augment/skills/",
21483
+ agentFile: "AGENTS.md"
21484
+ },
21485
+ zencoder: {
21486
+ skillsPath: ".zencoder/skills/",
21487
+ agentFile: "AGENTS.md"
21488
+ },
21489
+ junie: {
21490
+ skillsPath: ".junie/skills/",
21491
+ agentFile: "AGENTS.md"
21492
+ },
21493
+ openhands: {
21494
+ skillsPath: ".openhands/skills/",
21495
+ agentFile: "AGENTS.md"
21496
+ },
21497
+ kiro: {
21498
+ skillsPath: ".kiro/skills/",
21499
+ agentFile: "AGENTS.md"
21500
+ },
21501
+ replit: {
21502
+ skillsPath: ".replit/skills/",
21503
+ agentFile: "AGENTS.md"
21504
+ },
21505
+ kimi: {
21506
+ skillsPath: ".kimi/skills/",
21507
+ agentFile: "AGENTS.md"
21508
+ },
21509
+ universal: {
21510
+ skillsPath: ".agents/skills/",
21511
+ agentFile: "AGENTS.md"
21424
21512
  }
21425
21513
  };
21426
21514
  USER_CLIENT_MAPPINGS = {
@@ -21433,12 +21521,12 @@ var init_client_mapping = __esm(() => {
21433
21521
  hooksPath: ".claude/hooks/"
21434
21522
  },
21435
21523
  copilot: {
21436
- skillsPath: ".agents/skills/",
21524
+ skillsPath: ".copilot/skills/",
21437
21525
  agentFile: "AGENTS.md",
21438
21526
  githubPath: ".copilot/"
21439
21527
  },
21440
21528
  codex: {
21441
- skillsPath: ".agents/skills/",
21529
+ skillsPath: ".codex/skills/",
21442
21530
  agentFile: "AGENTS.md"
21443
21531
  },
21444
21532
  cursor: {
@@ -21447,11 +21535,11 @@ var init_client_mapping = __esm(() => {
21447
21535
  },
21448
21536
  opencode: {
21449
21537
  commandsPath: ".opencode/commands/",
21450
- skillsPath: ".agents/skills/",
21538
+ skillsPath: ".opencode/skills/",
21451
21539
  agentFile: "AGENTS.md"
21452
21540
  },
21453
21541
  gemini: {
21454
- skillsPath: ".agents/skills/",
21542
+ skillsPath: ".gemini/skills/",
21455
21543
  agentFile: "GEMINI.md",
21456
21544
  agentFileFallback: "AGENTS.md"
21457
21545
  },
@@ -21461,13 +21549,73 @@ var init_client_mapping = __esm(() => {
21461
21549
  hooksPath: ".factory/hooks/"
21462
21550
  },
21463
21551
  ampcode: {
21464
- skillsPath: ".agents/skills/",
21552
+ skillsPath: ".ampcode/skills/",
21465
21553
  agentFile: "AGENTS.md"
21466
21554
  },
21467
21555
  vscode: {
21468
- skillsPath: ".agents/skills/",
21556
+ skillsPath: ".copilot/skills/",
21469
21557
  agentFile: "AGENTS.md",
21470
21558
  githubPath: ".copilot/"
21559
+ },
21560
+ openclaw: {
21561
+ skillsPath: "skills/",
21562
+ agentFile: "AGENTS.md"
21563
+ },
21564
+ windsurf: {
21565
+ skillsPath: ".codeium/windsurf/skills/",
21566
+ agentFile: "AGENTS.md"
21567
+ },
21568
+ cline: {
21569
+ skillsPath: ".cline/skills/",
21570
+ agentFile: "AGENTS.md"
21571
+ },
21572
+ continue: {
21573
+ skillsPath: ".continue/skills/",
21574
+ agentFile: "AGENTS.md"
21575
+ },
21576
+ roo: {
21577
+ skillsPath: ".roo/skills/",
21578
+ agentFile: "AGENTS.md"
21579
+ },
21580
+ kilo: {
21581
+ skillsPath: ".kilocode/skills/",
21582
+ agentFile: "AGENTS.md"
21583
+ },
21584
+ trae: {
21585
+ skillsPath: ".trae/skills/",
21586
+ agentFile: "AGENTS.md"
21587
+ },
21588
+ augment: {
21589
+ skillsPath: ".augment/skills/",
21590
+ agentFile: "AGENTS.md"
21591
+ },
21592
+ zencoder: {
21593
+ skillsPath: ".zencoder/skills/",
21594
+ agentFile: "AGENTS.md"
21595
+ },
21596
+ junie: {
21597
+ skillsPath: ".junie/skills/",
21598
+ agentFile: "AGENTS.md"
21599
+ },
21600
+ openhands: {
21601
+ skillsPath: ".openhands/skills/",
21602
+ agentFile: "AGENTS.md"
21603
+ },
21604
+ kiro: {
21605
+ skillsPath: ".kiro/skills/",
21606
+ agentFile: "AGENTS.md"
21607
+ },
21608
+ replit: {
21609
+ skillsPath: ".replit/skills/",
21610
+ agentFile: "AGENTS.md"
21611
+ },
21612
+ kimi: {
21613
+ skillsPath: ".kimi/skills/",
21614
+ agentFile: "AGENTS.md"
21615
+ },
21616
+ universal: {
21617
+ skillsPath: ".agents/skills/",
21618
+ agentFile: "AGENTS.md"
21471
21619
  }
21472
21620
  };
21473
21621
  });
@@ -25933,9 +26081,12 @@ async function hasUserPlugin(plugin) {
25933
26081
  const config = await getUserWorkspaceConfig();
25934
26082
  if (!config)
25935
26083
  return false;
25936
- if (config.plugins.indexOf(plugin) !== -1)
26084
+ if (config.plugins.some((entry) => getPluginSource(entry) === plugin))
25937
26085
  return true;
25938
- return config.plugins.some((p) => p.startsWith(`${plugin}@`) || p === plugin);
26086
+ return config.plugins.some((entry) => {
26087
+ const source = getPluginSource(entry);
26088
+ return source.startsWith(`${plugin}@`) || source === plugin;
26089
+ });
25939
26090
  }
25940
26091
  async function removeUserPlugin(plugin) {
25941
26092
  await ensureUserWorkspace();
@@ -25943,9 +26094,12 @@ async function removeUserPlugin(plugin) {
25943
26094
  try {
25944
26095
  const content = await readFile6(configPath, "utf-8");
25945
26096
  const config = load(content);
25946
- let index = config.plugins.indexOf(plugin);
26097
+ let index = config.plugins.findIndex((entry) => getPluginSource(entry) === plugin);
25947
26098
  if (index === -1) {
25948
- index = config.plugins.findIndex((p) => p.startsWith(`${plugin}@`) || p === plugin);
26099
+ index = config.plugins.findIndex((entry) => {
26100
+ const source = getPluginSource(entry);
26101
+ return source.startsWith(`${plugin}@`) || source === plugin;
26102
+ });
25949
26103
  }
25950
26104
  if (index === -1) {
25951
26105
  const identity = await resolveGitHubIdentity(plugin);
@@ -25954,7 +26108,7 @@ async function removeUserPlugin(plugin) {
25954
26108
  const p = config.plugins[i2];
25955
26109
  if (!p)
25956
26110
  continue;
25957
- const existing = await resolveGitHubIdentity(p);
26111
+ const existing = await resolveGitHubIdentity(getPluginSource(p));
25958
26112
  if (existing === identity) {
25959
26113
  index = i2;
25960
26114
  break;
@@ -25968,7 +26122,7 @@ async function removeUserPlugin(plugin) {
25968
26122
  error: `Plugin not found in user config: ${plugin}`
25969
26123
  };
25970
26124
  }
25971
- const removedEntry = config.plugins[index];
26125
+ const removedEntry = getPluginSource(config.plugins[index]);
25972
26126
  config.plugins.splice(index, 1);
25973
26127
  pruneDisabledSkillsForPlugin(config, removedEntry);
25974
26128
  await writeFile2(configPath, dump(config, { lineWidth: -1 }), "utf-8");
@@ -25984,8 +26138,8 @@ async function getUserPluginsForMarketplace(marketplaceName) {
25984
26138
  const config = await getUserWorkspaceConfig();
25985
26139
  if (!config)
25986
26140
  return [];
25987
- return config.plugins.filter((p) => {
25988
- const parsed = parsePluginSpec(p);
26141
+ return config.plugins.map((entry) => getPluginSource(entry)).filter((source) => {
26142
+ const parsed = parsePluginSpec(source);
25989
26143
  return parsed?.marketplaceName === marketplaceName;
25990
26144
  });
25991
26145
  }
@@ -25993,16 +26147,16 @@ async function removeUserPluginsForMarketplace(marketplaceName) {
25993
26147
  const config = await getUserWorkspaceConfig();
25994
26148
  if (!config)
25995
26149
  return [];
25996
- const matching = config.plugins.filter((p) => {
25997
- const parsed = parsePluginSpec(p);
26150
+ const matching = config.plugins.filter((entry) => {
26151
+ const parsed = parsePluginSpec(getPluginSource(entry));
25998
26152
  return parsed?.marketplaceName === marketplaceName;
25999
26153
  });
26000
26154
  if (matching.length === 0)
26001
26155
  return [];
26002
26156
  const configPath = getUserWorkspaceConfigPath();
26003
- config.plugins = config.plugins.filter((p) => !matching.includes(p));
26157
+ config.plugins = config.plugins.filter((entry) => !matching.includes(entry));
26004
26158
  await writeFile2(configPath, dump(config, { lineWidth: -1 }), "utf-8");
26005
- return matching;
26159
+ return matching.map((entry) => getPluginSource(entry));
26006
26160
  }
26007
26161
  async function resolveGitHubIdentity(pluginSource) {
26008
26162
  if (isGitHubUrl(pluginSource)) {
@@ -26031,7 +26185,7 @@ async function addPluginToUserConfig(plugin, configPath, autoRegistered) {
26031
26185
  try {
26032
26186
  const content = await readFile6(configPath, "utf-8");
26033
26187
  const config = load(content);
26034
- if (config.plugins.includes(plugin)) {
26188
+ if (config.plugins.some((entry) => getPluginSource(entry) === plugin)) {
26035
26189
  return {
26036
26190
  success: false,
26037
26191
  error: `Plugin already exists in user config: ${plugin}`
@@ -26040,11 +26194,12 @@ async function addPluginToUserConfig(plugin, configPath, autoRegistered) {
26040
26194
  const newIdentity = await resolveGitHubIdentity(plugin);
26041
26195
  if (newIdentity) {
26042
26196
  for (const existing of config.plugins) {
26043
- const existingIdentity = await resolveGitHubIdentity(existing);
26197
+ const existingSource = getPluginSource(existing);
26198
+ const existingIdentity = await resolveGitHubIdentity(existingSource);
26044
26199
  if (existingIdentity === newIdentity) {
26045
26200
  return {
26046
26201
  success: false,
26047
- error: `Plugin duplicates existing entry '${existing}': both resolve to ${newIdentity}`
26202
+ error: `Plugin duplicates existing entry '${existingSource}': both resolve to ${newIdentity}`
26048
26203
  };
26049
26204
  }
26050
26205
  }
@@ -26137,7 +26292,8 @@ async function getInstalledUserPlugins() {
26137
26292
  if (!config)
26138
26293
  return [];
26139
26294
  const result = [];
26140
- for (const plugin of config.plugins) {
26295
+ for (const pluginEntry of config.plugins) {
26296
+ const plugin = getPluginSource(pluginEntry);
26141
26297
  const parsed = parsePluginSpec(plugin);
26142
26298
  if (parsed) {
26143
26299
  result.push({
@@ -26160,7 +26316,8 @@ async function getInstalledProjectPlugins(workspacePath) {
26160
26316
  if (!config?.plugins)
26161
26317
  return [];
26162
26318
  const result = [];
26163
- for (const plugin of config.plugins) {
26319
+ for (const pluginEntry of config.plugins) {
26320
+ const plugin = getPluginSource(pluginEntry);
26164
26321
  const parsed = parsePluginSpec(plugin);
26165
26322
  if (parsed) {
26166
26323
  result.push({
@@ -26180,6 +26337,7 @@ var DEFAULT_USER_CLIENTS;
26180
26337
  var init_user_workspace = __esm(() => {
26181
26338
  init_js_yaml();
26182
26339
  init_constants();
26340
+ init_workspace_config();
26183
26341
  init_marketplace_manifest_parser();
26184
26342
  init_plugin_path();
26185
26343
  init_marketplace();
@@ -26889,7 +27047,7 @@ async function addPluginToConfig(plugin, configPath, autoRegistered) {
26889
27047
  try {
26890
27048
  const content = await readFile8(configPath, "utf-8");
26891
27049
  const config = load(content);
26892
- if (config.plugins.includes(plugin)) {
27050
+ if (config.plugins.some((entry) => getPluginSource(entry) === plugin)) {
26893
27051
  return {
26894
27052
  success: false,
26895
27053
  error: `Plugin already exists in .allagents/workspace.yaml: ${plugin}`
@@ -26917,10 +27075,13 @@ async function hasPlugin(plugin, workspacePath = process.cwd()) {
26917
27075
  try {
26918
27076
  const content = await readFile8(configPath, "utf-8");
26919
27077
  const config = load(content);
26920
- if (config.plugins.indexOf(plugin) !== -1)
27078
+ if (config.plugins.some((entry) => getPluginSource(entry) === plugin))
26921
27079
  return true;
26922
27080
  if (!isPluginSpec(plugin)) {
26923
- return config.plugins.some((p) => p.startsWith(`${plugin}@`) || p === plugin);
27081
+ return config.plugins.some((entry) => {
27082
+ const source = getPluginSource(entry);
27083
+ return source.startsWith(`${plugin}@`) || source === plugin;
27084
+ });
26924
27085
  }
26925
27086
  return false;
26926
27087
  } catch {
@@ -26939,9 +27100,12 @@ async function removePlugin(plugin, workspacePath = process.cwd()) {
26939
27100
  try {
26940
27101
  const content = await readFile8(configPath, "utf-8");
26941
27102
  const config = load(content);
26942
- let index = config.plugins.indexOf(plugin);
27103
+ let index = config.plugins.findIndex((entry) => getPluginSource(entry) === plugin);
26943
27104
  if (index === -1 && isPluginSpec(plugin) === false) {
26944
- index = config.plugins.findIndex((p) => p.startsWith(`${plugin}@`) || p === plugin);
27105
+ index = config.plugins.findIndex((entry) => {
27106
+ const source = getPluginSource(entry);
27107
+ return source.startsWith(`${plugin}@`) || source === plugin;
27108
+ });
26945
27109
  }
26946
27110
  if (index === -1) {
26947
27111
  return {
@@ -26949,7 +27113,7 @@ async function removePlugin(plugin, workspacePath = process.cwd()) {
26949
27113
  error: `Plugin not found in .allagents/workspace.yaml: ${plugin}`
26950
27114
  };
26951
27115
  }
26952
- const removedEntry = config.plugins[index];
27116
+ const removedEntry = getPluginSource(config.plugins[index]);
26953
27117
  config.plugins.splice(index, 1);
26954
27118
  pruneDisabledSkillsForPlugin(config, removedEntry);
26955
27119
  const newContent = dump(config, { lineWidth: -1 });
@@ -27047,6 +27211,7 @@ var DEFAULT_PROJECT_CLIENTS;
27047
27211
  var init_workspace_modify = __esm(() => {
27048
27212
  init_js_yaml();
27049
27213
  init_constants();
27214
+ init_workspace_config();
27050
27215
  init_plugin_path();
27051
27216
  init_marketplace();
27052
27217
  DEFAULT_PROJECT_CLIENTS = [
@@ -27711,6 +27876,9 @@ function mergeSyncResults(a, b) {
27711
27876
  ...mcpResult && { mcpResult }
27712
27877
  };
27713
27878
  }
27879
+ function collectSyncClients(workspaceClients, plans) {
27880
+ return [...new Set([...workspaceClients, ...plans.flatMap((plan) => plan.clients)])];
27881
+ }
27714
27882
  async function selectivePurgeWorkspace(workspacePath, state, clients, options2) {
27715
27883
  if (!state) {
27716
27884
  return [];
@@ -27922,6 +28090,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
27922
28090
  plugin: pluginSource,
27923
28091
  resolved: "",
27924
28092
  success: false,
28093
+ clients: [],
27925
28094
  error: resolved.error || "Unknown error"
27926
28095
  };
27927
28096
  }
@@ -27929,6 +28098,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
27929
28098
  plugin: pluginSource,
27930
28099
  resolved: resolved.path ?? "",
27931
28100
  success: true,
28101
+ clients: [],
27932
28102
  ...resolved.pluginName && { pluginName: resolved.pluginName }
27933
28103
  };
27934
28104
  }
@@ -27943,6 +28113,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
27943
28113
  plugin: pluginSource,
27944
28114
  resolved: "",
27945
28115
  success: false,
28116
+ clients: [],
27946
28117
  ...fetchResult.error && { error: fetchResult.error }
27947
28118
  };
27948
28119
  }
@@ -27950,7 +28121,8 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
27950
28121
  return {
27951
28122
  plugin: pluginSource,
27952
28123
  resolved: resolvedPath2,
27953
- success: true
28124
+ success: true,
28125
+ clients: []
27954
28126
  };
27955
28127
  }
27956
28128
  const resolvedPath = resolve9(workspacePath, pluginSource);
@@ -27959,36 +28131,39 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
27959
28131
  plugin: pluginSource,
27960
28132
  resolved: resolvedPath,
27961
28133
  success: false,
28134
+ clients: [],
27962
28135
  error: `Plugin not found at ${resolvedPath}`
27963
28136
  };
27964
28137
  }
27965
28138
  return {
27966
28139
  plugin: pluginSource,
27967
28140
  resolved: resolvedPath,
27968
- success: true
28141
+ success: true,
28142
+ clients: []
27969
28143
  };
27970
28144
  }
27971
- async function validateAllPlugins(plugins, workspacePath, offline) {
27972
- return Promise.all(plugins.map((plugin) => validatePlugin(plugin, workspacePath, offline)));
28145
+ function buildPluginSyncPlans(plugins, workspaceClients, selectedClients) {
28146
+ const selected = selectedClients ? new Set(selectedClients) : null;
28147
+ return plugins.map((plugin) => {
28148
+ const source = getPluginSource(plugin);
28149
+ const configuredClients = getPluginClients(plugin) ?? workspaceClients;
28150
+ const clients = selected ? configuredClients.filter((client) => selected.has(client)) : configuredClients;
28151
+ return { source, clients };
28152
+ });
28153
+ }
28154
+ async function validateAllPlugins(plans, workspacePath, offline) {
28155
+ return Promise.all(plans.map(async ({ source, clients }) => {
28156
+ const validated = await validatePlugin(source, workspacePath, offline);
28157
+ return { ...validated, clients };
28158
+ }));
27973
28159
  }
27974
28160
  async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryRun, skillNameMap, clientMappings, syncMode = "symlink") {
27975
28161
  const copyResults = [];
27976
28162
  const mappings = clientMappings ?? CLIENT_MAPPINGS;
27977
28163
  const clientList = clients;
27978
- if (syncMode === "symlink") {
28164
+ const hasUniversalClient = clientList.some((c) => isUniversalClient(c));
28165
+ if (syncMode === "symlink" && hasUniversalClient) {
27979
28166
  const { representativeClients } = deduplicateClientsByPath(clientList, mappings);
27980
- const canonicalRepresentative = representativeClients.find((c) => mappings[c]?.skillsPath === CANONICAL_SKILLS_PATH);
27981
- const needsCanonicalCopy = !canonicalRepresentative;
27982
- const nonUniversalClients = clientList.filter((c) => !isUniversalClient(c));
27983
- if (needsCanonicalCopy && nonUniversalClients.length > 0) {
27984
- const canonicalResults = await copyPluginToWorkspace(validatedPlugin.resolved, workspacePath, "copilot", {
27985
- dryRun,
27986
- ...skillNameMap && { skillNameMap },
27987
- syncMode: "copy"
27988
- });
27989
- const skillResults = canonicalResults.filter((r) => r.destination.includes(CANONICAL_SKILLS_PATH) && r.action === "copied");
27990
- copyResults.push(...skillResults);
27991
- }
27992
28167
  for (const representative of representativeClients) {
27993
28168
  if (isUniversalClient(representative)) {
27994
28169
  const results = await copyPluginToWorkspace(validatedPlugin.resolved, workspacePath, representative, {
@@ -28121,9 +28296,15 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28121
28296
  };
28122
28297
  }
28123
28298
  const hasRepositories = (config.repositories?.length ?? 0) > 0;
28124
- const clients = options2.clients ? config.clients.filter((c) => options2.clients?.includes(c)) : config.clients;
28299
+ const workspaceClients = options2.clients ? config.clients.filter((c) => options2.clients?.includes(c)) : config.clients;
28125
28300
  if (options2.clients) {
28126
- const invalidClients = options2.clients.filter((c) => !config.clients.includes(c));
28301
+ const availableClients = new Set(config.clients);
28302
+ for (const plugin of config.plugins) {
28303
+ for (const client of getPluginClients(plugin) ?? []) {
28304
+ availableClients.add(client);
28305
+ }
28306
+ }
28307
+ const invalidClients = options2.clients.filter((c) => !availableClients.has(c));
28127
28308
  if (invalidClients.length > 0) {
28128
28309
  return {
28129
28310
  success: false,
@@ -28133,12 +28314,15 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28133
28314
  totalSkipped: 0,
28134
28315
  totalGenerated: 0,
28135
28316
  error: `Client(s) not configured in workspace.yaml: ${invalidClients.join(", ")}
28136
- Configured clients: ${config.clients.join(", ")}`
28317
+ Configured clients: ${Array.from(availableClients).join(", ")}`
28137
28318
  };
28138
28319
  }
28139
28320
  }
28140
- await ensureMarketplacesRegistered(config.plugins);
28141
- const validatedPlugins = await validateAllPlugins(config.plugins, workspacePath, offline);
28321
+ const selectedClients = options2.clients;
28322
+ const pluginPlans = buildPluginSyncPlans(config.plugins, config.clients, selectedClients).filter((plan) => plan.clients.length > 0);
28323
+ const syncClients = collectSyncClients(workspaceClients, pluginPlans);
28324
+ await ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source));
28325
+ const validatedPlugins = await validateAllPlugins(pluginPlans, workspacePath, offline);
28142
28326
  let validatedWorkspaceSource = null;
28143
28327
  if (config.workspace?.source) {
28144
28328
  const sourceBasePath = workspaceSourceBase ?? workspacePath;
@@ -28158,7 +28342,7 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28158
28342
  const failedValidations = validatedPlugins.filter((v) => !v.success);
28159
28343
  const validPlugins = validatedPlugins.filter((v) => v.success);
28160
28344
  const warnings = failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`);
28161
- if (validPlugins.length === 0 && config.plugins.length > 0) {
28345
+ if (validPlugins.length === 0 && pluginPlans.length > 0) {
28162
28346
  return {
28163
28347
  success: false,
28164
28348
  pluginResults: [],
@@ -28173,12 +28357,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28173
28357
  };
28174
28358
  }
28175
28359
  const previousState = await loadSyncState(workspacePath);
28176
- const purgedPaths = previousState ? clients.map((client) => ({
28360
+ const purgedPaths = previousState ? syncClients.map((client) => ({
28177
28361
  client,
28178
28362
  paths: getPreviouslySyncedFiles(previousState, client)
28179
28363
  })).filter((p) => p.paths.length > 0) : [];
28180
28364
  if (!dryRun) {
28181
- await selectivePurgeWorkspace(workspacePath, previousState, clients, {
28365
+ await selectivePurgeWorkspace(workspacePath, previousState, syncClients, {
28182
28366
  partialSync: !!options2.clients
28183
28367
  });
28184
28368
  }
@@ -28188,7 +28372,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28188
28372
  const syncMode = config.syncMode ?? "symlink";
28189
28373
  const pluginResults = await Promise.all(validPlugins.map((validatedPlugin) => {
28190
28374
  const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
28191
- return copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryRun, skillNameMap, undefined, syncMode);
28375
+ return copyValidatedPlugin(validatedPlugin, workspacePath, validatedPlugin.clients, dryRun, skillNameMap, undefined, syncMode);
28192
28376
  }));
28193
28377
  let workspaceFileResults = [];
28194
28378
  if (config.workspace) {
@@ -28236,7 +28420,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
28236
28420
  };
28237
28421
  }
28238
28422
  workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories });
28239
- if (hasRepositories && !dryRun && clients.includes("claude") && sourcePath) {
28423
+ if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
28240
28424
  const claudePath = join15(workspacePath, "CLAUDE.md");
28241
28425
  const agentsPath = join15(workspacePath, "AGENTS.md");
28242
28426
  const claudeExistsInSource = existsSync12(join15(sourcePath, "CLAUDE.md"));
@@ -28248,7 +28432,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
28248
28432
  if (!config.workspace && !dryRun && !skipAgentFiles) {
28249
28433
  await updateAgentFiles(workspacePath);
28250
28434
  }
28251
- if (clients.includes("vscode") && !dryRun) {
28435
+ if (syncClients.includes("vscode") && !dryRun) {
28252
28436
  generateVscodeWorkspaceFile(workspacePath, config);
28253
28437
  }
28254
28438
  let totalCopied = 0;
@@ -28292,10 +28476,10 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
28292
28476
  ...pluginResults.flatMap((r) => r.copyResults),
28293
28477
  ...workspaceFileResults
28294
28478
  ];
28295
- const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, clients);
28479
+ const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, syncClients);
28296
28480
  if (options2.clients && previousState) {
28297
28481
  for (const [client, files] of Object.entries(previousState.files)) {
28298
- if (!clients.includes(client)) {
28482
+ if (!syncClients.includes(client)) {
28299
28483
  syncedFiles[client] = files;
28300
28484
  }
28301
28485
  }
@@ -28326,14 +28510,16 @@ async function syncUserWorkspace(options2 = {}) {
28326
28510
  totalGenerated: 0
28327
28511
  };
28328
28512
  }
28329
- const clients = config.clients;
28513
+ const workspaceClients = config.clients;
28330
28514
  const { offline = false, dryRun = false, force = false } = options2;
28331
- await ensureMarketplacesRegistered(config.plugins);
28332
- const validatedPlugins = await validateAllPlugins(config.plugins, homeDir, offline);
28515
+ const pluginPlans = buildPluginSyncPlans(config.plugins, workspaceClients).filter((plan) => plan.clients.length > 0);
28516
+ const syncClients = collectSyncClients(workspaceClients, pluginPlans);
28517
+ await ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source));
28518
+ const validatedPlugins = await validateAllPlugins(pluginPlans, homeDir, offline);
28333
28519
  const failedValidations = validatedPlugins.filter((v) => !v.success);
28334
28520
  const validPlugins = validatedPlugins.filter((v) => v.success);
28335
28521
  const warnings = failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`);
28336
- if (validPlugins.length === 0 && config.plugins.length > 0) {
28522
+ if (validPlugins.length === 0 && pluginPlans.length > 0) {
28337
28523
  return {
28338
28524
  success: false,
28339
28525
  pluginResults: [],
@@ -28349,7 +28535,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28349
28535
  }
28350
28536
  const previousState = await loadSyncState(homeDir);
28351
28537
  if (!dryRun) {
28352
- await selectivePurgeWorkspace(homeDir, previousState, clients);
28538
+ await selectivePurgeWorkspace(homeDir, previousState, syncClients);
28353
28539
  }
28354
28540
  const disabledSkillsSet = new Set(config.disabledSkills ?? []);
28355
28541
  const allSkills = await collectAllSkills(validPlugins, disabledSkillsSet);
@@ -28357,7 +28543,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28357
28543
  const syncMode = config.syncMode ?? "symlink";
28358
28544
  const pluginResults = await Promise.all(validPlugins.map((vp) => {
28359
28545
  const skillNameMap = pluginSkillMaps.get(vp.resolved);
28360
- return copyValidatedPlugin(vp, homeDir, clients, dryRun, skillNameMap, USER_CLIENT_MAPPINGS, syncMode);
28546
+ return copyValidatedPlugin(vp, homeDir, vp.clients, dryRun, skillNameMap, USER_CLIENT_MAPPINGS, syncMode);
28361
28547
  }));
28362
28548
  let totalCopied = 0;
28363
28549
  let totalFailed = 0;
@@ -28382,7 +28568,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28382
28568
  }
28383
28569
  }
28384
28570
  let mcpResult;
28385
- if (clients.includes("vscode")) {
28571
+ if (syncClients.includes("vscode")) {
28386
28572
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
28387
28573
  mcpResult = syncVscodeMcpConfig(validPlugins, { dryRun, force, trackedServers: trackedMcpServers });
28388
28574
  if (mcpResult.warnings.length > 0) {
@@ -28391,7 +28577,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28391
28577
  }
28392
28578
  if (!dryRun) {
28393
28579
  const allCopyResults = pluginResults.flatMap((r) => r.copyResults);
28394
- const syncedFiles = collectSyncedPaths(allCopyResults, homeDir, clients, USER_CLIENT_MAPPINGS);
28580
+ const syncedFiles = collectSyncedPaths(allCopyResults, homeDir, syncClients, USER_CLIENT_MAPPINGS);
28395
28581
  await saveSyncState(homeDir, {
28396
28582
  files: syncedFiles,
28397
28583
  ...mcpResult && { mcpServers: { vscode: mcpResult.trackedServers } }
@@ -28412,6 +28598,7 @@ var import_json52, VSCODE_TEMPLATE_FILE = "template.code-workspace";
28412
28598
  var init_sync = __esm(() => {
28413
28599
  init_constants();
28414
28600
  init_workspace_parser();
28601
+ init_workspace_config();
28415
28602
  init_plugin_path();
28416
28603
  init_plugin();
28417
28604
  init_transform();
@@ -28770,7 +28957,8 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
28770
28957
  try {
28771
28958
  const config = await parseWorkspaceConfig(configPath);
28772
28959
  const plugins = [];
28773
- for (const pluginSource of config.plugins) {
28960
+ for (const pluginEntry of config.plugins) {
28961
+ const pluginSource = getPluginSource(pluginEntry);
28774
28962
  if (isPluginSpec(pluginSource)) {
28775
28963
  const status = await getMarketplacePluginStatus(pluginSource);
28776
28964
  plugins.push(status);
@@ -28822,7 +29010,8 @@ async function getUserPluginStatuses() {
28822
29010
  if (!config)
28823
29011
  return [];
28824
29012
  const statuses = [];
28825
- for (const pluginSource of config.plugins) {
29013
+ for (const pluginEntry of config.plugins) {
29014
+ const pluginSource = getPluginSource(pluginEntry);
28826
29015
  if (isPluginSpec(pluginSource)) {
28827
29016
  statuses.push(await getMarketplacePluginStatus(pluginSource));
28828
29017
  } else {
@@ -28844,6 +29033,7 @@ async function getMarketplacePluginStatus(spec) {
28844
29033
  var init_status2 = __esm(() => {
28845
29034
  init_constants();
28846
29035
  init_workspace_parser();
29036
+ init_workspace_config();
28847
29037
  init_plugin_path();
28848
29038
  init_marketplace();
28849
29039
  init_user_workspace();
@@ -28943,7 +29133,8 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
28943
29133
  const config = load(content);
28944
29134
  const disabledSkills = new Set(config.disabledSkills ?? []);
28945
29135
  const skills = [];
28946
- for (const pluginSource of config.plugins) {
29136
+ for (const pluginEntry of config.plugins) {
29137
+ const pluginSource = getPluginSource(pluginEntry);
28947
29138
  const pluginPath = await resolvePluginPath(pluginSource, workspacePath);
28948
29139
  if (!pluginPath)
28949
29140
  continue;
@@ -28973,6 +29164,7 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
28973
29164
  var init_skills = __esm(() => {
28974
29165
  init_js_yaml();
28975
29166
  init_constants();
29167
+ init_workspace_config();
28976
29168
  init_plugin();
28977
29169
  init_plugin_path();
28978
29170
  init_marketplace();
@@ -29476,7 +29668,7 @@ var package_default;
29476
29668
  var init_package = __esm(() => {
29477
29669
  package_default = {
29478
29670
  name: "allagents",
29479
- version: "0.22.3",
29671
+ version: "0.24.0",
29480
29672
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
29481
29673
  type: "module",
29482
29674
  bin: {
@@ -29501,7 +29693,8 @@ var init_package = __esm(() => {
29501
29693
  check: "biome check src",
29502
29694
  "check:fix": "biome check --write src",
29503
29695
  prepare: "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
29504
- release: "bun run scripts/release.ts"
29696
+ release: "bun run scripts/release.ts",
29697
+ "publish:next": "bun run build && bun publish --tag next"
29505
29698
  },
29506
29699
  keywords: [
29507
29700
  "cli",
@@ -32597,6 +32790,7 @@ init_js_yaml();
32597
32790
  init_constants();
32598
32791
  init_marketplace();
32599
32792
  init_user_workspace();
32793
+ init_workspace_config();
32600
32794
  import { readFile as readFile12, writeFile as writeFile8 } from "node:fs/promises";
32601
32795
  import { existsSync as existsSync16 } from "node:fs";
32602
32796
  import { join as join19 } from "node:path";
@@ -32612,33 +32806,36 @@ async function isOrphanedPlugin(pluginSpec) {
32612
32806
  async function prunePlugins(plugins) {
32613
32807
  const removed = [];
32614
32808
  const kept = [];
32615
- for (const plugin of plugins) {
32809
+ const keptEntries = [];
32810
+ for (const pluginEntry of plugins) {
32811
+ const plugin = getPluginSource(pluginEntry);
32616
32812
  if (await isOrphanedPlugin(plugin)) {
32617
32813
  removed.push(plugin);
32618
32814
  } else {
32619
32815
  kept.push(plugin);
32816
+ keptEntries.push(pluginEntry);
32620
32817
  }
32621
32818
  }
32622
- return { removed, kept };
32819
+ return { removed, kept, keptEntries };
32623
32820
  }
32624
32821
  async function pruneOrphanedPlugins(workspacePath) {
32625
- let projectResult = { removed: [], kept: [] };
32822
+ let projectResult = { removed: [], kept: [], keptEntries: [] };
32626
32823
  const projectConfigPath = join19(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
32627
32824
  if (existsSync16(projectConfigPath) && !isUserConfigPath(workspacePath)) {
32628
32825
  const content = await readFile12(projectConfigPath, "utf-8");
32629
32826
  const config = load(content);
32630
32827
  projectResult = await prunePlugins(config.plugins);
32631
32828
  if (projectResult.removed.length > 0) {
32632
- config.plugins = projectResult.kept;
32829
+ config.plugins = projectResult.keptEntries;
32633
32830
  await writeFile8(projectConfigPath, dump(config, { lineWidth: -1 }), "utf-8");
32634
32831
  }
32635
32832
  }
32636
- let userResult = { removed: [], kept: [] };
32833
+ let userResult = { removed: [], kept: [], keptEntries: [] };
32637
32834
  const userConfig = await getUserWorkspaceConfig();
32638
32835
  if (userConfig) {
32639
32836
  userResult = await prunePlugins(userConfig.plugins);
32640
32837
  if (userResult.removed.length > 0) {
32641
- userConfig.plugins = userResult.kept;
32838
+ userConfig.plugins = userResult.keptEntries;
32642
32839
  const userConfigPath = getUserWorkspaceConfigPath();
32643
32840
  await writeFile8(userConfigPath, dump(userConfig, { lineWidth: -1 }), "utf-8");
32644
32841
  }
@@ -33946,6 +34143,7 @@ var skillsCmd = conciseSubcommands({
33946
34143
  });
33947
34144
 
33948
34145
  // src/cli/commands/plugin.ts
34146
+ init_workspace_config();
33949
34147
  async function runSyncAndPrint(options2) {
33950
34148
  if (!isJsonMode()) {
33951
34149
  console.log(`
@@ -34680,7 +34878,8 @@ var pluginUpdateCmd = import_cmd_ts4.command({
34680
34878
  if (existsSync20(configPath)) {
34681
34879
  const content = await readFile14(configPath, "utf-8");
34682
34880
  const config = load2(content);
34683
- for (const p of config.plugins ?? []) {
34881
+ for (const entry of config.plugins ?? []) {
34882
+ const p = getPluginSource(entry);
34684
34883
  if (!pluginsToUpdate.includes(p)) {
34685
34884
  pluginsToUpdate.push(p);
34686
34885
  }
@@ -34690,7 +34889,8 @@ var pluginUpdateCmd = import_cmd_ts4.command({
34690
34889
  if (updateUser) {
34691
34890
  const userConfig = await getUserWorkspaceConfig();
34692
34891
  if (userConfig) {
34693
- for (const p of userConfig.plugins ?? []) {
34892
+ for (const entry of userConfig.plugins ?? []) {
34893
+ const p = getPluginSource(entry);
34694
34894
  if (!pluginsToUpdate.includes(p)) {
34695
34895
  pluginsToUpdate.push(p);
34696
34896
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "0.22.3",
3
+ "version": "0.24.0",
4
4
  "description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,7 +25,8 @@
25
25
  "check": "biome check src",
26
26
  "check:fix": "biome check --write src",
27
27
  "prepare": "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
28
- "release": "bun run scripts/release.ts"
28
+ "release": "bun run scripts/release.ts",
29
+ "publish:next": "bun run build && bun publish --tag next"
29
30
  },
30
31
  "keywords": [
31
32
  "cli",