python-dmon 0.3.1__tar.gz → 0.5.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Atomie CHEN
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.
@@ -0,0 +1,287 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-dmon
3
+ Version: 0.5.0
4
+ Summary: A lightweight, cross-platform process manager for background tasks, local service stacks, and partial recovery.
5
+ Keywords: dmon,process manager,daemon,background,supervisor,local development,readiness,service management,coding agents
6
+ Author: Atomie CHEN
7
+ Author-email: Atomie CHEN <atomic_cwh@163.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Requires-Dist: colorama>=0.4.6
11
+ Requires-Dist: psutil>=7.1.0
12
+ Requires-Dist: python-dotenv>=1.0.1,<1.1
13
+ Requires-Dist: pyyaml>=6.0.3
14
+ Requires-Dist: termcolor>=2.4.0
15
+ Requires-Dist: tomli>=2.2.1 ; python_full_version < '3.11'
16
+ Requires-Python: >=3.8
17
+ Project-URL: Bug Tracker, https://github.com/atomiechen/dmon/issues
18
+ Project-URL: Changelog, https://github.com/atomiechen/dmon/blob/main/CHANGELOG.md
19
+ Project-URL: Homepage, https://github.com/atomiechen/dmon
20
+ Description-Content-Type: text/markdown
21
+
22
+ # dmon
23
+
24
+ ![dmon — The local process manager for developers and coding agents.](https://raw.githubusercontent.com/atomiechen/dmon/main/assets/banner.svg)
25
+
26
+
27
+ [![GitHub](https://img.shields.io/badge/github-dmon-blue?logo=github)](https://github.com/atomiechen/dmon)
28
+ [![PyPI](https://img.shields.io/pypi/v/python--dmon?logo=pypi&logoColor=white)](https://pypi.org/project/python-dmon/)
29
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/atomiechen/dmon)
30
+
31
+
32
+ A lightweight, cross-platform process manager for local services and development workflows.
33
+ Run any command as a background *task*, or supervise a stack with readiness checks
34
+ and repair failed members while healthy services keep running. Logging and log
35
+ rotation are built in.
36
+
37
+ For developers and coding agents, dmon records process identities and exposes
38
+ JSON status so later sessions can inspect and reuse existing services.
39
+ See [coding-agent setup](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md).
40
+
41
+ Shipped as the CLI tool `dmon`.
42
+
43
+
44
+ ## Features
45
+
46
+ - 🖥️ **Cross-platform:** Works on Linux, macOS, and Windows.
47
+ - ⚡ **Lightweight:** No daemon service or container runtime required.
48
+ - 🧩 **Flexible tasks:** Tasks can be configured in `pyproject.toml` or `dmon.yaml`; or run ad-hoc commands directly.
49
+ - 🔗 **Supervised stacks:** Start dependent tasks in order, wait for HTTP, TCP,
50
+ or command readiness, and report runtime degradation.
51
+ - 🌙 **Foreground or detached:** Keep a stack attached for development, or run
52
+ it under a recoverable background supervisor with `dmon stack up -d` and
53
+ `dmon stack down`.
54
+ - ⏱️ **Reusable readiness:** Wait for configured tasks or direct HTTP, TCP, and
55
+ command probes from scripts and deployment workflows.
56
+ - 🪵 **Logging & log rotation:** Keep active log files manageable, with optional archive retention limits.
57
+
58
+
59
+ ## Demos
60
+
61
+ The demos below cover everyday task management and supervised stacks. Both use this `dmon.yaml` and a small [heartbeat program](https://github.com/atomiechen/dmon/blob/main/scripts/recording/service.py):
62
+
63
+ ```yaml
64
+ tasks:
65
+ api: [python, -u, service.py, api]
66
+ worker: [python, -u, service.py, worker]
67
+ stacks:
68
+ dev: [api, worker]
69
+ ```
70
+
71
+ **Everyday tasks.** Run a command directly with `run` (no configuration needed),
72
+ then use `start`, `status`, and `stop` for a configured task. `exec` runs a
73
+ configured task in the foreground; Ctrl-C ends it. In this clip, `stop --all`
74
+ stops the sole ad-hoc task before the configured API is started.
75
+
76
+ ![Run an ad-hoc command, manage a configured task, and execute a task in the foreground](https://github.com/user-attachments/assets/2b60acab-d56d-43c0-a44b-f602243c7105)
77
+
78
+
79
+ **Keep healthy services running.** Start a stack, deliberately stop its worker,
80
+ and repair that member. The API keeps the same PID and its counter continues;
81
+ `stack down` stops both members. The lower panes show real files and live logs.
82
+
83
+ ![Start a stack, repair only its stopped worker, and clean up both members](https://github.com/user-attachments/assets/58d1a9f9-91d8-4096-9dca-ac53815194c8)
84
+
85
+
86
+
87
+ ## Installation
88
+
89
+ `dmon` requires Python 3.8+ and is available as [`python-dmon`](https://pypi.org/project/python-dmon/) on PyPI.
90
+ Managed commands can use any language.
91
+
92
+ ```sh
93
+ pip install python-dmon
94
+ ```
95
+
96
+ We recommend installing into an isolated environment, e.g., with `uv` / `pipx`:
97
+
98
+ ```sh
99
+ # Install globally with uv tool
100
+ uv tool install python-dmon
101
+
102
+ # Or with pipx
103
+ pipx install python-dmon
104
+
105
+ # Add as a dev dependency in your project
106
+ uv add --dev python-dmon
107
+ ```
108
+
109
+ You can also run dmon without installing it permanently:
110
+
111
+ ```sh
112
+ # With uvx (uv tool run)
113
+ uvx python-dmon
114
+
115
+ # Or with pipx
116
+ pipx run python-dmon
117
+ ```
118
+
119
+ To get the latest features, install from source:
120
+
121
+ ```sh
122
+ pip install git+https://github.com/atomiechen/dmon.git
123
+ ```
124
+
125
+ For coding agents, see the [setup instructions](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md) and the
126
+ [portable skill](https://github.com/atomiechen/dmon/blob/main/skills/dmon/SKILL.md). The skill is installed separately from the CLI.
127
+
128
+ ## Getting Started
129
+
130
+ ### Prepare Configuration
131
+
132
+ Create a `dmon.yaml` file:
133
+
134
+ ```yaml
135
+ tasks:
136
+ app: ["python", "-u", "server.py"] # exec form
137
+ # app: "python -u server.py" # or a shell string
138
+ ```
139
+
140
+ Without `--config`, dmon searches the current directory and its parents for
141
+ `dmon.yaml`, `dmon.yml`, or `pyproject.toml`. See the
142
+ [configuration reference](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md)
143
+ for TOML, environments, paths, defaults, and log rotation.
144
+
145
+ ### Run tasks
146
+
147
+ ```sh
148
+ dmon start app # Start in the background
149
+ dmon stop app # Stop the recorded process tree
150
+ dmon restart app
151
+ dmon status app
152
+ dmon exec app # Run in this terminal; Ctrl-C ends it
153
+ ```
154
+
155
+ `exec` runs one configured command directly, without registering a managed
156
+ background task. Use `start` to keep it discoverable through `status` and `list`.
157
+ You can pass multiple names to the other task commands. Multi-task `start` is
158
+ best-effort: successful tasks stay running if another fails. For related
159
+ services with ordered startup and rollback, use a stack.
160
+
161
+ ### Run a stack
162
+
163
+ ```yaml
164
+ tasks:
165
+ api:
166
+ cmd: [python, api.py]
167
+ ready:
168
+ http: http://127.0.0.1:8000/health
169
+ worker:
170
+ cmd: [python, worker.py]
171
+ depends_on: [api]
172
+ stacks:
173
+ dev: [api, worker]
174
+ ```
175
+
176
+ ```sh
177
+ dmon stack up dev # Foreground; Ctrl-C stops the stack
178
+ # Or keep it running under a background supervisor:
179
+ dmon stack up -d dev
180
+ dmon stack status dev
181
+ dmon stack logs --tail 100 dev
182
+ dmon stack repair dev worker --format json # Replace an exited member
183
+ dmon stack down dev
184
+ ```
185
+
186
+ Stack startup waits for readiness and rolls back tasks it started if startup
187
+ fails. After startup, an exited member degrades the stack while healthy peers
188
+ keep running. `repair` replaces that member through its live supervisor, so
189
+ later `down` includes the replacement. It reuses the supervisor's launch
190
+ configuration and environment; separately running `dmon start worker` does not
191
+ repair stack membership.
192
+
193
+ See [task and stack lifecycle](https://github.com/atomiechen/dmon/blob/main/docs/ownership.md)
194
+ for fail-fast behavior, detached restart, recovery, and ownership limits. Docker
195
+ Compose is still appropriate when container behavior itself must be tested.
196
+
197
+ ### Wait for readiness
198
+
199
+ `dmon wait` checks readiness without starting or stopping anything. Configured
200
+ tasks need a `ready` probe and must already be managed by `start` or a stack:
201
+
202
+ ```sh
203
+ dmon wait api
204
+ dmon wait api --timeout 60 --interval 0.5
205
+
206
+ # Direct probes need no configuration
207
+ dmon wait --http http://127.0.0.1:8000/health
208
+ dmon wait --tcp 127.0.0.1:5432
209
+ dmon wait --timeout 30 --command -- python healthcheck.py --verbose
210
+ ```
211
+
212
+ Put dmon options before `--command`; the optional second `--` marks the child
213
+ command. See [readiness configuration](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md#readiness)
214
+ for probe options, listener ownership checks, and wait results.
215
+
216
+ ### Run an ad-hoc command
217
+
218
+ ```sh
219
+ dmon run --name myserver python -u server.py
220
+ dmon run --name timer -- python -c 'import time; time.sleep(30)'
221
+ dmon run --shell echo "Hello World"
222
+ dmon run --cwd /path/to/script bash myscript.sh
223
+ ```
224
+
225
+ No configuration is needed. Without `--name`, dmon uses the fixed name
226
+ `default_run` to prevent duplicate runs.
227
+
228
+ ### List recorded tasks and their status
229
+
230
+ ```sh
231
+ dmon list
232
+ dmon status app --format json
233
+ dmon list --format json
234
+ dmon stack status dev --format json
235
+ dmon stack list --format json
236
+ dmon wait api --format json
237
+ ```
238
+
239
+ JSON is written only to stdout; actionable diagnostics remain on stderr. The
240
+ payload has a top-level `ok` field and a `tasks`, `stacks`, or `waits` array.
241
+ Inspection results contain `name`, `ok`, `error`, and an optional `snapshot`;
242
+ wait results contain the target, outcome, reason, elapsed time, and attempt
243
+ count. Existing exit-code semantics are unchanged. Interactive and streaming
244
+ commands do not offer JSON output.
245
+
246
+ ### Python API
247
+
248
+ The same task lifecycle and inspection logic is available without parsing CLI
249
+ output:
250
+
251
+ ```python
252
+ from dmon import Dmon
253
+
254
+ client = Dmon(config="dmon.yaml")
255
+ started = client.start("app")
256
+ task = client.status("app")
257
+ stacks = client.list_stacks()
258
+ client.stop("app")
259
+ ```
260
+
261
+ `client.wait("app", timeout=30)` also checks readiness when `app` has a
262
+ configured `ready` probe. API calls are synchronous and silent.
263
+ `start`, `stop`, and `restart` return an immutable `BatchResult`; `status`
264
+ and `stack_status` return `TaskResult` and `StackResult`. List and wait methods
265
+ return tuples of their corresponding result types. Expected runtime states such
266
+ as missing or exited metadata are results, while invalid configuration raises
267
+ `DmonConfigError`. The initial API intentionally does not start a supervised
268
+ stack or create implicit background threads.
269
+
270
+ ## Documentation
271
+
272
+ Start with the [documentation index](https://github.com/atomiechen/dmon/blob/main/docs/README.md):
273
+
274
+ - [Configuration](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md): task selection, YAML/TOML, environments, readiness, and logs.
275
+ - [Task and stack lifecycle](https://github.com/atomiechen/dmon/blob/main/docs/ownership.md): startup, repair, recovery, and process ownership.
276
+ - [Coding-agent setup](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md): install the workflow and continue across sessions.
277
+
278
+ ## Development
279
+
280
+ See [CONTRIBUTING.md](https://github.com/atomiechen/dmon/blob/main/CONTRIBUTING.md) for architecture, behavioral contracts,
281
+ validation, and the release workflow. Process, signal, log-rotation, and stack
282
+ changes must also pass the reproducible [manual test lab](https://github.com/atomiechen/dmon/blob/main/tests/manual/README.md).
283
+
284
+
285
+ ## License
286
+
287
+ [dmon](https://github.com/atomiechen/dmon) © 2025 by [Atomie CHEN](https://github.com/atomiechen) is licensed under the [MIT License](https://github.com/atomiechen/dmon/blob/main/LICENSE).
@@ -0,0 +1,266 @@
1
+ # dmon
2
+
3
+ ![dmon — The local process manager for developers and coding agents.](https://raw.githubusercontent.com/atomiechen/dmon/main/assets/banner.svg)
4
+
5
+
6
+ [![GitHub](https://img.shields.io/badge/github-dmon-blue?logo=github)](https://github.com/atomiechen/dmon)
7
+ [![PyPI](https://img.shields.io/pypi/v/python--dmon?logo=pypi&logoColor=white)](https://pypi.org/project/python-dmon/)
8
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/atomiechen/dmon)
9
+
10
+
11
+ A lightweight, cross-platform process manager for local services and development workflows.
12
+ Run any command as a background *task*, or supervise a stack with readiness checks
13
+ and repair failed members while healthy services keep running. Logging and log
14
+ rotation are built in.
15
+
16
+ For developers and coding agents, dmon records process identities and exposes
17
+ JSON status so later sessions can inspect and reuse existing services.
18
+ See [coding-agent setup](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md).
19
+
20
+ Shipped as the CLI tool `dmon`.
21
+
22
+
23
+ ## Features
24
+
25
+ - 🖥️ **Cross-platform:** Works on Linux, macOS, and Windows.
26
+ - ⚡ **Lightweight:** No daemon service or container runtime required.
27
+ - 🧩 **Flexible tasks:** Tasks can be configured in `pyproject.toml` or `dmon.yaml`; or run ad-hoc commands directly.
28
+ - 🔗 **Supervised stacks:** Start dependent tasks in order, wait for HTTP, TCP,
29
+ or command readiness, and report runtime degradation.
30
+ - 🌙 **Foreground or detached:** Keep a stack attached for development, or run
31
+ it under a recoverable background supervisor with `dmon stack up -d` and
32
+ `dmon stack down`.
33
+ - ⏱️ **Reusable readiness:** Wait for configured tasks or direct HTTP, TCP, and
34
+ command probes from scripts and deployment workflows.
35
+ - 🪵 **Logging & log rotation:** Keep active log files manageable, with optional archive retention limits.
36
+
37
+
38
+ ## Demos
39
+
40
+ The demos below cover everyday task management and supervised stacks. Both use this `dmon.yaml` and a small [heartbeat program](https://github.com/atomiechen/dmon/blob/main/scripts/recording/service.py):
41
+
42
+ ```yaml
43
+ tasks:
44
+ api: [python, -u, service.py, api]
45
+ worker: [python, -u, service.py, worker]
46
+ stacks:
47
+ dev: [api, worker]
48
+ ```
49
+
50
+ **Everyday tasks.** Run a command directly with `run` (no configuration needed),
51
+ then use `start`, `status`, and `stop` for a configured task. `exec` runs a
52
+ configured task in the foreground; Ctrl-C ends it. In this clip, `stop --all`
53
+ stops the sole ad-hoc task before the configured API is started.
54
+
55
+ ![Run an ad-hoc command, manage a configured task, and execute a task in the foreground](https://github.com/user-attachments/assets/2b60acab-d56d-43c0-a44b-f602243c7105)
56
+
57
+
58
+ **Keep healthy services running.** Start a stack, deliberately stop its worker,
59
+ and repair that member. The API keeps the same PID and its counter continues;
60
+ `stack down` stops both members. The lower panes show real files and live logs.
61
+
62
+ ![Start a stack, repair only its stopped worker, and clean up both members](https://github.com/user-attachments/assets/58d1a9f9-91d8-4096-9dca-ac53815194c8)
63
+
64
+
65
+
66
+ ## Installation
67
+
68
+ `dmon` requires Python 3.8+ and is available as [`python-dmon`](https://pypi.org/project/python-dmon/) on PyPI.
69
+ Managed commands can use any language.
70
+
71
+ ```sh
72
+ pip install python-dmon
73
+ ```
74
+
75
+ We recommend installing into an isolated environment, e.g., with `uv` / `pipx`:
76
+
77
+ ```sh
78
+ # Install globally with uv tool
79
+ uv tool install python-dmon
80
+
81
+ # Or with pipx
82
+ pipx install python-dmon
83
+
84
+ # Add as a dev dependency in your project
85
+ uv add --dev python-dmon
86
+ ```
87
+
88
+ You can also run dmon without installing it permanently:
89
+
90
+ ```sh
91
+ # With uvx (uv tool run)
92
+ uvx python-dmon
93
+
94
+ # Or with pipx
95
+ pipx run python-dmon
96
+ ```
97
+
98
+ To get the latest features, install from source:
99
+
100
+ ```sh
101
+ pip install git+https://github.com/atomiechen/dmon.git
102
+ ```
103
+
104
+ For coding agents, see the [setup instructions](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md) and the
105
+ [portable skill](https://github.com/atomiechen/dmon/blob/main/skills/dmon/SKILL.md). The skill is installed separately from the CLI.
106
+
107
+ ## Getting Started
108
+
109
+ ### Prepare Configuration
110
+
111
+ Create a `dmon.yaml` file:
112
+
113
+ ```yaml
114
+ tasks:
115
+ app: ["python", "-u", "server.py"] # exec form
116
+ # app: "python -u server.py" # or a shell string
117
+ ```
118
+
119
+ Without `--config`, dmon searches the current directory and its parents for
120
+ `dmon.yaml`, `dmon.yml`, or `pyproject.toml`. See the
121
+ [configuration reference](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md)
122
+ for TOML, environments, paths, defaults, and log rotation.
123
+
124
+ ### Run tasks
125
+
126
+ ```sh
127
+ dmon start app # Start in the background
128
+ dmon stop app # Stop the recorded process tree
129
+ dmon restart app
130
+ dmon status app
131
+ dmon exec app # Run in this terminal; Ctrl-C ends it
132
+ ```
133
+
134
+ `exec` runs one configured command directly, without registering a managed
135
+ background task. Use `start` to keep it discoverable through `status` and `list`.
136
+ You can pass multiple names to the other task commands. Multi-task `start` is
137
+ best-effort: successful tasks stay running if another fails. For related
138
+ services with ordered startup and rollback, use a stack.
139
+
140
+ ### Run a stack
141
+
142
+ ```yaml
143
+ tasks:
144
+ api:
145
+ cmd: [python, api.py]
146
+ ready:
147
+ http: http://127.0.0.1:8000/health
148
+ worker:
149
+ cmd: [python, worker.py]
150
+ depends_on: [api]
151
+ stacks:
152
+ dev: [api, worker]
153
+ ```
154
+
155
+ ```sh
156
+ dmon stack up dev # Foreground; Ctrl-C stops the stack
157
+ # Or keep it running under a background supervisor:
158
+ dmon stack up -d dev
159
+ dmon stack status dev
160
+ dmon stack logs --tail 100 dev
161
+ dmon stack repair dev worker --format json # Replace an exited member
162
+ dmon stack down dev
163
+ ```
164
+
165
+ Stack startup waits for readiness and rolls back tasks it started if startup
166
+ fails. After startup, an exited member degrades the stack while healthy peers
167
+ keep running. `repair` replaces that member through its live supervisor, so
168
+ later `down` includes the replacement. It reuses the supervisor's launch
169
+ configuration and environment; separately running `dmon start worker` does not
170
+ repair stack membership.
171
+
172
+ See [task and stack lifecycle](https://github.com/atomiechen/dmon/blob/main/docs/ownership.md)
173
+ for fail-fast behavior, detached restart, recovery, and ownership limits. Docker
174
+ Compose is still appropriate when container behavior itself must be tested.
175
+
176
+ ### Wait for readiness
177
+
178
+ `dmon wait` checks readiness without starting or stopping anything. Configured
179
+ tasks need a `ready` probe and must already be managed by `start` or a stack:
180
+
181
+ ```sh
182
+ dmon wait api
183
+ dmon wait api --timeout 60 --interval 0.5
184
+
185
+ # Direct probes need no configuration
186
+ dmon wait --http http://127.0.0.1:8000/health
187
+ dmon wait --tcp 127.0.0.1:5432
188
+ dmon wait --timeout 30 --command -- python healthcheck.py --verbose
189
+ ```
190
+
191
+ Put dmon options before `--command`; the optional second `--` marks the child
192
+ command. See [readiness configuration](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md#readiness)
193
+ for probe options, listener ownership checks, and wait results.
194
+
195
+ ### Run an ad-hoc command
196
+
197
+ ```sh
198
+ dmon run --name myserver python -u server.py
199
+ dmon run --name timer -- python -c 'import time; time.sleep(30)'
200
+ dmon run --shell echo "Hello World"
201
+ dmon run --cwd /path/to/script bash myscript.sh
202
+ ```
203
+
204
+ No configuration is needed. Without `--name`, dmon uses the fixed name
205
+ `default_run` to prevent duplicate runs.
206
+
207
+ ### List recorded tasks and their status
208
+
209
+ ```sh
210
+ dmon list
211
+ dmon status app --format json
212
+ dmon list --format json
213
+ dmon stack status dev --format json
214
+ dmon stack list --format json
215
+ dmon wait api --format json
216
+ ```
217
+
218
+ JSON is written only to stdout; actionable diagnostics remain on stderr. The
219
+ payload has a top-level `ok` field and a `tasks`, `stacks`, or `waits` array.
220
+ Inspection results contain `name`, `ok`, `error`, and an optional `snapshot`;
221
+ wait results contain the target, outcome, reason, elapsed time, and attempt
222
+ count. Existing exit-code semantics are unchanged. Interactive and streaming
223
+ commands do not offer JSON output.
224
+
225
+ ### Python API
226
+
227
+ The same task lifecycle and inspection logic is available without parsing CLI
228
+ output:
229
+
230
+ ```python
231
+ from dmon import Dmon
232
+
233
+ client = Dmon(config="dmon.yaml")
234
+ started = client.start("app")
235
+ task = client.status("app")
236
+ stacks = client.list_stacks()
237
+ client.stop("app")
238
+ ```
239
+
240
+ `client.wait("app", timeout=30)` also checks readiness when `app` has a
241
+ configured `ready` probe. API calls are synchronous and silent.
242
+ `start`, `stop`, and `restart` return an immutable `BatchResult`; `status`
243
+ and `stack_status` return `TaskResult` and `StackResult`. List and wait methods
244
+ return tuples of their corresponding result types. Expected runtime states such
245
+ as missing or exited metadata are results, while invalid configuration raises
246
+ `DmonConfigError`. The initial API intentionally does not start a supervised
247
+ stack or create implicit background threads.
248
+
249
+ ## Documentation
250
+
251
+ Start with the [documentation index](https://github.com/atomiechen/dmon/blob/main/docs/README.md):
252
+
253
+ - [Configuration](https://github.com/atomiechen/dmon/blob/main/docs/configuration.md): task selection, YAML/TOML, environments, readiness, and logs.
254
+ - [Task and stack lifecycle](https://github.com/atomiechen/dmon/blob/main/docs/ownership.md): startup, repair, recovery, and process ownership.
255
+ - [Coding-agent setup](https://github.com/atomiechen/dmon/blob/main/docs/agent-setup.md): install the workflow and continue across sessions.
256
+
257
+ ## Development
258
+
259
+ See [CONTRIBUTING.md](https://github.com/atomiechen/dmon/blob/main/CONTRIBUTING.md) for architecture, behavioral contracts,
260
+ validation, and the release workflow. Process, signal, log-rotation, and stack
261
+ changes must also pass the reproducible [manual test lab](https://github.com/atomiechen/dmon/blob/main/tests/manual/README.md).
262
+
263
+
264
+ ## License
265
+
266
+ [dmon](https://github.com/atomiechen/dmon) © 2025 by [Atomie CHEN](https://github.com/atomiechen) is licensed under the [MIT License](https://github.com/atomiechen/dmon/blob/main/LICENSE).
@@ -1,8 +1,10 @@
1
1
  [project]
2
2
  name = "python-dmon"
3
- version = "0.3.1"
4
- description = "A lightweight, cross-platform daemon manager that runs any command as a background process."
3
+ version = "0.5.0"
4
+ description = "A lightweight, cross-platform process manager for background tasks, local service stacks, and partial recovery."
5
5
  readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
6
8
  authors = [
7
9
  { name = "Atomie CHEN", email = "atomic_cwh@163.com" }
8
10
  ]
@@ -10,16 +12,17 @@ requires-python = ">=3.8"
10
12
  dependencies = [
11
13
  "colorama>=0.4.6",
12
14
  "psutil>=7.1.0",
15
+ "python-dotenv>=1.0.1,<1.1",
13
16
  "pyyaml>=6.0.3",
14
17
  "termcolor>=2.4.0",
15
18
  "tomli>=2.2.1 ; python_full_version < '3.11'",
16
19
  ]
17
- keywords = ["python-dmon", "dmon", "daemon", "background", "detach", "process management"]
20
+ keywords = ["dmon", "process manager", "daemon", "background", "supervisor", "local development", "readiness", "service management", "coding agents"]
18
21
 
19
22
  [project.urls]
20
- "Homepage" = "https://github.com/atomiechen/python-dmon"
21
- "Bug Tracker" = "https://github.com/atomiechen/python-dmon/issues"
22
- Changelog = "https://github.com/atomiechen/python-dmon/blob/main/CHANGELOG.md"
23
+ "Homepage" = "https://github.com/atomiechen/dmon"
24
+ "Bug Tracker" = "https://github.com/atomiechen/dmon/issues"
25
+ Changelog = "https://github.com/atomiechen/dmon/blob/main/CHANGELOG.md"
23
26
 
24
27
  [project.scripts]
25
28
  dmon = "dmon.__main__:main"
@@ -0,0 +1,23 @@
1
+ from .api import Dmon, DmonConfigError, DmonError
2
+ from .results import (
3
+ ActionResult,
4
+ BatchResult,
5
+ StackResult,
6
+ StackSnapshot,
7
+ TaskResult,
8
+ TaskSnapshot,
9
+ WaitResult,
10
+ )
11
+
12
+ __all__ = [
13
+ "ActionResult",
14
+ "BatchResult",
15
+ "Dmon",
16
+ "DmonConfigError",
17
+ "DmonError",
18
+ "StackResult",
19
+ "StackSnapshot",
20
+ "TaskResult",
21
+ "TaskSnapshot",
22
+ "WaitResult",
23
+ ]