allagents 1.7.1 → 1.7.2-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 +325 -118
  2. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -6,39 +6,60 @@ var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ function __accessProp(key) {
10
+ return this[key];
11
+ }
12
+ var __toESMCache_node;
13
+ var __toESMCache_esm;
9
14
  var __toESM = (mod, isNodeMode, target) => {
15
+ var canCache = mod != null && typeof mod === "object";
16
+ if (canCache) {
17
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
18
+ var cached = cache.get(mod);
19
+ if (cached)
20
+ return cached;
21
+ }
10
22
  target = mod != null ? __create(__getProtoOf(mod)) : {};
11
23
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
12
24
  for (let key of __getOwnPropNames(mod))
13
25
  if (!__hasOwnProp.call(to, key))
14
26
  __defProp(to, key, {
15
- get: () => mod[key],
27
+ get: __accessProp.bind(mod, key),
16
28
  enumerable: true
17
29
  });
30
+ if (canCache)
31
+ cache.set(mod, to);
18
32
  return to;
19
33
  };
20
- var __moduleCache = /* @__PURE__ */ new WeakMap;
21
34
  var __toCommonJS = (from) => {
22
- var entry = __moduleCache.get(from), desc;
35
+ var entry = (__moduleCache ??= new WeakMap).get(from), desc;
23
36
  if (entry)
24
37
  return entry;
25
38
  entry = __defProp({}, "__esModule", { value: true });
26
- if (from && typeof from === "object" || typeof from === "function")
27
- __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
28
- get: () => from[key],
29
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
- }));
39
+ if (from && typeof from === "object" || typeof from === "function") {
40
+ for (var key of __getOwnPropNames(from))
41
+ if (!__hasOwnProp.call(entry, key))
42
+ __defProp(entry, key, {
43
+ get: __accessProp.bind(from, key),
44
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
45
+ });
46
+ }
31
47
  __moduleCache.set(from, entry);
32
48
  return entry;
33
49
  };
50
+ var __moduleCache;
34
51
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
52
+ var __returnValue = (v) => v;
53
+ function __exportSetter(name, newValue) {
54
+ this[name] = __returnValue.bind(null, newValue);
55
+ }
35
56
  var __export = (target, all) => {
36
57
  for (var name in all)
37
58
  __defProp(target, name, {
38
59
  get: all[name],
39
60
  enumerable: true,
40
61
  configurable: true,
41
- set: (newValue) => all[name] = () => newValue
62
+ set: __exportSetter.bind(all, name)
42
63
  });
43
64
  };
44
65
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
@@ -11490,16 +11511,22 @@ function resolveInstallMode(pluginEntry, clientEntry) {
11490
11511
  return pluginMode;
11491
11512
  return clientEntry.install;
11492
11513
  }
11493
- var RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, McpProxyServerSchema, McpProxyConfigSchema, WorkspaceConfigSchema;
11514
+ var ManagedModeSchema, RepositorySchema, WorkspaceFileSchema, WorkspaceSchema, PluginSourceSchema, ClientTypeSchema, InstallModeSchema, ClientEntrySchema, PluginSkillsConfigSchema, PluginEntrySchema, VscodeConfigSchema, SyncModeSchema, McpProxyServerSchema, McpProxyConfigSchema, WorkspaceConfigSchema;
11494
11515
  var init_workspace_config = __esm(() => {
11495
11516
  init_zod();
11517
+ ManagedModeSchema = exports_external.union([
11518
+ exports_external.boolean(),
11519
+ exports_external.enum(["clone", "sync"])
11520
+ ]);
11496
11521
  RepositorySchema = exports_external.object({
11497
11522
  path: exports_external.string(),
11498
11523
  name: exports_external.string().optional(),
11499
11524
  source: exports_external.string().optional(),
11500
11525
  repo: exports_external.string().optional(),
11501
11526
  description: exports_external.string().optional(),
11502
- skills: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional()
11527
+ skills: exports_external.union([exports_external.boolean(), exports_external.array(exports_external.string())]).optional(),
11528
+ managed: ManagedModeSchema.optional(),
11529
+ branch: exports_external.string().optional()
11503
11530
  });
11504
11531
  WorkspaceFileSchema = exports_external.union([
11505
11532
  exports_external.string(),
@@ -29956,7 +29983,7 @@ class ClaudeNativeClient {
29956
29983
  for (const plugin of plugins) {
29957
29984
  const spec = this.toPluginSpec(plugin);
29958
29985
  if (spec) {
29959
- result.pluginsInstalled.push(spec);
29986
+ result.pluginsInstalled.push({ plugin: spec });
29960
29987
  } else {
29961
29988
  result.skipped.push(plugin);
29962
29989
  }
@@ -29983,7 +30010,7 @@ class ClaudeNativeClient {
29983
30010
  }
29984
30011
  const installResult = await this.installPlugin(spec, scope, options2);
29985
30012
  if (installResult.success) {
29986
- result.pluginsInstalled.push(spec);
30013
+ result.pluginsInstalled.push({ plugin: spec });
29987
30014
  } else {
29988
30015
  result.pluginsFailed.push({
29989
30016
  plugin: spec,
@@ -30051,7 +30078,7 @@ class CopilotNativeClient {
30051
30078
  for (const plugin of plugins) {
30052
30079
  const spec = this.toPluginSpec(plugin);
30053
30080
  if (spec) {
30054
- result.pluginsInstalled.push(spec);
30081
+ result.pluginsInstalled.push({ plugin: spec });
30055
30082
  } else {
30056
30083
  result.skipped.push(plugin);
30057
30084
  }
@@ -30078,7 +30105,7 @@ class CopilotNativeClient {
30078
30105
  }
30079
30106
  const installResult = await this.installPlugin(spec, scope, options2);
30080
30107
  if (installResult.success) {
30081
- result.pluginsInstalled.push(spec);
30108
+ result.pluginsInstalled.push({ plugin: spec });
30082
30109
  } else {
30083
30110
  const rawError = installResult.error ?? "Unknown error";
30084
30111
  const error = rawError.includes("Plugin path escapes marketplace directory") ? `${rawError} (Copilot rejected a plugin path from this marketplace manifest. Use file install for copilot to avoid native install for this plugin.)` : rawError;
@@ -30193,10 +30220,145 @@ function padStart2(str3, len) {
30193
30220
  return str3.length >= len ? str3 : " ".repeat(len - str3.length) + str3;
30194
30221
  }
30195
30222
 
30223
+ // src/core/managed-repos.ts
30224
+ import { existsSync as existsSync17 } from "node:fs";
30225
+ import { mkdir as mkdir8 } from "node:fs/promises";
30226
+ import { dirname as dirname11, resolve as resolve10 } from "node:path";
30227
+ function expandHome(p) {
30228
+ if (p.startsWith("~/") || p === "~") {
30229
+ return p.replace("~", getHomeDir());
30230
+ }
30231
+ return p;
30232
+ }
30233
+ function shouldClone(managed) {
30234
+ if (managed === undefined || managed === false)
30235
+ return false;
30236
+ return true;
30237
+ }
30238
+ function shouldPull(managed) {
30239
+ if (managed === true || managed === "sync")
30240
+ return true;
30241
+ return false;
30242
+ }
30243
+ function isValidRepo(repo) {
30244
+ return /^[\w.\-/]+$/.test(repo);
30245
+ }
30246
+ function buildCloneUrl(source, repo) {
30247
+ if (!isValidRepo(repo)) {
30248
+ throw new Error(`Invalid repo identifier: ${repo}`);
30249
+ }
30250
+ switch (source) {
30251
+ case "github":
30252
+ return `https://github.com/${repo}.git`;
30253
+ case "gitlab":
30254
+ return `https://gitlab.com/${repo}.git`;
30255
+ case "bitbucket":
30256
+ return `https://bitbucket.org/${repo}.git`;
30257
+ case "azure-devops": {
30258
+ const parts = repo.split("/");
30259
+ if (parts.length === 3) {
30260
+ return `https://dev.azure.com/${parts[0]}/${parts[1]}/_git/${parts[2]}`;
30261
+ }
30262
+ return `https://dev.azure.com/${repo}`;
30263
+ }
30264
+ default:
30265
+ return `https://${source}/${repo}.git`;
30266
+ }
30267
+ }
30268
+ async function cloneRepo(url, dest, branch) {
30269
+ await mkdir8(dirname11(dest), { recursive: true });
30270
+ const git = esm_default({ timeout: { block: CLONE_TIMEOUT_MS2 } });
30271
+ const cloneOptions = branch ? ["--branch", branch] : [];
30272
+ await git.clone(url, dest, cloneOptions);
30273
+ }
30274
+ async function pullRepo(repoPath, branch) {
30275
+ const git = esm_default(repoPath, { timeout: { block: CLONE_TIMEOUT_MS2 } });
30276
+ const status = await git.status();
30277
+ if (!status.isClean()) {
30278
+ return "uncommitted changes";
30279
+ }
30280
+ if (branch) {
30281
+ const currentBranch = status.current;
30282
+ if (currentBranch !== branch) {
30283
+ return `on branch '${currentBranch}', expected '${branch}'`;
30284
+ }
30285
+ }
30286
+ await git.pull();
30287
+ return;
30288
+ }
30289
+ async function processManagedRepos(repositories, workspacePath, options2 = {}) {
30290
+ if (options2.skipManaged || options2.offline || options2.dryRun)
30291
+ return [];
30292
+ const managed = repositories.filter((r) => r.managed);
30293
+ if (managed.length === 0)
30294
+ return [];
30295
+ const results = [];
30296
+ for (const repo of managed) {
30297
+ if (!repo.source || !repo.repo) {
30298
+ results.push({
30299
+ path: repo.path,
30300
+ repo: repo.repo ?? repo.path,
30301
+ action: "skipped",
30302
+ error: "managed requires both source and repo fields"
30303
+ });
30304
+ continue;
30305
+ }
30306
+ const expandedPath = expandHome(repo.path);
30307
+ const absolutePath = resolve10(workspacePath, expandedPath);
30308
+ if (!existsSync17(absolutePath)) {
30309
+ if (!shouldClone(repo.managed)) {
30310
+ results.push({ path: repo.path, repo: repo.repo, action: "skipped" });
30311
+ continue;
30312
+ }
30313
+ try {
30314
+ const url = buildCloneUrl(repo.source, repo.repo);
30315
+ await cloneRepo(url, absolutePath, repo.branch);
30316
+ results.push({ path: repo.path, repo: repo.repo, action: "cloned" });
30317
+ } catch (error) {
30318
+ results.push({
30319
+ path: repo.path,
30320
+ repo: repo.repo,
30321
+ action: "skipped",
30322
+ error: `clone failed: ${error instanceof Error ? error.message : String(error)}`
30323
+ });
30324
+ }
30325
+ } else if (shouldPull(repo.managed)) {
30326
+ try {
30327
+ const skipReason = await pullRepo(absolutePath, repo.branch);
30328
+ if (skipReason) {
30329
+ results.push({
30330
+ path: repo.path,
30331
+ repo: repo.repo,
30332
+ action: "skipped",
30333
+ error: `pull skipped: ${skipReason}`
30334
+ });
30335
+ } else {
30336
+ results.push({ path: repo.path, repo: repo.repo, action: "pulled" });
30337
+ }
30338
+ } catch (error) {
30339
+ results.push({
30340
+ path: repo.path,
30341
+ repo: repo.repo,
30342
+ action: "skipped",
30343
+ error: `pull failed: ${error instanceof Error ? error.message : String(error)}`
30344
+ });
30345
+ }
30346
+ } else {
30347
+ results.push({ path: repo.path, repo: repo.repo, action: "skipped" });
30348
+ }
30349
+ }
30350
+ return results;
30351
+ }
30352
+ var CLONE_TIMEOUT_MS2 = 120000;
30353
+ var init_managed_repos = __esm(() => {
30354
+ init_esm();
30355
+ init_constants();
30356
+ });
30357
+
30196
30358
  // src/core/sync.ts
30197
- import { existsSync as existsSync17, readFileSync as readFileSync4, writeFileSync as writeFileSync6, lstatSync as lstatSync2 } from "node:fs";
30359
+ import { existsSync as existsSync18, readFileSync as readFileSync4, writeFileSync as writeFileSync6, lstatSync as lstatSync2 } from "node:fs";
30198
30360
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
30199
- import { join as join19, resolve as resolve10, dirname as dirname11, relative as relative5 } from "node:path";
30361
+ import { join as join19, resolve as resolve11, dirname as dirname12, relative as relative5 } from "node:path";
30200
30362
  function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
30201
30363
  const pathToClients = new Map;
30202
30364
  for (const client of clients) {
@@ -30242,6 +30404,10 @@ function mergeSyncResults(a, b) {
30242
30404
  ...deletedArtifacts.length > 0 && { deletedArtifacts },
30243
30405
  ...mcpResults && { mcpResults },
30244
30406
  ...nativeResult && { nativeResult },
30407
+ ...(() => {
30408
+ const managedRepoResults = [...a.managedRepoResults || [], ...b.managedRepoResults || []];
30409
+ return managedRepoResults.length > 0 ? { managedRepoResults } : {};
30410
+ })(),
30245
30411
  ...mergeTiming(a.timing, b.timing)
30246
30412
  };
30247
30413
  }
@@ -30292,6 +30458,7 @@ function collectNativePluginSources(validPlugins) {
30292
30458
  function attachNativeClientContext(result, clientType) {
30293
30459
  return {
30294
30460
  ...result,
30461
+ pluginsInstalled: result.pluginsInstalled.map((installed) => ({ ...installed, client: clientType })),
30295
30462
  pluginsFailed: result.pluginsFailed.map((failure) => ({ ...failure, client: clientType }))
30296
30463
  };
30297
30464
  }
@@ -30337,16 +30504,16 @@ async function selectivePurgeWorkspace(workspacePath, state, clients) {
30337
30504
  return result;
30338
30505
  }
30339
30506
  async function cleanupEmptyParents(workspacePath, filePath) {
30340
- let parentPath = dirname11(filePath);
30507
+ let parentPath = dirname12(filePath);
30341
30508
  while (parentPath && parentPath !== "." && parentPath !== "/") {
30342
30509
  const fullParentPath = join19(workspacePath, parentPath);
30343
- if (!existsSync17(fullParentPath)) {
30344
- parentPath = dirname11(parentPath);
30510
+ if (!existsSync18(fullParentPath)) {
30511
+ parentPath = dirname12(parentPath);
30345
30512
  continue;
30346
30513
  }
30347
30514
  try {
30348
30515
  await rmdir(fullParentPath);
30349
- parentPath = dirname11(parentPath);
30516
+ parentPath = dirname12(parentPath);
30350
30517
  } catch {
30351
30518
  break;
30352
30519
  }
@@ -30426,7 +30593,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30426
30593
  continue;
30427
30594
  }
30428
30595
  const fullPath = join19(defaultSourcePath, file);
30429
- if (!existsSync17(fullPath)) {
30596
+ if (!existsSync18(fullPath)) {
30430
30597
  errors2.push(`File source not found: ${fullPath}`);
30431
30598
  }
30432
30599
  continue;
@@ -30445,7 +30612,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30445
30612
  continue;
30446
30613
  }
30447
30614
  const fullPath = join19(cachePath, parsed.filePath);
30448
- if (!existsSync17(fullPath)) {
30615
+ if (!existsSync18(fullPath)) {
30449
30616
  errors2.push(`Path not found in repository: ${cacheKey}/${parsed.filePath}`);
30450
30617
  }
30451
30618
  } else {
@@ -30453,13 +30620,13 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30453
30620
  if (file.source.startsWith("/")) {
30454
30621
  fullPath = file.source;
30455
30622
  } else if (file.source.startsWith("../")) {
30456
- fullPath = resolve10(file.source);
30623
+ fullPath = resolve11(file.source);
30457
30624
  } else if (defaultSourcePath) {
30458
30625
  fullPath = join19(defaultSourcePath, file.source);
30459
30626
  } else {
30460
- fullPath = resolve10(file.source);
30627
+ fullPath = resolve11(file.source);
30461
30628
  }
30462
- if (!existsSync17(fullPath)) {
30629
+ if (!existsSync18(fullPath)) {
30463
30630
  errors2.push(`File source not found: ${fullPath}`);
30464
30631
  }
30465
30632
  }
@@ -30469,7 +30636,7 @@ function validateFileSources(files, defaultSourcePath, githubCache) {
30469
30636
  continue;
30470
30637
  }
30471
30638
  const fullPath = join19(defaultSourcePath, file.dest ?? "");
30472
- if (!existsSync17(fullPath)) {
30639
+ if (!existsSync18(fullPath)) {
30473
30640
  errors2.push(`File source not found: ${fullPath}`);
30474
30641
  }
30475
30642
  }
@@ -30624,8 +30791,8 @@ async function validatePlugin(pluginSource, workspacePath, offline) {
30624
30791
  nativeClients: []
30625
30792
  };
30626
30793
  }
30627
- const resolvedPath = resolve10(workspacePath, pluginSource);
30628
- if (!existsSync17(resolvedPath)) {
30794
+ const resolvedPath = resolve11(workspacePath, pluginSource);
30795
+ if (!existsSync18(resolvedPath)) {
30629
30796
  return {
30630
30797
  plugin: pluginSource,
30631
30798
  resolved: resolvedPath,
@@ -30789,7 +30956,7 @@ function generateVscodeWorkspaceFile(workspacePath, config) {
30789
30956
  const configDir = join19(workspacePath, CONFIG_DIR);
30790
30957
  const templatePath = join19(configDir, VSCODE_TEMPLATE_FILE);
30791
30958
  let template;
30792
- if (existsSync17(templatePath)) {
30959
+ if (existsSync18(templatePath)) {
30793
30960
  try {
30794
30961
  template = import_json53.default.parse(readFileSync4(templatePath, "utf-8"));
30795
30962
  } catch (error) {
@@ -30936,7 +31103,7 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
30936
31103
  let updatedConfig = config;
30937
31104
  if (previousState?.vscodeWorkspaceHash && previousState?.vscodeWorkspaceRepos) {
30938
31105
  const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
30939
- if (existsSync17(outputPath)) {
31106
+ if (existsSync18(outputPath)) {
30940
31107
  const existingContent = readFileSync4(outputPath, "utf-8");
30941
31108
  const currentHash = computeWorkspaceHash(existingContent);
30942
31109
  if (currentHash !== previousState.vscodeWorkspaceHash) {
@@ -30966,7 +31133,7 @@ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previo
30966
31133
  }
30967
31134
  const writtenContent = generateVscodeWorkspaceFile(workspacePath, updatedConfig);
30968
31135
  const hash = computeWorkspaceHash(writtenContent);
30969
- const repos = updatedConfig.repositories.map((r) => resolve10(workspacePath, r.path).replace(/\\/g, "/"));
31136
+ const repos = updatedConfig.repositories.map((r) => resolve11(workspacePath, r.path).replace(/\\/g, "/"));
30970
31137
  return { config: updatedConfig, hash, repos };
30971
31138
  }
30972
31139
  async function persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, nativePluginsByClient, nativeResult, extra) {
@@ -30978,7 +31145,7 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
30978
31145
  const resolvedMappings = resolveClientMappings(syncClients, mappings);
30979
31146
  const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, syncClients, resolvedMappings);
30980
31147
  const nativePluginsState = {};
30981
- const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
31148
+ const installedSet = new Set((nativeResult?.pluginsInstalled ?? []).map((p) => p.plugin));
30982
31149
  for (const [client, sources] of nativePluginsByClient) {
30983
31150
  const nativeClient = getNativeClient(client);
30984
31151
  if (!nativeClient)
@@ -30999,11 +31166,11 @@ async function persistSyncState(workspacePath, pluginResults, workspaceFileResul
30999
31166
  }
31000
31167
  async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
31001
31168
  await migrateWorkspaceSkillsV1toV2(workspacePath);
31002
- const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options2;
31169
+ const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false, skipManaged = false } = options2;
31003
31170
  const sw = new Stopwatch;
31004
31171
  const configDir = join19(workspacePath, CONFIG_DIR);
31005
31172
  const configPath = join19(configDir, WORKSPACE_CONFIG_FILE);
31006
- if (!existsSync17(configPath)) {
31173
+ if (!existsSync18(configPath)) {
31007
31174
  return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
31008
31175
  Run 'allagents workspace init <path>' to create a new workspace`);
31009
31176
  }
@@ -31017,6 +31184,8 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
31017
31184
  for (const name of overrides) {
31018
31185
  console.warn(`Warning: Workspace marketplace '${name}' overrides user marketplace of the same name.`);
31019
31186
  }
31187
+ const managedRepoResults = await sw.measure("managed-repos", () => processManagedRepos(config.repositories ?? [], workspacePath, { offline, skipManaged, dryRun }));
31188
+ const managedWarnings = managedRepoResults.filter((r) => r.error).map((r) => `${r.repo}: ${r.error}`);
31020
31189
  const hasRepositories = (config.repositories?.length ?? 0) > 0;
31021
31190
  const { plans: pluginPlans, warnings: planWarnings } = buildPluginSyncPlans(config.plugins, config.clients, "project");
31022
31191
  const workspaceClients = config.clients;
@@ -31054,6 +31223,7 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
31054
31223
  const failedValidations = validatedPlugins.filter((v) => !v.success);
31055
31224
  const validPlugins = validatedPlugins.filter((v) => v.success);
31056
31225
  const warnings = [
31226
+ ...managedWarnings,
31057
31227
  ...planWarnings,
31058
31228
  ...workspaceSourceWarnings,
31059
31229
  ...failedValidations.map((v) => `${v.plugin}: ${v.error} (skipped)`)
@@ -31094,7 +31264,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
31094
31264
  if (hasRepositories && sourcePath) {
31095
31265
  for (const agentFile of AGENT_FILES) {
31096
31266
  const agentPath = join19(sourcePath, agentFile);
31097
- if (existsSync17(agentPath) && !filesToCopy.includes(agentFile)) {
31267
+ if (existsSync18(agentPath) && !filesToCopy.includes(agentFile)) {
31098
31268
  filesToCopy.push(agentFile);
31099
31269
  }
31100
31270
  }
@@ -31131,8 +31301,8 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31131
31301
  if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
31132
31302
  const claudePath = join19(workspacePath, "CLAUDE.md");
31133
31303
  const agentsPath = join19(workspacePath, "AGENTS.md");
31134
- const claudeExistsInSource = existsSync17(join19(sourcePath, "CLAUDE.md"));
31135
- if (!claudeExistsInSource && existsSync17(agentsPath) && !existsSync17(claudePath)) {
31304
+ const claudeExistsInSource = existsSync18(join19(sourcePath, "CLAUDE.md"));
31305
+ if (!claudeExistsInSource && existsSync18(agentsPath) && !existsSync18(claudePath)) {
31136
31306
  await copyFile(agentsPath, claudePath);
31137
31307
  }
31138
31308
  }
@@ -31276,6 +31446,7 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
31276
31446
  ...messages.length > 0 && { messages },
31277
31447
  ...Object.keys(mcpResults).length > 0 && { mcpResults },
31278
31448
  ...nativeResult && { nativeResult },
31449
+ ...managedRepoResults.length > 0 && { managedRepoResults },
31279
31450
  timing: sw.toJSON()
31280
31451
  };
31281
31452
  }
@@ -31305,7 +31476,7 @@ function readGitBranch(repoPath) {
31305
31476
  async function syncUserWorkspace(options2 = {}) {
31306
31477
  await migrateUserWorkspaceSkillsV1toV2();
31307
31478
  const sw = new Stopwatch;
31308
- const homeDir = resolve10(getHomeDir());
31479
+ const homeDir = resolve11(getHomeDir());
31309
31480
  const config = await getUserWorkspaceConfig();
31310
31481
  if (!config) {
31311
31482
  return {
@@ -31496,15 +31667,16 @@ var init_sync = __esm(() => {
31496
31667
  init_claude_mcp();
31497
31668
  init_copilot_mcp();
31498
31669
  init_native();
31670
+ init_managed_repos();
31499
31671
  import_json53 = __toESM(require_lib(), 1);
31500
31672
  });
31501
31673
 
31502
31674
  // src/core/github-fetch.ts
31503
- import { existsSync as existsSync18, readFileSync as readFileSync5 } from "node:fs";
31675
+ import { existsSync as existsSync19, readFileSync as readFileSync5 } from "node:fs";
31504
31676
  import { join as join20 } from "node:path";
31505
31677
  function readFileFromClone(tempDir, filePath) {
31506
31678
  const fullPath = join20(tempDir, filePath);
31507
- if (existsSync18(fullPath)) {
31679
+ if (existsSync19(fullPath)) {
31508
31680
  return readFileSync5(fullPath, "utf-8");
31509
31681
  }
31510
31682
  return null;
@@ -31603,15 +31775,15 @@ var init_github_fetch = __esm(() => {
31603
31775
  });
31604
31776
 
31605
31777
  // src/core/workspace.ts
31606
- import { cp as cp2, mkdir as mkdir8, readFile as readFile12, writeFile as writeFile8, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
31607
- import { existsSync as existsSync19 } from "node:fs";
31608
- import { join as join21, resolve as resolve11, dirname as dirname12, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31778
+ import { cp as cp2, mkdir as mkdir9, readFile as readFile12, writeFile as writeFile8, copyFile as copyFile2, unlink as unlink3 } from "node:fs/promises";
31779
+ import { existsSync as existsSync20 } from "node:fs";
31780
+ import { join as join21, resolve as resolve12, dirname as dirname13, relative as relative6, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
31609
31781
  import { fileURLToPath } from "node:url";
31610
31782
  async function initWorkspace(targetPath = ".", options2 = {}) {
31611
- const absoluteTarget = resolve11(targetPath);
31783
+ const absoluteTarget = resolve12(targetPath);
31612
31784
  const configDir = join21(absoluteTarget, CONFIG_DIR);
31613
31785
  const configPath = join21(configDir, WORKSPACE_CONFIG_FILE);
31614
- if (existsSync19(configPath)) {
31786
+ if (existsSync20(configPath)) {
31615
31787
  if (options2.force) {
31616
31788
  await unlink3(configPath);
31617
31789
  } else {
@@ -31620,7 +31792,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31620
31792
  }
31621
31793
  }
31622
31794
  const currentFilePath = fileURLToPath(import.meta.url);
31623
- const currentFileDir = dirname12(currentFilePath);
31795
+ const currentFileDir = dirname13(currentFilePath);
31624
31796
  const isProduction = currentFilePath.includes(`${sep2}dist${sep2}`);
31625
31797
  const defaultTemplatePath = isProduction ? join21(currentFileDir, "templates", "default") : join21(currentFileDir, "..", "templates", "default");
31626
31798
  let githubTempDir;
@@ -31628,8 +31800,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31628
31800
  let githubBasePath = "";
31629
31801
  let githubBranch = "main";
31630
31802
  try {
31631
- await mkdir8(absoluteTarget, { recursive: true });
31632
- await mkdir8(configDir, { recursive: true });
31803
+ await mkdir9(absoluteTarget, { recursive: true });
31804
+ await mkdir9(configDir, { recursive: true });
31633
31805
  await ensureConfigGitignore(absoluteTarget);
31634
31806
  let workspaceYamlContent;
31635
31807
  let sourceDir;
@@ -31661,8 +31833,8 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31661
31833
  }
31662
31834
  console.log(`✓ Using workspace.yaml from: ${options2.from}`);
31663
31835
  } else {
31664
- const fromPath = resolve11(options2.from);
31665
- if (!existsSync19(fromPath)) {
31836
+ const fromPath = resolve12(options2.from);
31837
+ if (!existsSync20(fromPath)) {
31666
31838
  throw new Error(`Template not found: ${fromPath}`);
31667
31839
  }
31668
31840
  const { stat: stat2 } = await import("node:fs/promises");
@@ -31671,10 +31843,10 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31671
31843
  if (fromStat.isDirectory()) {
31672
31844
  const nestedPath = join21(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31673
31845
  const rootPath = join21(fromPath, WORKSPACE_CONFIG_FILE);
31674
- if (existsSync19(nestedPath)) {
31846
+ if (existsSync20(nestedPath)) {
31675
31847
  sourceYamlPath = nestedPath;
31676
31848
  sourceDir = fromPath;
31677
- } else if (existsSync19(rootPath)) {
31849
+ } else if (existsSync20(rootPath)) {
31678
31850
  sourceYamlPath = rootPath;
31679
31851
  sourceDir = fromPath;
31680
31852
  } else {
@@ -31683,9 +31855,9 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31683
31855
  }
31684
31856
  } else {
31685
31857
  sourceYamlPath = fromPath;
31686
- const parentDir = dirname12(fromPath);
31858
+ const parentDir = dirname13(fromPath);
31687
31859
  if (parentDir.endsWith(CONFIG_DIR)) {
31688
- sourceDir = dirname12(parentDir);
31860
+ sourceDir = dirname13(parentDir);
31689
31861
  } else {
31690
31862
  sourceDir = parentDir;
31691
31863
  }
@@ -31697,7 +31869,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31697
31869
  if (workspace?.source) {
31698
31870
  const source = workspace.source;
31699
31871
  if (!isGitHubUrl(source) && !isAbsolute4(source)) {
31700
- workspace.source = resolve11(sourceDir, source);
31872
+ workspace.source = resolve12(sourceDir, source);
31701
31873
  workspaceYamlContent = dump(parsed2, { lineWidth: -1 });
31702
31874
  }
31703
31875
  }
@@ -31706,7 +31878,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31706
31878
  }
31707
31879
  } else {
31708
31880
  const defaultYamlPath = join21(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31709
- if (!existsSync19(defaultYamlPath)) {
31881
+ if (!existsSync20(defaultYamlPath)) {
31710
31882
  throw new Error(`Default template not found at: ${defaultTemplatePath}`);
31711
31883
  }
31712
31884
  workspaceYamlContent = await readFile12(defaultYamlPath, "utf-8");
@@ -31723,7 +31895,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31723
31895
  const VSCODE_TEMPLATE_FILE2 = "template.code-workspace";
31724
31896
  if (clientNames.includes("vscode") && options2.from) {
31725
31897
  const targetTemplatePath = join21(configDir, VSCODE_TEMPLATE_FILE2);
31726
- if (!existsSync19(targetTemplatePath)) {
31898
+ if (!existsSync20(targetTemplatePath)) {
31727
31899
  if (isGitHubUrl(options2.from) && githubTempDir) {
31728
31900
  if (parsedFromUrl) {
31729
31901
  const templatePath = githubBasePath ? `${githubBasePath}/${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}` : `${CONFIG_DIR}/${VSCODE_TEMPLATE_FILE2}`;
@@ -31734,7 +31906,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31734
31906
  }
31735
31907
  } else if (sourceDir) {
31736
31908
  const sourceTemplatePath = join21(sourceDir, CONFIG_DIR, VSCODE_TEMPLATE_FILE2);
31737
- if (existsSync19(sourceTemplatePath)) {
31909
+ if (existsSync20(sourceTemplatePath)) {
31738
31910
  await copyFile2(sourceTemplatePath, targetTemplatePath);
31739
31911
  }
31740
31912
  }
@@ -31748,7 +31920,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31748
31920
  if (parsedFromUrl) {
31749
31921
  for (const agentFile of AGENT_FILES) {
31750
31922
  const targetFilePath = join21(absoluteTarget, agentFile);
31751
- if (existsSync19(targetFilePath)) {
31923
+ if (existsSync20(targetFilePath)) {
31752
31924
  copiedAgentFiles.push(agentFile);
31753
31925
  continue;
31754
31926
  }
@@ -31764,12 +31936,12 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
31764
31936
  const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
31765
31937
  for (const agentFile of AGENT_FILES) {
31766
31938
  const targetFilePath = join21(absoluteTarget, agentFile);
31767
- if (existsSync19(targetFilePath)) {
31939
+ if (existsSync20(targetFilePath)) {
31768
31940
  copiedAgentFiles.push(agentFile);
31769
31941
  continue;
31770
31942
  }
31771
31943
  const sourcePath = join21(effectiveSourceDir, agentFile);
31772
- if (existsSync19(sourcePath)) {
31944
+ if (existsSync20(sourcePath)) {
31773
31945
  const content = await readFile12(sourcePath, "utf-8");
31774
31946
  await writeFile8(targetFilePath, content, "utf-8");
31775
31947
  copiedAgentFiles.push(agentFile);
@@ -31834,12 +32006,12 @@ async function seedCacheFromClone(tempDir, owner, repo, branch) {
31834
32006
  join21(getMarketplacesDir(), repo)
31835
32007
  ];
31836
32008
  for (const cachePath of cachePaths) {
31837
- if (existsSync19(cachePath))
32009
+ if (existsSync20(cachePath))
31838
32010
  continue;
31839
32011
  try {
31840
- const parentDir = dirname12(cachePath);
31841
- if (!existsSync19(parentDir)) {
31842
- await mkdir8(parentDir, { recursive: true });
32012
+ const parentDir = dirname13(cachePath);
32013
+ if (!existsSync20(parentDir)) {
32014
+ await mkdir9(parentDir, { recursive: true });
31843
32015
  }
31844
32016
  await cp2(tempDir, cachePath, { recursive: true });
31845
32017
  } catch {}
@@ -31859,11 +32031,11 @@ var init_workspace = __esm(() => {
31859
32031
  });
31860
32032
 
31861
32033
  // src/core/status.ts
31862
- import { existsSync as existsSync20 } from "node:fs";
32034
+ import { existsSync as existsSync21 } from "node:fs";
31863
32035
  import { join as join22 } from "node:path";
31864
32036
  async function getWorkspaceStatus(workspacePath = process.cwd()) {
31865
32037
  const configPath = join22(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
31866
- if (!existsSync20(configPath) || isUserConfigPath(workspacePath)) {
32038
+ if (!existsSync21(configPath) || isUserConfigPath(workspacePath)) {
31867
32039
  const userPlugins = await getUserPluginStatuses();
31868
32040
  return {
31869
32041
  success: true,
@@ -31905,7 +32077,7 @@ async function getWorkspaceStatus(workspacePath = process.cwd()) {
31905
32077
  function getPluginStatus(parsed) {
31906
32078
  if (parsed.type === "github") {
31907
32079
  const cachePath = parsed.owner && parsed.repo ? getPluginCachePath(parsed.owner, parsed.repo) : "";
31908
- const available2 = cachePath ? existsSync20(cachePath) : false;
32080
+ const available2 = cachePath ? existsSync21(cachePath) : false;
31909
32081
  return {
31910
32082
  source: parsed.original,
31911
32083
  type: "github",
@@ -31915,7 +32087,7 @@ function getPluginStatus(parsed) {
31915
32087
  ...parsed.repo && { repo: parsed.repo }
31916
32088
  };
31917
32089
  }
31918
- const available = existsSync20(parsed.normalized);
32090
+ const available = existsSync21(parsed.normalized);
31919
32091
  return {
31920
32092
  source: parsed.original,
31921
32093
  type: "local",
@@ -32144,8 +32316,9 @@ function formatNativeResult(nativeResult) {
32144
32316
  if (nativeResult.marketplacesAdded.length > 0) {
32145
32317
  lines.push(`Marketplaces registered: ${nativeResult.marketplacesAdded.join(", ")}`);
32146
32318
  }
32147
- for (const plugin of nativeResult.pluginsInstalled) {
32148
- lines.push(` + ${plugin} (installed via native CLI)`);
32319
+ for (const { plugin, client } of nativeResult.pluginsInstalled) {
32320
+ const cliName = client ? `${client} CLI` : "native CLI";
32321
+ lines.push(` + ${plugin} (installed via ${cliName})`);
32149
32322
  }
32150
32323
  for (const { client, plugin, error } of nativeResult.pluginsFailed) {
32151
32324
  const provider = client ? `[${client}] ` : "";
@@ -32242,14 +32415,38 @@ function buildSyncData(result) {
32242
32415
  },
32243
32416
  ...result.nativeResult && {
32244
32417
  nativePlugins: {
32245
- installed: result.nativeResult.pluginsInstalled,
32418
+ installed: result.nativeResult.pluginsInstalled.map((p) => p.plugin),
32246
32419
  failed: result.nativeResult.pluginsFailed,
32247
32420
  skipped: result.nativeResult.skipped,
32248
32421
  marketplacesAdded: result.nativeResult.marketplacesAdded
32249
32422
  }
32423
+ },
32424
+ ...result.managedRepoResults && result.managedRepoResults.length > 0 && {
32425
+ managedRepos: result.managedRepoResults.map((r) => ({
32426
+ repo: r.repo,
32427
+ path: r.path,
32428
+ action: r.action,
32429
+ ...r.error && { error: r.error }
32430
+ }))
32250
32431
  }
32251
32432
  };
32252
32433
  }
32434
+ function formatManagedRepoResults(results) {
32435
+ const actionResults = results.filter((r) => r.action !== "skipped" || r.error);
32436
+ if (actionResults.length === 0)
32437
+ return [];
32438
+ const lines = ["Repositories:"];
32439
+ for (const r of actionResults) {
32440
+ if (r.action === "cloned") {
32441
+ lines.push(` ✓ Cloned ${r.repo} → ${r.path}`);
32442
+ } else if (r.action === "pulled") {
32443
+ lines.push(` ✓ Pulled ${r.repo}`);
32444
+ } else if (r.error) {
32445
+ lines.push(` ✗ ${r.repo}: ${r.error}`);
32446
+ }
32447
+ }
32448
+ return lines;
32449
+ }
32253
32450
  var cachedLookup = null;
32254
32451
  var init_format_sync = __esm(() => {
32255
32452
  init_client_mapping();
@@ -34052,9 +34249,9 @@ var init_prompt_clients = __esm(() => {
34052
34249
  });
34053
34250
 
34054
34251
  // src/core/skills.ts
34055
- import { existsSync as existsSync23 } from "node:fs";
34252
+ import { existsSync as existsSync24 } from "node:fs";
34056
34253
  import { readFile as readFile14, readdir as readdir5 } from "node:fs/promises";
34057
- import { join as join25, basename as basename7, resolve as resolve13 } from "node:path";
34254
+ import { join as join25, basename as basename7, resolve as resolve14 } from "node:path";
34058
34255
  async function resolvePluginPath(pluginSource, workspacePath) {
34059
34256
  if (isPluginSpec(pluginSource)) {
34060
34257
  const resolved2 = await resolvePluginSpecWithAutoRegister(pluginSource, {
@@ -34078,12 +34275,12 @@ async function resolvePluginPath(pluginSource, workspacePath) {
34078
34275
  const path = parsed?.subpath ? join25(result.cachePath, parsed.subpath) : result.cachePath;
34079
34276
  return { path };
34080
34277
  }
34081
- const resolved = resolve13(workspacePath, pluginSource);
34082
- return existsSync23(resolved) ? { path: resolved } : null;
34278
+ const resolved = resolve14(workspacePath, pluginSource);
34279
+ return existsSync24(resolved) ? { path: resolved } : null;
34083
34280
  }
34084
34281
  async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
34085
34282
  const configPath = join25(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34086
- if (!existsSync23(configPath)) {
34283
+ if (!existsSync24(configPath)) {
34087
34284
  return [];
34088
34285
  }
34089
34286
  const content = await readFile14(configPath, "utf-8");
@@ -34103,7 +34300,7 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
34103
34300
  const pluginSkillsConfig = typeof pluginEntry === "string" ? undefined : pluginEntry.skills;
34104
34301
  const hasEnabledEntries = !pluginSkillsConfig && enabledSkills && [...enabledSkills].some((s) => s.startsWith(`${pluginName}`));
34105
34302
  let skillEntries;
34106
- if (existsSync23(skillsDir)) {
34303
+ if (existsSync24(skillsDir)) {
34107
34304
  const entries = await readdir5(skillsDir, { withFileTypes: true });
34108
34305
  skillEntries = entries.filter((e) => e.isDirectory()).map((e) => ({ name: e.name, skillPath: join25(skillsDir, e.name) }));
34109
34306
  } else {
@@ -34113,7 +34310,7 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
34113
34310
  if (!entry.isDirectory())
34114
34311
  continue;
34115
34312
  const skillMdPath = join25(pluginPath, entry.name, "SKILL.md");
34116
- if (existsSync23(skillMdPath)) {
34313
+ if (existsSync24(skillMdPath)) {
34117
34314
  flatSkills.push({ name: entry.name, skillPath: join25(pluginPath, entry.name) });
34118
34315
  }
34119
34316
  }
@@ -34121,7 +34318,7 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
34121
34318
  skillEntries = flatSkills;
34122
34319
  } else {
34123
34320
  const rootSkillMd = join25(pluginPath, "SKILL.md");
34124
- if (existsSync23(rootSkillMd)) {
34321
+ if (existsSync24(rootSkillMd)) {
34125
34322
  const skillContent = await readFile14(rootSkillMd, "utf-8");
34126
34323
  const metadata = parseSkillMetadata(skillContent);
34127
34324
  const skillName = metadata?.name ?? basename7(pluginPath);
@@ -34163,10 +34360,10 @@ async function findSkillByName(skillName, workspacePath = process.cwd()) {
34163
34360
  return allSkills.filter((s) => s.name === skillName);
34164
34361
  }
34165
34362
  async function discoverSkillNames(pluginPath) {
34166
- if (!existsSync23(pluginPath))
34363
+ if (!existsSync24(pluginPath))
34167
34364
  return [];
34168
34365
  const skillsDir = join25(pluginPath, "skills");
34169
- if (existsSync23(skillsDir)) {
34366
+ if (existsSync24(skillsDir)) {
34170
34367
  const entries2 = await readdir5(skillsDir, { withFileTypes: true });
34171
34368
  return entries2.filter((e) => e.isDirectory()).map((e) => e.name);
34172
34369
  }
@@ -34175,14 +34372,14 @@ async function discoverSkillNames(pluginPath) {
34175
34372
  for (const entry of entries) {
34176
34373
  if (!entry.isDirectory())
34177
34374
  continue;
34178
- if (existsSync23(join25(pluginPath, entry.name, "SKILL.md"))) {
34375
+ if (existsSync24(join25(pluginPath, entry.name, "SKILL.md"))) {
34179
34376
  flatSkills.push(entry.name);
34180
34377
  }
34181
34378
  }
34182
34379
  if (flatSkills.length > 0)
34183
34380
  return flatSkills;
34184
34381
  const rootSkillMd = join25(pluginPath, "SKILL.md");
34185
- if (existsSync23(rootSkillMd)) {
34382
+ if (existsSync24(rootSkillMd)) {
34186
34383
  try {
34187
34384
  const content = await readFile14(rootSkillMd, "utf-8");
34188
34385
  const { parseSkillMetadata: parseSkillMetadata2 } = await Promise.resolve().then(() => (init_skill(), exports_skill));
@@ -34293,12 +34490,12 @@ var require_isexe = __commonJS((exports, module) => {
34293
34490
  if (typeof Promise !== "function") {
34294
34491
  throw new TypeError("callback not provided");
34295
34492
  }
34296
- return new Promise(function(resolve14, reject) {
34493
+ return new Promise(function(resolve15, reject) {
34297
34494
  isexe(path, options2 || {}, function(er, is) {
34298
34495
  if (er) {
34299
34496
  reject(er);
34300
34497
  } else {
34301
- resolve14(is);
34498
+ resolve15(is);
34302
34499
  }
34303
34500
  });
34304
34501
  });
@@ -34360,27 +34557,27 @@ var require_which = __commonJS((exports, module) => {
34360
34557
  opt = {};
34361
34558
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
34362
34559
  const found = [];
34363
- const step = (i2) => new Promise((resolve14, reject) => {
34560
+ const step = (i2) => new Promise((resolve15, reject) => {
34364
34561
  if (i2 === pathEnv.length)
34365
- return opt.all && found.length ? resolve14(found) : reject(getNotFoundError(cmd));
34562
+ return opt.all && found.length ? resolve15(found) : reject(getNotFoundError(cmd));
34366
34563
  const ppRaw = pathEnv[i2];
34367
34564
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
34368
34565
  const pCmd = path.join(pathPart, cmd);
34369
34566
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
34370
- resolve14(subStep(p, i2, 0));
34567
+ resolve15(subStep(p, i2, 0));
34371
34568
  });
34372
- const subStep = (p, i2, ii) => new Promise((resolve14, reject) => {
34569
+ const subStep = (p, i2, ii) => new Promise((resolve15, reject) => {
34373
34570
  if (ii === pathExt.length)
34374
- return resolve14(step(i2 + 1));
34571
+ return resolve15(step(i2 + 1));
34375
34572
  const ext = pathExt[ii];
34376
34573
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
34377
34574
  if (!er && is) {
34378
34575
  if (opt.all)
34379
34576
  found.push(p + ext);
34380
34577
  else
34381
- return resolve14(p + ext);
34578
+ return resolve15(p + ext);
34382
34579
  }
34383
- return resolve14(subStep(p, i2, ii + 1));
34580
+ return resolve15(subStep(p, i2, ii + 1));
34384
34581
  });
34385
34582
  });
34386
34583
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -34702,7 +34899,7 @@ var package_default;
34702
34899
  var init_package = __esm(() => {
34703
34900
  package_default = {
34704
34901
  name: "allagents",
34705
- version: "1.7.1",
34902
+ version: "1.7.2-next.1",
34706
34903
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
34707
34904
  type: "module",
34708
34905
  bin: {
@@ -34729,7 +34926,9 @@ var init_package = __esm(() => {
34729
34926
  prepare: "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
34730
34927
  release: "bun run scripts/release.ts",
34731
34928
  "release:next": "bun run scripts/release.ts next",
34929
+ "release:finalize": "bun run scripts/release.ts finalize",
34732
34930
  prepublishOnly: `test "$ALLOW_PUBLISH" = '1' || (echo 'ERROR: Use bun run publish:next, then bun run promote:latest' && exit 1)`,
34931
+ publish: "bun run build && ALLOW_PUBLISH=1 npm publish",
34733
34932
  "publish:next": "bun run build && ALLOW_PUBLISH=1 npm publish --tag next",
34734
34933
  "promote:latest": "bun scripts/tag-channel.ts latest"
34735
34934
  },
@@ -34912,7 +35111,7 @@ class TuiCache {
34912
35111
  }
34913
35112
 
34914
35113
  // src/cli/tui/context.ts
34915
- import { existsSync as existsSync26 } from "node:fs";
35114
+ import { existsSync as existsSync27 } from "node:fs";
34916
35115
  import { join as join29 } from "node:path";
34917
35116
  async function getTuiContext(cwd = process.cwd(), cache2) {
34918
35117
  const cachedContext = cache2?.getContext();
@@ -34920,7 +35119,7 @@ async function getTuiContext(cwd = process.cwd(), cache2) {
34920
35119
  return cachedContext;
34921
35120
  }
34922
35121
  const configPath = join29(cwd, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
34923
- const hasWorkspace = existsSync26(configPath) && !isUserConfigPath(cwd);
35122
+ const hasWorkspace = existsSync27(configPath) && !isUserConfigPath(cwd);
34924
35123
  let projectPluginCount = 0;
34925
35124
  if (hasWorkspace) {
34926
35125
  try {
@@ -36336,8 +36535,8 @@ init_workspace();
36336
36535
  init_sync();
36337
36536
  init_status2();
36338
36537
  var import_cmd_ts2 = __toESM(require_cjs(), 1);
36339
- import { existsSync as existsSync22 } from "node:fs";
36340
- import { join as join24, resolve as resolve12 } from "node:path";
36538
+ import { existsSync as existsSync23 } from "node:fs";
36539
+ import { join as join24, resolve as resolve13 } from "node:path";
36341
36540
 
36342
36541
  // src/core/prune.ts
36343
36542
  init_js_yaml();
@@ -36346,7 +36545,7 @@ init_marketplace();
36346
36545
  init_user_workspace();
36347
36546
  init_workspace_config();
36348
36547
  import { readFile as readFile13, writeFile as writeFile9 } from "node:fs/promises";
36349
- import { existsSync as existsSync21 } from "node:fs";
36548
+ import { existsSync as existsSync22 } from "node:fs";
36350
36549
  import { join as join23 } from "node:path";
36351
36550
  async function isOrphanedPlugin(pluginSpec) {
36352
36551
  if (!isPluginSpec(pluginSpec))
@@ -36375,7 +36574,7 @@ async function prunePlugins(plugins) {
36375
36574
  async function pruneOrphanedPlugins(workspacePath) {
36376
36575
  let projectResult = { removed: [], kept: [], keptEntries: [] };
36377
36576
  const projectConfigPath = join23(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
36378
- if (existsSync21(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36577
+ if (existsSync22(projectConfigPath) && !isUserConfigPath(workspacePath)) {
36379
36578
  const content = await readFile13(projectConfigPath, "utf-8");
36380
36579
  const config = load(content);
36381
36580
  projectResult = await prunePlugins(config.plugins);
@@ -36658,9 +36857,10 @@ var syncCmd = import_cmd_ts2.command({
36658
36857
  offline: import_cmd_ts2.flag({ long: "offline", description: "Use cached plugins without fetching latest from remote" }),
36659
36858
  dryRun: import_cmd_ts2.flag({ long: "dry-run", short: "n", description: "Simulate sync without making changes" }),
36660
36859
  force: import_cmd_ts2.flag({ long: "force", short: "f", description: "Overwrite existing MCP server entries that differ from plugin config" }),
36661
- verbose: import_cmd_ts2.flag({ long: "verbose", short: "v", description: "Show informational sync messages" })
36860
+ verbose: import_cmd_ts2.flag({ long: "verbose", short: "v", description: "Show informational sync messages" }),
36861
+ noManaged: import_cmd_ts2.flag({ long: "no-managed", description: "Skip managed repository clone/pull operations" })
36662
36862
  },
36663
- handler: async ({ offline, dryRun, force, verbose }) => {
36863
+ handler: async ({ offline, dryRun, force, verbose, noManaged }) => {
36664
36864
  try {
36665
36865
  if (!isJsonMode() && dryRun) {
36666
36866
  console.log(`Dry run mode - no changes will be made
@@ -36668,7 +36868,7 @@ var syncCmd = import_cmd_ts2.command({
36668
36868
  }
36669
36869
  const userConfigExists = !!await getUserWorkspaceConfig();
36670
36870
  const projectConfigPath = join24(process.cwd(), ".allagents", "workspace.yaml");
36671
- const projectConfigExists = existsSync22(projectConfigPath);
36871
+ const projectConfigExists = existsSync23(projectConfigPath);
36672
36872
  if (!userConfigExists && !projectConfigExists) {
36673
36873
  await ensureUserWorkspace();
36674
36874
  if (isJsonMode()) {
@@ -36688,7 +36888,8 @@ var syncCmd = import_cmd_ts2.command({
36688
36888
  if (projectConfigExists) {
36689
36889
  const projectResult = await syncWorkspace(process.cwd(), {
36690
36890
  offline,
36691
- dryRun
36891
+ dryRun,
36892
+ skipManaged: noManaged
36692
36893
  });
36693
36894
  combined = combined ? mergeSyncResults(combined, projectResult) : projectResult;
36694
36895
  }
@@ -36717,6 +36918,12 @@ var syncCmd = import_cmd_ts2.command({
36717
36918
  }
36718
36919
  console.log("");
36719
36920
  }
36921
+ if (result.managedRepoResults && result.managedRepoResults.length > 0) {
36922
+ for (const line of formatManagedRepoResults(result.managedRepoResults)) {
36923
+ console.log(line);
36924
+ }
36925
+ console.log("");
36926
+ }
36720
36927
  for (const line of formatSyncHeader(result)) {
36721
36928
  console.log(line);
36722
36929
  }
@@ -36956,7 +37163,7 @@ var repoAddCmd = import_cmd_ts2.command({
36956
37163
  },
36957
37164
  handler: async ({ path: repoPath, description }) => {
36958
37165
  try {
36959
- const resolvedPath = resolve12(process.cwd(), repoPath);
37166
+ const resolvedPath = resolve13(process.cwd(), repoPath);
36960
37167
  const remote = await detectRemote(resolvedPath);
36961
37168
  const result = await addRepository(repoPath, {
36962
37169
  source: remote?.source,
@@ -37336,7 +37543,7 @@ init_workspace_modify();
37336
37543
  init_user_workspace();
37337
37544
  init_skills();
37338
37545
  var import_cmd_ts3 = __toESM(require_cjs(), 1);
37339
- import { existsSync as existsSync24 } from "node:fs";
37546
+ import { existsSync as existsSync25 } from "node:fs";
37340
37547
  import { readFile as readFile15 } from "node:fs/promises";
37341
37548
  import { join as join26 } from "node:path";
37342
37549
 
@@ -37429,7 +37636,7 @@ init_skill();
37429
37636
  init_marketplace();
37430
37637
  init_marketplace_manifest_parser();
37431
37638
  function hasProjectConfig(dir) {
37432
- return existsSync24(join26(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37639
+ return existsSync25(join26(dir, CONFIG_DIR, WORKSPACE_CONFIG_FILE));
37433
37640
  }
37434
37641
  function resolveScope(cwd) {
37435
37642
  if (isUserConfigPath(cwd))
@@ -38018,7 +38225,7 @@ init_workspace_config();
38018
38225
  init_constants();
38019
38226
  init_js_yaml();
38020
38227
  import { readFile as readFile16 } from "node:fs/promises";
38021
- import { existsSync as existsSync25 } from "node:fs";
38228
+ import { existsSync as existsSync26 } from "node:fs";
38022
38229
  import { join as join27 } from "node:path";
38023
38230
  async function runSyncAndPrint(options2) {
38024
38231
  if (!isJsonMode()) {
@@ -38264,7 +38471,7 @@ var marketplaceAddCmd = import_cmd_ts4.command({
38264
38471
  process.exit(1);
38265
38472
  }
38266
38473
  if (effectiveScope === "project") {
38267
- if (!existsSync25(join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38474
+ if (!existsSync26(join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE))) {
38268
38475
  const msg = 'No workspace found in current directory. Run "allagents workspace init" first.';
38269
38476
  if (isJsonMode()) {
38270
38477
  jsonOutput({ success: false, command: "plugin marketplace add", error: msg });
@@ -38571,7 +38778,7 @@ var pluginListCmd = import_cmd_ts4.command({
38571
38778
  };
38572
38779
  const pluginClients = new Map;
38573
38780
  async function loadConfigClients(configPath, scope) {
38574
- if (!existsSync25(configPath))
38781
+ if (!existsSync26(configPath))
38575
38782
  return;
38576
38783
  try {
38577
38784
  const content = await readFile16(configPath, "utf-8");
@@ -38729,7 +38936,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
38729
38936
  const isUser = scope === "user" || !scope && isUserConfigPath(process.cwd());
38730
38937
  if (isUser) {
38731
38938
  const userConfigPath = getUserWorkspaceConfigPath();
38732
- if (!existsSync25(userConfigPath)) {
38939
+ if (!existsSync26(userConfigPath)) {
38733
38940
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38734
38941
  const clients = await promptForClients2();
38735
38942
  if (clients === null) {
@@ -38742,7 +38949,7 @@ var pluginInstallCmd = import_cmd_ts4.command({
38742
38949
  }
38743
38950
  } else {
38744
38951
  const configPath = join27(process.cwd(), CONFIG_DIR, WORKSPACE_CONFIG_FILE);
38745
- if (!existsSync25(configPath)) {
38952
+ if (!existsSync26(configPath)) {
38746
38953
  const { promptForClients: promptForClients2 } = await Promise.resolve().then(() => (init_prompt_clients(), exports_prompt_clients));
38747
38954
  const clients = await promptForClients2();
38748
38955
  if (clients === null) {
@@ -39019,13 +39226,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
39019
39226
  }
39020
39227
  }
39021
39228
  if (updateProject && !isUserConfigPath(process.cwd())) {
39022
- const { existsSync: existsSync26 } = await import("node:fs");
39229
+ const { existsSync: existsSync27 } = await import("node:fs");
39023
39230
  const { readFile: readFile17 } = await import("node:fs/promises");
39024
39231
  const { join: join28 } = await import("node:path");
39025
39232
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
39026
39233
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
39027
39234
  const configPath = join28(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
39028
- if (existsSync26(configPath)) {
39235
+ if (existsSync27(configPath)) {
39029
39236
  const content = await readFile17(configPath, "utf-8");
39030
39237
  const config = load2(content);
39031
39238
  for (const entry of config.plugins ?? []) {
@@ -40058,7 +40265,7 @@ var setupTimeout = (spawned, { timeout, killSignal = "SIGTERM" }, spawnedPromise
40058
40265
  return spawnedPromise;
40059
40266
  }
40060
40267
  let timeoutId;
40061
- const timeoutPromise = new Promise((resolve14, reject) => {
40268
+ const timeoutPromise = new Promise((resolve15, reject) => {
40062
40269
  timeoutId = setTimeout(() => {
40063
40270
  timeoutKill(spawned, killSignal, reject);
40064
40271
  }, timeout);
@@ -40422,9 +40629,9 @@ var mergePromise = (spawned, promise) => {
40422
40629
  Reflect.defineProperty(spawned, property, { ...descriptor, value });
40423
40630
  }
40424
40631
  };
40425
- var getSpawnedPromise = (spawned) => new Promise((resolve14, reject) => {
40632
+ var getSpawnedPromise = (spawned) => new Promise((resolve15, reject) => {
40426
40633
  spawned.on("exit", (exitCode, signal) => {
40427
- resolve14({ exitCode, signal });
40634
+ resolve15({ exitCode, signal });
40428
40635
  });
40429
40636
  spawned.on("error", (error) => {
40430
40637
  reject(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "1.7.1",
3
+ "version": "1.7.2-next.1",
4
4
  "description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,7 +27,9 @@
27
27
  "prepare": "bun run build && (test -d .git && bunx prek install -t pre-push || true)",
28
28
  "release": "bun run scripts/release.ts",
29
29
  "release:next": "bun run scripts/release.ts next",
30
+ "release:finalize": "bun run scripts/release.ts finalize",
30
31
  "prepublishOnly": "test \"$ALLOW_PUBLISH\" = '1' || (echo 'ERROR: Use bun run publish:next, then bun run promote:latest' && exit 1)",
32
+ "publish": "bun run build && ALLOW_PUBLISH=1 npm publish",
31
33
  "publish:next": "bun run build && ALLOW_PUBLISH=1 npm publish --tag next",
32
34
  "promote:latest": "bun scripts/tag-channel.ts latest"
33
35
  },