pi-rnd 0.2.7 → 0.3.0
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 +2 -11
- package/dist/auto-install-agents.js +39 -0
- package/dist/auto-install-agents.js.map +1 -0
- package/dist/doctor.js +11 -12
- package/dist/doctor.js.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/spawn.js +0 -12
- package/dist/orchestrator/spawn.js.map +1 -1
- package/dist/subagents/agent-defs.js +69 -0
- package/dist/subagents/agent-defs.js.map +1 -0
- package/dist/subagents/manager.js +157 -0
- package/dist/subagents/manager.js.map +1 -0
- package/dist/subagents/rpc.js +41 -0
- package/dist/subagents/rpc.js.map +1 -0
- package/docs/PI-API.md +7 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -14,17 +14,8 @@ Ports the R&D framework methodology (pre-registration, information-barrier verif
|
|
|
14
14
|
|
|
15
15
|
- Node ≥ 20
|
|
16
16
|
- `@earendil-works/pi-coding-agent` (official PI runtime) installed and working
|
|
17
|
-
- `@tintinweb/pi-subagents` (community subagent extension, pinned to `^0.7.3`) installed: `pi install npm:@tintinweb/pi-subagents`
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`@tintinweb/pi-subagents` is a community extension, NOT shipped by official PI. PI explicitly omits subagents from its core surface, so any pipeline that needs plan→build→verify→integrate orchestration must reach outside the official packages. pi-rnd audited this package at v0.7.3 (2026-05-16); summary:
|
|
22
|
-
|
|
23
|
-
- No install scripts. Zero outbound network calls. One bounded `execFileSync` for git worktrees. Normal OSS hygiene (tests, biome, CI, semver CHANGELOG).
|
|
24
|
-
- Maintainer: tintinweb (security researcher, public GitHub presence).
|
|
25
|
-
- Same author as official PI maintains its transitive `@mariozechner/*` peer-deps — they're the deprecated personal-namespace publications of the same code now under `@earendil-works/*`.
|
|
26
|
-
|
|
27
|
-
Full audit: see `audits/pi-subagents-audit.md` in the R&D session artifacts. Re-audit on each minor or major bump.
|
|
18
|
+
Subagent functionality is built into pi-rnd directly via PI's public SDK (`createAgentSession`) — no external subagent extension is required.
|
|
28
19
|
|
|
29
20
|
## Develop
|
|
30
21
|
|
|
@@ -58,7 +49,7 @@ cp agents/*.md .pi/agents/
|
|
|
58
49
|
|
|
59
50
|
1. `~/.pi/agent/` (or `$PI_CODING_AGENT_DIR`) is writable
|
|
60
51
|
2. `$RND_DIR` is writable
|
|
61
|
-
3.
|
|
52
|
+
3. Native subagent module responds to `subagents:rpc:ping` within 2 s
|
|
62
53
|
4. Each of the 4 subagent `.md` files is discoverable
|
|
63
54
|
5. Each of the 11 skill directories is discoverable
|
|
64
55
|
6. Gate registry has registered seed gates (`gates: N`)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { access, copyFile, mkdir, readdir } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const PI_AGENT_DIR = process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
|
|
6
|
+
const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
7
|
+
export async function autoInstallBundledAgents() {
|
|
8
|
+
const bundledDir = join(PACKAGE_ROOT, "agents");
|
|
9
|
+
const targetDir = join(PI_AGENT_DIR, "agents");
|
|
10
|
+
const result = { copied: [], skipped: [], failed: [] };
|
|
11
|
+
let bundledFiles;
|
|
12
|
+
try {
|
|
13
|
+
bundledFiles = (await readdir(bundledDir)).filter((f) => f.endsWith(".md"));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
if (bundledFiles.length === 0)
|
|
19
|
+
return result;
|
|
20
|
+
await mkdir(targetDir, { recursive: true });
|
|
21
|
+
for (const file of bundledFiles) {
|
|
22
|
+
const dst = join(targetDir, file);
|
|
23
|
+
try {
|
|
24
|
+
await access(dst);
|
|
25
|
+
result.skipped.push(file);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
try {
|
|
29
|
+
await copyFile(join(bundledDir, file), dst);
|
|
30
|
+
result.copied.push(file);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
result.failed.push({ file, reason: err.message });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=auto-install-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-install-agents.js","sourceRoot":"","sources":["../src/auto-install-agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAErE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAQzE,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAE/C,MAAM,MAAM,GAAsB,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAE1E,IAAI,YAAsB,CAAC;IAE3B,IAAI,CAAC;QACH,YAAY,GAAG,CAAC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAE7C,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC;gBACH,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC5C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/doctor.js
CHANGED
|
@@ -70,12 +70,11 @@ async function checkDiscovery() {
|
|
|
70
70
|
const lines = ["§ discovery"];
|
|
71
71
|
const globalAgents = join(PI_AGENT_DIR, "agents");
|
|
72
72
|
const projectAgents = join(process.cwd(), ".pi", "agents");
|
|
73
|
-
const bundledAgents = join(PACKAGE_ROOT, "agents");
|
|
74
73
|
for (const name of AGENT_NAMES) {
|
|
75
|
-
const found = await tryAccess(join(projectAgents, `${name}.md`), join(globalAgents, `${name}.md`)
|
|
74
|
+
const found = await tryAccess(join(projectAgents, `${name}.md`), join(globalAgents, `${name}.md`));
|
|
76
75
|
lines.push(found
|
|
77
76
|
? `✓ agent ${name}: ${found}`
|
|
78
|
-
: `✗ agent ${name}: not found in .pi/agents
|
|
77
|
+
: `✗ agent ${name}: not found in .pi/agents/ or ~/.pi/agent/agents/ — auto-install at extension load should have placed them; try restarting pi`);
|
|
79
78
|
}
|
|
80
79
|
const globalSkills = join(PI_AGENT_DIR, "skills");
|
|
81
80
|
const projectSkills = join(process.cwd(), ".pi", "skills");
|
|
@@ -92,14 +91,14 @@ async function checkRoundTrip(pi, lines) {
|
|
|
92
91
|
lines.push("§ round-trip");
|
|
93
92
|
const ping = await rpcCall(pi, "ping", {}, 2000);
|
|
94
93
|
if (!ping?.success) {
|
|
95
|
-
lines.push("✗ pi-subagents not responding (ping timeout 2s) —
|
|
94
|
+
lines.push("✗ pi-rnd native subagents not responding (ping timeout 2s) — check the extension log for initialization errors");
|
|
96
95
|
return "error";
|
|
97
96
|
}
|
|
98
|
-
lines.push(`✓ pi-subagents loaded (protocol v${ping.data?.version ?? "?"})`);
|
|
97
|
+
lines.push(`✓ pi-rnd native subagents loaded (protocol v${ping.data?.version ?? "?"})`);
|
|
99
98
|
const roundTripBudgetMs = 30_000;
|
|
100
|
-
// subagents:started
|
|
101
|
-
//
|
|
102
|
-
//
|
|
99
|
+
// subagents:started may fire before the spawn RPC reply (the manager emits
|
|
100
|
+
// :started from agent_start, which can race with the synchronous id return).
|
|
101
|
+
// Buffer every started event with its id+timestamp and look up after spawn.
|
|
103
102
|
const startedEvents = new Map();
|
|
104
103
|
const unsubStarted = pi.events.on("subagents:started", (data) => {
|
|
105
104
|
const id = data?.id;
|
|
@@ -131,15 +130,15 @@ async function checkRoundTrip(pi, lines) {
|
|
|
131
130
|
const startedAtMs = startedEvents.get(targetId);
|
|
132
131
|
if (startedAtMs === undefined) {
|
|
133
132
|
lines.push(`✗ subagent ${targetId} never transitioned to running (no subagents:started observed for this id after ${roundTripBudgetMs / 1000}s) — ` +
|
|
134
|
-
`the
|
|
135
|
-
`Likely
|
|
133
|
+
`the manager accepted the spawn but agent_start never fired. ` +
|
|
134
|
+
`Likely an exception thrown inside createAgentSession before the lifecycle event.`);
|
|
136
135
|
return "error";
|
|
137
136
|
}
|
|
138
137
|
const sinceStartMs = Date.now() - startedAtMs;
|
|
139
138
|
lines.push(`⚠ subagent ${targetId} started but did not complete within ${roundTripBudgetMs / 1000}s ` +
|
|
140
139
|
`(${Math.round(sinceStartMs / 1000)}s since started event) — the LLM call is slow in this environment. ` +
|
|
141
140
|
`pi-rnd itself is healthy; this only affects /rnd-start latency. ` +
|
|
142
|
-
`
|
|
141
|
+
`Native subagents run in-process; no on-disk transcript. Re-run with PI_LOG_LEVEL=debug for stream details.`);
|
|
143
142
|
return "warning";
|
|
144
143
|
}
|
|
145
144
|
if (completion.status === "completed") {
|
|
@@ -154,7 +153,7 @@ export function registerRndDoctor(pi) {
|
|
|
154
153
|
pi.registerCommand("rnd-doctor", {
|
|
155
154
|
description: "Diagnose pi-rnd prerequisites (PI dir, subagents, discovery, gates, round-trip)",
|
|
156
155
|
handler: async (_args, ctx) => {
|
|
157
|
-
const lines = ["pi-rnd — doctor v0.
|
|
156
|
+
const lines = ["pi-rnd — doctor v0.3"];
|
|
158
157
|
const roundTripLines = [];
|
|
159
158
|
const [runtimeLines, discoveryLines, rtLevel] = await Promise.all([
|
|
160
159
|
checkPiRuntime(),
|
package/dist/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,MAAM,YAAY,GAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAErE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAEzE,MAAM,WAAW,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAU,CAAC;AAC9F,MAAM,WAAW,GAAG;IAClB,qBAAqB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,aAAa;IAC9E,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB;IACtE,mBAAmB,EAAE,gBAAgB,EAAE,cAAc;CAC7C,CAAC;AAEX,SAAS,OAAO,CACd,EAAgB,EAChB,MAAc,EACd,MAA+B,EAC/B,SAAiB;IAEjB,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAE/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,YAAY,GAAG,iBAAiB,MAAM,UAAU,SAAS,EAAE,CAAC;QAClE,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAAa,EAAE,EAAE;YACzD,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,IAAmB,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAG,KAAe;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,CAAC,CAAC;QACX,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,KAAK,GAAa,CAAC,cAAc,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,KAAK,GAAa,CAAC,aAAa,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
+
import { autoInstallBundledAgents } from "./auto-install-agents.js";
|
|
1
2
|
import { registerRndStart } from "./orchestrator/start.js";
|
|
2
3
|
import { registerGate, runGates } from "./gates/registry.js";
|
|
3
4
|
import { bashDiscipline } from "./gates/bash-discipline.js";
|
|
4
5
|
import { rndDirRequired } from "./gates/rnd-dir-required.js";
|
|
5
6
|
import { readEvidencePack } from "./gates/read-evidence-pack.js";
|
|
6
7
|
import { registerRndDoctor } from "./doctor.js";
|
|
7
|
-
|
|
8
|
+
import { createSubagentManager } from "./subagents/manager.js";
|
|
9
|
+
import { registerSubagentRpc } from "./subagents/rpc.js";
|
|
10
|
+
export default async function pirndFramework(pi) {
|
|
11
|
+
// Bundled agent .md files live in <pkgRoot>/agents/. The agent-defs loader
|
|
12
|
+
// resolves them via project → global → bundled lookup, but copying into the
|
|
13
|
+
// global dir keeps PI's own /agents UI discoverable without extra plumbing.
|
|
14
|
+
await autoInstallBundledAgents();
|
|
15
|
+
const manager = createSubagentManager(pi);
|
|
16
|
+
registerSubagentRpc(pi, manager);
|
|
8
17
|
registerRndStart(pi);
|
|
9
18
|
registerGate(bashDiscipline);
|
|
10
19
|
registerGate(rndDirRequired);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,cAAc,CAAC,EAAgB;IAC3D,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,wBAAwB,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAC1C,mBAAmB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAEjC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAErB,YAAY,CAAC,cAAc,CAAC,CAAC;IAC7B,YAAY,CAAC,cAAc,CAAC,CAAC;IAC7B,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAE/B,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEzD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,iBAAiB,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { readFile } from "node:fs/promises";
|
|
3
2
|
const DEFAULT_SPAWN_TIMEOUT_MS = 10_000;
|
|
4
3
|
const DEFAULT_COMPLETION_TIMEOUT_MS = 600_000;
|
|
5
4
|
export function rpcSpawn(pi, type, prompt, options, timeoutMs = DEFAULT_SPAWN_TIMEOUT_MS) {
|
|
@@ -53,15 +52,4 @@ export function waitForCompletion(pi, agentId, timeoutMs = DEFAULT_COMPLETION_TI
|
|
|
53
52
|
}, timeoutMs);
|
|
54
53
|
});
|
|
55
54
|
}
|
|
56
|
-
export async function readTranscript(agentId, sessionId, cwd) {
|
|
57
|
-
const uid = process.getuid?.() ?? 0;
|
|
58
|
-
const cwdEncoded = cwd.replace(/\//g, "-").replace(/^-/, "");
|
|
59
|
-
const path = `/tmp/pi-subagents-${uid}/${cwdEncoded}/${sessionId}/tasks/${agentId}.output`;
|
|
60
|
-
try {
|
|
61
|
-
return await readFile(path, "utf8");
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
55
|
//# sourceMappingURL=spawn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/orchestrator/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/orchestrator/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAKzC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AACxC,MAAM,6BAA6B,GAAG,OAAO,CAAC;AAE9C,MAAM,UAAU,QAAQ,CACtB,EAAgB,EAChB,IAAY,EACZ,MAAc,EACd,OAAsB,EACtB,YAAoB,wBAAwB;IAE5C,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,6BAA6B,SAAS,EAAE,CAAC;IAE9D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,IAAa,EAAE,EAAE;YACzD,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,IAAgC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,EAAE,CAAC;YACR,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,EAAgB,EAChB,OAAe,EACf,YAAoB,6BAA6B;IAEjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,MAAM,GAAG,CAAC,IAAa,EAAE,EAAE;YAC/B,MAAM,CAAC,GAAG,IAMT,CAAC;YAEF,IAAI,CAAC,EAAE,EAAE,KAAK,OAAO,IAAI,OAAO;gBAAE,OAAO;YACzC,OAAO,GAAG,IAAI,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC;gBACN,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;gBAC7B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC;gBAC7B,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAE3D,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { access, readFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { parseFrontmatter, stripFrontmatter } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import { getModel } from "@earendil-works/pi-ai";
|
|
8
|
+
// From dist/subagents/agent-defs.js the package root is two levels up.
|
|
9
|
+
const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
10
|
+
const PI_AGENT_DIR = process.env.PI_CODING_AGENT_DIR ?? join(homedir(), ".pi", "agent");
|
|
11
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
12
|
+
async function isReadable(path) {
|
|
13
|
+
try {
|
|
14
|
+
await access(path, constants.R_OK);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function stripLeadingHtmlComments(text) {
|
|
22
|
+
// Strip zero or more leading HTML comment blocks (<!-- ... -->) including
|
|
23
|
+
// surrounding whitespace, so the body starts with the actual content.
|
|
24
|
+
return text.replace(/^(\s*<!--[\s\S]*?-->\s*)+/, "");
|
|
25
|
+
}
|
|
26
|
+
// ── Exported API ──────────────────────────────────────────────────────────────
|
|
27
|
+
export async function resolveAgentPath(name) {
|
|
28
|
+
const candidates = [
|
|
29
|
+
join(process.cwd(), ".pi", "agents", `${name}.md`),
|
|
30
|
+
join(PI_AGENT_DIR, "agents", `${name}.md`),
|
|
31
|
+
join(PACKAGE_ROOT, "agents", `${name}.md`),
|
|
32
|
+
];
|
|
33
|
+
for (const candidate of candidates) {
|
|
34
|
+
if (await isReadable(candidate))
|
|
35
|
+
return candidate;
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
export async function loadAgentDef(name) {
|
|
40
|
+
const path = await resolveAgentPath(name);
|
|
41
|
+
if (!path) {
|
|
42
|
+
throw new Error(`Agent "${name}" not found in project, global, or bundled locations`);
|
|
43
|
+
}
|
|
44
|
+
const raw = await readFile(path, "utf8");
|
|
45
|
+
const { frontmatter } = parseFrontmatter(raw);
|
|
46
|
+
const body = stripLeadingHtmlComments(stripFrontmatter(raw));
|
|
47
|
+
return { name, path, frontmatter, body };
|
|
48
|
+
}
|
|
49
|
+
export function toSessionOptions(def) {
|
|
50
|
+
const { frontmatter, body } = def;
|
|
51
|
+
const toolsField = typeof frontmatter.tools === "string" ? frontmatter.tools : undefined;
|
|
52
|
+
const toolsOpt = toolsField === "none"
|
|
53
|
+
? { noTools: "all" }
|
|
54
|
+
: toolsField !== undefined
|
|
55
|
+
? { tools: toolsField.split(",").map((t) => t.trim().toLowerCase()) }
|
|
56
|
+
: {};
|
|
57
|
+
const thinkingLevel = typeof frontmatter.thinking === "string" ? frontmatter.thinking : undefined;
|
|
58
|
+
const modelId = typeof frontmatter.model === "string" ? frontmatter.model : undefined;
|
|
59
|
+
const model = modelId !== undefined ? getModel("anthropic", modelId) : undefined;
|
|
60
|
+
const maxTurns = typeof frontmatter.max_turns === "number" ? frontmatter.max_turns : undefined;
|
|
61
|
+
return {
|
|
62
|
+
...toolsOpt,
|
|
63
|
+
...(model !== undefined && { model }),
|
|
64
|
+
...(thinkingLevel !== undefined && { thinkingLevel }),
|
|
65
|
+
...(maxTurns !== undefined && { maxTurns }),
|
|
66
|
+
systemPrompt: body,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=agent-defs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-defs.js","sourceRoot":"","sources":["../../src/subagents/agent-defs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createAgentSession, SessionManager, } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { loadAgentDef, toSessionOptions } from "./agent-defs.js";
|
|
4
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
5
|
+
// max_turns: 0 means unlimited. When both caller and frontmatter specify a
|
|
6
|
+
// bound, the smaller one wins.
|
|
7
|
+
function stricterTurnLimit(a, b) {
|
|
8
|
+
if (a === 0)
|
|
9
|
+
return b;
|
|
10
|
+
if (b === 0)
|
|
11
|
+
return a;
|
|
12
|
+
return Math.min(a, b);
|
|
13
|
+
}
|
|
14
|
+
// ── Factory ───────────────────────────────────────────────────────────────────
|
|
15
|
+
export function createSubagentManager(pi) {
|
|
16
|
+
const sessions = new Map();
|
|
17
|
+
// ── Internal: run the LLM session for a spawned agent ─────────────────────
|
|
18
|
+
async function runSession(id, args, opts) {
|
|
19
|
+
const record = sessions.get(id);
|
|
20
|
+
let unsub;
|
|
21
|
+
try {
|
|
22
|
+
const { session } = await createAgentSession({
|
|
23
|
+
sessionManager: SessionManager.inMemory(),
|
|
24
|
+
...(opts.model !== undefined && { model: opts.model }),
|
|
25
|
+
...(opts.thinkingLevel !== undefined && { thinkingLevel: opts.thinkingLevel }),
|
|
26
|
+
...(opts.tools !== undefined && { tools: opts.tools }),
|
|
27
|
+
...(opts.noTools !== undefined && { noTools: opts.noTools }),
|
|
28
|
+
});
|
|
29
|
+
record.session = session;
|
|
30
|
+
// If stop() was called while createAgentSession was in-flight, clean up
|
|
31
|
+
// immediately and emit a terminal event so callers observing lifecycle
|
|
32
|
+
// events see a settled state.
|
|
33
|
+
if (record.stopped) {
|
|
34
|
+
await session.abort();
|
|
35
|
+
session.dispose();
|
|
36
|
+
pi.events.emit("subagents:failed", {
|
|
37
|
+
id,
|
|
38
|
+
type: args.type,
|
|
39
|
+
description: args.options?.description ?? "",
|
|
40
|
+
status: "aborted",
|
|
41
|
+
error: "Stopped by caller",
|
|
42
|
+
durationMs: Date.now() - record.startedAt,
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let turnCount = 0;
|
|
47
|
+
const maxTurns = opts.maxTurns ?? 0;
|
|
48
|
+
unsub = session.subscribe((event) => {
|
|
49
|
+
if (event.type === "agent_start") {
|
|
50
|
+
pi.events.emit("subagents:started", {
|
|
51
|
+
id,
|
|
52
|
+
type: args.type,
|
|
53
|
+
description: args.options?.description ?? "",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (event.type === "turn_end") {
|
|
57
|
+
turnCount += 1;
|
|
58
|
+
if (maxTurns > 0 && turnCount >= maxTurns) {
|
|
59
|
+
// Max turns reached — abort to prevent additional LLM calls.
|
|
60
|
+
void session.abort();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (event.type === "agent_end") {
|
|
64
|
+
const result = session.getLastAssistantText();
|
|
65
|
+
const durationMs = Date.now() - record.startedAt;
|
|
66
|
+
// Unsubscribe and dispose in the terminal path so it happens exactly once.
|
|
67
|
+
unsub?.();
|
|
68
|
+
unsub = undefined;
|
|
69
|
+
session.dispose();
|
|
70
|
+
if (record.stopped) {
|
|
71
|
+
pi.events.emit("subagents:failed", {
|
|
72
|
+
id,
|
|
73
|
+
type: args.type,
|
|
74
|
+
description: args.options?.description ?? "",
|
|
75
|
+
status: "aborted",
|
|
76
|
+
error: "Stopped by caller",
|
|
77
|
+
durationMs,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
pi.events.emit("subagents:completed", {
|
|
82
|
+
id,
|
|
83
|
+
type: args.type,
|
|
84
|
+
description: args.options?.description ?? "",
|
|
85
|
+
status: "completed",
|
|
86
|
+
result,
|
|
87
|
+
durationMs,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
// Prepend the agent body as a system-prompt context block before the
|
|
93
|
+
// user prompt. This is the simplest injection path since createAgentSession
|
|
94
|
+
// has no direct systemPrompt option — the agent body is the system prompt.
|
|
95
|
+
const userContent = opts.systemPrompt.trim().length > 0
|
|
96
|
+
? `<system>\n${opts.systemPrompt}\n</system>\n\n${args.prompt}`
|
|
97
|
+
: args.prompt;
|
|
98
|
+
await session.sendUserMessage(userContent);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
unsub?.();
|
|
102
|
+
unsub = undefined;
|
|
103
|
+
const durationMs = Date.now() - record.startedAt;
|
|
104
|
+
pi.events.emit("subagents:failed", {
|
|
105
|
+
id,
|
|
106
|
+
type: args.type,
|
|
107
|
+
description: args.options?.description ?? "",
|
|
108
|
+
status: "failed",
|
|
109
|
+
error: err instanceof Error ? err.message : String(err),
|
|
110
|
+
durationMs,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ── Public API ─────────────────────────────────────────────────────────────
|
|
115
|
+
async function spawn(args) {
|
|
116
|
+
const id = randomUUID();
|
|
117
|
+
// loadAgentDef is async — we await it so errors surface as a rejected
|
|
118
|
+
// spawn promise rather than a silent fire-and-forget failure.
|
|
119
|
+
const def = await loadAgentDef(args.type);
|
|
120
|
+
const opts = toSessionOptions(def);
|
|
121
|
+
const callerMaxTurns = args.options?.max_turns;
|
|
122
|
+
if (callerMaxTurns !== undefined) {
|
|
123
|
+
opts.maxTurns = stricterTurnLimit(callerMaxTurns, opts.maxTurns ?? 0);
|
|
124
|
+
}
|
|
125
|
+
const startedAt = Date.now();
|
|
126
|
+
sessions.set(id, { def, opts, startedAt, stopped: false });
|
|
127
|
+
pi.events.emit("subagents:created", {
|
|
128
|
+
id,
|
|
129
|
+
type: args.type,
|
|
130
|
+
description: args.options?.description ?? "",
|
|
131
|
+
isBackground: true,
|
|
132
|
+
});
|
|
133
|
+
// Run the actual LLM session asynchronously — caller already has the id.
|
|
134
|
+
void runSession(id, args, opts);
|
|
135
|
+
return id;
|
|
136
|
+
}
|
|
137
|
+
async function stop(id) {
|
|
138
|
+
const record = sessions.get(id);
|
|
139
|
+
if (!record)
|
|
140
|
+
return;
|
|
141
|
+
// Guard against double-stop — idempotent.
|
|
142
|
+
if (record.stopped)
|
|
143
|
+
return;
|
|
144
|
+
record.stopped = true;
|
|
145
|
+
// Signal abort. The agent_end handler in the subscriber is responsible for
|
|
146
|
+
// calling dispose() — we don't call it here to avoid a double-dispose race
|
|
147
|
+
// between stop() and the agent_end path.
|
|
148
|
+
if (record.session) {
|
|
149
|
+
await record.session.abort();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function ping() {
|
|
153
|
+
return { version: 2 };
|
|
154
|
+
}
|
|
155
|
+
return { spawn, stop, ping };
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/subagents/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
2
|
+
const reply = (pi, channel, payload) => pi.events.emit(channel, payload);
|
|
3
|
+
const errorMessage = (err) => String(err?.message ?? err);
|
|
4
|
+
// ── RPC registration ──────────────────────────────────────────────────────────
|
|
5
|
+
// Invariant: PI's EventBus ignores handler return values, so async handlers
|
|
6
|
+
// here MUST keep every `await` inside their try/catch — an unhandled rejection
|
|
7
|
+
// would surface only via process-level handlers, not through the RPC reply.
|
|
8
|
+
export function registerSubagentRpc(pi, manager) {
|
|
9
|
+
const unsubPing = pi.events.on("subagents:rpc:ping", (data) => {
|
|
10
|
+
const { requestId } = data;
|
|
11
|
+
reply(pi, `subagents:rpc:ping:reply:${requestId}`, { success: true, data: manager.ping() });
|
|
12
|
+
});
|
|
13
|
+
const unsubSpawn = pi.events.on("subagents:rpc:spawn", async (data) => {
|
|
14
|
+
const { requestId, type, prompt, options } = data;
|
|
15
|
+
const channel = `subagents:rpc:spawn:reply:${requestId}`;
|
|
16
|
+
try {
|
|
17
|
+
const id = await manager.spawn({ type, prompt, options: options });
|
|
18
|
+
reply(pi, channel, { success: true, data: { id } });
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
reply(pi, channel, { success: false, error: errorMessage(err) });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
const unsubStop = pi.events.on("subagents:rpc:stop", async (data) => {
|
|
25
|
+
const { requestId, agentId } = data;
|
|
26
|
+
const channel = `subagents:rpc:stop:reply:${requestId}`;
|
|
27
|
+
try {
|
|
28
|
+
await manager.stop(agentId);
|
|
29
|
+
reply(pi, channel, { success: true });
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
reply(pi, channel, { success: false, error: errorMessage(err) });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return () => {
|
|
36
|
+
unsubPing();
|
|
37
|
+
unsubSpawn();
|
|
38
|
+
unsubStop();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/subagents/rpc.ts"],"names":[],"mappings":"AAQA,iFAAiF;AAEjF,MAAM,KAAK,GAAG,CAAC,EAAgB,EAAE,OAAe,EAAE,OAAc,EAAE,EAAE,CAClE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEnC,MAAM,YAAY,GAAG,CAAC,GAAY,EAAU,EAAE,CAC5C,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,CAAC;AAEzC,iFAAiF;AAEjF,4EAA4E;AAC5E,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,UAAU,mBAAmB,CAAC,EAAgB,EAAE,OAAwB;IAC5E,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,IAAa,EAAE,EAAE;QACrE,MAAM,EAAE,SAAS,EAAE,GAAG,IAA6B,CAAC;QACpD,KAAK,CAAC,EAAE,EAAE,4BAA4B,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,qBAAqB,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC7E,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GACxC,IAA8E,CAAC;QACjF,MAAM,OAAO,GAAG,6BAA6B,SAAS,EAAE,CAAC;QAEzD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAgB,EAAE,CAAC,CAAC;YAC5E,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC3E,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAA8C,CAAC;QAC9E,MAAM,OAAO,GAAG,4BAA4B,SAAS,EAAE,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5B,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
|
package/docs/PI-API.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
> Citation format: `(file:line-range)` — paths abbreviated as `pi-agent/` for
|
|
4
4
|
> `@earendil-works/pi-coding-agent/dist/core/` and `pi-sub/` for
|
|
5
5
|
> `@tintinweb/pi-subagents/src/`.
|
|
6
|
+
>
|
|
7
|
+
> **Note (v0.3+):** pi-rnd no longer depends on `@tintinweb/pi-subagents` — the
|
|
8
|
+
> subagent module was reimplemented in-tree at `src/subagents/` on top of PI's
|
|
9
|
+
> public `createAgentSession` SDK. Sections 2 and 3 (RPC contract, lifecycle
|
|
10
|
+
> events) still describe the exact wire shape the native module preserves, so
|
|
11
|
+
> they remain the protocol spec the implementation honors. `pi-sub/` citations
|
|
12
|
+
> are historical reference for that shape.
|
|
6
13
|
|
|
7
14
|
---
|
|
8
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-rnd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Scientific-method R&D orchestration for PI Coding Agent — methodology skills, subagent definitions, /rnd-start pipeline, /rnd-doctor, and a composable tool_call gate registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,8 +35,7 @@
|
|
|
35
35
|
"subagents"
|
|
36
36
|
],
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
39
|
-
"@tintinweb/pi-subagents": "^0.7.3"
|
|
38
|
+
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
40
39
|
},
|
|
41
40
|
"devDependencies": {
|
|
42
41
|
"@earendil-works/pi-coding-agent": "^0.74.0",
|