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.
Files changed (80) hide show
  1. spartito-0.1.0/LICENSE +21 -0
  2. spartito-0.1.0/PKG-INFO +221 -0
  3. spartito-0.1.0/README.md +185 -0
  4. spartito-0.1.0/pyproject.toml +86 -0
  5. spartito-0.1.0/pyproject.toml.orig +86 -0
  6. spartito-0.1.0/src/orchestrator/__init__.py +11 -0
  7. spartito-0.1.0/src/orchestrator/__main__.py +6 -0
  8. spartito-0.1.0/src/orchestrator/app_open.py +105 -0
  9. spartito-0.1.0/src/orchestrator/autostart.py +435 -0
  10. spartito-0.1.0/src/orchestrator/board.py +600 -0
  11. spartito-0.1.0/src/orchestrator/cli.py +1570 -0
  12. spartito-0.1.0/src/orchestrator/config.py +93 -0
  13. spartito-0.1.0/src/orchestrator/core/__init__.py +11 -0
  14. spartito-0.1.0/src/orchestrator/core/access.py +89 -0
  15. spartito-0.1.0/src/orchestrator/core/archive.py +281 -0
  16. spartito-0.1.0/src/orchestrator/core/board_git.py +259 -0
  17. spartito-0.1.0/src/orchestrator/core/boards.py +392 -0
  18. spartito-0.1.0/src/orchestrator/core/compaction.py +191 -0
  19. spartito-0.1.0/src/orchestrator/core/delivery.py +163 -0
  20. spartito-0.1.0/src/orchestrator/core/dispatch.py +312 -0
  21. spartito-0.1.0/src/orchestrator/core/launcher.py +88 -0
  22. spartito-0.1.0/src/orchestrator/core/lifecycle.py +80 -0
  23. spartito-0.1.0/src/orchestrator/core/notices.py +218 -0
  24. spartito-0.1.0/src/orchestrator/core/reads.py +93 -0
  25. spartito-0.1.0/src/orchestrator/core/setup.py +176 -0
  26. spartito-0.1.0/src/orchestrator/core/views.py +278 -0
  27. spartito-0.1.0/src/orchestrator/decisions.py +216 -0
  28. spartito-0.1.0/src/orchestrator/desktop.py +1553 -0
  29. spartito-0.1.0/src/orchestrator/errors.py +12 -0
  30. spartito-0.1.0/src/orchestrator/git.py +354 -0
  31. spartito-0.1.0/src/orchestrator/gui/__init__.py +1 -0
  32. spartito-0.1.0/src/orchestrator/gui/icon.icns +0 -0
  33. spartito-0.1.0/src/orchestrator/gui/launcher.py +466 -0
  34. spartito-0.1.0/src/orchestrator/gui/locate.py +40 -0
  35. spartito-0.1.0/src/orchestrator/gui/menubar.py +315 -0
  36. spartito-0.1.0/src/orchestrator/gui/notifier.py +906 -0
  37. spartito-0.1.0/src/orchestrator/gui/window.py +1089 -0
  38. spartito-0.1.0/src/orchestrator/keep_awake.py +118 -0
  39. spartito-0.1.0/src/orchestrator/loadout.py +201 -0
  40. spartito-0.1.0/src/orchestrator/mcp_server.py +640 -0
  41. spartito-0.1.0/src/orchestrator/memory_guard.py +190 -0
  42. spartito-0.1.0/src/orchestrator/models.py +256 -0
  43. spartito-0.1.0/src/orchestrator/notify.py +365 -0
  44. spartito-0.1.0/src/orchestrator/providers/__init__.py +36 -0
  45. spartito-0.1.0/src/orchestrator/providers/base.py +112 -0
  46. spartito-0.1.0/src/orchestrator/providers/claude.py +453 -0
  47. spartito-0.1.0/src/orchestrator/providers/codex.py +242 -0
  48. spartito-0.1.0/src/orchestrator/replies.py +99 -0
  49. spartito-0.1.0/src/orchestrator/roles/lead.md +54 -0
  50. spartito-0.1.0/src/orchestrator/roles/orchestrator.md +54 -0
  51. spartito-0.1.0/src/orchestrator/roles/planner.md +18 -0
  52. spartito-0.1.0/src/orchestrator/roles/planner.schema.json +72 -0
  53. spartito-0.1.0/src/orchestrator/roles/reviewer.md +22 -0
  54. spartito-0.1.0/src/orchestrator/roles/reviewer.schema.json +64 -0
  55. spartito-0.1.0/src/orchestrator/roles/tester.md +21 -0
  56. spartito-0.1.0/src/orchestrator/roles/tester.schema.json +65 -0
  57. spartito-0.1.0/src/orchestrator/roles/worker.md +24 -0
  58. spartito-0.1.0/src/orchestrator/roles/worker.schema.json +61 -0
  59. spartito-0.1.0/src/orchestrator/roles.py +198 -0
  60. spartito-0.1.0/src/orchestrator/runner.py +908 -0
  61. spartito-0.1.0/src/orchestrator/service.py +358 -0
  62. spartito-0.1.0/src/orchestrator/settings.py +240 -0
  63. spartito-0.1.0/src/orchestrator/store.py +1559 -0
  64. spartito-0.1.0/src/orchestrator/textfmt.py +22 -0
  65. spartito-0.1.0/src/orchestrator/timeline.py +136 -0
  66. spartito-0.1.0/src/orchestrator/web/__init__.py +0 -0
  67. spartito-0.1.0/src/orchestrator/web/app.py +490 -0
  68. spartito-0.1.0/src/orchestrator/web/board_api.py +118 -0
  69. spartito-0.1.0/src/orchestrator/web/index.html +215 -0
  70. spartito-0.1.0/src/orchestrator/web/serve.py +94 -0
  71. spartito-0.1.0/src/orchestrator/web/static/app.css +366 -0
  72. spartito-0.1.0/src/orchestrator/web/static/app.js +1786 -0
  73. spartito-0.1.0/src/orchestrator/web/static/board.css +150 -0
  74. spartito-0.1.0/src/orchestrator/web/static/board.js +1085 -0
  75. spartito-0.1.0/src/orchestrator/web/static/icon-192.png +0 -0
  76. spartito-0.1.0/src/orchestrator/web/static/icon-512.png +0 -0
  77. spartito-0.1.0/src/orchestrator/web/static/icon-apple-180.png +0 -0
  78. spartito-0.1.0/src/orchestrator/web/static/icon-maskable-512.png +0 -0
  79. spartito-0.1.0/src/orchestrator/web/static/icon.svg +1 -0
  80. 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.
@@ -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).
@@ -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"
@@ -0,0 +1,6 @@
1
+ """`python -m orchestrator`: the command line (what the background service runs)."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()