fbuild 1.2.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. fbuild/__init__.py +390 -0
  2. fbuild/assets/example.txt +1 -0
  3. fbuild/build/__init__.py +117 -0
  4. fbuild/build/archive_creator.py +186 -0
  5. fbuild/build/binary_generator.py +444 -0
  6. fbuild/build/build_component_factory.py +131 -0
  7. fbuild/build/build_info_generator.py +624 -0
  8. fbuild/build/build_state.py +325 -0
  9. fbuild/build/build_utils.py +93 -0
  10. fbuild/build/compilation_executor.py +422 -0
  11. fbuild/build/compiler.py +165 -0
  12. fbuild/build/compiler_avr.py +574 -0
  13. fbuild/build/configurable_compiler.py +664 -0
  14. fbuild/build/configurable_linker.py +637 -0
  15. fbuild/build/flag_builder.py +214 -0
  16. fbuild/build/library_dependency_processor.py +185 -0
  17. fbuild/build/linker.py +708 -0
  18. fbuild/build/orchestrator.py +67 -0
  19. fbuild/build/orchestrator_avr.py +651 -0
  20. fbuild/build/orchestrator_esp32.py +878 -0
  21. fbuild/build/orchestrator_rp2040.py +719 -0
  22. fbuild/build/orchestrator_stm32.py +696 -0
  23. fbuild/build/orchestrator_teensy.py +580 -0
  24. fbuild/build/source_compilation_orchestrator.py +218 -0
  25. fbuild/build/source_scanner.py +516 -0
  26. fbuild/cli.py +717 -0
  27. fbuild/cli_utils.py +314 -0
  28. fbuild/config/__init__.py +16 -0
  29. fbuild/config/board_config.py +542 -0
  30. fbuild/config/board_loader.py +92 -0
  31. fbuild/config/ini_parser.py +369 -0
  32. fbuild/config/mcu_specs.py +88 -0
  33. fbuild/daemon/__init__.py +42 -0
  34. fbuild/daemon/async_client.py +531 -0
  35. fbuild/daemon/client.py +1505 -0
  36. fbuild/daemon/compilation_queue.py +293 -0
  37. fbuild/daemon/configuration_lock.py +865 -0
  38. fbuild/daemon/daemon.py +585 -0
  39. fbuild/daemon/daemon_context.py +293 -0
  40. fbuild/daemon/error_collector.py +263 -0
  41. fbuild/daemon/file_cache.py +332 -0
  42. fbuild/daemon/firmware_ledger.py +546 -0
  43. fbuild/daemon/lock_manager.py +508 -0
  44. fbuild/daemon/logging_utils.py +149 -0
  45. fbuild/daemon/messages.py +957 -0
  46. fbuild/daemon/operation_registry.py +288 -0
  47. fbuild/daemon/port_state_manager.py +249 -0
  48. fbuild/daemon/process_tracker.py +366 -0
  49. fbuild/daemon/processors/__init__.py +18 -0
  50. fbuild/daemon/processors/build_processor.py +248 -0
  51. fbuild/daemon/processors/deploy_processor.py +664 -0
  52. fbuild/daemon/processors/install_deps_processor.py +431 -0
  53. fbuild/daemon/processors/locking_processor.py +777 -0
  54. fbuild/daemon/processors/monitor_processor.py +285 -0
  55. fbuild/daemon/request_processor.py +457 -0
  56. fbuild/daemon/shared_serial.py +819 -0
  57. fbuild/daemon/status_manager.py +238 -0
  58. fbuild/daemon/subprocess_manager.py +316 -0
  59. fbuild/deploy/__init__.py +21 -0
  60. fbuild/deploy/deployer.py +67 -0
  61. fbuild/deploy/deployer_esp32.py +310 -0
  62. fbuild/deploy/docker_utils.py +315 -0
  63. fbuild/deploy/monitor.py +519 -0
  64. fbuild/deploy/qemu_runner.py +603 -0
  65. fbuild/interrupt_utils.py +34 -0
  66. fbuild/ledger/__init__.py +52 -0
  67. fbuild/ledger/board_ledger.py +560 -0
  68. fbuild/output.py +352 -0
  69. fbuild/packages/__init__.py +66 -0
  70. fbuild/packages/archive_utils.py +1098 -0
  71. fbuild/packages/arduino_core.py +412 -0
  72. fbuild/packages/cache.py +256 -0
  73. fbuild/packages/concurrent_manager.py +510 -0
  74. fbuild/packages/downloader.py +518 -0
  75. fbuild/packages/fingerprint.py +423 -0
  76. fbuild/packages/framework_esp32.py +538 -0
  77. fbuild/packages/framework_rp2040.py +349 -0
  78. fbuild/packages/framework_stm32.py +459 -0
  79. fbuild/packages/framework_teensy.py +346 -0
  80. fbuild/packages/github_utils.py +96 -0
  81. fbuild/packages/header_trampoline_cache.py +394 -0
  82. fbuild/packages/library_compiler.py +203 -0
  83. fbuild/packages/library_manager.py +549 -0
  84. fbuild/packages/library_manager_esp32.py +725 -0
  85. fbuild/packages/package.py +163 -0
  86. fbuild/packages/platform_esp32.py +383 -0
  87. fbuild/packages/platform_rp2040.py +400 -0
  88. fbuild/packages/platform_stm32.py +581 -0
  89. fbuild/packages/platform_teensy.py +312 -0
  90. fbuild/packages/platform_utils.py +131 -0
  91. fbuild/packages/platformio_registry.py +369 -0
  92. fbuild/packages/sdk_utils.py +231 -0
  93. fbuild/packages/toolchain.py +436 -0
  94. fbuild/packages/toolchain_binaries.py +196 -0
  95. fbuild/packages/toolchain_esp32.py +489 -0
  96. fbuild/packages/toolchain_metadata.py +185 -0
  97. fbuild/packages/toolchain_rp2040.py +436 -0
  98. fbuild/packages/toolchain_stm32.py +417 -0
  99. fbuild/packages/toolchain_teensy.py +404 -0
  100. fbuild/platform_configs/esp32.json +150 -0
  101. fbuild/platform_configs/esp32c2.json +144 -0
  102. fbuild/platform_configs/esp32c3.json +143 -0
  103. fbuild/platform_configs/esp32c5.json +151 -0
  104. fbuild/platform_configs/esp32c6.json +151 -0
  105. fbuild/platform_configs/esp32p4.json +149 -0
  106. fbuild/platform_configs/esp32s3.json +151 -0
  107. fbuild/platform_configs/imxrt1062.json +56 -0
  108. fbuild/platform_configs/rp2040.json +70 -0
  109. fbuild/platform_configs/rp2350.json +76 -0
  110. fbuild/platform_configs/stm32f1.json +59 -0
  111. fbuild/platform_configs/stm32f4.json +63 -0
  112. fbuild/py.typed +0 -0
  113. fbuild-1.2.8.dist-info/METADATA +468 -0
  114. fbuild-1.2.8.dist-info/RECORD +121 -0
  115. fbuild-1.2.8.dist-info/WHEEL +5 -0
  116. fbuild-1.2.8.dist-info/entry_points.txt +5 -0
  117. fbuild-1.2.8.dist-info/licenses/LICENSE +21 -0
  118. fbuild-1.2.8.dist-info/top_level.txt +2 -0
  119. fbuild_lint/__init__.py +0 -0
  120. fbuild_lint/ruff_plugins/__init__.py +0 -0
  121. fbuild_lint/ruff_plugins/keyboard_interrupt_checker.py +158 -0
@@ -0,0 +1,369 @@
1
+ """
2
+ PlatformIO.ini configuration parser.
3
+
4
+ This module provides functionality to parse platformio.ini files and extract
5
+ environment configurations for building embedded projects.
6
+ """
7
+
8
+ import configparser
9
+ from pathlib import Path
10
+ from typing import Dict, List, Optional
11
+
12
+
13
+ class PlatformIOConfigError(Exception):
14
+ """Exception raised for platformio.ini configuration errors."""
15
+
16
+ pass
17
+
18
+
19
+ class PlatformIOConfig:
20
+ """
21
+ Parser for platformio.ini configuration files.
22
+
23
+ This class handles parsing of PlatformIO-style INI files, extracting
24
+ environment configurations, and validating required fields.
25
+
26
+ Example platformio.ini:
27
+ [env:uno]
28
+ platform = atmelavr
29
+ board = uno
30
+ framework = arduino
31
+
32
+ Usage:
33
+ config = PlatformIOConfig(Path("platformio.ini"))
34
+ envs = config.get_environments()
35
+ uno_config = config.get_env_config("uno")
36
+ """
37
+
38
+ REQUIRED_FIELDS = {"platform", "board", "framework"}
39
+
40
+ def __init__(self, ini_path: Path):
41
+ """
42
+ Initialize the parser with a platformio.ini file.
43
+
44
+ Args:
45
+ ini_path: Path to the platformio.ini file
46
+
47
+ Raises:
48
+ PlatformIOConfigError: If the file doesn't exist or cannot be parsed
49
+ """
50
+ self.ini_path = ini_path
51
+
52
+ if not ini_path.exists():
53
+ raise PlatformIOConfigError(f"Configuration file not found: {ini_path}")
54
+
55
+ # Use interpolation=None to disable Python's built-in interpolation.
56
+ # PlatformIO uses a different syntax: ${env:section.key} instead of ${section:key}
57
+ # We handle this manually in get_env_config() with a custom regex-based interpolation.
58
+ self.config = configparser.ConfigParser(allow_no_value=True, interpolation=None)
59
+
60
+ try:
61
+ self.config.read(ini_path, encoding="utf-8")
62
+ except configparser.Error as e:
63
+ raise PlatformIOConfigError(f"Failed to parse {ini_path}: {e}") from e
64
+
65
+ def get_environments(self) -> List[str]:
66
+ """
67
+ Get list of all environment names defined in the config.
68
+
69
+ Returns:
70
+ List of environment names (e.g., ['uno', 'mega', 'nano'])
71
+
72
+ Example:
73
+ For [env:uno], [env:mega], returns ['uno', 'mega']
74
+ """
75
+ envs = []
76
+ for section in self.config.sections():
77
+ if section.startswith("env:"):
78
+ env_name = section.split(":", 1)[1]
79
+ envs.append(env_name)
80
+ return envs
81
+
82
+ def get_env_config(self, env_name: str, _visited: Optional[set] = None, _validate: bool = True) -> Dict[str, str]:
83
+ """
84
+ Get configuration for a specific environment with inheritance support.
85
+
86
+ Args:
87
+ env_name: Name of the environment (e.g., 'uno')
88
+ _visited: Internal parameter for circular dependency detection
89
+ _validate: Internal parameter to control validation (default: True)
90
+
91
+ Returns:
92
+ Dictionary of configuration key-value pairs
93
+
94
+ Raises:
95
+ PlatformIOConfigError: If environment not found, missing required fields,
96
+ or circular dependency detected
97
+
98
+ Example:
99
+ config.get_env_config('uno')
100
+ # Returns: {'platform': 'atmelavr', 'board': 'uno', 'framework': 'arduino'}
101
+ """
102
+ # Initialize visited set for circular dependency detection
103
+ if _visited is None:
104
+ _visited = set()
105
+
106
+ # Check for circular dependency
107
+ if env_name in _visited:
108
+ chain = " -> ".join(_visited) + f" -> {env_name}"
109
+ raise PlatformIOConfigError(f"Circular dependency detected in environment inheritance: {chain}")
110
+
111
+ _visited.add(env_name)
112
+
113
+ section = f"env:{env_name}"
114
+
115
+ if section not in self.config:
116
+ available = ", ".join(self.get_environments())
117
+ raise PlatformIOConfigError(f"Environment '{env_name}' not found. " + f"Available environments: {available or 'none'}")
118
+
119
+ # Collect all key-value pairs from the environment section
120
+ # Use raw=True to avoid interpolation errors when referencing parent environments
121
+ env_config = {}
122
+ for key in self.config[section]:
123
+ value = self.config[section].get(key, raw=True)
124
+ # Handle multi-line values (like lib_deps)
125
+ env_config[key] = value.strip() if value else ""
126
+
127
+ # Also check if there's a base [env] section to inherit from
128
+ if "env" in self.config:
129
+ base_config = {}
130
+ for key in self.config["env"]:
131
+ value = self.config["env"].get(key, raw=True)
132
+ base_config[key] = value.strip() if value else ""
133
+ # Environment-specific values override base values
134
+ env_config = {**base_config, **env_config}
135
+
136
+ # Handle 'extends' directive for environment inheritance
137
+ if "extends" in env_config:
138
+ parent_ref = env_config["extends"].strip()
139
+ # Parse parent reference (can be "env:parent" or just "parent")
140
+ parent_name = parent_ref.replace("env:", "").strip()
141
+
142
+ # Recursively get parent config (don't validate parent, it might be abstract)
143
+ parent_config = self.get_env_config(parent_name, _visited, _validate=False)
144
+
145
+ # Merge: parent values first, then child overrides
146
+ merged_config = parent_config.copy()
147
+ for key, value in env_config.items():
148
+ if key == "extends":
149
+ # Remove 'extends' key from final config
150
+ continue
151
+ merged_config[key] = value
152
+
153
+ env_config = merged_config
154
+
155
+ # Now perform manual variable interpolation for cross-environment references
156
+ # This handles ${env:parent.key} syntax
157
+ import re
158
+
159
+ interpolated_config = {}
160
+ for key, value in env_config.items():
161
+ # Look for ${env:name.key} patterns
162
+ pattern = r"\$\{env:([^}]+)\}"
163
+ matches = re.findall(pattern, value)
164
+
165
+ interpolated_value = value
166
+ for match in matches:
167
+ # Parse the reference: "env:parent.build_flags"
168
+ parts = match.split(".")
169
+ if len(parts) == 2:
170
+ ref_env = parts[0]
171
+ ref_key = parts[1]
172
+
173
+ # Get the referenced environment's config
174
+ # Create a new visited set to avoid false circular dependency detection
175
+ # Don't validate the referenced environment (it might be an abstract base)
176
+ ref_config = self.get_env_config(ref_env, set(), _validate=False)
177
+
178
+ if ref_key in ref_config:
179
+ # Replace the variable reference with the actual value
180
+ interpolated_value = interpolated_value.replace(f"${{env:{match}}}", ref_config[ref_key])
181
+
182
+ interpolated_config[key] = interpolated_value
183
+
184
+ env_config = interpolated_config
185
+
186
+ # Validate required fields (only if validation is enabled)
187
+ if _validate:
188
+ missing_fields = self.REQUIRED_FIELDS - set(env_config.keys())
189
+ if missing_fields:
190
+ raise PlatformIOConfigError(f"Environment '{env_name}' is missing required fields: " + f"{', '.join(sorted(missing_fields))}")
191
+
192
+ return env_config
193
+
194
+ def get_build_flags(self, env_name: str) -> List[str]:
195
+ """
196
+ Parse and return build flags for an environment.
197
+
198
+ Args:
199
+ env_name: Name of the environment
200
+
201
+ Returns:
202
+ List of build flags
203
+
204
+ Example:
205
+ For build_flags = -DDEBUG -DVERSION=1.0
206
+ Returns: ['-DDEBUG', '-DVERSION=1.0']
207
+ """
208
+ env_config = self.get_env_config(env_name)
209
+ build_flags_str = env_config.get("build_flags", "")
210
+
211
+ if not build_flags_str:
212
+ return []
213
+
214
+ # Split on whitespace and newlines, filter empty strings
215
+ raw_flags = build_flags_str.split()
216
+ flags = []
217
+
218
+ # Handle cases like "-D FLAG" which should become "-DFLAG"
219
+ # PlatformIO allows "-D FLAG=value" format (space after -D)
220
+ i = 0
221
+ while i < len(raw_flags):
222
+ flag = raw_flags[i]
223
+ if flag == "-D" and i + 1 < len(raw_flags):
224
+ # Next token is the define name/value
225
+ next_token = raw_flags[i + 1]
226
+ # Only combine if next token doesn't start with dash
227
+ if not next_token.startswith("-"):
228
+ flags.append(f"-D{next_token}")
229
+ i += 2
230
+ continue
231
+ if flag:
232
+ flags.append(flag)
233
+ i += 1
234
+
235
+ return flags
236
+
237
+ def get_lib_deps(self, env_name: str) -> List[str]:
238
+ """
239
+ Parse and return library dependencies for an environment.
240
+
241
+ Args:
242
+ env_name: Name of the environment
243
+
244
+ Returns:
245
+ List of library dependencies
246
+
247
+ Example:
248
+ For lib_deps =
249
+ SPI
250
+ Wire
251
+ Returns: ['SPI', 'Wire']
252
+ """
253
+ env_config = self.get_env_config(env_name)
254
+ lib_deps_str = env_config.get("lib_deps", "")
255
+
256
+ if not lib_deps_str:
257
+ return []
258
+
259
+ # Split on newlines and commas, strip whitespace, filter empty
260
+ deps = []
261
+ for line in lib_deps_str.split("\n"):
262
+ for dep in line.split(","):
263
+ dep = dep.strip()
264
+ if dep:
265
+ deps.append(dep)
266
+ return deps
267
+
268
+ def has_environment(self, env_name: str) -> bool:
269
+ """
270
+ Check if an environment exists in the configuration.
271
+
272
+ Args:
273
+ env_name: Name of the environment to check
274
+
275
+ Returns:
276
+ True if environment exists, False otherwise
277
+ """
278
+ return f"env:{env_name}" in self.config
279
+
280
+ def get_default_environment(self) -> Optional[str]:
281
+ """
282
+ Get the default environment from platformio.ini.
283
+
284
+ Returns:
285
+ Default environment name, or first available environment, or None
286
+
287
+ Example:
288
+ If [platformio] section has default_envs = uno, returns 'uno'
289
+ Otherwise returns the first environment found
290
+ """
291
+ # Check for explicit default_envs in [platformio] section
292
+ if "platformio" in self.config:
293
+ default_envs = self.config["platformio"].get("default_envs", "").strip()
294
+ if default_envs:
295
+ # Can be comma-separated, take the first one
296
+ return default_envs.split(",")[0].strip()
297
+
298
+ # Fall back to first environment
299
+ envs = self.get_environments()
300
+ return envs[0] if envs else None
301
+
302
+ def get_src_dir(self) -> Optional[str]:
303
+ """
304
+ Get source directory override from [platformio] section.
305
+
306
+ Returns:
307
+ Source directory path relative to project root, or None if not specified
308
+
309
+ Example:
310
+ If [platformio] section has src_dir = examples/Blink, returns 'examples/Blink'
311
+ """
312
+ if "platformio" in self.config:
313
+ src_dir = self.config["platformio"].get("src_dir", "").strip()
314
+ # Remove inline comments (everything after ';')
315
+ if ";" in src_dir:
316
+ src_dir = src_dir.split(";")[0].strip()
317
+ return src_dir if src_dir else None
318
+ return None
319
+
320
+ def get_platformio_config(self, key: str, default: Optional[str] = None) -> Optional[str]:
321
+ """
322
+ Get a configuration value from the [platformio] section.
323
+
324
+ Args:
325
+ key: Configuration key to retrieve
326
+ default: Default value if key not found
327
+
328
+ Returns:
329
+ Configuration value or default
330
+
331
+ Example:
332
+ build_cache_dir = config.get_platformio_config('build_cache_dir', '.pio/build_cache')
333
+ """
334
+ if "platformio" in self.config:
335
+ value = self.config["platformio"].get(key, "").strip()
336
+ return value if value else default
337
+ return default
338
+
339
+ def get_board_overrides(self, env_name: str) -> Dict[str, str]:
340
+ """
341
+ Get board build and upload overrides from environment configuration.
342
+
343
+ Extracts all board_build.* and board_upload.* settings from the
344
+ environment configuration.
345
+
346
+ Args:
347
+ env_name: Name of the environment
348
+
349
+ Returns:
350
+ Dictionary of board override settings (e.g., {'flash_mode': 'dio', 'flash_size': '4MB'})
351
+
352
+ Example:
353
+ For board_build.flash_mode = dio and board_build.flash_size = 4MB
354
+ Returns: {'flash_mode': 'dio', 'flash_size': '4MB'}
355
+ """
356
+ env_config = self.get_env_config(env_name)
357
+ overrides = {}
358
+
359
+ for key, value in env_config.items():
360
+ if key.startswith("board_build."):
361
+ # Extract the override key (e.g., "flash_mode" from "board_build.flash_mode")
362
+ override_key = key.replace("board_build.", "")
363
+ overrides[override_key] = value
364
+ elif key.startswith("board_upload."):
365
+ # Also handle upload overrides
366
+ override_key = "upload_" + key.replace("board_upload.", "")
367
+ overrides[override_key] = value
368
+
369
+ return overrides
@@ -0,0 +1,88 @@
1
+ """
2
+ MCU specifications for various embedded platforms.
3
+
4
+ This module centralizes hardware specifications like flash size and RAM
5
+ for different microcontrollers, making it easier to maintain and extend.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from typing import Optional
10
+
11
+
12
+ @dataclass
13
+ class MCUSpec:
14
+ """Hardware specifications for a microcontroller."""
15
+
16
+ mcu_id: str
17
+ max_flash: int # Maximum flash size in bytes
18
+ max_ram: int # Maximum RAM size in bytes
19
+ bootloader_size: int = 0 # Bootloader size in bytes (subtracted from flash)
20
+
21
+ @property
22
+ def usable_flash(self) -> int:
23
+ """Get usable flash after accounting for bootloader."""
24
+ return self.max_flash - self.bootloader_size
25
+
26
+
27
+ # AVR MCU specifications
28
+ AVR_SPECS = {
29
+ "atmega328p": MCUSpec(
30
+ mcu_id="atmega328p",
31
+ max_flash=32768, # 32KB
32
+ max_ram=2048, # 2KB
33
+ bootloader_size=512, # 512B bootloader
34
+ ),
35
+ "atmega2560": MCUSpec(
36
+ mcu_id="atmega2560",
37
+ max_flash=262144, # 256KB
38
+ max_ram=8192, # 8KB
39
+ bootloader_size=8192, # 8KB bootloader
40
+ ),
41
+ "atmega32u4": MCUSpec(
42
+ mcu_id="atmega32u4",
43
+ max_flash=32768, # 32KB
44
+ max_ram=2560, # 2.5KB
45
+ bootloader_size=4096, # 4KB bootloader
46
+ ),
47
+ }
48
+
49
+
50
+ def get_mcu_spec(mcu_id: str) -> Optional[MCUSpec]:
51
+ """
52
+ Get MCU specifications by ID.
53
+
54
+ Args:
55
+ mcu_id: MCU identifier (e.g., 'atmega328p')
56
+
57
+ Returns:
58
+ MCUSpec if found, None otherwise
59
+ """
60
+ return AVR_SPECS.get(mcu_id.lower())
61
+
62
+
63
+ def get_max_flash(mcu_id: str) -> Optional[int]:
64
+ """
65
+ Get maximum usable flash for an MCU (after bootloader).
66
+
67
+ Args:
68
+ mcu_id: MCU identifier
69
+
70
+ Returns:
71
+ Usable flash size in bytes, or None if MCU not found
72
+ """
73
+ spec = get_mcu_spec(mcu_id)
74
+ return spec.usable_flash if spec else None
75
+
76
+
77
+ def get_max_ram(mcu_id: str) -> Optional[int]:
78
+ """
79
+ Get maximum RAM for an MCU.
80
+
81
+ Args:
82
+ mcu_id: MCU identifier
83
+
84
+ Returns:
85
+ RAM size in bytes, or None if MCU not found
86
+ """
87
+ spec = get_mcu_spec(mcu_id)
88
+ return spec.max_ram if spec else None
@@ -0,0 +1,42 @@
1
+ """
2
+ fbuild Daemon - Concurrent Deploy and Monitor Management
3
+
4
+ This package provides a singleton daemon for managing concurrent deploy and monitor
5
+ operations with proper locking and process tree tracking.
6
+ """
7
+
8
+ from fbuild.daemon.client import (
9
+ ensure_daemon_running,
10
+ get_daemon_status,
11
+ request_build,
12
+ request_deploy,
13
+ request_install_dependencies,
14
+ request_monitor,
15
+ stop_daemon,
16
+ )
17
+ from fbuild.daemon.messages import (
18
+ BuildRequest,
19
+ DaemonState,
20
+ DaemonStatus,
21
+ DeployRequest,
22
+ InstallDependenciesRequest,
23
+ MonitorRequest,
24
+ OperationType,
25
+ )
26
+
27
+ __all__ = [
28
+ "BuildRequest",
29
+ "DaemonState",
30
+ "DaemonStatus",
31
+ "DeployRequest",
32
+ "InstallDependenciesRequest",
33
+ "MonitorRequest",
34
+ "OperationType",
35
+ "ensure_daemon_running",
36
+ "get_daemon_status",
37
+ "request_build",
38
+ "request_deploy",
39
+ "request_install_dependencies",
40
+ "request_monitor",
41
+ "stop_daemon",
42
+ ]