allagents 0.26.5 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +0 -3
  2. package/dist/index.js +1099 -1075
  3. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -11462,6 +11462,9 @@ function getPluginClients(plugin) {
11462
11462
  function getPluginInstallMode(plugin) {
11463
11463
  return typeof plugin === "string" ? undefined : plugin.install;
11464
11464
  }
11465
+ function getPluginExclude(plugin) {
11466
+ return typeof plugin === "string" ? undefined : plugin.exclude;
11467
+ }
11465
11468
  function normalizeClientEntry(entry) {
11466
11469
  if (typeof entry === "string") {
11467
11470
  return { name: entry, install: "file" };
@@ -11537,7 +11540,8 @@ var init_workspace_config = __esm(() => {
11537
11540
  exports_external.object({
11538
11541
  source: PluginSourceSchema,
11539
11542
  clients: exports_external.array(ClientTypeSchema).optional(),
11540
- install: InstallModeSchema.optional()
11543
+ install: InstallModeSchema.optional(),
11544
+ exclude: exports_external.array(exports_external.string()).optional()
11541
11545
  })
11542
11546
  ]);
11543
11547
  VscodeConfigSchema = exports_external.object({
@@ -15909,21 +15913,8 @@ var init_plugin_path = __esm(() => {
15909
15913
  init_constants();
15910
15914
  });
15911
15915
 
15912
- // src/models/plugin-config.ts
15913
- var PluginManifestSchema;
15914
- var init_plugin_config = __esm(() => {
15915
- init_zod();
15916
- PluginManifestSchema = exports_external.object({
15917
- name: exports_external.string(),
15918
- version: exports_external.string(),
15919
- description: exports_external.string(),
15920
- author: exports_external.string().optional(),
15921
- license: exports_external.string().optional()
15922
- });
15923
- });
15924
-
15925
15916
  // src/core/plugin.ts
15926
- import { mkdir, readdir, stat, readFile as readFile2 } from "node:fs/promises";
15917
+ import { mkdir, readdir, stat } from "node:fs/promises";
15927
15918
  import { existsSync as existsSync2 } from "node:fs";
15928
15919
  import { basename, dirname, join as join3, resolve as resolve3 } from "node:path";
15929
15920
  async function fetchPlugin(url, options = {}, deps = {}) {
@@ -16022,18 +16013,7 @@ async function doFetchPlugin(cachePath, owner, repo, offline, branch, deps) {
16022
16013
  };
16023
16014
  }
16024
16015
  }
16025
- async function getPluginName(pluginPath) {
16026
- const manifestPath = join3(pluginPath, "plugin.json");
16027
- if (existsSync2(manifestPath)) {
16028
- try {
16029
- const content = await readFile2(manifestPath, "utf-8");
16030
- const manifest = JSON.parse(content);
16031
- const result = PluginManifestSchema.safeParse(manifest);
16032
- if (result.success && result.data.name) {
16033
- return result.data.name;
16034
- }
16035
- } catch {}
16036
- }
16016
+ function getPluginName(pluginPath) {
16037
16017
  return basename(pluginPath);
16038
16018
  }
16039
16019
  async function updatePlugin(pluginSpec, deps) {
@@ -16113,448 +16093,157 @@ async function updatePlugin(pluginSpec, deps) {
16113
16093
  var inflight;
16114
16094
  var init_plugin = __esm(() => {
16115
16095
  init_plugin_path();
16116
- init_plugin_config();
16117
16096
  init_constants();
16118
16097
  init_git();
16119
16098
  inflight = new Map;
16120
16099
  });
16121
16100
 
16122
- // node_modules/fast-glob/out/utils/array.js
16123
- var require_array = __commonJS((exports) => {
16124
- Object.defineProperty(exports, "__esModule", { value: true });
16125
- exports.splitWhen = exports.flatten = undefined;
16126
- function flatten(items) {
16127
- return items.reduce((collection, item) => [].concat(collection, item), []);
16128
- }
16129
- exports.flatten = flatten;
16130
- function splitWhen(items, predicate) {
16131
- const result = [[]];
16132
- let groupIndex = 0;
16133
- for (const item of items) {
16134
- if (predicate(item)) {
16135
- groupIndex++;
16136
- result[groupIndex] = [];
16137
- } else {
16138
- result[groupIndex].push(item);
16101
+ // node_modules/braces/lib/utils.js
16102
+ var require_utils2 = __commonJS((exports) => {
16103
+ exports.isInteger = (num) => {
16104
+ if (typeof num === "number") {
16105
+ return Number.isInteger(num);
16106
+ }
16107
+ if (typeof num === "string" && num.trim() !== "") {
16108
+ return Number.isInteger(Number(num));
16109
+ }
16110
+ return false;
16111
+ };
16112
+ exports.find = (node, type2) => node.nodes.find((node2) => node2.type === type2);
16113
+ exports.exceedsLimit = (min, max, step = 1, limit) => {
16114
+ if (limit === false)
16115
+ return false;
16116
+ if (!exports.isInteger(min) || !exports.isInteger(max))
16117
+ return false;
16118
+ return (Number(max) - Number(min)) / Number(step) >= limit;
16119
+ };
16120
+ exports.escapeNode = (block, n = 0, type2) => {
16121
+ const node = block.nodes[n];
16122
+ if (!node)
16123
+ return;
16124
+ if (type2 && node.type === type2 || node.type === "open" || node.type === "close") {
16125
+ if (node.escaped !== true) {
16126
+ node.value = "\\" + node.value;
16127
+ node.escaped = true;
16139
16128
  }
16140
16129
  }
16141
- return result;
16142
- }
16143
- exports.splitWhen = splitWhen;
16144
- });
16145
-
16146
- // node_modules/fast-glob/out/utils/errno.js
16147
- var require_errno = __commonJS((exports) => {
16148
- Object.defineProperty(exports, "__esModule", { value: true });
16149
- exports.isEnoentCodeError = undefined;
16150
- function isEnoentCodeError(error) {
16151
- return error.code === "ENOENT";
16152
- }
16153
- exports.isEnoentCodeError = isEnoentCodeError;
16154
- });
16155
-
16156
- // node_modules/fast-glob/out/utils/fs.js
16157
- var require_fs = __commonJS((exports) => {
16158
- Object.defineProperty(exports, "__esModule", { value: true });
16159
- exports.createDirentFromStats = undefined;
16160
-
16161
- class DirentFromStats {
16162
- constructor(name, stats) {
16163
- this.name = name;
16164
- this.isBlockDevice = stats.isBlockDevice.bind(stats);
16165
- this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
16166
- this.isDirectory = stats.isDirectory.bind(stats);
16167
- this.isFIFO = stats.isFIFO.bind(stats);
16168
- this.isFile = stats.isFile.bind(stats);
16169
- this.isSocket = stats.isSocket.bind(stats);
16170
- this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
16130
+ };
16131
+ exports.encloseBrace = (node) => {
16132
+ if (node.type !== "brace")
16133
+ return false;
16134
+ if (node.commas >> 0 + node.ranges >> 0 === 0) {
16135
+ node.invalid = true;
16136
+ return true;
16171
16137
  }
16172
- }
16173
- function createDirentFromStats(name, stats) {
16174
- return new DirentFromStats(name, stats);
16175
- }
16176
- exports.createDirentFromStats = createDirentFromStats;
16138
+ return false;
16139
+ };
16140
+ exports.isInvalidBrace = (block) => {
16141
+ if (block.type !== "brace")
16142
+ return false;
16143
+ if (block.invalid === true || block.dollar)
16144
+ return true;
16145
+ if (block.commas >> 0 + block.ranges >> 0 === 0) {
16146
+ block.invalid = true;
16147
+ return true;
16148
+ }
16149
+ if (block.open !== true || block.close !== true) {
16150
+ block.invalid = true;
16151
+ return true;
16152
+ }
16153
+ return false;
16154
+ };
16155
+ exports.isOpenOrClose = (node) => {
16156
+ if (node.type === "open" || node.type === "close") {
16157
+ return true;
16158
+ }
16159
+ return node.open === true || node.close === true;
16160
+ };
16161
+ exports.reduce = (nodes) => nodes.reduce((acc, node) => {
16162
+ if (node.type === "text")
16163
+ acc.push(node.value);
16164
+ if (node.type === "range")
16165
+ node.type = "text";
16166
+ return acc;
16167
+ }, []);
16168
+ exports.flatten = (...args) => {
16169
+ const result = [];
16170
+ const flat = (arr) => {
16171
+ for (let i2 = 0;i2 < arr.length; i2++) {
16172
+ const ele = arr[i2];
16173
+ if (Array.isArray(ele)) {
16174
+ flat(ele);
16175
+ continue;
16176
+ }
16177
+ if (ele !== undefined) {
16178
+ result.push(ele);
16179
+ }
16180
+ }
16181
+ return result;
16182
+ };
16183
+ flat(args);
16184
+ return result;
16185
+ };
16177
16186
  });
16178
16187
 
16179
- // node_modules/fast-glob/out/utils/path.js
16180
- var require_path = __commonJS((exports) => {
16181
- Object.defineProperty(exports, "__esModule", { value: true });
16182
- exports.convertPosixPathToPattern = exports.convertWindowsPathToPattern = exports.convertPathToPattern = exports.escapePosixPath = exports.escapeWindowsPath = exports.escape = exports.removeLeadingDotSegment = exports.makeAbsolute = exports.unixify = undefined;
16183
- var os2 = __require("os");
16184
- var path = __require("path");
16185
- var IS_WINDOWS_PLATFORM = os2.platform() === "win32";
16186
- var LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2;
16187
- var POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
16188
- var WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g;
16189
- var DOS_DEVICE_PATH_RE = /^\\\\([.?])/;
16190
- var WINDOWS_BACKSLASHES_RE = /\\(?![!()+@[\]{}])/g;
16191
- function unixify(filepath) {
16192
- return filepath.replace(/\\/g, "/");
16193
- }
16194
- exports.unixify = unixify;
16195
- function makeAbsolute(cwd, filepath) {
16196
- return path.resolve(cwd, filepath);
16197
- }
16198
- exports.makeAbsolute = makeAbsolute;
16199
- function removeLeadingDotSegment(entry) {
16200
- if (entry.charAt(0) === ".") {
16201
- const secondCharactery = entry.charAt(1);
16202
- if (secondCharactery === "/" || secondCharactery === "\\") {
16203
- return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT);
16188
+ // node_modules/braces/lib/stringify.js
16189
+ var require_stringify2 = __commonJS((exports, module) => {
16190
+ var utils = require_utils2();
16191
+ module.exports = (ast, options = {}) => {
16192
+ const stringify = (node, parent = {}) => {
16193
+ const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
16194
+ const invalidNode = node.invalid === true && options.escapeInvalid === true;
16195
+ let output = "";
16196
+ if (node.value) {
16197
+ if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
16198
+ return "\\" + node.value;
16199
+ }
16200
+ return node.value;
16204
16201
  }
16205
- }
16206
- return entry;
16207
- }
16208
- exports.removeLeadingDotSegment = removeLeadingDotSegment;
16209
- exports.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath;
16210
- function escapeWindowsPath(pattern) {
16211
- return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, "\\$2");
16212
- }
16213
- exports.escapeWindowsPath = escapeWindowsPath;
16214
- function escapePosixPath(pattern) {
16215
- return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, "\\$2");
16216
- }
16217
- exports.escapePosixPath = escapePosixPath;
16218
- exports.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern;
16219
- function convertWindowsPathToPattern(filepath) {
16220
- return escapeWindowsPath(filepath).replace(DOS_DEVICE_PATH_RE, "//$1").replace(WINDOWS_BACKSLASHES_RE, "/");
16221
- }
16222
- exports.convertWindowsPathToPattern = convertWindowsPathToPattern;
16223
- function convertPosixPathToPattern(filepath) {
16224
- return escapePosixPath(filepath);
16225
- }
16226
- exports.convertPosixPathToPattern = convertPosixPathToPattern;
16202
+ if (node.value) {
16203
+ return node.value;
16204
+ }
16205
+ if (node.nodes) {
16206
+ for (const child of node.nodes) {
16207
+ output += stringify(child);
16208
+ }
16209
+ }
16210
+ return output;
16211
+ };
16212
+ return stringify(ast);
16213
+ };
16227
16214
  });
16228
16215
 
16229
- // node_modules/is-extglob/index.js
16230
- var require_is_extglob = __commonJS((exports, module) => {
16216
+ // node_modules/is-number/index.js
16217
+ var require_is_number = __commonJS((exports, module) => {
16231
16218
  /*!
16232
- * is-extglob <https://github.com/jonschlinkert/is-extglob>
16219
+ * is-number <https://github.com/jonschlinkert/is-number>
16233
16220
  *
16234
- * Copyright (c) 2014-2016, Jon Schlinkert.
16235
- * Licensed under the MIT License.
16221
+ * Copyright (c) 2014-present, Jon Schlinkert.
16222
+ * Released under the MIT License.
16236
16223
  */
16237
- module.exports = function isExtglob(str2) {
16238
- if (typeof str2 !== "string" || str2 === "") {
16239
- return false;
16224
+ module.exports = function(num) {
16225
+ if (typeof num === "number") {
16226
+ return num - num === 0;
16240
16227
  }
16241
- var match;
16242
- while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str2)) {
16243
- if (match[2])
16244
- return true;
16245
- str2 = str2.slice(match.index + match[0].length);
16228
+ if (typeof num === "string" && num.trim() !== "") {
16229
+ return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
16246
16230
  }
16247
16231
  return false;
16248
16232
  };
16249
16233
  });
16250
16234
 
16251
- // node_modules/is-glob/index.js
16252
- var require_is_glob = __commonJS((exports, module) => {
16235
+ // node_modules/to-regex-range/index.js
16236
+ var require_to_regex_range = __commonJS((exports, module) => {
16253
16237
  /*!
16254
- * is-glob <https://github.com/jonschlinkert/is-glob>
16238
+ * to-regex-range <https://github.com/micromatch/to-regex-range>
16255
16239
  *
16256
- * Copyright (c) 2014-2017, Jon Schlinkert.
16240
+ * Copyright (c) 2015-present, Jon Schlinkert.
16257
16241
  * Released under the MIT License.
16258
16242
  */
16259
- var isExtglob = require_is_extglob();
16260
- var chars = { "{": "}", "(": ")", "[": "]" };
16261
- var strictCheck = function(str2) {
16262
- if (str2[0] === "!") {
16263
- return true;
16264
- }
16265
- var index = 0;
16266
- var pipeIndex = -2;
16267
- var closeSquareIndex = -2;
16268
- var closeCurlyIndex = -2;
16269
- var closeParenIndex = -2;
16270
- var backSlashIndex = -2;
16271
- while (index < str2.length) {
16272
- if (str2[index] === "*") {
16273
- return true;
16274
- }
16275
- if (str2[index + 1] === "?" && /[\].+)]/.test(str2[index])) {
16276
- return true;
16277
- }
16278
- if (closeSquareIndex !== -1 && str2[index] === "[" && str2[index + 1] !== "]") {
16279
- if (closeSquareIndex < index) {
16280
- closeSquareIndex = str2.indexOf("]", index);
16281
- }
16282
- if (closeSquareIndex > index) {
16283
- if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
16284
- return true;
16285
- }
16286
- backSlashIndex = str2.indexOf("\\", index);
16287
- if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
16288
- return true;
16289
- }
16290
- }
16291
- }
16292
- if (closeCurlyIndex !== -1 && str2[index] === "{" && str2[index + 1] !== "}") {
16293
- closeCurlyIndex = str2.indexOf("}", index);
16294
- if (closeCurlyIndex > index) {
16295
- backSlashIndex = str2.indexOf("\\", index);
16296
- if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
16297
- return true;
16298
- }
16299
- }
16300
- }
16301
- if (closeParenIndex !== -1 && str2[index] === "(" && str2[index + 1] === "?" && /[:!=]/.test(str2[index + 2]) && str2[index + 3] !== ")") {
16302
- closeParenIndex = str2.indexOf(")", index);
16303
- if (closeParenIndex > index) {
16304
- backSlashIndex = str2.indexOf("\\", index);
16305
- if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
16306
- return true;
16307
- }
16308
- }
16309
- }
16310
- if (pipeIndex !== -1 && str2[index] === "(" && str2[index + 1] !== "|") {
16311
- if (pipeIndex < index) {
16312
- pipeIndex = str2.indexOf("|", index);
16313
- }
16314
- if (pipeIndex !== -1 && str2[pipeIndex + 1] !== ")") {
16315
- closeParenIndex = str2.indexOf(")", pipeIndex);
16316
- if (closeParenIndex > pipeIndex) {
16317
- backSlashIndex = str2.indexOf("\\", pipeIndex);
16318
- if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
16319
- return true;
16320
- }
16321
- }
16322
- }
16323
- }
16324
- if (str2[index] === "\\") {
16325
- var open = str2[index + 1];
16326
- index += 2;
16327
- var close = chars[open];
16328
- if (close) {
16329
- var n = str2.indexOf(close, index);
16330
- if (n !== -1) {
16331
- index = n + 1;
16332
- }
16333
- }
16334
- if (str2[index] === "!") {
16335
- return true;
16336
- }
16337
- } else {
16338
- index++;
16339
- }
16340
- }
16341
- return false;
16342
- };
16343
- var relaxedCheck = function(str2) {
16344
- if (str2[0] === "!") {
16345
- return true;
16346
- }
16347
- var index = 0;
16348
- while (index < str2.length) {
16349
- if (/[*?{}()[\]]/.test(str2[index])) {
16350
- return true;
16351
- }
16352
- if (str2[index] === "\\") {
16353
- var open = str2[index + 1];
16354
- index += 2;
16355
- var close = chars[open];
16356
- if (close) {
16357
- var n = str2.indexOf(close, index);
16358
- if (n !== -1) {
16359
- index = n + 1;
16360
- }
16361
- }
16362
- if (str2[index] === "!") {
16363
- return true;
16364
- }
16365
- } else {
16366
- index++;
16367
- }
16368
- }
16369
- return false;
16370
- };
16371
- module.exports = function isGlob(str2, options) {
16372
- if (typeof str2 !== "string" || str2 === "") {
16373
- return false;
16374
- }
16375
- if (isExtglob(str2)) {
16376
- return true;
16377
- }
16378
- var check = strictCheck;
16379
- if (options && options.strict === false) {
16380
- check = relaxedCheck;
16381
- }
16382
- return check(str2);
16383
- };
16384
- });
16385
-
16386
- // node_modules/glob-parent/index.js
16387
- var require_glob_parent = __commonJS((exports, module) => {
16388
- var isGlob = require_is_glob();
16389
- var pathPosixDirname = __require("path").posix.dirname;
16390
- var isWin32 = __require("os").platform() === "win32";
16391
- var slash = "/";
16392
- var backslash = /\\/g;
16393
- var enclosure = /[\{\[].*[\}\]]$/;
16394
- var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
16395
- var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;
16396
- module.exports = function globParent(str2, opts) {
16397
- var options = Object.assign({ flipBackslashes: true }, opts);
16398
- if (options.flipBackslashes && isWin32 && str2.indexOf(slash) < 0) {
16399
- str2 = str2.replace(backslash, slash);
16400
- }
16401
- if (enclosure.test(str2)) {
16402
- str2 += slash;
16403
- }
16404
- str2 += "a";
16405
- do {
16406
- str2 = pathPosixDirname(str2);
16407
- } while (isGlob(str2) || globby.test(str2));
16408
- return str2.replace(escaped, "$1");
16409
- };
16410
- });
16411
-
16412
- // node_modules/braces/lib/utils.js
16413
- var require_utils2 = __commonJS((exports) => {
16414
- exports.isInteger = (num) => {
16415
- if (typeof num === "number") {
16416
- return Number.isInteger(num);
16417
- }
16418
- if (typeof num === "string" && num.trim() !== "") {
16419
- return Number.isInteger(Number(num));
16420
- }
16421
- return false;
16422
- };
16423
- exports.find = (node, type2) => node.nodes.find((node2) => node2.type === type2);
16424
- exports.exceedsLimit = (min, max, step = 1, limit) => {
16425
- if (limit === false)
16426
- return false;
16427
- if (!exports.isInteger(min) || !exports.isInteger(max))
16428
- return false;
16429
- return (Number(max) - Number(min)) / Number(step) >= limit;
16430
- };
16431
- exports.escapeNode = (block, n = 0, type2) => {
16432
- const node = block.nodes[n];
16433
- if (!node)
16434
- return;
16435
- if (type2 && node.type === type2 || node.type === "open" || node.type === "close") {
16436
- if (node.escaped !== true) {
16437
- node.value = "\\" + node.value;
16438
- node.escaped = true;
16439
- }
16440
- }
16441
- };
16442
- exports.encloseBrace = (node) => {
16443
- if (node.type !== "brace")
16444
- return false;
16445
- if (node.commas >> 0 + node.ranges >> 0 === 0) {
16446
- node.invalid = true;
16447
- return true;
16448
- }
16449
- return false;
16450
- };
16451
- exports.isInvalidBrace = (block) => {
16452
- if (block.type !== "brace")
16453
- return false;
16454
- if (block.invalid === true || block.dollar)
16455
- return true;
16456
- if (block.commas >> 0 + block.ranges >> 0 === 0) {
16457
- block.invalid = true;
16458
- return true;
16459
- }
16460
- if (block.open !== true || block.close !== true) {
16461
- block.invalid = true;
16462
- return true;
16463
- }
16464
- return false;
16465
- };
16466
- exports.isOpenOrClose = (node) => {
16467
- if (node.type === "open" || node.type === "close") {
16468
- return true;
16469
- }
16470
- return node.open === true || node.close === true;
16471
- };
16472
- exports.reduce = (nodes) => nodes.reduce((acc, node) => {
16473
- if (node.type === "text")
16474
- acc.push(node.value);
16475
- if (node.type === "range")
16476
- node.type = "text";
16477
- return acc;
16478
- }, []);
16479
- exports.flatten = (...args) => {
16480
- const result = [];
16481
- const flat = (arr) => {
16482
- for (let i2 = 0;i2 < arr.length; i2++) {
16483
- const ele = arr[i2];
16484
- if (Array.isArray(ele)) {
16485
- flat(ele);
16486
- continue;
16487
- }
16488
- if (ele !== undefined) {
16489
- result.push(ele);
16490
- }
16491
- }
16492
- return result;
16493
- };
16494
- flat(args);
16495
- return result;
16496
- };
16497
- });
16498
-
16499
- // node_modules/braces/lib/stringify.js
16500
- var require_stringify2 = __commonJS((exports, module) => {
16501
- var utils = require_utils2();
16502
- module.exports = (ast, options = {}) => {
16503
- const stringify = (node, parent = {}) => {
16504
- const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
16505
- const invalidNode = node.invalid === true && options.escapeInvalid === true;
16506
- let output = "";
16507
- if (node.value) {
16508
- if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
16509
- return "\\" + node.value;
16510
- }
16511
- return node.value;
16512
- }
16513
- if (node.value) {
16514
- return node.value;
16515
- }
16516
- if (node.nodes) {
16517
- for (const child of node.nodes) {
16518
- output += stringify(child);
16519
- }
16520
- }
16521
- return output;
16522
- };
16523
- return stringify(ast);
16524
- };
16525
- });
16526
-
16527
- // node_modules/is-number/index.js
16528
- var require_is_number = __commonJS((exports, module) => {
16529
- /*!
16530
- * is-number <https://github.com/jonschlinkert/is-number>
16531
- *
16532
- * Copyright (c) 2014-present, Jon Schlinkert.
16533
- * Released under the MIT License.
16534
- */
16535
- module.exports = function(num) {
16536
- if (typeof num === "number") {
16537
- return num - num === 0;
16538
- }
16539
- if (typeof num === "string" && num.trim() !== "") {
16540
- return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
16541
- }
16542
- return false;
16543
- };
16544
- });
16545
-
16546
- // node_modules/to-regex-range/index.js
16547
- var require_to_regex_range = __commonJS((exports, module) => {
16548
- /*!
16549
- * to-regex-range <https://github.com/micromatch/to-regex-range>
16550
- *
16551
- * Copyright (c) 2015-present, Jon Schlinkert.
16552
- * Released under the MIT License.
16553
- */
16554
- var isNumber = require_is_number();
16555
- var toRegexRange = (min, max, options) => {
16556
- if (isNumber(min) === false) {
16557
- throw new TypeError("toRegexRange: expected the first argument to be a number");
16243
+ var isNumber = require_is_number();
16244
+ var toRegexRange = (min, max, options) => {
16245
+ if (isNumber(min) === false) {
16246
+ throw new TypeError("toRegexRange: expected the first argument to be a number");
16558
16247
  }
16559
16248
  if (max === undefined || min === max) {
16560
16249
  return String(min);
@@ -18799,252 +18488,542 @@ var require_picomatch = __commonJS((exports, module) => {
18799
18488
  }
18800
18489
  return returnObject ? result : true;
18801
18490
  };
18802
- if (returnState) {
18803
- matcher.state = state;
18491
+ if (returnState) {
18492
+ matcher.state = state;
18493
+ }
18494
+ return matcher;
18495
+ };
18496
+ picomatch.test = (input, regex2, options, { glob, posix } = {}) => {
18497
+ if (typeof input !== "string") {
18498
+ throw new TypeError("Expected input to be a string");
18499
+ }
18500
+ if (input === "") {
18501
+ return { isMatch: false, output: "" };
18502
+ }
18503
+ const opts = options || {};
18504
+ const format = opts.format || (posix ? utils.toPosixSlashes : null);
18505
+ let match = input === glob;
18506
+ let output = match && format ? format(input) : input;
18507
+ if (match === false) {
18508
+ output = format ? format(input) : input;
18509
+ match = output === glob;
18510
+ }
18511
+ if (match === false || opts.capture === true) {
18512
+ if (opts.matchBase === true || opts.basename === true) {
18513
+ match = picomatch.matchBase(input, regex2, options, posix);
18514
+ } else {
18515
+ match = regex2.exec(output);
18516
+ }
18517
+ }
18518
+ return { isMatch: Boolean(match), match, output };
18519
+ };
18520
+ picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
18521
+ const regex2 = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
18522
+ return regex2.test(path.basename(input));
18523
+ };
18524
+ picomatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2);
18525
+ picomatch.parse = (pattern, options) => {
18526
+ if (Array.isArray(pattern))
18527
+ return pattern.map((p) => picomatch.parse(p, options));
18528
+ return parse(pattern, { ...options, fastpaths: false });
18529
+ };
18530
+ picomatch.scan = (input, options) => scan(input, options);
18531
+ picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
18532
+ if (returnOutput === true) {
18533
+ return state.output;
18534
+ }
18535
+ const opts = options || {};
18536
+ const prepend = opts.contains ? "" : "^";
18537
+ const append2 = opts.contains ? "" : "$";
18538
+ let source = `${prepend}(?:${state.output})${append2}`;
18539
+ if (state && state.negated === true) {
18540
+ source = `^(?!${source}).*$`;
18541
+ }
18542
+ const regex2 = picomatch.toRegex(source, options);
18543
+ if (returnState === true) {
18544
+ regex2.state = state;
18545
+ }
18546
+ return regex2;
18547
+ };
18548
+ picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
18549
+ if (!input || typeof input !== "string") {
18550
+ throw new TypeError("Expected a non-empty string");
18551
+ }
18552
+ let parsed = { negated: false, fastpaths: true };
18553
+ if (options.fastpaths !== false && (input[0] === "." || input[0] === "*")) {
18554
+ parsed.output = parse.fastpaths(input, options);
18555
+ }
18556
+ if (!parsed.output) {
18557
+ parsed = parse(input, options);
18558
+ }
18559
+ return picomatch.compileRe(parsed, options, returnOutput, returnState);
18560
+ };
18561
+ picomatch.toRegex = (source, options) => {
18562
+ try {
18563
+ const opts = options || {};
18564
+ return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
18565
+ } catch (err) {
18566
+ if (options && options.debug === true)
18567
+ throw err;
18568
+ return /$^/;
18569
+ }
18570
+ };
18571
+ picomatch.constants = constants;
18572
+ module.exports = picomatch;
18573
+ });
18574
+
18575
+ // node_modules/micromatch/index.js
18576
+ var require_micromatch = __commonJS((exports, module) => {
18577
+ var util3 = __require("util");
18578
+ var braces = require_braces();
18579
+ var picomatch = require_picomatch();
18580
+ var utils = require_utils3();
18581
+ var isEmptyString = (v) => v === "" || v === "./";
18582
+ var hasBraces = (v) => {
18583
+ const index = v.indexOf("{");
18584
+ return index > -1 && v.indexOf("}", index) > -1;
18585
+ };
18586
+ var micromatch = (list, patterns, options) => {
18587
+ patterns = [].concat(patterns);
18588
+ list = [].concat(list);
18589
+ let omit = new Set;
18590
+ let keep = new Set;
18591
+ let items = new Set;
18592
+ let negatives = 0;
18593
+ let onResult = (state) => {
18594
+ items.add(state.output);
18595
+ if (options && options.onResult) {
18596
+ options.onResult(state);
18597
+ }
18598
+ };
18599
+ for (let i2 = 0;i2 < patterns.length; i2++) {
18600
+ let isMatch = picomatch(String(patterns[i2]), { ...options, onResult }, true);
18601
+ let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
18602
+ if (negated)
18603
+ negatives++;
18604
+ for (let item of list) {
18605
+ let matched = isMatch(item, true);
18606
+ let match = negated ? !matched.isMatch : matched.isMatch;
18607
+ if (!match)
18608
+ continue;
18609
+ if (negated) {
18610
+ omit.add(matched.output);
18611
+ } else {
18612
+ omit.delete(matched.output);
18613
+ keep.add(matched.output);
18614
+ }
18615
+ }
18616
+ }
18617
+ let result = negatives === patterns.length ? [...items] : [...keep];
18618
+ let matches = result.filter((item) => !omit.has(item));
18619
+ if (options && matches.length === 0) {
18620
+ if (options.failglob === true) {
18621
+ throw new Error(`No matches found for "${patterns.join(", ")}"`);
18622
+ }
18623
+ if (options.nonull === true || options.nullglob === true) {
18624
+ return options.unescape ? patterns.map((p) => p.replace(/\\/g, "")) : patterns;
18625
+ }
18626
+ }
18627
+ return matches;
18628
+ };
18629
+ micromatch.match = micromatch;
18630
+ micromatch.matcher = (pattern, options) => picomatch(pattern, options);
18631
+ micromatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2);
18632
+ micromatch.any = micromatch.isMatch;
18633
+ micromatch.not = (list, patterns, options = {}) => {
18634
+ patterns = [].concat(patterns).map(String);
18635
+ let result = new Set;
18636
+ let items = [];
18637
+ let onResult = (state) => {
18638
+ if (options.onResult)
18639
+ options.onResult(state);
18640
+ items.push(state.output);
18641
+ };
18642
+ let matches = new Set(micromatch(list, patterns, { ...options, onResult }));
18643
+ for (let item of items) {
18644
+ if (!matches.has(item)) {
18645
+ result.add(item);
18646
+ }
18804
18647
  }
18805
- return matcher;
18648
+ return [...result];
18806
18649
  };
18807
- picomatch.test = (input, regex2, options, { glob, posix } = {}) => {
18808
- if (typeof input !== "string") {
18809
- throw new TypeError("Expected input to be a string");
18650
+ micromatch.contains = (str2, pattern, options) => {
18651
+ if (typeof str2 !== "string") {
18652
+ throw new TypeError(`Expected a string: "${util3.inspect(str2)}"`);
18810
18653
  }
18811
- if (input === "") {
18812
- return { isMatch: false, output: "" };
18654
+ if (Array.isArray(pattern)) {
18655
+ return pattern.some((p) => micromatch.contains(str2, p, options));
18813
18656
  }
18814
- const opts = options || {};
18815
- const format = opts.format || (posix ? utils.toPosixSlashes : null);
18816
- let match = input === glob;
18817
- let output = match && format ? format(input) : input;
18818
- if (match === false) {
18819
- output = format ? format(input) : input;
18820
- match = output === glob;
18657
+ if (typeof pattern === "string") {
18658
+ if (isEmptyString(str2) || isEmptyString(pattern)) {
18659
+ return false;
18660
+ }
18661
+ if (str2.includes(pattern) || str2.startsWith("./") && str2.slice(2).includes(pattern)) {
18662
+ return true;
18663
+ }
18821
18664
  }
18822
- if (match === false || opts.capture === true) {
18823
- if (opts.matchBase === true || opts.basename === true) {
18824
- match = picomatch.matchBase(input, regex2, options, posix);
18825
- } else {
18826
- match = regex2.exec(output);
18665
+ return micromatch.isMatch(str2, pattern, { ...options, contains: true });
18666
+ };
18667
+ micromatch.matchKeys = (obj, patterns, options) => {
18668
+ if (!utils.isObject(obj)) {
18669
+ throw new TypeError("Expected the first argument to be an object");
18670
+ }
18671
+ let keys = micromatch(Object.keys(obj), patterns, options);
18672
+ let res = {};
18673
+ for (let key of keys)
18674
+ res[key] = obj[key];
18675
+ return res;
18676
+ };
18677
+ micromatch.some = (list, patterns, options) => {
18678
+ let items = [].concat(list);
18679
+ for (let pattern of [].concat(patterns)) {
18680
+ let isMatch = picomatch(String(pattern), options);
18681
+ if (items.some((item) => isMatch(item))) {
18682
+ return true;
18827
18683
  }
18828
18684
  }
18829
- return { isMatch: Boolean(match), match, output };
18685
+ return false;
18830
18686
  };
18831
- picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
18832
- const regex2 = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
18833
- return regex2.test(path.basename(input));
18687
+ micromatch.every = (list, patterns, options) => {
18688
+ let items = [].concat(list);
18689
+ for (let pattern of [].concat(patterns)) {
18690
+ let isMatch = picomatch(String(pattern), options);
18691
+ if (!items.every((item) => isMatch(item))) {
18692
+ return false;
18693
+ }
18694
+ }
18695
+ return true;
18834
18696
  };
18835
- picomatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2);
18836
- picomatch.parse = (pattern, options) => {
18837
- if (Array.isArray(pattern))
18838
- return pattern.map((p) => picomatch.parse(p, options));
18839
- return parse(pattern, { ...options, fastpaths: false });
18697
+ micromatch.all = (str2, patterns, options) => {
18698
+ if (typeof str2 !== "string") {
18699
+ throw new TypeError(`Expected a string: "${util3.inspect(str2)}"`);
18700
+ }
18701
+ return [].concat(patterns).every((p) => picomatch(p, options)(str2));
18840
18702
  };
18841
- picomatch.scan = (input, options) => scan(input, options);
18842
- picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
18843
- if (returnOutput === true) {
18844
- return state.output;
18703
+ micromatch.capture = (glob, input, options) => {
18704
+ let posix = utils.isWindows(options);
18705
+ let regex2 = picomatch.makeRe(String(glob), { ...options, capture: true });
18706
+ let match = regex2.exec(posix ? utils.toPosixSlashes(input) : input);
18707
+ if (match) {
18708
+ return match.slice(1).map((v) => v === undefined ? "" : v);
18845
18709
  }
18846
- const opts = options || {};
18847
- const prepend = opts.contains ? "" : "^";
18848
- const append2 = opts.contains ? "" : "$";
18849
- let source = `${prepend}(?:${state.output})${append2}`;
18850
- if (state && state.negated === true) {
18851
- source = `^(?!${source}).*$`;
18710
+ };
18711
+ micromatch.makeRe = (...args) => picomatch.makeRe(...args);
18712
+ micromatch.scan = (...args) => picomatch.scan(...args);
18713
+ micromatch.parse = (patterns, options) => {
18714
+ let res = [];
18715
+ for (let pattern of [].concat(patterns || [])) {
18716
+ for (let str2 of braces(String(pattern), options)) {
18717
+ res.push(picomatch.parse(str2, options));
18718
+ }
18852
18719
  }
18853
- const regex2 = picomatch.toRegex(source, options);
18854
- if (returnState === true) {
18855
- regex2.state = state;
18720
+ return res;
18721
+ };
18722
+ micromatch.braces = (pattern, options) => {
18723
+ if (typeof pattern !== "string")
18724
+ throw new TypeError("Expected a string");
18725
+ if (options && options.nobrace === true || !hasBraces(pattern)) {
18726
+ return [pattern];
18856
18727
  }
18857
- return regex2;
18728
+ return braces(pattern, options);
18858
18729
  };
18859
- picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
18860
- if (!input || typeof input !== "string") {
18861
- throw new TypeError("Expected a non-empty string");
18730
+ micromatch.braceExpand = (pattern, options) => {
18731
+ if (typeof pattern !== "string")
18732
+ throw new TypeError("Expected a string");
18733
+ return micromatch.braces(pattern, { ...options, expand: true });
18734
+ };
18735
+ micromatch.hasBraces = hasBraces;
18736
+ module.exports = micromatch;
18737
+ });
18738
+
18739
+ // node_modules/fast-glob/out/utils/array.js
18740
+ var require_array = __commonJS((exports) => {
18741
+ Object.defineProperty(exports, "__esModule", { value: true });
18742
+ exports.splitWhen = exports.flatten = undefined;
18743
+ function flatten(items) {
18744
+ return items.reduce((collection, item) => [].concat(collection, item), []);
18745
+ }
18746
+ exports.flatten = flatten;
18747
+ function splitWhen(items, predicate) {
18748
+ const result = [[]];
18749
+ let groupIndex = 0;
18750
+ for (const item of items) {
18751
+ if (predicate(item)) {
18752
+ groupIndex++;
18753
+ result[groupIndex] = [];
18754
+ } else {
18755
+ result[groupIndex].push(item);
18756
+ }
18862
18757
  }
18863
- let parsed = { negated: false, fastpaths: true };
18864
- if (options.fastpaths !== false && (input[0] === "." || input[0] === "*")) {
18865
- parsed.output = parse.fastpaths(input, options);
18758
+ return result;
18759
+ }
18760
+ exports.splitWhen = splitWhen;
18761
+ });
18762
+
18763
+ // node_modules/fast-glob/out/utils/errno.js
18764
+ var require_errno = __commonJS((exports) => {
18765
+ Object.defineProperty(exports, "__esModule", { value: true });
18766
+ exports.isEnoentCodeError = undefined;
18767
+ function isEnoentCodeError(error) {
18768
+ return error.code === "ENOENT";
18769
+ }
18770
+ exports.isEnoentCodeError = isEnoentCodeError;
18771
+ });
18772
+
18773
+ // node_modules/fast-glob/out/utils/fs.js
18774
+ var require_fs = __commonJS((exports) => {
18775
+ Object.defineProperty(exports, "__esModule", { value: true });
18776
+ exports.createDirentFromStats = undefined;
18777
+
18778
+ class DirentFromStats {
18779
+ constructor(name, stats) {
18780
+ this.name = name;
18781
+ this.isBlockDevice = stats.isBlockDevice.bind(stats);
18782
+ this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
18783
+ this.isDirectory = stats.isDirectory.bind(stats);
18784
+ this.isFIFO = stats.isFIFO.bind(stats);
18785
+ this.isFile = stats.isFile.bind(stats);
18786
+ this.isSocket = stats.isSocket.bind(stats);
18787
+ this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
18866
18788
  }
18867
- if (!parsed.output) {
18868
- parsed = parse(input, options);
18789
+ }
18790
+ function createDirentFromStats(name, stats) {
18791
+ return new DirentFromStats(name, stats);
18792
+ }
18793
+ exports.createDirentFromStats = createDirentFromStats;
18794
+ });
18795
+
18796
+ // node_modules/fast-glob/out/utils/path.js
18797
+ var require_path = __commonJS((exports) => {
18798
+ Object.defineProperty(exports, "__esModule", { value: true });
18799
+ exports.convertPosixPathToPattern = exports.convertWindowsPathToPattern = exports.convertPathToPattern = exports.escapePosixPath = exports.escapeWindowsPath = exports.escape = exports.removeLeadingDotSegment = exports.makeAbsolute = exports.unixify = undefined;
18800
+ var os2 = __require("os");
18801
+ var path = __require("path");
18802
+ var IS_WINDOWS_PLATFORM = os2.platform() === "win32";
18803
+ var LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2;
18804
+ var POSIX_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\()|\\(?![!()*+?@[\]{|}]))/g;
18805
+ var WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()[\]{}]|^!|[!+@](?=\())/g;
18806
+ var DOS_DEVICE_PATH_RE = /^\\\\([.?])/;
18807
+ var WINDOWS_BACKSLASHES_RE = /\\(?![!()+@[\]{}])/g;
18808
+ function unixify(filepath) {
18809
+ return filepath.replace(/\\/g, "/");
18810
+ }
18811
+ exports.unixify = unixify;
18812
+ function makeAbsolute(cwd, filepath) {
18813
+ return path.resolve(cwd, filepath);
18814
+ }
18815
+ exports.makeAbsolute = makeAbsolute;
18816
+ function removeLeadingDotSegment(entry) {
18817
+ if (entry.charAt(0) === ".") {
18818
+ const secondCharactery = entry.charAt(1);
18819
+ if (secondCharactery === "/" || secondCharactery === "\\") {
18820
+ return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT);
18821
+ }
18822
+ }
18823
+ return entry;
18824
+ }
18825
+ exports.removeLeadingDotSegment = removeLeadingDotSegment;
18826
+ exports.escape = IS_WINDOWS_PLATFORM ? escapeWindowsPath : escapePosixPath;
18827
+ function escapeWindowsPath(pattern) {
18828
+ return pattern.replace(WINDOWS_UNESCAPED_GLOB_SYMBOLS_RE, "\\$2");
18829
+ }
18830
+ exports.escapeWindowsPath = escapeWindowsPath;
18831
+ function escapePosixPath(pattern) {
18832
+ return pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS_RE, "\\$2");
18833
+ }
18834
+ exports.escapePosixPath = escapePosixPath;
18835
+ exports.convertPathToPattern = IS_WINDOWS_PLATFORM ? convertWindowsPathToPattern : convertPosixPathToPattern;
18836
+ function convertWindowsPathToPattern(filepath) {
18837
+ return escapeWindowsPath(filepath).replace(DOS_DEVICE_PATH_RE, "//$1").replace(WINDOWS_BACKSLASHES_RE, "/");
18838
+ }
18839
+ exports.convertWindowsPathToPattern = convertWindowsPathToPattern;
18840
+ function convertPosixPathToPattern(filepath) {
18841
+ return escapePosixPath(filepath);
18842
+ }
18843
+ exports.convertPosixPathToPattern = convertPosixPathToPattern;
18844
+ });
18845
+
18846
+ // node_modules/is-extglob/index.js
18847
+ var require_is_extglob = __commonJS((exports, module) => {
18848
+ /*!
18849
+ * is-extglob <https://github.com/jonschlinkert/is-extglob>
18850
+ *
18851
+ * Copyright (c) 2014-2016, Jon Schlinkert.
18852
+ * Licensed under the MIT License.
18853
+ */
18854
+ module.exports = function isExtglob(str2) {
18855
+ if (typeof str2 !== "string" || str2 === "") {
18856
+ return false;
18869
18857
  }
18870
- return picomatch.compileRe(parsed, options, returnOutput, returnState);
18871
- };
18872
- picomatch.toRegex = (source, options) => {
18873
- try {
18874
- const opts = options || {};
18875
- return new RegExp(source, opts.flags || (opts.nocase ? "i" : ""));
18876
- } catch (err) {
18877
- if (options && options.debug === true)
18878
- throw err;
18879
- return /$^/;
18858
+ var match;
18859
+ while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str2)) {
18860
+ if (match[2])
18861
+ return true;
18862
+ str2 = str2.slice(match.index + match[0].length);
18880
18863
  }
18864
+ return false;
18881
18865
  };
18882
- picomatch.constants = constants;
18883
- module.exports = picomatch;
18884
18866
  });
18885
18867
 
18886
- // node_modules/micromatch/index.js
18887
- var require_micromatch = __commonJS((exports, module) => {
18888
- var util3 = __require("util");
18889
- var braces = require_braces();
18890
- var picomatch = require_picomatch();
18891
- var utils = require_utils3();
18892
- var isEmptyString = (v) => v === "" || v === "./";
18893
- var hasBraces = (v) => {
18894
- const index = v.indexOf("{");
18895
- return index > -1 && v.indexOf("}", index) > -1;
18896
- };
18897
- var micromatch = (list, patterns, options) => {
18898
- patterns = [].concat(patterns);
18899
- list = [].concat(list);
18900
- let omit = new Set;
18901
- let keep = new Set;
18902
- let items = new Set;
18903
- let negatives = 0;
18904
- let onResult = (state) => {
18905
- items.add(state.output);
18906
- if (options && options.onResult) {
18907
- options.onResult(state);
18868
+ // node_modules/is-glob/index.js
18869
+ var require_is_glob = __commonJS((exports, module) => {
18870
+ /*!
18871
+ * is-glob <https://github.com/jonschlinkert/is-glob>
18872
+ *
18873
+ * Copyright (c) 2014-2017, Jon Schlinkert.
18874
+ * Released under the MIT License.
18875
+ */
18876
+ var isExtglob = require_is_extglob();
18877
+ var chars = { "{": "}", "(": ")", "[": "]" };
18878
+ var strictCheck = function(str2) {
18879
+ if (str2[0] === "!") {
18880
+ return true;
18881
+ }
18882
+ var index = 0;
18883
+ var pipeIndex = -2;
18884
+ var closeSquareIndex = -2;
18885
+ var closeCurlyIndex = -2;
18886
+ var closeParenIndex = -2;
18887
+ var backSlashIndex = -2;
18888
+ while (index < str2.length) {
18889
+ if (str2[index] === "*") {
18890
+ return true;
18908
18891
  }
18909
- };
18910
- for (let i2 = 0;i2 < patterns.length; i2++) {
18911
- let isMatch = picomatch(String(patterns[i2]), { ...options, onResult }, true);
18912
- let negated = isMatch.state.negated || isMatch.state.negatedExtglob;
18913
- if (negated)
18914
- negatives++;
18915
- for (let item of list) {
18916
- let matched = isMatch(item, true);
18917
- let match = negated ? !matched.isMatch : matched.isMatch;
18918
- if (!match)
18919
- continue;
18920
- if (negated) {
18921
- omit.add(matched.output);
18922
- } else {
18923
- omit.delete(matched.output);
18924
- keep.add(matched.output);
18925
- }
18892
+ if (str2[index + 1] === "?" && /[\].+)]/.test(str2[index])) {
18893
+ return true;
18926
18894
  }
18927
- }
18928
- let result = negatives === patterns.length ? [...items] : [...keep];
18929
- let matches = result.filter((item) => !omit.has(item));
18930
- if (options && matches.length === 0) {
18931
- if (options.failglob === true) {
18932
- throw new Error(`No matches found for "${patterns.join(", ")}"`);
18895
+ if (closeSquareIndex !== -1 && str2[index] === "[" && str2[index + 1] !== "]") {
18896
+ if (closeSquareIndex < index) {
18897
+ closeSquareIndex = str2.indexOf("]", index);
18898
+ }
18899
+ if (closeSquareIndex > index) {
18900
+ if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
18901
+ return true;
18902
+ }
18903
+ backSlashIndex = str2.indexOf("\\", index);
18904
+ if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
18905
+ return true;
18906
+ }
18907
+ }
18933
18908
  }
18934
- if (options.nonull === true || options.nullglob === true) {
18935
- return options.unescape ? patterns.map((p) => p.replace(/\\/g, "")) : patterns;
18909
+ if (closeCurlyIndex !== -1 && str2[index] === "{" && str2[index + 1] !== "}") {
18910
+ closeCurlyIndex = str2.indexOf("}", index);
18911
+ if (closeCurlyIndex > index) {
18912
+ backSlashIndex = str2.indexOf("\\", index);
18913
+ if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
18914
+ return true;
18915
+ }
18916
+ }
18936
18917
  }
18937
- }
18938
- return matches;
18939
- };
18940
- micromatch.match = micromatch;
18941
- micromatch.matcher = (pattern, options) => picomatch(pattern, options);
18942
- micromatch.isMatch = (str2, patterns, options) => picomatch(patterns, options)(str2);
18943
- micromatch.any = micromatch.isMatch;
18944
- micromatch.not = (list, patterns, options = {}) => {
18945
- patterns = [].concat(patterns).map(String);
18946
- let result = new Set;
18947
- let items = [];
18948
- let onResult = (state) => {
18949
- if (options.onResult)
18950
- options.onResult(state);
18951
- items.push(state.output);
18952
- };
18953
- let matches = new Set(micromatch(list, patterns, { ...options, onResult }));
18954
- for (let item of items) {
18955
- if (!matches.has(item)) {
18956
- result.add(item);
18918
+ if (closeParenIndex !== -1 && str2[index] === "(" && str2[index + 1] === "?" && /[:!=]/.test(str2[index + 2]) && str2[index + 3] !== ")") {
18919
+ closeParenIndex = str2.indexOf(")", index);
18920
+ if (closeParenIndex > index) {
18921
+ backSlashIndex = str2.indexOf("\\", index);
18922
+ if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
18923
+ return true;
18924
+ }
18925
+ }
18957
18926
  }
18958
- }
18959
- return [...result];
18960
- };
18961
- micromatch.contains = (str2, pattern, options) => {
18962
- if (typeof str2 !== "string") {
18963
- throw new TypeError(`Expected a string: "${util3.inspect(str2)}"`);
18964
- }
18965
- if (Array.isArray(pattern)) {
18966
- return pattern.some((p) => micromatch.contains(str2, p, options));
18967
- }
18968
- if (typeof pattern === "string") {
18969
- if (isEmptyString(str2) || isEmptyString(pattern)) {
18970
- return false;
18927
+ if (pipeIndex !== -1 && str2[index] === "(" && str2[index + 1] !== "|") {
18928
+ if (pipeIndex < index) {
18929
+ pipeIndex = str2.indexOf("|", index);
18930
+ }
18931
+ if (pipeIndex !== -1 && str2[pipeIndex + 1] !== ")") {
18932
+ closeParenIndex = str2.indexOf(")", pipeIndex);
18933
+ if (closeParenIndex > pipeIndex) {
18934
+ backSlashIndex = str2.indexOf("\\", pipeIndex);
18935
+ if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
18936
+ return true;
18937
+ }
18938
+ }
18939
+ }
18971
18940
  }
18972
- if (str2.includes(pattern) || str2.startsWith("./") && str2.slice(2).includes(pattern)) {
18973
- return true;
18941
+ if (str2[index] === "\\") {
18942
+ var open = str2[index + 1];
18943
+ index += 2;
18944
+ var close = chars[open];
18945
+ if (close) {
18946
+ var n = str2.indexOf(close, index);
18947
+ if (n !== -1) {
18948
+ index = n + 1;
18949
+ }
18950
+ }
18951
+ if (str2[index] === "!") {
18952
+ return true;
18953
+ }
18954
+ } else {
18955
+ index++;
18974
18956
  }
18975
18957
  }
18976
- return micromatch.isMatch(str2, pattern, { ...options, contains: true });
18958
+ return false;
18977
18959
  };
18978
- micromatch.matchKeys = (obj, patterns, options) => {
18979
- if (!utils.isObject(obj)) {
18980
- throw new TypeError("Expected the first argument to be an object");
18960
+ var relaxedCheck = function(str2) {
18961
+ if (str2[0] === "!") {
18962
+ return true;
18981
18963
  }
18982
- let keys = micromatch(Object.keys(obj), patterns, options);
18983
- let res = {};
18984
- for (let key of keys)
18985
- res[key] = obj[key];
18986
- return res;
18987
- };
18988
- micromatch.some = (list, patterns, options) => {
18989
- let items = [].concat(list);
18990
- for (let pattern of [].concat(patterns)) {
18991
- let isMatch = picomatch(String(pattern), options);
18992
- if (items.some((item) => isMatch(item))) {
18964
+ var index = 0;
18965
+ while (index < str2.length) {
18966
+ if (/[*?{}()[\]]/.test(str2[index])) {
18993
18967
  return true;
18994
18968
  }
18969
+ if (str2[index] === "\\") {
18970
+ var open = str2[index + 1];
18971
+ index += 2;
18972
+ var close = chars[open];
18973
+ if (close) {
18974
+ var n = str2.indexOf(close, index);
18975
+ if (n !== -1) {
18976
+ index = n + 1;
18977
+ }
18978
+ }
18979
+ if (str2[index] === "!") {
18980
+ return true;
18981
+ }
18982
+ } else {
18983
+ index++;
18984
+ }
18995
18985
  }
18996
18986
  return false;
18997
18987
  };
18998
- micromatch.every = (list, patterns, options) => {
18999
- let items = [].concat(list);
19000
- for (let pattern of [].concat(patterns)) {
19001
- let isMatch = picomatch(String(pattern), options);
19002
- if (!items.every((item) => isMatch(item))) {
19003
- return false;
19004
- }
18988
+ module.exports = function isGlob(str2, options) {
18989
+ if (typeof str2 !== "string" || str2 === "") {
18990
+ return false;
19005
18991
  }
19006
- return true;
19007
- };
19008
- micromatch.all = (str2, patterns, options) => {
19009
- if (typeof str2 !== "string") {
19010
- throw new TypeError(`Expected a string: "${util3.inspect(str2)}"`);
18992
+ if (isExtglob(str2)) {
18993
+ return true;
19011
18994
  }
19012
- return [].concat(patterns).every((p) => picomatch(p, options)(str2));
19013
- };
19014
- micromatch.capture = (glob, input, options) => {
19015
- let posix = utils.isWindows(options);
19016
- let regex2 = picomatch.makeRe(String(glob), { ...options, capture: true });
19017
- let match = regex2.exec(posix ? utils.toPosixSlashes(input) : input);
19018
- if (match) {
19019
- return match.slice(1).map((v) => v === undefined ? "" : v);
18995
+ var check = strictCheck;
18996
+ if (options && options.strict === false) {
18997
+ check = relaxedCheck;
19020
18998
  }
18999
+ return check(str2);
19021
19000
  };
19022
- micromatch.makeRe = (...args) => picomatch.makeRe(...args);
19023
- micromatch.scan = (...args) => picomatch.scan(...args);
19024
- micromatch.parse = (patterns, options) => {
19025
- let res = [];
19026
- for (let pattern of [].concat(patterns || [])) {
19027
- for (let str2 of braces(String(pattern), options)) {
19028
- res.push(picomatch.parse(str2, options));
19029
- }
19001
+ });
19002
+
19003
+ // node_modules/glob-parent/index.js
19004
+ var require_glob_parent = __commonJS((exports, module) => {
19005
+ var isGlob = require_is_glob();
19006
+ var pathPosixDirname = __require("path").posix.dirname;
19007
+ var isWin32 = __require("os").platform() === "win32";
19008
+ var slash = "/";
19009
+ var backslash = /\\/g;
19010
+ var enclosure = /[\{\[].*[\}\]]$/;
19011
+ var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
19012
+ var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;
19013
+ module.exports = function globParent(str2, opts) {
19014
+ var options = Object.assign({ flipBackslashes: true }, opts);
19015
+ if (options.flipBackslashes && isWin32 && str2.indexOf(slash) < 0) {
19016
+ str2 = str2.replace(backslash, slash);
19030
19017
  }
19031
- return res;
19032
- };
19033
- micromatch.braces = (pattern, options) => {
19034
- if (typeof pattern !== "string")
19035
- throw new TypeError("Expected a string");
19036
- if (options && options.nobrace === true || !hasBraces(pattern)) {
19037
- return [pattern];
19018
+ if (enclosure.test(str2)) {
19019
+ str2 += slash;
19038
19020
  }
19039
- return braces(pattern, options);
19040
- };
19041
- micromatch.braceExpand = (pattern, options) => {
19042
- if (typeof pattern !== "string")
19043
- throw new TypeError("Expected a string");
19044
- return micromatch.braces(pattern, { ...options, expand: true });
19021
+ str2 += "a";
19022
+ do {
19023
+ str2 = pathPosixDirname(str2);
19024
+ } while (isGlob(str2) || globby.test(str2));
19025
+ return str2.replace(escaped, "$1");
19045
19026
  };
19046
- micromatch.hasBraces = hasBraces;
19047
- module.exports = micromatch;
19048
19027
  });
19049
19028
 
19050
19029
  // node_modules/fast-glob/out/utils/pattern.js
@@ -21429,6 +21408,16 @@ var init_glob_patterns = __esm(() => {
21429
21408
  function isUniversalClient(client) {
21430
21409
  return client === "universal";
21431
21410
  }
21411
+ function resolveClientMappings(clients, baseMappings) {
21412
+ if (!clients.includes("vscode"))
21413
+ return baseMappings;
21414
+ if (!clients.includes("copilot"))
21415
+ return baseMappings;
21416
+ return {
21417
+ ...baseMappings,
21418
+ vscode: { ...baseMappings.copilot }
21419
+ };
21420
+ }
21432
21421
  var CLIENT_MAPPINGS, CANONICAL_SKILLS_PATH = ".agents/skills/", USER_CLIENT_MAPPINGS;
21433
21422
  var init_client_mapping = __esm(() => {
21434
21423
  CLIENT_MAPPINGS = {
@@ -21473,9 +21462,8 @@ var init_client_mapping = __esm(() => {
21473
21462
  agentFile: "AGENTS.md"
21474
21463
  },
21475
21464
  vscode: {
21476
- skillsPath: ".github/skills/",
21477
- agentFile: "AGENTS.md",
21478
- githubPath: ".github/"
21465
+ skillsPath: ".agents/skills/",
21466
+ agentFile: "AGENTS.md"
21479
21467
  },
21480
21468
  openclaw: {
21481
21469
  skillsPath: "skills/",
@@ -21580,9 +21568,8 @@ var init_client_mapping = __esm(() => {
21580
21568
  agentFile: "AGENTS.md"
21581
21569
  },
21582
21570
  vscode: {
21583
- skillsPath: ".copilot/skills/",
21584
- agentFile: "AGENTS.md",
21585
- githubPath: ".copilot/"
21571
+ skillsPath: ".agents/skills/",
21572
+ agentFile: "AGENTS.md"
21586
21573
  },
21587
21574
  openclaw: {
21588
21575
  skillsPath: "skills/",
@@ -21785,7 +21772,7 @@ var init_link_adjuster = __esm(() => {
21785
21772
  });
21786
21773
 
21787
21774
  // src/core/transform.ts
21788
- import { readFile as readFile3, writeFile, mkdir as mkdir3, cp, readdir as readdir2 } from "node:fs/promises";
21775
+ import { readFile as readFile2, writeFile, mkdir as mkdir3, cp, readdir as readdir2 } from "node:fs/promises";
21789
21776
  import { existsSync as existsSync3 } from "node:fs";
21790
21777
  import { join as join6, dirname as dirname4, relative as relative2 } from "node:path";
21791
21778
  async function ensureWorkspaceRules(filePath, repositories) {
@@ -21797,7 +21784,7 @@ async function ensureWorkspaceRules(filePath, repositories) {
21797
21784
  `, "utf-8");
21798
21785
  return;
21799
21786
  }
21800
- const content = await readFile3(filePath, "utf-8");
21787
+ const content = await readFile2(filePath, "utf-8");
21801
21788
  const startIndex = content.indexOf(startMarker);
21802
21789
  const endIndex = content.indexOf(endMarker);
21803
21790
  if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
@@ -21808,6 +21795,28 @@ async function ensureWorkspaceRules(filePath, repositories) {
21808
21795
  await writeFile(filePath, content + rulesContent, "utf-8");
21809
21796
  }
21810
21797
  }
21798
+ function isExcluded(pluginPath, filePath, exclude) {
21799
+ if (!exclude || exclude.length === 0)
21800
+ return false;
21801
+ const relativePath = relative2(pluginPath, filePath).replaceAll("\\", "/");
21802
+ return import_micromatch.default.isMatch(relativePath, exclude);
21803
+ }
21804
+ async function copyDirectoryWithExclusions(sourceDir, destDir, pluginPath, exclude) {
21805
+ await mkdir3(destDir, { recursive: true });
21806
+ const entries = await readdir2(sourceDir, { withFileTypes: true });
21807
+ for (const entry of entries) {
21808
+ const sourcePath = join6(sourceDir, entry.name);
21809
+ const destPath = join6(destDir, entry.name);
21810
+ if (isExcluded(pluginPath, sourcePath, exclude)) {
21811
+ continue;
21812
+ }
21813
+ if (entry.isDirectory()) {
21814
+ await copyDirectoryWithExclusions(sourcePath, destPath, pluginPath, exclude);
21815
+ } else {
21816
+ await cp(sourcePath, destPath);
21817
+ }
21818
+ }
21819
+ }
21811
21820
  function getMapping(client, options) {
21812
21821
  return options?.clientMappings?.[client] ?? CLIENT_MAPPINGS[client];
21813
21822
  }
@@ -21828,14 +21837,14 @@ async function copyCommands(pluginPath, workspacePath, client, options = {}) {
21828
21837
  }
21829
21838
  const files = await readdir2(sourceDir);
21830
21839
  const mdFiles = files.filter((f) => f.endsWith(".md"));
21831
- const copyPromises = mdFiles.map(async (file) => {
21840
+ const copyPromises = mdFiles.filter((file) => !isExcluded(pluginPath, join6(sourceDir, file), options.exclude)).map(async (file) => {
21832
21841
  const sourcePath = join6(sourceDir, file);
21833
21842
  const destPath = join6(destDir, file);
21834
21843
  if (dryRun) {
21835
21844
  return { source: sourcePath, destination: destPath, action: "copied" };
21836
21845
  }
21837
21846
  try {
21838
- const content = await readFile3(sourcePath, "utf-8");
21847
+ const content = await readFile2(sourcePath, "utf-8");
21839
21848
  await writeFile(destPath, content, "utf-8");
21840
21849
  return { source: sourcePath, destination: destPath, action: "copied" };
21841
21850
  } catch (error) {
@@ -21865,7 +21874,7 @@ async function copySkills(pluginPath, workspacePath, client, options = {}) {
21865
21874
  await mkdir3(destDir, { recursive: true });
21866
21875
  }
21867
21876
  const entries = await readdir2(sourceDir, { withFileTypes: true });
21868
- let skillDirs = entries.filter((e) => e.isDirectory());
21877
+ let skillDirs = entries.filter((e) => e.isDirectory()).filter((e) => !isExcluded(pluginPath, join6(sourceDir, e.name), options.exclude));
21869
21878
  if (skillNameMap) {
21870
21879
  skillDirs = skillDirs.filter((e) => skillNameMap.has(e.name));
21871
21880
  }
@@ -21893,7 +21902,11 @@ async function copySkills(pluginPath, workspacePath, client, options = {}) {
21893
21902
  }
21894
21903
  }
21895
21904
  try {
21896
- await cp(skillSourcePath, skillDestPath, { recursive: true });
21905
+ if (options.exclude && options.exclude.length > 0) {
21906
+ await copyDirectoryWithExclusions(skillSourcePath, skillDestPath, pluginPath, options.exclude);
21907
+ } else {
21908
+ await cp(skillSourcePath, skillDestPath, { recursive: true });
21909
+ }
21897
21910
  return {
21898
21911
  source: skillSourcePath,
21899
21912
  destination: skillDestPath,
@@ -21943,7 +21956,11 @@ async function copyHooks(pluginPath, workspacePath, client, options = {}) {
21943
21956
  }
21944
21957
  await mkdir3(destDir, { recursive: true });
21945
21958
  try {
21946
- await cp(sourceDir, destDir, { recursive: true });
21959
+ if (options.exclude && options.exclude.length > 0) {
21960
+ await copyDirectoryWithExclusions(sourceDir, destDir, pluginPath, options.exclude);
21961
+ } else {
21962
+ await cp(sourceDir, destDir, { recursive: true });
21963
+ }
21947
21964
  results.push({ source: sourceDir, destination: destDir, action: "copied" });
21948
21965
  } catch (error) {
21949
21966
  results.push({
@@ -21972,14 +21989,14 @@ async function copyAgents(pluginPath, workspacePath, client, options = {}) {
21972
21989
  }
21973
21990
  const files = await readdir2(sourceDir);
21974
21991
  const mdFiles = files.filter((f) => f.endsWith(".md"));
21975
- const copyPromises = mdFiles.map(async (file) => {
21992
+ const copyPromises = mdFiles.filter((file) => !isExcluded(pluginPath, join6(sourceDir, file), options.exclude)).map(async (file) => {
21976
21993
  const sourcePath = join6(sourceDir, file);
21977
21994
  const destPath = join6(destDir, file);
21978
21995
  if (dryRun) {
21979
21996
  return { source: sourcePath, destination: destPath, action: "copied" };
21980
21997
  }
21981
21998
  try {
21982
- const content = await readFile3(sourcePath, "utf-8");
21999
+ const content = await readFile2(sourcePath, "utf-8");
21983
22000
  await writeFile(destPath, content, "utf-8");
21984
22001
  return { source: sourcePath, destination: destPath, action: "copied" };
21985
22002
  } catch (error) {
@@ -21993,19 +22010,22 @@ async function copyAgents(pluginPath, workspacePath, client, options = {}) {
21993
22010
  });
21994
22011
  return Promise.all(copyPromises);
21995
22012
  }
21996
- async function copyAndAdjustDirectory(sourceDir, destDir, sourceBase, skillsPath, skillNameMap) {
22013
+ async function copyAndAdjustDirectory(sourceDir, destDir, sourceBase, pluginPath, skillsPath, skillNameMap, exclude) {
21997
22014
  await mkdir3(destDir, { recursive: true });
21998
22015
  const entries = await readdir2(sourceDir, { withFileTypes: true });
21999
22016
  for (const entry of entries) {
22000
22017
  const sourcePath = join6(sourceDir, entry.name);
22001
22018
  const destPath = join6(destDir, entry.name);
22019
+ if (isExcluded(pluginPath, sourcePath, exclude)) {
22020
+ continue;
22021
+ }
22002
22022
  if (entry.isDirectory()) {
22003
- await copyAndAdjustDirectory(sourcePath, destPath, sourceBase, skillsPath, skillNameMap);
22023
+ await copyAndAdjustDirectory(sourcePath, destPath, sourceBase, pluginPath, skillsPath, skillNameMap, exclude);
22004
22024
  } else {
22005
22025
  const relativePath = relative2(sourceBase, sourcePath).replaceAll("\\", "/");
22006
22026
  const isMarkdown = entry.name.endsWith(".md") || entry.name.endsWith(".markdown");
22007
22027
  if (isMarkdown) {
22008
- let content = await readFile3(sourcePath, "utf-8");
22028
+ let content = await readFile2(sourcePath, "utf-8");
22009
22029
  content = adjustLinksInContent(content, relativePath, {
22010
22030
  ...skillNameMap && { skillNameMap },
22011
22031
  workspaceSkillsPath: skillsPath
@@ -22034,8 +22054,8 @@ async function copyGitHubContent(pluginPath, workspacePath, client, options = {}
22034
22054
  return results;
22035
22055
  }
22036
22056
  try {
22037
- if (mapping.skillsPath) {
22038
- await copyAndAdjustDirectory(sourceDir, destDir, sourceDir, mapping.skillsPath, skillNameMap);
22057
+ if (mapping.skillsPath || options.exclude && options.exclude.length > 0) {
22058
+ await copyAndAdjustDirectory(sourceDir, destDir, sourceDir, pluginPath, mapping.skillsPath ?? "", skillNameMap, options.exclude);
22039
22059
  } else {
22040
22060
  await cp(sourceDir, destDir, { recursive: true });
22041
22061
  }
@@ -22181,7 +22201,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options = {}
22181
22201
  }
22182
22202
  try {
22183
22203
  await mkdir3(dirname4(destPath), { recursive: true });
22184
- const content = await readFile3(resolved.sourcePath, "utf-8");
22204
+ const content = await readFile2(resolved.sourcePath, "utf-8");
22185
22205
  await writeFile(destPath, content, "utf-8");
22186
22206
  results.push({ source: resolved.sourcePath, destination: destPath, action: "copied" });
22187
22207
  if (AGENT_FILES2.includes(resolved.relativePath)) {
@@ -22252,7 +22272,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options = {}
22252
22272
  }
22253
22273
  try {
22254
22274
  await mkdir3(dirname4(destPath), { recursive: true });
22255
- const content = await readFile3(srcPath, "utf-8");
22275
+ const content = await readFile2(srcPath, "utf-8");
22256
22276
  await writeFile(destPath, content, "utf-8");
22257
22277
  results.push({ source: srcPath, destination: destPath, action: "copied" });
22258
22278
  if (AGENT_FILES2.includes(entry.dest)) {
@@ -22284,7 +22304,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options = {}
22284
22304
  }
22285
22305
  return results;
22286
22306
  }
22287
- var AGENT_FILES2;
22307
+ var import_micromatch, AGENT_FILES2;
22288
22308
  var init_transform = __esm(() => {
22289
22309
  init_glob_patterns();
22290
22310
  init_client_mapping();
@@ -22292,6 +22312,7 @@ var init_transform = __esm(() => {
22292
22312
  init_plugin_path();
22293
22313
  init_symlink();
22294
22314
  init_link_adjuster();
22315
+ import_micromatch = __toESM(require_micromatch(), 1);
22295
22316
  AGENT_FILES2 = ["AGENTS.md", "CLAUDE.md"];
22296
22317
  });
22297
22318
 
@@ -22348,7 +22369,7 @@ var init_marketplace_manifest = __esm(() => {
22348
22369
  });
22349
22370
 
22350
22371
  // src/utils/marketplace-manifest-parser.ts
22351
- import { readFile as readFile4 } from "node:fs/promises";
22372
+ import { readFile as readFile3 } from "node:fs/promises";
22352
22373
  import { existsSync as existsSync4 } from "node:fs";
22353
22374
  import { join as join7, resolve as resolve5 } from "node:path";
22354
22375
  async function parseMarketplaceManifest(marketplacePath) {
@@ -22361,7 +22382,7 @@ async function parseMarketplaceManifest(marketplacePath) {
22361
22382
  }
22362
22383
  let raw;
22363
22384
  try {
22364
- raw = await readFile4(manifestPath, "utf-8");
22385
+ raw = await readFile3(manifestPath, "utf-8");
22365
22386
  } catch (err) {
22366
22387
  return {
22367
22388
  success: false,
@@ -22482,7 +22503,7 @@ __export(exports_user_workspace, {
22482
22503
  addUserDisabledSkill: () => addUserDisabledSkill
22483
22504
  });
22484
22505
  import { existsSync as existsSync5 } from "node:fs";
22485
- import { mkdir as mkdir4, readFile as readFile5, writeFile as writeFile2 } from "node:fs/promises";
22506
+ import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
22486
22507
  import { join as join8, resolve as resolve6 } from "node:path";
22487
22508
  function getUserWorkspaceConfigPath() {
22488
22509
  return join8(getAllagentsDir(), WORKSPACE_CONFIG_FILE);
@@ -22509,7 +22530,7 @@ async function getUserWorkspaceConfig() {
22509
22530
  if (!existsSync5(configPath))
22510
22531
  return null;
22511
22532
  try {
22512
- const content = await readFile5(configPath, "utf-8");
22533
+ const content = await readFile4(configPath, "utf-8");
22513
22534
  return load(content);
22514
22535
  } catch {
22515
22536
  return null;
@@ -22566,7 +22587,7 @@ async function removeUserPlugin(plugin) {
22566
22587
  await ensureUserWorkspace();
22567
22588
  const configPath = getUserWorkspaceConfigPath();
22568
22589
  try {
22569
- const content = await readFile5(configPath, "utf-8");
22590
+ const content = await readFile4(configPath, "utf-8");
22570
22591
  const config = load(content);
22571
22592
  let index = config.plugins.findIndex((entry) => getPluginSource(entry) === plugin);
22572
22593
  if (index === -1) {
@@ -22657,7 +22678,7 @@ async function resolveGitHubIdentity(pluginSource) {
22657
22678
  }
22658
22679
  async function addPluginToUserConfig(plugin, configPath, autoRegistered) {
22659
22680
  try {
22660
- const content = await readFile5(configPath, "utf-8");
22681
+ const content = await readFile4(configPath, "utf-8");
22661
22682
  const config = load(content);
22662
22683
  if (config.plugins.some((entry) => getPluginSource(entry) === plugin)) {
22663
22684
  return {
@@ -22696,7 +22717,7 @@ async function setUserClients(clients) {
22696
22717
  await ensureUserWorkspace();
22697
22718
  const configPath = getUserWorkspaceConfigPath();
22698
22719
  try {
22699
- const content = await readFile5(configPath, "utf-8");
22720
+ const content = await readFile4(configPath, "utf-8");
22700
22721
  const config = load(content);
22701
22722
  config.clients = clients;
22702
22723
  await writeFile2(configPath, dump(config, { lineWidth: -1 }), "utf-8");
@@ -22716,7 +22737,7 @@ async function addUserDisabledSkill(skillKey) {
22716
22737
  await ensureUserWorkspace();
22717
22738
  const configPath = getUserWorkspaceConfigPath();
22718
22739
  try {
22719
- const content = await readFile5(configPath, "utf-8");
22740
+ const content = await readFile4(configPath, "utf-8");
22720
22741
  const config = load(content);
22721
22742
  const disabledSkills = config.disabledSkills ?? [];
22722
22743
  if (disabledSkills.includes(skillKey)) {
@@ -22739,7 +22760,7 @@ async function removeUserDisabledSkill(skillKey) {
22739
22760
  await ensureUserWorkspace();
22740
22761
  const configPath = getUserWorkspaceConfigPath();
22741
22762
  try {
22742
- const content = await readFile5(configPath, "utf-8");
22763
+ const content = await readFile4(configPath, "utf-8");
22743
22764
  const config = load(content);
22744
22765
  const disabledSkills = config.disabledSkills ?? [];
22745
22766
  if (!disabledSkills.includes(skillKey)) {
@@ -22785,7 +22806,7 @@ async function getInstalledProjectPlugins(workspacePath) {
22785
22806
  if (!existsSync5(configPath))
22786
22807
  return [];
22787
22808
  try {
22788
- const content = await readFile5(configPath, "utf-8");
22809
+ const content = await readFile4(configPath, "utf-8");
22789
22810
  const config = load(content);
22790
22811
  if (!config?.plugins)
22791
22812
  return [];
@@ -22831,7 +22852,7 @@ var init_user_workspace = __esm(() => {
22831
22852
 
22832
22853
  // src/core/marketplace.ts
22833
22854
  import { existsSync as existsSync6 } from "node:fs";
22834
- import { mkdir as mkdir5, readFile as readFile6, readdir as readdir3, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
22855
+ import { mkdir as mkdir5, readFile as readFile5, readdir as readdir3, rm as rm3, writeFile as writeFile3 } from "node:fs/promises";
22835
22856
  import { basename as basename2, join as join9, resolve as resolve7 } from "node:path";
22836
22857
  function parseLocation(location) {
22837
22858
  const [owner = "", repo = "", ...rest] = location.split("/");
@@ -22853,7 +22874,7 @@ async function loadRegistry() {
22853
22874
  return { version: 1, marketplaces: {} };
22854
22875
  }
22855
22876
  try {
22856
- const content = await readFile6(registryPath, "utf-8");
22877
+ const content = await readFile5(registryPath, "utf-8");
22857
22878
  return JSON.parse(content);
22858
22879
  } catch {
22859
22880
  return { version: 1, marketplaces: {} };
@@ -23453,13 +23474,13 @@ var init_marketplace = __esm(() => {
23453
23474
 
23454
23475
  // src/core/workspace-modify.ts
23455
23476
  import { existsSync as existsSync7 } from "node:fs";
23456
- import { mkdir as mkdir6, readFile as readFile7, writeFile as writeFile4 } from "node:fs/promises";
23477
+ import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile4 } from "node:fs/promises";
23457
23478
  import { join as join10 } from "node:path";
23458
23479
  async function setClients(clients, workspacePath = process.cwd()) {
23459
23480
  try {
23460
23481
  await ensureWorkspace(workspacePath);
23461
23482
  const configPath = join10(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
23462
- const content = await readFile7(configPath, "utf-8");
23483
+ const content = await readFile6(configPath, "utf-8");
23463
23484
  const config = load(content);
23464
23485
  config.clients = clients;
23465
23486
  await writeFile4(configPath, dump(config, { lineWidth: -1 }), "utf-8");
@@ -23525,7 +23546,7 @@ async function addPlugin(plugin, workspacePath = process.cwd()) {
23525
23546
  }
23526
23547
  async function addPluginToConfig(plugin, configPath, autoRegistered) {
23527
23548
  try {
23528
- const content = await readFile7(configPath, "utf-8");
23549
+ const content = await readFile6(configPath, "utf-8");
23529
23550
  const config = load(content);
23530
23551
  if (config.plugins.some((entry) => getPluginSource(entry) === plugin)) {
23531
23552
  return {
@@ -23553,7 +23574,7 @@ async function hasPlugin(plugin, workspacePath = process.cwd()) {
23553
23574
  if (!existsSync7(configPath))
23554
23575
  return false;
23555
23576
  try {
23556
- const content = await readFile7(configPath, "utf-8");
23577
+ const content = await readFile6(configPath, "utf-8");
23557
23578
  const config = load(content);
23558
23579
  if (config.plugins.some((entry) => getPluginSource(entry) === plugin))
23559
23580
  return true;
@@ -23578,7 +23599,7 @@ async function removePlugin(plugin, workspacePath = process.cwd()) {
23578
23599
  };
23579
23600
  }
23580
23601
  try {
23581
- const content = await readFile7(configPath, "utf-8");
23602
+ const content = await readFile6(configPath, "utf-8");
23582
23603
  const config = load(content);
23583
23604
  let index = config.plugins.findIndex((entry) => getPluginSource(entry) === plugin);
23584
23605
  if (index === -1 && isPluginSpec(plugin) === false) {
@@ -23637,7 +23658,7 @@ async function addDisabledSkill(skillKey, workspacePath = process.cwd()) {
23637
23658
  };
23638
23659
  }
23639
23660
  try {
23640
- const content = await readFile7(configPath, "utf-8");
23661
+ const content = await readFile6(configPath, "utf-8");
23641
23662
  const config = load(content);
23642
23663
  const disabledSkills = config.disabledSkills ?? [];
23643
23664
  if (disabledSkills.includes(skillKey)) {
@@ -23665,7 +23686,7 @@ async function removeDisabledSkill(skillKey, workspacePath = process.cwd()) {
23665
23686
  };
23666
23687
  }
23667
23688
  try {
23668
- const content = await readFile7(configPath, "utf-8");
23689
+ const content = await readFile6(configPath, "utf-8");
23669
23690
  const config = load(content);
23670
23691
  const disabledSkills = config.disabledSkills ?? [];
23671
23692
  if (!disabledSkills.includes(skillKey)) {
@@ -23687,6 +23708,26 @@ async function removeDisabledSkill(skillKey, workspacePath = process.cwd()) {
23687
23708
  };
23688
23709
  }
23689
23710
  }
23711
+ async function updateRepositories(changes, workspacePath = process.cwd()) {
23712
+ if (changes.remove.length === 0 && changes.add.length === 0) {
23713
+ return { success: true };
23714
+ }
23715
+ const configPath = join10(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
23716
+ try {
23717
+ const content = await readFile6(configPath, "utf-8");
23718
+ const config = load(content);
23719
+ const removeSet = new Set(changes.remove);
23720
+ config.repositories = config.repositories.filter((repo) => !removeSet.has(repo.path));
23721
+ config.repositories.push(...changes.add);
23722
+ await writeFile4(configPath, dump(config, { lineWidth: -1 }), "utf-8");
23723
+ return { success: true };
23724
+ } catch (error) {
23725
+ return {
23726
+ success: false,
23727
+ error: error instanceof Error ? error.message : String(error)
23728
+ };
23729
+ }
23730
+ }
23690
23731
  var DEFAULT_PROJECT_CLIENTS;
23691
23732
  var init_workspace_modify = __esm(() => {
23692
23733
  init_js_yaml();
@@ -23703,7 +23744,7 @@ var init_workspace_modify = __esm(() => {
23703
23744
  });
23704
23745
 
23705
23746
  // src/core/workspace-repo.ts
23706
- import { readFile as readFile8, writeFile as writeFile5 } from "node:fs/promises";
23747
+ import { readFile as readFile7, writeFile as writeFile5 } from "node:fs/promises";
23707
23748
  import { existsSync as existsSync8 } from "node:fs";
23708
23749
  import { join as join11 } from "node:path";
23709
23750
  async function detectRemote(repoPath) {
@@ -23750,7 +23791,7 @@ async function addRepository(path, options = {}, workspacePath = process.cwd())
23750
23791
  const configPath = join11(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
23751
23792
  await ensureWorkspace(workspacePath);
23752
23793
  try {
23753
- const content = await readFile8(configPath, "utf-8");
23794
+ const content = await readFile7(configPath, "utf-8");
23754
23795
  const config = load(content);
23755
23796
  if (config.repositories.some((r) => normalizePath(r.path) === normalizedPath)) {
23756
23797
  return { success: false, error: `Repository already exists: ${normalizedPath}` };
@@ -23779,7 +23820,7 @@ async function removeRepository(path, workspacePath = process.cwd()) {
23779
23820
  };
23780
23821
  }
23781
23822
  try {
23782
- const content = await readFile8(configPath, "utf-8");
23823
+ const content = await readFile7(configPath, "utf-8");
23783
23824
  const config = load(content);
23784
23825
  const normalizedPath = normalizePath(path);
23785
23826
  const index = config.repositories.findIndex((r) => normalizePath(r.path) === normalizedPath);
@@ -23798,7 +23839,7 @@ async function listRepositories(workspacePath = process.cwd()) {
23798
23839
  if (!existsSync8(configPath))
23799
23840
  return [];
23800
23841
  try {
23801
- const content = await readFile8(configPath, "utf-8");
23842
+ const content = await readFile7(configPath, "utf-8");
23802
23843
  const config = load(content);
23803
23844
  return config.repositories ?? [];
23804
23845
  } catch {
@@ -23809,7 +23850,7 @@ async function updateAgentFiles(workspacePath = process.cwd()) {
23809
23850
  const configPath = join11(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
23810
23851
  if (!existsSync8(configPath))
23811
23852
  return;
23812
- const content = await readFile8(configPath, "utf-8");
23853
+ const content = await readFile7(configPath, "utf-8");
23813
23854
  const config = load(content);
23814
23855
  if (config.repositories.length === 0)
23815
23856
  return;
@@ -23989,12 +24030,14 @@ var init_sync_state = __esm(() => {
23989
24030
  lastSync: exports_external.string(),
23990
24031
  files: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())),
23991
24032
  mcpServers: exports_external.record(exports_external.string(), exports_external.array(exports_external.string())).optional(),
23992
- nativePlugins: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())).optional()
24033
+ nativePlugins: exports_external.record(ClientTypeSchema, exports_external.array(exports_external.string())).optional(),
24034
+ vscodeWorkspaceHash: exports_external.string().optional(),
24035
+ vscodeWorkspaceRepos: exports_external.array(exports_external.string()).optional()
23993
24036
  });
23994
24037
  });
23995
24038
 
23996
24039
  // src/core/sync-state.ts
23997
- import { readFile as readFile9, writeFile as writeFile6, mkdir as mkdir7 } from "node:fs/promises";
24040
+ import { readFile as readFile8, writeFile as writeFile6, mkdir as mkdir7 } from "node:fs/promises";
23998
24041
  import { existsSync as existsSync9 } from "node:fs";
23999
24042
  import { join as join12, dirname as dirname5 } from "node:path";
24000
24043
  function getSyncStatePath(workspacePath) {
@@ -24006,7 +24049,7 @@ async function loadSyncState(workspacePath) {
24006
24049
  return null;
24007
24050
  }
24008
24051
  try {
24009
- const content = await readFile9(statePath, "utf-8");
24052
+ const content = await readFile8(statePath, "utf-8");
24010
24053
  const parsed = JSON.parse(content);
24011
24054
  const result = SyncStateSchema.safeParse(parsed);
24012
24055
  if (!result.success) {
@@ -24025,7 +24068,9 @@ async function saveSyncState(workspacePath, data) {
24025
24068
  lastSync: new Date().toISOString(),
24026
24069
  files: normalizedData.files,
24027
24070
  ...normalizedData.mcpServers && { mcpServers: normalizedData.mcpServers },
24028
- ...normalizedData.nativePlugins && { nativePlugins: normalizedData.nativePlugins }
24071
+ ...normalizedData.nativePlugins && { nativePlugins: normalizedData.nativePlugins },
24072
+ ...normalizedData.vscodeWorkspaceHash && { vscodeWorkspaceHash: normalizedData.vscodeWorkspaceHash },
24073
+ ...normalizedData.vscodeWorkspaceRepos && { vscodeWorkspaceRepos: normalizedData.vscodeWorkspaceRepos }
24029
24074
  };
24030
24075
  await mkdir7(dirname5(statePath), { recursive: true });
24031
24076
  await writeFile6(statePath, JSON.stringify(state, null, 2), "utf-8");
@@ -24053,7 +24098,8 @@ var init_sync_state2 = __esm(() => {
24053
24098
  });
24054
24099
 
24055
24100
  // src/core/vscode-workspace.ts
24056
- import { resolve as resolve8, basename as basename3, isAbsolute as isAbsolute3 } from "node:path";
24101
+ import { createHash as createHash2 } from "node:crypto";
24102
+ import { resolve as resolve8, basename as basename3, isAbsolute as isAbsolute3, relative as relative3 } from "node:path";
24057
24103
  function buildPathPlaceholderMap(repositories, workspacePath) {
24058
24104
  const map2 = new Map;
24059
24105
  for (const repo of repositories) {
@@ -24136,6 +24182,48 @@ function getWorkspaceOutputPath(workspacePath, vscodeConfig) {
24136
24182
  const dirName = basename3(resolve8(workspacePath));
24137
24183
  return resolve8(workspacePath, `${dirName}.code-workspace`);
24138
24184
  }
24185
+ function computeWorkspaceHash(content) {
24186
+ return createHash2("sha256").update(content).digest("hex");
24187
+ }
24188
+ function reconcileVscodeWorkspaceFolders(workspacePath, codeWorkspaceFolders, lastSyncedRepos, currentRepos) {
24189
+ const normalizedWorkspacePath = resolve8(workspacePath).replace(/\\/g, "/");
24190
+ const codeWorkspaceAbsPaths = new Set;
24191
+ for (const folder of codeWorkspaceFolders) {
24192
+ if (folder.path === ".")
24193
+ continue;
24194
+ const absPath = (isAbsolute3(folder.path) ? folder.path : resolve8(workspacePath, folder.path)).replace(/\\/g, "/");
24195
+ codeWorkspaceAbsPaths.add(absPath);
24196
+ }
24197
+ const lastSyncedSet = new Set(lastSyncedRepos.map((p) => p.replace(/\\/g, "/")));
24198
+ const currentReposByAbsPath = new Map;
24199
+ for (const repo of currentRepos) {
24200
+ const absPath = resolve8(workspacePath, repo.path).replace(/\\/g, "/");
24201
+ currentReposByAbsPath.set(absPath, repo);
24202
+ }
24203
+ const currentAbsPaths = new Set(currentReposByAbsPath.keys());
24204
+ const added = [];
24205
+ const removed = [];
24206
+ const updatedRepos = [];
24207
+ for (const [absPath, repo] of currentReposByAbsPath) {
24208
+ const inLastSync = lastSyncedSet.has(absPath);
24209
+ const inCodeWorkspace = codeWorkspaceAbsPaths.has(absPath);
24210
+ if (inLastSync && !inCodeWorkspace) {
24211
+ removed.push(repo.path);
24212
+ } else {
24213
+ updatedRepos.push(repo);
24214
+ }
24215
+ }
24216
+ for (const absPath of codeWorkspaceAbsPaths) {
24217
+ const inLastSync = lastSyncedSet.has(absPath);
24218
+ const inCurrentRepos = currentAbsPaths.has(absPath);
24219
+ if (!inLastSync && !inCurrentRepos) {
24220
+ const relPath = relative3(normalizedWorkspacePath, absPath).replace(/\\/g, "/");
24221
+ added.push(relPath);
24222
+ updatedRepos.push({ path: relPath });
24223
+ }
24224
+ }
24225
+ return { updatedRepos, added, removed };
24226
+ }
24139
24227
  var DEFAULT_SETTINGS;
24140
24228
  var init_vscode_workspace = __esm(() => {
24141
24229
  DEFAULT_SETTINGS = {
@@ -24594,7 +24682,7 @@ var init_native = __esm(() => {
24594
24682
  // src/core/sync.ts
24595
24683
  import { existsSync as existsSync11, readFileSync as readFileSync2, writeFileSync as writeFileSync2, lstatSync } from "node:fs";
24596
24684
  import { rm as rm4, unlink as unlink2, rmdir, copyFile } from "node:fs/promises";
24597
- import { join as join14, resolve as resolve9, dirname as dirname7, relative as relative3 } from "node:path";
24685
+ import { join as join14, resolve as resolve9, dirname as dirname7, relative as relative4 } from "node:path";
24598
24686
  function deduplicateClientsByPath(clients, clientMappings = CLIENT_MAPPINGS) {
24599
24687
  const pathToClients = new Map;
24600
24688
  for (const client of clients) {
@@ -24692,13 +24780,16 @@ async function selectivePurgeWorkspace(workspacePath, state, clients, options) {
24692
24780
  const purgedPaths = [];
24693
24781
  for (const filePath of previousFiles) {
24694
24782
  const fullPath = join14(workspacePath, filePath);
24695
- if (!existsSync11(fullPath)) {
24783
+ const cleanPath = fullPath.replace(/\/$/, "");
24784
+ let stats;
24785
+ try {
24786
+ stats = lstatSync(cleanPath);
24787
+ } catch {
24696
24788
  continue;
24697
24789
  }
24698
24790
  try {
24699
- const stats = lstatSync(fullPath.replace(/\/$/, ""));
24700
24791
  if (stats.isSymbolicLink()) {
24701
- await unlink2(fullPath.replace(/\/$/, ""));
24792
+ await unlink2(cleanPath);
24702
24793
  } else if (filePath.endsWith("/")) {
24703
24794
  await rm4(fullPath, { recursive: true, force: true });
24704
24795
  } else {
@@ -24864,7 +24955,7 @@ function collectSyncedPaths(copyResults, workspacePath, clients, clientMappings)
24864
24955
  if (copyResult.action !== "copied" && copyResult.action !== "generated") {
24865
24956
  continue;
24866
24957
  }
24867
- const relativePath = relative3(workspacePath, copyResult.destination).replace(/\\/g, "/");
24958
+ const relativePath = relative4(workspacePath, copyResult.destination).replace(/\\/g, "/");
24868
24959
  for (const client of clients) {
24869
24960
  const mapping = mappings[client];
24870
24961
  if (mapping.skillsPath && relativePath.startsWith(mapping.skillsPath)) {
@@ -24975,20 +25066,25 @@ function buildPluginSyncPlans(plugins, clientEntries, scope, selectedClients) {
24975
25066
  fileClients.push(client);
24976
25067
  }
24977
25068
  }
24978
- return { source, clients: fileClients, nativeClients };
25069
+ const exclude = getPluginExclude(plugin);
25070
+ return { source, clients: fileClients, nativeClients, ...exclude && { exclude } };
24979
25071
  });
24980
25072
  return { plans, warnings };
24981
25073
  }
24982
25074
  async function validateAllPlugins(plans, workspacePath, offline) {
24983
- return Promise.all(plans.map(async ({ source, clients, nativeClients }) => {
25075
+ return Promise.all(plans.map(async ({ source, clients, nativeClients, exclude }) => {
24984
25076
  const validated = await validatePlugin(source, workspacePath, offline);
24985
- return { ...validated, clients, nativeClients };
25077
+ const result = { ...validated, clients, nativeClients };
25078
+ if (exclude)
25079
+ result.exclude = exclude;
25080
+ return result;
24986
25081
  }));
24987
25082
  }
24988
25083
  async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryRun, skillNameMap, clientMappings, syncMode = "symlink") {
24989
25084
  const copyResults = [];
24990
- const mappings = clientMappings ?? CLIENT_MAPPINGS;
25085
+ const mappings = resolveClientMappings(clients, clientMappings ?? CLIENT_MAPPINGS);
24991
25086
  const clientList = clients;
25087
+ const exclude = validatedPlugin.exclude;
24992
25088
  const hasUniversalClient = clientList.some((c) => isUniversalClient(c));
24993
25089
  if (syncMode === "symlink" && hasUniversalClient) {
24994
25090
  const { representativeClients } = deduplicateClientsByPath(clientList, mappings);
@@ -24997,17 +25093,19 @@ async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryR
24997
25093
  const results = await copyPluginToWorkspace(validatedPlugin.resolved, workspacePath, representative, {
24998
25094
  dryRun,
24999
25095
  ...skillNameMap && { skillNameMap },
25000
- ...clientMappings && { clientMappings },
25001
- syncMode: "copy"
25096
+ clientMappings: mappings,
25097
+ syncMode: "copy",
25098
+ ...exclude && { exclude }
25002
25099
  });
25003
25100
  copyResults.push(...results);
25004
25101
  } else {
25005
25102
  const results = await copyPluginToWorkspace(validatedPlugin.resolved, workspacePath, representative, {
25006
25103
  dryRun,
25007
25104
  ...skillNameMap && { skillNameMap },
25008
- ...clientMappings && { clientMappings },
25105
+ clientMappings: mappings,
25009
25106
  syncMode: "symlink",
25010
- canonicalSkillsPath: CANONICAL_SKILLS_PATH
25107
+ canonicalSkillsPath: CANONICAL_SKILLS_PATH,
25108
+ ...exclude && { exclude }
25011
25109
  });
25012
25110
  copyResults.push(...results);
25013
25111
  }
@@ -25018,8 +25116,9 @@ async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryR
25018
25116
  const results = await copyPluginToWorkspace(validatedPlugin.resolved, workspacePath, client, {
25019
25117
  dryRun,
25020
25118
  ...skillNameMap && { skillNameMap },
25021
- ...clientMappings && { clientMappings },
25022
- syncMode: "copy"
25119
+ clientMappings: mappings,
25120
+ syncMode: "copy",
25121
+ ...exclude && { exclude }
25023
25122
  });
25024
25123
  copyResults.push(...results);
25025
25124
  }
@@ -25035,7 +25134,7 @@ async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryR
25035
25134
  async function collectAllSkills(validatedPlugins, disabledSkills) {
25036
25135
  const allSkills = [];
25037
25136
  for (const plugin of validatedPlugins) {
25038
- const pluginName = plugin.pluginName ?? await getPluginName(plugin.resolved);
25137
+ const pluginName = plugin.pluginName ?? getPluginName(plugin.resolved);
25039
25138
  const skills = await collectPluginSkills(plugin.resolved, plugin.plugin, disabledSkills, pluginName);
25040
25139
  for (const skill of skills) {
25041
25140
  allSkills.push({
@@ -25068,60 +25167,257 @@ function buildPluginSkillNameMaps(allSkills) {
25068
25167
  pluginMap = new Map;
25069
25168
  pluginMaps.set(skill.pluginPath, pluginMap);
25070
25169
  }
25071
- pluginMap.set(skill.folderName, resolvedName);
25170
+ pluginMap.set(skill.folderName, resolvedName);
25171
+ }
25172
+ }
25173
+ return pluginMaps;
25174
+ }
25175
+ function generateVscodeWorkspaceFile(workspacePath, config) {
25176
+ const configDir = join14(workspacePath, CONFIG_DIR);
25177
+ const templatePath = join14(configDir, VSCODE_TEMPLATE_FILE);
25178
+ let template;
25179
+ if (existsSync11(templatePath)) {
25180
+ try {
25181
+ template = import_json52.default.parse(readFileSync2(templatePath, "utf-8"));
25182
+ } catch (error) {
25183
+ throw new Error(`Failed to parse ${templatePath}: ${error instanceof Error ? error.message : String(error)}`);
25184
+ }
25185
+ }
25186
+ const content = generateVscodeWorkspace({
25187
+ workspacePath,
25188
+ repositories: config.repositories,
25189
+ template
25190
+ });
25191
+ const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
25192
+ const contentStr = `${JSON.stringify(content, null, "\t")}
25193
+ `;
25194
+ writeFileSync2(outputPath, contentStr, "utf-8");
25195
+ return contentStr;
25196
+ }
25197
+ function failedSyncResult(error, overrides) {
25198
+ return {
25199
+ success: false,
25200
+ pluginResults: [],
25201
+ totalCopied: 0,
25202
+ totalFailed: 0,
25203
+ totalSkipped: 0,
25204
+ totalGenerated: 0,
25205
+ error,
25206
+ ...overrides
25207
+ };
25208
+ }
25209
+ function validateRequestedClients(requestedClients, configClientTypes, plugins) {
25210
+ const availableClients = new Set(configClientTypes);
25211
+ for (const plugin of plugins) {
25212
+ for (const client of getPluginClients(plugin) ?? []) {
25213
+ availableClients.add(client);
25214
+ }
25215
+ }
25216
+ const invalidClients = requestedClients.filter((c) => !availableClients.has(c));
25217
+ if (invalidClients.length > 0) {
25218
+ return `Client(s) not configured in workspace.yaml: ${invalidClients.join(", ")}
25219
+ Configured clients: ${Array.from(availableClients).join(", ")}`;
25220
+ }
25221
+ return null;
25222
+ }
25223
+ function countCopyResults(pluginResults, workspaceFileResults) {
25224
+ let totalCopied = 0;
25225
+ let totalFailed = 0;
25226
+ let totalSkipped = 0;
25227
+ let totalGenerated = 0;
25228
+ for (const pluginResult of pluginResults) {
25229
+ for (const copyResult of pluginResult.copyResults) {
25230
+ switch (copyResult.action) {
25231
+ case "copied":
25232
+ totalCopied++;
25233
+ break;
25234
+ case "failed":
25235
+ totalFailed++;
25236
+ break;
25237
+ case "skipped":
25238
+ totalSkipped++;
25239
+ break;
25240
+ case "generated":
25241
+ totalGenerated++;
25242
+ break;
25243
+ }
25244
+ }
25245
+ }
25246
+ for (const result of workspaceFileResults) {
25247
+ switch (result.action) {
25248
+ case "copied":
25249
+ totalCopied++;
25250
+ break;
25251
+ case "failed":
25252
+ totalFailed++;
25253
+ break;
25254
+ case "skipped":
25255
+ totalSkipped++;
25256
+ break;
25257
+ }
25258
+ }
25259
+ return { totalCopied, totalFailed, totalSkipped, totalGenerated };
25260
+ }
25261
+ async function syncNativePlugins(validPlugins, previousState, scope, workspacePath, dryRun, warnings, messages) {
25262
+ const {
25263
+ pluginsByClient: nativePluginsByClient,
25264
+ marketplaceSourcesByClient: nativeMarketplaceSources
25265
+ } = collectNativePluginSources(validPlugins);
25266
+ const previousNativeClients = previousState?.nativePlugins ? Object.keys(previousState.nativePlugins).filter((c) => (previousState.nativePlugins?.[c]?.length ?? 0) > 0) : [];
25267
+ const hasNativeWork = nativePluginsByClient.size > 0 || previousNativeClients.length > 0;
25268
+ if (hasNativeWork && !dryRun) {
25269
+ const allClients = new Set([...nativePluginsByClient.keys(), ...previousNativeClients]);
25270
+ const perClientResults = [];
25271
+ for (const clientType of allClients) {
25272
+ const nativeClient = getNativeClient(clientType);
25273
+ if (!nativeClient) {
25274
+ const sources = nativePluginsByClient.get(clientType);
25275
+ if (sources && sources.length > 0) {
25276
+ warnings.push(`Native install: no native client for ${clientType}, skipping`);
25277
+ }
25278
+ continue;
25279
+ }
25280
+ const cliAvailable = await nativeClient.isAvailable();
25281
+ if (!cliAvailable) {
25282
+ const sources = nativePluginsByClient.get(clientType);
25283
+ if (sources && sources.length > 0) {
25284
+ messages.push(`Native install: ${clientType} CLI not found, skipping native plugin installation`);
25285
+ }
25286
+ continue;
25287
+ }
25288
+ const marketplaceSources = nativeMarketplaceSources.get(clientType);
25289
+ if (marketplaceSources) {
25290
+ for (const source of marketplaceSources) {
25291
+ if (scope === "project") {
25292
+ await nativeClient.addMarketplace(source, { cwd: workspacePath });
25293
+ } else {
25294
+ await nativeClient.addMarketplace(source);
25295
+ }
25296
+ }
25297
+ }
25298
+ const currentSources = nativePluginsByClient.get(clientType) ?? [];
25299
+ const currentSpecs = currentSources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null);
25300
+ const previousPlugins = getPreviouslySyncedNativePlugins(previousState, clientType);
25301
+ const removed = previousPlugins.filter((p) => !currentSpecs.includes(p));
25302
+ for (const plugin of removed) {
25303
+ try {
25304
+ if (scope === "project") {
25305
+ await nativeClient.uninstallPlugin(plugin, "project", { cwd: workspacePath });
25306
+ } else {
25307
+ await nativeClient.uninstallPlugin(plugin, "user");
25308
+ }
25309
+ } catch (err) {
25310
+ warnings.push(`Native uninstall failed for ${plugin}: ${err instanceof Error ? err.message : String(err)}`);
25311
+ }
25312
+ }
25313
+ if (currentSources.length > 0) {
25314
+ const syncOpts = scope === "project" ? { cwd: workspacePath } : undefined;
25315
+ perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(currentSources, scope, syncOpts), clientType));
25316
+ }
25317
+ }
25318
+ if (perClientResults.length > 0) {
25319
+ return mergeNativeSyncResults(perClientResults);
25320
+ }
25321
+ } else if (nativePluginsByClient.size > 0 && dryRun) {
25322
+ const perClientResults = [];
25323
+ for (const [clientType, sources] of nativePluginsByClient) {
25324
+ const nativeClient = getNativeClient(clientType);
25325
+ if (nativeClient && sources.length > 0) {
25326
+ const syncOpts = scope === "project" ? { cwd: workspacePath, dryRun: true } : { dryRun: true };
25327
+ perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(sources, scope, syncOpts), clientType));
25328
+ }
25329
+ }
25330
+ if (perClientResults.length > 0) {
25331
+ return mergeNativeSyncResults(perClientResults);
25332
+ }
25333
+ }
25334
+ return;
25335
+ }
25336
+ async function syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages) {
25337
+ let updatedConfig = config;
25338
+ if (previousState?.vscodeWorkspaceHash && previousState?.vscodeWorkspaceRepos) {
25339
+ const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
25340
+ if (existsSync11(outputPath)) {
25341
+ const existingContent = readFileSync2(outputPath, "utf-8");
25342
+ const currentHash = computeWorkspaceHash(existingContent);
25343
+ if (currentHash !== previousState.vscodeWorkspaceHash) {
25344
+ try {
25345
+ const existingWorkspace = JSON.parse(existingContent);
25346
+ const folders = Array.isArray(existingWorkspace.folders) ? existingWorkspace.folders : [];
25347
+ const reconciled = reconcileVscodeWorkspaceFolders(workspacePath, folders, previousState.vscodeWorkspaceRepos, config.repositories);
25348
+ if (reconciled.added.length > 0 || reconciled.removed.length > 0) {
25349
+ await updateRepositories({ remove: reconciled.removed, add: reconciled.added.map((p) => ({ path: p })) }, workspacePath);
25350
+ updatedConfig = await parseWorkspaceConfig(configPath);
25351
+ if (reconciled.removed.length > 0) {
25352
+ messages.push(`Repositories removed (from .code-workspace): ${reconciled.removed.join(", ")}`);
25353
+ }
25354
+ if (reconciled.added.length > 0) {
25355
+ messages.push(`Repositories added (from .code-workspace): ${reconciled.added.join(", ")}`);
25356
+ }
25357
+ }
25358
+ } catch {}
25359
+ }
25072
25360
  }
25073
25361
  }
25074
- return pluginMaps;
25362
+ const writtenContent = generateVscodeWorkspaceFile(workspacePath, updatedConfig);
25363
+ const hash = computeWorkspaceHash(writtenContent);
25364
+ const repos = updatedConfig.repositories.map((r) => resolve9(workspacePath, r.path).replace(/\\/g, "/"));
25365
+ return { config: updatedConfig, hash, repos };
25075
25366
  }
25076
- function generateVscodeWorkspaceFile(workspacePath, config) {
25077
- const configDir = join14(workspacePath, CONFIG_DIR);
25078
- const templatePath = join14(configDir, VSCODE_TEMPLATE_FILE);
25079
- let template;
25080
- if (existsSync11(templatePath)) {
25081
- try {
25082
- template = import_json52.default.parse(readFileSync2(templatePath, "utf-8"));
25083
- } catch (error) {
25084
- throw new Error(`Failed to parse ${templatePath}: ${error instanceof Error ? error.message : String(error)}`);
25367
+ async function persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, previousState, options, nativePluginsByClient, nativeResult, extra) {
25368
+ const allCopyResults = [
25369
+ ...pluginResults.flatMap((r) => r.copyResults),
25370
+ ...workspaceFileResults
25371
+ ];
25372
+ const mappings = extra?.clientMappings ?? CLIENT_MAPPINGS;
25373
+ const resolvedMappings = resolveClientMappings(syncClients, mappings);
25374
+ const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, syncClients, resolvedMappings);
25375
+ if (options.clients && previousState) {
25376
+ for (const [client, files] of Object.entries(previousState.files)) {
25377
+ if (!syncClients.includes(client)) {
25378
+ syncedFiles[client] = files;
25379
+ }
25085
25380
  }
25086
25381
  }
25087
- const content = generateVscodeWorkspace({
25088
- workspacePath,
25089
- repositories: config.repositories,
25090
- template
25382
+ const nativePluginsState = {};
25383
+ const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
25384
+ for (const [client, sources] of nativePluginsByClient) {
25385
+ const nativeClient = getNativeClient(client);
25386
+ if (!nativeClient)
25387
+ continue;
25388
+ const clientSpecs = sources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null && installedSet.has(s));
25389
+ if (clientSpecs.length > 0) {
25390
+ nativePluginsState[client] = clientSpecs;
25391
+ }
25392
+ }
25393
+ if (options.clients && previousState?.nativePlugins) {
25394
+ for (const [client, plugins] of Object.entries(previousState.nativePlugins)) {
25395
+ if (!syncClients.includes(client)) {
25396
+ nativePluginsState[client] = plugins;
25397
+ }
25398
+ }
25399
+ }
25400
+ await saveSyncState(workspacePath, {
25401
+ files: syncedFiles,
25402
+ ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState },
25403
+ ...extra?.vscodeState?.hash && { vscodeWorkspaceHash: extra.vscodeState.hash },
25404
+ ...extra?.vscodeState?.repos && { vscodeWorkspaceRepos: extra.vscodeState.repos },
25405
+ ...extra?.mcpTrackedServers && { mcpServers: { vscode: extra.mcpTrackedServers } }
25091
25406
  });
25092
- const outputPath = getWorkspaceOutputPath(workspacePath, config.vscode);
25093
- writeFileSync2(outputPath, `${JSON.stringify(content, null, "\t")}
25094
- `, "utf-8");
25095
25407
  }
25096
25408
  async function syncWorkspace(workspacePath = process.cwd(), options = {}) {
25097
25409
  const { offline = false, dryRun = false, workspaceSourceBase, skipAgentFiles = false } = options;
25098
25410
  const configDir = join14(workspacePath, CONFIG_DIR);
25099
25411
  const configPath = join14(configDir, WORKSPACE_CONFIG_FILE);
25100
25412
  if (!existsSync11(configPath)) {
25101
- return {
25102
- success: false,
25103
- pluginResults: [],
25104
- totalCopied: 0,
25105
- totalFailed: 0,
25106
- totalSkipped: 0,
25107
- totalGenerated: 0,
25108
- error: `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
25109
- Run 'allagents workspace init <path>' to create a new workspace`
25110
- };
25413
+ return failedSyncResult(`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE} not found in ${workspacePath}
25414
+ Run 'allagents workspace init <path>' to create a new workspace`);
25111
25415
  }
25112
25416
  let config;
25113
25417
  try {
25114
25418
  config = await parseWorkspaceConfig(configPath);
25115
25419
  } catch (error) {
25116
- return {
25117
- success: false,
25118
- pluginResults: [],
25119
- totalCopied: 0,
25120
- totalFailed: 0,
25121
- totalSkipped: 0,
25122
- totalGenerated: 0,
25123
- error: error instanceof Error ? error.message : `Failed to parse ${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`
25124
- };
25420
+ return failedSyncResult(error instanceof Error ? error.message : `Failed to parse ${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`);
25125
25421
  }
25126
25422
  const hasRepositories = (config.repositories?.length ?? 0) > 0;
25127
25423
  const configClientTypes = getClientTypes(config.clients);
@@ -25130,24 +25426,9 @@ async function syncWorkspace(workspacePath = process.cwd(), options = {}) {
25130
25426
  return options.clients?.includes(name);
25131
25427
  }) : config.clients;
25132
25428
  if (options.clients) {
25133
- const availableClients = new Set(configClientTypes);
25134
- for (const plugin of config.plugins) {
25135
- for (const client of getPluginClients(plugin) ?? []) {
25136
- availableClients.add(client);
25137
- }
25138
- }
25139
- const invalidClients = options.clients.filter((c) => !availableClients.has(c));
25140
- if (invalidClients.length > 0) {
25141
- return {
25142
- success: false,
25143
- pluginResults: [],
25144
- totalCopied: 0,
25145
- totalFailed: 0,
25146
- totalSkipped: 0,
25147
- totalGenerated: 0,
25148
- error: `Client(s) not configured in workspace.yaml: ${invalidClients.join(", ")}
25149
- Configured clients: ${Array.from(availableClients).join(", ")}`
25150
- };
25429
+ const clientError = validateRequestedClients(options.clients, configClientTypes, config.plugins);
25430
+ if (clientError) {
25431
+ return failedSyncResult(clientError);
25151
25432
  }
25152
25433
  }
25153
25434
  const selectedClients = options.clients;
@@ -25161,15 +25442,7 @@ async function syncWorkspace(workspacePath = process.cwd(), options = {}) {
25161
25442
  const sourceBasePath = workspaceSourceBase ?? workspacePath;
25162
25443
  validatedWorkspaceSource = await validatePlugin(config.workspace.source, sourceBasePath, offline);
25163
25444
  if (!validatedWorkspaceSource.success) {
25164
- return {
25165
- success: false,
25166
- pluginResults: [],
25167
- totalCopied: 0,
25168
- totalFailed: 1,
25169
- totalSkipped: 0,
25170
- totalGenerated: 0,
25171
- error: `Workspace source validation failed: ${validatedWorkspaceSource.error}`
25172
- };
25445
+ return failedSyncResult(`Workspace source validation failed: ${validatedWorkspaceSource.error}`, { totalFailed: 1 });
25173
25446
  }
25174
25447
  }
25175
25448
  const failedValidations = validatedPlugins.filter((v) => !v.success);
@@ -25180,18 +25453,9 @@ async function syncWorkspace(workspacePath = process.cwd(), options = {}) {
25180
25453
  ];
25181
25454
  const messages = [];
25182
25455
  if (validPlugins.length === 0 && filteredPlans.length > 0) {
25183
- return {
25184
- success: false,
25185
- pluginResults: [],
25186
- totalCopied: 0,
25187
- totalFailed: failedValidations.length,
25188
- totalSkipped: 0,
25189
- totalGenerated: 0,
25190
- warnings,
25191
- error: `All plugins failed validation (workspace unchanged):
25456
+ return failedSyncResult(`All plugins failed validation (workspace unchanged):
25192
25457
  ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25193
- `)}`
25194
- };
25458
+ `)}`, { totalFailed: failedValidations.length, warnings });
25195
25459
  }
25196
25460
  const previousState = await loadSyncState(workspacePath);
25197
25461
  const purgedPaths = previousState ? syncClients.map((client) => ({
@@ -25211,69 +25475,7 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25211
25475
  const skillNameMap = pluginSkillMaps.get(validatedPlugin.resolved);
25212
25476
  return copyValidatedPlugin(validatedPlugin, workspacePath, validatedPlugin.clients, dryRun, skillNameMap, undefined, syncMode);
25213
25477
  }));
25214
- let nativeResult;
25215
- const {
25216
- pluginsByClient: nativePluginsByClient,
25217
- marketplaceSourcesByClient: nativeMarketplaceSources
25218
- } = collectNativePluginSources(validPlugins);
25219
- const previousNativeClients = previousState?.nativePlugins ? Object.keys(previousState.nativePlugins).filter((c) => (previousState.nativePlugins?.[c]?.length ?? 0) > 0) : [];
25220
- const hasNativeWork = nativePluginsByClient.size > 0 || previousNativeClients.length > 0;
25221
- if (hasNativeWork && !dryRun) {
25222
- const allClients = new Set([...nativePluginsByClient.keys(), ...previousNativeClients]);
25223
- const perClientResults = [];
25224
- for (const clientType of allClients) {
25225
- const nativeClient = getNativeClient(clientType);
25226
- if (!nativeClient) {
25227
- const sources = nativePluginsByClient.get(clientType);
25228
- if (sources && sources.length > 0) {
25229
- warnings.push(`Native install: no native client for ${clientType}, skipping`);
25230
- }
25231
- continue;
25232
- }
25233
- const cliAvailable = await nativeClient.isAvailable();
25234
- if (!cliAvailable) {
25235
- const sources = nativePluginsByClient.get(clientType);
25236
- if (sources && sources.length > 0) {
25237
- messages.push(`Native install: ${clientType} CLI not found, skipping native plugin installation`);
25238
- }
25239
- continue;
25240
- }
25241
- const marketplaceSources = nativeMarketplaceSources.get(clientType);
25242
- if (marketplaceSources) {
25243
- for (const source of marketplaceSources) {
25244
- await nativeClient.addMarketplace(source, { cwd: workspacePath });
25245
- }
25246
- }
25247
- const currentSources = nativePluginsByClient.get(clientType) ?? [];
25248
- const currentSpecs = currentSources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null);
25249
- const previousPlugins = getPreviouslySyncedNativePlugins(previousState, clientType);
25250
- const removed = previousPlugins.filter((p) => !currentSpecs.includes(p));
25251
- for (const plugin of removed) {
25252
- try {
25253
- await nativeClient.uninstallPlugin(plugin, "project", { cwd: workspacePath });
25254
- } catch (err) {
25255
- warnings.push(`Native uninstall failed for ${plugin}: ${err instanceof Error ? err.message : String(err)}`);
25256
- }
25257
- }
25258
- if (currentSources.length > 0) {
25259
- perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(currentSources, "project", { cwd: workspacePath }), clientType));
25260
- }
25261
- }
25262
- if (perClientResults.length > 0) {
25263
- nativeResult = mergeNativeSyncResults(perClientResults);
25264
- }
25265
- } else if (nativePluginsByClient.size > 0 && dryRun) {
25266
- const perClientResults = [];
25267
- for (const [clientType, sources] of nativePluginsByClient) {
25268
- const nativeClient = getNativeClient(clientType);
25269
- if (nativeClient && sources.length > 0) {
25270
- perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(sources, "project", { cwd: workspacePath, dryRun: true }), clientType));
25271
- }
25272
- }
25273
- if (perClientResults.length > 0) {
25274
- nativeResult = mergeNativeSyncResults(perClientResults);
25275
- }
25276
- }
25478
+ const nativeResult = await syncNativePlugins(validPlugins, previousState, "project", workspacePath, dryRun, warnings, messages);
25277
25479
  let workspaceFileResults = [];
25278
25480
  if (config.workspace) {
25279
25481
  const sourcePath = validatedWorkspaceSource?.resolved;
@@ -25291,33 +25493,17 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25291
25493
  if (fileSourceRepos.length > 0) {
25292
25494
  const { cache: cache2, errors: errors2 } = await fetchFileSourceRepos(fileSourceRepos);
25293
25495
  if (errors2.length > 0) {
25294
- return {
25295
- success: false,
25296
- pluginResults,
25297
- totalCopied: 0,
25298
- totalFailed: errors2.length,
25299
- totalSkipped: 0,
25300
- totalGenerated: 0,
25301
- error: `File source fetch failed (workspace unchanged):
25496
+ return failedSyncResult(`File source fetch failed (workspace unchanged):
25302
25497
  ${errors2.map((e) => ` - ${e}`).join(`
25303
- `)}`
25304
- };
25498
+ `)}`, { pluginResults, totalFailed: errors2.length });
25305
25499
  }
25306
25500
  githubCache = cache2;
25307
25501
  }
25308
25502
  const fileValidationErrors = validateFileSources(filesToCopy, sourcePath, githubCache);
25309
25503
  if (fileValidationErrors.length > 0) {
25310
- return {
25311
- success: false,
25312
- pluginResults,
25313
- totalCopied: 0,
25314
- totalFailed: fileValidationErrors.length,
25315
- totalSkipped: 0,
25316
- totalGenerated: 0,
25317
- error: `File source validation failed (workspace unchanged):
25504
+ return failedSyncResult(`File source validation failed (workspace unchanged):
25318
25505
  ${fileValidationErrors.map((e) => ` - ${e}`).join(`
25319
- `)}`
25320
- };
25506
+ `)}`, { pluginResults, totalFailed: fileValidationErrors.length });
25321
25507
  }
25322
25508
  workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun, githubCache, repositories: config.repositories });
25323
25509
  if (hasRepositories && !dryRun && syncClients.includes("claude") && sourcePath) {
@@ -25332,80 +25518,19 @@ ${fileValidationErrors.map((e) => ` - ${e}`).join(`
25332
25518
  if (!config.workspace && !dryRun && !skipAgentFiles) {
25333
25519
  await updateAgentFiles(workspacePath);
25334
25520
  }
25521
+ let vscodeState;
25335
25522
  if (syncClients.includes("vscode") && !dryRun) {
25336
- generateVscodeWorkspaceFile(workspacePath, config);
25337
- }
25338
- let totalCopied = 0;
25339
- let totalFailed = 0;
25340
- let totalSkipped = 0;
25341
- let totalGenerated = 0;
25342
- for (const pluginResult of pluginResults) {
25343
- for (const copyResult of pluginResult.copyResults) {
25344
- switch (copyResult.action) {
25345
- case "copied":
25346
- totalCopied++;
25347
- break;
25348
- case "failed":
25349
- totalFailed++;
25350
- break;
25351
- case "skipped":
25352
- totalSkipped++;
25353
- break;
25354
- case "generated":
25355
- totalGenerated++;
25356
- break;
25357
- }
25358
- }
25359
- }
25360
- for (const result of workspaceFileResults) {
25361
- switch (result.action) {
25362
- case "copied":
25363
- totalCopied++;
25364
- break;
25365
- case "failed":
25366
- totalFailed++;
25367
- break;
25368
- case "skipped":
25369
- totalSkipped++;
25370
- break;
25523
+ const result = await syncVscodeWorkspaceFile(workspacePath, config, configPath, previousState, messages);
25524
+ config = result.config;
25525
+ if (result.hash && result.repos) {
25526
+ vscodeState = { hash: result.hash, repos: result.repos };
25371
25527
  }
25372
25528
  }
25529
+ const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, workspaceFileResults);
25373
25530
  const hasFailures = pluginResults.some((r) => !r.success) || totalFailed > 0;
25531
+ const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
25374
25532
  if (!dryRun) {
25375
- const allCopyResults = [
25376
- ...pluginResults.flatMap((r) => r.copyResults),
25377
- ...workspaceFileResults
25378
- ];
25379
- const syncedFiles = collectSyncedPaths(allCopyResults, workspacePath, syncClients);
25380
- if (options.clients && previousState) {
25381
- for (const [client, files] of Object.entries(previousState.files)) {
25382
- if (!syncClients.includes(client)) {
25383
- syncedFiles[client] = files;
25384
- }
25385
- }
25386
- }
25387
- const nativePluginsState = {};
25388
- const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
25389
- for (const [client, sources] of nativePluginsByClient) {
25390
- const nativeClient = getNativeClient(client);
25391
- if (!nativeClient)
25392
- continue;
25393
- const clientSpecs = sources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null && installedSet.has(s));
25394
- if (clientSpecs.length > 0) {
25395
- nativePluginsState[client] = clientSpecs;
25396
- }
25397
- }
25398
- if (options.clients && previousState?.nativePlugins) {
25399
- for (const [client, plugins] of Object.entries(previousState.nativePlugins)) {
25400
- if (!syncClients.includes(client)) {
25401
- nativePluginsState[client] = plugins;
25402
- }
25403
- }
25404
- }
25405
- await saveSyncState(workspacePath, {
25406
- files: syncedFiles,
25407
- ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState }
25408
- });
25533
+ await persistSyncState(workspacePath, pluginResults, workspaceFileResults, syncClients, previousState, options, nativePluginsByClient, nativeResult, vscodeState ? { vscodeState } : undefined);
25409
25534
  }
25410
25535
  return {
25411
25536
  success: !hasFailures,
@@ -25448,18 +25573,9 @@ async function syncUserWorkspace(options = {}) {
25448
25573
  ];
25449
25574
  const messages = [];
25450
25575
  if (validPlugins.length === 0 && pluginPlans.length > 0) {
25451
- return {
25452
- success: false,
25453
- pluginResults: [],
25454
- totalCopied: 0,
25455
- totalFailed: failedValidations.length,
25456
- totalSkipped: 0,
25457
- totalGenerated: 0,
25458
- warnings,
25459
- error: `All plugins failed validation:
25576
+ return failedSyncResult(`All plugins failed validation:
25460
25577
  ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25461
- `)}`
25462
- };
25578
+ `)}`, { totalFailed: failedValidations.length, warnings });
25463
25579
  }
25464
25580
  const previousState = await loadSyncState(homeDir);
25465
25581
  if (!dryRun) {
@@ -25471,30 +25587,10 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25471
25587
  const syncMode = config.syncMode ?? "symlink";
25472
25588
  const pluginResults = await Promise.all(validPlugins.map((vp) => {
25473
25589
  const skillNameMap = pluginSkillMaps.get(vp.resolved);
25474
- return copyValidatedPlugin(vp, homeDir, vp.clients, dryRun, skillNameMap, USER_CLIENT_MAPPINGS, syncMode);
25590
+ const resolvedUserMappings = resolveClientMappings(vp.clients, USER_CLIENT_MAPPINGS);
25591
+ return copyValidatedPlugin(vp, homeDir, vp.clients, dryRun, skillNameMap, resolvedUserMappings, syncMode);
25475
25592
  }));
25476
- let totalCopied = 0;
25477
- let totalFailed = 0;
25478
- let totalSkipped = 0;
25479
- let totalGenerated = 0;
25480
- for (const pluginResult of pluginResults) {
25481
- for (const copyResult of pluginResult.copyResults) {
25482
- switch (copyResult.action) {
25483
- case "copied":
25484
- totalCopied++;
25485
- break;
25486
- case "failed":
25487
- totalFailed++;
25488
- break;
25489
- case "skipped":
25490
- totalSkipped++;
25491
- break;
25492
- case "generated":
25493
- totalGenerated++;
25494
- break;
25495
- }
25496
- }
25497
- }
25593
+ const { totalCopied, totalFailed, totalSkipped, totalGenerated } = countCopyResults(pluginResults, []);
25498
25594
  let mcpResult;
25499
25595
  if (syncClients.includes("vscode")) {
25500
25596
  const trackedMcpServers = getPreviouslySyncedMcpServers(previousState, "vscode");
@@ -25503,87 +25599,12 @@ ${failedValidations.map((v) => ` - ${v.plugin}: ${v.error}`).join(`
25503
25599
  warnings.push(...mcpResult.warnings);
25504
25600
  }
25505
25601
  }
25506
- let nativeResult;
25507
- const {
25508
- pluginsByClient: nativePluginsByClient,
25509
- marketplaceSourcesByClient: nativeMarketplaceSources
25510
- } = collectNativePluginSources(validPlugins);
25511
- const previousNativeClients = previousState?.nativePlugins ? Object.keys(previousState.nativePlugins).filter((c) => (previousState.nativePlugins?.[c]?.length ?? 0) > 0) : [];
25512
- const hasNativeWork = nativePluginsByClient.size > 0 || previousNativeClients.length > 0;
25513
- if (hasNativeWork && !dryRun) {
25514
- const allClients = new Set([...nativePluginsByClient.keys(), ...previousNativeClients]);
25515
- const perClientResults = [];
25516
- for (const clientType of allClients) {
25517
- const nativeClient = getNativeClient(clientType);
25518
- if (!nativeClient) {
25519
- const sources = nativePluginsByClient.get(clientType);
25520
- if (sources && sources.length > 0) {
25521
- warnings.push(`Native install: no native client for ${clientType}, skipping`);
25522
- }
25523
- continue;
25524
- }
25525
- const cliAvailable = await nativeClient.isAvailable();
25526
- if (!cliAvailable) {
25527
- const sources = nativePluginsByClient.get(clientType);
25528
- if (sources && sources.length > 0) {
25529
- messages.push(`Native install: ${clientType} CLI not found, skipping native plugin installation`);
25530
- }
25531
- continue;
25532
- }
25533
- const marketplaceSources = nativeMarketplaceSources.get(clientType);
25534
- if (marketplaceSources) {
25535
- for (const source of marketplaceSources) {
25536
- await nativeClient.addMarketplace(source);
25537
- }
25538
- }
25539
- const currentSources = nativePluginsByClient.get(clientType) ?? [];
25540
- const currentSpecs = currentSources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null);
25541
- const previousPlugins = getPreviouslySyncedNativePlugins(previousState, clientType);
25542
- const removed = previousPlugins.filter((p) => !currentSpecs.includes(p));
25543
- for (const plugin of removed) {
25544
- try {
25545
- await nativeClient.uninstallPlugin(plugin, "user");
25546
- } catch (err) {
25547
- warnings.push(`Native uninstall failed for ${plugin}: ${err instanceof Error ? err.message : String(err)}`);
25548
- }
25549
- }
25550
- if (currentSources.length > 0) {
25551
- perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(currentSources, "user"), clientType));
25552
- }
25553
- }
25554
- if (perClientResults.length > 0) {
25555
- nativeResult = mergeNativeSyncResults(perClientResults);
25556
- }
25557
- } else if (nativePluginsByClient.size > 0 && dryRun) {
25558
- const perClientResults = [];
25559
- for (const [clientType, sources] of nativePluginsByClient) {
25560
- const nativeClient = getNativeClient(clientType);
25561
- if (nativeClient && sources.length > 0) {
25562
- perClientResults.push(attachNativeClientContext(await nativeClient.syncPlugins(sources, "user", { dryRun: true }), clientType));
25563
- }
25564
- }
25565
- if (perClientResults.length > 0) {
25566
- nativeResult = mergeNativeSyncResults(perClientResults);
25567
- }
25568
- }
25602
+ const nativeResult = await syncNativePlugins(validPlugins, previousState, "user", homeDir, dryRun, warnings, messages);
25569
25603
  if (!dryRun) {
25570
- const allCopyResults = pluginResults.flatMap((r) => r.copyResults);
25571
- const syncedFiles = collectSyncedPaths(allCopyResults, homeDir, syncClients, USER_CLIENT_MAPPINGS);
25572
- const nativePluginsState = {};
25573
- const installedSet = new Set(nativeResult?.pluginsInstalled ?? []);
25574
- for (const [client, sources] of nativePluginsByClient) {
25575
- const nativeClient = getNativeClient(client);
25576
- if (!nativeClient)
25577
- continue;
25578
- const clientSpecs = sources.map((s) => nativeClient.toPluginSpec(s)).filter((s) => s !== null && installedSet.has(s));
25579
- if (clientSpecs.length > 0) {
25580
- nativePluginsState[client] = clientSpecs;
25581
- }
25582
- }
25583
- await saveSyncState(homeDir, {
25584
- files: syncedFiles,
25585
- ...mcpResult && { mcpServers: { vscode: mcpResult.trackedServers } },
25586
- ...Object.keys(nativePluginsState).length > 0 && { nativePlugins: nativePluginsState }
25604
+ const { pluginsByClient: nativePluginsByClient } = collectNativePluginSources(validPlugins);
25605
+ await persistSyncState(homeDir, pluginResults, [], syncClients, previousState, {}, nativePluginsByClient, nativeResult, {
25606
+ clientMappings: USER_CLIENT_MAPPINGS,
25607
+ ...mcpResult && { mcpTrackedServers: mcpResult.trackedServers }
25587
25608
  });
25588
25609
  }
25589
25610
  return {
@@ -25614,6 +25635,7 @@ var init_sync = __esm(() => {
25614
25635
  init_sync_state2();
25615
25636
  init_user_workspace();
25616
25637
  init_vscode_workspace();
25638
+ init_workspace_modify();
25617
25639
  init_vscode_mcp();
25618
25640
  init_native();
25619
25641
  import_json52 = __toESM(require_lib(), 1);
@@ -25717,9 +25739,9 @@ var init_github_fetch = __esm(() => {
25717
25739
  });
25718
25740
 
25719
25741
  // src/core/workspace.ts
25720
- import { mkdir as mkdir8, readFile as readFile10, writeFile as writeFile7, copyFile as copyFile2 } from "node:fs/promises";
25742
+ import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile7, copyFile as copyFile2 } from "node:fs/promises";
25721
25743
  import { existsSync as existsSync13 } from "node:fs";
25722
- import { join as join16, resolve as resolve10, dirname as dirname8, relative as relative4, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
25744
+ import { join as join16, resolve as resolve10, dirname as dirname8, relative as relative5, sep as sep2, isAbsolute as isAbsolute4 } from "node:path";
25723
25745
  import { fileURLToPath } from "node:url";
25724
25746
  async function initWorkspace(targetPath = ".", options = {}) {
25725
25747
  const absoluteTarget = resolve10(targetPath);
@@ -25797,7 +25819,7 @@ async function initWorkspace(targetPath = ".", options = {}) {
25797
25819
  sourceDir = parentDir;
25798
25820
  }
25799
25821
  }
25800
- workspaceYamlContent = await readFile10(sourceYamlPath, "utf-8");
25822
+ workspaceYamlContent = await readFile9(sourceYamlPath, "utf-8");
25801
25823
  if (sourceDir) {
25802
25824
  const parsed2 = load(workspaceYamlContent);
25803
25825
  const workspace = parsed2?.workspace;
@@ -25816,7 +25838,7 @@ async function initWorkspace(targetPath = ".", options = {}) {
25816
25838
  if (!existsSync13(defaultYamlPath)) {
25817
25839
  throw new Error(`Default template not found at: ${defaultTemplatePath}`);
25818
25840
  }
25819
- workspaceYamlContent = await readFile10(defaultYamlPath, "utf-8");
25841
+ workspaceYamlContent = await readFile9(defaultYamlPath, "utf-8");
25820
25842
  }
25821
25843
  if (options.clients && options.clients.length > 0) {
25822
25844
  const configParsed = load(workspaceYamlContent);
@@ -25881,7 +25903,7 @@ async function initWorkspace(targetPath = ".", options = {}) {
25881
25903
  }
25882
25904
  const sourcePath = join16(effectiveSourceDir, agentFile);
25883
25905
  if (existsSync13(sourcePath)) {
25884
- const content = await readFile10(sourcePath, "utf-8");
25906
+ const content = await readFile9(sourcePath, "utf-8");
25885
25907
  await writeFile7(targetFilePath, content, "utf-8");
25886
25908
  copiedAgentFiles.push(agentFile);
25887
25909
  }
@@ -25920,7 +25942,7 @@ Syncing plugins...`);
25920
25942
  if (targetPath !== ".") {
25921
25943
  console.log(`
25922
25944
  Next steps:`);
25923
- console.log(` cd ${relative4(process.cwd(), absoluteTarget)}`);
25945
+ console.log(` cd ${relative5(process.cwd(), absoluteTarget)}`);
25924
25946
  }
25925
25947
  return {
25926
25948
  path: absoluteTarget,
@@ -26134,7 +26156,7 @@ function buildSyncData(result) {
26134
26156
 
26135
26157
  // src/core/skills.ts
26136
26158
  import { existsSync as existsSync17 } from "node:fs";
26137
- import { readFile as readFile12, readdir as readdir4 } from "node:fs/promises";
26159
+ import { readFile as readFile11, readdir as readdir4 } from "node:fs/promises";
26138
26160
  import { join as join20, resolve as resolve12 } from "node:path";
26139
26161
  async function resolvePluginPath(pluginSource, workspacePath) {
26140
26162
  if (isPluginSpec(pluginSource)) {
@@ -26161,7 +26183,7 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
26161
26183
  if (!existsSync17(configPath)) {
26162
26184
  return [];
26163
26185
  }
26164
- const content = await readFile12(configPath, "utf-8");
26186
+ const content = await readFile11(configPath, "utf-8");
26165
26187
  const config = load(content);
26166
26188
  const disabledSkills = new Set(config.disabledSkills ?? []);
26167
26189
  const skills = [];
@@ -26170,7 +26192,7 @@ async function getAllSkillsFromPlugins(workspacePath = process.cwd()) {
26170
26192
  const pluginPath = await resolvePluginPath(pluginSource, workspacePath);
26171
26193
  if (!pluginPath)
26172
26194
  continue;
26173
- const pluginName = await getPluginName(pluginPath);
26195
+ const pluginName = getPluginName(pluginPath);
26174
26196
  const skillsDir = join20(pluginPath, "skills");
26175
26197
  if (!existsSync17(skillsDir))
26176
26198
  continue;
@@ -26700,7 +26722,7 @@ var package_default;
26700
26722
  var init_package = __esm(() => {
26701
26723
  package_default = {
26702
26724
  name: "allagents",
26703
- version: "0.26.5",
26725
+ version: "0.29.0",
26704
26726
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
26705
26727
  type: "module",
26706
26728
  bin: {
@@ -26751,6 +26773,7 @@ var init_package = __esm(() => {
26751
26773
  "gray-matter": "^4.0.3",
26752
26774
  "js-yaml": "^4.1.0",
26753
26775
  json5: "^2.2.3",
26776
+ micromatch: "^4.0.8",
26754
26777
  "simple-git": "^3.30.0",
26755
26778
  zod: "^3.22.4"
26756
26779
  },
@@ -26759,6 +26782,7 @@ var init_package = __esm(() => {
26759
26782
  "@j178/prek": "^0.3.0",
26760
26783
  "@types/bun": "latest",
26761
26784
  "@types/js-yaml": "^4.0.9",
26785
+ "@types/micromatch": "^4.0.10",
26762
26786
  "@types/node": "^20.11.5",
26763
26787
  shx: "^0.4.0",
26764
26788
  typescript: "^5.3.3"
@@ -26771,13 +26795,13 @@ var init_package = __esm(() => {
26771
26795
  });
26772
26796
 
26773
26797
  // src/cli/update-check.ts
26774
- import { readFile as readFile14 } from "node:fs/promises";
26798
+ import { readFile as readFile13 } from "node:fs/promises";
26775
26799
  import { join as join23 } from "node:path";
26776
26800
  import { spawn as spawn3 } from "node:child_process";
26777
26801
  async function getCachedUpdateInfo(path3) {
26778
26802
  const filePath = path3 ?? join23(getHomeDir(), CONFIG_DIR, CACHE_FILE);
26779
26803
  try {
26780
- const raw = await readFile14(filePath, "utf-8");
26804
+ const raw = await readFile13(filePath, "utf-8");
26781
26805
  const data = JSON.parse(raw);
26782
26806
  if (typeof data.latestVersion === "string" && typeof data.lastCheckedAt === "string") {
26783
26807
  return data;
@@ -29693,7 +29717,7 @@ __export(exports_wizard, {
29693
29717
  runWizard: () => runWizard,
29694
29718
  buildMenuOptions: () => buildMenuOptions
29695
29719
  });
29696
- import { relative as relative5 } from "node:path";
29720
+ import { relative as relative6 } from "node:path";
29697
29721
  function buildMenuOptions(context) {
29698
29722
  const options = [];
29699
29723
  if (context.needsSync) {
@@ -29710,7 +29734,7 @@ function buildMenuOptions(context) {
29710
29734
  function buildSummary(context) {
29711
29735
  const lines = [];
29712
29736
  if (context.hasWorkspace && context.workspacePath) {
29713
- const relPath = relative5(process.cwd(), context.workspacePath) || ".";
29737
+ const relPath = relative6(process.cwd(), context.workspacePath) || ".";
29714
29738
  lines.push(`Workspace: ${relPath}`);
29715
29739
  lines.push(`Project plugins: ${context.projectPluginCount}`);
29716
29740
  } else {
@@ -29849,7 +29873,7 @@ init_constants();
29849
29873
  init_marketplace();
29850
29874
  init_user_workspace();
29851
29875
  init_workspace_config();
29852
- import { readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
29876
+ import { readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
29853
29877
  import { existsSync as existsSync15 } from "node:fs";
29854
29878
  import { join as join18 } from "node:path";
29855
29879
  async function isOrphanedPlugin(pluginSpec) {
@@ -29880,7 +29904,7 @@ async function pruneOrphanedPlugins(workspacePath) {
29880
29904
  let projectResult = { removed: [], kept: [], keptEntries: [] };
29881
29905
  const projectConfigPath = join18(workspacePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
29882
29906
  if (existsSync15(projectConfigPath) && !isUserConfigPath(workspacePath)) {
29883
- const content = await readFile11(projectConfigPath, "utf-8");
29907
+ const content = await readFile10(projectConfigPath, "utf-8");
29884
29908
  const config = load(content);
29885
29909
  projectResult = await prunePlugins(config.plugins);
29886
29910
  if (projectResult.removed.length > 0) {
@@ -31239,7 +31263,7 @@ var skillsCmd = conciseSubcommands({
31239
31263
  init_workspace_config();
31240
31264
  init_constants();
31241
31265
  init_js_yaml();
31242
- import { readFile as readFile13 } from "node:fs/promises";
31266
+ import { readFile as readFile12 } from "node:fs/promises";
31243
31267
  import { existsSync as existsSync19 } from "node:fs";
31244
31268
  import { join as join22 } from "node:path";
31245
31269
  async function runSyncAndPrint(options) {
@@ -31708,7 +31732,7 @@ var pluginListCmd = import_cmd_ts4.command({
31708
31732
  if (!existsSync19(configPath))
31709
31733
  return;
31710
31734
  try {
31711
- const content = await readFile13(configPath, "utf-8");
31735
+ const content = await readFile12(configPath, "utf-8");
31712
31736
  const config = load(content);
31713
31737
  if (!config?.plugins || !config?.clients)
31714
31738
  return;
@@ -32059,13 +32083,13 @@ var pluginUpdateCmd = import_cmd_ts4.command({
32059
32083
  }
32060
32084
  if (updateProject && !isUserConfigPath(process.cwd())) {
32061
32085
  const { existsSync: existsSync20 } = await import("node:fs");
32062
- const { readFile: readFile14 } = await import("node:fs/promises");
32086
+ const { readFile: readFile13 } = await import("node:fs/promises");
32063
32087
  const { join: join23 } = await import("node:path");
32064
32088
  const { load: load2 } = await Promise.resolve().then(() => (init_js_yaml(), exports_js_yaml));
32065
32089
  const { CONFIG_DIR: CONFIG_DIR2, WORKSPACE_CONFIG_FILE: WORKSPACE_CONFIG_FILE2 } = await Promise.resolve().then(() => (init_constants(), exports_constants));
32066
32090
  const configPath = join23(process.cwd(), CONFIG_DIR2, WORKSPACE_CONFIG_FILE2);
32067
32091
  if (existsSync20(configPath)) {
32068
- const content = await readFile14(configPath, "utf-8");
32092
+ const content = await readFile13(configPath, "utf-8");
32069
32093
  const config = load2(content);
32070
32094
  for (const entry of config.plugins ?? []) {
32071
32095
  const p = getPluginSource(entry);