fastled 1.4.35__tar.gz → 1.4.36__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 (148) hide show
  1. {fastled-1.4.35 → fastled-1.4.36}/.cursorrules +36 -1
  2. fastled-1.4.36/.vscode/launch.json +26 -0
  3. fastled-1.4.36/EXTENDED_INO.md +463 -0
  4. {fastled-1.4.35 → fastled-1.4.36}/PKG-INFO +2 -1
  5. {fastled-1.4.35 → fastled-1.4.36}/pyproject.toml +1 -1
  6. fastled-1.4.36/requirements.docker.txt +1 -0
  7. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/__version__.py +1 -1
  8. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/app.py +26 -0
  9. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/args.py +5 -0
  10. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/client_server.py +20 -15
  11. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/docker_manager.py +12 -6
  12. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/parse_args.py +9 -1
  13. fastled-1.4.36/src/fastled/select_sketch_directory.py +67 -0
  14. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/PKG-INFO +2 -1
  15. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/SOURCES.txt +1 -0
  16. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/requires.txt +1 -0
  17. fastled-1.4.35/.vscode/launch.json +0 -14
  18. fastled-1.4.35/requirements.docker.txt +0 -1
  19. fastled-1.4.35/src/fastled/select_sketch_directory.py +0 -37
  20. {fastled-1.4.35 → fastled-1.4.36}/.aiderignore +0 -0
  21. {fastled-1.4.35 → fastled-1.4.36}/.dockerignore +0 -0
  22. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/build_multi_docker_image.yml +0 -0
  23. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/build_webpage.yml +0 -0
  24. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/lint.yml +0 -0
  25. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/publish_release.yml +0 -0
  26. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/template_build_docker_image.yml +0 -0
  27. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/test_build_exe.yml +0 -0
  28. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/test_macos.yml +0 -0
  29. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/test_ubuntu.yml +0 -0
  30. {fastled-1.4.35 → fastled-1.4.36}/.github/workflows/test_win.yml +0 -0
  31. {fastled-1.4.35 → fastled-1.4.36}/.gitignore +0 -0
  32. {fastled-1.4.35 → fastled-1.4.36}/.pylintrc +0 -0
  33. {fastled-1.4.35 → fastled-1.4.36}/.vscode/settings.json +0 -0
  34. {fastled-1.4.35 → fastled-1.4.36}/.vscode/tasks.json +0 -0
  35. {fastled-1.4.35 → fastled-1.4.36}/DEBUGGER.md +0 -0
  36. {fastled-1.4.35 → fastled-1.4.36}/Dockerfile +0 -0
  37. {fastled-1.4.35 → fastled-1.4.36}/FAQ.md +0 -0
  38. {fastled-1.4.35 → fastled-1.4.36}/LICENSE +0 -0
  39. {fastled-1.4.35 → fastled-1.4.36}/MANIFEST.in +0 -0
  40. {fastled-1.4.35 → fastled-1.4.36}/README.md +0 -0
  41. {fastled-1.4.35 → fastled-1.4.36}/RELEASE.md +0 -0
  42. {fastled-1.4.35 → fastled-1.4.36}/TODO.md +0 -0
  43. {fastled-1.4.35 → fastled-1.4.36}/build_exe.py +0 -0
  44. {fastled-1.4.35 → fastled-1.4.36}/build_local_docker.py +0 -0
  45. {fastled-1.4.35 → fastled-1.4.36}/build_site.py +0 -0
  46. {fastled-1.4.35 → fastled-1.4.36}/chrome_vscode_bridge_design_task.md +0 -0
  47. {fastled-1.4.35 → fastled-1.4.36}/clean +0 -0
  48. {fastled-1.4.35 → fastled-1.4.36}/compiler/debug.sh +0 -0
  49. {fastled-1.4.35 → fastled-1.4.36}/compiler/run.py +0 -0
  50. {fastled-1.4.35 → fastled-1.4.36}/demo/100dots.html +0 -0
  51. {fastled-1.4.35 → fastled-1.4.36}/demo/demo_threejs.html +0 -0
  52. {fastled-1.4.35 → fastled-1.4.36}/demo/micdemo.html +0 -0
  53. {fastled-1.4.35 → fastled-1.4.36}/demo/mp3upload.html +0 -0
  54. {fastled-1.4.35 → fastled-1.4.36}/demo/webgl_postprocessing_unreal_bloom.html +0 -0
  55. {fastled-1.4.35 → fastled-1.4.36}/docker-compose.yml +0 -0
  56. {fastled-1.4.35 → fastled-1.4.36}/entrypoint.sh +0 -0
  57. {fastled-1.4.35 → fastled-1.4.36}/install +0 -0
  58. {fastled-1.4.35 → fastled-1.4.36}/install_linux.sh +0 -0
  59. {fastled-1.4.35 → fastled-1.4.36}/lint +0 -0
  60. {fastled-1.4.35 → fastled-1.4.36}/requirements.testing.txt +0 -0
  61. {fastled-1.4.35 → fastled-1.4.36}/setup.cfg +0 -0
  62. {fastled-1.4.35 → fastled-1.4.36}/setup.py +0 -0
  63. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/__init__.py +0 -0
  64. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/__main__.py +0 -0
  65. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/assets/example.txt +0 -0
  66. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/assets/localhost-key.pem +0 -0
  67. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/assets/localhost.pem +0 -0
  68. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/cli.py +0 -0
  69. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/cli_test.py +0 -0
  70. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/cli_test_interactive.py +0 -0
  71. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/compile_server.py +0 -0
  72. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/compile_server_impl.py +0 -0
  73. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/emoji_util.py +0 -0
  74. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/filewatcher.py +0 -0
  75. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/find_good_connection.py +0 -0
  76. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/__init__.py +0 -0
  77. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/examples_manager.py +0 -0
  78. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/extension_manager.py +0 -0
  79. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/main.py +0 -0
  80. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/project_detection.py +0 -0
  81. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/test_install.py +0 -0
  82. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/install/vscode_config.py +0 -0
  83. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/interruptible_http.py +0 -0
  84. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/keyboard.py +0 -0
  85. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/keyz.py +0 -0
  86. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/live_client.py +0 -0
  87. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/open_browser.py +0 -0
  88. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/paths.py +0 -0
  89. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/playwright/chrome_extension_downloader.py +0 -0
  90. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/playwright/playwright_browser.py +0 -0
  91. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/playwright/resize_tracking.py +0 -0
  92. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/print_filter.py +0 -0
  93. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/project_init.py +0 -0
  94. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/server_flask.py +0 -0
  95. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/server_start.py +0 -0
  96. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/settings.py +0 -0
  97. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/site/build.py +0 -0
  98. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/site/examples.py +0 -0
  99. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/sketch.py +0 -0
  100. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/spinner.py +0 -0
  101. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/string_diff.py +0 -0
  102. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/test/can_run_local_docker_tests.py +0 -0
  103. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/test/examples.py +0 -0
  104. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/types.py +0 -0
  105. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/util.py +0 -0
  106. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/version.py +0 -0
  107. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/web_compile.py +0 -0
  108. {fastled-1.4.35 → fastled-1.4.36}/src/fastled/zip_files.py +0 -0
  109. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/dependency_links.txt +0 -0
  110. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/entry_points.txt +0 -0
  111. {fastled-1.4.35 → fastled-1.4.36}/src/fastled.egg-info/top_level.txt +0 -0
  112. {fastled-1.4.35 → fastled-1.4.36}/task.md +0 -0
  113. {fastled-1.4.35 → fastled-1.4.36}/task2.md +0 -0
  114. {fastled-1.4.35 → fastled-1.4.36}/test +0 -0
  115. {fastled-1.4.35 → fastled-1.4.36}/tests/integration/test_build_examples.py +0 -0
  116. {fastled-1.4.35 → fastled-1.4.36}/tests/integration/test_examples.py +0 -0
  117. {fastled-1.4.35 → fastled-1.4.36}/tests/integration/test_libcompile.py +0 -0
  118. {fastled-1.4.35 → fastled-1.4.36}/tests/integration/test_playwright_integration.py +0 -0
  119. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/html/index.html +0 -0
  120. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_api.py +0 -0
  121. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_bad_ino.py +0 -0
  122. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_banner_string.py +0 -0
  123. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_cli.py +0 -0
  124. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_cli_no_platformio.py +0 -0
  125. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_compile_server.py +0 -0
  126. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_debug_fetch_source_files.py +0 -0
  127. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_docker_linux_on_windows.py +0 -0
  128. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_embedded_data.py +0 -0
  129. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_filechanger.py +0 -0
  130. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_flask_headers.py +0 -0
  131. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_http_server.py +0 -0
  132. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/bad/bad.ino +0 -0
  133. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/bad_platformio/bad_platformio.ino +0 -0
  134. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/bad_platformio/platformio.ini +0 -0
  135. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/embedded/data/bigdata.dat +0 -0
  136. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/embedded/wasm.ino +0 -0
  137. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_ino/wasm/wasm.ino +0 -0
  138. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_manual_api_invocation.py +0 -0
  139. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_no_platformio_compile.py +0 -0
  140. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_project_init.py +0 -0
  141. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_server_and_client_seperatly.py +0 -0
  142. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_session_compile.py +0 -0
  143. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_string_diff.py +0 -0
  144. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_string_diff_comprehensive.py +0 -0
  145. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_version.py +0 -0
  146. {fastled-1.4.35 → fastled-1.4.36}/tests/unit/test_webcompile.py +0 -0
  147. {fastled-1.4.35 → fastled-1.4.36}/upload_package.sh +0 -0
  148. {fastled-1.4.35 → fastled-1.4.36}/vscode-plugin/readme +0 -0
@@ -31,8 +31,43 @@
31
31
  3. Install dependencies with `uv add <package>`
32
32
  4. Run scripts with `uv run <script>`
33
33
 
34
+ ## Emoji/Emoticon Usage
35
+
36
+ **ALWAYS use the `EMO()` function for emojis, NEVER hardcode emojis directly!**
37
+
38
+ ### Guidelines:
39
+ - ✅ Use: `from fastled.emoji_util import EMO` then `EMO('⚠️', 'WARNING:')`
40
+ - ✅ Use: `from fastled.emoji_util import safe_print` for Unicode-safe printing
41
+ - ❌ NEVER use: hardcoded emojis like `print("⚠️ Warning")`
42
+ - ❌ NEVER use: raw Unicode without fallback handling
43
+
44
+ ### Common Patterns:
45
+ - Warning messages: `EMO('⚠️', 'WARNING:')`
46
+ - Success messages: `EMO('✅', 'SUCCESS:')`
47
+ - Error messages: `EMO('❌', 'ERROR:')`
48
+ - Info messages: `EMO('ℹ️', 'INFO:')`
49
+ - Playwright/browser: `EMO('🎭', '*')`
50
+ - Package/install: `EMO('📦', '*')`
51
+
52
+ ### Rationale:
53
+ - Windows cmd.exe has poor Unicode support and will crash on raw emojis
54
+ - The `EMO()` function provides fallback text for systems that don't support emojis
55
+ - Ensures consistent behavior across all platforms (Windows, macOS, Linux)
56
+ - Prevents application crashes due to encoding issues
57
+
58
+ ### Examples:
59
+ ```python
60
+ # Good - with EMO function
61
+ from fastled.emoji_util import EMO
62
+ print(f"{EMO('⚠️', 'WARNING:')} Debug mode detected with Playwright installed")
63
+
64
+ # Bad - hardcoded emoji
65
+ print("⚠️ Debug mode detected with Playwright installed")
66
+ ```
67
+
34
68
  ## Additional Rules:
35
69
  - When suggesting Python commands, always prefix with `uv run`
36
70
  - When creating scripts that execute Python, use `uv run` in the script
37
71
  - When documenting Python usage, emphasize `uv run` syntax
38
- - Update any existing scripts that use `python` or `python3` to use `uv run`
72
+ - Update any existing scripts that use `python` or `python3` to use `uv run`
73
+ - When adding user-facing messages with emojis, always use the `EMO()` function
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "🎯 Auto Debug (Smart File Detection)",
6
+ "type": "auto-debug",
7
+ "request": "launch",
8
+ "map": {
9
+ "*.ino": "Arduino: Run .ino with FastLED",
10
+ "*.py": "Python: Current File (UV)"
11
+ }
12
+ },
13
+ {
14
+ "name": "Python: Current File (UV)",
15
+ "type": "python",
16
+ "request": "launch",
17
+ "program": "${file}",
18
+ "console": "integratedTerminal",
19
+ "cwd": "${workspaceFolder}",
20
+ "env": {
21
+ "PYTHONPATH": "${workspaceFolder}/src"
22
+ },
23
+ "justMyCode": true
24
+ }
25
+ ]
26
+ }
@@ -0,0 +1,463 @@
1
+ # Extended INO Format Specification
2
+
3
+ ## Overview
4
+
5
+ Extended INO is a format that allows Arduino sketch files (`.ino`) to embed build configuration metadata directly within the source code, similar to Astral UV's inlined script dependencies. This enables self-contained sketches that carry their own build requirements, making them more portable and easier to share.
6
+
7
+ ## Motivation
8
+
9
+ Traditional Arduino development requires external configuration files (`platformio.ini`, `arduino-cli.yaml`) or IDE-specific settings to specify build parameters. Extended INO embeds this configuration directly in the sketch file, providing:
10
+
11
+ - **Portability**: Sketches carry their build requirements
12
+ - **Self-Documentation**: Build configuration is visible alongside code
13
+ - **Reproducibility**: Consistent builds across different environments
14
+ - **Simplicity**: Single file contains both code and configuration
15
+
16
+ ## Format Specification
17
+
18
+ ### Basic Structure
19
+
20
+ Extended INO files use a comment block with TOML configuration embedded between delimiter markers:
21
+
22
+ ```cpp
23
+ // /// extended-ino
24
+ // [build]
25
+ // board = "arduino:avr:uno"
26
+ //
27
+ // [flags]
28
+ // build = ["-DDEBUG=1", "-O2"]
29
+ // link = ["-Wl,--gc-sections"]
30
+ //
31
+ // [defines]
32
+ // DEBUG = "1"
33
+ // VERSION = "\"1.0.0\""
34
+ // ///
35
+
36
+ #include <FastLED.h>
37
+
38
+ void setup() {
39
+ // Your Arduino code here
40
+ }
41
+
42
+ void loop() {
43
+ // Your Arduino code here
44
+ }
45
+ ```
46
+
47
+ ### Delimiter Rules
48
+
49
+ - Start delimiter: `// /// extended-ino`
50
+ - End delimiter: `// ///`
51
+ - All configuration lines must be prefixed with `// ` (comment prefix + space)
52
+ - The content between delimiters must be valid TOML
53
+ - All relative paths in configuration are resolved relative to the sketch file's directory
54
+
55
+ ### Required Fields
56
+
57
+ #### `[build]` Section
58
+
59
+ - `board` (string): Board Fully Qualified Name (FQBN)
60
+ - Format: `package:architecture:board_id`
61
+ - Example: `"arduino:avr:uno"`, `"esp32:esp32:esp32"`
62
+
63
+ ### Optional Fields
64
+
65
+ #### `[flags]` Section
66
+
67
+ - `build` (array of strings): Compiler flags passed during compilation
68
+ - `link` (array of strings): Linker flags passed during linking
69
+ - `upload` (array of strings): Upload-specific flags
70
+
71
+ #### `[defines]` Section
72
+
73
+ Key-value pairs of preprocessor definitions:
74
+ - Keys become `#define` names
75
+ - Values become `#define` values
76
+ - String values should be quoted appropriately for C/C++
77
+
78
+ #### `[dependencies]` Section
79
+
80
+ - `libraries` (array of strings): Library dependencies with optional version constraints
81
+ - `additional_urls` (array of strings): Board Manager package index URLs for custom boards
82
+ - `cores` (array of strings): Core dependencies
83
+ - `tools` (array of strings): Tool dependencies
84
+
85
+ #### `[settings]` Section
86
+
87
+ - `cpu_frequency` (string): CPU frequency setting
88
+ - `flash_frequency` (string): Flash frequency setting
89
+ - `upload_speed` (integer): Upload baud rate
90
+ - `partition_scheme` (string): Flash partition scheme
91
+
92
+ #### `[cli]` Section (Essential Arduino CLI Settings)
93
+
94
+ **Required for Build Process:**
95
+ - `directories_user` (string): Arduino sketchbook directory for libraries and hardware
96
+ - `directories_data` (string): Arduino CLI data directory for core installations
97
+ - `export_binaries` (boolean): Always save compiled binaries to sketch folder
98
+
99
+ **Required for Custom Boards:**
100
+ - `board_manager_additional_urls` (array of strings): URLs for additional board package indexes
101
+ - `enable_unsafe_library_install` (boolean): Allow installation from git URLs or zip files
102
+
103
+ #### `[cli_optional]` Section (Nice-to-Have Arduino CLI Settings)
104
+
105
+ **Build Performance:**
106
+ - `build_cache_path` (string): Custom location for build cache files
107
+ - `build_cache_extra_paths` (array of strings): Additional directories to include in build cache
108
+ - `build_cache_ttl` (string): Time-to-live for cached compilation units (e.g., "720h")
109
+
110
+ **Development Experience:**
111
+ - `logging_level` (string): Log verbosity level ("trace", "debug", "info", "warn", "error", "fatal")
112
+ - `logging_file` (string): Log file path for persistent logging
113
+ - `output_no_color` (boolean): Disable colored output for terminals that don't support it
114
+ - `locale` (string): Language setting for Arduino CLI messages
115
+
116
+ **Network Configuration:**
117
+ - `network_proxy` (string): HTTP/HTTPS proxy server URL
118
+ - `connection_timeout` (string): Network timeout duration (e.g., "10s")
119
+
120
+ **Advanced Features:**
121
+ - `daemon_port` (string): gRPC port for Arduino CLI daemon mode
122
+ - `metrics_enabled` (boolean): Enable telemetry collection
123
+ - `updater_enable_notification` (boolean): Check for Arduino CLI updates
124
+
125
+ ## Multi-Board Support
126
+
127
+ Extended INO supports multiple board configurations using TOML table arrays:
128
+
129
+ ```cpp
130
+ // /// extended-ino
131
+ // [[board]]
132
+ // fqbn = "arduino:avr:uno"
133
+ //
134
+ // [board.flags]
135
+ // build = ["-DARDUINO_UNO=1"]
136
+ //
137
+ // [board.defines]
138
+ // BOARD_TYPE = "\"UNO\""
139
+ //
140
+ // [[board]]
141
+ // fqbn = "esp32:esp32:esp32"
142
+ //
143
+ // [board.flags]
144
+ // build = ["-DARDUINO_ESP32=1"]
145
+ //
146
+ // [board.defines]
147
+ // BOARD_TYPE = "\"ESP32\""
148
+ // ///
149
+ ```
150
+
151
+ ## Examples
152
+
153
+ ### Simple Example
154
+
155
+ ```cpp
156
+ // /// extended-ino
157
+ // [build]
158
+ // board = "arduino:avr:uno"
159
+ //
160
+ // [defines]
161
+ // LED_PIN = "13"
162
+ // BAUD_RATE = "9600"
163
+ // ///
164
+
165
+ void setup() {
166
+ pinMode(LED_PIN, OUTPUT);
167
+ Serial.begin(BAUD_RATE);
168
+ }
169
+
170
+ void loop() {
171
+ digitalWrite(LED_PIN, HIGH);
172
+ delay(1000);
173
+ digitalWrite(LED_PIN, LOW);
174
+ delay(1000);
175
+ }
176
+ ```
177
+
178
+ ### Advanced Example
179
+
180
+ ```cpp
181
+ // /// extended-ino
182
+ // [build]
183
+ // board = "esp32:esp32:esp32"
184
+ //
185
+ // [flags]
186
+ // build = [
187
+ // "-DCORE_DEBUG_LEVEL=4",
188
+ // "-DARDUINO_RUNNING_CORE=1",
189
+ // "-DARDUINO_EVENT_RUNNING_CORE=1"
190
+ // ]
191
+ // link = ["-Wl,--gc-sections"]
192
+ //
193
+ // [defines]
194
+ // WIFI_SSID = "\"MyNetwork\""
195
+ // WIFI_PASSWORD = "\"MyPassword\""
196
+ // DEBUG_ENABLED = "1"
197
+ //
198
+ // [dependencies]
199
+ // libraries = ["WiFi", "WebServer", "ArduinoJson@>=6.0.0"]
200
+ // additional_urls = ["https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json"]
201
+ //
202
+ // [settings]
203
+ // cpu_frequency = "240MHz"
204
+ // flash_frequency = "80MHz"
205
+ // upload_speed = 921600
206
+ // partition_scheme = "default"
207
+ //
208
+ // [cli]
209
+ // directories_user = "/home/user/Arduino"
210
+ // export_binaries = true
211
+ // board_manager_additional_urls = ["https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"]
212
+ //
213
+ // [cli_optional]
214
+ // build_cache_ttl = "720h"
215
+ // logging_level = "info"
216
+ // output_no_color = false
217
+ // ///
218
+
219
+ #include <WiFi.h>
220
+ #include <WebServer.h>
221
+ #include <ArduinoJson.h>
222
+
223
+ void setup() {
224
+ Serial.begin(115200);
225
+ WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
226
+ }
227
+
228
+ void loop() {
229
+ // Application code
230
+ }
231
+ ```
232
+
233
+ ### Arduino CLI Configuration Example
234
+
235
+ ```cpp
236
+ // /// extended-ino
237
+ // [build]
238
+ // board = "esp32:esp32:esp32dev"
239
+ //
240
+ // [dependencies]
241
+ // libraries = ["FastLED@>=3.6.0", "WiFiManager", "ArduinoJson@^6.21.0"]
242
+ // additional_urls = [
243
+ // "https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json",
244
+ // "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"
245
+ // ]
246
+ //
247
+ // [defines]
248
+ // FASTLED_INTERNAL = "1"
249
+ // LED_COUNT = "100"
250
+ //
251
+ // [cli]
252
+ // directories_user = "./libraries" # Relative to sketch directory
253
+ // directories_data = "./arduino-data" # Relative to sketch directory
254
+ // export_binaries = true
255
+ // enable_unsafe_library_install = true
256
+ //
257
+ // [cli_optional]
258
+ // build_cache_path = "./build-cache" # Relative to sketch directory
259
+ // build_cache_ttl = "168h"
260
+ // logging_level = "debug"
261
+ // logging_file = "./arduino-cli.log" # Relative to sketch directory
262
+ // ///
263
+
264
+ #include <FastLED.h>
265
+ #include <WiFiManager.h>
266
+ #include <ArduinoJson.h>
267
+
268
+ CRGB leds[LED_COUNT];
269
+
270
+ void setup() {
271
+ FastLED.addLeds<WS2812B, 2, GRB>(leds, LED_COUNT);
272
+ WiFiManager wifiManager;
273
+ wifiManager.autoConnect("FastLED_Setup");
274
+ }
275
+
276
+ void loop() {
277
+ // LED effects and WiFi communication
278
+ }
279
+ ```
280
+
281
+ ### Multi-Board Example
282
+
283
+ ```cpp
284
+ // /// extended-ino
285
+ // [[board]]
286
+ // fqbn = "arduino:avr:uno"
287
+ //
288
+ // [board.defines]
289
+ // LED_COUNT = "50"
290
+ // DATA_PIN = "6"
291
+ //
292
+ // [board.flags]
293
+ // build = ["-DAVR_BOARD=1"]
294
+ //
295
+ // [[board]]
296
+ // fqbn = "esp32:esp32:esp32"
297
+ //
298
+ // [board.defines]
299
+ // LED_COUNT = "100"
300
+ // DATA_PIN = "2"
301
+ //
302
+ // [board.flags]
303
+ // build = ["-DESP32_BOARD=1"]
304
+ //
305
+ // [board.settings]
306
+ // cpu_frequency = "240MHz"
307
+ // ///
308
+
309
+ #include <FastLED.h>
310
+
311
+ CRGB leds[LED_COUNT];
312
+
313
+ void setup() {
314
+ FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, LED_COUNT);
315
+ }
316
+
317
+ void loop() {
318
+ // LED animation code
319
+ }
320
+ ```
321
+
322
+ ## Implementation Considerations
323
+
324
+ ### Parsing
325
+
326
+ 1. **Automatic Discovery**: Detect Extended INO configuration in any `.ino` file being processed (no path argument required)
327
+ 2. **Comment Extraction**: Parse comment blocks between delimiters within the sketch file
328
+ 3. **TOML Validation**: Validate embedded TOML syntax
329
+ 4. **Field Validation**: Ensure required fields are present
330
+ 5. **Board Resolution**: Validate FQBN format and availability
331
+ 6. **Path Resolution**: Use sketch file directory as base path for all relative paths and generated files
332
+
333
+ ### Integration Points
334
+
335
+ Extended INO can integrate with:
336
+
337
+ - **Arduino CLI**: Generate temporary `arduino-cli.yaml` configuration files from `[cli]` and `[cli_optional]` sections
338
+ - **PlatformIO**: Convert to `platformio.ini` format using board, flags, and dependencies
339
+ - **Arduino IDE 2.x**: Plugin/extension support for parsing and applying Extended INO configuration
340
+ - **VS Code**: Language server extensions with Arduino CLI integration
341
+
342
+ ### Arduino CLI Configuration Generation
343
+
344
+ Extended INO tools can generate Arduino CLI configuration files from embedded metadata:
345
+
346
+ ```yaml
347
+ # Generated arduino-cli.yaml from Extended INO [cli] section
348
+ board_manager:
349
+ additional_urls:
350
+ - "https://adafruit.github.io/arduino-board-index/package_adafruit_index.json"
351
+
352
+ directories:
353
+ user: "./libraries"
354
+ data: "./arduino-data"
355
+
356
+ sketch:
357
+ always_export_binaries: true
358
+
359
+ library:
360
+ enable_unsafe_install: true
361
+
362
+ build_cache:
363
+ path: "./build-cache"
364
+ ttl: "168h"
365
+
366
+ logging:
367
+ level: "debug"
368
+ file: "./arduino-cli.log"
369
+ ```
370
+
371
+ ### Error Handling
372
+
373
+ - **Invalid TOML**: Clear syntax error messages with line numbers
374
+ - **Missing Required Fields**: Specify which fields are missing
375
+ - **Invalid FQBN**: Validate board availability
376
+ - **Conflicting Configurations**: Handle multi-board conflicts
377
+
378
+ ### Backward Compatibility
379
+
380
+ - Files without Extended INO blocks remain valid Arduino sketches
381
+ - Existing build systems can ignore the comment blocks
382
+ - Gradual adoption possible
383
+
384
+ ## Future Considerations
385
+
386
+ ### Planned Extensions
387
+
388
+ 1. **Variable Substitution**: Environment variable and computed value support
389
+ 2. **Conditional Configuration**: Platform-specific sections
390
+ 3. **Include Support**: Reference external configuration fragments
391
+ 4. **Version Constraints**: Semantic versioning for dependencies
392
+ 5. **Custom Build Steps**: Pre/post-build actions
393
+
394
+ ### Example Future Syntax
395
+
396
+ ```cpp
397
+ // /// extended-ino
398
+ // [build]
399
+ // board = "${BOARD_FQBN:-arduino:avr:uno}"
400
+ //
401
+ // [conditional.esp32]
402
+ // condition = "platform == 'esp32'"
403
+ //
404
+ // [conditional.esp32.defines]
405
+ // WIFI_ENABLED = "1"
406
+ //
407
+ // [includes]
408
+ // common = "./common-config.toml"
409
+ // ///
410
+ ```
411
+
412
+ ## Tool Invocation
413
+
414
+ Extended INO tools operate directly on sketch files without requiring explicit path arguments:
415
+
416
+ ```bash
417
+ # Tool discovers configuration from the sketch file automatically
418
+ extended-ino-build MySketch.ino
419
+
420
+ # Working directory becomes the sketch's directory
421
+ extended-ino-compile MyProject/MySketch.ino
422
+
423
+ # All generated files appear in the sketch's directory
424
+ extended-ino-upload ./examples/Blink/Blink.ino
425
+ ```
426
+
427
+ **Key Behaviors:**
428
+ - **Implicit Path Discovery**: Tools automatically detect Extended INO configuration in the specified `.ino` file
429
+ - **Working Directory**: The sketch file's directory becomes the base path for all operations
430
+ - **Generated Files**: All temporary files (`arduino-cli.yaml`, `platformio.ini`, build cache) are created relative to the sketch location
431
+ - **No Path Arguments**: Tools never require separate path or directory arguments beyond the sketch file itself
432
+
433
+ ## Tooling Support
434
+
435
+ ### Required Tools
436
+
437
+ - **TOML Parser**: For configuration extraction and validation from sketch files
438
+ - **Board Database**: FQBN validation and resolution
439
+ - **Build System Integration**: Convert to native build formats using sketch file location as working directory
440
+
441
+ ### Recommended Workflow
442
+
443
+ 1. **Parse**: Extract and validate Extended INO configuration from comment block in the sketch file
444
+ 2. **Resolve**: Validate board FQBN and check dependency availability
445
+ 3. **Configure**: Generate temporary `arduino-cli.yaml` from `[cli]` and `[cli_optional]` sections in the sketch directory
446
+ 4. **Dependencies**: Install libraries and board packages as specified
447
+ 5. **Generate**: Create appropriate build system files (platformio.ini, compile_commands.json) in the sketch directory
448
+ 6. **Build**: Execute Arduino CLI build process with generated configuration using the sketch file path
449
+ 7. **Export**: Save binaries to sketch directory if `export_binaries` is enabled
450
+ 8. **Clean**: Remove temporary configuration files and build artifacts from sketch directory
451
+
452
+ ## Conclusion
453
+
454
+ Extended INO provides a self-contained format for Arduino sketches that embeds build configuration alongside source code. This improves portability, reproducibility, and ease of sharing while maintaining backward compatibility with existing Arduino development workflows.
455
+
456
+ The format integrates comprehensive Arduino CLI configuration options, enabling complete control over the build environment, dependency management, and development experience through embedded TOML metadata.
457
+
458
+ The format is designed to be:
459
+ - **Human-readable**: TOML syntax is clear and well-documented
460
+ - **Tool-friendly**: Structured format enables automated processing and Arduino CLI integration
461
+ - **Extensible**: Future features can be added without breaking changes
462
+ - **Compatible**: Works with existing Arduino ecosystems and CLI tools
463
+ - **Comprehensive**: Covers essential build settings and optional developer experience enhancements
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastled
3
- Version: 1.4.35
3
+ Version: 1.4.36
4
4
  Summary: FastLED Wasm Compiler
5
5
  Home-page: https://github.com/zackees/fastled-wasm
6
6
  Maintainer: Zachary Vorhies
@@ -23,6 +23,7 @@ Requires-Dist: flask-cors>=4.0.0
23
23
  Requires-Dist: livereload
24
24
  Requires-Dist: disklru>=2.0.4
25
25
  Requires-Dist: playwright>=1.40.0
26
+ Requires-Dist: websockify>=0.13.0
26
27
  Dynamic: home-page
27
28
  Dynamic: license-file
28
29
  Dynamic: maintainer
@@ -26,7 +26,7 @@ dependencies = [
26
26
  "livereload",
27
27
  "disklru>=2.0.4",
28
28
  "playwright>=1.40.0",
29
-
29
+ "websockify>=0.13.0",
30
30
  ]
31
31
 
32
32
  dynamic = ["version"]
@@ -0,0 +1 @@
1
+ fastled-wasm-server>=1.1.42
@@ -1,6 +1,6 @@
1
1
  # IMPORTANT! There's a bug in github which will REJECT any version update
2
2
  # that has any other change in the repo. Please bump the version as the
3
3
  # ONLY change in a commit, or else the pypi update and the release will fail.
4
- __version__ = "1.4.35"
4
+ __version__ = "1.4.36"
5
5
 
6
6
  __version_url_latest__ = "https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/src/fastled/__version__.py"
@@ -12,6 +12,7 @@ from fastled.compile_server import CompileServer
12
12
  from fastled.emoji_util import EMO
13
13
  from fastled.filewatcher import file_watcher_set
14
14
  from fastled.parse_args import Args, parse_args
15
+ from fastled.settings import DEFAULT_URL
15
16
  from fastled.sketch import find_sketch_directories, looks_like_fastled_repo
16
17
 
17
18
 
@@ -53,6 +54,31 @@ def main() -> int:
53
54
 
54
55
  args = parse_args()
55
56
 
57
+ if args.emsdk_headers:
58
+ import httpx
59
+
60
+ out_path = args.emsdk_headers
61
+ base_url = args.web if isinstance(args.web, str) else DEFAULT_URL
62
+ try:
63
+ response = httpx.get(f"{base_url}/headers/emsdk")
64
+ if response.status_code == 200:
65
+ Path(out_path).parent.mkdir(parents=True, exist_ok=True)
66
+ with open(out_path, "wb") as f:
67
+ f.write(response.content)
68
+ print(f"{EMO('✅','SUCCESS:')} EMSDK headers exported to {out_path}")
69
+ return 0
70
+ else:
71
+ print(
72
+ f"{EMO('❌','ERROR:')} Failed to export EMSDK headers: HTTP {response.status_code}"
73
+ )
74
+ return 1
75
+ except KeyboardInterrupt:
76
+ print("\nExiting from main...")
77
+ return 1
78
+ except Exception as e:
79
+ print(f"{EMO('❌','ERROR:')} Exception: {e}")
80
+ return 1
81
+
56
82
  # Handle --install command early
57
83
  if args.install:
58
84
  from fastled.install.main import fastled_install
@@ -29,6 +29,7 @@ class Args:
29
29
  install: bool = False # Install FastLED development environment
30
30
  dry_run: bool = False # Dry run mode for testing
31
31
  no_interactive: bool = False # Non-interactive mode
32
+ emsdk_headers: str | None = None # Path to export EMSDK headers ZIP
32
33
 
33
34
  @staticmethod
34
35
  def from_namespace(args: argparse.Namespace) -> "Args":
@@ -84,6 +85,9 @@ class Args:
84
85
  assert isinstance(
85
86
  args.no_interactive, bool
86
87
  ), f"expected bool, got {type(args.no_interactive)}"
88
+ assert isinstance(
89
+ args.emsdk_headers, str | None
90
+ ), f"expected str | None, got {type(args.emsdk_headers)}"
87
91
 
88
92
  init: bool | str = False
89
93
  if args.init is None:
@@ -115,5 +119,6 @@ class Args:
115
119
  ram_disk_size=args.ram_disk_size,
116
120
  install=args.install,
117
121
  dry_run=args.dry_run,
122
+ emsdk_headers=args.emsdk_headers,
118
123
  no_interactive=args.no_interactive,
119
124
  )