Revert "feat(skills): add dryRun flag for scan prune path"

This reverts commit 13f0fee7d86334291f6faa2794ba67e9c7e90f35.
This commit is contained in:
2026-04-13 00:36:53 +00:00
parent e739a2d130
commit 6094081a71
8 changed files with 1 additions and 92 deletions
-2
View File
@@ -176,7 +176,6 @@ export type {
CompanySkillProjectScanRequest,
CompanySkillProjectScanSkipped,
CompanySkillProjectScanConflict,
CompanySkillProjectScanPruned,
CompanySkillProjectScanResult,
CompanySkillCreateRequest,
CompanySkillFileDetail,
@@ -562,7 +561,6 @@ export {
companySkillProjectScanRequestSchema,
companySkillProjectScanSkippedSchema,
companySkillProjectScanConflictSchema,
companySkillProjectScanPrunedSchema,
companySkillProjectScanResultSchema,
companySkillCreateSchema,
companySkillFileDetailSchema,
@@ -93,7 +93,6 @@ export interface CompanySkillImportResult {
export interface CompanySkillProjectScanRequest {
projectIds?: string[];
workspaceIds?: string[];
dryRun?: boolean;
}
export interface CompanySkillProjectScanSkipped {
@@ -119,14 +118,6 @@ export interface CompanySkillProjectScanConflict {
reason: string;
}
export interface CompanySkillProjectScanPruned {
skillId: string;
slug: string;
key: string;
sourceLocator: string | null;
affectedAgents: string[];
}
export interface CompanySkillProjectScanResult {
scannedProjects: number;
scannedWorkspaces: number;
@@ -135,9 +126,7 @@ export interface CompanySkillProjectScanResult {
updated: CompanySkill[];
skipped: CompanySkillProjectScanSkipped[];
conflicts: CompanySkillProjectScanConflict[];
pruned: CompanySkillProjectScanPruned[];
warnings: string[];
dryRun: boolean;
}
export interface CompanySkillCreateRequest {
-1
View File
@@ -28,7 +28,6 @@ export type {
CompanySkillProjectScanRequest,
CompanySkillProjectScanSkipped,
CompanySkillProjectScanConflict,
CompanySkillProjectScanPruned,
CompanySkillProjectScanResult,
CompanySkillCreateRequest,
CompanySkillFileDetail,
@@ -76,7 +76,6 @@ export const companySkillUpdateAuthSchema = z.object({
export const companySkillProjectScanRequestSchema = z.object({
projectIds: z.array(z.string().uuid()).optional(),
workspaceIds: z.array(z.string().uuid()).optional(),
dryRun: z.boolean().optional(),
});
export const companySkillProjectScanSkippedSchema = z.object({
@@ -102,14 +101,6 @@ export const companySkillProjectScanConflictSchema = z.object({
reason: z.string().min(1),
});
export const companySkillProjectScanPrunedSchema = z.object({
skillId: z.string().uuid(),
slug: z.string().min(1),
key: z.string().min(1),
sourceLocator: z.string().nullable(),
affectedAgents: z.array(z.string()),
});
export const companySkillProjectScanResultSchema = z.object({
scannedProjects: z.number().int().nonnegative(),
scannedWorkspaces: z.number().int().nonnegative(),
@@ -118,9 +109,7 @@ export const companySkillProjectScanResultSchema = z.object({
updated: z.array(companySkillSchema),
skipped: z.array(companySkillProjectScanSkippedSchema),
conflicts: z.array(companySkillProjectScanConflictSchema),
pruned: z.array(companySkillProjectScanPrunedSchema),
warnings: z.array(z.string()),
dryRun: z.boolean(),
});
export const companySkillCreateSchema = z.object({
-1
View File
@@ -48,7 +48,6 @@ export {
companySkillProjectScanRequestSchema,
companySkillProjectScanSkippedSchema,
companySkillProjectScanConflictSchema,
companySkillProjectScanPrunedSchema,
companySkillProjectScanResultSchema,
companySkillCreateSchema,
companySkillFileDetailSchema,
@@ -282,46 +282,4 @@ describeEmbeddedPostgres("scanProjectWorkspaces prune path", () => {
]),
);
});
it("reports pruned skills without deleting when dryRun is true", async () => {
stubGitHubSource(["keep-skill"]);
const { companySkillService } = await import("../services/company-skills.js");
const svc = companySkillService(db);
const result = await svc.scanProjectWorkspaces(companyId, { dryRun: true });
// The result should flag dryRun and list what would be pruned
expect(result.dryRun).toBe(true);
expect(result.pruned).toEqual(
expect.arrayContaining([
expect.objectContaining({
slug: "prune-skill",
affectedAgents: expect.arrayContaining(["Builder"]),
}),
]),
);
// No warnings emitted (nothing was actually deleted)
const pruneWarnings = result.warnings.filter((w) => w.includes("prune-skill"));
expect(pruneWarnings).toHaveLength(0);
// Both skills should still exist in the database
const remaining = await db
.select()
.from(companySkills)
.where(eq(companySkills.companyId, companyId));
const remainingSlugs = remaining.map((r) => r.slug);
expect(remainingSlugs).toContain("keep-skill");
expect(remainingSlugs).toContain("prune-skill");
// Agent config should be unchanged
const [agentRow] = await db
.select()
.from(agents)
.where(eq(agents.id, agentId));
const config = agentRow!.adapterConfig as Record<string, unknown>;
const syncConfig = config.paperclipSkillSync as Record<string, unknown>;
const desiredSkills = syncConfig.desiredSkills as string[];
expect(desiredSkills).toContain("test-org/test-skills/prune-skill");
});
});
@@ -78,9 +78,7 @@ describe("company skill mutation permissions", () => {
updated: [],
skipped: [],
conflicts: [],
pruned: [],
warnings: [],
dryRun: false,
});
mockLogActivity.mockResolvedValue(undefined);
mockAccessService.canUser.mockResolvedValue(true);
@@ -295,13 +293,9 @@ describe("company skill mutation permissions", () => {
updated: [],
skipped: [],
conflicts: [],
pruned: [
{ skillId: "skill-1", slug: "ghost-skill", key: "vercel-labs/agent-browser/ghost-skill", sourceLocator: "https://github.com/vercel-labs/agent-browser", affectedAgents: ["Builder"] },
],
warnings: [
'Skill "ghost-skill" was removed from https://github.com/vercel-labs/agent-browser and detached from Builder.',
],
dryRun: false,
});
const res = await request(await createApp({
+1 -18
View File
@@ -17,7 +17,6 @@ import type {
CompanySkillImportResult,
CompanySkillListItem,
CompanySkillProjectScanConflict,
CompanySkillProjectScanPruned,
CompanySkillProjectScanRequest,
CompanySkillProjectScanResult,
CompanySkillProjectScanSkipped,
@@ -1861,10 +1860,8 @@ export function companySkillService(db: Db) {
? await projects.listByIds(companyId, input.projectIds)
: await projects.list(companyId);
const workspaceFilter = new Set(input.workspaceIds ?? []);
const dryRun = input.dryRun === true;
const skipped: CompanySkillProjectScanSkipped[] = [];
const conflicts: CompanySkillProjectScanConflict[] = [];
const pruned: CompanySkillProjectScanPruned[] = [];
const warnings: string[] = [];
const imported: CompanySkill[] = [];
const updated: CompanySkill[] = [];
@@ -2046,18 +2043,6 @@ export function companySkillService(db: Db) {
for (const skill of skillsAtSource) {
if (currentSlugs.has(skill.slug)) continue;
const usedByAgents = await usage(companyId, skill.key);
const affectedAgentNames = usedByAgents.map((a) => a.name);
pruned.push({
skillId: skill.id,
slug: skill.slug,
key: skill.key,
sourceLocator: skill.sourceLocator,
affectedAgents: affectedAgentNames,
});
if (dryRun) continue;
if (usedByAgents.length > 0) {
// Detach the skill from all agents that have it, then delete
for (const agent of usedByAgents) {
@@ -2074,7 +2059,7 @@ export function companySkillService(db: Db) {
}
}
warnings.push(
`Skill "${skill.slug}" was removed from ${sourceLocator} and detached from ${affectedAgentNames.join(", ")}.`,
`Skill "${skill.slug}" was removed from ${sourceLocator} and detached from ${usedByAgents.map((a) => a.name).join(", ")}.`,
);
} else {
warnings.push(
@@ -2097,9 +2082,7 @@ export function companySkillService(db: Db) {
updated,
skipped,
conflicts,
pruned,
warnings,
dryRun,
};
}