@maxiaochao/pi-toolkit 0.11.1 → 0.11.3
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 +13 -0
- package/package.json +1 -1
- package/packages/herdr-subagents/CHANGELOG.md +9 -0
- package/packages/herdr-subagents/README.md +2 -0
- package/packages/herdr-subagents/agents/analyst.md +1 -1
- package/packages/herdr-subagents/agents/explorer.md +1 -1
- package/packages/herdr-subagents/agents/reviewer.md +1 -1
- package/packages/herdr-subagents/agents/worker.md +1 -1
- package/packages/herdr-subagents/package.json +1 -1
- package/packages/herdr-subagents/src/live-agent.ts +3 -1
- package/packages/herdr-subagents/src/personas.ts +1 -0
- package/packages/herdr-subagents/tests/run-tests.mjs +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 2026-10-12 - v0.11.3
|
|
2
|
+
|
|
3
|
+
- harden coordinated publishing and make local release checks authoritative
|
|
4
|
+
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
- Replace split child/root publishing with one idempotent root-tag workflow, make final-version local checks authoritative, keep CI publication-only, and remove timing-sensitive Herdr lifecycle assertions.
|
|
8
|
+
|
|
9
|
+
## 2026-10-12 - v0.11.2
|
|
10
|
+
|
|
11
|
+
- bundle herdr-subagents v0.4.12: enable codemode for child agents while preserving persona tool boundaries
|
|
12
|
+
- Enable `codemode` for bundled Herdr Subagents children while preserving persona tool boundaries.
|
|
13
|
+
|
|
1
14
|
## 2026-10-12 - v0.11.1
|
|
2
15
|
|
|
3
16
|
- bundle herdr-subagents v0.4.11: add architecture documentation and clear-output guidance evaluation
|
package/package.json
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
- Make lifecycle tests accept both valid report-first and observation-first execution orderings.
|
|
4
|
+
|
|
5
|
+
## 2026-10-12 - v0.4.12
|
|
6
|
+
|
|
7
|
+
- enable codemode for child agents while preserving persona tool boundaries
|
|
8
|
+
- Enable `codemode` for every child Pi while preserving each persona's existing tool allowlist and read/write boundary.
|
|
9
|
+
|
|
1
10
|
## 2026-10-12 - v0.4.11
|
|
2
11
|
|
|
3
12
|
- add architecture documentation and clear-output guidance evaluation
|
|
@@ -172,6 +172,8 @@ Each `personas.<name>` object supports exactly these overrides:
|
|
|
172
172
|
|
|
173
173
|
JSON persona overrides cannot change `name`, `description`, `access`, `tools`, or the system prompt; define those in persona Markdown.
|
|
174
174
|
|
|
175
|
+
Every child Pi explicitly loads and enables `codemode`. Built-in personas include it in their tool allowlists. Custom personas may omit `tools` and inherit Pi's defaults plus `codemode`, or list `codemode` explicitly alongside their allowed tools. A read-only persona remains read-only because codemode can call only the tools enabled for that child session.
|
|
176
|
+
|
|
175
177
|
A global configuration can establish shared defaults:
|
|
176
178
|
|
|
177
179
|
```json
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: analyst
|
|
3
3
|
description: Neutral read-only analyst for dynamically assigned roles
|
|
4
4
|
access: read
|
|
5
|
-
tools: read, bash, grep, find, ls
|
|
5
|
+
tools: read, bash, grep, find, ls, codemode
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
Act as an independent analyst and follow the role and evaluation method in the task prompt. Do not modify project files. Separate direct evidence, inference, and unknowns, and report concrete evidence with useful paths.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: explorer
|
|
3
3
|
description: Read-only explorer for fast codebase investigation
|
|
4
4
|
access: read
|
|
5
|
-
tools: read, bash, grep, find, ls
|
|
5
|
+
tools: read, bash, grep, find, ls, codemode
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
Investigate the assigned question without modifying files. Report concrete evidence and useful paths.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: reviewer
|
|
3
3
|
description: Read-only reviewer for correctness and maintainability risks
|
|
4
4
|
access: read
|
|
5
|
-
tools: read, bash, grep, find, ls
|
|
5
|
+
tools: read, bash, grep, find, ls, codemode
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
Review the assigned work without modifying files. Report actionable findings with concrete evidence.
|
|
@@ -36,13 +36,15 @@ export function childPiArgs(task: LiveTaskRecord, systemPromptFile: string): str
|
|
|
36
36
|
"--session", task.sessionFile,
|
|
37
37
|
"--name", `Subagent: ${task.name ?? task.agent ?? "worker"}`,
|
|
38
38
|
"--no-extensions",
|
|
39
|
+
"--extension", "builtin:codemode",
|
|
39
40
|
"--extension", fileURLToPath(new URL("../extensions/subagent-report.ts", import.meta.url)),
|
|
40
41
|
"--no-skills",
|
|
41
42
|
"--append-system-prompt", systemPromptFile,
|
|
42
43
|
];
|
|
43
44
|
if (task.model) args.push("--model", task.model);
|
|
44
45
|
if (task.thinking) args.push("--thinking", task.thinking);
|
|
45
|
-
if (task.tools?.length) args.push("--tools", [...new Set([...task.tools, "subagent_report"])].join(","));
|
|
46
|
+
if (task.tools?.length) args.push("--tools", [...new Set([...task.tools, "codemode", "subagent_report"])].join(","));
|
|
47
|
+
else args.push("--tools", "+codemode");
|
|
46
48
|
for (const skill of task.skills ?? []) args.push("--skill", skill);
|
|
47
49
|
return args;
|
|
48
50
|
}
|
|
@@ -24,6 +24,7 @@ import { RunPaneAllocator } from "../src/run-pane-allocator.ts";
|
|
|
24
24
|
import { aggregateTaskStatus } from "../src/run-status.ts";
|
|
25
25
|
import { isAbortError } from "../src/errors.ts";
|
|
26
26
|
import { acquireDirectoryLock, withRunStateLock } from "../src/run-state.ts";
|
|
27
|
+
import { childPiArgs } from "../src/live-agent.ts";
|
|
27
28
|
import registerSubagentReport from "../extensions/subagent-report.ts";
|
|
28
29
|
|
|
29
30
|
/** Drives one task through the batch runner and projects its single result like a task-scoped run. */
|
|
@@ -457,13 +458,13 @@ try {
|
|
|
457
458
|
herdr,
|
|
458
459
|
});
|
|
459
460
|
check("compact successful report", success.ok && success.status === "completed" && success.summary === "Authentication review completed." && success.documents.length === 1 && !success.output.includes("FULL RESULT"));
|
|
460
|
-
check("Herdr lifecycle", herdr.calls.map(([name]) => name).join(",") === "createTab,renamePane,startAgent,promptAgent,
|
|
461
|
+
check("Herdr lifecycle", herdr.calls.map(([name]) => name).filter((name) => name !== "getAgentState").join(",") === "createTab,renamePane,startAgent,promptAgent,isTabFocused,closeTab");
|
|
461
462
|
const createRequest = herdr.calls.find(([name]) => name === "createTab")[1];
|
|
462
463
|
const startRequest = herdr.calls.find(([name]) => name === "startAgent")[1];
|
|
463
464
|
check("named unfocused tab in parent workspace", createRequest.workspaceId === "w1" && createRequest.cwd === root && createRequest.label === "SA · auth-review" && createRequest.focus === false);
|
|
464
465
|
check("ordinary execution never steals pane focus", !herdr.calls.some(([name]) => name === "focusPane"));
|
|
465
466
|
check("child environment points at durable task and parent pane", createRequest.env.PI_HERDR_SUBAGENTS_CHILD === "1" && createRequest.env.PI_HERDR_SUBAGENTS_TASK_DIR.includes(join(".pi", "herdr-subagents", "runs")) && createRequest.env.PI_HERDR_SUBAGENTS_PARENT_PANE_ID === "w1:p-parent");
|
|
466
|
-
check("persistent isolated child Pi", startRequest.kind === "pi" && startRequest.paneId === "w1:p2" && startRequest.args.includes("--session") && startRequest.args.includes("--no-extensions") && startRequest.args.includes("--extension") && startRequest.args.includes("--no-skills") && startRequest.args.includes("--model") && startRequest.args.includes("fake/model") && startRequest.args.includes("--tools") && startRequest.args.includes("read,grep,subagent_report"));
|
|
467
|
+
check("persistent isolated child Pi", startRequest.kind === "pi" && startRequest.paneId === "w1:p2" && startRequest.args.includes("--session") && startRequest.args.includes("--no-extensions") && startRequest.args.includes("builtin:codemode") && startRequest.args.includes("--extension") && startRequest.args.includes("--no-skills") && startRequest.args.includes("--model") && startRequest.args.includes("fake/model") && startRequest.args.includes("--tools") && startRequest.args.includes("read,grep,codemode,subagent_report"));
|
|
467
468
|
const promptRequest = herdr.calls.find(([name]) => name === "promptAgent")[1];
|
|
468
469
|
check("prompt submitted through Herdr", promptRequest.prompt === "Review authentication" && promptRequest.target === startRequest.name);
|
|
469
470
|
|
|
@@ -480,7 +481,7 @@ try {
|
|
|
480
481
|
model: { provider: "fake", id: "model" },
|
|
481
482
|
thinkingLevel: "medium",
|
|
482
483
|
}, { agentsDirectory: join(process.cwd(), "agents"), herdr: extensionHerdr });
|
|
483
|
-
check("public extension behavior uses injectable Herdr", !publicResult.isError && publicResult.content[0].text.includes("Authentication review completed.") && !publicResult.content[0].text.includes("FULL RESULT") && extensionHerdr.calls.map(([name]) => name).join(",") === "createTab,renamePane,startAgent,promptAgent,
|
|
484
|
+
check("public extension behavior uses injectable Herdr", !publicResult.isError && publicResult.content[0].text.includes("Authentication review completed.") && !publicResult.content[0].text.includes("FULL RESULT") && extensionHerdr.calls.map(([name]) => name).filter((name) => name !== "getAgentState").join(",") === "createTab,renamePane,startAgent,promptAgent,isTabFocused,closeTab", JSON.stringify({ publicResult, calls: extensionHerdr.calls.map(([name]) => name) }));
|
|
484
485
|
let singleStalledWarning = "";
|
|
485
486
|
await runSingleTask("single slow task", { cwd: root, herdr: fakeHerdr(), stalledWarningSeconds: 0.001, onStalled: (message) => { singleStalledWarning = message; } });
|
|
486
487
|
check("single-task execution emits configured stalled warning", singleStalledWarning.includes("appears stalled"));
|
|
@@ -570,6 +571,10 @@ try {
|
|
|
570
571
|
|
|
571
572
|
const definition = parseAgentMarkdown(`---\nname: reviewer\ndescription: Review code\nmodel: fake/model\ntools: read, grep\n---\nReview carefully.`, "reviewer.md");
|
|
572
573
|
check("persona frontmatter parsing", definition.name === "reviewer" && definition.model === "fake/model" && definition.tools?.join(",") === "read,grep" && definition.systemPrompt === "Review carefully.");
|
|
574
|
+
const inheritedToolArgs = childPiArgs({ id: "inherited", sessionFile: "/tmp/inherited.jsonl" }, "/tmp/system.md");
|
|
575
|
+
check("child Pi enables codemode when a persona inherits default tools", inheritedToolArgs.includes("builtin:codemode") && inheritedToolArgs[inheritedToolArgs.indexOf("--tools") + 1] === "+codemode");
|
|
576
|
+
const explicitToolArgs = childPiArgs({ id: "explicit", sessionFile: "/tmp/explicit.jsonl", tools: ["read"] }, "/tmp/system.md");
|
|
577
|
+
check("child Pi enables codemode with an explicit tool allowlist", explicitToolArgs.includes("builtin:codemode") && explicitToolArgs.includes("read,codemode,subagent_report"));
|
|
573
578
|
const agentsDir = join(root, "agents");
|
|
574
579
|
await import("node:fs/promises").then(({ mkdir }) => mkdir(agentsDir));
|
|
575
580
|
writeFileSync(join(agentsDir, "worker.md"), `---\nname: worker\ndescription: Worker\n---\nDo work.`);
|
|
@@ -578,7 +583,7 @@ try {
|
|
|
578
583
|
check("persona discovery and diagnostics", discovery.agents.length === 1 && discovery.agents[0].name === "worker" && discovery.diagnostics.length === 1);
|
|
579
584
|
const packageDiscovery = discoverPackageAgents(join(process.cwd(), "agents"));
|
|
580
585
|
const analystPersona = packageDiscovery.agents.find((persona) => persona.name === "analyst");
|
|
581
|
-
check("built-in analyst is neutral and read-only", packageDiscovery.diagnostics.length === 0 && analystPersona?.access === "read" && analystPersona.model === undefined && analystPersona.tools?.join(",") === "read,bash,grep,find,ls" && /independent analyst/.test(analystPersona.systemPrompt) && /direct evidence, inference, and unknowns/.test(analystPersona.systemPrompt) && !/auditor|replicator|adversary/.test(analystPersona.systemPrompt));
|
|
586
|
+
check("built-in analyst is neutral and read-only", packageDiscovery.diagnostics.length === 0 && analystPersona?.access === "read" && analystPersona.model === undefined && analystPersona.tools?.join(",") === "read,bash,grep,find,ls,codemode" && /independent analyst/.test(analystPersona.systemPrompt) && /direct evidence, inference, and unknowns/.test(analystPersona.systemPrompt) && !/auditor|replicator|adversary/.test(analystPersona.systemPrompt));
|
|
582
587
|
|
|
583
588
|
const configRoot = join(root, "configuration");
|
|
584
589
|
const packageAgents = join(configRoot, "package-agents");
|