Self-hosted event server that pushes a notification the instant a parallel coding-agent session blocks, needs review, fails, or finishes.
Project description
taskswarm (Python)
Self-hosted event server that pushes a notification the instant a parallel coding-agent session blocks, needs review, fails, or finishes.
Why this exists
Running three or four coding-agent sessions in parallel turns into a
tab-switching problem: nothing pushes state to you, so you find out a
session has been sitting on a permission prompt for ten minutes only by
polling terminals by eye. TaskSwarm closes that gap: every agent session
reports its state to a small local HTTP server, and the instant one
transitions to blocked, needs-review, failed, or done, TaskSwarm
fires a local OS notification and updates a live status page over
Server-Sent Events. No polling, no account, no cloud dependency by default.
This package is the Python distribution of TaskSwarm -- a genuine, independent port of the server, CLI, event schema, and notification logic, not a wrapper around the Node binary. It has zero runtime dependencies: no HTTP framework, no schema-validation library, nothing beyond the Python standard library.
Install
Publish status: this package is fully built and tested (117 passing
tests, a real end-to-end server-lifecycle suite included), with a built
wheel and sdist ready to go. The pip install taskswarm publish itself is
pending -- PyPI's account-level "too many new projects created" rate
limit blocked the first upload for this account, unrelated to code
readiness. Until that clears:
git clone https://github.com/RudrenduPaul/taskswarm.git
cd taskswarm/python
pip install -e .
Once published:
pip install taskswarm
or with uv:
uv add taskswarm
The complementary JS/TS distribution is already live on npm as
taskswarm-cli (npm install -g taskswarm-cli, or npx taskswarm-cli start with no install step) -- see the
project README for
that package. Both are first-class and maintained together; neither is a
replacement for the other. This Python port is the one still waiting on
its first publish.
Quickstart
# Terminal 1: start the server
taskswarm start
# TaskSwarm server listening on http://127.0.0.1:4173
# Live status page: http://127.0.0.1:4173/?token=<your-token>
# Terminal 2: report a session's status as it works
taskswarm agent report-status --task my-fix --repo ./api --state running
taskswarm agent report-status --task my-fix --repo ./api --state done
Open the live status page URL printed by start. The row for my-fix
updates the instant each report-status call lands, no refresh.
Or call the library directly, in-process, without a subprocess:
from taskswarm import start_server
from taskswarm.adapters import GenericAdapter
from taskswarm.client.api_client import post_event
running = start_server()
adapter = GenericAdapter()
event_input = adapter.to_event_input(
{"session_id": "my-fix", "repo": "./api", "status": "done", "agent_type": "generic"}
)
event = post_event(running.config.to_dict(), event_input)
print(event["session_id"], "->", event["status"])
running.close()
What it does
- Event server, not a board you have to keep open.
taskswarm startboots an HTTP+SSE server (stdlibhttp.server, no framework dependency) that acceptsPOST /events, servesGET /eventsfor current session state, and streams new events overGET /live(Server-Sent Events) to the bundled live status page. - Push notification on the four states that mean "look at this now."
The moment a session's status transitions to
blocked,needs-review,failed, ordone, TaskSwarm fires a native OS notification (osascripton macOS, a terminal-bell console fallback elsewhere). Notification dedup keys on the(status, blocked_reason)pair, so a second, different permission prompt still notifies even though the status (needs-review) didn't change. - A wrapper-script adapter for any agent.
taskswarm agent report-status --task <id> --repo <path> --state <state>is the one primitive every integration is built on -- callable from any script wrapping any CLI agent (Codex, Cursor, or anything else). - A Claude Code hooks adapter, ported with the same behavior as the npm
package's:
taskswarm hooks install claude-codewritesStopandNotificationhook entries into.claude/settings.json, pointed at the exact, already-installed console script on disk (never a floating PATH lookup re-resolved on every hook fire). - A bearer-token-gated local API, bound to loopback by default.
POST /eventsand the live page both require the token TaskSwarm generates on first run (~/.taskswarm/config.json, written0600). Rotate it withtaskswarm token rotate. - Agent-native by design. Every subcommand ships a
--jsonflag with a stable schema, including error output. - ntfy.sh is opt-in, never default. The only notification channel that
leaves your machine, and it's off unless you configure it in
~/.taskswarm/config.json.
CLI reference
| Command | Description | Key options |
|---|---|---|
taskswarm start |
Start the TaskSwarm server and print the live status page URL | --json |
taskswarm task add |
Register a new task | --title <title> (required), --repo <path> (required), --json |
taskswarm task list |
List tracked tasks, enriched with live status when the server is reachable | --json |
taskswarm agent report-status |
Report a status transition for a task/session to the local server | --task <id> (required), --repo <path> (required), --state <state> (required, one of queued|running|blocked|needs-review|done|failed), --blocked-reason <text>, --agent-type <type> (claude-code|codex|cursor|generic, default generic), --json |
taskswarm token rotate |
Generate a new bearer token, invalidating the old one | --json |
taskswarm hooks install <adapter> |
Install hooks for an agent integration (currently claude-code) |
--scope <project|local|user> (default project), --project-dir <path>, --json |
taskswarm hooks claude-code-relay |
Internal: reads a hook payload from stdin and relays it. Installed automatically; not meant to be run by hand. | none |
taskswarm --version prints taskswarm 0.1.0. The taskswarm-cli console
script installed by this package is an identical alias, matching both bin
entries the npm package ships.
How it works
agent session / hook / wrapper script
|
v
POST /events (bearer token required) -> event schema validation
|
v
EventStore (in-memory + append-only JSONL log at ~/.taskswarm/events.jsonl)
|
+--> notify() -- fires on a transition into blocked/needs-review/failed/done
| |
| +--> local OS notification (always on)
| +--> ntfy.sh (opt-in only)
|
+--> GET /live (Server-Sent Events) -> live status page
Full data model and the exact notification-dedup rule are in docs/concepts.md.
Security
The local API is gated by a bearer token generated on first run and stored
0600 at ~/.taskswarm/config.json; the server binds to 127.0.0.1 by
default. Token comparison uses hmac.compare_digest (constant-time,
avoiding timing side-channels), the same property the TypeScript version
gets from crypto.timingSafeEqual. See
SECURITY.md
for the full posture, including what this server does not protect
against (it is a local developer tool, not designed to be exposed on a
shared or public network). Honest note: this project does not currently
publish SLSA provenance, Sigstore signatures, or an SBOM, and has no
OpenSSF Scorecard badge -- none of that infrastructure exists yet for
either distribution, so it isn't claimed here.
Contributing
See CONTRIBUTING.md for the full guide, covering both the TypeScript and Python codebases.
cd python
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
License
MIT, see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file taskswarm-0.1.0.tar.gz.
File metadata
- Download URL: taskswarm-0.1.0.tar.gz
- Upload date:
- Size: 42.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17d802e57692b7ead0bde996b9d20bc21c1bc51efc60264a8ce79b04dfad4736
|
|
| MD5 |
57530e18d386173447cef8797280f8f1
|
|
| BLAKE2b-256 |
5fb07504537891be97bdcaa4569b6bef2edb8b8f633bdeea7a65d4ac0f7e8af9
|
File details
Details for the file taskswarm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: taskswarm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d10ce8e14578b8b945483f49c39d4290fe2d981e6e5d1ea0ccb27655efe4536
|
|
| MD5 |
cead378d774bb82ff4a1afe1fe2c194f
|
|
| BLAKE2b-256 |
edb1d3c14ffba8b5855bb05a74244237e943a65b3df092a654d18f97ba4e9a79
|