hapbeat-helper 0.1.2__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.
Files changed (26) hide show
  1. hapbeat_helper-0.1.2/LICENSE +21 -0
  2. hapbeat_helper-0.1.2/PKG-INFO +229 -0
  3. hapbeat_helper-0.1.2/README.md +197 -0
  4. hapbeat_helper-0.1.2/pyproject.toml +53 -0
  5. hapbeat_helper-0.1.2/setup.cfg +4 -0
  6. hapbeat_helper-0.1.2/src/hapbeat_helper/__init__.py +10 -0
  7. hapbeat_helper-0.1.2/src/hapbeat_helper/__main__.py +6 -0
  8. hapbeat_helper-0.1.2/src/hapbeat_helper/cli.py +328 -0
  9. hapbeat_helper-0.1.2/src/hapbeat_helper/device_registry.py +131 -0
  10. hapbeat_helper-0.1.2/src/hapbeat_helper/mdns_scanner.py +147 -0
  11. hapbeat_helper-0.1.2/src/hapbeat_helper/pack_normalize.py +144 -0
  12. hapbeat_helper-0.1.2/src/hapbeat_helper/protocol.py +164 -0
  13. hapbeat_helper-0.1.2/src/hapbeat_helper/server.py +2058 -0
  14. hapbeat_helper-0.1.2/src/hapbeat_helper/service/__init__.py +24 -0
  15. hapbeat_helper-0.1.2/src/hapbeat_helper/service/macos.py +161 -0
  16. hapbeat_helper-0.1.2/src/hapbeat_helper/service/windows.py +331 -0
  17. hapbeat_helper-0.1.2/src/hapbeat_helper/tcp_client.py +240 -0
  18. hapbeat_helper-0.1.2/src/hapbeat_helper/udp_listener.py +196 -0
  19. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/PKG-INFO +229 -0
  20. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/SOURCES.txt +24 -0
  21. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/dependency_links.txt +1 -0
  22. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/entry_points.txt +2 -0
  23. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/requires.txt +8 -0
  24. hapbeat_helper-0.1.2/src/hapbeat_helper.egg-info/top_level.txt +1 -0
  25. hapbeat_helper-0.1.2/tests/test_protocol.py +51 -0
  26. hapbeat_helper-0.1.2/tests/test_registry.py +35 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hapbeat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,229 @@
1
+ Metadata-Version: 2.4
2
+ Name: hapbeat-helper
3
+ Version: 0.1.2
4
+ Summary: Local daemon bridging Hapbeat Studio (web) to Hapbeat devices
5
+ Author-email: Hapbeat <yus988@hapbeat.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://devtools.hapbeat.com/
8
+ Project-URL: Repository, https://github.com/hapbeat/hapbeat-helper
9
+ Project-URL: Issues, https://github.com/hapbeat/hapbeat-helper/issues
10
+ Keywords: hapbeat,haptics,studio,websocket,mdns,iot
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Embedded Systems
21
+ Classifier: Topic :: System :: Hardware
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: websockets>=12
26
+ Requires-Dist: zeroconf>=0.131
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8; extra == "dev"
29
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
30
+ Provides-Extra: normalize
31
+ Dynamic: license-file
32
+
33
+ # hapbeat-helper
34
+
35
+ Local daemon that bridges **Hapbeat Studio** (Web SPA at `https://devtools.hapbeat.com`)
36
+ to Hapbeat hardware on the local network.
37
+
38
+ The browser cannot do mDNS, UDP broadcast, or raw TCP sockets directly.
39
+ `hapbeat-helper` runs in the background, exposes a WebSocket on
40
+ `ws://localhost:7703`, and relays Studio requests to the devices using
41
+ UDP (port 7700) and TCP (port 7701).
42
+
43
+ ```
44
+ Studio (https://devtools.hapbeat.com)
45
+ │ ws://localhost:7703 (JSON)
46
+
47
+ hapbeat-helper (this daemon)
48
+ │ UDP 7700 (PLAY / STOP / PING / streaming)
49
+ │ TCP 7701 (config / kit deploy)
50
+ │ mDNS (_hapbeat._udp.local.)
51
+
52
+ Hapbeat devices
53
+ ```
54
+
55
+ ## Install
56
+
57
+ `hapbeat-helper` is distributed as a Python CLI that runs in its own
58
+ isolated environment. The recommended installer is **pipx** — it puts
59
+ each Python tool in a separate venv and exposes the entry point on your
60
+ PATH, so you don't need to think about Python versions or dependency
61
+ conflicts.
62
+
63
+ ### Step 1 — Install pipx (once per machine)
64
+
65
+ #### macOS
66
+
67
+ ```bash
68
+ brew install pipx
69
+ pipx ensurepath
70
+ ```
71
+
72
+ #### Windows
73
+
74
+ ```powershell
75
+ py -m pip install --user pipx
76
+ py -m pipx ensurepath
77
+ # Close and reopen your terminal so the new PATH takes effect.
78
+ pipx --version # should print the version
79
+ ```
80
+
81
+ > **Windows tip:** if `pipx` is still "not recognized" after reopening
82
+ > the shell, use `py -m pipx ...` for everything below (it works
83
+ > identically). The bare `pipx` command becomes available once
84
+ > `%APPDATA%\Python\Python3xx\Scripts` is on your `Path`.
85
+ >
86
+ > **OneDrive / cloud-synced home directory:** if your `C:\Users\<you>\`
87
+ > is synced by OneDrive, pipx may fail with `WinError 448 — untrusted
88
+ > mount point`. Move pipx out of the synced tree by setting these
89
+ > environment variables (User scope) and reopening the shell:
90
+ >
91
+ > ```powershell
92
+ > [Environment]::SetEnvironmentVariable('PIPX_HOME', 'C:\pipx\home', 'User')
93
+ > [Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin', 'User')
94
+ > ```
95
+
96
+ ### Step 2 — Install hapbeat-helper
97
+
98
+ Once pipx is on your PATH:
99
+
100
+ ```bash
101
+ pipx install hapbeat-helper
102
+ ```
103
+
104
+ That's it. `hapbeat-helper` will be available in any new terminal.
105
+
106
+ ### Local development (from a clone of this repo)
107
+
108
+ ```bash
109
+ # editable install via pipx (changes in src/ are picked up live)
110
+ pipx install -e .
111
+
112
+ # or — preferred during active dev — a plain venv:
113
+ python -m venv .venv
114
+ # macOS:
115
+ .venv/bin/pip install -e ".[dev]"
116
+ .venv/bin/hapbeat-helper start
117
+ # Windows:
118
+ .venv\Scripts\pip install -e ".[dev]"
119
+ .venv\Scripts\hapbeat-helper start
120
+ ```
121
+
122
+ ### Updating
123
+
124
+ ```bash
125
+ pipx upgrade hapbeat-helper
126
+ ```
127
+
128
+ If you installed editable from a clone (`pipx install -e .` or
129
+ `pip install -e ".[dev]"`), updates are automatic — just `git pull` and
130
+ restart the daemon. The Python package picks up changes in `src/` on
131
+ the next process start.
132
+
133
+ > **WS protocol mismatch?** When Studio reports
134
+ > `ERROR: unknown type: <message>` in the log drawer, your helper is
135
+ > older than the Studio build. `git pull && restart` (or `pipx upgrade`).
136
+
137
+ ### Uninstalling
138
+
139
+ ```bash
140
+ pipx uninstall hapbeat-helper
141
+ ```
142
+
143
+ ## Run
144
+
145
+ ### Option A — Auto-start service (recommended)
146
+
147
+ Register hapbeat-helper as an OS-level service so it starts automatically
148
+ every time you log in. After this one-time setup you never need to open a
149
+ terminal again:
150
+
151
+ ```bash
152
+ hapbeat-helper install-service
153
+ ```
154
+
155
+ To check the registration state:
156
+
157
+ ```bash
158
+ hapbeat-helper service-status
159
+ ```
160
+
161
+ To remove the auto-start registration:
162
+
163
+ ```bash
164
+ hapbeat-helper uninstall-service
165
+ ```
166
+
167
+ Platform notes:
168
+ - **macOS** — creates `~/Library/LaunchAgents/com.hapbeat.helper.plist` (launchd)
169
+ - **Windows** — drops a hidden VBS shim into the Startup folder (`%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hapbeat-helper.vbs`) that launches the daemon at login with no console window. stdout/stderr → `%LOCALAPPDATA%\hapbeat-helper\hapbeat-helper.log`
170
+
171
+ ### Option B — Foreground (dev / debug)
172
+
173
+ ```bash
174
+ hapbeat-helper start
175
+ ```
176
+
177
+ Then open https://devtools.hapbeat.com — Studio will connect automatically.
178
+
179
+ Press `Ctrl+C` to stop.
180
+
181
+ ### Other commands
182
+
183
+ ```bash
184
+ hapbeat-helper status # check whether a daemon is reachable on 7703
185
+ hapbeat-helper version # print version
186
+ hapbeat-helper config show # show config path
187
+ ```
188
+
189
+ ## Verify
190
+
191
+ Quick smoke test using `websocat`:
192
+
193
+ ```bash
194
+ echo '{"type":"ping","payload":{}}' | websocat ws://localhost:7703
195
+ echo '{"type":"list_devices","payload":{}}' | websocat ws://localhost:7703
196
+ ```
197
+
198
+ ## Troubleshooting
199
+
200
+ - **Studio reports "Helper 未接続"** — run `hapbeat-helper install-service` (once)
201
+ or start manually with `hapbeat-helper start`.
202
+ - **Browser cannot connect to `ws://localhost:7703` from HTTPS Studio** —
203
+ Chrome and Edge allow this by default. Firefox requires
204
+ `network.websocket.allowInsecureFromHTTPS = true` in `about:config`.
205
+ - **No devices found** — confirm the Hapbeat devices and this PC are on the
206
+ same Wi-Fi network. Some hotspot/AP modes block UDP broadcast and mDNS.
207
+ - **Port 7700 / 7703 already in use** — stop any running `hapbeat-manager`
208
+ (it owns the same ports). The two cannot run at the same time.
209
+ - **Windows: `pipx install` fails with `WinError 448 — untrusted mount
210
+ point`** — your home directory is under OneDrive (or another reparse
211
+ point). pipx finished installing the package but cannot finalize the
212
+ shim under `~/.local/bin/`. Either run `hapbeat-helper.exe` from that
213
+ path directly, or relocate pipx outside the synced tree:
214
+
215
+ ```powershell
216
+ [Environment]::SetEnvironmentVariable('PIPX_HOME', 'C:\pipx\home', 'User')
217
+ [Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin', 'User')
218
+ # Reopen the shell, then:
219
+ py -m pipx ensurepath
220
+ py -m pipx install hapbeat-helper
221
+ ```
222
+ - **`pipx` not recognized after `pip install --user pipx`** — the user
223
+ Scripts dir is not on `Path` yet. Run `py -m pipx ensurepath` and open
224
+ a new terminal. As a fallback, every `pipx X` call also works as
225
+ `py -m pipx X`.
226
+
227
+ ## License
228
+
229
+ MIT
@@ -0,0 +1,197 @@
1
+ # hapbeat-helper
2
+
3
+ Local daemon that bridges **Hapbeat Studio** (Web SPA at `https://devtools.hapbeat.com`)
4
+ to Hapbeat hardware on the local network.
5
+
6
+ The browser cannot do mDNS, UDP broadcast, or raw TCP sockets directly.
7
+ `hapbeat-helper` runs in the background, exposes a WebSocket on
8
+ `ws://localhost:7703`, and relays Studio requests to the devices using
9
+ UDP (port 7700) and TCP (port 7701).
10
+
11
+ ```
12
+ Studio (https://devtools.hapbeat.com)
13
+ │ ws://localhost:7703 (JSON)
14
+
15
+ hapbeat-helper (this daemon)
16
+ │ UDP 7700 (PLAY / STOP / PING / streaming)
17
+ │ TCP 7701 (config / kit deploy)
18
+ │ mDNS (_hapbeat._udp.local.)
19
+
20
+ Hapbeat devices
21
+ ```
22
+
23
+ ## Install
24
+
25
+ `hapbeat-helper` is distributed as a Python CLI that runs in its own
26
+ isolated environment. The recommended installer is **pipx** — it puts
27
+ each Python tool in a separate venv and exposes the entry point on your
28
+ PATH, so you don't need to think about Python versions or dependency
29
+ conflicts.
30
+
31
+ ### Step 1 — Install pipx (once per machine)
32
+
33
+ #### macOS
34
+
35
+ ```bash
36
+ brew install pipx
37
+ pipx ensurepath
38
+ ```
39
+
40
+ #### Windows
41
+
42
+ ```powershell
43
+ py -m pip install --user pipx
44
+ py -m pipx ensurepath
45
+ # Close and reopen your terminal so the new PATH takes effect.
46
+ pipx --version # should print the version
47
+ ```
48
+
49
+ > **Windows tip:** if `pipx` is still "not recognized" after reopening
50
+ > the shell, use `py -m pipx ...` for everything below (it works
51
+ > identically). The bare `pipx` command becomes available once
52
+ > `%APPDATA%\Python\Python3xx\Scripts` is on your `Path`.
53
+ >
54
+ > **OneDrive / cloud-synced home directory:** if your `C:\Users\<you>\`
55
+ > is synced by OneDrive, pipx may fail with `WinError 448 — untrusted
56
+ > mount point`. Move pipx out of the synced tree by setting these
57
+ > environment variables (User scope) and reopening the shell:
58
+ >
59
+ > ```powershell
60
+ > [Environment]::SetEnvironmentVariable('PIPX_HOME', 'C:\pipx\home', 'User')
61
+ > [Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin', 'User')
62
+ > ```
63
+
64
+ ### Step 2 — Install hapbeat-helper
65
+
66
+ Once pipx is on your PATH:
67
+
68
+ ```bash
69
+ pipx install hapbeat-helper
70
+ ```
71
+
72
+ That's it. `hapbeat-helper` will be available in any new terminal.
73
+
74
+ ### Local development (from a clone of this repo)
75
+
76
+ ```bash
77
+ # editable install via pipx (changes in src/ are picked up live)
78
+ pipx install -e .
79
+
80
+ # or — preferred during active dev — a plain venv:
81
+ python -m venv .venv
82
+ # macOS:
83
+ .venv/bin/pip install -e ".[dev]"
84
+ .venv/bin/hapbeat-helper start
85
+ # Windows:
86
+ .venv\Scripts\pip install -e ".[dev]"
87
+ .venv\Scripts\hapbeat-helper start
88
+ ```
89
+
90
+ ### Updating
91
+
92
+ ```bash
93
+ pipx upgrade hapbeat-helper
94
+ ```
95
+
96
+ If you installed editable from a clone (`pipx install -e .` or
97
+ `pip install -e ".[dev]"`), updates are automatic — just `git pull` and
98
+ restart the daemon. The Python package picks up changes in `src/` on
99
+ the next process start.
100
+
101
+ > **WS protocol mismatch?** When Studio reports
102
+ > `ERROR: unknown type: <message>` in the log drawer, your helper is
103
+ > older than the Studio build. `git pull && restart` (or `pipx upgrade`).
104
+
105
+ ### Uninstalling
106
+
107
+ ```bash
108
+ pipx uninstall hapbeat-helper
109
+ ```
110
+
111
+ ## Run
112
+
113
+ ### Option A — Auto-start service (recommended)
114
+
115
+ Register hapbeat-helper as an OS-level service so it starts automatically
116
+ every time you log in. After this one-time setup you never need to open a
117
+ terminal again:
118
+
119
+ ```bash
120
+ hapbeat-helper install-service
121
+ ```
122
+
123
+ To check the registration state:
124
+
125
+ ```bash
126
+ hapbeat-helper service-status
127
+ ```
128
+
129
+ To remove the auto-start registration:
130
+
131
+ ```bash
132
+ hapbeat-helper uninstall-service
133
+ ```
134
+
135
+ Platform notes:
136
+ - **macOS** — creates `~/Library/LaunchAgents/com.hapbeat.helper.plist` (launchd)
137
+ - **Windows** — drops a hidden VBS shim into the Startup folder (`%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hapbeat-helper.vbs`) that launches the daemon at login with no console window. stdout/stderr → `%LOCALAPPDATA%\hapbeat-helper\hapbeat-helper.log`
138
+
139
+ ### Option B — Foreground (dev / debug)
140
+
141
+ ```bash
142
+ hapbeat-helper start
143
+ ```
144
+
145
+ Then open https://devtools.hapbeat.com — Studio will connect automatically.
146
+
147
+ Press `Ctrl+C` to stop.
148
+
149
+ ### Other commands
150
+
151
+ ```bash
152
+ hapbeat-helper status # check whether a daemon is reachable on 7703
153
+ hapbeat-helper version # print version
154
+ hapbeat-helper config show # show config path
155
+ ```
156
+
157
+ ## Verify
158
+
159
+ Quick smoke test using `websocat`:
160
+
161
+ ```bash
162
+ echo '{"type":"ping","payload":{}}' | websocat ws://localhost:7703
163
+ echo '{"type":"list_devices","payload":{}}' | websocat ws://localhost:7703
164
+ ```
165
+
166
+ ## Troubleshooting
167
+
168
+ - **Studio reports "Helper 未接続"** — run `hapbeat-helper install-service` (once)
169
+ or start manually with `hapbeat-helper start`.
170
+ - **Browser cannot connect to `ws://localhost:7703` from HTTPS Studio** —
171
+ Chrome and Edge allow this by default. Firefox requires
172
+ `network.websocket.allowInsecureFromHTTPS = true` in `about:config`.
173
+ - **No devices found** — confirm the Hapbeat devices and this PC are on the
174
+ same Wi-Fi network. Some hotspot/AP modes block UDP broadcast and mDNS.
175
+ - **Port 7700 / 7703 already in use** — stop any running `hapbeat-manager`
176
+ (it owns the same ports). The two cannot run at the same time.
177
+ - **Windows: `pipx install` fails with `WinError 448 — untrusted mount
178
+ point`** — your home directory is under OneDrive (or another reparse
179
+ point). pipx finished installing the package but cannot finalize the
180
+ shim under `~/.local/bin/`. Either run `hapbeat-helper.exe` from that
181
+ path directly, or relocate pipx outside the synced tree:
182
+
183
+ ```powershell
184
+ [Environment]::SetEnvironmentVariable('PIPX_HOME', 'C:\pipx\home', 'User')
185
+ [Environment]::SetEnvironmentVariable('PIPX_BIN_DIR', 'C:\pipx\bin', 'User')
186
+ # Reopen the shell, then:
187
+ py -m pipx ensurepath
188
+ py -m pipx install hapbeat-helper
189
+ ```
190
+ - **`pipx` not recognized after `pip install --user pipx`** — the user
191
+ Scripts dir is not on `Path` yet. Run `py -m pipx ensurepath` and open
192
+ a new terminal. As a fallback, every `pipx X` call also works as
193
+ `py -m pipx X`.
194
+
195
+ ## License
196
+
197
+ MIT
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "hapbeat-helper"
7
+ version = "0.1.2"
8
+ description = "Local daemon bridging Hapbeat Studio (web) to Hapbeat devices"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Hapbeat", email = "yus988@hapbeat.com" }]
13
+ keywords = ["hapbeat", "haptics", "studio", "websocket", "mdns", "iot"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Embedded Systems",
25
+ "Topic :: System :: Hardware",
26
+ ]
27
+ dependencies = [
28
+ "websockets>=12",
29
+ "zeroconf>=0.131",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://devtools.hapbeat.com/"
34
+ Repository = "https://github.com/hapbeat/hapbeat-helper"
35
+ Issues = "https://github.com/hapbeat/hapbeat-helper/issues"
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "pytest>=8",
40
+ "pytest-asyncio>=0.23",
41
+ ]
42
+ # Pack/Kit normalization (ffmpeg subprocess needed at runtime)
43
+ normalize = []
44
+
45
+ [project.scripts]
46
+ hapbeat-helper = "hapbeat_helper.cli:main"
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.pytest.ini_options]
52
+ asyncio_mode = "auto"
53
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,10 @@
1
+ """hapbeat-helper — local daemon bridging Studio (web) to Hapbeat devices."""
2
+
3
+ try:
4
+ # Generated by scripts/gen_version.py (gitignored).
5
+ # Present in local dev installs; absent in PyPI releases.
6
+ from hapbeat_helper._version import __version__
7
+ except ImportError:
8
+ # Fallback: release version embedded at publish time.
9
+ # Keep this in sync with pyproject.toml [project] version.
10
+ __version__ = "0.1.2"
@@ -0,0 +1,6 @@
1
+ """Allow `python -m hapbeat_helper` to invoke the CLI."""
2
+
3
+ from hapbeat_helper.cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()