agent-notifier 0.1.2__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 (47) hide show
  1. agent_notifier-0.1.2/LICENSE +21 -0
  2. agent_notifier-0.1.2/PKG-INFO +490 -0
  3. agent_notifier-0.1.2/README.md +457 -0
  4. agent_notifier-0.1.2/agent_notifier.egg-info/PKG-INFO +490 -0
  5. agent_notifier-0.1.2/agent_notifier.egg-info/SOURCES.txt +45 -0
  6. agent_notifier-0.1.2/agent_notifier.egg-info/dependency_links.txt +1 -0
  7. agent_notifier-0.1.2/agent_notifier.egg-info/entry_points.txt +5 -0
  8. agent_notifier-0.1.2/agent_notifier.egg-info/requires.txt +15 -0
  9. agent_notifier-0.1.2/agent_notifier.egg-info/top_level.txt +1 -0
  10. agent_notifier-0.1.2/agentnotifier/__init__.py +5 -0
  11. agent_notifier-0.1.2/agentnotifier/bridges.py +51 -0
  12. agent_notifier-0.1.2/agentnotifier/cli.py +1235 -0
  13. agent_notifier-0.1.2/agentnotifier/config/__init__.py +1 -0
  14. agent_notifier-0.1.2/agentnotifier/config/config.py +98 -0
  15. agent_notifier-0.1.2/agentnotifier/core/__init__.py +1 -0
  16. agent_notifier-0.1.2/agentnotifier/core/notifications.py +127 -0
  17. agent_notifier-0.1.2/agentnotifier/core/output.py +20 -0
  18. agent_notifier-0.1.2/agentnotifier/core/procinfo.py +53 -0
  19. agent_notifier-0.1.2/agentnotifier/core/result.py +45 -0
  20. agent_notifier-0.1.2/agentnotifier/core/runner.py +74 -0
  21. agent_notifier-0.1.2/agentnotifier/core/timefmt.py +24 -0
  22. agent_notifier-0.1.2/agentnotifier/core/watcher.py +118 -0
  23. agent_notifier-0.1.2/agentnotifier/notifier/__init__.py +21 -0
  24. agent_notifier-0.1.2/agentnotifier/notifier/base.py +65 -0
  25. agent_notifier-0.1.2/agentnotifier/notifier/console.py +27 -0
  26. agent_notifier-0.1.2/agentnotifier/notifier/linux.py +69 -0
  27. agent_notifier-0.1.2/agentnotifier/notifier/macos.py +104 -0
  28. agent_notifier-0.1.2/agentnotifier/notifier/null.py +35 -0
  29. agent_notifier-0.1.2/agentnotifier/notifier/windows.py +107 -0
  30. agent_notifier-0.1.2/agentnotifier/notify/__init__.py +21 -0
  31. agent_notifier-0.1.2/agentnotifier/notify/base.py +65 -0
  32. agent_notifier-0.1.2/agentnotifier/notify/console.py +27 -0
  33. agent_notifier-0.1.2/agentnotifier/notify/linux.py +69 -0
  34. agent_notifier-0.1.2/agentnotifier/notify/macos.py +91 -0
  35. agent_notifier-0.1.2/agentnotifier/notify/null.py +35 -0
  36. agent_notifier-0.1.2/agentnotifier/notify/windows.py +107 -0
  37. agent_notifier-0.1.2/pyproject.toml +72 -0
  38. agent_notifier-0.1.2/setup.cfg +4 -0
  39. agent_notifier-0.1.2/tests/test_auto_detect.py +79 -0
  40. agent_notifier-0.1.2/tests/test_bridges.py +87 -0
  41. agent_notifier-0.1.2/tests/test_cli_commands.py +378 -0
  42. agent_notifier-0.1.2/tests/test_config.py +33 -0
  43. agent_notifier-0.1.2/tests/test_integration.py +8 -0
  44. agent_notifier-0.1.2/tests/test_notify.py +211 -0
  45. agent_notifier-0.1.2/tests/test_output.py +9 -0
  46. agent_notifier-0.1.2/tests/test_runner.py +45 -0
  47. agent_notifier-0.1.2/tests/test_watcher.py +6 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agent-notify contributors
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,490 @@
1
+ Metadata-Version: 2.1
2
+ Name: agent-notifier
3
+ Version: 0.1.2
4
+ Summary: Cross-platform notifications for long-running agentic CLI tools
5
+ Author: agent-notifier contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Kipung/AgentNotifier
8
+ Project-URL: Repository, https://github.com/Kipung/AgentNotifier
9
+ Project-URL: Issues, https://github.com/Kipung/AgentNotifier/issues
10
+ Keywords: cli,notification,agents,codex,developer-tools
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Build Tools
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: click<9.0,>=8.1
25
+ Requires-Dist: tomli>=2.0; python_version < "3.11"
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.2; extra == "dev"
28
+ Requires-Dist: pytest>=8.0; extra == "dev"
29
+ Requires-Dist: ruff>=0.5; extra == "dev"
30
+ Requires-Dist: twine>=5.1; extra == "dev"
31
+ Provides-Extra: windows
32
+ Requires-Dist: win10toast>=0.9; platform_system == "Windows" and extra == "windows"
33
+
34
+ # agent-notifier
35
+
36
+ `agent-notifier` sends notifications when long-running CLI/agent tasks finish.
37
+
38
+ It supports two usage styles:
39
+
40
+ 1. Wrap a command (`agent-notifier run -- ...`)
41
+ 2. Receive task-level events from interactive agents (Codex, Claude Code, Gemini, Ollama pipelines)
42
+
43
+ ## Why People Use This
44
+
45
+ - You can keep coding in one window and get notified when a background task completes.
46
+ - Notifications include success/failure, duration, and exit code.
47
+ - Works on macOS, Windows, and Linux (with console fallback when desktop notifications are unavailable).
48
+
49
+ ## Install
50
+
51
+ Recommended:
52
+
53
+ ```bash
54
+ python3 -m pip install --user pipx
55
+ python3 -m pipx ensurepath
56
+ pipx install agent-notifier
57
+ ```
58
+
59
+ Alternative:
60
+
61
+ ```bash
62
+ pip install agent-notifier
63
+ ```
64
+
65
+ If `pipx install agent-notifier` fails because the package is not yet on PyPI, install from this repo checkout:
66
+
67
+ ```bash
68
+ cd /path/to/AgentPulse/packages/agent-notifier
69
+ pipx install .
70
+ ```
71
+
72
+ From source:
73
+
74
+ ```bash
75
+ python -m pip install -e .
76
+ ```
77
+
78
+ Confirm install:
79
+
80
+ ```bash
81
+ agent-notifier --help
82
+ agent-notifier test-notifier --channel console
83
+ ```
84
+
85
+ ## Zero-To-Working Setup (macOS, Verified)
86
+
87
+ Validated on March 2, 2026 with:
88
+ - macOS 26.2
89
+ - iTerm2
90
+ - `codex-cli 0.107.0`
91
+ - Gemini CLI (`AfterAgent` hook)
92
+
93
+ Run the helper from the repo checkout:
94
+
95
+ ```bash
96
+ cd /path/to/AgentPulse/packages/agent-notifier
97
+ ./examples/setup_macos.sh --trust-dir "/absolute/path/to/your/project" --open-settings
98
+ ```
99
+
100
+ What this script does:
101
+ - Installs `terminal-notifier` with Homebrew when available.
102
+ - Installs/updates `agent-notifier` from local source checkout.
103
+ - Configures Codex hook in `~/.codex/config.toml` using `notify = [...]`.
104
+ - Configures Gemini `AfterAgent` hook in `~/.gemini/settings.json`.
105
+ - Marks your project as trusted in `~/.gemini/trustedFolders.json`.
106
+ - Creates timestamped backups before editing existing Codex/Gemini config files.
107
+ - Runs `test-notifier` and a Codex bridge smoke test.
108
+
109
+ Important limitation:
110
+ - macOS notification permissions cannot be auto-granted by CLI tools.
111
+ - You must manually allow notifications for your terminal app (Terminal/iTerm) in System Settings -> Notifications.
112
+
113
+ ## 2-Minute Quickstart
114
+
115
+ Run any long command through the wrapper:
116
+
117
+ ```bash
118
+ agent-notifier run -- python3 -c "import time; time.sleep(8)"
119
+ ```
120
+
121
+ If the command fails, the notification title changes to `Failed`.
122
+
123
+ ## Behavior Model
124
+
125
+ `agent-notifier` is task-level first for interactive tools.
126
+ It notifies when hook events fire (Codex/Claude/Gemini integrations), not when you exit your shell.
127
+
128
+ ## Interactive Tool Setup
129
+
130
+ ### Codex CLI
131
+
132
+ Codex provides a notification hook.
133
+
134
+ Preferred (works great with `pipx`/`pip` installs):
135
+
136
+ ```bash
137
+ BRIDGE_PATH="$(command -v agent-notifier-codex-hook)"
138
+ echo "$BRIDGE_PATH"
139
+ ```
140
+
141
+ If you're running from a source checkout, use the included script bridge:
142
+
143
+ ```bash
144
+ chmod +x examples/codex_notifier_bridge.sh
145
+ BRIDGE_PATH="$(realpath examples/codex_notifier_bridge.sh)"
146
+ echo "$BRIDGE_PATH"
147
+ ```
148
+
149
+ Add to `~/.codex/config.toml`:
150
+
151
+ ```toml
152
+ notify = [
153
+ "/absolute/path/to/agent-notifier-codex-hook-or-script"
154
+ ]
155
+ ```
156
+
157
+ Codex key naming:
158
+ - `notify` is the Codex config key (official in current Codex CLI builds).
159
+ - It is unrelated to this package's internal naming (`agent-notifier`).
160
+
161
+ Legacy filename `examples/codex_notify_bridge.sh` is also supported.
162
+
163
+ Optional debug logs:
164
+
165
+ ```bash
166
+ export AGENT_NOTIFIER_DEBUG=1
167
+ ```
168
+
169
+ Log location:
170
+ `~/.agentnotifier/logs/codex_notifier.log`
171
+
172
+ #### Manual Verified Flow: macOS + iTerm + Codex
173
+
174
+ Use this exact flow if you do not use `examples/setup_macos.sh`:
175
+
176
+ 1. Set Codex config key to `notify` (not `notifier`) in `~/.codex/config.toml`:
177
+
178
+ ```toml
179
+ notify = [
180
+ "/absolute/path/to/examples/codex_notifier_bridge.sh"
181
+ ]
182
+ ```
183
+
184
+ 2. Ensure the bridge is executable:
185
+
186
+ ```bash
187
+ chmod +x examples/codex_notifier_bridge.sh
188
+ ```
189
+
190
+ 3. Restart Codex fully (fresh process), then complete one prompt.
191
+
192
+ 4. If you still do not see a popup, enable debug and inspect hook calls:
193
+
194
+ ```bash
195
+ export AGENT_NOTIFIER_DEBUG=1
196
+ tail -n 80 ~/.agentnotifier/logs/codex_notifier.log
197
+ ```
198
+
199
+ 5. Manual bridge test (copy-paste safe):
200
+
201
+ ```bash
202
+ ./examples/codex_notifier_bridge.sh --channel both --verbose type=agent-turn-complete turn-id=manual-check
203
+ ```
204
+
205
+ Expected behavior:
206
+ - You should hear a chime and/or see a desktop notification.
207
+ - The debug log should show `type=agent-turn-complete` payloads and `exit=0`.
208
+
209
+ Common causes when chime works but popup does not:
210
+ - macOS notification permissions disabled for your terminal app.
211
+ - Focus / Do Not Disturb enabled.
212
+ - Banner style disabled in System Settings -> Notifications.
213
+
214
+ ### Claude Code
215
+
216
+ Preferred bridge command (installed via `pipx`/`pip`):
217
+
218
+ ```bash
219
+ command -v agent-notifier-claude-hook
220
+ ```
221
+
222
+ Configure hooks in `.claude/settings.local.json` (or user settings):
223
+
224
+ ```json
225
+ {
226
+ "hooks": {
227
+ "Stop": [
228
+ {
229
+ "matcher": "*",
230
+ "hooks": [
231
+ {
232
+ "type": "command",
233
+ "command": "agent-notifier-claude-hook --event Stop"
234
+ }
235
+ ]
236
+ }
237
+ ],
238
+ "SubagentStop": [
239
+ {
240
+ "matcher": "*",
241
+ "hooks": [
242
+ {
243
+ "type": "command",
244
+ "command": "agent-notifier-claude-hook --event SubagentStop"
245
+ }
246
+ ]
247
+ }
248
+ ]
249
+ }
250
+ }
251
+ ```
252
+
253
+ ### Gemini CLI
254
+
255
+ Config files:
256
+ - `~/.gemini/settings.json` (hooks)
257
+ - `~/.gemini/trustedFolders.json` (folder trust)
258
+
259
+ Preferred bridge command (installed via `pipx`/`pip`):
260
+
261
+ ```bash
262
+ command -v agent-notifier-gemini-hook
263
+ ```
264
+
265
+ Configure `AfterAgent` hook:
266
+
267
+ ```json
268
+ {
269
+ "hooksConfig": {
270
+ "enabled": true
271
+ },
272
+ "hooks": {
273
+ "AfterAgent": [
274
+ {
275
+ "matcher": "*",
276
+ "hooks": [
277
+ {
278
+ "type": "command",
279
+ "command": "agent-notifier-gemini-hook",
280
+ "timeout": 10000
281
+ }
282
+ ]
283
+ }
284
+ ]
285
+ }
286
+ }
287
+ ```
288
+
289
+ Gemini trust requirement:
290
+ - Hooks may not run in untrusted project folders.
291
+ - If `AfterAgent` does not fire, confirm the current project path is trusted in `~/.gemini/trustedFolders.json`.
292
+
293
+ Quick check (`$PROJECT_DIR` is the folder where you run Gemini):
294
+
295
+ ```bash
296
+ PROJECT_DIR="/absolute/path/to/your/project"
297
+ rg -n "\"$PROJECT_DIR\"|TRUST_FOLDER" ~/.gemini/trustedFolders.json
298
+ ```
299
+
300
+ Example update:
301
+
302
+ ```bash
303
+ PROJECT_DIR="/absolute/path/to/your/project"
304
+ jq --arg p "$PROJECT_DIR" '. + {($p):"TRUST_FOLDER"}' ~/.gemini/trustedFolders.json > /tmp/trustedFolders.json && mv /tmp/trustedFolders.json ~/.gemini/trustedFolders.json
305
+ ```
306
+
307
+ Restart Gemini after changing trust settings.
308
+
309
+ Temporary hook-fire debug:
310
+
311
+ ```json
312
+ {
313
+ "type": "command",
314
+ "command": "agent-notifier-gemini-hook >> /tmp/gemini_afteragent.log 2>&1",
315
+ "timeout": 10000
316
+ }
317
+ ```
318
+
319
+ Then run:
320
+
321
+ ```bash
322
+ tail -n 20 /tmp/gemini_afteragent.log
323
+ ```
324
+
325
+ ### Ollama
326
+
327
+ - Pure interactive `ollama run` currently has no native per-turn completion hook.
328
+ - If you use `ollama launch codex` or `ollama launch claude`, configure Codex/Claude hooks above.
329
+ - For non-interactive JSON output (`--format json`), pipe into `agent-notifier ollama-hook`.
330
+
331
+ Example:
332
+
333
+ ```bash
334
+ ollama run llama3 --format json | agent-notifier ollama-hook --name ollama --channel both
335
+ ```
336
+
337
+ ## Core Commands
338
+
339
+ `agent-notifier run -- <cmd...>`
340
+ - Run and notify on completion.
341
+ - Wrapper exits with the same exit code as the wrapped command.
342
+
343
+ `agent-notifier watch --pid <pid>`
344
+ - Watch an existing process ID until exit.
345
+
346
+ `agent-notifier test-notifier`
347
+ - Send a sample notification.
348
+
349
+ `agent-notifier tail --file <path> --pattern <text>`
350
+ - Notify when a log pattern appears.
351
+
352
+ Hook bridge commands used by integrations:
353
+ - `agent-notifier-codex-hook`
354
+ - `agent-notifier-gemini-hook`
355
+ - `agent-notifier-claude-hook`
356
+ - `agent-notifier codex-hook` (direct mode)
357
+ - `agent-notifier gemini-hook` (direct mode)
358
+ - `agent-notifier claude-hook` (direct mode)
359
+ - `agent-notifier ollama-hook`
360
+
361
+ ## Common Customizations
362
+
363
+ Suppress notifications while terminal is focused (macOS):
364
+
365
+ ```bash
366
+ agent-notifier gemini-hook --quiet-when-focused
367
+ ```
368
+
369
+ Note: `--quiet-when-focused` is optional. If you copied older hook examples that included it by default and notifications seem missing, remove that flag.
370
+
371
+ Add sound:
372
+
373
+ ```bash
374
+ agent-notifier claude-hook --chime ping
375
+ ```
376
+
377
+ Force console output:
378
+
379
+ ```bash
380
+ agent-notifier run --channel console -- your-command
381
+ ```
382
+
383
+ ## Configuration
384
+
385
+ Environment variables:
386
+
387
+ - `AGENT_NOTIFIER_TITLE_PREFIX="Agent"`
388
+ - `AGENT_NOTIFIER_CHANNELS="desktop,console"`
389
+ - `AGENT_NOTIFIER_TAIL_LINES=20`
390
+ - `AGENT_NOTIFIER_POLL_INTERVAL=1.0`
391
+
392
+ Optional TOML config at `~/.agentnotifier/config.toml`:
393
+
394
+ ```toml
395
+ title_prefix = "Agent"
396
+ channels = ["desktop"]
397
+ tail_lines = 20
398
+ poll_interval = 1.0
399
+ ```
400
+
401
+ Environment variables override file values.
402
+
403
+ ## Troubleshooting
404
+
405
+ ### I only get notifications when I exit the CLI
406
+
407
+ Check your tool hooks configuration. This project intentionally focuses on task-level notifications.
408
+ If notifications only appear on session exit, verify your CLI is calling `codex-hook`, `claude-hook`, or `gemini-hook` on task completion events.
409
+
410
+ ### Desktop notifications do not appear
411
+
412
+ 1. Test fallback path:
413
+ - `agent-notifier test-notifier --channel console`
414
+ 2. Test desktop + diagnostics:
415
+ - `agent-notifier test-notifier --channel both --verbose`
416
+ 3. Verify platform backend:
417
+ - macOS uses `terminal-notifier` first, then `osascript`
418
+ - Windows uses PowerShell/BurntToast (with `win10toast` fallback)
419
+ - Linux uses `notify-send` (package `libnotify-bin` on Debian/Ubuntu)
420
+ 4. macOS permission gate:
421
+ - Notifications must be allowed manually for your terminal app in System Settings -> Notifications.
422
+
423
+ ### Codex notifications not firing
424
+
425
+ 1. Confirm `notify` is configured in `~/.codex/config.toml`.
426
+ 2. Confirm bridge command/path resolves:
427
+ - `command -v agent-notifier-codex-hook` (preferred), or
428
+ - `chmod +x examples/codex_notifier_bridge.sh` (source checkout)
429
+ 3. Restart Codex after config changes (required).
430
+ 4. Enable bridge debug logs with `AGENT_NOTIFIER_DEBUG=1` and inspect `~/.agentnotifier/logs/codex_notifier.log`.
431
+ 5. Do not use the `notifier` key in Codex config; use `notify`.
432
+
433
+ ### Scenario Matrix (Quick Diagnosis)
434
+
435
+ Use this section to map a symptom to a concrete next action.
436
+
437
+ | Symptom | What it usually means | Verify | Fix |
438
+ | --- | --- | --- | --- |
439
+ | No notifications from Codex and log file never updates | Codex hook not wired | `tail -n 20 ~/.agentnotifier/logs/codex_notifier.log` after a completed turn | Use `notify = [...]` in `~/.codex/config.toml` and restart Codex |
440
+ | Codex log updates with `agent-turn-complete` payloads but no popup | Hook runs, desktop backend or OS UI is blocking | `agent-notifier test-notifier --channel both --verbose` | Enable notifications for your terminal app, disable Focus/Do Not Disturb, enable banners |
441
+ | Chime plays but no popup | Sound path works, visual notifications blocked by OS settings | Run `agent-notifier test-notifier --channel both --verbose` | In System Settings -> Notifications, allow alerts for terminal/iTerm and `terminal-notifier` (if listed) |
442
+ | `zsh: command not found: agent-notifier` | Installed in a different Python env or not on `PATH` | `command -v agent-notifier` | Use absolute binary path (for example `~/miniconda3/bin/agent-notifier-codex-hook`) or update `PATH` |
443
+ | Manual bridge test prints `[codex] Done` but Codex turns show nothing | Bridge itself is healthy; Codex config/session issue | Run manual test and compare with Codex log updates | Restart Codex fully; confirm the same bridge path is in `notify = [...]` |
444
+ | Manual bridge command returns no output but exit code is `0` | Event did not match (often malformed payload text) | Use key-value payload form | Run: `./examples/codex_notifier_bridge.sh --channel both --verbose type=agent-turn-complete turn-id=manual-check` |
445
+ | Gemini `AfterAgent` hook never runs | Project path is untrusted in Gemini | Set hook command to write `/tmp/gemini_afteragent.log` and verify file updates | Add project path as `TRUST_FOLDER` in `~/.gemini/trustedFolders.json`, restart Gemini |
446
+ | Desktop backend failure mentions `terminal-notifier` | `terminal-notifier` present but failing/crashing | `agent-notifier test-notifier --channel both --verbose` | Reinstall/fix `terminal-notifier` or rely on `osascript` fallback |
447
+ | Linux desktop popup missing | `notify-send` missing/unavailable | `command -v notify-send` | Install `libnotify-bin` (Debian/Ubuntu) or use `--channel console` |
448
+ | Windows desktop popup missing | BurntToast/PowerShell path unavailable | `agent-notifier test-notifier --channel both --verbose` | Install optional extras: `pip install "agent-notifier[windows]"` |
449
+
450
+ ## Platform Notes
451
+
452
+ macOS:
453
+ - Desktop notifications via `terminal-notifier` (preferred, third-party) or Notification Center (`osascript` fallback).
454
+ - `terminal-notifier` is not an Apple-official binary; it is a widely used open-source tool.
455
+ - Install with Homebrew: `brew install terminal-notifier`
456
+ - You can still work without it because `osascript` fallback is built in.
457
+
458
+ Windows:
459
+ - Primary backend: PowerShell + BurntToast.
460
+ - Optional fallback dependency: `pip install "agent-notifier[windows]"`.
461
+
462
+ Linux:
463
+ - Desktop notifications via `notify-send`.
464
+ - Debian/Ubuntu install: `sudo apt install libnotify-bin`.
465
+
466
+ ## For Maintainers
467
+
468
+ Development checks:
469
+
470
+ ```bash
471
+ python -m pip install -e ".[dev]"
472
+ ruff check .
473
+ pytest -q
474
+ python -m build
475
+ twine check dist/*
476
+ ```
477
+
478
+ Release checklist:
479
+ - `docs/release_checklist.md`
480
+
481
+ Project/process docs:
482
+ - `docs/project_charter.md`
483
+ - `docs/scrum_working_agreement.md`
484
+ - `docs/assumptions.md`
485
+ - `docs/commit_plan.md`
486
+ - `SECURITY.md`
487
+
488
+ ## License
489
+
490
+ MIT (`LICENSE`)