Language-aware house style and a resizable chat split

House style now follows the app language: Chinese UI forces the new
bundled humanizer-zh skill into every run, English forces humanizer -
one variant per run, picked by preference with cross-language fallback
so an older catalogue never silently loses house style. Both variants
are protected from grant/revoke, list_skills labels each with its
language, the bundle guard requires both, and startup sync imports the
new skill into existing orgs on next launch. Covered by a unit test
that flips app_state.language and asserts which humanizer compiles.

The chat split is now adjustable: drag the conversation list's right
edge (200-480px, persisted in localStorage) and the composer textarea
grew a native vertical resize grip capped at 40vh.
This commit is contained in:
ZacharyZhang-NY committed 2026-07-09 01:14:05 -04:00
1 parent c027508b97
commit eaaf36f859
16 files changed
+931 -45

No files matched your search

+6
View File
@@ -14,6 +14,12 @@ export function seedBuiltinSkillsFixture(root: string): string {
"---\nname: humanizer\nversion: 2.1.1\ndescription: |\n Remove signs of AI-generated writing from text.\n---\n\nWrite like a person.\n",
"utf8",
);
mkdirSync(join(root, "Humanizer-zh"), { recursive: true });
writeFileSync(
join(root, "Humanizer-zh", "SKILL.md"),
"---\nname: humanizer-zh\nversion: 1.0.0\ndescription: |\n 去除文本中的 AI 生成痕迹。\n---\n\n像真人一样写作。\n",
"utf8",
);
mkdirSync(join(root, "engineering"), { recursive: true });
writeFileSync(
join(root, "engineering", "engineering-backend-architect.md"),
+1 -1
View File
@@ -182,7 +182,7 @@ test("onboards, hires, and creates work in the Electron shell", async () => {
const result = await api.loadSnapshot() as { ok: true; data: { skillDefinitions: Array<{ slug: string }> } };
return result.data.skillDefinitions.map((skill) => skill.slug).sort();
});
expect(skillSlugs).toEqual(["engineering-backend-architect", "humanizer"]);
expect(skillSlugs).toEqual(["engineering-backend-architect", "humanizer", "humanizer-zh"]);
// The global pause toggle lives in the topbar on every page.
const pauseToggle = page.getByRole("button", { name: "Pause agents" });