weft 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 (49) hide show
  1. weft-0.1.0/.gitignore +77 -0
  2. weft-0.1.0/LICENSE +21 -0
  3. weft-0.1.0/PKG-INFO +515 -0
  4. weft-0.1.0/README.md +472 -0
  5. weft-0.1.0/docs/specifications/README.md +214 -0
  6. weft-0.1.0/pyproject.toml +141 -0
  7. weft-0.1.0/weft/__init__.py +25 -0
  8. weft-0.1.0/weft/__main__.py +6 -0
  9. weft-0.1.0/weft/_constants.py +428 -0
  10. weft-0.1.0/weft/cli.py +1208 -0
  11. weft-0.1.0/weft/cli_utils.py +119 -0
  12. weft-0.1.0/weft/commands/__init__.py +21 -0
  13. weft-0.1.0/weft/commands/dump.py +146 -0
  14. weft-0.1.0/weft/commands/handlers.py +94 -0
  15. weft-0.1.0/weft/commands/init.py +60 -0
  16. weft-0.1.0/weft/commands/interactive.py +298 -0
  17. weft-0.1.0/weft/commands/load.py +442 -0
  18. weft-0.1.0/weft/commands/queue.py +550 -0
  19. weft-0.1.0/weft/commands/result.py +362 -0
  20. weft-0.1.0/weft/commands/run.py +1539 -0
  21. weft-0.1.0/weft/commands/specs.py +166 -0
  22. weft-0.1.0/weft/commands/status.py +535 -0
  23. weft-0.1.0/weft/commands/tasks.py +218 -0
  24. weft-0.1.0/weft/commands/tidy.py +23 -0
  25. weft-0.1.0/weft/commands/validate_taskspec.py +94 -0
  26. weft-0.1.0/weft/commands/worker.py +281 -0
  27. weft-0.1.0/weft/config.py +0 -0
  28. weft-0.1.0/weft/context.py +305 -0
  29. weft-0.1.0/weft/core/__init__.py +57 -0
  30. weft-0.1.0/weft/core/callable.py +135 -0
  31. weft-0.1.0/weft/core/launcher.py +71 -0
  32. weft-0.1.0/weft/core/manager.py +798 -0
  33. weft-0.1.0/weft/core/resource_monitor.py +356 -0
  34. weft-0.1.0/weft/core/targets.py +136 -0
  35. weft-0.1.0/weft/core/tasks/__init__.py +21 -0
  36. weft-0.1.0/weft/core/tasks/base.py +1090 -0
  37. weft-0.1.0/weft/core/tasks/consumer.py +597 -0
  38. weft-0.1.0/weft/core/tasks/debugger.py +95 -0
  39. weft-0.1.0/weft/core/tasks/interactive.py +399 -0
  40. weft-0.1.0/weft/core/tasks/monitor.py +87 -0
  41. weft-0.1.0/weft/core/tasks/multiqueue_watcher.py +454 -0
  42. weft-0.1.0/weft/core/tasks/observer.py +97 -0
  43. weft-0.1.0/weft/core/tasks/runner.py +367 -0
  44. weft-0.1.0/weft/core/tasks/sessions.py +181 -0
  45. weft-0.1.0/weft/core/taskspec.py +1081 -0
  46. weft-0.1.0/weft/helpers.py +585 -0
  47. weft-0.1.0/weft/manager_process.py +37 -0
  48. weft-0.1.0/weft/shell/__init__.py +34 -0
  49. weft-0.1.0/weft/shell/known_interpreters.py +60 -0
weft-0.1.0/.gitignore ADDED
@@ -0,0 +1,77 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ MANIFEST
23
+
24
+ # Virtual environments
25
+ venv/
26
+ ENV/
27
+ env/
28
+ .venv
29
+
30
+ # IDEs
31
+ .vscode/
32
+ .idea/
33
+ *.swp
34
+ *.swo
35
+ *~
36
+
37
+ # Testing
38
+ .coverage
39
+ .coverage.*
40
+ .pytest_cache/
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .mypy_cache/
45
+ .dmypy.json
46
+ dmypy.json
47
+ .ruff_cache/
48
+ .ruff/
49
+ .pytest_cache/
50
+
51
+ # SimpleBroker specific
52
+ *.db-shm
53
+ *.db-wal
54
+ .broker.db*
55
+ test.db
56
+ benchmark_pragma.py
57
+
58
+ # OS
59
+ .DS_Store
60
+ Thumbs.db
61
+
62
+ # Temporary files
63
+ *.tmp
64
+ *.bak
65
+ *.log
66
+
67
+ # Multi-agent
68
+ .claude
69
+ .mcp.json
70
+ agent_history/
71
+ .broker.db
72
+ .broker.db-shm
73
+ .broker.db-wal
74
+ *comments*.md
75
+ .code/
76
+ # This is in context for agents but we don't want it to check it in here
77
+ simplebroker/
weft-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Van Lindberg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
weft-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,515 @@
1
+ Metadata-Version: 2.4
2
+ Name: weft
3
+ Version: 0.1.0
4
+ Summary: A lightweight workflow execution framework
5
+ Project-URL: Homepage, https://github.com/VanL/weft
6
+ Project-URL: Documentation, https://github.com/VanL/weft#readme
7
+ Project-URL: Repository, https://github.com/VanL/weft.git
8
+ Project-URL: Issues, https://github.com/VanL/weft/issues
9
+ Author-email: Van Lindberg <van@modelmonster.ai>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: automation,orchestration,task-execution,workflow
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: System :: Distributed Computing
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: aider-chat>=0.85.2
26
+ Requires-Dist: llm>=0.26
27
+ Requires-Dist: psutil>=7.0.0
28
+ Requires-Dist: pydantic>=2.0.0
29
+ Requires-Dist: rich>=14.0.0
30
+ Requires-Dist: setproctitle>=1.3.7
31
+ Requires-Dist: simplebroker>=2.5.1
32
+ Requires-Dist: typer>=0.16.0
33
+ Requires-Dist: typing-extensions>=4.0.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: mypy>=1.0; extra == 'dev'
36
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
37
+ Requires-Dist: pytest-timeout>=2.4.0; extra == 'dev'
38
+ Requires-Dist: pytest-xdist>=3.0; extra == 'dev'
39
+ Requires-Dist: pytest>=7.0; extra == 'dev'
40
+ Requires-Dist: ruff>=0.12; extra == 'dev'
41
+ Requires-Dist: types-psutil>=5.9.5; extra == 'dev'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # Weft
45
+
46
+ *A durable task execution system. Persistent workers, multiprocess isolation, comprehensive observability.*
47
+
48
+ ```bash
49
+ $ weft run echo "hello world"
50
+ hello world
51
+
52
+ $ weft run --spec task.json
53
+ # streams task output and returns when complete
54
+
55
+ $ weft status
56
+ System: OK
57
+ ```
58
+
59
+ Weft is a queue-based task execution system focused on enabling interaction between AI agents, user-provided functions, and existing CLI tools. It combines the simplicity of direct command execution with the power of durable task queues, multiprocess isolation, and comprehensive state tracking.
60
+
61
+
62
+ ## Quick Start
63
+
64
+ ```bash
65
+ # Initialize project
66
+ $ weft init
67
+ Initialized weft in .weft/
68
+
69
+ # Run a simple command
70
+ $ weft run echo "hello world"
71
+ hello world
72
+
73
+ # Run with resource limits
74
+ $ weft run --memory 100 --cpu 50 python script.py
75
+
76
+ # Run and wait for completion
77
+ $ weft run --wait --timeout 30 ./long-task.sh
78
+
79
+ # Run a saved task spec (from .weft/tasks/)
80
+ $ weft run --spec data-cleanup
81
+
82
+ # Run a pipeline spec (from .weft/pipelines/)
83
+ $ weft run --pipeline etl-job
84
+
85
+ # Run a Python function
86
+ $ weft run --function mymodule:process_data --arg input.csv --kw mode=fast
87
+
88
+ # Check system status
89
+ $ weft status
90
+ System: OK
91
+
92
+ # Get task result
93
+ $ weft result 1234567890
94
+ {"status": "completed", "return_code": 0, "output": "..."}
95
+ ```
96
+
97
+ ## Core Concepts
98
+
99
+ ### Project Context
100
+
101
+ Weft uses `.weft/` directories for project isolation, similar to git repositories:
102
+
103
+ ```text
104
+ myproject/
105
+ .weft/
106
+ broker.db # SimpleBroker database
107
+ tasks/ # Saved task specs
108
+ pipelines/ # Saved pipeline specs
109
+ autostart/ # Autostart manifests (lifecycle + defaults)
110
+ outputs/ # Large output spillover
111
+ logs/ # Centralized logging
112
+ ...
113
+ ```
114
+
115
+ Run `weft` commands from anywhere in the project tree - it searches upward to find `.weft/`.
116
+
117
+ ### Task IDs (TIDs)
118
+
119
+ Every task receives a unique 64-bit SimpleBroker timestamp (hybrid microseconds + logical counter), typically 19 digits:
120
+
121
+ - **Full TID**: `1837025672140161024` (Unique task ID)
122
+ - **Short TID**: `0161024` (last 10 digits for convenience)
123
+ - Used for correlation across queues and process titles
124
+ - Monotonic within a context, format-compatible with time.time_ns()
125
+ - The spawn-request message ID becomes the task TID for the full lifecycle
126
+
127
+ ### Queue Structure
128
+
129
+ Each task gets its own queues:
130
+
131
+ ```
132
+ T{tid}.inbox # Work messages to process
133
+ T{tid}.reserved # Messages being processed (reservation pattern)
134
+ T{tid}.outbox # Results and output
135
+ T{tid}.ctrl_in # Control commands (STOP, STATUS, PING)
136
+ T{tid}.ctrl_out # Status responses
137
+
138
+ weft.log.tasks # Global state log (all tasks)
139
+ weft.spawn.requests # Task spawn requests to manager
140
+ weft.state.workers # Manager liveness tracking (runtime state)
141
+ weft.state.tid_mappings # Short->full TID mappings (runtime state)
142
+ weft.state.streaming # Active streaming sessions (runtime state)
143
+ ```
144
+
145
+ Queues under `weft.state.*` are runtime-only and excluded from dumps by default.
146
+
147
+ ### Reservation Pattern
148
+
149
+ Weft implements inbox -> reserved -> outbox flow for reliable message processing:
150
+
151
+ 1. **Reserve**: Move message from inbox to reserved
152
+ 2. **Process**: Execute work while message is in reserved
153
+ 3. **Complete**: Write output to outbox, delete from reserved (or apply policy)
154
+
155
+ If a task crashes mid-work, the message remains in reserved for manual recovery or explicit requeue.
156
+
157
+ **Idempotency guidance**
158
+ - Single-message tasks may use `tid` as an idempotency key.
159
+ - Multi-message tasks should use the inbox/reserved message ID (timestamp).
160
+ - Recommended composite key: `tid:message_id`.
161
+
162
+ Configurable policies (`keep`, `requeue`, `clear`) control reserved queue behavior on errors.
163
+
164
+ ### Managers
165
+
166
+ Persistent worker processes that:
167
+ - Monitor `weft.spawn.requests` for new tasks
168
+ - Launch child task processes
169
+ - Track process lifecycle
170
+ - Auto-terminate after idle timeout (default 600 seconds)
171
+ - Launch autostart tasks on boot
172
+
173
+ ### Process Titles
174
+
175
+ Tasks update their process title for observability:
176
+
177
+ ```bash
178
+ $ ps aux | grep weft
179
+ weft-proj-0161024:mytask:running
180
+ weft-proj-0161025:worker:completed
181
+ ```
182
+
183
+ Format: `weft-{context_short}-{short_tid}:{name}:{status}[:details]`
184
+
185
+ ## Command Reference
186
+
187
+ ### Project Management
188
+
189
+ ```bash
190
+ # Initialize new project
191
+ weft init [--autostart/--no-autostart]
192
+
193
+ # Show system status
194
+ weft status [--json]
195
+
196
+ # Task detail view
197
+ weft task status TID [--process] [--watch] [--json]
198
+
199
+ # List tasks
200
+ weft list [--stats] [--status STATUS] [--json]
201
+
202
+ # System maintenance
203
+ weft system tidy
204
+ weft system dump -o FILE
205
+ weft system load -i FILE
206
+ ```
207
+
208
+ ### Task Execution
209
+
210
+ ```bash
211
+ # Run command
212
+ weft run COMMAND [args...]
213
+ weft run --spec NAME|PATH
214
+ weft run --pipeline NAME|PATH
215
+ weft run --function module:func [--arg VALUE] [--kw KEY=VALUE]
216
+
217
+ # Execution options
218
+ --wait # Wait for completion
219
+ --timeout N # Timeout in seconds
220
+ --memory N # Memory limit in MB
221
+ --cpu N # CPU limit (percentage)
222
+ --env KEY=VALUE # Environment variable
223
+ --autostart/--no-autostart # Enable/disable autostart manifests
224
+ --arg VALUE # Positional arg for --function (repeatable)
225
+ --kw KEY=VALUE # Keyword arg for --function (repeatable)
226
+
227
+ # Get results
228
+ weft result TID [--timeout N] [--stream] [--json]
229
+ weft result --all [--peek]
230
+ ```
231
+
232
+ ### Queue Operations
233
+
234
+ ```bash
235
+ # Direct queue access
236
+ weft queue read QUEUE [--json] [--all]
237
+ weft queue write QUEUE MESSAGE
238
+ weft queue peek QUEUE [--json] [--all]
239
+ weft queue move SOURCE DEST [--all]
240
+ weft queue list [--pattern PATTERN]
241
+ weft queue watch QUEUE [--json] [--peek]
242
+
243
+ # Broadcast and aliases
244
+ weft queue broadcast MESSAGE [--pattern GLOB]
245
+ weft queue alias add ALIAS TARGET
246
+ weft queue alias remove ALIAS
247
+ weft queue alias list [--target QUEUE]
248
+ ```
249
+
250
+ ### Autostart Tasks
251
+
252
+ Manifest files in `.weft/autostart/*.json` are automatically launched when the manager starts. Autostart targets must reference stored task specs or pipelines (no inline TaskSpecs).
253
+
254
+ ```bash
255
+ # Save a task spec
256
+ $ cat > .weft/tasks/queue-monitor.json <<EOF
257
+ {
258
+ "name": "queue-monitor",
259
+ "spec": {
260
+ "type": "function",
261
+ "function_target": "monitoring.watch_queues",
262
+ "timeout": null
263
+ }
264
+ }
265
+ EOF
266
+
267
+ # Create autostart manifest
268
+ $ cat > .weft/autostart/monitor.json <<EOF
269
+ {
270
+ "name": "queue-monitor",
271
+ "target": { "type": "task", "name": "queue-monitor" },
272
+ "policy": { "mode": "ensure" }
273
+ }
274
+ EOF
275
+
276
+ # Next manager start will launch it automatically
277
+ $ weft run echo "trigger manager"
278
+ ```
279
+
280
+ Control autostart behavior:
281
+ - `weft init --no-autostart` - Skip autostart directory creation
282
+ - `weft run --no-autostart` - Skip launching autostart tasks
283
+ - `WEFT_AUTOSTART_TASKS=false` - Disable via environment
284
+
285
+ ## TaskSpec Format
286
+
287
+ Tasks are configured with JSON specifications:
288
+
289
+ ```json
290
+ {
291
+ "name": "process-data",
292
+ "spec": {
293
+ "type": "command",
294
+ "process_target": "python",
295
+ "args": ["process.py"],
296
+ "timeout": 300,
297
+ "limits": {
298
+ "memory_mb": 512,
299
+ "cpu_percent": 75,
300
+ "max_fds": 100
301
+ },
302
+ "env": {"LOG_LEVEL": "debug"},
303
+ "stream_output": true,
304
+ "cleanup_on_exit": true
305
+ }
306
+ }
307
+ ```
308
+
309
+ **Spec fields:**
310
+ - `type`: `"command"` or `"function"`
311
+ - `process_target`: Command executable (for commands)
312
+ - `function_target`: Module:function string (for functions)
313
+ - `args`: Additional argv items (appended for commands, *args for functions)
314
+ - `keyword_args`: Keyword args for function targets
315
+ - `timeout`: Seconds (null for no timeout)
316
+ - `limits`: Resource constraints
317
+ - `env`: Environment variables
318
+ - `stream_output`: Enable output streaming
319
+ - `cleanup_on_exit`: Delete empty queues on completion (outbox retained until consumed)
320
+ - `weft_context`: Runtime-expanded project context (set by Manager)
321
+
322
+ **Runtime expansion:**
323
+ - TaskSpec templates omit `tid`, `io`, `state`, and `spec.weft_context`.
324
+ - The Manager expands these at spawn time. The spawn-request message ID becomes the task TID.
325
+
326
+ ## State Tracking
327
+
328
+ All state changes are logged to `weft.log.tasks`:
329
+
330
+ ```json
331
+ {
332
+ "event": "work_completed",
333
+ "tid": "1837025672140161024",
334
+ "tid_short": "0161024",
335
+ "status": "completed",
336
+ "timestamp": 1705329000123456789,
337
+ "taskspec": {...},
338
+ "task_pid": 12345,
339
+ "return_code": 0
340
+ }
341
+ ```
342
+
343
+ Events include:
344
+ - `task_initialized` - Task startup
345
+ - `work_started` - Processing begins
346
+ - `work_completed` - Success
347
+ - `work_failed` - Execution error
348
+ - `work_timeout` - Timeout exceeded
349
+ - `work_limit_violation` - Resource limit hit
350
+ - `control_*` - Control message handling
351
+
352
+
353
+ ## Resource Monitoring
354
+
355
+ Tasks track resource usage with psutil:
356
+
357
+ ```python
358
+ # Resource limits in TaskSpec
359
+ "limits": {
360
+ "memory_mb": 512, # Max memory
361
+ "cpu_percent": 75, # Max CPU (0-100)
362
+ "max_fds": 100, # Max file descriptors
363
+ "max_connections": 50 # Max network connections
364
+ }
365
+ ```
366
+
367
+ Violations trigger `work_limit_violation` events and task termination.
368
+
369
+ ## Exit Codes
370
+
371
+ ```bash
372
+ 0 - Success
373
+ 1 - General error
374
+ 2 - Not found (task, queue, spec)
375
+ 124 - Timeout
376
+ ```
377
+
378
+ ## Common Patterns
379
+
380
+ ### Background Processing
381
+
382
+ ```bash
383
+ # Launch task without waiting
384
+ $ weft run ./background-job.sh
385
+
386
+ # Check status later
387
+ $ weft status
388
+ Tasks: 1 running
389
+
390
+ # Get result when ready
391
+ $ weft result <tid>
392
+ ```
393
+
394
+ ### Pipeline Processing
395
+
396
+ ```bash
397
+ # Task chain via queues
398
+ $ weft run --spec extract.json # Writes to "raw.data"
399
+ $ weft run --spec transform.json # Reads "raw.data", writes "clean.data"
400
+ $ weft run --spec load.json # Reads "clean.data"
401
+
402
+ # Or use queue operations directly
403
+ $ weft queue write input.queue "data.csv"
404
+ $ weft run --spec processor.json
405
+ $ weft queue read output.queue
406
+ ```
407
+
408
+ ### Persistent Watchers
409
+
410
+ ```bash
411
+ # Save task spec
412
+ $ cat > .weft/tasks/file-watcher.json <<EOF
413
+ {
414
+ "name": "file-watcher",
415
+ "spec": {
416
+ "type": "function",
417
+ "function_target": "watchers.watch_directory",
418
+ "timeout": null
419
+ }
420
+ }
421
+ EOF
422
+
423
+ # Create autostart manifest
424
+ $ cat > .weft/autostart/file-watcher.json <<EOF
425
+ {
426
+ "name": "file-watcher",
427
+ "target": { "type": "task", "name": "file-watcher" },
428
+ "policy": { "mode": "ensure" }
429
+ }
430
+ EOF
431
+
432
+ # Starts automatically with manager
433
+ $ weft run echo "start"
434
+
435
+ # Verify running
436
+ $ ps aux | grep weft
437
+ weft-proj-1234567:file-watcher:running
438
+ ```
439
+
440
+ ### Resource-Constrained Execution
441
+
442
+ ```bash
443
+ # Limit memory and CPU
444
+ $ weft run --memory 100 --cpu 25 ./memory-intensive.py
445
+
446
+ # With timeout
447
+ $ weft run --timeout 60 --memory 500 ./task.sh
448
+ ```
449
+
450
+ ## Architecture
451
+
452
+ ### Components
453
+
454
+ - **TaskSpec**: Validated task configuration with partial immutability
455
+ - **Manager**: Persistent worker process for task spawning
456
+ - **Consumer**: Task executor with reservation pattern
457
+ - **BaseTask**: Abstract base providing queue wiring and state tracking
458
+ - **TaskRunner**: Multiprocess execution wrapper with timeout/monitoring
459
+ - **ResourceMonitor**: psutil-based resource tracking and limit enforcement
460
+
461
+ ### Task Lifecycle
462
+
463
+ ```
464
+ 1. CLI: weft run COMMAND
465
+ 2. Manager auto-started if needed
466
+ 3. TaskSpec template created and validated
467
+ 4. Spawn request written to weft.spawn.requests (message ID becomes TID)
468
+ 5. Manager expands TaskSpec and spawns Consumer process
469
+ 6. Consumer reserves work from inbox
470
+ 7. TaskRunner executes in child process
471
+ 8. Output written to outbox
472
+ 9. State logged to weft.log.tasks
473
+ 10. CLI retrieves result
474
+ ```
475
+
476
+ ### Multiprocess Isolation
477
+
478
+ Tasks execute in separate processes using `multiprocessing.spawn`:
479
+ - Clean process environment
480
+ - No inherited state from parent
481
+ - Resource monitoring per process
482
+ - Crash isolation
483
+ - Timeout enforcement
484
+
485
+ ## Development
486
+
487
+ ```bash
488
+ # Install development dependencies
489
+ uv sync --all-extras
490
+
491
+ # Run tests
492
+ uv run pytest
493
+ uv run pytest tests/tasks/
494
+ uv run pytest tests/cli/
495
+
496
+ # Linting
497
+ uv run ruff check weft tests
498
+ uv run ruff format weft tests
499
+ uv run mypy weft
500
+
501
+ # Build
502
+ uv build
503
+ ```
504
+
505
+ ## Configuration
506
+
507
+ Environment variables:
508
+
509
+ - `WEFT_MANAGER_LIFETIME_TIMEOUT` - Manager idle timeout (default: 600s)
510
+ - `WEFT_MANAGER_REUSE_ENABLED` - Keep manager running (default: true)
511
+ - `WEFT_AUTOSTART_TASKS` - Enable autostart (default: true)
512
+
513
+ ## License
514
+
515
+ MIT