waitbus 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.
- waitbus-0.1.0/.github/CONTRIBUTING.md +350 -0
- waitbus-0.1.0/.gitignore +73 -0
- waitbus-0.1.0/CHANGELOG.md +63 -0
- waitbus-0.1.0/LICENSE +21 -0
- waitbus-0.1.0/NOTICE +121 -0
- waitbus-0.1.0/PKG-INFO +758 -0
- waitbus-0.1.0/README.md +705 -0
- waitbus-0.1.0/SECURITY.md +456 -0
- waitbus-0.1.0/SKILL.md +260 -0
- waitbus-0.1.0/installers/launchd/MANIFEST.txt +11 -0
- waitbus-0.1.0/installers/launchd/dev.waitbus.broadcast.plist +43 -0
- waitbus-0.1.0/installers/launchd/dev.waitbus.etag-poll.plist +34 -0
- waitbus-0.1.0/installers/launchd/dev.waitbus.listener.plist +44 -0
- waitbus-0.1.0/installers/launchd/dev.waitbus.watchdog.plist +32 -0
- waitbus-0.1.0/pyproject.toml +672 -0
- waitbus-0.1.0/systemd/MANIFEST.txt +16 -0
- waitbus-0.1.0/systemd/waitbus-broadcast.service +50 -0
- waitbus-0.1.0/systemd/waitbus-broadcast.socket +18 -0
- waitbus-0.1.0/systemd/waitbus-common.conf +42 -0
- waitbus-0.1.0/systemd/waitbus-etag-poll.service +36 -0
- waitbus-0.1.0/systemd/waitbus-etag-poll.timer +11 -0
- waitbus-0.1.0/systemd/waitbus-forward@.service +46 -0
- waitbus-0.1.0/systemd/waitbus-listener.service +53 -0
- waitbus-0.1.0/systemd/waitbus-watchdog.service +53 -0
- waitbus-0.1.0/systemd/waitbus-watchdog.timer +14 -0
- waitbus-0.1.0/tests/_agent_harness.py +112 -0
- waitbus-0.1.0/tests/_daemon_helpers.py +83 -0
- waitbus-0.1.0/tests/_subscriber_harness.py +93 -0
- waitbus-0.1.0/tests/_webhook_redactor.py +251 -0
- waitbus-0.1.0/tests/_wire_helpers.py +130 -0
- waitbus-0.1.0/tests/conftest.py +266 -0
- waitbus-0.1.0/tests/data/expected-sdist-manifest.txt +270 -0
- waitbus-0.1.0/tests/data/expected_mcp_frame.json +21 -0
- waitbus-0.1.0/tests/data/mcp_wire_baseline.jsonl +16 -0
- waitbus-0.1.0/tests/data/mcp_wire_spec_reference.jsonl +21 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/README.md +0 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/commit_message_emoji.json +64 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/delete_branch.json +27 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/issues_opened_with_secret_pattern.json +50 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/pull_request_body_unicode_control.json +70 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/pull_request_review_with_pii_email.json +66 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/push_with_large_deletion.json +110 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/release_published.json +50 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/workflow_job_completed_failure.json +69 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/workflow_run_action_requested_conclusion_null.json +96 -0
- waitbus-0.1.0/tests/data/webhook_fixtures/workflow_run_missing_head_commit.json +89 -0
- waitbus-0.1.0/tests/test_addressed_messaging.py +434 -0
- waitbus-0.1.0/tests/test_agent_integration_langgraph.py +99 -0
- waitbus-0.1.0/tests/test_agent_integration_pydantic_ai.py +115 -0
- waitbus-0.1.0/tests/test_artifact_hygiene.py +76 -0
- waitbus-0.1.0/tests/test_attestation.py +430 -0
- waitbus-0.1.0/tests/test_await_predicate_characterization.py +385 -0
- waitbus-0.1.0/tests/test_bench_helper_adoption.py +173 -0
- waitbus-0.1.0/tests/test_broadcast.py +2385 -0
- waitbus-0.1.0/tests/test_broadcast_exception_mapping.py +53 -0
- waitbus-0.1.0/tests/test_broadcast_robustness.py +535 -0
- waitbus-0.1.0/tests/test_broadcast_sub.py +1190 -0
- waitbus-0.1.0/tests/test_cli.py +387 -0
- waitbus-0.1.0/tests/test_cli_allowlist.py +330 -0
- waitbus-0.1.0/tests/test_cli_completion.py +171 -0
- waitbus-0.1.0/tests/test_cli_demo.py +55 -0
- waitbus-0.1.0/tests/test_cli_demo_decoders.py +129 -0
- waitbus-0.1.0/tests/test_cli_emit.py +120 -0
- waitbus-0.1.0/tests/test_cli_on.py +758 -0
- waitbus-0.1.0/tests/test_cli_serve.py +506 -0
- waitbus-0.1.0/tests/test_cli_sources.py +377 -0
- waitbus-0.1.0/tests/test_cli_stats.py +122 -0
- waitbus-0.1.0/tests/test_cli_subcommands.py +124 -0
- waitbus-0.1.0/tests/test_cli_swarm_demo.py +115 -0
- waitbus-0.1.0/tests/test_cli_top.py +339 -0
- waitbus-0.1.0/tests/test_cli_version.py +85 -0
- waitbus-0.1.0/tests/test_cli_wait.py +183 -0
- waitbus-0.1.0/tests/test_cloudevents.py +175 -0
- waitbus-0.1.0/tests/test_coalesce.py +513 -0
- waitbus-0.1.0/tests/test_coalesce_collapse_property.py +156 -0
- waitbus-0.1.0/tests/test_columns.py +85 -0
- waitbus-0.1.0/tests/test_complexity_table.py +290 -0
- waitbus-0.1.0/tests/test_compose_clauses.py +229 -0
- waitbus-0.1.0/tests/test_config.py +580 -0
- waitbus-0.1.0/tests/test_config_construction.py +64 -0
- waitbus-0.1.0/tests/test_config_validate.py +242 -0
- waitbus-0.1.0/tests/test_consumer_api_anchors.py +180 -0
- waitbus-0.1.0/tests/test_custom_sources.py +788 -0
- waitbus-0.1.0/tests/test_daemon_plugin_wireup.py +261 -0
- waitbus-0.1.0/tests/test_daemon_spawner_watch.py +278 -0
- waitbus-0.1.0/tests/test_db.py +289 -0
- waitbus-0.1.0/tests/test_db_prune.py +364 -0
- waitbus-0.1.0/tests/test_docker_watch_live.py +172 -0
- waitbus-0.1.0/tests/test_doorbell.py +348 -0
- waitbus-0.1.0/tests/test_e2e_scenarios.py +338 -0
- waitbus-0.1.0/tests/test_emit.py +361 -0
- waitbus-0.1.0/tests/test_emit_batch_property.py +197 -0
- waitbus-0.1.0/tests/test_emitter_examples.py +170 -0
- waitbus-0.1.0/tests/test_emitter_recipes.py +187 -0
- waitbus-0.1.0/tests/test_emitter_snippet.py +169 -0
- waitbus-0.1.0/tests/test_etag_poll.py +777 -0
- waitbus-0.1.0/tests/test_events_analyze.py +153 -0
- waitbus-0.1.0/tests/test_events_query.py +385 -0
- waitbus-0.1.0/tests/test_frame.py +658 -0
- waitbus-0.1.0/tests/test_frame_catalogue_consistency.py +208 -0
- waitbus-0.1.0/tests/test_fs_watch_live.py +134 -0
- waitbus-0.1.0/tests/test_grafana_dashboard.py +169 -0
- waitbus-0.1.0/tests/test_hero_swarm_e2e.py +105 -0
- waitbus-0.1.0/tests/test_http_base.py +71 -0
- waitbus-0.1.0/tests/test_init_migration.py +144 -0
- waitbus-0.1.0/tests/test_init_pyi_drift.py +84 -0
- waitbus-0.1.0/tests/test_install.py +212 -0
- waitbus-0.1.0/tests/test_install_launchd.py +232 -0
- waitbus-0.1.0/tests/test_listener.py +1061 -0
- waitbus-0.1.0/tests/test_listener_secret_loaders.py +76 -0
- waitbus-0.1.0/tests/test_listener_threading.py +131 -0
- waitbus-0.1.0/tests/test_log.py +141 -0
- waitbus-0.1.0/tests/test_mcp.py +510 -0
- waitbus-0.1.0/tests/test_mcp_coverage.py +855 -0
- waitbus-0.1.0/tests/test_mcp_e2e.py +182 -0
- waitbus-0.1.0/tests/test_mcp_event_payload_cap.py +209 -0
- waitbus-0.1.0/tests/test_mcp_session_state.py +37 -0
- waitbus-0.1.0/tests/test_mcp_surface.py +791 -0
- waitbus-0.1.0/tests/test_mcp_tail_events_async.py +259 -0
- waitbus-0.1.0/tests/test_mcp_wire_e2e.py +129 -0
- waitbus-0.1.0/tests/test_metrics.py +659 -0
- waitbus-0.1.0/tests/test_metrics_call_sites.py +203 -0
- waitbus-0.1.0/tests/test_metrics_endpoint.py +403 -0
- waitbus-0.1.0/tests/test_metrics_snapshot.py +151 -0
- waitbus-0.1.0/tests/test_migrations.py +381 -0
- waitbus-0.1.0/tests/test_multilingual_snippets.py +358 -0
- waitbus-0.1.0/tests/test_no_bun_residue.py +113 -0
- waitbus-0.1.0/tests/test_open_conn_pragmas.py +113 -0
- waitbus-0.1.0/tests/test_paths.py +209 -0
- waitbus-0.1.0/tests/test_peercred.py +127 -0
- waitbus-0.1.0/tests/test_plugin_config.py +348 -0
- waitbus-0.1.0/tests/test_pr_monitor.py +557 -0
- waitbus-0.1.0/tests/test_pr_monitor_tick.py +216 -0
- waitbus-0.1.0/tests/test_predicate.py +420 -0
- waitbus-0.1.0/tests/test_predicate_property.py +185 -0
- waitbus-0.1.0/tests/test_property_frame.py +398 -0
- waitbus-0.1.0/tests/test_property_ulid.py +69 -0
- waitbus-0.1.0/tests/test_property_validators.py +180 -0
- waitbus-0.1.0/tests/test_protocols.py +32 -0
- waitbus-0.1.0/tests/test_read_events_coverage.py +975 -0
- waitbus-0.1.0/tests/test_read_events_watch.py +367 -0
- waitbus-0.1.0/tests/test_replay_drain_and_print.py +144 -0
- waitbus-0.1.0/tests/test_sdist_manifest.py +167 -0
- waitbus-0.1.0/tests/test_secrets.py +212 -0
- waitbus-0.1.0/tests/test_serve_e2e.py +251 -0
- waitbus-0.1.0/tests/test_serve_unit.py +339 -0
- waitbus-0.1.0/tests/test_skill_md.py +127 -0
- waitbus-0.1.0/tests/test_sources.py +644 -0
- waitbus-0.1.0/tests/test_sourcespec_local_boundary.py +147 -0
- waitbus-0.1.0/tests/test_sourcespec_validation_property.py +233 -0
- waitbus-0.1.0/tests/test_stats.py +410 -0
- waitbus-0.1.0/tests/test_status_subcommand.py +188 -0
- waitbus-0.1.0/tests/test_subscribe_envelope_hygiene.py +174 -0
- waitbus-0.1.0/tests/test_subscribe_local_boundary.py +77 -0
- waitbus-0.1.0/tests/test_subscribe_sdk.py +363 -0
- waitbus-0.1.0/tests/test_subscribe_sdk_compose.py +237 -0
- waitbus-0.1.0/tests/test_subscriber_snippet.py +184 -0
- waitbus-0.1.0/tests/test_systemd_units.py +192 -0
- waitbus-0.1.0/tests/test_terminal_classifier.py +282 -0
- waitbus-0.1.0/tests/test_types.py +238 -0
- waitbus-0.1.0/tests/test_ulid.py +181 -0
- waitbus-0.1.0/tests/test_untrusted.py +108 -0
- waitbus-0.1.0/tests/test_verify_plugin.py +143 -0
- waitbus-0.1.0/tests/test_wait_for_race_immunity.py +136 -0
- waitbus-0.1.0/tests/test_waitbus_wait.py +463 -0
- waitbus-0.1.0/tests/test_waitbus_wait_compose.py +436 -0
- waitbus-0.1.0/tests/test_waitbus_wait_universal.py +476 -0
- waitbus-0.1.0/tests/test_watchdog_check.py +147 -0
- waitbus-0.1.0/tests/test_webhook_fixtures_redactor.py +430 -0
- waitbus-0.1.0/tests/test_webhook_fixtures_wire_conformance.py +206 -0
- waitbus-0.1.0/tests/test_wire_v1_conformance.py +265 -0
- waitbus-0.1.0/waitbus/__init__.py +93 -0
- waitbus-0.1.0/waitbus/__init__.pyi +38 -0
- waitbus-0.1.0/waitbus/_broadcast_sub.py +737 -0
- waitbus-0.1.0/waitbus/_cloudevents.py +164 -0
- waitbus-0.1.0/waitbus/_columns.py +115 -0
- waitbus-0.1.0/waitbus/_compose.py +129 -0
- waitbus-0.1.0/waitbus/_config.py +359 -0
- waitbus-0.1.0/waitbus/_db.py +698 -0
- waitbus-0.1.0/waitbus/_doorbell.py +251 -0
- waitbus-0.1.0/waitbus/_duration.py +33 -0
- waitbus-0.1.0/waitbus/_emit.py +373 -0
- waitbus-0.1.0/waitbus/_frame.py +332 -0
- waitbus-0.1.0/waitbus/_http.py +40 -0
- waitbus-0.1.0/waitbus/_log.py +34 -0
- waitbus-0.1.0/waitbus/_mcp_constants.py +104 -0
- waitbus-0.1.0/waitbus/_mcp_models.py +245 -0
- waitbus-0.1.0/waitbus/_mcp_subscriptions.py +198 -0
- waitbus-0.1.0/waitbus/_messaging.py +308 -0
- waitbus-0.1.0/waitbus/_metrics.py +418 -0
- waitbus-0.1.0/waitbus/_metrics_http.py +106 -0
- waitbus-0.1.0/waitbus/_paths.py +187 -0
- waitbus-0.1.0/waitbus/_peercred.py +72 -0
- waitbus-0.1.0/waitbus/_predicate.py +390 -0
- waitbus-0.1.0/waitbus/_protocols.py +24 -0
- waitbus-0.1.0/waitbus/_sdnotify.py +37 -0
- waitbus-0.1.0/waitbus/_secrets.py +125 -0
- waitbus-0.1.0/waitbus/_subscribe.py +507 -0
- waitbus-0.1.0/waitbus/_terminal.py +134 -0
- waitbus-0.1.0/waitbus/_types.py +189 -0
- waitbus-0.1.0/waitbus/_ulid.py +107 -0
- waitbus-0.1.0/waitbus/_untrusted.py +109 -0
- waitbus-0.1.0/waitbus/_version.py +11 -0
- waitbus-0.1.0/waitbus/broadcast.py +1816 -0
- waitbus-0.1.0/waitbus/broadcast_tap.py +131 -0
- waitbus-0.1.0/waitbus/cli/__init__.py +67 -0
- waitbus-0.1.0/waitbus/cli/_exit_codes.py +81 -0
- waitbus-0.1.0/waitbus/cli/_shared.py +906 -0
- waitbus-0.1.0/waitbus/cli/allowlist.py +353 -0
- waitbus-0.1.0/waitbus/cli/daemons/__init__.py +20 -0
- waitbus-0.1.0/waitbus/cli/daemons/broadcast.py +73 -0
- waitbus-0.1.0/waitbus/cli/daemons/etag_poll.py +39 -0
- waitbus-0.1.0/waitbus/cli/daemons/listener.py +39 -0
- waitbus-0.1.0/waitbus/cli/daemons/mcp.py +50 -0
- waitbus-0.1.0/waitbus/cli/daemons/pr_monitor.py +38 -0
- waitbus-0.1.0/waitbus/cli/daemons/read_events.py +49 -0
- waitbus-0.1.0/waitbus/cli/daemons/watchdog_check.py +38 -0
- waitbus-0.1.0/waitbus/cli/db/__init__.py +8 -0
- waitbus-0.1.0/waitbus/cli/db/migrate.py +113 -0
- waitbus-0.1.0/waitbus/cli/db/prune.py +317 -0
- waitbus-0.1.0/waitbus/cli/demo.py +593 -0
- waitbus-0.1.0/waitbus/cli/doctor.py +55 -0
- waitbus-0.1.0/waitbus/cli/emit.py +114 -0
- waitbus-0.1.0/waitbus/cli/init.py +97 -0
- waitbus-0.1.0/waitbus/cli/install/__init__.py +9 -0
- waitbus-0.1.0/waitbus/cli/install/credentials.py +111 -0
- waitbus-0.1.0/waitbus/cli/install/launchd.py +136 -0
- waitbus-0.1.0/waitbus/cli/install/systemd.py +122 -0
- waitbus-0.1.0/waitbus/cli/main.py +150 -0
- waitbus-0.1.0/waitbus/cli/on.py +25 -0
- waitbus-0.1.0/waitbus/cli/query/__init__.py +5 -0
- waitbus-0.1.0/waitbus/cli/query/events.py +145 -0
- waitbus-0.1.0/waitbus/cli/replay.py +21 -0
- waitbus-0.1.0/waitbus/cli/serve.py +603 -0
- waitbus-0.1.0/waitbus/cli/sources.py +460 -0
- waitbus-0.1.0/waitbus/cli/stats.py +131 -0
- waitbus-0.1.0/waitbus/cli/status.py +109 -0
- waitbus-0.1.0/waitbus/cli/stress.py +49 -0
- waitbus-0.1.0/waitbus/cli/swarm_demo.py +291 -0
- waitbus-0.1.0/waitbus/cli/top.py +25 -0
- waitbus-0.1.0/waitbus/cli/verify_plugin.py +59 -0
- waitbus-0.1.0/waitbus/cli/wait.py +24 -0
- waitbus-0.1.0/waitbus/coalesce.py +196 -0
- waitbus-0.1.0/waitbus/config_validate.py +359 -0
- waitbus-0.1.0/waitbus/etag_poll.py +718 -0
- waitbus-0.1.0/waitbus/events_analyze.py +140 -0
- waitbus-0.1.0/waitbus/events_query.py +363 -0
- waitbus-0.1.0/waitbus/listener.py +731 -0
- waitbus-0.1.0/waitbus/mcp.py +1463 -0
- waitbus-0.1.0/waitbus/migrations/0001_initial_schema.sql +87 -0
- waitbus-0.1.0/waitbus/migrations/0002_add_daemon_sequence.sql +94 -0
- waitbus-0.1.0/waitbus/migrations/__init__.py +401 -0
- waitbus-0.1.0/waitbus/on.py +730 -0
- waitbus-0.1.0/waitbus/pr_monitor.py +405 -0
- waitbus-0.1.0/waitbus/py.typed +0 -0
- waitbus-0.1.0/waitbus/read_events.py +545 -0
- waitbus-0.1.0/waitbus/replay.py +295 -0
- waitbus-0.1.0/waitbus/schema.sql +130 -0
- waitbus-0.1.0/waitbus/sources/__init__.py +83 -0
- waitbus-0.1.0/waitbus/sources/_attestation.py +379 -0
- waitbus-0.1.0/waitbus/sources/_config.py +446 -0
- waitbus-0.1.0/waitbus/sources/_protocol.py +324 -0
- waitbus-0.1.0/waitbus/sources/_registry.py +806 -0
- waitbus-0.1.0/waitbus/sources/docker_watch.py +492 -0
- waitbus-0.1.0/waitbus/sources/fs_watch.py +307 -0
- waitbus-0.1.0/waitbus/sources/pytest_emit.py +330 -0
- waitbus-0.1.0/waitbus/stats.py +492 -0
- waitbus-0.1.0/waitbus/top.py +256 -0
- waitbus-0.1.0/waitbus/wait.py +713 -0
- waitbus-0.1.0/waitbus/watchdog_check.py +225 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Contributing to waitbus
|
|
2
|
+
|
|
3
|
+
waitbus is a single-author project at present. Contributions are welcome via
|
|
4
|
+
GitHub issues (bug reports, feature requests) and pull requests. This document
|
|
5
|
+
covers the local development workflow, per-surface testing, version sync, and
|
|
6
|
+
release policy. For install and operation, see [README.md](../README.md).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Quick start (local dev)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
git clone https://github.com/astrogilda/waitbus && cd waitbus
|
|
14
|
+
uv sync --all-groups
|
|
15
|
+
uvx prek install -f
|
|
16
|
+
uv run pytest tests/ -p no:xdist
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
All runtime deps live in `[project.dependencies]`; dev deps (pytest, ruff,
|
|
20
|
+
mypy, hypothesis, build, tiktoken) live in `[dependency-groups].dev`.
|
|
21
|
+
`uv sync --all-groups` installs both. The git hook manager is `prek`
|
|
22
|
+
(Rust drop-in alternative to the pre-commit framework, schema-compatible
|
|
23
|
+
with the same `.pre-commit-config.yaml`); CI runs `uvx prek run --all-files`
|
|
24
|
+
on every push.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Project conventions
|
|
29
|
+
|
|
30
|
+
- **Python target:** 3.11 minimum (`requires-python = ">=3.11"`). CI tests 3.11, 3.12, 3.13, and 3.14.
|
|
31
|
+
- **Ruff rule set:** `["E", "F", "I", "N", "UP", "B", "SIM", "RUF"]`. `tests/*` allows `E402` for property-test deferred imports.
|
|
32
|
+
- **Line length:** 120 characters.
|
|
33
|
+
- **Mypy strict** on `waitbus/` only; tests are excluded (`[tool.mypy] files = ["waitbus"]`).
|
|
34
|
+
- **Tests run serial:** `pytest -p no:xdist`. Hypothesis fixture races occur under xdist.
|
|
35
|
+
- **Runtime dependency closure:** `typer` (CLI), `platformdirs` (path resolution), `mcp` + `pydantic` + `pydantic-core` (MCP server).
|
|
36
|
+
|
|
37
|
+
### Per-surface dev commands
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Full test suite (serial)
|
|
41
|
+
uv run pytest tests/ -vv -p no:xdist
|
|
42
|
+
|
|
43
|
+
# Lint
|
|
44
|
+
uv run ruff check waitbus tests scripts
|
|
45
|
+
|
|
46
|
+
# Type-check
|
|
47
|
+
uv run mypy waitbus
|
|
48
|
+
|
|
49
|
+
# Integration test (wheel build + install-in-venv + entry-point assertions)
|
|
50
|
+
uv run pytest tests/test_install.py -vv -p no:xdist -m slow
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The test suite has ~600 tests. Use `-p no:xdist` (serial mode) in development
|
|
54
|
+
and CI to avoid Hypothesis fixture races. The slow integration test builds a
|
|
55
|
+
wheel, installs it into a fresh venv, and asserts entry-points and
|
|
56
|
+
`systemd-analyze verify` output — it runs in roughly one second on a warm cache.
|
|
57
|
+
|
|
58
|
+
### MCP server
|
|
59
|
+
|
|
60
|
+
The MCP server lives in `waitbus/mcp.py` and is reachable via
|
|
61
|
+
`waitbus mcp serve`. It subscribes to the broadcast socket over stdlib
|
|
62
|
+
`socket.socket(AF_UNIX, SOCK_STREAM)` and re-emits each non-heartbeat frame
|
|
63
|
+
as both a vendor-specific Claude Code notification frame
|
|
64
|
+
(`notifications/claude/channel`) and a standard `notifications/resources/updated`
|
|
65
|
+
frame (for Claude Desktop and generic MCP clients).
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Run the MCP-server unit tests (fast, mocks the broadcast socket)
|
|
69
|
+
uv run pytest tests/test_mcp.py -vv -p no:xdist
|
|
70
|
+
|
|
71
|
+
# Run the server against a live broadcast daemon (Ctrl+D to stop)
|
|
72
|
+
uv run waitbus mcp serve
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
On macOS the server logs one info message and idles — the broadcast daemon
|
|
76
|
+
stack is Linux-only.
|
|
77
|
+
|
|
78
|
+
### Systemd units
|
|
79
|
+
|
|
80
|
+
Validate units before committing:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
systemd-analyze --user verify systemd/*.service systemd/*.socket systemd/*.timer
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
CI runs this check as well. When adding or removing unit files, update
|
|
87
|
+
`systemd/MANIFEST.txt` — `waitbus install-systemd --sync` reads that file
|
|
88
|
+
to compute orphan units from previous package versions.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Development install vs released install
|
|
93
|
+
|
|
94
|
+
**Working from a checkout:**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv pip install --editable .
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Console scripts point at your source tree — edits are picked up immediately.
|
|
101
|
+
However, editable installs do **not** place `share/systemd/user/` on disk.
|
|
102
|
+
Hatchling's `shared-data` directive only fires during a wheel build, not during
|
|
103
|
+
`--editable`. For systemd-unit testing during dev, build a wheel and install it
|
|
104
|
+
into a throwaway venv:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv build --wheel
|
|
108
|
+
# Install the produced dist/waitbus-*.whl into a fresh venv
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Or symlink the dev unit files to `~/.config/systemd/user/` manually for rapid
|
|
112
|
+
iteration without a wheel rebuild.
|
|
113
|
+
|
|
114
|
+
**Working from a released wheel:**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
uv tool install waitbus
|
|
118
|
+
waitbus install-systemd
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Loading the plugin locally
|
|
124
|
+
|
|
125
|
+
To test the full Claude Code plugin without installing from the registry:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
claude --plugin-dir /path/to/waitbus --dangerously-load-development-channels
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`.mcp.json` invokes `uvx --from waitbus waitbus mcp serve`, which
|
|
132
|
+
resolves the latest published `waitbus` from PyPI. To exercise local
|
|
133
|
+
source instead, either `uv tool install --editable .` from this directory
|
|
134
|
+
(rebinds the `waitbus` shim onto your working tree) or temporarily swap the
|
|
135
|
+
`.mcp.json` `args` to `["run", "waitbus", "mcp", "serve"]`.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Updating the sdist manifest snapshot
|
|
140
|
+
|
|
141
|
+
The sdist hygiene test in `tests/test_sdist_manifest.py` asserts that the file
|
|
142
|
+
list inside the produced source distribution matches a committed snapshot at
|
|
143
|
+
`tests/data/expected-sdist-manifest.txt`, plus a size budget, a copyleft-header
|
|
144
|
+
scan, and a forbidden-paths regression guard.
|
|
145
|
+
|
|
146
|
+
When you add or remove a file that ships in the sdist, regenerate the snapshot
|
|
147
|
+
in the same PR:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
uv build --sdist
|
|
151
|
+
tar tzf dist/waitbus-*.tar.gz | sort > tests/data/expected-sdist-manifest.txt
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Review the diff before committing — an unexpected addition is exactly what this
|
|
155
|
+
test is designed to catch.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Linux + systemd assumption
|
|
160
|
+
|
|
161
|
+
The daemon stack is **Linux-only** at runtime. The Python library, listener, ETag
|
|
162
|
+
poller, and query CLI work on macOS, but without systemd integration.
|
|
163
|
+
|
|
164
|
+
Specific reasons:
|
|
165
|
+
|
|
166
|
+
- `broadcast.py` authenticates subscribers with `SO_PEERCRED` and coalesces
|
|
167
|
+
doorbell wakeups with `os.eventfd`, both Linux-only. The wire itself is
|
|
168
|
+
`AF_UNIX SOCK_STREAM` with length-prefix framing (portable; macOS lacks
|
|
169
|
+
`SOCK_SEQPACKET`), but the broadcast, doorbell, and `read-events --watch`
|
|
170
|
+
test modules carry `pytestmark = pytest.mark.skipif(sys.platform != "linux", ...)`
|
|
171
|
+
for the eventfd and peer-credential paths.
|
|
172
|
+
- `broadcast._peer_uid` resolves `SO_PEERCRED` via
|
|
173
|
+
`getattr(socket, "SO_PEERCRED", None)` so the package still imports cleanly
|
|
174
|
+
on macOS for the library and listener surfaces.
|
|
175
|
+
- The MCP server (`waitbus/mcp.py`) subscribes to the broadcast bus; on macOS
|
|
176
|
+
it emits one info-severity notification and exits cleanly because that
|
|
177
|
+
broadcast daemon stack is Linux-only.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Version sync
|
|
182
|
+
|
|
183
|
+
The canonical version lives in `pyproject.toml [project].version`. Three
|
|
184
|
+
manifests must agree: `pyproject.toml`, `.claude-plugin/plugin.json`, and
|
|
185
|
+
`server.json`. Propagate with:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
scripts/sync-versions.py # mutate all three manifests; exit 0
|
|
189
|
+
scripts/sync-versions.py --check # exit 1 on any drift
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
The `--check` mode runs in the pre-commit hook and in CI. Never bump version
|
|
193
|
+
fields manually in `plugin.json` or `server.json` — only edit `pyproject.toml`
|
|
194
|
+
and then run `sync-versions.py`.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Commit conventions
|
|
199
|
+
|
|
200
|
+
Commits and PR titles follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
feat(waitbus): add broadcast lag counter metric
|
|
204
|
+
fix(waitbus): handle SIGTERM during fan-out drain
|
|
205
|
+
docs(waitbus): expand install-systemd shared-data note
|
|
206
|
+
test(waitbus): add Hypothesis property tests for ULID ordering
|
|
207
|
+
chore(waitbus): update pre-commit hook versions
|
|
208
|
+
ci(waitbus): add systemd-analyze verify step to workflow
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Rules:
|
|
212
|
+
- No emoji.
|
|
213
|
+
- No internal jargon (no internal project jargon).
|
|
214
|
+
- Subject line under 72 characters, imperative mood.
|
|
215
|
+
- PR body explains *why*, not *what*.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Commit signing
|
|
220
|
+
|
|
221
|
+
We recommend signing your commits. Release tags are already signed, and signed
|
|
222
|
+
commits extend that chain of trust back through the history they tag.
|
|
223
|
+
|
|
224
|
+
Enable signing locally with either an SSH key or a GPG key:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# SSH-key signing (simplest if you already push over SSH):
|
|
228
|
+
git config commit.gpgsign true
|
|
229
|
+
git config gpg.format ssh
|
|
230
|
+
git config user.signingkey ~/.ssh/id_ed25519.pub
|
|
231
|
+
|
|
232
|
+
# Or GPG-key signing:
|
|
233
|
+
git config commit.gpgsign true
|
|
234
|
+
git config user.signingkey <your-gpg-key-id>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This is a recommendation, not a CI gate: signed commits are not enforced on
|
|
238
|
+
pull requests (that would be premature ahead of a public, multi-contributor
|
|
239
|
+
flow). The signed release tag remains the enforced trust boundary.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Console scripts (1)
|
|
244
|
+
|
|
245
|
+
The package ships a single entry point: `waitbus`. All previous per-daemon
|
|
246
|
+
scripts are now sub-commands of that umbrella CLI.
|
|
247
|
+
|
|
248
|
+
| Sub-command | Purpose |
|
|
249
|
+
|-------------|---------|
|
|
250
|
+
| `waitbus init` | Create state directory and SQLite schema |
|
|
251
|
+
| `waitbus install-systemd` | Copy systemd user units (Linux) |
|
|
252
|
+
| `waitbus install-launchd` | Copy launchd plists (macOS) |
|
|
253
|
+
| `waitbus keygen` | Store HMAC secret in OS keyring |
|
|
254
|
+
| `waitbus doctor` | Health-gate: config, keyring, binaries, daemons |
|
|
255
|
+
| `waitbus status` | Operational dashboard: event counts, daemon liveness |
|
|
256
|
+
| `waitbus verify-plugin` | Validate `.claude-plugin/plugin.json` fields |
|
|
257
|
+
| `waitbus listener serve` | HTTP webhook receiver (loopback :9000) |
|
|
258
|
+
| `waitbus broadcast serve` | AF_UNIX SOCK_STREAM fan-out daemon |
|
|
259
|
+
| `waitbus etag-poll run` | ETag-aware backup poller (one-shot) |
|
|
260
|
+
| `waitbus mcp serve` | MCP server (stdio), re-emits broadcast events |
|
|
261
|
+
| `waitbus read-events list` | Query the event store |
|
|
262
|
+
| `waitbus read-events watch` | Tail the event store (live) |
|
|
263
|
+
| `waitbus pr-monitor tick` | Roll job events into per-PR state |
|
|
264
|
+
| `waitbus watchdog-check run` | Alertmanager watchdog freshness probe |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Systemd units (8)
|
|
269
|
+
|
|
270
|
+
| Unit file | Purpose |
|
|
271
|
+
|-----------|---------|
|
|
272
|
+
| `waitbus-listener.service` | Webhook HTTP server |
|
|
273
|
+
| `waitbus-broadcast.service` | Broadcast daemon (socket-activated) |
|
|
274
|
+
| `waitbus-broadcast.socket` | AF_UNIX SOCK_STREAM activation socket |
|
|
275
|
+
| `waitbus-etag-poll.service` | ETag poller one-shot service |
|
|
276
|
+
| `waitbus-etag-poll.timer` | 45-second timer for the poller |
|
|
277
|
+
| `waitbus-watchdog.service` | Ingestion-silence detector service |
|
|
278
|
+
| `waitbus-watchdog.timer` | Timer for the watchdog probe |
|
|
279
|
+
| `waitbus-forward@.service` | Templated per-repository forwarder |
|
|
280
|
+
|
|
281
|
+
All eight units use `ExecStart=%h/.local/bin/waitbus <subcmd> <verb>` and
|
|
282
|
+
carry systemd hardening directives (`PrivateTmp`, `ProtectSystem=strict`,
|
|
283
|
+
`NoNewPrivileges`, `SystemCallFilter` allow-list). `waitbus install-systemd`
|
|
284
|
+
copies them from the wheel's `share/systemd/user/` destination into
|
|
285
|
+
`~/.config/systemd/user/`.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## `--dry-run` vs `doctor`
|
|
290
|
+
|
|
291
|
+
- **`waitbus init --dry-run`** — prints intended actions and always exits 0.
|
|
292
|
+
Use for inspection before committing to install actions.
|
|
293
|
+
- **`waitbus doctor`** — reads the *current* state of config, keyring,
|
|
294
|
+
binaries, and systemd units. Exits 0 if everything resolves; exits 1 on any
|
|
295
|
+
issue. Use as a health gate before and after deploys.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Versioning policy
|
|
300
|
+
|
|
301
|
+
This project follows [Semantic Versioning](https://semver.org/). Pre-1.0
|
|
302
|
+
releases may refine the API based on real-world usage. After 6+ months of
|
|
303
|
+
stable public usage, v1.0 will declare API stability.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Release process
|
|
308
|
+
|
|
309
|
+
1. Bump `pyproject.toml [project].version` to the target (e.g., `0.2.0`).
|
|
310
|
+
2. Run `scripts/sync-versions.py` to propagate to all manifests.
|
|
311
|
+
3. Update `CHANGELOG.md` — add a dated section for the new version.
|
|
312
|
+
4. Commit + push + open PR. CI must pass before merging.
|
|
313
|
+
5. After merge to main:
|
|
314
|
+
```bash
|
|
315
|
+
git tag v0.2.0
|
|
316
|
+
git push origin v0.2.0
|
|
317
|
+
```
|
|
318
|
+
6. The tag triggers `.github/workflows/release.yml`, which:
|
|
319
|
+
- Publishes `waitbus` to PyPI (OIDC + sigstore attestations).
|
|
320
|
+
- Registers `io.github.astrogilda/waitbus` with the MCP Registry.
|
|
321
|
+
- Creates a GitHub Release with the plugin `.zip` attached.
|
|
322
|
+
|
|
323
|
+
Pre-release tags (`-rc1`, `-alpha`, `-beta`, `-dev`) trigger the full test
|
|
324
|
+
matrix as a rehearsal but skip every publish job, so the PyPI version slot is
|
|
325
|
+
not burned on a dry run. Only tags matching `vN.N.N` or `vN.N.N.postN` shapes
|
|
326
|
+
invoke the publish jobs.
|
|
327
|
+
|
|
328
|
+
### Partial-publish recovery
|
|
329
|
+
|
|
330
|
+
The three publish steps (PyPI, MCP Registry, GitHub Release) are
|
|
331
|
+
decoupled. If one succeeds and another fails:
|
|
332
|
+
|
|
333
|
+
- **PyPI** is immutable. Bump to `0.2.0.post1` in `pyproject.toml`, run
|
|
334
|
+
`sync-versions.py`, and retag `v0.2.0.post1`. The `.post1` PEP 440
|
|
335
|
+
post-release suffix signals the artifact identity is stable.
|
|
336
|
+
- **MCP Registry** accepts a retag of the same version number, so `.post1` is
|
|
337
|
+
only required when PyPI was the registry that succeeded.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Code of Conduct
|
|
342
|
+
|
|
343
|
+
A `CODE_OF_CONDUCT.md` lives at the repo root (Contributor Covenant 2.1 adoption).
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
MIT. By contributing you agree that your contributions are MIT-licensed under
|
|
350
|
+
the same terms as the rest of this project. See [LICENSE](../LICENSE).
|
waitbus-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Python build / cache artifacts
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# Virtualenv (managed by `uv sync` or `pip install -e`)
|
|
9
|
+
.venv/
|
|
10
|
+
|
|
11
|
+
# Test / type-check / property-test / lint caches
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.mypy_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.hypothesis/
|
|
16
|
+
.coverage
|
|
17
|
+
coverage.json
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# IDE / editor scratch
|
|
21
|
+
.vscode/
|
|
22
|
+
.idea/
|
|
23
|
+
|
|
24
|
+
# LSP/MCP project state cache (local, no upstream consumers)
|
|
25
|
+
.serena/
|
|
26
|
+
|
|
27
|
+
# Claude harness session state (per-conversation correlation IDs; not source)
|
|
28
|
+
.claude_correlation/
|
|
29
|
+
|
|
30
|
+
# Per-run benchmark output JSONs (host- and timestamp-stamped). Only the
|
|
31
|
+
# committed baselines under benchmarks/baselines/ are tracked; per-run
|
|
32
|
+
# results land here for ad-hoc inspection but are runner-specific.
|
|
33
|
+
benchmarks/results/*.json
|
|
34
|
+
|
|
35
|
+
# Vendored hetzner-bench-toolkit clone used by scripts/run_soak_on_hetzner.sh
|
|
36
|
+
# on the maintainer-side soak runner. It is an embedded git checkout that
|
|
37
|
+
# should not be tracked here and is already excluded from the sdist via
|
|
38
|
+
# `[tool.hatch.build.targets.sdist].exclude` in pyproject.toml.
|
|
39
|
+
scripts/.hbt/
|
|
40
|
+
|
|
41
|
+
# Crawl / context bundles (derived artifacts, never committed)
|
|
42
|
+
crawl-output/
|
|
43
|
+
|
|
44
|
+
# Operator-local pytest run logs (per-run timestamped .log + .junit.xml +
|
|
45
|
+
# warnings.log). Persistent across reboots so a failed / skipped / warned
|
|
46
|
+
# run can be retroactively inspected without re-execution. Drop here via
|
|
47
|
+
# scripts/run_full_pytest.sh.
|
|
48
|
+
.local-pytest-logs/
|
|
49
|
+
|
|
50
|
+
# Operator-local stress run logs (per-run timestamped .log + .verdict.json
|
|
51
|
+
# + .progress.jsonl). Persistent across reboots so an operator-driven
|
|
52
|
+
# real-mode stress invocation can be re-inspected without re-execution.
|
|
53
|
+
.local-stress-logs/
|
|
54
|
+
|
|
55
|
+
# Operator-local reference fixtures: live-recorded LLM envelopes the
|
|
56
|
+
# operator captures off ``claude -p`` / ``gemini -p`` runs and uses as a
|
|
57
|
+
# source-of-truth shape reference. The tests embed envelope content
|
|
58
|
+
# inline (see ``tests/test_stress_real_drivers.py``); this directory is
|
|
59
|
+
# the operator's working copy of the live captures and is not shipped.
|
|
60
|
+
tests/fixtures/
|
|
61
|
+
|
|
62
|
+
# Code-intelligence index snapshot — generated, rebuildable; not source.
|
|
63
|
+
codedb.snapshot
|
|
64
|
+
|
|
65
|
+
# Benchmark run output — per-run timestamped verdict/log/progress scratch the
|
|
66
|
+
# benches write here; a good run is promoted to benchmarks/baselines/ (which IS
|
|
67
|
+
# committed). The dir itself is kept via .gitkeep; individual runs are scratch.
|
|
68
|
+
benchmarks/results/*
|
|
69
|
+
!benchmarks/results/.gitkeep
|
|
70
|
+
|
|
71
|
+
# local soak-run outputs (fetched from Hetzner)
|
|
72
|
+
soak-verdict.json
|
|
73
|
+
soak-verdict.json.progress.jsonl
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **waitbus** are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Versioning
|
|
9
|
+
|
|
10
|
+
Pre-1.0 releases may refine the API based on real-world usage; v1.0 will
|
|
11
|
+
declare API stability after a period of stable public use.
|
|
12
|
+
|
|
13
|
+
## [0.1.0] — first public release
|
|
14
|
+
|
|
15
|
+
waitbus is a workstation-local async event bus for your machine's agents:
|
|
16
|
+
wait on anything from any source, and let your agents coordinate over the
|
|
17
|
+
same local bus. It is local-only (an `AF_UNIX` socket, no network egress),
|
|
18
|
+
durable (events persist to SQLite with replay), and zero-polling (an
|
|
19
|
+
`eventfd` doorbell wakes subscribers instead of a clock loop).
|
|
20
|
+
|
|
21
|
+
### Sources — wait on what already finished or failed
|
|
22
|
+
|
|
23
|
+
- **CI jobs** — a GitHub workflow run finishing or failing.
|
|
24
|
+
- **Test runs** — a pytest run passing or failing.
|
|
25
|
+
- **Containers** — docker container lifecycle events.
|
|
26
|
+
- **Filesystem** — file and directory changes.
|
|
27
|
+
- Third-party sources register through the `waitbus.sources.v1` entry-point group.
|
|
28
|
+
|
|
29
|
+
### Subscribers — any agent or script can wait and react
|
|
30
|
+
|
|
31
|
+
- **Agent frameworks** — Pydantic AI and LangGraph agents subscribe and react over the public SDK.
|
|
32
|
+
- **Claude Code** — receives pushes over the MCP notification channel.
|
|
33
|
+
- **Any MCP client** — pulls events via tool calls or a `tail_events` long-poll.
|
|
34
|
+
- **Scripts / CLI** — `waitbus wait`, plus hand-decoding subscriber snippets in Python, Go, Rust, and TypeScript.
|
|
35
|
+
|
|
36
|
+
### Core
|
|
37
|
+
|
|
38
|
+
- `waitbus wait <predicate>` blocks until a matching event arrives, with a
|
|
39
|
+
`since=` cursor for durable offline catch-up.
|
|
40
|
+
- Daemon broadcast fan-out delivers each event to every subscriber over its
|
|
41
|
+
own buffer.
|
|
42
|
+
- Cross-agent failure broadcast: when one peer fails, the rest of the swarm
|
|
43
|
+
is notified on the same bus.
|
|
44
|
+
- Broadcast wire protocol v1 (frozen): typed frames with an open `kind`
|
|
45
|
+
discriminator, an ack-first subscribe handshake, and an `event_id` identity
|
|
46
|
+
carried on every data frame.
|
|
47
|
+
- Backpressure with whole-frame delivery: a subscriber that falls behind is
|
|
48
|
+
evicted with a `subscribe_rejected{lag_limit_exceeded}` frame when the wire
|
|
49
|
+
sits at a frame boundary, or a clean EOF otherwise — never a torn frame.
|
|
50
|
+
- Opt-in loopback Prometheus `/metrics` on the broadcast daemon;
|
|
51
|
+
`waitbus_broadcast_events_delivered_total` counts event frames only, at
|
|
52
|
+
kernel-accept (control frames are never counted).
|
|
53
|
+
- `waitbus serve` supervises the broadcast daemon plus the configured source
|
|
54
|
+
watchers in one foreground process: a daemon crash or a startup failure
|
|
55
|
+
exits 1, and the docker watcher stops gracefully at shutdown.
|
|
56
|
+
|
|
57
|
+
### Install
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
pip install waitbus
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
[0.1.0]: https://github.com/astrogilda/waitbus/releases/tag/v0.1.0
|
waitbus-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sankalp Gilda
|
|
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.
|
waitbus-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
waitbus
|
|
2
|
+
Copyright (c) 2026 Sankalp Gilda
|
|
3
|
+
|
|
4
|
+
This product is licensed under the MIT License. See the LICENSE file for the
|
|
5
|
+
full license text.
|
|
6
|
+
|
|
7
|
+
This product bundles no third-party source code. It does, however, declare a
|
|
8
|
+
runtime dependency closure that `pip install waitbus` resolves and installs
|
|
9
|
+
alongside it. The packages below are NOT redistributed inside the waitbus sdist
|
|
10
|
+
or wheel; each is fetched from its own publisher and retains its own license
|
|
11
|
+
and copyright. They are enumerated here so downstream redistributors have a
|
|
12
|
+
single place to find the licenses that apply to a complete waitbus install.
|
|
13
|
+
|
|
14
|
+
A per-dependency license audit (method, resolved versions, verdict) is
|
|
15
|
+
recorded in docs/DEPENDENCY_LICENSES.md. Every license below is
|
|
16
|
+
redistribution-compatible with waitbus's MIT license. The one weak-copyleft
|
|
17
|
+
dependency, certifi (MPL-2.0), is file-level copyleft: its obligations attach
|
|
18
|
+
only to modifications of certifi's own files, not to the MIT-licensed work
|
|
19
|
+
that merely depends on it.
|
|
20
|
+
|
|
21
|
+
Licenses are taken from each package's published distribution metadata
|
|
22
|
+
(SPDX license expression, then OSI trove classifiers, then the License
|
|
23
|
+
field). Where the metadata gives an SPDX expression with a choice (for
|
|
24
|
+
example "MIT OR Apache-2.0"), waitbus exercises no election; the package
|
|
25
|
+
remains available under all of the offered terms.
|
|
26
|
+
|
|
27
|
+
------------------------------------------------------------------------------
|
|
28
|
+
Runtime dependencies (the closure `pip install waitbus` resolves)
|
|
29
|
+
------------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
Direct runtime dependencies (declared in pyproject.toml [project.dependencies]):
|
|
32
|
+
|
|
33
|
+
mcp MIT https://modelcontextprotocol.io
|
|
34
|
+
Copyright (c) Anthropic, PBC
|
|
35
|
+
msgspec BSD-3-Clause https://github.com/jcrist/msgspec
|
|
36
|
+
Copyright (c) Jim Crist-Harif
|
|
37
|
+
platformdirs MIT https://github.com/tox-dev/platformdirs
|
|
38
|
+
Copyright (c) The platformdirs developers
|
|
39
|
+
prometheus-client Apache-2.0 AND BSD-2-Clause https://github.com/prometheus/client_python
|
|
40
|
+
Copyright (c) The Prometheus Authors
|
|
41
|
+
pydantic-settings MIT https://github.com/pydantic/pydantic-settings
|
|
42
|
+
Copyright (c) Samuel Colvin and other contributors
|
|
43
|
+
stamina MIT https://github.com/hynek/stamina
|
|
44
|
+
Copyright (c) Hynek Schlawack
|
|
45
|
+
typer MIT https://github.com/fastapi/typer
|
|
46
|
+
Copyright (c) Sebastian Ramirez
|
|
47
|
+
|
|
48
|
+
Transitive runtime dependencies (pulled in by the packages above). Two
|
|
49
|
+
entries, colorama and pywin32, install only on Windows (they carry a
|
|
50
|
+
sys_platform == 'win32' marker) and are not installed on Linux or macOS:
|
|
51
|
+
|
|
52
|
+
annotated-doc MIT https://github.com/fastapi/annotated-doc
|
|
53
|
+
annotated-types MIT https://github.com/annotated-types/annotated-types
|
|
54
|
+
anyio MIT https://github.com/agronholm/anyio
|
|
55
|
+
attrs MIT https://github.com/python-attrs/attrs
|
|
56
|
+
certifi MPL-2.0 https://github.com/certifi/python-certifi
|
|
57
|
+
click BSD-3-Clause https://github.com/pallets/click
|
|
58
|
+
colorama BSD-3-Clause (Windows only) https://github.com/tartley/colorama
|
|
59
|
+
h11 MIT https://github.com/python-hyper/h11
|
|
60
|
+
httpcore BSD-3-Clause https://github.com/encode/httpcore
|
|
61
|
+
httpx BSD-3-Clause https://github.com/encode/httpx
|
|
62
|
+
httpx-sse MIT https://github.com/florimondmanca/httpx-sse
|
|
63
|
+
idna BSD-3-Clause https://github.com/kjd/idna
|
|
64
|
+
jsonschema MIT https://github.com/python-jsonschema/jsonschema
|
|
65
|
+
jsonschema-specifications MIT https://github.com/python-jsonschema/jsonschema-specifications
|
|
66
|
+
markdown-it-py MIT https://github.com/executablebooks/markdown-it-py
|
|
67
|
+
mdurl MIT https://github.com/executablebooks/mdurl
|
|
68
|
+
pydantic MIT https://github.com/pydantic/pydantic
|
|
69
|
+
pydantic-core MIT https://github.com/pydantic/pydantic-core
|
|
70
|
+
pygments BSD-2-Clause https://github.com/pygments/pygments
|
|
71
|
+
pyjwt MIT https://github.com/jpadilla/pyjwt
|
|
72
|
+
python-dotenv BSD-3-Clause https://github.com/theskumar/python-dotenv
|
|
73
|
+
python-multipart Apache-2.0 https://github.com/Kludex/python-multipart
|
|
74
|
+
pywin32 PSF-2.0 (Windows only) https://github.com/mhammond/pywin32
|
|
75
|
+
referencing MIT https://github.com/python-jsonschema/referencing
|
|
76
|
+
rich MIT https://github.com/Textualize/rich
|
|
77
|
+
rpds-py MIT https://github.com/crate-py/rpds
|
|
78
|
+
shellingham ISC https://github.com/sarugaku/shellingham
|
|
79
|
+
sse-starlette BSD-3-Clause https://github.com/sysid/sse-starlette
|
|
80
|
+
starlette BSD-3-Clause https://github.com/encode/starlette
|
|
81
|
+
tenacity Apache-2.0 https://github.com/jd/tenacity
|
|
82
|
+
typing-extensions PSF-2.0 https://github.com/python/typing_extensions
|
|
83
|
+
typing-inspection MIT https://github.com/pydantic/typing-inspection
|
|
84
|
+
uvicorn BSD-3-Clause https://github.com/encode/uvicorn
|
|
85
|
+
|
|
86
|
+
------------------------------------------------------------------------------
|
|
87
|
+
Optional dependencies (installed only via the matching extra)
|
|
88
|
+
------------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
[analyze] duckdb MIT https://github.com/duckdb/duckdb
|
|
91
|
+
[fs] watchdog Apache-2.0 https://github.com/gorakhargosh/watchdog
|
|
92
|
+
[bench] / [soak] hdrhistogram Apache-2.0 https://github.com/HdrHistogram/HdrHistogram_py
|
|
93
|
+
[bench] / [soak] pbr Apache-2.0 https://opendev.org/openstack/pbr
|
|
94
|
+
[bench] / [soak] setuptools MIT https://github.com/pypa/setuptools
|
|
95
|
+
[bench] tiktoken MIT https://github.com/openai/tiktoken
|
|
96
|
+
[bench] regex Apache-2.0 AND CNRI-Python https://github.com/mrabarnett/mrab-regex
|
|
97
|
+
[bench] requests Apache-2.0 https://github.com/psf/requests
|
|
98
|
+
[bench] charset-normalizer MIT https://github.com/jawah/charset_normalizer
|
|
99
|
+
[plugin-verify] pypi-attestations Apache-2.0 https://github.com/trailofbits/pypi-attestations
|
|
100
|
+
[plugin-verify] sigstore Apache-2.0 https://github.com/sigstore/sigstore-python
|
|
101
|
+
[plugin-verify] sigstore-models Apache-2.0 https://github.com/sigstore/sigstore-python
|
|
102
|
+
[plugin-verify] sigstore-rekor-types Apache-2.0 https://github.com/sigstore/rekor
|
|
103
|
+
[plugin-verify] cryptography Apache-2.0 OR BSD-3-Clause https://github.com/pyca/cryptography
|
|
104
|
+
[plugin-verify] pyopenssl Apache-2.0 https://github.com/pyca/pyopenssl
|
|
105
|
+
[plugin-verify] cffi MIT https://github.com/python-cffi/cffi
|
|
106
|
+
[plugin-verify] pycparser BSD-3-Clause https://github.com/eliben/pycparser
|
|
107
|
+
[plugin-verify] pyasn1 BSD-2-Clause https://github.com/pyasn1/pyasn1
|
|
108
|
+
[plugin-verify] securesystemslib MIT https://github.com/secure-systems-lab/securesystemslib
|
|
109
|
+
[plugin-verify] tuf Apache-2.0 OR MIT https://github.com/theupdateframework/python-tuf
|
|
110
|
+
[plugin-verify] id Apache-2.0 https://github.com/di/id
|
|
111
|
+
[plugin-verify] rfc3161-client Apache-2.0 https://github.com/trailofbits/rfc3161-client
|
|
112
|
+
[plugin-verify] rfc3986 Apache-2.0 https://github.com/python-hyper/rfc3986
|
|
113
|
+
[plugin-verify] rfc8785 Apache-2.0 https://github.com/trailofbits/rfc8785.py
|
|
114
|
+
[plugin-verify] packaging Apache-2.0 OR BSD-2-Clause https://github.com/pypa/packaging
|
|
115
|
+
[plugin-verify] requests Apache-2.0 https://github.com/psf/requests
|
|
116
|
+
[plugin-verify] charset-normalizer MIT https://github.com/jawah/charset_normalizer
|
|
117
|
+
[plugin-verify] urllib3 MIT https://github.com/urllib3/urllib3
|
|
118
|
+
|
|
119
|
+
Copyright holders for the transitive and optional packages above are recorded
|
|
120
|
+
in each package's own distribution metadata and license file; consult the
|
|
121
|
+
project URLs for the authoritative copyright and license text.
|