Circadian
Automatically switch your opencode TUI theme by time of day — a day theme and a night theme, with a gentle manual override.
0
893
359 in 7 days
38.1
Multi-signal model
1 hour ago
2026-10-05
Install and configure
opencode.jsonWrites to this project's opencode.json — applies to this repository only.
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-circadian@0.3.2"]
}Writes to ~/.config/opencode/opencode.json — applies to every project.
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-circadian@0.3.2"]
}If you want to modify the plugin locally, install it into the project and reference the local path.
shell
pnpm add -D opencode-circadianOpenCode loads npm dependencies through its embedded runtime on startup and caches them locally — no manual global install needed.
Automatically switch your opencode TUI theme by time of day — a day theme and a night theme — with a gentle manual override.
Two modes:
fixed(default) — day/night boundaries are hours you configure.solar— boundaries follow the actual sunrise/sunset for a latitude/longitude you configure (day between sunrise and sunset).
Features:
- Applies the right theme at launch (corrects it if the wrong one was selected).
- Switches live at the day/night boundary while opencode is running.
- Respects manual
/themechanges: if you switch themes mid-period, circadian leaves it alone until the next boundary. - Shows a small toast whenever it actually switches (
☀ day theme/☾ night theme). Silent when the theme is already correct.
Install
Add it to your tui.json (~/.config/opencode/tui.json) plugin array:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": ["opencode-circadian@latest"]
}
opencode installs npm plugins automatically at startup. Restart opencode and
you're set — with no options it uses catppuccin during the day and aura at
night (both built-in themes).
Configuration
Pass options using the tuple form ([spec, options]):
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
["opencode-circadian@latest", {
"mode": "fixed",
"dayTheme": "everforest",
"nightTheme": "tokyonight",
"dayStartHour": 6,
"nightStartHour": 20,
"checkIntervalMs": 60000,
"toast": true
}]
]
}
| Option | Type | Default | Description |
|---|---|---|---|
mode |
"fixed" | "solar" |
"fixed" |
How day/night boundaries are determined (see below). |
dayTheme |
string |
"catppuccin" |
Theme applied during the day. |
nightTheme |
string |
"aura" |
Theme applied at night. |
dayStartHour |
number |
7 |
Fixed mode. Hour (0–23, local time) the day period begins. |
nightStartHour |
number |
19 |
Fixed mode. Hour (0–23, local time) the night period begins. |
latitude |
number |
— | Solar mode. Degrees, -90–90 (required for solar mode). |
longitude |
number |
— | Solar mode. Degrees, -180–180 (required for solar mode). |
checkIntervalMs |
number |
60000 |
Fallback re-check interval (clamped to 1000–86400000). |
toast |
boolean |
true |
Show a toast when the theme switches. |
Invalid values fall back to their defaults. In fixed mode, boundaries may wrap
across midnight — e.g. dayStartHour: 20, nightStartHour: 6 makes "day" span
20:00–05:59.
Solar mode
Set mode to "solar" and provide your latitude/longitude. The day theme
applies between sunrise and sunset, the night theme the rest of the time.
Sunrise and sunset are recomputed each day, so the boundaries track the seasons
automatically. No timezone is needed — the calculation uses absolute time.
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
["opencode-circadian@latest", {
"mode": "solar",
"dayTheme": "everforest",
"nightTheme": "tokyonight",
"latitude": 42.70,
"longitude": 23.32
}]
]
}
Finding your latitude/longitude (one time): search your city on OpenStreetMap or Google Maps, right-click your location, and copy the two numbers (latitude first, then longitude). Paste them into the config. A couple of decimal places is plenty of precision.
If mode is "solar" but latitude/longitude are missing or out of range,
the plugin falls back to fixed mode with the default hours, so it never gets
stuck. In polar regions, days when the sun never sets use the day theme and days
when it never rises use the night theme.
How it behaves
- On launch: applies the correct theme for the current time. If that means changing away from whatever was selected, you get a toast. If it was already correct, nothing happens.
- While running: it switches when the day/night boundary is crossed (a fixed
hour, or the day's sunrise/sunset in solar mode), on time regardless of
checkIntervalMs. A manual/themechange survives until the next boundary. - After sleep: if the machine slept through one or more boundaries, the theme for the current period is re-applied on wake, even if the period is the same as before sleep.
- Missing theme: if a configured theme isn't installed, it warns once via a toast at the boundary and leaves the current theme unchanged (it won't spam the warning every tick).
- Unexpected errors: it never crashes opencode. Each distinct error is
written once to the opencode log (service
opencode-circadian, up to 20 per session), you get a single warning toast, and it keeps retrying.
Requirements
- opencode with the TUI plugin API (
api.theme.set/has/selected). - The configured theme names must exist — either built-in themes or ones you've installed.
- A truecolor (24-bit) terminal for correct theme rendering.
Contributing
Contributions are welcome! See CONTRIBUTING.md for the dev setup and conventions. Please also read the Code of Conduct.
Changelog
See CHANGELOG.md.
License
MIT © Ventsislav Kostadinov
Similar plugins
Tui Quota Usage
opencode-tui-quota-usage
OpenCode quota usage sidebar tracker for OpenCode V2 CLI/TUI
Pty
opencode-pty
OpenCode plugin for interactive PTY management - run background processes, send input, read output with regex filtering
Bg
@imransyafi/opencode-bg
OpenCode plugin for interactive PTY management - run background processes, send input, read output with regex filtering