diff --git a/server/src/__tests__/agent-skills-routes.test.ts b/server/src/__tests__/agent-skills-routes.test.ts index 07c40f7cf3d..1ba32715fa5 100644 --- a/server/src/__tests__/agent-skills-routes.test.ts +++ b/server/src/__tests__/agent-skills-routes.test.ts @@ -44,6 +44,7 @@ const mockAgentInstructionsService = vi.hoisted(() => ({ const mockCompanySkillService = vi.hoisted(() => ({ listRuntimeSkillEntries: vi.fn(), + resolveRequestedSkillEntries: vi.fn(), resolveRequestedSkillKeys: vi.fn(), })); @@ -258,6 +259,13 @@ describe.sequential("agent skill routes", () => { : value, ), ); + mockCompanySkillService.resolveRequestedSkillEntries.mockImplementation( + async (_companyId: string, requested: Array<{ key: string; versionId?: string | null }>) => + requested.map((entry) => ({ + key: entry.key === "paperclip" ? "paperclipai/paperclip/paperclip" : entry.key, + versionId: entry.versionId ?? null, + })), + ); mockAdapter.listSkills.mockResolvedValue({ adapterType: "claude_local", supported: true, @@ -338,9 +346,10 @@ describe.sequential("agent skill routes", () => { ); expect(res.status, JSON.stringify(res.body)).toBe(200); - expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", { + expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", expect.objectContaining({ materializeMissing: false, - }); + versionSelections: expect.any(Map), + })); expect(mockAdapter.listSkills).toHaveBeenCalledWith( expect.objectContaining({ adapterType: "claude_local", @@ -369,9 +378,10 @@ describe.sequential("agent skill routes", () => { ); expect(res.status, JSON.stringify(res.body)).toBe(200); - expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", { + expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", expect.objectContaining({ materializeMissing: false, - }); + versionSelections: expect.any(Map), + })); }); it("passes ACPX Claude config through the agent skill listing route", async () => { @@ -398,9 +408,10 @@ describe.sequential("agent skill routes", () => { ); expect(res.status, JSON.stringify(res.body)).toBe(200); - expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", { + expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", expect.objectContaining({ materializeMissing: false, - }); + versionSelections: expect.any(Map), + })); expect(mockAdapter.listSkills).toHaveBeenCalledWith( expect.objectContaining({ adapterType: "acpx_local", @@ -485,9 +496,10 @@ describe.sequential("agent skill routes", () => { ); expect(res.status, JSON.stringify(res.body)).toBe(200); - expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", { + expect(mockCompanySkillService.listRuntimeSkillEntries).toHaveBeenCalledWith("company-1", expect.objectContaining({ materializeMissing: false, - }); + versionSelections: expect.any(Map), + })); }); it("skips runtime materialization when syncing Claude skills", async () => { diff --git a/server/src/routes/openapi.ts b/server/src/routes/openapi.ts index 81b900610f9..ab1cc85bb16 100644 --- a/server/src/routes/openapi.ts +++ b/server/src/routes/openapi.ts @@ -4268,7 +4268,19 @@ for (const route of [ ["get", "/api/skills/catalog/{catalogId}", "Get a catalog skill"], ["get", "/api/skills/catalog/{catalogId}/files", "List catalog skill files"], ["post", "/api/companies/{companyId}/skills/install-catalog", "Install a catalog skill"], + ["get", "/api/companies/{companyId}/skills/categories", "List company skill categories"], ["post", "/api/companies/{companyId}/skills/{skillId}/audit", "Audit a company skill"], + ["patch", "/api/companies/{companyId}/skills/{skillId}", "Update a company skill"], + ["get", "/api/companies/{companyId}/skills/{skillId}/versions", "List skill versions"], + ["post", "/api/companies/{companyId}/skills/{skillId}/versions", "Create a skill version"], + ["get", "/api/companies/{companyId}/skills/{skillId}/versions/{versionId}", "Get a skill version"], + ["post", "/api/companies/{companyId}/skills/{skillId}/star", "Star a company skill"], + ["delete", "/api/companies/{companyId}/skills/{skillId}/star", "Unstar a company skill"], + ["post", "/api/companies/{companyId}/skills/{skillId}/fork", "Fork a company skill"], + ["get", "/api/companies/{companyId}/skills/{skillId}/comments", "List skill comments"], + ["post", "/api/companies/{companyId}/skills/{skillId}/comments", "Create a skill comment"], + ["patch", "/api/companies/{companyId}/skills/{skillId}/comments/{commentId}", "Update a skill comment"], + ["delete", "/api/companies/{companyId}/skills/{skillId}/comments/{commentId}", "Delete a skill comment"], ["post", "/api/companies/{companyId}/skills/{skillId}/reset", "Reset a company skill"], ] as const) { registerCurrentRoute({