Official
themes
The stock themes: presets of every colour, type size, corner and density token, chosen per light and dark mode and edited in Settings.
The app opens the listing; nothing installs until an agent in your Plugins workspace has read the files and you enable the plugin. In a terminal: cvg install convergence/themes@0.3.0
Permissions in 0.3.0
Files
settings-model.ts1.2 KB
// The plugin's settings read safely: a hand-edited file with a bad shape
// keeps the defaults instead of failing the plugin.
import * as z from "zod";
import type { SettingValue } from "convergence";
import { allPresets, chosen, duplicate, STOCK } from "./presets.ts";
import type { Preset, ThemeSettings } from "./presets.ts";
export { allPresets, chosen, duplicate, STOCK };
export type { Preset, ThemeSettings };
const presetSchema = z.object({
name: z.string(),
mode: z.enum(["light", "dark"]),
tokens: z.record(z.string(), z.unknown()),
});
/** The settings, with anything malformed dropped. */
export function readSettings(values: Readonly<Record<string, SettingValue>>): ThemeSettings {
const presets: Record<string, Omit<Preset, "id" | "stock">> = {};
const rawPresets = z.record(z.string(), z.unknown()).safeParse(values["presets"]);
for (const [id, raw] of Object.entries(rawPresets.success ? rawPresets.data : {})) {
const parsed = presetSchema.safeParse(raw);
if (parsed.success) presets[id] = parsed.data as Omit<Preset, "id" | "stock">;
}
const active = z.object({ light: z.string().optional(), dark: z.string().optional() }).safeParse(values["active"]);
return { presets, active: active.success ? active.data : {} };
}Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.3.0latest | Oct 5, 2026 | >=2 <3 | 7.9 KB | 1 permission | Listed |
No comments yet.