Files
04ecb58e70 feat(skills): redesign available skills modal layout and grouping (#720)
* feat(skills): redesign available skills modal layout and grouping

Polish the conversation skills modal with scoped sections, clearer header
controls, monochrome pills, and consistent spacing while runtime or data loads.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): align modal section labels with API terminology

Rename Personal/Built-in section headers to User skills and Public skills
so the Available Skills modal matches load_user/load_public naming.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor: translation.json

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: hieptl <hieptl.developer@gmail.com>
2026-05-22 15:38:33 +07:00

67 lines
2.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { SkillInfo } from "#/types/settings";
import { getSkillScope, groupSkillsByScope } from "#/utils/skill-scope";
function buildSkill(overrides: Partial<SkillInfo> = {}): SkillInfo {
return {
name: "test-skill",
type: "knowledge",
source: null,
...overrides,
};
}
describe("getSkillScope", () => {
it("classifies public catalog skills", () => {
expect(
getSkillScope(
buildSkill({
source: "/Users/test/.openhands/cache/skills/public-skills/skills/deno/SKILL.md",
}),
),
).toBe("public");
expect(getSkillScope(buildSkill({ source: "public" }))).toBe("public");
});
it("classifies personal user skills from home directories", () => {
expect(
getSkillScope(
buildSkill({
source: "/Users/test/.agents/skills/my-skill/SKILL.md",
}),
),
).toBe("personal");
expect(getSkillScope(buildSkill({ source: "user" }))).toBe("personal");
});
it("classifies project skills from the workspace", () => {
const projectDir = "/workspace/project/agent-canvas";
expect(
getSkillScope(
buildSkill({
source: `${projectDir}/.agents/skills/default-tools/SKILL.md`,
}),
projectDir,
),
).toBe("project");
expect(getSkillScope(buildSkill({ source: "project" }))).toBe("project");
});
});
describe("groupSkillsByScope", () => {
it("groups and sorts skills by scope", () => {
const grouped = groupSkillsByScope([
buildSkill({ name: "beta", source: "public" }),
buildSkill({ name: "alpha", source: "user" }),
buildSkill({
name: "gamma",
source: "/workspace/project/.agents/skills/gamma/SKILL.md",
}),
], "/workspace/project");
expect(grouped.public.map((skill) => skill.name)).toEqual(["beta"]);
expect(grouped.personal.map((skill) => skill.name)).toEqual(["alpha"]);
expect(grouped.project.map((skill) => skill.name)).toEqual(["gamma"]);
});
});