taskswarm-cli 0.1.0__py3-none-any.whl

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,217 @@
1
+ Metadata-Version: 2.4
2
+ Name: taskswarm-cli
3
+ Version: 0.1.0
4
+ Summary: Self-hosted event server that pushes a notification the instant a parallel coding-agent session blocks, needs review, fails, or finishes.
5
+ Project-URL: Homepage, https://github.com/RudrenduPaul/taskswarm
6
+ Project-URL: Repository, https://github.com/RudrenduPaul/taskswarm
7
+ Project-URL: Bug Tracker, https://github.com/RudrenduPaul/taskswarm/issues
8
+ Project-URL: Changelog, https://github.com/RudrenduPaul/taskswarm/blob/main/CHANGELOG.md
9
+ Project-URL: Documentation, https://github.com/RudrenduPaul/taskswarm/blob/main/docs/getting-started.md
10
+ Project-URL: Author - Rudrendu Paul, https://github.com/RudrenduPaul
11
+ Project-URL: Author - Sourav Nandy, https://github.com/Sourav-nandy-ai
12
+ Author: Rudrendu Paul, Sourav Nandy
13
+ License-Expression: MIT
14
+ License-File: LICENSE
15
+ Keywords: claude-code,cli,coding-agent,dashboard,event-server,multi-agent,notifications,orchestration,self-hosted
16
+ Classifier: Development Status :: 3 - Alpha
17
+ Classifier: Environment :: Console
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Programming Language :: Python :: 3
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Programming Language :: Python :: 3.11
25
+ Classifier: Programming Language :: Python :: 3.12
26
+ Classifier: Programming Language :: Python :: 3.13
27
+ Classifier: Topic :: Software Development :: Build Tools
28
+ Classifier: Topic :: System :: Monitoring
29
+ Requires-Python: >=3.9
30
+ Provides-Extra: dev
31
+ Requires-Dist: build<2,>=1.0; extra == 'dev'
32
+ Requires-Dist: pytest<9,>=7.0; extra == 'dev'
33
+ Requires-Dist: twine<7,>=5.0; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # taskswarm (Python)
37
+
38
+ Self-hosted event server that pushes a notification the instant a parallel
39
+ coding-agent session blocks, needs review, fails, or finishes.
40
+
41
+ [![PyPI version](https://img.shields.io/pypi/v/taskswarm.svg)](https://pypi.org/project/taskswarm/)
42
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/RudrenduPaul/taskswarm/blob/main/LICENSE)
43
+ [![Python versions](https://img.shields.io/pypi/pyversions/taskswarm.svg)](https://pypi.org/project/taskswarm/)
44
+ [![CI](https://github.com/RudrenduPaul/taskswarm/actions/workflows/ci.yml/badge.svg)](https://github.com/RudrenduPaul/taskswarm/actions/workflows/ci.yml)
45
+
46
+ ## Why this exists
47
+
48
+ Running three or four coding-agent sessions in parallel turns into a
49
+ tab-switching problem: nothing pushes state to you, so you find out a
50
+ session has been sitting on a permission prompt for ten minutes only by
51
+ polling terminals by eye. TaskSwarm closes that gap: every agent session
52
+ reports its state to a small local HTTP server, and the instant one
53
+ transitions to `blocked`, `needs-review`, `failed`, or `done`, TaskSwarm
54
+ fires a local OS notification and updates a live status page over
55
+ Server-Sent Events. No polling, no account, no cloud dependency by default.
56
+
57
+ This package is the **Python distribution** of TaskSwarm -- a genuine,
58
+ independent port of the server, CLI, event schema, and notification logic,
59
+ not a wrapper around the Node binary. It has zero runtime dependencies: no
60
+ HTTP framework, no schema-validation library, nothing beyond the Python
61
+ standard library.
62
+
63
+ ## Install
64
+
65
+ Live on PyPI as `taskswarm`:
66
+
67
+ ```bash
68
+ pip install taskswarm
69
+ ```
70
+
71
+ or with [uv](https://docs.astral.sh/uv/):
72
+
73
+ ```bash
74
+ uv add taskswarm
75
+ ```
76
+
77
+ The complementary JS/TS distribution is already live on npm as
78
+ `taskswarm-cli` (`npm install -g taskswarm-cli`, or `npx taskswarm-cli
79
+ start` with no install step) -- see the
80
+ [project README](https://github.com/RudrenduPaul/taskswarm#readme) for
81
+ that package. Both are first-class and maintained together; neither is a
82
+ replacement for the other.
83
+
84
+ ## Quickstart
85
+
86
+ ```bash
87
+ # Terminal 1: start the server
88
+ taskswarm start
89
+ # TaskSwarm server listening on http://127.0.0.1:4173
90
+ # Live status page: http://127.0.0.1:4173/?token=<your-token>
91
+
92
+ # Terminal 2: report a session's status as it works
93
+ taskswarm agent report-status --task my-fix --repo ./api --state running
94
+ taskswarm agent report-status --task my-fix --repo ./api --state done
95
+ ```
96
+
97
+ Open the live status page URL printed by `start`. The row for `my-fix`
98
+ updates the instant each `report-status` call lands, no refresh.
99
+
100
+ Or call the library directly, in-process, without a subprocess:
101
+
102
+ ```python
103
+ from taskswarm import start_server
104
+ from taskswarm.adapters import GenericAdapter
105
+ from taskswarm.client.api_client import post_event
106
+
107
+ running = start_server()
108
+ adapter = GenericAdapter()
109
+ event_input = adapter.to_event_input(
110
+ {"session_id": "my-fix", "repo": "./api", "status": "done", "agent_type": "generic"}
111
+ )
112
+ event = post_event(running.config.to_dict(), event_input)
113
+ print(event["session_id"], "->", event["status"])
114
+ running.close()
115
+ ```
116
+
117
+ ## What it does
118
+
119
+ - **Event server, not a board you have to keep open.** `taskswarm start`
120
+ boots an HTTP+SSE server (stdlib `http.server`, no framework dependency)
121
+ that accepts `POST /events`, serves `GET /events` for current session
122
+ state, and streams new events over `GET /live` (Server-Sent Events) to
123
+ the bundled live status page.
124
+ - **Push notification on the four states that mean "look at this now."**
125
+ The moment a session's status transitions to `blocked`, `needs-review`,
126
+ `failed`, or `done`, TaskSwarm fires a native OS notification
127
+ (`osascript` on macOS, a terminal-bell console fallback elsewhere).
128
+ Notification dedup keys on the `(status, blocked_reason)` pair, so a
129
+ second, different permission prompt still notifies even though the
130
+ status (`needs-review`) didn't change.
131
+ - **A wrapper-script adapter for any agent.**
132
+ `taskswarm agent report-status --task <id> --repo <path> --state <state>`
133
+ is the one primitive every integration is built on -- callable from any
134
+ script wrapping any CLI agent (Codex, Cursor, or anything else).
135
+ - **A Claude Code hooks adapter**, ported with the same behavior as the npm
136
+ package's: `taskswarm hooks install claude-code` writes `Stop` and
137
+ `Notification` hook entries into `.claude/settings.json`, pointed at the
138
+ exact, already-installed console script on disk (never a floating PATH
139
+ lookup re-resolved on every hook fire).
140
+ - **A bearer-token-gated local API, bound to loopback by default.**
141
+ `POST /events` and the live page both require the token TaskSwarm
142
+ generates on first run (`~/.taskswarm/config.json`, written `0600`).
143
+ Rotate it with `taskswarm token rotate`.
144
+ - **Agent-native by design.** Every subcommand ships a `--json` flag with a
145
+ stable schema, including error output.
146
+ - **ntfy.sh is opt-in, never default.** The only notification channel that
147
+ leaves your machine, and it's off unless you configure it in
148
+ `~/.taskswarm/config.json`.
149
+
150
+ ## CLI reference
151
+
152
+ | Command | Description | Key options |
153
+ | ----------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
154
+ | `taskswarm start` | Start the TaskSwarm server and print the live status page URL | `--json` |
155
+ | `taskswarm task add` | Register a new task | `--title <title>` (required), `--repo <path>` (required), `--json` |
156
+ | `taskswarm task list` | List tracked tasks, enriched with live status when the server is reachable | `--json` |
157
+ | `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` |
158
+ | `taskswarm token rotate` | Generate a new bearer token, invalidating the old one | `--json` |
159
+ | `taskswarm hooks install <adapter>` | Install hooks for an agent integration (currently `claude-code`) | `--scope <project\|local\|user>` (default `project`), `--project-dir <path>`, `--json` |
160
+ | `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 |
161
+
162
+ `taskswarm --version` prints `taskswarm 0.1.0`. The `taskswarm-cli` console
163
+ script installed by this package is an identical alias, matching both `bin`
164
+ entries the npm package ships.
165
+
166
+ ## How it works
167
+
168
+ ```
169
+ agent session / hook / wrapper script
170
+ |
171
+ v
172
+ POST /events (bearer token required) -> event schema validation
173
+ |
174
+ v
175
+ EventStore (in-memory + append-only JSONL log at ~/.taskswarm/events.jsonl)
176
+ |
177
+ +--> notify() -- fires on a transition into blocked/needs-review/failed/done
178
+ | |
179
+ | +--> local OS notification (always on)
180
+ | +--> ntfy.sh (opt-in only)
181
+ |
182
+ +--> GET /live (Server-Sent Events) -> live status page
183
+ ```
184
+
185
+ Full data model and the exact notification-dedup rule are in
186
+ [docs/concepts.md](https://github.com/RudrenduPaul/taskswarm/blob/main/docs/concepts.md).
187
+
188
+ ## Security
189
+
190
+ The local API is gated by a bearer token generated on first run and stored
191
+ `0600` at `~/.taskswarm/config.json`; the server binds to `127.0.0.1` by
192
+ default. Token comparison uses `hmac.compare_digest` (constant-time,
193
+ avoiding timing side-channels), the same property the TypeScript version
194
+ gets from `crypto.timingSafeEqual`. See
195
+ [SECURITY.md](https://github.com/RudrenduPaul/taskswarm/blob/main/SECURITY.md)
196
+ for the full posture, including what this server does **not** protect
197
+ against (it is a local developer tool, not designed to be exposed on a
198
+ shared or public network). **Honest note**: this project does not currently
199
+ publish SLSA provenance, Sigstore signatures, or an SBOM, and has no
200
+ OpenSSF Scorecard badge -- none of that infrastructure exists yet for
201
+ either distribution, so it isn't claimed here.
202
+
203
+ ## Contributing
204
+
205
+ See [CONTRIBUTING.md](https://github.com/RudrenduPaul/taskswarm/blob/main/CONTRIBUTING.md)
206
+ for the full guide, covering both the TypeScript and Python codebases.
207
+
208
+ ```bash
209
+ cd python
210
+ python3 -m venv .venv && source .venv/bin/activate
211
+ pip install -e ".[dev]"
212
+ pytest
213
+ ```
214
+
215
+ ## License
216
+
217
+ MIT, see [LICENSE](https://github.com/RudrenduPaul/taskswarm/blob/main/LICENSE).
@@ -0,0 +1,30 @@
1
+ taskswarm/__init__.py,sha256=YKU8D5Ojv2GkYuH6lKwLc29qzcYlSp5FvQtEe5rjz2E,1947
2
+ taskswarm/cli.py,sha256=l9xY2VVdwmm-9bQHmC5z2ZnvL1vcHyHDby-_tWjdhOk,12160
3
+ taskswarm/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ taskswarm/adapters/__init__.py,sha256=otjh_TU2gWSAUOLH_LU55tpJ1Id0xQM8R2-pxeJDutc,323
5
+ taskswarm/adapters/claude_code_adapter.py,sha256=uuAD4SMAoht_TqUeyWoUw0gbkY18vyj3BmBWmDO_v4k,9837
6
+ taskswarm/adapters/generic_adapter.py,sha256=UGG7rZ8Tt1w2dYqNvFOwkJH-wlFK3Qg-bGPQq-EoTX4,1927
7
+ taskswarm/adapters/types.py,sha256=3GonzdISwccugOQSMWt1DqdPzZ8k8SnOjkiHYe7GoiE,801
8
+ taskswarm/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ taskswarm/client/api_client.py,sha256=IBlmOditARXPG_e2clGCVALaDlnxtEJxENMFiEowQVI,2422
10
+ taskswarm/client/tasks_registry.py,sha256=kIY90Ee1HctlWzKy_hPLceMB-5wtzNnJMXS4wDXIfpI,4029
11
+ taskswarm/notifications/__init__.py,sha256=o7OzCZn2ZhSEO4maHXfc9d5K_E9kT0QhkkC8C56lwm0,115
12
+ taskswarm/notifications/dispatch.py,sha256=7ZzlQrM8MBDxLSMbeWT-DExhadsGCbDjyWQqudTS2Wc,3641
13
+ taskswarm/notifications/ntfy.py,sha256=yj0Dylf1u-y6giSrVemdNsdaYer47GUd0yvr5KYaa0M,2622
14
+ taskswarm/notifications/os_notify.py,sha256=Cv1wkgGlMJJbHeOsY3o27qrDwpKQa7ZuMFjw8xL-sfI,2324
15
+ taskswarm/schema/__init__.py,sha256=cyWQUq_bTQ0QUl9wAHygmjSreJ9skLwy25lWHVsgO0o,463
16
+ taskswarm/schema/events.py,sha256=1y7xL943s-MWGpSmgclEdly9YKV4sAvl2cCn0d7d2h0,8494
17
+ taskswarm/server/__init__.py,sha256=pvxFZ9Q66KshNDMQ7emTj7hjwz2J7VosJrLXhmTPY1U,720
18
+ taskswarm/server/auth.py,sha256=HoyGEBUlqRhjr6qxBDHFdlvVUKLx2GQLkrWhRabUv9o,1015
19
+ taskswarm/server/config.py,sha256=sgbAaNtMG7OaOcg8XT0V_nCV06qwu9X3pcCZ4FHaXy4,5130
20
+ taskswarm/server/event_store.py,sha256=Na7sUBy7DlIQ4TlgJuhSQMiy9j5FdVaYpXtt6U6uiBY,5942
21
+ taskswarm/server/http_server.py,sha256=r6ZigVXkLf38vOrFYoIuveXD0COJCB0hpxmC5jHByAE,9679
22
+ taskswarm/server/server.py,sha256=jkHOhKyEkjk-Rv8OGY8vYBI9_4dWDcIcdQf8wNs6Ot0,2818
23
+ taskswarm/ui/index.html,sha256=_pA-s0HLPOxDRV7N6a7k4bSdXQ5xDhiA_sUs2MVHTQ8,6596
24
+ taskswarm/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ taskswarm/util/sync_sleep.py,sha256=QrMEpagV5bjdzfs-UC4PkNDYRimUw0zWY9VVbNcZn-0,673
26
+ taskswarm_cli-0.1.0.dist-info/METADATA,sha256=uzpjCOY8ZlANh_z17kfXQBPNlwdpOssBR87D_Ee9xrQ,12693
27
+ taskswarm_cli-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
28
+ taskswarm_cli-0.1.0.dist-info/entry_points.txt,sha256=bev456K-eZwGlQ_BEKgSn508VXTrG8-msjhXYTL4SZs,84
29
+ taskswarm_cli-0.1.0.dist-info/licenses/LICENSE,sha256=BfVFjPafHBvDFGiOExHmSA9zx3abipLGkjV1O2MZj9Y,1070
30
+ taskswarm_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ taskswarm = taskswarm.cli:main
3
+ taskswarm-cli = taskswarm.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rudrendu Paul
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.