Skip to main content

taskswarm (Python)

Self-hosted event server that pushes a notification the instant a parallel coding-agent session blocks, needs review, fails, or finishes.

PyPI version License: MIT Python versions CI

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

Live on PyPI as taskswarm-cli (renamed from the original taskswarm package, which has stopped receiving updates and points here):

pip install taskswarm-cli

or with uv:

uv add taskswarm-cli

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.

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 start boots an HTTP+SSE server (stdlib http.server, no framework dependency) that accepts POST /events, serves GET /events for current session state, and streams new events over GET /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, or done, TaskSwarm fires a native OS notification (osascript on 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-code writes Stop and Notification hook 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 /events and the live page both require the token TaskSwarm generates on first run (~/.taskswarm/config.json, written 0600). Rotate it with taskswarm token rotate.
  • Agent-native by design. Every subcommand ships a --json flag 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 the installed package's own version number, read live from pyproject.toml (so it always matches whatever release you actually have installed, rather than a fixed number that would go stale here). 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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

taskswarm_cli-0.1.2.tar.gz (42.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

taskswarm_cli-0.1.2-py3-none-any.whl (41.2 kB view details)

Uploaded Python 3

File details

Details for the file taskswarm_cli-0.1.2.tar.gz.

File metadata

  • Download URL: taskswarm_cli-0.1.2.tar.gz
  • Upload date:
  • Size: 42.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for taskswarm_cli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 490640916fc79da58175fc184427704fc4c19fc6f0bd8afee9b834da29f3c1c7
MD5 a0bcb3339a7bb6c2671012495bead573
BLAKE2b-256 47d7bdc50cca03bbaf73192cdf3685f8e949136cc30b8f84fd5c2a2b9bdac8c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for taskswarm_cli-0.1.2.tar.gz:

Publisher: publish-pypi.yml on RudrenduPaul/taskswarm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file taskswarm_cli-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: taskswarm_cli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 41.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for taskswarm_cli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 970b2d7002ef6aa82fd94825292f6f7b5115fe02ed7f879b6a7beb3eb7a65366
MD5 c14b0cef66c9cf1b9a485757cbe793f9
BLAKE2b-256 e32d4f375caccd2f7c3213256572752a2da89ac206b00cf3e913f66404739cc2

See more details on using hashes here.

Provenance

The following attestation bundles were made for taskswarm_cli-0.1.2-py3-none-any.whl:

Publisher: publish-pypi.yml on RudrenduPaul/taskswarm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.4

2 files

0.1.3

2 files

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page