spartito 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.
- spartito-0.1.0/LICENSE +21 -0
- spartito-0.1.0/PKG-INFO +221 -0
- spartito-0.1.0/README.md +185 -0
- spartito-0.1.0/pyproject.toml +86 -0
- spartito-0.1.0/pyproject.toml.orig +86 -0
- spartito-0.1.0/src/orchestrator/__init__.py +11 -0
- spartito-0.1.0/src/orchestrator/__main__.py +6 -0
- spartito-0.1.0/src/orchestrator/app_open.py +105 -0
- spartito-0.1.0/src/orchestrator/autostart.py +435 -0
- spartito-0.1.0/src/orchestrator/board.py +600 -0
- spartito-0.1.0/src/orchestrator/cli.py +1570 -0
- spartito-0.1.0/src/orchestrator/config.py +93 -0
- spartito-0.1.0/src/orchestrator/core/__init__.py +11 -0
- spartito-0.1.0/src/orchestrator/core/access.py +89 -0
- spartito-0.1.0/src/orchestrator/core/archive.py +281 -0
- spartito-0.1.0/src/orchestrator/core/board_git.py +259 -0
- spartito-0.1.0/src/orchestrator/core/boards.py +392 -0
- spartito-0.1.0/src/orchestrator/core/compaction.py +191 -0
- spartito-0.1.0/src/orchestrator/core/delivery.py +163 -0
- spartito-0.1.0/src/orchestrator/core/dispatch.py +312 -0
- spartito-0.1.0/src/orchestrator/core/launcher.py +88 -0
- spartito-0.1.0/src/orchestrator/core/lifecycle.py +80 -0
- spartito-0.1.0/src/orchestrator/core/notices.py +218 -0
- spartito-0.1.0/src/orchestrator/core/reads.py +93 -0
- spartito-0.1.0/src/orchestrator/core/setup.py +176 -0
- spartito-0.1.0/src/orchestrator/core/views.py +278 -0
- spartito-0.1.0/src/orchestrator/decisions.py +216 -0
- spartito-0.1.0/src/orchestrator/desktop.py +1553 -0
- spartito-0.1.0/src/orchestrator/errors.py +12 -0
- spartito-0.1.0/src/orchestrator/git.py +354 -0
- spartito-0.1.0/src/orchestrator/gui/__init__.py +1 -0
- spartito-0.1.0/src/orchestrator/gui/icon.icns +0 -0
- spartito-0.1.0/src/orchestrator/gui/launcher.py +466 -0
- spartito-0.1.0/src/orchestrator/gui/locate.py +40 -0
- spartito-0.1.0/src/orchestrator/gui/menubar.py +315 -0
- spartito-0.1.0/src/orchestrator/gui/notifier.py +906 -0
- spartito-0.1.0/src/orchestrator/gui/window.py +1089 -0
- spartito-0.1.0/src/orchestrator/keep_awake.py +118 -0
- spartito-0.1.0/src/orchestrator/loadout.py +201 -0
- spartito-0.1.0/src/orchestrator/mcp_server.py +640 -0
- spartito-0.1.0/src/orchestrator/memory_guard.py +190 -0
- spartito-0.1.0/src/orchestrator/models.py +256 -0
- spartito-0.1.0/src/orchestrator/notify.py +365 -0
- spartito-0.1.0/src/orchestrator/providers/__init__.py +36 -0
- spartito-0.1.0/src/orchestrator/providers/base.py +112 -0
- spartito-0.1.0/src/orchestrator/providers/claude.py +453 -0
- spartito-0.1.0/src/orchestrator/providers/codex.py +242 -0
- spartito-0.1.0/src/orchestrator/replies.py +99 -0
- spartito-0.1.0/src/orchestrator/roles/lead.md +54 -0
- spartito-0.1.0/src/orchestrator/roles/orchestrator.md +54 -0
- spartito-0.1.0/src/orchestrator/roles/planner.md +18 -0
- spartito-0.1.0/src/orchestrator/roles/planner.schema.json +72 -0
- spartito-0.1.0/src/orchestrator/roles/reviewer.md +22 -0
- spartito-0.1.0/src/orchestrator/roles/reviewer.schema.json +64 -0
- spartito-0.1.0/src/orchestrator/roles/tester.md +21 -0
- spartito-0.1.0/src/orchestrator/roles/tester.schema.json +65 -0
- spartito-0.1.0/src/orchestrator/roles/worker.md +24 -0
- spartito-0.1.0/src/orchestrator/roles/worker.schema.json +61 -0
- spartito-0.1.0/src/orchestrator/roles.py +198 -0
- spartito-0.1.0/src/orchestrator/runner.py +908 -0
- spartito-0.1.0/src/orchestrator/service.py +358 -0
- spartito-0.1.0/src/orchestrator/settings.py +240 -0
- spartito-0.1.0/src/orchestrator/store.py +1559 -0
- spartito-0.1.0/src/orchestrator/textfmt.py +22 -0
- spartito-0.1.0/src/orchestrator/timeline.py +136 -0
- spartito-0.1.0/src/orchestrator/web/__init__.py +0 -0
- spartito-0.1.0/src/orchestrator/web/app.py +490 -0
- spartito-0.1.0/src/orchestrator/web/board_api.py +118 -0
- spartito-0.1.0/src/orchestrator/web/index.html +215 -0
- spartito-0.1.0/src/orchestrator/web/serve.py +94 -0
- spartito-0.1.0/src/orchestrator/web/static/app.css +366 -0
- spartito-0.1.0/src/orchestrator/web/static/app.js +1786 -0
- spartito-0.1.0/src/orchestrator/web/static/board.css +150 -0
- spartito-0.1.0/src/orchestrator/web/static/board.js +1085 -0
- spartito-0.1.0/src/orchestrator/web/static/icon-192.png +0 -0
- spartito-0.1.0/src/orchestrator/web/static/icon-512.png +0 -0
- spartito-0.1.0/src/orchestrator/web/static/icon-apple-180.png +0 -0
- spartito-0.1.0/src/orchestrator/web/static/icon-maskable-512.png +0 -0
- spartito-0.1.0/src/orchestrator/web/static/icon.svg +1 -0
- spartito-0.1.0/src/orchestrator/web/static/tick.js +9 -0
spartito-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Spartito 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.
|
spartito-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spartito
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Run Claude Code and Codex agents in parallel, each in its own git worktree, steered through one orchestrator agent
|
|
5
|
+
Keywords: agents,ai,claude-code,codex,coding-agents,git-worktree,mcp,orchestration
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Dist: anyio>=4.16.0
|
|
20
|
+
Requires-Dist: mcp>=2.3.0
|
|
21
|
+
Requires-Dist: starlette>=1.10.0
|
|
22
|
+
Requires-Dist: typer>=0.29.0
|
|
23
|
+
Requires-Dist: uvicorn>=0.54.0
|
|
24
|
+
Requires-Dist: pywebview>=6.2 ; sys_platform == 'darwin' and extra == 'app'
|
|
25
|
+
Requires-Dist: pyobjc-framework-usernotifications>=13.0 ; sys_platform == 'darwin' and extra == 'app'
|
|
26
|
+
Requires-Dist: pywebview[qt]>=6.2 ; sys_platform == 'linux' and extra == 'app'
|
|
27
|
+
Requires-Dist: pyobjc-framework-cocoa>=13.0 ; sys_platform == 'darwin' and extra == 'menubar'
|
|
28
|
+
Requires-Python: >=3.14
|
|
29
|
+
Project-URL: Homepage, https://github.com/foszto/spartito
|
|
30
|
+
Project-URL: Repository, https://github.com/foszto/spartito
|
|
31
|
+
Project-URL: Issues, https://github.com/foszto/spartito/issues
|
|
32
|
+
Project-URL: Documentation, https://github.com/foszto/spartito/tree/master/docs
|
|
33
|
+
Provides-Extra: app
|
|
34
|
+
Provides-Extra: menubar
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# Spartito
|
|
38
|
+
|
|
39
|
+
Spartito runs Claude Code and Codex agents headless and in parallel, each in its own git
|
|
40
|
+
worktree and branch. You steer them through one orchestrator agent (shown as *Maestro*) from a
|
|
41
|
+
web dashboard or the command line, instead of managing many terminal sessions by hand. It is
|
|
42
|
+
for developers who already use Claude Code or Codex and want several agents working on their
|
|
43
|
+
repositories at once.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
you ── orchestrator (Maestro)
|
|
47
|
+
└─ project ── project lead (in the project's main checkout)
|
|
48
|
+
├─ worker (own git worktree, branch orch/<agent-id>)
|
|
49
|
+
├─ reviewer (reads the worker's worktree after it finishes)
|
|
50
|
+
└─ ...
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The command is `spartito`; the Python package is `orchestrator`. The internal names stay as they
|
|
54
|
+
were: the `orch` MCP server and its tools, the `ORCH_*` variables, `orch.db` and the agents'
|
|
55
|
+
`orch/` branches.
|
|
56
|
+
|
|
57
|
+
## Features
|
|
58
|
+
|
|
59
|
+
- One conversation with an orchestrator agent that briefs a project lead per project; leads
|
|
60
|
+
start and coordinate their own agents.
|
|
61
|
+
- Agents run headless (`claude -p`, `codex exec`) in parallel, each in its own git worktree and
|
|
62
|
+
branch, or in a worktree shared with another agent (review, test, fix).
|
|
63
|
+
- Packaged roles: orchestrator, lead, planner, worker, reviewer, tester; custom roles are
|
|
64
|
+
Markdown files.
|
|
65
|
+
- Results travel up automatically: a parent is woken with its agents' answers when they are
|
|
66
|
+
done; tasks can depend on each other and embed another agent's answer.
|
|
67
|
+
- Web dashboard: conversations, tool calls, queued messages, model and effort per agent,
|
|
68
|
+
context size, tokens and cost.
|
|
69
|
+
- Model and effort per tier (orchestrator, lead, worker), per provider, globally or per
|
|
70
|
+
project; per-agent overrides.
|
|
71
|
+
- Persistent task board per project, and a list of decisions that wait for you.
|
|
72
|
+
- Automatic compaction of long conversations, automatic archiving of finished agents, keeping
|
|
73
|
+
the machine awake while agents work, desktop notifications.
|
|
74
|
+
- The dashboard as a desktop application: a background service, an installable page,
|
|
75
|
+
notifications whose click opens the agent or decision, and its own window (`spartito app`).
|
|
76
|
+
- No daemon: every turn is its own process; all state is in one SQLite database.
|
|
77
|
+
|
|
78
|
+
## Requirements
|
|
79
|
+
|
|
80
|
+
- macOS or Linux (see [Platform support](https://github.com/foszto/spartito#platform-support)).
|
|
81
|
+
- Python 3.14 and [uv](https://docs.astral.sh/uv/).
|
|
82
|
+
- `git`.
|
|
83
|
+
- The `claude` (Claude Code) CLI, installed and logged in, and optionally the `codex` CLI.
|
|
84
|
+
The defaults use Claude Code: the orchestrator agent, `spartito chat`, and every project
|
|
85
|
+
registered without `--provider`, so the quick start below needs `claude`. A Codex-only or
|
|
86
|
+
mixed setup is configured per project and per agent:
|
|
87
|
+
[docs/configuration.md](https://github.com/foszto/spartito/blob/master/docs/configuration.md#providers-and-permissions).
|
|
88
|
+
|
|
89
|
+
## Installation
|
|
90
|
+
|
|
91
|
+
From a checkout of this repository, the recommended install:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
uv tool install --editable '.[app,menubar]' # puts `spartito` on the PATH
|
|
95
|
+
spartito --help
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The extras bring the native window of `spartito app` (`app`) and the macOS menu-bar item
|
|
99
|
+
(`menubar`; nothing on Linux). On Linux, `app` pulls in PyQt6, which is GPL-3.0-only: see
|
|
100
|
+
[docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md#optional-dependencies).
|
|
101
|
+
|
|
102
|
+
Alternatives: `uv tool install --editable .` without the extras (`spartito app` then opens a
|
|
103
|
+
browser window, and on macOS notifications do not come from Spartito itself), or no install
|
|
104
|
+
at all, prefixing every command with `uv run` inside the checkout (`uv run spartito …`).
|
|
105
|
+
Installed before the command was renamed? See
|
|
106
|
+
[Upgrading from `orch`](https://github.com/foszto/spartito/blob/master/docs/usage.md#upgrading-from-orch). Installed from a checkout before the distribution was renamed
|
|
107
|
+
to `spartito`? See
|
|
108
|
+
[Upgrading to the distribution name `spartito`](https://github.com/foszto/spartito/blob/master/docs/usage.md#upgrading-to-the-distribution-name-spartito).
|
|
109
|
+
|
|
110
|
+
Spartito keeps its state in `~/.orchestrator/`. Set `ORCH_HOME` to use another directory.
|
|
111
|
+
|
|
112
|
+
## Quick start
|
|
113
|
+
|
|
114
|
+
Register a git repository as a project. Its currently checked-out branch becomes the
|
|
115
|
+
project's base branch, from which agent branches start:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
spartito project add ~/src/my-app
|
|
119
|
+
# added my-app /home/dev/src/my-app (base branch: main)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Through the orchestrator.** The recommended way: the dashboard as a background service, and
|
|
123
|
+
Spartito as an application:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
spartito service install # dashboard at http://127.0.0.1:8787, in the background and at login
|
|
127
|
+
spartito app install # a launcher with Spartito's own name and icon
|
|
128
|
+
spartito app # or open Spartito like any application
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The service is a launchd agent on macOS and a systemd user unit on Linux, restarted when it
|
|
132
|
+
fails. The launcher is `~/Applications/Spartito.app` on macOS and a desktop entry on Linux;
|
|
133
|
+
notifications come from Spartito, and a click opens the agent or decision (macOS: once
|
|
134
|
+
Spartito is allowed to notify; Linux: with libnotify 0.7.10 or later). Both are undone with
|
|
135
|
+
`spartito service uninstall` and `spartito app uninstall`. The dashboard has no login: keep it
|
|
136
|
+
on the loopback address (the default), as anyone who can reach it controls agents that run
|
|
137
|
+
code ([docs/usage.md](https://github.com/foszto/spartito/blob/master/docs/usage.md#dashboard)). Details per platform:
|
|
138
|
+
[docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md).
|
|
139
|
+
|
|
140
|
+
Without the service or the window (or where no window is available): `spartito web` serves
|
|
141
|
+
the dashboard at `http://127.0.0.1:8787` until Ctrl-C; open it in a browser.
|
|
142
|
+
|
|
143
|
+
Select **Maestro** and describe the goal, for example: *"In my-app, fix the login redirect
|
|
144
|
+
loop. Have a worker implement it with Claude and a reviewer check it with Codex."* The
|
|
145
|
+
orchestrator passes the brief to the project lead, which starts the agents. They appear in the
|
|
146
|
+
left-hand list as they start; click one to follow its conversation. When the lead's agents are
|
|
147
|
+
done, the lead reports to the orchestrator, which reports to you. Alternatively, `spartito chat`
|
|
148
|
+
opens the orchestrator as an interactive Claude Code session in the terminal: a separate
|
|
149
|
+
conversation with the same tools and the same state.
|
|
150
|
+
|
|
151
|
+
**Directly from the command line.**
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
spartito spawn -p my-app -n fix-login "Fix the redirect loop after login. Add a regression test."
|
|
155
|
+
# fix-login-3f2a run 1 /home/dev/.orchestrator/worktrees/my-app/fix-login-3f2a
|
|
156
|
+
|
|
157
|
+
spartito logs fix-login-3f2a -f # follow what it does
|
|
158
|
+
spartito wait fix-login-3f2a # block until it is done
|
|
159
|
+
spartito status fix-login-3f2a # result, commits and changes in its worktree
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The worker commits on branch `orch/fix-login-3f2a`. Review and merge it yourself; agents do
|
|
163
|
+
not merge:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
cd ~/src/my-app
|
|
167
|
+
git log --oneline main..orch/fix-login-3f2a
|
|
168
|
+
git merge orch/fix-login-3f2a
|
|
169
|
+
spartito archive fix-login-3f2a # hide it from the lists; everything is kept
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## How it fits together
|
|
173
|
+
|
|
174
|
+
Every agent is a headless Claude Code or Codex session with a role. A message to an agent
|
|
175
|
+
starts a *turn*: `spartito`, the dashboard or the MCP server records it in a SQLite database
|
|
176
|
+
under `~/.orchestrator/` and starts one detached runner process, which runs the CLI in the
|
|
177
|
+
agent's worktree and records its output as events. The orchestrator and the project leads
|
|
178
|
+
get the `orch` MCP tools to start agents, wait for them, keep the task board and ask you for
|
|
179
|
+
decisions; when an agent and its sub-agents are done, their parent receives their answers in
|
|
180
|
+
an automatic notification turn. The command line, the dashboard, the desktop window and the
|
|
181
|
+
MCP tools are views on the same database. More: [docs/concepts.md](https://github.com/foszto/spartito/blob/master/docs/concepts.md),
|
|
182
|
+
[docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md).
|
|
183
|
+
|
|
184
|
+
## Documentation
|
|
185
|
+
|
|
186
|
+
- [docs/concepts.md](https://github.com/foszto/spartito/blob/master/docs/concepts.md): orchestrator, leads, roles, worktrees, turns, results.
|
|
187
|
+
- [docs/usage.md](https://github.com/foszto/spartito/blob/master/docs/usage.md): every command and option, and the dashboard.
|
|
188
|
+
- [docs/agents.md](https://github.com/foszto/spartito/blob/master/docs/agents.md): MCP tools, queue, dependencies, notifications, decisions, archiving, compaction, cost.
|
|
189
|
+
- [docs/configuration.md](https://github.com/foszto/spartito/blob/master/docs/configuration.md): model and effort, settings, loadout, roles, providers, files.
|
|
190
|
+
- [docs/board.md](https://github.com/foszto/spartito/blob/master/docs/board.md): the task board across projects.
|
|
191
|
+
- [docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md): background service, installable page, notifications, `spartito app`, menu bar.
|
|
192
|
+
- [docs/desktop-checklist.md](https://github.com/foszto/spartito/blob/master/docs/desktop-checklist.md): manual checks of the desktop app.
|
|
193
|
+
- [docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md): how it works at run time, limitations, code layout.
|
|
194
|
+
- [docs/releasing.md](https://github.com/foszto/spartito/blob/master/docs/releasing.md): the version, publishing to PyPI, the release workflow.
|
|
195
|
+
- [CONTRIBUTING.md](https://github.com/foszto/spartito/blob/master/CONTRIBUTING.md): setup, checks, conventions, pull requests, bug reports.
|
|
196
|
+
- [ROADMAP.md](https://github.com/foszto/spartito/blob/master/ROADMAP.md): where Spartito is heading, in phases, with the open questions.
|
|
197
|
+
|
|
198
|
+
## Platform support
|
|
199
|
+
|
|
200
|
+
Developed and used on macOS; Linux is supported, with parts not yet tested on a real machine;
|
|
201
|
+
Windows is not supported (process handling relies on POSIX process groups and sessions).
|
|
202
|
+
Details and other limitations:
|
|
203
|
+
[docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md#platform-support-and-limitations); the desktop
|
|
204
|
+
features per platform: [docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md#platform-support).
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
uv sync
|
|
210
|
+
uv run pytest # uses a fake provider and real git worktrees; no claude/codex calls
|
|
211
|
+
uv run pytest -n auto # the same in parallel (pytest-xdist): about 6x faster, the usual way
|
|
212
|
+
uv run ruff check . && uv run ruff format --check .
|
|
213
|
+
node --check src/orchestrator/web/static/app.js
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
How to contribute, the checks a change must pass and how to report a bug:
|
|
217
|
+
[CONTRIBUTING.md](https://github.com/foszto/spartito/blob/master/CONTRIBUTING.md).
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT, see [LICENSE](https://github.com/foszto/spartito/blob/master/LICENSE).
|
spartito-0.1.0/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Spartito
|
|
2
|
+
|
|
3
|
+
Spartito runs Claude Code and Codex agents headless and in parallel, each in its own git
|
|
4
|
+
worktree and branch. You steer them through one orchestrator agent (shown as *Maestro*) from a
|
|
5
|
+
web dashboard or the command line, instead of managing many terminal sessions by hand. It is
|
|
6
|
+
for developers who already use Claude Code or Codex and want several agents working on their
|
|
7
|
+
repositories at once.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
you ── orchestrator (Maestro)
|
|
11
|
+
└─ project ── project lead (in the project's main checkout)
|
|
12
|
+
├─ worker (own git worktree, branch orch/<agent-id>)
|
|
13
|
+
├─ reviewer (reads the worker's worktree after it finishes)
|
|
14
|
+
└─ ...
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The command is `spartito`; the Python package is `orchestrator`. The internal names stay as they
|
|
18
|
+
were: the `orch` MCP server and its tools, the `ORCH_*` variables, `orch.db` and the agents'
|
|
19
|
+
`orch/` branches.
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- One conversation with an orchestrator agent that briefs a project lead per project; leads
|
|
24
|
+
start and coordinate their own agents.
|
|
25
|
+
- Agents run headless (`claude -p`, `codex exec`) in parallel, each in its own git worktree and
|
|
26
|
+
branch, or in a worktree shared with another agent (review, test, fix).
|
|
27
|
+
- Packaged roles: orchestrator, lead, planner, worker, reviewer, tester; custom roles are
|
|
28
|
+
Markdown files.
|
|
29
|
+
- Results travel up automatically: a parent is woken with its agents' answers when they are
|
|
30
|
+
done; tasks can depend on each other and embed another agent's answer.
|
|
31
|
+
- Web dashboard: conversations, tool calls, queued messages, model and effort per agent,
|
|
32
|
+
context size, tokens and cost.
|
|
33
|
+
- Model and effort per tier (orchestrator, lead, worker), per provider, globally or per
|
|
34
|
+
project; per-agent overrides.
|
|
35
|
+
- Persistent task board per project, and a list of decisions that wait for you.
|
|
36
|
+
- Automatic compaction of long conversations, automatic archiving of finished agents, keeping
|
|
37
|
+
the machine awake while agents work, desktop notifications.
|
|
38
|
+
- The dashboard as a desktop application: a background service, an installable page,
|
|
39
|
+
notifications whose click opens the agent or decision, and its own window (`spartito app`).
|
|
40
|
+
- No daemon: every turn is its own process; all state is in one SQLite database.
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
|
|
44
|
+
- macOS or Linux (see [Platform support](https://github.com/foszto/spartito#platform-support)).
|
|
45
|
+
- Python 3.14 and [uv](https://docs.astral.sh/uv/).
|
|
46
|
+
- `git`.
|
|
47
|
+
- The `claude` (Claude Code) CLI, installed and logged in, and optionally the `codex` CLI.
|
|
48
|
+
The defaults use Claude Code: the orchestrator agent, `spartito chat`, and every project
|
|
49
|
+
registered without `--provider`, so the quick start below needs `claude`. A Codex-only or
|
|
50
|
+
mixed setup is configured per project and per agent:
|
|
51
|
+
[docs/configuration.md](https://github.com/foszto/spartito/blob/master/docs/configuration.md#providers-and-permissions).
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
From a checkout of this repository, the recommended install:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
uv tool install --editable '.[app,menubar]' # puts `spartito` on the PATH
|
|
59
|
+
spartito --help
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The extras bring the native window of `spartito app` (`app`) and the macOS menu-bar item
|
|
63
|
+
(`menubar`; nothing on Linux). On Linux, `app` pulls in PyQt6, which is GPL-3.0-only: see
|
|
64
|
+
[docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md#optional-dependencies).
|
|
65
|
+
|
|
66
|
+
Alternatives: `uv tool install --editable .` without the extras (`spartito app` then opens a
|
|
67
|
+
browser window, and on macOS notifications do not come from Spartito itself), or no install
|
|
68
|
+
at all, prefixing every command with `uv run` inside the checkout (`uv run spartito …`).
|
|
69
|
+
Installed before the command was renamed? See
|
|
70
|
+
[Upgrading from `orch`](https://github.com/foszto/spartito/blob/master/docs/usage.md#upgrading-from-orch). Installed from a checkout before the distribution was renamed
|
|
71
|
+
to `spartito`? See
|
|
72
|
+
[Upgrading to the distribution name `spartito`](https://github.com/foszto/spartito/blob/master/docs/usage.md#upgrading-to-the-distribution-name-spartito).
|
|
73
|
+
|
|
74
|
+
Spartito keeps its state in `~/.orchestrator/`. Set `ORCH_HOME` to use another directory.
|
|
75
|
+
|
|
76
|
+
## Quick start
|
|
77
|
+
|
|
78
|
+
Register a git repository as a project. Its currently checked-out branch becomes the
|
|
79
|
+
project's base branch, from which agent branches start:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
spartito project add ~/src/my-app
|
|
83
|
+
# added my-app /home/dev/src/my-app (base branch: main)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Through the orchestrator.** The recommended way: the dashboard as a background service, and
|
|
87
|
+
Spartito as an application:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
spartito service install # dashboard at http://127.0.0.1:8787, in the background and at login
|
|
91
|
+
spartito app install # a launcher with Spartito's own name and icon
|
|
92
|
+
spartito app # or open Spartito like any application
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The service is a launchd agent on macOS and a systemd user unit on Linux, restarted when it
|
|
96
|
+
fails. The launcher is `~/Applications/Spartito.app` on macOS and a desktop entry on Linux;
|
|
97
|
+
notifications come from Spartito, and a click opens the agent or decision (macOS: once
|
|
98
|
+
Spartito is allowed to notify; Linux: with libnotify 0.7.10 or later). Both are undone with
|
|
99
|
+
`spartito service uninstall` and `spartito app uninstall`. The dashboard has no login: keep it
|
|
100
|
+
on the loopback address (the default), as anyone who can reach it controls agents that run
|
|
101
|
+
code ([docs/usage.md](https://github.com/foszto/spartito/blob/master/docs/usage.md#dashboard)). Details per platform:
|
|
102
|
+
[docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md).
|
|
103
|
+
|
|
104
|
+
Without the service or the window (or where no window is available): `spartito web` serves
|
|
105
|
+
the dashboard at `http://127.0.0.1:8787` until Ctrl-C; open it in a browser.
|
|
106
|
+
|
|
107
|
+
Select **Maestro** and describe the goal, for example: *"In my-app, fix the login redirect
|
|
108
|
+
loop. Have a worker implement it with Claude and a reviewer check it with Codex."* The
|
|
109
|
+
orchestrator passes the brief to the project lead, which starts the agents. They appear in the
|
|
110
|
+
left-hand list as they start; click one to follow its conversation. When the lead's agents are
|
|
111
|
+
done, the lead reports to the orchestrator, which reports to you. Alternatively, `spartito chat`
|
|
112
|
+
opens the orchestrator as an interactive Claude Code session in the terminal: a separate
|
|
113
|
+
conversation with the same tools and the same state.
|
|
114
|
+
|
|
115
|
+
**Directly from the command line.**
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
spartito spawn -p my-app -n fix-login "Fix the redirect loop after login. Add a regression test."
|
|
119
|
+
# fix-login-3f2a run 1 /home/dev/.orchestrator/worktrees/my-app/fix-login-3f2a
|
|
120
|
+
|
|
121
|
+
spartito logs fix-login-3f2a -f # follow what it does
|
|
122
|
+
spartito wait fix-login-3f2a # block until it is done
|
|
123
|
+
spartito status fix-login-3f2a # result, commits and changes in its worktree
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The worker commits on branch `orch/fix-login-3f2a`. Review and merge it yourself; agents do
|
|
127
|
+
not merge:
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
cd ~/src/my-app
|
|
131
|
+
git log --oneline main..orch/fix-login-3f2a
|
|
132
|
+
git merge orch/fix-login-3f2a
|
|
133
|
+
spartito archive fix-login-3f2a # hide it from the lists; everything is kept
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## How it fits together
|
|
137
|
+
|
|
138
|
+
Every agent is a headless Claude Code or Codex session with a role. A message to an agent
|
|
139
|
+
starts a *turn*: `spartito`, the dashboard or the MCP server records it in a SQLite database
|
|
140
|
+
under `~/.orchestrator/` and starts one detached runner process, which runs the CLI in the
|
|
141
|
+
agent's worktree and records its output as events. The orchestrator and the project leads
|
|
142
|
+
get the `orch` MCP tools to start agents, wait for them, keep the task board and ask you for
|
|
143
|
+
decisions; when an agent and its sub-agents are done, their parent receives their answers in
|
|
144
|
+
an automatic notification turn. The command line, the dashboard, the desktop window and the
|
|
145
|
+
MCP tools are views on the same database. More: [docs/concepts.md](https://github.com/foszto/spartito/blob/master/docs/concepts.md),
|
|
146
|
+
[docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md).
|
|
147
|
+
|
|
148
|
+
## Documentation
|
|
149
|
+
|
|
150
|
+
- [docs/concepts.md](https://github.com/foszto/spartito/blob/master/docs/concepts.md): orchestrator, leads, roles, worktrees, turns, results.
|
|
151
|
+
- [docs/usage.md](https://github.com/foszto/spartito/blob/master/docs/usage.md): every command and option, and the dashboard.
|
|
152
|
+
- [docs/agents.md](https://github.com/foszto/spartito/blob/master/docs/agents.md): MCP tools, queue, dependencies, notifications, decisions, archiving, compaction, cost.
|
|
153
|
+
- [docs/configuration.md](https://github.com/foszto/spartito/blob/master/docs/configuration.md): model and effort, settings, loadout, roles, providers, files.
|
|
154
|
+
- [docs/board.md](https://github.com/foszto/spartito/blob/master/docs/board.md): the task board across projects.
|
|
155
|
+
- [docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md): background service, installable page, notifications, `spartito app`, menu bar.
|
|
156
|
+
- [docs/desktop-checklist.md](https://github.com/foszto/spartito/blob/master/docs/desktop-checklist.md): manual checks of the desktop app.
|
|
157
|
+
- [docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md): how it works at run time, limitations, code layout.
|
|
158
|
+
- [docs/releasing.md](https://github.com/foszto/spartito/blob/master/docs/releasing.md): the version, publishing to PyPI, the release workflow.
|
|
159
|
+
- [CONTRIBUTING.md](https://github.com/foszto/spartito/blob/master/CONTRIBUTING.md): setup, checks, conventions, pull requests, bug reports.
|
|
160
|
+
- [ROADMAP.md](https://github.com/foszto/spartito/blob/master/ROADMAP.md): where Spartito is heading, in phases, with the open questions.
|
|
161
|
+
|
|
162
|
+
## Platform support
|
|
163
|
+
|
|
164
|
+
Developed and used on macOS; Linux is supported, with parts not yet tested on a real machine;
|
|
165
|
+
Windows is not supported (process handling relies on POSIX process groups and sessions).
|
|
166
|
+
Details and other limitations:
|
|
167
|
+
[docs/architecture.md](https://github.com/foszto/spartito/blob/master/docs/architecture.md#platform-support-and-limitations); the desktop
|
|
168
|
+
features per platform: [docs/desktop.md](https://github.com/foszto/spartito/blob/master/docs/desktop.md#platform-support).
|
|
169
|
+
|
|
170
|
+
## Development
|
|
171
|
+
|
|
172
|
+
```sh
|
|
173
|
+
uv sync
|
|
174
|
+
uv run pytest # uses a fake provider and real git worktrees; no claude/codex calls
|
|
175
|
+
uv run pytest -n auto # the same in parallel (pytest-xdist): about 6x faster, the usual way
|
|
176
|
+
uv run ruff check . && uv run ruff format --check .
|
|
177
|
+
node --check src/orchestrator/web/static/app.js
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
How to contribute, the checks a change must pass and how to report a bug:
|
|
181
|
+
[CONTRIBUTING.md](https://github.com/foszto/spartito/blob/master/CONTRIBUTING.md).
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT, see [LICENSE](https://github.com/foszto/spartito/blob/master/LICENSE).
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "spartito"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Run Claude Code and Codex agents in parallel, each in its own git worktree, steered through one orchestrator agent"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.14"
|
|
9
|
+
keywords = [
|
|
10
|
+
"agents",
|
|
11
|
+
"ai",
|
|
12
|
+
"claude-code",
|
|
13
|
+
"codex",
|
|
14
|
+
"coding-agents",
|
|
15
|
+
"git-worktree",
|
|
16
|
+
"mcp",
|
|
17
|
+
"orchestration",
|
|
18
|
+
]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
"Environment :: Console",
|
|
22
|
+
"Environment :: Web Environment",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Operating System :: MacOS",
|
|
25
|
+
"Operating System :: POSIX :: Linux",
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
29
|
+
"Topic :: Software Development",
|
|
30
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
31
|
+
]
|
|
32
|
+
dependencies = [
|
|
33
|
+
"anyio>=4.16.0",
|
|
34
|
+
"mcp>=2.3.0",
|
|
35
|
+
"starlette>=1.10.0",
|
|
36
|
+
"typer>=0.29.0",
|
|
37
|
+
"uvicorn>=0.54.0",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
app = [
|
|
42
|
+
"pywebview>=6.2; sys_platform == 'darwin'",
|
|
43
|
+
"pyobjc-framework-UserNotifications>=13.0; sys_platform == 'darwin'",
|
|
44
|
+
"pywebview[qt]>=6.2; sys_platform == 'linux'",
|
|
45
|
+
]
|
|
46
|
+
menubar = ["pyobjc-framework-Cocoa>=13.0; sys_platform == 'darwin'"]
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://github.com/foszto/spartito"
|
|
50
|
+
Repository = "https://github.com/foszto/spartito"
|
|
51
|
+
Issues = "https://github.com/foszto/spartito/issues"
|
|
52
|
+
Documentation = "https://github.com/foszto/spartito/tree/master/docs"
|
|
53
|
+
|
|
54
|
+
[project.scripts]
|
|
55
|
+
spartito = "orchestrator.cli:main"
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["uv_build>=0.11.29,<0.12.0"]
|
|
59
|
+
build-backend = "uv_build"
|
|
60
|
+
|
|
61
|
+
[tool.uv.build-backend]
|
|
62
|
+
module-name = "orchestrator"
|
|
63
|
+
|
|
64
|
+
[tool.ruff]
|
|
65
|
+
line-length = 100
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = [
|
|
69
|
+
"E",
|
|
70
|
+
"F",
|
|
71
|
+
"I",
|
|
72
|
+
"B",
|
|
73
|
+
"UP",
|
|
74
|
+
"SIM",
|
|
75
|
+
]
|
|
76
|
+
ignore = ["E501"]
|
|
77
|
+
|
|
78
|
+
[tool.pytest.ini_options]
|
|
79
|
+
testpaths = ["tests"]
|
|
80
|
+
|
|
81
|
+
[dependency-groups]
|
|
82
|
+
dev = [
|
|
83
|
+
"pytest>=9.2.0",
|
|
84
|
+
"pytest-xdist>=3.8.0",
|
|
85
|
+
"ruff>=0.17.4",
|
|
86
|
+
]
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "spartito"
|
|
3
|
+
# The one place of the version: `uv version <new>` bumps it; the package reads it from the
|
|
4
|
+
# installed metadata (orchestrator.__version__). A release tag is `v<version>` (docs/releasing.md).
|
|
5
|
+
version = "0.1.0"
|
|
6
|
+
description = "Run Claude Code and Codex agents in parallel, each in its own git worktree, steered through one orchestrator agent"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
license = "MIT"
|
|
9
|
+
license-files = ["LICENSE"]
|
|
10
|
+
requires-python = ">=3.14"
|
|
11
|
+
keywords = [
|
|
12
|
+
"agents",
|
|
13
|
+
"ai",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"codex",
|
|
16
|
+
"coding-agents",
|
|
17
|
+
"git-worktree",
|
|
18
|
+
"mcp",
|
|
19
|
+
"orchestration",
|
|
20
|
+
]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 3 - Alpha",
|
|
23
|
+
"Environment :: Console",
|
|
24
|
+
"Environment :: Web Environment",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"Operating System :: MacOS",
|
|
27
|
+
"Operating System :: POSIX :: Linux",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
|
+
"Topic :: Software Development",
|
|
32
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
33
|
+
]
|
|
34
|
+
dependencies = [
|
|
35
|
+
"anyio>=4.16.0",
|
|
36
|
+
"mcp>=2.3.0",
|
|
37
|
+
"starlette>=1.10.0",
|
|
38
|
+
"typer>=0.29.0",
|
|
39
|
+
"uvicorn>=0.54.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
# The native window of `spartito app`: Cocoa on macOS (pyobjc); Qt on Linux (pywebview's own `qt`
|
|
44
|
+
# extra: PyQt6 and PyQt6-WebEngine, GPL-3.0, installed only with this extra and only there).
|
|
45
|
+
# On macOS also the notifications Spartito posts itself (UserNotifications, MIT).
|
|
46
|
+
app = [
|
|
47
|
+
"pywebview>=6.2; sys_platform == 'darwin'",
|
|
48
|
+
"pyobjc-framework-UserNotifications>=13.0; sys_platform == 'darwin'",
|
|
49
|
+
"pywebview[qt]>=6.2; sys_platform == 'linux'",
|
|
50
|
+
]
|
|
51
|
+
# The menu-bar status item of `spartito menubar` (macOS only): Cocoa through pyobjc.
|
|
52
|
+
menubar = ["pyobjc-framework-Cocoa>=13.0; sys_platform == 'darwin'"]
|
|
53
|
+
|
|
54
|
+
[project.urls]
|
|
55
|
+
Homepage = "https://github.com/foszto/spartito"
|
|
56
|
+
Repository = "https://github.com/foszto/spartito"
|
|
57
|
+
Issues = "https://github.com/foszto/spartito/issues"
|
|
58
|
+
Documentation = "https://github.com/foszto/spartito/tree/master/docs"
|
|
59
|
+
|
|
60
|
+
[project.scripts]
|
|
61
|
+
spartito = "orchestrator.cli:main"
|
|
62
|
+
|
|
63
|
+
[build-system]
|
|
64
|
+
requires = ["uv_build>=0.11.29,<0.12.0"]
|
|
65
|
+
build-backend = "uv_build"
|
|
66
|
+
|
|
67
|
+
[tool.uv.build-backend]
|
|
68
|
+
# The distribution is `spartito`; the import package keeps its name `orchestrator`.
|
|
69
|
+
module-name = "orchestrator"
|
|
70
|
+
|
|
71
|
+
[dependency-groups]
|
|
72
|
+
dev = [
|
|
73
|
+
"pytest>=9.2.0",
|
|
74
|
+
"pytest-xdist>=3.8.0",
|
|
75
|
+
"ruff>=0.17.4",
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[tool.ruff]
|
|
79
|
+
line-length = 100
|
|
80
|
+
|
|
81
|
+
[tool.ruff.lint]
|
|
82
|
+
select = ["E", "F", "I", "B", "UP", "SIM"]
|
|
83
|
+
ignore = ["E501"]
|
|
84
|
+
|
|
85
|
+
[tool.pytest.ini_options]
|
|
86
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""A small orchestrator for fleets of coding agents (Claude Code, Codex)."""
|
|
2
|
+
|
|
3
|
+
from importlib import metadata
|
|
4
|
+
|
|
5
|
+
# The version lives in pyproject.toml only; this reads the installed distribution's metadata.
|
|
6
|
+
# Without it (an environment that installed this checkout under another distribution name,
|
|
7
|
+
# before it is reinstalled: docs/releasing.md) the version is unknown, nothing else changes.
|
|
8
|
+
try:
|
|
9
|
+
__version__ = metadata.version("spartito")
|
|
10
|
+
except metadata.PackageNotFoundError:
|
|
11
|
+
__version__ = "0+unknown"
|