@narumitw/pi-subagents 2.1.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/README.md +181 -1250
  2. package/dist/child-communication-bridge.ts +136 -0
  3. package/dist/child-communication-bridge.ts.map +7 -0
  4. package/dist/chunks/chunk-UKTWUQRM.js +667 -0
  5. package/dist/chunks/chunk-UKTWUQRM.js.map +7 -0
  6. package/dist/index.ts +1448 -1598
  7. package/dist/index.ts.map +4 -4
  8. package/docs/design-principles.md +31 -0
  9. package/docs/ipc-transport-idea.md +103 -0
  10. package/docs/tools.md +109 -0
  11. package/package.json +11 -19
  12. package/src/broker-credentials.ts +71 -0
  13. package/src/child-communication-bridge.ts +153 -0
  14. package/src/child-communication-tools.ts +147 -0
  15. package/src/completion-renderer.ts +60 -0
  16. package/src/index.ts +1 -1
  17. package/src/message-broker.ts +628 -0
  18. package/src/model-output.ts +42 -0
  19. package/src/process.ts +688 -0
  20. package/src/runtime.ts +538 -0
  21. package/src/subagents.ts +33 -34
  22. package/src/tools.ts +416 -0
  23. package/src/types.ts +85 -0
  24. package/src/widget.ts +130 -0
  25. package/dist/chunks/auto-transport-FUUKFDIG.ts +0 -109
  26. package/dist/chunks/auto-transport-FUUKFDIG.ts.map +0 -7
  27. package/dist/chunks/capability-grant-PR72SWWS.ts +0 -19
  28. package/dist/chunks/capability-grant-PR72SWWS.ts.map +0 -7
  29. package/dist/chunks/child-peer-bridge.ts +0 -108
  30. package/dist/chunks/child-peer-bridge.ts.map +0 -7
  31. package/dist/chunks/chunk-2LMJU25E.ts +0 -1641
  32. package/dist/chunks/chunk-2LMJU25E.ts.map +0 -7
  33. package/dist/chunks/chunk-47SK2QYC.ts +0 -56
  34. package/dist/chunks/chunk-47SK2QYC.ts.map +0 -7
  35. package/dist/chunks/chunk-4AQSF7AS.ts +0 -29
  36. package/dist/chunks/chunk-4AQSF7AS.ts.map +0 -7
  37. package/dist/chunks/chunk-5DGRMKNV.ts +0 -126
  38. package/dist/chunks/chunk-5DGRMKNV.ts.map +0 -7
  39. package/dist/chunks/chunk-6H6TBBED.ts +0 -108
  40. package/dist/chunks/chunk-6H6TBBED.ts.map +0 -7
  41. package/dist/chunks/chunk-6KJ34M6S.ts +0 -159
  42. package/dist/chunks/chunk-6KJ34M6S.ts.map +0 -7
  43. package/dist/chunks/chunk-6NSJVPXX.ts +0 -480
  44. package/dist/chunks/chunk-6NSJVPXX.ts.map +0 -7
  45. package/dist/chunks/chunk-7AAJEUSL.ts +0 -238
  46. package/dist/chunks/chunk-7AAJEUSL.ts.map +0 -7
  47. package/dist/chunks/chunk-BFK2Z4ZF.ts +0 -189
  48. package/dist/chunks/chunk-BFK2Z4ZF.ts.map +0 -7
  49. package/dist/chunks/chunk-BOAXY55Y.ts +0 -153
  50. package/dist/chunks/chunk-BOAXY55Y.ts.map +0 -7
  51. package/dist/chunks/chunk-D4CR7T73.ts +0 -353
  52. package/dist/chunks/chunk-D4CR7T73.ts.map +0 -7
  53. package/dist/chunks/chunk-FEVPWRMU.ts +0 -300
  54. package/dist/chunks/chunk-FEVPWRMU.ts.map +0 -7
  55. package/dist/chunks/chunk-G6VZTCFH.ts +0 -70
  56. package/dist/chunks/chunk-G6VZTCFH.ts.map +0 -7
  57. package/dist/chunks/chunk-H3FP6DLR.ts +0 -160
  58. package/dist/chunks/chunk-H3FP6DLR.ts.map +0 -7
  59. package/dist/chunks/chunk-HA36LPCO.ts +0 -130
  60. package/dist/chunks/chunk-HA36LPCO.ts.map +0 -7
  61. package/dist/chunks/chunk-HOP5FXDT.ts +0 -27
  62. package/dist/chunks/chunk-HOP5FXDT.ts.map +0 -7
  63. package/dist/chunks/chunk-IGAMVWFN.ts +0 -139
  64. package/dist/chunks/chunk-IGAMVWFN.ts.map +0 -7
  65. package/dist/chunks/chunk-ILEQ27AL.ts +0 -45
  66. package/dist/chunks/chunk-ILEQ27AL.ts.map +0 -7
  67. package/dist/chunks/chunk-ITVWPNU4.ts +0 -819
  68. package/dist/chunks/chunk-ITVWPNU4.ts.map +0 -7
  69. package/dist/chunks/chunk-IWC32VPY.ts +0 -172
  70. package/dist/chunks/chunk-IWC32VPY.ts.map +0 -7
  71. package/dist/chunks/chunk-JSZIP73U.ts +0 -362
  72. package/dist/chunks/chunk-JSZIP73U.ts.map +0 -7
  73. package/dist/chunks/chunk-JU6LUNLP.ts +0 -380
  74. package/dist/chunks/chunk-JU6LUNLP.ts.map +0 -7
  75. package/dist/chunks/chunk-KMGKCEO4.ts +0 -38
  76. package/dist/chunks/chunk-KMGKCEO4.ts.map +0 -7
  77. package/dist/chunks/chunk-LASD73CM.ts +0 -339
  78. package/dist/chunks/chunk-LASD73CM.ts.map +0 -7
  79. package/dist/chunks/chunk-LEOYDZI3.ts +0 -22
  80. package/dist/chunks/chunk-LEOYDZI3.ts.map +0 -7
  81. package/dist/chunks/chunk-LL4LP2T7.ts +0 -737
  82. package/dist/chunks/chunk-LL4LP2T7.ts.map +0 -7
  83. package/dist/chunks/chunk-N2T5IN4X.ts +0 -18
  84. package/dist/chunks/chunk-N2T5IN4X.ts.map +0 -7
  85. package/dist/chunks/chunk-N7BLVXKK.ts +0 -73
  86. package/dist/chunks/chunk-N7BLVXKK.ts.map +0 -7
  87. package/dist/chunks/chunk-NLT67IZS.ts +0 -322
  88. package/dist/chunks/chunk-NLT67IZS.ts.map +0 -7
  89. package/dist/chunks/chunk-NTRPLF46.ts +0 -63
  90. package/dist/chunks/chunk-NTRPLF46.ts.map +0 -7
  91. package/dist/chunks/chunk-ONDTY4EL.ts +0 -91
  92. package/dist/chunks/chunk-ONDTY4EL.ts.map +0 -7
  93. package/dist/chunks/chunk-OVPHFGKO.ts +0 -1769
  94. package/dist/chunks/chunk-OVPHFGKO.ts.map +0 -7
  95. package/dist/chunks/chunk-P7OH4XMF.ts +0 -60
  96. package/dist/chunks/chunk-P7OH4XMF.ts.map +0 -7
  97. package/dist/chunks/chunk-PBZMBTNJ.ts +0 -422
  98. package/dist/chunks/chunk-PBZMBTNJ.ts.map +0 -7
  99. package/dist/chunks/chunk-PGLSFLYW.ts +0 -52
  100. package/dist/chunks/chunk-PGLSFLYW.ts.map +0 -7
  101. package/dist/chunks/chunk-RRR66UWR.ts +0 -28
  102. package/dist/chunks/chunk-RRR66UWR.ts.map +0 -7
  103. package/dist/chunks/chunk-RSUXZD6S.ts +0 -275
  104. package/dist/chunks/chunk-RSUXZD6S.ts.map +0 -7
  105. package/dist/chunks/chunk-RTCVYIZA.ts +0 -221
  106. package/dist/chunks/chunk-RTCVYIZA.ts.map +0 -7
  107. package/dist/chunks/chunk-RY2AEGMZ.ts +0 -34
  108. package/dist/chunks/chunk-RY2AEGMZ.ts.map +0 -7
  109. package/dist/chunks/chunk-SWGQLFSD.ts +0 -60
  110. package/dist/chunks/chunk-SWGQLFSD.ts.map +0 -7
  111. package/dist/chunks/chunk-TM2R67J3.ts +0 -52
  112. package/dist/chunks/chunk-TM2R67J3.ts.map +0 -7
  113. package/dist/chunks/chunk-TMZRHIIK.ts +0 -497
  114. package/dist/chunks/chunk-TMZRHIIK.ts.map +0 -7
  115. package/dist/chunks/chunk-TZ34IQ3M.ts +0 -59
  116. package/dist/chunks/chunk-TZ34IQ3M.ts.map +0 -7
  117. package/dist/chunks/chunk-UMBPMVJW.ts +0 -22
  118. package/dist/chunks/chunk-UMBPMVJW.ts.map +0 -7
  119. package/dist/chunks/chunk-VDG7LTYE.ts +0 -80
  120. package/dist/chunks/chunk-VDG7LTYE.ts.map +0 -7
  121. package/dist/chunks/chunk-X4NMONPE.ts +0 -73
  122. package/dist/chunks/chunk-X4NMONPE.ts.map +0 -7
  123. package/dist/chunks/chunk-YPJEN6NU.ts +0 -65
  124. package/dist/chunks/chunk-YPJEN6NU.ts.map +0 -7
  125. package/dist/chunks/chunk-YU53SHA7.ts +0 -328
  126. package/dist/chunks/chunk-YU53SHA7.ts.map +0 -7
  127. package/dist/chunks/completion-delivery-RSJU6BXL.ts +0 -17
  128. package/dist/chunks/completion-delivery-RSJU6BXL.ts.map +0 -7
  129. package/dist/chunks/config-status-FKGDECZ3.ts +0 -35
  130. package/dist/chunks/config-status-FKGDECZ3.ts.map +0 -7
  131. package/dist/chunks/config-ui-ABHYNGQ7.ts +0 -1212
  132. package/dist/chunks/config-ui-ABHYNGQ7.ts.map +0 -7
  133. package/dist/chunks/consult-LJU3IQY5.ts +0 -519
  134. package/dist/chunks/consult-LJU3IQY5.ts.map +0 -7
  135. package/dist/chunks/context-QDKLVQXE.ts +0 -11
  136. package/dist/chunks/context-QDKLVQXE.ts.map +0 -7
  137. package/dist/chunks/create-stateful-transport-JWC2EFYL.ts +0 -130
  138. package/dist/chunks/create-stateful-transport-JWC2EFYL.ts.map +0 -7
  139. package/dist/chunks/cwd-policy-NB6XZ5GF.ts +0 -17
  140. package/dist/chunks/cwd-policy-NB6XZ5GF.ts.map +0 -7
  141. package/dist/chunks/delegation-contract-LA56I5DT.ts +0 -24
  142. package/dist/chunks/delegation-contract-LA56I5DT.ts.map +0 -7
  143. package/dist/chunks/discovery-MIFB2U4Y.ts +0 -12
  144. package/dist/chunks/discovery-MIFB2U4Y.ts.map +0 -7
  145. package/dist/chunks/execution-Q2JZLKJA.ts +0 -4037
  146. package/dist/chunks/execution-Q2JZLKJA.ts.map +0 -7
  147. package/dist/chunks/in-process-transport-HJ6TZXC3.ts +0 -39
  148. package/dist/chunks/in-process-transport-HJ6TZXC3.ts.map +0 -7
  149. package/dist/chunks/inspect-UH2TKH6E.ts +0 -634
  150. package/dist/chunks/inspect-UH2TKH6E.ts.map +0 -7
  151. package/dist/chunks/peer-communication-KL36Z6CO.ts +0 -294
  152. package/dist/chunks/peer-communication-KL36Z6CO.ts.map +0 -7
  153. package/dist/chunks/persistence-UY3PY6E5.ts +0 -348
  154. package/dist/chunks/persistence-UY3PY6E5.ts.map +0 -7
  155. package/dist/chunks/registry-BT54L6CY.ts +0 -1445
  156. package/dist/chunks/registry-BT54L6CY.ts.map +0 -7
  157. package/dist/chunks/retained-semantic-state-GM75FZGE.ts +0 -81
  158. package/dist/chunks/retained-semantic-state-GM75FZGE.ts.map +0 -7
  159. package/dist/chunks/rpc-transport-7R7DVCEB.ts +0 -1222
  160. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +0 -7
  161. package/dist/chunks/runtime-policy-5YELCOVC.ts +0 -15
  162. package/dist/chunks/runtime-policy-5YELCOVC.ts.map +0 -7
  163. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts +0 -19
  164. package/dist/chunks/semantic-snapshot-WPJ3UAFW.ts.map +0 -7
  165. package/dist/chunks/spawn-idempotency-BNHOSMZW.ts +0 -13
  166. package/dist/chunks/spawn-idempotency-BNHOSMZW.ts.map +0 -7
  167. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts +0 -15
  168. package/dist/chunks/stateful-lifecycle-JAR6K55H.ts.map +0 -7
  169. package/dist/chunks/subprocess-transport-VHZJRBTW.ts +0 -160
  170. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +0 -7
  171. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +0 -164
  172. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +0 -7
  173. package/dist/chunks/workspace-WDKLN72J.ts +0 -11
  174. package/dist/chunks/workspace-WDKLN72J.ts.map +0 -7
  175. package/docs/async-runtime-protocol.md +0 -84
  176. package/docs/implementation-notes/pi-subagents-capability-matrix.md +0 -62
  177. package/docs/implementation-notes/pi-subagents-current-direction.md +0 -99
  178. package/docs/implementation-notes/pi-subagents-rpc-v1.md +0 -153
  179. package/docs/pi-subagents-diagrams.md +0 -183
  180. package/src/adaptive-scheduler.ts +0 -224
  181. package/src/admission-benchmark.ts +0 -95
  182. package/src/admission-policy.ts +0 -78
  183. package/src/agent-projection.ts +0 -53
  184. package/src/agents/built-ins.ts +0 -71
  185. package/src/agents/catalog.ts +0 -241
  186. package/src/agents/discovery.ts +0 -265
  187. package/src/agents/types.ts +0 -100
  188. package/src/agents.ts +0 -51
  189. package/src/async-subagent-benchmark.ts +0 -532
  190. package/src/auto-transport.ts +0 -121
  191. package/src/blocking-status.ts +0 -63
  192. package/src/cached-module-loader.ts +0 -18
  193. package/src/capabilities.ts +0 -145
  194. package/src/capability-grant.ts +0 -115
  195. package/src/capability-router.ts +0 -107
  196. package/src/child-peer-bridge.ts +0 -124
  197. package/src/child-peer-tools.ts +0 -132
  198. package/src/completion-delivery.ts +0 -409
  199. package/src/completion-render.ts +0 -190
  200. package/src/completion-requirement.ts +0 -479
  201. package/src/completion-routing.ts +0 -24
  202. package/src/config-registration.ts +0 -114
  203. package/src/config-status.ts +0 -217
  204. package/src/config-ui.ts +0 -983
  205. package/src/consult-policy.ts +0 -15
  206. package/src/consult-registration.ts +0 -125
  207. package/src/consult-render.ts +0 -194
  208. package/src/consult-resources.ts +0 -51
  209. package/src/consult-tool.ts +0 -95
  210. package/src/consult.ts +0 -566
  211. package/src/context.ts +0 -126
  212. package/src/create-stateful-transport.ts +0 -157
  213. package/src/cwd-policy.ts +0 -183
  214. package/src/delegation-contract.ts +0 -463
  215. package/src/execution/budget.ts +0 -56
  216. package/src/execution/runtime-policy.ts +0 -19
  217. package/src/execution-plan.ts +0 -322
  218. package/src/execution-ui.ts +0 -259
  219. package/src/execution.ts +0 -1679
  220. package/src/in-process-transport.ts +0 -941
  221. package/src/inspect-registration.ts +0 -64
  222. package/src/inspect-render.ts +0 -334
  223. package/src/inspect-tool.ts +0 -45
  224. package/src/inspect.ts +0 -769
  225. package/src/integration-controller.ts +0 -98
  226. package/src/limits.ts +0 -75
  227. package/src/orchestration-metrics.ts +0 -116
  228. package/src/outcome.ts +0 -61
  229. package/src/panel-child-group.ts +0 -35
  230. package/src/panel-contract.ts +0 -343
  231. package/src/panel-evidence.ts +0 -59
  232. package/src/panel-execution.ts +0 -769
  233. package/src/panel-failure.ts +0 -56
  234. package/src/panel-planning.ts +0 -175
  235. package/src/panel-presets.ts +0 -3
  236. package/src/panel-prompts.ts +0 -132
  237. package/src/panel-reconciliation.ts +0 -57
  238. package/src/panel-render.ts +0 -103
  239. package/src/parallel-limit-ui.ts +0 -113
  240. package/src/params.ts +0 -278
  241. package/src/peer-communication.ts +0 -352
  242. package/src/peer-transport.ts +0 -49
  243. package/src/persistence.ts +0 -522
  244. package/src/pi-args.ts +0 -43
  245. package/src/pi-invocation.ts +0 -168
  246. package/src/process-control.ts +0 -43
  247. package/src/prompt-resources.ts +0 -38
  248. package/src/prompt-source-safety.ts +0 -48
  249. package/src/protocol.ts +0 -76
  250. package/src/registry-types.ts +0 -204
  251. package/src/registry.ts +0 -1698
  252. package/src/render-common.ts +0 -252
  253. package/src/render.ts +0 -704
  254. package/src/result-contract.ts +0 -431
  255. package/src/retained-semantic-state.ts +0 -100
  256. package/src/rpc-timeout-finalization.ts +0 -207
  257. package/src/rpc-transport-metadata.ts +0 -65
  258. package/src/rpc-transport.ts +0 -1035
  259. package/src/rpc-turn-capture.ts +0 -217
  260. package/src/runner-outcome.ts +0 -31
  261. package/src/runner-result.ts +0 -55
  262. package/src/runner-types.ts +0 -102
  263. package/src/runner-usage.ts +0 -48
  264. package/src/runner.ts +0 -866
  265. package/src/safe-text.ts +0 -67
  266. package/src/semantic-snapshot.ts +0 -214
  267. package/src/session-guidance-contract.ts +0 -399
  268. package/src/settings/inspection.ts +0 -302
  269. package/src/settings/schema.ts +0 -195
  270. package/src/settings-reader.ts +0 -215
  271. package/src/settings.ts +0 -452
  272. package/src/spawn-idempotency.ts +0 -68
  273. package/src/stateful-agent-view.ts +0 -85
  274. package/src/stateful-config.ts +0 -13
  275. package/src/stateful-guidance.ts +0 -29
  276. package/src/stateful-lifecycle.ts +0 -74
  277. package/src/stateful-limit-ui.ts +0 -249
  278. package/src/stateful-limits.ts +0 -96
  279. package/src/stateful-prompt.ts +0 -49
  280. package/src/stateful-registration.ts +0 -1320
  281. package/src/stateful-render.ts +0 -318
  282. package/src/stateful-safety.ts +0 -47
  283. package/src/stateful-tool-params.ts +0 -215
  284. package/src/stateful.ts +0 -12
  285. package/src/subagent-details.ts +0 -43
  286. package/src/subagents-extension.ts +0 -355
  287. package/src/subprocess-transport.ts +0 -145
  288. package/src/supervision.ts +0 -104
  289. package/src/task-path.ts +0 -65
  290. package/src/timeout-checkpoint.ts +0 -305
  291. package/src/timeout-finalization.ts +0 -75
  292. package/src/tool-schema-compatibility.ts +0 -73
  293. package/src/transport-types.ts +0 -74
  294. package/src/transport-ui.ts +0 -135
  295. package/src/transport.ts +0 -43
  296. package/src/turn-budget.ts +0 -109
  297. package/src/usage-format.ts +0 -42
  298. package/src/usage-recording-config.ts +0 -13
  299. package/src/usage-recording-store.ts +0 -183
  300. package/src/usage-recording.ts +0 -478
  301. package/src/verification-harness.ts +0 -516
  302. package/src/verification-policy.ts +0 -67
  303. package/src/verification-receipt.ts +0 -275
  304. package/src/verified-execution-benchmark.ts +0 -86
  305. package/src/verified-execution-contract.ts +0 -191
  306. package/src/verified-execution-schema.ts +0 -32
  307. package/src/work-item-ledger.ts +0 -1404
  308. package/src/work-item-persistence.ts +0 -254
  309. package/src/workflow-completion-controller.ts +0 -397
  310. package/src/workflow-planning.ts +0 -172
  311. package/src/workflow-tree-identity.ts +0 -289
  312. package/src/workflow-ui.ts +0 -69
  313. package/src/workflow-verification.ts +0 -296
  314. package/src/workspace.ts +0 -174
@@ -1,164 +0,0 @@
1
- // @generated by scripts/build-runtime.mjs; do not edit.
2
- // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
-
4
- // src/usage-recording-store.ts
5
- import { randomUUID } from "node:crypto";
6
- import { chmod, lstat, mkdir, readdir, rm, writeFile } from "node:fs/promises";
7
- import path from "node:path";
8
- var WRITER_PATTERN = /^runtime-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\.jsonl$/u;
9
- var MAX_EVENT_BYTES = 8 * 1024;
10
- var WRITE_TIMEOUT_MS = 2e3;
11
- var UsageEventStore = class {
12
- path;
13
- writerPath;
14
- mutationTail = Promise.resolve();
15
- lifecycle = new AbortController();
16
- closed = false;
17
- constructor(rootPath, options = {}) {
18
- this.path = rootPath;
19
- this.createId = options.createId ?? randomUUID;
20
- this.now = options.now ?? Date.now;
21
- this.writerPath = path.join(rootPath, `runtime-${validId(this.createId())}.jsonl`);
22
- }
23
- createId;
24
- now;
25
- append(event) {
26
- if (this.closed) return Promise.reject(new Error("Usage recording storage is closed."));
27
- const frame = encodeEvent(event);
28
- return this.enqueue(
29
- () => withTimeout(
30
- (signal) => this.appendFrame(frame, signal),
31
- this.lifecycle.signal,
32
- WRITE_TIMEOUT_MS,
33
- "Usage recording write timed out"
34
- )
35
- );
36
- }
37
- prune(retentionDays) {
38
- if (this.closed) return Promise.reject(new Error("Usage recording storage is closed."));
39
- return this.enqueue(
40
- () => withTimeout(
41
- async (signal) => {
42
- await ensurePrivateDirectory(this.path);
43
- signal.throwIfAborted();
44
- const cutoff = this.now() - retentionDays * 24 * 60 * 60 * 1e3;
45
- for (const entry of await readdir(this.path, { withFileTypes: true })) {
46
- signal.throwIfAborted();
47
- if (!entry.isFile() || !WRITER_PATTERN.test(entry.name)) continue;
48
- const candidate = path.join(this.path, entry.name);
49
- if (candidate === this.writerPath) continue;
50
- let metadata;
51
- try {
52
- metadata = await lstat(candidate);
53
- } catch (error) {
54
- if (isNodeError(error) && error.code === "ENOENT") continue;
55
- throw error;
56
- }
57
- if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.mtimeMs >= cutoff) {
58
- continue;
59
- }
60
- await rm(candidate, { force: true });
61
- }
62
- },
63
- this.lifecycle.signal,
64
- WRITE_TIMEOUT_MS,
65
- "Usage recording retention cleanup timed out"
66
- )
67
- );
68
- }
69
- async close() {
70
- if (this.closed) return;
71
- this.closed = true;
72
- this.lifecycle.abort(new DOMException("Usage recording storage closed", "AbortError"));
73
- await this.mutationTail;
74
- }
75
- enqueue(operation) {
76
- const result = this.mutationTail.then(operation);
77
- this.mutationTail = result.catch(() => void 0);
78
- return result;
79
- }
80
- async appendFrame(frame, signal) {
81
- await ensurePrivateDirectory(this.path);
82
- signal.throwIfAborted();
83
- await assertOptionalPrivateRegularFile(this.writerPath);
84
- signal.throwIfAborted();
85
- await writeFile(this.writerPath, frame, {
86
- encoding: "utf8",
87
- flag: "a",
88
- mode: 384,
89
- signal
90
- });
91
- if (process.platform !== "win32") await chmod(this.writerPath, 384);
92
- }
93
- };
94
- function encodeEvent(event) {
95
- const frame = `${JSON.stringify(event)}
96
- `;
97
- if (Buffer.byteLength(frame) > MAX_EVENT_BYTES) {
98
- throw new Error("Usage recording event exceeds the storage bound.");
99
- }
100
- return frame;
101
- }
102
- async function ensurePrivateDirectory(directoryPath) {
103
- try {
104
- const metadata = await lstat(directoryPath);
105
- if (!metadata.isDirectory() || metadata.isSymbolicLink()) {
106
- throw new Error("Usage recording storage must be a regular directory, not a link.");
107
- }
108
- } catch (error) {
109
- if (!isNodeError(error) || error.code !== "ENOENT") throw error;
110
- await mkdir(directoryPath, { recursive: true, mode: 448 });
111
- const metadata = await lstat(directoryPath);
112
- if (!metadata.isDirectory() || metadata.isSymbolicLink()) {
113
- throw new Error("Usage recording storage must be a regular directory, not a link.");
114
- }
115
- }
116
- if (process.platform !== "win32") await chmod(directoryPath, 448);
117
- }
118
- async function assertOptionalPrivateRegularFile(filePath) {
119
- try {
120
- const metadata = await lstat(filePath);
121
- if (!metadata.isFile() || metadata.isSymbolicLink()) {
122
- throw new Error("Usage recording writers must be regular files, not links.");
123
- }
124
- if (process.platform !== "win32") await chmod(filePath, 384);
125
- } catch (error) {
126
- if (isNodeError(error) && error.code === "ENOENT") return;
127
- throw error;
128
- }
129
- }
130
- async function withTimeout(operation, lifecycleSignal, timeoutMs, message) {
131
- lifecycleSignal.throwIfAborted();
132
- const controller = new AbortController();
133
- const abortLifecycle = () => controller.abort(
134
- lifecycleSignal.reason ?? new DOMException("Usage recording storage closed", "AbortError")
135
- );
136
- lifecycleSignal.addEventListener("abort", abortLifecycle, { once: true });
137
- const timer = setTimeout(
138
- () => controller.abort(new DOMException(message, "TimeoutError")),
139
- timeoutMs
140
- );
141
- try {
142
- return await operation(controller.signal);
143
- } catch (error) {
144
- if (controller.signal.aborted) throw controller.signal.reason;
145
- throw error;
146
- } finally {
147
- clearTimeout(timer);
148
- lifecycleSignal.removeEventListener("abort", abortLifecycle);
149
- }
150
- }
151
- function validId(value) {
152
- if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(value)) {
153
- throw new Error("Usage recording storage received an invalid writer identity.");
154
- }
155
- return value;
156
- }
157
- function isNodeError(error) {
158
- return error instanceof Error && "code" in error;
159
- }
160
- export {
161
- UsageEventStore,
162
- encodeEvent
163
- };
164
- //# sourceMappingURL=usage-recording-store-CW3EH2SZ.ts.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/usage-recording-store.ts"],
4
- "sourcesContent": ["import { randomUUID } from \"node:crypto\";\nimport { chmod, lstat, mkdir, readdir, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nconst WRITER_PATTERN =\n\t/^runtime-[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\.jsonl$/u;\nconst MAX_EVENT_BYTES = 8 * 1024;\nconst WRITE_TIMEOUT_MS = 2_000;\n\nexport interface UsageEventStorePort {\n\treadonly path: string;\n\tappend(event: unknown): Promise<void>;\n\tprune(retentionDays: number): Promise<void>;\n\tclose(): Promise<void>;\n}\n\nexport class UsageEventStore implements UsageEventStorePort {\n\treadonly path: string;\n\tprivate readonly writerPath: string;\n\tprivate mutationTail: Promise<void> = Promise.resolve();\n\tprivate readonly lifecycle = new AbortController();\n\tprivate closed = false;\n\n\tconstructor(rootPath: string, options: { createId?: () => string; now?: () => number } = {}) {\n\t\tthis.path = rootPath;\n\t\tthis.createId = options.createId ?? randomUUID;\n\t\tthis.now = options.now ?? Date.now;\n\t\tthis.writerPath = path.join(rootPath, `runtime-${validId(this.createId())}.jsonl`);\n\t}\n\n\tprivate readonly createId: () => string;\n\tprivate readonly now: () => number;\n\n\tappend(event: unknown): Promise<void> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Usage recording storage is closed.\"));\n\t\tconst frame = encodeEvent(event);\n\t\treturn this.enqueue(() =>\n\t\t\twithTimeout(\n\t\t\t\t(signal) => this.appendFrame(frame, signal),\n\t\t\t\tthis.lifecycle.signal,\n\t\t\t\tWRITE_TIMEOUT_MS,\n\t\t\t\t\"Usage recording write timed out\",\n\t\t\t),\n\t\t);\n\t}\n\n\tprune(retentionDays: number): Promise<void> {\n\t\tif (this.closed) return Promise.reject(new Error(\"Usage recording storage is closed.\"));\n\t\treturn this.enqueue(() =>\n\t\t\twithTimeout(\n\t\t\t\tasync (signal) => {\n\t\t\t\t\tawait ensurePrivateDirectory(this.path);\n\t\t\t\t\tsignal.throwIfAborted();\n\t\t\t\t\tconst cutoff = this.now() - retentionDays * 24 * 60 * 60 * 1000;\n\t\t\t\t\tfor (const entry of await readdir(this.path, { withFileTypes: true })) {\n\t\t\t\t\t\tsignal.throwIfAborted();\n\t\t\t\t\t\tif (!entry.isFile() || !WRITER_PATTERN.test(entry.name)) continue;\n\t\t\t\t\t\tconst candidate = path.join(this.path, entry.name);\n\t\t\t\t\t\tif (candidate === this.writerPath) continue;\n\t\t\t\t\t\tlet metadata: Awaited<ReturnType<typeof lstat>>;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tmetadata = await lstat(candidate);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (isNodeError(error) && error.code === \"ENOENT\") continue;\n\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!metadata.isFile() || metadata.isSymbolicLink() || metadata.mtimeMs >= cutoff) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tawait rm(candidate, { force: true });\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tthis.lifecycle.signal,\n\t\t\t\tWRITE_TIMEOUT_MS,\n\t\t\t\t\"Usage recording retention cleanup timed out\",\n\t\t\t),\n\t\t);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\tthis.lifecycle.abort(new DOMException(\"Usage recording storage closed\", \"AbortError\"));\n\t\tawait this.mutationTail;\n\t}\n\n\tprivate enqueue(operation: () => Promise<void>): Promise<void> {\n\t\tconst result = this.mutationTail.then(operation);\n\t\tthis.mutationTail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tprivate async appendFrame(frame: string, signal: AbortSignal): Promise<void> {\n\t\tawait ensurePrivateDirectory(this.path);\n\t\tsignal.throwIfAborted();\n\t\tawait assertOptionalPrivateRegularFile(this.writerPath);\n\t\tsignal.throwIfAborted();\n\t\tawait writeFile(this.writerPath, frame, {\n\t\t\tencoding: \"utf8\",\n\t\t\tflag: \"a\",\n\t\t\tmode: 0o600,\n\t\t\tsignal,\n\t\t});\n\t\tif (process.platform !== \"win32\") await chmod(this.writerPath, 0o600);\n\t}\n}\n\nexport function encodeEvent(event: unknown): string {\n\tconst frame = `${JSON.stringify(event)}\\n`;\n\tif (Buffer.byteLength(frame) > MAX_EVENT_BYTES) {\n\t\tthrow new Error(\"Usage recording event exceeds the storage bound.\");\n\t}\n\treturn frame;\n}\n\nasync function ensurePrivateDirectory(directoryPath: string): Promise<void> {\n\ttry {\n\t\tconst metadata = await lstat(directoryPath);\n\t\tif (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n\t\t\tthrow new Error(\"Usage recording storage must be a regular directory, not a link.\");\n\t\t}\n\t} catch (error) {\n\t\tif (!isNodeError(error) || error.code !== \"ENOENT\") throw error;\n\t\tawait mkdir(directoryPath, { recursive: true, mode: 0o700 });\n\t\tconst metadata = await lstat(directoryPath);\n\t\tif (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n\t\t\tthrow new Error(\"Usage recording storage must be a regular directory, not a link.\");\n\t\t}\n\t}\n\tif (process.platform !== \"win32\") await chmod(directoryPath, 0o700);\n}\n\nasync function assertOptionalPrivateRegularFile(filePath: string): Promise<void> {\n\ttry {\n\t\tconst metadata = await lstat(filePath);\n\t\tif (!metadata.isFile() || metadata.isSymbolicLink()) {\n\t\t\tthrow new Error(\"Usage recording writers must be regular files, not links.\");\n\t\t}\n\t\tif (process.platform !== \"win32\") await chmod(filePath, 0o600);\n\t} catch (error) {\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") return;\n\t\tthrow error;\n\t}\n}\n\nasync function withTimeout<T>(\n\toperation: (signal: AbortSignal) => Promise<T>,\n\tlifecycleSignal: AbortSignal,\n\ttimeoutMs: number,\n\tmessage: string,\n): Promise<T> {\n\tlifecycleSignal.throwIfAborted();\n\tconst controller = new AbortController();\n\tconst abortLifecycle = () =>\n\t\tcontroller.abort(\n\t\t\tlifecycleSignal.reason ?? new DOMException(\"Usage recording storage closed\", \"AbortError\"),\n\t\t);\n\tlifecycleSignal.addEventListener(\"abort\", abortLifecycle, { once: true });\n\tconst timer = setTimeout(\n\t\t() => controller.abort(new DOMException(message, \"TimeoutError\")),\n\t\ttimeoutMs,\n\t);\n\ttry {\n\t\treturn await operation(controller.signal);\n\t} catch (error) {\n\t\tif (controller.signal.aborted) throw controller.signal.reason;\n\t\tthrow error;\n\t} finally {\n\t\tclearTimeout(timer);\n\t\tlifecycleSignal.removeEventListener(\"abort\", abortLifecycle);\n\t}\n}\n\nfunction validId(value: string): string {\n\tif (!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(value)) {\n\t\tthrow new Error(\"Usage recording storage received an invalid writer identity.\");\n\t}\n\treturn value;\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,11 +0,0 @@
1
- // @generated by scripts/build-runtime.mjs; do not edit.
2
- // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
- import {
4
- WorkspaceManager,
5
- assertWorkspaceIsolationReady
6
- } from "./chunk-6KJ34M6S.ts";
7
- export {
8
- WorkspaceManager,
9
- assertWorkspaceIsolationReady
10
- };
11
- //# sourceMappingURL=workspace-WDKLN72J.ts.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
7
- }
@@ -1,84 +0,0 @@
1
- # Async runtime protocol
2
-
3
- This document defines `pi-subagents:completion-requirement:v1` and the current runtime boundary for final-answer-dependent detached work.
4
-
5
- ## Requirement identity
6
-
7
- A caller marks one `subagent_spawn` or `subagent_send` turn with `completionRequirement: "required"`.
8
- The runtime binds that requirement to the accepted `agentId`, executor-owned `runId`, and monotonically increasing turn generation.
9
- Agent names and task paths are display and addressing aids and never replace exact run identity.
10
- Omitting the field or using `background` preserves prior behavior and does not create a final-answer dependency.
11
-
12
- ## State ownership
13
-
14
- `AgentRegistry` owns requirement transitions with the child turn and persisted completion outbox.
15
- Tool-result `details.agent.completionRequirements` provides fork-sensitive branch evidence.
16
- Session restoration retains exact requirements found on the active branch and treats sessions without visible subagent state as a possible compacted continuation.
17
- The successful lifecycle tool result and delivered completion message are the ordinary model-visible requirement handoff.
18
- When a resume changes a pending run to cancelled and interrupted while its stale handoff remains in model context, `before_agent_start` appends one hidden versioned transition after that handoff.
19
- This append-only transition also applies when leading summaries retain the stale handoff, prevents duplicate publication on later turns, and participates in fork-sensitive branch reconstruction.
20
- If leading compaction or branch summaries remove the handoff, the `context` hook restores one canonical hidden `pi-subagent-required-completions` fallback immediately after the summaries.
21
- A branch-local custom session entry records the exact restored boundary so reload and tree navigation reconstruct the correct historical fallback.
22
- The fallback remains at that fixed boundary for the leading-summary epoch, while a later completion or cancellation transition supersedes it at the conversation tail.
23
- `CompletionDeliveryBroker` owns exact completion visibility acknowledgement and asks the registry to mark the corresponding requirement visible.
24
- No timer, waiter, or UI object owns requirement truth.
25
-
26
- ## States
27
-
28
- A newly accepted exact run enters `pending`.
29
- A durably persisted terminal completion moves the exact run to `available` and records its completion ID and terminal child state.
30
- Observation of that exact completion ID in the intended parent context moves the run to `visible`.
31
- Interruption, close, restore of a non-running owner, or shutdown moves an unfinished requirement to `cancelled` with an explicit terminal state.
32
- Duplicate completion delivery and acknowledgement are idempotent.
33
- A follow-up receives a new run ID and generation and creates a requirement only when that follow-up explicitly requests one.
34
- The runtime bounds retained requirement records per agent and rejects a sixty-fifth unresolved required run before acceptance so every unresolved exact identity fits in the canonical parent context.
35
-
36
- ## Parent behavior
37
-
38
- Pending and available requirements remain final-answer dependencies.
39
- A newly established canonical fallback omits requirements already visible at that boundary.
40
- A fallback retained from an earlier request remains historical prefix context after visibility changes, and the later completion message supplies the superseding state.
41
- Cancelled requirements are terminal and must be reported rather than silently treated as successful evidence.
42
- A failed, partial, interrupted, stale, or cancelled child never satisfies mutating acceptance or independent-verification requirements merely because its turn settled.
43
-
44
- ## Prompt-cache boundary
45
-
46
- Provider-visible subagent tool definitions and prompt metadata remain stable within one configured tool-surface epoch.
47
- A versioned hidden session-guidance message carries the bounded agent catalog, completion delivery, capacity, cwd policy, and consultation resource policy without placing mutable values in leading tool metadata.
48
- The initial guidance contract is persisted once before the first agent turn when no equivalent retained contract exists.
49
- A successfully applied live policy change appends a superseding guidance contract without triggering a model turn.
50
- Compaction restores missing guidance and required-completion fallbacks in deterministic order after leading summaries.
51
- These rules preserve normalized cache-eligible prefixes across ordinary turns but do not guarantee a provider-reported cache hit.
52
-
53
- ## Budget termination
54
-
55
- Omitted limits use runtime or agent policy and are recorded as runtime-sourced telemetry.
56
- Explicit timeout, idle, turn, and tool-call limits remain compatible and are recorded as explicit sources.
57
- A limit stop with non-empty successful bounded finalization becomes a typed `partial` outcome with the exact termination reason.
58
- Empty finalization, failed finalization, malformed required structured output, and transport failures remain failed or contract-invalid.
59
- Partial evidence is available to the parent but is not successful verification or mutating acceptance.
60
-
61
- ## Pi core boundary
62
-
63
- The inspected supported Pi runtime emits provider `message_update` events before the TUI, RPC, JSON, and SDK surfaces display them.
64
- An extension `message_end` handler can replace the finalized same-role message but cannot retract previously displayed deltas.
65
- Steering is queued after the extension `input` event, direct RPC steering bypasses that event, and tool abort signals do not observe every accepted steer.
66
- Therefore an extension cannot provide a hard pre-display final-answer barrier or a reliably steer-interruptible join across all supported modes.
67
- `subagent_await` remains the bounded non-polling compatibility join and accurately states that queued steering is blocked until the tool settles.
68
-
69
- A future core implementation would need replay-safe post-enqueue input activity, exact session-owned blocker handles, pre-display buffering or suppression, bounded timeout, and abort, replacement, reload, shutdown, and headless-mode semantics.
70
- This repository does not modify or publish Pi core packages for this work.
71
-
72
- ## Codex reference
73
-
74
- Codex `wait_agent` uses replay-safe pending activity plus an event-driven watch receiver for mailbox and steering activity.
75
- Codex completion context uses a typed `FINAL_ANSWER` envelope with explicit task, sender, and payload fields.
76
- Codex rollout budgets use shared runtime-owned accounting and acknowledge reminders only after context insertion.
77
- These patterns inform waiting, completion identity, and budget ownership, but Codex also does not provide an absolute pre-display final-answer barrier.
78
-
79
- ## Compatibility fallback
80
-
81
- Older persisted agents without requirement metadata behave as background work.
82
- Current Pi versions continue using bounded persisted at-least-once completion delivery and optional idle-root auto-resume.
83
- The package must not claim that prompt guidance, context injection, automatic delivery, or finalized-message replacement is a hard barrier.
84
- The deprecated synchronous `subagent` tool remains available for unmatched chain, fan-in, panel, workflow, and compatibility callers.
@@ -1,62 +0,0 @@
1
- # pi-subagents capability matrix
2
-
3
- This matrix records the maintained capability boundaries of `@narumitw/pi-subagents`.
4
- The package README owns public schemas and usage.
5
- Source and focused tests are the executable authority.
6
-
7
- | Capability | Status and boundary | Evidence |
8
- | --- | --- | --- |
9
- | Blocking orchestration | Deprecated `subagent` remains a compatibility tool for single, parallel, chain, fan-in, panel, and explicit dependency workflows; the complete request is preflighted before launch and its schema and execution contract remain supported | `src/execution.ts`, `src/panel-execution.ts`, blocking execution and workflow tests |
10
- | Detached addressable agents | `subagent_spawn` returns an opaque id and canonical task path without waiting for completion | `src/stateful-registration.ts`, registry and stateful registration tests |
11
- | Follow-up and retained lifecycle | `subagent_send` starts follow-up work; `subagent_await` blocks for one current turn without interrupting on wait timeout or cancellation; `subagent_manage` supports only interrupt and close; `subagent_mailbox` owns queue-only send and acknowledged read | `src/stateful-tool-params.ts`, registry and lifecycle tests |
12
- | Metadata-only inspection | `subagent_inspect` is registered in every workflow and never launches children, changes lifecycle state, or reads or acknowledges mailbox content | `src/inspect.ts`, `test/inspect.test.ts` |
13
- | Synchronous read-only consultation | `subagent_consult` runs one ephemeral child with extensions disabled and only the effective subset of `read`, `grep`, `find`, and `ls` | `src/consult.ts`, `src/consult-policy.ts`, `test/consult.test.ts` |
14
- | Workflow-dependent tool surface | `all` registers eight tools including supported `subagent_await` and `subagent_consult` plus deprecated `subagent`; `async-only` registers detached lifecycle plus inspection; `blocking-only` registers deprecated `subagent` plus supported consultation and inspection; `disabled` registers inspection only | `src/subagents-extension.ts`, settings UI and registration tests |
15
- | Transport selection | Stateful execution supports `subprocess`, `in-process`, `rpc`, and `auto`; subprocess remains the compatibility default and selection never falls back after acceptance | `src/create-stateful-transport.ts`, transport tests |
16
- | Automatic transport | Read-only built-in tools select in-process, write-capable built-ins select RPC, and extension or custom tools select fresh subprocess execution | `src/auto-transport.ts`, automatic transport tests |
17
- | In-process SDK boundary | In-process children use public session-service and model-resolution APIs, disable child extensions, and reject unsupported tools without widening or fallback | `src/in-process-transport.ts`, in-process transport tests |
18
- | Persistent RPC transport | One retained agent lazily owns at most one exact-loaded Pi RPC child; `agent_settled` is the completion boundary and accepted work is never replayed automatically | `src/rpc-transport.ts`, [`pi-subagents-rpc-v1.md`](pi-subagents-rpc-v1.md) |
19
- | Detached completion delivery | `next-turn` is the default non-waking delivery; opt-in `auto-resume` steers completion into active root context without a wake, or requests at most one in-flight synthesis turn when the root is idle and has no pending input; exact completion IDs remain pending until context acknowledgement | `src/completion-delivery.ts`, completion-delivery tests |
20
- | Deterministic timeout and cleanup | Work, idle, turn, and tool budgets use bounded abort and process or session cleanup; explicit parent interruption never starts timeout finalization | runner, transport, timeout, and cleanup tests |
21
- | Bounded protocol and output | Model-facing content and safe projections are bounded to 50 KiB or 2,000 lines | `src/protocol.ts`, `src/limits.ts`, rendering and inspection tests |
22
- | Partial structured outcomes | Blocking, detached, and consultation paths preserve bounded post-launch evidence and usage; structured-v2 keeps claims, artifacts, verification, limitations, and unresolved dependencies | result-contract, runner, consultation, and orchestration tests |
23
- | Enforced delegation contracts | Optional `pi-subagents:delegation:v2` contracts validate declared capabilities, dependencies, evidence, side-effect policy, and supported enforcement without claiming unsupported path, network, or secret guarantees | `src/delegation-contract.ts`, contract and workflow tests |
24
- | Recursion guard | `PI_SUBAGENT_DEPTH` and `PI_SUBAGENT_MAX_DEPTH` bound nested delegation | `src/execution.ts`, runtime policy and runner tests |
25
- | Hierarchical ownership | Parent, root, depth, children, and authenticated task paths are persisted; subtree interrupt and close run child-first | `src/registry.ts`, registry and orchestration tests |
26
- | Bounded mailbox and peer delivery | Mailboxes support acknowledgement and deduplication; inspection exposes only counts; nested peer delivery uses session-scoped authenticated channels | registry, peer transport, mailbox, and inspection tests |
27
- | Shared and isolated workspaces | Shared-workspace agents may write concurrently by default; deprecated `allowConcurrentWrites` is a no-op; opt-in clean-Git worktrees provide disposable repository isolation | `src/stateful-registration.ts`, `src/workspace.ts`, workspace tests |
28
- | Separate active and retained capacity | FIFO active-turn scheduling and retained-agent limits are independent and hierarchy depth and child counts are bounded separately | `src/registry.ts`, capacity and fairness tests |
29
- | Parent context selection | Context supports none, all, summary, recent N user turns, and selected entry ids; projection is text-only, sanitized, and bounded | `src/context.ts`, context protocol tests |
30
- | Target trust resolution | Current workspace uses session trust; external targets use the nearest saved `ProjectTrustStore` decision, with a nearer denial winning | `src/cwd-policy.ts`, `test/cwd-policy.test.ts` |
31
- | Consultation target policy | Consultation defaults to any existing target and removes inherited target and project resources when effective trust is absent | `src/consult.ts`, consultation cwd and trust tests |
32
- | General delegation target policy | Delegation defaults to trusted targets; blocking and detached requests are preflighted and every transport receives the same resolved trust decision | execution, stateful, cwd-policy, and transport tests |
33
- | Durable logical history | Versioned private state restores inert; retained transports seed bounded sanitized context and logical history once after explicit follow-up | `src/persistence.ts`, persistence and orchestration tests |
34
- | Automatic side-effect resume | Restored records never restart work; semantic resource skew requires explicit revalidation before a follow-up | persistence, semantic snapshot, and lifecycle tests |
35
- | Stable tool schema | Registered tool membership does not change across retained-agent state transitions; workflow changes require reload | registration and settings UI tests |
36
- | Native transcript switching | Unsupported because Pi exposes no supported child transcript or session switch handle | public SDK boundary review |
37
- | Approval, sandbox, and header inheritance | Unsupported as a general guarantee and reported explicitly in result policy metadata | result policy and transport tests |
38
- | Filesystem isolation | Optional disposable worktree only; cwd and trust policies are not OS sandboxes and do not restrict absolute paths, processes, network, or credentials | `src/workspace.ts`, README security boundary |
39
- | Extension-owned autonomous planning | Removed; topology belongs to the main agent or a caller-authored workflow request | built-in catalog, execution, and registration tests |
40
-
41
- ## Read-only boundary
42
-
43
- `subagent_inspect` is side-effect-free at the extension capability boundary.
44
- It uses pure settings and metadata snapshots, applies project-trust gates before project discovery, and omits prompts, history, context content, mailbox content, credential-bearing model fields, and unsafe paths.
45
-
46
- `subagent_consult` is synchronous and non-retained.
47
- Missing agent tool configuration selects the read-only default set, an explicit empty list selects no tools, and any explicit list is intersected with the supported read-only built-ins.
48
- Extensions, sessions, lifecycle tools, shell execution, and file mutation tools are disabled.
49
- Pre-launch failures throw.
50
- Once a child starts, bounded partial evidence and nested usage are retained and the finalized Pi tool result is marked as an error when consultation fails.
51
-
52
- These are executor and resource-loading guarantees, not filesystem, network, process, or confidentiality sandboxes.
53
- A consultation can read an accessible absolute path when explicitly asked and calls the configured model over the network.
54
-
55
- ## Runtime ownership boundary
56
-
57
- The logical registry owns ids, hierarchy, capacity, mailboxes, completion delivery, persistence, semantic revalidation, and workspace cleanup.
58
- Each retained turn owns one transport session or process according to its fixed effective transport.
59
- Close, expiry, replacement, reload, and shutdown abort work and release transport and disposable-workspace ownership.
60
-
61
- Pi core still owns provider execution, active-turn admission, message ordering, retries, compaction, interactive transcript selection, and global scheduling.
62
- The extension does not claim inherited approval or sandbox policy, provider-header hooks, extension state, or a core-owned child-session tree.
@@ -1,99 +0,0 @@
1
- # pi-subagents current direction
2
-
3
- This note is the entry point for current `@narumitw/pi-subagents` planning.
4
-
5
- ## Current product shape
6
-
7
- `pi-subagents` is a delegation runtime, not an automatic planner.
8
-
9
- The main agent decides whether to delegate and how to split work.
10
-
11
- The built-in catalog is intentionally small:
12
-
13
- | Built-in | Purpose | Default tools |
14
- | --- | --- | --- |
15
- | `explorer` | Bounded read-only repository exploration with cited paths and evidence. | `read`, `grep`, `find`, `ls` |
16
- | `worker` | Write-capable parallel implementation, command execution, and fixes. | Pi default tools |
17
-
18
- Removed built-ins and tools are not part of the active surface:
19
-
20
- - `planner`;
21
- - `reviewer`;
22
- - `general`;
23
- - `general-purpose`; and
24
- - `subagent_auto`.
25
-
26
- ## Delegation rules
27
-
28
- Use no subagent for simple, latency-sensitive, conversational, tightly coupled, or single-lane implementation work that the main agent can do directly.
29
-
30
- Use `explorer` when a bounded read-only search can save main-context space or run independently.
31
-
32
- Keep overall planning, immediate critical-path work, integration, final verification, and the final answer in the main agent.
33
-
34
- A worker may directly implement a bounded slice with clear ownership when it can run independently beside useful non-overlapping main-agent work.
35
-
36
- Use one async `worker` only when the main agent has named that local work to continue immediately and the worker result has a supported delivery and integration path.
37
-
38
- If the main agent has no such local work, it should implement directly instead of spawning one worker.
39
-
40
- Use two or more workers only for disjoint implementation slices whose parallel progress justifies coordination, and keep integration ownership in the main agent.
41
-
42
- A single worker without concurrent main-agent work remains an explicit escape hatch for a user-requested specialist model, tool profile, or isolation boundary rather than the ordinary implementation path.
43
-
44
- Use custom user or project agents for specialist review, verification, or shell-capable read-mostly work.
45
-
46
- Custom project agents remain subject to existing trust and confirmation behavior.
47
-
48
- Review should usually be handled by the main agent plus review skills and deterministic checks.
49
-
50
- Use custom verifier agents only when independent child verification is explicitly worth the added cost and coordination.
51
-
52
- ## Tool-surface direction
53
-
54
- `all` remains the compatibility default, while `async-only` remains an optional smaller tool surface.
55
-
56
- `async-only` exposes `subagent_spawn`, `subagent_send`, `subagent_manage`, `subagent_mailbox`, and `subagent_inspect`.
57
- `all` additionally exposes supported `subagent_await` and `subagent_consult` plus deprecated blocking `subagent` for compatibility.
58
-
59
- `subagent_spawn` is preferred only when detached execution creates real parallelism rather than moving the main agent's only useful task into a child.
60
-
61
- After spawning one worker, the main agent should immediately continue the named non-overlapping work instead of only announcing the spawn, waiting, polling, or ending the turn.
62
-
63
- Final-answer-dependent detached work needs a supported synthesis path such as opt-in `auto-resume`; default `next-turn` delivery remains appropriate only when the current response does not depend on the result.
64
-
65
- Blocking `subagent` is deprecated for new work but remains available with its existing schema and execution behavior for established callers and explicit requests whose chain, fan-in, panel, or workflow semantics lack a detached replacement.
66
-
67
- No removal release or date is set until those compatibility modes have a separately approved replacement or migration.
68
-
69
- `subagent_consult` remains a supported synchronous read-only exception.
70
-
71
- `subagent_await` remains a supported intentional join after useful overlapping parent work is complete.
72
-
73
- The four async lifecycle tools remain split because start, follow-up, lifecycle, and queue operations have distinct contracts.
74
- `subagent_await` remains separate because waiting blocks the parent, its timeout never interrupts the child, and the async-only workflow must omit it.
75
-
76
- Changing the default, removing deprecated `subagent`, or consolidating lifecycle tools needs a separate approved migration decision.
77
-
78
- ## Active follow-ups
79
-
80
- None.
81
-
82
- New implementation work should respond to demonstrated user needs rather than extending automatic or adaptive routing speculatively.
83
-
84
- ## Current reference notes
85
-
86
- - Git history for the completed main-agent-led delegation guidance records the accepted delegation rubric and verification evidence.
87
- - Git history for the completed async-first tool-surface work records the earlier tool-surface decision and implementation evidence.
88
- - [`pi-subagents-capability-matrix.md`](pi-subagents-capability-matrix.md) records maintained capability, detached lifecycle, transport, trust, and runtime-ownership boundaries.
89
- - [`pi-subagents-rpc-v1.md`](pi-subagents-rpc-v1.md) records the persistent RPC transport contract.
90
-
91
- ## Historical evidence
92
-
93
- The consolidated [research synthesis](../../../../docs/research/coding-agent-subagents-research.md) records the architecture conclusions available at the research cutoff.
94
-
95
- The companion [evidence catalog](../../../../docs/research/coding-agent-subagents-evidence-catalog.md) preserves paper-level results, caveats, and primary sources.
96
-
97
- Superseded automation, proactivity, and old runtime notes were removed to keep the active docs small.
98
-
99
- Git history remains the record of earlier research drafts and raw search transcripts.
@@ -1,153 +0,0 @@
1
- # pi-subagents RPC v1
2
-
3
- `pi-subagents:v1` is the extension-owned transport and metadata contract layered over Pi's built-in RPC JSONL protocol.
4
-
5
- It does not add commands to Pi RPC or alter Pi command and event payloads.
6
-
7
- ## Envelope
8
-
9
- Extension-owned progress, run inspection, and completion metadata may include these bounded fields:
10
-
11
- ```json
12
- {
13
- "protocol": "pi-subagents:v1",
14
- "agentId": "sa_…",
15
- "transport": "rpc",
16
- "phase": "starting | ready | accepted | running | finalizing | retrying | compacting | settled | failed | interrupted",
17
- "timing": {},
18
- "provider": "…",
19
- "model": "…",
20
- "thinkingLevel": "medium",
21
- "usage": {}
22
- }
23
- ```
24
-
25
- Fields are additive and optional within v1.
26
-
27
- A breaking lifecycle or envelope change requires another protocol identifier.
28
-
29
- Raw prompts, chain-of-thought, credentials, headers, environment values, full stderr, and raw tool arguments never enter the envelope.
30
-
31
- ## Usage accounting
32
-
33
- Pi 0.84.2 RPC `message_update.usage` values are cumulative for the current assistant message.
34
-
35
- RPC v1 keeps the latest validated update as one replaceable in-flight snapshot instead of adding successive updates together.
36
-
37
- A valid `message_end.message.usage` is authoritative for the finalized assistant message.
38
-
39
- When final usage has no valid token or total-cost field, RPC v1 commits the latest valid in-flight snapshot instead.
40
-
41
- A new assistant `message_start` commits usage from an interrupted prior attempt before tracking the new cumulative stream.
42
-
43
- Timeout finalization commits the interrupted work snapshot before clearing captured output and starting the bounded summary attempt.
44
-
45
- Progress and terminal outcomes expose the safe sum of committed usage plus the current in-flight snapshot.
46
-
47
- Only non-negative finite values no larger than `Number.MAX_SAFE_INTEGER` enter telemetry, and `totalTokens` is derived from valid components only when no valid reported total exists.
48
-
49
- The `turns` field continues to count finalized assistant messages only, so interrupted attempts and tool-result messages do not increment it.
50
-
51
- Usage progress contains only normalized token counts, total cost, and finalized-turn count, and never adds raw RPC events, prompts, content, reasoning, credentials, headers, or environment values to the envelope.
52
-
53
- ## Lifecycle
54
-
55
- One retained `agentId` lazily owns at most one RPC child.
56
-
57
- The child starts through the exact loaded Pi package with `--mode rpc --no-session --no-extensions`.
58
-
59
- A correlated `get_state` response is the readiness handshake.
60
-
61
- The task timeout begins only after readiness.
62
-
63
- Optional idle, assistant-turn, and tool-call budgets begin with prompt execution and observe only completed assistant messages or tool results as meaningful progress.
64
-
65
- The transport subscribes before sending `prompt`.
66
-
67
- A successful prompt response means accepted, not completed.
68
-
69
- `agent_end` is a low-level run boundary and cannot complete a retained turn.
70
-
71
- `agent_settled` is the authoritative completion boundary after retries, compaction, and queued continuations settle.
72
-
73
- Abort and timeout send the Pi RPC `abort` command and wait for settlement within a bounded grace period.
74
-
75
- After a work, idle, assistant-turn, or tool-call budget stop settles, the transport creates a bounded redacted checkpoint and sends one bounded finalization prompt that requests only a summary of already gathered evidence and explicitly forbids further tool use.
76
-
77
- Pi RPC does not currently replace an existing child session's active tool set for one turn, so the finalization deadline and abort path remain authoritative if the model disregards that instruction.
78
-
79
- The finalization turn has a separate model-work deadline of at most 45 seconds, followed only by bounded abort and process-cleanup grace, and never replays the timed-out task.
80
-
81
- Explicit parent interruption does not start finalization.
82
-
83
- A child that does not settle after work or finalization abort is terminated and cannot be reused.
84
-
85
- An accepted or ambiguously accepted task is never replayed automatically.
86
-
87
- Process exit marks the turn failed or interrupted with bounded partial evidence.
88
-
89
- Budget-stopped outcomes keep exit `124` and add a `pi-subagents:termination:v1` report with the stop reason, selected limit, deterministic `pi-subagents:checkpoint:v1`, side-effect warning, and finalization status.
90
-
91
- Release, expiry, close, session replacement, reload, and shutdown abort owned work and terminate the process group until captured streams close.
92
-
93
- Extension UI requests fail closed in v1.
94
-
95
- ## Resources and tools
96
-
97
- RPC v1 supports Pi built-in tools only.
98
-
99
- Child extensions stay disabled to prevent recursive `pi-subagents` loading and duplicate extension side effects.
100
-
101
- Custom or extension tools fail before RPC child creation with a subprocess recommendation.
102
-
103
- The selected cwd, project-trust decision, role prompt, model, thinking level, context, mailbox input, execution budgets, recursion depth, and output bounds retain their existing owners.
104
-
105
- `subagent_spawn.timeoutMs`, `idleTimeoutMs`, `maxTurns`, and `maxToolCalls` are retained as agent defaults, while the same fields on `subagent_send` override only one follow-up turn.
106
-
107
- RPC session-file persistence stays disabled because `AgentPersistence` owns sanitized logical recovery records.
108
-
109
- A restored record starts no process until an explicit follow-up arrives.
110
-
111
- Its first new RPC turn seeds bounded sanitized parent context and logical history exactly once.
112
-
113
- ## Automatic selection
114
-
115
- `stateful.transport: "auto"` selects exactly one transport before child creation.
116
-
117
- Read-only built-in tool sets select `in-process` for the lowest startup overhead.
118
-
119
- The current built-in `explorer` default uses only `read`, `grep`, `find`, and `ls`, so it remains eligible for this route.
120
-
121
- Write-capable built-in tool sets select `rpc` for a persistent separate process.
122
-
123
- Extension or custom tools select the existing fresh `subprocess` path.
124
-
125
- The selection remains fixed for the retained agent's current runtime lifetime.
126
-
127
- A restored inert record is preflighted again on its first explicit follow-up.
128
-
129
- No startup or post-acceptance failure triggers automatic fallback.
130
-
131
- ## Execution defaults
132
-
133
- Fast, Balanced, and Deep execution profiles were removed.
134
-
135
- The built-in `explorer` defaults to `low` thinking for bounded read-only exploration.
136
-
137
- The built-in `worker` inherits model and thinking unless a caller, frontmatter, or per-agent setting selects a value.
138
-
139
- Execution defaults do not change tools, transport, completion delivery, parent context, or explicit tool-call limits.
140
-
141
- ## Measurement
142
-
143
- Run `just benchmark-subagents` for serial offline startup and retained state-command measurements.
144
-
145
- The benchmark makes no provider request and therefore measures transport overhead rather than model quality or latency.
146
-
147
- A provider-backed smoke is optional and must stop after one clear external quota, credential, or entitlement failure.
148
-
149
- A seven-sample isolated-agent run on 2026-08-09 recorded 27.728 ms median deterministic fresh subprocess turn overhead with 0.782 ms MAD, 0.073 ms first retained RPC turn with 0.006 ms MAD, 0.037 ms retained RPC follow-up with 0.004 ms MAD, 445.631 ms real Pi RPC readiness with 9.765 ms MAD, 0.893 ms retained real Pi RPC `get_state` with 0.036 ms MAD, 3.759 ms in-process session creation with 0.198 ms MAD, and 0.001 ms retained in-process state access with 0.000 ms MAD.
150
-
151
- The deterministic turn measurements use a fake Pi while the readiness and SDK measurements use an isolated real Pi installation without credentials.
152
-
153
- The measurement supports retained transports as startup-overhead improvements without claiming provider-turn latency or quality.