@dyml/skill-manager 1.0.3 → 1.0.5

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.
@@ -26486,7 +26486,7 @@ async function getSymlinkInfo(skillPath) {
26486
26486
  }
26487
26487
  return { isSymlink: false, target: null };
26488
26488
  }
26489
- async function scanSkill(skillPath, location) {
26489
+ async function scanSkill(skillPath, location, source) {
26490
26490
  try {
26491
26491
  const exists = await import_fs_extra.default.pathExists(skillPath);
26492
26492
  if (!exists) {
@@ -26508,6 +26508,7 @@ async function scanSkill(skillPath, location) {
26508
26508
  description: frontmatter.description || "",
26509
26509
  version: meta?.version || null,
26510
26510
  location,
26511
+ source,
26511
26512
  path: skillPath,
26512
26513
  isSymlink,
26513
26514
  symlinkTarget: target,
@@ -26519,7 +26520,7 @@ async function scanSkill(skillPath, location) {
26519
26520
  return null;
26520
26521
  }
26521
26522
  }
26522
- async function scanSkillsDir(dirPath, location) {
26523
+ async function scanSkillsDir(dirPath, location, source) {
26523
26524
  const skills = [];
26524
26525
  try {
26525
26526
  const exists = await import_fs_extra.default.pathExists(dirPath);
@@ -26530,7 +26531,7 @@ async function scanSkillsDir(dirPath, location) {
26530
26531
  for (const entry of entries) {
26531
26532
  if (entry.isDirectory() || entry.isSymbolicLink()) {
26532
26533
  const skillPath = path2.join(dirPath, entry.name);
26533
- const skill = await scanSkill(skillPath, location);
26534
+ const skill = await scanSkill(skillPath, location, source);
26534
26535
  if (skill) {
26535
26536
  skills.push(skill);
26536
26537
  }
@@ -26569,7 +26570,7 @@ async function scanPluginsCache() {
26569
26570
  try {
26570
26571
  const skillDirs = await findPluginSkillDirs(pluginsDir);
26571
26572
  for (const skillDir of skillDirs) {
26572
- const skill = await scanSkill(skillDir, "system");
26573
+ const skill = await scanSkill(skillDir, "system", "plugins");
26573
26574
  if (skill) {
26574
26575
  skills.push(skill);
26575
26576
  }
@@ -26585,7 +26586,7 @@ async function scanAllSkills(options = {}) {
26585
26586
  const [global2, project, system, plugins] = await Promise.all([
26586
26587
  scanSkillsDir(getGlobalSkillsDir(), "global"),
26587
26588
  scanSkillsDir(getProjectSkillsDir(projectRoot), "project"),
26588
- scanSkillsDir(getSystemSkillsDir(), "system"),
26589
+ scanSkillsDir(getSystemSkillsDir(), "system", "agents"),
26589
26590
  scanPluginsCache()
26590
26591
  ]);
26591
26592
  const allSystem = [...system, ...plugins];
@@ -26713,11 +26714,26 @@ function SkillTable({ skills, selectedIndex, width, maxVisibleRows = 15 }) {
26713
26714
  locationDisplay = truncatePath(skill.path, pathWidth);
26714
26715
  locationColor = "blue";
26715
26716
  } else {
26716
- locationDisplay = "\u7CFB\u7EDF";
26717
- locationColor = "gray";
26717
+ if (skill.source === "plugins") {
26718
+ locationDisplay = "Plugin";
26719
+ locationColor = "magenta";
26720
+ } else if (skill.source === "agents") {
26721
+ locationDisplay = "Agents";
26722
+ locationColor = "gray";
26723
+ } else {
26724
+ locationDisplay = "\u7CFB\u7EDF";
26725
+ locationColor = "gray";
26726
+ }
26727
+ }
26728
+ let statusDisplay;
26729
+ let statusColor;
26730
+ if (skill.location === "system") {
26731
+ statusDisplay = skill.source === "plugins" ? "\u63D2\u4EF6" : skill.source === "agents" ? "\u4EE3\u7406" : "\u7CFB\u7EDF";
26732
+ statusColor = skill.source === "plugins" ? "magenta" : "yellow";
26733
+ } else {
26734
+ statusDisplay = skill.isSymlink ? "\u94FE\u63A5" : "\u2713";
26735
+ statusColor = skill.isSymlink ? "yellow" : "green";
26718
26736
  }
26719
- const statusDisplay = skill.isSymlink ? "\u94FE\u63A5" : "\u2713";
26720
- const statusColor = skill.isSymlink ? "yellow" : "green";
26721
26737
  return /* @__PURE__ */ import_react23.default.createElement(Box_default, { key: skill.path, paddingX: 1 }, /* @__PURE__ */ import_react23.default.createElement(Box_default, { width: nameWidth }, /* @__PURE__ */ import_react23.default.createElement(
26722
26738
  Text,
26723
26739
  {
@@ -26758,13 +26774,21 @@ function StatusBar({ selectedSkill, width }) {
26758
26774
  if (!selectedSkill) {
26759
26775
  return /* @__PURE__ */ import_react24.default.createElement(Box_default, { paddingX: 1 }, /* @__PURE__ */ import_react24.default.createElement(Text, { dimColor: true }, "\u672A\u9009\u4E2D\u6280\u80FD"));
26760
26776
  }
26761
- return /* @__PURE__ */ import_react24.default.createElement(Box_default, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { bold: true, color: "cyan" }, "\u5DF2\u9009\u4E2D: "), /* @__PURE__ */ import_react24.default.createElement(Text, { bold: true }, selectedSkill.name)), selectedSkill.location === "project" && /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray" }, "\u8DEF\u5F84: "), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "blue" }, selectedSkill.path)), selectedSkill.description && /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray", wrap: "wrap" }, selectedSkill.description.slice(0, width - 10), selectedSkill.description.length > width - 10 ? "..." : "")));
26777
+ const getSourceLabel = (skill) => {
26778
+ if (skill.location === "system") {
26779
+ if (skill.source === "plugins") return " [\u63D2\u4EF6]";
26780
+ if (skill.source === "agents") return " [\u4EE3\u7406]";
26781
+ return " [\u7CFB\u7EDF]";
26782
+ }
26783
+ return "";
26784
+ };
26785
+ return /* @__PURE__ */ import_react24.default.createElement(Box_default, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { bold: true, color: "cyan" }, "\u5DF2\u9009\u4E2D: "), /* @__PURE__ */ import_react24.default.createElement(Text, { bold: true }, selectedSkill.name), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray" }, getSourceLabel(selectedSkill))), selectedSkill.location === "project" && /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray" }, "\u8DEF\u5F84: "), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "blue" }, selectedSkill.path)), selectedSkill.location === "system" && /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray" }, "\u6765\u6E90: "), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "magenta" }, selectedSkill.source === "plugins" ? "Plugin \u7F13\u5B58" : selectedSkill.source === "agents" ? "Agents \u76EE\u5F55" : "\u7CFB\u7EDF"), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray" }, " | "), /* @__PURE__ */ import_react24.default.createElement(Text, { color: "blue" }, selectedSkill.path)), selectedSkill.description && /* @__PURE__ */ import_react24.default.createElement(Box_default, null, /* @__PURE__ */ import_react24.default.createElement(Text, { color: "gray", wrap: "wrap" }, selectedSkill.description.slice(0, width - 10), selectedSkill.description.length > width - 10 ? "..." : "")));
26762
26786
  }
26763
26787
 
26764
26788
  // src/ui/components/ActionBar.tsx
26765
26789
  var import_react25 = __toESM(require_react(), 1);
26766
26790
  function ActionBar({ canUninstall, canUpdate }) {
26767
- return /* @__PURE__ */ import_react25.default.createElement(Box_default, { paddingX: 1, gap: 2 }, /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[i]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5B89\u88C5")), canUninstall && /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[u]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5378\u8F7D")), canUpdate && /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[U]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u66F4\u65B0")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[v]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u8BE6\u60C5")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[s]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u641C\u7D22")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[r]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5237\u65B0")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[q]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u9000\u51FA")));
26791
+ return /* @__PURE__ */ import_react25.default.createElement(Box_default, { paddingX: 1, gap: 2 }, /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[i]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5B89\u88C5")), canUninstall && /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "red" }, "[d]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5378\u8F7D")), canUpdate && /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "green" }, "[p]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u66F4\u65B0\u9009\u4E2D")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[v]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u8BE6\u60C5")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[s]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u641C\u7D22")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[r]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u5237\u65B0")), /* @__PURE__ */ import_react25.default.createElement(Text, null, /* @__PURE__ */ import_react25.default.createElement(Text, { bold: true, color: "cyan" }, "[q]"), /* @__PURE__ */ import_react25.default.createElement(Text, { dimColor: true }, " \u9000\u51FA")));
26768
26792
  }
26769
26793
 
26770
26794
  // src/ui/components/TabBar.tsx
@@ -26958,45 +26982,34 @@ function execSafe2(command, args, cwd2, timeout) {
26958
26982
  if (code === 0) {
26959
26983
  resolve({ stdout, stderr });
26960
26984
  } else {
26961
- reject(new Error(`\u547D\u4EE4\u6267\u884C\u5931\u8D25 (\u4EE3\u7801 ${code}): ${stderr || stdout}`));
26985
+ reject(new Error(`Command failed (code ${code}): ${stderr || stdout}`));
26962
26986
  }
26963
26987
  });
26964
26988
  });
26965
26989
  }
26966
- function validatePath(projectRoot) {
26967
- const resolved = path4.resolve(projectRoot);
26968
- if (!path4.isAbsolute(resolved)) {
26969
- return { valid: false, error: "\u9879\u76EE\u8DEF\u5F84\u5FC5\u987B\u662F\u7EDD\u5BF9\u8DEF\u5F84" };
26970
- }
26971
- if (resolved.includes("..")) {
26972
- return { valid: false, error: "\u65E0\u6548\u7684\u8DEF\u5F84" };
26973
- }
26974
- return { valid: true };
26975
- }
26976
- async function updateAllSkills(projectRoot = process.cwd()) {
26977
- const validation = validatePath(projectRoot);
26978
- if (!validation.valid) {
26990
+ async function updateSkill(skill) {
26991
+ if (skill.location === "system") {
26979
26992
  return {
26980
26993
  success: false,
26981
- message: `\u65E0\u6548\u7684\u9879\u76EE\u8DEF\u5F84: ${validation.error}`
26994
+ message: "\u7CFB\u7EDF\u7EA7\u6280\u80FD\u65E0\u6CD5\u76F4\u63A5\u66F4\u65B0\uFF0C\u8BF7\u4F7F\u7528 add-skill \u5DE5\u5177\u66F4\u65B0"
26982
26995
  };
26983
26996
  }
26984
26997
  try {
26985
- logger.info("\u6B63\u5728\u66F4\u65B0\u6240\u6709\u6280\u80FD...");
26986
- const { stdout, stderr } = await execSafe2("npx", ["skills", "update"], projectRoot, 12e4);
26998
+ logger.info(`Updating skill: ${skill.name}...`);
26999
+ const { stdout, stderr } = await execSafe2("npx", ["add-skill", skill.name], process.cwd(), 12e4);
26987
27000
  if (stderr && !stderr.includes("npm warn")) {
26988
- logger.warn("\u66F4\u65B0\u8F93\u51FA:", stderr);
27001
+ logger.warn("Update output:", stderr);
26989
27002
  }
26990
27003
  return {
26991
27004
  success: true,
26992
- message: stdout.trim() || "\u6280\u80FD\u66F4\u65B0\u6210\u529F"
27005
+ message: stdout.trim() || `Skill ${skill.name} updated successfully`
26993
27006
  };
26994
27007
  } catch (error) {
26995
27008
  const message = error instanceof Error ? error.message : String(error);
26996
- logger.error("\u66F4\u65B0\u5931\u8D25:", message);
27009
+ logger.error("Update failed:", message);
26997
27010
  return {
26998
27011
  success: false,
26999
- message: `\u66F4\u65B0\u6280\u80FD\u5931\u8D25: ${message}`
27012
+ message: `Failed to update skill ${skill.name}: ${message}`
27000
27013
  };
27001
27014
  }
27002
27015
  }
@@ -27152,7 +27165,7 @@ function MainScreen() {
27152
27165
  } else if (input === "i") {
27153
27166
  setScreen("install");
27154
27167
  setInstallPackage("");
27155
- } else if (input === "u" && selectedSkill) {
27168
+ } else if (input === "d" && selectedSkill) {
27156
27169
  if (selectedSkill.location === "system") {
27157
27170
  setMessage({
27158
27171
  text: "\u65E0\u6CD5\u5378\u8F7D\u7CFB\u7EDF\u7EA7\u6280\u80FD",
@@ -27162,17 +27175,25 @@ function MainScreen() {
27162
27175
  } else {
27163
27176
  setScreen("confirm-uninstall");
27164
27177
  }
27165
- } else if (input === "U") {
27166
- setMessage({ text: "\u6B63\u5728\u68C0\u67E5\u66F4\u65B0...", type: "info" });
27167
- setScreen("message");
27168
- const result = await updateAllSkills();
27169
- setMessage({
27170
- text: result.message,
27171
- type: result.success ? "success" : "error"
27172
- });
27173
- setScreen("message");
27174
- if (result.success) {
27175
- await refresh();
27178
+ } else if (input === "p" && selectedSkill) {
27179
+ if (selectedSkill.location === "system") {
27180
+ setMessage({
27181
+ text: "\u7CFB\u7EDF\u7EA7\u6280\u80FD\u65E0\u6CD5\u76F4\u63A5\u66F4\u65B0",
27182
+ type: "error"
27183
+ });
27184
+ setScreen("message");
27185
+ } else {
27186
+ setMessage({ text: `\u6B63\u5728\u66F4\u65B0 ${selectedSkill.name}...`, type: "info" });
27187
+ setScreen("message");
27188
+ const result = await updateSkill(selectedSkill);
27189
+ setMessage({
27190
+ text: result.message,
27191
+ type: result.success ? "success" : "error"
27192
+ });
27193
+ setScreen("message");
27194
+ if (result.success) {
27195
+ await refresh();
27196
+ }
27176
27197
  }
27177
27198
  } else if (input === "v" && selectedSkill) {
27178
27199
  setScreen("detail");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyml/skill-manager",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "TUI-based skill manager for Claude Code",
5
5
  "type": "module",
6
6
  "main": "dist/skill-manager.mjs",