@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.
- package/bin/ash.mjs +31 -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
|
|
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