@agentskillshub/cli 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/bin/ash.mjs +31 -2
  2. package/package.json +1 -1
package/bin/ash.mjs CHANGED
@@ -42,6 +42,9 @@ const GRADE = {
42
42
  unknown: { label: "UNAUDITED", mark: "⚪" },
43
43
  };
44
44
 
45
+ // CJK detection — Chinese queries have no word boundaries, so we bigram them.
46
+ const CJK = /[一-鿿]/;
47
+
45
48
  // ─── tiny ANSI (auto-off when not a TTY / NO_COLOR) ──────────────────────────
46
49
  const tty = process.stdout.isTTY && !process.env.NO_COLOR;
47
50
  const c = (code, s) => (tty ? `\x1b[${code}m${s}\x1b[0m` : s);
@@ -143,13 +146,26 @@ function scoreRow(row, tokens) {
143
146
  const full = (row.f || "").toLowerCase();
144
147
  const desc = (row.d || "").toLowerCase();
145
148
  const tags = (row.t || []).join(" ").toLowerCase();
149
+ // Bilingual scenario keywords (field `w`) — lets Chinese queries match
150
+ // English-only repos via our curated scenario titles, and ranks
151
+ // scenario-relevant skills higher. Empty/undefined on older indexes.
152
+ const scen = (row.w || "").toLowerCase();
146
153
  let score = 0;
147
154
  for (const tok of tokens) {
148
155
  if (name === tok) score += 50;
149
156
  else if (name.includes(tok)) score += 20;
150
157
  if (full.includes(tok)) score += 8;
158
+ if (scen.includes(tok)) score += 12;
151
159
  if (tags.includes(tok)) score += 10;
152
160
  if (desc.includes(tok)) score += 5;
161
+ // CJK compound queries arrive as one space-less token ("抓取网站").
162
+ // Fall back to 2-char windows so a keyword like "抓取" still matches.
163
+ if (CJK.test(tok) && tok.length >= 3) {
164
+ for (let i = 0; i + 2 <= tok.length; i++) {
165
+ const bg = tok.slice(i, i + 2);
166
+ if (scen.includes(bg)) { score += 9; break; }
167
+ }
168
+ }
153
169
  }
154
170
  if (score === 0) return -1; // matched nothing
155
171
  return score + (row.q || 0) / 20 + Math.min(row.s, 50000) / 25000; // quality + popularity tiebreak
@@ -165,9 +181,22 @@ function applyFilters(skills, f) {
165
181
  });
166
182
  }
167
183
 
184
+ /** Tokenize a query. Splits on whitespace AND at latin↔CJK boundaries, so a
185
+ * glued mixed query like "ppt制作" becomes ["ppt", "制作"] (otherwise it's one
186
+ * token that matches nothing). Pure-CJK compounds still rely on the bigram
187
+ * fallback in scoreRow. */
188
+ function tokenize(q) {
189
+ return q
190
+ .toLowerCase()
191
+ .replace(/([a-z0-9])([一-鿿])/g, "$1 $2")
192
+ .replace(/([一-鿿])([a-z0-9])/g, "$1 $2")
193
+ .split(/\s+/)
194
+ .filter(Boolean);
195
+ }
196
+
168
197
  function runSearch(index, args) {
169
198
  const f = parseFilters(args);
170
- const tokens = f.query.toLowerCase().split(/\s+/).filter(Boolean);
199
+ const tokens = tokenize(f.query);
171
200
  const pool = applyFilters(index.skills, f);
172
201
  const ranked = pool
173
202
  .map((r) => ({ r, score: scoreRow(r, tokens) }))
@@ -247,7 +276,7 @@ function runAudit(index, args) {
247
276
  return console.log(JSON.stringify({ ...expand(row), in_catalog: true, verdict: VERDICT[row.g] || VERDICT.unknown, tier_note: "Basic (free). 5-dimension deep audit + any GitHub URL → Pro." }, null, 2));
248
277
  }
249
278
  console.log(`\n${bold(cyan(row.f))} ${yellow(starStr(row.s))}${row.o ? green(" ✓ official") : ""}`);
250
- console.log(`Security: ${gradeBadge(row.g)} Quality: ${row.q}/100`);
279
+ console.log(`Security: ${gradeBadge(row.g)} Quality: ${Math.round(row.q ?? 0)}/100`);
251
280
  if (row.d) console.log(dim(`\n ${row.d}`));
252
281
  console.log(`\n${bold("Basic verdict")} ${dim("(free tier)")}`);
253
282
  console.log(` ${VERDICT[row.g] || VERDICT.unknown}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentskillshub/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Search, audit, and install open-source AI agent skills & MCP servers from the terminal — security-graded, quality-scored.",
5
5
  "type": "module",
6
6
  "bin": {