hadsync 0.2.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 (51) hide show
  1. hadsync-0.2.2/.claude/settings.local.json +13 -0
  2. hadsync-0.2.2/.github/ISSUE_TEMPLATE/bug_report.md +34 -0
  3. hadsync-0.2.2/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  4. hadsync-0.2.2/.gitignore +32 -0
  5. hadsync-0.2.2/.hadsync.yaml +12 -0
  6. hadsync-0.2.2/CHANGELOG.md +103 -0
  7. hadsync-0.2.2/CONTRIBUTING.md +42 -0
  8. hadsync-0.2.2/LICENSE +21 -0
  9. hadsync-0.2.2/PKG-INFO +403 -0
  10. hadsync-0.2.2/README.md +346 -0
  11. hadsync-0.2.2/docs/diff-conflict-summary.jpg +0 -0
  12. hadsync-0.2.2/docs/diff-show-flag.jpg +0 -0
  13. hadsync-0.2.2/docs/vscode-autocomplete.jpg +0 -0
  14. hadsync-0.2.2/docs/vscode-command-palette.jpg +0 -0
  15. hadsync-0.2.2/docs/vscode-entities-screenshot.jpg +0 -0
  16. hadsync-0.2.2/docs/vscode-problems-panel.jpg +0 -0
  17. hadsync-0.2.2/docs/vscode-screenshot.jpg +0 -0
  18. hadsync-0.2.2/hadsync/__init__.py +1 -0
  19. hadsync-0.2.2/hadsync/cli.py +979 -0
  20. hadsync-0.2.2/hadsync/config.py +123 -0
  21. hadsync-0.2.2/hadsync/converter.py +73 -0
  22. hadsync-0.2.2/hadsync/entities.py +134 -0
  23. hadsync-0.2.2/hadsync/ha_rest.py +41 -0
  24. hadsync-0.2.2/hadsync/ha_ws.py +144 -0
  25. hadsync-0.2.2/hadsync/output.py +20 -0
  26. hadsync-0.2.2/hadsync/schema.py +138 -0
  27. hadsync-0.2.2/hadsync/state.py +57 -0
  28. hadsync-0.2.2/hadsync/validator.py +168 -0
  29. hadsync-0.2.2/hadsync/watcher.py +119 -0
  30. hadsync-0.2.2/hadsync_design.docx +0 -0
  31. hadsync-0.2.2/pyproject.toml +71 -0
  32. hadsync-0.2.2/tests/__init__.py +0 -0
  33. hadsync-0.2.2/tests/unit/__init__.py +0 -0
  34. hadsync-0.2.2/tests/unit/test_config.py +146 -0
  35. hadsync-0.2.2/tests/unit/test_converter.py +120 -0
  36. hadsync-0.2.2/tests/unit/test_entities.py +218 -0
  37. hadsync-0.2.2/tests/unit/test_schema.py +112 -0
  38. hadsync-0.2.2/tests/unit/test_state.py +64 -0
  39. hadsync-0.2.2/tests/unit/test_validator.py +103 -0
  40. hadsync-0.2.2/vscode-hadsync/.vscodeignore +8 -0
  41. hadsync-0.2.2/vscode-hadsync/LICENSE +21 -0
  42. hadsync-0.2.2/vscode-hadsync/README.md +100 -0
  43. hadsync-0.2.2/vscode-hadsync/package-lock.json +59 -0
  44. hadsync-0.2.2/vscode-hadsync/package.json +119 -0
  45. hadsync-0.2.2/vscode-hadsync/src/commands.ts +270 -0
  46. hadsync-0.2.2/vscode-hadsync/src/completion.ts +54 -0
  47. hadsync-0.2.2/vscode-hadsync/src/diagnostics.ts +115 -0
  48. hadsync-0.2.2/vscode-hadsync/src/extension.ts +130 -0
  49. hadsync-0.2.2/vscode-hadsync/src/runner.ts +106 -0
  50. hadsync-0.2.2/vscode-hadsync/src/statusBar.ts +107 -0
  51. hadsync-0.2.2/vscode-hadsync/tsconfig.json +12 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python3 -c ' *)",
5
+ "Bash(HA_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1MWNjNTg4MzY0NzA0ODk0YThjOWMwMDg2ZGEwYTc2MCIsImlhdCI6MTc3ODE3NjgyNiwiZXhwIjoyMDkzNTM2ODI2fQ.BFWPnJp6Zxm0TIw5kGn2hImfEk51LOHnqQ_Zm5Dr09I hadsync init)",
6
+ "Bash(HA_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1MWNjNTg4MzY0NzA0ODk0YThjOWMwMDg2ZGEwYTc2MCIsImlhdCI6MTc3ODE3NjgyNiwiZXhwIjoyMDkzNTM2ODI2fQ.BFWPnJp6Zxm0TIw5kGn2hImfEk51LOHnqQ_Zm5Dr09I hadsync config *)",
7
+ "Bash(python3 -c \"import websockets; print\\(dir\\(websockets\\)\\)\")",
8
+ "Bash(git init *)",
9
+ "Bash(HA_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI1MWNjNTg4MzY0NzA0ODk0YThjOWMwMDg2ZGEwYTc2MCIsImlhdCI6MTc3ODE3NjgyNiwiZXhwIjoyMDkzNTM2ODI2fQ.BFWPnJp6Zxm0TIw5kGn2hImfEk51LOHnqQ_Zm5Dr09I hadsync *)",
10
+ "Read(//Users/ggevorgyan/git/esp32/esp-tool/**)"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Bug report
3
+ about: Something isn't working as expected
4
+ labels: bug
5
+ ---
6
+
7
+ **hadsync version**
8
+ <!-- run: hadsync --version -->
9
+
10
+ **Home Assistant version**
11
+ <!-- run: hadsync list (shows HA version on connect), or check HA → Settings → About -->
12
+
13
+ **Command that failed**
14
+ ```
15
+ hadsync ...
16
+ ```
17
+
18
+ **What happened**
19
+ <!-- Clear description of the bug -->
20
+
21
+ **Steps to reproduce**
22
+ 1.
23
+ 2.
24
+ 3.
25
+
26
+ **Expected behaviour**
27
+
28
+ **Actual behaviour / error output**
29
+ ```
30
+ paste output here
31
+ ```
32
+
33
+ **Additional context**
34
+ <!-- Dashboard type (storage-mode vs strategy), network setup, etc. -->
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an improvement or new command
4
+ labels: enhancement
5
+ ---
6
+
7
+ **What problem does this solve?**
8
+ <!-- Describe the workflow gap or pain point -->
9
+
10
+ **Proposed solution**
11
+ <!-- How you'd like it to work. CLI examples are helpful. -->
12
+
13
+ **Alternatives considered**
14
+ <!-- Other approaches you've thought of -->
15
+
16
+ **Additional context**
17
+ <!-- Screenshots, HA version, dashboard structure, etc. -->
@@ -0,0 +1,32 @@
1
+ # Python
2
+ .venv/
3
+ uv.lock
4
+ .python-version
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ .eggs/
11
+
12
+ # Testing / coverage
13
+ .pytest_cache/
14
+ .coverage
15
+ htmlcov/
16
+
17
+ # Editors
18
+ .vscode/
19
+ .idea/
20
+ *.swp
21
+
22
+ # hadsync runtime files
23
+ .hadsync-state.json
24
+ .ha-entities.json
25
+
26
+ # dashboard workspace — lives in its own repo
27
+ ha-dashboards/
28
+
29
+ # VS Code extension build artifacts
30
+ vscode-hadsync/out/
31
+ vscode-hadsync/node_modules/
32
+ vscode-hadsync/*.vsix
@@ -0,0 +1,12 @@
1
+ ha_url: http://192.168.68.103:8123
2
+ ha_token: ${HA_TOKEN}
3
+ workspace: /Users/ggevorgyan/git/esp32/esphome/home-assistant-dashboards
4
+ pull:
5
+ refresh_entities: true
6
+ dashboards: all
7
+ push:
8
+ require_validation: true
9
+ confirm: true
10
+ validation:
11
+ warn_on_unknown_entities: true
12
+ entity_cache_max_age_days: 7
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ ## [v0.2.2] — 2026-05-10
4
+
5
+ ### Fixed — VS Code Extension
6
+
7
+ - **Stale diagnostics after external pull** — Problems panel no longer retains old errors after `hadsync pull` is run from the terminal. A `FileSystemWatcher` on `**/lovelace.yaml` now re-validates automatically when any file changes on disk, regardless of whether the change came from VS Code or an external process.
8
+ - **Incorrect "N modified" in status bar** — The status bar was counting every dashboard that had never been pushed as "modified", showing e.g. `13 modified` immediately after a clean pull. Fixed to use the same mtime-vs-last_pull comparison as `hadsync status` in the CLI — "modified" now means the local file was actually edited since the last pull.
9
+
10
+ [v0.2.2]: https://github.com/gevgev/hadsync/releases/tag/v0.2.2
11
+
12
+ ---
13
+
14
+ ## [v0.2.1] — 2026-05-10
15
+
16
+ ### Added — Phase 1b (Conflict Detection)
17
+
18
+ - **`hadsync diff` conflict detection** — stores a hash of the HA config at every pull; diff now classifies each divergence into one of four verdicts:
19
+ - **CONFLICT** — both local and HA changed since last pull (shown in red with explicit next-step options)
20
+ - **HA changed only** — warns and suggests `hadsync pull <id>`
21
+ - **Local changed only** — warns and suggests `hadsync push <id>`
22
+ - **No baseline** — generic message when dashboard was never pulled with the new hash tracking
23
+ - **Pull timestamp in diff output** — `Last pull: 2026-05-10 18:19 (2h ago)` shown for each dashboard
24
+ - **Annotated change summary** — HA and local card counts now show `← changed since pull` or `(unchanged since pull)` tags
25
+ - **`ha_config_hash`** field in `.hadsync-state.json` — 16-char SHA-256 prefix of the normalized HA config stored on every pull; enables HA-side change detection without keeping a full config snapshot
26
+
27
+ ### Fixed
28
+
29
+ - **Error handling gaps (community review)** — VS Code extension now shows `showErrorMessage()` popups on command failure; detects `hadsync not found` at activation with an Open Settings link; `onDidSaveTextDocument` wrapped in try/catch; 60-second subprocess timeout prevents VS Code freeze
30
+ - **Python error messages** — `ha_ws.py` now distinguishes connection refused, DNS failure, timeout, and auth_invalid with targeted, actionable messages including next-step hints (e.g. where to generate a long-lived token in HA)
31
+ - **Watch mode resilience** — `watcher.py` event handler wrapped in try/catch so an unexpected crash no longer silently kills the watchdog observer thread
32
+
33
+ [v0.2.1]: https://github.com/gevgev/hadsync/releases/tag/v0.2.1
34
+
35
+ ---
36
+
37
+ ## [v0.2.0] — 2026-05-09
38
+
39
+ Phases 2, 3, and 4 complete. All four design phases are now implemented.
40
+
41
+ ### Added — Phase 2 (Entity Validation)
42
+
43
+ - **`hadsync entities refresh`** — fetches all entity states from HA `/api/states` and writes `.ha-entities.json`
44
+ - **`hadsync entities list [filter]`** — lists cached entities with domain and friendly name, filtered by substring
45
+ - **Entity ID extraction** — recursive walk of any Lovelace config depth; handles `entity:`, `entities:` (strings and dicts), conditional conditions, stack nesting, picture-elements, and any other nesting pattern
46
+ - **Phase 2 validation** — unknown entity IDs reported with line numbers; silently skipped if cache is absent (no friction before first `entities refresh`)
47
+ - **Cache age warning** — warns when entity cache exceeds `validation.entity_cache_max_age_days` (default: 7)
48
+ - **`validation.warn_on_unknown_entities`** config flag — controls whether unknown IDs are warnings (default) or errors that block push
49
+
50
+ ### Added — Phase 3 (Schema Validation & Watch)
51
+
52
+ - **`hadsync watch [ID] [--auto-push]`** — watches workspace for `lovelace.yaml` saves; runs Phase 1+2+3 validation on every change; pushes to HA automatically when validation passes if `--auto-push` is set
53
+ - **Phase 3 card schema validation** — 35 standard Lovelace card types with required-field checks; `custom:*` always passes; unknown non-custom types warn rather than block; extra prefixes configurable via `validation.custom_card_types`
54
+ - **Enhanced `hadsync diff`** — view-by-view change summary (`+ added`, `- removed`, `~ N cards changed`) shown before the optional unified diff
55
+ - **`validation.custom_card_types`** config field — list of additional type prefixes treated as valid alongside `custom:*`
56
+
57
+ ### Added — Phase 4 (VS Code Extension)
58
+
59
+ - **`vscode-hadsync/`** — VS Code extension written in TypeScript; activates on any workspace containing `.hadsync.yaml`
60
+ - **11 palette commands** (`Cmd+Shift+P`): pull (all / active), push (all / active, with confirmation dialog), validate (all / active), diff, status, list, entities refresh, entities search
61
+ - **Inline diagnostics** — on `lovelace.yaml` save, runs `hadsync --json-output validate`; errors and warnings appear in the Problems panel and as editor squiggles with correct line numbers
62
+ - **Status bar** — bottom-left item shows last pull time or modified-dashboard count; reads `.hadsync-state.json` directly; click opens status table
63
+ - **Entity ID autocomplete** — completion items from `.ha-entities.json` triggered by `entity: ` and list item patterns; includes friendly name and domain in detail
64
+ - **Context menu** — validate / push / diff available on right-click in any `lovelace.yaml` editor
65
+ - **Settings**: `hadsync.executablePath`, `hadsync.validateOnSave` (default: true), `hadsync.autoPushOnSave` (default: false)
66
+
67
+ ### Changed
68
+
69
+ - **`hadsync validate --json-output`** — emits structured JSON (per-dashboard file path, passed flag, issue list with severity/message/line); used by the VS Code extension for diagnostics; human output unchanged when flag is absent
70
+ - **Validation pipeline** — `hadsync validate` and `hadsync push` pre-push validation now run Phase 1 + Phase 2 + Phase 3 in sequence
71
+ - **`hadsync diff`** — now includes view-level summary before optional unified diff
72
+
73
+ ### Notes
74
+
75
+ - Tested against **Home Assistant 2026.5.0**
76
+ - VS Code extension requires `hadsync` on PATH or `hadsync.executablePath` setting; `HA_TOKEN` must be in the environment VS Code inherits
77
+
78
+ ---
79
+
80
+ ## [v0.1.0] — 2026-05-08
81
+
82
+ Initial release. Phase 1 (Core CLI) complete.
83
+
84
+ ### Added
85
+
86
+ - **`hadsync init`** — interactive setup: HA URL, token env var (with validation to catch pasted token values), workspace directory. Tests live HA connection.
87
+ - **`hadsync list`** — discovers all storage-mode Lovelace dashboards on the HA instance.
88
+ - **`hadsync pull [ID]`** — downloads one or all dashboards from HA as local YAML; auto-refreshes entity cache (`.ha-entities.json`); skips strategy-based dashboards with a warning.
89
+ - **`hadsync push [ID]`** — uploads local YAML to HA with layered safety: pre-push validation, no-op guard (skips if already in sync), change summary (view/card counts), destructive-change warnings, explicit per-dashboard confirmation, and `--dry-run` mode.
90
+ - **`hadsync validate [ID]`** — standalone YAML validation (syntax + structure) with PASS / WARN / FAIL per dashboard and line numbers on errors. Safe for CI pipelines — no HA connection required.
91
+ - **`hadsync status`** — sync status table: last pull time, last push time, local state (clean / modified / never pulled). No HA connection required.
92
+ - **`hadsync diff [ID] [--show]`** — compares local YAML against live HA state. `--show` renders a coloured unified diff (red = HA, green = local).
93
+ - **`hadsync config show`** — displays resolved config with masked token and workspace source.
94
+ - **`HADSYNC_WORKSPACE` env var** — overrides the workspace directory at runtime without editing config.
95
+
96
+ ### Notes
97
+
98
+ - Tested against **Home Assistant 2026.5.0**.
99
+ - The HA WebSocket commands referenced in common documentation (`lovelace/dashboards`, `lovelace/save_config`) do not exist in HA 2026.5. This release uses the correct equivalents: `get_panels` (filtered by `component_name=lovelace`) and `lovelace/config/save`.
100
+ - Strategy-based dashboards (auto-generated by HA, e.g. the default Overview using `original-states` strategy) are detected during pull and skipped — they cannot be meaningfully round-tripped as static YAML.
101
+
102
+ [v0.2.0]: https://github.com/gevgev/hadsync/releases/tag/v0.2.0
103
+ [v0.1.0]: https://github.com/gevgev/hadsync/releases/tag/v0.1.0
@@ -0,0 +1,42 @@
1
+ # Contributing to hadsync
2
+
3
+ Contributions are welcome — bug reports, feature requests, and pull requests.
4
+
5
+ ## Before you open a PR
6
+
7
+ - Check [open issues](https://github.com/gevgev/hadsync/issues) to avoid duplicate work
8
+ - For anything beyond a small fix, open an issue first to discuss the approach
9
+
10
+ ## Development setup
11
+
12
+ ```bash
13
+ git clone https://github.com/gevgev/hadsync.git
14
+ cd hadsync
15
+ uv tool install --editable . # or: pip install -e ".[dev]"
16
+ pytest tests/
17
+ ```
18
+
19
+ ## Running tests
20
+
21
+ ```bash
22
+ pytest tests/ # 43 unit tests, no HA connection required
23
+ pytest tests/unit/ # unit tests only
24
+ ```
25
+
26
+ Unit tests use no live HA instance. If you change `ha_ws.py`, please also test manually against a real HA instance — the WebSocket API has version-specific behavior that mocks cannot fully capture.
27
+
28
+ ## HA version compatibility
29
+
30
+ hadsync is tested against **Home Assistant 2026.5**. Please note the HA version you tested against in your PR description.
31
+
32
+ > **Note:** The WS commands used differ from common documentation. See [HA API Notes](README.md#ha-api-notes) in the README before touching the WebSocket client.
33
+
34
+ ## Code style
35
+
36
+ - Python 3.11+, type annotations throughout
37
+ - No comments describing *what* the code does — only *why* when non-obvious
38
+ - Keep modules focused: CLI routing lives in `cli.py`, HA communication in `ha_ws.py` / `ha_rest.py`, etc.
39
+
40
+ ## Reporting bugs
41
+
42
+ Please use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md) and include your HA version — it matters for reproducing WS API issues.
hadsync-0.2.2/LICENSE ADDED
@@ -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.