@tec-explorer/skillpot 0.7.0 → 0.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.
package/dist/cli.mjs CHANGED
@@ -973,8 +973,8 @@ var require_command = __commonJS({
973
973
  "node_modules/commander/lib/command.js"(exports) {
974
974
  var EventEmitter3 = __require("node:events").EventEmitter;
975
975
  var childProcess = __require("node:child_process");
976
- var path17 = __require("node:path");
977
- var fs15 = __require("node:fs");
976
+ var path18 = __require("node:path");
977
+ var fs16 = __require("node:fs");
978
978
  var process13 = __require("node:process");
979
979
  var { Argument: Argument2, humanReadableArgName } = require_argument();
980
980
  var { CommanderError: CommanderError2 } = require_error();
@@ -1906,11 +1906,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1906
1906
  let launchWithNode = false;
1907
1907
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1908
1908
  function findFile(baseDir, baseName) {
1909
- const localBin = path17.resolve(baseDir, baseName);
1910
- if (fs15.existsSync(localBin)) return localBin;
1911
- if (sourceExt.includes(path17.extname(baseName))) return void 0;
1909
+ const localBin = path18.resolve(baseDir, baseName);
1910
+ if (fs16.existsSync(localBin)) return localBin;
1911
+ if (sourceExt.includes(path18.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs15.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs16.existsSync(`${localBin}${ext}`)
1914
1914
  );
1915
1915
  if (foundExt) return `${localBin}${foundExt}`;
1916
1916
  return void 0;
@@ -1922,21 +1922,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1922
1922
  if (this._scriptPath) {
1923
1923
  let resolvedScriptPath;
1924
1924
  try {
1925
- resolvedScriptPath = fs15.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs16.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
1929
- executableDir = path17.resolve(
1930
- path17.dirname(resolvedScriptPath),
1929
+ executableDir = path18.resolve(
1930
+ path18.dirname(resolvedScriptPath),
1931
1931
  executableDir
1932
1932
  );
1933
1933
  }
1934
1934
  if (executableDir) {
1935
1935
  let localFile = findFile(executableDir, executableFile);
1936
1936
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1937
- const legacyName = path17.basename(
1937
+ const legacyName = path18.basename(
1938
1938
  this._scriptPath,
1939
- path17.extname(this._scriptPath)
1939
+ path18.extname(this._scriptPath)
1940
1940
  );
1941
1941
  if (legacyName !== this._name) {
1942
1942
  localFile = findFile(
@@ -1947,7 +1947,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1947
1947
  }
1948
1948
  executableFile = localFile || executableFile;
1949
1949
  }
1950
- launchWithNode = sourceExt.includes(path17.extname(executableFile));
1950
+ launchWithNode = sourceExt.includes(path18.extname(executableFile));
1951
1951
  let proc;
1952
1952
  if (process13.platform !== "win32") {
1953
1953
  if (launchWithNode) {
@@ -2787,7 +2787,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2787
2787
  * @return {Command}
2788
2788
  */
2789
2789
  nameFromFilename(filename) {
2790
- this._name = path17.basename(filename, path17.extname(filename));
2790
+ this._name = path18.basename(filename, path18.extname(filename));
2791
2791
  return this;
2792
2792
  }
2793
2793
  /**
@@ -2801,9 +2801,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2801
2801
  * @param {string} [path]
2802
2802
  * @return {(string|null|Command)}
2803
2803
  */
2804
- executableDir(path18) {
2805
- if (path18 === void 0) return this._executableDir;
2806
- this._executableDir = path18;
2804
+ executableDir(path19) {
2805
+ if (path19 === void 0) return this._executableDir;
2806
+ this._executableDir = path19;
2807
2807
  return this;
2808
2808
  }
2809
2809
  /**
@@ -3182,17 +3182,17 @@ var require_visit = __commonJS({
3182
3182
  visit.BREAK = BREAK;
3183
3183
  visit.SKIP = SKIP;
3184
3184
  visit.REMOVE = REMOVE;
3185
- function visit_(key, node, visitor, path17) {
3186
- const ctrl = callVisitor(key, node, visitor, path17);
3185
+ function visit_(key, node, visitor, path18) {
3186
+ const ctrl = callVisitor(key, node, visitor, path18);
3187
3187
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3188
- replaceNode(key, path17, ctrl);
3189
- return visit_(key, ctrl, visitor, path17);
3188
+ replaceNode(key, path18, ctrl);
3189
+ return visit_(key, ctrl, visitor, path18);
3190
3190
  }
3191
3191
  if (typeof ctrl !== "symbol") {
3192
3192
  if (identity.isCollection(node)) {
3193
- path17 = Object.freeze(path17.concat(node));
3193
+ path18 = Object.freeze(path18.concat(node));
3194
3194
  for (let i = 0; i < node.items.length; ++i) {
3195
- const ci = visit_(i, node.items[i], visitor, path17);
3195
+ const ci = visit_(i, node.items[i], visitor, path18);
3196
3196
  if (typeof ci === "number")
3197
3197
  i = ci - 1;
3198
3198
  else if (ci === BREAK)
@@ -3203,13 +3203,13 @@ var require_visit = __commonJS({
3203
3203
  }
3204
3204
  }
3205
3205
  } else if (identity.isPair(node)) {
3206
- path17 = Object.freeze(path17.concat(node));
3207
- const ck = visit_("key", node.key, visitor, path17);
3206
+ path18 = Object.freeze(path18.concat(node));
3207
+ const ck = visit_("key", node.key, visitor, path18);
3208
3208
  if (ck === BREAK)
3209
3209
  return BREAK;
3210
3210
  else if (ck === REMOVE)
3211
3211
  node.key = null;
3212
- const cv = visit_("value", node.value, visitor, path17);
3212
+ const cv = visit_("value", node.value, visitor, path18);
3213
3213
  if (cv === BREAK)
3214
3214
  return BREAK;
3215
3215
  else if (cv === REMOVE)
@@ -3230,17 +3230,17 @@ var require_visit = __commonJS({
3230
3230
  visitAsync.BREAK = BREAK;
3231
3231
  visitAsync.SKIP = SKIP;
3232
3232
  visitAsync.REMOVE = REMOVE;
3233
- async function visitAsync_(key, node, visitor, path17) {
3234
- const ctrl = await callVisitor(key, node, visitor, path17);
3233
+ async function visitAsync_(key, node, visitor, path18) {
3234
+ const ctrl = await callVisitor(key, node, visitor, path18);
3235
3235
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3236
- replaceNode(key, path17, ctrl);
3237
- return visitAsync_(key, ctrl, visitor, path17);
3236
+ replaceNode(key, path18, ctrl);
3237
+ return visitAsync_(key, ctrl, visitor, path18);
3238
3238
  }
3239
3239
  if (typeof ctrl !== "symbol") {
3240
3240
  if (identity.isCollection(node)) {
3241
- path17 = Object.freeze(path17.concat(node));
3241
+ path18 = Object.freeze(path18.concat(node));
3242
3242
  for (let i = 0; i < node.items.length; ++i) {
3243
- const ci = await visitAsync_(i, node.items[i], visitor, path17);
3243
+ const ci = await visitAsync_(i, node.items[i], visitor, path18);
3244
3244
  if (typeof ci === "number")
3245
3245
  i = ci - 1;
3246
3246
  else if (ci === BREAK)
@@ -3251,13 +3251,13 @@ var require_visit = __commonJS({
3251
3251
  }
3252
3252
  }
3253
3253
  } else if (identity.isPair(node)) {
3254
- path17 = Object.freeze(path17.concat(node));
3255
- const ck = await visitAsync_("key", node.key, visitor, path17);
3254
+ path18 = Object.freeze(path18.concat(node));
3255
+ const ck = await visitAsync_("key", node.key, visitor, path18);
3256
3256
  if (ck === BREAK)
3257
3257
  return BREAK;
3258
3258
  else if (ck === REMOVE)
3259
3259
  node.key = null;
3260
- const cv = await visitAsync_("value", node.value, visitor, path17);
3260
+ const cv = await visitAsync_("value", node.value, visitor, path18);
3261
3261
  if (cv === BREAK)
3262
3262
  return BREAK;
3263
3263
  else if (cv === REMOVE)
@@ -3284,23 +3284,23 @@ var require_visit = __commonJS({
3284
3284
  }
3285
3285
  return visitor;
3286
3286
  }
3287
- function callVisitor(key, node, visitor, path17) {
3287
+ function callVisitor(key, node, visitor, path18) {
3288
3288
  if (typeof visitor === "function")
3289
- return visitor(key, node, path17);
3289
+ return visitor(key, node, path18);
3290
3290
  if (identity.isMap(node))
3291
- return visitor.Map?.(key, node, path17);
3291
+ return visitor.Map?.(key, node, path18);
3292
3292
  if (identity.isSeq(node))
3293
- return visitor.Seq?.(key, node, path17);
3293
+ return visitor.Seq?.(key, node, path18);
3294
3294
  if (identity.isPair(node))
3295
- return visitor.Pair?.(key, node, path17);
3295
+ return visitor.Pair?.(key, node, path18);
3296
3296
  if (identity.isScalar(node))
3297
- return visitor.Scalar?.(key, node, path17);
3297
+ return visitor.Scalar?.(key, node, path18);
3298
3298
  if (identity.isAlias(node))
3299
- return visitor.Alias?.(key, node, path17);
3299
+ return visitor.Alias?.(key, node, path18);
3300
3300
  return void 0;
3301
3301
  }
3302
- function replaceNode(key, path17, node) {
3303
- const parent = path17[path17.length - 1];
3302
+ function replaceNode(key, path18, node) {
3303
+ const parent = path18[path18.length - 1];
3304
3304
  if (identity.isCollection(parent)) {
3305
3305
  parent.items[key] = node;
3306
3306
  } else if (identity.isPair(parent)) {
@@ -3910,10 +3910,10 @@ var require_Collection = __commonJS({
3910
3910
  var createNode2 = require_createNode();
3911
3911
  var identity = require_identity();
3912
3912
  var Node = require_Node();
3913
- function collectionFromPath(schema, path17, value) {
3913
+ function collectionFromPath(schema, path18, value) {
3914
3914
  let v = value;
3915
- for (let i = path17.length - 1; i >= 0; --i) {
3916
- const k = path17[i];
3915
+ for (let i = path18.length - 1; i >= 0; --i) {
3916
+ const k = path18[i];
3917
3917
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
3918
3918
  const a = [];
3919
3919
  a[k] = v;
@@ -3932,7 +3932,7 @@ var require_Collection = __commonJS({
3932
3932
  sourceObjects: /* @__PURE__ */ new Map()
3933
3933
  });
3934
3934
  }
3935
- var isEmptyPath = (path17) => path17 == null || typeof path17 === "object" && !!path17[Symbol.iterator]().next().done;
3935
+ var isEmptyPath = (path18) => path18 == null || typeof path18 === "object" && !!path18[Symbol.iterator]().next().done;
3936
3936
  var Collection = class extends Node.NodeBase {
3937
3937
  constructor(type, schema) {
3938
3938
  super(type);
@@ -3962,11 +3962,11 @@ var require_Collection = __commonJS({
3962
3962
  * be a Pair instance or a `{ key, value }` object, which may not have a key
3963
3963
  * that already exists in the map.
3964
3964
  */
3965
- addIn(path17, value) {
3966
- if (isEmptyPath(path17))
3965
+ addIn(path18, value) {
3966
+ if (isEmptyPath(path18))
3967
3967
  this.add(value);
3968
3968
  else {
3969
- const [key, ...rest] = path17;
3969
+ const [key, ...rest] = path18;
3970
3970
  const node = this.get(key, true);
3971
3971
  if (identity.isCollection(node))
3972
3972
  node.addIn(rest, value);
@@ -3980,8 +3980,8 @@ var require_Collection = __commonJS({
3980
3980
  * Removes a value from the collection.
3981
3981
  * @returns `true` if the item was found and removed.
3982
3982
  */
3983
- deleteIn(path17) {
3984
- const [key, ...rest] = path17;
3983
+ deleteIn(path18) {
3984
+ const [key, ...rest] = path18;
3985
3985
  if (rest.length === 0)
3986
3986
  return this.delete(key);
3987
3987
  const node = this.get(key, true);
@@ -3995,8 +3995,8 @@ var require_Collection = __commonJS({
3995
3995
  * scalar values from their surrounding node; to disable set `keepScalar` to
3996
3996
  * `true` (collections are always returned intact).
3997
3997
  */
3998
- getIn(path17, keepScalar) {
3999
- const [key, ...rest] = path17;
3998
+ getIn(path18, keepScalar) {
3999
+ const [key, ...rest] = path18;
4000
4000
  const node = this.get(key, true);
4001
4001
  if (rest.length === 0)
4002
4002
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -4014,8 +4014,8 @@ var require_Collection = __commonJS({
4014
4014
  /**
4015
4015
  * Checks if the collection includes a value with the key `key`.
4016
4016
  */
4017
- hasIn(path17) {
4018
- const [key, ...rest] = path17;
4017
+ hasIn(path18) {
4018
+ const [key, ...rest] = path18;
4019
4019
  if (rest.length === 0)
4020
4020
  return this.has(key);
4021
4021
  const node = this.get(key, true);
@@ -4025,8 +4025,8 @@ var require_Collection = __commonJS({
4025
4025
  * Sets a value in this collection. For `!!set`, `value` needs to be a
4026
4026
  * boolean to add/remove the item from the set.
4027
4027
  */
4028
- setIn(path17, value) {
4029
- const [key, ...rest] = path17;
4028
+ setIn(path18, value) {
4029
+ const [key, ...rest] = path18;
4030
4030
  if (rest.length === 0) {
4031
4031
  this.set(key, value);
4032
4032
  } else {
@@ -4573,7 +4573,7 @@ var require_stringify = __commonJS({
4573
4573
  props.push(doc.directives.tagString(tag));
4574
4574
  return props.join(" ");
4575
4575
  }
4576
- function stringify2(item, ctx, onComment, onChompKeep) {
4576
+ function stringify3(item, ctx, onComment, onChompKeep) {
4577
4577
  if (identity.isPair(item))
4578
4578
  return item.toString(ctx, onComment, onChompKeep);
4579
4579
  if (identity.isAlias(item)) {
@@ -4602,7 +4602,7 @@ var require_stringify = __commonJS({
4602
4602
  ${ctx.indent}${str}`;
4603
4603
  }
4604
4604
  exports.createStringifyContext = createStringifyContext;
4605
- exports.stringify = stringify2;
4605
+ exports.stringify = stringify3;
4606
4606
  }
4607
4607
  });
4608
4608
 
@@ -4612,7 +4612,7 @@ var require_stringifyPair = __commonJS({
4612
4612
  "use strict";
4613
4613
  var identity = require_identity();
4614
4614
  var Scalar = require_Scalar();
4615
- var stringify2 = require_stringify();
4615
+ var stringify3 = require_stringify();
4616
4616
  var stringifyComment = require_stringifyComment();
4617
4617
  function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
4618
4618
  const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
@@ -4634,7 +4634,7 @@ var require_stringifyPair = __commonJS({
4634
4634
  });
4635
4635
  let keyCommentDone = false;
4636
4636
  let chompKeep = false;
4637
- let str = stringify2.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
4637
+ let str = stringify3.stringify(key, ctx, () => keyCommentDone = true, () => chompKeep = true);
4638
4638
  if (!explicitKey && !ctx.inFlow && str.length > 1024) {
4639
4639
  if (simpleKeys)
4640
4640
  throw new Error("With simple keys, single line scalar must not span more than 1024 characters");
@@ -4686,7 +4686,7 @@ ${indent}:`;
4686
4686
  ctx.indent = ctx.indent.substring(2);
4687
4687
  }
4688
4688
  let valueCommentDone = false;
4689
- const valueStr = stringify2.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
4689
+ const valueStr = stringify3.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
4690
4690
  let ws = " ";
4691
4691
  if (keyComment || vsb || vcb) {
4692
4692
  ws = vsb ? "\n" : "";
@@ -4827,7 +4827,7 @@ var require_addPairToJSMap = __commonJS({
4827
4827
  "use strict";
4828
4828
  var log = require_log();
4829
4829
  var merge = require_merge();
4830
- var stringify2 = require_stringify();
4830
+ var stringify3 = require_stringify();
4831
4831
  var identity = require_identity();
4832
4832
  var toJS = require_toJS();
4833
4833
  function addPairToJSMap(ctx, map, { key, value }) {
@@ -4863,7 +4863,7 @@ var require_addPairToJSMap = __commonJS({
4863
4863
  if (typeof jsKey !== "object")
4864
4864
  return String(jsKey);
4865
4865
  if (identity.isNode(key) && ctx?.doc) {
4866
- const strCtx = stringify2.createStringifyContext(ctx.doc, {});
4866
+ const strCtx = stringify3.createStringifyContext(ctx.doc, {});
4867
4867
  strCtx.anchors = /* @__PURE__ */ new Set();
4868
4868
  for (const node of ctx.anchors.keys())
4869
4869
  strCtx.anchors.add(node.anchor);
@@ -4930,12 +4930,12 @@ var require_stringifyCollection = __commonJS({
4930
4930
  "node_modules/yaml/dist/stringify/stringifyCollection.js"(exports) {
4931
4931
  "use strict";
4932
4932
  var identity = require_identity();
4933
- var stringify2 = require_stringify();
4933
+ var stringify3 = require_stringify();
4934
4934
  var stringifyComment = require_stringifyComment();
4935
4935
  function stringifyCollection(collection, ctx, options) {
4936
4936
  const flow = ctx.inFlow ?? collection.flow;
4937
- const stringify3 = flow ? stringifyFlowCollection : stringifyBlockCollection;
4938
- return stringify3(collection, ctx, options);
4937
+ const stringify4 = flow ? stringifyFlowCollection : stringifyBlockCollection;
4938
+ return stringify4(collection, ctx, options);
4939
4939
  }
4940
4940
  function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {
4941
4941
  const { indent, options: { commentString } } = ctx;
@@ -4960,7 +4960,7 @@ var require_stringifyCollection = __commonJS({
4960
4960
  }
4961
4961
  }
4962
4962
  chompKeep = false;
4963
- let str2 = stringify2.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
4963
+ let str2 = stringify3.stringify(item, itemCtx, () => comment2 = null, () => chompKeep = true);
4964
4964
  if (comment2)
4965
4965
  str2 += stringifyComment.lineComment(str2, itemIndent, commentString(comment2));
4966
4966
  if (chompKeep && comment2)
@@ -5027,7 +5027,7 @@ ${indent}${line}` : "\n";
5027
5027
  }
5028
5028
  if (comment)
5029
5029
  reqNewline = true;
5030
- let str = stringify2.stringify(item, itemCtx, () => comment = null);
5030
+ let str = stringify3.stringify(item, itemCtx, () => comment = null);
5031
5031
  reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
5032
5032
  if (i < items.length - 1) {
5033
5033
  str += ",";
@@ -6388,7 +6388,7 @@ var require_stringifyDocument = __commonJS({
6388
6388
  "node_modules/yaml/dist/stringify/stringifyDocument.js"(exports) {
6389
6389
  "use strict";
6390
6390
  var identity = require_identity();
6391
- var stringify2 = require_stringify();
6391
+ var stringify3 = require_stringify();
6392
6392
  var stringifyComment = require_stringifyComment();
6393
6393
  function stringifyDocument(doc, options) {
6394
6394
  const lines = [];
@@ -6403,7 +6403,7 @@ var require_stringifyDocument = __commonJS({
6403
6403
  }
6404
6404
  if (hasDirectives)
6405
6405
  lines.push("---");
6406
- const ctx = stringify2.createStringifyContext(doc, options);
6406
+ const ctx = stringify3.createStringifyContext(doc, options);
6407
6407
  const { commentString } = ctx.options;
6408
6408
  if (doc.commentBefore) {
6409
6409
  if (lines.length !== 1)
@@ -6425,7 +6425,7 @@ var require_stringifyDocument = __commonJS({
6425
6425
  contentComment = doc.contents.comment;
6426
6426
  }
6427
6427
  const onChompKeep = contentComment ? void 0 : () => chompKeep = true;
6428
- let body = stringify2.stringify(doc.contents, ctx, () => contentComment = null, onChompKeep);
6428
+ let body = stringify3.stringify(doc.contents, ctx, () => contentComment = null, onChompKeep);
6429
6429
  if (contentComment)
6430
6430
  body += stringifyComment.lineComment(body, "", commentString(contentComment));
6431
6431
  if ((body[0] === "|" || body[0] === ">") && lines[lines.length - 1] === "---") {
@@ -6433,7 +6433,7 @@ var require_stringifyDocument = __commonJS({
6433
6433
  } else
6434
6434
  lines.push(body);
6435
6435
  } else {
6436
- lines.push(stringify2.stringify(doc.contents, ctx));
6436
+ lines.push(stringify3.stringify(doc.contents, ctx));
6437
6437
  }
6438
6438
  if (doc.directives?.docEnd) {
6439
6439
  if (doc.comment) {
@@ -6541,9 +6541,9 @@ var require_Document = __commonJS({
6541
6541
  this.contents.add(value);
6542
6542
  }
6543
6543
  /** Adds a value to the document. */
6544
- addIn(path17, value) {
6544
+ addIn(path18, value) {
6545
6545
  if (assertCollection(this.contents))
6546
- this.contents.addIn(path17, value);
6546
+ this.contents.addIn(path18, value);
6547
6547
  }
6548
6548
  /**
6549
6549
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -6618,14 +6618,14 @@ var require_Document = __commonJS({
6618
6618
  * Removes a value from the document.
6619
6619
  * @returns `true` if the item was found and removed.
6620
6620
  */
6621
- deleteIn(path17) {
6622
- if (Collection.isEmptyPath(path17)) {
6621
+ deleteIn(path18) {
6622
+ if (Collection.isEmptyPath(path18)) {
6623
6623
  if (this.contents == null)
6624
6624
  return false;
6625
6625
  this.contents = null;
6626
6626
  return true;
6627
6627
  }
6628
- return assertCollection(this.contents) ? this.contents.deleteIn(path17) : false;
6628
+ return assertCollection(this.contents) ? this.contents.deleteIn(path18) : false;
6629
6629
  }
6630
6630
  /**
6631
6631
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -6640,10 +6640,10 @@ var require_Document = __commonJS({
6640
6640
  * scalar values from their surrounding node; to disable set `keepScalar` to
6641
6641
  * `true` (collections are always returned intact).
6642
6642
  */
6643
- getIn(path17, keepScalar) {
6644
- if (Collection.isEmptyPath(path17))
6643
+ getIn(path18, keepScalar) {
6644
+ if (Collection.isEmptyPath(path18))
6645
6645
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
6646
- return identity.isCollection(this.contents) ? this.contents.getIn(path17, keepScalar) : void 0;
6646
+ return identity.isCollection(this.contents) ? this.contents.getIn(path18, keepScalar) : void 0;
6647
6647
  }
6648
6648
  /**
6649
6649
  * Checks if the document includes a value with the key `key`.
@@ -6654,10 +6654,10 @@ var require_Document = __commonJS({
6654
6654
  /**
6655
6655
  * Checks if the document includes a value at `path`.
6656
6656
  */
6657
- hasIn(path17) {
6658
- if (Collection.isEmptyPath(path17))
6657
+ hasIn(path18) {
6658
+ if (Collection.isEmptyPath(path18))
6659
6659
  return this.contents !== void 0;
6660
- return identity.isCollection(this.contents) ? this.contents.hasIn(path17) : false;
6660
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path18) : false;
6661
6661
  }
6662
6662
  /**
6663
6663
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -6674,13 +6674,13 @@ var require_Document = __commonJS({
6674
6674
  * Sets a value in this document. For `!!set`, `value` needs to be a
6675
6675
  * boolean to add/remove the item from the set.
6676
6676
  */
6677
- setIn(path17, value) {
6678
- if (Collection.isEmptyPath(path17)) {
6677
+ setIn(path18, value) {
6678
+ if (Collection.isEmptyPath(path18)) {
6679
6679
  this.contents = value;
6680
6680
  } else if (this.contents == null) {
6681
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path17), value);
6681
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path18), value);
6682
6682
  } else if (assertCollection(this.contents)) {
6683
- this.contents.setIn(path17, value);
6683
+ this.contents.setIn(path18, value);
6684
6684
  }
6685
6685
  }
6686
6686
  /**
@@ -8568,7 +8568,7 @@ var require_cst_scalar = __commonJS({
8568
8568
  var require_cst_stringify = __commonJS({
8569
8569
  "node_modules/yaml/dist/parse/cst-stringify.js"(exports) {
8570
8570
  "use strict";
8571
- var stringify2 = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
8571
+ var stringify3 = (cst) => "type" in cst ? stringifyToken(cst) : stringifyItem(cst);
8572
8572
  function stringifyToken(token) {
8573
8573
  switch (token.type) {
8574
8574
  case "block-scalar": {
@@ -8621,7 +8621,7 @@ var require_cst_stringify = __commonJS({
8621
8621
  res += stringifyToken(value);
8622
8622
  return res;
8623
8623
  }
8624
- exports.stringify = stringify2;
8624
+ exports.stringify = stringify3;
8625
8625
  }
8626
8626
  });
8627
8627
 
@@ -8640,9 +8640,9 @@ var require_cst_visit = __commonJS({
8640
8640
  visit.BREAK = BREAK;
8641
8641
  visit.SKIP = SKIP;
8642
8642
  visit.REMOVE = REMOVE;
8643
- visit.itemAtPath = (cst, path17) => {
8643
+ visit.itemAtPath = (cst, path18) => {
8644
8644
  let item = cst;
8645
- for (const [field, index] of path17) {
8645
+ for (const [field, index] of path18) {
8646
8646
  const tok = item?.[field];
8647
8647
  if (tok && "items" in tok) {
8648
8648
  item = tok.items[index];
@@ -8651,23 +8651,23 @@ var require_cst_visit = __commonJS({
8651
8651
  }
8652
8652
  return item;
8653
8653
  };
8654
- visit.parentCollection = (cst, path17) => {
8655
- const parent = visit.itemAtPath(cst, path17.slice(0, -1));
8656
- const field = path17[path17.length - 1][0];
8654
+ visit.parentCollection = (cst, path18) => {
8655
+ const parent = visit.itemAtPath(cst, path18.slice(0, -1));
8656
+ const field = path18[path18.length - 1][0];
8657
8657
  const coll = parent?.[field];
8658
8658
  if (coll && "items" in coll)
8659
8659
  return coll;
8660
8660
  throw new Error("Parent collection not found");
8661
8661
  };
8662
- function _visit(path17, item, visitor) {
8663
- let ctrl = visitor(item, path17);
8662
+ function _visit(path18, item, visitor) {
8663
+ let ctrl = visitor(item, path18);
8664
8664
  if (typeof ctrl === "symbol")
8665
8665
  return ctrl;
8666
8666
  for (const field of ["key", "value"]) {
8667
8667
  const token = item[field];
8668
8668
  if (token && "items" in token) {
8669
8669
  for (let i = 0; i < token.items.length; ++i) {
8670
- const ci = _visit(Object.freeze(path17.concat([[field, i]])), token.items[i], visitor);
8670
+ const ci = _visit(Object.freeze(path18.concat([[field, i]])), token.items[i], visitor);
8671
8671
  if (typeof ci === "number")
8672
8672
  i = ci - 1;
8673
8673
  else if (ci === BREAK)
@@ -8678,10 +8678,10 @@ var require_cst_visit = __commonJS({
8678
8678
  }
8679
8679
  }
8680
8680
  if (typeof ctrl === "function" && field === "key")
8681
- ctrl = ctrl(item, path17);
8681
+ ctrl = ctrl(item, path18);
8682
8682
  }
8683
8683
  }
8684
- return typeof ctrl === "function" ? ctrl(item, path17) : ctrl;
8684
+ return typeof ctrl === "function" ? ctrl(item, path18) : ctrl;
8685
8685
  }
8686
8686
  exports.visit = visit;
8687
8687
  }
@@ -9983,14 +9983,14 @@ var require_parser = __commonJS({
9983
9983
  case "scalar":
9984
9984
  case "single-quoted-scalar":
9985
9985
  case "double-quoted-scalar": {
9986
- const fs15 = this.flowScalar(this.type);
9986
+ const fs16 = this.flowScalar(this.type);
9987
9987
  if (atNextItem || it.value) {
9988
- map.items.push({ start, key: fs15, sep: [] });
9988
+ map.items.push({ start, key: fs16, sep: [] });
9989
9989
  this.onKeyLine = true;
9990
9990
  } else if (it.sep) {
9991
- this.stack.push(fs15);
9991
+ this.stack.push(fs16);
9992
9992
  } else {
9993
- Object.assign(it, { key: fs15, sep: [] });
9993
+ Object.assign(it, { key: fs16, sep: [] });
9994
9994
  this.onKeyLine = true;
9995
9995
  }
9996
9996
  return;
@@ -10118,13 +10118,13 @@ var require_parser = __commonJS({
10118
10118
  case "scalar":
10119
10119
  case "single-quoted-scalar":
10120
10120
  case "double-quoted-scalar": {
10121
- const fs15 = this.flowScalar(this.type);
10121
+ const fs16 = this.flowScalar(this.type);
10122
10122
  if (!it || it.value)
10123
- fc.items.push({ start: [], key: fs15, sep: [] });
10123
+ fc.items.push({ start: [], key: fs16, sep: [] });
10124
10124
  else if (it.sep)
10125
- this.stack.push(fs15);
10125
+ this.stack.push(fs16);
10126
10126
  else
10127
- Object.assign(it, { key: fs15, sep: [] });
10127
+ Object.assign(it, { key: fs16, sep: [] });
10128
10128
  return;
10129
10129
  }
10130
10130
  case "flow-map-end":
@@ -10332,7 +10332,7 @@ var require_public_api = __commonJS({
10332
10332
  }
10333
10333
  return doc;
10334
10334
  }
10335
- function parse3(src, reviver, options) {
10335
+ function parse4(src, reviver, options) {
10336
10336
  let _reviver = void 0;
10337
10337
  if (typeof reviver === "function") {
10338
10338
  _reviver = reviver;
@@ -10351,7 +10351,7 @@ var require_public_api = __commonJS({
10351
10351
  }
10352
10352
  return doc.toJS(Object.assign({ reviver: _reviver }, options));
10353
10353
  }
10354
- function stringify2(value, replacer, options) {
10354
+ function stringify3(value, replacer, options) {
10355
10355
  let _replacer = null;
10356
10356
  if (typeof replacer === "function" || Array.isArray(replacer)) {
10357
10357
  _replacer = replacer;
@@ -10373,10 +10373,10 @@ var require_public_api = __commonJS({
10373
10373
  return value.toString(options);
10374
10374
  return new Document.Document(value, _replacer, options).toString(options);
10375
10375
  }
10376
- exports.parse = parse3;
10376
+ exports.parse = parse4;
10377
10377
  exports.parseAllDocuments = parseAllDocuments;
10378
10378
  exports.parseDocument = parseDocument;
10379
- exports.stringify = stringify2;
10379
+ exports.stringify = stringify3;
10380
10380
  }
10381
10381
  });
10382
10382
 
@@ -33138,10 +33138,10 @@ var require_react_reconciler_development = __commonJS({
33138
33138
  var setErrorHandler = null;
33139
33139
  var setSuspenseHandler = null;
33140
33140
  {
33141
- var copyWithDeleteImpl = function(obj, path17, index2) {
33142
- var key = path17[index2];
33141
+ var copyWithDeleteImpl = function(obj, path18, index2) {
33142
+ var key = path18[index2];
33143
33143
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
33144
- if (index2 + 1 === path17.length) {
33144
+ if (index2 + 1 === path18.length) {
33145
33145
  if (isArray(updated)) {
33146
33146
  updated.splice(key, 1);
33147
33147
  } else {
@@ -33149,11 +33149,11 @@ var require_react_reconciler_development = __commonJS({
33149
33149
  }
33150
33150
  return updated;
33151
33151
  }
33152
- updated[key] = copyWithDeleteImpl(obj[key], path17, index2 + 1);
33152
+ updated[key] = copyWithDeleteImpl(obj[key], path18, index2 + 1);
33153
33153
  return updated;
33154
33154
  };
33155
- var copyWithDelete = function(obj, path17) {
33156
- return copyWithDeleteImpl(obj, path17, 0);
33155
+ var copyWithDelete = function(obj, path18) {
33156
+ return copyWithDeleteImpl(obj, path18, 0);
33157
33157
  };
33158
33158
  var copyWithRenameImpl = function(obj, oldPath, newPath, index2) {
33159
33159
  var oldKey = oldPath[index2];
@@ -33191,17 +33191,17 @@ var require_react_reconciler_development = __commonJS({
33191
33191
  }
33192
33192
  return copyWithRenameImpl(obj, oldPath, newPath, 0);
33193
33193
  };
33194
- var copyWithSetImpl = function(obj, path17, index2, value) {
33195
- if (index2 >= path17.length) {
33194
+ var copyWithSetImpl = function(obj, path18, index2, value) {
33195
+ if (index2 >= path18.length) {
33196
33196
  return value;
33197
33197
  }
33198
- var key = path17[index2];
33198
+ var key = path18[index2];
33199
33199
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
33200
- updated[key] = copyWithSetImpl(obj[key], path17, index2 + 1, value);
33200
+ updated[key] = copyWithSetImpl(obj[key], path18, index2 + 1, value);
33201
33201
  return updated;
33202
33202
  };
33203
- var copyWithSet = function(obj, path17, value) {
33204
- return copyWithSetImpl(obj, path17, 0, value);
33203
+ var copyWithSet = function(obj, path18, value) {
33204
+ return copyWithSetImpl(obj, path18, 0, value);
33205
33205
  };
33206
33206
  var findHook = function(fiber, id) {
33207
33207
  var currentHook2 = fiber.memoizedState;
@@ -33211,10 +33211,10 @@ var require_react_reconciler_development = __commonJS({
33211
33211
  }
33212
33212
  return currentHook2;
33213
33213
  };
33214
- overrideHookState = function(fiber, id, path17, value) {
33214
+ overrideHookState = function(fiber, id, path18, value) {
33215
33215
  var hook = findHook(fiber, id);
33216
33216
  if (hook !== null) {
33217
- var newState = copyWithSet(hook.memoizedState, path17, value);
33217
+ var newState = copyWithSet(hook.memoizedState, path18, value);
33218
33218
  hook.memoizedState = newState;
33219
33219
  hook.baseState = newState;
33220
33220
  fiber.memoizedProps = assign({}, fiber.memoizedProps);
@@ -33224,10 +33224,10 @@ var require_react_reconciler_development = __commonJS({
33224
33224
  }
33225
33225
  }
33226
33226
  };
33227
- overrideHookStateDeletePath = function(fiber, id, path17) {
33227
+ overrideHookStateDeletePath = function(fiber, id, path18) {
33228
33228
  var hook = findHook(fiber, id);
33229
33229
  if (hook !== null) {
33230
- var newState = copyWithDelete(hook.memoizedState, path17);
33230
+ var newState = copyWithDelete(hook.memoizedState, path18);
33231
33231
  hook.memoizedState = newState;
33232
33232
  hook.baseState = newState;
33233
33233
  fiber.memoizedProps = assign({}, fiber.memoizedProps);
@@ -33250,8 +33250,8 @@ var require_react_reconciler_development = __commonJS({
33250
33250
  }
33251
33251
  }
33252
33252
  };
33253
- overrideProps = function(fiber, path17, value) {
33254
- fiber.pendingProps = copyWithSet(fiber.memoizedProps, path17, value);
33253
+ overrideProps = function(fiber, path18, value) {
33254
+ fiber.pendingProps = copyWithSet(fiber.memoizedProps, path18, value);
33255
33255
  if (fiber.alternate) {
33256
33256
  fiber.alternate.pendingProps = fiber.pendingProps;
33257
33257
  }
@@ -33260,8 +33260,8 @@ var require_react_reconciler_development = __commonJS({
33260
33260
  scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
33261
33261
  }
33262
33262
  };
33263
- overridePropsDeletePath = function(fiber, path17) {
33264
- fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path17);
33263
+ overridePropsDeletePath = function(fiber, path18) {
33264
+ fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path18);
33265
33265
  if (fiber.alternate) {
33266
33266
  fiber.alternate.pendingProps = fiber.pendingProps;
33267
33267
  }
@@ -35551,7 +35551,7 @@ var require_extension = __commonJS({
35551
35551
  if (dest[name] === void 0) dest[name] = [elem];
35552
35552
  else dest[name].push(elem);
35553
35553
  }
35554
- function parse3(header) {
35554
+ function parse4(header) {
35555
35555
  const offers = /* @__PURE__ */ Object.create(null);
35556
35556
  let params = /* @__PURE__ */ Object.create(null);
35557
35557
  let mustUnescape = false;
@@ -35691,7 +35691,7 @@ var require_extension = __commonJS({
35691
35691
  }).join(", ");
35692
35692
  }).join(", ");
35693
35693
  }
35694
- module.exports = { format, parse: parse3 };
35694
+ module.exports = { format, parse: parse4 };
35695
35695
  }
35696
35696
  });
35697
35697
 
@@ -35725,7 +35725,7 @@ var require_websocket = __commonJS({
35725
35725
  var {
35726
35726
  EventTarget: { addEventListener, removeEventListener }
35727
35727
  } = require_event_target();
35728
- var { format, parse: parse3 } = require_extension();
35728
+ var { format, parse: parse4 } = require_extension();
35729
35729
  var { toBuffer } = require_buffer_util();
35730
35730
  var kAborted = Symbol("kAborted");
35731
35731
  var protocolVersions = [8, 13];
@@ -36402,7 +36402,7 @@ var require_websocket = __commonJS({
36402
36402
  }
36403
36403
  let extensions;
36404
36404
  try {
36405
- extensions = parse3(secWebSocketExtensions);
36405
+ extensions = parse4(secWebSocketExtensions);
36406
36406
  } catch (err) {
36407
36407
  const message = "Invalid Sec-WebSocket-Extensions header";
36408
36408
  abortHandshake(websocket, socket, message);
@@ -36694,7 +36694,7 @@ var require_subprotocol = __commonJS({
36694
36694
  "node_modules/ws/lib/subprotocol.js"(exports, module) {
36695
36695
  "use strict";
36696
36696
  var { tokenChars } = require_validation();
36697
- function parse3(header) {
36697
+ function parse4(header) {
36698
36698
  const protocols = /* @__PURE__ */ new Set();
36699
36699
  let start = -1;
36700
36700
  let end = -1;
@@ -36730,7 +36730,7 @@ var require_subprotocol = __commonJS({
36730
36730
  protocols.add(protocol);
36731
36731
  return protocols;
36732
36732
  }
36733
- module.exports = { parse: parse3 };
36733
+ module.exports = { parse: parse4 };
36734
36734
  }
36735
36735
  });
36736
36736
 
@@ -38583,6 +38583,7 @@ var require_jsx_runtime = __commonJS({
38583
38583
  });
38584
38584
 
38585
38585
  // src/cli.ts
38586
+ import path17 from "node:path";
38586
38587
  import * as readline2 from "node:readline";
38587
38588
 
38588
38589
  // node_modules/commander/esm.mjs
@@ -39109,7 +39110,28 @@ var DANGEROUS_PATTERNS = [
39109
39110
  [/\bcurl\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "curl \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39110
39111
  [/\bwget\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "wget \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39111
39112
  [/\bsudo\b/, "sudo \u63D0\u6743"],
39112
- [/\bchmod\s+777\b/, "chmod 777 \u5F00\u653E\u5199\u6743\u9650"]
39113
+ [/\bchmod\s+777\b/, "chmod 777 \u5F00\u653E\u5199\u6743\u9650"],
39114
+ // —— 凭据与敏感信息(§9.1:读取 env / credentials)——
39115
+ [/\.ssh[/']|\.aws[/']|\.kube[/']|\.netrc\b/, "\u89E6\u78B0 SSH/\u4E91\u5382\u5546\u51ED\u636E\u6587\u4EF6"],
39116
+ [
39117
+ /\b(?:API[_-]?KEY|APIKEY|SECRET[_-]?KEY|ACCESS[_-]?TOKEN|PRIVATE[_-]?KEY|AWS_SECRET[_-]?ACCESS[_-]?KEY)\b/i,
39118
+ "\u5F15\u7528\u5BC6\u94A5\u7C7B\u6807\u8BC6\u7B26"
39119
+ ],
39120
+ [/\bprintenv\b/, "printenv \u5BFC\u51FA\u73AF\u5883\u53D8\u91CF"],
39121
+ [
39122
+ /process\.env\.[A-Z_]*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)\w*/i,
39123
+ "\u8BFB\u53D6 Node \u5BC6\u94A5\u7C7B\u73AF\u5883\u53D8\u91CF"
39124
+ ],
39125
+ // —— 外发数据(§9.1:外发网络请求)——
39126
+ [
39127
+ /\bcurl\b[^\n]*(?:-X\s*(?:POST|PUT)\b|--data(?:-binary|-raw|-urlencode)?\b|--form\b|--upload-file\b|\s-T\s)/,
39128
+ "curl \u5411\u5916\u53D1\u9001\u6570\u636E\uFF08POST/PUT/\u4E0A\u4F20\uFF09"
39129
+ ],
39130
+ [/\bwget\b[^\n]*--(?:post-data|post-file)\b/, "wget \u5411\u5916\u53D1\u9001\u6570\u636E"],
39131
+ [/\bnc\b[^\n]*\s-e\b/, "nc -e \u8FDC\u7A0B\u6267\u884C/\u53CD\u5F39 shell"],
39132
+ [/\b(?:scp|rsync)\b[^\n]*\b\w+@(?!localhost|127\.0\.0\.1)/, "\u5411\u8FDC\u7AEF\u4E3B\u673A\u62F7\u8D1D\u6587\u4EF6"],
39133
+ // —— 反取证 ——
39134
+ [/\.(?:bash|zsh)_history/, "\u89E6\u78B0 shell \u5386\u53F2\u6587\u4EF6"]
39113
39135
  ];
39114
39136
  var SCRIPT_EXT = /\.(sh|bash|zsh|py|js|mjs|cjs|ts|rb|pl)$/;
39115
39137
  function lintSkill(dir) {
@@ -39320,25 +39342,234 @@ async function installFromMarket(url, subdir, opts = {}) {
39320
39342
  return addSkill(`${url}#${subdir}`, { name: opts.name, for: opts.for });
39321
39343
  }
39322
39344
 
39323
- // src/core/doctor.ts
39345
+ // src/tui/matrix.ts
39324
39346
  import fs8 from "node:fs";
39325
39347
  import path11 from "node:path";
39348
+ function deriveMatrix(agents) {
39349
+ const config = loadConfig();
39350
+ const skills = Object.keys(config.skills).sort();
39351
+ const list = agents ?? detectAll().map((r) => ({
39352
+ id: r.id,
39353
+ name: r.name,
39354
+ installed: r.installed,
39355
+ skillsDir: r.skillsDir
39356
+ }));
39357
+ const cells = {};
39358
+ for (const s of skills) {
39359
+ cells[s] = {};
39360
+ for (const a of list) {
39361
+ const target = path11.join(a.skillsDir, s);
39362
+ let actual = false;
39363
+ let managed = false;
39364
+ try {
39365
+ const st = fs8.lstatSync(target);
39366
+ actual = true;
39367
+ managed = st.isSymbolicLink() && fs8.realpathSync(target) === fs8.realpathSync(skillDir(s));
39368
+ } catch {
39369
+ }
39370
+ cells[s][a.id] = {
39371
+ enabled: config.skills[s].expose[a.id] === true,
39372
+ actual,
39373
+ managed
39374
+ };
39375
+ }
39376
+ }
39377
+ return { skills, agents: list, cells };
39378
+ }
39379
+
39380
+ // src/core/audit.ts
39381
+ function runAudit() {
39382
+ const matrix = deriveMatrix();
39383
+ const config = loadConfig();
39384
+ const agents = [];
39385
+ for (const a of matrix.agents) {
39386
+ if (!a.installed) continue;
39387
+ const active = [];
39388
+ const external = [];
39389
+ const findings = [];
39390
+ for (const skill of matrix.skills) {
39391
+ const cs = matrix.cells[skill]?.[a.id];
39392
+ if (!cs) continue;
39393
+ if (cs.actual && cs.managed) {
39394
+ active.push({
39395
+ skill,
39396
+ source: config.skills[skill]?.source ?? "\u672A\u767B\u8BB0\uFF08\u4E2D\u592E\u4ED3\u5E93\u5B58\u5728\u4F46 config \u7F3A\u5931\uFF09",
39397
+ enabled: cs.enabled
39398
+ });
39399
+ if (!cs.enabled) {
39400
+ findings.push({
39401
+ level: "warn",
39402
+ agent: a.id,
39403
+ message: `'${skill}' \u53D7\u7BA1\u94FE\u63A5\u4ECD\u5B58\u5728\uFF0C\u4F46\u77E9\u9635\u5DF2\u58F0\u660E\u5173\u95ED\uFF08disable \u6216 doctor --fix \u53EF\u6E05\u7406\uFF09`
39404
+ });
39405
+ }
39406
+ } else if (cs.actual && !cs.managed) {
39407
+ external.push({ name: skill, path: `${a.skillsDir}/${skill}` });
39408
+ if (cs.enabled) {
39409
+ findings.push({
39410
+ level: "error",
39411
+ agent: a.id,
39412
+ message: `'${skill}' \u58F0\u660E\u5BF9 ${a.id} \u5F00\u653E\uFF0C\u4F46\u8BE5\u4F4D\u7F6E\u88AB\u5916\u90E8\u540C\u540D\u6761\u76EE\u5360\u7528\u2014\u2014\u5B9E\u9645\u751F\u6548\u7684\u4E0D\u662F\u4E2D\u592E\u4ED3\u5E93\u7248\u672C\uFF08\u53EF\u80FD\u88AB\u7ED5\u8FC7/\u906E\u853D\uFF09`
39413
+ });
39414
+ }
39415
+ } else if (cs.enabled && !cs.actual) {
39416
+ findings.push({
39417
+ level: "warn",
39418
+ agent: a.id,
39419
+ message: `'${skill}' \u58F0\u660E\u5F00\u653E\u4F46\u94FE\u63A5\u7F3A\u5931\uFF08\u6F02\u79FB\uFF0Cdoctor --fix \u53EF\u91CD\u540C\u6B65\uFF09`
39420
+ });
39421
+ }
39422
+ }
39423
+ agents.push({
39424
+ agent: a.id,
39425
+ agentName: a.name,
39426
+ active,
39427
+ external,
39428
+ findings
39429
+ });
39430
+ }
39431
+ return { agents, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
39432
+ }
39433
+
39434
+ // src/core/team-sync.ts
39435
+ var import_yaml3 = __toESM(require_dist());
39436
+ import fs9 from "node:fs";
39437
+ function loadManifest(file) {
39438
+ if (!fs9.existsSync(file)) throw new Error(`\u6E05\u5355\u4E0D\u5B58\u5728\uFF1A${file}`);
39439
+ let data = null;
39440
+ try {
39441
+ data = (0, import_yaml3.parse)(fs9.readFileSync(file, "utf8"));
39442
+ } catch (e) {
39443
+ throw new Error(`\u6E05\u5355\u89E3\u6790\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
39444
+ }
39445
+ if (!data || typeof data !== "object" || !data.skills || typeof data.skills !== "object") {
39446
+ throw new Error(`\u6E05\u5355\u683C\u5F0F\u4E0D\u5408\u6CD5\uFF1A${file}\uFF08\u9700\u8981 version: 1 \u4E0E skills \u5B57\u6BB5\uFF09`);
39447
+ }
39448
+ return { version: 1, skills: data.skills };
39449
+ }
39450
+ function exportManifest(file, names) {
39451
+ const config = loadConfig();
39452
+ const all = Object.entries(config.skills);
39453
+ const picked = names?.length ? all.filter(([n]) => names.includes(n)) : all;
39454
+ if (!picked.length) throw new Error("\u4E2D\u592E\u4ED3\u5E93\u4E3A\u7A7A\uFF08\u6216\u672A\u5339\u914D\u5230\u6307\u5B9A skill\uFF09\uFF0C\u65E0\u53EF\u5BFC\u51FA\u5185\u5BB9");
39455
+ const warnings = [];
39456
+ const skills = {};
39457
+ for (const [n, e] of picked) {
39458
+ skills[n] = {
39459
+ source: e.source,
39460
+ checksum: e.checksum,
39461
+ expose: Object.fromEntries(Object.entries(e.expose).filter(([, v]) => v === true))
39462
+ };
39463
+ if (e.source.startsWith("local:")) {
39464
+ warnings.push(
39465
+ `'${n}' \u4E3A local \u6765\u6E90\uFF08${e.source}\uFF09\u2014\u2014\u961F\u53CB\u65E0\u6CD5\u4ECE\u672C\u673A\u8DEF\u5F84\u5BF9\u9F50\uFF0C\u5EFA\u8BAE\u6539\u4E3A git \u6E90\u540E\u91CD\u65B0\u5BFC\u51FA`
39466
+ );
39467
+ }
39468
+ }
39469
+ const manifest = { version: 1, skills };
39470
+ fs9.writeFileSync(file, (0, import_yaml3.stringify)(manifest));
39471
+ return { manifest, file, warnings };
39472
+ }
39473
+ function applyExpose(name, expose) {
39474
+ const enabled = [];
39475
+ for (const [agent, on] of Object.entries(expose ?? {})) {
39476
+ if (on !== true) continue;
39477
+ try {
39478
+ const r = enableSkill(name, [agent]);
39479
+ if (r.linked.length) enabled.push(agent);
39480
+ } catch {
39481
+ }
39482
+ }
39483
+ return enabled;
39484
+ }
39485
+ async function syncManifest(file, opts = {}) {
39486
+ const manifest = loadManifest(file);
39487
+ const config = loadConfig();
39488
+ const out = [];
39489
+ for (const [name, entry] of Object.entries(manifest.skills)) {
39490
+ try {
39491
+ const installed = !!config.skills[name];
39492
+ const src = entry.source.replace(/^git:/, "");
39493
+ if (entry.source.startsWith("local:")) {
39494
+ out.push({
39495
+ skill: name,
39496
+ action: installed ? "ok" : "skip",
39497
+ detail: installed ? "local \u6765\u6E90\uFF0C\u8DF3\u8FC7\u5BF9\u9F50\uFF08\u4EC5\u672C\u673A\u6709\u610F\u4E49\uFF09" : `local \u6765\u6E90\uFF08${entry.source}\uFF09\u5728\u672C\u673A\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u5B89\u88C5`
39498
+ });
39499
+ continue;
39500
+ }
39501
+ if (!isGitSource(src)) {
39502
+ out.push({ skill: name, action: "skip", detail: `\u4E0D\u652F\u6301\u7684\u6765\u6E90\uFF1A${entry.source}` });
39503
+ continue;
39504
+ }
39505
+ if (!installed) {
39506
+ if (opts.dryRun) {
39507
+ out.push({ skill: name, action: "install", dryRun: true });
39508
+ continue;
39509
+ }
39510
+ const r = await addSkill(src, { name, for: Object.entries(entry.expose ?? {}).filter(([, v]) => v === true).map(([a]) => a) });
39511
+ let detail = r.checksum === entry.checksum ? void 0 : "\u5DF2\u5B89\u88C5\uFF0C\u4F46\u4E0E\u6E05\u5355 checksum \u4E0D\u4E00\u81F4\uFF08\u8FDC\u7AEF\u53EF\u80FD\u5DF2\u66F4\u65B0\uFF09";
39512
+ out.push({ skill: name, action: "install", detail });
39513
+ continue;
39514
+ }
39515
+ if (entry.checksum && dirChecksum(skillDir(name)) !== entry.checksum) {
39516
+ if (opts.dryRun) {
39517
+ out.push({
39518
+ skill: name,
39519
+ action: "reinstall",
39520
+ dryRun: true,
39521
+ detail: "\u672C\u673A\u7248\u672C\u4E0E\u6E05\u5355\u9501\u5B9A\u7684 checksum \u4E0D\u4E00\u81F4\uFF0C\u5C06\u91CD\u88C5\u5BF9\u9F50"
39522
+ });
39523
+ continue;
39524
+ }
39525
+ uninstallSkill(name);
39526
+ const r = await addSkill(src, { name, for: Object.entries(entry.expose ?? {}).filter(([, v]) => v === true).map(([a]) => a) });
39527
+ out.push({
39528
+ skill: name,
39529
+ action: "reinstall",
39530
+ detail: r.checksum === entry.checksum ? "\u5DF2\u91CD\u88C5\u5BF9\u9F50\u6E05\u5355\u7248\u672C" : "\u5DF2\u91CD\u88C5\uFF0C\u4F46\u4ECD\u4E0E\u6E05\u5355 checksum \u4E0D\u4E00\u81F4\uFF08\u8FDC\u7AEF\u53EF\u80FD\u5DF2\u66F4\u65B0\uFF0C\u5EFA\u8BAE\u66F4\u65B0\u6E05\u5355\uFF09"
39531
+ });
39532
+ continue;
39533
+ }
39534
+ applyExpose(name, entry.expose);
39535
+ out.push({ skill: name, action: "ok" });
39536
+ } catch (e) {
39537
+ out.push({
39538
+ skill: name,
39539
+ action: "error",
39540
+ detail: e instanceof Error ? e.message : String(e)
39541
+ });
39542
+ }
39543
+ }
39544
+ return out;
39545
+ }
39546
+ var SYNC_ACTION_LABELS = {
39547
+ install: "\u5B89\u88C5",
39548
+ reinstall: "\u91CD\u88C5\u5BF9\u9F50",
39549
+ ok: "\u5DF2\u4E00\u81F4",
39550
+ skip: "\u8DF3\u8FC7",
39551
+ error: "\u5931\u8D25"
39552
+ };
39553
+
39554
+ // src/core/doctor.ts
39555
+ import fs10 from "node:fs";
39556
+ import path12 from "node:path";
39326
39557
  function runDoctor() {
39327
39558
  const issues = [];
39328
39559
  const config = loadConfig();
39329
39560
  const state = loadState();
39330
39561
  const home = agentHome();
39331
39562
  for (const [name, entry] of Object.entries(config.skills)) {
39332
- if (!fs8.existsSync(path11.join(skillDir(name), "SKILL.md"))) {
39563
+ if (!fs10.existsSync(path12.join(skillDir(name), "SKILL.md"))) {
39333
39564
  issues.push({
39334
39565
  level: "error",
39335
39566
  message: `config \u4E2D\u7684 '${name}' \u5728\u4E2D\u592E\u4ED3\u5E93\u7F3A\u5931\uFF08source=${entry.source}\uFF09`
39336
39567
  });
39337
39568
  }
39338
39569
  }
39339
- if (fs8.existsSync(storeDir())) {
39340
- for (const e of fs8.readdirSync(storeDir(), { withFileTypes: true })) {
39341
- if (e.isDirectory() && !config.skills[e.name] && fs8.existsSync(path11.join(storeDir(), e.name, "SKILL.md"))) {
39570
+ if (fs10.existsSync(storeDir())) {
39571
+ for (const e of fs10.readdirSync(storeDir(), { withFileTypes: true })) {
39572
+ if (e.isDirectory() && !config.skills[e.name] && fs10.existsSync(path12.join(storeDir(), e.name, "SKILL.md"))) {
39342
39573
  issues.push({
39343
39574
  level: "warn",
39344
39575
  message: `\u4E2D\u592E\u4ED3\u5E93\u4E2D\u7684 '${e.name}' \u672A\u767B\u8BB0\u8FDB config\uFF08\u624B\u52A8\u62F7\u5165\uFF1F\uFF09`,
@@ -39350,7 +39581,7 @@ function runDoctor() {
39350
39581
  for (const link2 of state.links) {
39351
39582
  let st = null;
39352
39583
  try {
39353
- st = fs8.lstatSync(link2.link_path);
39584
+ st = fs10.lstatSync(link2.link_path);
39354
39585
  } catch {
39355
39586
  }
39356
39587
  if (!st) {
@@ -39368,7 +39599,7 @@ function runDoctor() {
39368
39599
  });
39369
39600
  continue;
39370
39601
  }
39371
- if (!fs8.existsSync(link2.link_path)) {
39602
+ if (!fs10.existsSync(link2.link_path)) {
39372
39603
  issues.push({
39373
39604
  level: "error",
39374
39605
  message: `\u65AD\u94FE\uFF1A${link2.link_path} \u6307\u5411\u7684\u76EE\u6807\u4E0D\u5B58\u5728`,
@@ -39378,19 +39609,19 @@ function runDoctor() {
39378
39609
  }
39379
39610
  for (const agent of AGENTS) {
39380
39611
  const dir = agent.skillsDir(home);
39381
- if (!fs8.existsSync(dir)) continue;
39612
+ if (!fs10.existsSync(dir)) continue;
39382
39613
  let entries = [];
39383
39614
  try {
39384
- entries = fs8.readdirSync(dir, { withFileTypes: true });
39615
+ entries = fs10.readdirSync(dir, { withFileTypes: true });
39385
39616
  } catch {
39386
39617
  continue;
39387
39618
  }
39388
39619
  for (const e of entries) {
39389
39620
  if (!e.isSymbolicLink()) continue;
39390
- const linkPath = path11.join(dir, e.name);
39621
+ const linkPath = path12.join(dir, e.name);
39391
39622
  let target = "";
39392
39623
  try {
39393
- target = fs8.readlinkSync(linkPath);
39624
+ target = fs10.readlinkSync(linkPath);
39394
39625
  } catch {
39395
39626
  continue;
39396
39627
  }
@@ -39406,8 +39637,8 @@ function runDoctor() {
39406
39637
  }
39407
39638
  for (const [name, entry] of Object.entries(config.skills)) {
39408
39639
  for (const agent of AGENTS) {
39409
- const target = path11.join(agent.skillsDir(home), name);
39410
- const exposed = fs8.existsSync(target);
39640
+ const target = path12.join(agent.skillsDir(home), name);
39641
+ const exposed = fs10.existsSync(target);
39411
39642
  const wanted = entry.expose[agent.id] === true;
39412
39643
  if (wanted && !exposed) {
39413
39644
  issues.push({
@@ -39432,7 +39663,7 @@ function fixDoctor() {
39432
39663
  state.links = state.links.filter((l) => {
39433
39664
  let ok = false;
39434
39665
  try {
39435
- ok = fs8.existsSync(l.link_path) && fs8.lstatSync(l.link_path).isSymbolicLink();
39666
+ ok = fs10.existsSync(l.link_path) && fs10.lstatSync(l.link_path).isSymbolicLink();
39436
39667
  } catch {
39437
39668
  ok = false;
39438
39669
  }
@@ -39445,10 +39676,10 @@ function fixDoctor() {
39445
39676
  saveState(state);
39446
39677
  const config = loadConfig();
39447
39678
  for (const [name, entry] of Object.entries(config.skills)) {
39448
- if (!fs8.existsSync(path11.join(skillDir(name), "SKILL.md"))) continue;
39679
+ if (!fs10.existsSync(path12.join(skillDir(name), "SKILL.md"))) continue;
39449
39680
  for (const agent of AGENTS) {
39450
- const target = path11.join(agent.skillsDir(agentHome()), name);
39451
- const exposed = fs8.existsSync(target);
39681
+ const target = path12.join(agent.skillsDir(agentHome()), name);
39682
+ const exposed = fs10.existsSync(target);
39452
39683
  const wanted = entry.expose[agent.id] === true;
39453
39684
  if (wanted && !exposed) {
39454
39685
  try {
@@ -39470,7 +39701,7 @@ function fixDoctor() {
39470
39701
  function isOurSymlink(target, state, skill, agentId) {
39471
39702
  let isLink = false;
39472
39703
  try {
39473
- isLink = fs8.lstatSync(target).isSymbolicLink();
39704
+ isLink = fs10.lstatSync(target).isSymbolicLink();
39474
39705
  } catch {
39475
39706
  return false;
39476
39707
  }
@@ -39481,13 +39712,13 @@ function isOurSymlink(target, state, skill, agentId) {
39481
39712
  if (inLedger) return true;
39482
39713
  let real = null;
39483
39714
  try {
39484
- real = fs8.realpathSync(target);
39715
+ real = fs10.realpathSync(target);
39485
39716
  } catch {
39486
39717
  return false;
39487
39718
  }
39488
39719
  let storeReal = null;
39489
39720
  try {
39490
- storeReal = fs8.realpathSync(skillDir(skill));
39721
+ storeReal = fs10.realpathSync(skillDir(skill));
39491
39722
  } catch {
39492
39723
  return false;
39493
39724
  }
@@ -39495,21 +39726,21 @@ function isOurSymlink(target, state, skill, agentId) {
39495
39726
  }
39496
39727
  function sameRealPath(a, b) {
39497
39728
  try {
39498
- return fs8.realpathSync(a) === fs8.realpathSync(b);
39729
+ return fs10.realpathSync(a) === fs10.realpathSync(b);
39499
39730
  } catch {
39500
39731
  return false;
39501
39732
  }
39502
39733
  }
39503
39734
 
39504
39735
  // src/core/adopt.ts
39505
- import fs9 from "node:fs";
39506
- import path12 from "node:path";
39736
+ import fs11 from "node:fs";
39737
+ import path13 from "node:path";
39507
39738
  function isManagedByStore(dir) {
39508
39739
  try {
39509
- if (!fs9.lstatSync(dir).isSymbolicLink()) return false;
39510
- const real = fs9.realpathSync(dir);
39511
- const storeReal = fs9.realpathSync(storeDir());
39512
- return real === storeReal || real.startsWith(storeReal + path12.sep);
39740
+ if (!fs11.lstatSync(dir).isSymbolicLink()) return false;
39741
+ const real = fs11.realpathSync(dir);
39742
+ const storeReal = fs11.realpathSync(storeDir());
39743
+ return real === storeReal || real.startsWith(storeReal + path13.sep);
39513
39744
  } catch {
39514
39745
  return false;
39515
39746
  }
@@ -39518,13 +39749,13 @@ function scanAgentSkills(agentId) {
39518
39749
  const agent = getAgent(agentId);
39519
39750
  if (!agent) throw new Error(`\u672A\u77E5 agent '${agentId}'`);
39520
39751
  const dir = agent.skillsDir(agentHome());
39521
- if (!fs9.existsSync(dir)) return [];
39752
+ if (!fs11.existsSync(dir)) return [];
39522
39753
  const out = [];
39523
- for (const e of fs9.readdirSync(dir, { withFileTypes: true })) {
39754
+ for (const e of fs11.readdirSync(dir, { withFileTypes: true })) {
39524
39755
  if (e.name.startsWith(".")) continue;
39525
39756
  if (!e.isDirectory() && !e.isSymbolicLink()) continue;
39526
- const p = path12.join(dir, e.name);
39527
- if (!fs9.existsSync(path12.join(p, "SKILL.md"))) continue;
39757
+ const p = path13.join(dir, e.name);
39758
+ if (!fs11.existsSync(path13.join(p, "SKILL.md"))) continue;
39528
39759
  out.push({ name: e.name, path: p });
39529
39760
  }
39530
39761
  return out;
@@ -39532,7 +39763,7 @@ function scanAgentSkills(agentId) {
39532
39763
  function scanAdoptable(agentId) {
39533
39764
  return scanAgentSkills(agentId).filter((s) => {
39534
39765
  try {
39535
- return !fs9.lstatSync(s.path).isSymbolicLink();
39766
+ return !fs11.lstatSync(s.path).isSymbolicLink();
39536
39767
  } catch {
39537
39768
  return false;
39538
39769
  }
@@ -39563,7 +39794,7 @@ function adoptSkills(opts = {}) {
39563
39794
  }
39564
39795
  let isOwnSymlink = false;
39565
39796
  try {
39566
- isOwnSymlink = fs9.lstatSync(skill.path).isSymbolicLink();
39797
+ isOwnSymlink = fs11.lstatSync(skill.path).isSymbolicLink();
39567
39798
  } catch {
39568
39799
  }
39569
39800
  if (isOwnSymlink) {
@@ -39583,7 +39814,7 @@ function adoptSkills(opts = {}) {
39583
39814
  items.push({ agent: agentId, name: skill.name, path: skill.path, status: "skipped-invalid", detail: "\u76EE\u5F55\u540D\u4E0D\u5408\u6CD5" });
39584
39815
  continue;
39585
39816
  }
39586
- const existsInStore = !!config.skills[name] || fs9.existsSync(skillDir(name));
39817
+ const existsInStore = !!config.skills[name] || fs11.existsSync(skillDir(name));
39587
39818
  if (opts.dryRun) {
39588
39819
  items.push({
39589
39820
  agent: agentId,
@@ -39640,7 +39871,7 @@ function adoptSkills(opts = {}) {
39640
39871
  saveConfig(config);
39641
39872
  for (const mv of pendingMoves) {
39642
39873
  try {
39643
- fs9.rmSync(mv.path, { recursive: true, force: true });
39874
+ fs11.rmSync(mv.path, { recursive: true, force: true });
39644
39875
  enableSkill(mv.name, [mv.agentId]);
39645
39876
  items.push({
39646
39877
  agent: mv.agentId,
@@ -39675,30 +39906,56 @@ function adoptSkills(opts = {}) {
39675
39906
  }
39676
39907
 
39677
39908
  // src/core/update.ts
39678
- import fs10 from "node:fs";
39909
+ import fs12 from "node:fs";
39679
39910
  import os3 from "node:os";
39680
- import path13 from "node:path";
39911
+ import path14 from "node:path";
39681
39912
  import { execFile as execFile3 } from "node:child_process";
39682
39913
  import { promisify as promisify3 } from "node:util";
39683
39914
  var execFileP3 = promisify3(execFile3);
39915
+ function diffTree(oldDir, newDir) {
39916
+ const IGNORED2 = /* @__PURE__ */ new Set([".git"]);
39917
+ const collect = (root) => {
39918
+ const map = /* @__PURE__ */ new Map();
39919
+ const walk = (d) => {
39920
+ for (const e of fs12.readdirSync(d, { withFileTypes: true })) {
39921
+ if (IGNORED2.has(e.name)) continue;
39922
+ const p = path14.join(d, e.name);
39923
+ if (e.isDirectory()) walk(p);
39924
+ else if (e.isFile()) map.set(path14.relative(root, p), p);
39925
+ }
39926
+ };
39927
+ walk(root);
39928
+ return map;
39929
+ };
39930
+ const oldFiles = collect(oldDir);
39931
+ const newFiles = collect(newDir);
39932
+ const diff2 = { added: [], removed: [], modified: [] };
39933
+ for (const [rel, p] of newFiles) {
39934
+ if (!oldFiles.has(rel)) diff2.added.push(rel);
39935
+ else if (fs12.readFileSync(p) !== fs12.readFileSync(oldFiles.get(rel))) diff2.modified.push(rel);
39936
+ }
39937
+ for (const rel of oldFiles.keys()) if (!newFiles.has(rel)) diff2.removed.push(rel);
39938
+ for (const k of ["added", "removed", "modified"]) diff2[k].sort();
39939
+ return diff2;
39940
+ }
39684
39941
  function parseGitSource(source) {
39685
39942
  return source.startsWith("git:") ? source.slice(4) : null;
39686
39943
  }
39687
39944
  async function fetchRemote(repoSpec) {
39688
39945
  const [url, sub] = repoSpec.split("#");
39689
- const cloneDir = fs10.mkdtempSync(path13.join(os3.tmpdir(), "skillpot-update-"));
39946
+ const cloneDir = fs12.mkdtempSync(path14.join(os3.tmpdir(), "skillpot-update-"));
39690
39947
  try {
39691
39948
  await execFileP3("git", ["clone", "--depth", "1", url, cloneDir], {
39692
39949
  timeout: 3e5,
39693
39950
  maxBuffer: 16 * 1024 * 1024
39694
39951
  });
39695
- const contentDir = sub ? path13.join(cloneDir, sub) : cloneDir;
39696
- if (!fs10.existsSync(path13.join(contentDir, "SKILL.md"))) {
39952
+ const contentDir = sub ? path14.join(cloneDir, sub) : cloneDir;
39953
+ if (!fs12.existsSync(path14.join(contentDir, "SKILL.md"))) {
39697
39954
  throw new Error(`\u8FDC\u7AEF ${sub ? `#${sub} ` : ""}\u4E2D\u6CA1\u6709 SKILL.md`);
39698
39955
  }
39699
39956
  return { checksum: dirChecksum(contentDir), cloneDir, sub };
39700
39957
  } catch (e) {
39701
- fs10.rmSync(cloneDir, { recursive: true, force: true });
39958
+ fs12.rmSync(cloneDir, { recursive: true, force: true });
39702
39959
  throw e;
39703
39960
  }
39704
39961
  }
@@ -39717,7 +39974,7 @@ async function updateSkills(name, opts = {}) {
39717
39974
  results.push({ skill: n, status: "local", detail: entry.source });
39718
39975
  continue;
39719
39976
  }
39720
- if (!fs10.existsSync(skillDir(n))) {
39977
+ if (!fs12.existsSync(skillDir(n))) {
39721
39978
  results.push({ skill: n, status: "error", detail: "\u4E2D\u592E\u4ED3\u5E93\u7F3A\u5931" });
39722
39979
  continue;
39723
39980
  }
@@ -39728,24 +39985,35 @@ async function updateSkills(name, opts = {}) {
39728
39985
  results.push({ skill: n, status: "up-to-date" });
39729
39986
  continue;
39730
39987
  }
39988
+ const srcDir = fetched.sub ? path14.join(fetched.cloneDir, fetched.sub) : fetched.cloneDir;
39989
+ const diff2 = diffTree(skillDir(n), srcDir);
39731
39990
  if (opts.check) {
39732
- results.push({ skill: n, status: "outdated", detail: `\u8FDC\u7AEF ${fetched.checksum.slice(0, 15)}` });
39991
+ results.push({
39992
+ skill: n,
39993
+ status: "outdated",
39994
+ detail: `\u8FDC\u7AEF ${fetched.checksum.slice(0, 15)}`,
39995
+ diff: diff2
39996
+ });
39733
39997
  continue;
39734
39998
  }
39735
- const staging = fs10.mkdtempSync(path13.join(os3.tmpdir(), "skillpot-new-"));
39999
+ const staging = fs12.mkdtempSync(path14.join(os3.tmpdir(), "skillpot-new-"));
39736
40000
  try {
39737
- const srcDir = fetched.sub ? path13.join(fetched.cloneDir, fetched.sub) : fetched.cloneDir;
39738
- fs10.cpSync(srcDir, staging, { recursive: true });
39739
- fs10.rmSync(skillDir(n), { recursive: true, force: true });
39740
- fs10.cpSync(staging, skillDir(n), { recursive: true });
40001
+ fs12.cpSync(srcDir, staging, { recursive: true });
40002
+ fs12.rmSync(skillDir(n), { recursive: true, force: true });
40003
+ fs12.cpSync(staging, skillDir(n), { recursive: true });
39741
40004
  } finally {
39742
- fs10.rmSync(staging, { recursive: true, force: true });
40005
+ fs12.rmSync(staging, { recursive: true, force: true });
39743
40006
  }
39744
40007
  entry.checksum = dirChecksum(skillDir(n));
39745
40008
  entry.installed_at = (/* @__PURE__ */ new Date()).toISOString();
39746
- results.push({ skill: n, status: "updated", detail: entry.checksum.slice(0, 15) });
40009
+ results.push({
40010
+ skill: n,
40011
+ status: "updated",
40012
+ detail: entry.checksum.slice(0, 15),
40013
+ diff: diff2
40014
+ });
39747
40015
  } finally {
39748
- fs10.rmSync(fetched.cloneDir, { recursive: true, force: true });
40016
+ fs12.rmSync(fetched.cloneDir, { recursive: true, force: true });
39749
40017
  }
39750
40018
  } catch (e) {
39751
40019
  results.push({ skill: n, status: "error", detail: e instanceof Error ? e.message : String(e) });
@@ -39759,21 +40027,21 @@ async function updateSkills(name, opts = {}) {
39759
40027
  import readline from "node:readline";
39760
40028
 
39761
40029
  // src/core/skill-detail.ts
39762
- import fs11 from "node:fs";
39763
- import path14 from "node:path";
40030
+ import fs13 from "node:fs";
40031
+ import path15 from "node:path";
39764
40032
  function readSkillDetail(name) {
39765
40033
  const dir = skillDir(name);
39766
- const mdPath = path14.join(dir, "SKILL.md");
39767
- if (!fs11.existsSync(mdPath)) return null;
40034
+ const mdPath = path15.join(dir, "SKILL.md");
40035
+ if (!fs13.existsSync(mdPath)) return null;
39768
40036
  const files = [];
39769
40037
  const walk = (d) => {
39770
- for (const e of fs11.readdirSync(d, { withFileTypes: true })) {
39771
- const p = path14.join(d, e.name);
40038
+ for (const e of fs13.readdirSync(d, { withFileTypes: true })) {
40039
+ const p = path15.join(d, e.name);
39772
40040
  if (e.isDirectory()) {
39773
- files.push(path14.relative(dir, p) + "/");
40041
+ files.push(path15.relative(dir, p) + "/");
39774
40042
  walk(p);
39775
40043
  } else {
39776
- files.push(path14.relative(dir, p));
40044
+ files.push(path15.relative(dir, p));
39777
40045
  }
39778
40046
  }
39779
40047
  };
@@ -39782,7 +40050,7 @@ function readSkillDetail(name) {
39782
40050
  name,
39783
40051
  meta: readSkillMeta(dir),
39784
40052
  files: files.sort(),
39785
- skillMd: fs11.readFileSync(mdPath, "utf8")
40053
+ skillMd: fs13.readFileSync(mdPath, "utf8")
39786
40054
  };
39787
40055
  }
39788
40056
 
@@ -39913,47 +40181,12 @@ function startMcpServer() {
39913
40181
 
39914
40182
  // src/core/gui-server.ts
39915
40183
  import crypto3 from "node:crypto";
39916
- import fs13 from "node:fs";
40184
+ import fs14 from "node:fs";
39917
40185
  import http from "node:http";
39918
40186
  import path16 from "node:path";
39919
40187
  import { spawn } from "node:child_process";
39920
40188
  import { fileURLToPath } from "node:url";
39921
40189
 
39922
- // src/tui/matrix.ts
39923
- import fs12 from "node:fs";
39924
- import path15 from "node:path";
39925
- function deriveMatrix(agents) {
39926
- const config = loadConfig();
39927
- const skills = Object.keys(config.skills).sort();
39928
- const list = agents ?? detectAll().map((r) => ({
39929
- id: r.id,
39930
- name: r.name,
39931
- installed: r.installed,
39932
- skillsDir: r.skillsDir
39933
- }));
39934
- const cells = {};
39935
- for (const s of skills) {
39936
- cells[s] = {};
39937
- for (const a of list) {
39938
- const target = path15.join(a.skillsDir, s);
39939
- let actual = false;
39940
- let managed = false;
39941
- try {
39942
- const st = fs12.lstatSync(target);
39943
- actual = true;
39944
- managed = st.isSymbolicLink() && fs12.realpathSync(target) === fs12.realpathSync(skillDir(s));
39945
- } catch {
39946
- }
39947
- cells[s][a.id] = {
39948
- enabled: config.skills[s].expose[a.id] === true,
39949
- actual,
39950
- managed
39951
- };
39952
- }
39953
- }
39954
- return { skills, agents: list, cells };
39955
- }
39956
-
39957
40190
  // src/tui/cells.ts
39958
40191
  var import_picocolors = __toESM(require_picocolors());
39959
40192
  function cellGlyph(cs) {
@@ -40064,7 +40297,7 @@ async function handleApiRequest(method, pathname, query, body, expectedToken, go
40064
40297
  let inStore = false;
40065
40298
  try {
40066
40299
  const n = sanitizeSkillName(s.name);
40067
- inStore = !!config.skills[n] || fs13.existsSync(skillDir(n));
40300
+ inStore = !!config.skills[n] || fs14.existsSync(skillDir(n));
40068
40301
  } catch {
40069
40302
  valid = false;
40070
40303
  }
@@ -40239,13 +40472,13 @@ function guiDistDir() {
40239
40472
  path16.resolve(fileURLToPath(new URL("../../dist/gui/", import.meta.url)))
40240
40473
  ];
40241
40474
  for (const dir of candidates) {
40242
- if (fs13.existsSync(path16.join(dir, "index.html"))) return dir;
40475
+ if (fs14.existsSync(path16.join(dir, "index.html"))) return dir;
40243
40476
  }
40244
40477
  return candidates[0];
40245
40478
  }
40246
40479
  function serveStatic(pathname, res) {
40247
40480
  const root = guiDistDir();
40248
- if (!fs13.existsSync(path16.join(root, "index.html"))) {
40481
+ if (!fs14.existsSync(path16.join(root, "index.html"))) {
40249
40482
  res.writeHead(503, { "content-type": "text/plain; charset=utf-8" });
40250
40483
  res.end("GUI \u524D\u7AEF\u672A\u6784\u5EFA\uFF1A\u5728\u9879\u76EE\u6839\u76EE\u5F55\u8FD0\u884C npm run build:gui\uFF08npm \u53D1\u5E03\u5305\u5185\u5DF2\u81EA\u5E26\uFF09\u3002");
40251
40484
  return;
@@ -40257,7 +40490,7 @@ function serveStatic(pathname, res) {
40257
40490
  res.end("forbidden");
40258
40491
  return;
40259
40492
  }
40260
- if (!fs13.existsSync(file) || fs13.statSync(file).isDirectory()) {
40493
+ if (!fs14.existsSync(file) || fs14.statSync(file).isDirectory()) {
40261
40494
  file = path16.join(root, "index.html");
40262
40495
  }
40263
40496
  const ext = path16.extname(file).toLowerCase();
@@ -40265,7 +40498,7 @@ function serveStatic(pathname, res) {
40265
40498
  "content-type": MIME[ext] ?? "application/octet-stream",
40266
40499
  "cache-control": rel.startsWith("assets/") ? "public, max-age=31536000, immutable" : "no-store"
40267
40500
  });
40268
- fs13.createReadStream(file).pipe(res);
40501
+ fs14.createReadStream(file).pipe(res);
40269
40502
  }
40270
40503
  async function startGuiServer(opts = {}) {
40271
40504
  const token = crypto3.randomBytes(16).toString("hex");
@@ -44949,7 +45182,7 @@ var FocusContext_default = FocusContext;
44949
45182
  // node_modules/ink/build/components/ErrorOverview.js
44950
45183
  var import_react8 = __toESM(require_react(), 1);
44951
45184
  var import_stack_utils = __toESM(require_stack_utils(), 1);
44952
- import * as fs14 from "node:fs";
45185
+ import * as fs15 from "node:fs";
44953
45186
  import { cwd } from "node:process";
44954
45187
 
44955
45188
  // node_modules/convert-to-spaces/dist/index.js
@@ -45039,8 +45272,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
45039
45272
  }
45040
45273
 
45041
45274
  // node_modules/ink/build/components/ErrorOverview.js
45042
- var cleanupPath = (path17) => {
45043
- return path17?.replace(`file://${cwd()}/`, "");
45275
+ var cleanupPath = (path18) => {
45276
+ return path18?.replace(`file://${cwd()}/`, "");
45044
45277
  };
45045
45278
  var stackUtils = new import_stack_utils.default({
45046
45279
  cwd: cwd(),
@@ -45052,8 +45285,8 @@ function ErrorOverview({ error }) {
45052
45285
  const filePath = cleanupPath(origin?.file);
45053
45286
  let excerpt;
45054
45287
  let lineWidth = 0;
45055
- if (filePath && origin?.line && fs14.existsSync(filePath)) {
45056
- const sourceCode = fs14.readFileSync(filePath, "utf8");
45288
+ if (filePath && origin?.line && fs15.existsSync(filePath)) {
45289
+ const sourceCode = fs15.readFileSync(filePath, "utf8");
45057
45290
  excerpt = dist_default3(sourceCode, origin.line);
45058
45291
  if (excerpt) {
45059
45292
  for (const { line } of excerpt) {
@@ -46288,6 +46521,45 @@ program2.command("doctor").description("\u4F53\u68C0\uFF1A\u65AD\u94FE\u3001expo
46288
46521
  printIssues(issues);
46289
46522
  })
46290
46523
  );
46524
+ program2.command("audit").description("\u5BA1\u8BA1\uFF1A\u6BCF\u4E2A Agent \u5B9E\u9645\u751F\u6548\u7684 skill\u3001\u6765\u6E90\u4E0E\u88AB\u7ED5\u8FC7/\u906E\u853D\u60C5\u51B5").option("--json", "\u4EE5 JSON \u8F93\u51FA").action(
46525
+ run((opts) => {
46526
+ const report = runAudit();
46527
+ if (opts.json) {
46528
+ console.log(JSON.stringify(report, null, 2));
46529
+ return;
46530
+ }
46531
+ for (const a of report.agents) {
46532
+ console.log(
46533
+ import_picocolors2.default.bold(`${a.agentName} (${a.agent})`) + ` \u2014 \u5B9E\u9645\u751F\u6548 ${a.active.length} \u4E2A`
46534
+ );
46535
+ if (a.active.length) {
46536
+ console.log(
46537
+ renderTable(
46538
+ ["Skill", "\u6765\u6E90", "\u58F0\u660E"],
46539
+ a.active.map((e) => [
46540
+ e.skill,
46541
+ e.source.length > 64 ? e.source.slice(0, 61) + "\u2026" : e.source,
46542
+ e.enabled ? "\u5F00\u653E" : import_picocolors2.default.yellow("\u5173\u95ED\uFF08\u94FE\u63A5\u6B8B\u7559\uFF09")
46543
+ ])
46544
+ )
46545
+ );
46546
+ } else {
46547
+ console.log(import_picocolors2.default.dim(" \uFF08\u65E0\u751F\u6548 skill\uFF09"));
46548
+ }
46549
+ for (const e of a.external) {
46550
+ console.log(import_picocolors2.default.yellow(`\u26A0 \u5916\u90E8\u540C\u540D\u6761\u76EE\uFF08\u975E\u672C\u5DE5\u5177\u521B\u5EFA\uFF09\uFF1A${e.path}`));
46551
+ }
46552
+ for (const f of a.findings) {
46553
+ console.log(f.level === "error" ? import_picocolors2.default.red(`\u2717 ${f.message}`) : import_picocolors2.default.yellow(`\u26A0 ${f.message}`));
46554
+ }
46555
+ console.log();
46556
+ }
46557
+ const total = report.agents.reduce((n, a) => n + a.findings.length, 0);
46558
+ console.log(
46559
+ total ? import_picocolors2.default.yellow(`\u5BA1\u8BA1\u5B8C\u6210\uFF0C\u5171 ${total} \u6761\u53D1\u73B0\uFF0C\u8BE6\u89C1\u4E0A\u8868`) : import_picocolors2.default.green("\u5BA1\u8BA1\u901A\u8FC7\uFF1A\u5404 Agent \u5B9E\u9645\u751F\u6548\u72B6\u6001\u4E0E\u77E9\u9635\u4E00\u81F4")
46560
+ );
46561
+ })
46562
+ );
46291
46563
  function printIssues(issues) {
46292
46564
  for (const i of issues) {
46293
46565
  const tag = i.level === "error" ? import_picocolors2.default.red("error") : import_picocolors2.default.yellow("warn ");
@@ -46375,7 +46647,20 @@ program2.command("update [skill]").description("\u68C0\u67E5\u5E76\u5E94\u7528 g
46375
46647
  console.log(
46376
46648
  renderTable(
46377
46649
  ["Skill", "\u72B6\u6001", "\u5907\u6CE8"],
46378
- results.map((r) => [r.skill, label[r.status] ?? r.status, r.detail ?? ""])
46650
+ results.map((r) => {
46651
+ let note = r.detail ?? "";
46652
+ if (r.diff) {
46653
+ const { added, modified, removed } = r.diff;
46654
+ const counts = [
46655
+ added.length ? `+${added.length}` : "",
46656
+ modified.length ? `~${modified.length}` : "",
46657
+ removed.length ? `-${removed.length}` : ""
46658
+ ].filter(Boolean).join(" ");
46659
+ const paths = [...added, ...modified, ...removed];
46660
+ note = `${note ? note + " " : ""}diff ${counts}\uFF08${paths.slice(0, 4).join("\u3001")}${paths.length > 4 ? " \u7B49" : ""}\uFF09`;
46661
+ }
46662
+ return [r.skill, label[r.status] ?? r.status, note];
46663
+ })
46379
46664
  )
46380
46665
  );
46381
46666
  })
@@ -46462,6 +46747,43 @@ program2.command("market [url]").description("\u6D4F\u89C8\u6280\u80FD\u6E90\u91
46462
46747
  );
46463
46748
  })
46464
46749
  );
46750
+ program2.command("sync").description("\u56E2\u961F\u5BF9\u9F50\uFF1A\u6309\u9879\u76EE\u6E05\u5355\uFF08\u9ED8\u8BA4 ./.skillpot.yaml\uFF09\u5B89\u88C5/\u5BF9\u9F50 skill \u5E76\u5E94\u7528\u5F00\u653E\u77E9\u9635").option("--file <path>", "\u6E05\u5355\u8DEF\u5F84\uFF08\u9ED8\u8BA4 ./.skillpot.yaml\uFF09").option("--export", "\u628A\u5F53\u524D\u4E2D\u592E\u4ED3\u5E93\u5BFC\u51FA\u4E3A\u6E05\u5355\uFF08\u914D\u5408 --file/--skill\uFF09").option("--skill <skills>", "\u5BFC\u51FA\u65F6\u4EC5\u5BFC\u51FA\u6307\u5B9A skill\uFF08\u9017\u53F7\u5206\u9694\uFF09").option("--dry-run", "\u53EA\u5C55\u793A\u5C06\u5BF9\u9F50\u7684\u52A8\u4F5C\uFF0C\u4E0D\u505A\u4EFB\u4F55\u53D8\u66F4").action(
46751
+ run(async (opts) => {
46752
+ const file = path17.resolve(opts.file ?? ".skillpot.yaml");
46753
+ if (opts.export) {
46754
+ const { manifest, warnings } = exportManifest(file, opts.skill?.split(","));
46755
+ console.log(import_picocolors2.default.green(`\u2714 \u5DF2\u5BFC\u51FA ${Object.keys(manifest.skills).length} \u4E2A skill \u2192 ${file}`));
46756
+ for (const w of warnings) console.log(import_picocolors2.default.yellow(`\u26A0 ${w}`));
46757
+ console.log(import_picocolors2.default.dim("\u63D0\u4EA4\u8FDB\u9879\u76EE\u4ED3\u5E93\u540E\uFF0C\u56E2\u961F\u6210\u5458\u6267\u884C skillpot sync \u5373\u53EF\u4E00\u952E\u5BF9\u9F50"));
46758
+ return;
46759
+ }
46760
+ const items = await syncManifest(file, { dryRun: opts.dryRun });
46761
+ if (!items.length) {
46762
+ console.log(import_picocolors2.default.dim("\u6E05\u5355\u4E3A\u7A7A\uFF0C\u65E0\u53EF\u5BF9\u9F50\u5185\u5BB9"));
46763
+ return;
46764
+ }
46765
+ console.log(
46766
+ renderTable(
46767
+ ["Skill", "\u52A8\u4F5C", "\u8BF4\u660E"],
46768
+ items.map((i) => [
46769
+ i.skill,
46770
+ SYNC_ACTION_LABELS[i.action] + (i.dryRun ? "\uFF08\u5C06\u6267\u884C\uFF09" : ""),
46771
+ i.detail ?? ""
46772
+ ])
46773
+ )
46774
+ );
46775
+ const counts = items.reduce((m, i) => {
46776
+ m[i.action] = (m[i.action] ?? 0) + 1;
46777
+ return m;
46778
+ }, {});
46779
+ const summary = Object.entries(counts).map(([k, v]) => `${SYNC_ACTION_LABELS[k] ?? k} ${v}`).join("\uFF0C");
46780
+ console.log(
46781
+ opts.dryRun ? import_picocolors2.default.dim(`\u4EE5\u4E0A\u4E3A\u8BD5\u8FD0\u884C\u7ED3\u679C\uFF08--dry-run\uFF09\uFF0C\u672A\u505A\u4EFB\u4F55\u53D8\u66F4\u3002${summary}`) : import_picocolors2.default.green(`\u5BF9\u9F50\u5B8C\u6210\uFF1A${summary}`)
46782
+ );
46783
+ const errors = items.filter((i) => i.action === "error");
46784
+ if (errors.length) process.exitCode = 1;
46785
+ })
46786
+ );
46465
46787
  for (const cmd of program2.commands) cmd.allowExcessArguments(false);
46466
46788
  await program2.parseAsync(process.argv);
46467
46789
  /*! Bundled license information: