Build on Candeo
Everything Candeo lights with is a file you can open: an effect is a short TypeScript file, a device is a JSON description, and your other tools talk to it over a local API. Write your own, try it at once, and share it if you like.
Four ways in
Write an effect
A function that, thirty times a second, gets the keyboard and the time and paints every key. Settings people can change, the sound, your typing, signals.
Write an effect →Describe a device
How to find it, the bytes it expects, where its lights sit and the effects its firmware runs — as data, no code and no rebuild.
Describe a device →Send signals
A named value from a script, a build or Home Assistant, which rules and settings follow. Off until you turn it on, and every request carries a token.
Send signals →Connect an assistant
Claude, Codex, GitHub Copilot, Cursor or VS Code read your devices, layouts, effects and the effects API through MCP, to help you write an effect. Off until you turn it on.
Connect an assistant →Effects can also follow the music: what Candeo hears, and how a setting follows it.
Your files, in your folder
What you write lives in your Documents, where you can back it up, version it
or share it:
Documents\candeo\effects— one.tsfile per effect;Documents\candeo\devices— one.jsonfile per device definition.
The ones Candeo ships are listed beside yours and open read only. Duplicate an effect, or Copy to yours a device definition, to start from one that works. A file dropped in the folder shows up after Refresh.
The editor
Candeo opens both kinds of file in its own editor — the one behind Visual Studio Code — and checks them as you type: an effect against the effects API, with completion and the types of everything it receives; a device definition against its schema, with the documentation of each field on hover.
- Ctrl+S puts the text in shape and saves it;
- F1, or the ⌨ button, lists the other shortcuts;
- an effect plays in the simulator as soon as it is saved; a device definition takes effect on the device at once, when it is the one the device uses.
Prefer your own editor? Edit the files there, then Refresh.
References
- The effects API — every type and helper an effect can use, as the editor knows them.
-
The device definition schema — every field
of a definition, and what it accepts. Name it in
$schemaand any editor that reads JSON schemas checks your file. - The signals API — the one local endpoint, its token and what it accepts.
- The MCP server — the tools and resources an assistant reads, and what it is never given.
- The shipped effects and the built-in device definitions — written against the same API and schema as yours.
How Candeo is built
- The protocols are documented, with how each fact was established and the firmware version behind it — docs/protocol.
- Decisions are written before the code, and kept when they turn out wrong — docs/design.
- A device is data, read by one interpreter, and every built-in definition replays reference frames captured on the device: the tests check the bytes without the hardware.
- One engine runs the effects, in Rust, in a thread that outlives the window: closing it changes nothing on the keyboard.
The protocols were established by observing the hardware: USB captures, then writes and reads checked one by one. Facts about a protocol are not subject to copyright, and surveying them for interoperability is provided for by Article L.122-6-1 IV of the French Intellectual Property Code, transposing Directive 2009/24/EC, Article 6.
Contribute
Candeo is a Tauri application — Rust underneath, Vue and TypeScript for the window — under the GPL, version 3 only. To run it from source, with stable Rust 1.97 or later, Node 22 or later and pnpm 10 or later:
AGENTS.md holds the rules for changing the repository and the checks CI runs. A device of yours can become a built-in one: see making it built in.
What comes next
- The computer as a source — CPU, memory and network for effects and settings, then temperatures and the GPU (#242).
- More devices, contributed — what a protocol contribution carries to be reviewable by someone without the hardware.
- Linux with a real device, then the nobody at the computer trigger there (#183).
- winget — installing and updating in one command.