flameconnect 0.1.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.
Files changed (155) hide show
  1. flameconnect-0.1.0/.ai/task-manager/.init-metadata.json +18 -0
  2. flameconnect-0.1.0/.ai/task-manager/README.md +7 -0
  3. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/plan-01--project-foundation.md +401 -0
  4. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/01--project-scaffolding.md +126 -0
  5. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/02--models-constants-exceptions.md +108 -0
  6. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/03--wire-protocol.md +83 -0
  7. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/04--auth-module.md +97 -0
  8. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/05--async-client.md +133 -0
  9. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/06--tests-protocol-and-client.md +115 -0
  10. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/07--cli-tool.md +133 -0
  11. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/08--tui-dashboard.md +127 -0
  12. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/09--ci-cd-workflows.md +145 -0
  13. flameconnect-0.1.0/.ai/task-manager/archive/01--project-foundation/tasks/10--readme.md +116 -0
  14. flameconnect-0.1.0/.ai/task-manager/archive/02--fireplace-state-controls/plan-02--fireplace-state-controls.md +259 -0
  15. flameconnect-0.1.0/.ai/task-manager/archive/02--fireplace-state-controls/tasks/01--refactor-dataclasses-replace.md +47 -0
  16. flameconnect-0.1.0/.ai/task-manager/archive/02--fireplace-state-controls/tasks/02--add-cli-set-commands.md +53 -0
  17. flameconnect-0.1.0/.ai/task-manager/archive/02--fireplace-state-controls/tasks/03--add-tui-keybindings.md +67 -0
  18. flameconnect-0.1.0/.ai/task-manager/archive/02--fireplace-state-controls/tasks/04--add-tests.md +61 -0
  19. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/plan-03--flame-effect-controls.md +315 -0
  20. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/tasks/01--named-colors-and-cli-commands.md +167 -0
  21. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/tasks/02--flame-color-and-media-theme-screens.md +127 -0
  22. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/tasks/03--color-screen.md +185 -0
  23. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/tasks/04--tui-keybindings-and-actions.md +270 -0
  24. flameconnect-0.1.0/.ai/task-manager/archive/03--flame-effect-controls/tasks/05--tests.md +231 -0
  25. flameconnect-0.1.0/.ai/task-manager/archive/04--tui-visual-polish/plan-04--tui-visual-polish.md +351 -0
  26. flameconnect-0.1.0/.ai/task-manager/archive/04--tui-visual-polish/tasks/01--widgets-formatter-overhaul.md +104 -0
  27. flameconnect-0.1.0/.ai/task-manager/archive/04--tui-visual-polish/tasks/02--layout-footer-help-info.md +131 -0
  28. flameconnect-0.1.0/.ai/task-manager/archive/04--tui-visual-polish/tasks/03--heat-mode-fire-switcher-dialogs.md +144 -0
  29. flameconnect-0.1.0/.ai/task-manager/archive/04--tui-visual-polish/tasks/04--tests.md +139 -0
  30. flameconnect-0.1.0/.ai/task-manager/archive/05--fireplace-visual-overhaul/plan-05--fireplace-visual-overhaul.md +256 -0
  31. flameconnect-0.1.0/.ai/task-manager/archive/05--fireplace-visual-overhaul/tasks/01--rewrite-fireplace-visual-rendering.md +54 -0
  32. flameconnect-0.1.0/.ai/task-manager/archive/05--fireplace-visual-overhaul/tasks/02--wire-dashboard-state-to-visual.md +39 -0
  33. flameconnect-0.1.0/.ai/task-manager/archive/05--fireplace-visual-overhaul/tasks/03--add-tests-for-new-rendering.md +48 -0
  34. flameconnect-0.1.0/.ai/task-manager/archive/06--responsive-tui-layout/plan-06--responsive-tui-layout.md +226 -0
  35. flameconnect-0.1.0/.ai/task-manager/archive/06--responsive-tui-layout/tasks/01--implement-responsive-layout.md +60 -0
  36. flameconnect-0.1.0/.ai/task-manager/archive/06--responsive-tui-layout/tasks/02--add-responsive-layout-tests.md +46 -0
  37. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/plan-07--tui-fixes-and-features.md +437 -0
  38. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/01--fix-parameter-panel-border.md +49 -0
  39. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/02--version-header-and-help-toggle.md +46 -0
  40. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/03--label-rename-and-temp-unit-display.md +54 -0
  41. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/04--dialog-ux-improvements.md +57 -0
  42. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/05--flame-animation-and-heat-visual.md +65 -0
  43. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/06--media-theme-investigation.md +42 -0
  44. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/07--clickable-parameter-fields.md +96 -0
  45. flameconnect-0.1.0/.ai/task-manager/archive/07--tui-fixes-and-features/tasks/08--temperature-adjustment-dialog.md +73 -0
  46. flameconnect-0.1.0/.ai/task-manager/archive/08--tui-refinements/plan-08--tui-refinements.md +319 -0
  47. flameconnect-0.1.0/.ai/task-manager/archive/08--tui-refinements/tasks/01--clickable-values-only.md +59 -0
  48. flameconnect-0.1.0/.ai/task-manager/archive/08--tui-refinements/tasks/02--git-hash-and-label-renames.md +63 -0
  49. flameconnect-0.1.0/.ai/task-manager/archive/08--tui-refinements/tasks/03--fireplace-visual-refinements.md +71 -0
  50. flameconnect-0.1.0/.ai/task-manager/archive/08--tui-refinements/tasks/04--temperature-conversion.md +78 -0
  51. flameconnect-0.1.0/.ai/task-manager/archive/09--tui-bug-fixes/plan-09--tui-bug-fixes.md +167 -0
  52. flameconnect-0.1.0/.ai/task-manager/archive/09--tui-bug-fixes/tasks/01--fix-flame-effect-graphic.md +55 -0
  53. flameconnect-0.1.0/.ai/task-manager/archive/09--tui-bug-fixes/tasks/02--fix-click-values.md +49 -0
  54. flameconnect-0.1.0/.ai/task-manager/archive/09--tui-bug-fixes/tasks/03--fix-duplicate-overhead-light.md +53 -0
  55. flameconnect-0.1.0/.ai/task-manager/archive/10--pytest-cov-integration/plan-10--pytest-cov-integration.md +139 -0
  56. flameconnect-0.1.0/.ai/task-manager/archive/10--pytest-cov-integration/tasks/01--add-pytest-cov-dependency-and-config.md +37 -0
  57. flameconnect-0.1.0/.ai/task-manager/archive/10--pytest-cov-integration/tasks/02--update-ci-pytest-command.md +35 -0
  58. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/plan-11--increase-test-coverage.md +186 -0
  59. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/tasks/01--cli-command-display-tests.md +47 -0
  60. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/tasks/02--tui-app-action-tests.md +46 -0
  61. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/tasks/03--tui-widget-format-tests.md +44 -0
  62. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/tasks/04--tui-screen-tests.md +58 -0
  63. flameconnect-0.1.0/.ai/task-manager/archive/11--increase-test-coverage/tasks/05--core-module-edge-case-tests.md +49 -0
  64. flameconnect-0.1.0/.ai/task-manager/config/TASK_MANAGER.md +109 -0
  65. flameconnect-0.1.0/.ai/task-manager/config/hooks/POST_ERROR_DETECTION.md +48 -0
  66. flameconnect-0.1.0/.ai/task-manager/config/hooks/POST_PHASE.md +24 -0
  67. flameconnect-0.1.0/.ai/task-manager/config/hooks/POST_PLAN.md +3 -0
  68. flameconnect-0.1.0/.ai/task-manager/config/hooks/POST_TASK_GENERATION_ALL.md +162 -0
  69. flameconnect-0.1.0/.ai/task-manager/config/hooks/PRE_PHASE.md +28 -0
  70. flameconnect-0.1.0/.ai/task-manager/config/hooks/PRE_PLAN.md +58 -0
  71. flameconnect-0.1.0/.ai/task-manager/config/hooks/PRE_TASK_ASSIGNMENT.md +84 -0
  72. flameconnect-0.1.0/.ai/task-manager/config/scripts/check-task-dependencies.cjs +357 -0
  73. flameconnect-0.1.0/.ai/task-manager/config/scripts/compose-prompt.cjs +234 -0
  74. flameconnect-0.1.0/.ai/task-manager/config/scripts/detect-assistant.cjs +67 -0
  75. flameconnect-0.1.0/.ai/task-manager/config/scripts/get-next-plan-id.cjs +431 -0
  76. flameconnect-0.1.0/.ai/task-manager/config/scripts/get-next-task-id.cjs +160 -0
  77. flameconnect-0.1.0/.ai/task-manager/config/scripts/package-lock.json +49 -0
  78. flameconnect-0.1.0/.ai/task-manager/config/scripts/package.json +5 -0
  79. flameconnect-0.1.0/.ai/task-manager/config/scripts/read-assistant-config.cjs +99 -0
  80. flameconnect-0.1.0/.ai/task-manager/config/scripts/validate-plan-blueprint.cjs +333 -0
  81. flameconnect-0.1.0/.ai/task-manager/config/templates/BLUEPRINT_TEMPLATE.md +26 -0
  82. flameconnect-0.1.0/.ai/task-manager/config/templates/EXECUTION_SUMMARY_TEMPLATE.md +13 -0
  83. flameconnect-0.1.0/.ai/task-manager/config/templates/PLAN_TEMPLATE.md +92 -0
  84. flameconnect-0.1.0/.ai/task-manager/config/templates/TASK_TEMPLATE.md +36 -0
  85. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/plan-12--mutation-testing-expansion.md +141 -0
  86. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/tasks/01--mutmut-config-and-ci.md +27 -0
  87. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/tasks/02--kill-protocol-mutants.md +28 -0
  88. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/tasks/03--kill-client-mutants.md +27 -0
  89. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/tasks/04--kill-auth-mutants.md +27 -0
  90. flameconnect-0.1.0/.ai/task-manager/plans/12--mutation-testing-expansion/tasks/05--kill-b2c-mutants.md +27 -0
  91. flameconnect-0.1.0/.claude/agents/plan-creator.md +95 -0
  92. flameconnect-0.1.0/.claude/commands/tasks/create-plan.md +144 -0
  93. flameconnect-0.1.0/.claude/commands/tasks/execute-blueprint.md +191 -0
  94. flameconnect-0.1.0/.claude/commands/tasks/execute-task.md +259 -0
  95. flameconnect-0.1.0/.claude/commands/tasks/fix-broken-tests.md +39 -0
  96. flameconnect-0.1.0/.claude/commands/tasks/full-workflow.md +437 -0
  97. flameconnect-0.1.0/.claude/commands/tasks/generate-tasks.md +321 -0
  98. flameconnect-0.1.0/.claude/commands/tasks/refine-plan.md +130 -0
  99. flameconnect-0.1.0/.github/workflows/ci.yml +29 -0
  100. flameconnect-0.1.0/.github/workflows/conventional-commits.yml +14 -0
  101. flameconnect-0.1.0/.github/workflows/publish-to-pypi.yml +69 -0
  102. flameconnect-0.1.0/.github/workflows/release.yml +41 -0
  103. flameconnect-0.1.0/.gitignore +14 -0
  104. flameconnect-0.1.0/.pre-commit-config.yaml +30 -0
  105. flameconnect-0.1.0/CHANGELOG.md +108 -0
  106. flameconnect-0.1.0/FLAMECONNECT_API_REPORT.md +1059 -0
  107. flameconnect-0.1.0/LICENSE +199 -0
  108. flameconnect-0.1.0/PKG-INFO +292 -0
  109. flameconnect-0.1.0/README.md +270 -0
  110. flameconnect-0.1.0/images/flameconnect-0.1.0.png +0 -0
  111. flameconnect-0.1.0/pyproject.toml +52 -0
  112. flameconnect-0.1.0/renovate.json +8 -0
  113. flameconnect-0.1.0/setup.cfg +7 -0
  114. flameconnect-0.1.0/src/flameconnect/__init__.py +86 -0
  115. flameconnect-0.1.0/src/flameconnect/__main__.py +3 -0
  116. flameconnect-0.1.0/src/flameconnect/auth.py +213 -0
  117. flameconnect-0.1.0/src/flameconnect/b2c_login.py +327 -0
  118. flameconnect-0.1.0/src/flameconnect/cli.py +996 -0
  119. flameconnect-0.1.0/src/flameconnect/client.py +288 -0
  120. flameconnect-0.1.0/src/flameconnect/const.py +47 -0
  121. flameconnect-0.1.0/src/flameconnect/exceptions.py +23 -0
  122. flameconnect-0.1.0/src/flameconnect/models.py +313 -0
  123. flameconnect-0.1.0/src/flameconnect/protocol.py +473 -0
  124. flameconnect-0.1.0/src/flameconnect/py.typed +0 -0
  125. flameconnect-0.1.0/src/flameconnect/tui/__init__.py +7 -0
  126. flameconnect-0.1.0/src/flameconnect/tui/app.py +1086 -0
  127. flameconnect-0.1.0/src/flameconnect/tui/auth_screen.py +224 -0
  128. flameconnect-0.1.0/src/flameconnect/tui/color_screen.py +175 -0
  129. flameconnect-0.1.0/src/flameconnect/tui/fire_select_screen.py +118 -0
  130. flameconnect-0.1.0/src/flameconnect/tui/flame_color_screen.py +108 -0
  131. flameconnect-0.1.0/src/flameconnect/tui/flame_speed_screen.py +89 -0
  132. flameconnect-0.1.0/src/flameconnect/tui/heat_mode_screen.py +158 -0
  133. flameconnect-0.1.0/src/flameconnect/tui/media_theme_screen.py +122 -0
  134. flameconnect-0.1.0/src/flameconnect/tui/screens.py +308 -0
  135. flameconnect-0.1.0/src/flameconnect/tui/temperature_screen.py +154 -0
  136. flameconnect-0.1.0/src/flameconnect/tui/timer_screen.py +118 -0
  137. flameconnect-0.1.0/src/flameconnect/tui/widgets.py +1003 -0
  138. flameconnect-0.1.0/tests/__init__.py +0 -0
  139. flameconnect-0.1.0/tests/conftest.py +30 -0
  140. flameconnect-0.1.0/tests/fixtures/get_fire_overview.json +55 -0
  141. flameconnect-0.1.0/tests/fixtures/get_fires.json +13 -0
  142. flameconnect-0.1.0/tests/test_auth.py +814 -0
  143. flameconnect-0.1.0/tests/test_b2c_login.py +1164 -0
  144. flameconnect-0.1.0/tests/test_cli_commands.py +1669 -0
  145. flameconnect-0.1.0/tests/test_cli_set.py +815 -0
  146. flameconnect-0.1.0/tests/test_client.py +1220 -0
  147. flameconnect-0.1.0/tests/test_fireplace_visual.py +312 -0
  148. flameconnect-0.1.0/tests/test_main.py +18 -0
  149. flameconnect-0.1.0/tests/test_models.py +201 -0
  150. flameconnect-0.1.0/tests/test_protocol.py +1563 -0
  151. flameconnect-0.1.0/tests/test_responsive_layout.py +89 -0
  152. flameconnect-0.1.0/tests/test_tui_actions.py +3296 -0
  153. flameconnect-0.1.0/tests/test_tui_screens.py +1908 -0
  154. flameconnect-0.1.0/tests/test_widgets_format.py +1126 -0
  155. flameconnect-0.1.0/uv.lock +1252 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "version": "1.26.0",
3
+ "timestamp": "2026-02-23T15:47:51.120Z",
4
+ "files": {
5
+ "config/TASK_MANAGER.md": "ad37290f6f5bced23be611198f288f8c196452183aa139197085c3da73174b49",
6
+ "config/hooks/POST_ERROR_DETECTION.md": "ed4e1691880ea54ea43c318dc236c326ed81a3ce2785321a25e6db747a6e7e88",
7
+ "config/hooks/POST_PHASE.md": "d79fccfee4629ffc226db97f6f755c4dd068ee9c30f7d8bf98dfc55b104003c5",
8
+ "config/hooks/POST_PLAN.md": "4c9850cb6d11d74065b6c4a00137fe00540aeea7b44d9edbfc8211ff5ea34662",
9
+ "config/hooks/POST_TASK_GENERATION_ALL.md": "aa86468a634da40ae141670b960473bce10589190b0f9119bf07d64cd49a9a7b",
10
+ "config/hooks/PRE_PHASE.md": "efd9ad1ae9265ef36388cd5dfd9f96a45ae98f7f3d1a2eb5cc8caec01f4efb23",
11
+ "config/hooks/PRE_PLAN.md": "b8291630f12a1745e00b4a8079e9b7d8d5f7cd3c146df505b2fc8fa175dea1b9",
12
+ "config/hooks/PRE_TASK_ASSIGNMENT.md": "94735720070a6084560cc89708deb1e123f8c8b24c9ed8ffbb95886423d4b9f7",
13
+ "config/templates/BLUEPRINT_TEMPLATE.md": "f67488cd05a2fcdbf8a58a863d1315cde4f77a3b42d7e752374feb31620e8063",
14
+ "config/templates/EXECUTION_SUMMARY_TEMPLATE.md": "9023bd2f6e39169068fd8684254679c82bc76ddbde3d2881eadd76c107f083c2",
15
+ "config/templates/PLAN_TEMPLATE.md": "c506f6f9394bc4b75e4ccc9fafcef244219bb255a9efd7b95852e8f21123728b",
16
+ "config/templates/TASK_TEMPLATE.md": "e0fa4d9bde7d9ab9edcf4f32785011c7125424f5199a0994c5900ef0352c4e02"
17
+ }
18
+ }
@@ -0,0 +1,7 @@
1
+ # AI Task Manager
2
+
3
+ This directory contains AI-assisted task management files for this project.
4
+
5
+ Managed by the [AI Task Manager](https://www.github.com/e0ipso/ai-task-manager) project.
6
+
7
+ **Documentation**: https://mateuaguilo.com/ai-task-manager
@@ -0,0 +1,401 @@
1
+ ---
2
+ id: 1
3
+ summary: "Transform flameconnect from a standalone script into a fully-packaged async Python library with CLI, TUI, testing, CI/CD, and PyPI publishing"
4
+ created: 2026-02-23
5
+ ---
6
+
7
+ # Plan: FlameConnect Project Foundation
8
+
9
+ ## Original Work Order
10
+ > Create a plan to implement all project philosophy and technology choices in the .ai/task-manager/config/TASK_MANAGER.md file.
11
+
12
+ ## Plan Clarifications
13
+
14
+ | Question | Answer |
15
+ |----------|--------|
16
+ | Async strategy | Fully async: aiohttp for HTTP, msal wrapped with asyncio.to_thread() |
17
+ | Package name | `flameconnect` (confirmed available on PyPI) |
18
+ | Home Assistant integration | Library + CLI only; HA integration is a separate future project |
19
+ | API endpoint scope | Core control endpoints: GetFires, GetFireOverview, WriteWifiParameters. Note: there is no separate ReadWifiParameters endpoint — parameter reading is done via GetFireOverview. README documents what is and isn't implemented. |
20
+ | Auth library | msal with async wrapper (msal is well-tested for Azure AD B2C) |
21
+ | TUI mode | Included in this plan using textual |
22
+ | TUI dependency | Optional packaging extra: `pip install flameconnect[tui]` / `uv add flameconnect[tui]`. Keeps base library lightweight for HA consumers. |
23
+ | Mutation testing | Runs in the main CI pipeline on every push/PR alongside ruff, mypy, and pytest. |
24
+ | Live API testing | Permitted during development. Before making any live API call: explain what the call does, ask the user for confirmation, then ask if the result matched expectations. CI tests still use fixtures/mocks only. |
25
+
26
+ ## Executive Summary
27
+
28
+ This plan transforms the existing `flameconnect_reader.py` standalone script into a production-quality, async-first Python library with a CLI and TUI interface. The project currently exists as a single 570-line script using synchronous `requests` and `msal` with no packaging, tests, type annotations, linting, or CI/CD.
29
+
30
+ The approach restructures the code into a proper Python package managed by `uv`, replaces synchronous HTTP calls with `aiohttp`, adds strict type annotations enforced by `mypy`, comprehensive tests with `pytest` and mutation testing via `mutmut`, a CLI tool, a textual-based TUI, and a complete CI/CD pipeline using GitHub Actions with conventional commits and release-please for automated releases to PyPI.
31
+
32
+ The plan prioritizes the three core control endpoints (GetFires, GetFireOverview, WriteWifiParameters) which together cover fireplace discovery, state reading, and parameter control. The remaining 30+ API endpoints are documented as future work in the README.
33
+
34
+ ## Context
35
+
36
+ ### Current State vs Target State
37
+
38
+ | Current State | Target State | Why? |
39
+ |---|---|---|
40
+ | Single script (`flameconnect_reader.py`, 570 lines) | Proper Python package with modular structure | Enables import as library, distribution via PyPI, and consumption by Home Assistant |
41
+ | Synchronous HTTP via `requests` | Async HTTP via `aiohttp` | Home Assistant is fully async; sync wrappers in executors add overhead and complexity |
42
+ | No type annotations in code | Full type annotations, mypy strict mode | Catches bugs at development time, enables IDE support, required by HA contribution guidelines |
43
+ | No tests (0% coverage) | pytest with fixtures + mutmut mutation testing | Ensures correctness, prevents regressions, validates test quality |
44
+ | No packaging (pyproject.toml, etc.) | uv-managed project with pyproject.toml | Enables dependency management, versioning, and PyPI distribution |
45
+ | No linting or formatting | ruff for linting + formatting | Consistent code style, catches common errors |
46
+ | No CI/CD | GitHub Actions workflows | Automated testing, linting, release management |
47
+ | No versioning or releases | Conventional commits + release-please + PyPI | Automated semantic versioning and package publishing |
48
+ | Hardcoded MSAL browser login only | Token injection + built-in credential handling | Supports both Home Assistant (token injection) and standalone use (browser login) |
49
+ | No CLI interface | CLI tool built on the async library | Command-line access to all fireplace operations |
50
+ | No TUI | Textual-based TUI mode | Interactive dashboard showing fireplace status and controls |
51
+ | README is an API report | Human-oriented README with usage docs | Clear onboarding for users and contributors |
52
+ | Uses `print()` for output | stdlib `logging` module | Proper log levels, follows HA conventions, no print() in library code |
53
+
54
+ ### Background
55
+
56
+ The flameconnect project was created by reverse-engineering the Flame Connect Android APK (v2.22.0). The API report (`FLAMECONNECT_API_REPORT.md`) documents 30+ endpoints and a binary wire protocol for fireplace parameter control. The existing script demonstrates that the API integration works correctly - the challenge is now restructuring it into a well-engineered library.
57
+
58
+ Key constraints:
59
+ - **Minimal dependencies**: Prioritize packages already in Home Assistant (aiohttp is included, msal is not but is necessary for standalone auth)
60
+ - **Azure AD B2C auth**: The upstream API uses Microsoft's B2C tenant, making msal the most reliable auth option
61
+ - **Binary wire protocol**: Parameters use a base64-encoded binary format that must be carefully preserved during refactoring
62
+ - **Live API calls permitted during development**: To validate that the refactored code works against the real API, live calls are allowed during development. However, a strict protocol must be followed: (1) explain to the user what API call will be made and why, (2) get explicit user confirmation before making it, (3) ask the user to verify whether the result was correct. This respects the upstream API (no spam) while enabling real-world validation.
63
+ - **CI tests use fixtures/mocks only**: Automated tests must never make live API calls. All CI test fixtures should be derived from real API responses captured during development.
64
+
65
+ ## Architectural Approach
66
+
67
+ ```mermaid
68
+ graph TB
69
+ subgraph "Package: flameconnect"
70
+ direction TB
71
+ A[auth.py<br/>Token injection + MSAL] --> B[client.py<br/>Async API client]
72
+ B --> D[protocol.py<br/>Binary wire encoding/decoding]
73
+ B --> C[models.py<br/>Dataclasses + enums]
74
+ D --> C
75
+ end
76
+
77
+ subgraph "Interfaces"
78
+ E[cli.py<br/>CLI commands] --> B
79
+ F[tui/<br/>Textual dashboard] --> B
80
+ end
81
+
82
+ subgraph "Infrastructure"
83
+ G[pyproject.toml<br/>uv, ruff, mypy config]
84
+ H[GitHub Actions<br/>CI/CD workflows]
85
+ I[Tests<br/>pytest + mutmut]
86
+ end
87
+ ```
88
+
89
+ ### Package Structure
90
+ **Objective**: Organize the codebase into a proper Python package with clear module boundaries.
91
+
92
+ The `flameconnect` package will be structured as:
93
+
94
+ ```
95
+ src/flameconnect/
96
+ __init__.py # Public API exports
97
+ __main__.py # Entry point for `python -m flameconnect`
98
+ py.typed # PEP 561 marker for typed package (enables mypy for consumers)
99
+ auth.py # Authentication (token injection + MSAL credential flow)
100
+ client.py # FlameConnectClient - async API client
101
+ models.py # Dataclasses for API responses, enums, typed parameters
102
+ protocol.py # Binary wire protocol encoding/decoding
103
+ exceptions.py # Custom exception hierarchy
104
+ const.py # Constants (API URLs, headers, parameter IDs)
105
+ cli.py # CLI entry point using argparse (stdlib, zero extra dependencies)
106
+ tui/
107
+ __init__.py
108
+ app.py # Textual App subclass
109
+ screens.py # TUI screens (dashboard, control)
110
+ widgets.py # Custom widgets (flame display, heat controls)
111
+ ```
112
+
113
+ The `src/` layout is used because it prevents accidental imports of the uninstalled package and is the modern Python packaging standard. The `py.typed` marker file (PEP 561) signals to mypy that this package ships inline type annotations, enabling type checking for downstream consumers.
114
+
115
+ ### Async Client Design
116
+ **Objective**: Provide a clean async API that supports both Home Assistant token injection and standalone credential handling.
117
+
118
+ The `FlameConnectClient` will accept an `aiohttp.ClientSession` (optional, creates its own if not provided) and authentication via either:
119
+ 1. **Token injection**: A string token or an `async callable` that returns a token (for Home Assistant)
120
+ 2. **Built-in credentials**: MSAL-based browser login with persistent token cache (for CLI/standalone use)
121
+
122
+ The client will be an async context manager:
123
+ ```python
124
+ async with FlameConnectClient(auth=token_provider) as client:
125
+ fires = await client.get_fires()
126
+ ```
127
+
128
+ All API methods return typed dataclasses from `models.py`, not raw dicts. The binary wire protocol is encapsulated in `protocol.py` so callers never deal with base64/struct directly.
129
+
130
+ ### Models and Type System
131
+ **Objective**: Replace raw dicts and magic numbers with typed dataclasses and enums enforced by mypy strict mode.
132
+
133
+ All API responses will be represented as `dataclass` or `NamedTuple` types. The existing enum mappings (FIRE_MODE, FLAME_EFFECT, HEAT_STATUS, etc.) become proper Python `Enum` classes. Parameter types will use typed dataclasses with proper field definitions.
134
+
135
+ The wire protocol encoding/decoding in `protocol.py` will accept and return these typed models, providing a clean boundary between the binary format and the rest of the library. Note: the existing script has incomplete decoders — Sound (369) and Log Effect (370) have display code but no binary decoding logic, and only Mode (321) and Flame Effect (322) have encoders. All 11 parameter types (236, 321, 322, 323, 325, 326, 327, 329, 369, 370) must have complete decode implementations, with encode implementations for all writable parameters. The `FLAMECONNECT_API_REPORT.md` documents the wire format for each.
136
+
137
+ ### CLI Tool
138
+ **Objective**: Provide command-line access to all fireplace operations.
139
+
140
+ The CLI will use Python's `argparse` from stdlib (zero extra dependencies, aligning with the minimal-dependencies philosophy) to expose commands:
141
+ - `flameconnect list` - List registered fireplaces
142
+ - `flameconnect status <fire_id>` - Show current fireplace state
143
+ - `flameconnect on <fire_id>` - Turn on fireplace
144
+ - `flameconnect off <fire_id>` - Turn off fireplace
145
+ - `flameconnect set <fire_id> <param> <value>` - Set parameters (flame, heat, timer, etc.)
146
+ - `flameconnect tui` - Launch the textual TUI
147
+
148
+ The CLI will use `asyncio.run()` to bridge sync entry points to the async library. Authentication will use the built-in MSAL credential flow with token caching.
149
+
150
+ ### TUI Dashboard
151
+ **Objective**: Provide an interactive terminal interface for monitoring and controlling fireplaces using textual.
152
+
153
+ The TUI will be a textual `App` that displays:
154
+ - A list of registered fireplaces with connection status
155
+ - A dashboard view for the selected fireplace showing:
156
+ - Current mode (standby/manual)
157
+ - Flame effect settings (speed, brightness, color)
158
+ - Heat settings (status, temperature, mode)
159
+ - Timer status
160
+ - Error codes (if any)
161
+ - Interactive controls for toggling power, adjusting flame/heat settings
162
+ - Auto-refresh of fireplace state on a configurable interval
163
+
164
+ The TUI will be launched via `flameconnect tui` and requires the optional `tui` extra (`pip install flameconnect[tui]` or `uv add flameconnect[tui]`). The `textual` import is lazy — it only occurs when the `tui` command is invoked, so the base library remains lightweight for consumers like Home Assistant. If a user runs `flameconnect tui` without the extra installed, they will get a clear error message with installation instructions.
165
+
166
+ ### Testing Strategy
167
+ **Objective**: Achieve high test coverage through two complementary approaches — automated fixture-based tests for CI, and live API validation during development.
168
+
169
+ **Automated tests (CI)**: Tests will use `pytest` with `aiohttp` test utilities and `pytest-aiohttp` for async test support. All API responses will be captured as JSON fixtures. Mutation testing with `mutmut` validates that tests catch real code changes.
170
+
171
+ **Live API validation (development)**: During implementation, the developer may make real API calls to validate correctness. This follows a strict three-step protocol:
172
+ 1. **Explain**: Describe the API call (endpoint, parameters, expected effect)
173
+ 2. **Confirm**: Wait for explicit user approval before executing
174
+ 3. **Verify**: Ask the user to confirm whether the result matched expectations
175
+
176
+ This enables capturing real API response shapes for fixtures and verifying that encoded parameters produce the expected fireplace behavior. Live validation is especially valuable for the wire protocol (Task 03), async client (Task 05), and CLI (Task 07).
177
+
178
+ ```
179
+ tests/
180
+ conftest.py # Shared fixtures, mock session factory
181
+ test_auth.py # Auth token injection and MSAL flow tests
182
+ test_client.py # API client method tests with mocked responses
183
+ test_models.py # Dataclass construction and validation
184
+ test_protocol.py # Wire protocol encode/decode round-trip tests
185
+ test_cli.py # CLI argument parsing and command execution
186
+ fixtures/ # JSON response fixtures derived from real API responses
187
+ ```
188
+
189
+ ### CI/CD Pipeline
190
+ **Objective**: Automate linting, testing, and release management via GitHub Actions.
191
+
192
+ Three workflows:
193
+ 1. **CI** (on push/PR): Run ruff lint + format check, mypy strict, pytest, and mutmut mutation testing. All checks must pass before merge.
194
+ 2. **Conventional Commits** (on PR): Validate PR title and commit messages follow conventional commit format.
195
+ 3. **Release** (on merge to main): release-please creates release PRs with changelog; on release, build and publish to PyPI. Initial version will be 0.1.0.
196
+
197
+ ### Logging
198
+ **Objective**: Replace all `print()` calls with stdlib `logging` following Home Assistant conventions.
199
+
200
+ The library will use `logging.getLogger(__name__)` in each module. No `print()` in library code. The CLI/TUI will configure log handlers and levels. Debug logging will include API request/response details for troubleshooting.
201
+
202
+ ## Risk Considerations and Mitigation Strategies
203
+
204
+ <details>
205
+ <summary>Technical Risks</summary>
206
+
207
+ - **MSAL async wrapping**: msal is synchronous and uses blocking I/O. Running in `asyncio.to_thread()` works but adds thread pool overhead.
208
+ - **Mitigation**: Auth happens infrequently (once at startup, then token refresh). The overhead is negligible for this use case.
209
+ - **Binary protocol fidelity**: Refactoring the wire protocol encoding/decoding could introduce subtle byte-level bugs.
210
+ - **Mitigation**: Create comprehensive round-trip tests using known-good encoded values from the existing script before refactoring.
211
+ - **aiohttp session lifecycle**: Mismanaged sessions can leak connections.
212
+ - **Mitigation**: Use async context manager pattern consistently; provide both session injection and auto-creation.
213
+ </details>
214
+
215
+ <details>
216
+ <summary>Implementation Risks</summary>
217
+
218
+ - **Scope of refactoring**: Transforming a working script into a packaged library touches every line of code.
219
+ - **Mitigation**: Extract and test the wire protocol first (it's the most delicate part), then build the client around tested primitives.
220
+ - **textual API stability**: textual is actively developed and APIs may change.
221
+ - **Mitigation**: Pin textual version in dependencies; keep TUI as a separate module that can be updated independently.
222
+ </details>
223
+
224
+ <details>
225
+ <summary>Integration Risks</summary>
226
+
227
+ - **PyPI name availability**: ~~Resolved~~ — `flameconnect` is confirmed available on PyPI as of 2026-02-23.
228
+ - **Azure AD B2C token format changes**: The upstream auth API could change.
229
+ - **Mitigation**: The auth module is isolated; changes only affect `auth.py` and its tests.
230
+ </details>
231
+
232
+ <details>
233
+ <summary>Quality Risks</summary>
234
+
235
+ - **Incomplete wire protocol in existing code**: The current `decode_parameter` function handles parameters 236, 321–327, and 329, but the display functions for Sound (369) and Log Effect (370) reference keys that are never populated by the decoder. These decoders and encoders must be completed during refactoring, not just ported.
236
+ - **Mitigation**: Use the `FLAMECONNECT_API_REPORT.md` wire format documentation to implement complete encode/decode for all parameter types. Round-trip tests will verify correctness.
237
+ - **mutmut CI time**: Mutation testing can be slow on larger codebases.
238
+ - **Mitigation**: Start with mutmut on the focused protocol and models modules. Expand coverage as the codebase grows. Consider parallelizing mutation runs in CI.
239
+ </details>
240
+
241
+ ## Success Criteria
242
+
243
+ ### Primary Success Criteria
244
+ 1. `flameconnect` is installable via `pip install flameconnect` (or `uv add flameconnect`) from PyPI
245
+ 2. The async library can discover fireplaces, read state, and control parameters (on/off, flame effect, heat, timer)
246
+ 3. `flameconnect list`, `flameconnect status`, `flameconnect on/off`, and `flameconnect set` CLI commands work correctly
247
+ 4. `flameconnect tui` launches an interactive terminal dashboard with live fireplace status and controls
248
+ 5. mypy strict mode passes with zero errors
249
+ 6. ruff lint and format checks pass with zero warnings
250
+ 7. pytest achieves high test coverage with all tests passing using fixtures (no live API calls)
251
+ 8. mutmut mutation testing demonstrates meaningful test coverage (mutants are caught)
252
+ 9. GitHub Actions CI runs linting, type checking, and tests on every push/PR
253
+ 10. Conventional commits are validated in CI
254
+ 11. release-please automates versioning and PyPI publishing on merge to main
255
+ 12. README is written for humans with clear installation, usage examples, and API coverage documentation
256
+
257
+ ## Resource Requirements
258
+
259
+ ### Development Skills
260
+ - Python async programming (aiohttp, asyncio)
261
+ - Python packaging (pyproject.toml, src layout, uv)
262
+ - Azure AD B2C authentication (msal)
263
+ - Binary protocol handling (struct, base64)
264
+ - Terminal UI development (textual)
265
+ - GitHub Actions CI/CD
266
+ - Type system (mypy strict mode)
267
+
268
+ ### Technical Infrastructure
269
+ - **Python 3.13+**: Required runtime
270
+ - **uv**: Dependency management and virtual environment
271
+ - **ruff**: Linting and formatting
272
+ - **mypy**: Static type checking
273
+ - **pytest + pytest-aiohttp**: Test framework
274
+ - **mutmut**: Mutation testing
275
+ - **textual**: TUI framework
276
+ - **aiohttp**: Async HTTP client
277
+ - **msal**: Azure AD B2C authentication
278
+ - **GitHub Actions**: CI/CD platform
279
+ - **release-please**: Automated release management
280
+ - **PyPI**: Package distribution
281
+
282
+ ## Integration Strategy
283
+
284
+ The library is designed as a standalone package that can be consumed by:
285
+ 1. **Direct users**: Via the CLI and TUI for personal fireplace control
286
+ 2. **Home Assistant**: Via token injection into the async client (HA passes its own aiohttp session and access token)
287
+ 3. **Other integrations**: Any Python async application can use the library's public API
288
+
289
+ The token injection pattern ensures the library doesn't impose authentication decisions on consumers. The async-first design means no `executor` wrapping is needed in Home Assistant.
290
+
291
+ ## Notes
292
+
293
+ - The existing `flameconnect_reader.py` will be preserved as a reference during development and can be removed once the library is feature-complete
294
+ - The `FLAMECONNECT_API_REPORT.md` serves as the canonical API reference and should be kept up to date
295
+ - The `decomp/` directory contains reverse-engineering artifacts and is gitignored; it stays as reference material
296
+ - Only three core control endpoints are in scope: **GetFires** (list fireplaces), **GetFireOverview** (read state and parameters), and **WriteWifiParameters** (send control commands). There is no separate `ReadWifiParameters` endpoint — all parameter reading is done via `GetFireOverview`. Additional endpoints documented in the API report can be added incrementally in future plans.
297
+ - The README should clearly document which endpoints are implemented and which are available for future contribution
298
+ - Initial PyPI release version: **0.1.0**
299
+
300
+ ## Task Dependency Graph
301
+
302
+ ```mermaid
303
+ graph TD
304
+ T01[Task 01: Project Scaffolding] --> T02[Task 02: Models/Constants/Exceptions]
305
+ T02 --> T03[Task 03: Wire Protocol]
306
+ T02 --> T04[Task 04: Auth Module]
307
+ T03 --> T05[Task 05: Async Client]
308
+ T04 --> T05
309
+ T05 --> T06[Task 06: Tests]
310
+ T05 --> T07[Task 07: CLI Tool]
311
+ T05 --> T08[Task 08: TUI Dashboard]
312
+ T06 --> T09[Task 09: CI/CD Workflows]
313
+ T07 --> T10[Task 10: README]
314
+ T08 --> T10
315
+ ```
316
+
317
+ ## Execution Blueprint
318
+
319
+ **Validation Gates:**
320
+ - Reference: `/config/hooks/POST_PHASE.md`
321
+
322
+ ### ✅ Phase 1: Project Foundation
323
+ **Parallel Tasks:**
324
+ - ✔️ Task 01: Initialize project scaffolding with uv and configure tooling
325
+
326
+ ### ✅ Phase 2: Core Types
327
+ **Parallel Tasks:**
328
+ - ✔️ Task 02: Implement models, enums, constants, and exceptions (depends on: 01)
329
+
330
+ ### ✅ Phase 3: Core Modules
331
+ **Parallel Tasks:**
332
+ - ✔️ Task 03: Implement binary wire protocol encoding and decoding (depends on: 02)
333
+ - ✔️ Task 04: Implement authentication module with token injection and MSAL (depends on: 02)
334
+
335
+ ### ✅ Phase 4: API Client
336
+ **Parallel Tasks:**
337
+ - ✔️ Task 05: Implement async API client (depends on: 03, 04)
338
+
339
+ ### ✅ Phase 5: Interfaces and Testing
340
+ **Parallel Tasks:**
341
+ - ✔️ Task 06: Implement tests for protocol, client, and auth modules (depends on: 05)
342
+ - ✔️ Task 07: Implement CLI tool with argparse (depends on: 05)
343
+ - ✔️ Task 08: Implement textual TUI dashboard (depends on: 05)
344
+
345
+ ### ✅ Phase 6: Infrastructure and Documentation
346
+ **Parallel Tasks:**
347
+ - ✔️ Task 09: Set up GitHub Actions CI/CD workflows (depends on: 06)
348
+ - ✔️ Task 10: Write human-oriented README (depends on: 07, 08)
349
+
350
+ ### Execution Summary
351
+ - Total Phases: 6
352
+ - Total Tasks: 10
353
+ - Maximum Parallelism: 3 tasks (in Phase 5)
354
+ - Critical Path Length: 6 phases (01 → 02 → 03 → 05 → 06 → 09)
355
+
356
+ ### Refinement Changelog
357
+
358
+ - 2026-02-23: Corrected API endpoint list — removed non-existent `ReadWifiParameters` endpoint (reading is via `GetFireOverview`)
359
+ - 2026-02-23: Fixed architecture diagram dependency direction (protocol depends on models, not vice versa)
360
+ - 2026-02-23: Added `__main__.py` and `py.typed` marker to package structure
361
+ - 2026-02-23: Resolved CLI framework as `argparse` (removed "or click-minimal" ambiguity)
362
+ - 2026-02-23: Specified textual as optional packaging extra (`flameconnect[tui]`)
363
+ - 2026-02-23: Confirmed `flameconnect` name available on PyPI, removed from risk list
364
+ - 2026-02-23: Added quality risk about incomplete Sound/Log Effect wire protocol decoders in existing code
365
+ - 2026-02-23: Clarified mutmut runs in main CI pipeline per user preference
366
+ - 2026-02-23: Added initial version 0.1.0 specification
367
+ - 2026-02-23: Added live API testing policy — live calls permitted during development with explain/confirm/verify protocol; CI tests remain fixture-only
368
+
369
+ ## Execution Summary
370
+
371
+ **Status**: Completed Successfully
372
+ **Completed Date**: 2026-02-23
373
+
374
+ ### Results
375
+ All 10 tasks across 6 phases completed successfully. The flameconnect library is now a fully packaged, async-first Python library:
376
+
377
+ - **13 source files** in `src/flameconnect/` (including 4 TUI files)
378
+ - **91 tests** passing across 4 test files (protocol, client, auth, models)
379
+ - **All quality gates pass**: ruff check, ruff format, mypy --strict (0 errors)
380
+ - **6 commits** on `project-foundation` branch following conventional commit format
381
+
382
+ Key deliverables:
383
+ - Wire protocol with complete encode/decode for all 10 parameter types
384
+ - Async API client with typed methods and context manager pattern
385
+ - Dual auth: MSAL interactive flow + token injection for HA
386
+ - CLI with list/status/on/off/set/tui commands
387
+ - Textual TUI dashboard with auto-refresh and power toggle
388
+ - GitHub Actions CI/CD with mutation testing, conventional commits, and release-please
389
+
390
+ ### Noteworthy Events
391
+ - **Protocol bug fix**: The test agent discovered that `_encode_heat_settings` was missing a trailing padding byte, producing 9-byte output instead of the required 10 bytes. Fixed by adding a padding byte to match the wire format.
392
+ - **`fs-extra` npm dependency**: The task dependency checking script required `fs-extra` which was not initially installed. Fixed with `npm install`.
393
+ - **ruff exclusion for reference script**: `flameconnect_reader.py` (the original script) failed ruff linting. Added it to `[tool.ruff] exclude` rather than modifying the reference.
394
+ - **No live API validation performed**: All tasks completed with static analysis and fixture-based tests only. Live validation was deferred to user testing.
395
+
396
+ ### Recommendations
397
+ 1. Run `flameconnect list` and `flameconnect status` against the live API to validate end-to-end before publishing
398
+ 2. Configure PyPI trusted publishing and GitHub `pypi` environment before the first release
399
+ 3. Replace `USERNAME` placeholder in README badges with the actual GitHub username
400
+ 4. Consider adding `test_cli.py` for CLI argument parsing tests in a future iteration
401
+ 5. Run `mutmut` locally to verify mutation test results before merging
@@ -0,0 +1,126 @@
1
+ ---
2
+ id: 1
3
+ group: "packaging"
4
+ dependencies: []
5
+ status: "completed"
6
+ created: "2026-02-23"
7
+ skills:
8
+ - python
9
+ - packaging
10
+ status: "completed"
11
+ status: "completed"
12
+ ---
13
+ # Initialize project scaffolding with uv and configure tooling
14
+
15
+ ## Objective
16
+ Create the Python package skeleton with `src/` layout, configure `pyproject.toml` with all dependencies and tool settings (ruff, mypy, pytest, mutmut), and initialize the uv project. This is the foundation all other tasks build on.
17
+
18
+ ## Skills Required
19
+ - Python packaging (pyproject.toml, src layout, PEP 621)
20
+ - uv dependency manager
21
+
22
+ ## Acceptance Criteria
23
+ - [ ] `pyproject.toml` exists with project metadata (name=flameconnect, version=0.1.0, python>=3.13)
24
+ - [ ] `src/flameconnect/__init__.py` exists with package version
25
+ - [ ] `src/flameconnect/__main__.py` exists (delegates to CLI)
26
+ - [ ] `src/flameconnect/py.typed` marker file exists (empty file)
27
+ - [ ] Dependencies declared: aiohttp, msal (runtime); ruff, mypy, pytest, pytest-aiohttp, mutmut (dev)
28
+ - [ ] Optional dependency group `tui` with textual
29
+ - [ ] `[project.scripts]` entry: `flameconnect = "flameconnect.cli:main"`
30
+ - [ ] ruff config in pyproject.toml (line-length=88, target-version="py313")
31
+ - [ ] mypy config in pyproject.toml (strict=true)
32
+ - [ ] pytest config in pyproject.toml
33
+ - [ ] `uv sync` succeeds and installs all dependencies
34
+ - [ ] `tests/` directory with empty `conftest.py` and `__init__.py`
35
+ - [ ] `.gitignore` updated for uv (.venv, dist, *.egg-info, .mypy_cache, .ruff_cache, .pytest_cache, .mutmut-cache)
36
+
37
+ Use your internal Todo tool to track these and keep on track.
38
+
39
+ ## Technical Requirements
40
+ - Use PEP 621 `[project]` table in pyproject.toml (not legacy setup.py/setup.cfg)
41
+ - Use `[build-system]` with hatchling as build backend (standard for uv)
42
+ - `src/` layout: `[tool.hatch.build.targets.wheel] packages = ["src/flameconnect"]`
43
+ - Python requires-python = ">=3.13"
44
+ - Initial version: "0.1.0"
45
+
46
+ ## Input Dependencies
47
+ None — this is the first task.
48
+
49
+ ## Output Artifacts
50
+ - `pyproject.toml` — complete project configuration
51
+ - `src/flameconnect/__init__.py`, `__main__.py`, `py.typed`
52
+ - `tests/conftest.py`, `tests/__init__.py`
53
+ - `.venv/` created by uv
54
+ - Updated `.gitignore`
55
+
56
+ ## Implementation Notes
57
+
58
+ <details>
59
+ <summary>Detailed implementation guidance</summary>
60
+
61
+ 1. **Initialize the project**: Run `uv init` if not already initialized, or manually create `pyproject.toml`. The project is already a git repo.
62
+
63
+ 2. **pyproject.toml structure**:
64
+ ```toml
65
+ [build-system]
66
+ requires = ["hatchling"]
67
+ build-backend = "hatchling.build"
68
+
69
+ [project]
70
+ name = "flameconnect"
71
+ version = "0.1.0"
72
+ description = "Async Python library for controlling Dimplex/Faber fireplaces via the Flame Connect cloud API"
73
+ readme = "README.md"
74
+ license = "MIT"
75
+ requires-python = ">=3.13"
76
+ dependencies = [
77
+ "aiohttp>=3.9",
78
+ "msal>=1.28",
79
+ ]
80
+
81
+ [project.optional-dependencies]
82
+ tui = ["textual>=0.50"]
83
+ dev = [
84
+ "ruff>=0.4",
85
+ "mypy>=1.10",
86
+ "pytest>=8.0",
87
+ "pytest-aiohttp>=1.0",
88
+ "pytest-asyncio>=0.23",
89
+ "mutmut>=2.4",
90
+ "aioresponses>=0.7",
91
+ ]
92
+
93
+ [project.scripts]
94
+ flameconnect = "flameconnect.cli:main"
95
+
96
+ [tool.hatch.build.targets.wheel]
97
+ packages = ["src/flameconnect"]
98
+
99
+ [tool.ruff]
100
+ line-length = 88
101
+ target-version = "py313"
102
+
103
+ [tool.ruff.lint]
104
+ select = ["E", "F", "W", "I", "UP", "B", "SIM", "TCH"]
105
+
106
+ [tool.mypy]
107
+ strict = true
108
+
109
+ [tool.pytest.ini_options]
110
+ asyncio_mode = "auto"
111
+ testpaths = ["tests"]
112
+ ```
113
+
114
+ 3. **Create directory structure**:
115
+ - `src/flameconnect/__init__.py` — export `__version__ = "0.1.0"`
116
+ - `src/flameconnect/__main__.py` — `from flameconnect.cli import main; main()`
117
+ - `src/flameconnect/py.typed` — empty file
118
+ - `tests/__init__.py` — empty
119
+ - `tests/conftest.py` — empty (will be populated by test tasks)
120
+
121
+ 4. **Update .gitignore**: Add uv/Python packaging entries (`.venv/`, `dist/`, `*.egg-info/`, `.mypy_cache/`, `.ruff_cache/`, `.pytest_cache/`, `.mutmut-cache/`)
122
+
123
+ 5. **Run `uv sync`** to create the virtual environment and install all dependencies.
124
+
125
+ 6. **Important**: `src/flameconnect/cli.py` does not need to exist yet — just ensure the entry point in pyproject.toml points to the correct location for when it's created in task 7.
126
+ </details>
@@ -0,0 +1,108 @@
1
+ ---
2
+ id: 2
3
+ group: "core-library"
4
+ dependencies: [1]
5
+ status: "completed"
6
+ created: "2026-02-23"
7
+ skills:
8
+ - python
9
+ status: "completed"
10
+ status: "completed"
11
+ ---
12
+ # Implement models, enums, constants, and exceptions
13
+
14
+ ## Objective
15
+ Create the typed foundation of the library: Python `Enum` classes for all parameter values, `dataclass` types for API responses and parameter structures, constants for API configuration, and a custom exception hierarchy. These are the building blocks consumed by all other modules.
16
+
17
+ ## Skills Required
18
+ - Python type system (dataclasses, Enum, type annotations)
19
+
20
+ ## Acceptance Criteria
21
+ - [ ] `src/flameconnect/const.py` — API base URL, client ID, authority, scopes, default headers, ParameterId constants
22
+ - [ ] `src/flameconnect/models.py` — All enums (FireMode, FlameEffect, HeatStatus, HeatMode, HeatControl, FlameColor, LightStatus, TimerStatus, TempUnit, LogEffect, MediaTheme, ConnectionState) and dataclasses (Fire, FireOverview, ModeParam, FlameEffectParam, HeatParam, HeatModeParam, TimerParam, SoftwareVersionParam, ErrorParam, TempUnitParam, SoundParam, LogEffectParam)
23
+ - [ ] `src/flameconnect/exceptions.py` — FlameConnectError base, AuthenticationError, ApiError, ProtocolError
24
+ - [ ] All files pass `mypy --strict` with zero errors
25
+ - [ ] All files pass `ruff check` and `ruff format --check` with zero errors
26
+
27
+ Use your internal Todo tool to track these and keep on track.
28
+
29
+ ## Technical Requirements
30
+ - Use `@dataclass(frozen=True, slots=True)` for immutable parameter types
31
+ - Use `IntEnum` for enums that map to wire protocol integer values
32
+ - Dataclasses must have full type annotations (no `Any` types)
33
+ - Temperature fields should be `float` type
34
+ - RGBW color fields should use a nested `RGBWColor` dataclass with `red`, `green`, `blue`, `white` as `int` fields
35
+
36
+ ## Input Dependencies
37
+ - Task 1: Package skeleton must exist (`src/flameconnect/` directory, `pyproject.toml`)
38
+
39
+ ## Output Artifacts
40
+ - `src/flameconnect/const.py`
41
+ - `src/flameconnect/models.py`
42
+ - `src/flameconnect/exceptions.py`
43
+
44
+ ## Implementation Notes
45
+
46
+ <details>
47
+ <summary>Detailed implementation guidance</summary>
48
+
49
+ 1. **const.py**: Extract all constants from `flameconnect_reader.py`:
50
+ ```python
51
+ API_BASE = "https://mobileapi.gdhv-iot.com"
52
+ CLIENT_ID = "1af761dc-085a-411f-9cb9-53e5e2115bd2"
53
+ AUTHORITY = "https://gdhvb2cflameconnect.b2clogin.com/gdhvb2cflameconnect.onmicrosoft.com/B2C_1A_FirePhoneSignUpOrSignInWithPhoneOrEmail"
54
+ SCOPES = ["https://gdhvb2cflameconnect.onmicrosoft.com/Mobile/read"]
55
+ ```
56
+ Include default HTTP headers (app_name, api_version, app_version, etc.) as a dict constant.
57
+ Include `ParameterId` constants as an `IntEnum` or module-level constants:
58
+ - TEMPERATURE_UNIT = 236, MODE = 321, FLAME_EFFECT = 322, HEAT_SETTINGS = 323, HEAT_MODE = 325, TIMER = 326, SOFTWARE_VERSION = 327, ERROR = 329, SOUND = 369, LOG_EFFECT = 370
59
+
60
+ 2. **models.py**: Reference `flameconnect_reader.py` lines 33-59 for existing enum mappings. Convert each dict to a proper `IntEnum`:
61
+ ```python
62
+ class FireMode(IntEnum):
63
+ STANDBY = 0
64
+ MANUAL = 1
65
+ ```
66
+
67
+ For parameter dataclasses, reference the `decode_parameter` function (lines 224-283) and `FLAMECONNECT_API_REPORT.md` parameter reference section. Each decoded parameter type gets its own dataclass.
68
+
69
+ The `Fire` dataclass represents a fireplace from the GetFires response:
70
+ ```python
71
+ @dataclass(frozen=True, slots=True)
72
+ class Fire:
73
+ fire_id: str
74
+ friendly_name: str
75
+ brand: str
76
+ product_type: str
77
+ product_model: str
78
+ item_code: str
79
+ connection_state: ConnectionState
80
+ with_heat: bool
81
+ is_iot_fire: bool
82
+ ```
83
+
84
+ Create a `RGBWColor` dataclass reused in FlameEffectParam and LogEffectParam:
85
+ ```python
86
+ @dataclass(frozen=True, slots=True)
87
+ class RGBWColor:
88
+ red: int
89
+ green: int
90
+ blue: int
91
+ white: int
92
+ ```
93
+
94
+ The `FlameEffectParam` dataclass should include media_theme (RGBWColor + theme + light), overhead_light (RGBWColor + light), flame fields, etc. Reference lines 234-248 of flameconnect_reader.py.
95
+
96
+ 3. **exceptions.py**: Simple hierarchy:
97
+ ```python
98
+ class FlameConnectError(Exception): ...
99
+ class AuthenticationError(FlameConnectError): ...
100
+ class ApiError(FlameConnectError):
101
+ def __init__(self, status: int, message: str) -> None: ...
102
+ class ProtocolError(FlameConnectError): ...
103
+ ```
104
+
105
+ 4. **Important**: Use `logging.getLogger(__name__)` in any module that needs logging. No `print()`.
106
+
107
+ 5. **Update `__init__.py`**: Export the key public types (FlameConnectError, Fire, and the parameter dataclasses) from the package root.
108
+ </details>