@gotgenes/pi-subagents 10.0.1 → 10.1.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/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [10.1.0](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v10.0.1...pi-subagents-v10.1.0) (2026-05-27)
9
+
10
+
11
+ ### Features
12
+
13
+ * **pi-subagents:** add abort() to AgentRecord ([bbc9dc7](https://github.com/gotgenes/pi-packages/commit/bbc9dc779d2ff845680f6de34d0ef33c10cdf124))
14
+ * **pi-subagents:** add setupWorktree() to AgentRecord ([1786fdb](https://github.com/gotgenes/pi-packages/commit/1786fdb939d3e858d6453b71a43b9fb3c3346a88))
15
+ * **pi-subagents:** add steer buffering to AgentRecord ([a22d8c7](https://github.com/gotgenes/pi-packages/commit/a22d8c77e8074e1fe9f396305267380d9f3558b3))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **pi-subagents:** remove unused AgentInit/AgentStatus re-exports from types.ts ([6789cb7](https://github.com/gotgenes/pi-packages/commit/6789cb72e26eefd54da4ff6ee5dd847c4fa78385))
21
+
22
+
23
+ ### Documentation
24
+
25
+ * **pi-subagents:** archive Phase 14, advance to Phase 15 ([a8147fb](https://github.com/gotgenes/pi-packages/commit/a8147fb3f6be9af6d73089bbb42b40080e8e04a7))
26
+ * **pi-subagents:** update architecture for Agent rename ([#227](https://github.com/gotgenes/pi-packages/issues/227)) ([f9afc88](https://github.com/gotgenes/pi-packages/commit/f9afc88dcc21213abe453baa032563ff37499ca9))
27
+ * plan evolve AgentRecord into Agent with behavior ([#227](https://github.com/gotgenes/pi-packages/issues/227)) ([d56ff97](https://github.com/gotgenes/pi-packages/commit/d56ff97408063de6467149dc332e35d4078dd137))
28
+ * replace \n with <br/> in Mermaid node labels ([3312a45](https://github.com/gotgenes/pi-packages/commit/3312a4559100cf9ae923f67819653b5a99fceb12))
29
+ * **retro:** add planning stage notes for issue [#227](https://github.com/gotgenes/pi-packages/issues/227) ([ccd9788](https://github.com/gotgenes/pi-packages/commit/ccd9788ac619ae9f0380cb4b0c0b632efb0faf68))
30
+ * **retro:** add retro notes for issue [#239](https://github.com/gotgenes/pi-packages/issues/239) ([58a19a1](https://github.com/gotgenes/pi-packages/commit/58a19a1e65d93c753ef7ba9c24e34d4ebb6f172d))
31
+ * **retro:** add TDD stage notes for issue [#227](https://github.com/gotgenes/pi-packages/issues/227) ([66cf314](https://github.com/gotgenes/pi-packages/commit/66cf314aa4bef736a689d547e75e8bede1757f85))
32
+
8
33
  ## [10.0.1](https://github.com/gotgenes/pi-packages/compare/pi-subagents-v10.0.0...pi-subagents-v10.0.1) (2026-05-27)
9
34
 
10
35
 
@@ -34,44 +34,44 @@ The extension is organized around six domains, each responsible for one aspect o
34
34
  flowchart TB
35
35
  subgraph config["Config domain"]
36
36
  direction TB
37
- AgentTypeRegistry["AgentTypeRegistry\n(registry of agent types)"]
38
- DefaultAgents["default-agents\n(built-in types)"]
39
- CustomAgents["custom-agents\n(user .md files)"]
40
- InvocationConfig["invocation-config\n(per-call merge)"]
37
+ AgentTypeRegistry["AgentTypeRegistry<br/>(registry of agent types)"]
38
+ DefaultAgents["default-agents<br/>(built-in types)"]
39
+ CustomAgents["custom-agents<br/>(user .md files)"]
40
+ InvocationConfig["invocation-config<br/>(per-call merge)"]
41
41
  end
42
42
 
43
43
  subgraph session["Session domain"]
44
44
  direction TB
45
- SessionConfig["assembleSessionConfig\n(pure assembler)"]
46
- Prompts["prompts\n(system prompt)"]
47
- Context["context\n(parent history)"]
48
- SafeFs["safe-fs\n(symlink/name guards)"]
49
- SkillLoader["skill-loader\n(preload skills)"]
50
- Env["env\n(git/platform)"]
51
- ModelResolver["model-resolver\n(fuzzy match)"]
45
+ SessionConfig["assembleSessionConfig<br/>(pure assembler)"]
46
+ Prompts["prompts<br/>(system prompt)"]
47
+ Context["context<br/>(parent history)"]
48
+ SafeFs["safe-fs<br/>(symlink/name guards)"]
49
+ SkillLoader["skill-loader<br/>(preload skills)"]
50
+ Env["env<br/>(git/platform)"]
51
+ ModelResolver["model-resolver<br/>(fuzzy match)"]
52
52
  end
53
53
 
54
54
  subgraph lifecycle["Lifecycle domain"]
55
55
  direction TB
56
- AgentManager["AgentManager\n(spawn, queue, abort)"]
57
- AgentRunner["agent-runner\n(session, turns, results)"]
58
- AgentRecord["AgentRecord\n(status state machine)"]
59
- ParentSnapshot["ParentSnapshot\n(frozen parent state)"]
60
- Worktree["worktree\n(git isolation)"]
56
+ AgentManager["AgentManager<br/>(spawn, queue, abort)"]
57
+ AgentRunner["agent-runner<br/>(session, turns, results)"]
58
+ AgentRecord["Agent<br/>(status, behavior: abort/steer/worktree)"]
59
+ ParentSnapshot["ParentSnapshot<br/>(frozen parent state)"]
60
+ Worktree["worktree<br/>(git isolation)"]
61
61
  end
62
62
 
63
63
  subgraph observation["Observation domain"]
64
64
  direction TB
65
- RecordObserver["record-observer\n(stats via events)"]
66
- Notification["notification\n(completion nudges)"]
67
- UIObserver["ui-observer\n(streaming state)"]
65
+ RecordObserver["record-observer<br/>(stats via events)"]
66
+ Notification["notification<br/>(completion nudges)"]
67
+ UIObserver["ui-observer<br/>(streaming state)"]
68
68
  end
69
69
 
70
70
  subgraph tools["Tools domain"]
71
71
  direction TB
72
- AgentTool["subagent tool\n(dispatch)"]
73
- ResultRenderer["result-renderer\n(pure rendering)"]
74
- SpawnConfig["spawn-config\n(resolve params)"]
72
+ AgentTool["subagent tool<br/>(dispatch)"]
73
+ ResultRenderer["result-renderer<br/>(pure rendering)"]
74
+ SpawnConfig["spawn-config<br/>(resolve params)"]
75
75
  FgRunner["foreground-runner"]
76
76
  BgSpawner["background-spawner"]
77
77
  GetResult["get_subagent_result"]
@@ -80,9 +80,9 @@ flowchart TB
80
80
 
81
81
  subgraph ui["UI domain"]
82
82
  direction TB
83
- Widget["agent-widget\n(live status)"]
84
- ConvViewer["conversation-viewer\n(session overlay)"]
85
- Menu["agent-menu\n(slash command)"]
83
+ Widget["agent-widget<br/>(live status)"]
84
+ ConvViewer["conversation-viewer<br/>(session overlay)"]
85
+ Menu["agent-menu<br/>(slash command)"]
86
86
  end
87
87
 
88
88
  AgentTool --> AgentManager
@@ -105,7 +105,7 @@ classDiagram
105
105
  +id: string
106
106
  +type: SubagentType
107
107
  +description: string
108
- +status: AgentRecordStatus
108
+ +status: AgentStatus
109
109
  +result?: string
110
110
  +error?: string
111
111
  +toolUses: number
@@ -120,16 +120,19 @@ classDiagram
120
120
  +markError()
121
121
  +markStopped()
122
122
  +resetForResume()
123
+ +abort(): boolean
124
+ +queueSteer(message)
125
+ +flushPendingSteers(session)
126
+ +setupWorktree(worktrees, isolation)
123
127
  }
124
128
 
125
129
  class AgentManager {
126
130
  +spawn(snapshot, type, prompt, config)
127
131
  +spawnAndWait(snapshot, type, prompt, config)
128
132
  +resume(id, snapshot, exec)
129
- +getRecord(id): AgentRecord
130
- +listAgents(): AgentRecord[]
133
+ +getRecord(id): Agent
134
+ +listAgents(): Agent[]
131
135
  +abort(id)
132
- +queueSteer(id, message)
133
136
  }
134
137
 
135
138
  class AgentTypeRegistry {
@@ -216,10 +219,10 @@ sequenceDiagram
216
219
  Asm-->>Runner: SessionConfig
217
220
  Runner->>Child: create session + run turn loop
218
221
  Child-->>Runner: result text
219
- Runner-->>Mgr: update AgentRecord
220
- Note over Mgr: record-observer subscribes to session events for stats
222
+ Runner-->>Mgr: update Agent
223
+ Note over Mgr: agent-observer subscribes to session events for stats
221
224
  Note over Mgr: ui-observer subscribes for streaming state
222
- Mgr-->>Tool: AgentRecord
225
+ Mgr-->>Tool: Agent
223
226
  Tool-->>LLM: formatted result
224
227
  ```
225
228
 
@@ -259,7 +262,7 @@ src/
259
262
  ├── lifecycle/ agent execution and state tracking
260
263
  │ ├── agent-manager.ts spawn, queue, abort, resume, concurrency
261
264
  │ ├── agent-runner.ts session creation, turn loop, tool filtering
262
- │ ├── agent-record.ts status state machine
265
+ │ ├── agent.ts status state machine, per-agent behavior (abort, steer, worktree)
263
266
  │ ├── parent-snapshot.ts immutable spawn-time parent state
264
267
  │ ├── execution-state.ts session/output phase state
265
268
  │ ├── permission-bridge.ts optional bridge to pi-permission-system registry
@@ -504,7 +507,7 @@ Bags with 10+ fields are the highest priority for decomposition.
504
507
  | `AgentToolDeps` | 8 | agent-tool | ✓ done |
505
508
  | `AgentMenuDeps` | 8 | agent-menu | ✓ done |
506
509
  | `ConversationViewerOptions` | 8 | conversation-viewer | Low |
507
- | `AgentRecordInit` | 8 | agent-record | Low |
510
+ | `AgentInit` | 8 | agent | Low |
508
511
 
509
512
  ### Complexity hotspots
510
513
 
@@ -665,103 +668,11 @@ Phase 13 addressed remaining closure factories, the last fallow refactoring targ
665
668
  All six steps are closed: [#214], [#215], [#216], [#217], [#218], [#219].
666
669
  See [phase-13-remaining-smells.md](history/phase-13-remaining-smells.md) for details.
667
670
 
668
- ## Improvement roadmap (Phase 14 — strip policy from core)
671
+ ## Phase 14 (complete)
669
672
 
670
- Phase 14 removes tool and extension policy enforcement from pi-subagents.
671
- This code duplicates what pi-permission-system already provides with richer semantics (allow/ask/deny vs. binary hide).
672
- Removing it simplifies `runAgent`, shrinks `AgentConfig` and `SessionConfig`, and makes the Phase 15 domain-model work operate on a cleaner codebase.
673
-
674
- ### Findings summary
675
-
676
- | Finding | Category | Impact | Risk | Priority |
677
- | ----------------------------------------------------------------------------------------- | ------------- | ------ | ---- | -------- |
678
- | `disallowed_tools` duplicates pi-permission-system's `permission:` frontmatter | A: Overlap | 4 | 2 | 12 |
679
- | `extensions: string[]` allowlist is tool filtering disguised as lifecycle control | A: Overlap | 3 | 2 | 9 |
680
- | `filterActiveTools` ran twice (pre-bind + post-bind) to catch extension-registered tools | B: Complexity | 3 | 1 | ✓ done |
681
- | `ToolFilterConfig` existed solely to carry filtering state through the runner | C: Accidental | 2 | 1 | ✓ done |
682
- | `Agent` tool name is PascalCase — misaligns with Pi's lowercase built-in convention | D: Convention | 2 | 1 | 3 |
683
-
684
- ### Step 1: Remove `disallowed_tools` — [#237] ✅ Complete
685
-
686
- Remove the `disallowedTools` field from `AgentConfig` and all code that processes it.
687
-
688
- 1. Remove `disallowedTools` from the `AgentConfig` interface in `types.ts`.
689
- 2. Remove `disallowed_tools` parsing from custom agent frontmatter in `custom-agents.ts`.
690
- 3. Remove `disallowedSet` from `ToolFilterConfig` in `session-config.ts`.
691
- 4. Remove the `disallowedSet` construction in `assembleSessionConfig`.
692
- 5. Remove the `disallowedSet` branch from `filterActiveTools` in `agent-runner.ts`.
693
- 6. Remove `disallowed_tools` from the agent config editor UI.
694
- 7. Remove `disallowed_tools` from the agent creation wizard.
695
- 8. Update tests.
696
-
697
- - Target: `types.ts`, `custom-agents.ts`, `session-config.ts`, `agent-runner.ts`, `ui/agent-config-editor.ts`, `ui/agent-creation-wizard.ts`
698
- - Smell: A (responsibility overlap with pi-permission-system)
699
- - Outcome: users migrate to `permission:` frontmatter for tool restrictions; single source of truth for access control
700
-
701
- ### Step 2: Remove `extensions` filtering — [#238] ✅ Complete
702
-
703
- Remove the `extensions: string[]` allowlist and simplify the field to a boolean.
704
- The `extensions: false` case (used by `isolated`) is retained in this step and removed in Phase 16.
705
-
706
- 1. Change `extensions` type from `true | string[] | false` to `boolean` in `AgentConfig`.
707
- 2. Remove the `extensions` array branch from `filterActiveTools` in `agent-runner.ts`.
708
- 3. Remove `extensions` from the agent config editor and creation wizard.
709
- 4. Update custom agent frontmatter parsing to treat array values as `true` (with a warning).
710
- 5. Update tests.
711
-
712
- - Target: `types.ts`, `agent-runner.ts`, `session-config.ts`, `ui/agent-config-editor.ts`, `ui/agent-creation-wizard.ts`
713
- - Smell: A (tool filtering disguised as extension lifecycle control)
714
- - Outcome: `filterActiveTools` reduces to two concerns: recursion guard and `extensions: false` passthrough
715
-
716
- ### Step 3: Collapse `filterActiveTools` to recursion guard — [#239] ✅ Complete
717
-
718
- With Steps 1–2 complete, `filterActiveTools` had only two remaining branches: the `EXCLUDED_TOOL_NAMES` recursion guard and the `extensions === false` passthrough.
719
- Inlined the `extensions === false` passthrough into the callsite and reduced the function to its essential purpose.
720
-
721
- 1. Simplified `filterActiveTools` to filter only `EXCLUDED_TOOL_NAMES`.
722
- 2. Removed `ToolFilterConfig` — the function no longer needs a config bag.
723
- 3. Removed the pre-bind filter call — extension tools aren't in the active set pre-bind, so the guard is a no-op there.
724
- 4. Kept a single post-bind filter call for the recursion guard.
725
- 5. Flattened `SessionConfig` — removed `toolFilter: ToolFilterConfig`; `toolNames` and `extensions` are top-level fields.
726
- 6. Updated tests.
727
-
728
- - Target: `agent-runner.ts`, `session-config.ts`
729
- - Smell: B (accidental complexity), C (two-pass filter dance)
730
- - Outcome: `filterActiveTools` is a one-liner; `SessionConfig` loses one nested type; the pre-bind/post-bind dance is gone
731
-
732
- ### Step 4: Rename `Agent` tool to `subagent` — [#242] ✅ Complete
733
-
734
- Rename the `Agent` tool to `subagent` to align with Pi's built-in tool naming convention (all lowercase: `read`, `bash`, `write`, `edit`, `find`, `grep`, `ls`).
735
- The PascalCase name was inherited from tintinweb/pi-subagents (mimicking Claude Code's convention), but Pi uses lowercase for all built-in tools.
736
- The companion tools are already lowercase snake_case (`get_subagent_result`, `steer_subagent`), and nicobailon/pi-subagents already uses `subagent`.
737
-
738
- 1. Rename tool name from `"Agent"` to `"subagent"` in `agent-tool.ts`.
739
- 2. Update `label` and `promptSnippet` in the tool definition.
740
- 3. Update `EXCLUDED_TOOL_NAMES` in `agent-runner.ts`.
741
- 4. Update the fallback display name in `agent-tool.ts`.
742
- 5. Update architecture docs (tool references, domain diagrams, cross-extension section).
743
- 6. Update pi-permission-system docs that reference the `Agent` tool name.
744
- 7. Update tests.
745
-
746
- - Target: `tools/agent-tool.ts`, `lifecycle/agent-runner.ts`, `docs/`, `../pi-permission-system/docs/`
747
- - Smell: D (convention mismatch — PascalCase in a lowercase ecosystem)
748
- - Outcome: all three tools use consistent lowercase naming; aligns with Pi's built-in convention
749
-
750
- ### Step dependency diagram
751
-
752
- ```mermaid
753
- flowchart LR
754
- S1["Step 1\nRemove disallowed_tools"]
755
- S2["Step 2\nRemove extensions filtering"]
756
- S3["Step 3\nCollapse filterActiveTools"]
757
- S4["Step 4\nRename Agent to subagent"]
758
-
759
- S1 --> S3
760
- S2 --> S3
761
- ```
762
-
763
- Steps 1, 2, and 4 are independent and can proceed in parallel.
764
- Step 3 depends on Steps 1 and 2.
673
+ Phase 14 removed tool and extension policy enforcement from pi-subagents, eliminating overlap with pi-permission-system.
674
+ All four steps are closed: [#237], [#238], [#239], [#242].
675
+ See [phase-14-strip-policy.md](history/phase-14-strip-policy.md) for details.
765
676
 
766
677
  [#237]: https://github.com/gotgenes/pi-packages/issues/237
767
678
  [#238]: https://github.com/gotgenes/pi-packages/issues/238
@@ -789,7 +700,7 @@ The scheduling concern (queue, concurrency counter, drain) is tangled into `Agen
789
700
  | `resume()` duplicates observer subscribe/unsubscribe pattern | A: Redundant | 2 | 1 | 8 |
790
701
  | `exec`/`registry` relay-only deps on `AgentManager` | C: Coupling | 2 | 1 | 6 |
791
702
 
792
- ### Step 1: Evolve AgentRecord into Agent with behavior — [#227]
703
+ ### Step 1: Evolve AgentRecord into Agent with behavior — [#227] ✅ Complete
793
704
 
794
705
  Rename `AgentRecord` → `Agent` (or wrap it).
795
706
  Move per-agent behavior from `AgentManager` into the agent:
@@ -854,12 +765,12 @@ The agent manages its own observer subscription lifecycle.
854
765
 
855
766
  ```mermaid
856
767
  flowchart LR
857
- S1["Step 1\nAgent with behavior"]
858
- S2["Step 2\nasync startAgent"]
859
- S3["Step 3\nonSessionCreated observer"]
860
- S4["Step 4\nConcurrencyQueue"]
861
- S5["Step 5\nrelay deps"]
862
- S6["Step 6\nresume unification"]
768
+ S1["Step 1<br/>Agent with behavior"]
769
+ S2["Step 2<br/>async startAgent"]
770
+ S3["Step 3<br/>onSessionCreated observer"]
771
+ S4["Step 4<br/>ConcurrencyQueue"]
772
+ S5["Step 5<br/>relay deps"]
773
+ S6["Step 6<br/>resume unification"]
863
774
 
864
775
  S1 --> S2
865
776
  S1 --> S6
@@ -896,7 +807,7 @@ By this point the core is minimal and stable — the API boundary has been prove
896
807
 
897
808
  ## Refactoring history
898
809
 
899
- Phases 1–5 and 7–12 are complete.
810
+ Phases 1–5, 7–14 are complete.
900
811
  Phase 6 (UI extraction to a separate package) is deferred.
901
812
  Detailed records are preserved in per-phase history files:
902
813
 
@@ -915,7 +826,7 @@ Detailed records are preserved in per-phase history files:
915
826
  | 11 | Closure factories to classes | Complete | [phase-11-closure-to-class.md](history/phase-11-closure-to-class.md) |
916
827
  | 12 | Complexity reduction and test fixture extraction | Complete | [phase-12-complexity-test-fixtures.md](history/phase-12-complexity-test-fixtures.md) |
917
828
  | 13 | Remaining structural smells | Complete | [phase-13-remaining-smells.md](history/phase-13-remaining-smells.md) |
918
- | 14 | Strip policy from core | Planned | |
829
+ | 14 | Strip policy from core | Complete | [phase-14-strip-policy.md](history/phase-14-strip-policy.md) |
919
830
  | 15 | Domain model evolution | Planned | — |
920
831
  | 16 | Invert dependencies | Planned | — |
921
832
  | 17 | Extract UI to separate package | Planned | — |
@@ -936,7 +847,7 @@ Detailed records are preserved in per-phase history files:
936
847
  | Phase 11 | #192, #193, #194, #195, #196 | SessionContext, runtime queries, interface alignment, tool classes, runner/menu classes, index.ts simplification |
937
848
  | Phase 12 | #205, #206, #207, #208 | renderWidgetLines, showAgentDetail, widget update, shared test fixtures |
938
849
  | Phase 13 | #214, #215, #216, #217, #218, #219 | Closure-to-class, buildParentContext, startAgent decomp, overwrite guard, settings SDK, test duplication |
939
- | Phase 14 | #237, #238, #239 | Remove disallowed_tools, remove extensions filtering, collapse filterActiveTools |
850
+ | Phase 14 | #237, #238, #239, #242 | Remove disallowed_tools, remove extensions filtering, collapse filterActiveTools, rename Agent to subagent |
940
851
  | Phase 15 | #227, #228, #229, #230, #231, #232 | Agent domain model, async startAgent, onSessionCreated observer, ConcurrencyQueue, relay deps, resume unification |
941
852
 
942
853
  The remaining open issue is #22 (parent-session resolution), a cross-extension track that does not gate the structural work.
@@ -0,0 +1,49 @@
1
+ # Phase 14: Strip policy from core
2
+
3
+ ## Summary
4
+
5
+ Phase 14 removed tool and extension policy enforcement from pi-subagents.
6
+ This code duplicated what pi-permission-system already provides with richer semantics (allow/ask/deny vs. binary hide).
7
+ Removing it simplified `runAgent`, shrunk `AgentConfig` and `SessionConfig`, and prepared a cleaner codebase for Phase 15's domain-model work.
8
+
9
+ All four steps are closed: [#237], [#238], [#239], [#242].
10
+
11
+ ## Steps
12
+
13
+ ### Step 1: Remove `disallowed_tools` — [#237]
14
+
15
+ Removed the `disallowedTools` field from `AgentConfig` and all code that processed it.
16
+ Users migrate to `permission:` frontmatter for tool restrictions.
17
+
18
+ - Target: `types.ts`, `custom-agents.ts`, `session-config.ts`, `agent-runner.ts`, `ui/agent-config-editor.ts`, `ui/agent-creation-wizard.ts`
19
+ - Outcome: single source of truth for access control in pi-permission-system
20
+
21
+ ### Step 2: Remove `extensions` filtering — [#238]
22
+
23
+ Removed the `extensions: string[]` allowlist and simplified the field to a boolean.
24
+ The `extensions: false` case (used by `isolated`) was retained for Phase 16.
25
+
26
+ - Target: `types.ts`, `agent-runner.ts`, `session-config.ts`, `ui/agent-config-editor.ts`, `ui/agent-creation-wizard.ts`
27
+ - Outcome: `filterActiveTools` reduced to two concerns: recursion guard and `extensions: false` passthrough
28
+
29
+ ### Step 3: Collapse `filterActiveTools` to recursion guard — [#239]
30
+
31
+ With Steps 1–2 complete, `filterActiveTools` was reduced to its essential purpose: filtering `EXCLUDED_TOOL_NAMES` to prevent recursive agent spawning.
32
+
33
+ - Removed `ToolFilterConfig` — the function no longer needs a config bag.
34
+ - Removed the pre-bind filter call — extension tools aren't in the active set pre-bind.
35
+ - Flattened `SessionConfig` — removed `toolFilter: ToolFilterConfig`; `toolNames` and `extensions` are top-level fields.
36
+ - Target: `agent-runner.ts`, `session-config.ts`
37
+ - Outcome: `filterActiveTools` is a one-liner; the pre-bind/post-bind dance is gone
38
+
39
+ ### Step 4: Rename `Agent` tool to `subagent` — [#242]
40
+
41
+ Renamed the `Agent` tool to `subagent` to align with Pi's built-in tool naming convention (all lowercase).
42
+
43
+ - Target: `tools/agent-tool.ts`, `lifecycle/agent-runner.ts`, `docs/`, `../pi-permission-system/docs/`
44
+ - Outcome: all three tools use consistent lowercase naming
45
+
46
+ [#237]: https://github.com/gotgenes/pi-packages/issues/237
47
+ [#238]: https://github.com/gotgenes/pi-packages/issues/238
48
+ [#239]: https://github.com/gotgenes/pi-packages/issues/239
49
+ [#242]: https://github.com/gotgenes/pi-packages/issues/242