skilld 0.15.2 → 0.15.3

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
@@ -776,15 +776,26 @@ function highlightTerms(content, terms) {
776
776
  const pattern = new RegExp(`(${sorted.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "gi");
777
777
  return content.replace(pattern, "\x1B[33m$1\x1B[0m");
778
778
  }
779
- function formatSnippet(r) {
779
+ function scoreLabel(pct) {
780
+ return `${pct >= 70 ? "\x1B[32m" : pct >= 40 ? "\x1B[33m" : "\x1B[90m"}${pct}%\x1B[0m`;
781
+ }
782
+ function normalizeScores(results) {
783
+ const map = /* @__PURE__ */ new Map();
784
+ const max = results.reduce((m, r) => Math.max(m, r.score), 0);
785
+ for (const r of results) map.set(r, max > 0 ? Math.round(r.score / max * 100) : 0);
786
+ return map;
787
+ }
788
+ function formatSnippet(r, versions, pct) {
780
789
  const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`;
781
790
  const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`;
782
- const score = `\x1B[90m${r.score.toFixed(2)}\x1B[0m`;
791
+ const score = pct != null ? scoreLabel(pct) : `\x1B[90m${r.score.toFixed(2)}\x1B[0m`;
792
+ const version = versions?.get(r.package);
793
+ const pkgLabel = version ? `${r.package}@${version}` : r.package;
783
794
  const scopeStr = r.scope?.length ? `${r.scope.map((e) => e.name).join(".")} → ` : "";
784
795
  const entityStr = r.entities?.map((e) => e.signature || `${e.type} ${e.name}`).join(", ");
785
796
  const highlighted = highlightTerms(r.content, r.highlights);
786
797
  return [
787
- `${r.package} ${score}${entityStr ? ` \x1B[36m${scopeStr}${entityStr}\x1B[0m` : ""}`,
798
+ `${pkgLabel} ${score}${entityStr ? ` \x1B[36m${scopeStr}${entityStr}\x1B[0m` : ""}`,
788
799
  `\x1B[90m${refPath}:${lineRange}\x1B[0m`,
789
800
  ` ${highlighted.replace(/\n/g, "\n ")}`
790
801
  ].join("\n");
@@ -3428,6 +3439,7 @@ const removeCommandDef = defineCommand({
3428
3439
  });
3429
3440
  var search_exports = /* @__PURE__ */ __exportAll({
3430
3441
  findPackageDbs: () => findPackageDbs,
3442
+ getPackageVersions: () => getPackageVersions,
3431
3443
  listLockPackages: () => listLockPackages,
3432
3444
  parseFilterPrefix: () => parseFilterPrefix,
3433
3445
  searchCommand: () => searchCommand,
@@ -3438,6 +3450,13 @@ function findPackageDbs(packageFilter) {
3438
3450
  if (!lock) return [];
3439
3451
  return filterLockDbs(lock, packageFilter);
3440
3452
  }
3453
+ function getPackageVersions(cwd = process.cwd()) {
3454
+ const lock = readProjectLock(cwd);
3455
+ const map = /* @__PURE__ */ new Map();
3456
+ if (!lock) return map;
3457
+ for (const s of Object.values(lock.skills)) if (s.packageName && s.version) map.set(s.packageName, s.version);
3458
+ return map;
3459
+ }
3441
3460
  function readProjectLock(cwd) {
3442
3461
  const shared = getSharedSkillsDir(cwd);
3443
3462
  if (shared) {
@@ -3451,7 +3470,9 @@ function readProjectLock(cwd) {
3451
3470
  function listLockPackages(cwd = process.cwd()) {
3452
3471
  const lock = readProjectLock(cwd);
3453
3472
  if (!lock) return [];
3454
- return [...new Set(Object.values(lock.skills).map((s) => s.packageName).filter(Boolean))];
3473
+ const seen = /* @__PURE__ */ new Map();
3474
+ for (const s of Object.values(lock.skills)) if (s.packageName && s.version) seen.set(s.packageName, s.version);
3475
+ return [...seen].map(([name, version]) => `${name}@${version}`);
3455
3476
  }
3456
3477
  function filterLockDbs(lock, packageFilter) {
3457
3478
  if (!lock) return [];
@@ -3510,6 +3531,7 @@ function parseFilterPrefix(rawQuery) {
3510
3531
  }
3511
3532
  async function searchCommand(rawQuery, packageFilter) {
3512
3533
  const dbs = findPackageDbs(packageFilter);
3534
+ const versions = getPackageVersions();
3513
3535
  if (dbs.length === 0) {
3514
3536
  if (packageFilter) {
3515
3537
  const available = listLockPackages();
@@ -3520,16 +3542,25 @@ async function searchCommand(rawQuery, packageFilter) {
3520
3542
  }
3521
3543
  const { query, filter } = parseFilterPrefix(rawQuery);
3522
3544
  const start = performance.now();
3523
- const merged = (await Promise.all(dbs.map((dbPath) => searchSnippets(query, { dbPath }, {
3524
- limit: filter ? 10 : 5,
3545
+ const allResults = await Promise.all(dbs.map((dbPath) => searchSnippets(query, { dbPath }, {
3546
+ limit: filter ? 20 : 10,
3525
3547
  filter
3526
- })))).flat().sort((a, b) => b.score - a.score).slice(0, 5);
3548
+ })));
3549
+ const seen = /* @__PURE__ */ new Set();
3550
+ const merged = allResults.flat().sort((a, b) => b.score - a.score).filter((r) => {
3551
+ const key = `${r.source}:${r.lineStart}-${r.lineEnd}`;
3552
+ if (seen.has(key)) return false;
3553
+ seen.add(key);
3554
+ return true;
3555
+ }).slice(0, 5);
3527
3556
  const elapsed = ((performance.now() - start) / 1e3).toFixed(2);
3528
3557
  if (merged.length === 0) {
3529
3558
  p.log.warn(`No results for "${query}"`);
3530
3559
  return;
3531
3560
  }
3532
- const output = sanitizeMarkdown(merged.map((r) => formatSnippet(r)).join("\n\n"));
3561
+ for (const r of merged) r.content = sanitizeMarkdown(r.content);
3562
+ const scores = normalizeScores(merged);
3563
+ const output = merged.map((r) => formatSnippet(r, versions, scores.get(r))).join("\n\n");
3533
3564
  const summary = `${merged.length} results (${elapsed}s)`;
3534
3565
  if (!!detectCurrentAgent()) {
3535
3566
  const sanitized = output.replace(/<\/search-results>/gi, "&lt;/search-results&gt;");
@@ -3577,11 +3608,6 @@ function filterToSearchFilter(label) {
3577
3608
  if (label === "releases") return { type: "release" };
3578
3609
  return { type: { $in: ["doc", "docs"] } };
3579
3610
  }
3580
- function scoreColor(score) {
3581
- if (score >= .7) return "\x1B[32m";
3582
- if (score >= .4) return "\x1B[33m";
3583
- return "\x1B[90m";
3584
- }
3585
3611
  const SPINNER_FRAMES = [
3586
3612
  "◐",
3587
3613
  "◓",
@@ -3590,6 +3616,7 @@ const SPINNER_FRAMES = [
3590
3616
  ];
3591
3617
  async function interactiveSearch(packageFilter) {
3592
3618
  const dbs = findPackageDbs(packageFilter);
3619
+ const versions = getPackageVersions();
3593
3620
  if (dbs.length === 0) {
3594
3621
  let msg;
3595
3622
  if (packageFilter) {
@@ -3646,18 +3673,21 @@ async function interactiveSearch(packageFilter) {
3646
3673
  } else {
3647
3674
  lines.push("");
3648
3675
  const shown = results.slice(0, maxResults);
3676
+ const scores = normalizeScores(results);
3649
3677
  for (let i = 0; i < shown.length; i++) {
3650
3678
  const r = shown[i];
3651
3679
  const selected = i === selectedIndex;
3652
3680
  const bullet = selected ? "\x1B[36m●\x1B[0m" : "\x1B[90m○\x1B[0m";
3653
- const sc = scoreColor(r.score);
3681
+ const sc = scoreLabel(scores.get(r) ?? 0);
3654
3682
  const { title, path, preview } = formatCompactSnippet(r, cols);
3655
3683
  const highlighted = highlightTerms(preview, r.highlights);
3684
+ const ver = versions.get(r.package);
3685
+ const pkgLabel = ver ? `${r.package}@${ver}` : r.package;
3656
3686
  if (selected) {
3657
- lines.push(` ${bullet} \x1B[1m${r.package}\x1B[0m ${sc}${r.score.toFixed(2)}\x1B[0m \x1B[36m${title}\x1B[0m`);
3687
+ lines.push(` ${bullet} \x1B[1m${pkgLabel}\x1B[0m ${sc} \x1B[36m${title}\x1B[0m`);
3658
3688
  lines.push(` \x1B[90m${path}\x1B[0m`);
3659
3689
  lines.push(` ${highlighted}`);
3660
- } else lines.push(` ${bullet} \x1B[90m${r.package}\x1B[0m ${sc}${r.score.toFixed(2)}\x1B[0m \x1B[90m${title}\x1B[0m`);
3690
+ } else lines.push(` ${bullet} \x1B[90m${pkgLabel}\x1B[0m ${sc} \x1B[90m${title}\x1B[0m`);
3661
3691
  }
3662
3692
  }
3663
3693
  lines.push("");
@@ -3733,9 +3763,10 @@ async function interactiveSearch(packageFilter) {
3733
3763
  const refPath = `.claude/skills/${r.package}/.skilld/${r.source}`;
3734
3764
  const lineRange = r.lineStart === r.lineEnd ? `L${r.lineStart}` : `L${r.lineStart}-${r.lineEnd}`;
3735
3765
  const highlighted = highlightTerms(sanitizeMarkdown(r.content), r.highlights);
3766
+ const rVer = versions.get(r.package);
3736
3767
  const out = [
3737
3768
  "",
3738
- ` \x1B[1m${r.package}\x1B[0m ${scoreColor(r.score)}${r.score.toFixed(2)}\x1B[0m`,
3769
+ ` \x1B[1m${rVer ? `${r.package}@${rVer}` : r.package}\x1B[0m ${scoreLabel(normalizeScores(results).get(r) ?? 0)}`,
3739
3770
  ` \x1B[90m${refPath}:${lineRange}\x1B[0m`,
3740
3771
  "",
3741
3772
  ` ${highlighted.replace(/\n/g, "\n ")}`,