skillbench-cli 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.
- skillbench_cli-0.1.0/.gitignore +6 -0
- skillbench_cli-0.1.0/LICENSE +21 -0
- skillbench_cli-0.1.0/PKG-INFO +218 -0
- skillbench_cli-0.1.0/README.md +197 -0
- skillbench_cli-0.1.0/pyproject.toml +46 -0
- skillbench_cli-0.1.0/src/skillbench/__init__.py +1 -0
- skillbench_cli-0.1.0/src/skillbench/assertions.py +250 -0
- skillbench_cli-0.1.0/src/skillbench/claude.py +277 -0
- skillbench_cli-0.1.0/src/skillbench/cli.py +323 -0
- skillbench_cli-0.1.0/src/skillbench/config.py +269 -0
- skillbench_cli-0.1.0/src/skillbench/dashboard.py +543 -0
- skillbench_cli-0.1.0/src/skillbench/progress.py +219 -0
- skillbench_cli-0.1.0/src/skillbench/runner.py +471 -0
- skillbench_cli-0.1.0/src/skillbench/scaffold.py +106 -0
- skillbench_cli-0.1.0/src/skillbench/skills.py +168 -0
- skillbench_cli-0.1.0/src/skillbench/workspace.py +124 -0
- skillbench_cli-0.1.0/uv.lock +149 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Saul
|
|
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,218 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: skillbench-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Test your Claude Code skills and agent workflows, the way you test code.
|
|
5
|
+
Project-URL: Homepage, https://github.com/adamsaul314/skillbench
|
|
6
|
+
Project-URL: Issues, https://github.com/adamsaul314/skillbench/issues
|
|
7
|
+
Author: Adam Saul
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: agents,claude,claude-code,evals,skills,testing
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Software Development :: Testing
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Requires-Dist: pyyaml>=6.0
|
|
19
|
+
Requires-Dist: rich>=13.7
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# skillbench
|
|
23
|
+
|
|
24
|
+
Test your Claude Code skills and agent workflows, the way you test code.
|
|
25
|
+
|
|
26
|
+
You write a small YAML file that says *"send this to Claude, then check these things"*. skillbench runs Claude Code for real on a copy of your repo, records everything it did, and tells you **pass** or **fail**.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. Install
|
|
31
|
+
|
|
32
|
+
You need Python 3.11+, git, and Claude Code installed and logged in (check with `claude --version`). Then install with whichever tool you use:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
pip install skillbench-cli
|
|
36
|
+
pipx install skillbench-cli
|
|
37
|
+
uv tool install skillbench-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The command is `skillbench` either way. To try it without installing: `uvx --from skillbench-cli skillbench init`.
|
|
41
|
+
|
|
42
|
+
## 2. Try it (2 minutes)
|
|
43
|
+
|
|
44
|
+
In your repo:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
skillbench init # creates a skillbench/ folder with two example tests
|
|
48
|
+
skillbench skill # runs the skill test
|
|
49
|
+
skillbench agent # runs the agent test
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
You'll see something like:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
[1/1] hello-greets-by-name default model
|
|
56
|
+
hello-greets-by-name: pass in 2.3s
|
|
57
|
+
dashboard: skillbench/runs/index.html
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Open `skillbench/runs/index.html` in your browser to see exactly what Claude did: every message, tool call and check.
|
|
61
|
+
|
|
62
|
+
That's it. The rest of this page shows how to write your own tests.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Two kinds of test
|
|
67
|
+
|
|
68
|
+
| | **Skill test** | **Agent test** |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Question it answers | "When my skill runs, does it do the right thing?" | "Given a normal request, does Claude pick the right skills and get the job done?" |
|
|
71
|
+
| Lives in | `skillbench/skills/` | `skillbench/agent/` |
|
|
72
|
+
| Run with | `skillbench skill` | `skillbench agent` |
|
|
73
|
+
| You write | `skill:` and `input:` | `prompt:` |
|
|
74
|
+
|
|
75
|
+
### A skill test
|
|
76
|
+
|
|
77
|
+
`skillbench/skills/grilling.yaml`
|
|
78
|
+
|
|
79
|
+
```yaml
|
|
80
|
+
skill: grilling # your skill's name
|
|
81
|
+
input: an idea for a todo app # what to send it
|
|
82
|
+
fixture: . # run it on a copy of this repo
|
|
83
|
+
|
|
84
|
+
assert:
|
|
85
|
+
- final_text_contains: "Q1"
|
|
86
|
+
- tool_not_called: Write
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
skillbench finds the skill wherever it lives in your repo (`.claude/skills/`, `skills/`, `.github/skills/` or a plugin) and runs it as `/grilling an idea for a todo app`.
|
|
90
|
+
|
|
91
|
+
### An agent test
|
|
92
|
+
|
|
93
|
+
`skillbench/agent/csv-export.yaml`
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
prompt: add CSV export to the report page
|
|
97
|
+
fixture: .
|
|
98
|
+
|
|
99
|
+
answers: # replies, sent one at a time when Claude asks something
|
|
100
|
+
- Yes to all your recommendations.
|
|
101
|
+
- approved
|
|
102
|
+
|
|
103
|
+
assert:
|
|
104
|
+
- skill_invoked: planner
|
|
105
|
+
- tool_order: [Read, Edit, Bash]
|
|
106
|
+
- command_succeeds: python -m pytest -q
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Nothing is forced here. Claude sees every skill in your repo and decides for itself, and the test checks what it chose.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 4. Checks you can make
|
|
114
|
+
|
|
115
|
+
Put any of these under `assert:`.
|
|
116
|
+
|
|
117
|
+
| Check | Passes when |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `skill_invoked: grilling` | Claude used that skill |
|
|
120
|
+
| `skill_not_invoked: grilling` | Claude didn't use that skill |
|
|
121
|
+
| `tool_order: [Read, Edit]` | Claude used these tools in this order (other tools in between are fine) |
|
|
122
|
+
| `tool_not_called: Write` | Claude never used that tool |
|
|
123
|
+
| `final_text_contains: "Done"` | Claude's last message contains the text |
|
|
124
|
+
| `file_contains: {path: notes.md, text: "approved"}` | That file exists afterwards and contains the text |
|
|
125
|
+
| `command_succeeds: python -m pytest -q` | The command runs successfully in the workspace afterwards |
|
|
126
|
+
|
|
127
|
+
A test passes when every check passes.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 5. Which repo Claude works in (`fixture:`)
|
|
132
|
+
|
|
133
|
+
Claude always works on a **copy**, so your real files are never touched.
|
|
134
|
+
|
|
135
|
+
| `fixture:` | Claude gets |
|
|
136
|
+
|---|---|
|
|
137
|
+
| *(leave it out)* | An empty folder |
|
|
138
|
+
| `.` | A copy of your repo, including work you haven't committed |
|
|
139
|
+
| `some/folder` | A copy of that folder |
|
|
140
|
+
| `https://github.com/you/app.git` | A fresh clone |
|
|
141
|
+
| `{git: https://github.com/you/app.git, ref: v1.2}` | A clone at that branch, tag or commit |
|
|
142
|
+
|
|
143
|
+
Paths are relative to your repo root. The copy is kept after the run so you can look inside, and its path is in the dashboard.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 6. Running tests
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
skillbench skill # all skill tests
|
|
151
|
+
skillbench skill grilling # just the tests for one skill (or one test by name)
|
|
152
|
+
skillbench agent csv-export # one agent test
|
|
153
|
+
skillbench agent --repeat 5 # run each test 5 times
|
|
154
|
+
skillbench agent --model claude-sonnet-5-5
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
While it runs you'll see the current test, what Claude is doing, and roughly how long is left.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 7. More options
|
|
162
|
+
|
|
163
|
+
You won't need these to start.
|
|
164
|
+
|
|
165
|
+
**Check a skill gets picked on its own.** List prompts that should and shouldn't trigger it. Each runs briefly and stops as soon as Claude decides:
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
skill: grilling
|
|
169
|
+
triggers:
|
|
170
|
+
should: ["stress-test my plan"]
|
|
171
|
+
should_not: ["fix this typo"]
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Answer Claude yourself.** Add `interactive: true` and skillbench asks *you* in the terminal whenever Claude is waiting for a reply. Press Enter on an empty line to finish.
|
|
175
|
+
|
|
176
|
+
**Check for flakiness.** Claude doesn't do exactly the same thing every time. `--repeat 5` (or `repeat: 5` in the test) runs it 5 times and shows how often each check passed. Add `min_pass_rate: 0.8` to pass when 4 out of 5 runs pass.
|
|
177
|
+
|
|
178
|
+
**Set defaults for every test** in `skillbench/skillbench.yaml`:
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
model: claude-sonnet-5-5
|
|
182
|
+
timeout_s: 600 # seconds before a turn is stopped
|
|
183
|
+
fixture: .
|
|
184
|
+
repeat: 1
|
|
185
|
+
min_pass_rate: 1.0
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
A test's own settings win over these, and command-line flags win over both.
|
|
189
|
+
|
|
190
|
+
**All test fields:**
|
|
191
|
+
|
|
192
|
+
| Field | Meaning |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `skill` / `input` | Skill tests: which skill, and what to send it |
|
|
195
|
+
| `prompt` | Agent tests: the first message |
|
|
196
|
+
| `answers` | Replies sent one per turn |
|
|
197
|
+
| `interactive` | Ask you in the terminal for replies |
|
|
198
|
+
| `triggers` | Prompts that should / shouldn't pick the skill |
|
|
199
|
+
| `fixture` | Which repo Claude works in |
|
|
200
|
+
| `assert` | The checks |
|
|
201
|
+
| `name` | A display name (defaults to the file name) |
|
|
202
|
+
| `timeout_s`, `repeat`, `min_pass_rate` | As above |
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Good to know
|
|
207
|
+
|
|
208
|
+
- **It costs real usage.** Every run is a real Claude session. Start with skill tests; long agent tests take longer and cost more.
|
|
209
|
+
- **Your personal setup is ignored.** Only the skills and plugins in the repo being tested are loaded, so results don't depend on whose machine runs them.
|
|
210
|
+
- **Only test repos you trust.** Claude has full tool access inside the copy, and `command_succeeds` runs commands there.
|
|
211
|
+
- **`command_succeeds` uses your system shell** (`sh` on Mac/Linux, `cmd` on Windows), so keep commands simple if you share tests across systems.
|
|
212
|
+
- **Results** are in `skillbench/runs/`, which is git-ignored. Each run has a `run.json` and Claude's raw output.
|
|
213
|
+
|
|
214
|
+
| Status | Meaning |
|
|
215
|
+
|---|---|
|
|
216
|
+
| `pass` | Every check passed |
|
|
217
|
+
| `fail` | Claude finished, but a check failed |
|
|
218
|
+
| `error` | Claude crashed or timed out, or the skill or fixture couldn't be found |
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# skillbench
|
|
2
|
+
|
|
3
|
+
Test your Claude Code skills and agent workflows, the way you test code.
|
|
4
|
+
|
|
5
|
+
You write a small YAML file that says *"send this to Claude, then check these things"*. skillbench runs Claude Code for real on a copy of your repo, records everything it did, and tells you **pass** or **fail**.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Install
|
|
10
|
+
|
|
11
|
+
You need Python 3.11+, git, and Claude Code installed and logged in (check with `claude --version`). Then install with whichever tool you use:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pip install skillbench-cli
|
|
15
|
+
pipx install skillbench-cli
|
|
16
|
+
uv tool install skillbench-cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The command is `skillbench` either way. To try it without installing: `uvx --from skillbench-cli skillbench init`.
|
|
20
|
+
|
|
21
|
+
## 2. Try it (2 minutes)
|
|
22
|
+
|
|
23
|
+
In your repo:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
skillbench init # creates a skillbench/ folder with two example tests
|
|
27
|
+
skillbench skill # runs the skill test
|
|
28
|
+
skillbench agent # runs the agent test
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You'll see something like:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
[1/1] hello-greets-by-name default model
|
|
35
|
+
hello-greets-by-name: pass in 2.3s
|
|
36
|
+
dashboard: skillbench/runs/index.html
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Open `skillbench/runs/index.html` in your browser to see exactly what Claude did: every message, tool call and check.
|
|
40
|
+
|
|
41
|
+
That's it. The rest of this page shows how to write your own tests.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. Two kinds of test
|
|
46
|
+
|
|
47
|
+
| | **Skill test** | **Agent test** |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| Question it answers | "When my skill runs, does it do the right thing?" | "Given a normal request, does Claude pick the right skills and get the job done?" |
|
|
50
|
+
| Lives in | `skillbench/skills/` | `skillbench/agent/` |
|
|
51
|
+
| Run with | `skillbench skill` | `skillbench agent` |
|
|
52
|
+
| You write | `skill:` and `input:` | `prompt:` |
|
|
53
|
+
|
|
54
|
+
### A skill test
|
|
55
|
+
|
|
56
|
+
`skillbench/skills/grilling.yaml`
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
skill: grilling # your skill's name
|
|
60
|
+
input: an idea for a todo app # what to send it
|
|
61
|
+
fixture: . # run it on a copy of this repo
|
|
62
|
+
|
|
63
|
+
assert:
|
|
64
|
+
- final_text_contains: "Q1"
|
|
65
|
+
- tool_not_called: Write
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
skillbench finds the skill wherever it lives in your repo (`.claude/skills/`, `skills/`, `.github/skills/` or a plugin) and runs it as `/grilling an idea for a todo app`.
|
|
69
|
+
|
|
70
|
+
### An agent test
|
|
71
|
+
|
|
72
|
+
`skillbench/agent/csv-export.yaml`
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
prompt: add CSV export to the report page
|
|
76
|
+
fixture: .
|
|
77
|
+
|
|
78
|
+
answers: # replies, sent one at a time when Claude asks something
|
|
79
|
+
- Yes to all your recommendations.
|
|
80
|
+
- approved
|
|
81
|
+
|
|
82
|
+
assert:
|
|
83
|
+
- skill_invoked: planner
|
|
84
|
+
- tool_order: [Read, Edit, Bash]
|
|
85
|
+
- command_succeeds: python -m pytest -q
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Nothing is forced here. Claude sees every skill in your repo and decides for itself, and the test checks what it chose.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 4. Checks you can make
|
|
93
|
+
|
|
94
|
+
Put any of these under `assert:`.
|
|
95
|
+
|
|
96
|
+
| Check | Passes when |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `skill_invoked: grilling` | Claude used that skill |
|
|
99
|
+
| `skill_not_invoked: grilling` | Claude didn't use that skill |
|
|
100
|
+
| `tool_order: [Read, Edit]` | Claude used these tools in this order (other tools in between are fine) |
|
|
101
|
+
| `tool_not_called: Write` | Claude never used that tool |
|
|
102
|
+
| `final_text_contains: "Done"` | Claude's last message contains the text |
|
|
103
|
+
| `file_contains: {path: notes.md, text: "approved"}` | That file exists afterwards and contains the text |
|
|
104
|
+
| `command_succeeds: python -m pytest -q` | The command runs successfully in the workspace afterwards |
|
|
105
|
+
|
|
106
|
+
A test passes when every check passes.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 5. Which repo Claude works in (`fixture:`)
|
|
111
|
+
|
|
112
|
+
Claude always works on a **copy**, so your real files are never touched.
|
|
113
|
+
|
|
114
|
+
| `fixture:` | Claude gets |
|
|
115
|
+
|---|---|
|
|
116
|
+
| *(leave it out)* | An empty folder |
|
|
117
|
+
| `.` | A copy of your repo, including work you haven't committed |
|
|
118
|
+
| `some/folder` | A copy of that folder |
|
|
119
|
+
| `https://github.com/you/app.git` | A fresh clone |
|
|
120
|
+
| `{git: https://github.com/you/app.git, ref: v1.2}` | A clone at that branch, tag or commit |
|
|
121
|
+
|
|
122
|
+
Paths are relative to your repo root. The copy is kept after the run so you can look inside, and its path is in the dashboard.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 6. Running tests
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
skillbench skill # all skill tests
|
|
130
|
+
skillbench skill grilling # just the tests for one skill (or one test by name)
|
|
131
|
+
skillbench agent csv-export # one agent test
|
|
132
|
+
skillbench agent --repeat 5 # run each test 5 times
|
|
133
|
+
skillbench agent --model claude-sonnet-5-5
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
While it runs you'll see the current test, what Claude is doing, and roughly how long is left.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 7. More options
|
|
141
|
+
|
|
142
|
+
You won't need these to start.
|
|
143
|
+
|
|
144
|
+
**Check a skill gets picked on its own.** List prompts that should and shouldn't trigger it. Each runs briefly and stops as soon as Claude decides:
|
|
145
|
+
|
|
146
|
+
```yaml
|
|
147
|
+
skill: grilling
|
|
148
|
+
triggers:
|
|
149
|
+
should: ["stress-test my plan"]
|
|
150
|
+
should_not: ["fix this typo"]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Answer Claude yourself.** Add `interactive: true` and skillbench asks *you* in the terminal whenever Claude is waiting for a reply. Press Enter on an empty line to finish.
|
|
154
|
+
|
|
155
|
+
**Check for flakiness.** Claude doesn't do exactly the same thing every time. `--repeat 5` (or `repeat: 5` in the test) runs it 5 times and shows how often each check passed. Add `min_pass_rate: 0.8` to pass when 4 out of 5 runs pass.
|
|
156
|
+
|
|
157
|
+
**Set defaults for every test** in `skillbench/skillbench.yaml`:
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
model: claude-sonnet-5-5
|
|
161
|
+
timeout_s: 600 # seconds before a turn is stopped
|
|
162
|
+
fixture: .
|
|
163
|
+
repeat: 1
|
|
164
|
+
min_pass_rate: 1.0
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
A test's own settings win over these, and command-line flags win over both.
|
|
168
|
+
|
|
169
|
+
**All test fields:**
|
|
170
|
+
|
|
171
|
+
| Field | Meaning |
|
|
172
|
+
|---|---|
|
|
173
|
+
| `skill` / `input` | Skill tests: which skill, and what to send it |
|
|
174
|
+
| `prompt` | Agent tests: the first message |
|
|
175
|
+
| `answers` | Replies sent one per turn |
|
|
176
|
+
| `interactive` | Ask you in the terminal for replies |
|
|
177
|
+
| `triggers` | Prompts that should / shouldn't pick the skill |
|
|
178
|
+
| `fixture` | Which repo Claude works in |
|
|
179
|
+
| `assert` | The checks |
|
|
180
|
+
| `name` | A display name (defaults to the file name) |
|
|
181
|
+
| `timeout_s`, `repeat`, `min_pass_rate` | As above |
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Good to know
|
|
186
|
+
|
|
187
|
+
- **It costs real usage.** Every run is a real Claude session. Start with skill tests; long agent tests take longer and cost more.
|
|
188
|
+
- **Your personal setup is ignored.** Only the skills and plugins in the repo being tested are loaded, so results don't depend on whose machine runs them.
|
|
189
|
+
- **Only test repos you trust.** Claude has full tool access inside the copy, and `command_succeeds` runs commands there.
|
|
190
|
+
- **`command_succeeds` uses your system shell** (`sh` on Mac/Linux, `cmd` on Windows), so keep commands simple if you share tests across systems.
|
|
191
|
+
- **Results** are in `skillbench/runs/`, which is git-ignored. Each run has a `run.json` and Claude's raw output.
|
|
192
|
+
|
|
193
|
+
| Status | Meaning |
|
|
194
|
+
|---|---|
|
|
195
|
+
| `pass` | Every check passed |
|
|
196
|
+
| `fail` | Claude finished, but a check failed |
|
|
197
|
+
| `error` | Claude crashed or timed out, or the skill or fixture couldn't be found |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "skillbench-cli"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Test your Claude Code skills and agent workflows, the way you test code."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Adam Saul" }]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
keywords = ["claude", "claude-code", "agents", "skills", "evals", "testing"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Topic :: Software Development :: Testing",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"pyyaml>=6.0",
|
|
21
|
+
"rich>=13.7",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/adamsaul314/skillbench"
|
|
26
|
+
Issues = "https://github.com/adamsaul314/skillbench/issues"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
skillbench = "skillbench.cli:main"
|
|
30
|
+
|
|
31
|
+
[dependency-groups]
|
|
32
|
+
dev = ["ruff>=0.6"]
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["hatchling"]
|
|
36
|
+
build-backend = "hatchling.build"
|
|
37
|
+
|
|
38
|
+
[tool.hatch.build.targets.wheel]
|
|
39
|
+
packages = ["src/skillbench"]
|
|
40
|
+
|
|
41
|
+
[tool.ruff]
|
|
42
|
+
line-length = 100
|
|
43
|
+
target-version = "py311"
|
|
44
|
+
|
|
45
|
+
[tool.ruff.lint]
|
|
46
|
+
select = ["E", "F", "W", "I", "B", "UP", "SIM"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""skillbench: eval framework for agent skills."""
|