// Action chips: the Claude tools a helper may call, and the mapping from the // model's tool_use blocks to the `actions` array shipped inside the encrypted // message payload. The CLIENT is the whitelist that matters (ui.js // sanitizeActions) — this file only decides what the model can *propose*. // Chips never auto-run: the member taps to apply, which is why the set is // small, harmless, and reversible. Dependency-free so tests can import it. // Keep the theme list + descriptions in step with web/static/ui.js THEMES. // Exported so the deterministic command floor (commands.mjs) validates against // the same lists the model tools do. export const THEMES = ["litroom", "lagoon", "sunny", "plum", "linen", "classic"]; export const APPEARANCES = ["light", "dark", "system"]; export const CHIP_TOOLS = [ { name: "set_theme", description: "Attach a one-tap button that switches the member's colour theme when THEY tap it. " + "Themes: litroom (warm amber 'Lit Room'), lagoon (teal), sunny (yellow), plum (purple), " + "linen (soft neutral), classic (blue). Use when someone asks to change the look/colours.", input_schema: { type: "object", properties: { theme: { type: "string", enum: THEMES } }, required: ["theme"], }, }, { name: "set_appearance", description: "Attach a one-tap button that switches light/dark mode when the member taps it. " + "'system' follows their device. Use when someone asks for light mode, dark mode, etc.", input_schema: { type: "object", properties: { appearance: { type: "string", enum: ["light", "dark", "system"] } }, required: ["appearance"], }, }, { name: "open_theme_picker", description: "Attach a one-tap button that opens the theme picker, for when they want to browse the options.", input_schema: { type: "object", properties: {} }, }, { name: "open_profile", description: "Attach a one-tap button that opens the member's own profile editor (screen name + photo).", input_schema: { type: "object", properties: {} }, }, ]; // actionsFromToolUse maps the response's tool_use blocks to payload actions. // Unknown tools and malformed inputs are dropped (the client re-validates too). export function actionsFromToolUse(content) { const out = []; for (const b of content || []) { if (b.type !== "tool_use") continue; const input = b.input || {}; if (b.name === "set_theme" && THEMES.includes(input.theme)) out.push({ type: "set_theme", theme: input.theme }); else if (b.name === "set_appearance" && APPEARANCES.includes(input.appearance)) out.push({ type: "set_appearance", appearance: input.appearance }); else if (b.name === "open_theme_picker") out.push({ type: "open_theme_picker" }); else if (b.name === "open_profile") out.push({ type: "open_profile" }); } return out; }