remoku 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
remoku-2.0.0/PKG-INFO ADDED
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 2.4
2
+ Name: remoku
3
+ Version: 2.0.0
4
+ Summary: A native desktop remote for Roku TVs and players, built on Roku's External Control Protocol.
5
+ Keywords: roku,remote-control,ecp,desktop,nicegui,home-automation
6
+ Author: slug-enjoyer
7
+ Author-email: slug-enjoyer <81844498+slug-enjoyer@users.noreply.github.com>
8
+ License-Expression: GPL-3.0-only
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: X11 Applications
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Home Automation
21
+ Classifier: Topic :: Multimedia :: Video
22
+ Classifier: Typing :: Typed
23
+ Requires-Dist: nicegui>=3.0
24
+ Requires-Dist: requests>=2.31
25
+ Requires-Dist: pywebview>=6.0 ; sys_platform != 'linux'
26
+ Requires-Dist: pywebview[qt]>=6.0 ; sys_platform == 'linux'
27
+ Requires-Python: >=3.10
28
+ Project-URL: Repository, https://github.com/slug-enjoyer/remoku
29
+ Project-URL: Issues, https://github.com/slug-enjoyer/remoku/issues
30
+ Project-URL: Changelog, https://github.com/slug-enjoyer/remoku/blob/main/CHANGELOG.md
31
+ Description-Content-Type: text/markdown
32
+
33
+ # remoku
34
+
35
+ [![PyPI - Version](https://img.shields.io/pypi/v/remoku?style=for-the-badge&color=blue)](https://pypi.org/project/remoku/)
36
+ [![PyPI - License](https://img.shields.io/pypi/l/remoku?style=for-the-badge&color=blue)](https://github.com/slug-enjoyer/remoku/blob/main/LICENSE)
37
+ [![PyPI - Python Version](https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge)](https://pypi.org/project/remoku/)
38
+ [![build](https://img.shields.io/github/actions/workflow/status/slug-enjoyer/remoku/ci.yml?branch=main&style=for-the-badge&label=build)](https://github.com/slug-enjoyer/remoku/actions/workflows/ci.yml)
39
+
40
+ A small native desktop remote for Roku TVs and players, built directly on
41
+ Roku's public
42
+ [External Control Protocol (ECP)](https://developer.roku.com/docs/developer-program/dev-tools/external-control-api.md).
43
+
44
+ The UI is [NiceGUI](https://nicegui.io/) running in a native window
45
+ (pywebview): `remoku` opens a window, full stop — no browser tab, no server
46
+ to manage, no browser mode.
47
+
48
+ Every Roku runs a tiny REST server on TCP port 8060. This app talks to it
49
+ directly — no accounts, no cloud, no companion service.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ uv tool install remoku
55
+ ```
56
+
57
+ or with [pipx](https://pipx.pypa.io/):
58
+
59
+ ```bash
60
+ pipx install remoku
61
+ ```
62
+
63
+ That gives you the `remoku` command (plus a `rokuremote` alias) in an
64
+ isolated environment. To also get a desktop entry and icons, run the
65
+ installer:
66
+
67
+ ```bash
68
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh
69
+ ```
70
+
71
+ It installs with uv (or pipx) under `~/.local` — no root, nothing
72
+ system-wide — and drops a launcher into your app menu. If PyPI is
73
+ unreachable, the installer falls back to the GitHub repository.
74
+
75
+ ```bash
76
+ # install somewhere else
77
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --prefix /opt/remoku
78
+
79
+ # a specific branch or tag (also used for the desktop entry and icons)
80
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --ref v2.0.0
81
+
82
+ # just the command, no desktop entry
83
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --no-desktop
84
+
85
+ # uninstall (settings and icon cache are kept)
86
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --uninstall
87
+ ```
88
+
89
+ ## Features
90
+
91
+ - Purple Roku-style remote in a native window: power, back, home, info,
92
+ instant replay, D-pad with OK, playback, volume
93
+ - App shortcuts grid, loaded from the device (`/query/apps`) with real
94
+ icons; click a tile to launch
95
+ - TV inputs in their own row, including custom names (e.g. "Nintendo
96
+ Switch", "Soundbar") configured on the TV
97
+ - A "Type to the Roku" box: each keystroke streams to the device, and
98
+ deleting a character sends Backspace, so you can edit as you type
99
+ - Device discovery: SSDP, plus an ARP-assisted scan of the local /24 that
100
+ stays gentle on consumer routers (broad high-concurrency scans can take
101
+ the whole Wi-Fi network down for ~10 seconds)
102
+ - Wake button: Roku TVs in standby only answer `device-info` and reply 403
103
+ to everything else; the button sends Wake-on-LAN and waits for the TV to
104
+ come up
105
+ - Typing: letters, digits and punctuation go straight to the Roku whenever
106
+ its on-screen keyboard is up, with no mode to toggle
107
+ - Keyboard control: the arrow keys behave like the D-pad, so the whole
108
+ remote is usable without a mouse
109
+
110
+ ## Requirements
111
+
112
+ - Python 3.10+
113
+ - A graphical session (X11 or Wayland)
114
+
115
+ That's all: the Qt backend ships as wheels, so there is nothing to install
116
+ for GTK or WebKit. On Linux the window uses Qt (PyQt6) and falls back to
117
+ GTK/WebKit2 when PyGObject is available.
118
+
119
+ ## Usage
120
+
121
+ ```bash
122
+ remoku # start the native window
123
+ remoku --ip 192.0.2.50
124
+ remoku --list # print Roku devices found on the network
125
+ remoku --apps # print apps/inputs of the last used device
126
+ remoku --key Home # send a single keypress
127
+ rokuremote --help # rokuremote is an alias for remoku
128
+ ```
129
+
130
+ The last used device is remembered in `~/.config/remoku/devices.json`;
131
+ app icons are cached in `~/.cache/remoku/icons/`.
132
+
133
+ ## Keyboard shortcuts
134
+
135
+ | Key | Action |
136
+ | --- | --- |
137
+ | Arrows | Up, Down, Left, Right |
138
+ | Enter | Select (OK), or press the focused on-screen button |
139
+ | Esc | Home |
140
+ | Backspace | Backspace (deletes while typing) |
141
+ | Letters / digits / punctuation / space | Typed to the Roku |
142
+ | Alt + W / A / S / D | Up / Left / Down / Right |
143
+ | Alt + B | Back |
144
+ | Alt + H | Home |
145
+ | Alt + I | Info |
146
+ | Alt + O | Select (OK) |
147
+ | Alt + R, F or P | Rewind, Fast forward, Play/pause |
148
+ | Alt + `,` `.` or `/` | Rewind, Fast forward, Play/pause |
149
+ | Alt + `[` or `-` | Volume down |
150
+ | Alt + `]`, `+` or `=` | Volume up |
151
+ | Alt + `\` or M | Mute |
152
+ | Ctrl + Up / Down | Volume up / down |
153
+ | Tab / Shift+Tab | Move focus through the window |
154
+
155
+ Printable keys are always forwarded to the Roku as `Lit_` characters.
156
+ Roku ignores those unless a text field is focused, which means typing
157
+ simply works whenever the TV's on-screen keyboard is up. Roku's API has no
158
+ way to ask whether a keyboard is open (verified against
159
+ `/query/active-app`, `/query/device-info` and friends), which is why the
160
+ remote keys that used to live on letters moved to Alt combinations. When a
161
+ button in the window has focus, Enter presses that button instead of
162
+ reaching the Roku.
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ git clone https://github.com/slug-enjoyer/remoku
168
+ cd remoku
169
+
170
+ just install # uv sync --all-extras
171
+ just run # launch the native window from source
172
+ just lint # ruff format + check, pyrefly
173
+ just test # pytest with coverage (gate: 80%)
174
+ just security # bandit
175
+ just build # uv build
176
+ just version bump patch # commitizen: bump, changelog, tag
177
+ ```
178
+
179
+ Every push and pull request runs lint, the test matrix (Python 3.10–3.14),
180
+ bandit and a build check; tagging `v*` runs the tests again and publishes
181
+ to PyPI with uv (trusted publishing).
182
+
183
+ The test suite is hermetic by construction: an autouse guard raises on any
184
+ non-loopback network access, and XDG paths are redirected into a temp
185
+ sandbox, so tests never touch a real device, the network or your real
186
+ config — `tests/test_hermeticity.py` proves it.
187
+
188
+ ## Secret scanning
189
+
190
+ A pre-commit hook blocks commits that contain secrets and warns (without
191
+ blocking) when staged lines look like local/private values such as LAN
192
+ addresses, MAC addresses or home directory paths.
193
+
194
+ ```bash
195
+ just hooks # enable the hook for this clone (per-clone git config)
196
+ just audit # scan the whole repo, history included, any time
197
+
198
+ make hooks # same thing, if you prefer make
199
+ make audit
200
+ ```
201
+
202
+ It runs [gitleaks](https://github.com/gitleaks/gitleaks) when installed
203
+ (`sudo pacman -S gitleaks`) and falls back to a small built-in check
204
+ otherwise. A deliberate example can be marked on its line with the comment
205
+ `sensitive-example`; `git commit --no-verify` bypasses the hook entirely.
206
+
207
+ ## Notes and troubleshooting
208
+
209
+ - Since Roku OS 14.1, remote commands require **Settings → System →
210
+ Advanced system settings → Control by mobile apps → Enabled** on the
211
+ device. If a command is refused, the app says so in the status bar.
212
+ - A Roku TV in standby (`power-mode: Ready`) answers `device-info` but
213
+ refuses every other command with HTTP 403, which looks like the setting
214
+ above being off even when it is on. In that case the app shows a **Wake
215
+ TV** button, which sends a Wake-on-LAN magic packet and waits for the TV
216
+ to come up (this is what Roku's own mobile app does). If waking does not
217
+ work, enable **Settings → System → Power → Fast TV start** on the TV.
218
+ - SSDP discovery is unreliable on many Wi-Fi networks because access
219
+ points drop multicast between clients. When that happens the app falls
220
+ back to scanning: it pokes the kernel into resolving every address in
221
+ the local /24 via ARP (a single UDP datagram each), then TCP-probes only
222
+ the hosts that actually exist. If the ARP table cannot be read it falls
223
+ back to a low-concurrency TCP scan, and it never scans wider than a /24.
224
+ - Connecting to a device is retried up to three times if the network is
225
+ briefly busy, and the startup scan runs only after the first connection
226
+ attempt finishes.
227
+ - Power/volume buttons only appear for devices that report support for
228
+ them (Roku TVs, or players using TV controls over HDMI-CEC).
229
+
230
+ ## License
231
+
232
+ GPL-3.0. See [LICENSE](LICENSE).
remoku-2.0.0/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # remoku
2
+
3
+ [![PyPI - Version](https://img.shields.io/pypi/v/remoku?style=for-the-badge&color=blue)](https://pypi.org/project/remoku/)
4
+ [![PyPI - License](https://img.shields.io/pypi/l/remoku?style=for-the-badge&color=blue)](https://github.com/slug-enjoyer/remoku/blob/main/LICENSE)
5
+ [![PyPI - Python Version](https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge)](https://pypi.org/project/remoku/)
6
+ [![build](https://img.shields.io/github/actions/workflow/status/slug-enjoyer/remoku/ci.yml?branch=main&style=for-the-badge&label=build)](https://github.com/slug-enjoyer/remoku/actions/workflows/ci.yml)
7
+
8
+ A small native desktop remote for Roku TVs and players, built directly on
9
+ Roku's public
10
+ [External Control Protocol (ECP)](https://developer.roku.com/docs/developer-program/dev-tools/external-control-api.md).
11
+
12
+ The UI is [NiceGUI](https://nicegui.io/) running in a native window
13
+ (pywebview): `remoku` opens a window, full stop — no browser tab, no server
14
+ to manage, no browser mode.
15
+
16
+ Every Roku runs a tiny REST server on TCP port 8060. This app talks to it
17
+ directly — no accounts, no cloud, no companion service.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ uv tool install remoku
23
+ ```
24
+
25
+ or with [pipx](https://pipx.pypa.io/):
26
+
27
+ ```bash
28
+ pipx install remoku
29
+ ```
30
+
31
+ That gives you the `remoku` command (plus a `rokuremote` alias) in an
32
+ isolated environment. To also get a desktop entry and icons, run the
33
+ installer:
34
+
35
+ ```bash
36
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh
37
+ ```
38
+
39
+ It installs with uv (or pipx) under `~/.local` — no root, nothing
40
+ system-wide — and drops a launcher into your app menu. If PyPI is
41
+ unreachable, the installer falls back to the GitHub repository.
42
+
43
+ ```bash
44
+ # install somewhere else
45
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --prefix /opt/remoku
46
+
47
+ # a specific branch or tag (also used for the desktop entry and icons)
48
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --ref v2.0.0
49
+
50
+ # just the command, no desktop entry
51
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --no-desktop
52
+
53
+ # uninstall (settings and icon cache are kept)
54
+ curl -fsSL https://raw.githubusercontent.com/slug-enjoyer/remoku/main/install.sh | sh -s -- --uninstall
55
+ ```
56
+
57
+ ## Features
58
+
59
+ - Purple Roku-style remote in a native window: power, back, home, info,
60
+ instant replay, D-pad with OK, playback, volume
61
+ - App shortcuts grid, loaded from the device (`/query/apps`) with real
62
+ icons; click a tile to launch
63
+ - TV inputs in their own row, including custom names (e.g. "Nintendo
64
+ Switch", "Soundbar") configured on the TV
65
+ - A "Type to the Roku" box: each keystroke streams to the device, and
66
+ deleting a character sends Backspace, so you can edit as you type
67
+ - Device discovery: SSDP, plus an ARP-assisted scan of the local /24 that
68
+ stays gentle on consumer routers (broad high-concurrency scans can take
69
+ the whole Wi-Fi network down for ~10 seconds)
70
+ - Wake button: Roku TVs in standby only answer `device-info` and reply 403
71
+ to everything else; the button sends Wake-on-LAN and waits for the TV to
72
+ come up
73
+ - Typing: letters, digits and punctuation go straight to the Roku whenever
74
+ its on-screen keyboard is up, with no mode to toggle
75
+ - Keyboard control: the arrow keys behave like the D-pad, so the whole
76
+ remote is usable without a mouse
77
+
78
+ ## Requirements
79
+
80
+ - Python 3.10+
81
+ - A graphical session (X11 or Wayland)
82
+
83
+ That's all: the Qt backend ships as wheels, so there is nothing to install
84
+ for GTK or WebKit. On Linux the window uses Qt (PyQt6) and falls back to
85
+ GTK/WebKit2 when PyGObject is available.
86
+
87
+ ## Usage
88
+
89
+ ```bash
90
+ remoku # start the native window
91
+ remoku --ip 192.0.2.50
92
+ remoku --list # print Roku devices found on the network
93
+ remoku --apps # print apps/inputs of the last used device
94
+ remoku --key Home # send a single keypress
95
+ rokuremote --help # rokuremote is an alias for remoku
96
+ ```
97
+
98
+ The last used device is remembered in `~/.config/remoku/devices.json`;
99
+ app icons are cached in `~/.cache/remoku/icons/`.
100
+
101
+ ## Keyboard shortcuts
102
+
103
+ | Key | Action |
104
+ | --- | --- |
105
+ | Arrows | Up, Down, Left, Right |
106
+ | Enter | Select (OK), or press the focused on-screen button |
107
+ | Esc | Home |
108
+ | Backspace | Backspace (deletes while typing) |
109
+ | Letters / digits / punctuation / space | Typed to the Roku |
110
+ | Alt + W / A / S / D | Up / Left / Down / Right |
111
+ | Alt + B | Back |
112
+ | Alt + H | Home |
113
+ | Alt + I | Info |
114
+ | Alt + O | Select (OK) |
115
+ | Alt + R, F or P | Rewind, Fast forward, Play/pause |
116
+ | Alt + `,` `.` or `/` | Rewind, Fast forward, Play/pause |
117
+ | Alt + `[` or `-` | Volume down |
118
+ | Alt + `]`, `+` or `=` | Volume up |
119
+ | Alt + `\` or M | Mute |
120
+ | Ctrl + Up / Down | Volume up / down |
121
+ | Tab / Shift+Tab | Move focus through the window |
122
+
123
+ Printable keys are always forwarded to the Roku as `Lit_` characters.
124
+ Roku ignores those unless a text field is focused, which means typing
125
+ simply works whenever the TV's on-screen keyboard is up. Roku's API has no
126
+ way to ask whether a keyboard is open (verified against
127
+ `/query/active-app`, `/query/device-info` and friends), which is why the
128
+ remote keys that used to live on letters moved to Alt combinations. When a
129
+ button in the window has focus, Enter presses that button instead of
130
+ reaching the Roku.
131
+
132
+ ## Development
133
+
134
+ ```bash
135
+ git clone https://github.com/slug-enjoyer/remoku
136
+ cd remoku
137
+
138
+ just install # uv sync --all-extras
139
+ just run # launch the native window from source
140
+ just lint # ruff format + check, pyrefly
141
+ just test # pytest with coverage (gate: 80%)
142
+ just security # bandit
143
+ just build # uv build
144
+ just version bump patch # commitizen: bump, changelog, tag
145
+ ```
146
+
147
+ Every push and pull request runs lint, the test matrix (Python 3.10–3.14),
148
+ bandit and a build check; tagging `v*` runs the tests again and publishes
149
+ to PyPI with uv (trusted publishing).
150
+
151
+ The test suite is hermetic by construction: an autouse guard raises on any
152
+ non-loopback network access, and XDG paths are redirected into a temp
153
+ sandbox, so tests never touch a real device, the network or your real
154
+ config — `tests/test_hermeticity.py` proves it.
155
+
156
+ ## Secret scanning
157
+
158
+ A pre-commit hook blocks commits that contain secrets and warns (without
159
+ blocking) when staged lines look like local/private values such as LAN
160
+ addresses, MAC addresses or home directory paths.
161
+
162
+ ```bash
163
+ just hooks # enable the hook for this clone (per-clone git config)
164
+ just audit # scan the whole repo, history included, any time
165
+
166
+ make hooks # same thing, if you prefer make
167
+ make audit
168
+ ```
169
+
170
+ It runs [gitleaks](https://github.com/gitleaks/gitleaks) when installed
171
+ (`sudo pacman -S gitleaks`) and falls back to a small built-in check
172
+ otherwise. A deliberate example can be marked on its line with the comment
173
+ `sensitive-example`; `git commit --no-verify` bypasses the hook entirely.
174
+
175
+ ## Notes and troubleshooting
176
+
177
+ - Since Roku OS 14.1, remote commands require **Settings → System →
178
+ Advanced system settings → Control by mobile apps → Enabled** on the
179
+ device. If a command is refused, the app says so in the status bar.
180
+ - A Roku TV in standby (`power-mode: Ready`) answers `device-info` but
181
+ refuses every other command with HTTP 403, which looks like the setting
182
+ above being off even when it is on. In that case the app shows a **Wake
183
+ TV** button, which sends a Wake-on-LAN magic packet and waits for the TV
184
+ to come up (this is what Roku's own mobile app does). If waking does not
185
+ work, enable **Settings → System → Power → Fast TV start** on the TV.
186
+ - SSDP discovery is unreliable on many Wi-Fi networks because access
187
+ points drop multicast between clients. When that happens the app falls
188
+ back to scanning: it pokes the kernel into resolving every address in
189
+ the local /24 via ARP (a single UDP datagram each), then TCP-probes only
190
+ the hosts that actually exist. If the ARP table cannot be read it falls
191
+ back to a low-concurrency TCP scan, and it never scans wider than a /24.
192
+ - Connecting to a device is retried up to three times if the network is
193
+ briefly busy, and the startup scan runs only after the first connection
194
+ attempt finishes.
195
+ - Power/volume buttons only appear for devices that report support for
196
+ them (Roku TVs, or players using TV controls over HDMI-CEC).
197
+
198
+ ## License
199
+
200
+ GPL-3.0. See [LICENSE](LICENSE).
@@ -0,0 +1,147 @@
1
+ [project]
2
+ name = "remoku"
3
+ version = "2.0.0"
4
+ description = "A native desktop remote for Roku TVs and players, built on Roku's External Control Protocol."
5
+ readme = "README.md"
6
+ license = "GPL-3.0-only"
7
+ requires-python = ">=3.10"
8
+ dependencies = [
9
+ "nicegui>=3.0",
10
+ "requests>=2.31",
11
+ "pywebview>=6.0; sys_platform != 'linux'",
12
+ "pywebview[qt]>=6.0; sys_platform == 'linux'",
13
+ ]
14
+ keywords = [
15
+ "roku",
16
+ "remote-control",
17
+ "ecp",
18
+ "desktop",
19
+ "nicegui",
20
+ "home-automation",
21
+ ]
22
+ classifiers = [
23
+ "Development Status :: 4 - Beta",
24
+ "Environment :: X11 Applications",
25
+ "Intended Audience :: End Users/Desktop",
26
+ "Natural Language :: English",
27
+ "Operating System :: OS Independent",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Programming Language :: Python :: 3.14",
34
+ "Topic :: Home Automation",
35
+ "Topic :: Multimedia :: Video",
36
+ "Typing :: Typed",
37
+ ]
38
+
39
+ [[project.authors]]
40
+ name = "slug-enjoyer"
41
+ email = "81844498+slug-enjoyer@users.noreply.github.com"
42
+
43
+ [project.urls]
44
+ Repository = "https://github.com/slug-enjoyer/remoku"
45
+ Issues = "https://github.com/slug-enjoyer/remoku/issues"
46
+ Changelog = "https://github.com/slug-enjoyer/remoku/blob/main/CHANGELOG.md"
47
+
48
+ [project.scripts]
49
+ remoku = "remoku.__main__:main"
50
+ rokuremote = "remoku.__main__:main"
51
+
52
+ [build-system]
53
+ requires = ["uv_build>=0.9,<0.13"]
54
+ build-backend = "uv_build"
55
+
56
+ [dependency-groups]
57
+ dev = [
58
+ "bandit>=1.8.0",
59
+ "commitizen>=4.0.0",
60
+ "pyrefly>=0.30.0",
61
+ "pytest>=8.0.0",
62
+ "pytest-asyncio>=1.0.0",
63
+ "pytest-cov>=6.0.0",
64
+ "pytest-mock>=3.14.0",
65
+ "ruff>=0.9.0",
66
+ ]
67
+
68
+ [tool.ruff]
69
+ line-length = 120
70
+ target-version = "py310"
71
+ src = [
72
+ "src/remoku",
73
+ "tests",
74
+ ]
75
+
76
+ [tool.ruff.lint]
77
+ select = [
78
+ "E",
79
+ "F",
80
+ "W",
81
+ "I",
82
+ "N",
83
+ "UP",
84
+ "YTT",
85
+ "ANN",
86
+ "S",
87
+ "B",
88
+ "C4",
89
+ "SIM",
90
+ "PTH",
91
+ "RUF",
92
+ "PERF",
93
+ "BLE",
94
+ "T20",
95
+ "ERA",
96
+ "TCH",
97
+ "ARG",
98
+ "FBT",
99
+ "RET",
100
+ "FURB",
101
+ ]
102
+ ignore = ["ANN401"]
103
+
104
+ [tool.ruff.lint.per-file-ignores]
105
+ "src/remoku/__main__.py" = ["T20"]
106
+ "tests/*" = [
107
+ "ANN",
108
+ "S",
109
+ "ARG",
110
+ "FBT",
111
+ "T20",
112
+ "PTH",
113
+ ]
114
+
115
+ [tool.ruff.format]
116
+ quote-style = "double"
117
+ line-ending = "lf"
118
+
119
+ [tool.pyrefly]
120
+ project-includes = ["src/remoku"]
121
+
122
+ [tool.bandit]
123
+ exclude_dirs = ["tests"]
124
+
125
+ [tool.coverage.run]
126
+ source = ["remoku"]
127
+ branch = true
128
+ omit = ["src/remoku/__main__.py"]
129
+
130
+ [tool.coverage.report]
131
+ fail_under = 80
132
+ show_missing = true
133
+
134
+ [tool.pytest.ini_options]
135
+ asyncio_mode = "auto"
136
+ testpaths = ["tests"]
137
+ main_file = "tests/main.py"
138
+
139
+ [tool.commitizen]
140
+ name = "cz_conventional_commits"
141
+ version = "2.0.0"
142
+ tag_format = "v$version"
143
+ version_files = [
144
+ "pyproject.toml:version",
145
+ "src/remoku/__init__.py",
146
+ ]
147
+ update_changelog_on_bump = true