@narumitw/pi-subagents 2.0.6 → 2.1.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 (180) hide show
  1. package/README.md +171 -60
  2. package/dist/chunks/{auto-transport-SY2VHUFH.ts → auto-transport-FUUKFDIG.ts} +6 -6
  3. package/dist/chunks/{capability-grant-CGEWOEKE.ts → capability-grant-PR72SWWS.ts} +4 -4
  4. package/dist/chunks/{chunk-CBP76ARQ.ts → chunk-2LMJU25E.ts} +172 -74
  5. package/dist/chunks/chunk-2LMJU25E.ts.map +7 -0
  6. package/dist/chunks/{chunk-DPPVEQAM.ts → chunk-4AQSF7AS.ts} +1 -1
  7. package/dist/chunks/chunk-4AQSF7AS.ts.map +7 -0
  8. package/dist/chunks/chunk-6H6TBBED.ts +108 -0
  9. package/dist/chunks/chunk-6H6TBBED.ts.map +7 -0
  10. package/dist/chunks/{chunk-YBUWBRF7.ts → chunk-6NSJVPXX.ts} +6 -16
  11. package/dist/chunks/{chunk-YBUWBRF7.ts.map → chunk-6NSJVPXX.ts.map} +2 -2
  12. package/dist/chunks/{chunk-DSOOH73Y.ts → chunk-7AAJEUSL.ts} +3 -3
  13. package/dist/chunks/{chunk-DSOOH73Y.ts.map → chunk-7AAJEUSL.ts.map} +2 -2
  14. package/dist/chunks/{chunk-7QPPBBXZ.ts → chunk-D4CR7T73.ts} +21 -3
  15. package/dist/chunks/chunk-D4CR7T73.ts.map +7 -0
  16. package/dist/chunks/{chunk-NIF42QMF.ts → chunk-FEVPWRMU.ts} +7 -4
  17. package/dist/chunks/chunk-FEVPWRMU.ts.map +7 -0
  18. package/dist/chunks/{chunk-S2IWVK3J.ts → chunk-ILEQ27AL.ts} +3 -2
  19. package/dist/chunks/chunk-ILEQ27AL.ts.map +7 -0
  20. package/dist/chunks/{chunk-DQMN4OYM.ts → chunk-ITVWPNU4.ts} +12 -106
  21. package/dist/chunks/chunk-ITVWPNU4.ts.map +7 -0
  22. package/dist/chunks/{chunk-QDVGH2X7.ts → chunk-IWC32VPY.ts} +2 -1
  23. package/dist/chunks/{chunk-QDVGH2X7.ts.map → chunk-IWC32VPY.ts.map} +2 -2
  24. package/dist/chunks/{chunk-I2FAK44T.ts → chunk-JSZIP73U.ts} +48 -10
  25. package/dist/chunks/chunk-JSZIP73U.ts.map +7 -0
  26. package/dist/chunks/{chunk-ZHTNCZIA.ts → chunk-JU6LUNLP.ts} +2 -2
  27. package/dist/chunks/{chunk-PSK43Y6A.ts → chunk-LASD73CM.ts} +2 -2
  28. package/dist/chunks/{chunk-C4L6P266.ts → chunk-LEOYDZI3.ts} +1 -1
  29. package/dist/chunks/{chunk-C4L6P266.ts.map → chunk-LEOYDZI3.ts.map} +2 -2
  30. package/dist/chunks/{chunk-H3BFJ7HJ.ts → chunk-LL4LP2T7.ts} +5 -5
  31. package/dist/chunks/chunk-N2T5IN4X.ts +18 -0
  32. package/dist/chunks/chunk-N2T5IN4X.ts.map +7 -0
  33. package/dist/chunks/chunk-NLT67IZS.ts +322 -0
  34. package/dist/chunks/chunk-NLT67IZS.ts.map +7 -0
  35. package/dist/chunks/{chunk-G3RSMSXJ.ts → chunk-NTRPLF46.ts} +1 -1
  36. package/dist/chunks/chunk-NTRPLF46.ts.map +7 -0
  37. package/dist/chunks/{chunk-EFBPISNT.ts → chunk-PBZMBTNJ.ts} +104 -103
  38. package/dist/chunks/chunk-PBZMBTNJ.ts.map +7 -0
  39. package/dist/chunks/{chunk-SCZ33MYW.ts → chunk-PGLSFLYW.ts} +2 -2
  40. package/dist/chunks/{chunk-O4VO6JUJ.ts → chunk-TM2R67J3.ts} +3 -3
  41. package/dist/chunks/{chunk-QBORTI4W.ts → chunk-TMZRHIIK.ts} +32 -3
  42. package/dist/chunks/chunk-TMZRHIIK.ts.map +7 -0
  43. package/dist/chunks/chunk-TZ34IQ3M.ts +59 -0
  44. package/dist/chunks/chunk-TZ34IQ3M.ts.map +7 -0
  45. package/dist/chunks/{chunk-7OBINKFM.ts → chunk-VDG7LTYE.ts} +11 -11
  46. package/dist/chunks/chunk-VDG7LTYE.ts.map +7 -0
  47. package/dist/chunks/{chunk-AEUYS7JC.ts → chunk-X4NMONPE.ts} +1 -1
  48. package/dist/chunks/chunk-X4NMONPE.ts.map +7 -0
  49. package/dist/chunks/{chunk-HKC4ES4B.ts → chunk-YPJEN6NU.ts} +2 -2
  50. package/dist/chunks/{chunk-434NII74.ts → chunk-YU53SHA7.ts} +54 -8
  51. package/dist/chunks/chunk-YU53SHA7.ts.map +7 -0
  52. package/dist/chunks/{completion-delivery-YPOWSSV3.ts → completion-delivery-RSJU6BXL.ts} +5 -4
  53. package/dist/chunks/{config-status-J4GPWP46.ts → config-status-FKGDECZ3.ts} +7 -6
  54. package/dist/chunks/{config-ui-2YUCUEBM.ts → config-ui-ABHYNGQ7.ts} +297 -231
  55. package/dist/chunks/config-ui-ABHYNGQ7.ts.map +7 -0
  56. package/dist/chunks/{consult-IV7UBNQQ.ts → consult-LJU3IQY5.ts} +14 -13
  57. package/dist/chunks/consult-LJU3IQY5.ts.map +7 -0
  58. package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts → create-stateful-transport-JWC2EFYL.ts} +6 -6
  59. package/dist/chunks/{delegation-contract-WJPT4FVS.ts → delegation-contract-LA56I5DT.ts} +2 -2
  60. package/dist/chunks/{discovery-K25T3SH4.ts → discovery-MIFB2U4Y.ts} +3 -3
  61. package/dist/chunks/{execution-LA7HN5YF.ts → execution-Q2JZLKJA.ts} +19 -16
  62. package/dist/chunks/execution-Q2JZLKJA.ts.map +7 -0
  63. package/dist/chunks/{in-process-transport-4RF3J6XK.ts → in-process-transport-HJ6TZXC3.ts} +9 -9
  64. package/dist/chunks/{inspect-XV2QALMR.ts → inspect-UH2TKH6E.ts} +25 -10
  65. package/dist/chunks/inspect-UH2TKH6E.ts.map +7 -0
  66. package/dist/chunks/{persistence-VSGXAW4P.ts → persistence-UY3PY6E5.ts} +11 -7
  67. package/dist/chunks/persistence-UY3PY6E5.ts.map +7 -0
  68. package/dist/chunks/{registry-E6XPJB7L.ts → registry-BT54L6CY.ts} +136 -15
  69. package/dist/chunks/registry-BT54L6CY.ts.map +7 -0
  70. package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts → retained-semantic-state-GM75FZGE.ts} +3 -3
  71. package/dist/chunks/{rpc-transport-NEHBHWX4.ts → rpc-transport-7R7DVCEB.ts} +12 -16
  72. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +7 -0
  73. package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts → spawn-idempotency-BNHOSMZW.ts} +2 -2
  74. package/dist/chunks/{subprocess-transport-NSHOGDC4.ts → subprocess-transport-VHZJRBTW.ts} +15 -14
  75. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +7 -0
  76. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +164 -0
  77. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +7 -0
  78. package/dist/index.ts +682 -82
  79. package/dist/index.ts.map +3 -3
  80. package/docs/async-runtime-protocol.md +83 -0
  81. package/docs/implementation-notes/pi-subagents-capability-matrix.md +62 -0
  82. package/docs/implementation-notes/pi-subagents-current-direction.md +99 -0
  83. package/docs/implementation-notes/pi-subagents-rpc-v1.md +153 -0
  84. package/docs/pi-subagents-diagrams.md +183 -0
  85. package/package.json +9 -8
  86. package/src/agents/types.ts +2 -0
  87. package/src/async-subagent-benchmark.ts +532 -0
  88. package/src/completion-delivery.ts +71 -4
  89. package/src/completion-render.ts +1 -0
  90. package/src/completion-requirement.ts +479 -0
  91. package/src/config-registration.ts +5 -5
  92. package/src/config-status.ts +66 -70
  93. package/src/config-ui.ts +244 -150
  94. package/src/consult-registration.ts +4 -12
  95. package/src/consult-resources.ts +1 -1
  96. package/src/consult.ts +3 -8
  97. package/src/delegation-contract.ts +55 -9
  98. package/src/execution-plan.ts +1 -1
  99. package/src/execution-ui.ts +40 -29
  100. package/src/execution.ts +2 -3
  101. package/src/inspect.ts +24 -1
  102. package/src/orchestration-metrics.ts +1 -1
  103. package/src/panel-execution.ts +2 -3
  104. package/src/panel-failure.ts +1 -1
  105. package/src/panel-render.ts +1 -1
  106. package/src/parallel-limit-ui.ts +6 -5
  107. package/src/params.ts +2 -1
  108. package/src/persistence.ts +9 -0
  109. package/src/process-control.ts +43 -0
  110. package/src/registry-types.ts +5 -0
  111. package/src/registry.ts +162 -18
  112. package/src/render.ts +2 -1
  113. package/src/rpc-transport.ts +1 -1
  114. package/src/runner-outcome.ts +1 -1
  115. package/src/runner-result.ts +1 -1
  116. package/src/runner-types.ts +102 -0
  117. package/src/runner.ts +11 -192
  118. package/src/session-guidance-contract.ts +309 -0
  119. package/src/settings/inspection.ts +27 -0
  120. package/src/settings/schema.ts +9 -0
  121. package/src/settings-reader.ts +7 -0
  122. package/src/settings.ts +20 -0
  123. package/src/spawn-idempotency.ts +5 -0
  124. package/src/stateful-agent-view.ts +15 -19
  125. package/src/stateful-guidance.ts +11 -18
  126. package/src/stateful-limit-ui.ts +23 -20
  127. package/src/stateful-limits.ts +10 -10
  128. package/src/stateful-registration.ts +126 -36
  129. package/src/stateful-render.ts +27 -2
  130. package/src/subagent-details.ts +43 -0
  131. package/src/subagents-extension.ts +116 -68
  132. package/src/subagents.ts +2 -0
  133. package/src/subprocess-transport.ts +2 -1
  134. package/src/supervision.ts +2 -1
  135. package/src/timeout-finalization.ts +1 -1
  136. package/src/tool-schema-compatibility.ts +73 -0
  137. package/src/transport-types.ts +6 -0
  138. package/src/transport-ui.ts +18 -46
  139. package/src/usage-recording-config.ts +13 -0
  140. package/src/usage-recording-store.ts +183 -0
  141. package/src/usage-recording.ts +478 -0
  142. package/src/verification-harness.ts +1 -1
  143. package/src/workflow-ui.ts +17 -9
  144. package/dist/chunks/chunk-434NII74.ts.map +0 -7
  145. package/dist/chunks/chunk-7OBINKFM.ts.map +0 -7
  146. package/dist/chunks/chunk-7QPPBBXZ.ts.map +0 -7
  147. package/dist/chunks/chunk-AEUYS7JC.ts.map +0 -7
  148. package/dist/chunks/chunk-CBP76ARQ.ts.map +0 -7
  149. package/dist/chunks/chunk-DPPVEQAM.ts.map +0 -7
  150. package/dist/chunks/chunk-DQMN4OYM.ts.map +0 -7
  151. package/dist/chunks/chunk-EFBPISNT.ts.map +0 -7
  152. package/dist/chunks/chunk-G3RSMSXJ.ts.map +0 -7
  153. package/dist/chunks/chunk-I2FAK44T.ts.map +0 -7
  154. package/dist/chunks/chunk-NIF42QMF.ts.map +0 -7
  155. package/dist/chunks/chunk-QBORTI4W.ts.map +0 -7
  156. package/dist/chunks/chunk-S2IWVK3J.ts.map +0 -7
  157. package/dist/chunks/config-ui-2YUCUEBM.ts.map +0 -7
  158. package/dist/chunks/consult-IV7UBNQQ.ts.map +0 -7
  159. package/dist/chunks/execution-LA7HN5YF.ts.map +0 -7
  160. package/dist/chunks/inspect-XV2QALMR.ts.map +0 -7
  161. package/dist/chunks/persistence-VSGXAW4P.ts.map +0 -7
  162. package/dist/chunks/registry-E6XPJB7L.ts.map +0 -7
  163. package/dist/chunks/rpc-transport-NEHBHWX4.ts.map +0 -7
  164. package/dist/chunks/subprocess-transport-NSHOGDC4.ts.map +0 -7
  165. /package/dist/chunks/{auto-transport-SY2VHUFH.ts.map → auto-transport-FUUKFDIG.ts.map} +0 -0
  166. /package/dist/chunks/{capability-grant-CGEWOEKE.ts.map → capability-grant-PR72SWWS.ts.map} +0 -0
  167. /package/dist/chunks/{chunk-ZHTNCZIA.ts.map → chunk-JU6LUNLP.ts.map} +0 -0
  168. /package/dist/chunks/{chunk-PSK43Y6A.ts.map → chunk-LASD73CM.ts.map} +0 -0
  169. /package/dist/chunks/{chunk-H3BFJ7HJ.ts.map → chunk-LL4LP2T7.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-SCZ33MYW.ts.map → chunk-PGLSFLYW.ts.map} +0 -0
  171. /package/dist/chunks/{chunk-O4VO6JUJ.ts.map → chunk-TM2R67J3.ts.map} +0 -0
  172. /package/dist/chunks/{chunk-HKC4ES4B.ts.map → chunk-YPJEN6NU.ts.map} +0 -0
  173. /package/dist/chunks/{completion-delivery-YPOWSSV3.ts.map → completion-delivery-RSJU6BXL.ts.map} +0 -0
  174. /package/dist/chunks/{config-status-J4GPWP46.ts.map → config-status-FKGDECZ3.ts.map} +0 -0
  175. /package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts.map → create-stateful-transport-JWC2EFYL.ts.map} +0 -0
  176. /package/dist/chunks/{delegation-contract-WJPT4FVS.ts.map → delegation-contract-LA56I5DT.ts.map} +0 -0
  177. /package/dist/chunks/{discovery-K25T3SH4.ts.map → discovery-MIFB2U4Y.ts.map} +0 -0
  178. /package/dist/chunks/{in-process-transport-4RF3J6XK.ts.map → in-process-transport-HJ6TZXC3.ts.map} +0 -0
  179. /package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts.map → retained-semantic-state-GM75FZGE.ts.map} +0 -0
  180. /package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts.map → spawn-idempotency-BNHOSMZW.ts.map} +0 -0
@@ -1,17 +1,18 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
- import "./chunk-SCZ33MYW.ts";
3
+ import "./chunk-PGLSFLYW.ts";
4
4
  import {
5
5
  formatStatefulAgentLine
6
- } from "./chunk-CBP76ARQ.ts";
7
- import "./chunk-S2IWVK3J.ts";
6
+ } from "./chunk-2LMJU25E.ts";
7
+ import "./chunk-TZ34IQ3M.ts";
8
+ import "./chunk-ILEQ27AL.ts";
8
9
  import "./chunk-P7OH4XMF.ts";
9
10
  import "./chunk-N7BLVXKK.ts";
10
11
  import "./chunk-ONDTY4EL.ts";
11
- import "./chunk-O4VO6JUJ.ts";
12
+ import "./chunk-TM2R67J3.ts";
12
13
  import {
13
14
  discoverAgents
14
- } from "./chunk-PSK43Y6A.ts";
15
+ } from "./chunk-LASD73CM.ts";
15
16
  import "./chunk-RSUXZD6S.ts";
16
17
  import {
17
18
  applyStatefulLimitSetting,
@@ -31,7 +32,7 @@ import {
31
32
  statefulLimitListScreen,
32
33
  statusLines,
33
34
  workflowLabel
34
- } from "./chunk-EFBPISNT.ts";
35
+ } from "./chunk-PBZMBTNJ.ts";
35
36
  import "./chunk-KMGKCEO4.ts";
36
37
  import {
37
38
  sameToolSet,
@@ -43,8 +44,12 @@ import {
43
44
  updateConsultResourceSetting,
44
45
  updateCwdPolicySetting,
45
46
  updateDelegationWorkflowSetting,
46
- updateStatefulTransportSetting
47
- } from "./chunk-7QPPBBXZ.ts";
47
+ updateStatefulTransportSetting,
48
+ updateUsageRecordingSetting
49
+ } from "./chunk-D4CR7T73.ts";
50
+ import {
51
+ USAGE_RECORDING_RETENTION_DAYS
52
+ } from "./chunk-N2T5IN4X.ts";
48
53
  import {
49
54
  hasOwn,
50
55
  inspectBlockingParallelLimitSettings,
@@ -53,20 +58,22 @@ import {
53
58
  inspectCwdPolicySettings,
54
59
  inspectDelegationWorkflowSettings,
55
60
  inspectStatefulTransportSettings,
61
+ inspectUsageRecordingSettings,
56
62
  readSubagentSettings
57
- } from "./chunk-QBORTI4W.ts";
63
+ } from "./chunk-TMZRHIIK.ts";
58
64
  import {
59
65
  isStatefulLimitField
60
- } from "./chunk-7OBINKFM.ts";
61
- import "./chunk-DPPVEQAM.ts";
62
- import "./chunk-434NII74.ts";
63
- import "./chunk-C4L6P266.ts";
64
- import "./chunk-QDVGH2X7.ts";
66
+ } from "./chunk-VDG7LTYE.ts";
67
+ import "./chunk-4AQSF7AS.ts";
68
+ import "./chunk-YU53SHA7.ts";
69
+ import "./chunk-LEOYDZI3.ts";
70
+ import "./chunk-IWC32VPY.ts";
65
71
  import "./chunk-BFK2Z4ZF.ts";
72
+ import "./chunk-NLT67IZS.ts";
66
73
  import {
67
74
  safeTerminalLine
68
75
  } from "./chunk-SWGQLFSD.ts";
69
- import "./chunk-I2FAK44T.ts";
76
+ import "./chunk-JSZIP73U.ts";
70
77
  import {
71
78
  MAX_BLOCKING_PARALLEL_CONCURRENCY,
72
79
  MAX_CONFIGURABLE_PARALLEL_TASKS,
@@ -79,8 +86,8 @@ function executionAgentPickerScreen(agents) {
79
86
  const configured = readSubagentSettings()?.agents ?? {};
80
87
  return {
81
88
  kind: "actions",
82
- title: "Agent Execution Defaults",
83
- lines: ["Choose an agent to edit its inherited model, thinking, or timeout."],
89
+ title: "Model, Thinking, and Time Limit",
90
+ lines: ["Choose a subagent. A specific request can override these starting values."],
84
91
  items: [
85
92
  ...agents.map((agent) => {
86
93
  const value = configured[agent.name];
@@ -88,7 +95,7 @@ function executionAgentPickerScreen(agents) {
88
95
  id: agent.name,
89
96
  label: safeTerminalLine(agent.name),
90
97
  description: safeTerminalLine(
91
- `${agent.source} \xB7 model ${value?.model ?? agent.model ?? "inherited"} \xB7 thinking ${value?.thinkingLevel ?? agent.thinkingLevel ?? "inherited"} \xB7 timeout ${value?.timeoutMs ?? agent.timeoutMs ?? "inherited"}`
98
+ `${agent.source} \xB7 model ${value?.model ?? agent.model ?? "default"} \xB7 thinking ${value?.thinkingLevel ?? agent.thinkingLevel ?? "default"} \xB7 time limit ${value?.timeoutMs ?? agent.timeoutMs ?? "default"}`
92
99
  ),
93
100
  action: "pick-execution-agent"
94
101
  };
@@ -102,8 +109,8 @@ function executionAgentScreen(agent) {
102
109
  if (!agent) {
103
110
  return {
104
111
  kind: "actions",
105
- title: "Agent Execution Defaults",
106
- lines: ["No agent selected."],
112
+ title: "Model, Thinking, and Time Limit",
113
+ lines: ["No subagent selected."],
107
114
  items: [{ id: "back", label: "Back", action: "back" }],
108
115
  hint: "back"
109
116
  };
@@ -111,21 +118,21 @@ function executionAgentScreen(agent) {
111
118
  const configured = readSubagentSettings()?.agents?.[agent.name];
112
119
  return {
113
120
  kind: "actions",
114
- title: `${safeTerminalLine(agent.name)} execution`,
121
+ title: `${safeTerminalLine(agent.name)} defaults`,
115
122
  lines: [
116
- `Model: ${safeTerminalLine(configured?.model ?? agent.model ?? "inherited")}`,
117
- `Thinking: ${configured?.thinkingLevel ?? agent.thinkingLevel ?? "inherited"}`,
118
- `Timeout: ${configured?.timeoutMs ?? agent.timeoutMs ?? "inherited"}`,
119
- "Explicit tool-call values remain authoritative."
123
+ `Model: ${safeTerminalLine(configured?.model ?? agent.model ?? "agent or Pi default")}`,
124
+ `Thinking: ${configured?.thinkingLevel ?? agent.thinkingLevel ?? "agent or Pi default"}`,
125
+ `Time limit: ${configured?.timeoutMs ?? agent.timeoutMs ?? "agent or Pi default"}`,
126
+ "A specific subagent request can override these defaults."
120
127
  ],
121
128
  items: [
122
129
  { id: "thinking", label: "Thinking level", to: "execution-thinking" },
123
130
  { id: "model", label: "Model", to: "execution-model" },
124
- { id: "timeout", label: "Timeout", to: "execution-timeout" },
131
+ { id: "timeout", label: "Time limit", to: "execution-timeout" },
125
132
  {
126
133
  id: "reset",
127
- label: "Reset execution defaults",
128
- description: "Restore frontmatter or Pi inheritance without changing tools",
134
+ label: "Use agent or Pi defaults",
135
+ description: "Remove custom model, thinking, and time limit without changing tools",
129
136
  action: "reset-agent-execution"
130
137
  },
131
138
  { id: "back", label: "Back", action: "back" }
@@ -142,9 +149,18 @@ function executionThinkingScreen(agent) {
142
149
  {
143
150
  id: "thinking",
144
151
  label: "Default thinking level",
145
- description: "Explicit spawn or blocking call values still win.",
146
- currentValue: configured?.thinkingLevel ?? agent.thinkingLevel ?? "Inherited",
147
- values: ["Inherited", "off", "minimal", "low", "medium", "high", "xhigh", "max"],
152
+ description: "A specific subagent request can override this value.",
153
+ currentValue: configured?.thinkingLevel ?? agent.thinkingLevel ?? "Use agent or Pi default",
154
+ values: [
155
+ "Use agent or Pi default",
156
+ "off",
157
+ "minimal",
158
+ "low",
159
+ "medium",
160
+ "high",
161
+ "xhigh",
162
+ "max"
163
+ ],
148
164
  action: "set-agent-thinking"
149
165
  }
150
166
  ] : [],
@@ -158,14 +174,14 @@ function executionModelScreen(agent, ctx) {
158
174
  kind: "actions",
159
175
  title: agent ? `${safeTerminalLine(agent.name)} model` : "Agent model",
160
176
  lines: [
161
- `Current: ${safeTerminalLine(configured?.model ?? agent?.model ?? "inherited")}`,
162
- "Choose a session-available model or enter a custom Pi model pattern."
177
+ `Current: ${safeTerminalLine(configured?.model ?? agent?.model ?? "agent or Pi default")}`,
178
+ "Choose an available model or enter a custom Pi model pattern."
163
179
  ],
164
180
  items: agent ? [
165
181
  {
166
182
  id: "model:__inherited__",
167
- label: "Inherited",
168
- description: "Use frontmatter or active Pi model resolution",
183
+ label: "Use agent or Pi default",
184
+ description: "Remove the custom model setting",
169
185
  action: "set-agent-model"
170
186
  },
171
187
  ...models.map((model) => ({
@@ -190,9 +206,9 @@ function executionModelInputScreen(agent) {
190
206
  kind: "input",
191
207
  title: agent ? `${safeTerminalLine(agent.name)} model` : "Agent model",
192
208
  lines: [
193
- `Current: ${safeTerminalLine(configured?.model ?? agent?.model ?? "inherited")}`,
209
+ `Current: ${safeTerminalLine(configured?.model ?? agent?.model ?? "agent or Pi default")}`,
194
210
  "Enter a Pi CLI model pattern, including an optional :thinking suffix.",
195
- "Use Reset execution defaults to restore inheritance."
211
+ "Use agent or Pi defaults to remove this custom value."
196
212
  ],
197
213
  placeholder: "provider/model or model pattern",
198
214
  action: "set-agent-model",
@@ -203,20 +219,20 @@ function executionTimeoutInputScreen(agent) {
203
219
  const configured = agent ? readSubagentSettings()?.agents?.[agent.name] : void 0;
204
220
  return {
205
221
  kind: "input",
206
- title: agent ? `${safeTerminalLine(agent.name)} timeout` : "Agent timeout",
222
+ title: agent ? `${safeTerminalLine(agent.name)} time limit` : "Agent time limit",
207
223
  lines: [
208
- `Current: ${configured?.timeoutMs ?? agent?.timeoutMs ?? "inherited"}`,
224
+ `Current: ${configured?.timeoutMs ?? agent?.timeoutMs ?? "agent or Pi default"}`,
209
225
  `Allowed: 1-${MAX_SUBAGENT_TIMEOUT_MS} milliseconds.`,
210
- "Use Reset execution defaults to restore inheritance."
226
+ "Use agent or Pi defaults to remove this custom value."
211
227
  ],
212
- placeholder: "Timeout in milliseconds",
228
+ placeholder: "Time limit in milliseconds",
213
229
  action: "set-agent-timeout",
214
230
  hint: "back"
215
231
  };
216
232
  }
217
233
  function applyAgentThinking(agent, value, ctx) {
218
234
  if (!agent) return { kind: "rejected" };
219
- const thinkingLevel = value === "Inherited" ? void 0 : value;
235
+ const thinkingLevel = value === "Use agent or Pi default" ? void 0 : value;
220
236
  if (thinkingLevel !== void 0 && !["off", "minimal", "low", "medium", "high", "xhigh", "max"].includes(thinkingLevel)) {
221
237
  return { kind: "rejected" };
222
238
  }
@@ -236,12 +252,12 @@ function applyAgentTimeout(agent, value, ctx) {
236
252
  if (!agent) return { kind: "rejected" };
237
253
  const normalized = value?.trim() ?? "";
238
254
  if (!/^\d+$/u.test(normalized)) {
239
- ctx.ui.notify("Timeout must be a whole number of milliseconds.", "warning");
255
+ ctx.ui.notify("Time limit must be a whole number of milliseconds.", "warning");
240
256
  return { kind: "rejected" };
241
257
  }
242
258
  const timeoutMs = Number(normalized);
243
259
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > MAX_SUBAGENT_TIMEOUT_MS) {
244
- ctx.ui.notify(`Timeout must be between 1 and ${MAX_SUBAGENT_TIMEOUT_MS}.`, "warning");
260
+ ctx.ui.notify(`Time limit must be between 1 and ${MAX_SUBAGENT_TIMEOUT_MS}.`, "warning");
245
261
  return { kind: "rejected" };
246
262
  }
247
263
  return saveAgentPatch(agent.name, { timeoutMs }, ctx, "timeout");
@@ -283,11 +299,12 @@ function blockingParallelLimitScreen(runtime) {
283
299
  const limit = inspectBlockingParallelLimitSettings();
284
300
  return {
285
301
  kind: "input",
286
- title: "Maximum Parallel Workers",
302
+ title: "Blocking Worker Limit",
287
303
  lines: [
288
- `Current: ${runtime.getMaxParallelTasks()} worker tasks per blocking call`,
304
+ "This applies only to requests that make Pi wait for delegated work.",
305
+ `Current: ${runtime.getMaxParallelTasks()} subagents per blocking request`,
289
306
  `Allowed: 1-${MAX_CONFIGURABLE_PARALLEL_TASKS}`,
290
- `Parallel execution still starts at most ${MAX_BLOCKING_PARALLEL_CONCURRENCY} workers at once.`,
307
+ `Pi still starts at most ${MAX_BLOCKING_PARALLEL_CONCURRENCY} of them at once.`,
291
308
  safeTerminalText(limit.path)
292
309
  ],
293
310
  placeholder: "Enter a whole number",
@@ -352,14 +369,14 @@ function applyBlockingParallelLimitSetting(value, ctx, runtime) {
352
369
  }
353
370
  }
354
371
  ctx.ui.notify(
355
- `${settingsChanged ? "Saved and " : ""}applied: maximum ${next} parallel workers per blocking call.`,
372
+ `${settingsChanged ? "Saved and " : ""}applied: maximum ${next} subagents per blocking request.`,
356
373
  "info"
357
374
  );
358
375
  return { kind: "back" };
359
376
  }
360
377
  function notifyValidationError(ctx) {
361
378
  ctx.ui.notify(
362
- `Maximum parallel workers must be a whole number from 1 to ${MAX_CONFIGURABLE_PARALLEL_TASKS}.`,
379
+ `Blocking worker limit must be a whole number from 1 to ${MAX_CONFIGURABLE_PARALLEL_TASKS}.`,
363
380
  "warning"
364
381
  );
365
382
  }
@@ -374,23 +391,23 @@ function formatError2(error) {
374
391
  var TRANSPORT_OPTIONS = [
375
392
  {
376
393
  value: "subprocess",
377
- label: "Fresh subprocess",
378
- description: "Compatibility path with a fresh isolated Pi process for every turn."
394
+ label: "Fresh process",
395
+ description: "Start a separate Pi process for every turn. Most compatible, but slower for follow-ups."
379
396
  },
380
397
  {
381
398
  value: "in-process",
382
- label: "In process",
383
- description: "Lowest follow-up overhead for built-in tools, with shared memory and crash boundary."
399
+ label: "Inside Pi",
400
+ description: "Run built-in tools inside Pi for faster follow-ups. Shares Pi's memory and crash boundary."
384
401
  },
385
402
  {
386
403
  value: "rpc",
387
- label: "Persistent RPC process",
388
- description: "Retain native history in one isolated Pi process per active retained agent."
404
+ label: "Persistent process (RPC)",
405
+ description: "Keep one separate Pi process per background subagent so follow-ups preserve history."
389
406
  },
390
407
  {
391
408
  value: "auto",
392
- label: "Automatic",
393
- description: "Read-only built-ins use in-process, write-capable built-ins use RPC, and custom tools use subprocess."
409
+ label: "Automatic \xB7 Recommended",
410
+ description: "Let Pi choose a compatible method for each subagent and its tools."
394
411
  }
395
412
  ];
396
413
  function transportSettingsScreen(runtime) {
@@ -398,12 +415,13 @@ function transportSettingsScreen(runtime) {
398
415
  const current = runtime.getRuntimeStatus();
399
416
  return {
400
417
  kind: "actions",
401
- title: configured.error ? "Detached Transport \xB7 Read only" : "Detached Transport",
418
+ title: configured.error ? "Background Agent Transport \xB7 Read only" : "Background Agent Transport",
402
419
  lines: [
420
+ "Advanced: choose how Pi hosts background subagents.",
403
421
  `Current session: ${transportLabel(current.transport)}`,
404
422
  `Configured after reload: ${transportLabel(configured.value)} (${configured.source})`,
405
- "Transport isolation is not a filesystem or network sandbox.",
406
- "RPC v1 disables child extensions and supports built-in Pi tools only.",
423
+ "Separate processes do not restrict filesystem or network access.",
424
+ "Persistent process (RPC) supports built-in Pi tools and does not load child extensions.",
407
425
  ...configured.error ? [
408
426
  `Settings cannot be edited: ${safeTerminalLine(configured.error)}`,
409
427
  `Repair ${safeTerminalLine(configured.path)} and retry.`
@@ -429,7 +447,7 @@ async function applyTransportSetting(value, ctx, runtime, signal, isCurrent) {
429
447
  const status = runtime.getRuntimeStatus();
430
448
  if (status.retainedAgents > 0) {
431
449
  ctx.ui.notify(
432
- `Cannot change transport while ${status.retainedAgents} detached agent${status.retainedAgents === 1 ? " is" : "s are"} retained. Clear Current agents first.`,
450
+ `Cannot change transport while ${status.retainedAgents} subagent${status.retainedAgents === 1 ? " is" : "s are"} saved for follow-up. Clear Current subagents first.`,
433
451
  "warning"
434
452
  );
435
453
  return { kind: "rejected" };
@@ -451,7 +469,7 @@ This saves the setting but does not reload Pi automatically.`,
451
469
  }
452
470
  if (runtime.getRuntimeStatus().retainedAgents > 0) {
453
471
  ctx.ui.notify(
454
- "Detached agents appeared while confirming; clear them before changing transport.",
472
+ "New subagents were saved for follow-up while confirming. Clear them before changing transport.",
455
473
  "warning"
456
474
  );
457
475
  return { kind: "rejected" };
@@ -468,37 +486,6 @@ This saves the setting but does not reload Pi automatically.`,
468
486
  return { kind: "rejected" };
469
487
  }
470
488
  }
471
- function responsivenessSetupScreen(runtime) {
472
- const current = runtime.getRuntimeStatus();
473
- const configured = inspectStatefulTransportSettings();
474
- return {
475
- kind: "actions",
476
- title: "Responsiveness Setup",
477
- lines: [
478
- `Current transport: ${transportLabel(current.transport)}`,
479
- `Configured transport: ${transportLabel(configured.value)}`,
480
- "Transport, completion delivery, and thinking defaults are separate explicit choices.",
481
- "Use Automatic to reduce retained follow-up startup while keeping custom-tool compatibility."
482
- ],
483
- items: [
484
- {
485
- id: "auto",
486
- label: "Preview Automatic transport",
487
- description: "Choose a deterministic transport before each retained agent starts",
488
- action: "set-transport"
489
- },
490
- { id: "transport", label: "Compare all transports", to: "transport" },
491
- {
492
- id: "completion",
493
- label: "Completion delivery",
494
- description: "Choose separately whether an idle root resumes for synthesis",
495
- to: "settings"
496
- },
497
- { id: "back", label: "Back", action: "back" }
498
- ],
499
- hint: "back"
500
- };
501
- }
502
489
  function transportLabel(value) {
503
490
  return TRANSPORT_OPTIONS.find((option) => option.value === value)?.label ?? value;
504
491
  }
@@ -508,9 +495,9 @@ function isTransport(value) {
508
495
 
509
496
  // src/config-ui.ts
510
497
  var SUBCOMMANDS = [
511
- { value: "settings", label: "settings", description: "Configure subagent user settings" },
512
- { value: "status", label: "status", description: "Show effective subagent settings" },
513
- { value: "help", label: "help", description: "Show subagent settings help" }
498
+ { value: "settings", label: "settings", description: "Open grouped subagent settings" },
499
+ { value: "status", label: "status", description: "Show detailed subagent diagnostics" },
500
+ { value: "help", label: "help", description: "Show subagent first steps and safety help" }
514
501
  ];
515
502
  var TOOL_VIEWPORT_SIZE = 10;
516
503
  function registerSubagentConfigLifecycle(pi) {
@@ -531,7 +518,7 @@ function registerSubagentConfigCommand(pi, runtime, owner = registerSubagentConf
531
518
  }
532
519
  function registerSubagentPrimaryCommand(pi, runtime, owner) {
533
520
  pi.registerCommand("subagents", {
534
- description: "Manage current-session subagents and user settings",
521
+ description: "Manage subagents, settings, diagnostics, and help",
535
522
  getArgumentCompletions(prefix) {
536
523
  const normalized = prefix.trim().toLowerCase();
537
524
  const matches = SUBCOMMANDS.filter((item) => item.value.startsWith(normalized));
@@ -545,7 +532,7 @@ function registerSubagentPrimaryCommand(pi, runtime, owner) {
545
532
  }
546
533
  switch (subcommand) {
547
534
  case "settings":
548
- await showSubagentSettings(ctx, runtime, owner);
535
+ await showSubagentSettings(pi, ctx, runtime, owner);
549
536
  return;
550
537
  case "status":
551
538
  showSubagentStatus(ctx, runtime);
@@ -561,7 +548,7 @@ function registerSubagentPrimaryCommand(pi, runtime, owner) {
561
548
  }
562
549
  });
563
550
  }
564
- async function showSubagentManager(pi, ctx, runtime, owner) {
551
+ async function showSubagentManager(pi, ctx, runtime, owner, start = "main") {
565
552
  if (ctx.mode !== "tui") {
566
553
  showSubagentStatus(ctx, runtime);
567
554
  return;
@@ -575,7 +562,7 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
575
562
  let selectedExecutionAgent;
576
563
  let selectedStatefulLimit = "maxAgents";
577
564
  const menu = defineMenu({
578
- start: "main",
565
+ start,
579
566
  screens: {
580
567
  main: () => {
581
568
  const status = runtime.getRuntimeStatus();
@@ -587,29 +574,34 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
587
574
  items: [
588
575
  {
589
576
  id: "workflow",
590
- label: "Change delegation",
591
- description: "Choose async only (recommended) or a compatibility workflow",
577
+ label: "How subagents run",
578
+ description: "Choose whether Pi stays available while subagents work",
592
579
  to: "workflow"
593
580
  },
594
581
  {
595
582
  id: "agents",
596
- label: "Current agents",
597
- description: `${status.activeAgents} active \xB7 ${status.retainedAgents} retained`,
583
+ label: "Current subagents",
584
+ description: `${status.activeAgents} working \xB7 ${status.retainedAgents} saved for follow-up`,
598
585
  to: "agents"
599
586
  },
600
587
  {
601
588
  id: "settings",
602
589
  label: "Settings",
603
- description: "Configure targets, trusted resources, and async completion",
604
- to: "settings"
590
+ description: "Folders, completion, privacy, agent defaults, and advanced options",
591
+ to: "settings-hub"
605
592
  },
606
593
  {
607
- id: "advanced",
608
- label: "Advanced settings",
609
- description: "Agent permissions, parallel limit, runtime details, and settings path",
610
- to: "advanced"
594
+ id: "status",
595
+ label: "Diagnostics",
596
+ description: "Detailed runtime values, setting sources, and file paths",
597
+ to: "status"
611
598
  },
612
- { id: "help", label: "Help", to: "help" }
599
+ {
600
+ id: "help",
601
+ label: "Help",
602
+ description: "First steps, settings behavior, commands, and safety",
603
+ to: "help"
604
+ }
613
605
  ],
614
606
  hint: "close"
615
607
  };
@@ -619,11 +611,13 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
619
611
  const active = currentWorkflow(runtime, runtime.getRuntimeStatus());
620
612
  return {
621
613
  kind: "actions",
622
- title: "Change Delegation",
614
+ title: "How Subagents Run",
623
615
  lines: [
624
616
  `Current: ${workflowLabel(active)}`,
625
- "Recommended: Async only keeps the main agent responsive and omits blocking delegation and consultation.",
626
- "Final-answer-dependent detached work needs automatic resume.",
617
+ "Choose a workflow based on the tools and blocking behavior you need.",
618
+ "The blocking subagent tool is deprecated and remains available only for compatibility.",
619
+ "subagent_consult and subagent_await remain supported blocking helpers.",
620
+ "For results needed in the current answer, enable automatic continuation in Settings.",
627
621
  ...snapshot.value !== active ? [`Configured after reload: ${workflowLabel(snapshot.value)}`] : [],
628
622
  ...snapshot.error ? [
629
623
  `Settings cannot be edited: ${safeTerminalLine(snapshot.error)}`,
@@ -632,21 +626,21 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
632
626
  ],
633
627
  items: snapshot.error ? [] : [
634
628
  {
635
- id: "async-only",
636
- label: "Async only \xB7 Recommended",
637
- description: "Detached lifecycle plus inspection; omit blocking and consultation",
629
+ id: "all",
630
+ label: workflowLabel("all"),
631
+ description: "Background agents plus deprecated subagent and supported blocking helpers",
638
632
  action: "set-workflow"
639
633
  },
640
634
  {
641
- id: "all",
642
- label: "All delegation methods",
643
- description: "Compatibility: async, blocking, inspection, and consultation",
635
+ id: "async-only",
636
+ label: workflowLabel("async-only"),
637
+ description: "Subagents work in the background while you continue using Pi",
644
638
  action: "set-workflow"
645
639
  },
646
640
  {
647
641
  id: "blocking-only",
648
- label: "Blocking only",
649
- description: "Compatibility: blocking and consultation without async lifecycle",
642
+ label: workflowLabel("blocking-only"),
643
+ description: "No background agents; deprecated subagent plus read-only consultation",
650
644
  action: "set-workflow"
651
645
  }
652
646
  ],
@@ -658,14 +652,17 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
658
652
  const status = runtime.getRuntimeStatus();
659
653
  return {
660
654
  kind: "actions",
661
- title: "Current-session Subagents",
662
- lines: agents.length ? agents.map(formatStatefulAgentLine) : [formatEmptyStatefulRuntime(status)],
655
+ title: "Current Subagents",
656
+ lines: agents.length ? [
657
+ "Working subagents and subagents saved for follow-up in this session.",
658
+ ...agents.map(formatStatefulAgentLine)
659
+ ] : [formatEmptyStatefulRuntime(status)],
663
660
  items: [
664
661
  ...agents.length > 0 ? [
665
662
  {
666
663
  id: "clear",
667
- label: "Clear current-session agents",
668
- description: "Close and delete retained agents for this session",
664
+ label: "Clear current subagents",
665
+ description: "Stop running work and remove subagents saved for follow-up",
669
666
  action: "clear-agents"
670
667
  }
671
668
  ] : [],
@@ -674,72 +671,97 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
674
671
  hint: "back"
675
672
  };
676
673
  },
677
- settings: () => subagentSettingsScreen(runtime),
678
- advanced: () => {
674
+ "settings-hub": () => ({
675
+ kind: "actions",
676
+ title: "Subagent Settings",
677
+ lines: [
678
+ "Changes are saved immediately.",
679
+ "Transport and background-agent limits take effect after /reload."
680
+ ],
681
+ items: [
682
+ {
683
+ id: "access",
684
+ label: "Folders and trusted resources",
685
+ description: "Where subagents can start and what trusted consultations can load",
686
+ to: "access-settings"
687
+ },
688
+ {
689
+ id: "behavior",
690
+ label: "Completion and privacy",
691
+ description: "What Pi does when work finishes and optional local recording",
692
+ to: "behavior-settings"
693
+ },
694
+ {
695
+ id: "agents",
696
+ label: "Agent defaults",
697
+ description: "Tools, model, thinking effort, and time limit for each subagent",
698
+ to: "agent-settings"
699
+ },
700
+ {
701
+ id: "runtime",
702
+ label: "Advanced runtime settings",
703
+ description: "Transport and capacity controls that most users can leave unchanged",
704
+ to: "runtime-settings"
705
+ },
706
+ { id: "back", label: "Back", action: "back" }
707
+ ],
708
+ hint: "back"
709
+ }),
710
+ "access-settings": () => subagentAccessSettingsScreen(runtime),
711
+ "behavior-settings": () => subagentBehaviorSettingsScreen(runtime),
712
+ "agent-settings": () => ({
713
+ kind: "actions",
714
+ title: "Agent Defaults",
715
+ lines: ["Choose the starting settings for each subagent."],
716
+ items: [
717
+ {
718
+ id: "agent-tools",
719
+ label: "Tool permissions",
720
+ description: "Choose which tools each subagent may use",
721
+ action: "load-agent-picker"
722
+ },
723
+ {
724
+ id: "execution",
725
+ label: "Model, thinking, and time limit",
726
+ description: "Choose how each subagent starts unless a request overrides it",
727
+ to: "execution-agent-picker"
728
+ },
729
+ { id: "back", label: "Back", action: "back" }
730
+ ],
731
+ hint: "back"
732
+ }),
733
+ "runtime-settings": () => {
679
734
  const limit = inspectBlockingParallelLimitSettings();
680
735
  return {
681
736
  kind: "actions",
682
- title: "Advanced Subagent Settings",
737
+ title: "Advanced Runtime Settings",
738
+ lines: ["Most users can leave these settings unchanged."],
683
739
  items: [
684
740
  {
685
- id: "agent-tools",
686
- label: "Agent tool permissions",
687
- description: "Customize persistent per-agent tool allow-lists",
688
- action: "load-agent-picker"
689
- },
690
- {
691
- id: "status",
692
- label: "Runtime details",
693
- description: "Show transport, configured source, and settings path",
694
- to: "status"
741
+ id: "transport",
742
+ label: "Transport",
743
+ description: `How Pi hosts background subagents \xB7 Current: ${transportLabel(runtime.getRuntimeStatus().transport)}`,
744
+ to: "transport"
695
745
  },
696
746
  {
697
747
  id: "parallel-limit",
698
- label: "Maximum parallel workers",
699
- description: `Current: ${runtime.getMaxParallelTasks()} per blocking call`,
748
+ label: "Blocking worker limit",
749
+ description: `Maximum subagents per blocking request \xB7 Current: ${runtime.getMaxParallelTasks()}`,
700
750
  to: "parallel-limit",
701
751
  disabled: limit.error !== void 0,
702
752
  disabledReason: limit.error ? `Repair ${safeTerminalLine(limit.path)} before editing this setting` : void 0
703
753
  },
704
754
  {
705
755
  id: "stateful-limits",
706
- label: "Detached agent limits",
756
+ label: "Background agent limits",
707
757
  description: formatDetachedLimitSummary(runtime.getRuntimeStatus()),
708
758
  to: "stateful-limits"
709
759
  },
710
- {
711
- id: "performance",
712
- label: "Performance and execution",
713
- description: "Transport, responsiveness, and agent defaults",
714
- to: "performance"
715
- },
716
760
  { id: "back", label: "Back", action: "back" }
717
761
  ],
718
762
  hint: "back"
719
763
  };
720
764
  },
721
- performance: () => ({
722
- kind: "actions",
723
- title: "Performance and Execution",
724
- items: [
725
- {
726
- id: "responsiveness",
727
- label: "Responsiveness setup",
728
- description: "Preview automatic retained transport and completion guidance",
729
- to: "responsiveness"
730
- },
731
- { id: "transport", label: "Detached transport", to: "transport" },
732
- {
733
- id: "agents",
734
- label: "Agent execution defaults",
735
- description: "Model, thinking level, and timeout",
736
- to: "execution-agent-picker"
737
- },
738
- { id: "back", label: "Back", action: "back" }
739
- ],
740
- hint: "back"
741
- }),
742
- responsiveness: () => responsivenessSetupScreen(runtime),
743
765
  transport: () => transportSettingsScreen(runtime),
744
766
  "execution-agent-picker": () => executionAgentPickerScreen(availableAgents),
745
767
  "execution-agent": () => executionAgentScreen(selectedExecutionAgent),
@@ -752,13 +774,13 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
752
774
  "stateful-limit-input": () => statefulLimitInputScreen(selectedStatefulLimit, runtime),
753
775
  status: () => ({
754
776
  kind: "detail",
755
- title: "Subagent runtime details",
777
+ title: "Subagent Diagnostics",
756
778
  lines: statusLines(runtime),
757
779
  hint: "back"
758
780
  }),
759
781
  help: () => ({
760
782
  kind: "detail",
761
- title: "Subagents help",
783
+ title: "Subagents Help",
762
784
  lines: helpLines(runtime),
763
785
  hint: "back"
764
786
  }),
@@ -767,8 +789,8 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
767
789
  const configured = settings.agents ?? {};
768
790
  return {
769
791
  kind: "actions",
770
- title: "Subagent Tool Configuration",
771
- lines: ["Select an agent to configure its allowed tools."],
792
+ title: "Tool Permissions",
793
+ lines: ["Choose a subagent to change which tools it may use."],
772
794
  items: availableAgents.map((agent) => {
773
795
  const override = configured[agent.name];
774
796
  const hasOverride = override ? hasOwn(override, "tools") : false;
@@ -820,7 +842,7 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
820
842
  if (snapshot.error) return { kind: "rejected" };
821
843
  const active = currentWorkflow(runtime, runtime.getRuntimeStatus());
822
844
  if (itemId === active && itemId === snapshot.value) {
823
- ctx.ui.notify(`Delegation already uses ${workflowLabel(itemId)}.`, "info");
845
+ ctx.ui.notify(`Subagents already use ${workflowLabel(itemId)}.`, "info");
824
846
  return { kind: "stay" };
825
847
  }
826
848
  const requiresReload = itemId !== active;
@@ -838,7 +860,7 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
838
860
  updateDelegationWorkflowSetting(itemId);
839
861
  } catch (error) {
840
862
  ctx.ui.notify(
841
- `Delegation settings were not saved: ${formatError3(error)}. The current workflow is unchanged.`,
863
+ `How subagents run was not saved: ${formatError3(error)}. The current choice is unchanged.`,
842
864
  "error"
843
865
  );
844
866
  return { kind: "rejected" };
@@ -861,25 +883,22 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
861
883
  const agents = runtime.listAgents();
862
884
  if (agents.length === 0) return { kind: "stay" };
863
885
  const confirmed = await ctx.ui.confirm(
864
- "Clear current-session subagents?",
865
- `Close and delete ${agents.length} retained agent${agents.length === 1 ? "" : "s"}?`,
886
+ "Clear current subagents?",
887
+ `Stop work and remove ${agents.length} subagent${agents.length === 1 ? "" : "s"} saved for follow-up?`,
866
888
  { signal }
867
889
  );
868
890
  if (signal.aborted || !isCurrent()) return { kind: "close" };
869
891
  if (!confirmed) return { kind: "rejected" };
870
892
  if (runtime.listAgents().map((agent) => agent.id).join("\0") !== agents.map((agent) => agent.id).join("\0")) {
871
893
  ctx.ui.notify(
872
- "Detached agents changed while confirming; review the list again.",
894
+ "Current subagents changed while confirming; review the list again.",
873
895
  "warning"
874
896
  );
875
897
  return { kind: "rejected" };
876
898
  }
877
899
  const cleared = await runtime.clearAgents();
878
900
  if (signal.aborted || !isCurrent()) return { kind: "close" };
879
- ctx.ui.notify(
880
- `Cleared ${cleared} current-session subagent${cleared === 1 ? "" : "s"}.`,
881
- "info"
882
- );
901
+ ctx.ui.notify(`Cleared ${cleared} current subagent${cleared === 1 ? "" : "s"}.`, "info");
883
902
  return { kind: "stay" };
884
903
  },
885
904
  "set-transport": async ({ itemId, signal }) => applyTransportSetting(itemId, ctx, runtime, signal, isCurrent),
@@ -912,6 +931,7 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
912
931
  "set-consult-resources": async ({ value }) => applyConsultResourceSetting(value, ctx, runtime),
913
932
  "set-consultation-cwd": async ({ value }) => applyConsultationCwdSetting(value, ctx, runtime),
914
933
  "set-delegation-cwd": async ({ value }) => applyDelegationCwdSetting(value, ctx, runtime),
934
+ "set-usage-recording": async ({ value, signal }) => applyUsageRecordingSetting(value, ctx, runtime, { signal, isCurrent }),
915
935
  "load-agent-picker": async () => {
916
936
  availableAgents = discoverAgents(ctx.cwd, "user", readSubagentSettings() ?? {}).agents;
917
937
  if (availableAgents.length === 0) {
@@ -980,7 +1000,7 @@ async function showSubagentManager(pi, ctx, runtime, owner) {
980
1000
  isCurrent
981
1001
  });
982
1002
  }
983
- async function showSubagentSettings(ctx, runtime, owner) {
1003
+ async function showSubagentSettings(pi, ctx, runtime, owner) {
984
1004
  const snapshot = inspectConsultResourceSettings();
985
1005
  if (ctx.mode !== "tui") {
986
1006
  if (ctx.hasUI) {
@@ -991,84 +1011,130 @@ async function showSubagentSettings(ctx, runtime, owner) {
991
1011
  }
992
1012
  return;
993
1013
  }
994
- const generation = owner.generation;
995
- const isCurrent = () => generation === owner.generation && !owner.controller.signal.aborted;
996
- const { defineMenu, runMenu } = await import("@narumitw/pi-tui-kit");
997
- if (!isCurrent()) return;
998
- const menu = defineMenu({
999
- start: "settings",
1000
- screens: { settings: () => subagentSettingsScreen(runtime) },
1001
- actions: {
1002
- "set-completion": async ({ value }) => applyCompletionSetting(value, ctx, runtime),
1003
- "set-consult-resources": async ({ value }) => applyConsultResourceSetting(value, ctx, runtime),
1004
- "set-consultation-cwd": async ({ value }) => applyConsultationCwdSetting(value, ctx, runtime),
1005
- "set-delegation-cwd": async ({ value }) => applyDelegationCwdSetting(value, ctx, runtime)
1006
- }
1007
- });
1008
- await runMenu(ctx, menu, {
1009
- getState: () => void 0,
1010
- signal: owner.controller.signal,
1011
- isCurrent
1012
- });
1014
+ await showSubagentManager(pi, ctx, runtime, owner, "settings-hub");
1013
1015
  }
1014
- function subagentSettingsScreen(runtime) {
1015
- const completion = inspectCompletionDeliverySettings();
1016
+ function subagentAccessSettingsScreen(runtime) {
1016
1017
  const consult = inspectConsultResourceSettings();
1017
1018
  const cwdPolicy = inspectCwdPolicySettings();
1018
- const error = completion.error ?? consult.error ?? cwdPolicy.error;
1019
+ const error = consult.error ?? cwdPolicy.error;
1019
1020
  return {
1020
1021
  kind: "settings",
1021
- title: error ? "Subagent User Settings \xB7 Read only" : "Subagent User Settings",
1022
+ title: error ? "Folders and Trusted Resources \xB7 Read only" : "Folders and Trusted Resources",
1022
1023
  lines: [
1023
- "Applies now and to future sessions",
1024
- "Target and trust settings control startup resources, not filesystem access or sandboxing.",
1025
- "Manage folder trust with Pi /trust; restart Pi after changing it.",
1024
+ "Choose where subagents may start and what read-only consultations may load.",
1025
+ "These settings do not restrict files, shell commands, network access, or OS permissions.",
1026
+ "Manage saved folder trust with Pi /trust, then restart Pi.",
1026
1027
  safeTerminalLine(consult.path),
1027
1028
  ...error ? [`Settings cannot be edited: ${safeTerminalLine(error)}`] : []
1028
1029
  ],
1029
1030
  items: error ? [] : [
1030
1031
  {
1031
1032
  id: "consultationCwd",
1032
- label: "Read-only consultation target",
1033
- description: "Untrusted external targets inherit no target/project resources; agent and package read-only prompts remain.",
1033
+ label: "Where read-only consultations can start",
1034
+ description: "Use only this workspace, or allow other folders without loading untrusted project resources.",
1034
1035
  currentValue: consultationCwdLabel(runtime.getConsultationCwdPolicy()),
1035
- values: ["Anywhere \xB7 untrusted targets inherit nothing", "Current workspace only"],
1036
+ values: ["Any folder \xB7 no project resources when untrusted", "This workspace only"],
1036
1037
  action: "set-consultation-cwd"
1037
1038
  },
1038
1039
  {
1039
1040
  id: "delegationCwd",
1040
- label: "General delegation target",
1041
- description: "Controls starting directories, not absolute paths, shell commands, or OS permissions.",
1041
+ label: "Where subagents can start",
1042
+ description: "Limit subagents to this workspace, saved-trusted folders, or any folder Pi can access.",
1042
1043
  currentValue: delegationCwdLabel(runtime.getDelegationCwdPolicy()),
1043
1044
  values: [
1044
- "Current or saved-trusted folders",
1045
- "Current workspace only",
1046
- "Anywhere \xB7 normal Pi permissions"
1045
+ "This workspace or saved-trusted folders",
1046
+ "This workspace only",
1047
+ "Any folder Pi can access"
1047
1048
  ],
1048
1049
  action: "set-delegation-cwd"
1049
1050
  },
1050
1051
  {
1051
1052
  id: "consultResources",
1052
- label: "Consultation resources for trusted targets",
1053
- description: "Choose which trusted context, system, skill, and prompt resources a consultation inherits.",
1053
+ label: "Resources for trusted read-only consultations",
1054
+ description: "Choose how much project context, skills, and prompt guidance a trusted consultation may load.",
1054
1055
  currentValue: consultResourceLabel(runtime.getConsultResourcePolicy()),
1055
- values: ["Project context only", "No inherited resources", "All trusted resources"],
1056
+ values: ["Project context only", "No project resources", "All trusted resources"],
1056
1057
  action: "set-consult-resources"
1057
- },
1058
+ }
1059
+ ]
1060
+ };
1061
+ }
1062
+ function subagentBehaviorSettingsScreen(runtime) {
1063
+ const completion = inspectCompletionDeliverySettings();
1064
+ const usageRecording = inspectUsageRecordingSettings();
1065
+ const error = completion.error ?? usageRecording.error;
1066
+ return {
1067
+ kind: "settings",
1068
+ title: error ? "Completion and Privacy \xB7 Read only" : "Completion and Privacy",
1069
+ lines: [
1070
+ "These changes apply immediately and to future sessions.",
1071
+ safeTerminalLine(completion.path),
1072
+ ...error ? [`Settings cannot be edited: ${safeTerminalLine(error)}`] : []
1073
+ ],
1074
+ items: error ? [] : [
1058
1075
  {
1059
1076
  id: "completionDelivery",
1060
- label: "When async work finishes",
1061
- description: "Wait for your next turn, or request one synthesis turn after the root settles.",
1077
+ label: "When background work finishes",
1078
+ description: "Wait for your next message, or steer results into active work and continue automatically from idle.",
1062
1079
  currentValue: completionLabel(runtime.getCompletionDelivery()),
1063
- values: ["Wait until my next turn", "Resume automatically when finished"],
1080
+ values: ["Wait for my next message", "Continue automatically when work finishes"],
1064
1081
  action: "set-completion"
1082
+ },
1083
+ {
1084
+ id: "usageRecording",
1085
+ label: "Local usage recording",
1086
+ description: `Optionally keep content-free timing and lifecycle events on this device for ${USAGE_RECORDING_RETENTION_DAYS} days.`,
1087
+ currentValue: runtime.getUsageRecordingEnabled?.() ? "On \xB7 local only" : "Off",
1088
+ values: ["Off", "On \xB7 local only"],
1089
+ action: "set-usage-recording"
1065
1090
  }
1066
1091
  ]
1067
1092
  };
1068
1093
  }
1094
+ async function applyUsageRecordingSetting(value, ctx, runtime, options) {
1095
+ if (options.signal.aborted || !options.isCurrent()) return { kind: "close" };
1096
+ const previous = runtime.getUsageRecordingEnabled?.() ?? false;
1097
+ const next = value === "On \xB7 local only";
1098
+ if (next === previous) return { kind: "stay" };
1099
+ if (!runtime.setUsageRecordingEnabled) {
1100
+ ctx.ui.notify("Usage recording is unavailable in this session.", "error");
1101
+ return { kind: "rejected" };
1102
+ }
1103
+ try {
1104
+ updateUsageRecordingSetting(next);
1105
+ } catch (error) {
1106
+ ctx.ui.notify(`Subagent settings were not saved: ${formatError3(error)}`, "error");
1107
+ return { kind: "rejected" };
1108
+ }
1109
+ try {
1110
+ await runtime.setUsageRecordingEnabled(next);
1111
+ if (options.signal.aborted || !options.isCurrent()) return { kind: "close" };
1112
+ ctx.ui.notify(
1113
+ next ? `Local content-free usage recording enabled. Records stay on this device for ${USAGE_RECORDING_RETENTION_DAYS} days.` : "Local usage recording disabled. Existing records expire under the retention policy.",
1114
+ "info"
1115
+ );
1116
+ return { kind: "stay" };
1117
+ } catch (error) {
1118
+ if (options.signal.aborted || !options.isCurrent()) return { kind: "close" };
1119
+ try {
1120
+ updateUsageRecordingSetting(previous);
1121
+ await runtime.setUsageRecordingEnabled(previous);
1122
+ if (options.signal.aborted || !options.isCurrent()) return { kind: "close" };
1123
+ } catch (rollbackError) {
1124
+ if (options.signal.aborted || !options.isCurrent()) return { kind: "close" };
1125
+ ctx.ui.notify(
1126
+ `Usage recording could not be applied or rolled back: ${formatError3(new AggregateError([error, rollbackError]))}`,
1127
+ "error"
1128
+ );
1129
+ return { kind: "rejected" };
1130
+ }
1131
+ ctx.ui.notify(`Subagent settings were not applied: ${formatError3(error)}`, "error");
1132
+ return { kind: "rejected" };
1133
+ }
1134
+ }
1069
1135
  function applyCompletionSetting(value, ctx, runtime) {
1070
1136
  const previous = runtime.getCompletionDelivery();
1071
- const next = value === "Resume automatically when finished" ? "auto-resume" : "next-turn";
1137
+ const next = value === "Continue automatically when work finishes" ? "auto-resume" : "next-turn";
1072
1138
  if (next === previous) return { kind: "stay" };
1073
1139
  try {
1074
1140
  updateCompletionDeliverySetting(next);
@@ -1082,7 +1148,7 @@ function applyCompletionSetting(value, ctx, runtime) {
1082
1148
  }
1083
1149
  function applyConsultResourceSetting(value, ctx, runtime) {
1084
1150
  const previous = runtime.getConsultResourcePolicy();
1085
- const next = value === "No inherited resources" ? "none" : value === "All trusted resources" ? "all" : "project-context";
1151
+ const next = value === "No project resources" ? "none" : value === "All trusted resources" ? "all" : "project-context";
1086
1152
  if (next === previous) return { kind: "stay" };
1087
1153
  try {
1088
1154
  updateConsultResourceSetting(next);
@@ -1096,7 +1162,7 @@ function applyConsultResourceSetting(value, ctx, runtime) {
1096
1162
  }
1097
1163
  function applyConsultationCwdSetting(value, ctx, runtime) {
1098
1164
  const previous = runtime.getConsultationCwdPolicy();
1099
- const next = value === "Current workspace only" ? "current-workspace" : "anywhere";
1165
+ const next = value === "This workspace only" ? "current-workspace" : "anywhere";
1100
1166
  if (next === previous) return { kind: "stay" };
1101
1167
  try {
1102
1168
  updateCwdPolicySetting("consultation", next);
@@ -1110,7 +1176,7 @@ function applyConsultationCwdSetting(value, ctx, runtime) {
1110
1176
  }
1111
1177
  function applyDelegationCwdSetting(value, ctx, runtime) {
1112
1178
  const previous = runtime.getDelegationCwdPolicy();
1113
- const next = value === "Current workspace only" ? "current-workspace" : value === "Anywhere \xB7 normal Pi permissions" ? "anywhere" : "trusted-targets";
1179
+ const next = value === "This workspace only" ? "current-workspace" : value === "Any folder Pi can access" ? "anywhere" : "trusted-targets";
1114
1180
  if (next === previous) return { kind: "stay" };
1115
1181
  try {
1116
1182
  updateCwdPolicySetting("delegation", next);
@@ -1126,7 +1192,7 @@ function blockReloadWithRetainedAgents(ctx, runtime) {
1126
1192
  const status = runtime.getRuntimeStatus();
1127
1193
  if (status.retainedAgents === 0) return false;
1128
1194
  ctx.ui.notify(
1129
- `Cannot reload while ${status.retainedAgents} detached subagent${status.retainedAgents === 1 ? " is" : "s are"} retained (${status.activeAgents} active). Open Current agents and clear them after their work is safe to discard, then change delegation.`,
1195
+ `Cannot reload while ${status.retainedAgents} subagent${status.retainedAgents === 1 ? " is" : "s are"} saved for follow-up (${status.activeAgents} working). Open Current subagents and clear them after their work is safe to discard, then change how subagents run.`,
1130
1196
  "warning"
1131
1197
  );
1132
1198
  return true;
@@ -1143,4 +1209,4 @@ export {
1143
1209
  showSubagentManager,
1144
1210
  showSubagentSettings
1145
1211
  };
1146
- //# sourceMappingURL=config-ui-2YUCUEBM.ts.map
1212
+ //# sourceMappingURL=config-ui-ABHYNGQ7.ts.map