pi-open-agents 0.1.14 → 0.1.16

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 CHANGED
@@ -34,6 +34,38 @@ Existing `.agent.md` files work without changes (default `mode: all`).
34
34
 
35
35
  ---
36
36
 
37
+ ## Agents vs subagents (and why you need both)
38
+
39
+ People tend to lump "agents" and "subagents" together. They're not the same
40
+ thing, and the difference is the whole game.
41
+
42
+ An **agent** changes *your* session. Switch to one and the conversation you're
43
+ already having starts thinking with a different brain — different prompt,
44
+ different model, different tools, different rules. The thread keeps going;
45
+ what's running it changes. Planning wants a slow, deliberate mind. Coding wants
46
+ a fast one. Reviewing wants a skeptic. An agent is how you become the right one
47
+ for the moment.
48
+
49
+ A **subagent** never touches your session. It's a separate process you spin up
50
+ for one job — usually on a cheaper, faster model, with locked-down permissions
51
+ — that works in isolation and hands you back an answer. Your context stays
52
+ clean; your main model keeps its focus.
53
+
54
+ The payoff is using both. You sit in an **orchestrator** agent — the strong
55
+ model holding the plan — and delegate the grunt work to subagents: search these
56
+ five hundred files, run that test matrix, draft the boilerplate. One mind to
57
+ think, many hands to do. You get the big model's reasoning *and* the small
58
+ models' speed and economy, without one poisoning the other's context.
59
+
60
+ And the moment you delegate, control stops being optional. A subagent is a real
61
+ process with real tools — it can read your secrets, rewrite your files, run
62
+ shell. So you choose its model, set its thinking level, clip its permissions to
63
+ *read-only* or *git-only*, cap how deep it can recurse, decide who's even
64
+ allowed to spawn whom. That's not red tape. It's what turns *delegate and pray*
65
+ into *delegate and trust* — and it's exactly what this plugin gives you.
66
+
67
+ ---
68
+
37
69
  ## Why this exists
38
70
 
39
71
  Pi splits agent management across two separate plugins — one for primary agents,
@@ -91,8 +123,10 @@ permission:
91
123
  "subagent": deny # no delegation
92
124
  ```
93
125
 
94
- Tool names are normalized automatically: `write` → `edit`, `task` → `subagent`,
95
- `vscode` → `read`.
126
+ Tool names are normalized automatically: `task` → `subagent`, `vscode` → `read`,
127
+ `apply_patch` → `edit` (OpenCode-only tool). In pi, `write` and `edit` are
128
+ **separate** tools — `write` creates/overwrites files, `edit` does search-and-
129
+ replace — so they have separate permission categories.
96
130
 
97
131
  ### Auto-injected delegation guidance
98
132
 
@@ -118,6 +152,11 @@ This means:
118
152
  - Each subagent runs with exactly the model and tools it declares
119
153
  - Skills load per-agent, with wildcard support (`security-*`, `git-*`)
120
154
 
155
+ The `--tools` whitelist is derived from both explicit `tools:` arrays and
156
+ permission allow-lists. An agent with `permission: { read: allow, edit: allow }`
157
+ will only get `read` and `edit` in the child process. Wildcard permissions
158
+ (`*: allow`) cannot produce a finite whitelist — the child gets all tools.
159
+
121
160
  ### OpenCode compatibility
122
161
 
123
162
  Your `.opencode/agent/` files work as-is. The `tools` map format is auto-converted
@@ -133,6 +172,10 @@ tools:
133
172
  bash: false
134
173
  ```
135
174
 
175
+ The `tools` map is converted to permission rules and **also restricts the
176
+ subagent child process** — a subagent with `tools: { read: true, bash: false }`
177
+ will only have access to the `read` tool when spawned.
178
+
136
179
  ### Mode-based visibility
137
180
 
138
181
  | `mode` | TUI selector | `subagent` tool | `set_agent` tool |
@@ -249,9 +292,12 @@ Optional cleanup:
249
292
 
250
293
  ## Development
251
294
 
295
+ **Contributing?** Please read the [Contributing Guide](./CONTRIBUTING.md) before
296
+ opening an issue or pull request.
297
+
252
298
  ```bash
253
299
  npm install
254
- npm test # 84 tests
300
+ npm test # 117 tests
255
301
  npm run typecheck # tsc --noEmit
256
302
  ```
257
303
 
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: explorer
3
+ mode: subagent
4
+ description: Dedicated investigation and reconnaissance agent for codebases, remote systems, REST APIs, and log sources. Returns structured, dense findings ready for direct use by the calling agent.
5
+ # tools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'web', 'todo']
6
+ ---
7
+
8
+ You are an investigation agent. You explore codebases, remote systems, REST APIs, and log sources, then return precise, structured findings.
9
+
10
+ ## Scope
11
+
12
+ | Domain | Examples |
13
+ |--------|----------|
14
+ | **Codebases** | Directory trees, file contents, dependency graphs, architecture, call chains |
15
+ | **Remote systems** | SSH commands, cluster inspections, process lists, service status |
16
+ | **REST APIs** | Endpoint discovery, request/response probing, auth flows, error patterns |
17
+ | **Log sources** | Log files, journalctl, container logs, structured JSON logs, error correlation |
18
+
19
+ ## Principles
20
+
21
+ 1. **Answer the question, nothing else.** The calling agent gave you a specific task — deliver exactly what was asked.
22
+ 2. **Be precise.** File paths, line numbers, exact values, command output. No vagueness.
23
+ 3. **Be dense.** Strip filler. Every line in your response should carry information the caller needs.
24
+ 4. **Show evidence.** Quote relevant code, paste relevant output. The caller should not need to re-verify.
25
+ 5. **Structure the answer.** Use headings, tables, bullet lists — make it scannable. Start with a one-line TL;DR when the answer is complex.
26
+
27
+ ## Investigation Method
28
+
29
+ Adapt to the target. Do not follow a rigid checklist.
30
+
31
+ For **codebases**: identify entry points, trace the relevant path, report what you found and where.
32
+ For **remote systems**: run targeted commands, report exact output, flag anything unexpected.
33
+ For **APIs**: probe endpoints, capture status codes and response shapes, document the contract.
34
+ For **logs**: filter to the relevant window/level, correlate events, report patterns and anomalies.
35
+
36
+ If the task is broad ("explore this repo"), give a high-level architecture overview. If the task is specific ("how does auth work in module X"), trace the exact flow end-to-end.
37
+
38
+ ## Output Contract
39
+
40
+ Your response is the only thing the calling agent sees. It must be:
41
+ - **Self-contained** — no "you should also check…"; if something is relevant, include it now
42
+ - **Actionable** — the caller can make decisions from your answer without further exploration
43
+ - **Compact** — no preamble, no summary-of-what-you-did; just the findings
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-open-agents",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Unified agent and subagent management for pi coding agent, with OpenCode-compatible agent definitions.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -30,7 +30,8 @@
30
30
  "src/",
31
31
  "README.md",
32
32
  "LICENSE",
33
- "ATTRIBUTION.md"
33
+ "ATTRIBUTION.md",
34
+ "agents/"
34
35
  ],
35
36
  "scripts": {
36
37
  "typecheck": "tsc --noEmit",
@@ -64,6 +65,7 @@
64
65
  "devDependencies": {
65
66
  "@types/node": "^24.0.0",
66
67
  "tsx": "^4.19.0",
68
+ "typebox": "^1.3.10",
67
69
  "typescript": "^5.6.0"
68
70
  }
69
71
  }
package/src/tui/tools.ts CHANGED
@@ -14,6 +14,7 @@ import { Type } from "typebox";
14
14
  import type { AgentDefinition } from "../types.ts";
15
15
  import { selectableAgents } from "../discovery/loader.ts";
16
16
  import type { AgentManager } from "../primary/manager.ts";
17
+ import { isSubagentProcess } from "../subagent/env.ts";
17
18
  import { updateBanner } from "./banner.ts";
18
19
 
19
20
  /**
@@ -32,6 +33,10 @@ export function registerAgentTools(manager: AgentManager, pi: ExtensionAPI): voi
32
33
  reason: Type.Optional(Type.String({ description: "Reason for switching agents" })),
33
34
  }),
34
35
  async execute(_toolCallId, params, _signal, _onUpdate, ctx: ExtensionContext) {
36
+ if (isSubagentProcess(process.env)) {
37
+ throw new Error("set_agent is only available to the primary agent, not subagents.");
38
+ }
39
+
35
40
  const { agent: name, reason } = params;
36
41
 
37
42
  const agent = manager.getAgent(name);
@@ -40,6 +45,10 @@ export function registerAgentTools(manager: AgentManager, pi: ExtensionAPI): voi
40
45
  throw new Error(`Unknown agent "${name}". Available: ${available}`);
41
46
  }
42
47
 
48
+ if (agent.mode === "subagent") {
49
+ throw new Error(`Agent "${name}" is a subagent and cannot be set as the primary agent.`);
50
+ }
51
+
43
52
  const success = await manager.apply(name, pi, ctx);
44
53
  if (!success) {
45
54
  throw new Error(`Failed to apply agent "${name}"`);