@maxiaochao/pi-toolkit 0.10.24 → 0.11.1
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/CHANGELOG.md +10 -0
- package/evaluations/agents-md/README.md +19 -0
- package/evaluations/agents-md/run.mjs +217 -0
- package/evaluations/agents-md/tests/run-tests.mjs +52 -0
- package/global/AGENTS.md +13 -8
- package/package.json +2 -1
- package/packages/herdr-subagents/ARCHITECTURE.md +407 -0
- package/packages/herdr-subagents/CHANGELOG.md +4 -0
- package/packages/herdr-subagents/README.md +2 -0
- package/packages/herdr-subagents/package.json +2 -1
- package/packages/worktree/CHANGELOG.md +5 -0
- package/packages/worktree/README.md +6 -7
- package/packages/worktree/TESTING.md +5 -5
- package/packages/worktree/bin/pi-worktree +31 -66
- package/packages/worktree/bin/pi-worktree-completion.bash +4 -4
- package/packages/worktree/docs/demo.gif +0 -0
- package/packages/worktree/docs/screenshot.png +0 -0
- package/packages/worktree/extensions/worktree.ts +30 -30
- package/packages/worktree/package.json +1 -1
- package/packages/worktree/skills/pi-worktree/SKILL.md +3 -6
- package/packages/worktree/tests/extension.test.mjs +2 -2
- package/packages/worktree/tests/run-tests.sh +28 -32
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 2026-10-12 - v0.11.1
|
|
2
|
+
|
|
3
|
+
- bundle herdr-subagents v0.4.11: add architecture documentation and clear-output guidance evaluation
|
|
4
|
+
|
|
5
|
+
## 2026-10-12 - v0.11.0
|
|
6
|
+
|
|
7
|
+
- bundle worktree v0.4.0: Replace CLI start and prepare with the create-only command
|
|
8
|
+
- Replace `pi-worktree start` and `pi-worktree prepare` with the create-only `pi-worktree create` CLI; `/worktree start` and `enter_worktree` continue to switch the current Pi session.
|
|
9
|
+
|
|
1
10
|
## 2026-10-12 - v0.10.24
|
|
2
11
|
|
|
3
12
|
- bundle herdr-subagents v0.4.10: Stabilize concurrency checks and cancellation synchronization on slower CI runners.
|
|
@@ -5,6 +14,7 @@
|
|
|
5
14
|
## 2026-10-12 - v0.10.23
|
|
6
15
|
|
|
7
16
|
- bundle herdr-subagents v0.4.9: Stabilize concurrency checks on slower CI runners.
|
|
17
|
+
|
|
8
18
|
## 2026-10-12 - v0.10.22
|
|
9
19
|
|
|
10
20
|
- bundle herdr-subagents v0.4.8: make blocking behave identically in serial and parallel runs and let respond continue a named failed task from its saved session
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# AGENTS.md Clear Output Evaluation
|
|
2
|
+
|
|
3
|
+
This A/B evaluation measures the effect of the `Clear Output` guidance. The `before` variant uses a minimal coding-assistant prompt. The `after` variant adds only the two `Clear Output` rules.
|
|
4
|
+
|
|
5
|
+
Run the deterministic scorer tests:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run eval:agents:test
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Run the model evaluation:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run eval:agents -- --runs 2
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Set `PI_EVAL_MODEL` or pass `--model <provider/model>` to pin a model. Results are written to `results/latest.json` and `results/latest.md`.
|
|
18
|
+
|
|
19
|
+
The scorer measures sentence length, conjunction density, response language, terminology changes, and use of a visual for the branching-flow case. These are proxies. Review the saved outputs for correctness and completeness before accepting a prompt change.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const CLEAR_OUTPUT = `## Clear Output
|
|
6
|
+
|
|
7
|
+
- Make outputs easy to understand and verify. Use ASD-STE100-inspired principles: short sentences, one idea per sentence, and consistent terms. Apply its formal language rules only to English.
|
|
8
|
+
- When it improves understanding, use a diagram, HTML artifact, or video instead of long prose.`;
|
|
9
|
+
|
|
10
|
+
const BASE_SYSTEM = "You are an expert coding assistant. Give a direct and accurate answer. Reply in the same language as the user.";
|
|
11
|
+
|
|
12
|
+
export const variants = {
|
|
13
|
+
before: BASE_SYSTEM,
|
|
14
|
+
after: `${BASE_SYSTEM}\n\n${CLEAR_OUTPUT}`,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const cases = [
|
|
18
|
+
{
|
|
19
|
+
id: "english-explanation",
|
|
20
|
+
language: "en",
|
|
21
|
+
prompt: "Explain how optimistic concurrency control prevents lost updates. Include the read, write, conflict, and retry stages. Write for an application developer.",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "chinese-explanation",
|
|
25
|
+
language: "zh",
|
|
26
|
+
prompt: "向应用开发者解释乐观并发控制如何防止更新丢失。需要涵盖读取、写入、冲突和重试阶段。",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "term-consistency",
|
|
30
|
+
language: "en",
|
|
31
|
+
aliases: ["work item", "job", "task"],
|
|
32
|
+
prompt: "A queue API uses job, task, and work item for the same object. Explain its lifecycle from creation through processing to completion. Resolve the naming ambiguity in your answer.",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "visual-flow",
|
|
36
|
+
language: "en",
|
|
37
|
+
expectVisual: true,
|
|
38
|
+
prompt: "Explain this request flow: gateway to authentication; failed authentication to rejection; successful authentication to cache; cache miss to database; transient database failure retries twice, then returns an error. Make the branching and retry path easy to verify.",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
function splitSentences(text) {
|
|
43
|
+
return [...new Intl.Segmenter(undefined, { granularity: "sentence" }).segment(text)]
|
|
44
|
+
.map(({ segment }) => segment.trim())
|
|
45
|
+
.filter(Boolean);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function tokenCount(sentence, language) {
|
|
49
|
+
if (language === "zh") {
|
|
50
|
+
return (sentence.match(/[\p{Script=Han}]|[A-Za-z0-9]+/gu) ?? []).length;
|
|
51
|
+
}
|
|
52
|
+
return (sentence.match(/[\p{L}\p{N}]+(?:[-'][\p{L}\p{N}]+)*/gu) ?? []).length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function scoreOutput(text, testCase) {
|
|
56
|
+
const sentences = splitSentences(text);
|
|
57
|
+
const lengths = sentences.map((sentence) => tokenCount(sentence, testCase.language));
|
|
58
|
+
const limit = testCase.language === "zh" ? 35 : 25;
|
|
59
|
+
const conjunctionPattern = testCase.language === "zh"
|
|
60
|
+
? /(?:而且|但是|同时|以及|并且|然而|其中)/g
|
|
61
|
+
: /\b(?:and|but|while|whereas|which|although|however)\b/gi;
|
|
62
|
+
const conjunctions = sentences.reduce(
|
|
63
|
+
(sum, sentence) => sum + (sentence.match(conjunctionPattern) ?? []).length,
|
|
64
|
+
0,
|
|
65
|
+
);
|
|
66
|
+
const firstParagraphEnd = text.indexOf("\n\n");
|
|
67
|
+
const bodyAfterNaming = firstParagraphEnd >= 0
|
|
68
|
+
? text.slice(firstParagraphEnd + 2)
|
|
69
|
+
: sentences.slice(1).join(" ");
|
|
70
|
+
const usedAliasesAfterNaming = (testCase.aliases ?? []).filter((alias) =>
|
|
71
|
+
new RegExp(`\\b${alias.replaceAll(" ", "\\s+")}s?\\b`, "i").test(bodyAfterNaming),
|
|
72
|
+
);
|
|
73
|
+
const hasVisual = /```(?:mermaid)?|(?:-->|->|→|↓|├|└)|<svg\b|<html\b|\|[^\n]+\|[^\n]+\|/i.test(text);
|
|
74
|
+
const hanCharacters = (text.match(/[\p{Script=Han}]/gu) ?? []).length;
|
|
75
|
+
const latinWords = (text.match(/[A-Za-z]+/g) ?? []).length;
|
|
76
|
+
const languageMatches = testCase.language === "zh"
|
|
77
|
+
? hanCharacters >= 20
|
|
78
|
+
: hanCharacters <= Math.max(5, latinWords * 0.05);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
characters: text.length,
|
|
82
|
+
sentences: sentences.length,
|
|
83
|
+
averageSentenceTokens: lengths.length
|
|
84
|
+
? Number((lengths.reduce((sum, value) => sum + value, 0) / lengths.length).toFixed(1))
|
|
85
|
+
: 0,
|
|
86
|
+
longSentenceRate: lengths.length
|
|
87
|
+
? Number((lengths.filter((value) => value > limit).length / lengths.length).toFixed(2))
|
|
88
|
+
: 0,
|
|
89
|
+
conjunctionsPerSentence: lengths.length
|
|
90
|
+
? Number((conjunctions / lengths.length).toFixed(2))
|
|
91
|
+
: 0,
|
|
92
|
+
extraAliasesAfterNaming: Math.max(0, usedAliasesAfterNaming.length - 1),
|
|
93
|
+
languageMatches,
|
|
94
|
+
hasVisual,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function parseArguments(argv) {
|
|
99
|
+
const options = { runs: 1, model: process.env.PI_EVAL_MODEL };
|
|
100
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
101
|
+
if (argv[index] === "--runs") options.runs = Number(argv[++index]);
|
|
102
|
+
else if (argv[index] === "--model") options.model = argv[++index];
|
|
103
|
+
else throw new Error(`Unknown argument: ${argv[index]}`);
|
|
104
|
+
}
|
|
105
|
+
if (!Number.isInteger(options.runs) || options.runs < 1) {
|
|
106
|
+
throw new Error("--runs must be a positive integer");
|
|
107
|
+
}
|
|
108
|
+
return options;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function runPi(systemPrompt, prompt, model) {
|
|
112
|
+
const args = [
|
|
113
|
+
"--print",
|
|
114
|
+
"--no-session",
|
|
115
|
+
"--no-tools",
|
|
116
|
+
"--no-extensions",
|
|
117
|
+
"--no-skills",
|
|
118
|
+
"--no-prompt-templates",
|
|
119
|
+
"--no-themes",
|
|
120
|
+
"--no-context-files",
|
|
121
|
+
"--system-prompt",
|
|
122
|
+
systemPrompt,
|
|
123
|
+
];
|
|
124
|
+
if (model) args.push("--model", model);
|
|
125
|
+
args.push("--", prompt);
|
|
126
|
+
return execFileSync("pi", args, { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"] }).trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function average(rows, key) {
|
|
130
|
+
if (rows.length === 0) return 0;
|
|
131
|
+
return Number((rows.reduce((sum, row) => sum + Number(row.score[key]), 0) / rows.length).toFixed(2));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function summarize(results) {
|
|
135
|
+
return Object.fromEntries(Object.keys(variants).map((variant) => {
|
|
136
|
+
const rows = results.filter((result) => result.variant === variant);
|
|
137
|
+
const visualRows = rows.filter((result) => cases.find(({ id }) => id === result.caseId).expectVisual);
|
|
138
|
+
const terminologyRows = rows.filter((result) => cases.find(({ id }) => id === result.caseId).aliases);
|
|
139
|
+
return [variant, {
|
|
140
|
+
averageCharacters: average(rows, "characters"),
|
|
141
|
+
averageSentenceTokens: average(rows, "averageSentenceTokens"),
|
|
142
|
+
longSentenceRate: average(rows, "longSentenceRate"),
|
|
143
|
+
conjunctionsPerSentence: average(rows, "conjunctionsPerSentence"),
|
|
144
|
+
languageMatchRate: average(rows, "languageMatches"),
|
|
145
|
+
visualFlowRate: average(visualRows, "hasVisual"),
|
|
146
|
+
extraAliasesAfterNaming: average(terminologyRows, "extraAliasesAfterNaming"),
|
|
147
|
+
}];
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function markdownReport(payload) {
|
|
152
|
+
const { summary } = payload;
|
|
153
|
+
const lines = [
|
|
154
|
+
"# AGENTS.md Clear Output A/B Evaluation",
|
|
155
|
+
"",
|
|
156
|
+
`Runs per case: ${payload.options.runs}`,
|
|
157
|
+
`Model override: ${payload.options.model ?? "Pi default"}`,
|
|
158
|
+
"",
|
|
159
|
+
"| Variant | Mean characters | Mean sentence tokens | Long sentence rate | Conjunctions / sentence | Language match | Visual-flow rate | Extra aliases |",
|
|
160
|
+
"|---|---:|---:|---:|---:|---:|---:|---:|",
|
|
161
|
+
...Object.entries(summary).map(([name, score]) =>
|
|
162
|
+
`| ${name} | ${score.averageCharacters} | ${score.averageSentenceTokens} | ${score.longSentenceRate} | ${score.conjunctionsPerSentence} | ${score.languageMatchRate} | ${score.visualFlowRate} | ${score.extraAliasesAfterNaming} |`,
|
|
163
|
+
),
|
|
164
|
+
"",
|
|
165
|
+
"Lower is better for long sentence rate, conjunctions, and extra aliases after naming. Higher is better for language match and visual-flow rate. Character count is descriptive, not a quality score.",
|
|
166
|
+
"",
|
|
167
|
+
"## Per-case output",
|
|
168
|
+
"",
|
|
169
|
+
...payload.results.flatMap((result) => [
|
|
170
|
+
`### ${result.caseId} · ${result.variant} · run ${result.run}`,
|
|
171
|
+
"",
|
|
172
|
+
`Score: \`${JSON.stringify(result.score)}\``,
|
|
173
|
+
"",
|
|
174
|
+
result.output,
|
|
175
|
+
"",
|
|
176
|
+
]),
|
|
177
|
+
];
|
|
178
|
+
return `${lines.join("\n")}\n`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function main() {
|
|
182
|
+
const options = parseArguments(process.argv.slice(2));
|
|
183
|
+
const results = [];
|
|
184
|
+
for (let run = 1; run <= options.runs; run += 1) {
|
|
185
|
+
for (const testCase of cases) {
|
|
186
|
+
const order = run % 2 === 1 ? ["before", "after"] : ["after", "before"];
|
|
187
|
+
for (const variant of order) {
|
|
188
|
+
process.stderr.write(`Running ${testCase.id} / ${variant} / ${run}\n`);
|
|
189
|
+
const output = runPi(variants[variant], testCase.prompt, options.model);
|
|
190
|
+
results.push({
|
|
191
|
+
caseId: testCase.id,
|
|
192
|
+
variant,
|
|
193
|
+
run,
|
|
194
|
+
output,
|
|
195
|
+
score: scoreOutput(output, testCase),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const payload = {
|
|
202
|
+
generatedAt: new Date().toISOString(),
|
|
203
|
+
options,
|
|
204
|
+
summary: summarize(results),
|
|
205
|
+
results,
|
|
206
|
+
};
|
|
207
|
+
const resultDirectory = fileURLToPath(new URL("./results", import.meta.url));
|
|
208
|
+
mkdirSync(resultDirectory, { recursive: true });
|
|
209
|
+
writeFileSync(`${resultDirectory}/latest.json`, `${JSON.stringify(payload, null, 2)}\n`);
|
|
210
|
+
writeFileSync(`${resultDirectory}/latest.md`, markdownReport(payload));
|
|
211
|
+
console.log(JSON.stringify(payload.summary, null, 2));
|
|
212
|
+
console.log(`\nFull report: ${resultDirectory}/latest.md`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (process.argv[1] && import.meta.url === new URL(`file://${process.argv[1]}`).href) {
|
|
216
|
+
await main();
|
|
217
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { scoreOutput } from "../run.mjs";
|
|
3
|
+
|
|
4
|
+
const concise = scoreOutput(
|
|
5
|
+
"Read the record. Compare its version. Reject a conflict. Retry the operation.",
|
|
6
|
+
{ language: "en" },
|
|
7
|
+
);
|
|
8
|
+
assert.equal(concise.sentences, 4);
|
|
9
|
+
assert.equal(concise.longSentenceRate, 0);
|
|
10
|
+
assert.equal(concise.conjunctionsPerSentence, 0);
|
|
11
|
+
assert.equal(concise.languageMatches, true);
|
|
12
|
+
|
|
13
|
+
const dense = scoreOutput(
|
|
14
|
+
"Read the record and compare its version, but reject the write when another client changed it, while preserving the new value and returning a conflict which the caller can retry after loading the latest record.",
|
|
15
|
+
{ language: "en" },
|
|
16
|
+
);
|
|
17
|
+
assert.equal(dense.sentences, 1);
|
|
18
|
+
assert.equal(dense.longSentenceRate, 1);
|
|
19
|
+
assert.ok(dense.conjunctionsPerSentence >= 4);
|
|
20
|
+
|
|
21
|
+
const chinese = scoreOutput(
|
|
22
|
+
"客户端读取记录。客户端比较版本。版本冲突时,服务拒绝写入。客户端重新读取后重试。",
|
|
23
|
+
{ language: "zh" },
|
|
24
|
+
);
|
|
25
|
+
assert.equal(chinese.sentences, 4);
|
|
26
|
+
assert.equal(chinese.longSentenceRate, 0);
|
|
27
|
+
assert.equal(chinese.languageMatches, true);
|
|
28
|
+
|
|
29
|
+
const terms = scoreOutput(
|
|
30
|
+
"Create one work item. The worker processes the job and completes the task.",
|
|
31
|
+
{ language: "en", aliases: ["work item", "job", "task"] },
|
|
32
|
+
);
|
|
33
|
+
assert.equal(terms.extraAliasesAfterNaming, 1);
|
|
34
|
+
|
|
35
|
+
const canonicalTerm = scoreOutput(
|
|
36
|
+
"Use work item as the canonical term for job, task, and work item. Create the work item. Process the work item. Complete the work item.",
|
|
37
|
+
{ language: "en", aliases: ["work item", "job", "task"] },
|
|
38
|
+
);
|
|
39
|
+
assert.equal(canonicalTerm.extraAliasesAfterNaming, 0);
|
|
40
|
+
|
|
41
|
+
const wrongLanguage = scoreOutput("这是一个中文回答,包含足够多的中文字符,因此不应匹配英文问题。", {
|
|
42
|
+
language: "en",
|
|
43
|
+
});
|
|
44
|
+
assert.equal(wrongLanguage.languageMatches, false);
|
|
45
|
+
|
|
46
|
+
const visual = scoreOutput("gateway --> auth --> cache\n ↓\n reject", {
|
|
47
|
+
language: "en",
|
|
48
|
+
expectVisual: true,
|
|
49
|
+
});
|
|
50
|
+
assert.equal(visual.hasVisual, true);
|
|
51
|
+
|
|
52
|
+
console.log("AGENTS.md evaluation scorer tests passed");
|
package/global/AGENTS.md
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Behavioral guidelines to reduce common LLM coding mistakes. Project-specific instructions override this file when they conflict.
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1. Clear Output
|
|
6
|
+
|
|
7
|
+
- Make outputs easy to understand and verify. Use ASD-STE100-inspired principles: short sentences, one idea per sentence, and consistent terms. Apply its formal language rules only to English.
|
|
8
|
+
- When it improves understanding, use a diagram, HTML artifact, or video instead of long prose.
|
|
9
|
+
|
|
10
|
+
## 2. Think Before Coding
|
|
6
11
|
|
|
7
12
|
- Surface material assumptions, interpretations, and tradeoffs.
|
|
8
13
|
- If unresolved ambiguity would materially change the result, ask. When no human is reachable, choose a defensible interpretation, state it, and proceed with verifiable criteria.
|
|
9
14
|
- Prefer the simpler approach. Name conflicting requirements rather than silently compromising between them.
|
|
10
15
|
|
|
11
|
-
##
|
|
16
|
+
## 3. Minimal Solution
|
|
12
17
|
|
|
13
18
|
Understand the problem and relevant code flow before choosing the first rung that works:
|
|
14
19
|
|
|
@@ -24,11 +29,11 @@ Understand the problem and relevant code flow before choosing the first rung tha
|
|
|
24
29
|
- For states excluded by enforced invariants, fail visibly instead of inventing fallback behavior.
|
|
25
30
|
- State the ceiling and upgrade trigger of any deliberate simplification that cuts a real corner.
|
|
26
31
|
|
|
27
|
-
##
|
|
32
|
+
## 4. Skill Boundaries
|
|
28
33
|
|
|
29
34
|
After loading a skill, treat its documented interface as sufficient for normal use. Do not inspect the skill's implementation, installed executable, or package source unless the user asks to review, debug, or modify it; its documented behavior conflicts with observed behavior; or required usage details are missing from the skill.
|
|
30
35
|
|
|
31
|
-
##
|
|
36
|
+
## 5. Read, Then Change Surgically
|
|
32
37
|
|
|
33
38
|
Before editing, read the affected public API and its immediate callers. For a bug, find every statically discoverable caller and relevant implementation.
|
|
34
39
|
|
|
@@ -38,23 +43,23 @@ Every changed line traces to the user's request or to a defect that request reve
|
|
|
38
43
|
- Remove imports, variables, and functions that your changes make unused. Leave pre-existing dead code in place and mention it.
|
|
39
44
|
- Fix a faulty shared function once and name affected sibling callers; if only one caller is wrong, fix that caller instead of guarding a correct shared function.
|
|
40
45
|
|
|
41
|
-
##
|
|
46
|
+
## 6. Goal-Driven Execution
|
|
42
47
|
|
|
43
48
|
- Turn work into checkable outcomes: reproduce bugs before fixing them, preserve behavior during refactors, and optimize against a tested reference implementation.
|
|
44
49
|
- For multi-step or materially ambiguous work, state a brief plan and give every step its own verification.
|
|
45
50
|
- Leave the smallest relevant runnable check for new or changed non-trivial logic. Do not introduce a test framework solely for that check.
|
|
46
51
|
|
|
47
|
-
##
|
|
52
|
+
## 7. Fail Visibly
|
|
48
53
|
|
|
49
54
|
- "Completed" is wrong if anything required was silently skipped.
|
|
50
55
|
- "Tests pass" is wrong if any required test was skipped or not run.
|
|
51
56
|
- If a required input, file, or tool is missing, or a step is impossible under the stated constraints, report what is missing and what you need. Never fabricate it to make a check pass.
|
|
52
57
|
|
|
53
|
-
##
|
|
58
|
+
## 8. Frontend Verification
|
|
54
59
|
|
|
55
60
|
For frontend feature development, load the `web-browser` skill and verify the result in a real Chrome browser through CDP. Exercise the relevant user flow with real clicks, capture screenshots of the resulting UI, and test the actual behavior before reporting completion. Static inspection or non-browser tests do not replace this verification.
|
|
56
61
|
|
|
57
|
-
##
|
|
62
|
+
## 9. Worktree Isolation
|
|
58
63
|
|
|
59
64
|
For a Git-repository task that coordinates substantial changes across multiple files or modules, or implements a feature intended for release, ask before editing whether to isolate it in a worktree. Skip the question when already in a linked worktree.
|
|
60
65
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxiaochao/pi-toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Personal pi coding agent toolkit: scheduler, /btw, /cache_export, apply_patch, browser automation, and bundled theme/skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"files": [
|
|
14
14
|
"extensions",
|
|
15
|
+
"evaluations/agents-md",
|
|
15
16
|
"packages/cache-export",
|
|
16
17
|
"packages/codex-edit",
|
|
17
18
|
"packages/herdr-subagents",
|