@cydm/pie 1.0.6 → 1.0.8
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.
- package/README.md +156 -9
- package/dist/builtin/extensions/ask-user/index.js +2 -3
- package/dist/builtin/extensions/init/index.js +70 -68
- package/dist/builtin/extensions/kimi-attachments/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +85 -87
- package/dist/builtin/extensions/subagent/index.js +17 -7
- package/dist/builtin/extensions/todo/index.js +51 -22
- package/dist/builtin/skills/browser-tools/CHANGELOG.md +2 -44
- package/dist/builtin/skills/browser-tools/README.md +10 -99
- package/dist/builtin/skills/browser-tools/SKILL.md +21 -174
- package/dist/builtin/skills/browser-tools/package.json +6 -13
- package/dist/builtin/skills/browser-tools/playwright-cli.js +24 -0
- package/dist/builtin/skills/skill-creator/SKILL.md +17 -17
- package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.mjs +285 -0
- package/dist/builtin/skills/skill-creator/eval-viewer/viewer.html +1 -1
- package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.mjs +271 -0
- package/dist/builtin/skills/skill-creator/scripts/claude_cli.mjs +115 -0
- package/dist/builtin/skills/skill-creator/scripts/generate_report.mjs +224 -0
- package/dist/builtin/skills/skill-creator/scripts/improve_description.mjs +198 -0
- package/dist/builtin/skills/skill-creator/scripts/package_skill.mjs +132 -0
- package/dist/builtin/skills/skill-creator/scripts/pie_runner.mjs +115 -0
- package/dist/builtin/skills/skill-creator/scripts/quick_validate.mjs +44 -0
- package/dist/builtin/skills/skill-creator/scripts/run_eval.mjs +169 -0
- package/dist/builtin/skills/skill-creator/scripts/run_loop.mjs +297 -0
- package/dist/builtin/skills/skill-creator/scripts/skill_metadata.mjs +134 -0
- package/dist/chunks/chunk-6WD2NFIC.js +8383 -0
- package/dist/chunks/{chunk-MWFBYJOI.js → chunk-A5JSJAPK.js} +3973 -1313
- package/dist/chunks/chunk-NTYHFBUA.js +36 -0
- package/dist/chunks/chunk-ZRONUKTW.js +989 -0
- package/dist/chunks/{src-EGWRDMLB.js → src-3X3HBT2G.js} +1 -2
- package/dist/chunks/typescript-GSKWJIO4.js +210747 -0
- package/dist/cli.js +15261 -12502
- package/models.schema.json +238 -0
- package/package.json +34 -8
- package/dist/builtin/skills/browser-tools/browser-content.js +0 -103
- package/dist/builtin/skills/browser-tools/browser-cookies.js +0 -35
- package/dist/builtin/skills/browser-tools/browser-eval.js +0 -49
- package/dist/builtin/skills/browser-tools/browser-hn-scraper.js +0 -108
- package/dist/builtin/skills/browser-tools/browser-nav.js +0 -44
- package/dist/builtin/skills/browser-tools/browser-pick.js +0 -162
- package/dist/builtin/skills/browser-tools/browser-screenshot.js +0 -34
- package/dist/builtin/skills/browser-tools/browser-start.js +0 -86
- package/dist/builtin/skills/skill-creator/eval-viewer/generate_review.py +0 -471
- package/dist/builtin/skills/skill-creator/scripts/__init__.py +0 -0
- package/dist/builtin/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
- package/dist/builtin/skills/skill-creator/scripts/generate_report.py +0 -326
- package/dist/builtin/skills/skill-creator/scripts/improve_description.py +0 -247
- package/dist/builtin/skills/skill-creator/scripts/package_skill.py +0 -136
- package/dist/builtin/skills/skill-creator/scripts/quick_validate.py +0 -103
- package/dist/builtin/skills/skill-creator/scripts/run_eval.py +0 -310
- package/dist/builtin/skills/skill-creator/scripts/run_loop.py +0 -328
- package/dist/builtin/skills/skill-creator/scripts/utils.py +0 -47
- package/dist/chunks/capabilities-FENCOHVA.js +0 -9
- package/dist/chunks/chunk-JYBXCEJJ.js +0 -315
- package/dist/chunks/chunk-RID3574D.js +0 -2718
- package/dist/chunks/chunk-TBJ25UWB.js +0 -3657
- package/dist/chunks/chunk-XZXLO7YB.js +0 -322
- package/dist/chunks/file-logger-AL5VVZHH.js +0 -22
- package/dist/chunks/src-WRUACRN2.js +0 -132
|
@@ -1,196 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: browser-tools
|
|
3
|
-
description: Interactive browser automation via
|
|
3
|
+
description: Interactive browser automation via Microsoft Playwright CLI. Use when you need to open pages, inspect DOM snapshots, click/type, capture screenshots, inspect console/network output, or test frontend flows in a real browser.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Browser Tools
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Use Pie's packaged Microsoft Playwright CLI wrapper. Scripts live next to this skill; resolve `playwright-cli.js` against this skill's `baseDir` and use the resulting ordinary path with `bash`.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
No manual dependency install is required when this skill is shipped with Pie.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Common Commands
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
node <baseDir>/playwright-cli.js open https://example.com
|
|
16
|
+
node <baseDir>/playwright-cli.js goto https://example.com
|
|
17
|
+
node <baseDir>/playwright-cli.js snapshot
|
|
18
|
+
node <baseDir>/playwright-cli.js click "Submit"
|
|
19
|
+
node <baseDir>/playwright-cli.js type "hello"
|
|
20
|
+
node <baseDir>/playwright-cli.js screenshot
|
|
21
|
+
node <baseDir>/playwright-cli.js console
|
|
22
|
+
node <baseDir>/playwright-cli.js network
|
|
23
|
+
node <baseDir>/playwright-cli.js close
|
|
17
24
|
```
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
Use `node <baseDir>/playwright-cli.js --help` for the full command list.
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
{baseDir}/browser-start.js # Fresh profile
|
|
23
|
-
{baseDir}/browser-start.js --profile # Copy user's profile (cookies, logins)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Launch Chrome with remote debugging on `:9222`. Use `--profile` to preserve user's authentication state.
|
|
27
|
-
|
|
28
|
-
## Navigate
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
{baseDir}/browser-nav.js https://example.com
|
|
32
|
-
{baseDir}/browser-nav.js https://example.com --new
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Navigate to URLs. Use `--new` flag to open in a new tab instead of reusing current tab.
|
|
36
|
-
|
|
37
|
-
## Evaluate JavaScript
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
{baseDir}/browser-eval.js 'document.title'
|
|
41
|
-
{baseDir}/browser-eval.js 'document.querySelectorAll("a").length'
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Execute JavaScript in the active tab. Code runs in async context. Use this to extract data, inspect page state, or perform DOM operations programmatically.
|
|
45
|
-
|
|
46
|
-
## Screenshot
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
{baseDir}/browser-screenshot.js
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Capture current viewport and return temporary file path. Use this to visually inspect page state or verify UI changes.
|
|
53
|
-
|
|
54
|
-
## Pick Elements
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
{baseDir}/browser-pick.js "Click the submit button"
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**IMPORTANT**: Use this tool when the user wants to select specific DOM elements on the page. This launches an interactive picker that lets the user click elements to select them. The user can select multiple elements (Cmd/Ctrl+Click) and press Enter when done. The tool returns CSS selectors for the selected elements.
|
|
28
|
+
## Workflow
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
- User says "I want to click that button" → Use this tool to let them select it
|
|
64
|
-
- User says "extract data from these items" → Use this tool to let them select the elements
|
|
65
|
-
- When you need specific selectors but the page structure is complex or ambiguous
|
|
30
|
+
Start with `open` or `goto`, then use `snapshot` before interacting. Prefer snapshot, console, and network output for diagnosis; use screenshots when visual layout matters. Use named sessions with `-s=<session>` when you need to keep multiple browser flows separate.
|
|
66
31
|
|
|
67
|
-
|
|
32
|
+
If the browser is not installed, run:
|
|
68
33
|
|
|
69
34
|
```bash
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Display all cookies for the current tab including domain, path, httpOnly, and secure flags. Use this to debug authentication issues or inspect session state.
|
|
74
|
-
|
|
75
|
-
## Extract Page Content
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
{baseDir}/browser-content.js https://example.com
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Navigate to a URL and extract readable content as markdown. Uses Mozilla Readability for article extraction and Turndown for HTML-to-markdown conversion. Works on pages with JavaScript content (waits for page to load).
|
|
82
|
-
|
|
83
|
-
## When to Use
|
|
84
|
-
|
|
85
|
-
- Testing frontend code in a real browser
|
|
86
|
-
- Interacting with pages that require JavaScript
|
|
87
|
-
- When user needs to visually see or interact with a page
|
|
88
|
-
- Debugging authentication or session issues
|
|
89
|
-
- Scraping dynamic content that requires JS execution
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Efficiency Guide
|
|
94
|
-
|
|
95
|
-
### DOM Inspection Over Screenshots
|
|
96
|
-
|
|
97
|
-
**Don't** take screenshots to see page state. **Do** parse the DOM directly:
|
|
98
|
-
|
|
99
|
-
```javascript
|
|
100
|
-
// Get page structure
|
|
101
|
-
document.body.innerHTML.slice(0, 5000)
|
|
102
|
-
|
|
103
|
-
// Find interactive elements
|
|
104
|
-
Array.from(document.querySelectorAll('button, input, [role="button"]')).map(e => ({
|
|
105
|
-
id: e.id,
|
|
106
|
-
text: e.textContent.trim(),
|
|
107
|
-
class: e.className
|
|
108
|
-
}))
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Complex Scripts in Single Calls
|
|
112
|
-
|
|
113
|
-
Wrap everything in an IIFE to run multi-statement code:
|
|
114
|
-
|
|
115
|
-
```javascript
|
|
116
|
-
(function() {
|
|
117
|
-
// Multiple operations
|
|
118
|
-
const data = document.querySelector('#target').textContent;
|
|
119
|
-
const buttons = document.querySelectorAll('button');
|
|
120
|
-
|
|
121
|
-
// Interactions
|
|
122
|
-
buttons[0].click();
|
|
123
|
-
|
|
124
|
-
// Return results
|
|
125
|
-
return JSON.stringify({ data, buttonCount: buttons.length });
|
|
126
|
-
})()
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Batch Interactions
|
|
130
|
-
|
|
131
|
-
**Don't** make separate calls for each click. **Do** batch them:
|
|
132
|
-
|
|
133
|
-
```javascript
|
|
134
|
-
(function() {
|
|
135
|
-
const actions = ["btn1", "btn2", "btn3"];
|
|
136
|
-
actions.forEach(id => document.getElementById(id).click());
|
|
137
|
-
return "Done";
|
|
138
|
-
})()
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Typing/Input Sequences
|
|
142
|
-
|
|
143
|
-
```javascript
|
|
144
|
-
(function() {
|
|
145
|
-
const text = "HELLO";
|
|
146
|
-
for (const char of text) {
|
|
147
|
-
document.getElementById("key-" + char).click();
|
|
148
|
-
}
|
|
149
|
-
document.getElementById("submit").click();
|
|
150
|
-
return "Submitted: " + text;
|
|
151
|
-
})()
|
|
35
|
+
node <baseDir>/playwright-cli.js install-browser chromium
|
|
152
36
|
```
|
|
153
37
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Extract structured state in one call:
|
|
157
|
-
|
|
158
|
-
```javascript
|
|
159
|
-
(function() {
|
|
160
|
-
const state = {
|
|
161
|
-
score: document.querySelector('.score')?.textContent,
|
|
162
|
-
status: document.querySelector('.status')?.className,
|
|
163
|
-
items: Array.from(document.querySelectorAll('.item')).map(el => ({
|
|
164
|
-
text: el.textContent,
|
|
165
|
-
active: el.classList.contains('active')
|
|
166
|
-
}))
|
|
167
|
-
};
|
|
168
|
-
return JSON.stringify(state, null, 2);
|
|
169
|
-
})()
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Waiting for Updates
|
|
173
|
-
|
|
174
|
-
If DOM updates after actions, add a small delay with bash:
|
|
38
|
+
If a session gets stuck, use:
|
|
175
39
|
|
|
176
40
|
```bash
|
|
177
|
-
|
|
41
|
+
node <baseDir>/playwright-cli.js close
|
|
42
|
+
node <baseDir>/playwright-cli.js kill-all
|
|
178
43
|
```
|
|
179
|
-
|
|
180
|
-
### Investigate Before Interacting
|
|
181
|
-
|
|
182
|
-
Always start by understanding the page structure:
|
|
183
|
-
|
|
184
|
-
```javascript
|
|
185
|
-
(function() {
|
|
186
|
-
return {
|
|
187
|
-
title: document.title,
|
|
188
|
-
forms: document.forms.length,
|
|
189
|
-
buttons: document.querySelectorAll('button').length,
|
|
190
|
-
inputs: document.querySelectorAll('input').length,
|
|
191
|
-
mainContent: document.body.innerHTML.slice(0, 3000)
|
|
192
|
-
};
|
|
193
|
-
})()
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Then target specific elements based on what you find.
|
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-tools",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
6
|
-
"author": "
|
|
5
|
+
"description": "Microsoft Playwright CLI wrapper for collaborative site exploration",
|
|
6
|
+
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"jsdom": "^27.0.1",
|
|
12
|
-
"puppeteer": "^24.31.0",
|
|
13
|
-
"puppeteer-core": "^23.11.1",
|
|
14
|
-
"puppeteer-extra": "^3.3.6",
|
|
15
|
-
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
|
16
|
-
"turndown": "^7.2.2",
|
|
17
|
-
"turndown-plugin-gfm": "^1.0.2"
|
|
8
|
+
"private": true,
|
|
9
|
+
"pie": {
|
|
10
|
+
"dependenciesProvidedBy": "@cydm/pie"
|
|
18
11
|
}
|
|
19
12
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
|
|
8
|
+
export function resolvePlaywrightCli() {
|
|
9
|
+
return require.resolve("@playwright/cli/playwright-cli.js");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function runPlaywrightCli(args = process.argv.slice(2), options = {}) {
|
|
13
|
+
const bin = resolvePlaywrightCli();
|
|
14
|
+
return spawnSync(process.execPath, [bin, ...args], {
|
|
15
|
+
stdio: "inherit",
|
|
16
|
+
shell: false,
|
|
17
|
+
...options,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
22
|
+
const result = runPlaywrightCli();
|
|
23
|
+
process.exitCode = result.status ?? 1;
|
|
24
|
+
}
|
|
@@ -14,7 +14,7 @@ At a high level, the process of creating a skill goes like this:
|
|
|
14
14
|
- Create a few test prompts and run claude-with-access-to-the-skill on them
|
|
15
15
|
- Help the user evaluate the results both qualitatively and quantitatively
|
|
16
16
|
- While the runs happen in the background, draft some quantitative evals if there aren't any (if there are some, you can either use as is or modify if you feel something needs to change about them). Then explain them to the user (or if they already existed, explain the ones that already exist)
|
|
17
|
-
- Use the `eval-viewer/generate_review.
|
|
17
|
+
- Use the `eval-viewer/generate_review.mjs` script to show the user the results for them to look at, and also let them look at the quantitative metrics
|
|
18
18
|
- Rewrite the skill based on feedback from the user's evaluation of the results (and also if there are any glaring flaws that become apparent from the quantitative benchmarks)
|
|
19
19
|
- Repeat until you're satisfied
|
|
20
20
|
- Expand the test set and try again at larger scale
|
|
@@ -226,7 +226,7 @@ Once all runs are done:
|
|
|
226
226
|
|
|
227
227
|
2. **Aggregate into benchmark** — run the aggregation script from the skill-creator directory:
|
|
228
228
|
```bash
|
|
229
|
-
|
|
229
|
+
node <skill-creator-path>/scripts/aggregate_benchmark.mjs <workspace>/iteration-N --skill-name <name>
|
|
230
230
|
```
|
|
231
231
|
This produces `benchmark.json` and `benchmark.md` with pass_rate, time, and tokens for each configuration, with mean ± stddev and the delta. If generating benchmark.json manually, see `references/schemas.md` for the exact schema the viewer expects.
|
|
232
232
|
Put each with_skill version before its baseline counterpart.
|
|
@@ -235,7 +235,7 @@ Put each with_skill version before its baseline counterpart.
|
|
|
235
235
|
|
|
236
236
|
4. **Launch the viewer** with both qualitative outputs and quantitative data:
|
|
237
237
|
```bash
|
|
238
|
-
nohup
|
|
238
|
+
nohup node <skill-creator-path>/eval-viewer/generate_review.mjs \
|
|
239
239
|
<workspace>/iteration-N \
|
|
240
240
|
--skill-name "my-skill" \
|
|
241
241
|
--benchmark <workspace>/iteration-N/benchmark.json \
|
|
@@ -246,7 +246,7 @@ Put each with_skill version before its baseline counterpart.
|
|
|
246
246
|
|
|
247
247
|
**Cowork / headless environments:** If `webbrowser.open()` is not available or the environment has no display, use `--static <output_path>` to write a standalone HTML file instead of starting a server. Feedback will be downloaded as a `feedback.json` file when the user clicks "Submit All Reviews". After download, copy `feedback.json` into the workspace directory for the next iteration to pick up.
|
|
248
248
|
|
|
249
|
-
Note: please use generate_review.
|
|
249
|
+
Note: please use `generate_review.mjs` to create the viewer; there's no need to write custom HTML.
|
|
250
250
|
|
|
251
251
|
5. **Tell the user** something like: "I've opened the results in your browser. There are two tabs — 'Outputs' lets you click through each test case and leave feedback, 'Benchmark' shows the quantitative comparison. When you're done, come back here and let me know."
|
|
252
252
|
|
|
@@ -301,7 +301,7 @@ This is the heart of the loop. You've run the test cases, the user has reviewed
|
|
|
301
301
|
|
|
302
302
|
3. **Explain the why.** Try hard to explain the **why** behind everything you're asking the model to do. Today's LLMs are *smart*. They have good theory of mind and when given a good harness can go beyond rote instructions and really make things happen. Even if the feedback from the user is terse or frustrated, try to actually understand the task and why the user is writing what they wrote, and what they actually wrote, and then transmit this understanding into the instructions. If you find yourself writing ALWAYS or NEVER in all caps, or using super rigid structures, that's a yellow flag — if possible, reframe and explain the reasoning so that the model understands why the thing you're asking for is important. That's a more humane, powerful, and effective approach.
|
|
303
303
|
|
|
304
|
-
4. **Look for repeated work across test cases.** Read the transcripts from the test runs and notice if the subagents all independently wrote similar helper scripts or took the same multi-step approach to something. If all 3 test cases resulted in the subagent writing a `create_docx.
|
|
304
|
+
4. **Look for repeated work across test cases.** Read the transcripts from the test runs and notice if the subagents all independently wrote similar helper scripts or took the same multi-step approach to something. If all 3 test cases resulted in the subagent writing a `create_docx.mjs` or a `build_chart.mjs`, that's a strong signal the skill should bundle that script. Write it once, put it in `scripts/`, and tell the skill to use it. This saves every future invocation from reinventing the wheel.
|
|
305
305
|
|
|
306
306
|
This task is pretty important (we are trying to create billions a year in economic value here!) and your thinking time is not the blocker; take your time and really mull things over. I'd suggest writing a draft revision and then looking at it anew and making improvements. Really do your best to get into the head of the user and understand what they want and need.
|
|
307
307
|
|
|
@@ -332,7 +332,7 @@ This is optional, requires subagents, and most users won't need it. The human re
|
|
|
332
332
|
|
|
333
333
|
## Description Optimization
|
|
334
334
|
|
|
335
|
-
The description field in SKILL.md frontmatter is the primary mechanism that determines whether
|
|
335
|
+
The description field in SKILL.md frontmatter is the primary mechanism that determines whether Pie invokes a skill. After creating or improving a skill, offer to optimize the description for better triggering accuracy.
|
|
336
336
|
|
|
337
337
|
### Step 1: Generate trigger eval queries
|
|
338
338
|
|
|
@@ -379,7 +379,7 @@ Tell the user: "This will take some time — I'll run the optimization loop in t
|
|
|
379
379
|
Save the eval set to the workspace, then run in the background:
|
|
380
380
|
|
|
381
381
|
```bash
|
|
382
|
-
|
|
382
|
+
node <skill-creator-path>/scripts/run_loop.mjs \
|
|
383
383
|
--eval-set <path-to-trigger-eval.json> \
|
|
384
384
|
--skill-path <path-to-skill> \
|
|
385
385
|
--model <model-id-powering-this-session> \
|
|
@@ -391,11 +391,11 @@ Use the model ID from your system prompt (the one powering the current session)
|
|
|
391
391
|
|
|
392
392
|
While it runs, periodically tail the output to give the user updates on which iteration it's on and what the scores look like.
|
|
393
393
|
|
|
394
|
-
This handles the full optimization loop automatically. It splits the eval set into 60% train and 40% held-out test, evaluates the current description (running each query 3 times to get a reliable trigger rate), then
|
|
394
|
+
This handles the full optimization loop automatically. It splits the eval set into 60% train and 40% held-out test, evaluates the current description with Pie (running each query 3 times to get a reliable trigger rate), then asks Pie to propose improvements based on what failed. It re-evaluates each new description on both train and test, iterating up to 5 times. When it's done, it opens an HTML report in the browser showing the results per iteration and returns JSON with `best_description` — selected by test score rather than train score to avoid overfitting.
|
|
395
395
|
|
|
396
396
|
### How skill triggering works
|
|
397
397
|
|
|
398
|
-
Understanding the triggering mechanism helps design better eval queries. Skills appear in
|
|
398
|
+
Understanding the triggering mechanism helps design better eval queries. Skills appear in Pie's `available_skills` list with their name + description, and Pie decides whether to consult a skill based on that description. The important thing to know is that Pie only consults skills for tasks it can't easily handle on its own — simple, one-step queries like "read this PDF" may not trigger a skill even if the description matches perfectly, because Pie can handle them directly with basic tools. Complex, multi-step, or specialized queries reliably trigger skills when the description matches.
|
|
399
399
|
|
|
400
400
|
This means your eval queries should be substantive enough that Claude would actually benefit from consulting a skill. Simple queries like "read file X" are poor test cases — they won't trigger skills regardless of description quality.
|
|
401
401
|
|
|
@@ -410,7 +410,7 @@ Take `best_description` from the JSON output and update the skill's SKILL.md fro
|
|
|
410
410
|
Check whether you have access to the `present_files` tool. If you don't, skip this step. If you do, package the skill and present the .skill file to the user:
|
|
411
411
|
|
|
412
412
|
```bash
|
|
413
|
-
|
|
413
|
+
node <skill-creator-path>/scripts/package_skill.mjs <path/to/skill-folder>
|
|
414
414
|
```
|
|
415
415
|
|
|
416
416
|
After packaging, direct the user to the resulting `.skill` file path so they can install it.
|
|
@@ -429,11 +429,11 @@ In Claude.ai, the core workflow is the same (draft → test → review → impro
|
|
|
429
429
|
|
|
430
430
|
**The iteration loop**: Same as before — improve the skill, rerun the test cases, ask for feedback — just without the browser reviewer in the middle. You can still organize results into iteration directories on the filesystem if you have one.
|
|
431
431
|
|
|
432
|
-
**Description optimization**: This section
|
|
432
|
+
**Description optimization**: This section now defaults to Pie's own non-interactive runner. It does not require `claude -p`.
|
|
433
433
|
|
|
434
434
|
**Blind comparison**: Requires subagents. Skip it.
|
|
435
435
|
|
|
436
|
-
**Packaging**: The `package_skill.
|
|
436
|
+
**Packaging**: The `package_skill.mjs` script works anywhere with Node.js and a filesystem. On Claude.ai or Codex CLI, you can run it and the user can download the resulting `.skill` file.
|
|
437
437
|
|
|
438
438
|
**Updating an existing skill**: The user might be asking you to update an existing skill, not create a new one. In this case:
|
|
439
439
|
- **Preserve the original name.** Note the skill's directory name and `name` frontmatter field -- use them unchanged. E.g., if the installed skill is `research-helper`, output `research-helper.skill` (not `research-helper-v2`).
|
|
@@ -448,10 +448,10 @@ If you're in Cowork, the main things to know are:
|
|
|
448
448
|
|
|
449
449
|
- You have subagents, so the main workflow (spawn test cases in parallel, run baselines, grade, etc.) all works. (However, if you run into severe problems with timeouts, it's OK to run the test prompts in series rather than parallel.)
|
|
450
450
|
- You don't have a browser or display, so when generating the eval viewer, use `--static <output_path>` to write a standalone HTML file instead of starting a server. Then proffer a link that the user can click to open the HTML in their browser.
|
|
451
|
-
- For whatever reason, the Cowork setup seems to disincline Claude from generating the eval viewer after running the tests, so just to reiterate: whether you're in Cowork or in Claude Code, after running tests, you should always generate the eval viewer for the human to look at examples before revising the skill yourself and trying to make corrections, using `generate_review.
|
|
451
|
+
- For whatever reason, the Cowork setup seems to disincline Claude from generating the eval viewer after running the tests, so just to reiterate: whether you're in Cowork or in Claude Code, after running tests, you should always generate the eval viewer for the human to look at examples before revising the skill yourself and trying to make corrections, using `generate_review.mjs` (not writing your own boutique html code). Sorry in advance but I'm gonna go all caps here: GENERATE THE EVAL VIEWER *BEFORE* evaluating inputs yourself. You want to get them in front of the human ASAP!
|
|
452
452
|
- Feedback works differently: since there's no running server, the viewer's "Submit All Reviews" button will download `feedback.json` as a file. You can then read it from there (you may have to request access first).
|
|
453
|
-
- Packaging works — `package_skill.
|
|
454
|
-
- Description optimization (`run_loop.
|
|
453
|
+
- Packaging works — `package_skill.mjs` just needs Node.js and a filesystem.
|
|
454
|
+
- Description optimization (`run_loop.mjs` / `run_eval.mjs`) should work in Cowork just fine since it uses Pie's non-interactive runner, not a browser, but please save it until you've fully finished making the skill and the user agrees it's in good shape.
|
|
455
455
|
- **Updating an existing skill**: The user might be asking you to update an existing skill, not create a new one. Follow the update guidance in the claude.ai section above.
|
|
456
456
|
|
|
457
457
|
---
|
|
@@ -475,11 +475,11 @@ Repeating one more time the core loop here for emphasis:
|
|
|
475
475
|
- Draft or edit the skill
|
|
476
476
|
- Run claude-with-access-to-the-skill on test prompts
|
|
477
477
|
- With the user, evaluate the outputs:
|
|
478
|
-
- Create benchmark.json and run `eval-viewer/generate_review.
|
|
478
|
+
- Create benchmark.json and run `eval-viewer/generate_review.mjs` to help the user review them
|
|
479
479
|
- Run quantitative evals
|
|
480
480
|
- Repeat until you and the user are satisfied
|
|
481
481
|
- Package the final skill and return it to the user.
|
|
482
482
|
|
|
483
|
-
Please add steps to your TodoList, if you have such a thing, to make sure you don't forget. If you're in Cowork, please specifically put "Create evals JSON and run `eval-viewer/generate_review.
|
|
483
|
+
Please add steps to your TodoList, if you have such a thing, to make sure you don't forget. If you're in Cowork, please specifically put "Create evals JSON and run `eval-viewer/generate_review.mjs` so human can review test cases" in your TodoList to make sure it happens.
|
|
484
484
|
|
|
485
485
|
Good luck!
|