agent-team 0.5.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 (102) hide show
  1. agent_team-0.5.0/LICENSE +21 -0
  2. agent_team-0.5.0/PKG-INFO +180 -0
  3. agent_team-0.5.0/README.md +150 -0
  4. agent_team-0.5.0/pyproject.toml +45 -0
  5. agent_team-0.5.0/setup.cfg +4 -0
  6. agent_team-0.5.0/src/agent_team/__init__.py +3 -0
  7. agent_team-0.5.0/src/agent_team/agent.py +109 -0
  8. agent_team-0.5.0/src/agent_team/budget.py +56 -0
  9. agent_team-0.5.0/src/agent_team/cli.py +664 -0
  10. agent_team-0.5.0/src/agent_team/config.py +239 -0
  11. agent_team-0.5.0/src/agent_team/config_io.py +229 -0
  12. agent_team-0.5.0/src/agent_team/context.py +126 -0
  13. agent_team-0.5.0/src/agent_team/dashboard/__init__.py +1 -0
  14. agent_team-0.5.0/src/agent_team/dashboard/server.py +410 -0
  15. agent_team-0.5.0/src/agent_team/dashboard/static/__init__.py +0 -0
  16. agent_team-0.5.0/src/agent_team/dashboard/static/activity.js +110 -0
  17. agent_team-0.5.0/src/agent_team/dashboard/static/app.css +214 -0
  18. agent_team-0.5.0/src/agent_team/dashboard/static/app.js +351 -0
  19. agent_team-0.5.0/src/agent_team/dashboard/static/edit.js +312 -0
  20. agent_team-0.5.0/src/agent_team/dashboard/static/index.html +55 -0
  21. agent_team-0.5.0/src/agent_team/dashboard/static/projects.js +53 -0
  22. agent_team-0.5.0/src/agent_team/dashboard/static/runs.js +148 -0
  23. agent_team-0.5.0/src/agent_team/dashboard/static/settings.js +117 -0
  24. agent_team-0.5.0/src/agent_team/discovery.py +88 -0
  25. agent_team-0.5.0/src/agent_team/estimate.py +60 -0
  26. agent_team-0.5.0/src/agent_team/evals.py +186 -0
  27. agent_team-0.5.0/src/agent_team/files.py +247 -0
  28. agent_team-0.5.0/src/agent_team/gates.py +71 -0
  29. agent_team-0.5.0/src/agent_team/github.py +152 -0
  30. agent_team-0.5.0/src/agent_team/issues.py +101 -0
  31. agent_team-0.5.0/src/agent_team/jobs.py +244 -0
  32. agent_team-0.5.0/src/agent_team/keys.py +110 -0
  33. agent_team-0.5.0/src/agent_team/logs.py +106 -0
  34. agent_team-0.5.0/src/agent_team/memory.py +87 -0
  35. agent_team-0.5.0/src/agent_team/metrics.py +102 -0
  36. agent_team-0.5.0/src/agent_team/notify.py +65 -0
  37. agent_team-0.5.0/src/agent_team/projects.py +83 -0
  38. agent_team-0.5.0/src/agent_team/prompts/__init__.py +0 -0
  39. agent_team-0.5.0/src/agent_team/prompts/builder.md +15 -0
  40. agent_team-0.5.0/src/agent_team/prompts/devops.md +28 -0
  41. agent_team-0.5.0/src/agent_team/prompts/discuss.md +29 -0
  42. agent_team-0.5.0/src/agent_team/prompts/docs.md +12 -0
  43. agent_team-0.5.0/src/agent_team/prompts/factcheck.md +8 -0
  44. agent_team-0.5.0/src/agent_team/prompts/lead.md +33 -0
  45. agent_team-0.5.0/src/agent_team/prompts/marketing.md +18 -0
  46. agent_team-0.5.0/src/agent_team/prompts/member.md +10 -0
  47. agent_team-0.5.0/src/agent_team/prompts/qa.md +17 -0
  48. agent_team-0.5.0/src/agent_team/prompts/review_marketing.md +14 -0
  49. agent_team-0.5.0/src/agent_team/prompts/review_pr.md +26 -0
  50. agent_team-0.5.0/src/agent_team/prompts/security.md +20 -0
  51. agent_team-0.5.0/src/agent_team/prompts/signoff.md +13 -0
  52. agent_team-0.5.0/src/agent_team/providers/__init__.py +8 -0
  53. agent_team-0.5.0/src/agent_team/providers/anthropic_provider.py +150 -0
  54. agent_team-0.5.0/src/agent_team/providers/base.py +96 -0
  55. agent_team-0.5.0/src/agent_team/providers/http_providers.py +238 -0
  56. agent_team-0.5.0/src/agent_team/rank.py +67 -0
  57. agent_team-0.5.0/src/agent_team/readiness.py +189 -0
  58. agent_team-0.5.0/src/agent_team/review_tools.py +142 -0
  59. agent_team-0.5.0/src/agent_team/routing.py +28 -0
  60. agent_team-0.5.0/src/agent_team/sandbox.py +105 -0
  61. agent_team-0.5.0/src/agent_team/schedule.py +182 -0
  62. agent_team-0.5.0/src/agent_team/scoreboard.py +83 -0
  63. agent_team-0.5.0/src/agent_team/screenshots.py +135 -0
  64. agent_team-0.5.0/src/agent_team/secret_scan.py +89 -0
  65. agent_team-0.5.0/src/agent_team/server.py +119 -0
  66. agent_team-0.5.0/src/agent_team/skills.py +96 -0
  67. agent_team-0.5.0/src/agent_team/templates.py +109 -0
  68. agent_team-0.5.0/src/agent_team/tool_loop.py +58 -0
  69. agent_team-0.5.0/src/agent_team/ui.py +59 -0
  70. agent_team-0.5.0/src/agent_team/usage.py +136 -0
  71. agent_team-0.5.0/src/agent_team/workflows/__init__.py +1 -0
  72. agent_team-0.5.0/src/agent_team/workflows/autopilot.py +163 -0
  73. agent_team-0.5.0/src/agent_team/workflows/build.py +305 -0
  74. agent_team-0.5.0/src/agent_team/workflows/discuss.py +84 -0
  75. agent_team-0.5.0/src/agent_team/workflows/fix.py +173 -0
  76. agent_team-0.5.0/src/agent_team/workflows/init.py +253 -0
  77. agent_team-0.5.0/src/agent_team/workflows/market.py +86 -0
  78. agent_team-0.5.0/src/agent_team/workflows/setup.py +56 -0
  79. agent_team-0.5.0/src/agent_team/workflows/ship.py +539 -0
  80. agent_team-0.5.0/src/agent_team.egg-info/PKG-INFO +180 -0
  81. agent_team-0.5.0/src/agent_team.egg-info/SOURCES.txt +100 -0
  82. agent_team-0.5.0/src/agent_team.egg-info/dependency_links.txt +1 -0
  83. agent_team-0.5.0/src/agent_team.egg-info/entry_points.txt +2 -0
  84. agent_team-0.5.0/src/agent_team.egg-info/requires.txt +7 -0
  85. agent_team-0.5.0/src/agent_team.egg-info/top_level.txt +1 -0
  86. agent_team-0.5.0/tests/test_config.py +68 -0
  87. agent_team-0.5.0/tests/test_config_edit.py +140 -0
  88. agent_team-0.5.0/tests/test_dashboard.py +174 -0
  89. agent_team-0.5.0/tests/test_files.py +99 -0
  90. agent_team-0.5.0/tests/test_first_run.py +221 -0
  91. agent_team-0.5.0/tests/test_fix.py +200 -0
  92. agent_team-0.5.0/tests/test_guardrails.py +191 -0
  93. agent_team-0.5.0/tests/test_init_cli.py +98 -0
  94. agent_team-0.5.0/tests/test_next_level.py +357 -0
  95. agent_team-0.5.0/tests/test_remote.py +74 -0
  96. agent_team-0.5.0/tests/test_ship_rules.py +83 -0
  97. agent_team-0.5.0/tests/test_skills.py +88 -0
  98. agent_team-0.5.0/tests/test_v03.py +252 -0
  99. agent_team-0.5.0/tests/test_v04.py +189 -0
  100. agent_team-0.5.0/tests/test_v05.py +187 -0
  101. agent_team-0.5.0/tests/test_versions.py +27 -0
  102. agent_team-0.5.0/tests/test_workflows.py +140 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lakeba
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,180 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-team
3
+ Version: 0.5.0
4
+ Summary: A configurable team of AI agents (any model, any machine) that plans, builds, reviews, markets and ships a software project through GitHub.
5
+ Author: Lakeba
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/lakeba/agent-team
8
+ Project-URL: Documentation, https://lakeba.github.io/agent-team/
9
+ Project-URL: Changelog, https://github.com/lakeba/agent-team/blob/main/CHANGELOG.md
10
+ Keywords: ai,agents,llm,claude,ollama,github,devops
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: anthropic>=1.0
25
+ Provides-Extra: screenshots
26
+ Requires-Dist: pillow>=10; extra == "screenshots"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pillow>=10; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # agent-team
32
+
33
+ A configurable team of AI agents that works on a software project the way a small team would:
34
+ it plans a roadmap, builds features, reviews them, writes marketing material, and ships through
35
+ GitHub with pull requests, CI, sign-offs and releases.
36
+
37
+ Team members can run on any model and any machine: Claude through the Anthropic API, local
38
+ models through Ollama, any OpenAI-compatible server, or another machine running
39
+ `agent-team serve`. A team is described in a `.team.toml` file in each project, so adding a
40
+ member, a machine or a project is a configuration change.
41
+
42
+ It grew out of todo-py, a small command-line app this team planned, built, marketed and released
43
+ (v1.0.0 and v1.0.1); its team is in [examples/todo-py.team.toml](examples/todo-py.team.toml).
44
+
45
+ ## How the team works
46
+
47
+ | Workflow | Command | What happens |
48
+ |---|---|---|
49
+ | Discuss | `agent-team discuss "next features"` | Members talk in turn until they all agree; the lead updates `ROADMAP.md`. |
50
+ | Build | `agent-team build "task" --branch x --pr` | The lead writes `PLAN.md`, builders implement it (in parallel with `--parallel`), tests run each round, the lead reviews until approved, then a PR opens. Optional QA, security and docs members write tests first, review the result and update the docs. |
51
+ | Autopilot | `agent-team autopilot --milestone M2` | Works through the roadmap a PR at a time: the lead picks the next task, the team builds it, each devops shift reviews, fixes and merges, until the lead says the milestone is done (or it gets stuck, or hits a spend limit). |
52
+ | Fix | `agent-team fix 12` | When the lead requests changes on a PR, a builder applies the review on that PR's branch, the lead confirms the blocking points are addressed, and it pushes; the next shift reviews the new commit. |
53
+ | Market | `agent-team market` | The marketing member writes a brief, a website and a pitch deck; a fact-checker checks claims and the lead reviews with screenshots. |
54
+ | Set up | `agent-team setup --license "MIT, copyright 2026 Lakeba"` | The devops member drafts README, CONTRIBUTING, CHANGELOG, CI and templates. |
55
+ | Ship | `agent-team ship` | One devops shift on GitHub: triage, owner sign-offs, lead review, merge, release (or, with `release = "ask"`, a release proposal you approve with `ship --release X.Y.Z`), feedback digest. `agent-team schedule --every 6h` runs shifts unattended, never two at once. |
56
+ | Dashboard | `agent-team ui` | Overview, Team, Runs, Costs, live Activity charts (spend, runs, merges, problems, latest events), Settings (easy switches and team templates, always previewed as a diff) and Projects (every project on this Mac). A page on this machine: the team and whether each member is reachable, every run with each member's verdicts, estimated costs per member, day and run, and the GitHub state. Edit members, connections, guarantees and prices there, add a machine with a guided wizard, and review the diff before saving. Start runs there and follow their output live. |
57
+
58
+ Guardrails are enforced in code, not left to the models. A PR merges only when CI is green, the
59
+ lead approved the exact head commit, and every member who owns a changed path signed off that
60
+ same commit (the lead's approval is its own sign-off). On a re-review, reviewers block only on
61
+ points still open or problems the new commit introduces, so a PR that fixes what was asked passes. Releases need green CI on `main` and a CHANGELOG entry. Text from outside the team
62
+ always reaches the models marked as untrusted. Spend limits in `.team.toml` stop any run before it
63
+ costs more than you allow, and large projects get a focused context instead of every file.
64
+
65
+ Builders change files with small search/replace edits instead of rewriting them, and an edit
66
+ that doesn't match is refused and sent back. Reviewers read files, search, see the diff and run
67
+ the tests themselves. When a reviewer blocks for a reason that will matter again, the lesson is
68
+ kept and every member sees it in later work.
69
+
70
+ With `[sandbox] mode = "container"`, the code the team writes is tested in a throwaway container
71
+ with no network and none of your keys. Every push is checked for secrets first (key and token formats, private keys, `.env` files, and
72
+ the values in your keys file). Paths you list in `require_approval` wait for your approval of the
73
+ exact commit. Weaker models hand work to a stronger member after rejected rounds (`escalate_to`),
74
+ and `[notify]` posts to Slack or any webhook when PRs open or merge, approvals or releases wait
75
+ for you, or autopilot stops.
76
+
77
+ ## Install
78
+
79
+ Requirements: macOS or Linux, Python 3.11+ (on Ubuntu/Debian also `python3-venv`), git, and an
80
+ Anthropic API key for Claude members. Optional: [Ollama](https://ollama.com/)
81
+ for local models, on this machine or another. The workflows that work on GitHub (`build --pr`,
82
+ `ship`, `setup` and the plugin's PR steps) also need the [GitHub CLI](https://cli.github.com/)
83
+ signed in (`gh auth login`).
84
+
85
+ One command installs the CLI into its own environment under `~/.agent-team`, puts `agent-team` on
86
+ your `PATH` (`~/.local/bin`), and installs the Claude Code plugin if Claude Code is present:
87
+
88
+ ```bash
89
+ curl -fsSL https://raw.githubusercontent.com/lakeba/agent-team/main/scripts/install.sh | bash
90
+ ```
91
+
92
+ Run it again to update, then run `/reload-plugins` in any open Claude Code session (or start a new
93
+ one): an open session keeps the commands it started with. Options go after `bash -s --`, for example `| bash -s -- --ref v0.1.0`
94
+ for a specific version, `--no-plugin` to skip the plugin, or `--uninstall` to remove everything
95
+ it installed. If you prefer pipx: `pipx install git+https://github.com/lakeba/agent-team.git`
96
+ (that installs the CLI only).
97
+
98
+ ## Quick start
99
+
100
+ ```bash
101
+ agent-team keys set ANTHROPIC_API_KEY # asks for the key (hidden); every agent-team command finds it
102
+ cd ~/code/my-project
103
+ agent-team ready # checklist: git, GitHub, keys, Ollama, with the fix for anything missing
104
+ agent-team init # writes .team.toml; add --ollama-url http://HOST:11434 for Ollama on another machine
105
+ agent-team doctor # the checklist again, then checks every member can be reached
106
+ ```
107
+
108
+ Keys live in `~/.config/agent-team/env`, readable only by you, so they work the same from any shell,
109
+ the dashboard, background runs and schedules (Ubuntu's `~/.bashrc`, for one, is skipped by
110
+ non-interactive shells). A variable already exported in your environment wins.
111
+
112
+ Then edit `.team.toml` (or open `agent-team ui` and use **Edit team**): set the project's
113
+ guarantees, adjust the team, give members skills (Markdown files or Claude Code skill folders added
114
+ to their prompts), set spend limits under `[limits]`, and run a workflow:
115
+
116
+ ```bash
117
+ agent-team discuss "next features" # agree a roadmap
118
+ agent-team build "add an export command" --branch team/export --pr
119
+ agent-team ship # one devops shift on GitHub
120
+ ```
121
+
122
+ ### Other commands
123
+
124
+ | Command | What it does |
125
+ |---|---|
126
+ | `agent-team status [--json] [--health]` | The team, spend per member and today, recent and background runs, the schedule. |
127
+ | `agent-team ui` | The dashboard: see and edit the team, start runs, follow costs. |
128
+ | `agent-team jobs [start <workflow> \| stop <id> \| log <id>]` | Runs in the background, as the dashboard and the Claude panel start them. |
129
+ | `agent-team schedule --every 6h` | Run devops shifts on a schedule (launchd on macOS, cron elsewhere); `--remove` to stop. |
130
+ | `agent-team serve ...` | Serve a model on this machine as a team member for a team elsewhere. |
131
+ | `agent-team discover` | Find agent-team nodes on the local network. |
132
+ | `agent-team ready [--json]` | What this machine and project still need (git, GitHub, keys, Ollama, models), each with its fix. |
133
+ | `agent-team keys [set NAME \| remove NAME]` | API keys and tokens in agent-team's own keys file; values are never shown. |
134
+ | `agent-team issues [sync --milestone M2 --yes]` | The team's to-do list: `team:build` issues, created from the roadmap by the lead (shown first, created with `--yes`). Autopilot builds them and its PRs close them. |
135
+ | `agent-team approve [PR]` | Approve a PR's current commit when it changes paths in `require_approval`; with no number, list what's waiting. |
136
+ | `agent-team notify` | Send a test message to the `[notify]` webhook. |
137
+ | `agent-team eval [--only feature,bug]` | Runs fixed scenarios with your real models in a throwaway project (no GitHub): pass/fail, rounds and cost. Asks before spending. |
138
+ | `agent-team estimate build` | Predicts a run's cost from this project's past runs. |
139
+ | `agent-team projects` | Every project you use agent-team in: spend, runs, what waits for you. |
140
+ | `agent-team scoreboard` | Each builder's approval and first-round rate, average rounds and cost; each reviewer's pushback; cost per merged PR. |
141
+ | `agent-team memory [add TEXT \| forget N]` | The lessons the team learned from its reviews, which every member sees in later work. |
142
+ | `agent-team agents`, `agent-team doctor` | List the team; check every member can be reached. |
143
+
144
+ `build` takes `--parallel` (split the plan across every builder), `--skip qa,security,docs`,
145
+ `--rounds`, `--builder` and `--lead`. Every command takes `-C <project>`; `--help` lists the rest.
146
+
147
+ ### Use it from Claude Code
148
+
149
+ The installer adds the plugin. To add it by hand, at the prompt of a Claude Code session:
150
+
151
+ ```
152
+ /plugin install agent-team --marketplace lakeba/agent-team
153
+ ```
154
+
155
+ Then, in any project: `/team-init`, `/team-doctor`, `/team-plan`, `/team-build <task>`,
156
+ `/team-ship`, `/team-fix <PR>`, `/team-schedule <6h>`, `/team-market` and `/team-ui`. Claude runs the workflow where you can watch it, checks the
157
+ result, and reports back. In projects with a `.team.toml`, the plugin also opens an agent-team side
158
+ panel (or run `/team-panel`): the team, each member's health, recent runs and spend, with buttons to
159
+ refresh, check health, start a devops shift and start the dashboard, plus background runs you can
160
+ stop. `/team-run build <task>` (or `fix <PR>`, `discuss <topic>`, `ship`, `market`, `doctor`) starts a run in
161
+ the background and the panel follows it. The commands need the `agent-team` CLI on your `PATH`.
162
+
163
+ ## Documentation
164
+
165
+ - [Architecture](docs/architecture.md): providers, agents, workflows and how they fit.
166
+ - [Configuration](docs/configuration.md): every `.team.toml` setting.
167
+ - [Extending](docs/extending.md): add a team member, a role, a provider or a workflow.
168
+ - [Remote agents](docs/remote-agents.md): let another machine join the team.
169
+ - [Examples](examples/): the todo-py team, and a larger team across four machines with security,
170
+ QA and docs members, parallel builders and spend limits.
171
+ - [Changelog](CHANGELOG.md) and [roadmap](ROADMAP.md).
172
+
173
+ ## Licence
174
+
175
+ MIT, see [LICENSE](LICENSE).
176
+
177
+ ## Status
178
+
179
+ Version 0.2.5. The workflows were proven on todo-py; see [ROADMAP.md](ROADMAP.md) for what's next
180
+ and [CONTRIBUTING.md](CONTRIBUTING.md) to help.
@@ -0,0 +1,150 @@
1
+ # agent-team
2
+
3
+ A configurable team of AI agents that works on a software project the way a small team would:
4
+ it plans a roadmap, builds features, reviews them, writes marketing material, and ships through
5
+ GitHub with pull requests, CI, sign-offs and releases.
6
+
7
+ Team members can run on any model and any machine: Claude through the Anthropic API, local
8
+ models through Ollama, any OpenAI-compatible server, or another machine running
9
+ `agent-team serve`. A team is described in a `.team.toml` file in each project, so adding a
10
+ member, a machine or a project is a configuration change.
11
+
12
+ It grew out of todo-py, a small command-line app this team planned, built, marketed and released
13
+ (v1.0.0 and v1.0.1); its team is in [examples/todo-py.team.toml](examples/todo-py.team.toml).
14
+
15
+ ## How the team works
16
+
17
+ | Workflow | Command | What happens |
18
+ |---|---|---|
19
+ | Discuss | `agent-team discuss "next features"` | Members talk in turn until they all agree; the lead updates `ROADMAP.md`. |
20
+ | Build | `agent-team build "task" --branch x --pr` | The lead writes `PLAN.md`, builders implement it (in parallel with `--parallel`), tests run each round, the lead reviews until approved, then a PR opens. Optional QA, security and docs members write tests first, review the result and update the docs. |
21
+ | Autopilot | `agent-team autopilot --milestone M2` | Works through the roadmap a PR at a time: the lead picks the next task, the team builds it, each devops shift reviews, fixes and merges, until the lead says the milestone is done (or it gets stuck, or hits a spend limit). |
22
+ | Fix | `agent-team fix 12` | When the lead requests changes on a PR, a builder applies the review on that PR's branch, the lead confirms the blocking points are addressed, and it pushes; the next shift reviews the new commit. |
23
+ | Market | `agent-team market` | The marketing member writes a brief, a website and a pitch deck; a fact-checker checks claims and the lead reviews with screenshots. |
24
+ | Set up | `agent-team setup --license "MIT, copyright 2026 Lakeba"` | The devops member drafts README, CONTRIBUTING, CHANGELOG, CI and templates. |
25
+ | Ship | `agent-team ship` | One devops shift on GitHub: triage, owner sign-offs, lead review, merge, release (or, with `release = "ask"`, a release proposal you approve with `ship --release X.Y.Z`), feedback digest. `agent-team schedule --every 6h` runs shifts unattended, never two at once. |
26
+ | Dashboard | `agent-team ui` | Overview, Team, Runs, Costs, live Activity charts (spend, runs, merges, problems, latest events), Settings (easy switches and team templates, always previewed as a diff) and Projects (every project on this Mac). A page on this machine: the team and whether each member is reachable, every run with each member's verdicts, estimated costs per member, day and run, and the GitHub state. Edit members, connections, guarantees and prices there, add a machine with a guided wizard, and review the diff before saving. Start runs there and follow their output live. |
27
+
28
+ Guardrails are enforced in code, not left to the models. A PR merges only when CI is green, the
29
+ lead approved the exact head commit, and every member who owns a changed path signed off that
30
+ same commit (the lead's approval is its own sign-off). On a re-review, reviewers block only on
31
+ points still open or problems the new commit introduces, so a PR that fixes what was asked passes. Releases need green CI on `main` and a CHANGELOG entry. Text from outside the team
32
+ always reaches the models marked as untrusted. Spend limits in `.team.toml` stop any run before it
33
+ costs more than you allow, and large projects get a focused context instead of every file.
34
+
35
+ Builders change files with small search/replace edits instead of rewriting them, and an edit
36
+ that doesn't match is refused and sent back. Reviewers read files, search, see the diff and run
37
+ the tests themselves. When a reviewer blocks for a reason that will matter again, the lesson is
38
+ kept and every member sees it in later work.
39
+
40
+ With `[sandbox] mode = "container"`, the code the team writes is tested in a throwaway container
41
+ with no network and none of your keys. Every push is checked for secrets first (key and token formats, private keys, `.env` files, and
42
+ the values in your keys file). Paths you list in `require_approval` wait for your approval of the
43
+ exact commit. Weaker models hand work to a stronger member after rejected rounds (`escalate_to`),
44
+ and `[notify]` posts to Slack or any webhook when PRs open or merge, approvals or releases wait
45
+ for you, or autopilot stops.
46
+
47
+ ## Install
48
+
49
+ Requirements: macOS or Linux, Python 3.11+ (on Ubuntu/Debian also `python3-venv`), git, and an
50
+ Anthropic API key for Claude members. Optional: [Ollama](https://ollama.com/)
51
+ for local models, on this machine or another. The workflows that work on GitHub (`build --pr`,
52
+ `ship`, `setup` and the plugin's PR steps) also need the [GitHub CLI](https://cli.github.com/)
53
+ signed in (`gh auth login`).
54
+
55
+ One command installs the CLI into its own environment under `~/.agent-team`, puts `agent-team` on
56
+ your `PATH` (`~/.local/bin`), and installs the Claude Code plugin if Claude Code is present:
57
+
58
+ ```bash
59
+ curl -fsSL https://raw.githubusercontent.com/lakeba/agent-team/main/scripts/install.sh | bash
60
+ ```
61
+
62
+ Run it again to update, then run `/reload-plugins` in any open Claude Code session (or start a new
63
+ one): an open session keeps the commands it started with. Options go after `bash -s --`, for example `| bash -s -- --ref v0.1.0`
64
+ for a specific version, `--no-plugin` to skip the plugin, or `--uninstall` to remove everything
65
+ it installed. If you prefer pipx: `pipx install git+https://github.com/lakeba/agent-team.git`
66
+ (that installs the CLI only).
67
+
68
+ ## Quick start
69
+
70
+ ```bash
71
+ agent-team keys set ANTHROPIC_API_KEY # asks for the key (hidden); every agent-team command finds it
72
+ cd ~/code/my-project
73
+ agent-team ready # checklist: git, GitHub, keys, Ollama, with the fix for anything missing
74
+ agent-team init # writes .team.toml; add --ollama-url http://HOST:11434 for Ollama on another machine
75
+ agent-team doctor # the checklist again, then checks every member can be reached
76
+ ```
77
+
78
+ Keys live in `~/.config/agent-team/env`, readable only by you, so they work the same from any shell,
79
+ the dashboard, background runs and schedules (Ubuntu's `~/.bashrc`, for one, is skipped by
80
+ non-interactive shells). A variable already exported in your environment wins.
81
+
82
+ Then edit `.team.toml` (or open `agent-team ui` and use **Edit team**): set the project's
83
+ guarantees, adjust the team, give members skills (Markdown files or Claude Code skill folders added
84
+ to their prompts), set spend limits under `[limits]`, and run a workflow:
85
+
86
+ ```bash
87
+ agent-team discuss "next features" # agree a roadmap
88
+ agent-team build "add an export command" --branch team/export --pr
89
+ agent-team ship # one devops shift on GitHub
90
+ ```
91
+
92
+ ### Other commands
93
+
94
+ | Command | What it does |
95
+ |---|---|
96
+ | `agent-team status [--json] [--health]` | The team, spend per member and today, recent and background runs, the schedule. |
97
+ | `agent-team ui` | The dashboard: see and edit the team, start runs, follow costs. |
98
+ | `agent-team jobs [start <workflow> \| stop <id> \| log <id>]` | Runs in the background, as the dashboard and the Claude panel start them. |
99
+ | `agent-team schedule --every 6h` | Run devops shifts on a schedule (launchd on macOS, cron elsewhere); `--remove` to stop. |
100
+ | `agent-team serve ...` | Serve a model on this machine as a team member for a team elsewhere. |
101
+ | `agent-team discover` | Find agent-team nodes on the local network. |
102
+ | `agent-team ready [--json]` | What this machine and project still need (git, GitHub, keys, Ollama, models), each with its fix. |
103
+ | `agent-team keys [set NAME \| remove NAME]` | API keys and tokens in agent-team's own keys file; values are never shown. |
104
+ | `agent-team issues [sync --milestone M2 --yes]` | The team's to-do list: `team:build` issues, created from the roadmap by the lead (shown first, created with `--yes`). Autopilot builds them and its PRs close them. |
105
+ | `agent-team approve [PR]` | Approve a PR's current commit when it changes paths in `require_approval`; with no number, list what's waiting. |
106
+ | `agent-team notify` | Send a test message to the `[notify]` webhook. |
107
+ | `agent-team eval [--only feature,bug]` | Runs fixed scenarios with your real models in a throwaway project (no GitHub): pass/fail, rounds and cost. Asks before spending. |
108
+ | `agent-team estimate build` | Predicts a run's cost from this project's past runs. |
109
+ | `agent-team projects` | Every project you use agent-team in: spend, runs, what waits for you. |
110
+ | `agent-team scoreboard` | Each builder's approval and first-round rate, average rounds and cost; each reviewer's pushback; cost per merged PR. |
111
+ | `agent-team memory [add TEXT \| forget N]` | The lessons the team learned from its reviews, which every member sees in later work. |
112
+ | `agent-team agents`, `agent-team doctor` | List the team; check every member can be reached. |
113
+
114
+ `build` takes `--parallel` (split the plan across every builder), `--skip qa,security,docs`,
115
+ `--rounds`, `--builder` and `--lead`. Every command takes `-C <project>`; `--help` lists the rest.
116
+
117
+ ### Use it from Claude Code
118
+
119
+ The installer adds the plugin. To add it by hand, at the prompt of a Claude Code session:
120
+
121
+ ```
122
+ /plugin install agent-team --marketplace lakeba/agent-team
123
+ ```
124
+
125
+ Then, in any project: `/team-init`, `/team-doctor`, `/team-plan`, `/team-build <task>`,
126
+ `/team-ship`, `/team-fix <PR>`, `/team-schedule <6h>`, `/team-market` and `/team-ui`. Claude runs the workflow where you can watch it, checks the
127
+ result, and reports back. In projects with a `.team.toml`, the plugin also opens an agent-team side
128
+ panel (or run `/team-panel`): the team, each member's health, recent runs and spend, with buttons to
129
+ refresh, check health, start a devops shift and start the dashboard, plus background runs you can
130
+ stop. `/team-run build <task>` (or `fix <PR>`, `discuss <topic>`, `ship`, `market`, `doctor`) starts a run in
131
+ the background and the panel follows it. The commands need the `agent-team` CLI on your `PATH`.
132
+
133
+ ## Documentation
134
+
135
+ - [Architecture](docs/architecture.md): providers, agents, workflows and how they fit.
136
+ - [Configuration](docs/configuration.md): every `.team.toml` setting.
137
+ - [Extending](docs/extending.md): add a team member, a role, a provider or a workflow.
138
+ - [Remote agents](docs/remote-agents.md): let another machine join the team.
139
+ - [Examples](examples/): the todo-py team, and a larger team across four machines with security,
140
+ QA and docs members, parallel builders and spend limits.
141
+ - [Changelog](CHANGELOG.md) and [roadmap](ROADMAP.md).
142
+
143
+ ## Licence
144
+
145
+ MIT, see [LICENSE](LICENSE).
146
+
147
+ ## Status
148
+
149
+ Version 0.2.5. The workflows were proven on todo-py; see [ROADMAP.md](ROADMAP.md) for what's next
150
+ and [CONTRIBUTING.md](CONTRIBUTING.md) to help.
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "agent-team"
7
+ version = "0.5.0"
8
+ description = "A configurable team of AI agents (any model, any machine) that plans, builds, reviews, markets and ships a software project through GitHub."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Lakeba" }]
14
+ keywords = ["ai", "agents", "llm", "claude", "ollama", "github", "devops"]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "Operating System :: MacOS",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Topic :: Software Development",
26
+ ]
27
+ dependencies = ["anthropic>=1.0"]
28
+
29
+ [project.optional-dependencies]
30
+ screenshots = ["pillow>=10"]
31
+ dev = ["pillow>=10"]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/lakeba/agent-team"
35
+ Documentation = "https://lakeba.github.io/agent-team/"
36
+ Changelog = "https://github.com/lakeba/agent-team/blob/main/CHANGELOG.md"
37
+
38
+ [project.scripts]
39
+ agent-team = "agent_team.cli:main"
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
43
+
44
+ [tool.setuptools.package-data]
45
+ agent_team = ["prompts/*.md", "dashboard/static/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """agent-team: a configurable team of AI agents that works on a project through GitHub."""
2
+
3
+ __version__ = "0.5.0"
@@ -0,0 +1,109 @@
1
+ """A team member at runtime: its config, its provider, and an append-only conversation."""
2
+ from __future__ import annotations
3
+
4
+ from importlib import resources
5
+ from pathlib import Path
6
+
7
+ from . import budget, providers, ui, usage
8
+ from .config import AgentConfig, Team
9
+
10
+
11
+ def role_prompt(team: Team, agent: AgentConfig, name: str | None = None) -> str:
12
+ """The agent's prompt text: its own file if configured, else the packaged one for its role."""
13
+ if agent.prompt and name is None:
14
+ return (team.root / agent.prompt).read_text(encoding="utf-8")
15
+ fname = f"{name or agent.role}.md"
16
+ try:
17
+ return resources.files("agent_team.prompts").joinpath(fname).read_text(encoding="utf-8")
18
+ except FileNotFoundError:
19
+ return resources.files("agent_team.prompts").joinpath("member.md").read_text(encoding="utf-8")
20
+
21
+
22
+ def team_roster(team: Team) -> str:
23
+ lines = []
24
+ for a in team.agents.values():
25
+ where = team.providers[a.provider]
26
+ place = f"remote node {where.url}" if where.kind == "agent-http" else f"{where.kind} model {a.model}"
27
+ desc = f" {a.description}" if a.description else ""
28
+ owns = f" Owns: {', '.join(a.owns)}." if a.owns else ""
29
+ skills = f" Skills: {', '.join(_skill_names(team, a))}." if a.skills else ""
30
+ lines.append(f"- {a.name} ({a.role}, {place}).{desc}{owns}{skills}")
31
+ return "\n".join(lines)
32
+
33
+
34
+ class Agent:
35
+ def __init__(self, team: Team, cfg: AgentConfig, system: str, label_suffix: str = ""):
36
+ self.team, self.cfg, self.system = team, cfg, system
37
+ pcfg = team.providers[cfg.provider]
38
+ self.provider = providers.build(pcfg, team.secret(pcfg))
39
+ self.label = ui.label(cfg.name, cfg.role + label_suffix, cfg.color)
40
+ self.messages: list[dict] = [] # append-only, so provider-side reasoning stays valid
41
+
42
+ @property
43
+ def name(self) -> str:
44
+ return self.cfg.name
45
+
46
+ def turn(self, content) -> str:
47
+ if not self.provider.supports_images and not isinstance(content, str):
48
+ content = providers.base.to_text(content)
49
+ budget.check(self.team)
50
+ self.messages.append({"role": "user", "content": content})
51
+ reply = self.provider.complete(self.system, self.messages, model=self.cfg.model,
52
+ effort=self.cfg.effort, label=self.label)
53
+ self.messages.append({"role": "assistant", "content": reply.content})
54
+ # A remote node reports the model it really ran, so its member is priced correctly.
55
+ u = dict(reply.usage or {})
56
+ kind, model = u.pop("kind", "") or self.provider.kind, u.pop("model", "") or self.cfg.model
57
+ usage.record(self.team.root, self.cfg.name, kind, model, u)
58
+ return reply.text
59
+
60
+
61
+ def _skill_names(team: Team, cfg: AgentConfig) -> list[str]:
62
+ from . import skills
63
+ names = []
64
+ for entry in cfg.skills:
65
+ try:
66
+ names.append(skills.load_one(team, entry).name)
67
+ except Exception:
68
+ names.append(entry)
69
+ return names
70
+
71
+
72
+ def make(team: Team, cfg: AgentConfig, prompt_name: str | None = None, label_suffix: str = "",
73
+ **fields) -> Agent:
74
+ """Build an agent whose system prompt is its role prompt filled with team and project facts."""
75
+ template = role_prompt(team, cfg, prompt_name)
76
+ values = {
77
+ "name": cfg.name, "role": cfg.role, "project": team.project.name, "repo": team.project.repo,
78
+ "roster": team_roster(team), "owns": ", ".join(cfg.owns) or "nothing",
79
+ "guarantees": "\n".join(f"- {g}" for g in team.project.guarantees) or "- (none listed)",
80
+ "test_command": team.project.test_command or "(none configured)",
81
+ **fields,
82
+ }
83
+ system = _fill(template, values)
84
+ from . import memory
85
+ learned = memory.for_prompt(team.root)
86
+ if learned:
87
+ system = f"{system.rstrip()}\n\n{learned}"
88
+ if cfg.skills:
89
+ from . import skills
90
+ system = f"{system.rstrip()}\n\n{skills.render(skills.load(team, cfg))}"
91
+ return Agent(team, cfg, system, label_suffix)
92
+
93
+
94
+ def _fill(template: str, values: dict) -> str:
95
+ """str.format that leaves unknown {placeholders} and literal braces alone."""
96
+ class Keep(dict):
97
+ def __missing__(self, key):
98
+ return "{" + key + "}"
99
+ try:
100
+ return template.format_map(Keep(values))
101
+ except (ValueError, IndexError):
102
+ out = template
103
+ for k, v in values.items():
104
+ out = out.replace("{" + k + "}", str(v))
105
+ return out
106
+
107
+
108
+ def prompt_path(team: Team, agent: AgentConfig) -> Path | None:
109
+ return team.root / agent.prompt if agent.prompt else None
@@ -0,0 +1,56 @@
1
+ """Spend limits: stop a run before it costs more than `[limits]` allows.
2
+
3
+ [limits]
4
+ per_run = 5.0 # US dollars for one workflow run
5
+ per_day = 20.0 # US dollars per UTC day, across every run in this project
6
+
7
+ Checked before every model call, from the estimates in `.team/usage.jsonl`. A call already in
8
+ flight finishes, so a run can go over by at most one reply.
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from . import usage
13
+ from .config import Team
14
+
15
+
16
+ class SpendLimitError(RuntimeError):
17
+ pass
18
+
19
+
20
+ def spent(team: Team, run: str | None = None) -> dict:
21
+ """Estimated dollars spent in this run and today (UTC)."""
22
+ run = usage.current_run() if run is None else run
23
+ today = usage.now()[:10]
24
+ out = {"run": 0.0, "today": 0.0}
25
+ for e in usage.load(team.root):
26
+ cost = usage.price_for(e.get("model", ""), e.get("kind", ""), team.pricing).cost(e)
27
+ if run and e.get("run") == run:
28
+ out["run"] += cost
29
+ if (e.get("at") or "")[:10] == today:
30
+ out["today"] += cost
31
+ return {k: round(v, 4) for k, v in out.items()}
32
+
33
+
34
+ def milestone_spent(team: Team, milestone: str) -> float:
35
+ return round(sum(usage.price_for(e.get("model", ""), e.get("kind", ""), team.pricing).cost(e)
36
+ for e in usage.load(team.root) if e.get("milestone") == milestone), 4)
37
+
38
+
39
+ def check(team: Team) -> None:
40
+ limits = team.limits
41
+ milestone = usage.current_milestone()
42
+ cap = limits.milestones.get(milestone) if milestone else None
43
+ if cap:
44
+ spent_m = milestone_spent(team, milestone)
45
+ if spent_m >= cap:
46
+ raise SpendLimitError(f"milestone {milestone} has spent an estimated ${spent_m:.2f}, reaching its "
47
+ f"[limits.milestones] budget of ${cap:.2f}")
48
+ if not (limits.per_run or limits.per_day):
49
+ return
50
+ s = spent(team)
51
+ if limits.per_run and s["run"] >= limits.per_run:
52
+ raise SpendLimitError(f"this run has spent an estimated ${s['run']:.2f}, reaching the "
53
+ f"[limits].per_run limit of ${limits.per_run:.2f}")
54
+ if limits.per_day and s["today"] >= limits.per_day:
55
+ raise SpendLimitError(f"this project has spent an estimated ${s['today']:.2f} today (UTC), reaching "
56
+ f"the [limits].per_day limit of ${limits.per_day:.2f}")