@tec-explorer/skillpot 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 path15 = __require("node:path");
977
- var fs13 = __require("node:fs");
976
+ var path16 = __require("node:path");
977
+ var fs14 = __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 = path15.resolve(baseDir, baseName);
1910
- if (fs13.existsSync(localBin)) return localBin;
1911
- if (sourceExt.includes(path15.extname(baseName))) return void 0;
1909
+ const localBin = path16.resolve(baseDir, baseName);
1910
+ if (fs14.existsSync(localBin)) return localBin;
1911
+ if (sourceExt.includes(path16.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs13.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs14.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 = fs13.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs14.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
1929
- executableDir = path15.resolve(
1930
- path15.dirname(resolvedScriptPath),
1929
+ executableDir = path16.resolve(
1930
+ path16.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 = path15.basename(
1937
+ const legacyName = path16.basename(
1938
1938
  this._scriptPath,
1939
- path15.extname(this._scriptPath)
1939
+ path16.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(path15.extname(executableFile));
1950
+ launchWithNode = sourceExt.includes(path16.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 = path15.basename(filename, path15.extname(filename));
2790
+ this._name = path16.basename(filename, path16.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(path16) {
2805
- if (path16 === void 0) return this._executableDir;
2806
- this._executableDir = path16;
2804
+ executableDir(path17) {
2805
+ if (path17 === void 0) return this._executableDir;
2806
+ this._executableDir = path17;
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, path15) {
3186
- const ctrl = callVisitor(key, node, visitor, path15);
3185
+ function visit_(key, node, visitor, path16) {
3186
+ const ctrl = callVisitor(key, node, visitor, path16);
3187
3187
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3188
- replaceNode(key, path15, ctrl);
3189
- return visit_(key, ctrl, visitor, path15);
3188
+ replaceNode(key, path16, ctrl);
3189
+ return visit_(key, ctrl, visitor, path16);
3190
3190
  }
3191
3191
  if (typeof ctrl !== "symbol") {
3192
3192
  if (identity.isCollection(node)) {
3193
- path15 = Object.freeze(path15.concat(node));
3193
+ path16 = Object.freeze(path16.concat(node));
3194
3194
  for (let i = 0; i < node.items.length; ++i) {
3195
- const ci = visit_(i, node.items[i], visitor, path15);
3195
+ const ci = visit_(i, node.items[i], visitor, path16);
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
- path15 = Object.freeze(path15.concat(node));
3207
- const ck = visit_("key", node.key, visitor, path15);
3206
+ path16 = Object.freeze(path16.concat(node));
3207
+ const ck = visit_("key", node.key, visitor, path16);
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, path15);
3212
+ const cv = visit_("value", node.value, visitor, path16);
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, path15) {
3234
- const ctrl = await callVisitor(key, node, visitor, path15);
3233
+ async function visitAsync_(key, node, visitor, path16) {
3234
+ const ctrl = await callVisitor(key, node, visitor, path16);
3235
3235
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
3236
- replaceNode(key, path15, ctrl);
3237
- return visitAsync_(key, ctrl, visitor, path15);
3236
+ replaceNode(key, path16, ctrl);
3237
+ return visitAsync_(key, ctrl, visitor, path16);
3238
3238
  }
3239
3239
  if (typeof ctrl !== "symbol") {
3240
3240
  if (identity.isCollection(node)) {
3241
- path15 = Object.freeze(path15.concat(node));
3241
+ path16 = Object.freeze(path16.concat(node));
3242
3242
  for (let i = 0; i < node.items.length; ++i) {
3243
- const ci = await visitAsync_(i, node.items[i], visitor, path15);
3243
+ const ci = await visitAsync_(i, node.items[i], visitor, path16);
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
- path15 = Object.freeze(path15.concat(node));
3255
- const ck = await visitAsync_("key", node.key, visitor, path15);
3254
+ path16 = Object.freeze(path16.concat(node));
3255
+ const ck = await visitAsync_("key", node.key, visitor, path16);
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, path15);
3260
+ const cv = await visitAsync_("value", node.value, visitor, path16);
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, path15) {
3287
+ function callVisitor(key, node, visitor, path16) {
3288
3288
  if (typeof visitor === "function")
3289
- return visitor(key, node, path15);
3289
+ return visitor(key, node, path16);
3290
3290
  if (identity.isMap(node))
3291
- return visitor.Map?.(key, node, path15);
3291
+ return visitor.Map?.(key, node, path16);
3292
3292
  if (identity.isSeq(node))
3293
- return visitor.Seq?.(key, node, path15);
3293
+ return visitor.Seq?.(key, node, path16);
3294
3294
  if (identity.isPair(node))
3295
- return visitor.Pair?.(key, node, path15);
3295
+ return visitor.Pair?.(key, node, path16);
3296
3296
  if (identity.isScalar(node))
3297
- return visitor.Scalar?.(key, node, path15);
3297
+ return visitor.Scalar?.(key, node, path16);
3298
3298
  if (identity.isAlias(node))
3299
- return visitor.Alias?.(key, node, path15);
3299
+ return visitor.Alias?.(key, node, path16);
3300
3300
  return void 0;
3301
3301
  }
3302
- function replaceNode(key, path15, node) {
3303
- const parent = path15[path15.length - 1];
3302
+ function replaceNode(key, path16, node) {
3303
+ const parent = path16[path16.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, path15, value) {
3913
+ function collectionFromPath(schema, path16, value) {
3914
3914
  let v = value;
3915
- for (let i = path15.length - 1; i >= 0; --i) {
3916
- const k = path15[i];
3915
+ for (let i = path16.length - 1; i >= 0; --i) {
3916
+ const k = path16[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 = (path15) => path15 == null || typeof path15 === "object" && !!path15[Symbol.iterator]().next().done;
3935
+ var isEmptyPath = (path16) => path16 == null || typeof path16 === "object" && !!path16[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(path15, value) {
3966
- if (isEmptyPath(path15))
3965
+ addIn(path16, value) {
3966
+ if (isEmptyPath(path16))
3967
3967
  this.add(value);
3968
3968
  else {
3969
- const [key, ...rest] = path15;
3969
+ const [key, ...rest] = path16;
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(path15) {
3984
- const [key, ...rest] = path15;
3983
+ deleteIn(path16) {
3984
+ const [key, ...rest] = path16;
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(path15, keepScalar) {
3999
- const [key, ...rest] = path15;
3998
+ getIn(path16, keepScalar) {
3999
+ const [key, ...rest] = path16;
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(path15) {
4018
- const [key, ...rest] = path15;
4017
+ hasIn(path16) {
4018
+ const [key, ...rest] = path16;
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(path15, value) {
4029
- const [key, ...rest] = path15;
4028
+ setIn(path16, value) {
4029
+ const [key, ...rest] = path16;
4030
4030
  if (rest.length === 0) {
4031
4031
  this.set(key, value);
4032
4032
  } else {
@@ -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(path15, value) {
6544
+ addIn(path16, value) {
6545
6545
  if (assertCollection(this.contents))
6546
- this.contents.addIn(path15, value);
6546
+ this.contents.addIn(path16, 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(path15) {
6622
- if (Collection.isEmptyPath(path15)) {
6621
+ deleteIn(path16) {
6622
+ if (Collection.isEmptyPath(path16)) {
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(path15) : false;
6628
+ return assertCollection(this.contents) ? this.contents.deleteIn(path16) : 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(path15, keepScalar) {
6644
- if (Collection.isEmptyPath(path15))
6643
+ getIn(path16, keepScalar) {
6644
+ if (Collection.isEmptyPath(path16))
6645
6645
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
6646
- return identity.isCollection(this.contents) ? this.contents.getIn(path15, keepScalar) : void 0;
6646
+ return identity.isCollection(this.contents) ? this.contents.getIn(path16, 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(path15) {
6658
- if (Collection.isEmptyPath(path15))
6657
+ hasIn(path16) {
6658
+ if (Collection.isEmptyPath(path16))
6659
6659
  return this.contents !== void 0;
6660
- return identity.isCollection(this.contents) ? this.contents.hasIn(path15) : false;
6660
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path16) : 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(path15, value) {
6678
- if (Collection.isEmptyPath(path15)) {
6677
+ setIn(path16, value) {
6678
+ if (Collection.isEmptyPath(path16)) {
6679
6679
  this.contents = value;
6680
6680
  } else if (this.contents == null) {
6681
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path15), value);
6681
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path16), value);
6682
6682
  } else if (assertCollection(this.contents)) {
6683
- this.contents.setIn(path15, value);
6683
+ this.contents.setIn(path16, value);
6684
6684
  }
6685
6685
  }
6686
6686
  /**
@@ -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, path15) => {
8643
+ visit.itemAtPath = (cst, path16) => {
8644
8644
  let item = cst;
8645
- for (const [field, index] of path15) {
8645
+ for (const [field, index] of path16) {
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, path15) => {
8655
- const parent = visit.itemAtPath(cst, path15.slice(0, -1));
8656
- const field = path15[path15.length - 1][0];
8654
+ visit.parentCollection = (cst, path16) => {
8655
+ const parent = visit.itemAtPath(cst, path16.slice(0, -1));
8656
+ const field = path16[path16.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(path15, item, visitor) {
8663
- let ctrl = visitor(item, path15);
8662
+ function _visit(path16, item, visitor) {
8663
+ let ctrl = visitor(item, path16);
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(path15.concat([[field, i]])), token.items[i], visitor);
8670
+ const ci = _visit(Object.freeze(path16.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, path15);
8681
+ ctrl = ctrl(item, path16);
8682
8682
  }
8683
8683
  }
8684
- return typeof ctrl === "function" ? ctrl(item, path15) : ctrl;
8684
+ return typeof ctrl === "function" ? ctrl(item, path16) : 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 fs13 = this.flowScalar(this.type);
9986
+ const fs14 = this.flowScalar(this.type);
9987
9987
  if (atNextItem || it.value) {
9988
- map.items.push({ start, key: fs13, sep: [] });
9988
+ map.items.push({ start, key: fs14, sep: [] });
9989
9989
  this.onKeyLine = true;
9990
9990
  } else if (it.sep) {
9991
- this.stack.push(fs13);
9991
+ this.stack.push(fs14);
9992
9992
  } else {
9993
- Object.assign(it, { key: fs13, sep: [] });
9993
+ Object.assign(it, { key: fs14, 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 fs13 = this.flowScalar(this.type);
10121
+ const fs14 = this.flowScalar(this.type);
10122
10122
  if (!it || it.value)
10123
- fc.items.push({ start: [], key: fs13, sep: [] });
10123
+ fc.items.push({ start: [], key: fs14, sep: [] });
10124
10124
  else if (it.sep)
10125
- this.stack.push(fs13);
10125
+ this.stack.push(fs14);
10126
10126
  else
10127
- Object.assign(it, { key: fs13, sep: [] });
10127
+ Object.assign(it, { key: fs14, sep: [] });
10128
10128
  return;
10129
10129
  }
10130
10130
  case "flow-map-end":
@@ -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, path15, index2) {
33142
- var key = path15[index2];
33141
+ var copyWithDeleteImpl = function(obj, path16, index2) {
33142
+ var key = path16[index2];
33143
33143
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
33144
- if (index2 + 1 === path15.length) {
33144
+ if (index2 + 1 === path16.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], path15, index2 + 1);
33152
+ updated[key] = copyWithDeleteImpl(obj[key], path16, index2 + 1);
33153
33153
  return updated;
33154
33154
  };
33155
- var copyWithDelete = function(obj, path15) {
33156
- return copyWithDeleteImpl(obj, path15, 0);
33155
+ var copyWithDelete = function(obj, path16) {
33156
+ return copyWithDeleteImpl(obj, path16, 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, path15, index2, value) {
33195
- if (index2 >= path15.length) {
33194
+ var copyWithSetImpl = function(obj, path16, index2, value) {
33195
+ if (index2 >= path16.length) {
33196
33196
  return value;
33197
33197
  }
33198
- var key = path15[index2];
33198
+ var key = path16[index2];
33199
33199
  var updated = isArray(obj) ? obj.slice() : assign({}, obj);
33200
- updated[key] = copyWithSetImpl(obj[key], path15, index2 + 1, value);
33200
+ updated[key] = copyWithSetImpl(obj[key], path16, index2 + 1, value);
33201
33201
  return updated;
33202
33202
  };
33203
- var copyWithSet = function(obj, path15, value) {
33204
- return copyWithSetImpl(obj, path15, 0, value);
33203
+ var copyWithSet = function(obj, path16, value) {
33204
+ return copyWithSetImpl(obj, path16, 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, path15, value) {
33214
+ overrideHookState = function(fiber, id, path16, value) {
33215
33215
  var hook = findHook(fiber, id);
33216
33216
  if (hook !== null) {
33217
- var newState = copyWithSet(hook.memoizedState, path15, value);
33217
+ var newState = copyWithSet(hook.memoizedState, path16, 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, path15) {
33227
+ overrideHookStateDeletePath = function(fiber, id, path16) {
33228
33228
  var hook = findHook(fiber, id);
33229
33229
  if (hook !== null) {
33230
- var newState = copyWithDelete(hook.memoizedState, path15);
33230
+ var newState = copyWithDelete(hook.memoizedState, path16);
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, path15, value) {
33254
- fiber.pendingProps = copyWithSet(fiber.memoizedProps, path15, value);
33253
+ overrideProps = function(fiber, path16, value) {
33254
+ fiber.pendingProps = copyWithSet(fiber.memoizedProps, path16, 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, path15) {
33264
- fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path15);
33263
+ overridePropsDeletePath = function(fiber, path16) {
33264
+ fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path16);
33265
33265
  if (fiber.alternate) {
33266
33266
  fiber.alternate.pendingProps = fiber.pendingProps;
33267
33267
  }
@@ -35701,7 +35701,7 @@ var require_websocket = __commonJS({
35701
35701
  "use strict";
35702
35702
  var EventEmitter3 = __require("events");
35703
35703
  var https = __require("https");
35704
- var http = __require("http");
35704
+ var http2 = __require("http");
35705
35705
  var net = __require("net");
35706
35706
  var tls = __require("tls");
35707
35707
  var { randomBytes, createHash } = __require("crypto");
@@ -36243,7 +36243,7 @@ var require_websocket = __commonJS({
36243
36243
  }
36244
36244
  const defaultPort = isSecure ? 443 : 80;
36245
36245
  const key = randomBytes(16).toString("base64");
36246
- const request = isSecure ? https.request : http.request;
36246
+ const request = isSecure ? https.request : http2.request;
36247
36247
  const protocolSet = /* @__PURE__ */ new Set();
36248
36248
  let perMessageDeflate;
36249
36249
  opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
@@ -36739,7 +36739,7 @@ var require_websocket_server = __commonJS({
36739
36739
  "node_modules/ws/lib/websocket-server.js"(exports, module) {
36740
36740
  "use strict";
36741
36741
  var EventEmitter3 = __require("events");
36742
- var http = __require("http");
36742
+ var http2 = __require("http");
36743
36743
  var { Duplex } = __require("stream");
36744
36744
  var { createHash } = __require("crypto");
36745
36745
  var extension2 = require_extension();
@@ -36820,8 +36820,8 @@ var require_websocket_server = __commonJS({
36820
36820
  );
36821
36821
  }
36822
36822
  if (options.port != null) {
36823
- this._server = http.createServer((req, res) => {
36824
- const body = http.STATUS_CODES[426];
36823
+ this._server = http2.createServer((req, res) => {
36824
+ const body = http2.STATUS_CODES[426];
36825
36825
  res.writeHead(426, {
36826
36826
  "Content-Length": body.length,
36827
36827
  "Content-Type": "text/plain"
@@ -37110,7 +37110,7 @@ var require_websocket_server = __commonJS({
37110
37110
  this.destroy();
37111
37111
  }
37112
37112
  function abortHandshake(socket, code, message, headers) {
37113
- message = message || http.STATUS_CODES[code];
37113
+ message = message || http2.STATUS_CODES[code];
37114
37114
  headers = {
37115
37115
  Connection: "close",
37116
37116
  "Content-Type": "text/html",
@@ -37119,7 +37119,7 @@ var require_websocket_server = __commonJS({
37119
37119
  };
37120
37120
  socket.once("finish", socket.destroy);
37121
37121
  socket.end(
37122
- `HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r
37122
+ `HTTP/1.1 ${code} ${http2.STATUS_CODES[code]}\r
37123
37123
  ` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message
37124
37124
  );
37125
37125
  }
@@ -38583,7 +38583,6 @@ var require_jsx_runtime = __commonJS({
38583
38583
  });
38584
38584
 
38585
38585
  // src/cli.ts
38586
- import path14 from "node:path";
38587
38586
  import * as readline2 from "node:readline";
38588
38587
 
38589
38588
  // node_modules/commander/esm.mjs
@@ -38674,6 +38673,22 @@ var AGENTS = [
38674
38673
  fingerprints: (home) => [path2.join(home, ".gemini")],
38675
38674
  skillsDir: (home) => path2.join(home, ".gemini", "skills"),
38676
38675
  verified: "\u5B98\u65B9\u652F\u6301 Agent Skills\uFF0C\u5F85\u5B9E\u673A\u786E\u8BA4"
38676
+ },
38677
+ {
38678
+ id: "dsh",
38679
+ name: "DeepSeek CLI",
38680
+ binaries: ["dsh"],
38681
+ fingerprints: (home) => [path2.join(home, ".dsh")],
38682
+ skillsDir: (home) => path2.join(home, ".dsh", "skills"),
38683
+ verified: "\u76EE\u5F55\u5B9E\u6D4B\uFF1A~/.dsh/skills \u4E3A SKILL.md \u76EE\u5F55\u7EA6\u5B9A\uFF1Bsymlink \u53D1\u73B0\u4EFB\u5F85 dsh \u5B9E\u673A\u786E\u8BA4"
38684
+ },
38685
+ {
38686
+ id: "cursor",
38687
+ name: "Cursor",
38688
+ binaries: ["cursor"],
38689
+ fingerprints: (home) => [path2.join(home, ".cursor")],
38690
+ skillsDir: (home) => path2.join(home, ".cursor", "skills-cursor"),
38691
+ verified: "\u76EE\u5F55\u5B9E\u6D4B\uFF1A~/.cursor/skills-cursor \u4E3A Cursor Agent Skills\uFF08\u5B98\u65B9 create-skill \u6280\u80FD\u81EA\u8FF0\uFF09\uFF1B\u76EE\u5F55\u540D\u975E\u901A\u7528\u7EA6\u5B9A\uFF0Csymlink \u53D1\u73B0\u4EFB\u5F85\u5B9E\u673A\u786E\u8BA4"
38677
38692
  }
38678
38693
  ];
38679
38694
  function getAgent(id) {
@@ -38814,7 +38829,8 @@ import fs4 from "node:fs";
38814
38829
  import os2 from "node:os";
38815
38830
  import path6 from "node:path";
38816
38831
  import crypto from "node:crypto";
38817
- import { execFileSync as execFileSync2 } from "node:child_process";
38832
+ import { execFile } from "node:child_process";
38833
+ import { promisify } from "node:util";
38818
38834
 
38819
38835
  // src/util/frontmatter.ts
38820
38836
  var import_yaml2 = __toESM(require_dist());
@@ -38838,6 +38854,7 @@ function sanitizeSkillName(raw) {
38838
38854
  }
38839
38855
 
38840
38856
  // src/core/store.ts
38857
+ var execFileP = promisify(execFile);
38841
38858
  var IGNORED_ENTRIES = /* @__PURE__ */ new Set([".git", ".DS_Store"]);
38842
38859
  function dirChecksum(dir) {
38843
38860
  const hash = crypto.createHash("sha256");
@@ -38894,11 +38911,11 @@ function installFromLocal(srcDir, nameOverride) {
38894
38911
  checksum: dirChecksum(dest)
38895
38912
  };
38896
38913
  }
38897
- function installFromGit(repoSpec, nameOverride) {
38914
+ async function installFromGit(repoSpec, nameOverride) {
38898
38915
  const [url, sub] = repoSpec.split("#");
38899
38916
  const tmp = fs4.mkdtempSync(path6.join(os2.tmpdir(), "skillpot-clone-"));
38900
38917
  try {
38901
- execFileSync2("git", ["clone", "--depth", "1", url, tmp], { stdio: "pipe" });
38918
+ await execFileP("git", ["clone", "--depth", "1", url, tmp]);
38902
38919
  const srcDir = sub ? path6.join(tmp, sub) : tmp;
38903
38920
  return installFromLocal(srcDir, nameOverride);
38904
38921
  } finally {
@@ -38909,6 +38926,9 @@ function removeSkillDir(name) {
38909
38926
  fs4.rmSync(skillDir(name), { recursive: true, force: true });
38910
38927
  }
38911
38928
 
38929
+ // src/core/add.ts
38930
+ import path9 from "node:path";
38931
+
38912
38932
  // src/core/sync.ts
38913
38933
  import fs5 from "node:fs";
38914
38934
  import path7 from "node:path";
@@ -39071,25 +39091,143 @@ function safeReadlink(p) {
39071
39091
  }
39072
39092
  }
39073
39093
 
39074
- // src/core/doctor.ts
39094
+ // src/core/lint.ts
39075
39095
  import fs6 from "node:fs";
39076
39096
  import path8 from "node:path";
39097
+ var DANGEROUS_PATTERNS = [
39098
+ [/\brm\s+(?:-[a-zA-Z]+\s+)*-[a-zA-Z]*[rf]/, "rm \u9012\u5F52/\u5F3A\u5236\u5220\u9664"],
39099
+ [/\bcurl\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "curl \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39100
+ [/\bwget\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "wget \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39101
+ [/\bsudo\b/, "sudo \u63D0\u6743"],
39102
+ [/\bchmod\s+777\b/, "chmod 777 \u5F00\u653E\u5199\u6743\u9650"]
39103
+ ];
39104
+ var SCRIPT_EXT = /\.(sh|bash|zsh|py|js|mjs|cjs|ts|rb|pl)$/;
39105
+ function lintSkill(dir) {
39106
+ const issues = [];
39107
+ if (!fs6.existsSync(path8.join(dir, "SKILL.md"))) {
39108
+ return [{ level: "error", message: "\u7F3A\u5C11 SKILL.md" }];
39109
+ }
39110
+ const meta = readSkillMeta(dir);
39111
+ if (!meta) {
39112
+ issues.push({ level: "error", message: "SKILL.md frontmatter \u65E0\u6CD5\u89E3\u6790" });
39113
+ } else {
39114
+ if (!meta.name) {
39115
+ issues.push({ level: "warn", message: "frontmatter \u7F3A\u5C11 name\uFF08\u5B89\u88C5\u65F6\u5C06\u56DE\u9000\u4E3A\u76EE\u5F55\u540D\uFF09" });
39116
+ }
39117
+ const desc = typeof meta.description === "string" ? meta.description : "";
39118
+ if (!desc) {
39119
+ issues.push({
39120
+ level: "error",
39121
+ message: "frontmatter \u7F3A\u5C11 description\u2014\u2014Agent \u4F9D\u8D56\u5B83\u5224\u65AD\u4F55\u65F6\u89E6\u53D1"
39122
+ });
39123
+ } else if (desc.length < 20) {
39124
+ issues.push({ level: "warn", message: "description \u8FC7\u77ED\uFF08<20 \u5B57\u7B26\uFF09\uFF0C\u8DE8 Agent \u89E6\u53D1\u53EF\u80FD\u4E0D\u7A33\u5B9A" });
39125
+ } else if (desc.length > 1024) {
39126
+ issues.push({ level: "warn", message: "description \u8FC7\u957F\uFF08>1024 \u5B57\u7B26\uFF09" });
39127
+ }
39128
+ }
39129
+ const scripts = [];
39130
+ const walk = (d) => {
39131
+ let entries = [];
39132
+ try {
39133
+ entries = fs6.readdirSync(d, { withFileTypes: true });
39134
+ } catch {
39135
+ return;
39136
+ }
39137
+ for (const e of entries) {
39138
+ const p = path8.join(d, e.name);
39139
+ if (e.isDirectory()) walk(p);
39140
+ else if (e.isFile() && SCRIPT_EXT.test(e.name)) scripts.push(p);
39141
+ }
39142
+ };
39143
+ walk(dir);
39144
+ for (const s of scripts) {
39145
+ let text = "";
39146
+ try {
39147
+ text = fs6.readFileSync(s, "utf8");
39148
+ } catch {
39149
+ continue;
39150
+ }
39151
+ for (const [re, label] of DANGEROUS_PATTERNS) {
39152
+ if (re.test(text)) {
39153
+ issues.push({ level: "warn", message: `${path8.relative(dir, s)} \u7591\u4F3C\u9AD8\u5371\u64CD\u4F5C\uFF1A${label}` });
39154
+ }
39155
+ }
39156
+ }
39157
+ return issues;
39158
+ }
39159
+ function lintSummary(issues) {
39160
+ const errors = issues.filter((i) => i.level === "error").length;
39161
+ const warns = issues.filter((i) => i.level === "warn").length;
39162
+ if (errors) return `${errors} error / ${warns} warn`;
39163
+ if (warns) return `${warns} warn`;
39164
+ return "clean";
39165
+ }
39166
+
39167
+ // src/core/add.ts
39168
+ function isGitSource(source) {
39169
+ return /^https?:\/\//.test(source) || /^git@/.test(source) || /^file:\/\//.test(source) || /\.git$/.test(source);
39170
+ }
39171
+ async function addSkill(source, opts = {}) {
39172
+ if (!source || !source.trim()) throw new Error("\u7F3A\u5C11\u6765\u6E90\uFF1A\u672C\u5730\u76EE\u5F55\u6216 git URL");
39173
+ initStore();
39174
+ const isGit = isGitSource(source);
39175
+ const res = isGit ? await installFromGit(source, opts.name) : installFromLocal(source, opts.name);
39176
+ const config = loadConfig();
39177
+ config.skills[res.name] = {
39178
+ source: isGit ? `git:${source}` : `local:${path9.resolve(source)}`,
39179
+ checksum: res.checksum,
39180
+ installed_at: (/* @__PURE__ */ new Date()).toISOString(),
39181
+ expose: {}
39182
+ };
39183
+ saveConfig(config);
39184
+ let enabled = [];
39185
+ let skipped = [];
39186
+ if (opts.for?.length) {
39187
+ const r = enableSkill(res.name, opts.for);
39188
+ enabled = r.linked;
39189
+ skipped = r.skipped;
39190
+ }
39191
+ return {
39192
+ name: res.name,
39193
+ description: res.description,
39194
+ checksum: res.checksum,
39195
+ source: config.skills[res.name].source,
39196
+ lint: lintSkill(skillDir(res.name)),
39197
+ enabled,
39198
+ skipped
39199
+ };
39200
+ }
39201
+
39202
+ // src/core/uninstall.ts
39203
+ function uninstallSkill(name) {
39204
+ const config = loadConfig();
39205
+ if (!config.skills[name]) throw new Error(`config \u4E2D\u6CA1\u6709 skill '${name}'`);
39206
+ disableSkill(name, AGENTS.map((a) => a.id));
39207
+ removeSkillDir(name);
39208
+ delete config.skills[name];
39209
+ saveConfig(config);
39210
+ }
39211
+
39212
+ // src/core/doctor.ts
39213
+ import fs7 from "node:fs";
39214
+ import path10 from "node:path";
39077
39215
  function runDoctor() {
39078
39216
  const issues = [];
39079
39217
  const config = loadConfig();
39080
39218
  const state = loadState();
39081
39219
  const home = agentHome();
39082
39220
  for (const [name, entry] of Object.entries(config.skills)) {
39083
- if (!fs6.existsSync(path8.join(skillDir(name), "SKILL.md"))) {
39221
+ if (!fs7.existsSync(path10.join(skillDir(name), "SKILL.md"))) {
39084
39222
  issues.push({
39085
39223
  level: "error",
39086
39224
  message: `config \u4E2D\u7684 '${name}' \u5728\u4E2D\u592E\u4ED3\u5E93\u7F3A\u5931\uFF08source=${entry.source}\uFF09`
39087
39225
  });
39088
39226
  }
39089
39227
  }
39090
- if (fs6.existsSync(storeDir())) {
39091
- for (const e of fs6.readdirSync(storeDir(), { withFileTypes: true })) {
39092
- if (e.isDirectory() && !config.skills[e.name] && fs6.existsSync(path8.join(storeDir(), e.name, "SKILL.md"))) {
39228
+ if (fs7.existsSync(storeDir())) {
39229
+ for (const e of fs7.readdirSync(storeDir(), { withFileTypes: true })) {
39230
+ if (e.isDirectory() && !config.skills[e.name] && fs7.existsSync(path10.join(storeDir(), e.name, "SKILL.md"))) {
39093
39231
  issues.push({
39094
39232
  level: "warn",
39095
39233
  message: `\u4E2D\u592E\u4ED3\u5E93\u4E2D\u7684 '${e.name}' \u672A\u767B\u8BB0\u8FDB config\uFF08\u624B\u52A8\u62F7\u5165\uFF1F\uFF09`,
@@ -39101,7 +39239,7 @@ function runDoctor() {
39101
39239
  for (const link2 of state.links) {
39102
39240
  let st = null;
39103
39241
  try {
39104
- st = fs6.lstatSync(link2.link_path);
39242
+ st = fs7.lstatSync(link2.link_path);
39105
39243
  } catch {
39106
39244
  }
39107
39245
  if (!st) {
@@ -39119,7 +39257,7 @@ function runDoctor() {
39119
39257
  });
39120
39258
  continue;
39121
39259
  }
39122
- if (!fs6.existsSync(link2.link_path)) {
39260
+ if (!fs7.existsSync(link2.link_path)) {
39123
39261
  issues.push({
39124
39262
  level: "error",
39125
39263
  message: `\u65AD\u94FE\uFF1A${link2.link_path} \u6307\u5411\u7684\u76EE\u6807\u4E0D\u5B58\u5728`,
@@ -39129,19 +39267,19 @@ function runDoctor() {
39129
39267
  }
39130
39268
  for (const agent of AGENTS) {
39131
39269
  const dir = agent.skillsDir(home);
39132
- if (!fs6.existsSync(dir)) continue;
39270
+ if (!fs7.existsSync(dir)) continue;
39133
39271
  let entries = [];
39134
39272
  try {
39135
- entries = fs6.readdirSync(dir, { withFileTypes: true });
39273
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
39136
39274
  } catch {
39137
39275
  continue;
39138
39276
  }
39139
39277
  for (const e of entries) {
39140
39278
  if (!e.isSymbolicLink()) continue;
39141
- const linkPath = path8.join(dir, e.name);
39279
+ const linkPath = path10.join(dir, e.name);
39142
39280
  let target = "";
39143
39281
  try {
39144
- target = fs6.readlinkSync(linkPath);
39282
+ target = fs7.readlinkSync(linkPath);
39145
39283
  } catch {
39146
39284
  continue;
39147
39285
  }
@@ -39157,8 +39295,8 @@ function runDoctor() {
39157
39295
  }
39158
39296
  for (const [name, entry] of Object.entries(config.skills)) {
39159
39297
  for (const agent of AGENTS) {
39160
- const target = path8.join(agent.skillsDir(home), name);
39161
- const exposed = fs6.existsSync(target);
39298
+ const target = path10.join(agent.skillsDir(home), name);
39299
+ const exposed = fs7.existsSync(target);
39162
39300
  const wanted = entry.expose[agent.id] === true;
39163
39301
  if (wanted && !exposed) {
39164
39302
  issues.push({
@@ -39183,7 +39321,7 @@ function fixDoctor() {
39183
39321
  state.links = state.links.filter((l) => {
39184
39322
  let ok = false;
39185
39323
  try {
39186
- ok = fs6.existsSync(l.link_path) && fs6.lstatSync(l.link_path).isSymbolicLink();
39324
+ ok = fs7.existsSync(l.link_path) && fs7.lstatSync(l.link_path).isSymbolicLink();
39187
39325
  } catch {
39188
39326
  ok = false;
39189
39327
  }
@@ -39196,10 +39334,10 @@ function fixDoctor() {
39196
39334
  saveState(state);
39197
39335
  const config = loadConfig();
39198
39336
  for (const [name, entry] of Object.entries(config.skills)) {
39199
- if (!fs6.existsSync(path8.join(skillDir(name), "SKILL.md"))) continue;
39337
+ if (!fs7.existsSync(path10.join(skillDir(name), "SKILL.md"))) continue;
39200
39338
  for (const agent of AGENTS) {
39201
- const target = path8.join(agent.skillsDir(agentHome()), name);
39202
- const exposed = fs6.existsSync(target);
39339
+ const target = path10.join(agent.skillsDir(agentHome()), name);
39340
+ const exposed = fs7.existsSync(target);
39203
39341
  const wanted = entry.expose[agent.id] === true;
39204
39342
  if (wanted && !exposed) {
39205
39343
  try {
@@ -39221,7 +39359,7 @@ function fixDoctor() {
39221
39359
  function isOurSymlink(target, state, skill, agentId) {
39222
39360
  let isLink = false;
39223
39361
  try {
39224
- isLink = fs6.lstatSync(target).isSymbolicLink();
39362
+ isLink = fs7.lstatSync(target).isSymbolicLink();
39225
39363
  } catch {
39226
39364
  return false;
39227
39365
  }
@@ -39232,13 +39370,13 @@ function isOurSymlink(target, state, skill, agentId) {
39232
39370
  if (inLedger) return true;
39233
39371
  let real = null;
39234
39372
  try {
39235
- real = fs6.realpathSync(target);
39373
+ real = fs7.realpathSync(target);
39236
39374
  } catch {
39237
39375
  return false;
39238
39376
  }
39239
39377
  let storeReal = null;
39240
39378
  try {
39241
- storeReal = fs6.realpathSync(skillDir(skill));
39379
+ storeReal = fs7.realpathSync(skillDir(skill));
39242
39380
  } catch {
39243
39381
  return false;
39244
39382
  }
@@ -39246,21 +39384,21 @@ function isOurSymlink(target, state, skill, agentId) {
39246
39384
  }
39247
39385
  function sameRealPath(a, b) {
39248
39386
  try {
39249
- return fs6.realpathSync(a) === fs6.realpathSync(b);
39387
+ return fs7.realpathSync(a) === fs7.realpathSync(b);
39250
39388
  } catch {
39251
39389
  return false;
39252
39390
  }
39253
39391
  }
39254
39392
 
39255
39393
  // src/core/adopt.ts
39256
- import fs7 from "node:fs";
39257
- import path9 from "node:path";
39394
+ import fs8 from "node:fs";
39395
+ import path11 from "node:path";
39258
39396
  function isManagedByStore(dir) {
39259
39397
  try {
39260
- if (!fs7.lstatSync(dir).isSymbolicLink()) return false;
39261
- const real = fs7.realpathSync(dir);
39262
- const storeReal = fs7.realpathSync(storeDir());
39263
- return real === storeReal || real.startsWith(storeReal + path9.sep);
39398
+ if (!fs8.lstatSync(dir).isSymbolicLink()) return false;
39399
+ const real = fs8.realpathSync(dir);
39400
+ const storeReal = fs8.realpathSync(storeDir());
39401
+ return real === storeReal || real.startsWith(storeReal + path11.sep);
39264
39402
  } catch {
39265
39403
  return false;
39266
39404
  }
@@ -39269,13 +39407,13 @@ function scanAgentSkills(agentId) {
39269
39407
  const agent = getAgent(agentId);
39270
39408
  if (!agent) throw new Error(`\u672A\u77E5 agent '${agentId}'`);
39271
39409
  const dir = agent.skillsDir(agentHome());
39272
- if (!fs7.existsSync(dir)) return [];
39410
+ if (!fs8.existsSync(dir)) return [];
39273
39411
  const out = [];
39274
- for (const e of fs7.readdirSync(dir, { withFileTypes: true })) {
39412
+ for (const e of fs8.readdirSync(dir, { withFileTypes: true })) {
39275
39413
  if (e.name.startsWith(".")) continue;
39276
39414
  if (!e.isDirectory() && !e.isSymbolicLink()) continue;
39277
- const p = path9.join(dir, e.name);
39278
- if (!fs7.existsSync(path9.join(p, "SKILL.md"))) continue;
39415
+ const p = path11.join(dir, e.name);
39416
+ if (!fs8.existsSync(path11.join(p, "SKILL.md"))) continue;
39279
39417
  out.push({ name: e.name, path: p });
39280
39418
  }
39281
39419
  return out;
@@ -39283,7 +39421,7 @@ function scanAgentSkills(agentId) {
39283
39421
  function scanAdoptable(agentId) {
39284
39422
  return scanAgentSkills(agentId).filter((s) => {
39285
39423
  try {
39286
- return !fs7.lstatSync(s.path).isSymbolicLink();
39424
+ return !fs8.lstatSync(s.path).isSymbolicLink();
39287
39425
  } catch {
39288
39426
  return false;
39289
39427
  }
@@ -39295,6 +39433,7 @@ function adoptSkills(opts = {}) {
39295
39433
  if (!getAgent(id)) throw new Error(`\u672A\u77E5 agent '${id}'`);
39296
39434
  }
39297
39435
  const config = loadConfig();
39436
+ const pickSet = opts.only ? new Set(opts.only.map((o) => `${o.agent}\0${o.name}`)) : null;
39298
39437
  const items = [];
39299
39438
  const importedNames = [];
39300
39439
  const pendingMoves = [];
@@ -39306,13 +39445,14 @@ function adoptSkills(opts = {}) {
39306
39445
  continue;
39307
39446
  }
39308
39447
  for (const skill of found) {
39448
+ if (pickSet && !pickSet.has(`${agentId}\0${skill.name}`)) continue;
39309
39449
  if (isManagedByStore(skill.path)) {
39310
39450
  items.push({ agent: agentId, name: skill.name, path: skill.path, status: "skipped-managed" });
39311
39451
  continue;
39312
39452
  }
39313
39453
  let isOwnSymlink = false;
39314
39454
  try {
39315
- isOwnSymlink = fs7.lstatSync(skill.path).isSymbolicLink();
39455
+ isOwnSymlink = fs8.lstatSync(skill.path).isSymbolicLink();
39316
39456
  } catch {
39317
39457
  }
39318
39458
  if (isOwnSymlink) {
@@ -39332,7 +39472,7 @@ function adoptSkills(opts = {}) {
39332
39472
  items.push({ agent: agentId, name: skill.name, path: skill.path, status: "skipped-invalid", detail: "\u76EE\u5F55\u540D\u4E0D\u5408\u6CD5" });
39333
39473
  continue;
39334
39474
  }
39335
- const existsInStore = !!config.skills[name] || fs7.existsSync(skillDir(name));
39475
+ const existsInStore = !!config.skills[name] || fs8.existsSync(skillDir(name));
39336
39476
  if (opts.dryRun) {
39337
39477
  items.push({
39338
39478
  agent: agentId,
@@ -39389,7 +39529,7 @@ function adoptSkills(opts = {}) {
39389
39529
  saveConfig(config);
39390
39530
  for (const mv of pendingMoves) {
39391
39531
  try {
39392
- fs7.rmSync(mv.path, { recursive: true, force: true });
39532
+ fs8.rmSync(mv.path, { recursive: true, force: true });
39393
39533
  enableSkill(mv.name, [mv.agentId]);
39394
39534
  items.push({
39395
39535
  agent: mv.agentId,
@@ -39423,94 +39563,23 @@ function adoptSkills(opts = {}) {
39423
39563
  return { items, imported, linked, exists, skipped };
39424
39564
  }
39425
39565
 
39426
- // src/core/lint.ts
39427
- import fs8 from "node:fs";
39428
- import path10 from "node:path";
39429
- var DANGEROUS_PATTERNS = [
39430
- [/\brm\s+(?:-[a-zA-Z]+\s+)*-[a-zA-Z]*[rf]/, "rm \u9012\u5F52/\u5F3A\u5236\u5220\u9664"],
39431
- [/\bcurl\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "curl \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39432
- [/\bwget\s+[^\n|]*\|\s*(?:ba|z)?sh\b/, "wget \u7BA1\u9053\u6267\u884C\u811A\u672C"],
39433
- [/\bsudo\b/, "sudo \u63D0\u6743"],
39434
- [/\bchmod\s+777\b/, "chmod 777 \u5F00\u653E\u5199\u6743\u9650"]
39435
- ];
39436
- var SCRIPT_EXT = /\.(sh|bash|zsh|py|js|mjs|cjs|ts|rb|pl)$/;
39437
- function lintSkill(dir) {
39438
- const issues = [];
39439
- if (!fs8.existsSync(path10.join(dir, "SKILL.md"))) {
39440
- return [{ level: "error", message: "\u7F3A\u5C11 SKILL.md" }];
39441
- }
39442
- const meta = readSkillMeta(dir);
39443
- if (!meta) {
39444
- issues.push({ level: "error", message: "SKILL.md frontmatter \u65E0\u6CD5\u89E3\u6790" });
39445
- } else {
39446
- if (!meta.name) {
39447
- issues.push({ level: "warn", message: "frontmatter \u7F3A\u5C11 name\uFF08\u5B89\u88C5\u65F6\u5C06\u56DE\u9000\u4E3A\u76EE\u5F55\u540D\uFF09" });
39448
- }
39449
- const desc = typeof meta.description === "string" ? meta.description : "";
39450
- if (!desc) {
39451
- issues.push({
39452
- level: "error",
39453
- message: "frontmatter \u7F3A\u5C11 description\u2014\u2014Agent \u4F9D\u8D56\u5B83\u5224\u65AD\u4F55\u65F6\u89E6\u53D1"
39454
- });
39455
- } else if (desc.length < 20) {
39456
- issues.push({ level: "warn", message: "description \u8FC7\u77ED\uFF08<20 \u5B57\u7B26\uFF09\uFF0C\u8DE8 Agent \u89E6\u53D1\u53EF\u80FD\u4E0D\u7A33\u5B9A" });
39457
- } else if (desc.length > 1024) {
39458
- issues.push({ level: "warn", message: "description \u8FC7\u957F\uFF08>1024 \u5B57\u7B26\uFF09" });
39459
- }
39460
- }
39461
- const scripts = [];
39462
- const walk = (d) => {
39463
- let entries = [];
39464
- try {
39465
- entries = fs8.readdirSync(d, { withFileTypes: true });
39466
- } catch {
39467
- return;
39468
- }
39469
- for (const e of entries) {
39470
- const p = path10.join(d, e.name);
39471
- if (e.isDirectory()) walk(p);
39472
- else if (e.isFile() && SCRIPT_EXT.test(e.name)) scripts.push(p);
39473
- }
39474
- };
39475
- walk(dir);
39476
- for (const s of scripts) {
39477
- let text = "";
39478
- try {
39479
- text = fs8.readFileSync(s, "utf8");
39480
- } catch {
39481
- continue;
39482
- }
39483
- for (const [re, label] of DANGEROUS_PATTERNS) {
39484
- if (re.test(text)) {
39485
- issues.push({ level: "warn", message: `${path10.relative(dir, s)} \u7591\u4F3C\u9AD8\u5371\u64CD\u4F5C\uFF1A${label}` });
39486
- }
39487
- }
39488
- }
39489
- return issues;
39490
- }
39491
- function lintSummary(issues) {
39492
- const errors = issues.filter((i) => i.level === "error").length;
39493
- const warns = issues.filter((i) => i.level === "warn").length;
39494
- if (errors) return `${errors} error / ${warns} warn`;
39495
- if (warns) return `${warns} warn`;
39496
- return "clean";
39497
- }
39498
-
39499
39566
  // src/core/update.ts
39500
39567
  import fs9 from "node:fs";
39501
39568
  import os3 from "node:os";
39502
- import path11 from "node:path";
39503
- import { execFileSync as execFileSync3 } from "node:child_process";
39569
+ import path12 from "node:path";
39570
+ import { execFile as execFile2 } from "node:child_process";
39571
+ import { promisify as promisify2 } from "node:util";
39572
+ var execFileP2 = promisify2(execFile2);
39504
39573
  function parseGitSource(source) {
39505
39574
  return source.startsWith("git:") ? source.slice(4) : null;
39506
39575
  }
39507
- function fetchRemote(repoSpec) {
39576
+ async function fetchRemote(repoSpec) {
39508
39577
  const [url, sub] = repoSpec.split("#");
39509
- const cloneDir = fs9.mkdtempSync(path11.join(os3.tmpdir(), "skillpot-update-"));
39578
+ const cloneDir = fs9.mkdtempSync(path12.join(os3.tmpdir(), "skillpot-update-"));
39510
39579
  try {
39511
- execFileSync3("git", ["clone", "--depth", "1", url, cloneDir], { stdio: "pipe" });
39512
- const contentDir = sub ? path11.join(cloneDir, sub) : cloneDir;
39513
- if (!fs9.existsSync(path11.join(contentDir, "SKILL.md"))) {
39580
+ await execFileP2("git", ["clone", "--depth", "1", url, cloneDir]);
39581
+ const contentDir = sub ? path12.join(cloneDir, sub) : cloneDir;
39582
+ if (!fs9.existsSync(path12.join(contentDir, "SKILL.md"))) {
39514
39583
  throw new Error(`\u8FDC\u7AEF ${sub ? `#${sub} ` : ""}\u4E2D\u6CA1\u6709 SKILL.md`);
39515
39584
  }
39516
39585
  return { checksum: dirChecksum(contentDir), cloneDir, sub };
@@ -39519,7 +39588,7 @@ function fetchRemote(repoSpec) {
39519
39588
  throw e;
39520
39589
  }
39521
39590
  }
39522
- function updateSkills(name, opts = {}) {
39591
+ async function updateSkills(name, opts = {}) {
39523
39592
  const config = loadConfig();
39524
39593
  const names = name ? [name] : Object.keys(config.skills).sort();
39525
39594
  const results = [];
@@ -39539,7 +39608,7 @@ function updateSkills(name, opts = {}) {
39539
39608
  continue;
39540
39609
  }
39541
39610
  try {
39542
- const fetched = fetchRemote(repoSpec);
39611
+ const fetched = await fetchRemote(repoSpec);
39543
39612
  try {
39544
39613
  if (fetched.checksum === entry.checksum) {
39545
39614
  results.push({ skill: n, status: "up-to-date" });
@@ -39549,9 +39618,9 @@ function updateSkills(name, opts = {}) {
39549
39618
  results.push({ skill: n, status: "outdated", detail: `\u8FDC\u7AEF ${fetched.checksum.slice(0, 15)}` });
39550
39619
  continue;
39551
39620
  }
39552
- const staging = fs9.mkdtempSync(path11.join(os3.tmpdir(), "skillpot-new-"));
39621
+ const staging = fs9.mkdtempSync(path12.join(os3.tmpdir(), "skillpot-new-"));
39553
39622
  try {
39554
- const srcDir = fetched.sub ? path11.join(fetched.cloneDir, fetched.sub) : fetched.cloneDir;
39623
+ const srcDir = fetched.sub ? path12.join(fetched.cloneDir, fetched.sub) : fetched.cloneDir;
39555
39624
  fs9.cpSync(srcDir, staging, { recursive: true });
39556
39625
  fs9.rmSync(skillDir(n), { recursive: true, force: true });
39557
39626
  fs9.cpSync(staging, skillDir(n), { recursive: true });
@@ -39573,10 +39642,36 @@ function updateSkills(name, opts = {}) {
39573
39642
  }
39574
39643
 
39575
39644
  // src/core/mcp-server.ts
39576
- import fs10 from "node:fs";
39577
- import path12 from "node:path";
39578
39645
  import readline from "node:readline";
39579
39646
 
39647
+ // src/core/skill-detail.ts
39648
+ import fs10 from "node:fs";
39649
+ import path13 from "node:path";
39650
+ function readSkillDetail(name) {
39651
+ const dir = skillDir(name);
39652
+ const mdPath = path13.join(dir, "SKILL.md");
39653
+ if (!fs10.existsSync(mdPath)) return null;
39654
+ const files = [];
39655
+ const walk = (d) => {
39656
+ for (const e of fs10.readdirSync(d, { withFileTypes: true })) {
39657
+ const p = path13.join(d, e.name);
39658
+ if (e.isDirectory()) {
39659
+ files.push(path13.relative(dir, p) + "/");
39660
+ walk(p);
39661
+ } else {
39662
+ files.push(path13.relative(dir, p));
39663
+ }
39664
+ }
39665
+ };
39666
+ walk(dir);
39667
+ return {
39668
+ name,
39669
+ meta: readSkillMeta(dir),
39670
+ files: files.sort(),
39671
+ skillMd: fs10.readFileSync(mdPath, "utf8")
39672
+ };
39673
+ }
39674
+
39580
39675
  // src/version.ts
39581
39676
  import { readFileSync } from "node:fs";
39582
39677
  var pkg = JSON.parse(
@@ -39666,27 +39761,14 @@ function handleMcpMessage(raw) {
39666
39761
  if (name === "skillpot_list") {
39667
39762
  text = fmtList(visibleSkills(args.agent ? String(args.agent) : void 0));
39668
39763
  } else if (name === "skillpot_read") {
39669
- const dir = skillDir(String(args.skill));
39670
- if (!fs10.existsSync(path12.join(dir, "SKILL.md"))) {
39764
+ const detail = readSkillDetail(String(args.skill));
39765
+ if (!detail || detail.skillMd === null) {
39671
39766
  return respond({
39672
39767
  content: [{ type: "text", text: `skill not found: ${args.skill}` }],
39673
39768
  isError: true
39674
39769
  });
39675
39770
  }
39676
- const files = [];
39677
- const walk = (d) => {
39678
- for (const e of fs10.readdirSync(d, { withFileTypes: true })) {
39679
- const p = path12.join(d, e.name);
39680
- if (e.isDirectory()) {
39681
- files.push(path12.relative(dir, p) + "/");
39682
- walk(p);
39683
- } else {
39684
- files.push(path12.relative(dir, p));
39685
- }
39686
- }
39687
- };
39688
- walk(dir);
39689
- text = fs10.readFileSync(path12.join(dir, "SKILL.md"), "utf8") + "\n\n--- files ---\n" + files.sort().map((f) => "- " + f).join("\n");
39771
+ text = detail.skillMd + "\n\n--- files ---\n" + detail.files.map((f) => "- " + f).join("\n");
39690
39772
  } else if (name === "skillpot_search") {
39691
39773
  const q = String(args.query ?? "").toLowerCase();
39692
39774
  const list = visibleSkills().filter(
@@ -39715,6 +39797,389 @@ function startMcpServer() {
39715
39797
  rl.on("close", () => process.exit(0));
39716
39798
  }
39717
39799
 
39800
+ // src/core/gui-server.ts
39801
+ import crypto2 from "node:crypto";
39802
+ import fs12 from "node:fs";
39803
+ import http from "node:http";
39804
+ import path15 from "node:path";
39805
+ import { spawn } from "node:child_process";
39806
+ import { fileURLToPath } from "node:url";
39807
+
39808
+ // src/tui/matrix.ts
39809
+ import fs11 from "node:fs";
39810
+ import path14 from "node:path";
39811
+ function deriveMatrix(agents) {
39812
+ const config = loadConfig();
39813
+ const skills = Object.keys(config.skills).sort();
39814
+ const list = agents ?? detectAll().map((r) => ({
39815
+ id: r.id,
39816
+ name: r.name,
39817
+ installed: r.installed,
39818
+ skillsDir: r.skillsDir
39819
+ }));
39820
+ const cells = {};
39821
+ for (const s of skills) {
39822
+ cells[s] = {};
39823
+ for (const a of list) {
39824
+ const target = path14.join(a.skillsDir, s);
39825
+ let actual = false;
39826
+ let managed = false;
39827
+ try {
39828
+ const st = fs11.lstatSync(target);
39829
+ actual = true;
39830
+ managed = st.isSymbolicLink() && fs11.realpathSync(target) === fs11.realpathSync(skillDir(s));
39831
+ } catch {
39832
+ }
39833
+ cells[s][a.id] = {
39834
+ enabled: config.skills[s].expose[a.id] === true,
39835
+ actual,
39836
+ managed
39837
+ };
39838
+ }
39839
+ }
39840
+ return { skills, agents: list, cells };
39841
+ }
39842
+
39843
+ // src/tui/cells.ts
39844
+ var import_picocolors = __toESM(require_picocolors());
39845
+ function cellGlyph(cs) {
39846
+ if (cs.enabled && cs.managed) return { ch: "\u2713", tone: "ok" };
39847
+ if (cs.enabled && !cs.actual) return { ch: "\u26A0", tone: "warn" };
39848
+ if (cs.enabled && cs.actual && !cs.managed) return { ch: "!", tone: "conflict" };
39849
+ if (!cs.enabled && cs.managed) return { ch: "!", tone: "warn" };
39850
+ if (!cs.enabled && cs.actual) return { ch: "\xD7", tone: "conflict" };
39851
+ return { ch: "\xB7", tone: "muted" };
39852
+ }
39853
+ function paintCell(glyph) {
39854
+ switch (glyph.tone) {
39855
+ case "ok":
39856
+ return import_picocolors.default.green(glyph.ch);
39857
+ case "warn":
39858
+ return import_picocolors.default.yellow(glyph.ch);
39859
+ case "conflict":
39860
+ return import_picocolors.default.red(glyph.ch);
39861
+ default:
39862
+ return import_picocolors.default.dim(glyph.ch);
39863
+ }
39864
+ }
39865
+ var TUI_LEGEND = "\u2713 \u5DF2\u5F00\u653E \u26A0 \u6F02\u79FB\uFF08\u58F0\u660E\u5F00\u653E\u4F46\u94FE\u63A5\u7F3A\u5931\uFF09 ! \u94FE\u63A5\u72B6\u6001\u5F02\u5E38 \xD7 \u5916\u90E8\u540C\u540D\u5360\u7528 \xB7 \u672A\u5F00\u653E";
39866
+ function toggleCell(skill, agentId) {
39867
+ const config = loadConfig();
39868
+ const entry = config.skills[skill];
39869
+ if (!entry) return { ok: false, message: `skill \u4E0D\u5B58\u5728\uFF1A${skill}` };
39870
+ const wantEnable = entry.expose[agentId] !== true;
39871
+ try {
39872
+ const res = wantEnable ? enableSkill(skill, [agentId]) : disableSkill(skill, [agentId]);
39873
+ if (res.skipped.length) {
39874
+ return { ok: false, message: `${agentId}: ${res.skipped[0].reason}` };
39875
+ }
39876
+ return {
39877
+ ok: true,
39878
+ message: `${skill} \u5DF2${wantEnable ? "\u5F00\u653E" : "\u5173\u95ED"}\u7ED9 ${agentId}\uFF08\u91CD\u542F\u793A\u4F8B\u4F1A\u8BDD\u540E\u751F\u6548\uFF09`
39879
+ };
39880
+ } catch (e) {
39881
+ return { ok: false, message: e instanceof Error ? e.message : String(e) };
39882
+ }
39883
+ }
39884
+ var colWidth = (a) => Math.max(a.name.length, 3) + 2;
39885
+ function renderStatic(m) {
39886
+ if (!m.skills.length) {
39887
+ return "\u4E2D\u592E\u4ED3\u5E93\u4E3A\u7A7A\u3002\u8FD0\u884C skillpot adopt \u6536\u7F16\u5404 Agent \u5DF2\u6709 skill\uFF08--move \u4E3A\u79FB\u52A8\u6A21\u5F0F\uFF09\uFF0C\u6216 skillpot add \u5B89\u88C5\u3002";
39888
+ }
39889
+ const nameW = Math.max("Skill".length, ...m.skills.map((s) => s.length), 5) + 2;
39890
+ const pad2 = (s, w) => s.padEnd(w);
39891
+ const lines = [];
39892
+ lines.push(
39893
+ import_picocolors.default.bold(pad2("Skill", nameW)) + m.agents.map((a) => import_picocolors.default.bold(pad2(a.name, colWidth(a)))).join("")
39894
+ );
39895
+ for (const s of m.skills) {
39896
+ lines.push(
39897
+ pad2(s, nameW) + m.agents.map((a) => pad2(paintCell(cellGlyph(m.cells[s][a.id])), colWidth(a))).join("")
39898
+ );
39899
+ }
39900
+ lines.push("");
39901
+ lines.push(import_picocolors.default.dim(TUI_LEGEND));
39902
+ return lines.join("\n");
39903
+ }
39904
+
39905
+ // src/core/gui-server.ts
39906
+ var agentCache = null;
39907
+ var AGENT_CACHE_TTL_MS = 6e4;
39908
+ function cachedAgents() {
39909
+ if (agentCache && Date.now() - agentCache.at < AGENT_CACHE_TTL_MS) return agentCache.agents;
39910
+ agentCache = { at: Date.now(), agents: deriveMatrix().agents };
39911
+ return agentCache.agents;
39912
+ }
39913
+ function lintAll() {
39914
+ const out = {};
39915
+ for (const name of storeSkillNames()) {
39916
+ out[name] = lintSkill(skillDir(name));
39917
+ }
39918
+ return out;
39919
+ }
39920
+ async function handleApiRequest(method, pathname, query, body, expectedToken, gotToken) {
39921
+ if (!pathname.startsWith("/api/")) return null;
39922
+ if (method === "POST" && gotToken !== expectedToken) {
39923
+ return { status: 403, body: { error: "token \u7F3A\u5931\u6216\u4E0D\u5339\u914D\uFF0C\u8BF7\u4ECE\u7EC8\u7AEF\u8F93\u51FA\u7684\u5730\u5740\u6253\u5F00 GUI" } };
39924
+ }
39925
+ try {
39926
+ if (method === "GET" && pathname === "/api/state") {
39927
+ return {
39928
+ status: 200,
39929
+ body: {
39930
+ version: VERSION,
39931
+ skills: loadConfig().skills,
39932
+ matrix: deriveMatrix(cachedAgents())
39933
+ }
39934
+ };
39935
+ }
39936
+ if (method === "POST" && pathname === "/api/toggle") {
39937
+ const b = body ?? {};
39938
+ if (typeof b.skill !== "string" || typeof b.agent !== "string") {
39939
+ return { status: 400, body: { error: "\u9700\u8981 skill \u4E0E agent \u5B57\u7B26\u4E32\u5B57\u6BB5" } };
39940
+ }
39941
+ return { status: 200, body: toggleCell(b.skill, b.agent) };
39942
+ }
39943
+ if (method === "GET" && pathname === "/api/adopt") {
39944
+ const config = loadConfig();
39945
+ const agents = cachedAgents().filter((a) => a.installed).map((a) => ({
39946
+ id: a.id,
39947
+ name: a.name,
39948
+ skills: scanAdoptable(a.id).map((s) => {
39949
+ let valid = true;
39950
+ let inStore = false;
39951
+ try {
39952
+ const n = sanitizeSkillName(s.name);
39953
+ inStore = !!config.skills[n] || fs12.existsSync(skillDir(n));
39954
+ } catch {
39955
+ valid = false;
39956
+ }
39957
+ return { name: s.name, path: s.path, valid, inStore };
39958
+ })
39959
+ }));
39960
+ return { status: 200, body: { agents } };
39961
+ }
39962
+ if (method === "POST" && pathname === "/api/adopt") {
39963
+ const b = body ?? {};
39964
+ const picks = (b.picks ?? []).filter(
39965
+ (p) => typeof p?.agent === "string" && typeof p?.name === "string"
39966
+ );
39967
+ if (!picks.length) return { status: 400, body: { error: "\u6CA1\u6709\u52FE\u9009\u4EFB\u4F55\u53EF\u6536\u7F16\u9879" } };
39968
+ const report = adoptSkills({
39969
+ from: [...new Set(picks.map((p) => p.agent))],
39970
+ only: picks,
39971
+ move: b.move === true,
39972
+ enableFor: Array.isArray(b.enableFor) ? b.enableFor.filter((x) => typeof x === "string") : void 0
39973
+ });
39974
+ return { status: 200, body: report };
39975
+ }
39976
+ if (method === "POST" && pathname === "/api/add") {
39977
+ const b = body ?? {};
39978
+ if (typeof b.source !== "string") {
39979
+ return { status: 400, body: { error: "\u9700\u8981 source \u5B57\u6BB5\uFF08\u672C\u5730\u76EE\u5F55\u6216 git URL\uFF09" } };
39980
+ }
39981
+ const result = await addSkill(b.source, {
39982
+ name: typeof b.name === "string" && b.name.trim() ? b.name.trim() : void 0,
39983
+ for: Array.isArray(b.for) ? b.for.filter((x) => typeof x === "string") : void 0
39984
+ });
39985
+ return { status: 200, body: result };
39986
+ }
39987
+ if (method === "GET" && pathname.startsWith("/api/skill/")) {
39988
+ const name = decodeURIComponent(pathname.slice("/api/skill/".length));
39989
+ const detail = readSkillDetail(name);
39990
+ if (!detail) return { status: 404, body: { error: `skill \u4E0D\u5B58\u5728\uFF1A${name}` } };
39991
+ return { status: 200, body: { ...detail, lint: lintSkill(skillDir(name)) } };
39992
+ }
39993
+ if (method === "POST" && pathname === "/api/update") {
39994
+ const b = body ?? {};
39995
+ const results = await updateSkills(
39996
+ typeof b.skill === "string" && b.skill ? b.skill : void 0,
39997
+ { check: b.check === true }
39998
+ );
39999
+ return { status: 200, body: { results } };
40000
+ }
40001
+ if (method === "POST" && pathname === "/api/remove") {
40002
+ const b = body ?? {};
40003
+ if (typeof b.skill !== "string" || !b.skill) {
40004
+ return { status: 400, body: { error: "\u9700\u8981 skill \u5B57\u6BB5" } };
40005
+ }
40006
+ uninstallSkill(b.skill);
40007
+ return { status: 200, body: { ok: true, message: `\u5DF2\u5378\u8F7D ${b.skill}` } };
40008
+ }
40009
+ if (method === "GET" && pathname === "/api/doctor") {
40010
+ return { status: 200, body: { issues: runDoctor() } };
40011
+ }
40012
+ if (method === "POST" && pathname === "/api/doctor/fix") {
40013
+ return { status: 200, body: fixDoctor() };
40014
+ }
40015
+ if (method === "GET" && pathname === "/api/lint") {
40016
+ const skill = query.get("skill");
40017
+ if (skill) {
40018
+ return { status: 200, body: { [skill]: lintSkill(skillDir(skill)) } };
40019
+ }
40020
+ return { status: 200, body: lintAll() };
40021
+ }
40022
+ return { status: 404, body: { error: `\u672A\u77E5 API:${method} ${pathname}` } };
40023
+ } catch (e) {
40024
+ return {
40025
+ status: 500,
40026
+ body: { error: e instanceof Error ? e.message : String(e) }
40027
+ };
40028
+ }
40029
+ }
40030
+ var MIME = {
40031
+ ".html": "text/html; charset=utf-8",
40032
+ ".js": "text/javascript; charset=utf-8",
40033
+ ".css": "text/css; charset=utf-8",
40034
+ ".json": "application/json; charset=utf-8",
40035
+ ".svg": "image/svg+xml",
40036
+ ".png": "image/png",
40037
+ ".ico": "image/x-icon",
40038
+ ".woff2": "font/woff2",
40039
+ ".map": "application/json"
40040
+ };
40041
+ function readBody(req) {
40042
+ return new Promise((resolve) => {
40043
+ const chunks = [];
40044
+ req.on("data", (c) => chunks.push(c));
40045
+ req.on("end", () => {
40046
+ if (!chunks.length) return resolve(null);
40047
+ try {
40048
+ resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
40049
+ } catch {
40050
+ resolve(null);
40051
+ }
40052
+ });
40053
+ req.on("error", () => resolve(null));
40054
+ });
40055
+ }
40056
+ function openBrowser(url) {
40057
+ try {
40058
+ if (process.platform === "darwin") {
40059
+ spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
40060
+ } else if (process.platform === "win32") {
40061
+ spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" }).unref();
40062
+ } else {
40063
+ spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
40064
+ }
40065
+ } catch {
40066
+ }
40067
+ }
40068
+ function guiDistDir() {
40069
+ const candidates = [
40070
+ path15.resolve(fileURLToPath(new URL("./gui/", import.meta.url))),
40071
+ path15.resolve(fileURLToPath(new URL("../../dist/gui/", import.meta.url)))
40072
+ ];
40073
+ for (const dir of candidates) {
40074
+ if (fs12.existsSync(path15.join(dir, "index.html"))) return dir;
40075
+ }
40076
+ return candidates[0];
40077
+ }
40078
+ function serveStatic(pathname, res) {
40079
+ const root = guiDistDir();
40080
+ if (!fs12.existsSync(path15.join(root, "index.html"))) {
40081
+ res.writeHead(503, { "content-type": "text/plain; charset=utf-8" });
40082
+ 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");
40083
+ return;
40084
+ }
40085
+ const rel = pathname === "/" ? "index.html" : pathname.replace(/^\/+/, "");
40086
+ let file = path15.resolve(root, rel);
40087
+ if (!file.startsWith(root + path15.sep) && file !== root) {
40088
+ res.writeHead(403, { "content-type": "text/plain; charset=utf-8" });
40089
+ res.end("forbidden");
40090
+ return;
40091
+ }
40092
+ if (!fs12.existsSync(file) || fs12.statSync(file).isDirectory()) {
40093
+ file = path15.join(root, "index.html");
40094
+ }
40095
+ const ext = path15.extname(file).toLowerCase();
40096
+ res.writeHead(200, {
40097
+ "content-type": MIME[ext] ?? "application/octet-stream",
40098
+ "cache-control": rel.startsWith("assets/") ? "public, max-age=31536000, immutable" : "no-store"
40099
+ });
40100
+ fs12.createReadStream(file).pipe(res);
40101
+ }
40102
+ async function startGuiServer(opts = {}) {
40103
+ const token = crypto2.randomBytes(16).toString("hex");
40104
+ const host = opts.host ?? "127.0.0.1";
40105
+ const readAuthRequired = !["127.0.0.1", "localhost", "::1"].includes(host);
40106
+ const sseClients = /* @__PURE__ */ new Set();
40107
+ const broadcastChange = () => {
40108
+ for (const res of sseClients) res.write('data: {"type":"change"}\n\n');
40109
+ };
40110
+ const server = http.createServer(async (req, res) => {
40111
+ try {
40112
+ const url2 = new URL(req.url ?? "/", "http://127.0.0.1");
40113
+ if (url2.pathname.startsWith("/api/")) {
40114
+ const rawToken = req.headers["x-skillpot-token"] ?? url2.searchParams.get("token") ?? void 0;
40115
+ const gotToken = Array.isArray(rawToken) ? rawToken[0] : rawToken;
40116
+ if (readAuthRequired && gotToken !== token) {
40117
+ res.writeHead(403, { "content-type": "application/json; charset=utf-8" });
40118
+ res.end(JSON.stringify({ error: "token \u7F3A\u5931\u6216\u4E0D\u5339\u914D" }));
40119
+ return;
40120
+ }
40121
+ if (url2.pathname === "/api/events" && req.method === "GET") {
40122
+ res.writeHead(200, {
40123
+ "content-type": "text/event-stream",
40124
+ "cache-control": "no-store",
40125
+ connection: "keep-alive"
40126
+ });
40127
+ res.write(": connected\n\n");
40128
+ sseClients.add(res);
40129
+ const hb = setInterval(() => res.write(": hb\n\n"), 25e3);
40130
+ req.on("close", () => {
40131
+ clearInterval(hb);
40132
+ sseClients.delete(res);
40133
+ });
40134
+ return;
40135
+ }
40136
+ const body = req.method === "POST" ? await readBody(req) : null;
40137
+ const out = await handleApiRequest(
40138
+ req.method ?? "GET",
40139
+ url2.pathname,
40140
+ url2.searchParams,
40141
+ body,
40142
+ token,
40143
+ gotToken
40144
+ );
40145
+ if (!out) {
40146
+ res.writeHead(404, { "content-type": "application/json; charset=utf-8" });
40147
+ res.end(JSON.stringify({ error: "not found" }));
40148
+ return;
40149
+ }
40150
+ if (req.method === "POST" && out.status === 200) broadcastChange();
40151
+ res.writeHead(out.status, {
40152
+ "content-type": "application/json; charset=utf-8",
40153
+ "cache-control": "no-store"
40154
+ });
40155
+ res.end(JSON.stringify(out.body));
40156
+ return;
40157
+ }
40158
+ serveStatic(url2.pathname, res);
40159
+ } catch (e) {
40160
+ res.writeHead(500, { "content-type": "application/json; charset=utf-8" });
40161
+ res.end(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }));
40162
+ }
40163
+ });
40164
+ await new Promise((resolve, reject) => {
40165
+ server.once("error", reject);
40166
+ server.listen(opts.port ?? 0, host, () => resolve());
40167
+ });
40168
+ const addr = server.address();
40169
+ const port = typeof addr === "object" && addr ? addr.port : opts.port ?? 0;
40170
+ const url = `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}/?token=${token}`;
40171
+ if (opts.open !== false) openBrowser(url);
40172
+ return {
40173
+ url,
40174
+ port,
40175
+ token,
40176
+ close: () => new Promise((resolve) => {
40177
+ server.close(() => resolve());
40178
+ server.closeAllConnections();
40179
+ })
40180
+ };
40181
+ }
40182
+
39718
40183
  // src/tui/index.ts
39719
40184
  var import_react23 = __toESM(require_react());
39720
40185
 
@@ -44316,7 +44781,7 @@ var FocusContext_default = FocusContext;
44316
44781
  // node_modules/ink/build/components/ErrorOverview.js
44317
44782
  var import_react8 = __toESM(require_react(), 1);
44318
44783
  var import_stack_utils = __toESM(require_stack_utils(), 1);
44319
- import * as fs11 from "node:fs";
44784
+ import * as fs13 from "node:fs";
44320
44785
  import { cwd } from "node:process";
44321
44786
 
44322
44787
  // node_modules/convert-to-spaces/dist/index.js
@@ -44406,8 +44871,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
44406
44871
  }
44407
44872
 
44408
44873
  // node_modules/ink/build/components/ErrorOverview.js
44409
- var cleanupPath = (path15) => {
44410
- return path15?.replace(`file://${cwd()}/`, "");
44874
+ var cleanupPath = (path16) => {
44875
+ return path16?.replace(`file://${cwd()}/`, "");
44411
44876
  };
44412
44877
  var stackUtils = new import_stack_utils.default({
44413
44878
  cwd: cwd(),
@@ -44419,8 +44884,8 @@ function ErrorOverview({ error }) {
44419
44884
  const filePath = cleanupPath(origin?.file);
44420
44885
  let excerpt;
44421
44886
  let lineWidth = 0;
44422
- if (filePath && origin?.line && fs11.existsSync(filePath)) {
44423
- const sourceCode = fs11.readFileSync(filePath, "utf8");
44887
+ if (filePath && origin?.line && fs13.existsSync(filePath)) {
44888
+ const sourceCode = fs13.readFileSync(filePath, "utf8");
44424
44889
  excerpt = dist_default3(sourceCode, origin.line);
44425
44890
  if (excerpt) {
44426
44891
  for (const { line } of excerpt) {
@@ -45330,103 +45795,6 @@ var import_react20 = __toESM(require_react(), 1);
45330
45795
  // node_modules/ink/build/hooks/use-focus-manager.js
45331
45796
  var import_react21 = __toESM(require_react(), 1);
45332
45797
 
45333
- // src/tui/matrix.ts
45334
- import fs12 from "node:fs";
45335
- import path13 from "node:path";
45336
- function deriveMatrix() {
45337
- const config = loadConfig();
45338
- const skills = Object.keys(config.skills).sort();
45339
- const agents = detectAll().map((r) => ({
45340
- id: r.id,
45341
- name: r.name,
45342
- installed: r.installed,
45343
- skillsDir: r.skillsDir
45344
- }));
45345
- const cells = {};
45346
- for (const s of skills) {
45347
- cells[s] = {};
45348
- for (const a of agents) {
45349
- const target = path13.join(a.skillsDir, s);
45350
- let actual = false;
45351
- let managed = false;
45352
- try {
45353
- const st = fs12.lstatSync(target);
45354
- actual = true;
45355
- managed = st.isSymbolicLink() && fs12.realpathSync(target) === fs12.realpathSync(skillDir(s));
45356
- } catch {
45357
- }
45358
- cells[s][a.id] = {
45359
- enabled: config.skills[s].expose[a.id] === true,
45360
- actual,
45361
- managed
45362
- };
45363
- }
45364
- }
45365
- return { skills, agents, cells };
45366
- }
45367
-
45368
- // src/tui/cells.ts
45369
- var import_picocolors = __toESM(require_picocolors());
45370
- function cellGlyph(cs) {
45371
- if (cs.enabled && cs.managed) return { ch: "\u2713", tone: "ok" };
45372
- if (cs.enabled && !cs.actual) return { ch: "\u26A0", tone: "warn" };
45373
- if (cs.enabled && cs.actual && !cs.managed) return { ch: "!", tone: "conflict" };
45374
- if (!cs.enabled && cs.managed) return { ch: "!", tone: "warn" };
45375
- if (!cs.enabled && cs.actual) return { ch: "\xD7", tone: "conflict" };
45376
- return { ch: "\xB7", tone: "muted" };
45377
- }
45378
- function paintCell(glyph) {
45379
- switch (glyph.tone) {
45380
- case "ok":
45381
- return import_picocolors.default.green(glyph.ch);
45382
- case "warn":
45383
- return import_picocolors.default.yellow(glyph.ch);
45384
- case "conflict":
45385
- return import_picocolors.default.red(glyph.ch);
45386
- default:
45387
- return import_picocolors.default.dim(glyph.ch);
45388
- }
45389
- }
45390
- var TUI_LEGEND = "\u2713 \u5DF2\u5F00\u653E \u26A0 \u6F02\u79FB\uFF08\u58F0\u660E\u5F00\u653E\u4F46\u94FE\u63A5\u7F3A\u5931\uFF09 ! \u94FE\u63A5\u72B6\u6001\u5F02\u5E38 \xD7 \u5916\u90E8\u540C\u540D\u5360\u7528 \xB7 \u672A\u5F00\u653E";
45391
- function toggleCell(skill, agentId) {
45392
- const config = loadConfig();
45393
- const entry = config.skills[skill];
45394
- if (!entry) return { ok: false, message: `skill \u4E0D\u5B58\u5728\uFF1A${skill}` };
45395
- const wantEnable = entry.expose[agentId] !== true;
45396
- try {
45397
- const res = wantEnable ? enableSkill(skill, [agentId]) : disableSkill(skill, [agentId]);
45398
- if (res.skipped.length) {
45399
- return { ok: false, message: `${agentId}: ${res.skipped[0].reason}` };
45400
- }
45401
- return {
45402
- ok: true,
45403
- message: `${skill} \u5DF2${wantEnable ? "\u5F00\u653E" : "\u5173\u95ED"}\u7ED9 ${agentId}\uFF08\u91CD\u542F\u793A\u4F8B\u4F1A\u8BDD\u540E\u751F\u6548\uFF09`
45404
- };
45405
- } catch (e) {
45406
- return { ok: false, message: e instanceof Error ? e.message : String(e) };
45407
- }
45408
- }
45409
- var colWidth = (a) => Math.max(a.name.length, 3) + 2;
45410
- function renderStatic(m) {
45411
- if (!m.skills.length) {
45412
- return "\u4E2D\u592E\u4ED3\u5E93\u4E3A\u7A7A\u3002\u8FD0\u884C skillpot adopt \u6536\u7F16\u5404 Agent \u5DF2\u6709 skill\uFF08--move \u4E3A\u79FB\u52A8\u6A21\u5F0F\uFF09\uFF0C\u6216 skillpot add \u5B89\u88C5\u3002";
45413
- }
45414
- const nameW = Math.max("Skill".length, ...m.skills.map((s) => s.length), 5) + 2;
45415
- const pad2 = (s, w) => s.padEnd(w);
45416
- const lines = [];
45417
- lines.push(
45418
- import_picocolors.default.bold(pad2("Skill", nameW)) + m.agents.map((a) => import_picocolors.default.bold(pad2(a.name, colWidth(a)))).join("")
45419
- );
45420
- for (const s of m.skills) {
45421
- lines.push(
45422
- pad2(s, nameW) + m.agents.map((a) => pad2(paintCell(cellGlyph(m.cells[s][a.id])), colWidth(a))).join("")
45423
- );
45424
- }
45425
- lines.push("");
45426
- lines.push(import_picocolors.default.dim(TUI_LEGEND));
45427
- return lines.join("\n");
45428
- }
45429
-
45430
45798
  // src/tui/App.tsx
45431
45799
  var import_react22 = __toESM(require_react());
45432
45800
  var import_jsx_runtime = __toESM(require_jsx_runtime());
@@ -45657,33 +46025,27 @@ program2.command("agents").description("\u68C0\u6D4B\u672C\u673A\u5B89\u88C5\u76
45657
46025
  program2.command("add <source>").description(
45658
46026
  "\u5B89\u88C5 skill \u5230\u4E2D\u592E\u4ED3\u5E93\uFF08\u672C\u5730\u76EE\u5F55\u6216 git URL\uFF1Bgit \u652F\u6301 repo#subdir\u3002\u9ED8\u8BA4\u4E0D\u5BF9\u4EFB\u4F55 Agent \u5F00\u653E\uFF09"
45659
46027
  ).option("-n, --name <name>", "\u6307\u5B9A skill \u540D\uFF08\u9ED8\u8BA4\u53D6 frontmatter name \u6216\u76EE\u5F55\u540D\uFF09").action(
45660
- run((source, opts) => {
45661
- initStore();
45662
- const isGit = /^https?:\/\//.test(source) || /^git@/.test(source) || /^file:\/\//.test(source) || /\.git$/.test(source);
45663
- const res = isGit ? installFromGit(source, opts.name) : installFromLocal(source, opts.name);
45664
- const config = loadConfig();
45665
- config.skills[res.name] = {
45666
- source: isGit ? `git:${source}` : `local:${path14.resolve(source)}`,
45667
- checksum: res.checksum,
45668
- installed_at: (/* @__PURE__ */ new Date()).toISOString(),
45669
- expose: {}
45670
- };
45671
- saveConfig(config);
46028
+ run(async (source, opts) => {
46029
+ const res = await addSkill(source, { name: opts.name });
45672
46030
  console.log(import_picocolors2.default.green(`\u2714 \u5DF2\u5B89\u88C5 ${res.name}`));
45673
46031
  if (res.description) console.log(import_picocolors2.default.dim(` ${res.description.slice(0, 120)}`));
45674
- const issues = lintSkill(skillDir(res.name));
45675
- if (issues.length) {
45676
- for (const i of issues) {
45677
- const tag = i.level === "error" ? import_picocolors2.default.red("error") : import_picocolors2.default.yellow("warn ");
45678
- console.log(` ${tag} ${i.message}`);
45679
- }
45680
- console.log(import_picocolors2.default.dim(` lint: ${lintSummary(issues)}\uFF08skillpot lint ${res.name} \u67E5\u770B\u8BE6\u60C5\uFF09`));
46032
+ for (const i of res.lint) {
46033
+ const tag = i.level === "error" ? import_picocolors2.default.red("error") : import_picocolors2.default.yellow("warn ");
46034
+ console.log(` ${tag} ${i.message}`);
46035
+ }
46036
+ if (res.lint.length) {
46037
+ console.log(import_picocolors2.default.dim(` lint: ${lintSummary(res.lint)}\uFF08skillpot lint ${res.name} \u67E5\u770B\u8BE6\u60C5\uFF09`));
46038
+ }
46039
+ if (res.enabled.length) {
46040
+ console.log(import_picocolors2.default.green(`\u5DF2\u5F00\u653E\uFF1A${res.enabled.join(", ")}`));
46041
+ for (const s of res.skipped) console.log(import_picocolors2.default.yellow(`\u26A0 ${s.agent}: ${s.reason}`));
46042
+ } else {
46043
+ console.log(
46044
+ `\u9ED8\u8BA4\u672A\u5BF9\u4EFB\u4F55 Agent \u5F00\u653E\u3002\u6267\u884C ${import_picocolors2.default.cyan(
46045
+ `skillpot enable ${res.name} --for <agents>`
46046
+ )}\uFF08agents: ${AGENTS.map((a) => a.id).join(",")} \u6216 all\uFF09`
46047
+ );
45681
46048
  }
45682
- console.log(
45683
- `\u9ED8\u8BA4\u672A\u5BF9\u4EFB\u4F55 Agent \u5F00\u653E\u3002\u6267\u884C ${import_picocolors2.default.cyan(
45684
- `skillpot enable ${res.name} --for <agents>`
45685
- )}\uFF08agents: ${AGENTS.map((a) => a.id).join(",")} \u6216 all\uFF09`
45686
- );
45687
46049
  })
45688
46050
  );
45689
46051
  program2.command("list").description("\u5217\u51FA\u4E2D\u592E\u4ED3\u5E93\u4E2D\u7684 skill\u53CA\u5F00\u653E\u72B6\u6001").option("-a, --agent <id>", "\u53EA\u770B\u67D0\u4E2A Agent \u7684\u53EF\u89C1\u5217\u8868").action(
@@ -45734,12 +46096,7 @@ function reportSync(res, verb) {
45734
46096
  }
45735
46097
  program2.command("remove <skill>").description("\u4ECE\u4E2D\u592E\u4ED3\u5E93\u5378\u8F7D skill\uFF08\u64A4\u4E0B\u6240\u6709 Agent \u7684\u94FE\u63A5\u5E76\u5220\u9664\u6587\u4EF6\uFF09").action(
45736
46098
  run((skill) => {
45737
- const config = loadConfig();
45738
- if (!config.skills[skill]) throw new Error(`config \u4E2D\u6CA1\u6709 skill '${skill}'`);
45739
- disableSkill(skill, AGENTS.map((a) => a.id));
45740
- removeSkillDir(skill);
45741
- delete config.skills[skill];
45742
- saveConfig(config);
46099
+ uninstallSkill(skill);
45743
46100
  console.log(import_picocolors2.default.green(`\u2714 \u5DF2\u5378\u8F7D ${skill}`));
45744
46101
  })
45745
46102
  );
@@ -45838,8 +46195,8 @@ program2.command("lint [skill]").description("\u5B89\u5168\u4E0E\u8D28\u91CF\u68
45838
46195
  })
45839
46196
  );
45840
46197
  program2.command("update [skill]").description("\u68C0\u67E5\u5E76\u5E94\u7528 git \u6765\u6E90 skill \u7684\u66F4\u65B0\uFF08--check \u53EA\u62A5\u544A\uFF1Blocal \u6765\u6E90\u4F1A\u8DF3\u8FC7\uFF09").option("--check", "\u53EA\u68C0\u67E5\u8FDC\u7AEF\u662F\u5426\u6709\u66F4\u65B0\uFF0C\u4E0D\u5E94\u7528").action(
45841
- run((skill, opts) => {
45842
- const results = updateSkills(skill, { check: opts.check });
46198
+ run(async (skill, opts) => {
46199
+ const results = await updateSkills(skill, { check: opts.check });
45843
46200
  const label = {
45844
46201
  "up-to-date": "\uFF1D \u5DF2\u662F\u6700\u65B0",
45845
46202
  outdated: "\u2191 \u6709\u66F4\u65B0",
@@ -45865,6 +46222,30 @@ program2.command("tui").description("\u4EA4\u4E92\u5F0F\u5F00\u5173\u77E9\u9635\
45865
46222
  runTui({ once: opts.once });
45866
46223
  })
45867
46224
  );
46225
+ program2.command("gui").description("\u542F\u52A8\u672C\u5730 Web \u63A7\u5236\u53F0\uFF08\u9ED8\u8BA4\u4EC5\u76D1\u542C 127.0.0.1\uFF09\uFF1A\u77E9\u9635\u3001\u6536\u7F16\u3001\u5B89\u88C5\u3001\u7EF4\u62A4\u4E0E\u4F53\u68C0").option("--port <port>", "\u6307\u5B9A\u76D1\u542C\u7AEF\u53E3\uFF08\u9ED8\u8BA4\u968F\u673A\u7A7A\u95F2\u7AEF\u53E3\uFF09").option(
46226
+ "--host <host>",
46227
+ "\u76D1\u542C\u5730\u5740\uFF08\u9ED8\u8BA4 127.0.0.1\uFF1B\u8BBE\u4E3A 0.0.0.0 \u5141\u8BB8\u5C40\u57DF\u7F51\u8BBF\u95EE\uFF0C\u5C4A\u65F6\u6240\u6709\u8BF7\u6C42\u90FD\u8981\u6C42 token\uFF09"
46228
+ ).option("--no-open", "\u4E0D\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u4EC5\u6253\u5370\u8BBF\u95EE\u5730\u5740").action(
46229
+ run(async (opts) => {
46230
+ const port = opts.port ? Number(opts.port) : void 0;
46231
+ if (opts.port && (!Number.isInteger(port) || port <= 0 || port > 65535)) {
46232
+ throw new Error(`\u975E\u6CD5\u7AEF\u53E3\uFF1A${opts.port}`);
46233
+ }
46234
+ const { url } = await startGuiServer({
46235
+ port,
46236
+ host: opts.host,
46237
+ open: opts.open
46238
+ });
46239
+ console.log(import_picocolors2.default.bold(`\u2713 SkillPot GUI \u5DF2\u542F\u52A8\uFF1A${import_picocolors2.default.cyan(url)}`));
46240
+ if (opts.host && !["127.0.0.1", "localhost", "::1"].includes(opts.host)) {
46241
+ console.log(
46242
+ import_picocolors2.default.yellow("\u26A0 \u5DF2\u7ED1\u5B9A\u975E\u56DE\u73AF\u5730\u5740\uFF1A\u540C\u7F51\u6BB5\u8BBE\u5907\u53EF\u8BBF\u95EE\uFF0C\u6240\u6709\u8BF7\u6C42\uFF08\u542B\u8BFB\u53D6\uFF09\u5747\u8981\u6C42 token")
46243
+ );
46244
+ }
46245
+ if (opts.open === false) console.log(import_picocolors2.default.dim("\uFF08\u672A\u81EA\u52A8\u6253\u5F00\u6D4F\u89C8\u5668\uFF0C\u8BF7\u624B\u52A8\u8BBF\u95EE\u4E0A\u65B9\u5730\u5740\uFF09"));
46246
+ console.log(import_picocolors2.default.dim("\u6309 Ctrl+C \u9000\u51FA"));
46247
+ })
46248
+ );
45868
46249
  for (const cmd of program2.commands) cmd.allowExcessArguments(false);
45869
46250
  await program2.parseAsync(process.argv);
45870
46251
  /*! Bundled license information: