wbcli 0.0.1__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 (38) hide show
  1. wbcli-0.0.1/.github/CODEOWNERS +1 -0
  2. wbcli-0.0.1/.github/workflows/ci.yml +30 -0
  3. wbcli-0.0.1/.github/workflows/release.yml +110 -0
  4. wbcli-0.0.1/.gitignore +23 -0
  5. wbcli-0.0.1/LICENSE +21 -0
  6. wbcli-0.0.1/PKG-INFO +22 -0
  7. wbcli-0.0.1/README.md +208 -0
  8. wbcli-0.0.1/pyproject.toml +63 -0
  9. wbcli-0.0.1/setup.cfg +4 -0
  10. wbcli-0.0.1/tests/__init__.py +0 -0
  11. wbcli-0.0.1/tests/conftest.py +35 -0
  12. wbcli-0.0.1/tests/test_adapters.py +233 -0
  13. wbcli-0.0.1/tests/test_agents.py +138 -0
  14. wbcli-0.0.1/tests/test_cli.py +393 -0
  15. wbcli-0.0.1/tests/test_orchestrator.py +88 -0
  16. wbcli-0.0.1/tests/test_pipeline.py +227 -0
  17. wbcli-0.0.1/tests/test_plan_parser.py +134 -0
  18. wbcli-0.0.1/tests/test_prompt_builder.py +264 -0
  19. wbcli-0.0.1/tests/test_tmux.py +473 -0
  20. wbcli-0.0.1/tests/test_worktree.py +209 -0
  21. wbcli-0.0.1/uv.lock +400 -0
  22. wbcli-0.0.1/wbcli.egg-info/PKG-INFO +22 -0
  23. wbcli-0.0.1/wbcli.egg-info/SOURCES.txt +36 -0
  24. wbcli-0.0.1/wbcli.egg-info/dependency_links.txt +1 -0
  25. wbcli-0.0.1/wbcli.egg-info/entry_points.txt +2 -0
  26. wbcli-0.0.1/wbcli.egg-info/requires.txt +9 -0
  27. wbcli-0.0.1/wbcli.egg-info/top_level.txt +3 -0
  28. wbcli-0.0.1/workbench/__init__.py +6 -0
  29. wbcli-0.0.1/workbench/_version.py +24 -0
  30. wbcli-0.0.1/workbench/adapters.py +154 -0
  31. wbcli-0.0.1/workbench/agents.py +547 -0
  32. wbcli-0.0.1/workbench/cli.py +434 -0
  33. wbcli-0.0.1/workbench/orchestrator.py +343 -0
  34. wbcli-0.0.1/workbench/plan_parser.py +166 -0
  35. wbcli-0.0.1/workbench/skills/__init__.py +0 -0
  36. wbcli-0.0.1/workbench/skills/use-workbench/SKILL.md +238 -0
  37. wbcli-0.0.1/workbench/tmux.py +108 -0
  38. wbcli-0.0.1/workbench/worktree.py +262 -0
@@ -0,0 +1 @@
1
+ * @duncankmckinnon
@@ -0,0 +1,30 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0 # full history for setuptools-scm
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ allow-prereleases: true
25
+
26
+ - name: Install dependencies
27
+ run: pip install -e ".[dev]"
28
+
29
+ - name: Run tests with coverage
30
+ run: pytest tests/ -v
@@ -0,0 +1,110 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev]"
26
+
27
+ - name: Run tests
28
+ run: pytest tests/ -v
29
+
30
+ build:
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ with:
36
+ fetch-depth: 0 # full history for setuptools-scm
37
+
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Install build tools
43
+ run: pip install build
44
+
45
+ - name: Build package
46
+ run: python -m build
47
+
48
+ - name: Upload artifacts
49
+ uses: actions/upload-artifact@v4
50
+ with:
51
+ name: dist
52
+ path: dist/
53
+
54
+ publish-pypi:
55
+ needs: build
56
+ runs-on: ubuntu-latest
57
+ environment: "pypi"
58
+ steps:
59
+ - name: Download artifacts
60
+ uses: actions/download-artifact@v4
61
+ with:
62
+ name: dist
63
+ path: dist/
64
+
65
+ - name: Publish to PyPI
66
+ uses: pypa/gh-action-pypi-publish@release/v1
67
+
68
+ github-release:
69
+ needs: build
70
+ runs-on: ubuntu-latest
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ with:
74
+ fetch-depth: 0
75
+
76
+ - name: Download artifacts
77
+ uses: actions/download-artifact@v4
78
+ with:
79
+ name: dist
80
+ path: dist/
81
+
82
+ - name: Generate changelog
83
+ id: changelog
84
+ run: |
85
+ # Get previous tag
86
+ PREV_TAG=$(git tag --sort=-v:refname | head -2 | tail -1)
87
+ if [ -z "$PREV_TAG" ]; then
88
+ CHANGELOG=$(git log --oneline --no-decorate)
89
+ else
90
+ CHANGELOG=$(git log --oneline --no-decorate ${PREV_TAG}..HEAD)
91
+ fi
92
+ echo "changelog<<EOF" >> $GITHUB_OUTPUT
93
+ echo "$CHANGELOG" >> $GITHUB_OUTPUT
94
+ echo "EOF" >> $GITHUB_OUTPUT
95
+
96
+ - name: Create GitHub Release
97
+ uses: softprops/action-gh-release@v2
98
+ with:
99
+ body: |
100
+ ## Changes
101
+
102
+ ${{ steps.changelog.outputs.changelog }}
103
+
104
+ ## Install
105
+
106
+ ```bash
107
+ pip install wbcli
108
+ ```
109
+ files: dist/*
110
+ generate_release_notes: false
wbcli-0.0.1/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+ *.egg
8
+ workbench/_version.py
9
+ .coverage
10
+
11
+ # Virtual environments
12
+ .venv/
13
+
14
+ # Workbench runtime
15
+ .workbench/
16
+
17
+ # OS
18
+ .DS_Store
19
+
20
+ # IDE
21
+ .idea/
22
+ .vscode/
23
+ *.swp
wbcli-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Duncan McKinnon
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.
wbcli-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: wbcli
3
+ Version: 0.0.1
4
+ Summary: Lightweight multi-agent orchestrator for iterative development
5
+ Author: Duncan McKinnon
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/duncankmckinnon/workbench
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Programming Language :: Python :: 3.14
12
+ Requires-Python: >=3.11
13
+ License-File: LICENSE
14
+ Requires-Dist: click>=8.0
15
+ Requires-Dist: rich>=13.0
16
+ Requires-Dist: pyyaml>=6.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8.0; extra == "dev"
19
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
20
+ Requires-Dist: pytest-mock>=3.12; extra == "dev"
21
+ Requires-Dist: pytest-cov>=6.0; extra == "dev"
22
+ Dynamic: license-file
wbcli-0.0.1/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # Workbench
2
+
3
+ [![CI](https://github.com/duncankmckinnon/workbench/actions/workflows/ci.yml/badge.svg)](https://github.com/duncankmckinnon/workbench/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/wbcli)](https://pypi.org/project/wbcli/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/wbcli)](https://pypi.org/project/wbcli/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
+
8
+ Multi-agent orchestrator that dispatches AI coding agents in parallel across isolated git worktrees.
9
+
10
+ Write a markdown plan, run `wb run plan.md`, and workbench parses it into tasks, groups them into dependency waves, and runs each task through an implement → test → review → fix pipeline.
11
+
12
+ ## Requirements
13
+
14
+ - Python 3.11+
15
+ - tmux (recommended — `brew install tmux` / `apt install tmux`). Use `--no-tmux` without it.
16
+ - An agent CLI: [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (default), [Codex](https://github.com/openai/codex), or any custom CLI.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install wbcli
22
+ ```
23
+
24
+ For development:
25
+
26
+ ```bash
27
+ pip install -e ".[dev]" # includes pytest
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```bash
33
+ wb setup # create .workbench/ and install skills
34
+ wb preview plan.md # dry-run: show tasks and waves
35
+ wb run plan.md # run the plan
36
+ wb run plan.md -j 6 --no-tmux # 6 parallel agents, no tmux
37
+ wb run plan.md --agent codex # use codex instead of claude
38
+ wb status # show active worktrees
39
+ wb clean # remove all worktrees and wb/ branches
40
+ ```
41
+
42
+ ### Resuming a run
43
+
44
+ ```bash
45
+ wb run plan.md -b workbench-2 -w 3 # resume session branch from wave 3
46
+ ```
47
+
48
+ ### Directive overrides
49
+
50
+ Override the instructions given to any agent role:
51
+
52
+ ```bash
53
+ wb run plan.md --reviewer-directive "Focus only on security issues."
54
+ wb run plan.md --tester-directive "Run pytest with -x flag, fail fast."
55
+ ```
56
+
57
+ Available: `--implementor-directive`, `--tester-directive`, `--reviewer-directive`, `--fixer-directive`.
58
+
59
+ ## Plan format
60
+
61
+ ## TDD mode
62
+
63
+ Run with `--tdd` to write tests before implementation:
64
+
65
+ ```bash
66
+ wb run plan.md --tdd
67
+ ```
68
+
69
+ Pipeline becomes: **write tests → implement → verify tests → review → fix**
70
+
71
+ The tester agent writes comprehensive failing tests based on the task description, then the implementor writes code to make them pass. After that, normal test verification and review proceed as usual.
72
+
73
+ Cannot be combined with `--skip-test`.
74
+
75
+ ## Stopping agents
76
+
77
+ ```bash
78
+ wb stop # kill all active agent tmux sessions
79
+ wb stop --cleanup # also remove worktrees and branches
80
+ ```
81
+
82
+ ## CLI reference
83
+
84
+ | Command | Description |
85
+ |---|---|
86
+ | `wb run <plan>` | Execute a plan |
87
+ | `wb preview <plan>` | Dry-run preview of tasks and waves |
88
+ | `wb status` | Show active worktrees |
89
+ | `wb stop` | Stop all running agents and optionally clean up |
90
+ | `wb clean` | Remove all workbench worktrees and branches |
91
+ | `wb init` | Set up workbench for your agent platform |
92
+
93
+ ## Conventions
94
+ - Python 3.11+, type hints
95
+ - Tests: pytest, run with `uv run pytest`
96
+
97
+ | Flag | Description |
98
+ |---|---|
99
+ | `-j N` | Max concurrent tasks (default: 4) |
100
+ | `--tdd` | Test-driven: write tests first, then implement |
101
+ | `--skip-test` | Skip the test phase |
102
+ | `--skip-review` | Skip the review phase |
103
+ | `--max-retries N` | Max fix cycles per task (default: 2) |
104
+ | `--agent CMD` | Agent CLI command (default: `claude`) |
105
+ | `--no-tmux` | Run agents as subprocesses instead of in tmux sessions |
106
+ | `--session-branch NAME` | Resume an existing session branch |
107
+ | `--start-wave N` | Skip already-merged waves |
108
+ | `--cleanup` | Remove worktrees after completion |
109
+ | `--repo PATH` | Repository path (auto-detected if omitted) |
110
+
111
+ - `## Context` and `## Conventions` are injected into every agent's prompt.
112
+ - `Files:` declares which files the task owns (prevents parallel conflicts).
113
+ - `Depends:` references other tasks by slug (title lowercased, non-alphanumeric → `-`).
114
+ - Tasks without dependencies run in the earliest wave. Keep titles short (2-4 words) — they become dependency slugs.
115
+
116
+ ## Agent pipeline
117
+
118
+ Each task runs through:
119
+
120
+ ```
121
+ implement → test → review → fix (retry up to --max-retries)
122
+ ```
123
+
124
+ Skip stages with `--skip-test` or `--skip-review`. Merge conflicts between parallel branches are automatically resolved by a merger agent.
125
+
126
+ ## Custom agents
127
+
128
+ Define adapters in `.workbench/agents.yaml`:
129
+
130
+ ```yaml
131
+ agents:
132
+ my-agent:
133
+ command: my-agent-cli
134
+ args: ["--headless", "{prompt}"]
135
+ output_format: json
136
+ json_result_key: result
137
+ json_cost_key: cost_usd
138
+ ```
139
+
140
+ ```bash
141
+ wb run plan.md --agent my-agent
142
+ ```
143
+
144
+ ## Agent commands
145
+
146
+ Workbench bundles guidance files that teach agents how to write plans. `wb init` installs them in the right format for each platform:
147
+
148
+ ```bash
149
+ wb init --agent claude # installs as /use-workbench command in ~/.claude/commands/
150
+ wb init --agent cursor # installs as rule in .cursor/rules/
151
+ wb init --agent codex # appends to .codex/instructions.md
152
+ wb init --agent manual # prints paths for manual setup
153
+ wb init --symlink # symlink instead of copy (for development)
154
+ ```
155
+
156
+ `wb setup` combines `.workbench/` creation with command installation in one step.
157
+
158
+ ## Monitoring
159
+
160
+ With tmux (default), attach to watch an agent work:
161
+
162
+ ```bash
163
+ tmux attach -t wb-task-1-implementor
164
+ ```
165
+
166
+ Sessions are named `wb-task-<N>-<role>`.
167
+
168
+ ## CLI reference
169
+
170
+ | Command | Description |
171
+ |---|---|
172
+ | `wb run <plan>` | Execute a plan |
173
+ | `wb preview <plan>` | Show tasks and waves |
174
+ | `wb status` | Show active worktrees |
175
+ | `wb clean` | Remove worktrees and branches |
176
+ | `wb init` | Install skills for an agent platform |
177
+ | `wb setup` | Create `.workbench/` and install skills |
178
+
179
+ | `wb run` flag | Description |
180
+ |---|---|
181
+ | `-j N` | Max concurrent agents (default: 4) |
182
+ | `-r N` | Max fix retries per stage (default: 2) |
183
+ | `--skip-test` | Skip testing phase |
184
+ | `--skip-review` | Skip review phase |
185
+ | `--agent CMD` | Agent CLI (default: `claude`) |
186
+ | `--no-tmux` | Raw subprocess instead of tmux |
187
+ | `-b NAME` | Resume a session branch |
188
+ | `-w N` | Start from wave N |
189
+ | `--cleanup` | Remove worktrees after completion |
190
+ | `--*-directive` | Override role instructions |
191
+
192
+ ## Development
193
+
194
+ ```bash
195
+ pip install -e ".[dev]"
196
+ pytest # 114 tests
197
+ ```
198
+
199
+ Version is derived from git tags via `setuptools-scm`. Published to PyPI as [`wbcli`](https://pypi.org/project/wbcli/). To release:
200
+
201
+ ```bash
202
+ git tag v0.1.0
203
+ git push origin v0.1.0 # triggers CI → PyPI + GitHub Release
204
+ ```
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,63 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "setuptools-scm>=8.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "wbcli"
7
+ dynamic = ["version"]
8
+ description = "Lightweight multi-agent orchestrator for iterative development"
9
+ license = "MIT"
10
+ authors = [{name = "Duncan McKinnon"}]
11
+ requires-python = ">=3.11"
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Programming Language :: Python :: 3.14",
17
+ ]
18
+ dependencies = [
19
+ "click>=8.0",
20
+ "rich>=13.0",
21
+ "pyyaml>=6.0",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "pytest>=8.0",
27
+ "pytest-asyncio>=0.23",
28
+ "pytest-mock>=3.12",
29
+ "pytest-cov>=6.0",
30
+ ]
31
+
32
+ [project.urls]
33
+ Repository = "https://github.com/duncankmckinnon/workbench"
34
+
35
+ [project.scripts]
36
+ wb = "workbench.cli:main"
37
+
38
+ [tool.setuptools.packages.find]
39
+ where = ["."]
40
+
41
+ [tool.setuptools.package-data]
42
+ "workbench.skills" = ["**/*.md"]
43
+
44
+ [tool.setuptools_scm]
45
+ write_to = "workbench/_version.py"
46
+
47
+ [tool.pytest.ini_options]
48
+ asyncio_mode = "auto"
49
+ testpaths = ["tests"]
50
+ addopts = "--cov=workbench --cov-report=term-missing --cov-fail-under=70"
51
+
52
+ [tool.coverage.run]
53
+ omit = [
54
+ "workbench/_version.py",
55
+ "workbench/skills/*",
56
+ ]
57
+
58
+ [tool.coverage.report]
59
+ exclude_lines = [
60
+ "pragma: no cover",
61
+ "if __name__ == .__main__.",
62
+ "if TYPE_CHECKING:",
63
+ ]
wbcli-0.0.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,35 @@
1
+ """Shared test fixtures."""
2
+
3
+ import subprocess
4
+
5
+ import pytest
6
+
7
+
8
+ @pytest.fixture
9
+ def git_repo(tmp_path):
10
+ """Create a temporary git repo with main branch and initial commit."""
11
+ subprocess.run(
12
+ ["git", "init", "--initial-branch=main"],
13
+ cwd=tmp_path,
14
+ check=True,
15
+ capture_output=True,
16
+ )
17
+ subprocess.run(
18
+ ["git", "config", "user.email", "test@test.com"],
19
+ cwd=tmp_path,
20
+ capture_output=True,
21
+ )
22
+ subprocess.run(
23
+ ["git", "config", "user.name", "Test"],
24
+ cwd=tmp_path,
25
+ capture_output=True,
26
+ )
27
+ (tmp_path / "README.md").write_text("init")
28
+ subprocess.run(["git", "add", "."], cwd=tmp_path, capture_output=True)
29
+ subprocess.run(
30
+ ["git", "commit", "-m", "init"],
31
+ cwd=tmp_path,
32
+ check=True,
33
+ capture_output=True,
34
+ )
35
+ return tmp_path