allagents 0.24.1 → 0.25.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +783 -188
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -11459,7 +11459,25 @@ function getPluginSource(plugin) {
11459
11459
  function getPluginClients(plugin) {
11460
11460
  return typeof plugin === "string" ? undefined : plugin.clients;
11461
11461
  }
11462
- var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, WorkspaceConfigSchema;
11462
+ function getPluginInstallMode(plugin) {
11463
+ return typeof plugin === "string" ? undefined : plugin.install;
11464
+ }
11465
+ function normalizeClientEntry(entry) {
11466
+ if (typeof entry === "string") {
11467
+ return { name: entry, install: "file" };
11468
+ }
11469
+ return { name: entry.name, install: entry.install ?? "file" };
11470
+ }
11471
+ function getClientTypes(entries) {
11472
+ return entries.map((e) => typeof e === "string" ? e : e.name);
11473
+ }
11474
+ function resolveInstallMode(pluginEntry, clientEntry) {
11475
+ const pluginMode = getPluginInstallMode(pluginEntry);
11476
+ if (pluginMode)
11477
+ return pluginMode;
11478
+ return clientEntry.install;
11479
+ }
11480
+ var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, WorkspaceConfigSchema;
11463
11481
  var init_workspace_config = __esm(() => {
11464
11482
  init_zod();
11465
11483
  RepositorySchema = exports_external.object({
@@ -11481,6 +11499,7 @@ var init_workspace_config = __esm(() => {
11481
11499
  });
11482
11500
  PluginSourceSchema = exports_external.string();
11483
11501
  ClientTypeSchema = exports_external.enum([
11502
+ "universal",
11484
11503
  "claude",
11485
11504
  "copilot",
11486
11505
  "codex",
@@ -11503,14 +11522,22 @@ var init_workspace_config = __esm(() => {
11503
11522
  "openhands",
11504
11523
  "kiro",
11505
11524
  "replit",
11506
- "kimi",
11507
- "universal"
11525
+ "kimi"
11526
+ ]);
11527
+ InstallModeSchema = exports_external.enum(["file", "native"]);
11528
+ ClientEntrySchema = exports_external.union([
11529
+ ClientTypeSchema,
11530
+ exports_external.object({
11531
+ name: ClientTypeSchema,
11532
+ install: InstallModeSchema.default("file")
11533
+ })
11508
11534
  ]);
11509
11535
  PluginEntrySchema = exports_external.union([
11510
11536
  PluginSourceSchema,
11511
11537
  exports_external.object({
11512
11538
  source: PluginSourceSchema,
11513
- clients: exports_external.array(ClientTypeSchema).optional()
11539
+ clients: exports_external.array(ClientTypeSchema).optional(),
11540
+ install: InstallModeSchema.optional()
11514
11541
  })
11515
11542
  ]);
11516
11543
  VscodeConfigSchema = exports_external.object({
@@ -11521,7 +11548,7 @@ var init_workspace_config = __esm(() => {
11521
11548
  workspace: WorkspaceSchema.optional(),
11522
11549
  repositories: exports_external.array(RepositorySchema),
11523
11550
  plugins: exports_external.array(PluginEntrySchema),
11524
- clients: exports_external.array(ClientTypeSchema),
11551
+ clients: exports_external.array(ClientEntrySchema),
11525
11552
  vscode: VscodeConfigSchema.optional(),
11526
11553
  syncMode: SyncModeSchema.optional(),
11527
11554
  disabledSkills: exports_external.array(exports_external.string()).optional()
@@ -26411,16 +26438,14 @@ function findBySourceLocation(registry, sourceLocation) {
26411
26438
  }
26412
26439
  function parseMarketplaceSource(source) {
26413
26440
  if (source.startsWith("https://github.com/")) {
26414
- const match = source.match(/^https:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/(.+))?$/);
26415
- if (match) {
26416
- const [, owner, repo, branch] = match;
26417
- if (!repo)
26418
- return null;
26419
- const location = branch ? `${owner}/${repo}/${branch}` : `${owner}/${repo}`;
26441
+ const parsed = parseGitHubUrl(source);
26442
+ if (parsed) {
26443
+ const branch = parsed.branch && parsed.subpath ? `${parsed.branch}/${parsed.subpath}` : parsed.branch;
26444
+ const location = branch ? `${parsed.owner}/${parsed.repo}/${branch}` : `${parsed.owner}/${parsed.repo}`;
26420
26445
  return {
26421
26446
  type: "github",
26422
26447
  location,
26423
- name: repo,
26448
+ name: parsed.repo,
26424
26449
  ...branch && { branch }
26425
26450
  };
26426
26451
  }
@@ -26564,7 +26589,7 @@ async function addMarketplace(source, customName, branch) {
26564
26589
  marketplace: entry
26565
26590
  };
26566
26591
  }
26567
- async function removeMarketplace(name) {
26592
+ async function removeMarketplace(name, options2 = {}) {
26568
26593
  const registry = await loadRegistry();
26569
26594
  if (!registry.marketplaces[name]) {
26570
26595
  return {
@@ -26578,12 +26603,21 @@ async function removeMarketplace(name) {
26578
26603
  if (entry.source.type !== "local" && existsSync7(entry.path)) {
26579
26604
  await rm3(entry.path, { recursive: true, force: true });
26580
26605
  }
26581
- const { removeUserPluginsForMarketplace: removeUserPluginsForMarketplace2 } = await Promise.resolve().then(() => (init_user_workspace(), exports_user_workspace));
26582
- const removedUserPlugins = await removeUserPluginsForMarketplace2(name);
26606
+ if (options2.cascade) {
26607
+ const { removeUserPluginsForMarketplace: removeUserPluginsForMarketplace2 } = await Promise.resolve().then(() => (init_user_workspace(), exports_user_workspace));
26608
+ const removedUserPlugins = await removeUserPluginsForMarketplace2(name);
26609
+ return {
26610
+ success: true,
26611
+ marketplace: entry,
26612
+ removedUserPlugins
26613
+ };
26614
+ }
26615
+ const { getUserPluginsForMarketplace: getUserPluginsForMarketplace2 } = await Promise.resolve().then(() => (init_user_workspace(), exports_user_workspace));
26616
+ const retainedUserPlugins = await getUserPluginsForMarketplace2(name);
26583
26617
  return {
26584
26618
  success: true,
26585
26619
  marketplace: entry,
26586
- removedUserPlugins
26620
+ retainedUserPlugins
26587
26621
  };
26588
26622
  }
26589
26623
  async function listMarketplaces() {
@@ -26948,18 +26982,6 @@ async function ensureMarketplacesRegistered(plugins) {
26948
26982
  }
26949
26983
  return results;
26950
26984
  }
26951
- async function getMarketplaceVersion(marketplacePath) {
26952
- if (!existsSync7(marketplacePath)) {
26953
- return null;
26954
- }
26955
- try {
26956
- const git = esm_default(marketplacePath);
26957
- const log = await git.log({ maxCount: 1, format: { hash: "%h" } });
26958
- return log.latest?.hash || null;
26959
- } catch {
26960
- return null;
26961
- }
26962
- }
26963
26985
  var registeredSourceCache;
26964
26986
  var init_marketplace = __esm(() => {
26965
26987
  init_esm();
@@ -27508,7 +27530,8 @@ var init_sync_state = __esm(() => {
27508
27530
  version: exports_external.literal(1),
27509
27531
  lastSync: exports_external.string(),
27510
27532
  files: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())),
27511
- mcpServers: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional()
27533
+ mcpServers: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
27534
+ nativePlugins: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())).optional()
27512
27535
  });
27513
27536
  });
27514
27537
 
@@ -27543,7 +27566,8 @@ async function saveSyncState(workspacePath, data) {
27543
27566
  version: 1,
27544
27567
  lastSync: new Date().toISOString(),
27545
27568
  files: normalizedData.files,
27546
- ...normalizedData.mcpServers && { mcpServers: normalizedData.mcpServers }
27569
+ ...normalizedData.mcpServers && { mcpServers: normalizedData.mcpServers },
27570
+ ...normalizedData.nativePlugins && { nativePlugins: normalizedData.nativePlugins }
27547
27571
  };
27548
27572
  await mkdir7(dirname5(statePath), { recursive: true });
27549
27573
  await writeFile6(statePath, JSON.stringify(state, null, 2), "utf-8");
@@ -27560,6 +27584,11 @@ function getPreviouslySyncedMcpServers(state, scope) {
27560
27584
  }
27561
27585
  return state.mcpServers[scope] ?? [];
27562
27586
  }
27587
+ function getPreviouslySyncedNativePlugins(state, client) {
27588
+ if (!state?.nativePlugins)
27589
+ return [];
27590
+ return state.nativePlugins[client] ?? [];
27591
+ }
27563
27592
  var init_sync_state2 = __esm(() => {
27564
27593
  init_constants();
27565
27594
  init_sync_state();
@@ -27836,6 +27865,272 @@ var init_vscode_mcp = __esm(() => {
27836
27865
  import_json5 = __toESM(require_lib(), 1);
27837
27866
  });
27838
27867
 
27868
+ // src/core/native/types.ts
27869
+ import { spawn as spawn2 } from "node:child_process";
27870
+ function executeCommand(binary2, args, options2 = {}) {
27871
+ return new Promise((resolve9) => {
27872
+ const proc = spawn2(binary2, args, {
27873
+ cwd: options2.cwd,
27874
+ stdio: ["ignore", "pipe", "pipe"],
27875
+ env: { ...process.env }
27876
+ });
27877
+ let stdout = "";
27878
+ let stderr = "";
27879
+ proc.stdout.on("data", (data) => {
27880
+ stdout += data.toString();
27881
+ });
27882
+ proc.stderr.on("data", (data) => {
27883
+ stderr += data.toString();
27884
+ });
27885
+ let resolved = false;
27886
+ proc.on("close", (code) => {
27887
+ if (resolved)
27888
+ return;
27889
+ resolved = true;
27890
+ const trimmedStderr = stderr.trim();
27891
+ resolve9({
27892
+ success: code === 0,
27893
+ output: stdout.trim(),
27894
+ ...trimmedStderr && { error: trimmedStderr }
27895
+ });
27896
+ });
27897
+ proc.on("error", (err) => {
27898
+ if (resolved)
27899
+ return;
27900
+ resolved = true;
27901
+ resolve9({
27902
+ success: false,
27903
+ output: "",
27904
+ error: `Failed to execute ${binary2} CLI: ${err.message}`
27905
+ });
27906
+ });
27907
+ });
27908
+ }
27909
+ function mergeNativeSyncResults(results) {
27910
+ return results.reduce((acc, r) => ({
27911
+ marketplacesAdded: [...acc.marketplacesAdded, ...r.marketplacesAdded],
27912
+ pluginsInstalled: [...acc.pluginsInstalled, ...r.pluginsInstalled],
27913
+ pluginsFailed: [...acc.pluginsFailed, ...r.pluginsFailed],
27914
+ skipped: [...acc.skipped, ...r.skipped]
27915
+ }), { marketplacesAdded: [], pluginsInstalled: [], pluginsFailed: [], skipped: [] });
27916
+ }
27917
+ var init_types2 = () => {};
27918
+
27919
+ // src/core/native/claude.ts
27920
+ class ClaudeNativeClient {
27921
+ async isAvailable() {
27922
+ const result = await executeCommand("claude", ["--version"]);
27923
+ return result.success;
27924
+ }
27925
+ supportsScope(_scope) {
27926
+ return true;
27927
+ }
27928
+ toPluginSpec(allagentsSource) {
27929
+ const atIndex = allagentsSource.lastIndexOf("@");
27930
+ if (atIndex <= 0 || atIndex === allagentsSource.length - 1)
27931
+ return null;
27932
+ const pluginName = allagentsSource.slice(0, atIndex);
27933
+ const marketplacePart = allagentsSource.slice(atIndex + 1);
27934
+ if (marketplacePart.includes("/") && !marketplacePart.includes("://")) {
27935
+ const parts = marketplacePart.split("/");
27936
+ const repoName = parts[1];
27937
+ if (!repoName)
27938
+ return null;
27939
+ return `${pluginName}@${repoName}`;
27940
+ }
27941
+ return allagentsSource;
27942
+ }
27943
+ extractMarketplaceSource(pluginSpec) {
27944
+ const atIndex = pluginSpec.lastIndexOf("@");
27945
+ if (atIndex <= 0 || atIndex === pluginSpec.length - 1)
27946
+ return null;
27947
+ const marketplacePart = pluginSpec.slice(atIndex + 1);
27948
+ if (marketplacePart.includes("/") && !marketplacePart.includes("://")) {
27949
+ return marketplacePart;
27950
+ }
27951
+ return null;
27952
+ }
27953
+ addMarketplace(source, options2) {
27954
+ return executeCommand("claude", ["plugin", "marketplace", "add", source], options2);
27955
+ }
27956
+ installPlugin(spec, scope, options2) {
27957
+ return executeCommand("claude", ["plugin", "install", spec, "--scope", scope], options2);
27958
+ }
27959
+ uninstallPlugin(spec, scope, options2) {
27960
+ return executeCommand("claude", ["plugin", "uninstall", spec, "--scope", scope], options2);
27961
+ }
27962
+ async syncPlugins(plugins, scope = "project", options2 = {}) {
27963
+ const result = {
27964
+ marketplacesAdded: [],
27965
+ pluginsInstalled: [],
27966
+ pluginsFailed: [],
27967
+ skipped: []
27968
+ };
27969
+ if (options2.dryRun) {
27970
+ for (const plugin of plugins) {
27971
+ const spec = this.toPluginSpec(plugin);
27972
+ if (spec) {
27973
+ result.pluginsInstalled.push(spec);
27974
+ } else {
27975
+ result.skipped.push(plugin);
27976
+ }
27977
+ }
27978
+ return result;
27979
+ }
27980
+ const marketplaceSources = new Set;
27981
+ for (const plugin of plugins) {
27982
+ const source = this.extractMarketplaceSource(plugin);
27983
+ if (source)
27984
+ marketplaceSources.add(source);
27985
+ }
27986
+ for (const source of marketplaceSources) {
27987
+ const addResult = await this.addMarketplace(source, options2);
27988
+ if (addResult.success) {
27989
+ result.marketplacesAdded.push(source);
27990
+ }
27991
+ }
27992
+ for (const plugin of plugins) {
27993
+ const spec = this.toPluginSpec(plugin);
27994
+ if (!spec) {
27995
+ result.skipped.push(plugin);
27996
+ continue;
27997
+ }
27998
+ const installResult = await this.installPlugin(spec, scope, options2);
27999
+ if (installResult.success) {
28000
+ result.pluginsInstalled.push(spec);
28001
+ } else {
28002
+ result.pluginsFailed.push({
28003
+ plugin: spec,
28004
+ error: installResult.error ?? "Unknown error"
28005
+ });
28006
+ }
28007
+ }
28008
+ return result;
28009
+ }
28010
+ }
28011
+ var init_claude = __esm(() => {
28012
+ init_types2();
28013
+ });
28014
+
28015
+ // src/core/native/copilot.ts
28016
+ class CopilotNativeClient {
28017
+ async isAvailable() {
28018
+ const result = await executeCommand("copilot", ["--version"]);
28019
+ return result.success;
28020
+ }
28021
+ supportsScope(scope) {
28022
+ return scope === "user";
28023
+ }
28024
+ toPluginSpec(allagentsSource) {
28025
+ const atIndex = allagentsSource.lastIndexOf("@");
28026
+ if (atIndex <= 0 || atIndex === allagentsSource.length - 1)
28027
+ return null;
28028
+ const marketplacePart = allagentsSource.slice(atIndex + 1);
28029
+ if (marketplacePart.includes("://"))
28030
+ return null;
28031
+ if (marketplacePart.includes("/")) {
28032
+ const parts = marketplacePart.split("/");
28033
+ if (!parts[1])
28034
+ return null;
28035
+ }
28036
+ return allagentsSource;
28037
+ }
28038
+ extractMarketplaceSource(pluginSpec) {
28039
+ const atIndex = pluginSpec.lastIndexOf("@");
28040
+ if (atIndex <= 0 || atIndex === pluginSpec.length - 1)
28041
+ return null;
28042
+ const marketplacePart = pluginSpec.slice(atIndex + 1);
28043
+ if (marketplacePart.includes("/") && !marketplacePart.includes("://")) {
28044
+ return marketplacePart;
28045
+ }
28046
+ return null;
28047
+ }
28048
+ addMarketplace(source, options2) {
28049
+ return executeCommand("copilot", ["plugin", "marketplace", "add", source], options2);
28050
+ }
28051
+ installPlugin(spec, _scope, options2) {
28052
+ return executeCommand("copilot", ["plugin", "install", spec], options2);
28053
+ }
28054
+ uninstallPlugin(spec, _scope, options2) {
28055
+ return executeCommand("copilot", ["plugin", "uninstall", spec], options2);
28056
+ }
28057
+ async syncPlugins(plugins, scope = "user", options2 = {}) {
28058
+ const result = {
28059
+ marketplacesAdded: [],
28060
+ pluginsInstalled: [],
28061
+ pluginsFailed: [],
28062
+ skipped: []
28063
+ };
28064
+ if (options2.dryRun) {
28065
+ for (const plugin of plugins) {
28066
+ const spec = this.toPluginSpec(plugin);
28067
+ if (spec) {
28068
+ result.pluginsInstalled.push(spec);
28069
+ } else {
28070
+ result.skipped.push(plugin);
28071
+ }
28072
+ }
28073
+ return result;
28074
+ }
28075
+ const marketplaceSources = new Set;
28076
+ for (const plugin of plugins) {
28077
+ const source = this.extractMarketplaceSource(plugin);
28078
+ if (source)
28079
+ marketplaceSources.add(source);
28080
+ }
28081
+ for (const source of marketplaceSources) {
28082
+ const addResult = await this.addMarketplace(source, options2);
28083
+ if (addResult.success) {
28084
+ result.marketplacesAdded.push(source);
28085
+ }
28086
+ }
28087
+ for (const plugin of plugins) {
28088
+ const spec = this.toPluginSpec(plugin);
28089
+ if (!spec) {
28090
+ result.skipped.push(plugin);
28091
+ continue;
28092
+ }
28093
+ const installResult = await this.installPlugin(spec, scope, options2);
28094
+ if (installResult.success) {
28095
+ result.pluginsInstalled.push(spec);
28096
+ } else {
28097
+ result.pluginsFailed.push({
28098
+ plugin: spec,
28099
+ error: installResult.error ?? "Unknown error"
28100
+ });
28101
+ }
28102
+ }
28103
+ return result;
28104
+ }
28105
+ }
28106
+ var init_copilot = __esm(() => {
28107
+ init_types2();
28108
+ });
28109
+
28110
+ // src/core/native/registry.ts
28111
+ function getNativeClient(client) {
28112
+ switch (client) {
28113
+ case "claude":
28114
+ return new ClaudeNativeClient;
28115
+ case "copilot":
28116
+ return new CopilotNativeClient;
28117
+ default:
28118
+ return null;
28119
+ }
28120
+ }
28121
+ var init_registry = __esm(() => {
28122
+ init_claude();
28123
+ init_copilot();
28124
+ });
28125
+
28126
+ // src/core/native/index.ts
28127
+ var init_native = __esm(() => {
28128
+ init_types2();
28129
+ init_claude();
28130
+ init_copilot();
28131
+ init_registry();
28132
+ });
28133
+
27839
28134
  // src/core/sync.ts
27840
28135
  import { existsSync as existsSync12, readFileSync as readFileSync2, writeFileSync as writeFileSync2, lstatSync } from "node:fs";
27841
28136
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
@@ -27864,6 +28159,12 @@ function mergeSyncResults(a, b) {
27864
28159
  const warnings = [...a.warnings || [], ...b.warnings || []];
27865
28160
  const purgedPaths = [...a.purgedPaths || [], ...b.purgedPaths || []];
27866
28161
  const mcpResult = a.mcpResult ?? b.mcpResult;
28162
+ const nativeResult = a.nativeResult && b.nativeResult ? {
28163
+ marketplacesAdded: [...a.nativeResult.marketplacesAdded, ...b.nativeResult.marketplacesAdded],
28164
+ pluginsInstalled: [...a.nativeResult.pluginsInstalled, ...b.nativeResult.pluginsInstalled],
28165
+ pluginsFailed: [...a.nativeResult.pluginsFailed, ...b.nativeResult.pluginsFailed],
28166
+ skipped: [...a.nativeResult.skipped, ...b.nativeResult.skipped]
28167
+ } : a.nativeResult ?? b.nativeResult;
27867
28168
  return {
27868
28169
  success: a.success && b.success,
27869
28170
  pluginResults: [...a.pluginResults, ...b.pluginResults],
@@ -27873,11 +28174,13 @@ function mergeSyncResults(a, b) {
27873
28174
  totalGenerated: a.totalGenerated + b.totalGenerated,
27874
28175
  ...warnings.length > 0 && { warnings },
27875
28176
  ...purgedPaths.length > 0 && { purgedPaths },
27876
- ...mcpResult && { mcpResult }
28177
+ ...mcpResult && { mcpResult },
28178
+ ...nativeResult && { nativeResult }
27877
28179
  };
27878
28180
  }
27879
- function collectSyncClients(workspaceClients, plans) {
27880
- return [...new Set([...workspaceClients, ...plans.flatMap((plan) => plan.clients)])];
28181
+ function collectSyncClients(clientEntries, plans) {
28182
+ const workspaceClientTypes = getClientTypes(clientEntries);
28183
+ return [...new Set([...workspaceClientTypes, ...plans.flatMap((plan) => [...plan.clients, ...plan.nativeClients])])];
27881
28184
  }
27882
28185
  async function selectivePurgeWorkspace(workspacePath, state, clients, options2) {
27883
28186
  if (!state) {
@@ -28091,6 +28394,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28091
28394
  resolved: "",
28092
28395
  success: false,
28093
28396
  clients: [],
28397
+ nativeClients: [],
28094
28398
  error: resolved.error || "Unknown error"
28095
28399
  };
28096
28400
  }
@@ -28099,6 +28403,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28099
28403
  resolved: resolved.path ?? "",
28100
28404
  success: true,
28101
28405
  clients: [],
28406
+ nativeClients: [],
28102
28407
  ...resolved.pluginName && { pluginName: resolved.pluginName }
28103
28408
  };
28104
28409
  }
@@ -28114,6 +28419,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28114
28419
  resolved: "",
28115
28420
  success: false,
28116
28421
  clients: [],
28422
+ nativeClients: [],
28117
28423
  ...fetchResult.error && { error: fetchResult.error }
28118
28424
  };
28119
28425
  }
@@ -28122,7 +28428,8 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28122
28428
  plugin: pluginSource,
28123
28429
  resolved: resolvedPath2,
28124
28430
  success: true,
28125
- clients: []
28431
+ clients: [],
28432
+ nativeClients: []
28126
28433
  };
28127
28434
  }
28128
28435
  const resolvedPath = resolve9(workspacePath, pluginSource);
@@ -28132,6 +28439,7 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28132
28439
  resolved: resolvedPath,
28133
28440
  success: false,
28134
28441
  clients: [],
28442
+ nativeClients: [],
28135
28443
  error: `Plugin not found at ${resolvedPath}`
28136
28444
  };
28137
28445
  }
@@ -28139,22 +28447,43 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
28139
28447
  plugin: pluginSource,
28140
28448
  resolved: resolvedPath,
28141
28449
  success: true,
28142
- clients: []
28450
+ clients: [],
28451
+ nativeClients: []
28143
28452
  };
28144
28453
  }
28145
- function buildPluginSyncPlans(plugins, workspaceClients, selectedClients) {
28454
+ function buildPluginSyncPlans(plugins, clientEntries, scope, selectedClients) {
28455
+ const warnings = [];
28146
28456
  const selected = selectedClients ? new Set(selectedClients) : null;
28147
- return plugins.map((plugin) => {
28457
+ const workspaceClientTypes = getClientTypes(clientEntries);
28458
+ const plans = plugins.map((plugin) => {
28148
28459
  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 };
28460
+ const pluginClientTypes = getPluginClients(plugin) ?? workspaceClientTypes;
28461
+ const effectiveClients = selected ? pluginClientTypes.filter((c) => selected.has(c)) : pluginClientTypes;
28462
+ const fileClients = [];
28463
+ const nativeClients = [];
28464
+ for (const client of effectiveClients) {
28465
+ const clientEntry = normalizeClientEntry(clientEntries.find((e) => (typeof e === "string" ? e : e.name) === client) ?? client);
28466
+ const mode = resolveInstallMode(plugin, clientEntry);
28467
+ const nativeClient = mode === "native" ? getNativeClient(client) : null;
28468
+ if (nativeClient && nativeClient.toPluginSpec(source) !== null) {
28469
+ if (nativeClient.supportsScope(scope)) {
28470
+ nativeClients.push(client);
28471
+ } else {
28472
+ fileClients.push(client);
28473
+ warnings.push(`${client} native install only supports user scope, falling back to file copy`);
28474
+ }
28475
+ } else {
28476
+ fileClients.push(client);
28477
+ }
28478
+ }
28479
+ return { source, clients: fileClients, nativeClients };
28152
28480
  });
28481
+ return { plans, warnings };
28153
28482
  }
28154
28483
  async function validateAllPlugins(plans, workspacePath, offline) {
28155
- return Promise.all(plans.map(async ({ source, clients }) => {
28484
+ return Promise.all(plans.map(async ({ source, clients, nativeClients }) => {
28156
28485
  const validated = await validatePlugin(source, workspacePath, offline);
28157
- return { ...validated, clients };
28486
+ return { ...validated, clients, nativeClients };
28158
28487
  }));
28159
28488
  }
28160
28489
  async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryRun, skillNameMap, clientMappings, syncMode = "symlink") {
@@ -28296,9 +28625,13 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28296
28625
  };
28297
28626
  }
28298
28627
  const hasRepositories = (config.repositories?.length ?? 0) > 0;
28299
- const workspaceClients = options2.clients ? config.clients.filter((c) => options2.clients?.includes(c)) : config.clients;
28628
+ const configClientTypes = getClientTypes(config.clients);
28629
+ const workspaceClients = options2.clients ? config.clients.filter((c) => {
28630
+ const name = typeof c === "string" ? c : c.name;
28631
+ return options2.clients?.includes(name);
28632
+ }) : config.clients;
28300
28633
  if (options2.clients) {
28301
- const availableClients = new Set(config.clients);
28634
+ const availableClients = new Set(configClientTypes);
28302
28635
  for (const plugin of config.plugins) {
28303
28636
  for (const client of getPluginClients(plugin) ?? []) {
28304
28637
  availableClients.add(client);
@@ -28319,10 +28652,11 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28319
28652
  }
28320
28653
  }
28321
28654
  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);
28655
+ const { plans: pluginPlans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, config.clients, "project", selectedClients);
28656
+ const filteredPlans = pluginPlans.filter((plan) => plan.clients.length > 0 || plan.nativeClients.length > 0);
28657
+ const syncClients = collectSyncClients(workspaceClients, filteredPlans);
28658
+ await ensureMarketplacesRegistered(filteredPlans.map((plan) => plan.source));
28659
+ const validatedPlugins = await validateAllPlugins(filteredPlans, workspacePath, offline);
28326
28660
  let validatedWorkspaceSource = null;
28327
28661
  if (config.workspace?.source) {
28328
28662
  const sourceBasePath = workspaceSourceBase ?? workspacePath;
@@ -28341,8 +28675,11 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
28341
28675
  }
28342
28676
  const failedValidations = validatedPlugins.filter((v) => !v.success);
28343
28677
  const validPlugins = validatedPlugins.filter((v) => v.success);
28344
- const warnings = failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`);
28345
- if (validPlugins.length === 0 && pluginPlans.length > 0) {
28678
+ const warnings = [
28679
+ ...planWarnings,
28680
+ ...failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`)
28681
+ ];
28682
+ if (validPlugins.length === 0 && filteredPlans.length > 0) {
28346
28683
  return {
28347
28684
  success: false,
28348
28685
  pluginResults: [],
@@ -28374,6 +28711,67 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28374
28711
  const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
28375
28712
  return copyValidatedPlugin(validatedPlugin, workspacePath, validatedPlugin.clients, dryRun, skillNameMap, undefined, syncMode);
28376
28713
  }));
28714
+ let nativeResult;
28715
+ const nativePluginsByClient = new Map;
28716
+ for (const vp of validPlugins) {
28717
+ for (const client of vp.nativeClients) {
28718
+ const existing = nativePluginsByClient.get(client) ?? [];
28719
+ existing.push(vp.plugin);
28720
+ nativePluginsByClient.set(client, existing);
28721
+ }
28722
+ }
28723
+ const previousNativeClients = previousState?.nativePlugins ? Object.keys(previousState.nativePlugins).filter((c) => (previousState.nativePlugins?.[c]?.length ?? 0) > 0) : [];
28724
+ const hasNativeWork = nativePluginsByClient.size > 0 || previousNativeClients.length > 0;
28725
+ if (hasNativeWork && !dryRun) {
28726
+ const allClients = new Set([...nativePluginsByClient.keys(), ...previousNativeClients]);
28727
+ const perClientResults = [];
28728
+ for (const clientType of allClients) {
28729
+ const nativeClient = getNativeClient(clientType);
28730
+ if (!nativeClient) {
28731
+ const sources = nativePluginsByClient.get(clientType);
28732
+ if (sources && sources.length > 0) {
28733
+ warnings.push(`Native install: no native client for ${clientType}, skipping`);
28734
+ }
28735
+ continue;
28736
+ }
28737
+ const cliAvailable = await nativeClient.isAvailable();
28738
+ if (!cliAvailable) {
28739
+ const sources = nativePluginsByClient.get(clientType);
28740
+ if (sources && sources.length > 0) {
28741
+ warnings.push(`Native install: ${clientType} CLI not found, skipping native plugin installation`);
28742
+ }
28743
+ continue;
28744
+ }
28745
+ const currentSources = nativePluginsByClient.get(clientType) ?? [];
28746
+ const currentSpecs = currentSources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null);
28747
+ const previousPlugins = getPreviouslySyncedNativePlugins(previousState, clientType);
28748
+ const removed = previousPlugins.filter((p) => !currentSpecs.includes(p));
28749
+ for (const plugin of removed) {
28750
+ try {
28751
+ await nativeClient.uninstallPlugin(plugin, "project", { cwd: workspacePath });
28752
+ } catch (err) {
28753
+ warnings.push(`Native uninstall failed for ${plugin}: ${err instanceof Error ? err.message : String(err)}`);
28754
+ }
28755
+ }
28756
+ if (currentSources.length > 0) {
28757
+ perClientResults.push(await nativeClient.syncPlugins(currentSources, "project", { cwd: workspacePath }));
28758
+ }
28759
+ }
28760
+ if (perClientResults.length > 0) {
28761
+ nativeResult = mergeNativeSyncResults(perClientResults);
28762
+ }
28763
+ } else if (nativePluginsByClient.size > 0 && dryRun) {
28764
+ const perClientResults = [];
28765
+ for (const [clientType, sources] of nativePluginsByClient) {
28766
+ const nativeClient = getNativeClient(clientType);
28767
+ if (nativeClient && sources.length > 0) {
28768
+ perClientResults.push(await nativeClient.syncPlugins(sources, "project", { cwd: workspacePath, dryRun: true }));
28769
+ }
28770
+ }
28771
+ if (perClientResults.length > 0) {
28772
+ nativeResult = mergeNativeSyncResults(perClientResults);
28773
+ }
28774
+ }
28377
28775
  let workspaceFileResults = [];
28378
28776
  if (config.workspace) {
28379
28777
  const sourcePath = validatedWorkspaceSource?.resolved;
@@ -28484,7 +28882,28 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
28484
28882
  }
28485
28883
  }
28486
28884
  }
28487
- await saveSyncState(workspacePath, syncedFiles);
28885
+ const nativePluginsState = {};
28886
+ const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
28887
+ for (const [client, sources] of nativePluginsByClient) {
28888
+ const nativeClient = getNativeClient(client);
28889
+ if (!nativeClient)
28890
+ continue;
28891
+ const clientSpecs = sources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null && installedSet.has(s));
28892
+ if (clientSpecs.length > 0) {
28893
+ nativePluginsState[client] = clientSpecs;
28894
+ }
28895
+ }
28896
+ if (options2.clients && previousState?.nativePlugins) {
28897
+ for (const [client, plugins] of Object.entries(previousState.nativePlugins)) {
28898
+ if (!syncClients.includes(client)) {
28899
+ nativePluginsState[client] = plugins;
28900
+ }
28901
+ }
28902
+ }
28903
+ await saveSyncState(workspacePath, {
28904
+ files: syncedFiles,
28905
+ ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState }
28906
+ });
28488
28907
  }
28489
28908
  return {
28490
28909
  success: !hasFailures,
@@ -28494,7 +28913,8 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
28494
28913
  totalSkipped,
28495
28914
  totalGenerated,
28496
28915
  purgedPaths,
28497
- ...warnings.length > 0 && { warnings }
28916
+ ...warnings.length > 0 && { warnings },
28917
+ ...nativeResult && { nativeResult }
28498
28918
  };
28499
28919
  }
28500
28920
  async function syncUserWorkspace(options2 = {}) {
@@ -28512,13 +28932,17 @@ async function syncUserWorkspace(options2 = {}) {
28512
28932
  }
28513
28933
  const workspaceClients = config.clients;
28514
28934
  const { offline = false, dryRun = false, force = false } = options2;
28515
- const pluginPlans = buildPluginSyncPlans(config.plugins, workspaceClients).filter((plan) => plan.clients.length > 0);
28935
+ const { plans: allPluginPlans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, workspaceClients, "user");
28936
+ const pluginPlans = allPluginPlans.filter((plan) => plan.clients.length > 0 || plan.nativeClients.length > 0);
28516
28937
  const syncClients = collectSyncClients(workspaceClients, pluginPlans);
28517
28938
  await ensureMarketplacesRegistered(pluginPlans.map((plan) => plan.source));
28518
28939
  const validatedPlugins = await validateAllPlugins(pluginPlans, homeDir, offline);
28519
28940
  const failedValidations = validatedPlugins.filter((v) => !v.success);
28520
28941
  const validPlugins = validatedPlugins.filter((v) => v.success);
28521
- const warnings = failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`);
28942
+ const warnings = [
28943
+ ...planWarnings,
28944
+ ...failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`)
28945
+ ];
28522
28946
  if (validPlugins.length === 0 && pluginPlans.length > 0) {
28523
28947
  return {
28524
28948
  success: false,
@@ -28575,12 +28999,85 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28575
28999
  warnings.push(...mcpResult.warnings);
28576
29000
  }
28577
29001
  }
29002
+ let nativeResult;
29003
+ const nativePluginsByClient = new Map;
29004
+ for (const vp of validPlugins) {
29005
+ for (const client of vp.nativeClients) {
29006
+ const existing = nativePluginsByClient.get(client) ?? [];
29007
+ existing.push(vp.plugin);
29008
+ nativePluginsByClient.set(client, existing);
29009
+ }
29010
+ }
29011
+ const previousNativeClients = previousState?.nativePlugins ? Object.keys(previousState.nativePlugins).filter((c) => (previousState.nativePlugins?.[c]?.length ?? 0) > 0) : [];
29012
+ const hasNativeWork = nativePluginsByClient.size > 0 || previousNativeClients.length > 0;
29013
+ if (hasNativeWork && !dryRun) {
29014
+ const allClients = new Set([...nativePluginsByClient.keys(), ...previousNativeClients]);
29015
+ const perClientResults = [];
29016
+ for (const clientType of allClients) {
29017
+ const nativeClient = getNativeClient(clientType);
29018
+ if (!nativeClient) {
29019
+ const sources = nativePluginsByClient.get(clientType);
29020
+ if (sources && sources.length > 0) {
29021
+ warnings.push(`Native install: no native client for ${clientType}, skipping`);
29022
+ }
29023
+ continue;
29024
+ }
29025
+ const cliAvailable = await nativeClient.isAvailable();
29026
+ if (!cliAvailable) {
29027
+ const sources = nativePluginsByClient.get(clientType);
29028
+ if (sources && sources.length > 0) {
29029
+ warnings.push(`Native install: ${clientType} CLI not found, skipping native plugin installation`);
29030
+ }
29031
+ continue;
29032
+ }
29033
+ const currentSources = nativePluginsByClient.get(clientType) ?? [];
29034
+ const currentSpecs = currentSources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null);
29035
+ const previousPlugins = getPreviouslySyncedNativePlugins(previousState, clientType);
29036
+ const removed = previousPlugins.filter((p) => !currentSpecs.includes(p));
29037
+ for (const plugin of removed) {
29038
+ try {
29039
+ await nativeClient.uninstallPlugin(plugin, "user");
29040
+ } catch (err) {
29041
+ warnings.push(`Native uninstall failed for ${plugin}: ${err instanceof Error ? err.message : String(err)}`);
29042
+ }
29043
+ }
29044
+ if (currentSources.length > 0) {
29045
+ perClientResults.push(await nativeClient.syncPlugins(currentSources, "user"));
29046
+ }
29047
+ }
29048
+ if (perClientResults.length > 0) {
29049
+ nativeResult = mergeNativeSyncResults(perClientResults);
29050
+ }
29051
+ } else if (nativePluginsByClient.size > 0 && dryRun) {
29052
+ const perClientResults = [];
29053
+ for (const [clientType, sources] of nativePluginsByClient) {
29054
+ const nativeClient = getNativeClient(clientType);
29055
+ if (nativeClient && sources.length > 0) {
29056
+ perClientResults.push(await nativeClient.syncPlugins(sources, "user", { dryRun: true }));
29057
+ }
29058
+ }
29059
+ if (perClientResults.length > 0) {
29060
+ nativeResult = mergeNativeSyncResults(perClientResults);
29061
+ }
29062
+ }
28578
29063
  if (!dryRun) {
28579
29064
  const allCopyResults = pluginResults.flatMap((r) => r.copyResults);
28580
29065
  const syncedFiles = collectSyncedPaths(allCopyResults, homeDir, syncClients, USER_CLIENT_MAPPINGS);
29066
+ const nativePluginsState = {};
29067
+ const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
29068
+ for (const [client, sources] of nativePluginsByClient) {
29069
+ const nativeClient = getNativeClient(client);
29070
+ if (!nativeClient)
29071
+ continue;
29072
+ const clientSpecs = sources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null && installedSet.has(s));
29073
+ if (clientSpecs.length > 0) {
29074
+ nativePluginsState[client] = clientSpecs;
29075
+ }
29076
+ }
28581
29077
  await saveSyncState(homeDir, {
28582
29078
  files: syncedFiles,
28583
- ...mcpResult && { mcpServers: { vscode: mcpResult.trackedServers } }
29079
+ ...mcpResult && { mcpServers: { vscode: mcpResult.trackedServers } },
29080
+ ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState }
28584
29081
  });
28585
29082
  }
28586
29083
  return {
@@ -28591,7 +29088,8 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
28591
29088
  totalSkipped,
28592
29089
  totalGenerated,
28593
29090
  ...warnings.length > 0 && { warnings },
28594
- ...mcpResult && { mcpResult }
29091
+ ...mcpResult && { mcpResult },
29092
+ ...nativeResult && { nativeResult }
28595
29093
  };
28596
29094
  }
28597
29095
  var import_json52, VSCODE_TEMPLATE_FILE = "template.code-workspace";
@@ -28610,6 +29108,7 @@ var init_sync = __esm(() => {
28610
29108
  init_user_workspace();
28611
29109
  init_vscode_workspace();
28612
29110
  init_vscode_mcp();
29111
+ init_native();
28613
29112
  import_json52 = __toESM(require_lib(), 1);
28614
29113
  });
28615
29114
 
@@ -28973,7 +29472,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
28973
29472
  success: true,
28974
29473
  plugins,
28975
29474
  userPlugins,
28976
- clients: config.clients
29475
+ clients: getClientTypes(config.clients)
28977
29476
  };
28978
29477
  } catch (error) {
28979
29478
  return {
@@ -29068,6 +29567,22 @@ function formatMcpResult(mcpResult) {
29068
29567
  }
29069
29568
  return lines;
29070
29569
  }
29570
+ function formatNativeResult(nativeResult) {
29571
+ const lines = [];
29572
+ if (nativeResult.marketplacesAdded.length > 0) {
29573
+ lines.push(`Marketplaces registered: ${nativeResult.marketplacesAdded.join(", ")}`);
29574
+ }
29575
+ for (const plugin of nativeResult.pluginsInstalled) {
29576
+ lines.push(` + ${plugin} (installed via native CLI)`);
29577
+ }
29578
+ for (const { plugin, error } of nativeResult.pluginsFailed) {
29579
+ lines.push(` ✗ ${plugin}: ${error}`);
29580
+ }
29581
+ for (const plugin of nativeResult.skipped) {
29582
+ lines.push(` ⊘ ${plugin} (skipped — not a marketplace plugin)`);
29583
+ }
29584
+ return lines;
29585
+ }
29071
29586
  function buildSyncData(result) {
29072
29587
  return {
29073
29588
  copied: result.totalCopied,
@@ -29096,6 +29611,14 @@ function buildSyncData(result) {
29096
29611
  removedServers: result.mcpResult.removedServers,
29097
29612
  ...result.mcpResult.configPath && { configPath: result.mcpResult.configPath }
29098
29613
  }
29614
+ },
29615
+ ...result.nativeResult && {
29616
+ nativePlugins: {
29617
+ installed: result.nativeResult.pluginsInstalled,
29618
+ failed: result.nativeResult.pluginsFailed,
29619
+ skipped: result.nativeResult.skipped,
29620
+ marketplacesAdded: result.nativeResult.marketplacesAdded
29621
+ }
29099
29622
  }
29100
29623
  };
29101
29624
  }
@@ -29607,7 +30130,7 @@ var require_cross_spawn = __commonJS((exports, module) => {
29607
30130
  var cp2 = __require("child_process");
29608
30131
  var parse2 = require_parse5();
29609
30132
  var enoent = require_enoent();
29610
- function spawn2(command4, args, options2) {
30133
+ function spawn3(command4, args, options2) {
29611
30134
  const parsed = parse2(command4, args, options2);
29612
30135
  const spawned = cp2.spawn(parsed.command, parsed.args, parsed.options);
29613
30136
  enoent.hookChildProcess(spawned, parsed);
@@ -29619,8 +30142,8 @@ var require_cross_spawn = __commonJS((exports, module) => {
29619
30142
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
29620
30143
  return result;
29621
30144
  }
29622
- module.exports = spawn2;
29623
- module.exports.spawn = spawn2;
30145
+ module.exports = spawn3;
30146
+ module.exports.spawn = spawn3;
29624
30147
  module.exports.sync = spawnSync;
29625
30148
  module.exports._parse = parse2;
29626
30149
  module.exports._enoent = enoent;
@@ -29668,7 +30191,7 @@ var package_default;
29668
30191
  var init_package = __esm(() => {
29669
30192
  package_default = {
29670
30193
  name: "allagents",
29671
- version: "0.24.1",
30194
+ version: "0.25.0-next.1",
29672
30195
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
29673
30196
  type: "module",
29674
30197
  bin: {
@@ -29694,6 +30217,7 @@ var init_package = __esm(() => {
29694
30217
  "check:fix": "biome check --write src",
29695
30218
  prepare: "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
29696
30219
  release: "bun run scripts/release.ts",
30220
+ "release:next": "bun run scripts/release.ts next",
29697
30221
  "publish:next": "bun run build && bun publish --tag next"
29698
30222
  },
29699
30223
  keywords: [
@@ -29740,7 +30264,7 @@ var init_package = __esm(() => {
29740
30264
  // src/cli/update-check.ts
29741
30265
  import { readFile as readFile14 } from "node:fs/promises";
29742
30266
  import { join as join23 } from "node:path";
29743
- import { spawn as spawn2 } from "node:child_process";
30267
+ import { spawn as spawn3 } from "node:child_process";
29744
30268
  async function getCachedUpdateInfo(path3) {
29745
30269
  const filePath = path3 ?? join23(getHomeDir(), CONFIG_DIR, CACHE_FILE);
29746
30270
  try {
@@ -29804,7 +30328,7 @@ function backgroundUpdateCheck() {
29804
30328
  }).on('error', () => process.exit()).on('timeout', function() { this.destroy(); process.exit(); });
29805
30329
  `;
29806
30330
  try {
29807
- const child = spawn2(process.execPath, ["-e", script], {
30331
+ const child = spawn3(process.execPath, ["-e", script], {
29808
30332
  detached: true,
29809
30333
  stdio: "ignore",
29810
30334
  windowsHide: true
@@ -31704,6 +32228,9 @@ async function runSync(context) {
31704
32228
  const lines = result.pluginResults.map((pr) => `${pr.success ? "✓" : "✗"} ${pr.plugin}`);
31705
32229
  lines.push("");
31706
32230
  lines.push(`Copied: ${result.totalCopied} Failed: ${result.totalFailed} Skipped: ${result.totalSkipped}`);
32231
+ if (result.nativeResult) {
32232
+ lines.push(...formatNativeResult(result.nativeResult));
32233
+ }
31707
32234
  kt2(lines.join(`
31708
32235
  `), "Project Sync");
31709
32236
  }
@@ -31721,6 +32248,9 @@ async function runSync(context) {
31721
32248
  if (userResult.mcpResult) {
31722
32249
  lines.push(...formatMcpResult(userResult.mcpResult));
31723
32250
  }
32251
+ if (userResult.nativeResult) {
32252
+ lines.push(...formatNativeResult(userResult.nativeResult));
32253
+ }
31724
32254
  kt2(lines.join(`
31725
32255
  `), "User Sync");
31726
32256
  }
@@ -32309,10 +32839,29 @@ async function runMarketplaceDetail(marketplaceName, context, cache2) {
32309
32839
  if (Ct(confirmed) || !confirmed) {
32310
32840
  continue;
32311
32841
  }
32842
+ const linkedPlugins = await getUserPluginsForMarketplace(marketplaceName);
32843
+ let cascade = false;
32844
+ if (linkedPlugins.length > 0) {
32845
+ const pluginAction = await select({
32846
+ message: `${linkedPlugins.length} plugin(s) still reference this marketplace:
32847
+ ${linkedPlugins.map((pl) => ` - ${pl}`).join(`
32848
+ `)}
32849
+
32850
+ What would you like to do with them?`,
32851
+ options: [
32852
+ { value: "keep", label: "Keep plugins (can be removed later)" },
32853
+ { value: "remove", label: "Remove plugins from config" }
32854
+ ]
32855
+ });
32856
+ if (Ct(pluginAction)) {
32857
+ continue;
32858
+ }
32859
+ cascade = pluginAction === "remove";
32860
+ }
32312
32861
  try {
32313
32862
  const s = Ie();
32314
32863
  s.start("Removing marketplace...");
32315
- const result = await removeMarketplace(marketplaceName);
32864
+ const result = await removeMarketplace(marketplaceName, { cascade });
32316
32865
  s.stop(result.success ? "Marketplace removed" : "Failed to remove marketplace");
32317
32866
  if (!result.success) {
32318
32867
  kt2(result.error ?? "Unknown error", "Error");
@@ -32452,7 +33001,7 @@ async function runManageClients(context, cache2) {
32452
33001
  currentClients = status.clients ?? [];
32453
33002
  } else {
32454
33003
  const userConfig = await getUserWorkspaceConfig();
32455
- currentClients = userConfig?.clients ?? [];
33004
+ currentClients = userConfig?.clients ? getClientTypes(userConfig.clients) : [];
32456
33005
  }
32457
33006
  const allClients = ClientTypeSchema.options;
32458
33007
  const selectedClients = await multiselect3({
@@ -33183,6 +33732,16 @@ Warnings:`);
33183
33732
  }
33184
33733
  }
33185
33734
  }
33735
+ if (result.nativeResult) {
33736
+ const nativeLines = formatNativeResult(result.nativeResult);
33737
+ if (nativeLines.length > 0) {
33738
+ console.log(`
33739
+ native:`);
33740
+ for (const line of nativeLines) {
33741
+ console.log(line);
33742
+ }
33743
+ }
33744
+ }
33186
33745
  console.log(`
33187
33746
  Sync complete${dryRun ? " (dry run)" : ""}:`);
33188
33747
  console.log(` Total ${dryRun ? "would copy" : "copied"}: ${result.totalCopied}`);
@@ -33576,20 +34135,35 @@ var marketplaceUpdateMeta = {
33576
34135
  failed: "number"
33577
34136
  }
33578
34137
  };
33579
- var pluginListMeta = {
33580
- command: "plugin list",
33581
- description: "List available plugins from registered marketplaces",
33582
- whenToUse: "To browse available plugins before installing one into your workspace",
34138
+ var marketplaceBrowseMeta = {
34139
+ command: "plugin marketplace browse",
34140
+ description: "Browse available plugins in a marketplace",
34141
+ whenToUse: "To discover and browse available plugins in a specific marketplace before installing",
33583
34142
  examples: [
33584
- "allagents plugin list",
33585
- "allagents plugin list official"
34143
+ "allagents plugin marketplace browse official",
34144
+ "allagents plugin marketplace browse superpowers"
33586
34145
  ],
33587
- expectedOutput: "Lists plugins grouped by marketplace with install-ready names (plugin@marketplace). Shows total count.",
34146
+ expectedOutput: "Lists all plugins in the marketplace with descriptions and install status. Shows total count.",
33588
34147
  positionals: [
33589
- { name: "marketplace", type: "string", required: false, description: "Filter plugins by marketplace name" }
34148
+ { name: "name", type: "string", required: true, description: "Name of the marketplace to browse" }
34149
+ ],
34150
+ outputSchema: {
34151
+ marketplace: "string",
34152
+ plugins: [{ name: "string", description: "string | null", installed: "boolean", scope: "string | null" }],
34153
+ total: "number",
34154
+ installed: "number"
34155
+ }
34156
+ };
34157
+ var pluginListMeta = {
34158
+ command: "plugin list",
34159
+ description: "List installed plugins",
34160
+ whenToUse: "To see which plugins are currently installed in your workspace",
34161
+ examples: [
34162
+ "allagents plugin list"
33590
34163
  ],
34164
+ expectedOutput: "Lists installed plugins with their marketplace and scope. If none installed, suggests using marketplace browse.",
33591
34165
  outputSchema: {
33592
- plugins: [{ name: "string", marketplace: "string" }],
34166
+ plugins: [{ name: "string", marketplace: "string", scope: "string" }],
33593
34167
  total: "number"
33594
34168
  }
33595
34169
  };
@@ -34179,6 +34753,16 @@ Syncing workspace...
34179
34753
  }
34180
34754
  }
34181
34755
  }
34756
+ if (result.nativeResult) {
34757
+ const nativeLines = formatNativeResult(result.nativeResult);
34758
+ if (nativeLines.length > 0) {
34759
+ console.log(`
34760
+ native:`);
34761
+ for (const line of nativeLines) {
34762
+ console.log(line);
34763
+ }
34764
+ }
34765
+ }
34182
34766
  console.log(`
34183
34767
  Sync complete:`);
34184
34768
  console.log(` Total copied: ${result.totalCopied}`);
@@ -34238,6 +34822,16 @@ Syncing user workspace...
34238
34822
  }
34239
34823
  }
34240
34824
  }
34825
+ if (result.nativeResult) {
34826
+ const nativeLines = formatNativeResult(result.nativeResult);
34827
+ if (nativeLines.length > 0) {
34828
+ console.log(`
34829
+ native:`);
34830
+ for (const line of nativeLines) {
34831
+ console.log(line);
34832
+ }
34833
+ }
34834
+ }
34241
34835
  console.log(`
34242
34836
  User sync complete:`);
34243
34837
  console.log(` Total copied: ${result.totalCopied}`);
@@ -34378,17 +34972,21 @@ var marketplaceRemoveCmd = import_cmd_ts4.command({
34378
34972
  command: "plugin marketplace remove",
34379
34973
  data: {
34380
34974
  name,
34381
- path: result.marketplace?.path
34975
+ path: result.marketplace?.path,
34976
+ retainedUserPlugins: result.retainedUserPlugins ?? []
34382
34977
  }
34383
34978
  });
34384
34979
  return;
34385
34980
  }
34386
34981
  console.log(`✓ Marketplace '${name}' removed`);
34387
- if (result.removedUserPlugins && result.removedUserPlugins.length > 0) {
34388
- console.log(` Removed ${result.removedUserPlugins.length} user plugin(s):`);
34389
- for (const p of result.removedUserPlugins) {
34982
+ if (result.retainedUserPlugins && result.retainedUserPlugins.length > 0) {
34983
+ console.log(`
34984
+ ${result.retainedUserPlugins.length} plugin(s) still reference this marketplace:`);
34985
+ for (const p of result.retainedUserPlugins) {
34390
34986
  console.log(` - ${p}`);
34391
34987
  }
34988
+ console.log(`
34989
+ To remove them: allagents plugin remove <name>`);
34392
34990
  }
34393
34991
  } catch (error) {
34394
34992
  if (error instanceof Error) {
@@ -34463,52 +35061,31 @@ var marketplaceUpdateCmd = import_cmd_ts4.command({
34463
35061
  }
34464
35062
  }
34465
35063
  });
34466
- var marketplaceCmd = conciseSubcommands({
34467
- name: "marketplace",
34468
- description: "Manage plugin marketplaces",
34469
- cmds: {
34470
- list: marketplaceListCmd,
34471
- add: marketplaceAddCmd,
34472
- remove: marketplaceRemoveCmd,
34473
- update: marketplaceUpdateCmd
34474
- }
34475
- });
34476
- var pluginListCmd = import_cmd_ts4.command({
34477
- name: "list",
34478
- description: buildDescription(pluginListMeta),
35064
+ var marketplaceBrowseCmd = import_cmd_ts4.command({
35065
+ name: "browse",
35066
+ description: buildDescription(marketplaceBrowseMeta),
34479
35067
  args: {
34480
- marketplace: import_cmd_ts4.positional({ type: import_cmd_ts4.optional(import_cmd_ts4.string), displayName: "marketplace" })
35068
+ name: import_cmd_ts4.positional({ type: import_cmd_ts4.string, displayName: "name" })
34481
35069
  },
34482
- handler: async ({ marketplace }) => {
35070
+ handler: async ({ name }) => {
34483
35071
  try {
34484
- const marketplaces = await listMarketplaces();
34485
- if (marketplaces.length === 0) {
34486
- if (isJsonMode()) {
34487
- jsonOutput({
34488
- success: true,
34489
- command: "plugin list",
34490
- data: { plugins: [], total: 0 }
34491
- });
34492
- return;
34493
- }
34494
- console.log(`No marketplaces registered.
34495
- `);
34496
- console.log("Add a marketplace first:");
34497
- console.log(" allagents plugin marketplace add <source>");
34498
- return;
34499
- }
34500
- const toList = marketplace ? marketplaces.filter((m) => m.name === marketplace) : marketplaces;
34501
- if (marketplace && toList.length === 0) {
35072
+ if (!await findMarketplace(name)) {
35073
+ const error = `Marketplace '${name}' not found`;
34502
35074
  if (isJsonMode()) {
34503
- jsonOutput({ success: false, command: "plugin list", error: `Marketplace '${marketplace}' not found` });
35075
+ jsonOutput({ success: false, command: "plugin marketplace browse", error });
34504
35076
  process.exit(1);
34505
35077
  }
34506
- console.error(`Marketplace '${marketplace}' not found`);
35078
+ console.error(`Error: ${error}`);
35079
+ console.log(`
35080
+ To see registered marketplaces:`);
35081
+ console.log(" allagents plugin marketplace list");
34507
35082
  process.exit(1);
34508
35083
  }
35084
+ const result = await listMarketplacePlugins(name);
34509
35085
  const userPlugins = await getInstalledUserPlugins();
34510
35086
  const projectPlugins = await getInstalledProjectPlugins(process.cwd());
34511
35087
  const installedMap = new Map;
35088
+ const marketplaces = await listMarketplaces();
34512
35089
  const repoToMarketplace = new Map;
34513
35090
  for (const mp of marketplaces) {
34514
35091
  if (mp.source.type === "github") {
@@ -34518,8 +35095,8 @@ var pluginListCmd = import_cmd_ts4.command({
34518
35095
  }
34519
35096
  }
34520
35097
  }
34521
- const resolveMarketplaceName = (name) => {
34522
- return repoToMarketplace.get(name) ?? name;
35098
+ const resolveMarketplaceName = (mpName) => {
35099
+ return repoToMarketplace.get(mpName) ?? mpName;
34523
35100
  };
34524
35101
  for (const p of userPlugins) {
34525
35102
  const mpName = resolveMarketplaceName(p.marketplace);
@@ -34529,98 +35106,115 @@ var pluginListCmd = import_cmd_ts4.command({
34529
35106
  const mpName = resolveMarketplaceName(p.marketplace);
34530
35107
  installedMap.set(`${p.name}@${mpName}`, p);
34531
35108
  }
34532
- const versionMap = new Map;
34533
- for (const mp of toList) {
34534
- const version = await getMarketplaceVersion(mp.path);
34535
- versionMap.set(mp.name, version);
34536
- }
35109
+ const plugins = result.plugins.map((plugin) => {
35110
+ const key = `${plugin.name}@${name}`;
35111
+ const installed = installedMap.get(key);
35112
+ return {
35113
+ name: plugin.name,
35114
+ description: plugin.description ?? null,
35115
+ installed: !!installed,
35116
+ scope: installed?.scope ?? null
35117
+ };
35118
+ });
35119
+ const installedCount = plugins.filter((p) => p.installed).length;
34537
35120
  if (isJsonMode()) {
34538
- const allPlugins = [];
34539
- const allWarnings = [];
34540
- for (const mp of toList) {
34541
- const result = await listMarketplacePlugins(mp.name);
34542
- const version = versionMap.get(mp.name) ?? null;
34543
- for (const plugin of result.plugins) {
34544
- const key = `${plugin.name}@${mp.name}`;
34545
- const installed = installedMap.get(key);
34546
- allPlugins.push({
34547
- name: plugin.name,
34548
- marketplace: mp.name,
34549
- version,
34550
- scope: installed?.scope ?? null,
34551
- enabled: !!installed
34552
- });
34553
- }
34554
- for (const warning of result.warnings) {
34555
- allWarnings.push(`${mp.name}: ${warning}`);
34556
- }
34557
- }
34558
35121
  jsonOutput({
34559
35122
  success: true,
34560
- command: "plugin list",
35123
+ command: "plugin marketplace browse",
34561
35124
  data: {
34562
- plugins: allPlugins,
34563
- total: allPlugins.length,
34564
- ...allWarnings.length > 0 && { warnings: allWarnings }
35125
+ marketplace: name,
35126
+ plugins,
35127
+ total: plugins.length,
35128
+ installed: installedCount,
35129
+ ...result.warnings.length > 0 && { warnings: result.warnings }
34565
35130
  }
34566
35131
  });
34567
35132
  return;
34568
35133
  }
34569
- let totalPlugins = 0;
34570
- const allPluginEntries = [];
34571
- for (const mp of toList) {
34572
- const result = await listMarketplacePlugins(mp.name);
34573
- const version = versionMap.get(mp.name) ?? null;
34574
- for (const warning of result.warnings) {
34575
- allPluginEntries.push({
34576
- name: "",
34577
- marketplace: mp.name,
34578
- version,
34579
- installed: undefined,
34580
- warning
34581
- });
35134
+ for (const warning of result.warnings) {
35135
+ console.log(` Warning: ${warning}`);
35136
+ }
35137
+ if (plugins.length === 0) {
35138
+ console.log(`No plugins found in "${name}" marketplace.`);
35139
+ return;
35140
+ }
35141
+ console.log(`Plugins in "${name}" marketplace:
35142
+ `);
35143
+ for (const plugin of plugins) {
35144
+ const status = plugin.installed ? ` (installed - ${plugin.scope})` : "";
35145
+ console.log(` ❯ ${plugin.name}${status}`);
35146
+ if (plugin.description) {
35147
+ console.log(` ${plugin.description}`);
34582
35148
  }
34583
- for (const plugin of result.plugins) {
34584
- const key = `${plugin.name}@${mp.name}`;
34585
- const installed = installedMap.get(key);
34586
- allPluginEntries.push({
34587
- name: plugin.name,
34588
- marketplace: mp.name,
34589
- version,
34590
- installed
34591
- });
34592
- totalPlugins++;
35149
+ console.log();
35150
+ }
35151
+ console.log(`Total: ${plugins.length} plugins (${installedCount} installed)`);
35152
+ } catch (error) {
35153
+ if (error instanceof Error) {
35154
+ if (isJsonMode()) {
35155
+ jsonOutput({ success: false, command: "plugin marketplace browse", error: error.message });
35156
+ process.exit(1);
34593
35157
  }
35158
+ console.error(`Error: ${error.message}`);
35159
+ process.exit(1);
34594
35160
  }
34595
- if (totalPlugins === 0) {
34596
- console.log("No plugins found in registered marketplaces.");
35161
+ throw error;
35162
+ }
35163
+ }
35164
+ });
35165
+ var marketplaceCmd = conciseSubcommands({
35166
+ name: "marketplace",
35167
+ description: "Manage plugin marketplaces",
35168
+ cmds: {
35169
+ list: marketplaceListCmd,
35170
+ browse: marketplaceBrowseCmd,
35171
+ add: marketplaceAddCmd,
35172
+ remove: marketplaceRemoveCmd,
35173
+ update: marketplaceUpdateCmd
35174
+ }
35175
+ });
35176
+ var pluginListCmd = import_cmd_ts4.command({
35177
+ name: "list",
35178
+ description: buildDescription(pluginListMeta),
35179
+ args: {},
35180
+ handler: async () => {
35181
+ try {
35182
+ const userPlugins = await getInstalledUserPlugins();
35183
+ const projectPlugins = await getInstalledProjectPlugins(process.cwd());
35184
+ const allInstalled = [...userPlugins, ...projectPlugins];
35185
+ if (isJsonMode()) {
35186
+ jsonOutput({
35187
+ success: true,
35188
+ command: "plugin list",
35189
+ data: {
35190
+ plugins: allInstalled.map((p) => ({
35191
+ name: p.name,
35192
+ marketplace: p.marketplace,
35193
+ scope: p.scope
35194
+ })),
35195
+ total: allInstalled.length
35196
+ }
35197
+ });
34597
35198
  return;
34598
35199
  }
34599
- const installedPlugins = allPluginEntries.filter((e) => e.installed && !e.warning);
34600
- const availablePlugins = allPluginEntries.filter((e) => !e.installed && !e.warning);
34601
- const warnings = allPluginEntries.filter((e) => e.warning);
34602
- for (const entry of warnings) {
34603
- console.log(` Warning: ${entry.warning}`);
34604
- }
34605
- if (installedPlugins.length > 0) {
34606
- console.log(`Installed plugins:
35200
+ if (allInstalled.length === 0) {
35201
+ console.log(`No plugins installed.
34607
35202
  `);
34608
- for (const entry of installedPlugins) {
34609
- console.log(` ${entry.name}@${entry.marketplace}`);
34610
- console.log(` Version: ${entry.version ?? "unknown"}`);
34611
- console.log(` Scope: ${entry.installed?.scope}
35203
+ console.log("To discover available plugins:");
35204
+ console.log(` allagents plugin marketplace browse <name>
34612
35205
  `);
34613
- }
35206
+ console.log("To see registered marketplaces:");
35207
+ console.log(" allagents plugin marketplace list");
35208
+ return;
34614
35209
  }
34615
- if (availablePlugins.length > 0) {
34616
- console.log(`Available plugins:
35210
+ console.log(`Installed plugins:
34617
35211
  `);
34618
- for (const entry of availablePlugins) {
34619
- console.log(` ❯ ${entry.name}@${entry.marketplace}`);
34620
- console.log(` Version: ${entry.version ?? "unknown"}
35212
+ for (const p of allInstalled) {
35213
+ console.log(` ❯ ${p.spec}`);
35214
+ console.log(` Scope: ${p.scope}
34621
35215
  `);
34622
- }
34623
35216
  }
35217
+ console.log(`Total: ${allInstalled.length} installed`);
34624
35218
  } catch (error) {
34625
35219
  if (error instanceof Error) {
34626
35220
  if (isJsonMode()) {
@@ -36722,6 +37316,7 @@ var allCommands = [
36722
37316
  marketplaceAddMeta,
36723
37317
  marketplaceRemoveMeta,
36724
37318
  marketplaceUpdateMeta,
37319
+ marketplaceBrowseMeta,
36725
37320
  pluginListMeta,
36726
37321
  pluginValidateMeta,
36727
37322
  updateMeta