agentinit 1.8.1 → 1.9.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 (45) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +15 -1
  3. package/dist/cli.js +665 -339
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/apply.d.ts +1 -0
  6. package/dist/commands/apply.d.ts.map +1 -1
  7. package/dist/commands/apply.js +8 -1
  8. package/dist/commands/apply.js.map +1 -1
  9. package/dist/commands/plugins.d.ts.map +1 -1
  10. package/dist/commands/plugins.js +2 -0
  11. package/dist/commands/plugins.js.map +1 -1
  12. package/dist/commands/skills.d.ts.map +1 -1
  13. package/dist/commands/skills.js +31 -13
  14. package/dist/commands/skills.js.map +1 -1
  15. package/dist/commands/sync.d.ts.map +1 -1
  16. package/dist/commands/sync.js +6 -0
  17. package/dist/commands/sync.js.map +1 -1
  18. package/dist/core/managedState.d.ts +1 -0
  19. package/dist/core/managedState.d.ts.map +1 -1
  20. package/dist/core/managedState.js +40 -8
  21. package/dist/core/managedState.js.map +1 -1
  22. package/dist/core/pluginManager.d.ts.map +1 -1
  23. package/dist/core/pluginManager.js +46 -33
  24. package/dist/core/pluginManager.js.map +1 -1
  25. package/dist/core/projectSkills.d.ts +3 -3
  26. package/dist/core/projectSkills.d.ts.map +1 -1
  27. package/dist/core/projectSkills.js +22 -18
  28. package/dist/core/projectSkills.js.map +1 -1
  29. package/dist/core/propagator.d.ts +2 -0
  30. package/dist/core/propagator.d.ts.map +1 -1
  31. package/dist/core/propagator.js +89 -21
  32. package/dist/core/propagator.js.map +1 -1
  33. package/dist/core/skillsManager.d.ts +18 -5
  34. package/dist/core/skillsManager.d.ts.map +1 -1
  35. package/dist/core/skillsManager.js +175 -50
  36. package/dist/core/skillsManager.js.map +1 -1
  37. package/dist/types/plugins.d.ts +4 -5
  38. package/dist/types/plugins.d.ts.map +1 -1
  39. package/dist/types/skills.d.ts +18 -2
  40. package/dist/types/skills.d.ts.map +1 -1
  41. package/dist/utils/fs.d.ts +5 -0
  42. package/dist/utils/fs.d.ts.map +1 -1
  43. package/dist/utils/fs.js +86 -1
  44. package/dist/utils/fs.js.map +1 -1
  45. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -13587,20 +13587,20 @@ var require_parse_async = __commonJS((exports, module) => {
13587
13587
  const index = 0;
13588
13588
  const blocksize = opts.blocksize || 40960;
13589
13589
  const parser = new TOMLParser;
13590
- return new Promise((resolve6, reject) => {
13591
- setImmediate(parseAsyncNext, index, blocksize, resolve6, reject);
13590
+ return new Promise((resolve7, reject) => {
13591
+ setImmediate(parseAsyncNext, index, blocksize, resolve7, reject);
13592
13592
  });
13593
- function parseAsyncNext(index2, blocksize2, resolve6, reject) {
13593
+ function parseAsyncNext(index2, blocksize2, resolve7, reject) {
13594
13594
  if (index2 >= str2.length) {
13595
13595
  try {
13596
- return resolve6(parser.finish());
13596
+ return resolve7(parser.finish());
13597
13597
  } catch (err) {
13598
13598
  return reject(prettyError(err, str2));
13599
13599
  }
13600
13600
  }
13601
13601
  try {
13602
13602
  parser.parse(str2.slice(index2, index2 + blocksize2));
13603
- setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2, resolve6, reject);
13603
+ setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2, resolve7, reject);
13604
13604
  } catch (err) {
13605
13605
  reject(prettyError(err, str2));
13606
13606
  }
@@ -13623,7 +13623,7 @@ var require_parse_stream = __commonJS((exports, module) => {
13623
13623
  var parseReadable = function(stm) {
13624
13624
  const parser = new TOMLParser;
13625
13625
  stm.setEncoding("utf8");
13626
- return new Promise((resolve6, reject) => {
13626
+ return new Promise((resolve7, reject) => {
13627
13627
  let readable;
13628
13628
  let ended = false;
13629
13629
  let errored = false;
@@ -13632,7 +13632,7 @@ var require_parse_stream = __commonJS((exports, module) => {
13632
13632
  if (readable)
13633
13633
  return;
13634
13634
  try {
13635
- resolve6(parser.finish());
13635
+ resolve7(parser.finish());
13636
13636
  } catch (err) {
13637
13637
  reject(err);
13638
13638
  }
@@ -14840,51 +14840,51 @@ var require_uri_all = __commonJS((exports, module) => {
14840
14840
  }
14841
14841
  return uriTokens.join("");
14842
14842
  }
14843
- function resolveComponents(base2, relative4) {
14843
+ function resolveComponents(base2, relative5) {
14844
14844
  var options2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
14845
14845
  var skipNormalization = arguments[3];
14846
14846
  var target = {};
14847
14847
  if (!skipNormalization) {
14848
14848
  base2 = parse4(serialize(base2, options2), options2);
14849
- relative4 = parse4(serialize(relative4, options2), options2);
14849
+ relative5 = parse4(serialize(relative5, options2), options2);
14850
14850
  }
14851
14851
  options2 = options2 || {};
14852
- if (!options2.tolerant && relative4.scheme) {
14853
- target.scheme = relative4.scheme;
14854
- target.userinfo = relative4.userinfo;
14855
- target.host = relative4.host;
14856
- target.port = relative4.port;
14857
- target.path = removeDotSegments(relative4.path || "");
14858
- target.query = relative4.query;
14852
+ if (!options2.tolerant && relative5.scheme) {
14853
+ target.scheme = relative5.scheme;
14854
+ target.userinfo = relative5.userinfo;
14855
+ target.host = relative5.host;
14856
+ target.port = relative5.port;
14857
+ target.path = removeDotSegments(relative5.path || "");
14858
+ target.query = relative5.query;
14859
14859
  } else {
14860
- if (relative4.userinfo !== undefined || relative4.host !== undefined || relative4.port !== undefined) {
14861
- target.userinfo = relative4.userinfo;
14862
- target.host = relative4.host;
14863
- target.port = relative4.port;
14864
- target.path = removeDotSegments(relative4.path || "");
14865
- target.query = relative4.query;
14860
+ if (relative5.userinfo !== undefined || relative5.host !== undefined || relative5.port !== undefined) {
14861
+ target.userinfo = relative5.userinfo;
14862
+ target.host = relative5.host;
14863
+ target.port = relative5.port;
14864
+ target.path = removeDotSegments(relative5.path || "");
14865
+ target.query = relative5.query;
14866
14866
  } else {
14867
- if (!relative4.path) {
14867
+ if (!relative5.path) {
14868
14868
  target.path = base2.path;
14869
- if (relative4.query !== undefined) {
14870
- target.query = relative4.query;
14869
+ if (relative5.query !== undefined) {
14870
+ target.query = relative5.query;
14871
14871
  } else {
14872
14872
  target.query = base2.query;
14873
14873
  }
14874
14874
  } else {
14875
- if (relative4.path.charAt(0) === "/") {
14876
- target.path = removeDotSegments(relative4.path);
14875
+ if (relative5.path.charAt(0) === "/") {
14876
+ target.path = removeDotSegments(relative5.path);
14877
14877
  } else {
14878
14878
  if ((base2.userinfo !== undefined || base2.host !== undefined || base2.port !== undefined) && !base2.path) {
14879
- target.path = "/" + relative4.path;
14879
+ target.path = "/" + relative5.path;
14880
14880
  } else if (!base2.path) {
14881
- target.path = relative4.path;
14881
+ target.path = relative5.path;
14882
14882
  } else {
14883
- target.path = base2.path.slice(0, base2.path.lastIndexOf("/") + 1) + relative4.path;
14883
+ target.path = base2.path.slice(0, base2.path.lastIndexOf("/") + 1) + relative5.path;
14884
14884
  }
14885
14885
  target.path = removeDotSegments(target.path);
14886
14886
  }
14887
- target.query = relative4.query;
14887
+ target.query = relative5.query;
14888
14888
  }
14889
14889
  target.userinfo = base2.userinfo;
14890
14890
  target.host = base2.host;
@@ -14892,10 +14892,10 @@ var require_uri_all = __commonJS((exports, module) => {
14892
14892
  }
14893
14893
  target.scheme = base2.scheme;
14894
14894
  }
14895
- target.fragment = relative4.fragment;
14895
+ target.fragment = relative5.fragment;
14896
14896
  return target;
14897
14897
  }
14898
- function resolve10(baseURI, relativeURI, options2) {
14898
+ function resolve11(baseURI, relativeURI, options2) {
14899
14899
  var schemelessOptions = assign({ scheme: "null" }, options2);
14900
14900
  return serialize(resolveComponents(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions);
14901
14901
  }
@@ -15163,7 +15163,7 @@ var require_uri_all = __commonJS((exports, module) => {
15163
15163
  exports2.removeDotSegments = removeDotSegments;
15164
15164
  exports2.serialize = serialize;
15165
15165
  exports2.resolveComponents = resolveComponents;
15166
- exports2.resolve = resolve10;
15166
+ exports2.resolve = resolve11;
15167
15167
  exports2.normalize = normalize;
15168
15168
  exports2.equal = equal;
15169
15169
  exports2.escapeComponent = escapeComponent;
@@ -15526,13 +15526,13 @@ var require_json_schema_traverse = __commonJS((exports, module) => {
15526
15526
 
15527
15527
  // node_modules/ajv/lib/compile/resolve.js
15528
15528
  var require_resolve = __commonJS((exports, module) => {
15529
- var resolve10 = function(compile, root, ref) {
15529
+ var resolve11 = function(compile, root, ref) {
15530
15530
  var refVal = this._refs[ref];
15531
15531
  if (typeof refVal == "string") {
15532
15532
  if (this._refs[refVal])
15533
15533
  refVal = this._refs[refVal];
15534
15534
  else
15535
- return resolve10.call(this, compile, root, refVal);
15535
+ return resolve11.call(this, compile, root, refVal);
15536
15536
  }
15537
15537
  refVal = refVal || this._schemas[ref];
15538
15538
  if (refVal instanceof SchemaObject) {
@@ -15737,13 +15737,13 @@ var require_resolve = __commonJS((exports, module) => {
15737
15737
  var util6 = require_util3();
15738
15738
  var SchemaObject = require_schema_obj();
15739
15739
  var traverse = require_json_schema_traverse();
15740
- module.exports = resolve10;
15741
- resolve10.normalizeId = normalizeId;
15742
- resolve10.fullPath = getFullPath;
15743
- resolve10.url = resolveUrl;
15744
- resolve10.ids = resolveIds;
15745
- resolve10.inlineRef = inlineRef;
15746
- resolve10.schema = resolveSchema;
15740
+ module.exports = resolve11;
15741
+ resolve11.normalizeId = normalizeId;
15742
+ resolve11.fullPath = getFullPath;
15743
+ resolve11.url = resolveUrl;
15744
+ resolve11.ids = resolveIds;
15745
+ resolve11.inlineRef = inlineRef;
15746
+ resolve11.schema = resolveSchema;
15747
15747
  var PREVENT_SCOPE_CHANGE = util6.toHash(["properties", "patternProperties", "enum", "dependencies", "definitions"]);
15748
15748
  var SIMPLE_INLINED = util6.toHash([
15749
15749
  "type",
@@ -15774,15 +15774,15 @@ var require_error_classes = __commonJS((exports, module) => {
15774
15774
  };
15775
15775
  var MissingRefError = function(baseId, ref, message) {
15776
15776
  this.message = message || MissingRefError.message(baseId, ref);
15777
- this.missingRef = resolve10.url(baseId, ref);
15778
- this.missingSchema = resolve10.normalizeId(resolve10.fullPath(this.missingRef));
15777
+ this.missingRef = resolve11.url(baseId, ref);
15778
+ this.missingSchema = resolve11.normalizeId(resolve11.fullPath(this.missingRef));
15779
15779
  };
15780
15780
  var errorSubclass = function(Subclass) {
15781
15781
  Subclass.prototype = Object.create(Error.prototype);
15782
15782
  Subclass.prototype.constructor = Subclass;
15783
15783
  return Subclass;
15784
15784
  };
15785
- var resolve10 = require_resolve();
15785
+ var resolve11 = require_resolve();
15786
15786
  module.exports = {
15787
15787
  Validation: errorSubclass(ValidationError),
15788
15788
  MissingRef: errorSubclass(MissingRefError)
@@ -16376,7 +16376,7 @@ var require_compile = __commonJS((exports, module) => {
16376
16376
  RULES,
16377
16377
  validate: validateGenerator,
16378
16378
  util: util6,
16379
- resolve: resolve10,
16379
+ resolve: resolve11,
16380
16380
  resolveRef,
16381
16381
  usePattern,
16382
16382
  useDefault,
@@ -16415,7 +16415,7 @@ var require_compile = __commonJS((exports, module) => {
16415
16415
  return validate2;
16416
16416
  }
16417
16417
  function resolveRef(baseId2, ref, isRoot) {
16418
- ref = resolve10.url(baseId2, ref);
16418
+ ref = resolve11.url(baseId2, ref);
16419
16419
  var refIndex = refs[ref];
16420
16420
  var _refVal, refCode;
16421
16421
  if (refIndex !== undefined) {
@@ -16432,11 +16432,11 @@ var require_compile = __commonJS((exports, module) => {
16432
16432
  }
16433
16433
  }
16434
16434
  refCode = addLocalRef(ref);
16435
- var v2 = resolve10.call(self, localCompile, root, ref);
16435
+ var v2 = resolve11.call(self, localCompile, root, ref);
16436
16436
  if (v2 === undefined) {
16437
16437
  var localSchema = localRefs && localRefs[ref];
16438
16438
  if (localSchema) {
16439
- v2 = resolve10.inlineRef(localSchema, opts.inlineRefs) ? localSchema : compile.call(self, localSchema, root, localRefs, baseId2);
16439
+ v2 = resolve11.inlineRef(localSchema, opts.inlineRefs) ? localSchema : compile.call(self, localSchema, root, localRefs, baseId2);
16440
16440
  }
16441
16441
  }
16442
16442
  if (v2 === undefined) {
@@ -16578,7 +16578,7 @@ var require_compile = __commonJS((exports, module) => {
16578
16578
  code += statement(i, arr);
16579
16579
  return code;
16580
16580
  };
16581
- var resolve10 = require_resolve();
16581
+ var resolve11 = require_resolve();
16582
16582
  var util6 = require_util3();
16583
16583
  var errorClasses = require_error_classes();
16584
16584
  var stableStringify = require_fast_json_stable_stringify();
@@ -19827,7 +19827,7 @@ var require_ajv = __commonJS((exports, module) => {
19827
19827
  var id = this._getId(schema2);
19828
19828
  if (id !== undefined && typeof id != "string")
19829
19829
  throw new Error("schema id must be string");
19830
- key = resolve10.normalizeId(key || id);
19830
+ key = resolve11.normalizeId(key || id);
19831
19831
  checkUnique(this, key);
19832
19832
  this._schemas[key] = this._addSchema(schema2, _skipValidation, _meta, true);
19833
19833
  return this;
@@ -19873,7 +19873,7 @@ var require_ajv = __commonJS((exports, module) => {
19873
19873
  }
19874
19874
  };
19875
19875
  var _getSchemaFragment = function(self, ref) {
19876
- var res = resolve10.schema.call(self, { schema: {} }, ref);
19876
+ var res = resolve11.schema.call(self, { schema: {} }, ref);
19877
19877
  if (res) {
19878
19878
  var { schema: schema2, root, baseId } = res;
19879
19879
  var v = compileSchema.call(self, schema2, root, undefined, baseId);
@@ -19889,7 +19889,7 @@ var require_ajv = __commonJS((exports, module) => {
19889
19889
  }
19890
19890
  };
19891
19891
  var _getSchemaObj = function(self, keyRef) {
19892
- keyRef = resolve10.normalizeId(keyRef);
19892
+ keyRef = resolve11.normalizeId(keyRef);
19893
19893
  return self._schemas[keyRef] || self._refs[keyRef] || self._fragments[keyRef];
19894
19894
  };
19895
19895
  var removeSchema = function(schemaKeyRef) {
@@ -19917,7 +19917,7 @@ var require_ajv = __commonJS((exports, module) => {
19917
19917
  this._cache.del(cacheKey);
19918
19918
  var id = this._getId(schemaKeyRef);
19919
19919
  if (id) {
19920
- id = resolve10.normalizeId(id);
19920
+ id = resolve11.normalizeId(id);
19921
19921
  delete this._schemas[id];
19922
19922
  delete this._refs[id];
19923
19923
  }
@@ -19942,14 +19942,14 @@ var require_ajv = __commonJS((exports, module) => {
19942
19942
  if (cached)
19943
19943
  return cached;
19944
19944
  shouldAddSchema = shouldAddSchema || this._opts.addUsedSchema !== false;
19945
- var id = resolve10.normalizeId(this._getId(schema2));
19945
+ var id = resolve11.normalizeId(this._getId(schema2));
19946
19946
  if (id && shouldAddSchema)
19947
19947
  checkUnique(this, id);
19948
19948
  var willValidate = this._opts.validateSchema !== false && !skipValidation;
19949
19949
  var recursiveMeta;
19950
- if (willValidate && !(recursiveMeta = id && id == resolve10.normalizeId(schema2.$schema)))
19950
+ if (willValidate && !(recursiveMeta = id && id == resolve11.normalizeId(schema2.$schema)))
19951
19951
  this.validateSchema(schema2, true);
19952
- var localRefs = resolve10.ids.call(this, schema2);
19952
+ var localRefs = resolve11.ids.call(this, schema2);
19953
19953
  var schemaObj = new SchemaObject({
19954
19954
  id,
19955
19955
  schema: schema2,
@@ -20110,7 +20110,7 @@ var require_ajv = __commonJS((exports, module) => {
20110
20110
  var noop = function() {
20111
20111
  };
20112
20112
  var compileSchema = require_compile();
20113
- var resolve10 = require_resolve();
20113
+ var resolve11 = require_resolve();
20114
20114
  var Cache = require_cache();
20115
20115
  var SchemaObject = require_schema_obj();
20116
20116
  var stableStringify = require_fast_json_stable_stringify();
@@ -20171,27 +20171,27 @@ var require_windows = __commonJS((exports, module) => {
20171
20171
  return checkPathExt(path, options2);
20172
20172
  };
20173
20173
  var isexe = function(path, options2, cb) {
20174
- fs24.stat(path, function(er, stat) {
20174
+ fs25.stat(path, function(er, stat) {
20175
20175
  cb(er, er ? false : checkStat(stat, path, options2));
20176
20176
  });
20177
20177
  };
20178
20178
  var sync = function(path, options2) {
20179
- return checkStat(fs24.statSync(path), path, options2);
20179
+ return checkStat(fs25.statSync(path), path, options2);
20180
20180
  };
20181
20181
  module.exports = isexe;
20182
20182
  isexe.sync = sync;
20183
- var fs24 = __require("fs");
20183
+ var fs25 = __require("fs");
20184
20184
  });
20185
20185
 
20186
20186
  // node_modules/isexe/mode.js
20187
20187
  var require_mode = __commonJS((exports, module) => {
20188
20188
  var isexe = function(path, options2, cb) {
20189
- fs24.stat(path, function(er, stat) {
20189
+ fs25.stat(path, function(er, stat) {
20190
20190
  cb(er, er ? false : checkStat(stat, options2));
20191
20191
  });
20192
20192
  };
20193
20193
  var sync = function(path, options2) {
20194
- return checkStat(fs24.statSync(path), options2);
20194
+ return checkStat(fs25.statSync(path), options2);
20195
20195
  };
20196
20196
  var checkStat = function(stat, options2) {
20197
20197
  return stat.isFile() && checkMode(stat, options2);
@@ -20211,7 +20211,7 @@ var require_mode = __commonJS((exports, module) => {
20211
20211
  };
20212
20212
  module.exports = isexe;
20213
20213
  isexe.sync = sync;
20214
- var fs24 = __require("fs");
20214
+ var fs25 = __require("fs");
20215
20215
  });
20216
20216
 
20217
20217
  // node_modules/isexe/index.js
@@ -20225,12 +20225,12 @@ var require_isexe = __commonJS((exports, module) => {
20225
20225
  if (typeof Promise !== "function") {
20226
20226
  throw new TypeError("callback not provided");
20227
20227
  }
20228
- return new Promise(function(resolve10, reject) {
20228
+ return new Promise(function(resolve11, reject) {
20229
20229
  isexe(path, options2 || {}, function(er, is) {
20230
20230
  if (er) {
20231
20231
  reject(er);
20232
20232
  } else {
20233
- resolve10(is);
20233
+ resolve11(is);
20234
20234
  }
20235
20235
  });
20236
20236
  });
@@ -20256,7 +20256,7 @@ var require_isexe = __commonJS((exports, module) => {
20256
20256
  }
20257
20257
  }
20258
20258
  };
20259
- var fs24 = __require("fs");
20259
+ var fs25 = __require("fs");
20260
20260
  var core2;
20261
20261
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
20262
20262
  core2 = require_windows();
@@ -20301,27 +20301,27 @@ var require_which = __commonJS((exports, module) => {
20301
20301
  opt = {};
20302
20302
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
20303
20303
  const found = [];
20304
- const step = (i) => new Promise((resolve10, reject) => {
20304
+ const step = (i) => new Promise((resolve11, reject) => {
20305
20305
  if (i === pathEnv.length)
20306
- return opt.all && found.length ? resolve10(found) : reject(getNotFoundError(cmd));
20306
+ return opt.all && found.length ? resolve11(found) : reject(getNotFoundError(cmd));
20307
20307
  const ppRaw = pathEnv[i];
20308
20308
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
20309
20309
  const pCmd = path.join(pathPart, cmd);
20310
20310
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
20311
- resolve10(subStep(p, i, 0));
20311
+ resolve11(subStep(p, i, 0));
20312
20312
  });
20313
- const subStep = (p, i, ii) => new Promise((resolve10, reject) => {
20313
+ const subStep = (p, i, ii) => new Promise((resolve11, reject) => {
20314
20314
  if (ii === pathExt.length)
20315
- return resolve10(step(i + 1));
20315
+ return resolve11(step(i + 1));
20316
20316
  const ext = pathExt[ii];
20317
20317
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
20318
20318
  if (!er && is) {
20319
20319
  if (opt.all)
20320
20320
  found.push(p + ext);
20321
20321
  else
20322
- return resolve10(p + ext);
20322
+ return resolve11(p + ext);
20323
20323
  }
20324
- return resolve10(subStep(p, i, ii + 1));
20324
+ return resolve11(subStep(p, i, ii + 1));
20325
20325
  });
20326
20326
  });
20327
20327
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -20363,8 +20363,8 @@ var require_which = __commonJS((exports, module) => {
20363
20363
  var require_path_key = __commonJS((exports, module) => {
20364
20364
  var pathKey = (options2 = {}) => {
20365
20365
  const environment = options2.env || process.env;
20366
- const platform = options2.platform || process.platform;
20367
- if (platform !== "win32") {
20366
+ const platform2 = options2.platform || process.platform;
20367
+ if (platform2 !== "win32") {
20368
20368
  return "PATH";
20369
20369
  }
20370
20370
  return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
@@ -20463,14 +20463,14 @@ var require_readShebang = __commonJS((exports, module) => {
20463
20463
  const buffer = Buffer.alloc(size);
20464
20464
  let fd;
20465
20465
  try {
20466
- fd = fs24.openSync(command, "r");
20467
- fs24.readSync(fd, buffer, 0, size, 0);
20468
- fs24.closeSync(fd);
20466
+ fd = fs25.openSync(command, "r");
20467
+ fs25.readSync(fd, buffer, 0, size, 0);
20468
+ fs25.closeSync(fd);
20469
20469
  } catch (e) {
20470
20470
  }
20471
20471
  return shebangCommand(buffer.toString());
20472
20472
  };
20473
- var fs24 = __require("fs");
20473
+ var fs25 = __require("fs");
20474
20474
  var shebangCommand = require_shebang_command();
20475
20475
  module.exports = readShebang;
20476
20476
  });
@@ -21911,13 +21911,13 @@ var init_screen_manager = __esm(() => {
21911
21911
  // node_modules/@inquirer/core/dist/lib/promise-polyfill.js
21912
21912
  class PromisePolyfill extends Promise {
21913
21913
  static withResolver() {
21914
- let resolve11;
21914
+ let resolve12;
21915
21915
  let reject;
21916
21916
  const promise = new Promise((res, rej) => {
21917
- resolve11 = res;
21917
+ resolve12 = res;
21918
21918
  reject = rej;
21919
21919
  });
21920
- return { promise, resolve: resolve11, reject };
21920
+ return { promise, resolve: resolve12, reject };
21921
21921
  }
21922
21922
  }
21923
21923
  var init_promise_polyfill = __esm(() => {
@@ -21940,7 +21940,7 @@ function createPrompt(view) {
21940
21940
  output
21941
21941
  });
21942
21942
  const screen = new ScreenManager(rl);
21943
- const { promise, resolve: resolve11, reject } = PromisePolyfill.withResolver();
21943
+ const { promise, resolve: resolve12, reject } = PromisePolyfill.withResolver();
21944
21944
  const cancel = () => reject(new CancelPromptError);
21945
21945
  if (signal) {
21946
21946
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -21968,7 +21968,7 @@ function createPrompt(view) {
21968
21968
  cycle(() => {
21969
21969
  try {
21970
21970
  const nextView = view(config, (value) => {
21971
- setImmediate(() => resolve11(value));
21971
+ setImmediate(() => resolve12(value));
21972
21972
  });
21973
21973
  if (nextView === undefined) {
21974
21974
  const callerFilename = callSites[1]?.getFileName();
@@ -27848,26 +27848,26 @@ var require_lib3 = __commonJS((exports) => {
27848
27848
  return matches;
27849
27849
  };
27850
27850
  exports.analyse = analyse;
27851
- var detectFile = (filepath, opts = {}) => new Promise((resolve11, reject) => {
27851
+ var detectFile = (filepath, opts = {}) => new Promise((resolve12, reject) => {
27852
27852
  let fd;
27853
- const fs30 = (0, node_1.default)();
27853
+ const fs31 = (0, node_1.default)();
27854
27854
  const handler = (err, buffer) => {
27855
27855
  if (fd) {
27856
- fs30.closeSync(fd);
27856
+ fs31.closeSync(fd);
27857
27857
  }
27858
27858
  if (err) {
27859
27859
  reject(err);
27860
27860
  } else if (buffer) {
27861
- resolve11((0, exports.detect)(buffer));
27861
+ resolve12((0, exports.detect)(buffer));
27862
27862
  } else {
27863
27863
  reject(new Error("No error and no buffer received"));
27864
27864
  }
27865
27865
  };
27866
27866
  const sampleSize = (opts === null || opts === undefined ? undefined : opts.sampleSize) || 0;
27867
27867
  if (sampleSize > 0) {
27868
- fd = fs30.openSync(filepath, "r");
27868
+ fd = fs31.openSync(filepath, "r");
27869
27869
  let sample = Buffer.allocUnsafe(sampleSize);
27870
- fs30.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
27870
+ fs31.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
27871
27871
  if (err) {
27872
27872
  handler(err, null);
27873
27873
  } else {
@@ -27879,22 +27879,22 @@ var require_lib3 = __commonJS((exports) => {
27879
27879
  });
27880
27880
  return;
27881
27881
  }
27882
- fs30.readFile(filepath, handler);
27882
+ fs31.readFile(filepath, handler);
27883
27883
  });
27884
27884
  exports.detectFile = detectFile;
27885
27885
  var detectFileSync = (filepath, opts = {}) => {
27886
- const fs30 = (0, node_1.default)();
27886
+ const fs31 = (0, node_1.default)();
27887
27887
  if (opts && opts.sampleSize) {
27888
- const fd = fs30.openSync(filepath, "r");
27888
+ const fd = fs31.openSync(filepath, "r");
27889
27889
  let sample = Buffer.allocUnsafe(opts.sampleSize);
27890
- const bytesRead = fs30.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
27890
+ const bytesRead = fs31.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
27891
27891
  if (bytesRead < opts.sampleSize) {
27892
27892
  sample = sample.subarray(0, bytesRead);
27893
27893
  }
27894
- fs30.closeSync(fd);
27894
+ fs31.closeSync(fd);
27895
27895
  return (0, exports.detect)(sample);
27896
27896
  }
27897
- return (0, exports.detect)(fs30.readFileSync(filepath));
27897
+ return (0, exports.detect)(fs31.readFileSync(filepath));
27898
27898
  };
27899
27899
  exports.detectFileSync = detectFileSync;
27900
27900
  exports.default = {
@@ -32807,7 +32807,7 @@ var {
32807
32807
  } = import_.default;
32808
32808
 
32809
32809
  // dist/commands/init.js
32810
- import {resolve as resolve3} from "path";
32810
+ import {resolve as resolve4} from "path";
32811
32811
 
32812
32812
  // node_modules/ora/index.js
32813
32813
  import process9 from "node:process";
@@ -33983,7 +33983,8 @@ var logger = Logger.getInstance();
33983
33983
 
33984
33984
  // dist/utils/fs.js
33985
33985
  import {promises as fs} from "fs";
33986
- import {join, dirname} from "path";
33986
+ import {platform} from "os";
33987
+ import {join, dirname, basename, resolve, relative} from "path";
33987
33988
  async function fileExists(path) {
33988
33989
  try {
33989
33990
  await fs.access(path);
@@ -34064,9 +34065,85 @@ async function ensureDirectoryExists(filePath) {
34064
34065
  const dir = dirname(filePath);
34065
34066
  await fs.mkdir(dir, { recursive: true });
34066
34067
  }
34068
+ async function readSymlinkTarget(path) {
34069
+ try {
34070
+ return await fs.readlink(path);
34071
+ } catch {
34072
+ return null;
34073
+ }
34074
+ }
34075
+ async function resolveRealPathOrSelf(path) {
34076
+ const resolvedPath = resolve(path);
34077
+ try {
34078
+ return await fs.realpath(resolvedPath);
34079
+ } catch {
34080
+ return resolvedPath;
34081
+ }
34082
+ }
34083
+ async function resolveParentSymlinks(path) {
34084
+ const resolvedPath = resolve(path);
34085
+ const parentDir = dirname(resolvedPath);
34086
+ const baseName = basename(resolvedPath);
34087
+ try {
34088
+ const realParent = await fs.realpath(parentDir);
34089
+ return join(realParent, baseName);
34090
+ } catch {
34091
+ return resolvedPath;
34092
+ }
34093
+ }
34094
+ async function pathsReferToSameLocation(left, right) {
34095
+ const [realLeft, realRight] = await Promise.all([
34096
+ resolveRealPathOrSelf(left),
34097
+ resolveRealPathOrSelf(right)
34098
+ ]);
34099
+ if (realLeft === realRight) {
34100
+ return true;
34101
+ }
34102
+ const [leftWithResolvedParents, rightWithResolvedParents] = await Promise.all([
34103
+ resolveParentSymlinks(left),
34104
+ resolveParentSymlinks(right)
34105
+ ]);
34106
+ return leftWithResolvedParents === rightWithResolvedParents;
34107
+ }
34108
+ async function createRelativeSymlink(target, linkPath) {
34109
+ try {
34110
+ const resolvedTarget = resolve(target);
34111
+ const resolvedLinkPath = resolve(linkPath);
34112
+ if (await pathsReferToSameLocation(resolvedTarget, resolvedLinkPath)) {
34113
+ return true;
34114
+ }
34115
+ try {
34116
+ const stats = await fs.lstat(resolvedLinkPath);
34117
+ if (stats.isSymbolicLink()) {
34118
+ const existingTarget = await fs.readlink(resolvedLinkPath);
34119
+ const resolvedExistingTarget = resolve(dirname(resolvedLinkPath), existingTarget);
34120
+ if (resolvedExistingTarget === resolvedTarget) {
34121
+ return true;
34122
+ }
34123
+ await fs.rm(resolvedLinkPath, { force: true });
34124
+ } else {
34125
+ await fs.rm(resolvedLinkPath, { recursive: true, force: true });
34126
+ }
34127
+ } catch (error) {
34128
+ if (error && typeof error === "object" && "code" in error && error.code === "ELOOP") {
34129
+ await fs.rm(resolvedLinkPath, { force: true }).catch(() => {
34130
+ });
34131
+ }
34132
+ }
34133
+ await fs.mkdir(dirname(resolvedLinkPath), { recursive: true });
34134
+ const realLinkDir = await resolveParentSymlinks(dirname(resolvedLinkPath));
34135
+ const realTarget = await resolveRealPathOrSelf(resolvedTarget);
34136
+ const relativeTarget = relative(realLinkDir, realTarget);
34137
+ const symlinkType = platform() === "win32" ? "junction" : undefined;
34138
+ await fs.symlink(relativeTarget, resolvedLinkPath, symlinkType);
34139
+ return true;
34140
+ } catch {
34141
+ return false;
34142
+ }
34143
+ }
34067
34144
 
34068
34145
  // dist/core/agentDetector.js
34069
- import {resolve} from "path";
34146
+ import {resolve as resolve2} from "path";
34070
34147
  class AgentDetector {
34071
34148
  agentConfigs = [
34072
34149
  { name: "cursor", files: [".cursorrules", ".cursor/settings.json"] },
@@ -34096,7 +34173,7 @@ class AgentDetector {
34096
34173
  }
34097
34174
  async checkAgentFiles(projectPath, files) {
34098
34175
  for (const file of files) {
34099
- const fullPath = resolve(projectPath, file);
34176
+ const fullPath = resolve2(projectPath, file);
34100
34177
  if (await fileExists(fullPath)) {
34101
34178
  return { found: true, path: fullPath };
34102
34179
  }
@@ -34121,7 +34198,7 @@ class AgentDetector {
34121
34198
  }
34122
34199
 
34123
34200
  // dist/core/stackDetector.js
34124
- import {resolve as resolve2} from "path";
34201
+ import {resolve as resolve3} from "path";
34125
34202
  class StackDetector {
34126
34203
  lockFiles = [
34127
34204
  "package-lock.json",
@@ -34166,7 +34243,7 @@ class StackDetector {
34166
34243
  }
34167
34244
  async detectFromLockFiles(projectPath) {
34168
34245
  for (const lockFile of this.lockFiles) {
34169
- const lockPath = resolve2(projectPath, lockFile);
34246
+ const lockPath = resolve3(projectPath, lockFile);
34170
34247
  if (await fileExists(lockPath)) {
34171
34248
  return this.inferStackFromLockFile(projectPath, lockFile);
34172
34249
  }
@@ -34198,7 +34275,7 @@ class StackDetector {
34198
34275
  }
34199
34276
  async detectFromManifests(projectPath) {
34200
34277
  for (const manifest of this.manifestFiles) {
34201
- const manifestPath = resolve2(projectPath, manifest);
34278
+ const manifestPath = resolve3(projectPath, manifest);
34202
34279
  if (await fileExists(manifestPath)) {
34203
34280
  return this.inferStackFromManifest(projectPath, manifest);
34204
34281
  }
@@ -34230,7 +34307,7 @@ class StackDetector {
34230
34307
  }
34231
34308
  async detectFromConfigs(projectPath) {
34232
34309
  for (const config of this.configFiles) {
34233
- const configPath = resolve2(projectPath, config);
34310
+ const configPath = resolve3(projectPath, config);
34234
34311
  if (await fileExists(configPath)) {
34235
34312
  return this.inferStackFromConfig(projectPath, config);
34236
34313
  }
@@ -34289,7 +34366,7 @@ class StackDetector {
34289
34366
  };
34290
34367
  }
34291
34368
  async analyzeJavaScriptProject(projectPath) {
34292
- const packageJsonPath = resolve2(projectPath, "package.json");
34369
+ const packageJsonPath = resolve3(projectPath, "package.json");
34293
34370
  const packageJsonContent = await readFileIfExists(packageJsonPath);
34294
34371
  const info = {
34295
34372
  language: "javascript",
@@ -34304,7 +34381,7 @@ class StackDetector {
34304
34381
  ...packageJson.devDependencies
34305
34382
  };
34306
34383
  info.dependencies = Object.keys(allDeps);
34307
- if (allDeps.typescript || await fileExists(resolve2(projectPath, "tsconfig.json"))) {
34384
+ if (allDeps.typescript || await fileExists(resolve3(projectPath, "tsconfig.json"))) {
34308
34385
  info.language = "typescript";
34309
34386
  }
34310
34387
  if (allDeps.next)
@@ -34321,11 +34398,11 @@ class StackDetector {
34321
34398
  info.framework = "express";
34322
34399
  else if (allDeps.fastify)
34323
34400
  info.framework = "fastify";
34324
- if (await fileExists(resolve2(projectPath, "yarn.lock")))
34401
+ if (await fileExists(resolve3(projectPath, "yarn.lock")))
34325
34402
  info.packageManager = "yarn";
34326
- else if (await fileExists(resolve2(projectPath, "pnpm-lock.yaml")))
34403
+ else if (await fileExists(resolve3(projectPath, "pnpm-lock.yaml")))
34327
34404
  info.packageManager = "pnpm";
34328
- else if (await fileExists(resolve2(projectPath, "bun.lockb")))
34405
+ else if (await fileExists(resolve3(projectPath, "bun.lockb")))
34329
34406
  info.packageManager = "bun";
34330
34407
  else
34331
34408
  info.packageManager = "npm";
@@ -34604,7 +34681,7 @@ This is a {{STACK}} project{{FRAMEWORK_CONTEXT}}. The codebase follows modern de
34604
34681
  // dist/commands/init.js
34605
34682
  async function initCommand(options2) {
34606
34683
  const cwd = process.cwd();
34607
- const agentsPath = resolve3(cwd, "agents.md");
34684
+ const agentsPath = resolve4(cwd, "agents.md");
34608
34685
  logger.title("\uD83D\uDE80 AgentInit - Initialize Project");
34609
34686
  if (!options2.force && await fileExists(agentsPath)) {
34610
34687
  const response = await import_prompts.default({
@@ -34682,7 +34759,7 @@ async function initCommand(options2) {
34682
34759
  }
34683
34760
  var getProjectName = function(cwd) {
34684
34761
  try {
34685
- const packageJsonPath = resolve3(cwd, "package.json");
34762
+ const packageJsonPath = resolve4(cwd, "package.json");
34686
34763
  const packageJson = __require(packageJsonPath);
34687
34764
  return packageJson.name || cwd.split("/").pop() || "project";
34688
34765
  } catch {
@@ -34692,18 +34769,18 @@ var getProjectName = function(cwd) {
34692
34769
 
34693
34770
  // dist/core/skillsManager.js
34694
34771
  var import_gray_matter = __toESM(require_gray_matter(), 1);
34695
- import {resolve as resolve6, join as join3, relative} from "path";
34772
+ import {resolve as resolve7, join as join3, relative as relative2} from "path";
34696
34773
  import {promises as fs18} from "fs";
34697
- import {tmpdir} from "os";
34774
+ import {homedir as homedir3, tmpdir} from "os";
34698
34775
  import {execFile} from "child_process";
34699
34776
  import {promisify} from "util";
34700
34777
 
34701
34778
  // dist/agents/Agent.js
34702
- import {resolve as resolve5} from "path";
34779
+ import {resolve as resolve6} from "path";
34703
34780
  import {homedir as homedir2} from "os";
34704
34781
 
34705
34782
  // dist/utils/paths.js
34706
- import {resolve as resolve4, join as join2} from "path";
34783
+ import {resolve as resolve5, join as join2} from "path";
34707
34784
  import {homedir} from "os";
34708
34785
  function getHomeDirectory() {
34709
34786
  return homedir();
@@ -34737,8 +34814,8 @@ function resolveGlobalConfigPath(globalConfigPath, globalConfigPaths) {
34737
34814
  return expandTilde(globalConfigPath);
34738
34815
  }
34739
34816
  if (globalConfigPaths) {
34740
- const platform = getPlatform();
34741
- const platformPath = globalConfigPaths[platform];
34817
+ const platform2 = getPlatform();
34818
+ const platformPath = globalConfigPaths[platform2];
34742
34819
  if (platformPath) {
34743
34820
  return expandTilde(platformPath);
34744
34821
  }
@@ -34765,7 +34842,7 @@ function getFullGlobalConfigPath(globalConfigPath, globalConfigPaths) {
34765
34842
  return null;
34766
34843
  }
34767
34844
  const resolvedPath = resolveEnvironmentVariables(path);
34768
- return resolve4(resolvedPath);
34845
+ return resolve5(resolvedPath);
34769
34846
  }
34770
34847
 
34771
34848
  // node_modules/contextcalc/dist/lib/index.js
@@ -35198,7 +35275,7 @@ class Agent {
35198
35275
  }
35199
35276
  async detectPresence(projectPath) {
35200
35277
  for (const configFile of this.configFiles) {
35201
- const fullPath = resolve5(projectPath, configFile.path);
35278
+ const fullPath = resolve6(projectPath, configFile.path);
35202
35279
  if (await pathExists(fullPath, configFile.type)) {
35203
35280
  return {
35204
35281
  agent: this,
@@ -35209,7 +35286,7 @@ class Agent {
35209
35286
  return null;
35210
35287
  }
35211
35288
  getNativeMcpPath(projectPath) {
35212
- return resolve5(projectPath, this.nativeConfigPath);
35289
+ return resolve6(projectPath, this.nativeConfigPath);
35213
35290
  }
35214
35291
  getGlobalMcpPath() {
35215
35292
  return getFullGlobalConfigPath(this.definition.globalConfigPath, this.definition.globalConfigPaths);
@@ -35218,7 +35295,7 @@ class Agent {
35218
35295
  if (!this.capabilities.rules || !this.definition.rulesPath) {
35219
35296
  return null;
35220
35297
  }
35221
- return resolve5(projectPath, this.definition.rulesPath);
35298
+ return resolve6(projectPath, this.definition.rulesPath);
35222
35299
  }
35223
35300
  getGlobalRulesPath() {
35224
35301
  if (!this.capabilities.rules) {
@@ -35278,7 +35355,7 @@ class Agent {
35278
35355
  if (global3) {
35279
35356
  return this.definition.skillPaths.global.replace("~", homedir2());
35280
35357
  }
35281
- return resolve5(projectPath, this.definition.skillPaths.project);
35358
+ return resolve6(projectPath, this.definition.skillPaths.project);
35282
35359
  }
35283
35360
  getProjectRulesStandard() {
35284
35361
  return this.definition.projectStandards?.rules || null;
@@ -37370,7 +37447,7 @@ class SkillsManager {
37370
37447
  const skills = [];
37371
37448
  const seen = new Set;
37372
37449
  for (const searchDir of SKILL_SEARCH_DIRS) {
37373
- const fullDir = resolve6(repoPath, searchDir);
37450
+ const fullDir = resolve7(repoPath, searchDir);
37374
37451
  if (!await fileExists(fullDir))
37375
37452
  continue;
37376
37453
  const directSkillMd = join3(fullDir, "SKILL.md");
@@ -37378,7 +37455,7 @@ class SkillsManager {
37378
37455
  const parsed = await this.parseSkillMd(directSkillMd);
37379
37456
  if (parsed && !seen.has(parsed.name)) {
37380
37457
  seen.add(parsed.name);
37381
- skills.push({ ...parsed, path: resolve6(fullDir) });
37458
+ skills.push({ ...parsed, path: resolve7(fullDir) });
37382
37459
  }
37383
37460
  }
37384
37461
  const directSkillMdLower = join3(fullDir, "skill.md");
@@ -37386,7 +37463,7 @@ class SkillsManager {
37386
37463
  const parsed = await this.parseSkillMd(directSkillMdLower);
37387
37464
  if (parsed && !seen.has(parsed.name)) {
37388
37465
  seen.add(parsed.name);
37389
- skills.push({ ...parsed, path: resolve6(fullDir) });
37466
+ skills.push({ ...parsed, path: resolve7(fullDir) });
37390
37467
  }
37391
37468
  }
37392
37469
  if (!await isDirectory(fullDir))
@@ -37440,7 +37517,7 @@ class SkillsManager {
37440
37517
  async installSkill(skillPath, skillName, targetDir, copy = false) {
37441
37518
  const normalizedSkillName = this.normalizeSkillName(skillName);
37442
37519
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
37443
- await fs18.mkdir(resolve6(targetDir), { recursive: true });
37520
+ await fs18.mkdir(resolve7(targetDir), { recursive: true });
37444
37521
  if (await fileExists(destPath)) {
37445
37522
  await fs18.rm(destPath, { recursive: true, force: true });
37446
37523
  }
@@ -37454,7 +37531,7 @@ class SkillsManager {
37454
37531
  async installSkillFromContent(skillName, skillContent, targetDir) {
37455
37532
  const normalizedSkillName = this.normalizeSkillName(skillName);
37456
37533
  const destPath = this.resolveInstallPath(targetDir, normalizedSkillName);
37457
- await fs18.mkdir(resolve6(targetDir), { recursive: true });
37534
+ await fs18.mkdir(resolve7(targetDir), { recursive: true });
37458
37535
  if (await fileExists(destPath)) {
37459
37536
  await fs18.rm(destPath, { recursive: true, force: true });
37460
37537
  }
@@ -37462,6 +37539,95 @@ class SkillsManager {
37462
37539
  await fs18.writeFile(join3(destPath, "SKILL.md"), skillContent, "utf8");
37463
37540
  return destPath;
37464
37541
  }
37542
+ getCanonicalSkillsDir(projectPath, global3 = false) {
37543
+ return global3 ? resolve7(homedir3(), ".agents/skills") : resolve7(projectPath, ".agents/skills");
37544
+ }
37545
+ async getInstallPlan(skillName, agent, projectPath, options2 = {}) {
37546
+ const normalizedSkillName = this.normalizeSkillName(skillName);
37547
+ const skillsDir = agent.getSkillsDir(projectPath, options2.global);
37548
+ if (!skillsDir) {
37549
+ throw new Error(`No skills directory for ${agent.name}`);
37550
+ }
37551
+ const agentPath = this.resolveInstallPath(skillsDir, normalizedSkillName);
37552
+ if (options2.copy) {
37553
+ return {
37554
+ path: agentPath,
37555
+ mode: "copy"
37556
+ };
37557
+ }
37558
+ const canonicalPath = this.resolveInstallPath(this.getCanonicalSkillsDir(projectPath, options2.global ?? false), normalizedSkillName);
37559
+ if (await pathsReferToSameLocation(canonicalPath, agentPath)) {
37560
+ return {
37561
+ path: canonicalPath,
37562
+ canonicalPath,
37563
+ mode: "symlink"
37564
+ };
37565
+ }
37566
+ return {
37567
+ path: agentPath,
37568
+ canonicalPath,
37569
+ mode: "symlink"
37570
+ };
37571
+ }
37572
+ async installSkillForAgent(skillPath, skillName, agent, projectPath, options2 = {}) {
37573
+ const plan = await this.getInstallPlan(skillName, agent, projectPath, options2);
37574
+ const skillsDir = agent.getSkillsDir(projectPath, options2.global);
37575
+ if (!skillsDir) {
37576
+ throw new Error(`No skills directory for ${agent.name}`);
37577
+ }
37578
+ if (plan.mode === "copy") {
37579
+ await this.installSkill(skillPath, skillName, skillsDir, true);
37580
+ return plan;
37581
+ }
37582
+ const canonicalPath = plan.canonicalPath;
37583
+ if (!canonicalPath) {
37584
+ throw new Error(`Missing canonical path for ${skillName}`);
37585
+ }
37586
+ await this.cleanAndCreateDirectory(canonicalPath);
37587
+ await this.copyDir(skillPath, canonicalPath);
37588
+ if (plan.path === canonicalPath) {
37589
+ return plan;
37590
+ }
37591
+ const symlinkCreated = await createRelativeSymlink(canonicalPath, plan.path);
37592
+ if (!symlinkCreated) {
37593
+ await this.cleanAndCreateDirectory(plan.path);
37594
+ await this.copyDir(skillPath, plan.path);
37595
+ return {
37596
+ ...plan,
37597
+ symlinkFailed: true
37598
+ };
37599
+ }
37600
+ return plan;
37601
+ }
37602
+ async installSkillFromContentForAgent(skillName, skillContent, agent, projectPath, options2 = {}) {
37603
+ const plan = await this.getInstallPlan(skillName, agent, projectPath, options2);
37604
+ const skillsDir = agent.getSkillsDir(projectPath, options2.global);
37605
+ if (!skillsDir) {
37606
+ throw new Error(`No skills directory for ${agent.name}`);
37607
+ }
37608
+ if (plan.mode === "copy") {
37609
+ await this.installSkillFromContent(skillName, skillContent, skillsDir);
37610
+ return plan;
37611
+ }
37612
+ const canonicalPath = plan.canonicalPath;
37613
+ if (!canonicalPath) {
37614
+ throw new Error(`Missing canonical path for ${skillName}`);
37615
+ }
37616
+ await this.cleanAndCreateDirectory(canonicalPath);
37617
+ await fs18.writeFile(join3(canonicalPath, "SKILL.md"), skillContent, "utf8");
37618
+ if (plan.path === canonicalPath) {
37619
+ return plan;
37620
+ }
37621
+ const symlinkCreated = await createRelativeSymlink(canonicalPath, plan.path);
37622
+ if (!symlinkCreated) {
37623
+ await this.installSkillFromContent(skillName, skillContent, skillsDir);
37624
+ return {
37625
+ ...plan,
37626
+ symlinkFailed: true
37627
+ };
37628
+ }
37629
+ return plan;
37630
+ }
37465
37631
  normalizeSkillName(skillName) {
37466
37632
  const normalized = skillName.trim();
37467
37633
  if (!normalized) {
@@ -37473,9 +37639,9 @@ class SkillsManager {
37473
37639
  return normalized;
37474
37640
  }
37475
37641
  resolveInstallPath(targetDir, skillName) {
37476
- const resolvedTargetDir = resolve6(targetDir);
37477
- const destPath = resolve6(resolvedTargetDir, skillName);
37478
- const relativePath = relative(resolvedTargetDir, destPath);
37642
+ const resolvedTargetDir = resolve7(targetDir);
37643
+ const destPath = resolve7(resolvedTargetDir, skillName);
37644
+ const relativePath = relative2(resolvedTargetDir, destPath);
37479
37645
  if (relativePath === "" || relativePath.startsWith("..") || relativePath.includes("/../") || relativePath.includes("\\..\\")) {
37480
37646
  throw new Error(`Refusing to install skill outside target directory: ${skillName}`);
37481
37647
  }
@@ -37484,18 +37650,17 @@ class SkillsManager {
37484
37650
  getInstallPath(skillName, targetDir) {
37485
37651
  return this.resolveInstallPath(targetDir, this.normalizeSkillName(skillName));
37486
37652
  }
37653
+ async cleanAndCreateDirectory(path) {
37654
+ await fs18.rm(path, { recursive: true, force: true }).catch(() => {
37655
+ });
37656
+ await fs18.mkdir(path, { recursive: true });
37657
+ }
37658
+ isWithinPath(basePath, targetPath) {
37659
+ const relativePath = relative2(resolve7(basePath), resolve7(targetPath));
37660
+ return relativePath === "" || !relativePath.startsWith("..") && !relativePath.includes("/../") && !relativePath.includes("\\..\\");
37661
+ }
37487
37662
  async copyDir(src, dest) {
37488
- await fs18.mkdir(dest, { recursive: true });
37489
- const entries = await fs18.readdir(src, { withFileTypes: true });
37490
- for (const entry of entries) {
37491
- const srcPath = join3(src, entry.name);
37492
- const destPath = join3(dest, entry.name);
37493
- if (entry.isDirectory()) {
37494
- await this.copyDir(srcPath, destPath);
37495
- } else {
37496
- await fs18.copyFile(srcPath, destPath);
37497
- }
37498
- }
37663
+ await fs18.cp(src, dest, { recursive: true, dereference: true });
37499
37664
  }
37500
37665
  async addFromSource(source, projectPath, options2 = {}) {
37501
37666
  const resolved = this.resolveSource(source);
@@ -37507,7 +37672,7 @@ class SkillsManager {
37507
37672
  tempDir = await this.cloneRepo(resolved.url);
37508
37673
  repoPath = tempDir;
37509
37674
  } else {
37510
- repoPath = resolve6(resolved.path || source);
37675
+ repoPath = resolve7(resolved.path || source);
37511
37676
  if (!await fileExists(repoPath)) {
37512
37677
  throw new Error(`Local path not found: ${repoPath}`);
37513
37678
  }
@@ -37529,7 +37694,7 @@ class SkillsManager {
37529
37694
  };
37530
37695
  }
37531
37696
  const result = { installed: [], skipped: [] };
37532
- const dirToAgents = new Map;
37697
+ const installableAgents = [];
37533
37698
  for (const agent of agents) {
37534
37699
  if (!agent.supportsSkills()) {
37535
37700
  for (const skill of skills) {
@@ -37544,18 +37709,17 @@ class SkillsManager {
37544
37709
  }
37545
37710
  continue;
37546
37711
  }
37547
- const existing = dirToAgents.get(skillsDir) || [];
37548
- existing.push(agent);
37549
- dirToAgents.set(skillsDir, existing);
37712
+ installableAgents.push(agent);
37550
37713
  }
37551
37714
  for (const skill of skills) {
37552
- for (const [skillsDir, dirAgents] of dirToAgents) {
37715
+ for (const agent of installableAgents) {
37553
37716
  try {
37554
- const shouldCopy = options2.copy || resolved.type === "github";
37555
- const installedPath = await this.installSkill(skill.path, skill.name, skillsDir, shouldCopy);
37556
- for (const agent of dirAgents) {
37557
- result.installed.push({ skill, agent: agent.id, path: installedPath });
37558
- }
37717
+ const installOptions = {
37718
+ ...options2.global !== undefined ? { global: options2.global } : {},
37719
+ ...options2.copy !== undefined ? { copy: options2.copy } : {}
37720
+ };
37721
+ const installed = await this.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
37722
+ result.installed.push({ skill, agent: agent.id, ...installed });
37559
37723
  } catch (error) {
37560
37724
  result.skipped.push({ skill, reason: error.message });
37561
37725
  }
@@ -37571,6 +37735,9 @@ class SkillsManager {
37571
37735
  }
37572
37736
  async listInstalled(projectPath, options2 = {}) {
37573
37737
  const agents = await this.getTargetAgents(projectPath, options2);
37738
+ return this.listInstalledForAgents(projectPath, agents, options2);
37739
+ }
37740
+ async listInstalledForAgents(projectPath, agents, options2 = {}) {
37574
37741
  const installed = [];
37575
37742
  for (const agent of agents) {
37576
37743
  if (!agent.supportsSkills())
@@ -37597,9 +37764,17 @@ class SkillsManager {
37597
37764
  if (!parsed)
37598
37765
  continue;
37599
37766
  let isSymlink = false;
37767
+ let canonicalPath;
37600
37768
  try {
37601
37769
  const stat = await fs18.lstat(entryPath);
37602
37770
  isSymlink = stat.isSymbolicLink();
37771
+ const canonicalBase = this.getCanonicalSkillsDir(projectPath, scope === "global");
37772
+ const resolvedEntryPath = await resolveRealPathOrSelf(entryPath);
37773
+ if (this.isWithinPath(canonicalBase, resolvedEntryPath)) {
37774
+ canonicalPath = resolvedEntryPath;
37775
+ } else if (this.isWithinPath(canonicalBase, entryPath)) {
37776
+ canonicalPath = resolve7(entryPath);
37777
+ }
37603
37778
  } catch {
37604
37779
  }
37605
37780
  installed.push({
@@ -37608,7 +37783,9 @@ class SkillsManager {
37608
37783
  path: entryPath,
37609
37784
  agent: agent.id,
37610
37785
  scope,
37611
- isSymlink
37786
+ isSymlink,
37787
+ mode: canonicalPath ? "symlink" : "copy",
37788
+ ...canonicalPath ? { canonicalPath } : {}
37612
37789
  });
37613
37790
  }
37614
37791
  }
@@ -37617,42 +37794,60 @@ class SkillsManager {
37617
37794
  }
37618
37795
  async remove(skillNames, projectPath, options2 = {}) {
37619
37796
  const agents = await this.getTargetAgents(projectPath, options2);
37797
+ const allAgents = this.agentManager.getAllAgents().filter((agent) => agent.supportsSkills());
37620
37798
  const removed = [];
37621
37799
  const notFound = [];
37800
+ const skipped = [];
37622
37801
  const namesLower = new Set(skillNames.map((n) => n.toLowerCase()));
37623
- for (const agent of agents) {
37624
- if (!agent.supportsSkills())
37625
- continue;
37626
- const scopes = [];
37627
- if (!options2.global) {
37628
- scopes.push({ scope: "project", dir: agent.getSkillsDir(projectPath, false) });
37629
- }
37630
- if (options2.global) {
37631
- scopes.push({ scope: "global", dir: agent.getSkillsDir(projectPath, true) });
37802
+ const targetAgentIds = new Set(agents.map((agent) => agent.id));
37803
+ const installed = await this.listInstalledForAgents(projectPath, allAgents, options2);
37804
+ const scopedInstalled = installed.filter((entry) => options2.global ? entry.scope === "global" : entry.scope === "project");
37805
+ const targetedEntries = scopedInstalled.filter((entry) => targetAgentIds.has(entry.agent) && namesLower.has(entry.name.toLowerCase()));
37806
+ const targetedKeys = new Set(targetedEntries.map((entry) => `${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`));
37807
+ const remainingEntries = installed.filter((entry) => !targetedKeys.has(`${entry.agent}:${entry.scope}:${entry.path}:${entry.name}`));
37808
+ const removedPaths = new Set;
37809
+ const removedCanonicalPaths = new Set;
37810
+ for (const entry of targetedEntries) {
37811
+ const removedEntry = `${entry.agent}:${entry.name}`;
37812
+ if (entry.canonicalPath && entry.path === entry.canonicalPath) {
37813
+ const stillReferenced = remainingEntries.some((other) => other.name.toLowerCase() === entry.name.toLowerCase() && other.canonicalPath === entry.canonicalPath);
37814
+ if (stillReferenced) {
37815
+ skipped.push({
37816
+ name: entry.name,
37817
+ reason: `Shared canonical path still used by another agent: ${entry.canonicalPath}`
37818
+ });
37819
+ continue;
37820
+ }
37632
37821
  }
37633
- for (const { dir } of scopes) {
37634
- if (!dir || !await fileExists(dir))
37822
+ if (!removedPaths.has(entry.path)) {
37823
+ try {
37824
+ await fs18.rm(entry.path, { recursive: true, force: true });
37825
+ removedPaths.add(entry.path);
37826
+ } catch {
37827
+ skipped.push({
37828
+ name: entry.name,
37829
+ reason: `Could not remove skill path: ${entry.path}`
37830
+ });
37635
37831
  continue;
37636
- const entries = await listFiles(dir);
37637
- for (const entry of entries) {
37638
- if (!namesLower.has(entry.toLowerCase()))
37639
- continue;
37640
- const entryPath = join3(dir, entry);
37641
- try {
37642
- await fs18.rm(entryPath, { recursive: true, force: true });
37643
- removed.push(`${agent.id}:${entry}`);
37644
- } catch {
37645
- }
37646
37832
  }
37647
37833
  }
37834
+ if (entry.canonicalPath && entry.canonicalPath !== entry.path && !removedCanonicalPaths.has(entry.canonicalPath)) {
37835
+ const stillReferenced = remainingEntries.some((other) => other.name.toLowerCase() === entry.name.toLowerCase() && other.canonicalPath === entry.canonicalPath);
37836
+ if (!stillReferenced) {
37837
+ await fs18.rm(entry.canonicalPath, { recursive: true, force: true }).catch(() => {
37838
+ });
37839
+ removedCanonicalPaths.add(entry.canonicalPath);
37840
+ }
37841
+ }
37842
+ removed.push(removedEntry);
37648
37843
  }
37649
- const removedNames = new Set(removed.map((r) => r.split(":")[1]?.toLowerCase()));
37844
+ const foundNames = new Set(targetedEntries.map((entry) => entry.name.toLowerCase()));
37650
37845
  for (const name of skillNames) {
37651
- if (!removedNames.has(name.toLowerCase())) {
37846
+ if (!foundNames.has(name.toLowerCase())) {
37652
37847
  notFound.push(name);
37653
37848
  }
37654
37849
  }
37655
- return { removed, notFound };
37850
+ return { removed, notFound, skipped };
37656
37851
  }
37657
37852
  }
37658
37853
 
@@ -37723,11 +37918,12 @@ async function detectCommand(options2) {
37723
37918
  }
37724
37919
 
37725
37920
  // dist/commands/sync.js
37726
- import {relative as relative3} from "path";
37921
+ import {relative as relative4} from "path";
37727
37922
 
37728
37923
  // dist/core/propagator.js
37729
37924
  var import_gray_matter2 = __toESM(require_gray_matter(), 1);
37730
- import {resolve as resolve7} from "path";
37925
+ import {promises as fs20} from "fs";
37926
+ import {resolve as resolve8} from "path";
37731
37927
 
37732
37928
  // node_modules/js-yaml/dist/js-yaml.mjs
37733
37929
  var isNothing = function(subject) {
@@ -40356,6 +40552,9 @@ var parseTargets = function(value) {
40356
40552
  }
40357
40553
  return [];
40358
40554
  };
40555
+ var parseRulesAlias = function(value) {
40556
+ return typeof value === "string" && value.trim().toLowerCase() === "agents" ? "agents" : null;
40557
+ };
40359
40558
 
40360
40559
  class Propagator {
40361
40560
  agentAdapters = new Map;
@@ -40367,9 +40566,10 @@ class Propagator {
40367
40566
  success: true,
40368
40567
  changes: [],
40369
40568
  errors: [],
40569
+ warnings: [],
40370
40570
  resolvedTargets: []
40371
40571
  };
40372
- const agentsPath = resolve7(projectPath, "agents.md");
40572
+ const agentsPath = resolve8(projectPath, "agents.md");
40373
40573
  if (!await fileExists(agentsPath)) {
40374
40574
  result.success = false;
40375
40575
  result.errors.push("agents.md not found. Run `agentinit init` first.");
@@ -40384,12 +40584,14 @@ class Propagator {
40384
40584
  }
40385
40585
  const parsed = import_gray_matter2.default(agentsContent);
40386
40586
  const targets = await this.resolveTargets(projectPath, options2.targets, parsed.data.targets);
40587
+ const rulesAlias = parseRulesAlias(parsed.data.rules_alias);
40387
40588
  result.resolvedTargets = targets;
40388
- const generatedFiles = await this.buildGeneratedFiles(projectPath, parsed.content, targets);
40589
+ const generatedFiles = await this.buildGeneratedFiles(projectPath, parsed.content, targets, rulesAlias);
40389
40590
  for (const generatedFile of generatedFiles) {
40390
40591
  try {
40391
40592
  const syncResult = await this.writeGeneratedFile(projectPath, generatedFile, options2);
40392
40593
  result.changes.push(...syncResult.changes);
40594
+ result.warnings.push(...syncResult.warnings);
40393
40595
  if (!syncResult.success) {
40394
40596
  result.errors.push(...syncResult.errors);
40395
40597
  }
@@ -40421,51 +40623,86 @@ class Propagator {
40421
40623
  }
40422
40624
  return this.getDefaultTargets();
40423
40625
  }
40424
- async buildGeneratedFiles(projectPath, content, targets) {
40626
+ async buildGeneratedFiles(projectPath, content, targets, rulesAlias) {
40425
40627
  const generatedFiles = new Map;
40628
+ if (rulesAlias === "agents" && targets.includes("claude")) {
40629
+ this.mergeGeneratedFile(projectPath, generatedFiles, {
40630
+ path: "AGENTS.md",
40631
+ kind: "file",
40632
+ content
40633
+ }, "claude");
40634
+ this.mergeGeneratedFile(projectPath, generatedFiles, {
40635
+ path: "CLAUDE.md",
40636
+ kind: "symlink",
40637
+ target: "AGENTS.md",
40638
+ content
40639
+ }, "claude");
40640
+ }
40426
40641
  for (const target of targets) {
40642
+ if (target === "claude" && rulesAlias === "agents") {
40643
+ continue;
40644
+ }
40427
40645
  const adapter = this.agentAdapters.get(target);
40428
40646
  if (!adapter) {
40429
40647
  throw new Error(`No adapter found for agent: ${target}`);
40430
40648
  }
40431
40649
  const outputs = await adapter.buildOutputs(projectPath, content);
40432
40650
  for (const output of outputs) {
40433
- const outputPath = resolve7(projectPath, output.path);
40434
- const existing = generatedFiles.get(outputPath);
40435
- if (existing) {
40436
- if (existing.content !== output.content) {
40437
- throw new Error(`Conflicting generated content for ${output.path}`);
40438
- }
40439
- existing.agents.push(target);
40440
- continue;
40441
- }
40442
- generatedFiles.set(outputPath, {
40443
- path: outputPath,
40444
- content: normalizeContent(output.content),
40445
- agents: [target],
40446
- ignorePath: output.ignorePath ?? output.path
40447
- });
40651
+ this.mergeGeneratedFile(projectPath, generatedFiles, output, target);
40448
40652
  }
40449
40653
  }
40450
40654
  return [...generatedFiles.values()];
40451
40655
  }
40656
+ mergeGeneratedFile(projectPath, generatedFiles, output, agentId) {
40657
+ const outputPath = resolve8(projectPath, output.path);
40658
+ const nextKind = output.kind ?? "file";
40659
+ const nextContent = nextKind === "file" || output.content !== undefined ? normalizeContent(output.content || "") : undefined;
40660
+ const existing = generatedFiles.get(outputPath);
40661
+ if (existing) {
40662
+ if (existing.kind !== nextKind) {
40663
+ throw new Error(`Conflicting generated output type for ${output.path}`);
40664
+ }
40665
+ if (existing.target !== output.target) {
40666
+ throw new Error(`Conflicting generated symlink target for ${output.path}`);
40667
+ }
40668
+ if (existing.content !== nextContent) {
40669
+ throw new Error(`Conflicting generated content for ${output.path}`);
40670
+ }
40671
+ existing.agents.push(agentId);
40672
+ return;
40673
+ }
40674
+ generatedFiles.set(outputPath, {
40675
+ path: outputPath,
40676
+ kind: nextKind,
40677
+ agents: [agentId],
40678
+ ignorePath: output.ignorePath ?? output.path,
40679
+ ...nextContent !== undefined ? { content: nextContent } : {},
40680
+ ...output.target !== undefined ? { target: output.target } : {}
40681
+ });
40682
+ }
40452
40683
  async writeGeneratedFile(projectPath, generatedFile, options2) {
40453
40684
  const result = {
40454
40685
  success: true,
40455
40686
  changes: [],
40456
40687
  errors: [],
40688
+ warnings: [],
40457
40689
  resolvedTargets: []
40458
40690
  };
40459
40691
  const exists = await fileExists(generatedFile.path);
40460
- const existingContent = exists ? await readFileIfExists(generatedFile.path) : null;
40692
+ const existingStats = exists ? await fs20.lstat(generatedFile.path).catch(() => null) : null;
40693
+ const existingContent = exists && !existingStats?.isSymbolicLink() ? await readFileIfExists(generatedFile.path) : null;
40694
+ const existingTarget = existingStats?.isSymbolicLink() ? await readSymlinkTarget(generatedFile.path) : null;
40461
40695
  if (options2.managedState && !options2.dryRun) {
40462
40696
  await options2.managedState.trackGeneratedPath(generatedFile.path, {
40463
40697
  kind: "file",
40464
40698
  source: "sync",
40465
- ignorePath: resolve7(projectPath, generatedFile.ignorePath)
40699
+ ignorePath: resolve8(projectPath, generatedFile.ignorePath)
40466
40700
  });
40467
40701
  }
40468
- if (exists && existingContent === generatedFile.content) {
40702
+ if (generatedFile.kind === "file" && exists && !existingStats?.isSymbolicLink() && existingContent === generatedFile.content) {
40703
+ return result;
40704
+ }
40705
+ if (generatedFile.kind === "symlink" && exists && existingStats?.isSymbolicLink() && existingTarget === generatedFile.target) {
40469
40706
  return result;
40470
40707
  }
40471
40708
  if (options2.backup && exists) {
@@ -40481,7 +40718,19 @@ class Propagator {
40481
40718
  });
40482
40719
  }
40483
40720
  if (!options2.dryRun) {
40484
- await writeFile(generatedFile.path, generatedFile.content);
40721
+ if (generatedFile.kind === "file") {
40722
+ if (existingStats?.isSymbolicLink()) {
40723
+ await fs20.rm(generatedFile.path, { force: true }).catch(() => {
40724
+ });
40725
+ }
40726
+ await writeFile(generatedFile.path, generatedFile.content || "");
40727
+ } else {
40728
+ const symlinkCreated = await createRelativeSymlink(resolve8(projectPath, generatedFile.target || ""), generatedFile.path);
40729
+ if (!symlinkCreated) {
40730
+ await writeFile(generatedFile.path, generatedFile.content || "");
40731
+ result.warnings.push(`Could not create symlink for ${generatedFile.path}; wrote a copied file instead.`);
40732
+ }
40733
+ }
40485
40734
  }
40486
40735
  result.changes.push({
40487
40736
  agent: generatedFile.agents.join(", "),
@@ -40581,7 +40830,7 @@ class Propagator {
40581
40830
  });
40582
40831
  }
40583
40832
  async buildAiderConfig(projectPath) {
40584
- const configPath = resolve7(projectPath, ".aider.conf.yml");
40833
+ const configPath = resolve8(projectPath, ".aider.conf.yml");
40585
40834
  const existingContent = await readFileIfExists(configPath);
40586
40835
  let document = {};
40587
40836
  if (existingContent) {
@@ -40647,30 +40896,37 @@ ${content}
40647
40896
  }
40648
40897
 
40649
40898
  // dist/core/managedState.js
40650
- import {promises as fs21} from "fs";
40651
- import {dirname as dirname2, join as join4, relative as relative2, resolve as resolve8} from "path";
40899
+ import {promises as fs22} from "fs";
40900
+ import {dirname as dirname2, join as join4, relative as relative3, resolve as resolve9} from "path";
40652
40901
  var toPosixPath = function(value) {
40653
40902
  return value.replace(/\\/g, "/");
40654
40903
  };
40655
40904
  async function pathType(targetPath) {
40656
40905
  try {
40657
- const stat = await fs21.stat(targetPath);
40906
+ const stat = await fs22.lstat(targetPath);
40907
+ if (stat.isSymbolicLink()) {
40908
+ return "symlink";
40909
+ }
40658
40910
  return stat.isDirectory() ? "directory" : "file";
40659
40911
  } catch {
40660
40912
  return null;
40661
40913
  }
40662
40914
  }
40663
40915
  async function copyDirectory(src, dest) {
40664
- await fs21.mkdir(dest, { recursive: true });
40665
- const entries = await fs21.readdir(src, { withFileTypes: true });
40916
+ await fs22.mkdir(dest, { recursive: true });
40917
+ const entries = await fs22.readdir(src, { withFileTypes: true });
40666
40918
  for (const entry of entries) {
40667
40919
  const srcPath = join4(src, entry.name);
40668
40920
  const destPath = join4(dest, entry.name);
40669
40921
  if (entry.isDirectory()) {
40670
40922
  await copyDirectory(srcPath, destPath);
40923
+ } else if (entry.isSymbolicLink()) {
40924
+ const target = await fs22.readlink(srcPath);
40925
+ await fs22.mkdir(dirname2(destPath), { recursive: true });
40926
+ await fs22.symlink(target, destPath);
40671
40927
  } else {
40672
- await fs21.mkdir(dirname2(destPath), { recursive: true });
40673
- await fs21.copyFile(srcPath, destPath);
40928
+ await fs22.mkdir(dirname2(destPath), { recursive: true });
40929
+ await fs22.copyFile(srcPath, destPath);
40674
40930
  }
40675
40931
  }
40676
40932
  }
@@ -40679,11 +40935,14 @@ async function copyPath(src, dest) {
40679
40935
  if (!type2) {
40680
40936
  return;
40681
40937
  }
40682
- await fs21.mkdir(dirname2(dest), { recursive: true });
40683
- if (type2 === "directory") {
40938
+ await fs22.mkdir(dirname2(dest), { recursive: true });
40939
+ if (type2 === "symlink") {
40940
+ const target = await fs22.readlink(src);
40941
+ await fs22.symlink(target, dest);
40942
+ } else if (type2 === "directory") {
40684
40943
  await copyDirectory(src, dest);
40685
40944
  } else {
40686
- await fs21.copyFile(src, dest);
40945
+ await fs22.copyFile(src, dest);
40687
40946
  }
40688
40947
  }
40689
40948
  var MANAGED_STATE_FILE = "managed-state.json";
@@ -40701,7 +40960,7 @@ class ManagedStateStore {
40701
40960
  const statePath = join4(agentInitDir, MANAGED_STATE_FILE);
40702
40961
  const emptyState = { version: 1, entries: [] };
40703
40962
  try {
40704
- const raw = await fs21.readFile(statePath, "utf8");
40963
+ const raw = await fs22.readFile(statePath, "utf8");
40705
40964
  const parsed = JSON.parse(raw);
40706
40965
  if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.entries)) {
40707
40966
  return new ManagedStateStore(projectPath, emptyState);
@@ -40722,7 +40981,7 @@ class ManagedStateStore {
40722
40981
  }
40723
40982
  normalizeRelativePath(targetPath, preserveTrailingSlash = false) {
40724
40983
  const hasTrailingSlash = preserveTrailingSlash && /[\\/]$/.test(targetPath);
40725
- const relativePath = relative2(this.projectPath, resolve8(targetPath));
40984
+ const relativePath = relative3(this.projectPath, resolve9(targetPath));
40726
40985
  const normalizedPath = toPosixPath(relativePath);
40727
40986
  if (hasTrailingSlash && normalizedPath) {
40728
40987
  return normalizedPath.endsWith("/") ? normalizedPath : `${normalizedPath}/`;
@@ -40734,15 +40993,24 @@ class ManagedStateStore {
40734
40993
  return this.state.entries.find((entry) => entry.path === relativePath);
40735
40994
  }
40736
40995
  async createBackup(targetPath) {
40737
- if (!await fileExists(targetPath)) {
40738
- return;
40996
+ const type2 = await pathType(targetPath);
40997
+ if (!type2) {
40998
+ return {};
40999
+ }
41000
+ if (type2 === "symlink") {
41001
+ try {
41002
+ const backupLinkTarget = await fs22.readlink(targetPath);
41003
+ return { backupLinkTarget };
41004
+ } catch {
41005
+ return {};
41006
+ }
40739
41007
  }
40740
41008
  const relativeTargetPath = this.normalizeRelativePath(targetPath);
40741
41009
  const backupPath = join4(this.backupsDir, relativeTargetPath);
40742
41010
  if (!await fileExists(backupPath)) {
40743
41011
  await copyPath(targetPath, backupPath);
40744
41012
  }
40745
- return this.normalizeRelativePath(backupPath);
41013
+ return { backupPath: this.normalizeRelativePath(backupPath) };
40746
41014
  }
40747
41015
  async trackGeneratedPath(targetPath, options2) {
40748
41016
  const existing = this.getEntry(targetPath);
@@ -40753,13 +41021,14 @@ class ManagedStateStore {
40753
41021
  return existing;
40754
41022
  }
40755
41023
  const existedBefore = await fileExists(targetPath);
40756
- const backupPath = existedBefore ? await this.createBackup(targetPath) : undefined;
41024
+ const backup = existedBefore ? await this.createBackup(targetPath) : {};
40757
41025
  const entry = {
40758
41026
  path: this.normalizeRelativePath(targetPath),
40759
41027
  kind: options2.kind,
40760
41028
  source: options2.source,
40761
41029
  existedBefore,
40762
- ...backupPath ? { backupPath } : {},
41030
+ ...backup.backupPath ? { backupPath: backup.backupPath } : {},
41031
+ ...backup.backupLinkTarget ? { backupLinkTarget: backup.backupLinkTarget } : {},
40763
41032
  ...options2.ignorePath ? { ignorePath: this.normalizeRelativePath(options2.ignorePath, true) } : {}
40764
41033
  };
40765
41034
  this.state.entries.push(entry);
@@ -40784,8 +41053,8 @@ class ManagedStateStore {
40784
41053
  return [...paths2];
40785
41054
  }
40786
41055
  async save() {
40787
- await fs21.mkdir(this.agentInitDir, { recursive: true });
40788
- await fs21.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
41056
+ await fs22.mkdir(this.agentInitDir, { recursive: true });
41057
+ await fs22.writeFile(this.stateFilePath, JSON.stringify(this.state, null, 2), "utf8");
40789
41058
  }
40790
41059
  async revertAll(options2 = {}) {
40791
41060
  const summary = {
@@ -40795,25 +41064,34 @@ class ManagedStateStore {
40795
41064
  };
40796
41065
  const entries = [...this.state.entries].sort((a, b) => b.path.length - a.path.length);
40797
41066
  for (const entry of entries) {
40798
- const absolutePath = resolve8(this.projectPath, entry.path);
40799
- const backupPath = entry.backupPath ? resolve8(this.projectPath, entry.backupPath) : null;
40800
- if (entry.existedBefore && backupPath && await fileExists(backupPath)) {
41067
+ const absolutePath = resolve9(this.projectPath, entry.path);
41068
+ const backupPath = entry.backupPath ? resolve9(this.projectPath, entry.backupPath) : null;
41069
+ const backupLinkTarget = entry.backupLinkTarget;
41070
+ if (entry.existedBefore && backupLinkTarget !== undefined) {
41071
+ if (!options2.dryRun) {
41072
+ await fs22.rm(absolutePath, { recursive: true, force: true }).catch(() => {
41073
+ });
41074
+ await fs22.mkdir(dirname2(absolutePath), { recursive: true });
41075
+ await fs22.symlink(backupLinkTarget, absolutePath);
41076
+ }
41077
+ summary.restored++;
41078
+ } else if (entry.existedBefore && backupPath && await fileExists(backupPath)) {
40801
41079
  if (!options2.dryRun) {
40802
- await fs21.rm(absolutePath, { recursive: true, force: true }).catch(() => {
41080
+ await fs22.rm(absolutePath, { recursive: true, force: true }).catch(() => {
40803
41081
  });
40804
41082
  await copyPath(backupPath, absolutePath);
40805
41083
  }
40806
41084
  summary.restored++;
40807
41085
  } else {
40808
41086
  if (!options2.dryRun) {
40809
- await fs21.rm(absolutePath, { recursive: true, force: true }).catch(() => {
41087
+ await fs22.rm(absolutePath, { recursive: true, force: true }).catch(() => {
40810
41088
  });
40811
41089
  }
40812
41090
  summary.removed++;
40813
41091
  }
40814
41092
  if (!options2.keepBackups && backupPath && await fileExists(backupPath)) {
40815
41093
  if (!options2.dryRun) {
40816
- await fs21.rm(backupPath, { recursive: true, force: true }).catch(() => {
41094
+ await fs22.rm(backupPath, { recursive: true, force: true }).catch(() => {
40817
41095
  });
40818
41096
  }
40819
41097
  summary.backupsRemoved++;
@@ -40821,16 +41099,16 @@ class ManagedStateStore {
40821
41099
  }
40822
41100
  if (!options2.dryRun) {
40823
41101
  this.state.entries.length = 0;
40824
- await fs21.rm(this.stateFilePath, { force: true }).catch(() => {
41102
+ await fs22.rm(this.stateFilePath, { force: true }).catch(() => {
40825
41103
  });
40826
41104
  if (!options2.keepBackups) {
40827
- await fs21.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
41105
+ await fs22.rm(this.backupsDir, { recursive: true, force: true }).catch(() => {
40828
41106
  });
40829
41107
  }
40830
41108
  try {
40831
- const remainingEntries = await fs21.readdir(this.agentInitDir);
41109
+ const remainingEntries = await fs22.readdir(this.agentInitDir);
40832
41110
  if (remainingEntries.length === 0) {
40833
- await fs21.rm(this.agentInitDir, { recursive: true, force: true });
41111
+ await fs22.rm(this.agentInitDir, { recursive: true, force: true });
40834
41112
  }
40835
41113
  } catch {
40836
41114
  }
@@ -40869,6 +41147,9 @@ async function syncCommand(options2) {
40869
41147
  }
40870
41148
  if (result.success) {
40871
41149
  spinner.succeed("Synchronization complete");
41150
+ if (result.warnings.length > 0) {
41151
+ result.warnings.forEach((warning) => logger.warning(warning));
41152
+ }
40872
41153
  if (result.changes.length === 0) {
40873
41154
  logger.info("No changes needed - all configurations are up to date");
40874
41155
  } else {
@@ -40876,7 +41157,7 @@ async function syncCommand(options2) {
40876
41157
  for (const change of result.changes) {
40877
41158
  const action = change.action === "created" ? "\u2795" : change.action === "updated" ? "\uD83D\uDCDD" : "\uD83D\uDCBE";
40878
41159
  const names = change.agents.map((id) => agentManager4.getAgentById(id)?.name || id).join(", ");
40879
- logger.info(` ${action} ${relative3(cwd, change.file) || change.file}`);
41160
+ logger.info(` ${action} ${relative4(cwd, change.file) || change.file}`);
40880
41161
  logger.info(` Agents: ${names}`);
40881
41162
  }
40882
41163
  if (options2.backup && result.changes.some((c) => c.action === "backed_up")) {
@@ -40888,6 +41169,9 @@ async function syncCommand(options2) {
40888
41169
  for (const error of result.errors) {
40889
41170
  logger.error(error);
40890
41171
  }
41172
+ for (const warning of result.warnings) {
41173
+ logger.warning(warning);
41174
+ }
40891
41175
  if (result.changes.length > 0) {
40892
41176
  logger.warning("Partial sync completed. Some changes were applied:");
40893
41177
  for (const change of result.changes) {
@@ -40902,7 +41186,7 @@ async function syncCommand(options2) {
40902
41186
  }
40903
41187
 
40904
41188
  // dist/commands/apply.js
40905
- import {relative as relative4} from "path";
41189
+ import {relative as relative5} from "path";
40906
41190
 
40907
41191
  // dist/types/index.js
40908
41192
  var MCPServerType;
@@ -41203,7 +41487,7 @@ import {readFileSync as readFileSync3} from "fs";
41203
41487
 
41204
41488
  // dist/core/rulesTemplateLoader.js
41205
41489
  var toml = __toESM(require_toml(), 1);
41206
- import {resolve as resolve9, dirname as dirname4} from "path";
41490
+ import {resolve as resolve10, dirname as dirname4} from "path";
41207
41491
  import {fileURLToPath as fileURLToPath2} from "url";
41208
41492
  import {readFileSync as readFileSync2, readdirSync, existsSync} from "fs";
41209
41493
  var __filename2 = fileURLToPath2(import.meta.url);
@@ -41213,7 +41497,7 @@ class RulesTemplateLoader {
41213
41497
  templatesPath;
41214
41498
  templates = new Map;
41215
41499
  constructor() {
41216
- this.templatesPath = resolve9(__dirname2, "../templates/rules");
41500
+ this.templatesPath = resolve10(__dirname2, "../templates/rules");
41217
41501
  this.loadTemplates();
41218
41502
  }
41219
41503
  loadTemplates() {
@@ -41223,7 +41507,7 @@ class RulesTemplateLoader {
41223
41507
  const files = readdirSync(this.templatesPath).filter((file) => file.endsWith(".toml"));
41224
41508
  for (const file of files) {
41225
41509
  try {
41226
- const filePath = resolve9(this.templatesPath, file);
41510
+ const filePath = resolve10(this.templatesPath, file);
41227
41511
  const content = readFileSync2(filePath, "utf-8");
41228
41512
  const parsed = toml.default.parse(content);
41229
41513
  const template = {
@@ -46883,7 +47167,7 @@ class Protocol {
46883
47167
  }
46884
47168
  request(request, resultSchema, options2) {
46885
47169
  const { relatedRequestId, resumptionToken, onresumptiontoken } = options2 !== null && options2 !== undefined ? options2 : {};
46886
- return new Promise((resolve10, reject) => {
47170
+ return new Promise((resolve11, reject) => {
46887
47171
  var _a, _b, _c, _d, _e, _f;
46888
47172
  if (!this._transport) {
46889
47173
  reject(new Error("Not connected"));
@@ -46934,7 +47218,7 @@ class Protocol {
46934
47218
  }
46935
47219
  try {
46936
47220
  const result = resultSchema.parse(response.result);
46937
- resolve10(result);
47221
+ resolve11(result);
46938
47222
  } catch (error) {
46939
47223
  reject(error);
46940
47224
  }
@@ -47314,7 +47598,7 @@ class StdioClientTransport {
47314
47598
  if (this._process) {
47315
47599
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
47316
47600
  }
47317
- return new Promise((resolve10, reject) => {
47601
+ return new Promise((resolve11, reject) => {
47318
47602
  var _a, _b, _c, _d, _e;
47319
47603
  this._process = import_cross_spawn.default(this._serverParams.command, (_a = this._serverParams.args) !== null && _a !== undefined ? _a : [], {
47320
47604
  env: {
@@ -47337,7 +47621,7 @@ class StdioClientTransport {
47337
47621
  (_b2 = this.onerror) === null || _b2 === undefined || _b2.call(this, error);
47338
47622
  });
47339
47623
  this._process.on("spawn", () => {
47340
- resolve10();
47624
+ resolve11();
47341
47625
  });
47342
47626
  this._process.on("close", (_code) => {
47343
47627
  var _a2;
@@ -47392,16 +47676,16 @@ class StdioClientTransport {
47392
47676
  this._readBuffer.clear();
47393
47677
  }
47394
47678
  send(message) {
47395
- return new Promise((resolve10) => {
47679
+ return new Promise((resolve11) => {
47396
47680
  var _a;
47397
47681
  if (!((_a = this._process) === null || _a === undefined ? undefined : _a.stdin)) {
47398
47682
  throw new Error("Not connected");
47399
47683
  }
47400
47684
  const json2 = serializeMessage(message);
47401
47685
  if (this._process.stdin.write(json2)) {
47402
- resolve10();
47686
+ resolve11();
47403
47687
  } else {
47404
- this._process.stdin.once("drain", resolve10);
47688
+ this._process.stdin.once("drain", resolve11);
47405
47689
  }
47406
47690
  });
47407
47691
  }
@@ -48823,7 +49107,7 @@ class SSEClientTransport {
48823
49107
  _startOrAuth() {
48824
49108
  var _a, _b, _c;
48825
49109
  const fetchImpl = (_c = (_b = (_a = this === null || this === undefined ? undefined : this._eventSourceInit) === null || _a === undefined ? undefined : _a.fetch) !== null && _b !== undefined ? _b : this._fetch) !== null && _c !== undefined ? _c : fetch;
48826
- return new Promise((resolve10, reject) => {
49110
+ return new Promise((resolve11, reject) => {
48827
49111
  this._eventSource = new EventSource(this._url.href, {
48828
49112
  ...this._eventSourceInit,
48829
49113
  fetch: async (url, init2) => {
@@ -48843,7 +49127,7 @@ class SSEClientTransport {
48843
49127
  this._eventSource.onerror = (event) => {
48844
49128
  var _a2;
48845
49129
  if (event.code === 401 && this._authProvider) {
48846
- this._authThenStart().then(resolve10, reject);
49130
+ this._authThenStart().then(resolve11, reject);
48847
49131
  return;
48848
49132
  }
48849
49133
  const error = new SseError(event.code, event.message, event);
@@ -48866,7 +49150,7 @@ class SSEClientTransport {
48866
49150
  this.close();
48867
49151
  return;
48868
49152
  }
48869
- resolve10();
49153
+ resolve11();
48870
49154
  });
48871
49155
  this._eventSource.onmessage = (event) => {
48872
49156
  var _a2, _b2;
@@ -49527,11 +49811,11 @@ class MCPVerifier {
49527
49811
  }
49528
49812
 
49529
49813
  // dist/core/gitignoreManager.js
49530
- import {promises as fs24} from "fs";
49814
+ import {promises as fs25} from "fs";
49531
49815
  import {dirname as dirname5, join as join6} from "path";
49532
49816
  var normalizeIgnorePath = function(projectPath, value) {
49533
- const relative4 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
49534
- const normalized = relative4.replace(/\\/g, "/").replace(/^\/+/, "");
49817
+ const relative5 = value.startsWith(projectPath) ? value.slice(projectPath.length + 1) : value;
49818
+ const normalized = relative5.replace(/\\/g, "/").replace(/^\/+/, "");
49535
49819
  if (!normalized) {
49536
49820
  return normalized;
49537
49821
  }
@@ -49580,7 +49864,7 @@ async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
49580
49864
  if (options2.local) {
49581
49865
  const gitDir = join6(projectPath, ".git");
49582
49866
  try {
49583
- const stat = await fs24.stat(gitDir);
49867
+ const stat = await fs25.stat(gitDir);
49584
49868
  if (!stat.isDirectory()) {
49585
49869
  throw new Error;
49586
49870
  }
@@ -49591,13 +49875,13 @@ async function updateManagedIgnoreFile(projectPath, paths2, options2 = {}) {
49591
49875
  const normalizedPaths = [...new Set(paths2.map((path) => normalizeIgnorePath(projectPath, path)).filter(Boolean))].sort();
49592
49876
  let existingContent = "";
49593
49877
  try {
49594
- existingContent = await fs24.readFile(ignoreFilePath, "utf8");
49878
+ existingContent = await fs25.readFile(ignoreFilePath, "utf8");
49595
49879
  } catch {
49596
49880
  existingContent = "";
49597
49881
  }
49598
49882
  const updatedContent = updateManagedBlock(existingContent, normalizedPaths);
49599
- await fs24.mkdir(dirname5(ignoreFilePath), { recursive: true });
49600
- await fs24.writeFile(ignoreFilePath, updatedContent, "utf8");
49883
+ await fs25.mkdir(dirname5(ignoreFilePath), { recursive: true });
49884
+ await fs25.writeFile(ignoreFilePath, updatedContent, "utf8");
49601
49885
  return ignoreFilePath;
49602
49886
  }
49603
49887
  async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
@@ -49605,7 +49889,7 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
49605
49889
  const ignoreFilePath = join6(projectPath, ignoreFile);
49606
49890
  let content;
49607
49891
  try {
49608
- content = await fs24.readFile(ignoreFilePath, "utf8");
49892
+ content = await fs25.readFile(ignoreFilePath, "utf8");
49609
49893
  } catch {
49610
49894
  return false;
49611
49895
  }
@@ -49621,13 +49905,13 @@ async function removeManagedIgnoreBlock(projectPath, options2 = {}) {
49621
49905
  const afterBlock = content.slice(endIndex + END_MARKER.length).replace(/^\n+/, "");
49622
49906
  let nextContent = `${beforeBlock}${afterBlock}`.replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "");
49623
49907
  if (nextContent.trim() === "") {
49624
- await fs24.rm(ignoreFilePath, { force: true }).catch(() => {
49908
+ await fs25.rm(ignoreFilePath, { force: true }).catch(() => {
49625
49909
  });
49626
49910
  } else {
49627
49911
  if (!nextContent.endsWith("\n")) {
49628
49912
  nextContent += "\n";
49629
49913
  }
49630
- await fs24.writeFile(ignoreFilePath, nextContent, "utf8");
49914
+ await fs25.writeFile(ignoreFilePath, nextContent, "utf8");
49631
49915
  }
49632
49916
  return true;
49633
49917
  }
@@ -49635,7 +49919,7 @@ var START_MARKER = "# START AgentInit Generated Files";
49635
49919
  var END_MARKER = "# END AgentInit Generated Files";
49636
49920
 
49637
49921
  // dist/core/projectSkills.js
49638
- import {join as join7} from "path";
49922
+ import {dirname as dirname6, join as join7} from "path";
49639
49923
  async function discoverProjectSkills(projectPath, skillsManager3) {
49640
49924
  const sources = [];
49641
49925
  const skills = new Map;
@@ -49681,7 +49965,6 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
49681
49965
  skipped: skills.map((skill) => ({ skill, reason: "No target agents found" }))
49682
49966
  };
49683
49967
  }
49684
- const dirToAgents = new Map;
49685
49968
  for (const agent of targetAgents) {
49686
49969
  if (!agent.supportsSkills()) {
49687
49970
  for (const skill of skills) {
@@ -49696,25 +49979,30 @@ async function applyProjectSkills(projectPath, targetAgentIds, managedState2, op
49696
49979
  }
49697
49980
  continue;
49698
49981
  }
49699
- const existing = dirToAgents.get(skillsDir) || [];
49700
- existing.push(agent);
49701
- dirToAgents.set(skillsDir, existing);
49702
49982
  }
49703
- for (const [skillsDir, dirAgents] of dirToAgents) {
49983
+ for (const agent of targetAgents) {
49984
+ if (!agent.supportsSkills())
49985
+ continue;
49986
+ if (!agent.getSkillsDir(projectPath, false))
49987
+ continue;
49704
49988
  for (const skill of skills) {
49705
49989
  try {
49706
- const installPath = skillsManager3.getInstallPath(skill.name, skillsDir);
49990
+ const installOptions = {
49991
+ ...options2.copy !== undefined ? { copy: options2.copy } : {}
49992
+ };
49993
+ const installPlan = await skillsManager3.getInstallPlan(skill.name, agent, projectPath, installOptions);
49707
49994
  if (!options2.dryRun) {
49708
- await managedState2.trackGeneratedPath(installPath, {
49709
- kind: "directory",
49710
- source: "skills",
49711
- ignorePath: `${skillsDir}/`
49712
- });
49713
- }
49714
- const installedPath = options2.dryRun ? installPath : await skillsManager3.installSkill(skill.path, skill.name, skillsDir, true);
49715
- for (const agent of dirAgents) {
49716
- installed.push({ skill, agent: agent.id, path: installedPath });
49995
+ const generatedPaths = new Set([installPlan.path, installPlan.canonicalPath].filter((value) => !!value));
49996
+ for (const generatedPath of generatedPaths) {
49997
+ await managedState2.trackGeneratedPath(generatedPath, {
49998
+ kind: "directory",
49999
+ source: "skills",
50000
+ ignorePath: `${dirname6(generatedPath)}/`
50001
+ });
50002
+ }
49717
50003
  }
50004
+ const installResult = options2.dryRun ? installPlan : await skillsManager3.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
50005
+ installed.push({ skill, agent: agent.id, ...installResult });
49718
50006
  } catch (error) {
49719
50007
  skipped.push({ skill, reason: error.message });
49720
50008
  }
@@ -49781,10 +50069,14 @@ async function applyProjectCommand(options2) {
49781
50069
  }
49782
50070
  spinner.fail("Apply failed");
49783
50071
  syncResult.errors.forEach((error) => logger.error(error));
50072
+ syncResult.warnings.forEach((warning) => logger.warning(warning));
49784
50073
  return;
49785
50074
  }
49786
50075
  const skillsEnabled = options2.skills !== false;
49787
- const projectSkills2 = skillsEnabled ? await applyProjectSkills(cwd, syncResult.resolvedTargets, managedState3, options2.dryRun !== undefined ? { dryRun: options2.dryRun } : {}) : {
50076
+ const projectSkills2 = skillsEnabled ? await applyProjectSkills(cwd, syncResult.resolvedTargets, managedState3, {
50077
+ ...options2.dryRun !== undefined ? { dryRun: options2.dryRun } : {},
50078
+ ...options2.copySkills !== undefined ? { copy: options2.copySkills } : {}
50079
+ }) : {
49788
50080
  discovered: 0,
49789
50081
  sources: [],
49790
50082
  installed: [],
@@ -49804,6 +50096,9 @@ async function applyProjectCommand(options2) {
49804
50096
  await managedState3.save();
49805
50097
  }
49806
50098
  spinner.succeed("Apply complete");
50099
+ if (syncResult.warnings.length > 0) {
50100
+ syncResult.warnings.forEach((warning) => logger.warning(warning));
50101
+ }
49807
50102
  if (syncResult.changes.length === 0 && projectSkills2.installed.length === 0) {
49808
50103
  logger.info("No changes needed - generated files are already up to date");
49809
50104
  } else {
@@ -49813,7 +50108,7 @@ async function applyProjectCommand(options2) {
49813
50108
  if (change.action === "backed_up")
49814
50109
  return;
49815
50110
  const names = change.agents.map((id) => agentManager6.getAgentById(id)?.name || id).join(", ");
49816
- logger.info(` ${relative4(cwd, change.file) || change.file}`);
50111
+ logger.info(` ${relative5(cwd, change.file) || change.file}`);
49817
50112
  logger.info(` Agents: ${names}`);
49818
50113
  });
49819
50114
  }
@@ -49831,7 +50126,7 @@ async function applyProjectCommand(options2) {
49831
50126
  installsByPath.set(item.path, existing);
49832
50127
  }
49833
50128
  for (const [path, details] of installsByPath) {
49834
- logger.info(` ${relative4(cwd, path) || path}`);
50129
+ logger.info(` ${relative5(cwd, path) || path}`);
49835
50130
  logger.info(` Agents: ${[...details.agents].join(", ")}`);
49836
50131
  logger.info(` Skills: ${[...details.skills].join(", ")}`);
49837
50132
  }
@@ -50521,7 +50816,7 @@ async function revertCommand(options2) {
50521
50816
  }
50522
50817
 
50523
50818
  // dist/commands/skills.js
50524
- import {relative as relative5} from "path";
50819
+ import {relative as relative6} from "path";
50525
50820
  function registerSkillsCommand(program2) {
50526
50821
  const skills = program2.command("skills").description("Manage agent skills");
50527
50822
  skills.command("add <source>").description("Add skills from a GitHub repo or local path").option("-g, --global", "Install skills globally").option("-a, --agent <agents...>", "Target specific agent(s)").option("-s, --skill <names...>", "Install only specific skills by name").option("-l, --list", "List available skills from the source without installing").option("--copy", "Copy skill files instead of symlinking").option("-y, --yes", "Skip confirmation prompts").action(async (source, options2) => {
@@ -50559,8 +50854,8 @@ function registerSkillsCommand(program2) {
50559
50854
  logger.info(` ${green(name)} ${skill.description}`);
50560
50855
  }
50561
50856
  if (tempDir) {
50562
- const { promises: fs27 } = await import("fs");
50563
- await fs27.rm(tempDir, { recursive: true, force: true }).catch(() => {
50857
+ const { promises: fs28 } = await import("fs");
50858
+ await fs28.rm(tempDir, { recursive: true, force: true }).catch(() => {
50564
50859
  });
50565
50860
  }
50566
50861
  } catch (error) {
@@ -50596,7 +50891,7 @@ function registerSkillsCommand(program2) {
50596
50891
  byPath.set(path, existing);
50597
50892
  }
50598
50893
  for (const [path, details] of byPath) {
50599
- logger.info(` ${relative5(process.cwd(), path) || path}`);
50894
+ logger.info(` ${relative6(process.cwd(), path) || path}`);
50600
50895
  logger.info(` Agents: ${[...details.agents].join(", ")}`);
50601
50896
  logger.info(` Skills: ${green(String(details.skills.size))} installed (${[...details.skills].join(", ")})`);
50602
50897
  }
@@ -50625,19 +50920,32 @@ function registerSkillsCommand(program2) {
50625
50920
  logger.info("No skills installed.");
50626
50921
  return;
50627
50922
  }
50628
- const byAgent = new Map;
50923
+ const bySkill = new Map;
50629
50924
  for (const skill of installed) {
50630
- const list = byAgent.get(skill.agent) || [];
50631
- list.push(skill);
50632
- byAgent.set(skill.agent, list);
50633
- }
50634
- for (const [agent, agentSkills] of byAgent) {
50635
- logger.info(`\n ${green(agent)}`);
50636
- for (const skill of agentSkills) {
50637
- const symlink = skill.isSymlink ? " (symlink)" : "";
50638
- const scope = skill.scope === "global" ? " [global]" : "";
50639
- logger.info(` ${green(skill.name)} - ${skill.description}${scope}${symlink}`);
50925
+ const canonicalPath = skill.canonicalPath || skill.path;
50926
+ const key = `${skill.scope}:${canonicalPath}`;
50927
+ const existing = bySkill.get(key) || {
50928
+ name: skill.name,
50929
+ description: skill.description,
50930
+ path: canonicalPath,
50931
+ scope: skill.scope,
50932
+ mode: skill.mode,
50933
+ isSymlink: skill.isSymlink,
50934
+ agents: new Set
50935
+ };
50936
+ existing.isSymlink = existing.isSymlink || skill.isSymlink;
50937
+ if (skill.mode === "symlink") {
50938
+ existing.mode = "symlink";
50640
50939
  }
50940
+ existing.agents.add(agentManager8.getAgentById(skill.agent)?.name || skill.agent);
50941
+ bySkill.set(key, existing);
50942
+ }
50943
+ for (const skill of bySkill.values()) {
50944
+ const mode = skill.mode === "symlink" ? " (canonical)" : "";
50945
+ const scope = skill.scope === "global" ? " [global]" : "";
50946
+ logger.info(`\n ${green(skill.name)} - ${skill.description}${scope}${mode}`);
50947
+ logger.info(` Path: ${relative6(process.cwd(), skill.path) || skill.path}`);
50948
+ logger.info(` Agents: ${[...skill.agents].join(", ")}`);
50641
50949
  }
50642
50950
  });
50643
50951
  skills.command("remove [names...]").alias("rm").description("Remove installed skills by name").option("-g, --global", "Remove from global scope").option("-a, --agent <agents...>", "Target specific agent(s)").option("-y, --yes", "Skip confirmation prompts").action(async (names, options2) => {
@@ -50665,7 +50973,13 @@ function registerSkillsCommand(program2) {
50665
50973
  if (result.notFound.length > 0) {
50666
50974
  logger.warn(`Not found: ${result.notFound.join(", ")}`);
50667
50975
  }
50668
- if (result.removed.length === 0 && result.notFound.length === 0) {
50976
+ if (result.skipped.length > 0) {
50977
+ logger.warn(`Skipped: ${result.skipped.length}`);
50978
+ for (const entry of result.skipped) {
50979
+ logger.info(` ${entry.name}: ${entry.reason}`);
50980
+ }
50981
+ }
50982
+ if (result.removed.length === 0 && result.notFound.length === 0 && result.skipped.length === 0) {
50669
50983
  logger.info("Nothing to remove.");
50670
50984
  }
50671
50985
  });
@@ -51458,15 +51772,15 @@ function registerRulesCommand(program2) {
51458
51772
 
51459
51773
  // dist/core/pluginManager.js
51460
51774
  var import_gray_matter3 = __toESM(require_gray_matter(), 1);
51461
- import {resolve as resolve10, join as join8, basename} from "path";
51462
- import {promises as fs28} from "fs";
51463
- import {homedir as homedir3} from "os";
51775
+ import {resolve as resolve11, join as join8, basename as basename2} from "path";
51776
+ import {promises as fs29} from "fs";
51777
+ import {homedir as homedir4} from "os";
51464
51778
  var getMarketplaceCacheDir = function(registryId) {
51465
- return join8(homedir3(), ".agentinit", "marketplace-cache", registryId);
51779
+ return join8(homedir4(), ".agentinit", "marketplace-cache", registryId);
51466
51780
  };
51467
51781
  var getRegistryPath = function(projectPath, global3) {
51468
51782
  if (global3) {
51469
- return join8(homedir3(), ".agentinit", "plugins.json");
51783
+ return join8(homedir4(), ".agentinit", "plugins.json");
51470
51784
  }
51471
51785
  return join8(projectPath, ".agentinit", "plugins.json");
51472
51786
  };
@@ -51551,7 +51865,7 @@ class PluginManager {
51551
51865
  const cacheMetaPath = join8(cacheDir, ".agentinit-cache-meta.json");
51552
51866
  if (await fileExists(cacheMetaPath)) {
51553
51867
  try {
51554
- const meta = JSON.parse(await fs28.readFile(cacheMetaPath, "utf8"));
51868
+ const meta = JSON.parse(await fs29.readFile(cacheMetaPath, "utf8"));
51555
51869
  const age = Date.now() - (meta.fetchedAt || 0);
51556
51870
  if (age < registry.cacheTtlMs) {
51557
51871
  return cacheDir;
@@ -51566,22 +51880,22 @@ class PluginManager {
51566
51880
  try {
51567
51881
  await exec("git", ["pull", "--ff-only"], { cwd: cacheDir, timeout: 30000 });
51568
51882
  } catch {
51569
- await fs28.rm(cacheDir, { recursive: true, force: true });
51883
+ await fs29.rm(cacheDir, { recursive: true, force: true });
51570
51884
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
51571
51885
  }
51572
51886
  } else {
51573
51887
  await this.cloneMarketplace(registry.repoUrl, cacheDir);
51574
51888
  }
51575
- await fs28.mkdir(cacheDir, { recursive: true });
51576
- await fs28.writeFile(cacheMetaPath, JSON.stringify({ fetchedAt: Date.now() }));
51889
+ await fs29.mkdir(cacheDir, { recursive: true });
51890
+ await fs29.writeFile(cacheMetaPath, JSON.stringify({ fetchedAt: Date.now() }));
51577
51891
  return cacheDir;
51578
51892
  }
51579
51893
  async cloneMarketplace(repoUrl, dest) {
51580
- await fs28.mkdir(dest, { recursive: true });
51894
+ await fs29.mkdir(dest, { recursive: true });
51581
51895
  const { execFile: execFile2 } = await import("child_process");
51582
51896
  const { promisify: promisify2 } = await import("util");
51583
51897
  const exec = promisify2(execFile2);
51584
- await fs28.rm(dest, { recursive: true, force: true }).catch(() => {
51898
+ await fs29.rm(dest, { recursive: true, force: true }).catch(() => {
51585
51899
  });
51586
51900
  await exec("git", ["clone", "--depth", "1", repoUrl, dest], { timeout: 60000 });
51587
51901
  }
@@ -51630,7 +51944,7 @@ class PluginManager {
51630
51944
  let version = "0.0.0";
51631
51945
  if (await fileExists(manifestPath)) {
51632
51946
  try {
51633
- const manifest = JSON.parse(await fs28.readFile(manifestPath, "utf8"));
51947
+ const manifest = JSON.parse(await fs29.readFile(manifestPath, "utf8"));
51634
51948
  name = manifest.name || entry;
51635
51949
  description = manifest.description || "";
51636
51950
  version = manifest.version || "0.0.0";
@@ -51724,7 +52038,7 @@ class PluginManager {
51724
52038
  async parseGenericPlugin(pluginDir, source) {
51725
52039
  const skills = await this.skillsManager.discoverSkills(pluginDir);
51726
52040
  const mcpServers = await this.parseMcpJson(pluginDir);
51727
- const dirName = basename(pluginDir);
52041
+ const dirName = basename2(pluginDir);
51728
52042
  return {
51729
52043
  name: dirName,
51730
52044
  version: "0.0.0",
@@ -51781,7 +52095,7 @@ class PluginManager {
51781
52095
  if (manifest.commands) {
51782
52096
  const cmds = Array.isArray(manifest.commands) ? manifest.commands : [manifest.commands];
51783
52097
  for (const cmd of cmds) {
51784
- commandsDirs.push(resolve10(pluginDir, cmd));
52098
+ commandsDirs.push(resolve11(pluginDir, cmd));
51785
52099
  }
51786
52100
  } else {
51787
52101
  commandsDirs.push(join8(pluginDir, "commands"));
@@ -51805,7 +52119,7 @@ class PluginManager {
51805
52119
  const content = await readFileIfExists(cmdPath);
51806
52120
  if (!content)
51807
52121
  return null;
51808
- const fileName = basename(cmdPath, ".md");
52122
+ const fileName = basename2(cmdPath, ".md");
51809
52123
  let skillName;
51810
52124
  let description;
51811
52125
  let body;
@@ -51846,7 +52160,7 @@ ${body.trim()}
51846
52160
  tempDir = await this.skillsManager.cloneRepo(resolved.url);
51847
52161
  pluginDir = tempDir;
51848
52162
  } else {
51849
- pluginDir = resolve10(resolved.path || source);
52163
+ pluginDir = resolve11(resolved.path || source);
51850
52164
  if (!await fileExists(pluginDir)) {
51851
52165
  throw new Error(`Local path not found: ${pluginDir}`);
51852
52166
  }
@@ -51897,7 +52211,7 @@ ${body.trim()}
51897
52211
  };
51898
52212
  } finally {
51899
52213
  if (tempDir) {
51900
- await fs28.rm(tempDir, { recursive: true, force: true }).catch(() => {
52214
+ await fs29.rm(tempDir, { recursive: true, force: true }).catch(() => {
51901
52215
  });
51902
52216
  }
51903
52217
  }
@@ -51907,7 +52221,6 @@ ${body.trim()}
51907
52221
  const skipped = [];
51908
52222
  if (plugin.skills.length === 0)
51909
52223
  return { installed, skipped };
51910
- const dirToAgents = new Map;
51911
52224
  for (const agent of agents) {
51912
52225
  if (!agent.supportsSkills()) {
51913
52226
  for (const skill of plugin.skills) {
@@ -51915,24 +52228,20 @@ ${body.trim()}
51915
52228
  }
51916
52229
  continue;
51917
52230
  }
51918
- const skillsDir = agent.getSkillsDir(projectPath, options2.global);
51919
- if (!skillsDir) {
52231
+ if (!agent.getSkillsDir(projectPath, options2.global)) {
51920
52232
  for (const skill of plugin.skills) {
51921
52233
  skipped.push({ name: skill.name, reason: `No skills directory for ${agent.name}` });
51922
52234
  }
51923
52235
  continue;
51924
52236
  }
51925
- const existing = dirToAgents.get(skillsDir) || [];
51926
- existing.push(agent);
51927
- dirToAgents.set(skillsDir, existing);
51928
- }
51929
- for (const [skillsDir, dirAgents] of dirToAgents) {
51930
52237
  for (const skill of plugin.skills) {
51931
52238
  try {
51932
- const installedPath = skill.generatedContent ? await this.skillsManager.installSkillFromContent(skill.name, skill.generatedContent, skillsDir) : await this.skillsManager.installSkill(skill.path, skill.name, skillsDir, true);
51933
- for (const agent of dirAgents) {
51934
- installed.push({ name: skill.name, agent: agent.id, path: installedPath });
51935
- }
52239
+ const installOptions = {
52240
+ ...options2.global !== undefined ? { global: options2.global } : {},
52241
+ ...options2.copySkills !== undefined ? { copy: options2.copySkills } : {}
52242
+ };
52243
+ const installResult = skill.generatedContent ? await this.skillsManager.installSkillFromContentForAgent(skill.name, skill.generatedContent, agent, projectPath, installOptions) : await this.skillsManager.installSkillForAgent(skill.path, skill.name, agent, projectPath, installOptions);
52244
+ installed.push({ name: skill.name, agent: agent.id, ...installResult });
51936
52245
  } catch (error) {
51937
52246
  skipped.push({ name: skill.name, reason: error.message });
51938
52247
  }
@@ -52057,32 +52366,48 @@ ${body.trim()}
52057
52366
  const agentFilter = options2.agents?.length ? new Set(options2.agents) : null;
52058
52367
  const targetedSkills = agentFilter ? plugin.components.skills.filter((skill) => agentFilter.has(skill.agent)) : plugin.components.skills;
52059
52368
  const retainedSkills = agentFilter ? plugin.components.skills.filter((skill) => !agentFilter.has(skill.agent)) : [];
52060
- const retainedSkillPaths = new Set(retainedSkills.map((skill) => skill.path));
52369
+ const otherPluginSkills = registry.plugins.filter((entry) => entry.name !== plugin.name).flatMap((entry) => entry.components.skills);
52370
+ const remainingSkillRefs = [
52371
+ ...retainedSkills,
52372
+ ...otherPluginSkills
52373
+ ];
52061
52374
  const removedSkillPaths = new Set;
52062
- const sharedSkillPaths = new Set;
52375
+ const removedSkillKeys = new Set;
52376
+ const removedCanonicalPaths = new Set;
52063
52377
  for (const skill of targetedSkills) {
52064
- if (removedSkillPaths.has(skill.path) || sharedSkillPaths.has(skill.path)) {
52378
+ const skillKey = `${skill.agent}:${skill.path}:${skill.name}`;
52379
+ if (removedSkillKeys.has(skillKey)) {
52065
52380
  continue;
52066
52381
  }
52067
- if (retainedSkillPaths.has(skill.path)) {
52068
- sharedSkillPaths.add(skill.path);
52069
- details.push(`Skipped shared skill path: ${skill.path}`);
52382
+ const canonicalRef = skill.canonicalPath || skill.path;
52383
+ const sharedCanonicalPath = remainingSkillRefs.some((other) => (other.canonicalPath || other.path) === canonicalRef);
52384
+ if (skill.canonicalPath && skill.path === skill.canonicalPath && sharedCanonicalPath) {
52385
+ details.push(`Skipped shared canonical skill path: ${skill.path}`);
52070
52386
  continue;
52071
52387
  }
52072
- try {
52073
- await fs28.rm(skill.path, { recursive: true, force: true });
52074
- removedSkillPaths.add(skill.path);
52075
- } catch {
52076
- details.push(`Could not remove skill path: ${skill.path}`);
52388
+ if (!removedSkillPaths.has(skill.path)) {
52389
+ try {
52390
+ await fs29.rm(skill.path, { recursive: true, force: true });
52391
+ removedSkillPaths.add(skill.path);
52392
+ } catch {
52393
+ details.push(`Could not remove skill path: ${skill.path}`);
52394
+ continue;
52395
+ }
52077
52396
  }
52078
- }
52079
- const removedSkills = targetedSkills.filter((skill) => removedSkillPaths.has(skill.path));
52080
- for (const skill of removedSkills) {
52397
+ if (skill.canonicalPath && skill.canonicalPath !== skill.path && !removedCanonicalPaths.has(skill.canonicalPath) && !sharedCanonicalPath) {
52398
+ try {
52399
+ await fs29.rm(skill.canonicalPath, { recursive: true, force: true });
52400
+ removedCanonicalPaths.add(skill.canonicalPath);
52401
+ } catch {
52402
+ details.push(`Could not remove canonical skill path: ${skill.canonicalPath}`);
52403
+ }
52404
+ }
52405
+ removedSkillKeys.add(skillKey);
52081
52406
  details.push(`Removed skill: ${skill.name} (${skill.agent})`);
52082
52407
  }
52083
52408
  const remainingSkills = [
52084
52409
  ...retainedSkills,
52085
- ...targetedSkills.filter((skill) => !removedSkillPaths.has(skill.path))
52410
+ ...targetedSkills.filter((skill) => !removedSkillKeys.has(`${skill.agent}:${skill.path}:${skill.name}`))
52086
52411
  ];
52087
52412
  const targetedMcpServers = agentFilter ? plugin.components.mcpServers.filter((mcp) => agentFilter.has(mcp.agent)) : plugin.components.mcpServers;
52088
52413
  const retainedMcpServers = agentFilter ? plugin.components.mcpServers.filter((mcp) => !agentFilter.has(mcp.agent)) : [];
@@ -52138,7 +52463,7 @@ ${body.trim()}
52138
52463
  function registerPluginsCommand(program2) {
52139
52464
  const marketplaceHelp = new PluginManager().getMarketplaceIds().join(", ");
52140
52465
  const plugins = program2.command("plugins").description("Install agent-agnostic plugins from any marketplace or source");
52141
- plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect all agents").action(async (source, options2) => {
52466
+ plugins.command("install <source>").description("Install a plugin from <marketplace>/<name>, a GitHub repo, or a local path").option("--from <marketplace>", `Marketplace source override (available: ${marketplaceHelp})`).option("-a, --agent <agents...>", "Target specific agent(s)").option("-g, --global", "Install globally").option("--copy-skills", "Copy plugin skills instead of using canonical symlink installs").option("-l, --list", "Preview plugin contents without installing").option("-y, --yes", "Skip confirmation prompts, auto-detect all agents").action(async (source, options2) => {
52142
52467
  logger.title("\uD83D\uDD0C AgentInit - Plugins");
52143
52468
  const agentManager12 = new AgentManager;
52144
52469
  const pluginManager2 = new PluginManager(agentManager12);
@@ -52201,6 +52526,7 @@ function registerPluginsCommand(program2) {
52201
52526
  from: options2.from,
52202
52527
  agents: agentIds,
52203
52528
  global: options2.global,
52529
+ copySkills: options2.copySkills,
52204
52530
  yes: options2.yes
52205
52531
  });
52206
52532
  const p = result.plugin;
@@ -52395,7 +52721,7 @@ registerPluginsCommand(program2);
52395
52721
  program2.command("init").description("Initialize agents.md configuration for the current project").option("-f, --force", "Overwrite existing configuration").option("-t, --template <template>", "Use specific template (web, cli, library)").action(initCommand);
52396
52722
  program2.command("detect").description("Detect current project stack and existing agent configurations").option("-v, --verbose", "Show detailed detection results").action(detectCommand);
52397
52723
  program2.command("sync").description("Sync agents.md with agent-specific configuration files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Show what would be changed without making changes").option("-b, --backup", "Create backup before syncing").action(syncCommand);
52398
- program2.command("apply").description("Apply agents.md and project-owned skills to supported agent files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Preview changes without writing files").option("-b, --backup", "Create sibling .agentinit.backup files before overwriting").option("--no-skills", "Disable project-owned skills propagation").option("--no-gitignore", "Disable managed ignore block updates").option("--gitignore-local", "Write ignore entries to .git/info/exclude instead of .gitignore").allowUnknownOption(true).action(async (options2, command) => {
52724
+ program2.command("apply").description("Apply agents.md and project-owned skills to supported agent files").option("-a, --agent <agents...>", "Target specific agent(s)").option("-d, --dry-run", "Preview changes without writing files").option("-b, --backup", "Create sibling .agentinit.backup files before overwriting").option("--no-skills", "Disable project-owned skills propagation").option("--copy-skills", "Copy project-owned skills instead of using canonical symlink installs").option("--no-gitignore", "Disable managed ignore block updates").option("--gitignore-local", "Write ignore entries to .git/info/exclude instead of .gitignore").allowUnknownOption(true).action(async (options2, command) => {
52399
52725
  const rawArgs = command.parent.rawArgs.slice(3);
52400
52726
  if (hasLegacyApplyArgs(rawArgs)) {
52401
52727
  logger.warn("\u26A0 Legacy apply mode detected. Prefer:");