aboutsummaryrefslogtreecommitdiffstats
path: root/AGENTS.md
blob: 0de3b9bc7b997badbea550273b3c54a8701e0b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# AGENTS.md

Guidance for AI coding agents working in this repository.

## What this is

`deck-it` turns an Android tablet into a second monitor, a stream-deck and an
always-on control surface for a Slackware Hyprland desktop. The PC serves a web
page on a Unix socket and exposes it to the tablet with `adb reverse`; `wayvnc`
streams a headless output to AVNC. Python 3.11+ standard library, plus
`websocket-client` for obs-websocket. Plain HTML/CSS/JS frontend, bash launcher.
Keep the server dependency-free apart from that one package.

## How it fits together

- `deckit/server.py` is the stdlib HTTP server: it listens on
  `$XDG_RUNTIME_DIR/deck-it/http.sock`, serves `static/`, `/theme.css`,
  `/icons/<name>.svg` and `/api/<module>[/<action>]`.
- A module is `deckit/modules/<name>.py` exporting `make(cfg) -> Module`; the
  registry discovers files lazily. `state()` is read, `actions` are
  allow-listed, and the client sends ids, never commands.
- The page shell (`static/app.js`) builds tabs from each panel's `tab` property,
  mounts panels and polls `/api/<module>`.
- `deckit/theme.py` reads UDT's palette (`~/.config/rofi/udt/palette.rasi`) and
  `~/.cache/udt/udt-border.lua`; the frontend uses only those CSS variables.
  Text size is keystone's (`~/.config/keystone/fonts.json`, `override.deckit`
  else `base`) as `--udt-font-size` on `html`, so `deck.css` sizes text in
  `rem`. The shell re-reads `/theme.css` every 5s, so changes reach an open page.
- Launcher icons follow the icon theme Keystone sets (`gsettings
  org.gnome.desktop.interface icon-theme`); window icons resolve through the
  `.desktop` `Icon`/`StartupWMClass` mapping.
- `deckit/display.py` creates the headless output, centres it under the first
  monitor for `position = "auto-below"`, and paints it with the first monitor's
  swaybg image.
- The launcher (`deck-it`) handles USB and Wi-Fi (`pair`/`wifi`), the tunnels,
  wayvnc and AVNC. `adb mdns` may be unsupported; `deck-it wifi <ip:port>` or
  `[wifi] address` gives an explicit one; otherwise the last address that
  worked (`~/.config/deck-it/last-wifi`, kept across `stop` and reboots).
  `[display] enabled = false` skips the headless output, wayvnc and AVNC.
  `deck-it status` prints one JSON line for keystone's page; keep its keys.
- Config: `deckit/config.py` merges `~/.config/deck-it/config.toml` over the
  shipped `config.toml` per key within each table (a list is replaced whole).
  Keystone's deck-it page (quickshell repo, `desktop/modules/deckit`) writes
  that sparse file and reads the defaults from `deck-it defaults`; keep that
  JSON shape stable.
- A panel whose source can be switched off (OBS, build VM, LLM, K1C) shows
  `static/offline.js`'s card, not raw error text; the error goes in its tooltip.
- `k1c` reads a Klipper printer through Moonraker (`[k1c] url`); its one action
  is the emergency stop, a press-and-hold button on the tab. While the printer
  is off it backs off 10s between tries. The camera snapshot and the slicer
  thumbnail are loaded by the tablet straight from the printer.
- The page holds a Screen Wake Lock while visible, so the tablet never sleeps
  over the dashboard; nothing on the tablet's settings is changed.
- Launchers are `[launch] apps`, desktop ids run with `gtk-launch`; label and
  icon come from the `.desktop` file. The client sends the id, which must be
  configured and installed.

## Conventions

- New behaviour goes in a module under `deckit/modules/`, not in the server.
- Panels keep their scoped wrapper class (`.music`, `.sbb`, `.llm`, `.windows`)
  because the CSS is scoped to it.
- Hyprland Lua: a dispatcher must be wrapped in `hl.dispatch(...)` to execute.
  `hyprctl eval` alone only builds the dispatcher object.
- No personal data in code, docs, tests or commits; use placeholders.

## Testing

    python3 -m unittest discover -s tests

`node --check` any changed JS file. The real hardware paths (wayvnc, adb, OBS,
the tablet) are manual.

## Repo facts

- License: GPLv2 only (`LICENSE`, header in each source file).
- Work directly on master.