Skip to content

Commit 3122ef0

Browse files
A prune-only run summarizes as removal, never as an empty state
Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
1 parent 66e2d06 commit 3122ef0

2 files changed

Lines changed: 36 additions & 8 deletions

File tree

packages/cli/src/commands/skills/presentation.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,19 @@ function unmanagedClause(count: number): string {
2424
}
2525

2626
function syncSummary(result: SkillsSyncResult): string {
27-
if (result.agents.length === 0) {
28-
return "No agents are configured to sync skills for.";
29-
}
30-
if (result.packages.length === 0) {
31-
return "No Prisma packages with agent skills are installed.";
32-
}
33-
if (result.skills.length === 0) {
34-
return "No Prisma dependencies in your project ship agent skills to sync.";
27+
// The empty-state sentences hold only when this run also removed
28+
// nothing; a prune is work done, and its summary must match the
29+
// Removed table rendered beneath it.
30+
if (result.pruned.length === 0) {
31+
if (result.agents.length === 0) {
32+
return "No agents are configured to sync skills for.";
33+
}
34+
if (result.packages.length === 0) {
35+
return "No Prisma packages with agent skills are installed.";
36+
}
37+
if (result.skills.length === 0) {
38+
return "No Prisma dependencies in your project ship agent skills to sync.";
39+
}
3540
}
3641
const refusedDirs = result.refused.reduce(
3742
(count, skill) => count + skill.dirs.length,
@@ -40,6 +45,10 @@ function syncSummary(result: SkillsSyncResult): string {
4045
if (result.synced.length === 0 && result.pruned.length === 0) {
4146
return `Agent skills are up to date${unmanagedClause(refusedDirs)}.`;
4247
}
48+
const removed = `${result.pruned.length} skill${result.pruned.length === 1 ? "" : "s"}`;
49+
if (result.synced.length === 0 && result.pruned.length > 0) {
50+
return `Removed ${removed}${unmanagedClause(refusedDirs)}.`;
51+
}
4352
const synced = `${result.synced.length} skill${result.synced.length === 1 ? "" : "s"}`;
4453
const base =
4554
result.pruned.length === 0

packages/cli/tests/skills-sync.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,25 @@ describe("skills sync", () => {
330330
).toBe(true);
331331
});
332332

333+
it("summarizes a prune-only run as removal, not as an empty state", async () => {
334+
const root = await makeProjectRoot();
335+
await seedSyncedSkill(root, ".claude/skills", {
336+
skill: "prisma-8",
337+
library: "@prisma/orm-postgres",
338+
version: "8.1.0",
339+
});
340+
341+
const run = await makeCli().run(["skills", "sync"], {
342+
cwd: root,
343+
isTty: { stdout: true, stderr: true },
344+
});
345+
346+
expect(run.exitCode).toBe(0);
347+
expect(run.stderr).toContain("Removed 1 skill.");
348+
expect(run.stderr).not.toContain("are installed");
349+
expect(run.stderr).not.toContain("ship agent skills");
350+
});
351+
333352
it("keeps a skill still shipped by another installed package", async () => {
334353
const root = await makeProjectRoot();
335354
await installPackage(root, {

0 commit comments

Comments
 (0)