pruff-skills 0.7.2 → 0.9.0
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 +121 -45
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4258,6 +4258,8 @@ const CYAN$1 = "\x1B[36m";
|
|
|
4258
4258
|
const GREEN = "\x1B[32m";
|
|
4259
4259
|
const MAGENTA = "\x1B[35m";
|
|
4260
4260
|
const BLUE$1 = "\x1B[38;2;110;139;255m";
|
|
4261
|
+
const CHECKED = "◼";
|
|
4262
|
+
const UNCHECKED = "◻";
|
|
4261
4263
|
const CATALOG_SOURCE = process.env.PRUFF_SKILLS_CATALOG || "Pruff-Tech/pruff-skills";
|
|
4262
4264
|
async function fetchCatalogIndex(source) {
|
|
4263
4265
|
const rel = ".well-known/agent-skills/index.json";
|
|
@@ -4350,10 +4352,11 @@ function rowBadge(skill) {
|
|
|
4350
4352
|
if (parts.length === 0) return "";
|
|
4351
4353
|
return ` ${DIM$3}[${RESET$3}${parts.join(`${DIM$3} · ${RESET$3}`)}${DIM$3}]${RESET$3}`;
|
|
4352
4354
|
}
|
|
4353
|
-
async function runSearchPrompt(kind, initialQuery = "") {
|
|
4355
|
+
async function runSearchPrompt(kind, alreadyPicked = /* @__PURE__ */ new Set(), initialQuery = "") {
|
|
4354
4356
|
let results = [];
|
|
4355
4357
|
let selectedIndex = 0;
|
|
4356
4358
|
let query = initialQuery;
|
|
4359
|
+
const picked = new Set(alreadyPicked);
|
|
4357
4360
|
let loading = false;
|
|
4358
4361
|
let lastRenderedLines = 0;
|
|
4359
4362
|
const noun = kind === "agent" ? "subagents" : kind === "rule" ? "rules" : "skills";
|
|
@@ -4381,15 +4384,17 @@ async function runSearchPrompt(kind, initialQuery = "") {
|
|
|
4381
4384
|
const skill = visible[i];
|
|
4382
4385
|
const isSelected = idx === selectedIndex;
|
|
4383
4386
|
const arrow = isSelected ? `${BOLD$3}>${RESET$3}` : " ";
|
|
4387
|
+
const box = picked.has(skill.name) ? `${GREEN}${CHECKED}${RESET$3}` : `${DIM$3}${UNCHECKED}${RESET$3}`;
|
|
4384
4388
|
const name = isSelected ? `${BOLD$3}${skill.name}${RESET$3}` : `${TEXT$2}${skill.name}${RESET$3}`;
|
|
4385
4389
|
const loadingIndicator = loading && idx === 0 ? ` ${DIM$3}...${RESET$3}` : "";
|
|
4386
|
-
lines.push(` ${arrow} ${name}${rowBadge(skill)}${loadingIndicator}`);
|
|
4390
|
+
lines.push(` ${arrow} ${box} ${name}${rowBadge(skill)}${loadingIndicator}`);
|
|
4387
4391
|
}
|
|
4388
4392
|
const remaining = results.length - (from + visible.length);
|
|
4389
4393
|
if (remaining > 0) lines.push(` ${DIM$3}↓ ${remaining} more${RESET$3}`);
|
|
4390
4394
|
}
|
|
4391
4395
|
lines.push("");
|
|
4392
|
-
|
|
4396
|
+
const count = picked.size > 0 ? ` ${GREEN}(${picked.size} selected)${RESET$3}` : "";
|
|
4397
|
+
lines.push(`${DIM$3}up/down navigate | space toggle | enter done${count}${DIM$3} | esc back${RESET$3}`);
|
|
4393
4398
|
for (const line of lines) process.stdout.write(line + "\n");
|
|
4394
4399
|
lastRenderedLines = lines.length;
|
|
4395
4400
|
}
|
|
@@ -4428,8 +4433,19 @@ async function runSearchPrompt(kind, initialQuery = "") {
|
|
|
4428
4433
|
return;
|
|
4429
4434
|
}
|
|
4430
4435
|
if (key.name === "return") {
|
|
4436
|
+
const row = results[selectedIndex];
|
|
4437
|
+
if (picked.size === 0 && row) picked.add(row.name);
|
|
4431
4438
|
cleanup();
|
|
4432
|
-
resolve(
|
|
4439
|
+
resolve(picked);
|
|
4440
|
+
return;
|
|
4441
|
+
}
|
|
4442
|
+
if (key.name === "space") {
|
|
4443
|
+
const row = results[selectedIndex];
|
|
4444
|
+
if (row) {
|
|
4445
|
+
if (picked.has(row.name)) picked.delete(row.name);
|
|
4446
|
+
else picked.add(row.name);
|
|
4447
|
+
render();
|
|
4448
|
+
}
|
|
4433
4449
|
return;
|
|
4434
4450
|
}
|
|
4435
4451
|
if (key.name === "up") {
|
|
@@ -4490,59 +4506,99 @@ ${DIM$3} 2) npx pruff-skills add <skill>${RESET$3}`;
|
|
|
4490
4506
|
return;
|
|
4491
4507
|
}
|
|
4492
4508
|
const all = await searchSkillsAPI("");
|
|
4493
|
-
const
|
|
4494
|
-
const
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4509
|
+
const countOf = (kind) => all.filter((s) => s.kind === kind).length;
|
|
4510
|
+
const KINDS = [
|
|
4511
|
+
{
|
|
4512
|
+
value: "skill",
|
|
4513
|
+
label: "Skills",
|
|
4514
|
+
count: countOf("skill")
|
|
4515
|
+
},
|
|
4516
|
+
{
|
|
4517
|
+
value: "agent",
|
|
4518
|
+
label: "Subagents",
|
|
4519
|
+
count: countOf("agent")
|
|
4520
|
+
},
|
|
4521
|
+
{
|
|
4522
|
+
value: "rule",
|
|
4523
|
+
label: "Rules",
|
|
4524
|
+
count: countOf("rule")
|
|
4525
|
+
}
|
|
4526
|
+
];
|
|
4527
|
+
const pickedByKind = new Map(KINDS.map((k) => [k.value, /* @__PURE__ */ new Set()]));
|
|
4528
|
+
const totalPicked = () => [...pickedByKind.values()].reduce((n, set) => n + set.size, 0);
|
|
4529
|
+
const cancelled = () => {
|
|
4530
|
+
console.log(`${DIM$3}Search cancelled${RESET$3}`);
|
|
4531
|
+
console.log();
|
|
4532
|
+
};
|
|
4533
|
+
for (;;) {
|
|
4534
|
+
const total = totalPicked();
|
|
4535
|
+
const options = KINDS.map((k) => {
|
|
4536
|
+
const picked = pickedByKind.get(k.value).size;
|
|
4537
|
+
return {
|
|
4538
|
+
value: k.value,
|
|
4539
|
+
label: k.label,
|
|
4540
|
+
hint: picked > 0 ? `${k.count} · ${picked} selected` : `${k.count} available`
|
|
4541
|
+
};
|
|
4542
|
+
});
|
|
4543
|
+
if (total > 0) options.push({
|
|
4544
|
+
value: "review",
|
|
4545
|
+
label: "Review & install",
|
|
4546
|
+
hint: `${total} selected`
|
|
4547
|
+
});
|
|
4498
4548
|
const kindChoice = await ve({
|
|
4499
4549
|
message: "What are you looking for?",
|
|
4500
|
-
options
|
|
4501
|
-
{
|
|
4502
|
-
value: "skill",
|
|
4503
|
-
label: "Skills",
|
|
4504
|
-
hint: `${skillCount} available`
|
|
4505
|
-
},
|
|
4506
|
-
{
|
|
4507
|
-
value: "agent",
|
|
4508
|
-
label: "Subagents",
|
|
4509
|
-
hint: `${agentCount} available`
|
|
4510
|
-
},
|
|
4511
|
-
{
|
|
4512
|
-
value: "rule",
|
|
4513
|
-
label: "Rules",
|
|
4514
|
-
hint: `${ruleCount} available`
|
|
4515
|
-
}
|
|
4516
|
-
]
|
|
4550
|
+
options
|
|
4517
4551
|
});
|
|
4518
4552
|
if (pD(kindChoice)) {
|
|
4519
|
-
|
|
4520
|
-
console.log();
|
|
4553
|
+
cancelled();
|
|
4521
4554
|
return;
|
|
4522
4555
|
}
|
|
4556
|
+
if (kindChoice === "review") {
|
|
4557
|
+
console.log();
|
|
4558
|
+
for (const kind of KINDS) {
|
|
4559
|
+
const names = [...pickedByKind.get(kind.value)];
|
|
4560
|
+
if (names.length === 0) continue;
|
|
4561
|
+
console.log(`${TEXT$2}${kind.label}${RESET$3} ${DIM$3}(${names.length})${RESET$3}`);
|
|
4562
|
+
for (const name of names) {
|
|
4563
|
+
const note = all.find((s) => s.kind === kind.value && s.name === name)?.installed ? ` ${DIM$3}— already installed, will reinstall${RESET$3}` : "";
|
|
4564
|
+
console.log(` ${DIM$3}·${RESET$3} ${name}${note}`);
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
console.log();
|
|
4568
|
+
const confirmed = await ye({ message: `Install ${total} item${total === 1 ? "" : "s"}?` });
|
|
4569
|
+
if (pD(confirmed)) {
|
|
4570
|
+
cancelled();
|
|
4571
|
+
return;
|
|
4572
|
+
}
|
|
4573
|
+
if (!confirmed) continue;
|
|
4574
|
+
break;
|
|
4575
|
+
}
|
|
4523
4576
|
console.log();
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4577
|
+
const result = await runSearchPrompt(kindChoice, pickedByKind.get(kindChoice));
|
|
4578
|
+
if (result === null) {
|
|
4579
|
+
cancelled();
|
|
4580
|
+
return;
|
|
4581
|
+
}
|
|
4582
|
+
if (result !== "back") pickedByKind.set(kindChoice, result);
|
|
4530
4583
|
}
|
|
4531
|
-
const
|
|
4584
|
+
const skills = [...pickedByKind.get("skill")];
|
|
4585
|
+
const agents = [...pickedByKind.get("agent")];
|
|
4586
|
+
const rules = [...pickedByKind.get("rule")];
|
|
4587
|
+
String(skills.length + agents.length + rules.length);
|
|
4532
4588
|
console.log();
|
|
4533
|
-
if (
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
const pkg = selected.source || selected.slug;
|
|
4537
|
-
console.log(`${TEXT$2}Installing ${BOLD$3}${skillName}${RESET$3} from ${DIM$3}${pkg}${RESET$3}...`);
|
|
4589
|
+
if (skills.length > 0) {
|
|
4590
|
+
const pkg = CATALOG_SOURCE;
|
|
4591
|
+
console.log(`${TEXT$2}Installing ${BOLD$3}${skills.join(", ")}${RESET$3} from ${DIM$3}${pkg}${RESET$3}...`);
|
|
4538
4592
|
console.log();
|
|
4539
4593
|
const { source, options } = parseAddOptions([
|
|
4540
4594
|
pkg,
|
|
4541
4595
|
"--skill",
|
|
4542
|
-
|
|
4596
|
+
...skills
|
|
4543
4597
|
]);
|
|
4544
4598
|
await runAdd(source, options);
|
|
4545
4599
|
}
|
|
4600
|
+
if (agents.length > 0) await addAgents(agents, {});
|
|
4601
|
+
if (rules.length > 0) await addRules(rules, {});
|
|
4546
4602
|
console.log();
|
|
4547
4603
|
console.log(`${DIM$3}Installed.${RESET$3} ${TEXT$2}npx pruff-skills list${RESET$3} ${DIM$3}shows what's installed.${RESET$3}`);
|
|
4548
4604
|
console.log();
|
|
@@ -7852,19 +7908,39 @@ const TEAM_AGENTS = {
|
|
|
7852
7908
|
"codebase-navigator",
|
|
7853
7909
|
"db-query-reviewer",
|
|
7854
7910
|
"pruff-logs-investigator",
|
|
7855
|
-
"implementer"
|
|
7911
|
+
"implementer",
|
|
7912
|
+
"money-integrity-reviewer",
|
|
7913
|
+
"permission-guard-reviewer",
|
|
7914
|
+
"date-window-reviewer",
|
|
7915
|
+
"error-surface-reviewer",
|
|
7916
|
+
"lambda-good-practices-reviewer"
|
|
7856
7917
|
],
|
|
7857
7918
|
core: [
|
|
7858
7919
|
"codebase-navigator",
|
|
7859
7920
|
"pruff-logs-investigator",
|
|
7860
|
-
"implementer"
|
|
7921
|
+
"implementer",
|
|
7922
|
+
"money-integrity-reviewer",
|
|
7923
|
+
"date-window-reviewer",
|
|
7924
|
+
"error-surface-reviewer",
|
|
7925
|
+
"route-permission-reviewer"
|
|
7926
|
+
],
|
|
7927
|
+
growth: [
|
|
7928
|
+
"codebase-navigator",
|
|
7929
|
+
"implementer",
|
|
7930
|
+
"route-permission-reviewer",
|
|
7931
|
+
"error-surface-reviewer"
|
|
7861
7932
|
],
|
|
7862
|
-
growth: ["codebase-navigator", "implementer"],
|
|
7863
7933
|
shared: [
|
|
7864
7934
|
"codebase-navigator",
|
|
7865
7935
|
"db-query-reviewer",
|
|
7866
7936
|
"pruff-logs-investigator",
|
|
7867
|
-
"implementer"
|
|
7937
|
+
"implementer",
|
|
7938
|
+
"money-integrity-reviewer",
|
|
7939
|
+
"permission-guard-reviewer",
|
|
7940
|
+
"date-window-reviewer",
|
|
7941
|
+
"error-surface-reviewer",
|
|
7942
|
+
"route-permission-reviewer",
|
|
7943
|
+
"lambda-good-practices-reviewer"
|
|
7868
7944
|
]
|
|
7869
7945
|
};
|
|
7870
7946
|
const TEAMS = Object.keys(TEAM_SKILLS);
|