eleven / messenger Public

Clone
git clone https://amadan.net/eleven/messenger

Plain git — no account needed to clone.

Download

Download this file

1// Action chips: the Claude tools a helper may call, and the mapping from the
2// model's tool_use blocks to the `actions` array shipped inside the encrypted
3// message payload. The CLIENT is the whitelist that matters (ui.js
4// sanitizeActions) — this file only decides what the model can *propose*.
5// Chips never auto-run: the member taps to apply, which is why the set is
6// small, harmless, and reversible. Dependency-free so tests can import it.
7
8// Keep the theme list + descriptions in step with web/static/ui.js THEMES.
9// Exported so the deterministic command floor (commands.mjs) validates against
10// the same lists the model tools do.
11export const THEMES = ["litroom", "lagoon", "sunny", "plum", "linen", "classic"];
12export const APPEARANCES = ["light", "dark", "system"];
13
14export const CHIP_TOOLS = [
15 {
16 name: "set_theme",
17 description:
18 "Attach a one-tap button that switches the member's colour theme when THEY tap it. " +
19 "Themes: litroom (warm amber 'Lit Room'), lagoon (teal), sunny (yellow), plum (purple), " +
20 "linen (soft neutral), classic (blue). Use when someone asks to change the look/colours.",
21 input_schema: {
22 type: "object",
23 properties: { theme: { type: "string", enum: THEMES } },
24 required: ["theme"],
25 },
26 },
27 {
28 name: "set_appearance",
29 description:
30 "Attach a one-tap button that switches light/dark mode when the member taps it. " +
31 "'system' follows their device. Use when someone asks for light mode, dark mode, etc.",
32 input_schema: {
33 type: "object",
34 properties: { appearance: { type: "string", enum: ["light", "dark", "system"] } },
35 required: ["appearance"],
36 },
37 },
38 {
39 name: "open_theme_picker",
40 description:
41 "Attach a one-tap button that opens the theme picker, for when they want to browse the options.",
42 input_schema: { type: "object", properties: {} },
43 },
44 {
45 name: "open_profile",
46 description:
47 "Attach a one-tap button that opens the member's own profile editor (screen name + photo).",
48 input_schema: { type: "object", properties: {} },
49 },
50];
51
52// actionsFromToolUse maps the response's tool_use blocks to payload actions.
53// Unknown tools and malformed inputs are dropped (the client re-validates too).
54export function actionsFromToolUse(content) {
55 const out = [];
56 for (const b of content || []) {
57 if (b.type !== "tool_use") continue;
58 const input = b.input || {};
59 if (b.name === "set_theme" && THEMES.includes(input.theme)) out.push({ type: "set_theme", theme: input.theme });
60 else if (b.name === "set_appearance" && APPEARANCES.includes(input.appearance))
61 out.push({ type: "set_appearance", appearance: input.appearance });
62 else if (b.name === "open_theme_picker") out.push({ type: "open_theme_picker" });
63 else if (b.name === "open_profile") out.push({ type: "open_profile" });
64 }
65 return out;
66}
67