@pi-unipi/unipi 2.6.4 → 2.7.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.
Files changed (49) hide show
  1. package/package.json +16 -11
  2. package/packages/autocomplete/src/constants.ts +5 -0
  3. package/packages/subagents/README.md +89 -78
  4. package/packages/subagents/package.json +8 -2
  5. package/packages/subagents/skills/council-mode/SKILL.md +230 -0
  6. package/packages/subagents/skills/subagents/SKILL.md +49 -0
  7. package/packages/subagents/skills/subagents/references/constraints-and-recipes.md +259 -0
  8. package/packages/subagents/skills/subagents/references/execution-controls.md +454 -0
  9. package/packages/subagents/skills/subagents/references/management-authoring-rpc.md +161 -0
  10. package/packages/subagents/skills/subagents/references/multi-lane-orchestration.md +39 -0
  11. package/packages/subagents/skills/subagents/references/prompting-and-roles.md +267 -0
  12. package/packages/subagents/src/acceptance.ts +331 -0
  13. package/packages/subagents/src/agent-manager.ts +89 -6
  14. package/packages/subagents/src/agent-memory.ts +300 -0
  15. package/packages/subagents/src/agent-overrides.ts +183 -0
  16. package/packages/subagents/src/agent-runner.ts +10 -0
  17. package/packages/subagents/src/async-runner.ts +417 -0
  18. package/packages/subagents/src/authority-policy.ts +47 -0
  19. package/packages/subagents/src/budgets.ts +285 -0
  20. package/packages/subagents/src/child-safety.ts +140 -0
  21. package/packages/subagents/src/config.ts +80 -1
  22. package/packages/subagents/src/custom-agents.ts +236 -38
  23. package/packages/subagents/src/file-system-retry.ts +50 -0
  24. package/packages/subagents/src/fleet-data.ts +61 -0
  25. package/packages/subagents/src/fleet-view.ts +316 -0
  26. package/packages/subagents/src/foreground-detach.ts +59 -0
  27. package/packages/subagents/src/fork-context.ts +285 -0
  28. package/packages/subagents/src/guide.ts +129 -0
  29. package/packages/subagents/src/index.ts +515 -197
  30. package/packages/subagents/src/mission-state.ts +133 -0
  31. package/packages/subagents/src/mission-store.ts +434 -0
  32. package/packages/subagents/src/output-limits.ts +142 -0
  33. package/packages/subagents/src/parity-types.ts +315 -0
  34. package/packages/subagents/src/pi-args.ts +161 -0
  35. package/packages/subagents/src/pi-spawn.ts +147 -0
  36. package/packages/subagents/src/result-files.ts +232 -0
  37. package/packages/subagents/src/result-watcher.ts +221 -0
  38. package/packages/subagents/src/retained-children.ts +176 -0
  39. package/packages/subagents/src/run-fanout-budget.ts +356 -0
  40. package/packages/subagents/src/scheduled-runs.ts +351 -0
  41. package/packages/subagents/src/schemas.ts +263 -0
  42. package/packages/subagents/src/slash-commands.ts +77 -0
  43. package/packages/subagents/src/supervisor-channel.ts +249 -0
  44. package/packages/subagents/src/tool-handler.ts +1144 -0
  45. package/packages/subagents/src/types.ts +103 -2
  46. package/packages/subagents/src/workflow-script.ts +737 -0
  47. package/packages/subagents/src/workflow-worker.ts +384 -0
  48. package/packages/subagents/src/worktree.ts +614 -0
  49. package/packages/unipi/bundled.js +6577 -1093
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/unipi",
3
- "version": "2.6.4",
3
+ "version": "2.7.0",
4
4
  "description": "All-in-one extension suite for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -66,7 +66,11 @@
66
66
  "packages/milestone/skills",
67
67
  "packages/kanboard/skills",
68
68
  "packages/updater/skills",
69
- "packages/image/skills"
69
+ "packages/image/skills",
70
+ "packages/subagents/skills"
71
+ ],
72
+ "prompts": [
73
+ "packages/subagents/prompts"
70
74
  ]
71
75
  },
72
76
  "peerDependencies": {
@@ -78,30 +82,31 @@
78
82
  "dependencies": {
79
83
  "@pi-unipi/ask-user": "2.6.1",
80
84
  "@pi-unipi/btw": "2.6.1",
81
- "@pi-unipi/compactor": "2.6.1",
82
- "@pi-unipi/notify": "2.6.1",
83
85
  "@pi-unipi/command-enchantment": "2.6.1",
86
+ "@pi-unipi/compactor": "2.6.1",
84
87
  "@pi-unipi/core": "2.6.1",
88
+ "@pi-unipi/footer": "2.6.1",
89
+ "@pi-unipi/image": "2.6.1",
85
90
  "@pi-unipi/info-screen": "2.6.1",
91
+ "@pi-unipi/input-shortcuts": "2.6.1",
92
+ "@pi-unipi/kanboard": "2.6.1",
86
93
  "@pi-unipi/mcp": "2.6.1",
87
94
  "@pi-unipi/memory": "2.6.1",
95
+ "@pi-unipi/milestone": "2.6.1",
96
+ "@pi-unipi/notify": "2.6.1",
88
97
  "@pi-unipi/ralph": "2.6.1",
89
98
  "@pi-unipi/subagents": "2.6.1",
99
+ "@pi-unipi/updater": "2.6.1",
90
100
  "@pi-unipi/utility": "2.6.1",
91
- "@pi-unipi/milestone": "2.6.1",
92
- "@pi-unipi/kanboard": "2.6.1",
93
101
  "@pi-unipi/web-api": "2.6.1",
94
- "@pi-unipi/workflow": "2.6.1",
95
- "@pi-unipi/footer": "2.6.1",
96
- "@pi-unipi/updater": "2.6.1",
97
- "@pi-unipi/input-shortcuts": "2.6.1",
98
- "@pi-unipi/image": "2.6.1"
102
+ "@pi-unipi/workflow": "2.6.1"
99
103
  },
100
104
  "devDependencies": {
101
105
  "@earendil-works/pi-agent-core": "^0.80.0",
102
106
  "@earendil-works/pi-ai": "^0.80.0",
103
107
  "@earendil-works/pi-coding-agent": "^0.80.0",
104
108
  "@earendil-works/pi-tui": "^0.80.0",
109
+ "@types/better-sqlite3": "^9.6.0",
105
110
  "@types/node": "^25.6.0",
106
111
  "diff": "^7.0.0",
107
112
  "esbuild": "^0.27.7",
@@ -129,6 +129,11 @@ export const COMMAND_REGISTRY: Record<string, string> = {
129
129
  // ask-user (1 command)
130
130
  "unipi:ask-user-settings": "ask-user",
131
131
 
132
+ // subagents (3 commands)
133
+ "unipi:subagents-fleet": "subagents",
134
+ "unipi:subagents-doctor": "subagents",
135
+ "unipi:subagents-guide": "subagents",
136
+
132
137
  // info (2 commands)
133
138
  "unipi:info": "info",
134
139
  "unipi:info-settings": "info",
@@ -1,110 +1,121 @@
1
1
  # @pi-unipi/subagents
2
2
 
3
- Parallel execution with file locking. Spawn background or foreground agents to work on tasks concurrently research files, fix lint errors, run tests while the main agent keeps going.
4
-
5
- Two built-in agent types: `explore` for read-only research, `work` for file modifications with transparent locking. Define your own types as markdown files.
6
-
7
- ## Commands
8
-
9
- Subagents has no user commands. It's an agent tool package — the agent calls it directly.
10
-
11
- ## Special Triggers
12
-
13
- Workflow skills detect subagents and inject parallel strategies. When `@pi-unipi/subagents` is installed, these skills get enhanced:
14
-
15
- | Skill | What Changes |
16
- |-------|--------------|
17
- | `brainstorm` | Parallel research for different approaches |
18
- | `document` | Parallel documentation of different modules |
19
- | `gather-context` | Parallel codebase exploration |
20
- | `review-work` | Parallel task verification |
21
- | `scan-issues` | Parallel scanning by category |
22
- | `work` | Parallel task execution (with file locking) |
3
+ Delegate work to focused child agents — in parallel, in the background, or as scripted multi-agent workflows. Feature parity with [pi-subagents](https://github.com/nicobailon/pi-subagents), built on unipi conventions: foreground children run in-process (live widget streaming), background/fork/resume/worktree runs use child `pi` processes.
4
+
5
+ ## Agents
6
+
7
+ Built-in agents (lowest discovery priority — user/project definitions override):
8
+
9
+ | Agent | Use it for |
10
+ |-------|------------|
11
+ | `explore` | Read-only file research and parallel reads |
12
+ | `work` | File modifications with transparent locking |
13
+ | `scout` | Fast codebase recon: entry points, data flow, risks |
14
+ | `researcher` | Web research with sources (`web_search`, `multi_web_content_read`) |
15
+ | `worker` | Implementation: narrow edits, validation, escalation |
16
+ | `reviewer` | Code review of diffs, plans, solutions |
17
+ | `oracle` | Second opinion; challenges assumptions without editing |
18
+ | `delegate` | Lightweight general delegate close to the parent session |
19
+
20
+ Custom agents are markdown files with YAML frontmatter:
21
+
22
+ ```markdown
23
+ ---
24
+ name: security-reviewer
25
+ description: Security-focused review
26
+ tools: read, grep, find
27
+ thinking: high
28
+ memory: { scope: "project", path: "security-reviewer" }
29
+ ---
30
+
31
+ Review changes for unsafe input handling...
32
+ ```
23
33
 
24
- Subagents registers with the info-screen dashboard, showing active agents and their status. The footer displays agent activity in its extension status segment.
34
+ Discovery: project `.unipi/config/agents/` > global `~/.unipi/config/agents/` > builtins. Aliases resolve (`developer` `worker`, `advisor` `oracle`). Per-agent overrides live in `subagents.json`.
25
35
 
26
- ## Agent Tools
36
+ ## Tools
27
37
 
28
38
  | Tool | Description |
29
39
  |------|-------------|
30
- | `spawn_helper` | Launch a sub-agent for parallel work |
31
- | `get_helper_result` | Check status and retrieve results from a background agent |
32
-
33
- ### spawn_helper Parameters
34
-
35
- | Parameter | Description |
36
- |-----------|-------------|
37
- | `type` | Agent type (`explore`, `work`, or custom) |
38
- | `prompt` | Task for the agent |
39
- | `description` | Short description (3-5 words) |
40
- | `run_in_background` | Return immediately, notify on completion |
41
- | `max_turns` | Max agentic turns before stopping |
42
- | `model` | Model override (e.g. `"haiku"`, `"sonnet"`) |
43
- | `thinking` | Thinking level (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`) |
40
+ | `spawn_helper` | Launch agents: single child, `workflowScript` orchestration, or management `action`s |
41
+ | `get_helper_result` | Wait on / inspect background runs; `nonBlocking` wake subscriptions |
44
42
 
45
- ### Foreground (blocks until done)
43
+ ### Single child
46
44
 
47
45
  ```
48
- spawn_helper(
49
- type: "explore",
50
- prompt: "Find all auth-related files",
51
- description: "Research auth files"
52
- )
46
+ spawn_helper({ agent: "scout", task: "Analyze the auth flow" })
47
+ spawn_helper({ agent: "worker", task: "Implement it", run_in_background: true })
48
+ spawn_helper({ agent: "reviewer", task: "Review", gate: "npm test" })
53
49
  ```
54
50
 
55
- ### Background (returns immediately)
51
+ Legacy aliases (`type`, `prompt`, `max_turns`) still work.
56
52
 
53
+ ### Scripted workflows
54
+
55
+ ```js
56
+ spawn_helper({ workflowScript: `
57
+ const scan = await runs.run("scan", { agent: "scout", task: "Analyze auth" });
58
+ const reviews = await runs.all([
59
+ { key: "correctness", agent: "reviewer", task: "Review correctness: " + scan.output },
60
+ { key: "tests", agent: "reviewer", task: "Review tests: " + scan.output }
61
+ ]);
62
+ return reviews.map(r => r.output);
63
+ `, async: false })
57
64
  ```
58
- spawn_helper(
59
- type: "work",
60
- prompt: "Fix all lint errors in src/",
61
- description: "Fix lint errors",
62
- run_in_background: true
63
- )
64
- ```
65
65
 
66
- ### Check Background Result
66
+ `runs.run` / `runs.all` / `runs.steer` inside a sandboxed VM. Budgets (`turnBudget`, `toolBudget`, `usageBudget`), worktree isolation, fork context, and acceptance gates available per child.
67
+
68
+ ### Management actions
67
69
 
68
70
  ```
69
- get_helper_result(agent_id: "helper_abc123")
71
+ spawn_helper({ action: "list" | "get" | "status" | "children.list" })
72
+ spawn_helper({ action: "resume", id: "<run>", message: "Reconsider X" })
73
+ spawn_helper({ action: "doctor" | "guide", topic: "workflows" })
74
+ spawn_helper({ action: "mission.create", mission: { title, objective } })
75
+ spawn_helper({ action: "schedule.create", name, agent, task, every: "30m" })
70
76
  ```
71
77
 
72
- Foreground and retrieved background results have a hard 64 KiB model-visible ceiling. For raw results up to 16 MiB, larger output includes a bounded head/tail preview and a path to the complete private mode-0600 artifact under a mode-0700 `~/.unipi/tool-results/` directory. Use `read` with offset/limit to inspect only the needed region. Repeated retrieval reuses the same artifact. Results above the safety cap or artifact-write failures still return a preview with an explicit non-retention warning.
73
-
74
- ## Custom Agent Types
75
-
76
- Create markdown files defining agent behavior:
78
+ ## Observability
77
79
 
78
- ```bash
79
- # Global agents
80
- ~/.unipi/config/agents/reviewer.md
80
+ - **FleetView** panel: active work from both transports. `↓` to inspect, `j/k` navigate, `enter` opens transcripts, `esc` closes.
81
+ - **`/unipi:subagents-fleet`** · **`/unipi:subagents-doctor`** · **`/unipi:subagents-guide [topic]`**
82
+ - Background completions arrive as `<task-notification>` follow-ups automatically.
83
+ - Supervisor channel: blocked children can `contact_supervisor` for decisions.
81
84
 
82
- # Project agents
83
- <workspace>/.unipi/config/agents/deployer.md
84
- ```
85
+ ## Configuration
85
86
 
86
- ## Configurables
87
+ `~/.unipi/config/subagents.json` (global) + `<workspace>/.unipi/config/subagents.json`:
87
88
 
88
89
  ```json
89
- // ~/.unipi/config/subagents.json
90
90
  {
91
- "enabled": true,
92
- "maxConcurrent": 3,
93
- "types": {
94
- "explore": { "enabled": true },
95
- "work": { "enabled": true }
91
+ "subagents": {
92
+ "defaultModel": "ds/deepseek-v4-flash",
93
+ "asyncByDefault": true,
94
+ "maxSubagentSpawnsPerRun": 64,
95
+ "fleetViewPlacement": "belowEditor"
96
96
  }
97
97
  }
98
98
  ```
99
99
 
100
- | Setting | Default | What It Does |
101
- |---------|---------|--------------|
102
- | `enabled` | true | Enable/disable subagents |
103
- | `maxConcurrent` | 3 | Max agents running at once |
104
- | `types.{name}.enabled` | true | Disable built-in or custom agent types. Disabled types are omitted from tool guidance and rejected before queueing. |
100
+ Full key reference: `spawn_helper({ action: "guide", topic: "configuration" })`. Env overrides use the `UNIPI_SUBAGENT_*` prefix.
101
+
102
+ ## Storage
103
+
104
+ | Path | Contents |
105
+ |------|----------|
106
+ | `~/.unipi/missions/<project-hash>/` | Durable mission records |
107
+ | `~/.unipi/schedules/<project-hash>/` | Scheduled runs |
108
+ | `~/.unipi/agent-memory/` | Per-agent persistent memory |
109
+ | temp root (`unipi-subagents-*`) | Run artifacts, results, channels (auto-cleaned) |
110
+
111
+ ## Commands
105
112
 
106
- For custom agents, JSON configuration and Markdown frontmatter are both enforced: the type can run only when neither source sets `enabled: false`. Configuration is loaded when the extension starts, so reload the session after changing enablement.
113
+ | Command | Description |
114
+ |---------|-------------|
115
+ | `/unipi:subagents-fleet` | Show active fleet |
116
+ | `/unipi:subagents-doctor` | Config + capacity diagnosis |
117
+ | `/unipi:subagents-guide [topic]` | Bundled guide |
107
118
 
108
- ## License
119
+ ## Prompt shortcuts
109
120
 
110
- MIT
121
+ `/council`, `/parallel-review`, `/review-loop`, `/parallel-research`, `/gather-context-and-clarify`, `/parallel-cleanup` — packaged prompt templates for common orchestration patterns.
@@ -10,7 +10,8 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@pi-unipi/core": "2.6.1",
13
- "@earendil-works/pi-agent-core": "^0.80.0"
13
+ "@earendil-works/pi-agent-core": "^0.80.0",
14
+ "acorn": "8.18.0"
14
15
  },
15
16
  "devDependencies": {
16
17
  "typescript": "^5.8.3"
@@ -23,13 +24,18 @@
23
24
  "files": [
24
25
  "src/**/*.ts",
25
26
  "src/global.d.ts",
27
+ "agents/*.md",
28
+ "prompts/*.md",
29
+ "skills/**/*",
26
30
  "README.md"
27
31
  ],
28
32
  "pi": {
29
33
  "extensions": [
30
34
  "./src/index.ts"
31
35
  ],
32
- "skills": [],
36
+ "skills": [
37
+ "./skills"
38
+ ],
33
39
  "prompts": [],
34
40
  "themes": []
35
41
  }
@@ -0,0 +1,230 @@
1
+ ---
2
+ name: council-mode
3
+ description: Run a bounded supervisor-mediated advisor council. Use when the user asks for council mode, asks to convene advisors, debate a decision, cross-examine recommendations, or run /council.
4
+ ---
5
+
6
+ # Council Mode
7
+
8
+ This skill is for the parent supervisor only. Do not inject it into advisors. The
9
+ parent selects the roster, curates all cross-advisor communication, decides which
10
+ feedback is valid, and writes the decision memo. Advisors do not talk directly or
11
+ see peer transcripts by default. This is not free-form agent chat.
12
+
13
+ Use council mode for a material decision with real tradeoffs. Do not use it for a
14
+ trivial or settled question, or for implementation work. Read
15
+ `skills/pi-subagents/references/execution-controls.md` before you launch advisors.
16
+
17
+ ## Roster and limits
18
+
19
+ Roles such as architect, skeptic, operator, and performance reviewer belong to the
20
+ `/council` request. A `council-*` profile defines only model, tools, context, and
21
+ output defaults. Its profile configuration or explicit invocation owns its context
22
+ choice.
23
+
24
+ Create model-based profiles in your user or project agent directory. Do not add
25
+ them to this package. This is a valid example; roles still come from `/council`:
26
+
27
+ ```markdown
28
+ ---
29
+ name: council-sol
30
+ description: Read-only fresh-context advisor for bounded council decisions
31
+ tools: read, grep, find, ls
32
+ model: openai-codex/gpt-5.6-sol
33
+ thinking: high
34
+ systemPromptMode: replace
35
+ inheritProjectContext: true
36
+ inheritSkills: false
37
+ defaultContext: fresh
38
+ acceptanceRole: read-only
39
+ ---
40
+
41
+ Analyze only the assigned council role. Inspect evidence directly. Do not edit,
42
+ run mutating commands, commit, push, contact peers, or spawn subagents. Return
43
+ concise, cited advice using the report contract in the council task.
44
+ ```
45
+
46
+ After `spawn_helper({ action: "list" })`, prefer 2–3 executable names that start with
47
+ `council-`. The prefix is a naming convention, not runtime selection. If fewer
48
+ than two profiles are available, fill the roster with `oracle`, then `reviewer`,
49
+ until it has two advisors. Launch fallback `oracle` with `context: "fork"` so
50
+ global defaults cannot remove its parent-chat context. Let fallback `reviewer`
51
+ use its normal profile context. Note the fallback and known context modes in the
52
+ memo. Use the normal single-oracle consultation loop only when a requested roster
53
+ or unavailable builtins leaves fewer than two advisors.
54
+ Label that result as degraded mode. Never use more than four advisors.
55
+
56
+ Pass 1 is independent reports. Pass 2 is one cross-exam. The default pass cap is
57
+ 2. Run pass 3 only when `--max-passes 3` was requested and a material dispute can
58
+ be settled by evidence an advisor can produce. Never run an unbounded loop.
59
+
60
+ ## Protocol
61
+
62
+ 1. The parent writes a brief with the question, scope, non-goals, evidence targets,
63
+ roster, roles, and pass cap.
64
+ 2. Before Pass 1, tell the user the roster, roles, requested or known context
65
+ modes, and pass cap. Use a stable key, `phase`, and concise `label` for every
66
+ workflow child. For example, use `advisor-oracle`, `phase: "Council pass 1"`,
67
+ and `label: "Oracle — intent and consistency"`.
68
+ 3. Launch one async `workflowScript` with `runs.all` for independent advisor
69
+ reports. Set `context` when the selected advisor has a known profile context or
70
+ a fallback rule requests one, because a global default can otherwise override
71
+ that profile. Set `context: "fork"` for fallback `oracle`. If no advisor context
72
+ is known, omit `context` and disclose the unknown runtime default in the memo.
73
+ Each advisor is read-only and must not spawn children, edit files, run mutating
74
+ commands, commit, or push. Set `output: false` unless separate advisor artifacts
75
+ are explicitly requested or useful for the decision.
76
+ 4. Return one aggregate Pass 1 receipt. After it completes, tell the user the
77
+ completion count, agreement count, dispute count, and whether Pass 2 is needed.
78
+ 5. The parent synthesizes a claim matrix in session. It contains agreements,
79
+ disputed claims, missing proof, owner decisions, and a relay set of at most five
80
+ high-impact claims per advisor. Do not delegate this synthesis.
81
+ 6. Before Pass 2, tell the user how many claims are relayed and why each is
82
+ material. Launch a second async `workflowScript` with `runs.all` resume calls.
83
+ Each task is a curated challenge packet, not a peer transcript. A resume requires
84
+ a retained run id and a non-empty task. It excludes `agent` and rejects `gate`.
85
+ Record the new run id from every resume. Pass 3 resumes those latest ids. Return
86
+ one aggregate Pass 2 receipt.
87
+ 7. After Pass 2, tell the user whether the council converged or which owner
88
+ decisions remain. The parent writes the final memo. Do not delegate it.
89
+
90
+ If an advisor is not resumable, run the same profile in fresh context with its own
91
+ pass-1 report and the challenge packet. Label that response as a fresh-context
92
+ fallback, not a true cross-exam.
93
+
94
+ Do not set `clarify`, `worktree`, `gate`, turn budgets, tool budgets, or tight usage
95
+ budgets on advisors. Bound work through the roster, pass cap, and report length.
96
+
97
+ ## Advisor contracts and pass receipts
98
+
99
+ Pass-1 reports are at most about 600 words. Give each advisor the same
100
+ `outputSchema`, so reports are comparable without heading cleanup. The following
101
+ shape is a contract template. Use the runtime schema syntax supported by the
102
+ workflow and keep narrative fields as strings:
103
+
104
+ ```js
105
+ const pass1OutputSchema = {
106
+ type: "object",
107
+ required: [
108
+ "recommendation", "evidence", "assumptions", "risks", "confidence",
109
+ "challengeClaims", "ownerDecisions", "changeMyMind"
110
+ ],
111
+ properties: {
112
+ recommendation: { type: "string" },
113
+ evidence: {
114
+ type: "array",
115
+ items: {
116
+ type: "object",
117
+ required: ["claim", "sources"],
118
+ properties: {
119
+ claim: { type: "string" },
120
+ sources: { type: "array", items: { type: "string" } }
121
+ }
122
+ }
123
+ },
124
+ assumptions: {
125
+ type: "array",
126
+ items: {
127
+ type: "object",
128
+ required: ["assumption", "status"],
129
+ properties: {
130
+ assumption: { type: "string" },
131
+ status: { enum: ["verified", "unverified"] }
132
+ }
133
+ }
134
+ },
135
+ risks: { type: "array", items: { type: "string" } },
136
+ confidence: {
137
+ type: "object",
138
+ required: ["level", "reason"],
139
+ properties: {
140
+ level: { enum: ["high", "medium", "low"] },
141
+ reason: { type: "string" }
142
+ }
143
+ },
144
+ challengeClaims: { type: "array", items: { type: "string" }, maxItems: 3 },
145
+ ownerDecisions: { type: "array", items: { type: "string" } },
146
+ changeMyMind: { type: "array", items: { type: "string" } }
147
+ }
148
+ };
149
+ ```
150
+
151
+ Include this contract in each Pass 1 task: inspect supplied evidence directly; do
152
+ not see or ask about other advisors; stay read-only; do not spawn children; return
153
+ only the structured report.
154
+
155
+ After `runs.all`, return one aggregate receipt rather than making the parent find
156
+ separate artifacts. Preserve the result order or map it by stable key so each row
157
+ contains the advisor identity and report:
158
+
159
+ ```js
160
+ return {
161
+ pass: 1,
162
+ advisors: results.map((result, index) => ({
163
+ key: result.key,
164
+ agent: result.agent,
165
+ role: roster[index].role,
166
+ requestedContext: roster[index].context ?? "runtime-default-unknown",
167
+ runId: result.runId,
168
+ report: result.structuredOutput
169
+ }))
170
+ };
171
+ ```
172
+
173
+ Do not replace `runtime-default-unknown` with a guessed context. It records that
174
+ the launch intentionally omitted context.
175
+
176
+ A challenge packet contains only disputed claims, strong conflicting evidence,
177
+ missing proof, owner decisions, and high-impact risks. Attribute peer content as
178
+ "another advisor". Do not include full peer reports. Use a common Pass 2 contract:
179
+
180
+ ```js
181
+ const pass2OutputSchema = {
182
+ type: "object",
183
+ required: ["responses", "recommendationChanged", "outOfScopeFindings"],
184
+ properties: {
185
+ responses: {
186
+ type: "array",
187
+ items: {
188
+ type: "object",
189
+ required: ["claimId", "disposition", "reason", "sources"],
190
+ properties: {
191
+ claimId: { type: "string" },
192
+ disposition: {
193
+ enum: ["accept", "reject", "refine", "owner-decision"]
194
+ },
195
+ reason: { type: "string" },
196
+ sources: { type: "array", items: { type: "string" } }
197
+ }
198
+ }
199
+ },
200
+ recommendationChanged: {
201
+ type: "object",
202
+ required: ["changed", "reason"],
203
+ properties: { changed: { type: "boolean" }, reason: { type: "string" } }
204
+ },
205
+ outOfScopeFindings: { type: "array", items: { type: "string" } }
206
+ }
207
+ };
208
+ ```
209
+
210
+ Use stable resume keys such as `cross-oracle`, `phase: "Council pass 2"`, concise
211
+ labels, and `output: false` unless separate artifacts are requested or useful. The
212
+ aggregate Pass 2 receipt uses the same row shape as Pass 1, with the new `runId`
213
+ and `structuredOutput`.
214
+
215
+ ## Stop and memo
216
+
217
+ Converged means no disputed claim remains that both materially affects the
218
+ recommendation and can plausibly be settled by evidence. Stop at convergence, the
219
+ pass cap, failed fallback, or user interruption. Put unresolved disputes in owner
220
+ decisions. Never add a round for polish or symmetry.
221
+
222
+ The parent memo states the question and scope, recommendation, rationale, accepted
223
+ and rejected feedback with reasons, owner decisions, evidence and run ids,
224
+ confidence, what would change the decision, and the roster, roles, passes,
225
+ fallbacks, and known advisor context modes. State that fallback `oracle` is
226
+ context-aware and forked.
227
+
228
+ Council mode is not agent-to-agent chat, a transcript dump, mutation authority,
229
+ auto-escalation to writer lanes, or a council UI. Escalate to a writer only after
230
+ the parent memo and only when the user explicitly requests it.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: unipi subagents
3
+ description: |
4
+ Delegate work to builtin or custom subagents with single-agent, parallel,
5
+ scripted-chaining, async, forked-context, and coordinated workflows. Use
6
+ for advisory review, implementation handoffs, and multi-step tasks where a
7
+ single agent should stay in control while other agents contribute context,
8
+ planning, or execution.
9
+ ---
10
+
11
+ # Pi Subagents
12
+
13
+ This skill is for the main parent orchestrator only. Do not inject or follow it inside spawned child subagents. The parent session owns delegation, orchestration, review fanout, and final fix-worker launches. Ordinary children should not run their own subagent workflows; the explicit exception is a delegated fanout child whose resolved builtin `tools` includes `subagent`, and that child may use `subagent` only for the fanout work the parent assigned.
14
+
15
+ Use this skill when the parent orchestrator needs one specialized child or composed orchestration. Use `workflowScript` for all execution, including one isolated child. Chaining is still supported, but it is code-driven: use `await runs.run(...)` for sequential steps, `runs.all([...])` for parallel fanout, and ordinary JavaScript for branching, retries, gate monitors, and aggregation. Keep workflow helpers portable: use plain helper functions or explicit Promise chains, not nested `async function` helpers, async arrows, or async methods. Do not use legacy top-level `chain` / `tasks` inputs or durable `.chain.md` execution. Scripted workflows normally start asynchronously unless config sets `asyncByDefault:false`; set `async:true` explicitly when async behavior matters. Pass `async:false` only when the parent must block until completion. Async mode still shows progress. Do not use `async:false` for final reviews, backlog gates, run-to-completion convenience, or because no other work is available.
16
+
17
+ Package-installed agents appear in `spawn_helper({ action: "list" })` with builtin, user, and project agents. If `surf-cli` is installed as a Pi package, the Surf browser extension is loaded, and Chrome is logged into a ChatGPT Pro account, Surf can expose `gpt-pro`: a read-only async advisor that reaches ChatGPT web through Surf Oracle. Check it with `spawn_helper({ action: "get", agent: "gpt-pro" })` and run it with `subagent({ agent: "gpt-pro", task: "Review this plan and identify release risks." })`.
18
+
19
+ ## How to use this router
20
+
21
+ Read the matching reference file before acting. Paths are relative to this `SKILL.md`; resolve them against `skills/unipi subagents/` and load them with the read tool.
22
+
23
+ | Task | Read |
24
+ | --- | --- |
25
+ | Decide whether to delegate, choose agents, compare tool versus slash commands, apply prompt techniques, or understand builtin roles | `references/prompting-and-roles.md` |
26
+ | Use council mode, convene several advisors, debate a decision, cross-examine recommendations, critique or improve a plan with multiple model perspectives, or run `/council` | `../council-mode/SKILL.md` |
27
+ | Run one-child, scripted, async, scheduled, mission-backed, forked, watchdog, oracle, or intercom-coordinated workflows | `references/execution-controls.md` |
28
+ | Coordinate several independent tasks, worktrees, repositories, or writer lanes | `references/multi-lane-orchestration.md` |
29
+ | List/create/update/delete/eject/disable agents, inspect legacy chain records, edit agent files, use prompt-template integration, or expose extension RPC | `references/management-authoring-rpc.md` |
30
+ | Check safety constraints, best practices, standard workflows, or error handling | `references/constraints-and-recipes.md` |
31
+
32
+ For broad or uncertain requests, read more than one reference. For complex work, start with `references/prompting-and-roles.md` and `references/execution-controls.md`, then consult `references/constraints-and-recipes.md` before launching or reviewing child work.
33
+
34
+ ## Always-on constraints
35
+
36
+ - Keep the parent as orchestrator and final decision-maker.
37
+ - Before multiple mutation-capable lanes, record a lane board and each lane's isolation path.
38
+ - For plan, design, or architecture advice that asks for council mode, asks to convene several advisors, compare model perspectives, debate a decision, cross-examine recommendations, or critique and improve a plan, read `../council-mode/SKILL.md` and use Council Mode instead of ad hoc parallel oracle calls.
39
+ - For plan, design, or architecture advice that asks to consult, discuss with, or come to agreement with one `oracle`, use a short same-session consultation loop: read the first result, resume once with a targeted challenge when material tradeoffs remain, then synthesize the parent decision. Keep explicit one-shot, trivial, and fully settled consultations one-shot.
40
+ - Use one writer per cwd/worktree unless isolated worktrees are intentional.
41
+ - For cross-codebase work, record the target repo, explicit `cwd`, authority boundary, and expected output before launch. Do not assume the parent session cwd is the child repo.
42
+ - For parallel fanout, compare child prompts before launch. Do not send clone prompts with only issue numbers, titles, or broad file globs swapped; each child needs a lane-specific task, source seam, prior evidence, and decision that remains distinct without the item number. Launch that fanout as one async `workflowScript` with stable keys and aggregate output unless there is truly only one child.
43
+ - Prefer fresh-context review/validation fanout, then synthesize and apply fixes in the parent.
44
+ - Use async/background by default. Final reviews, gate checks, oracle checks, and backlog lanes stay async. Use `async:false` only when the parent must block until completion. Do not poll just to wait. For adaptive gates, branch in `workflowScript`.
45
+ - For Pi extension repos whose canonical checkout is under `~/.pi/agent/extensions`, never create lane worktrees as sibling directories there. Pi auto-loads `~/.pi/agent/extensions/*/index.ts`, so sibling worktrees can register duplicate tools. Put lanes under `~/.pi/agent/worktrees`, another worktree base outside auto-discovery, or a temporary clone. If a lane must run the modified extension itself, use an isolated Pi config home with `PI_CODING_AGENT_DIR=<lane-config> pi --no-extensions -e <lane>/index.ts`. Use full containers only when path and config isolation are insufficient.
46
+ - Preserve capability ceilings, including child tool restrictions and session-scoped allowed-agent restrictions.
47
+ - Escalate unresolved product, architecture, authority, release, merge, or safety decisions upward instead of letting a child decide silently.
48
+ - Treat receipts, CI, review bots, and external-run records as evidence, not authority to merge, close, comment, publish, or release.
49
+ - As a conservative orchestration policy, do not pass `turnBudget`, a hard `toolBudget`, or a tight `usageBudget` to mutation-capable workers. The default tool budget blocks read/search tools rather than mutation tools, and reported usage has no reservation model. If a worker is interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.