skilllib 1.11.5 → 1.11.7

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.
@@ -1931,7 +1931,7 @@ function setPluginOn(p, on) {
1931
1931
  }
1932
1932
  const r = setPluginIn(settingsFileOf(p), p.id, on);
1933
1933
  if (!r.ok) return { ok: false, message: `${p.id}: ${r.reason}` };
1934
- if (p.scope === "local" && p.projectPath) return { ...done, message: done.message + ignoreLocalSettings(p.projectPath) };
1934
+ if (p.scope === "local" && p.projectPath) return { ...done, message: `${done.message}; it's in .claude/settings.local.json${ignoreLocalSettings(p.projectPath)}` };
1935
1935
  return done;
1936
1936
  }
1937
1937
  function uninstallPlugin(p) {
@@ -1966,27 +1966,16 @@ function removePlugin(plugin, how) {
1966
1966
  if (plugin.settingsOnly && how === "delete") return { ok: false, message: `${plugin.id} isn't installed, only turned on in your settings: turn it off instead` };
1967
1967
  const lost = unplaced(plugin, how === "delete" ? "uninstall" : "disable");
1968
1968
  if (lost) return lost;
1969
- const viaSettings = plugin.synced || plugin.settingsOnly || !claudeBinary() && how === "off" && !plugin.projectPath;
1970
- if (!viaSettings && !claudeBinary()) {
1971
- return { ok: false, message: `${plugin.id}: nothing changed; Claude Code's CLI didn't run (tried \`claude\` on your PATH and ~/.local/bin/claude)` };
1972
- }
1973
- const wasOn = enabledPlugins(plugin.projectPath)[plugin.id] === true;
1969
+ const uninstall = how === "delete" && !plugin.synced;
1970
+ if (uninstall && !claudeBinary()) return { ok: false, message: `${plugin.id}: nothing changed; Claude Code's CLI didn't run (tried \`claude\` on your PATH and ~/.local/bin/claude)` };
1974
1971
  const yours = new Set(machineSkills().filter((m) => m.movable).map((m) => m.name));
1975
1972
  const imported = plugin.skills.filter((dir) => !yours.has(basename4(dir)) && latestVersion(basename4(dir)) === null).map((dir) => importSkill(dir).name);
1976
- const scope = plugin.scope ? ["--scope", plugin.scope] : [];
1977
- const r = viaSettings ? (
1978
- // Synced and settings-only plugins aren't installed, so `claude plugin` can't touch them: their switch is enabledPlugins.
1979
- setPluginIn(join11(claudeDir(), "settings.json"), plugin.id, false)
1980
- ) : (
1981
- // --keep-data, as uninstallPlugin: its saved data stays, so a restore brings it back as it was.
1982
- claude(["plugin", how === "delete" ? "uninstall" : "disable", plugin.id, ...how === "delete" ? ["--keep-data"] : [], ...scope], plugin.projectPath)
1983
- );
1984
1973
  const saved = imported.length ? `; ${imported.join(", ")} copied into Your skills` : "";
1985
- if (!r.ok) return { ok: false, message: `${plugin.id}: ${r.reason}${saved}` };
1986
- if (how === "delete" && !plugin.synced) recordRemovedPlugin(plugin.id, plugin.scope ?? "user", plugin.projectPath, wasOn);
1987
- const others = how === "delete" ? (installedPluginsJson()[plugin.id] ?? []).filter((e) => (e.scope ?? "user") !== (plugin.scope ?? "user") || e.projectPath !== plugin.projectPath) : [];
1974
+ const r = uninstall ? uninstallPlugin(plugin) : setPluginOn(plugin, false);
1975
+ if (!r.ok) return { ok: false, message: `${r.message}${saved}` };
1976
+ const others = uninstall ? (installedPluginsJson()[plugin.id] ?? []).filter((e) => (e.scope ?? "user") !== (plugin.scope ?? "user") || e.projectPath !== plugin.projectPath) : [];
1988
1977
  const left = others.length ? `; its ${others.map((e) => `${e.scope ?? "user"} install${e.projectPath ? ` in ${basename4(e.projectPath)}` : ""}`).join(", ")} stays` : "";
1989
- return { ok: true, message: `${plugin.id} ${how === "delete" && !plugin.synced ? `removed (${plugin.scope ?? "user"} install)` : "turned off"}${saved}${left}` };
1978
+ return { ok: true, message: uninstall ? `${plugin.id} removed (${plugin.scope ?? "user"} install)${saved}${left}` : `${r.message}${saved}` };
1990
1979
  }
1991
1980
  function recordRemovedPlugin(id, scope, projectPath, on = true) {
1992
1981
  const list2 = readState(removedFile()) ?? [];
@@ -2034,6 +2023,9 @@ function entriesOf(dirs, name) {
2034
2023
  return [{ dir, path, link: link2, real, hash: null }];
2035
2024
  });
2036
2025
  }
2026
+ function uniqueReals(entries) {
2027
+ return entries.filter((e, i, all) => !e.link && all.findIndex((o) => !o.link && o.real === e.real) === i);
2028
+ }
2037
2029
  function hashReals(reals) {
2038
2030
  if (reals.length > 1) for (const r of reals) r.hash = treeHash(r.path);
2039
2031
  }
@@ -2074,15 +2066,16 @@ function planProjectTidy(root, { keep = {}, enabled = enabledHarnesses() } = {})
2074
2066
  let git2;
2075
2067
  const skillsLock = projectSkillsLock(root);
2076
2068
  const dirs = repoTidyDirs(root).map(abs);
2069
+ const realRoot = realpathOrNull(root) ?? root;
2077
2070
  for (const name of namesIn(dirs)) {
2078
2071
  const entries = entriesOf(dirs, name);
2079
- const external = entries.find((e) => e.link && e.real && !(e.real + sep6).startsWith(realpathOrNull(root) + sep6));
2072
+ const external = entries.find((e) => e.link && e.real && !(e.real + sep6).startsWith(realRoot + sep6));
2080
2073
  if (external) {
2081
2074
  const differs = entries.some((e) => e !== external && e.real && existsSync11(join12(e.real, "SKILL.md")) && treeHash(e.real) !== treeHash(external.real));
2082
2075
  report.skipped.push({ name, reason: `${rel(external.path)} links outside the repo`, ...differs ? { differs } : {} });
2083
2076
  continue;
2084
2077
  }
2085
- const reals = entries.filter((e, i, all) => !e.link && all.findIndex((o) => !o.link && realpathOrNull(o.path) === realpathOrNull(e.path)) === i);
2078
+ const reals = uniqueReals(entries);
2086
2079
  if (reals.length === 0) continue;
2087
2080
  hashReals(reals);
2088
2081
  const dep = skills[name];
@@ -2146,7 +2139,7 @@ function planGlobalTidy({ keep = {}, enabled = enabledHarnesses() } = {}) {
2146
2139
  report.skipped.push({ name, reason: "a Claude Code plugin kept in a skills folder" });
2147
2140
  continue;
2148
2141
  }
2149
- const reals = entries.filter((e, i, all) => !e.link && all.findIndex((o) => !o.link && realpathOrNull(o.path) === realpathOrNull(e.path)) === i);
2142
+ const reals = uniqueReals(entries);
2150
2143
  if (reals.length < 2) continue;
2151
2144
  hashReals(reals);
2152
2145
  const kept = reals.find((r) => r.dir === keep[name]);
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  unhide,
32
32
  update,
33
33
  usage
34
- } from "./chunk-TE2EDZ7L.js";
34
+ } from "./chunk-PKQPUIN3.js";
35
35
 
36
36
  // src/index.ts
37
37
  import { readFileSync } from "fs";
@@ -138,10 +138,10 @@ async function main() {
138
138
  if (!["--version", "-v", "version", "help", "--help", "-h"].includes(command ?? "")) refreshAgentSkill();
139
139
  switch (command) {
140
140
  case void 0:
141
- return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-GFQUHPEC.js")).tui() : overview(args);
141
+ return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-B5PF3J3E.js")).tui() : overview(args);
142
142
  case "ui":
143
143
  if (!process.stdin.isTTY || !process.stdout.isTTY) throw new Error("`skilllib ui` needs an interactive terminal. Agents and scripts: use `skilllib status --json`.");
144
- return (await import("./tui-GFQUHPEC.js")).tui();
144
+ return (await import("./tui-B5PF3J3E.js")).tui();
145
145
  case "status":
146
146
  return status(args);
147
147
  case "add":
@@ -84,7 +84,7 @@ import {
84
84
  versionHistory,
85
85
  visibleProjects,
86
86
  withoutForceHint
87
- } from "./chunk-TE2EDZ7L.js";
87
+ } from "./chunk-PKQPUIN3.js";
88
88
 
89
89
  // src/tui/index.tsx
90
90
  import { render } from "ink";
@@ -1743,7 +1743,8 @@ function App({ initial, reload, loadUsage: loadUsage2 }) {
1743
1743
  if (isNameChar(input, key)) return setModal({ ...m, query: m.query + input.toLowerCase(), cursor: 0 });
1744
1744
  }
1745
1745
  }
1746
- const toastLines = toast && modal?.kind !== "confirm" ? wrap(toast, termCols - 2, 3).map((l) => " " + l) : [];
1746
+ const toastMax = Math.max(1, Math.min(Math.max(3, Math.floor(termRows / 3)), termRows - 8 - (sidebar ? 0 : 1)));
1747
+ const toastLines = toast && modal?.kind !== "confirm" ? wrap(toast, termCols - 2, toastMax).map((l) => " " + l) : [];
1747
1748
  const bottomH = Math.max(1, toastLines.length);
1748
1749
  const confirmLines = modal?.kind === "confirm" ? wrap(modal.fix.preview, columns - 6, 6) : [];
1749
1750
  const confirmH = modal?.kind === "confirm" ? confirmLines.length + 2 : 0;
@@ -1786,10 +1787,14 @@ function App({ initial, reload, loadUsage: loadUsage2 }) {
1786
1787
  }), here: onHelp }
1787
1788
  ];
1788
1789
  const sideAt = sideRows.findIndex((r) => r.here);
1790
+ const brand = " \u25C6 skilllib ";
1791
+ const tabsWidth = (short) => PLACES.reduce((n, [p, label]) => n + (short && p === "library" ? 6 : label.length) + 2 + (p === "health" && healthCount ? ` ${healthCount}`.length : 0), 0);
1792
+ const showBrand = brand.length + tabsWidth(false) <= columns;
1793
+ const shortTabs = !showBrand && tabsWidth(false) > columns;
1789
1794
  const topBar = /* @__PURE__ */ jsx2(Box2, { height: 1, width: columns, justifyContent: "space-between", children: /* @__PURE__ */ jsxs2(Box2, { children: [
1790
- /* @__PURE__ */ jsx2(Text2, { color: color.accent, bold: true, children: " \u25C6 skilllib " }),
1795
+ /* @__PURE__ */ jsx2(Text2, { color: color.accent, bold: true, children: showBrand ? brand : "" }),
1791
1796
  PLACES.map(([p, label]) => /* @__PURE__ */ jsxs2(Text2, { backgroundColor: place === p ? color.accent : void 0, color: place === p ? "#0B1020" : color.muted, bold: place === p, children: [
1792
- ` ${label}`,
1797
+ ` ${shortTabs && p === "library" ? "Skills" : label}`,
1793
1798
  /* @__PURE__ */ jsx2(Text2, { color: place === p ? "#0B1020" : healthWorst ? SEV[healthWorst.severity].color : color.green, children: p === "health" && healthCount ? ` ${healthCount}` : "" }),
1794
1799
  " "
1795
1800
  ] }, p))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilllib",
3
- "version": "1.11.5",
3
+ "version": "1.11.7",
4
4
  "description": "Manage your agent skills like dependencies. One library for all your skills; each repo gets only the ones it needs, and every agent can see them. Works with Claude Code, Cursor, Codex, Zed and Grok.",
5
5
  "keywords": [
6
6
  "agent-skills",