@maxiaochao/pi-toolkit 0.13.3 → 0.13.4
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 +5 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/packages/herdr-subagents/CHANGELOG.md +5 -0
- package/packages/herdr-subagents/README.md +3 -1
- package/packages/herdr-subagents/TESTING.md +2 -1
- package/packages/herdr-subagents/package.json +1 -1
- package/packages/herdr-subagents/src/tool.ts +1 -4
- package/packages/herdr-subagents/tests/config.mjs +14 -3
- package/packages/herdr-subagents/tests/core-state-machine.mjs +3 -1
- package/packages/herdr-subagents/tests/run-tests.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 2026-10-22 - v0.13.4
|
|
2
|
+
|
|
3
|
+
- herdr-subagents v0.7.3: keep Persona selection lists concise
|
|
4
|
+
|
|
1
5
|
## 2026-10-21 - v0.13.3
|
|
2
6
|
|
|
3
7
|
- codex-edit v0.2.0: persist personal routing rules in the Pi agent directory across package updates
|
|
@@ -9,6 +13,7 @@
|
|
|
9
13
|
|
|
10
14
|
## Unreleased
|
|
11
15
|
|
|
16
|
+
- Herdr Subagents: show only Persona names and descriptions in model-facing selection lists, preserving diagnostics and detailed user-facing inspection.
|
|
12
17
|
- Make Agent Team user-invoked only through `/skill:agent-team`, hidden from automatic model selection.
|
|
13
18
|
- Add `npm run release:check -- vX.Y.Z` to wait for GitHub publication and verify exact npm versions, remote tags, integrity, and all tarball contents against the release commit, including coordinated child releases.
|
|
14
19
|
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ Each child README owns its feature description, motivation or upstream alignment
|
|
|
42
42
|
|
|
43
43
|
Codex Edit personal routing rules belong in `~/.pi/agent/codex-edit.json`, not inside `node_modules`. User fields override bundled defaults; `models` replaces the complete default list. The file survives package updates and is shared by parent sessions and explicitly configured subagents using the same agent directory. Use `/reload` after editing it, and start new subagents. See [Codex Edit configuration](packages/codex-edit/README.md#configuration).
|
|
44
44
|
|
|
45
|
-
Herdr Subagents tasks require an explicit `agent` Persona; no default `worker` is selected. Choose `reviewer` for independent reviews of proposals, designs, documents, implementations, or analysis; `explorer` for codebase investigation; `worker` for file-changing work; and `analyst` for charter-defined agent-team roles. See [built-in Personas](packages/herdr-subagents/README.md#built-in-personas) for selection guidance and the distinction between parent-facing descriptions and child instructions. Personas can opt into local extension files or npm/git Pi packages through `extensions`. Set top-level `defaultExtensions` in `~/.pi/agent/herdr-subagents.json` (or project `.pi/herdr-subagents.json`) to share a fallback list; Persona-specific lists take precedence, and `[]` clears inherited sources. This uses native Pi package semantics: package-provided skills, prompt templates, and themes may also load, and `--no-skills` does not exclude explicitly selected package skills. See the [extension-source contract](packages/herdr-subagents/README.md#explicit-extension-sources-and-pi-packages) for precedence, isolation, and examples. The [real Herdr smoke test](packages/herdr-subagents/TESTING.md) preserves the configured analyst model and explicit authentication extensions while isolating unrelated settings.
|
|
45
|
+
Herdr Subagents tasks require an explicit `agent` Persona; no default `worker` is selected. Choose `reviewer` for independent reviews of proposals, designs, documents, implementations, or analysis; `explorer` for codebase investigation; `worker` for file-changing work; and `analyst` for charter-defined agent-team roles. Control `list` returns names and descriptions for selection, plus configuration diagnostics when present; use `/herdr-subagents agents` and `settings` for detailed configuration. See [built-in Personas](packages/herdr-subagents/README.md#built-in-personas) for selection guidance and the distinction between parent-facing descriptions and child instructions. Personas can opt into local extension files or npm/git Pi packages through `extensions`. Set top-level `defaultExtensions` in `~/.pi/agent/herdr-subagents.json` (or project `.pi/herdr-subagents.json`) to share a fallback list; Persona-specific lists take precedence, and `[]` clears inherited sources. This uses native Pi package semantics: package-provided skills, prompt templates, and themes may also load, and `--no-skills` does not exclude explicitly selected package skills. See the [extension-source contract](packages/herdr-subagents/README.md#explicit-extension-sources-and-pi-packages) for precedence, isolation, and examples. The [real Herdr smoke test](packages/herdr-subagents/TESTING.md) preserves the configured analyst model and explicit authentication extensions while isolating unrelated settings.
|
|
46
46
|
|
|
47
47
|
Multiple standalone children may be installed together. `pi-openai-account-pool` may also be installed alongside the complete toolkit because the toolkit does not embed it. Every other child in the table above, including `pi-background-tasks`, is embedded, so a second install exposes the same resource twice.
|
|
48
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxiaochao/pi-toolkit",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.4",
|
|
4
4
|
"description": "Personal pi coding agent toolkit: background tasks, scheduler, /btw, /cache_export, apply_patch, browser automation, and bundled theme/skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 2026-10-22 - v0.7.3
|
|
2
|
+
|
|
3
|
+
- keep Persona selection lists concise
|
|
4
|
+
- Limit model-facing Persona listings and unknown-Persona suggestions to names and descriptions. Preserve configuration diagnostics, detailed result metadata, and the `/herdr-subagents agents` and `settings` inspection commands.
|
|
5
|
+
|
|
1
6
|
## 2026-10-21 - v0.7.2
|
|
2
7
|
|
|
3
8
|
- clarify final answer submission through subagent_report
|
|
@@ -119,7 +119,7 @@ A batch containing a write-capable Persona must explicitly or effectively use `c
|
|
|
119
119
|
|
|
120
120
|
| Action | `runId` | Purpose |
|
|
121
121
|
| --- | --- | --- |
|
|
122
|
-
| `list` | Not accepted | List
|
|
122
|
+
| `list` | Not accepted | List Persona names and descriptions for task selection, plus configuration diagnostics when present. |
|
|
123
123
|
| `status` | Required | Show one run and its task states. |
|
|
124
124
|
| `history` | Not accepted | List durable project-local run history. |
|
|
125
125
|
| `cancel` | Required | Cancel an active run. |
|
|
@@ -127,6 +127,8 @@ A batch containing a write-capable Persona must explicitly or effectively use `c
|
|
|
127
127
|
|
|
128
128
|
Settled tasks are immutable. Follow-up work starts a new task or run; there is no resume/respond lifecycle.
|
|
129
129
|
|
|
130
|
+
The model-facing `list` text does not expand tools, skills, extensions, models, thinking levels, or configuration sources. Describe routing-relevant capabilities and constraints in each Persona's description. Use `/herdr-subagents agents` and `/herdr-subagents settings` for detailed configuration; full resolved data remains in the tool result's `details` metadata.
|
|
131
|
+
|
|
130
132
|
### Slash command
|
|
131
133
|
|
|
132
134
|
`/herdr-subagents` supports:
|
|
@@ -9,7 +9,8 @@ npm test --workspace @maxiaochao/pi-herdr-subagents
|
|
|
9
9
|
It verifies:
|
|
10
10
|
|
|
11
11
|
- global/project `defaultExtensions` replacement, trimming, source attribution, Persona JSON/Markdown precedence, explicit empty-list clearing, invalid-value diagnostics, and per-call reloads;
|
|
12
|
-
-
|
|
12
|
+
- concise Persona names/descriptions in model-facing listings and unknown-Persona errors, including empty lists and visible configuration diagnostics;
|
|
13
|
+
- resolved defaults in control result metadata, settings output, and child CLI arguments while preserving mandatory extensions;
|
|
13
14
|
- strict serial start order at concurrency one;
|
|
14
15
|
- bounded read-only parallelism;
|
|
15
16
|
- ordered results despite concurrent completion;
|
|
@@ -60,10 +60,7 @@ export function listText(discovery: SubagentConfiguration): string {
|
|
|
60
60
|
const lines = ["Available Herdr Subagents personas:"];
|
|
61
61
|
if (discovery.personas.length === 0) lines.push("- (none)");
|
|
62
62
|
for (const agent of discovery.personas) {
|
|
63
|
-
|
|
64
|
-
const tools = agent.tools?.join(", ") ?? "Pi default built-in tools";
|
|
65
|
-
const skills = agent.skills.join(", ") || "none";
|
|
66
|
-
lines.push(`- ${agent.name}: ${agent.description} (source: ${agent.source}; access: ${agent.access}; model: ${model} [${agent.modelSource}]; thinking: ${agent.thinking ?? "default"}; tools: ${tools}; skills: ${skills}; extensions: ${agent.extensions.join(", ") || "none"} [${agent.extensionsSource}])`);
|
|
63
|
+
lines.push(`- ${agent.name}: ${agent.description}`);
|
|
67
64
|
}
|
|
68
65
|
if (discovery.diagnostics.length > 0) {
|
|
69
66
|
lines.push("", "Persona diagnostics:", ...discovery.diagnostics.map((diagnostic) => `- ${diagnostic}`));
|
|
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { loadSubagentConfiguration } from "../src/config.ts";
|
|
6
6
|
import { childPiArgs } from "../src/live-agent.ts";
|
|
7
|
-
import { executeHerdrSubagentsControl } from "../src/tool.ts";
|
|
7
|
+
import { executeHerdrSubagentsControl, listText } from "../src/tool.ts";
|
|
8
8
|
|
|
9
9
|
const root = mkdtempSync(join(tmpdir(), "herdr-default-extensions-"));
|
|
10
10
|
const agents = join(root, "agents");
|
|
@@ -88,7 +88,18 @@ try {
|
|
|
88
88
|
const response = await executeHerdrSubagentsControl({ action: "list" }, undefined, undefined, { cwd: root }, { agentsDirectory: agents, configurationPaths: paths });
|
|
89
89
|
assert.deepEqual(response.details.agents.find(({ name }) => name === "plain").extensions, ["./updated.ts"]);
|
|
90
90
|
assert.deepEqual(response.details.settings.defaultExtensions, ["./updated.ts"]);
|
|
91
|
-
|
|
91
|
+
const expectedListing = [
|
|
92
|
+
"Available Herdr Subagents personas:",
|
|
93
|
+
"- cleared: Configuration fixture",
|
|
94
|
+
"- pinned: Configuration fixture",
|
|
95
|
+
"- plain: Configuration fixture",
|
|
96
|
+
].join("\n");
|
|
97
|
+
assert.equal(response.content[0].text, expectedListing, "Model-facing listings must contain only Persona names and descriptions");
|
|
98
|
+
assert.equal(listText({ ...configuration, personas: [] }), "Available Herdr Subagents personas:\n- (none)");
|
|
99
|
+
write(paths.projectConfig, { defaultExtensions: "./invalid.ts" });
|
|
100
|
+
const diagnosed = await executeHerdrSubagentsControl({ action: "list" }, undefined, undefined, { cwd: root }, { agentsDirectory: agents, configurationPaths: paths });
|
|
101
|
+
assert.equal(diagnosed.content[0].text, `${expectedListing}\n\nPersona diagnostics:\n- project defaultExtensions must be an array of non-empty strings`, "Concise listings must still surface invalid configuration");
|
|
102
|
+
assert.deepEqual(diagnosed.details.diagnostics, ["project defaultExtensions must be an array of non-empty strings"]);
|
|
92
103
|
write(paths.projectConfig, { defaultExtensions: [] });
|
|
93
104
|
const cleared = persona(load());
|
|
94
105
|
assert.deepEqual(cleared.extensions, []);
|
|
@@ -97,7 +108,7 @@ try {
|
|
|
97
108
|
assert.ok(clearedArgs.some((arg) => arg.endsWith("/extensions/subagent-report.ts")));
|
|
98
109
|
assert.ok(!clearedArgs.includes("./updated.ts"));
|
|
99
110
|
assert.deepEqual(selected.extensions, ["./updated.ts"]);
|
|
100
|
-
console.log("PASS defaults reach child arguments and
|
|
111
|
+
console.log("PASS concise Persona listings preserve diagnostics and detailed metadata; defaults reach child arguments and reload per call");
|
|
101
112
|
} finally {
|
|
102
113
|
rmSync(root, { recursive: true, force: true });
|
|
103
114
|
}
|
|
@@ -142,7 +142,7 @@ async function run(tasks, concurrency, herdr = fakeHerdr(), signal) {
|
|
|
142
142
|
assert.match(laterMissing.content[0].text, /tasks\[1\]\.agent.*required/);
|
|
143
143
|
const unknown = await execute({ tasks: [{ ...missing, agent: "unknown-persona" }] });
|
|
144
144
|
assert.equal(unknown.isError, true);
|
|
145
|
-
assert.
|
|
145
|
+
assert.equal(unknown.content[0].text, `Unknown persona 'unknown-persona'.\n\n${listed.content[0].text}`, "Unknown-Persona errors must reuse the concise selection list");
|
|
146
146
|
assert.deepEqual(herdr.starts, [], "Invalid requests must not start an Agent");
|
|
147
147
|
assert.equal(existsSync(join(root, ".pi", "herdr-subagents", "runs")), false, "Invalid requests must not create run records");
|
|
148
148
|
|
|
@@ -287,6 +287,8 @@ assert.throws(() => applyTaskStatus(terminal, "running"), /terminal tasks are im
|
|
|
287
287
|
const notifications = [];
|
|
288
288
|
await configuredCommands.get("herdr-subagents").handler("settings", { cwd: lifecycleRoot, ui: { notify(message) { notifications.push(message); } } });
|
|
289
289
|
assert.match(notifications[0], /defaultExtensions=\[\] \(project\)/, "Settings must show empty defaults and their source");
|
|
290
|
+
await configuredCommands.get("herdr-subagents").handler("agents", { cwd: lifecycleRoot, ui: { notify(message) { notifications.push(message); } } });
|
|
291
|
+
assert.match(notifications[1], /: (?:package|global|project), (?:read|write), model=.*thinking=.*tools=.*skills=.*extensions=/, "User-facing inspection must retain detailed configuration fields");
|
|
290
292
|
}
|
|
291
293
|
|
|
292
294
|
{
|
|
@@ -661,7 +661,7 @@ try {
|
|
|
661
661
|
const extensionHistory = await listSubagentHistory(extensionRoot);
|
|
662
662
|
check("history exposes saved extension sources", JSON.stringify(extensionHistory[0]?.tasks[0]?.extensions) === JSON.stringify(extensionSources));
|
|
663
663
|
const extensionList = await executeHerdrSubagents({ action: "list" }, undefined, undefined, { cwd: extensionRoot }, extensionDependencies);
|
|
664
|
-
check("persona listing
|
|
664
|
+
check("persona listing keeps extension configuration in metadata only", !extensionList.content[0].text.includes("npm:@example/pi-tools@1.0.0") && extensionList.details.agents[0].extensionsSource === "project persona" && JSON.stringify(extensionList.details.agents[0].extensions) === JSON.stringify(extensionSources));
|
|
665
665
|
writeFileSync(extensionPaths.projectConfig, JSON.stringify({ personas: { routed: { extensions: [] } } }));
|
|
666
666
|
check("empty project extension list clears lower-precedence sources", extensionPersona()?.extensions?.length === 0 && extensionPersona()?.extensionsSource === "project persona");
|
|
667
667
|
const extensionResumeHerdr = fakeHerdr();
|