@asterxsk/kiln 0.3.0 → 0.4.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 (267) hide show
  1. package/README.md +2 -2
  2. package/agent/version.txt +1 -1
  3. package/bin/kiln.js +10 -8
  4. package/package.json +1 -1
  5. package/agent.bak.20260905-190020/AGENTS.md +0 -67
  6. package/agent.bak.20260905-190020/README.md +0 -5
  7. package/agent.bak.20260905-190020/extensions/ask-user/index.ts +0 -418
  8. package/agent.bak.20260905-190020/extensions/ask-user/install.ps1 +0 -23
  9. package/agent.bak.20260905-190020/extensions/ask-user/install.sh +0 -21
  10. package/agent.bak.20260905-190020/extensions/ask-user/package-lock.json +0 -769
  11. package/agent.bak.20260905-190020/extensions/ask-user/package.json +0 -19
  12. package/agent.bak.20260905-190020/extensions/ask-user/prompt.ts +0 -45
  13. package/agent.bak.20260905-190020/extensions/ask-user/tsconfig.json +0 -7
  14. package/agent.bak.20260905-190020/extensions/background-terminals/docs/implementation-guide.md +0 -942
  15. package/agent.bak.20260905-190020/extensions/background-terminals/index.ts +0 -629
  16. package/agent.bak.20260905-190020/extensions/background-terminals/install.ps1 +0 -23
  17. package/agent.bak.20260905-190020/extensions/background-terminals/install.sh +0 -21
  18. package/agent.bak.20260905-190020/extensions/background-terminals/package-lock.json +0 -769
  19. package/agent.bak.20260905-190020/extensions/background-terminals/package.json +0 -17
  20. package/agent.bak.20260905-190020/extensions/background-terminals/src/domain.ts +0 -87
  21. package/agent.bak.20260905-190020/extensions/background-terminals/src/manager.ts +0 -907
  22. package/agent.bak.20260905-190020/extensions/background-terminals/src/output.ts +0 -84
  23. package/agent.bak.20260905-190020/extensions/background-terminals/src/prompt.ts +0 -142
  24. package/agent.bak.20260905-190020/extensions/background-terminals/src/result-delivery.ts +0 -27
  25. package/agent.bak.20260905-190020/extensions/background-terminals/src/runtime.ts +0 -36
  26. package/agent.bak.20260905-190020/extensions/background-terminals/src/ui/output-view.ts +0 -79
  27. package/agent.bak.20260905-190020/extensions/background-terminals/src/ui/ps.ts +0 -621
  28. package/agent.bak.20260905-190020/extensions/background-terminals/src/widget-order.ts +0 -121
  29. package/agent.bak.20260905-190020/extensions/background-terminals/test/manager.test.ts +0 -735
  30. package/agent.bak.20260905-190020/extensions/background-terminals/test/output.test.ts +0 -109
  31. package/agent.bak.20260905-190020/extensions/background-terminals/test/prompt.test.ts +0 -125
  32. package/agent.bak.20260905-190020/extensions/background-terminals/test/ps.test.ts +0 -82
  33. package/agent.bak.20260905-190020/extensions/background-terminals/test/result-delivery.test.ts +0 -44
  34. package/agent.bak.20260905-190020/extensions/background-terminals/tsconfig.json +0 -7
  35. package/agent.bak.20260905-190020/extensions/destructive/README.md +0 -34
  36. package/agent.bak.20260905-190020/extensions/destructive/index.ts +0 -124
  37. package/agent.bak.20260905-190020/extensions/destructive/install.ps1 +0 -23
  38. package/agent.bak.20260905-190020/extensions/destructive/install.sh +0 -21
  39. package/agent.bak.20260905-190020/extensions/file-search/index.ts +0 -459
  40. package/agent.bak.20260905-190020/extensions/file-search/install.ps1 +0 -23
  41. package/agent.bak.20260905-190020/extensions/file-search/install.sh +0 -21
  42. package/agent.bak.20260905-190020/extensions/file-search/package-lock.json +0 -2253
  43. package/agent.bak.20260905-190020/extensions/file-search/package.json +0 -23
  44. package/agent.bak.20260905-190020/extensions/file-search/src/args.ts +0 -122
  45. package/agent.bak.20260905-190020/extensions/file-search/src/binaries.ts +0 -422
  46. package/agent.bak.20260905-190020/extensions/file-search/src/output.ts +0 -126
  47. package/agent.bak.20260905-190020/extensions/file-search/src/process.ts +0 -146
  48. package/agent.bak.20260905-190020/extensions/file-search/src/prompt.ts +0 -52
  49. package/agent.bak.20260905-190020/extensions/file-search/test/index.spec.ts +0 -443
  50. package/agent.bak.20260905-190020/extensions/file-search/tsconfig.json +0 -7
  51. package/agent.bak.20260905-190020/extensions/goal/README.md +0 -50
  52. package/agent.bak.20260905-190020/extensions/goal/index.ts +0 -155
  53. package/agent.bak.20260905-190020/extensions/goal/install.ps1 +0 -23
  54. package/agent.bak.20260905-190020/extensions/goal/install.sh +0 -21
  55. package/agent.bak.20260905-190020/extensions/kiln-update/README.md +0 -25
  56. package/agent.bak.20260905-190020/extensions/kiln-update/index.ts +0 -99
  57. package/agent.bak.20260905-190020/extensions/kiln-update/install.ps1 +0 -23
  58. package/agent.bak.20260905-190020/extensions/kiln-update/install.sh +0 -21
  59. package/agent.bak.20260905-190020/extensions/modelconf/PLAN.md +0 -915
  60. package/agent.bak.20260905-190020/extensions/modelconf/README.md +0 -66
  61. package/agent.bak.20260905-190020/extensions/modelconf/index.ts +0 -296
  62. package/agent.bak.20260905-190020/extensions/modelconf/install.ps1 +0 -23
  63. package/agent.bak.20260905-190020/extensions/modelconf/install.sh +0 -21
  64. package/agent.bak.20260905-190020/extensions/modelconf/package-lock.json +0 -1809
  65. package/agent.bak.20260905-190020/extensions/modelconf/package.json +0 -13
  66. package/agent.bak.20260905-190020/extensions/modelconf/src/fuzzy.ts +0 -26
  67. package/agent.bak.20260905-190020/extensions/modelconf/src/glob.ts +0 -13
  68. package/agent.bak.20260905-190020/extensions/modelconf/src/persistence.test.ts +0 -46
  69. package/agent.bak.20260905-190020/extensions/modelconf/src/persistence.ts +0 -164
  70. package/agent.bak.20260905-190020/extensions/modelconf/src/ui/ModelConfView.test.ts +0 -75
  71. package/agent.bak.20260905-190020/extensions/modelconf/src/ui/ModelConfView.ts +0 -1101
  72. package/agent.bak.20260905-190020/extensions/modelconf/tsconfig.json +0 -15
  73. package/agent.bak.20260905-190020/extensions/pi-web-access/CHANGELOG.md +0 -690
  74. package/agent.bak.20260905-190020/extensions/pi-web-access/LICENSE +0 -21
  75. package/agent.bak.20260905-190020/extensions/pi-web-access/README.md +0 -470
  76. package/agent.bak.20260905-190020/extensions/pi-web-access/SECURITY.md +0 -5
  77. package/agent.bak.20260905-190020/extensions/pi-web-access/activity.ts +0 -101
  78. package/agent.bak.20260905-190020/extensions/pi-web-access/auth-fetch.ts +0 -148
  79. package/agent.bak.20260905-190020/extensions/pi-web-access/banner.png +0 -0
  80. package/agent.bak.20260905-190020/extensions/pi-web-access/brightdata-unlocker.ts +0 -272
  81. package/agent.bak.20260905-190020/extensions/pi-web-access/chrome-cookies.ts +0 -669
  82. package/agent.bak.20260905-190020/extensions/pi-web-access/content-find.ts +0 -139
  83. package/agent.bak.20260905-190020/extensions/pi-web-access/credential-source.ts +0 -191
  84. package/agent.bak.20260905-190020/extensions/pi-web-access/data-uri-sanitize.ts +0 -406
  85. package/agent.bak.20260905-190020/extensions/pi-web-access/datalab-pdf-extract.ts +0 -568
  86. package/agent.bak.20260905-190020/extensions/pi-web-access/declared-web-links.ts +0 -173
  87. package/agent.bak.20260905-190020/extensions/pi-web-access/evidence/CONTRACT-EVIDENCE.md +0 -496
  88. package/agent.bak.20260905-190020/extensions/pi-web-access/evidence/contract-probe.mjs +0 -140
  89. package/agent.bak.20260905-190020/extensions/pi-web-access/exa.ts +0 -526
  90. package/agent.bak.20260905-190020/extensions/pi-web-access/extract.ts +0 -1196
  91. package/agent.bak.20260905-190020/extensions/pi-web-access/feature-config.ts +0 -29
  92. package/agent.bak.20260905-190020/extensions/pi-web-access/fetch-params.ts +0 -111
  93. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-adc.ts +0 -298
  94. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-api.ts +0 -353
  95. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-pdf-extract.ts +0 -108
  96. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-search.ts +0 -21
  97. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-url-context.ts +0 -128
  98. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-web-config.ts +0 -101
  99. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-web.ts +0 -487
  100. package/agent.bak.20260905-190020/extensions/pi-web-access/github-api.ts +0 -197
  101. package/agent.bak.20260905-190020/extensions/pi-web-access/github-extract.ts +0 -746
  102. package/agent.bak.20260905-190020/extensions/pi-web-access/github-issue-pr.ts +0 -700
  103. package/agent.bak.20260905-190020/extensions/pi-web-access/index.ts +0 -1737
  104. package/agent.bak.20260905-190020/extensions/pi-web-access/package-lock.json +0 -5808
  105. package/agent.bak.20260905-190020/extensions/pi-web-access/package.json +0 -64
  106. package/agent.bak.20260905-190020/extensions/pi-web-access/page-query.ts +0 -96
  107. package/agent.bak.20260905-190020/extensions/pi-web-access/pdf-extract.ts +0 -409
  108. package/agent.bak.20260905-190020/extensions/pi-web-access/pi-web-fetch-demo.mp4 +0 -0
  109. package/agent.bak.20260905-190020/extensions/pi-web-access/promise-try.d.ts +0 -7
  110. package/agent.bak.20260905-190020/extensions/pi-web-access/query-rewrite.ts +0 -51
  111. package/agent.bak.20260905-190020/extensions/pi-web-access/render-search-error.ts +0 -170
  112. package/agent.bak.20260905-190020/extensions/pi-web-access/rsc-extract.ts +0 -338
  113. package/agent.bak.20260905-190020/extensions/pi-web-access/search-types.ts +0 -20
  114. package/agent.bak.20260905-190020/extensions/pi-web-access/source-check.ts +0 -282
  115. package/agent.bak.20260905-190020/extensions/pi-web-access/ssrf-protection.ts +0 -526
  116. package/agent.bak.20260905-190020/extensions/pi-web-access/storage.ts +0 -521
  117. package/agent.bak.20260905-190020/extensions/pi-web-access/summary-model-scope.ts +0 -125
  118. package/agent.bak.20260905-190020/extensions/pi-web-access/test/auth-fetch.test.mjs +0 -208
  119. package/agent.bak.20260905-190020/extensions/pi-web-access/test/brightdata-unlocker.test.mjs +0 -840
  120. package/agent.bak.20260905-190020/extensions/pi-web-access/test/chrome-cookie-extraction.test.mjs +0 -441
  121. package/agent.bak.20260905-190020/extensions/pi-web-access/test/config-path.test.mjs +0 -283
  122. package/agent.bak.20260905-190020/extensions/pi-web-access/test/content-find.test.mjs +0 -25
  123. package/agent.bak.20260905-190020/extensions/pi-web-access/test/credential-source.test.mjs +0 -118
  124. package/agent.bak.20260905-190020/extensions/pi-web-access/test/data-uri-sanitize.test.mjs +0 -210
  125. package/agent.bak.20260905-190020/extensions/pi-web-access/test/datalab-pdf-extract.test.mjs +0 -552
  126. package/agent.bak.20260905-190020/extensions/pi-web-access/test/declared-web-links.test.mjs +0 -212
  127. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-answer-storage.test.mjs +0 -40
  128. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-cache-storage.test.mjs +0 -334
  129. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-content-domain-policy.test.mjs +0 -95
  130. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-modes.test.mjs +0 -53
  131. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-not-found-guidance.test.mjs +0 -92
  132. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-params.test.mjs +0 -86
  133. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-render-call.test.mjs +0 -34
  134. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-routing.test.mjs +0 -173
  135. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-adc-auth.test.mjs +0 -257
  136. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-api-transport.test.mjs +0 -170
  137. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-pdf-extract.test.mjs +0 -133
  138. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-web-cookie-opt-in.test.mjs +0 -178
  139. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-web-header-overflow.test.mjs +0 -148
  140. package/agent.bak.20260905-190020/extensions/pi-web-access/test/get-search-content.test.mjs +0 -223
  141. package/agent.bak.20260905-190020/extensions/pi-web-access/test/github-extract.test.mjs +0 -378
  142. package/agent.bak.20260905-190020/extensions/pi-web-access/test/github-issue-pr.test.mjs +0 -565
  143. package/agent.bak.20260905-190020/extensions/pi-web-access/test/inline-content-config.test.mjs +0 -99
  144. package/agent.bak.20260905-190020/extensions/pi-web-access/test/lazy-extract-load.test.mjs +0 -118
  145. package/agent.bak.20260905-190020/extensions/pi-web-access/test/local-video-oversize.test.mjs +0 -52
  146. package/agent.bak.20260905-190020/extensions/pi-web-access/test/package-typebox-dependency.test.mjs +0 -50
  147. package/agent.bak.20260905-190020/extensions/pi-web-access/test/page-query.test.mjs +0 -51
  148. package/agent.bak.20260905-190020/extensions/pi-web-access/test/pdf-config.test.mjs +0 -140
  149. package/agent.bak.20260905-190020/extensions/pi-web-access/test/pdf-extract.test.mjs +0 -500
  150. package/agent.bak.20260905-190020/extensions/pi-web-access/test/proxy-transport.test.mjs +0 -286
  151. package/agent.bak.20260905-190020/extensions/pi-web-access/test/query-rewrite.test.mjs +0 -52
  152. package/agent.bak.20260905-190020/extensions/pi-web-access/test/rsc-fallback.test.mjs +0 -102
  153. package/agent.bak.20260905-190020/extensions/pi-web-access/test/search-error-render.test.mjs +0 -152
  154. package/agent.bak.20260905-190020/extensions/pi-web-access/test/search-providers.test.mjs +0 -274
  155. package/agent.bak.20260905-190020/extensions/pi-web-access/test/source-check.test.mjs +0 -179
  156. package/agent.bak.20260905-190020/extensions/pi-web-access/test/ssrf-allow-ranges-config.test.mjs +0 -205
  157. package/agent.bak.20260905-190020/extensions/pi-web-access/test/ssrf-protection.test.mjs +0 -456
  158. package/agent.bak.20260905-190020/extensions/pi-web-access/test/summary-model-scope.test.mjs +0 -106
  159. package/agent.bak.20260905-190020/extensions/pi-web-access/test/tool-registration-config.test.mjs +0 -182
  160. package/agent.bak.20260905-190020/extensions/pi-web-access/test/web-search-answer-render.test.mjs +0 -66
  161. package/agent.bak.20260905-190020/extensions/pi-web-access/test/youtube-extract-errors.test.mjs +0 -64
  162. package/agent.bak.20260905-190020/extensions/pi-web-access/tsconfig.json +0 -11
  163. package/agent.bak.20260905-190020/extensions/pi-web-access/utils.ts +0 -451
  164. package/agent.bak.20260905-190020/extensions/pi-web-access/video-extract.ts +0 -392
  165. package/agent.bak.20260905-190020/extensions/pi-web-access/youtube-extract.ts +0 -328
  166. package/agent.bak.20260905-190020/extensions/shared/activity-status.ts +0 -31
  167. package/agent.bak.20260905-190020/extensions/shared/child-session.ts +0 -148
  168. package/agent.bak.20260905-190020/extensions/shared/context-utilization.ts +0 -47
  169. package/agent.bak.20260905-190020/extensions/shared/dashboard-state.ts +0 -99
  170. package/agent.bak.20260905-190020/extensions/shared/install.ps1 +0 -23
  171. package/agent.bak.20260905-190020/extensions/shared/install.sh +0 -21
  172. package/agent.bak.20260905-190020/extensions/shared/test/child-session.test.ts +0 -270
  173. package/agent.bak.20260905-190020/extensions/shared/test/context-utilization.test.ts +0 -48
  174. package/agent.bak.20260905-190020/extensions/shared/test/tool-call-timeout.test.ts +0 -117
  175. package/agent.bak.20260905-190020/extensions/shared/test/widget-order.test.ts +0 -167
  176. package/agent.bak.20260905-190020/extensions/shared/tool-call-timeout.ts +0 -104
  177. package/agent.bak.20260905-190020/extensions/skillsconf/README.md +0 -74
  178. package/agent.bak.20260905-190020/extensions/skillsconf/index.ts +0 -92
  179. package/agent.bak.20260905-190020/extensions/skillsconf/install.ps1 +0 -23
  180. package/agent.bak.20260905-190020/extensions/skillsconf/install.sh +0 -21
  181. package/agent.bak.20260905-190020/extensions/skillsconf/package-lock.json +0 -1809
  182. package/agent.bak.20260905-190020/extensions/skillsconf/package.json +0 -18
  183. package/agent.bak.20260905-190020/extensions/skillsconf/src/delete-skill.test.ts +0 -64
  184. package/agent.bak.20260905-190020/extensions/skillsconf/src/delete-skill.ts +0 -45
  185. package/agent.bak.20260905-190020/extensions/skillsconf/src/filter.test.ts +0 -80
  186. package/agent.bak.20260905-190020/extensions/skillsconf/src/filter.ts +0 -74
  187. package/agent.bak.20260905-190020/extensions/skillsconf/src/fuzzy.ts +0 -26
  188. package/agent.bak.20260905-190020/extensions/skillsconf/src/persistence.test.ts +0 -72
  189. package/agent.bak.20260905-190020/extensions/skillsconf/src/persistence.ts +0 -169
  190. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/SkillConfView.test.ts +0 -337
  191. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/SkillConfView.ts +0 -758
  192. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/text-input.ts +0 -91
  193. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/tui-helpers.ts +0 -144
  194. package/agent.bak.20260905-190020/extensions/skillsconf/tsconfig.json +0 -15
  195. package/agent.bak.20260905-190020/extensions/statusline/index.ts +0 -282
  196. package/agent.bak.20260905-190020/extensions/statusline/install.ps1 +0 -23
  197. package/agent.bak.20260905-190020/extensions/statusline/install.sh +0 -21
  198. package/agent.bak.20260905-190020/extensions/subagents/docs/design-plan.md +0 -568
  199. package/agent.bak.20260905-190020/extensions/subagents/docs/effect-v4-extension-guide.md +0 -354
  200. package/agent.bak.20260905-190020/extensions/subagents/docs/effect-v4-notes.md +0 -571
  201. package/agent.bak.20260905-190020/extensions/subagents/index.ts +0 -826
  202. package/agent.bak.20260905-190020/extensions/subagents/install.ps1 +0 -23
  203. package/agent.bak.20260905-190020/extensions/subagents/install.sh +0 -21
  204. package/agent.bak.20260905-190020/extensions/subagents/package-lock.json +0 -2244
  205. package/agent.bak.20260905-190020/extensions/subagents/package.json +0 -19
  206. package/agent.bak.20260905-190020/extensions/subagents/src/backend.ts +0 -73
  207. package/agent.bak.20260905-190020/extensions/subagents/src/backends/claude.ts +0 -701
  208. package/agent.bak.20260905-190020/extensions/subagents/src/backends/codex.ts +0 -1060
  209. package/agent.bak.20260905-190020/extensions/subagents/src/backends/pi.ts +0 -575
  210. package/agent.bak.20260905-190020/extensions/subagents/src/backends/stub.ts +0 -300
  211. package/agent.bak.20260905-190020/extensions/subagents/src/by-the-way.ts +0 -21
  212. package/agent.bak.20260905-190020/extensions/subagents/src/domain.ts +0 -253
  213. package/agent.bak.20260905-190020/extensions/subagents/src/format.ts +0 -74
  214. package/agent.bak.20260905-190020/extensions/subagents/src/manager.ts +0 -736
  215. package/agent.bak.20260905-190020/extensions/subagents/src/prompt.ts +0 -92
  216. package/agent.bak.20260905-190020/extensions/subagents/src/result-delivery.ts +0 -20
  217. package/agent.bak.20260905-190020/extensions/subagents/src/runtime.ts +0 -53
  218. package/agent.bak.20260905-190020/extensions/subagents/src/ui/takeover.ts +0 -583
  219. package/agent.bak.20260905-190020/extensions/subagents/src/ui/transcript.ts +0 -201
  220. package/agent.bak.20260905-190020/extensions/subagents/src/widget-order.ts +0 -121
  221. package/agent.bak.20260905-190020/extensions/subagents/test/by-the-way.test.ts +0 -29
  222. package/agent.bak.20260905-190020/extensions/subagents/test/claude.test.ts +0 -119
  223. package/agent.bak.20260905-190020/extensions/subagents/test/codex.test.ts +0 -102
  224. package/agent.bak.20260905-190020/extensions/subagents/test/context-usage.test.ts +0 -107
  225. package/agent.bak.20260905-190020/extensions/subagents/test/manager.test.ts +0 -276
  226. package/agent.bak.20260905-190020/extensions/subagents/test/result-delivery.test.ts +0 -27
  227. package/agent.bak.20260905-190020/extensions/subagents/test/takeover.test.ts +0 -29
  228. package/agent.bak.20260905-190020/extensions/subagents/tsconfig.json +0 -7
  229. package/agent.bak.20260905-190020/extensions/taste/index.ts +0 -443
  230. package/agent.bak.20260905-190020/extensions/taste/install.ps1 +0 -23
  231. package/agent.bak.20260905-190020/extensions/taste/install.sh +0 -21
  232. package/agent.bak.20260905-190020/extensions/todo/AGENTS.md +0 -38
  233. package/agent.bak.20260905-190020/extensions/todo/LICENSE +0 -21
  234. package/agent.bak.20260905-190020/extensions/todo/config.ts +0 -55
  235. package/agent.bak.20260905-190020/extensions/todo/index.ts +0 -151
  236. package/agent.bak.20260905-190020/extensions/todo/install.ps1 +0 -23
  237. package/agent.bak.20260905-190020/extensions/todo/install.sh +0 -21
  238. package/agent.bak.20260905-190020/extensions/todo/locales/de.json +0 -17
  239. package/agent.bak.20260905-190020/extensions/todo/locales/en.json +0 -15
  240. package/agent.bak.20260905-190020/extensions/todo/locales/es.json +0 -17
  241. package/agent.bak.20260905-190020/extensions/todo/locales/fr.json +0 -17
  242. package/agent.bak.20260905-190020/extensions/todo/locales/pt-BR.json +0 -17
  243. package/agent.bak.20260905-190020/extensions/todo/locales/pt.json +0 -17
  244. package/agent.bak.20260905-190020/extensions/todo/locales/ru.json +0 -17
  245. package/agent.bak.20260905-190020/extensions/todo/locales/uk.json +0 -17
  246. package/agent.bak.20260905-190020/extensions/todo/locales/zh.json +0 -17
  247. package/agent.bak.20260905-190020/extensions/todo/package-lock.json +0 -3358
  248. package/agent.bak.20260905-190020/extensions/todo/package.json +0 -67
  249. package/agent.bak.20260905-190020/extensions/todo/state/i18n-bridge.ts +0 -64
  250. package/agent.bak.20260905-190020/extensions/todo/state/invariants.ts +0 -20
  251. package/agent.bak.20260905-190020/extensions/todo/state/replay.ts +0 -38
  252. package/agent.bak.20260905-190020/extensions/todo/state/selectors.ts +0 -107
  253. package/agent.bak.20260905-190020/extensions/todo/state/state-reducer.ts +0 -326
  254. package/agent.bak.20260905-190020/extensions/todo/state/state.ts +0 -18
  255. package/agent.bak.20260905-190020/extensions/todo/state/store.ts +0 -82
  256. package/agent.bak.20260905-190020/extensions/todo/state/task-graph.ts +0 -57
  257. package/agent.bak.20260905-190020/extensions/todo/todo-overlay.ts +0 -204
  258. package/agent.bak.20260905-190020/extensions/todo/todo.ts +0 -155
  259. package/agent.bak.20260905-190020/extensions/todo/tool/response-envelope.ts +0 -109
  260. package/agent.bak.20260905-190020/extensions/todo/tool/types.ts +0 -206
  261. package/agent.bak.20260905-190020/extensions/todo/view/format.ts +0 -177
  262. package/agent.bak.20260905-190020/extensions/todo/widget-order.ts +0 -121
  263. package/agent.bak.20260905-190020/extensions/trim-context/README.md +0 -54
  264. package/agent.bak.20260905-190020/extensions/trim-context/index.ts +0 -487
  265. package/agent.bak.20260905-190020/extensions/trim-context/install.ps1 +0 -23
  266. package/agent.bak.20260905-190020/extensions/trim-context/install.sh +0 -21
  267. package/agent.bak.20260905-190020/keybindings.json +0 -7
@@ -1,568 +0,0 @@
1
- # subagents — Design Plan
2
-
3
- A pi extension that fires off background subagents from a parent pi session, where each
4
- subagent can be powered by one of three backends — **pi** (in-process SDK session),
5
- **Claude Code** (`@anthropic-ai/claude-agent-sdk`), or **Codex** (`codex app-server`) —
6
- unified behind a single Effect v4 service interface.
7
-
8
- > **Status:** this document describes the original v1 plan (stubbed backends). All
9
- > three backends are now REAL implementations — see `src/backends/{pi,claude,codex}.ts`.
10
- > The stub machinery survives in `src/backends/stub.ts` for the manager test registry.
11
-
12
- **Scope of the first version:** interface design + stubbed backend internals + the v1 UI
13
- carried over. No real Claude/Codex process integration yet; the pi backend may also stay
14
- stubbed initially so the manager/UI/tool loop can be exercised end to end with zero
15
- external dependencies.
16
-
17
- **Location:** `/Users/davis/.pi/agent/extensions/subagents/` — fully self-contained
18
- (no imports from `../shared` or `../subagents`; the handful of shared helpers v1 uses are
19
- copied in).
20
-
21
- ---
22
-
23
- ## 1. V1 inventory (what must be preserved)
24
-
25
- Source: `/Users/davis/.pi/agent/extensions/subagents/` (`index.ts`, `manager.ts`,
26
- `prompt.ts`, `result-delivery.ts`, `takeover.ts`) plus `../shared/` helpers.
27
-
28
- ### 1.1 Tools exposed to the parent LLM
29
-
30
- | Tool | Parameters | Behavior |
31
- |---|---|---|
32
- | `subagent_spawn` | `prompt`, `title`, `working_dir?`, `model?`, `provider?`, `reasoning_effort?` | Fire-and-forget spawn. Returns immediately with an id (`sa-N`). Enforces `MAX_RUNNING = 4` with a synchronous reservation so parallel tool calls can't race past the cap. Validates `working_dir`, resolves model against the registry (inherit parent model/thinking level by default), truncates title to 160 chars. |
33
- | `subagent_wait` | `ids[]` (max 64) | Blocks until all listed subagents settle; respects the tool `AbortSignal`; streams `Waiting for ...` via `onUpdate`. Marks the awaited results "consumed" so they are not also auto-delivered. Output budgets: 48KB total, 16KB per agent, with per-section fallbacks (`[omitted: ...]`). Errors on unknown ids (lists known ids). |
34
- | `subagent_cancel` | `ids[]` | Aborts running subagents (marks consumed first to avoid duplicate delivery), waits for settlement, reports per-id `Cancelled ...` / `was already <status>`. Partial transcripts remain on disk. |
35
- | `subagent_check` | `id` | Non-blocking peek: status line, turn count, error text, up to 2KB/20 lines of latest output (includes the live streaming assistant message). Does not consume the result. |
36
- | `subagent_list` | — | One `describeSubagent()` line per agent: `id [status] "title" (provider/model, ctx%, elapsed, cwd)`. |
37
-
38
- Prompt metadata (all strings live in `prompt.ts`): `subagent_spawn` has a
39
- `promptSnippet` and two `promptGuidelines` (delegate self-contained tasks; don't block on
40
- `subagent_wait` unless necessary). Tool descriptions explain fire-and-forget semantics,
41
- the concurrency cap, and that children can't orchestrate/see the parent conversation.
42
-
43
- ### 1.2 State tracking (v1 `SubagentManager`)
44
-
45
- - Plain class with `Map<string, Subagent>`; each `Subagent` = `{ id, title, prompt, cwd,
46
- session: AgentSession, status: "running" | "done" | "error", createdAt, settledAt?,
47
- errorText?, unsubscribeLifecycle }`.
48
- - Children are **in-process pi `AgentSession`s** created via the SDK
49
- (`createAgentSession` + `SessionManager.create(cwd)` → real session files visible in
50
- `/resume`), with child resources loaded per-cwd (`DefaultResourceLoader`, trust-gated
51
- project resources) and a tool denylist (`excludeTools`: the subagent_* tools,
52
- `workflow`, `ask_user`).
53
- - Settlement is driven by session lifecycle events (`agent_start` re-marks running;
54
- `agent_settled` settles). Failure detection: thrown prompt error, last assistant
55
- `stopReason === "error" | "aborted"`, error text bounded to 4096 chars.
56
- - Change notification: `addChangeListener()` + `nextChange(signal)` promise — used by
57
- `waitFor`, the footer status, and the dashboard.
58
- - `waitFor(ids, signal, onPending)` keeps a `waitInterest` refcount per id so settles
59
- during an active wait are marked consumed.
60
- - `send(sub, text)`: steer via `session.steer()` while streaming, else start a fresh
61
- `prompt()` run (used by takeover).
62
- - Caps and cleanup: `MAX_RUNNING = 4`, `MAX_TRACKED = 64` with LRU pruning of settled
63
- agents, `STOP_TIMEOUT_MS = 5s` bounded aborts, force-dispose fallback, idempotent
64
- `disposeAll()` on `session_shutdown`.
65
-
66
- ### 1.3 Result delivery back to the parent
67
-
68
- - When a child settles **unconsumed**, `onSettled` defers it into a tiny
69
- `createDeferredResultDelivery` buffer (defer/consume/drain/clear keyed by id).
70
- - Flush happens when the parent goes idle: immediately if `sessionContext.isIdle()`,
71
- otherwise on the parent's `agent_settled` event. A later `subagent_wait` can still
72
- consume a deferred result before flush (that's why it is a buffer, not an immediate
73
- send).
74
- - Delivery = `pi.sendMessage({ customType: "subagent-result", content, display: true,
75
- details: { id, title, status } }, { deliverAs: "followUp", triggerTurn: true })`.
76
- Content is built by `buildSubagentResultMessage` (`Subagent sa-N "title"
77
- finished/failed.` + optional `Error:` line + output truncated to 24KB/600 lines with a
78
- pointer to the child session file for the full transcript).
79
-
80
- ### 1.4 UI (carried over into v2 essentially as-is)
81
-
82
- 1. **Footer status** (`ctx.ui.setStatus("subagents", ...)`): `subagents: ■ 2 running ·
83
- ■ 1 done · ■ 1 failed · /subagents to view` (warning/success/error colored squares;
84
- cleared when no subagents). Driven by manager change listener.
85
- 2. **`subagent-result` message renderer**: status icon (`■`/`x`) + bold accent header
86
- `subagent sa-N · title · finished/failed`; collapsed = first 8 body lines +
87
- `... (ctrl+o to expand)`; expanded = header + `Markdown` component render of the body.
88
- 3. **`/subagents` command** → `openSubagentPicker` loop (TUI mode only; notifies and
89
- bails in non-TUI or when there are no subagents):
90
- - **SubagentDashboard** — fullscreen overlay (`anchor: "center", width: "100%",
91
- maxHeight: "100%"`), bordered list panel titled `agents · settled/total`. Each row:
92
- selection marker `❯`, status glyph, title, dim id on the left; model id · context
93
- utilization (`%/capacity`) · elapsed · status word on the right. Scroll window
94
- centered on the selection with `... N more` markers. 1Hz ticker re-render for
95
- elapsed/token columns + manager change subscription. Keys: `tui.select.up/down`
96
- **and** `j`/`k` to move, `tui.select.confirm` to take over, `x` to abort the
97
- selected running agent, `tui.select.cancel` to close. Hint line shows the
98
- *configured* keys via `keybindings.getKeys()`.
99
- - **TakeoverView** — fullscreen overlay for one subagent: header line (status glyph,
100
- `id · title · status · elapsed · provider/model · ctx%`), fixed-height transcript
101
- viewport (error line and scroll indicator consume viewport rows so height never
102
- jumps), an `Input` line, and a hint row. Keys: `tui.input.submit` send (steer if
103
- streaming, new run if idle), `app.interrupt`/`tui.select.cancel` back to dashboard,
104
- `app.clear` abort run, `tui.editor.cursorUp/Down` scroll ±6 lines,
105
- `tui.editor.pageUp/Down` page. Renders are throttled to 50ms because streaming can
106
- emit per-token events.
107
- - **Transcript rendering** (`buildTranscriptLines`): sanitizes ANSI/tabs/control
108
- chars; user messages as `> ` accent-prefixed wrapped lines; assistant text wrapped
109
- plain; thinking as dim italic `~ ` lines; tool calls as `→ toolname {args}`; tool
110
- results as one dim `output:`/red `error:` first line. Includes the **live streaming
111
- assistant message**, **live tool executions** (running/done/error marker + first
112
- output line preview, tracked from `tool_execution_*` events until the final tool
113
- result message lands), and **queued steering/follow-up messages** (`> [queued
114
- steer] ...`) so Enter visibly acknowledges input.
115
-
116
- **V2 requirement:** all of the above renders from a *normalized* per-subagent view
117
- instead of poking at `sub.session` directly — that is the main UI refactor, everything
118
- else ports over mostly verbatim.
119
-
120
- ---
121
-
122
- ## 2. Backend integration facts
123
-
124
- These shape the interface even though v1-of-v2 stubs the internals. (Traced from the
125
- "T3 Code" codebase which integrates Codex and Claude Code.)
126
-
127
- | | Interactive sessions | One-shot tasks | Event shape | Interrupt | Steering |
128
- |---|---|---|---|---|---|
129
- | **pi** | In-process `createAgentSession()` (pi SDK); real session files; `session.subscribe()` | `session.prompt()` and read final assistant message (or `pi -p` subprocess, not needed) | `AgentSessionEvent` (message_start/update/end, tool_execution_*, agent_start/settled, queue_update, ...) | `session.abort()` | `session.steer()` / `followUp()` |
130
- | **Claude Code** | `@anthropic-ai/claude-agent-sdk` `query()` — SDK launches the `claude` executable and streams JSON messages (assistant/user/result/system, streaming partials, tool_use blocks) | `claude -p --output-format json` | SDK message stream (async iterable) | `query.interrupt()` / abort controller | streaming-input mode: push more user messages into the input iterable |
131
- | **Codex** | spawn `codex app-server` child process, JSON-RPC over stdin/stdout (`newConversation` / `sendUserTurn`, notifications: `agentMessageDelta`, `execCommandBegin/End`, `taskComplete`, `tokenCount`, ...) | `codex exec` (prints result to stdout, `--json` for events) | JSON-RPC notifications | `interruptConversation` request | send another `sendUserTurn` on the same conversation |
132
-
133
- Common denominator all three can supply:
134
-
135
- - an async event stream with: lifecycle (started/turn/settled), assistant text
136
- (deltas and/or completed messages), reasoning text, tool execution begin/update/end,
137
- token usage, errors;
138
- - a way to send a follow-up/steering user message into a live session;
139
- - an interrupt operation;
140
- - a final result text per run;
141
- - metadata: backend name, model identifier, session/log file path (pi session file,
142
- Claude session id + projects dir JSONL, Codex rollout path), working dir.
143
-
144
- That is exactly what the normalized event model below encodes.
145
-
146
- ---
147
-
148
- ## 3. Architecture
149
-
150
- ### 3.1 Effect v4 conventions used
151
-
152
- - Single `effect` package (v4 beta). Services defined with
153
- `ServiceMap.Service<T>()("id", ...)` / `ServiceMap.Key`; wiring via `Layer`;
154
- `ManagedRuntime.make(layer)` at the extension edge with `runtime.runPromise(effect,
155
- { signal })` inside `async execute()` tool handlers and `await runtime.dispose()` on
156
- `session_shutdown`.
157
- - `Effect.gen` generators throughout the internals. `async`/`Promise` appears **only**
158
- in: tool `execute()` bodies, `pi.on(...)` handlers, the `/subagents` command handler,
159
- and the imperative TUI component classes (which are callback-driven, not effectful).
160
- - Streams: `Stream<SubagentEvent>` per subagent, produced by backends
161
- (`Stream.callback` for push-based sources like JSON-RPC notifications / SDK
162
- iterables), consumed by a manager fiber per subagent.
163
- - Errors: tagged error classes (`Data.TaggedError`) — `SpawnError`, `BackendUnavailable`,
164
- `SubagentNotFound`, `ConcurrencyLimitError`, `SendError`, `InterruptTimeout`. Tool
165
- handlers map these to thrown `Error`s with the same user-facing messages v1 uses.
166
-
167
- ### 3.2 Domain model (`src/domain.ts`)
168
-
169
- ```ts
170
- type BackendName = "pi" | "claude" | "codex";
171
- type SubagentStatus = "running" | "done" | "error"; // unchanged from v1
172
-
173
- interface SpawnTask {
174
- prompt: string;
175
- title: string;
176
- cwd: string;
177
- // Generic model hint; each backend interprets/validates it its own way.
178
- model?: string; // pi: "provider/model-id"; claude: model alias; codex: model slug
179
- reasoningEffort?: string; // pi thinking level; codex reasoning effort; claude: ignored/mapped
180
- parentContext: { // resolved by the tool layer, passed opaquely
181
- parentCwd: string;
182
- projectTrusted: boolean;
183
- inheritedModelRef?: { provider: string; id: string }; // pi only
184
- inheritedThinkingLevel?: string;
185
- };
186
- }
187
-
188
- interface SubagentMeta {
189
- backend: BackendName;
190
- modelLabel?: string; // "anthropic/claude-opus-4-5", "gpt-5-codex", ...
191
- contextWindow?: number; // for utilization %, when known
192
- sessionFilePath?: string; // pi session file / claude JSONL / codex rollout path
193
- nativeSessionId?: string; // claude session id, codex conversation id
194
- }
195
- ```
196
-
197
- ### 3.3 Normalized event model (`src/domain.ts`)
198
-
199
- One discriminated union covers everything the v1 UI and manager need. Backends translate
200
- their native streams into this; nothing downstream knows which backend produced it.
201
-
202
- ```ts
203
- type SubagentEvent =
204
- // lifecycle
205
- | { _tag: "RunStarted" } // pi agent_start / claude init / codex turn start
206
- | { _tag: "RunSettled"; outcome: RunOutcome } // terminal per run (a session can run again via send())
207
- // transcript building blocks
208
- | { _tag: "UserMessage"; text: string } // initial prompt + takeover sends, echoed by backend
209
- | { _tag: "AssistantDelta"; kind: "text" | "thinking"; delta: string }
210
- | { _tag: "AssistantMessage"; parts: TranscriptPart[] } // finalized message (replaces live buffer)
211
- | { _tag: "ToolStart"; toolId: string; name: string; argsPreview?: string }
212
- | { _tag: "ToolUpdate"; toolId: string; outputPreview?: string }
213
- | { _tag: "ToolEnd"; toolId: string; isError: boolean; outputPreview?: string }
214
- // bookkeeping
215
- | { _tag: "QueueChanged"; queued: ReadonlyArray<{ text: string; kind: "steer" | "follow-up" }> }
216
- | { _tag: "UsageChanged"; tokens?: number; contextWindow?: number }
217
- | { _tag: "MetaChanged"; meta: Partial<SubagentMeta> } // model switched, session file known, ...
218
- | { _tag: "BackendError"; message: string }; // non-fatal diagnostics (fatal → RunSettled outcome)
219
-
220
- type RunOutcome =
221
- | { _tag: "Completed"; finalText: string }
222
- | { _tag: "Failed"; errorText: string; partialText?: string }
223
- | { _tag: "Interrupted"; partialText?: string };
224
-
225
- type TranscriptPart =
226
- | { type: "text"; text: string }
227
- | { type: "thinking"; text: string; redacted?: boolean }
228
- | { type: "toolCall"; toolId: string; name: string; argsPreview?: string };
229
- ```
230
-
231
- Mapping sanity check against what the v1 UI renders:
232
-
233
- | v1 render source | v2 event source |
234
- |---|---|
235
- | `sub.session.messages` (user/assistant/toolResult) | fold of `UserMessage` / `AssistantMessage` / `ToolEnd` into the snapshot transcript |
236
- | streaming message (`agent.state.streamingMessage`) | live buffer fed by `AssistantDelta` (cleared on `AssistantMessage`/`RunSettled`) |
237
- | live tool map from `tool_execution_*` | `ToolStart/Update/End` (entries drop when the finalized assistant/tool item lands, same as v1) |
238
- | queued steer/follow-up messages | `QueueChanged` |
239
- | status / errorText / settledAt | `RunStarted` / `RunSettled` |
240
- | model + context utilization columns | `MetaChanged` + `UsageChanged` |
241
- | `finalOutput` / `latestOutput` for check/wait/result delivery | `RunOutcome.finalText` (+ live buffer for `latestOutput`) |
242
-
243
- Previews (`argsPreview`, `outputPreview`) are pre-flattened single-line strings because
244
- the UI only ever shows one sanitized line — this avoids leaking three different native
245
- "tool result" shapes through the interface.
246
-
247
- ### 3.4 The `SubagentBackend` service (`src/backend.ts`)
248
-
249
- One interface; three implementations; a registry keyed by `BackendName`.
250
-
251
- ```ts
252
- interface SubagentBackend {
253
- readonly name: BackendName;
254
- readonly capabilities: {
255
- steering: boolean; // can send() into a live run (all three eventually; stubs: true)
256
- modelSelection: boolean;
257
- reasoningEffort: boolean;
258
- };
259
- /** Probe availability (binary on PATH, SDK importable, API key). Cheap + cached. */
260
- readonly available: Effect.Effect<boolean>;
261
- /**
262
- * Spawn a session. Scoped: releasing the scope interrupts/kills the underlying
263
- * session/process. Returns a live handle immediately (fire-and-forget semantics
264
- * live in the manager, not here).
265
- */
266
- spawn(task: SpawnTask): Effect.Effect<SubagentSession, SpawnError, Scope.Scope>;
267
- }
268
-
269
- interface SubagentSession {
270
- readonly meta: Effect.Effect<SubagentMeta>; // snapshot; also updated via MetaChanged
271
- /** All activity. Single consumer (the manager). Ends after the final RunSettled on close. */
272
- readonly events: Stream.Stream<SubagentEvent, never>;
273
- /** Steer while running, or start a fresh run when idle (v1 `manager.send` semantics). */
274
- send(text: string): Effect.Effect<void, SendError>;
275
- /** Interrupt the active run; resolves when the backend acknowledges. Bounded by the caller. */
276
- readonly interrupt: Effect.Effect<void>;
277
- /** Resolves with the outcome of the most recent run (mirrors the last RunSettled). */
278
- readonly awaitSettled: Effect.Effect<RunOutcome>;
279
- }
280
-
281
- // Registry: a plain ServiceMap.Key holding a ReadonlyMap<BackendName, SubagentBackend>,
282
- // built by a Layer that collects the three backend layers. Adding a 4th backend = one
283
- // new file + one line in the registry layer.
284
- class BackendRegistry extends ServiceMap.Key<BackendRegistry,
285
- ReadonlyMap<BackendName, SubagentBackend>>()("subagents/BackendRegistry") {}
286
- ```
287
-
288
- Design choices worth calling out:
289
-
290
- - **`spawn` is scoped, not paired with an explicit `dispose`.** The manager opens one
291
- `Scope` per subagent and closes it on cancel/prune/disposeAll — this replaces v1's
292
- `shutdownAndDisposeChildSession` + WeakMap-idempotence machinery with Effect's own
293
- guaranteed-once finalization. Timeout-bounded teardown (`5s`, then force) is a
294
- finalizer concern inside each backend.
295
- - **`send` unifies steer/new-run.** v1's `manager.send` already had these semantics; the
296
- interface keeps the decision inside the backend because "is a run active" is
297
- backend-native state.
298
- - **Events, not message arrays, are the contract.** The manager folds events into
299
- snapshots; backends never expose native message types. The pi backend has the richest
300
- native data and simply down-converts.
301
- - **No `exec()` one-shot operation in v1 of this extension** — see Open Questions; the
302
- interface deliberately leaves room to add `exec(task): Effect<RunOutcome>` later
303
- without touching the manager.
304
-
305
- ### 3.5 `SubagentManager` service (`src/manager.ts`)
306
-
307
- Owns the registry of running/finished subagents. Effect service; internally a `Ref` (or
308
- plain mutable map guarded by the single-threaded JS model) of entries plus a
309
- **synchronous read model** for the TUI.
310
-
311
- ```ts
312
- interface SubagentEntry {
313
- id: string; // "sa-N", same scheme as v1
314
- backend: BackendName;
315
- title: string; prompt: string; cwd: string;
316
- scope: Scope.Closeable; // owns the SubagentSession
317
- session: SubagentSession;
318
- eventPump: Fiber.Fiber<void>; // folds events → snapshot, fires settle hooks
319
- }
320
-
321
- interface SubagentSnapshot { // what the UI and tools read; plain immutable data
322
- id: string; backend: BackendName; title: string; cwd: string;
323
- status: SubagentStatus;
324
- createdAt: number; settledAt?: number;
325
- errorText?: string;
326
- meta: SubagentMeta;
327
- usage: { tokens?: number; contextWindow?: number };
328
- transcript: ReadonlyArray<TranscriptItem>; // finalized items
329
- liveAssistant?: { text: string; thinking: string };
330
- liveTools: ReadonlyArray<LiveToolState>; // v1's LiveToolEvent, verbatim
331
- queued: ReadonlyArray<{ text: string; kind: "steer" | "follow-up" }>;
332
- finalText: string; // last Completed finalText (v1 finalOutput)
333
- latestText: string; // finalText or live buffer (v1 latestOutput)
334
- turns: number; // count of AssistantMessage events (for subagent_check)
335
- }
336
-
337
- class SubagentManager extends ServiceMap.Key<SubagentManager, {
338
- spawn(backend: BackendName, task: SpawnTask):
339
- Effect.Effect<SubagentSnapshot, SpawnError | ConcurrencyLimitError | BackendUnavailable>;
340
- waitFor(ids: string[], onPending?: (pending: string[]) => void):
341
- Effect.Effect<void, SubagentNotFound>; // interruption = tool signal abort
342
- cancel(ids: string[]): Effect.Effect<CancelReport, SubagentNotFound>;
343
- send(id: string, text: string): Effect.Effect<void, SubagentNotFound | SendError>;
344
- get(id: string): Effect.Effect<SubagentSnapshot | undefined>;
345
- list: Effect.Effect<ReadonlyArray<SubagentSnapshot>>;
346
- disposeAll: Effect.Effect<void>;
347
- /** Synchronous read model for the TUI (see 3.6). */
348
- readonly view: SubagentReadModel;
349
- }>()("subagents/SubagentManager") {}
350
- ```
351
-
352
- Behavior preserved from v1, expressed in Effect terms:
353
-
354
- - **Concurrency cap**: `MAX_RUNNING = 4` enforced with a synchronous
355
- reserve-before-first-yield counter (same race-avoidance rationale as v1); the cap
356
- counts *running* agents across all backends (see Open Questions for per-backend caps).
357
- - **Settlement**: the per-subagent event pump fiber updates the snapshot on every event;
358
- on `RunSettled` it computes `status`/`errorText` (bounded to 4096 chars) and invokes
359
- the settle hook with `consumed = waitInterest > 0`. `waitFor` keeps the same
360
- wait-interest refcounts (a `Ref<Map<string, number>>`) and wakes on snapshot changes
361
- (a `Latch`/`PubSub`-based "next change" primitive replacing v1's resolver array).
362
- - **Cancel**: mark consumed → `session.interrupt` with 5s bound → close scope on
363
- timeout → wait for settle. Same "already \<status\>" reporting.
364
- - **Pruning**: `MAX_TRACKED = 64`, oldest settled non-wait-interested entries pruned by
365
- closing their scopes; cleanup tracked so `disposeAll` can await it.
366
- - **Settle → result delivery hook**: the manager exposes `onSettled` wiring identical in
367
- spirit to v1: the extension layer registers a callback that defers into the
368
- `result-delivery` buffer and flushes on parent idle / `agent_settled`. The
369
- `createDeferredResultDelivery` module is copied over unchanged (it is pure and already
370
- has a test).
371
-
372
- ### 3.6 Synchronous read model for the TUI (`src/read-model.ts`)
373
-
374
- The TUI components (`Component` classes with `render(width)`/`handleInput(data)`) are
375
- imperative and render synchronously — they cannot `yield*` effects. Bridge:
376
-
377
- ```ts
378
- interface SubagentReadModel {
379
- list(): ReadonlyArray<SubagentSnapshot>; // sync snapshot reads
380
- get(id: string): SubagentSnapshot | undefined;
381
- subscribe(listener: () => void): () => void; // any-change notification (dashboard, footer)
382
- subscribeTo(id: string, l: () => void): () => void; // per-agent (takeover view)
383
- // sync fire-and-forget commands, executed via the ManagedRuntime under the hood:
384
- requestSend(id: string, text: string): void; // TakeoverView input submit
385
- requestAbort(id: string): void; // dashboard `x`, takeover app.clear
386
- }
387
- ```
388
-
389
- The manager's event pump writes each new snapshot into this store (plain mutable map +
390
- listener set) as its last step, so the UI is always at most one microtask behind the
391
- Effect world and v1's dashboard/takeover code ports with only these substitutions:
392
-
393
- | v1 | v2 |
394
- |---|---|
395
- | `manager.list()` / `manager.get(id)` | `view.list()` / `view.get(id)` |
396
- | `manager.addChangeListener` | `view.subscribe` |
397
- | `sub.session.subscribe(handleSessionEvent)` + local live-tool map | `view.subscribeTo(id, ...)` + read `snapshot.liveTools` / `liveAssistant` (the fold moved into the manager) |
398
- | `manager.send(sub, text)` / `manager.abort(sub)` | `view.requestSend(id, text)` / `view.requestAbort(id)` |
399
- | `buildTranscriptLines(sub, ...)` reading `session.messages` | `buildTranscriptLines(snapshot, ...)` reading `snapshot.transcript` + live state + `snapshot.queued` |
400
-
401
- Keybindings, layout math, scroll behavior, 1Hz ticker, 50ms render throttle, sanitize
402
- logic: copied as-is.
403
-
404
- ### 3.7 Extension edge (`index.ts` + `src/runtime.ts`)
405
-
406
- ```
407
- Layer graph:
408
- PiBackendStub.layer ─┐
409
- ClaudeBackendStub.layer ─┼→ BackendRegistry.layer ─→ SubagentManager.layer ─→ AppLayer
410
- CodexBackendStub.layer ─┘
411
- ```
412
-
413
- - `const runtime = ManagedRuntime.make(AppLayer)` — created lazily on first use (per the
414
- extension-docs guidance to not start background resources in the factory;
415
- `ManagedRuntime` builds its layer on first run, which satisfies this, but we still
416
- gate creation behind `session_start`). `session_shutdown`: `runtime.runPromise(
417
- manager.disposeAll)` then `await runtime.dispose()`, then recreate on the next
418
- `session_start` (handles `/new`, `/resume`, `/reload`).
419
- - **Tool handlers are the async boundary.** Each `execute(toolCallId, params, signal,
420
- onUpdate, ctx)` builds one `Effect.gen` program and runs it with
421
- `runtime.runPromise(program, { signal })`; tool-visible errors are converted from
422
- tagged errors to `Error` messages matching v1 wording. `onUpdate` and `ctx`
423
- (model registry, cwd, trust) are captured into the program as plain values/callbacks.
424
- - **Tool schema change:** `subagent_spawn` gains
425
- `agent: StringEnum(["pi", "claude", "codex"])` (optional, default `"pi"`), and
426
- `model`/`provider`/`reasoning_effort` keep their v1 shapes but are documented as
427
- backend-interpreted (pi validates against the registry; claude/codex validate against
428
- their own known-model rules — stubs accept anything). `describeSubagent` lines and the
429
- dashboard gain the backend name (e.g. `sa-3 [running] "title" (codex, gpt-5-codex,
430
- 41%/272k, 1m32s, /repo)`).
431
- - `pi.registerMessageRenderer("subagent-result", ...)`, `pi.registerCommand(
432
- "subagents", ...)`, footer status updates, and the result-delivery flush hooks
433
- (`agent_settled`, idle-check on settle) are wired exactly like v1 — these all live
434
- outside the runtime and call into it only via `runPromise`/the read model.
435
-
436
- ### 3.8 What the stubs do (v1 of this extension)
437
-
438
- All three backends share a `createStubSession(profile)` helper (`src/backends/stub.ts`)
439
- that fakes a plausible session so the manager, tools, result delivery, and both TUI
440
- views are exercised end to end:
441
-
442
- - **spawn**: emits `MetaChanged` (backend-flavored model label + fake session file path
443
- under `os.tmpdir()`, e.g. `.../subagents-stub/sa-1.jsonl`, actually written with the
444
- transcript so "full transcript in session file" pointers resolve), then `RunStarted`,
445
- then a scripted turn: 2–3 `AssistantDelta` batches on a timer (~200ms cadence so
446
- streaming is visible), one fake `ToolStart/Update/End` cycle (`bash` with an args
447
- preview), `UsageChanged` ramping tokens, a final `AssistantMessage`, and `RunSettled`
448
- with `Completed` — final text echoes the task: `"[stub:claude] completed: <first 200
449
- chars of prompt>"`. Total runtime ~3–6s (configurable per profile) so `subagent_wait`,
450
- the footer counters, and the dashboard's running→done transition are observable.
451
- - **send**: emits `UserMessage` + `QueueChanged` (briefly, to exercise the queued-line
452
- rendering) and runs another scripted turn — so takeover steering works.
453
- - **interrupt**: stops the script timer and settles with `Interrupted` (→ status
454
- `error`, errorText `"Run was aborted"`, matching v1) — so `subagent_cancel` and the
455
- `x`/`app.clear` keybindings work.
456
- - **failure path**: a magic prompt prefix (e.g. `FAIL:`) makes the run settle with
457
- `Failed` — so error rendering, `errorText` rows, and failed result delivery are
458
- testable without real backends.
459
- - **Backend differentiation**: per-backend profiles vary the model label
460
- (`anthropic/claude-opus-4-5` vs `claude-sonnet-4-5` vs `gpt-5-codex`), fake context
461
- window, tool names, and delta cadence — enough to verify the UI treats backends
462
- uniformly. `available` returns `true` for stubs (real impls will probe binaries/SDK).
463
- - The **pi stub** can later be swapped for the real in-process SDK implementation by
464
- porting v1's `manager.ts` session code behind the same `SubagentSession` shape; that
465
- port is the first post-stub milestone.
466
-
467
- ---
468
-
469
- ## 4. File/module layout
470
-
471
- ```
472
- /Users/davis/.pi/agent/extensions/subagents/
473
- ├── package.json # name, "effect": "^4.0.0-beta.x"; pi extension entry via pi.extensions
474
- ├── package-lock.json / node_modules/ (after npm install)
475
- ├── docs/
476
- │ └── design-plan.md # this document
477
- ├── index.ts # extension factory: runtime lifecycle, 5 tools, /subagents
478
- │ # command, message renderer, footer status, result flush hooks
479
- └── src/
480
- ├── domain.ts # BackendName, SubagentStatus, SpawnTask, SubagentEvent,
481
- │ # RunOutcome, TranscriptItem/Part, SubagentSnapshot, tagged errors
482
- ├── backend.ts # SubagentBackend + SubagentSession interfaces, BackendRegistry
483
- │ # key + registry layer
484
- ├── backends/
485
- │ ├── stub.ts # shared scripted fake-session machinery
486
- │ ├── pi.ts # PiBackend layer (v1: stub profile; later: real pi SDK sessions)
487
- │ ├── claude.ts # ClaudeBackend layer (v1: stub; later: @anthropic-ai/claude-agent-sdk)
488
- │ └── codex.ts # CodexBackend layer (v1: stub; later: codex app-server JSON-RPC)
489
- ├── manager.ts # SubagentManager service + layer: registry, cap, waitFor,
490
- │ # cancel, prune, settle hook, event-fold into snapshots
491
- ├── read-model.ts # sync SubagentReadModel bridge for the TUI
492
- ├── runtime.ts # AppLayer composition + ManagedRuntime create/dispose helpers
493
- ├── result-delivery.ts # deferred delivery buffer (copied from v1, unchanged)
494
- ├── result-delivery.test.ts
495
- ├── prompt.ts # all model-facing strings (v1 copy + `agent` param description)
496
- ├── format.ts # elapsed/context-utilization/activity-status formatting
497
- │ # (merged copies of ../shared/{context-utilization,activity-status}.ts)
498
- └── ui/
499
- ├── transcript.ts # sanitize + buildTranscriptLines over SubagentSnapshot
500
- └── takeover.ts # SubagentDashboard + TakeoverView + openSubagentPicker (ported)
501
- ```
502
-
503
- Notes:
504
- - `package.json` is needed because `effect` is an npm dependency (extension-with-deps
505
- style from the extension docs). Everything else avoids new dependencies.
506
- - v1's `child-session.ts` trust/tool-policy helpers are **not** copied in v1 of v2 (the
507
- stubs don't need them); the real pi backend will bring the needed subset into
508
- `backends/pi.ts` when implemented. The `resolveStandaloneChildProjectTrust` logic *is*
509
- still referenced by the design (SpawnTask.parentContext.projectTrusted) so the tool
510
- layer computes trust the same way v1 does.
511
- - Suggested project scripts (per house rules, to be added): `check` (`tsc --noEmit`),
512
- `test` (`node --test` or vitest for `result-delivery` + manager fold tests against
513
- stub backends).
514
-
515
- ---
516
-
517
- ## 5. Migration/coexistence note
518
-
519
- v1 and v2 register the same tool names (`subagent_spawn`, ...) and the same
520
- `/subagents` command. While both live in `~/.pi/agent/extensions/`, pi will suffix
521
- duplicate commands (`/subagents:1`, `/subagents:2`) and both tool sets would be
522
- registered. During development, either (a) v2 uses temporary names
523
- (`subagent2_spawn`, `/subagents2`), or (b) v1 is moved out of the auto-discovery dir.
524
- Recommendation: (a) during development, rename to final names when v2 replaces v1.
525
-
526
- ---
527
-
528
- ## 6. Open questions (need user input)
529
-
530
- 1. **Per-backend spawn options.** v1's `model`/`provider`/`reasoning_effort` are
531
- pi-shaped. Options: (a) keep one generic `model` string + `reasoning_effort` that
532
- each backend interprets (proposed above — simplest for the LLM); (b) add a
533
- `backend_options` free-form object; (c) per-backend defaults in a config file with no
534
- per-spawn override. Which surface do you want the parent LLM to have?
535
- 2. **One-shot exec mode.** Should the interface expose a separate cheap
536
- `exec(task): Effect<RunOutcome>` (mapping to `codex exec` / `claude -p
537
- --output-format json` / a fresh in-memory pi session), or is one interactive-session
538
- path enough? Exec would forfeit takeover/steering for that subagent — is a
539
- `mode: "session" | "exec"` spawn parameter desirable, or backend-internal
540
- optimization only?
541
- 3. **Permissions/sandboxing for Claude/Codex children.** Subagents are headless, so
542
- interactive permission prompts are impossible. Do we run Claude with
543
- `bypassPermissions`/`--dangerously-skip-permissions` and Codex with
544
- `--full-auto`-style sandbox + never-ask approval policy? Should this be a global
545
- extension setting, per-spawn, or hardcoded? (Pi children inherit v1's trust-store
546
- logic — keep that as-is?)
547
- 4. **Concurrency cap scope.** Keep one global `MAX_RUNNING = 4`, or per-backend caps
548
- (e.g. 4 pi + 2 claude + 2 codex)? Global is proposed as default.
549
- 5. **Steering support parity in real backends.** Codex steering means
550
- interrupt-then-new-turn or queued `sendUserTurn`; Claude requires streaming-input
551
- mode from the start. OK to declare `capabilities.steering` and have the TakeoverView
552
- input show "(steering not supported)" if a backend can't, or is steering a hard
553
- requirement for all three?
554
- 6. **Model/thinking inheritance across backends.** When `agent: "claude"` and no model
555
- given, what's the default (e.g. always `opus`/`sonnet`)? Inheriting the parent pi
556
- model is meaningless cross-backend. Proposal: per-backend default model in a small
557
- config block; confirm.
558
- 7. **Binary/SDK discovery + failure UX.** When `codex`/`claude` isn't installed or has
559
- no credentials, should `subagent_spawn` fail fast with a clear tool error (proposed),
560
- or should the backends be hidden from the `agent` enum dynamically?
561
- 8. **Result truncation budgets.** Keep v1's numbers (24KB result message, 48KB wait
562
- total, 16KB per agent, 2KB check preview) unchanged?
563
- 9. **Effect version pinning.** Effect v4 is beta — pin an exact `4.0.0-beta.x` and
564
- accept manual bumps, or track the beta dist-tag?
565
- 10. **Persistence across reloads.** v1 loses all subagents on `session_shutdown`
566
- (disposeAll). Codex/Claude children are external processes that *could* outlive a
567
- pi reload — should v2 keep v1's kill-everything behavior (proposed for v1 of v2) or
568
- plan for reattach later?