hadsync 0.2.2__py3-none-any.whl

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.
@@ -0,0 +1,403 @@
1
+ Metadata-Version: 2.4
2
+ Name: hadsync
3
+ Version: 0.2.2
4
+ Summary: Home Assistant Dashboard Sync — pull, edit, and push Lovelace dashboards as code
5
+ Project-URL: Homepage, https://github.com/gevgev/hadsync
6
+ Project-URL: Repository, https://github.com/gevgev/hadsync
7
+ Project-URL: Bug Tracker, https://github.com/gevgev/hadsync/issues
8
+ Project-URL: Changelog, https://github.com/gevgev/hadsync/blob/main/CHANGELOG.md
9
+ Author-email: Gevorg Gevorgyan <gevgev66@gmail.com>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Gevorg Gevorgyan
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: cli,dashboard,home-assistant,home-automation,lovelace,yaml
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Intended Audience :: Developers
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Topic :: Home Automation
42
+ Classifier: Topic :: Software Development :: Version Control
43
+ Requires-Python: >=3.11
44
+ Requires-Dist: httpx>=0.27
45
+ Requires-Dist: pydantic>=2
46
+ Requires-Dist: rich>=13
47
+ Requires-Dist: ruamel-yaml>=0.18
48
+ Requires-Dist: typer>=0.12
49
+ Requires-Dist: watchdog>=4
50
+ Requires-Dist: websockets>=12
51
+ Provides-Extra: dev
52
+ Requires-Dist: coverage>=7; extra == 'dev'
53
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
54
+ Requires-Dist: pytest-mock>=3; extra == 'dev'
55
+ Requires-Dist: pytest>=8; extra == 'dev'
56
+ Description-Content-Type: text/markdown
57
+
58
+ # hadsync
59
+
60
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
61
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)
62
+ [![Tested on HA 2026.5](https://img.shields.io/badge/Home%20Assistant-2026.5-41BDF5?logo=home-assistant&logoColor=white)](https://www.home-assistant.io/)
63
+
64
+ **Home Assistant Dashboard Sync** — pull, edit, and push Lovelace dashboards as code.
65
+
66
+ HA stores Lovelace dashboard configs in its internal storage layer. There is no supported workflow for editing dashboards locally in a code editor, tracking changes with git, and pushing updates back safely. `hadsync` bridges that gap via the HA WebSocket API.
67
+
68
+ ![hadsync VS Code extension — dashboard explorer, entity autocomplete, and sync status table](docs/vscode-screenshot.jpg)
69
+ *Dashboard explorer, entity ID autocomplete, and hadsync sync status — all in VS Code.*
70
+
71
+ ![Hovering over an entity ID shows live state, last-changed time, and attributes from your running HA instance](docs/vscode-entities-screenshot.jpg)
72
+ *Hover any entity ID to see its live value and attributes, courtesy of the HA Config Helper extension.*
73
+
74
+ ---
75
+
76
+ [Features](#features) · [Quick Start](#quick-start) · [Commands](#commands) · [In Action](#in-action) · [Conflict Detection](#conflict-detection) · [Validation](#validation) · [VS Code Extension](#vs-code-extension) · [Configuration](#configuration) · [Installation](#installation)
77
+
78
+ ---
79
+
80
+ ## Features
81
+
82
+ - Pull any or all Lovelace dashboards from a live HA instance to local YAML
83
+ - Push locally edited YAML back to HA — change summary, destructive-change warnings, explicit confirmation
84
+ - Three-phase validation (syntax → entity IDs → card schema) run before every push
85
+ - Diff local YAML vs live HA state — conflict detection, view-level summary, coloured unified diff
86
+ - Entity ID validation against a cached HA entity registry (621 entities on a typical instance)
87
+ - Card schema validation — 35 standard Lovelace card types, `custom:*` always allowed
88
+ - Watch mode — validates on every file save; optional auto-push when validation passes
89
+ - Status table — last pull/push timestamps and local change detection per dashboard
90
+ - **VS Code extension** — inline diagnostics, command palette, status bar, entity ID autocomplete
91
+ - Git-friendly: plain YAML files, one directory per dashboard named by `url_path`
92
+
93
+ ## Installation
94
+
95
+ ```bash
96
+ pip install hadsync # once published to PyPI
97
+ ```
98
+
99
+ Requires Python 3.11+.
100
+
101
+ ### Install from source
102
+
103
+ **With uv — installs `hadsync` globally so it works from any directory:**
104
+
105
+ ```bash
106
+ # production install (run from anywhere after this)
107
+ uv tool install /path/to/hadsync
108
+
109
+ # editable install — code changes take effect immediately, no reinstall needed
110
+ uv tool install --editable /path/to/hadsync
111
+
112
+ # update after pulling new commits (non-editable)
113
+ uv tool install --reinstall /path/to/hadsync
114
+ ```
115
+
116
+ **With pip:**
117
+
118
+ ```bash
119
+ pip install -e ".[dev]"
120
+ ```
121
+
122
+ ## Two-Repo Setup (Recommended)
123
+
124
+ hadsync is designed to keep two things separate:
125
+
126
+ - **`hadsync/`** — this repo ([github.com/gevgev/hadsync](https://github.com/gevgev/hadsync)), CLI tool source code only
127
+ - **`home-assistant-dashboards/`** — a dedicated repo for your dashboard YAML files
128
+
129
+ This means your dashboard history is independent of the tool version history, and you can share or back up dashboards without exposing tool internals.
130
+
131
+ ## Quick Start
132
+
133
+ ```bash
134
+ # 1. Set your HA long-lived access token
135
+ export HA_TOKEN=eyJ...
136
+
137
+ # 2. Create and enter your dashboards repo
138
+ mkdir home-assistant-dashboards && cd home-assistant-dashboards
139
+ git init
140
+
141
+ # 3. Initialize hadsync (creates .hadsync.yaml here, workspace defaults to .)
142
+ hadsync init
143
+
144
+ # 4. List available dashboards on your HA instance
145
+ hadsync list
146
+
147
+ # 5. Pull all dashboards to local YAML
148
+ hadsync pull
149
+
150
+ # 6. Edit in VS Code (or any editor)
151
+ code .
152
+
153
+ # 7. Validate before pushing
154
+ hadsync validate
155
+
156
+ # 8. Push back to HA
157
+ hadsync push
158
+ ```
159
+
160
+ Alternatively, keep `.hadsync.yaml` anywhere and point to the dashboards folder via env var:
161
+
162
+ ```bash
163
+ export HA_TOKEN=eyJ...
164
+ export HADSYNC_WORKSPACE=~/home-assistant-dashboards
165
+ hadsync pull # works from any directory
166
+ ```
167
+
168
+ ## Configuration
169
+
170
+ `hadsync init` creates `.hadsync.yaml` in the current directory:
171
+
172
+ ```yaml
173
+ ha_url: http://homeassistant.local:8123
174
+ ha_token: ${HA_TOKEN} # env var reference — never store the token literally
175
+ workspace: . # path to dashboard YAML files; defaults to current directory
176
+
177
+ pull:
178
+ refresh_entities: true # refresh entity cache on every pull
179
+ dashboards: all # or list: [lovelace, battery-status]
180
+
181
+ push:
182
+ require_validation: true # block push on validation errors
183
+ confirm: true # ask for confirmation before each push
184
+
185
+ validation:
186
+ warn_on_unknown_entities: true # Phase 2: warn vs error for unknown entity IDs
187
+ entity_cache_max_age_days: 7 # warn if entity cache is older than this
188
+ custom_card_types: [] # Phase 3: extra type prefixes treated as valid
189
+ # e.g. ["my-custom:"] alongside custom:*
190
+ ```
191
+
192
+ ### Environment Variables
193
+
194
+ | Variable | Description |
195
+ |---|---|
196
+ | `HA_TOKEN` | HA long-lived access token (referenced as `${HA_TOKEN}` in config) |
197
+ | `HADSYNC_WORKSPACE` | Override the workspace directory at runtime — takes priority over config |
198
+
199
+ The token is always referenced via an environment variable. Never embed it in the config file.
200
+
201
+ ## Commands
202
+
203
+ | Command | Description |
204
+ |---|---|
205
+ | `hadsync init` | Interactive setup: URL, token env var, workspace dir |
206
+ | `hadsync list` | List all storage-mode dashboards on the HA instance |
207
+ | `hadsync pull [ID]` | Pull one or all dashboards from HA to local YAML; refreshes entity cache |
208
+ | `hadsync push [ID]` | Push local YAML to HA — validates (P1+P2+P3), shows change summary, confirms |
209
+ | `hadsync push [ID] --dry-run` | Show what would be sent without pushing |
210
+ | `hadsync diff [ID]` | Compare local vs HA — conflict detection, pull timestamp, view-level summary |
211
+ | `hadsync diff [ID] --show` | As above, plus coloured unified diff |
212
+ | `hadsync validate [ID]` | Run Phase 1+2+3 validation without pushing |
213
+ | `hadsync watch [ID]` | Watch for file saves and validate automatically |
214
+ | `hadsync watch [ID] --auto-push` | Watch and push to HA when validation passes |
215
+ | `hadsync status` | Table: last pull, last push, local change state per dashboard |
216
+ | `hadsync entities refresh` | Fetch all entity IDs from HA and update local cache |
217
+ | `hadsync entities list [filter]` | List cached entities, filtered by domain or friendly name |
218
+ | `hadsync config show` | Print resolved config (token masked, workspace source shown) |
219
+ | `hadsync config set KEY VALUE` | Set a config value |
220
+
221
+ **Global flags:** `--dry-run`, `--verbose / -v`, `--quiet / -q`, `--yes / -y`, `--json-output`, `--config PATH`
222
+
223
+ ## Validation
224
+
225
+ `hadsync validate` (and pre-push validation in `hadsync push`) runs three phases:
226
+
227
+ | Phase | What it checks |
228
+ |---|---|
229
+ | 1 — Syntax & structure | YAML parse errors (with line numbers), `views` key present and a list, no non-mapping view entries |
230
+ | 2 — Entity IDs | Every `entity:` / `entities:` reference checked against `.ha-entities.json` cache; warns on unknowns; skipped if cache absent |
231
+ | 3 — Card schema | Each card's `type` is a known standard type; required fields are present; `custom:*` cards always pass |
232
+
233
+ Phase 2 is silently skipped if the entity cache doesn't exist yet — run `hadsync entities refresh` to enable it. Phase 3 warns on unknown types rather than blocking, so HACS cards never cause failures.
234
+
235
+ ## Conflict Detection
236
+
237
+ Every `hadsync pull` stores a hash of the HA config in `.hadsync-state.json`. `hadsync diff` uses this to classify divergences:
238
+
239
+ | Situation | HA hash | Local mtime | Verdict |
240
+ |---|---|---|---|
241
+ | Both changed since pull | changed | > last pull | **CONFLICT** — explicit next-step options shown |
242
+ | HA changed, local clean | changed | ≤ last pull | Suggests `hadsync pull <id>` |
243
+ | Local changed, HA untouched | same | > last pull | Suggests `hadsync push <id>` |
244
+ | Never pulled / old state | no hash | — | Diff shown without classification |
245
+
246
+ Example CONFLICT output:
247
+ ```
248
+ battery-status
249
+ Last pull: 2026-05-10 18:19 (2h ago)
250
+ HA: 1 views, 5 cards ← changed since pull
251
+ Local: 1 views, 5 cards ← modified since pull
252
+ ~ Battery Status: content changed
253
+
254
+ ✗ CONFLICT — both sides changed since last pull.
255
+ hadsync push battery-status — overwrite HA with local (discards HA edits)
256
+ hadsync pull battery-status — overwrite local with HA (discards local edits)
257
+ ```
258
+
259
+ ## In Action
260
+
261
+ ### `hadsync diff` — conflict summary
262
+
263
+ ![hadsync diff showing a CONFLICT: HA has 6 views 33 cards, local has 6 views 32 cards, both changed since last pull](docs/diff-conflict-summary.jpg)
264
+
265
+ *Both HA and local changed since the last pull — hadsync detects the conflict, identifies the modified view, and shows the two resolution options with their consequences.*
266
+
267
+ ### `hadsync diff --show` — unified diff
268
+
269
+ ![hadsync diff --show displaying the full coloured unified diff below the conflict summary](docs/diff-show-flag.jpg)
270
+
271
+ *The `--show` flag appends a full coloured unified diff beneath the conflict summary: red lines are what HA currently has, green lines are what your local file contains. Changes are shown at the YAML level so you can see exactly which card fields or view titles were edited on each side.*
272
+
273
+ ### VS Code — inline diagnostics and Problems panel
274
+
275
+ ![VS Code editor showing yellow squiggles on lines 192 and 227, with the Problems panel listing an unknown entity ID and a card missing its required entity field](docs/vscode-problems-panel.jpg)
276
+
277
+ *hadsync validation runs on every save and surfaces issues as inline squiggles and Problems panel entries with exact line numbers — here flagging an unknown entity ID (`sensor.meter_patio_co2_concentration` no longer exists in HA) and a `sensor` card that is missing its required `entity` field. Both issues are caught before anything is pushed to HA.*
278
+
279
+ ### VS Code — entity autocomplete alongside live diagnostics
280
+
281
+ ![VS Code autocomplete dropdown showing sensor.meter_* entity completions while the Problems panel below simultaneously shows two active hadsync warnings](docs/vscode-autocomplete.jpg)
282
+
283
+ *Typing a partial entity ID opens a completion list drawn from the hadsync entity cache (621 entities, refreshed on pull). Friendly names appear on the right for quick identification. The Problems panel remains visible below — you can fix the flagged issue and pick the correct entity in the same editor without switching context.*
284
+
285
+ ### VS Code — command palette
286
+
287
+ ![VS Code command palette showing all hadsync commands: Validate All Dashboards, Diff This Dashboard, List HA Dashboards, Show Sync Status, Pull, Push, Refresh Entity Cache, and more](docs/vscode-command-palette.jpg)
288
+
289
+ *All hadsync operations are available from `Cmd+Shift+P`. The full set — validate, diff, pull, push, status, list, entity cache refresh, entity search — without leaving VS Code or opening a terminal.*
290
+
291
+ ## Workspace Layout
292
+
293
+ ```
294
+ home-assistant-dashboards/ # dashboards repo — committed to git
295
+ .hadsync.yaml # connection config (workspace: .)
296
+ .gitignore # excludes state/cache files
297
+ battery-status/
298
+ lovelace.yaml
299
+ lovelace-cameras/
300
+ lovelace.yaml
301
+ dashboard-security/
302
+ lovelace.yaml
303
+ ... # one directory per dashboard (named by url_path)
304
+ ```
305
+
306
+ Files excluded from git (auto-added to `.gitignore` by `hadsync init`):
307
+ - `.hadsync-state.json` — last pull/push timestamps per dashboard
308
+ - `.ha-entities.json` — entity ID cache (refreshed on every pull)
309
+
310
+ ## Development
311
+
312
+ ```bash
313
+ # Install globally so hadsync works from any directory
314
+ uv tool install --editable /path/to/hadsync
315
+
316
+ # Install dev dependencies for running tests
317
+ uv sync --extra dev
318
+ uv run pytest tests/
319
+
320
+ # Run against a real HA instance
321
+ export HA_TOKEN=eyJ...
322
+ hadsync list
323
+ ```
324
+
325
+ ## VS Code Extension
326
+
327
+ The `vscode-hadsync/` directory contains a VS Code extension that wraps the CLI.
328
+
329
+ ### Installation (one-time)
330
+
331
+ ```bash
332
+ # 1. Enter the extension directory
333
+ cd /path/to/hadsync/vscode-hadsync
334
+
335
+ # 2. Install Node dependencies and compile TypeScript
336
+ npm install
337
+ npm run compile # produces vscode-hadsync/out/
338
+
339
+ # 3. Package into a .vsix installer file
340
+ npx @vscode/vsce package --no-dependencies
341
+ # → creates vscode-hadsync/hadsync-0.1.0.vsix
342
+
343
+ # 4. Install in VS Code (command line — easiest)
344
+ code --install-extension hadsync-0.1.0.vsix
345
+ ```
346
+
347
+ After step 4, restart VS Code. The extension activates automatically in any workspace folder that contains a `.hadsync.yaml` file.
348
+
349
+ **Alternative (VS Code UI):** `Cmd+Shift+P` → `Extensions: Install from VSIX...` → navigate to `vscode-hadsync/hadsync-0.1.0.vsix` → Open.
350
+
351
+ ### Updating after CLI changes
352
+
353
+ Re-run steps 2–4 whenever you pull new commits to the hadsync CLI:
354
+
355
+ ```bash
356
+ cd vscode-hadsync
357
+ npm run compile && npx @vscode/vsce package --no-dependencies
358
+ code --install-extension hadsync-0.1.0.vsix
359
+ ```
360
+
361
+ ### Features
362
+
363
+ - **Inline diagnostics** — validates every `lovelace.yaml` on save; errors and warnings appear in the Problems panel (`Cmd+Shift+M`) and as editor squiggles with line numbers; **automatically re-validates when files change externally** (e.g. after `hadsync pull` in the terminal)
364
+ - **Command palette** (`Cmd+Shift+P`) — pull, push (with VS Code confirmation dialog), validate, diff, status, list, entities refresh/search
365
+ - **Status bar** — bottom-left shows last pull time or count of locally-modified dashboards (based on file mtime, matching `hadsync status`); click for full status table
366
+ - **Entity autocomplete** — typing `entity: ` triggers completions from `.ha-entities.json` with friendly name and domain
367
+ - **Right-click context menu** — validate / push / diff available directly in any `lovelace.yaml` editor
368
+
369
+ Pair hadsync with the [Home Assistant Config Helper](https://marketplace.visualstudio.com/items?itemName=keesschollaart.vscode-home-assistant) extension for a complete live editing experience: hover over any entity ID to see its **current state, last-changed timestamp, and attributes** pulled directly from your running HA instance — while hadsync validation ensures every referenced entity actually exists.
370
+
371
+ ### Settings
372
+
373
+ | Setting | Default | Description |
374
+ |---|---|---|
375
+ | `hadsync.executablePath` | `""` | Full path to hadsync binary. Leave blank to use PATH. |
376
+ | `hadsync.validateOnSave` | `true` | Validate automatically when a lovelace.yaml is saved. |
377
+ | `hadsync.autoPushOnSave` | `false` | Push to HA automatically after a clean validation on save. |
378
+
379
+ ## Implementation Status
380
+
381
+ | Phase | Description | Status |
382
+ |---|---|---|
383
+ | 1 — Core CLI | pull / push / validate / diff / status / state tracking | ✅ Complete |
384
+ | 2 — Entity Validation | entity cache, entity ID existence checks in YAML | ✅ Complete |
385
+ | 3 — Schema Validation & Watch | card type schema, watch mode, auto-push, enhanced diff | ✅ Complete |
386
+ | 4 — VS Code Extension | palette commands, inline diagnostics, entity autocomplete | ✅ Complete |
387
+
388
+ ## HA API Notes
389
+
390
+ Tested against **Home Assistant 2026.5**. Key WS commands used:
391
+
392
+ | Operation | Command |
393
+ |---|---|
394
+ | List dashboards | `get_panels` (filter `component_name=lovelace`) |
395
+ | Fetch dashboard config | `lovelace/config` with `url_path` |
396
+ | Save dashboard config | `lovelace/config/save` with `url_path` |
397
+ | Fetch entity list | `GET /api/states` (REST) |
398
+
399
+ > **Note:** The design document references `lovelace/dashboards` and `lovelace/save_config` — these commands do not exist in HA 2026.5. The correct commands are listed above.
400
+
401
+ ## License
402
+
403
+ MIT
@@ -0,0 +1,17 @@
1
+ hadsync/__init__.py,sha256=m6kyaNpwBcP1XYcqrelX2oS3PJuOnElOcRdBa9pEb8c,22
2
+ hadsync/cli.py,sha256=Nkp7GqdexZOyq_8MZklQtLcrhjbreHf5J9nuvxrNuMs,38423
3
+ hadsync/config.py,sha256=MCSUb0MN1PdJkLNiPHKarY5sSYHJXvT8gjnRq3d2GFI,3689
4
+ hadsync/converter.py,sha256=zdV5IN_PkIPlIV5hXIyFwj9v5Mbf8feopfU3x5-Y8Vk,2312
5
+ hadsync/entities.py,sha256=iTlzgiCPLuWV4siUL7GcXOeRf0YvOQiTIslzqSqtwgc,4773
6
+ hadsync/ha_rest.py,sha256=MjL5rkUzpuHvMVkIAc4Amvte1wKPyFnsv-MQvjrw3qg,1450
7
+ hadsync/ha_ws.py,sha256=BTlKZ0eRaKw2SgNF2OUc4Bqn50Z4K4KXBfACx7r0PVY,5468
8
+ hadsync/output.py,sha256=bFsbI76BD5VoJbQGKJzkeaiK1uAEDxzoWNGKbOCouXE,405
9
+ hadsync/schema.py,sha256=lbOJLFCWkCh_OPz6MebA1afxJvsmvyOMOn02kN25g2g,4796
10
+ hadsync/state.py,sha256=qSVYOowMUER9ner-Zh5OUqvRXHlaa74ELo4iAHvE7FU,1551
11
+ hadsync/validator.py,sha256=A01og62_s3UnuPV3FoT3zIl6poImBnDNkNQhho-nfHc,5376
12
+ hadsync/watcher.py,sha256=eb7HWp-bu8OLNBmWb0p24USzuzYldw4JVWy9_-AokgA,4370
13
+ hadsync-0.2.2.dist-info/METADATA,sha256=cVUjEiEo72Xl32QOk8Wpt3cYBJn7n92E7gCo5kmNY3w,18524
14
+ hadsync-0.2.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
15
+ hadsync-0.2.2.dist-info/entry_points.txt,sha256=KQkNXB6K0HWv9poRjkr4K9KypZw_8PRm3i4arFxFkYY,44
16
+ hadsync-0.2.2.dist-info/licenses/LICENSE,sha256=60WRi_GtNcs3ReWbyAZOXvQdoN0F1x_G2GR0lWirTak,1073
17
+ hadsync-0.2.2.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hadsync = hadsync.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gevorg Gevorgyan
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.