pi-subagents-lite 1.3.0 → 1.4.1

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 (53) hide show
  1. package/README.md +184 -235
  2. package/package.json +1 -1
  3. package/src/{agent-discovery.ts → agents/agent-discovery.ts} +10 -7
  4. package/src/{agent-manager.ts → agents/agent-manager.ts} +34 -74
  5. package/src/{agent-runner.ts → agents/agent-runner.ts} +130 -181
  6. package/src/{agent-status.ts → agents/agent-status.ts} +4 -4
  7. package/src/agents/agent-types.ts +339 -0
  8. package/src/{default-agents.ts → agents/default-agents.ts} +2 -5
  9. package/src/{output-file.ts → agents/output-file.ts} +68 -1
  10. package/src/{tool-execution.ts → agents/tool-execution.ts} +60 -222
  11. package/src/agents/types.ts +54 -0
  12. package/src/{usage.ts → agents/usage.ts} +7 -0
  13. package/src/{config-io.ts → config/config-io.ts} +20 -3
  14. package/src/config/config-store.ts +472 -0
  15. package/src/config/types.ts +26 -0
  16. package/src/events.ts +185 -0
  17. package/src/index.ts +8 -281
  18. package/src/{model-precedence.ts → models/model-precedence.ts} +33 -0
  19. package/src/{model-selector.ts → models/model-selector.ts} +1 -1
  20. package/src/{context.ts → prompt/context.ts} +1 -1
  21. package/src/prompt/prompts.ts +180 -0
  22. package/src/prompt/skill-loader.ts +195 -0
  23. package/src/registration.ts +101 -0
  24. package/src/shell.ts +101 -0
  25. package/src/spawn/spawn-coordinator.ts +232 -0
  26. package/src/status-note.ts +10 -0
  27. package/src/types.ts +47 -71
  28. package/src/ui/agent-widget.ts +61 -49
  29. package/src/{format.ts → ui/format.ts} +64 -26
  30. package/src/ui/menu/helpers.ts +93 -0
  31. package/src/ui/menu/menu-concurrency.ts +192 -0
  32. package/src/ui/menu/menu-debug.ts +125 -0
  33. package/src/ui/menu/menu-model-settings.ts +208 -0
  34. package/src/ui/menu/menu-running-agents.ts +224 -0
  35. package/src/ui/menu/menu-spawn-options.ts +87 -0
  36. package/src/ui/menu/menu-spawn-wizard.ts +418 -0
  37. package/src/ui/menu/menu-system-prompt.ts +109 -0
  38. package/src/ui/menu/menu-widget-settings.ts +130 -0
  39. package/src/ui/menu/menus.ts +101 -0
  40. package/src/ui/menu/submenus/confirm.ts +47 -0
  41. package/src/ui/menu/submenus/model-select.ts +70 -0
  42. package/src/ui/menu/submenus/numeric-input.ts +98 -0
  43. package/src/ui/menu/wrappers/settings-list.ts +205 -0
  44. package/src/{renderer.ts → ui/renderer.ts} +7 -6
  45. package/src/{result-viewer.ts → ui/result-viewer.ts} +7 -2
  46. package/src/ui/types.ts +11 -0
  47. package/src/agent-types.ts +0 -184
  48. package/src/config-mutator.ts +0 -183
  49. package/src/menus.ts +0 -1333
  50. package/src/prompts.ts +0 -94
  51. package/src/skill-loader.ts +0 -178
  52. package/src/state.ts +0 -83
  53. /package/src/{worktree-validator.ts → spawn/worktree-validator.ts} +0 -0
package/README.md CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  **Sub-agents for [pi](https://pi.dev) — schema-first, zero-fluff.**
7
7
 
8
- Spawn specialized agents with isolated sessions, custom tools, and per-type models — all at minimal token cost.
8
+ Spawn specialized agents with isolated sessions, custom tools, and per-type models at minimal token cost.
9
9
 
10
10
  ## Schema-First Design
11
11
 
12
- Every tool the LLM sees costs tokens — in the system prompt, and in every turn's context. Most extensions add description text, prompt snippets, and usage guidelines that compound across the session. This extension takes a **schema-first** approach: the tool name and parameter names **are** the schema. No bloated descriptions, no prose.
12
+ Every tool the LLM sees costs tokens — in the system prompt and in every turn. Most extensions layer on descriptions, prompt snippets, and usage guidelines that compound across the session. This extension takes a **schema-first** approach: the tool name and parameter names *are* the schema. No bloated descriptions, no prose.
13
13
 
14
14
  | Standard | Schema-first |
15
15
  |---|---|
@@ -18,100 +18,113 @@ Every tool the LLM sees costs tokens — in the system prompt, and in every turn
18
18
  | `promptGuidelines` with rules | _(none)_ |
19
19
  | Parameters with `.description()` | Bare `Type.String()` |
20
20
 
21
- Tool names like `Agent`, `StopAgent`, and `AgentStatus`, and parameter names like `prompt`, `description`, `run_in_background` are self-documenting. The LLM infers usage from the schema — no verbose descriptions needed. Tool results reinforce correct usage with clear success/error messages.
21
+ Names like `Agent`, `StopAgent`, `AgentStatus`, `run_in_background`, `worktree_path` are self-documenting. Results reinforce correct usage with clear success/error messages.
22
22
 
23
- **Result:** foreground and background agents, custom agent types, per-model concurrency, cost tracking, steering, model overrides, agent status — all with minimal token overhead.
23
+ **Result:** foreground and background agents, custom agent types, per-model concurrency, cost tracking, steering, model overrides, and agent status — all with minimal token overhead.
24
24
 
25
25
  ## Features
26
26
 
27
- - **Three tools** — `Agent` (spawn), `StopAgent` (stop), and `AgentStatus` (list agents)
28
- - **Manual spawn** — spawn agents from the `/agents` menu without asking the LLM. Full control over model, thinking, turns, and background mode.
29
- - **Foreground & background** — block or fire-and-forget with auto-delivered results
30
- - **Custom agent types** — define via `.md` files with YAML frontmatter (tools, model, thinking, turn limits)
31
- - **Smart model resolution** — 6-level precedence: session config → frontmatter → parent. Set once, forget
32
- - **Concurrency control** — per-model and per-provider slot limits with automatic queuing
33
- - **Cost tracking** — input/output/cache tokens and dollar cost per agent
34
- - **Cost display** — toggle agent cost in stats and status bar (OFF by default)
35
- - **Live widget** — persistent status bar above the editor showing running/completed agents
36
- - **Widget settings** — force compact mode, max lines, opt-in ctrl+o sync
37
- - **Result viewer** — fullscreen markdown viewer with stats
38
- - **Steer** — inject mid-execution guidance into running agents
39
- - **Output logs** — human-readable, `tail -f` friendly
40
- - **Grace turns** — configurable grace turns after `max_turns` before hard abort
41
- - **Reload safety** — warns when active agents are killed by session reload
42
- - **Worktree support** — `worktree_path` parameter runs agents in a git worktree with validated path, worktree agent discovery, and UI label
27
+ - **Three tools** — `Agent` (spawn), `StopAgent` (stop), `AgentStatus` (list)
28
+ - **Foreground & background** — block, or fire-and-forget with auto-delivered results
29
+ - **Custom agent types** — `.md` files with YAML frontmatter (tools, model, thinking, turn/token limits)
30
+ - **Manual spawn** — from `/agents`, no LLM round-trip; full control over model, thinking, turns, tokens, background
31
+ - **Model resolution** — 6-level precedence chain; set once, forget
32
+ - **Concurrency** — per-model and per-provider slot limits with automatic queuing
33
+ - **Steering** — inject mid-execution guidance into running agents
34
+ - **Cost & usage tracking** — input/output/cache tokens and dollar cost per agent (toggle in stats)
35
+ - **Live widget** — persistent status bar with running/completed agents, full and compact modes
36
+ - **Result viewer** — fullscreen markdown with stats
37
+ - **Worktrees** — run agents in a git worktree via `worktree_path`
38
+ - **Output logs** — `tail -f` friendly, ISO-timestamped
43
39
 
44
40
  ## Install
45
41
 
46
42
  ```bash
47
43
  pi install npm:pi-subagents-lite
48
- pi install -l npm:pi-subagents-lite # project-local
49
- pi -e npm:pi-subagents-lite # try without installing
44
+ pi install -l npm:pi-subagents-lite # project-local
45
+ pi -e npm:pi-subagents-lite # try without installing
50
46
  ```
51
47
 
52
48
  ## Quick Start
53
49
 
54
- The LLM calls the `Agent` tool like any other tool. A foreground agent returns its result inline with stats; a background agent acknowledges immediately and auto-delivers the result when done.
50
+ The LLM calls `Agent` like any other tool. Foreground agents return inline with stats; background agents acknowledge immediately and auto-deliver on completion.
55
51
 
56
- ```
57
- ⠹ Working...
52
+ Running agents appear in the live widget:
58
53
 
54
+ ```
59
55
  ● Agents
60
- ├─ ⠙ Agent Write model precedence unit tests 6🛠 ·3⟳ ·8.1k(6%)·12s
56
+ ├─ ⠙ Agent Write model precedence unit tests 6🛠 ·3⟳ ·↑6.8k↓1.3k 612s
61
57
  │ │ tail -f /tmp/pi-agent-outputs/bb3382a9-1f7e-474.log
62
58
  │ └ The file already exists but is ~175 lines. The user wants a …
63
- ├─ ⠙ Agent Code review of agent-runner.ts 4🛠 ·2⟳ ·8.7k(4%)·12s
64
- │ │ tail -f /tmp/pi-agent-outputs/23689696-3cd3-400.log
59
+ ├─ ⠙ Agent Code review of agent-runner.ts 4🛠 ·2⟳ ·↑7.2k↓1.5k 412s
65
60
  │ └ Now let me check the types and related files for context on …
66
- └─ ⠙ Explore Explore codebase architecture 13🛠 ·4⟳ ·19.0k(15%)·12s
67
- │ tail -f /tmp/pi-agent-outputs/4f6b0f08-7a9a-419.log
61
+ └─ ⠙ Explore Explore codebase architecture 13🛠 ·4⟳ ·↑16.1k↓2.9k 1512s
68
62
  └ ## Architecture Summary: pi-subagents-lite
69
63
  ```
70
- Then you are notified like this for async (background) invocation:
64
+
65
+ Background agents deliver a result notification when done:
71
66
 
72
67
  ```
73
68
  Subagent Result
74
69
 
75
- ✓ Explore (model-name)·13🛠 ·5⟳ ·30.8k(15%)·21s
70
+ ✓ Explore (model-name)·13🛠 ·5⟳ ·↑25.9k↓4.9k 1521s
76
71
  Explore codebase architecture
77
72
  tail -f /tmp/pi-agent-outputs/4f6b0f08-7a9a-419.log
78
73
  ```
79
74
 
80
- or inline:
75
+ Foreground results land inline:
81
76
 
82
77
  ```
83
78
  ▸ Explore
84
- ✓ 31🛠 ·6⟳ ·57.3k(28%)·39s
79
+ ✓ 31🛠 ·6⟳ ·↑48.1k↓9.2k 2839s
85
80
  Explore project directory structure
86
81
  ```
87
82
 
88
- Stop a running agent at any time via /agents command
83
+ Stop a running agent from `/agents`:
89
84
 
90
85
  ```
91
86
  ○ Agents
92
- └─ ■ Agent Code review of agent-runner.ts 12🛠 ·10⟳ ·39.0k(8%)·52s stopped
93
- tail -f /tmp/pi-agent-outputs/23689696-3cd3-400.log
87
+ └─ ■ Agent Code review of agent-runner.ts 12🛠 ·10⟳ ·↑32.8k↓6.2k 852s stopped
88
+ tail -f /tmp/pi-agent-outputs/23689696-3cd3-400.log
94
89
  ```
95
90
 
96
- ### Agent Tool Parameters
91
+ ## Tools
92
+
93
+ ### `Agent`
94
+
95
+ Spawn a sub-agent.
97
96
 
98
97
  | Parameter | Required | Description |
99
98
  |---|---|---|
100
99
  | `prompt` | ✅ | The task for the sub-agent |
101
- | `description` | | Brief description for the LLM caller (optional — if omitted, derived from prompt) |
102
- | `agent` | | Type name — `general-purpose`, `Explore`, or any custom type you define (see [Custom Agent Types](#custom-agent-types)). The available values are **auto-populated** from `.md` files in your agent directories drop a file, it appears in the enum. Set `hidden: true` in frontmatter to hide a type from this list (still callable by name). |
100
+ | `description` | | Brief description for the caller (optional — derived from `prompt` if omitted) |
101
+ | `agent` | | Type name — `general-purpose`, `Explore`, or any custom type. **Auto-populated** from `.md` files in your agent directories; drop a file, it appears in the enum. `hidden: true` hides a type from the list (still callable by name). |
103
102
  | `run_in_background` | | Fire-and-forget; result delivered automatically when done |
104
- | `worktree_path` | | Absolute path to a git worktree. Agent runs in that worktree's context, discovers agents from its `.pi/agents/` directory, and displays a worktree label in the widget and menus. Path is validated against the parent repo's git common dir. |
103
+ | `worktree_path` | | Absolute path to a git worktree. Agent runs in that worktree's context, discovers agents from its `.pi/agents/`, and shows a worktree label in the UI. Validated against the parent repo's git common dir. |
105
104
 
106
- > `model`, `max_turns`, and `thinking` are **not visible to the LLM** through tool introspection the extension injects them at call time from agent config and frontmatter. `model` is resolved via the [Model Resolution](#model-resolution) chain; `max_turns`/`thinking` come from the agent's config. See [Custom Agent Types](#custom-agent-types) to set them.
105
+ > `model`, `max_turns`, `max_tokens`, and `thinking` are **not visible to the LLM** — injected at call time from agent config and frontmatter. See [Custom Agent Types](#custom-agent-types).
107
106
 
108
- ## Custom Agent Types
107
+ ### `StopAgent`
108
+
109
+ Stop a running agent by ID.
110
+
111
+ | Parameter | Required | Description |
112
+ |---|---|---|
113
+ | `agent_id` | ✅ | The agent ID returned by `Agent` at spawn |
109
114
 
110
- Drop a `.md` file into `.pi/agents/` (project) or `~/.pi/agent/agents/` (global). The frontmatter configures the agent; the body is its system prompt.
115
+ IDs come from the `Agent` result, the `StopAgent` error (lists all running IDs), or `/agents` **Running agents**.
111
116
 
112
- The file's `name` frontmatter field (or the filename without extension) becomes the agent type name and **automatically populates the `agent` parameter's enum** in the tool schema. No registration step needed — the extension scans these directories at session start and makes every discovered agent available to the LLM. Files added during a session are discovered on the next call that references them — no restart required.
117
+ ### `AgentStatus`
113
118
 
114
- Built-in types (`general-purpose`, `Explore`) are always available. User agents override built-ins with the same name; project agents override user agents (see [Merge precedence](#merge-precedence)).
119
+ List all agents with type, short ID, and status. Output: `type·short_id·status, ...` (e.g. `general-purpose·a1b2c3·running, Explore·d4e5f6·completed`).
120
+
121
+ The result nudges the LLM to wait for automatic notifications instead of polling — preventing wasteful repeated calls while still letting it discover agents when needed.
122
+
123
+ ## Custom Agent Types
124
+
125
+ Drop a `.md` file into `.pi/agents/` (project) or `~/.pi/agent/agents/` (global). Frontmatter configures the agent; the body is its system prompt. The `name` field (or filename) becomes the agent type and **auto-populates the `agent` parameter's enum** — no registration. Files added mid-session are picked up on the next call that references them.
126
+
127
+ Built-ins `general-purpose` and `Explore` are always available. **Project agents override user agents, which override built-ins.**
115
128
 
116
129
  ```markdown
117
130
  ---
@@ -121,165 +134,108 @@ description: Review code for security issues
121
134
  tools: [read, bash, grep]
122
135
  extensions: false
123
136
  skills: false
124
- model: anthropic/claude-sonnet-4-5-20250514
137
+ model: zai/glm-5.2
125
138
  thinking: high
126
- max_turns: 10
139
+ max_turns: 80
127
140
  ---
128
141
 
129
142
  You are a security review specialist. Analyze code for vulnerabilities,
130
143
  focusing on injection flaws, auth bypasses, and insecure defaults.
131
144
  ```
132
145
 
133
- **Minimal agent — just name and description:**
146
+ A minimal agent — just `name` and `description` — gets everything: all tools, extensions, and skills, same as `general-purpose`. Set restrictions only when you want them.
134
147
 
135
- ```markdown
136
- ---
137
- name: my-agent
138
- description: Does something
139
- ---
140
-
141
- System prompt here.
142
- ```
143
-
144
- This agent gets everything: all tools, all extensions, all skills. Same as `general-purpose`. No boilerplate needed — set restrictions only when you want them.
145
-
146
- **Frontmatter reference:**
148
+ ### Frontmatter reference
147
149
 
148
150
  | Field | Type | Default | Description |
149
151
  |---|---|---|---|
150
- | `name` | string | filename | Agent type name. Used as the enum value in the `agent` parameter. Must be unique across all agent types. |
151
- | `display_name` | string | `name` | Human-readable label shown in the UI widget, `/agents` menu, and result viewer. |
152
- | `description` | string | `""` | Short description displayed in the `/agents` type list and tool rendering. Keep it one sentence. |
153
- | `tools` | `true` \| `string[]` \| `false` | `true` | **Tool whitelist.** Controls which tool schemas the LLM sees. Accepts built-in names and extension tool references (see below). `true` = all tools visible; `false` = no tools; `string[]` = only listed tools visible. Mutually exclusive with `exclude_tools`. |
154
- | `exclude_tools` | `string[]` | none | **Tool blacklist.** All tools except these are visible. Mutually exclusive with `tools` (when `tools` is `string[]`). |
155
- | `extensions` | `true` \| `string[]` \| `false` | `true` | **Extension loader.** Controls which extensions load (hooks + commands fire). Does NOT control tool visibility. `true` = load all; `false` = load none; `string[]` = load only listed extensions. Mutually exclusive with `exclude_extensions`. |
156
- | `exclude_extensions` | `string[]` | none | **Extension blacklist.** All extensions except these load. Mutually exclusive with `extensions` (when `extensions` is `string[]`). |
157
- | `skills` | `true` \| `string[]` \| `false` | `true` | **Skill whitelist.** Controls which skills are available (metadata injected into system prompt). `true` = all skills; `false` = no skills; `string[]` = only listed skills. |
158
- | `preload_skills` | `string[]` \| `false` | `false` | **Full skill injection.** Dumps complete SKILL.md content into system prompt instead of metadata-only. `string[]` = list of skills to preload; `false` = none. |
159
- | `model` | string | inherit parent | Default model as `"provider/model-id"`. Override via `/agents` or `subagents-lite.json`. See [Model Resolution](#model-resolution). |
160
- | `thinking` | string | inherit parent | Default thinking level. One of: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`. |
161
- | `max_turns` | number | unlimited | Soft turn limit. Agent gets a steer message at the limit, then `max_turns + 5` grace turns before hard abort. |
162
- | `hidden` | `true` \| `false` | `false` | `true` hides the agent type from the tool schema's enum (LLM can't see or invoke it). Agent is still callable by name. Running agents unaffected. |
163
-
164
- #### `tools` field values
165
-
166
- The `tools` field accepts built-in tool names and extension tool references:
167
-
168
- | Value | Meaning | Example |
169
- |---|---|---|
170
- | `true` | All tools visible (default) | `tools: true` or omit the field |
171
- | `false` | No tools visible | `tools: false` |
172
- | `[read, bash, grep]` | Only listed built-in tools | `tools: [read, bash]` |
173
- | `[web_search]` | Extension tool by name | `tools: [read, web_search]` |
174
- | `[tavily/*]` | All tools from an extension | `tools: [read, tavily/*]` |
175
- | `[tavily/web_search]` | Specific tool from extension | `tools: [read, tavily/web_search]` |
176
- | Mixed | Combine the above | `tools: [read, bash, tavily/*, exa_search]` |
152
+ | `name` | string | filename | Agent type name (the `agent` enum value). Must be unique. |
153
+ | `display_name` | string | `name` | Label in the widget, `/agents` menu, and result viewer. |
154
+ | `description` | string | `""` | One-sentence description in the `/agents` list and tool rendering. |
155
+ | `tools` | `true` \| `string[]` \| `false` | `true` | **Tool whitelist** which tool schemas the LLM sees. Accepts built-in names and extension tool references (see below). Mutually exclusive with `exclude_tools`. |
156
+ | `exclude_tools` | `string[]` | none | **Tool blacklist** all tools except these are visible. Supports `ext/*` syntax. Mutually exclusive with `tools` (when `tools` is `string[]`). |
157
+ | `extensions` | `true` \| `string[]` \| `false` | `true` | **Extension loader** which extensions load (hooks + commands fire). Does NOT control tool visibility. Mutually exclusive with `exclude_extensions`. |
158
+ | `exclude_extensions` | `string[]` | none | **Extension blacklist** all extensions except these load. Mutually exclusive with `extensions` (when `extensions` is `string[]`). |
159
+ | `skills` | `true` \| `string[]` \| `false` | `true` | **Skill whitelist** which skills are available (metadata in system prompt). |
160
+ | `preload_skills` | `string[]` \| `false` | `false` | **Full skill injection** dump complete SKILL.md content into the system prompt instead of metadata-only. |
161
+ | `model` | string | inherit parent | Default model as `"provider/model-id"`. See [Model Resolution](#model-resolution). |
162
+ | `thinking` | string | inherit parent | One of: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`. |
163
+ | `max_turns` | number | unlimited | Soft turn limit. Agent gets a steer at the limit, then `max_turns + graceTurns` before hard abort. |
164
+ | `max_tokens` | number | unlimited | Max output tokens per LLM response. Injected into provider request payloads. |
165
+ | `hidden` | `true` \| `false` | `false` | `true` hides the type from the enum (LLM can't see or invoke it). Still callable by name. |
166
+
167
+ ### Tool control (`tools` / `exclude_tools`)
168
+
169
+ Use a whitelist (`tools`) when an agent needs few tools, or a blacklist (`exclude_tools`) when it needs most. You can use **either**, not both; if both are set, the whitelist wins.
177
170
 
178
171
  Built-in tool names: `read`, `bash`, `edit`, `write`, `grep`.
179
172
 
180
- #### Blacklist mode (`exclude_tools` and `exclude_extensions`)
181
-
182
- When you have many tools or extensions and want to disable a few, use the blacklist fields:
173
+ | Value | Meaning |
174
+ |---|---|
175
+ | `true` / omitted | All tools visible |
176
+ | `false` | No tools visible |
177
+ | `[read, bash]` | Only listed built-in tools |
178
+ | `[web_search]` | Extension tool by name |
179
+ | `[tavily/*]` | All tools from an extension |
180
+ | `[tavily/web_search]` | Specific tool from an extension |
183
181
 
184
182
  ```yaml
185
- ---
186
- name: restricted-agent
187
- description: Agent with write disabled
188
- exclude_tools: [write] # all tools except write
189
- exclude_extensions: [quality-monitor] # all extensions except quality-monitor
190
- ---
191
- ```
192
-
193
- `exclude_tools` supports the same `ext/*` syntax as `tools`:
183
+ # Read-only via whitelist
184
+ tools: [read, bash, grep]
185
+ extensions: false
194
186
 
195
- ```yaml
196
- exclude_tools: [tavily/*] # hide all tavily tools (extension still loads)
197
- exclude_tools: [write, tavily/*] # hide write + all tavily tools
198
- exclude_tools: [tavily/web_search] # hide only web_search from tavily
187
+ # Same result via blacklist (easier to maintain as the toolset grows)
188
+ exclude_tools: [edit, write]
199
189
  ```
200
190
 
201
- | Field | Mutually exclusive with | Behavior |
202
- |---|---|---|
203
- | `exclude_tools` | `tools` (when `tools` is `string[]`) | All tools except listed ones visible. Supports `ext/*` syntax. |
204
- | `exclude_extensions` | `extensions` (when `extensions` is `string[]`) | All extensions except listed ones load. |
205
-
206
- **Constraint:** You can use EITHER `tools` OR `exclude_tools`, not both. Same for `extensions`/`exclude_extensions`. If both are set, the whitelist (`tools`/`extensions`) wins.
191
+ > `exclude_tools: [tavily/*]` hides tavily's tools but the extension still loads (hooks fire). Use `exclude_extensions: [tavily]` to prevent loading entirely.
207
192
 
208
- **Note:** `exclude_tools: [tavily/*]` hides tavily's tools but the extension still loads (hooks fire). Use `exclude_extensions: [tavily]` to prevent the extension from loading entirely.
193
+ ### Extensions & skills
209
194
 
210
- #### `extensions` field values
195
+ **What they are:**
196
+ - **Tools** are callable functions — `read`, `bash`, `edit`, `write`, `grep` (built-in), or `web_search` / `tavily/*` (from extensions). The `tools` whitelist controls which tool schemas the LLM sees.
197
+ - **Skills** are reusable instruction files (`SKILL.md`) that teach an agent how to do a task — e.g. `debug`, `tdd`. By default the agent sees only skill metadata (name, description, path) in its system prompt and reads the full content on-demand via `read`.
198
+ - **Extensions** are pi plugins (e.g. `tavily`, `pi-tokf`) that register tools and hooks. Loading one makes its hooks fire and its tools *available* — but those tools still need to pass the `tools` whitelist to be visible.
211
199
 
212
- The `extensions` field controls which extensions load. It does NOT affect tool visibility.
213
-
214
- | Value | Meaning | Example |
215
- |---|---|---|
216
- | `true` | Load all extensions (default) | `extensions: true` or omit the field |
217
- | `false` | Load no extensions | `extensions: false` |
218
- | `[tavily]` | Load only listed extensions | `extensions: [tavily, pi-tokf]` |
219
- | `[tavily/web_search]` | Load extension (tool part ignored) | `extensions: [tavily/web_search]` loads all of tavily |
200
+ `extensions` controls which extensions **load** (hooks + tool registration), not tool visibility. `skills` and `preload_skills` control skill availability. Same whitelist/blacklist rules and `ext/*` syntax as `tools`.
220
201
 
221
- #### `skills` and `preload_skills` field values
222
-
223
- Skills have two injection modes:
224
-
225
- | Field | Value | Effect |
226
- |---|---|---|
227
- | `skills` | `true` | All skills available (metadata-only in system prompt) |
228
- | `skills` | `false` | No skills |
229
- | `skills` | `[debug, tdd]` | Only listed skills (metadata-only) |
230
- | `preload_skills` | `[debug]` | Dump full SKILL.md content into system prompt |
231
- | `preload_skills` | `false` | No preloading (default) |
232
-
233
- Metadata-only means the agent sees skill name, description, and file path. It reads the full content on-demand via the `read` tool. Preloading injects the full content upfront — higher token cost but no read latency.
234
-
235
- ### Token-Saving Frontmatter Settings
236
-
237
- Every tool schema and every skill snippet you inject costs tokens — in every turn. These frontmatter fields are your main levers:
202
+ | `extensions` value | Meaning |
203
+ |---|---|
204
+ | `true` / omitted | Load all extensions |
205
+ | `false` | Load none |
206
+ | `[tavily, pi-tokf]` | Load only listed extensions |
238
207
 
239
- | Setting | What it controls | Token impact |
208
+ | Skill field | Value | Effect |
240
209
  |---|---|---|
241
- | `tools: [a, b, c]` | Which tool schemas the LLM sees (built-in + extension tools) | High each tool has a schema (name, params, description) injected every turn. Fewer tools = fewer tokens. |
242
- | `tools: [ext-name/*]` | All tools from a specific extension | Medium lazy shorthand for listing each tool individually. |
243
- | `extensions: false` | Disables all extensions (no hooks, no commands) | Medium — extensions can register hooks that fire every turn. |
244
- | `extensions: ["my-ext"]` | Load only specific extensions | Medium — pick only what the agent needs. |
245
- | `skills: ["skill-a"]` | Whitelist skills — injects metadata only (name, description, location) | Low — agent reads full content on-demand via `read` tool. No prose in system prompt. |
246
- | `skills: false` | Disables all skills | Zero skill tokens. |
247
- | `preload_skills: ["skill-a"]` | Dump full SKILL.md content into system prompt | **Highest** — skill prompts are prose, not schemas. A verbose skill can be 10-50x the token cost of a tool schema. |
248
- | `exclude_tools: [write]` | Disable specific tools (blacklist mode) | High — same as whitelist but without listing everything. |
249
- | `exclude_extensions: [ext]` | Disable specific extensions (blacklist mode) | Medium — same as whitelist but without listing everything. |
250
-
251
- **Practical examples:**
252
-
253
- ```yaml
254
- # Read-only agent: whitelist approach
255
- tools: [read, bash, grep]
256
- extensions: false
257
- skills: false
210
+ | `skills` | `true` / `[debug, tdd]` / `false` | All / listed / no skills (metadata-only in system prompt) |
211
+ | `preload_skills` | `[debug]` / `false` | Dump full SKILL.md content / none (default) |
258
212
 
259
- # Read-only agent: blacklist approach (same result, easier to maintain)
260
- exclude_tools: [edit, write]
213
+ **Implicit loading.** `loadSkillsImplicitly` and `loadExtensionsImplicitly` are config globals that decide what an agent gets when its frontmatter **omits** `skills` / `extensions`. They default ON, so an agent that says nothing about either gets everything. Turn them OFF (in config, or `/agents` → System prompt) to default every new agent to nothing — isolated sessions and minimal token cost, with agents opting in explicitly via `skills: [debug]` / `extensions: [tavily]`. A concrete frontmatter value always overrides the global.
261
214
 
262
- # Agent that uses all tools except write, and all extensions except quality-monitor
263
- exclude_tools: [write]
264
- exclude_extensions: [quality-monitor]
265
- ```
266
-
267
- ### Merge precedence
268
-
269
- Project agents override user agents, which override built-ins (`general-purpose`, `Explore`). Agent types discovered from `.md` files automatically appear in the `agent` parameter's enum — no registration required. Files added during a session are discovered on the next call that references them.
215
+ **Token cost ranking** (highest lowest): `preload_skills` ≫ `tools`/`exclude_tools` (each tool schema every turn) > `extensions` (hooks fire every turn) > `skills` (metadata-only, agent reads full content on-demand) > `skills: false` (zero). Prefer metadata skills over preloading; whitelist tools aggressively for narrow agents.
270
216
 
271
217
  ## Model Resolution
272
218
 
273
219
  The extension picks the right model automatically. Precedence (highest first):
274
220
 
275
- 1. **Session per-type override** — `/agents > Model settings`, lasts the session
221
+ 1. **Session per-type override** — `/agents` Model settings, lasts the session
276
222
  2. **Session global default** — temporary
277
223
  3. **Config per-type override** — `~/.pi/agent/subagents-lite.json`
278
224
  4. **Config global default**
279
- 5. **Agent frontmatter** — `model` in `.md` file
225
+ 5. **Agent frontmatter** — `model` in `.md`
280
226
  6. **Parent model** — inherit from the calling agent
281
227
 
282
- The LLM never passes `model` — it's injected at call time via the `tool_call` listener. Set it once in config or frontmatter and forget about it.
228
+ The LLM never passes `model` — it's injected at call time. Set it once in config or frontmatter and forget.
229
+
230
+ ## System Prompt Mode
231
+
232
+ Control how the subagent system prompt is built via `systemPromptMode` (default: `replace`):
233
+
234
+ - **`replace`** — minimal generic prompt plus the agent's own `<agent_instructions>`. Lowest token cost, most isolated.
235
+ - **`inherit`** — parent's system prompt (scaffolding stripped to avoid duplication) plus `<agent_instructions>`. Best when agents need parent context and guidelines.
236
+ - **`custom`** — content of `~/.pi/agent/subagents-lite-prompt.md` plus `<agent_instructions>`. Full control.
237
+
238
+ When `includeContextFiles` is `true` (default), AGENTS.md files from the project root and `~/.pi/agent/` load as `<project_context>` before agent-specific instructions — shared static context improves KV cache prefix hit rates. Toggle off to cut token cost.
283
239
 
284
240
  ## Commands
285
241
 
@@ -287,121 +243,114 @@ The LLM never passes `model` — it's injected at call time via the `tool_call`
287
243
 
288
244
  Management menu with four sections:
289
245
 
290
- - **Running agents** — list with status and description; per-agent actions: view snapshot, view result, view error, steer, stop; bulk stop all running
291
- - **Spawn agent** — manually spawn an agent without asking the LLM. Pick a type, enter a prompt, configure options (model, thinking, max turns, grace turns, background), and spawn. Options are pre-filled from agent config and current settings. Spawn immediately or customize first.
292
- - **Settings** — model, concurrency, and widget settings grouped together
293
- - **Model settings** — global default, per-type overrides, force background mode, cost display toggle, grace turns
246
+ - **Running agents** — status and description; per-agent actions (view snapshot, result, error; steer; stop) and bulk stop
247
+ - **Spawn agent** — manually spawn without the LLM. Pick a type, enter a prompt, tune options (model, thinking, max turns, max tokens, grace turns, background), then spawn. Options pre-fill from agent config.
248
+ - **Settings**
249
+ - **Model settings** — global default, per-type overrides, session overrides, clear all
250
+ - **Spawn options** — force background, grace turns, default max turns, default thinking, disable default agents
251
+ - **System prompt** — mode, custom prompt file, include AGENTS.md, load skills/extensions implicitly
294
252
  - **Concurrency** — default limit, per-provider and per-model slots, reset to defaults
295
- - **Widget settings** — force compact mode, max lines (full/compact), ctrl+o shortcut
296
- - **Debug** — agent types, agent briefing (sends capabilities to the LLM)
253
+ - **Widget settings** — force compact, max lines, description length, ctrl+o shortcut, usage stats (toggle tools, turns, input/output tokens, context %, cost, time)
297
254
 
298
255
  ## Interface
299
256
 
300
- ### Live Widget
301
-
302
- Persistent bar above the editor showing running and completed agents. Updates live during execution.
257
+ ### Live widget
303
258
 
304
- - Running agents show a spinner, current tool activity, turn count, token usage (with optional context-fill percent), and elapsed time
305
- - Completed agents show a check mark with final stats
306
- - Click `tail -f` path to follow output logs in real time
307
- - Two display modes: **full** (header + `tail -f` path + activity) and **compact** (single line, description truncated to 30 chars, activity inline)
259
+ Persistent bar above the editor showing running and completed agents, updating live. Running agents show a spinner, current tool activity, turn count, token usage (with optional context-fill %), and elapsed time. Completed agents show a check mark with final stats. Click the `tail -f` path to follow output logs.
308
260
 
309
- **Full mode** (tree structure with branch connectors):
261
+ **Full mode** (tree, header + `tail -f` path + activity):
310
262
  ```
311
- ├─ ⠙ Explore description 3🛠 ·5≤30⟳ ·12.0k(45%)·1h 2m 3s
263
+ ├─ ⠙ Explore description 3🛠 ·5≤30⟳ ·↑10.2k↓1.8k 451h 2m 3s
312
264
  │ │ tail -f /tmp/pi-agent-outputs/...
313
265
  │ └ thinking…
314
266
  ```
315
267
 
316
- **Compact mode** (single line, description truncated):
268
+ **Compact mode** (single line, description truncated, activity inline):
317
269
  ```
318
- ├─ ⠙ Explore description trunc… 3🛠 ·5≤30⟳ ·12.0k(45%)·1h 2m 3s thinking…
270
+ ├─ ⠙ Explore description trunc… 3🛠 ·5≤30⟳ ·↑10.2k↓1.8k 451h 2m 3s thinking…
319
271
  ```
320
272
 
321
- Turn format uses `≤` and `⟳` glyphs (`5≤30⟳` = 5 of 30 turns). Token count uses compact notation (`12.0k`) with optional context-fill percent in parentheses. No "tokens" label the glyphs are self-explanatory.
322
-
323
- **Compact mode is active when:**
324
- - **Force compact mode** is ON (in `/agents > Widget settings`), OR
325
- - **Ctrl+o shortcut** is ON and the user has pressed ctrl+o to collapse tool expansion
326
-
327
- Force compact always wins. When force compact is ON, ctrl+o state changes are ignored.
273
+ Turn format uses `≤` and `⟳` (`5≤30⟳` = 5 of 30 turns). Turn count is colored by usage: normal < 80%, warning 80–99%, error at 100%. The max is hidden when well below the limit. Token glyphs (`↑` input, `↓` output) are self-explanatory — no "tokens" label.
328
274
 
329
- ### Result Viewer
275
+ Compact mode is active when **Force compact** is ON, or **ctrl+o shortcut** is ON and the user has collapsed tool expansion. Force compact always wins.
330
276
 
331
- Fullscreen markdown viewer for agent results. Opens automatically when viewing a completed agent's result from the `/agents` menu.
277
+ ### Result viewer
332
278
 
333
- Key bindings: `↑↓` navigate · `PgUp/PgDn` · `g`/`G` top/bottom · `f` toggle fullscreen · `r` refresh · `q`/`Esc` close
279
+ Fullscreen markdown viewer for completed agent results — opens automatically from `/agents`. Keys: `↑↓` / `PgUp/PgDn` navigate · `g`/`G` top/bottom · `f` fullscreen · `r` refresh · `q`/`Esc` close. Stats line: `↑12.0k · ↓8.0k · W3.0k · $0.024 · 15 turns · 47s`.
334
280
 
335
- Stats line: ` ↑12.0k · ↓8.0k · W3.0k · $0.024 · 15 turns · 47s`
336
-
337
- When **Cost display** is enabled (ON), agent stats show dollar cost: `✓ Builder·2🛠 ·5⟳ ·12.3k·$0.008·10s`. The status bar shows total agent cost: `agents: $0.008` or `2 agents: $0.008`.
281
+ With **Cost display** ON, stats show dollar cost (`✓ Builder·2🛠 ·5⟳ ·↑10.2k1.8k $0.008·10s`) and the status bar totals it (`agents: $0.008`). Toggle as a session override from Model settings.
338
282
 
339
283
  ## Configuration
340
284
 
341
- `~/.pi/agent/subagents-lite.json` — managed via `/agents` menu, or edit directly:
285
+ `~/.pi/agent/subagents-lite.json` — managed via `/agents`, or edit directly. Per-type model overrides (e.g. `"Explore"`) are dynamic keys alongside the special fields.
342
286
 
343
287
  ```json
344
288
  {
345
289
  "agent": {
346
- "default": null,
347
- "forceBackground": false,
348
- "showCost": true,
290
+ "default": "zai/glm-5.2",
291
+ "forceBackground": true,
349
292
  "graceTurns": 6,
293
+ "showCost": true,
294
+ "showTools": false,
295
+ "showTurns": true,
296
+ "showInput": true,
297
+ "showOutput": true,
298
+ "showContext": true,
299
+ "showTime": true,
350
300
  "widgetMaxLines": 12,
351
301
  "widgetMaxLinesCompact": 6,
352
- "widgetCompact": false,
302
+ "widgetDescLengthFull": 50,
303
+ "widgetCompact": true,
353
304
  "widgetShortcut": false,
354
- "Explore": "anthropic/claude-haiku-4-5-20251001"
305
+ "systemPromptMode": "inherit",
306
+ "includeContextFiles": true,
307
+ "loadSkillsImplicitly": false,
308
+ "loadExtensionsImplicitly": false,
309
+ "disableDefaultAgents": false,
310
+ "Explore": "xiaomi/mimo-v2.5",
311
+ "builder": "xiaomi/mimo-v2-pro",
312
+ "architecture-reviewer": "zai/glm-5.2",
313
+ "planner": "zai/glm-5.2"
355
314
  },
356
315
  "concurrency": {
357
316
  "default": 4,
358
- "providers": { "ollama": 2 },
359
- "models": {
360
- "anthropic/claude-sonnet-4-5-20250514": 3
361
- }
317
+ "providers": {
318
+ "llamacpp": 1,
319
+ "ai.lan": 2
320
+ },
321
+ "models": {}
362
322
  }
363
323
  }
364
324
  ```
365
325
 
366
- > **Note:** `agent.default` (global fallback), `agent.forceBackground` (flag), `agent.showCost` (toggle cost display), `agent.graceTurns` (grace turns after `max_turns` before hard abort), widget settings (`widgetMaxLines`, `widgetMaxLinesCompact`, `widgetCompact`, `widgetShortcut`), and per-type overrides like `"Explore"` are peers in the same object. Agent type names become dynamic keys alongside the special fields.
367
-
368
326
  ### Widget settings
369
327
 
370
328
  | Field | Default | Description |
371
329
  |---|---|---|
372
- | `widgetMaxLines` | `12` | Maximum body lines in full mode (excluding the heading). |
373
- | `widgetMaxLinesCompact` | half of `widgetMaxLines` | Maximum body lines in compact mode. |
330
+ | `widgetMaxLines` | `12` | Max body lines in full mode (excluding heading). |
331
+ | `widgetMaxLinesCompact` | half of `widgetMaxLines` | Max body lines in compact mode. |
332
+ | `widgetDescLengthFull` | `50` | Max description length in full mode. |
333
+ | `widgetDescLengthCompact` | `30` | Max description length in compact mode. |
374
334
  | `widgetCompact` | `false` | Force compact mode regardless of ctrl+o state. |
375
- | `widgetShortcut` | `false` | Opt-in: when ON, ctrl+o (tool expansion toggle) syncs with widget compact mode. When OFF, compact mode is manual-only via `widgetCompact`. |
335
+ | `widgetShortcut` | `false` | When ON, ctrl+o (tool expansion toggle) syncs with widget compact mode. When OFF, compact is manual via `widgetCompact`. |
376
336
 
377
- > **Reload safety:** if a session reload (e.g. `/reload` or extension reload) kills running agents, the UI notifies you with the count of lost agents. Output logs and completed results are preserved on disk.
337
+ ### Stats visibility
378
338
 
379
- ## StopAgent Tool
380
-
381
- Stop a running agent by ID. Returns a success message or an error if the agent isn't found.
382
-
383
- | Parameter | Required | Description |
339
+ | Field | Default | Description |
384
340
  |---|---|---|
385
- | `agent_id` | ✅ | The agent ID returned by the `Agent` tool when the agent was spawned |
386
-
387
- Agent IDs can be discovered from:
388
- - The `Agent` tool's result (shown on spawn)
389
- - The `StopAgent` error message, which lists all running agent IDs
390
- - The `/agents` menu's **Running agents** section
391
-
392
- ## AgentStatus Tool
393
-
394
- List all agents with their type, short ID, and status. Returns a formatted list of all agents (running, queued, completed, stopped, error) and a nudge message reminding the LLM not to poll.
395
-
396
- **Usage:** The LLM calls `AgentStatus` to check on agents, but the extension nudges it to wait for automatic notifications instead of polling. This prevents wasteful repeated calls while still allowing the LLM to discover agents when needed.
397
-
398
- **Output format:** `type·short_id·status, type·short_id·status, ...`
341
+ | `showTools` | `true` | Tool count (🛠). |
342
+ | `showTurns` | `true` | Turn count (⟳). |
343
+ | `showInput` | `true` | Input tokens (↑). |
344
+ | `showOutput` | `true` | Output tokens (↓). |
345
+ | `showContext` | `true` | Context-fill percent (%). |
346
+ | `showCost` | `false` | Dollar cost ($). |
347
+ | `showTime` | `true` | Elapsed time. |
399
348
 
400
- Example: `general-purpose·a1b2c3·running, Explore·d4e5f6·completed`
349
+ > **Reload safety:** if a session reload (`/reload`, extension reload) kills running agents, the UI reports the count lost. Output logs and completed results are preserved on disk.
401
350
 
402
351
  ## Output Logs
403
352
 
404
- `/tmp/pi-agent-outputs/<agentId>.log` — append-only, human-readable, `tail -f` friendly. Every line is prefixed with an ISO 8601 timestamp:
353
+ `/tmp/pi-agent-outputs/<agentId>.log` — append-only, human-readable, `tail -f` friendly. Every line is ISO-8601 timestamped:
405
354
 
406
355
  ```
407
356
  2026-05-27T12:00:00.000Z [USER] Find all authentication files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-subagents-lite",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "Lightweight sub-agents for pi — spawn specialized agents with isolated sessions, tools, and models.",
5
5
  "keywords": [
6
6
  "pi-package",