@baique/pi-web-sky 0.1.54 → 0.1.56

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 (509) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +14 -10
  3. package/.next/build-manifest.json +4 -4
  4. package/.next/next-server.js.nft.json +1 -1
  5. package/.next/prerender-manifest.json +6 -6
  6. package/.next/react-loadable-manifest.json +3 -3
  7. package/.next/required-server-files.js +6 -6
  8. package/.next/required-server-files.json +6 -6
  9. package/.next/routes-manifest.json +28 -0
  10. package/.next/server/app/_global-error/page.js +2 -2
  11. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/_global-error.html +1 -1
  13. package/.next/server/app/_global-error.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/server/app/_not-found/page.js +1 -1
  18. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/server/app/_not-found.html +1 -1
  20. package/.next/server/app/_not-found.rsc +4 -3
  21. package/.next/server/app/_not-found.segments/_full.segment.rsc +4 -3
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -3
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -2
  24. package/.next/server/app/api/agent/[id]/bash-output/route.js +2 -2
  25. package/.next/server/app/api/agent/[id]/bash-output/route_client-reference-manifest.js +1 -1
  26. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  27. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/agent/[id]/route.js +1 -1
  30. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  31. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/agent/new/route.js +1 -1
  33. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  34. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/agent/running/route.js +1 -1
  36. package/.next/server/app/api/agent/running/route.js.nft.json +1 -1
  37. package/.next/server/app/api/agent/running/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/app-update/route.js +1 -1
  39. package/.next/server/app/api/app-update/route_client-reference-manifest.js +1 -1
  40. package/.next/server/app/api/auth/all-providers/route.js +1 -1
  41. package/.next/server/app/api/auth/all-providers/route_client-reference-manifest.js +1 -1
  42. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
  43. package/.next/server/app/api/auth/api-key/[provider]/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
  45. package/.next/server/app/api/auth/login/[provider]/route_client-reference-manifest.js +1 -1
  46. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
  47. package/.next/server/app/api/auth/logout/[provider]/route_client-reference-manifest.js +1 -1
  48. package/.next/server/app/api/auth/providers/route.js +1 -1
  49. package/.next/server/app/api/auth/providers/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/board-assets/[...path]/route.js +2 -2
  51. package/.next/server/app/api/board-assets/[...path]/route_client-reference-manifest.js +1 -1
  52. package/.next/server/app/api/board-assets/route.js +2 -2
  53. package/.next/server/app/api/board-assets/route_client-reference-manifest.js +1 -1
  54. package/.next/server/app/api/boards/[id]/add-session/route.js +1 -0
  55. package/.next/server/app/api/boards/[id]/add-session/route.js.nft.json +1 -0
  56. package/.next/server/app/api/boards/[id]/add-session/route_client-reference-manifest.js +1 -0
  57. package/.next/server/app/api/boards/[id]/reconcile/route.js +1 -1
  58. package/.next/server/app/api/boards/[id]/reconcile/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/boards/[id]/route.js +1 -1
  60. package/.next/server/app/api/boards/[id]/route_client-reference-manifest.js +1 -1
  61. package/.next/server/app/api/boards/reorder/route.js +2 -2
  62. package/.next/server/app/api/boards/reorder/route_client-reference-manifest.js +1 -1
  63. package/.next/server/app/api/boards/route.js +2 -2
  64. package/.next/server/app/api/boards/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/cwd/browse/route.js +1 -1
  66. package/.next/server/app/api/cwd/browse/route_client-reference-manifest.js +1 -1
  67. package/.next/server/app/api/cwd/validate/route.js +2 -2
  68. package/.next/server/app/api/cwd/validate/route_client-reference-manifest.js +1 -1
  69. package/.next/server/app/api/default-cwd/route.js +2 -2
  70. package/.next/server/app/api/default-cwd/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/file-index/route.js +2 -2
  72. package/.next/server/app/api/file-index/route_client-reference-manifest.js +1 -1
  73. package/.next/server/app/api/files/[...path]/route.js +3 -3
  74. package/.next/server/app/api/files/[...path]/route_client-reference-manifest.js +1 -1
  75. package/.next/server/app/api/git/diff/route.js +1 -1
  76. package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/git/status/route.js +1 -1
  78. package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/home/route.js +1 -1
  80. package/.next/server/app/api/home/route_client-reference-manifest.js +1 -1
  81. package/.next/server/app/api/mcp/route.js +2 -2
  82. package/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/models/route.js +2 -2
  84. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  85. package/.next/server/app/api/models-config/catalog/route.js +1 -1
  86. package/.next/server/app/api/models-config/catalog/route_client-reference-manifest.js +1 -1
  87. package/.next/server/app/api/models-config/discover/route.js +1 -1
  88. package/.next/server/app/api/models-config/discover/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/models-config/route.js +1 -1
  90. package/.next/server/app/api/models-config/route_client-reference-manifest.js +1 -1
  91. package/.next/server/app/api/models-config/test/route.js +1 -1
  92. package/.next/server/app/api/models-config/test/route_client-reference-manifest.js +1 -1
  93. package/.next/server/app/api/plugins/route.js +2 -2
  94. package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/project-trust/route.js +1 -1
  96. package/.next/server/app/api/project-trust/route.js.nft.json +1 -1
  97. package/.next/server/app/api/project-trust/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/quota/route.js +1 -1
  99. package/.next/server/app/api/quota/route_client-reference-manifest.js +1 -1
  100. package/.next/server/app/api/search/route.js +2 -2
  101. package/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  102. package/.next/server/app/api/sessions/[id]/auto-name/route.js +2 -2
  103. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -1
  104. package/.next/server/app/api/sessions/[id]/auto-name/route_client-reference-manifest.js +1 -1
  105. package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
  106. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -1
  107. package/.next/server/app/api/sessions/[id]/context/route_client-reference-manifest.js +1 -1
  108. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +2 -2
  109. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/api/sessions/[id]/export/route.js +3 -3
  111. package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -1
  112. package/.next/server/app/api/sessions/[id]/minimap/route.js +1 -1
  113. package/.next/server/app/api/sessions/[id]/minimap/route.js.nft.json +1 -1
  114. package/.next/server/app/api/sessions/[id]/minimap/route_client-reference-manifest.js +1 -1
  115. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  116. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  117. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
  118. package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
  119. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -1
  120. package/.next/server/app/api/sessions/[id]/state/route_client-reference-manifest.js +1 -1
  121. package/.next/server/app/api/sessions/[id]/todos/route.js +1 -1
  122. package/.next/server/app/api/sessions/[id]/todos/route.js.nft.json +1 -1
  123. package/.next/server/app/api/sessions/[id]/todos/route_client-reference-manifest.js +1 -1
  124. package/.next/server/app/api/sessions/route.js +1 -1
  125. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  126. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  127. package/.next/server/app/api/sessions/summary/route.js +2 -2
  128. package/.next/server/app/api/sessions/summary/route_client-reference-manifest.js +1 -1
  129. package/.next/server/app/api/skills/check/route.js +1 -1
  130. package/.next/server/app/api/skills/check/route_client-reference-manifest.js +1 -1
  131. package/.next/server/app/api/skills/install/route.js +2 -2
  132. package/.next/server/app/api/skills/install/route_client-reference-manifest.js +1 -1
  133. package/.next/server/app/api/skills/route.js +1 -1
  134. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  135. package/.next/server/app/api/skills/search/route.js +1 -1
  136. package/.next/server/app/api/skills/search/route_client-reference-manifest.js +1 -1
  137. package/.next/server/app/api/skills/update/route.js +1 -1
  138. package/.next/server/app/api/skills/update/route_client-reference-manifest.js +1 -1
  139. package/.next/server/app/api/subagents/[id]/route.js +1 -0
  140. package/.next/server/app/api/subagents/[id]/route.js.nft.json +1 -0
  141. package/.next/server/app/api/subagents/[id]/route_client-reference-manifest.js +1 -0
  142. package/.next/server/app/api/subagents/profiles/route.js +30 -0
  143. package/.next/server/app/api/subagents/profiles/route.js.nft.json +1 -0
  144. package/.next/server/app/api/subagents/profiles/route_client-reference-manifest.js +1 -0
  145. package/.next/server/app/api/subagents/settings/route.js +1 -0
  146. package/.next/server/app/api/subagents/settings/route.js.nft.json +1 -0
  147. package/.next/server/app/api/subagents/settings/route_client-reference-manifest.js +1 -0
  148. package/.next/server/app/api/task-card-questions/[id]/answer/route.js +2 -2
  149. package/.next/server/app/api/task-card-questions/[id]/answer/route_client-reference-manifest.js +1 -1
  150. package/.next/server/app/api/task-card-questions/route.js +2 -2
  151. package/.next/server/app/api/task-card-questions/route_client-reference-manifest.js +1 -1
  152. package/.next/server/app/api/task-cards/[id]/route.js +1 -1
  153. package/.next/server/app/api/task-cards/[id]/route_client-reference-manifest.js +1 -1
  154. package/.next/server/app/api/task-cards/route.js +1 -1
  155. package/.next/server/app/api/task-cards/route_client-reference-manifest.js +1 -1
  156. package/.next/server/app/api/task-cards/unbind/route.js +3 -3
  157. package/.next/server/app/api/task-cards/unbind/route_client-reference-manifest.js +1 -1
  158. package/.next/server/app/api/task-scheduler/status/route.js +1 -1
  159. package/.next/server/app/api/task-scheduler/status/route.js.nft.json +1 -1
  160. package/.next/server/app/api/task-scheduler/status/route_client-reference-manifest.js +1 -1
  161. package/.next/server/app/api/tasks/[id]/assign-session/route.js +12 -12
  162. package/.next/server/app/api/tasks/[id]/assign-session/route_client-reference-manifest.js +1 -1
  163. package/.next/server/app/api/tasks/[id]/board/route.js +1 -1
  164. package/.next/server/app/api/tasks/[id]/board/route_client-reference-manifest.js +1 -1
  165. package/.next/server/app/api/tasks/[id]/route.js +1 -1
  166. package/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
  167. package/.next/server/app/api/tasks/[id]/route_client-reference-manifest.js +1 -1
  168. package/.next/server/app/api/tasks/reorder/route.js +12 -12
  169. package/.next/server/app/api/tasks/reorder/route_client-reference-manifest.js +1 -1
  170. package/.next/server/app/api/tasks/route.js +12 -12
  171. package/.next/server/app/api/tasks/route_client-reference-manifest.js +1 -1
  172. package/.next/server/app/api/terminal/[id]/events/route.js +3 -3
  173. package/.next/server/app/api/terminal/[id]/events/route_client-reference-manifest.js +1 -1
  174. package/.next/server/app/api/terminal/[id]/route.js +2 -2
  175. package/.next/server/app/api/terminal/[id]/route_client-reference-manifest.js +1 -1
  176. package/.next/server/app/api/terminal/route.js +2 -2
  177. package/.next/server/app/api/terminal/route_client-reference-manifest.js +1 -1
  178. package/.next/server/app/api/worktrees/route.js +2 -2
  179. package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
  180. package/.next/server/app/api/yjs-version/route.js +1 -1
  181. package/.next/server/app/api/yjs-version/route_client-reference-manifest.js +1 -1
  182. package/.next/server/app/favicon.ico/route.js +1 -1
  183. package/.next/server/app/index.html +1 -1
  184. package/.next/server/app/index.rsc +6 -5
  185. package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -5
  186. package/.next/server/app/index.segments/_full.segment.rsc +6 -5
  187. package/.next/server/app/index.segments/_tree.segment.rsc +3 -2
  188. package/.next/server/app/manifest.webmanifest/route.js +2 -2
  189. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
  190. package/.next/server/app/page.js +175 -8
  191. package/.next/server/app/page_client-reference-manifest.js +1 -1
  192. package/.next/server/app-paths-manifest.json +14 -10
  193. package/.next/server/chunks/1937.js +1 -1
  194. package/.next/server/chunks/2430.js +4 -4
  195. package/.next/server/chunks/3500.js +1 -1
  196. package/.next/server/chunks/402.js +13 -3
  197. package/.next/server/chunks/426.js +14 -0
  198. package/.next/server/chunks/4457.js +13 -13
  199. package/.next/server/chunks/542.js +23 -4
  200. package/.next/server/chunks/5794.js +2 -2
  201. package/.next/server/chunks/5940.js +1 -1
  202. package/.next/server/chunks/6429.js +15 -2
  203. package/.next/server/chunks/6525.js +12 -2
  204. package/.next/server/chunks/6583.js +1 -1
  205. package/.next/server/chunks/7048.js +6 -0
  206. package/.next/server/instrumentation.js +1 -1
  207. package/.next/server/middleware-build-manifest.js +1 -1
  208. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/.next/server/middleware.js +3 -3
  210. package/.next/server/next-font-manifest.js +1 -1
  211. package/.next/server/next-font-manifest.json +1 -1
  212. package/.next/server/pages/404.html +1 -1
  213. package/.next/server/pages/500.html +1 -1
  214. package/.next/server/server-reference-manifest.json +1 -1
  215. package/.next/static/chunks/752.adce8bc3ebbaf4b6.js +1 -0
  216. package/.next/static/chunks/8088.0cad1ff2e09fd8ff.js +1 -0
  217. package/.next/static/chunks/app/_global-error/page-ad6e695deb9de65c.js +1 -0
  218. package/.next/static/chunks/app/_not-found/page-63a39396532d2582.js +1 -0
  219. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-ad6e695deb9de65c.js +1 -0
  220. package/.next/static/chunks/app/api/agent/[id]/events/route-ad6e695deb9de65c.js +1 -0
  221. package/.next/static/chunks/app/api/agent/[id]/route-ad6e695deb9de65c.js +1 -0
  222. package/.next/static/chunks/app/api/agent/new/route-ad6e695deb9de65c.js +1 -0
  223. package/.next/static/chunks/app/api/agent/running/route-ad6e695deb9de65c.js +1 -0
  224. package/.next/static/chunks/app/api/app-update/route-ad6e695deb9de65c.js +1 -0
  225. package/.next/static/chunks/app/api/auth/all-providers/route-ad6e695deb9de65c.js +1 -0
  226. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-ad6e695deb9de65c.js +1 -0
  227. package/.next/static/chunks/app/api/auth/login/[provider]/route-ad6e695deb9de65c.js +1 -0
  228. package/.next/static/chunks/app/api/auth/logout/[provider]/route-ad6e695deb9de65c.js +1 -0
  229. package/.next/static/chunks/app/api/auth/providers/route-ad6e695deb9de65c.js +1 -0
  230. package/.next/static/chunks/app/api/board-assets/[...path]/route-ad6e695deb9de65c.js +1 -0
  231. package/.next/static/chunks/app/api/board-assets/route-ad6e695deb9de65c.js +1 -0
  232. package/.next/static/chunks/app/api/boards/[id]/add-session/route-ad6e695deb9de65c.js +1 -0
  233. package/.next/static/chunks/app/api/boards/[id]/reconcile/route-ad6e695deb9de65c.js +1 -0
  234. package/.next/static/chunks/app/api/boards/[id]/route-ad6e695deb9de65c.js +1 -0
  235. package/.next/static/chunks/app/api/boards/reorder/route-ad6e695deb9de65c.js +1 -0
  236. package/.next/static/chunks/app/api/boards/route-ad6e695deb9de65c.js +1 -0
  237. package/.next/static/chunks/app/api/cwd/browse/route-ad6e695deb9de65c.js +1 -0
  238. package/.next/static/chunks/app/api/cwd/validate/route-ad6e695deb9de65c.js +1 -0
  239. package/.next/static/chunks/app/api/default-cwd/route-ad6e695deb9de65c.js +1 -0
  240. package/.next/static/chunks/app/api/file-index/route-ad6e695deb9de65c.js +1 -0
  241. package/.next/static/chunks/app/api/files/[...path]/route-ad6e695deb9de65c.js +1 -0
  242. package/.next/static/chunks/app/api/git/diff/route-ad6e695deb9de65c.js +1 -0
  243. package/.next/static/chunks/app/api/git/status/route-ad6e695deb9de65c.js +1 -0
  244. package/.next/static/chunks/app/api/home/route-ad6e695deb9de65c.js +1 -0
  245. package/.next/static/chunks/app/api/mcp/route-ad6e695deb9de65c.js +1 -0
  246. package/.next/static/chunks/app/api/models/route-ad6e695deb9de65c.js +1 -0
  247. package/.next/static/chunks/app/api/models-config/catalog/route-ad6e695deb9de65c.js +1 -0
  248. package/.next/static/chunks/app/api/models-config/discover/route-ad6e695deb9de65c.js +1 -0
  249. package/.next/static/chunks/app/api/models-config/route-ad6e695deb9de65c.js +1 -0
  250. package/.next/static/chunks/app/api/models-config/test/route-ad6e695deb9de65c.js +1 -0
  251. package/.next/static/chunks/app/api/plugins/route-ad6e695deb9de65c.js +1 -0
  252. package/.next/static/chunks/app/api/project-trust/route-ad6e695deb9de65c.js +1 -0
  253. package/.next/static/chunks/app/api/quota/route-ad6e695deb9de65c.js +1 -0
  254. package/.next/static/chunks/app/api/search/route-ad6e695deb9de65c.js +1 -0
  255. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-ad6e695deb9de65c.js +1 -0
  256. package/.next/static/chunks/app/api/sessions/[id]/context/route-ad6e695deb9de65c.js +1 -0
  257. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-ad6e695deb9de65c.js +1 -0
  258. package/.next/static/chunks/app/api/sessions/[id]/export/route-ad6e695deb9de65c.js +1 -0
  259. package/.next/static/chunks/app/api/sessions/[id]/minimap/route-ad6e695deb9de65c.js +1 -0
  260. package/.next/static/chunks/app/api/sessions/[id]/route-ad6e695deb9de65c.js +1 -0
  261. package/.next/static/chunks/app/api/sessions/[id]/state/route-ad6e695deb9de65c.js +1 -0
  262. package/.next/static/chunks/app/api/sessions/[id]/todos/route-ad6e695deb9de65c.js +1 -0
  263. package/.next/static/chunks/app/api/sessions/route-ad6e695deb9de65c.js +1 -0
  264. package/.next/static/chunks/app/api/sessions/summary/route-ad6e695deb9de65c.js +1 -0
  265. package/.next/static/chunks/app/api/skills/check/route-ad6e695deb9de65c.js +1 -0
  266. package/.next/static/chunks/app/api/skills/install/route-ad6e695deb9de65c.js +1 -0
  267. package/.next/static/chunks/app/api/skills/route-ad6e695deb9de65c.js +1 -0
  268. package/.next/static/chunks/app/api/skills/search/route-ad6e695deb9de65c.js +1 -0
  269. package/.next/static/chunks/app/api/skills/update/route-ad6e695deb9de65c.js +1 -0
  270. package/.next/static/chunks/app/api/subagents/[id]/route-ad6e695deb9de65c.js +1 -0
  271. package/.next/static/chunks/app/api/subagents/profiles/route-ad6e695deb9de65c.js +1 -0
  272. package/.next/static/chunks/app/api/subagents/settings/route-ad6e695deb9de65c.js +1 -0
  273. package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-ad6e695deb9de65c.js +1 -0
  274. package/.next/static/chunks/app/api/task-card-questions/route-ad6e695deb9de65c.js +1 -0
  275. package/.next/static/chunks/app/api/task-cards/[id]/route-ad6e695deb9de65c.js +1 -0
  276. package/.next/static/chunks/app/api/task-cards/route-ad6e695deb9de65c.js +1 -0
  277. package/.next/static/chunks/app/api/task-cards/unbind/route-ad6e695deb9de65c.js +1 -0
  278. package/.next/static/chunks/app/api/task-scheduler/status/route-ad6e695deb9de65c.js +1 -0
  279. package/.next/static/chunks/app/api/tasks/[id]/assign-session/route-ad6e695deb9de65c.js +1 -0
  280. package/.next/static/chunks/app/api/tasks/[id]/board/route-ad6e695deb9de65c.js +1 -0
  281. package/.next/static/chunks/app/api/tasks/[id]/route-ad6e695deb9de65c.js +1 -0
  282. package/.next/static/chunks/app/api/tasks/reorder/route-ad6e695deb9de65c.js +1 -0
  283. package/.next/static/chunks/app/api/tasks/route-ad6e695deb9de65c.js +1 -0
  284. package/.next/static/chunks/app/api/terminal/[id]/events/route-ad6e695deb9de65c.js +1 -0
  285. package/.next/static/chunks/app/api/terminal/[id]/route-ad6e695deb9de65c.js +1 -0
  286. package/.next/static/chunks/app/api/terminal/route-ad6e695deb9de65c.js +1 -0
  287. package/.next/static/chunks/app/api/worktrees/route-ad6e695deb9de65c.js +1 -0
  288. package/.next/static/chunks/app/api/yjs-version/route-ad6e695deb9de65c.js +1 -0
  289. package/.next/static/chunks/app/layout-87087b955e0c9507.js +1 -0
  290. package/.next/static/chunks/app/manifest.webmanifest/route-ad6e695deb9de65c.js +1 -0
  291. package/.next/static/chunks/app/page-efca6bf51a5f8ccb.js +256 -0
  292. package/.next/static/chunks/main-app-1f89e7ad7ae1ff87.js +1 -0
  293. package/.next/static/chunks/next/dist/client/components/builtin/app-error-ad6e695deb9de65c.js +1 -0
  294. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-ad6e695deb9de65c.js +1 -0
  295. package/.next/static/chunks/next/dist/client/components/builtin/global-error-d3784ab2e32f3c6e.js +1 -0
  296. package/.next/static/chunks/next/dist/client/components/builtin/not-found-ad6e695deb9de65c.js +1 -0
  297. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-ad6e695deb9de65c.js +1 -0
  298. package/.next/static/chunks/{webpack-3df5ae3897959c33.js → webpack-4de8e8dd9f2f3173.js} +1 -1
  299. package/.next/static/css/bb9361c7f832a89d.css +1 -0
  300. package/.next/static/css/c6d32b6031181be7.css +1 -0
  301. package/.next/static/k8ZFqwz7d-bnK0ZiUVgCc/_buildManifest.js +1 -0
  302. package/.next/trace +7 -8
  303. package/.next/trace-build +1 -1
  304. package/.next/types/app/api/agent/[id]/bash-output/route.ts +1 -1
  305. package/.next/types/app/api/agent/[id]/events/route.ts +1 -1
  306. package/.next/types/app/api/agent/[id]/route.ts +1 -1
  307. package/.next/types/app/api/agent/new/route.ts +1 -1
  308. package/.next/types/app/api/agent/running/route.ts +1 -1
  309. package/.next/types/app/api/app-update/route.ts +1 -1
  310. package/.next/types/app/api/auth/all-providers/route.ts +1 -1
  311. package/.next/types/app/api/auth/api-key/[provider]/route.ts +1 -1
  312. package/.next/types/app/api/auth/login/[provider]/route.ts +1 -1
  313. package/.next/types/app/api/auth/logout/[provider]/route.ts +1 -1
  314. package/.next/types/app/api/auth/providers/route.ts +1 -1
  315. package/.next/types/app/api/board-assets/[...path]/route.ts +1 -1
  316. package/.next/types/app/api/board-assets/route.ts +1 -1
  317. package/.next/types/app/api/boards/[id]/add-session/route.ts +353 -0
  318. package/.next/types/app/api/boards/[id]/reconcile/route.ts +1 -1
  319. package/.next/types/app/api/boards/[id]/route.ts +1 -1
  320. package/.next/types/app/api/boards/reorder/route.ts +1 -1
  321. package/.next/types/app/api/boards/route.ts +1 -1
  322. package/.next/types/app/api/cwd/browse/route.ts +1 -1
  323. package/.next/types/app/api/cwd/validate/route.ts +1 -1
  324. package/.next/types/app/api/default-cwd/route.ts +1 -1
  325. package/.next/types/app/api/file-index/route.ts +1 -1
  326. package/.next/types/app/api/files/[...path]/route.ts +1 -1
  327. package/.next/types/app/api/git/diff/route.ts +1 -1
  328. package/.next/types/app/api/git/status/route.ts +1 -1
  329. package/.next/types/app/api/home/route.ts +1 -1
  330. package/.next/types/app/api/mcp/route.ts +1 -1
  331. package/.next/types/app/api/models/route.ts +1 -1
  332. package/.next/types/app/api/models-config/catalog/route.ts +1 -1
  333. package/.next/types/app/api/models-config/discover/route.ts +1 -1
  334. package/.next/types/app/api/models-config/route.ts +1 -1
  335. package/.next/types/app/api/models-config/test/route.ts +1 -1
  336. package/.next/types/app/api/plugins/route.ts +1 -1
  337. package/.next/types/app/api/project-trust/route.ts +1 -1
  338. package/.next/types/app/api/quota/route.ts +1 -1
  339. package/.next/types/app/api/search/route.ts +1 -1
  340. package/.next/types/app/api/sessions/[id]/auto-name/route.ts +1 -1
  341. package/.next/types/app/api/sessions/[id]/context/route.ts +1 -1
  342. package/.next/types/app/api/sessions/[id]/entries/[entryId]/thinking/route.ts +1 -1
  343. package/.next/types/app/api/sessions/[id]/export/route.ts +1 -1
  344. package/.next/types/app/api/sessions/[id]/minimap/route.ts +1 -1
  345. package/.next/types/app/api/sessions/[id]/route.ts +1 -1
  346. package/.next/types/app/api/sessions/[id]/state/route.ts +1 -1
  347. package/.next/types/app/api/sessions/[id]/todos/route.ts +1 -1
  348. package/.next/types/app/api/sessions/route.ts +1 -1
  349. package/.next/types/app/api/sessions/summary/route.ts +1 -1
  350. package/.next/types/app/api/skills/check/route.ts +1 -1
  351. package/.next/types/app/api/skills/install/route.ts +1 -1
  352. package/.next/types/app/api/skills/route.ts +1 -1
  353. package/.next/types/app/api/skills/search/route.ts +1 -1
  354. package/.next/types/app/api/skills/update/route.ts +1 -1
  355. package/.next/types/app/api/subagents/[id]/route.ts +353 -0
  356. package/.next/types/app/api/subagents/profiles/route.ts +353 -0
  357. package/.next/types/app/api/subagents/settings/route.ts +353 -0
  358. package/.next/types/app/api/task-card-questions/[id]/answer/route.ts +1 -1
  359. package/.next/types/app/api/task-card-questions/route.ts +1 -1
  360. package/.next/types/app/api/task-cards/[id]/route.ts +1 -1
  361. package/.next/types/app/api/task-cards/route.ts +1 -1
  362. package/.next/types/app/api/task-cards/unbind/route.ts +1 -1
  363. package/.next/types/app/api/task-scheduler/status/route.ts +1 -1
  364. package/.next/types/app/api/tasks/[id]/assign-session/route.ts +1 -1
  365. package/.next/types/app/api/tasks/[id]/board/route.ts +1 -1
  366. package/.next/types/app/api/tasks/[id]/route.ts +1 -1
  367. package/.next/types/app/api/tasks/reorder/route.ts +1 -1
  368. package/.next/types/app/api/tasks/route.ts +1 -1
  369. package/.next/types/app/api/terminal/[id]/events/route.ts +1 -1
  370. package/.next/types/app/api/terminal/[id]/route.ts +1 -1
  371. package/.next/types/app/api/terminal/route.ts +1 -1
  372. package/.next/types/app/api/worktrees/route.ts +1 -1
  373. package/.next/types/app/api/yjs-version/route.ts +1 -1
  374. package/.next/types/app/layout.ts +1 -1
  375. package/.next/types/app/page.ts +1 -1
  376. package/.next/types/routes.d.ts +5 -1
  377. package/.next/types/validator.ts +36 -0
  378. package/lib/api-types.ts +10 -0
  379. package/lib/board-events.rename.test.mjs +39 -0
  380. package/lib/board-events.ts +17 -0
  381. package/lib/board-reconcile.test.mjs +20 -0
  382. package/lib/board-reconcile.ts +54 -0
  383. package/lib/chat-lazy-load.test.mjs +0 -62
  384. package/lib/chat-lazy-load.ts +0 -13
  385. package/lib/chat-only.ts +23 -0
  386. package/lib/draft-stash.ts +4 -5
  387. package/lib/file-types.ts +16 -1
  388. package/lib/i18n/messages/en.ts +91 -0
  389. package/lib/i18n/messages/zh-CN.ts +91 -0
  390. package/lib/id.test.mjs +38 -0
  391. package/lib/id.ts +17 -0
  392. package/lib/message-text.ts +24 -0
  393. package/lib/models-cache.ts +1 -1
  394. package/lib/pi-types.ts +19 -1
  395. package/lib/pin-store.ts +85 -0
  396. package/lib/powershell-settings.ts +106 -0
  397. package/lib/quoted-selection.ts +4 -0
  398. package/lib/rpc-manager.ts +208 -22
  399. package/lib/session-family.test.mjs +49 -0
  400. package/lib/session-family.ts +80 -0
  401. package/lib/session-index-scanner.ts +39 -0
  402. package/lib/session-time-group.test.mjs +38 -0
  403. package/lib/session-time-group.ts +55 -0
  404. package/lib/settings-navigation.ts +124 -0
  405. package/lib/subagent-extension.test.mjs +424 -0
  406. package/lib/subagent-extension.ts +309 -0
  407. package/lib/subagent-input.test.mjs +63 -0
  408. package/lib/subagent-input.ts +71 -0
  409. package/lib/subagent-isolation.test.mjs +51 -0
  410. package/lib/subagent-profile-precedence.ts +20 -0
  411. package/lib/subagent-prompt.test.mjs +64 -0
  412. package/lib/subagent-prompt.ts +31 -0
  413. package/lib/subagent-queue.test.mjs +35 -0
  414. package/lib/subagent-queue.ts +74 -0
  415. package/lib/subagent-runtime.test.mjs +150 -0
  416. package/lib/subagent-runtime.ts +587 -0
  417. package/lib/subagent-settings.test.mjs +50 -0
  418. package/lib/subagent-settings.ts +93 -0
  419. package/lib/subagents.test.mjs +601 -0
  420. package/lib/subagents.ts +602 -0
  421. package/lib/tool-presets.ts +4 -0
  422. package/lib/types.ts +19 -0
  423. package/package.json +1 -1
  424. package/.next/static/chunks/752.3119700876725f3b.js +0 -1
  425. package/.next/static/chunks/7975.95edcabc69eee4eb.js +0 -1
  426. package/.next/static/chunks/app/_global-error/page-2d5f6296c7e693c6.js +0 -1
  427. package/.next/static/chunks/app/_not-found/page-af4fe23994cb3d66.js +0 -1
  428. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-2d5f6296c7e693c6.js +0 -1
  429. package/.next/static/chunks/app/api/agent/[id]/events/route-2d5f6296c7e693c6.js +0 -1
  430. package/.next/static/chunks/app/api/agent/[id]/route-2d5f6296c7e693c6.js +0 -1
  431. package/.next/static/chunks/app/api/agent/new/route-2d5f6296c7e693c6.js +0 -1
  432. package/.next/static/chunks/app/api/agent/running/route-2d5f6296c7e693c6.js +0 -1
  433. package/.next/static/chunks/app/api/app-update/route-2d5f6296c7e693c6.js +0 -1
  434. package/.next/static/chunks/app/api/auth/all-providers/route-2d5f6296c7e693c6.js +0 -1
  435. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-2d5f6296c7e693c6.js +0 -1
  436. package/.next/static/chunks/app/api/auth/login/[provider]/route-2d5f6296c7e693c6.js +0 -1
  437. package/.next/static/chunks/app/api/auth/logout/[provider]/route-2d5f6296c7e693c6.js +0 -1
  438. package/.next/static/chunks/app/api/auth/providers/route-2d5f6296c7e693c6.js +0 -1
  439. package/.next/static/chunks/app/api/board-assets/[...path]/route-2d5f6296c7e693c6.js +0 -1
  440. package/.next/static/chunks/app/api/board-assets/route-2d5f6296c7e693c6.js +0 -1
  441. package/.next/static/chunks/app/api/boards/[id]/reconcile/route-2d5f6296c7e693c6.js +0 -1
  442. package/.next/static/chunks/app/api/boards/[id]/route-2d5f6296c7e693c6.js +0 -1
  443. package/.next/static/chunks/app/api/boards/reorder/route-2d5f6296c7e693c6.js +0 -1
  444. package/.next/static/chunks/app/api/boards/route-2d5f6296c7e693c6.js +0 -1
  445. package/.next/static/chunks/app/api/cwd/browse/route-2d5f6296c7e693c6.js +0 -1
  446. package/.next/static/chunks/app/api/cwd/validate/route-2d5f6296c7e693c6.js +0 -1
  447. package/.next/static/chunks/app/api/default-cwd/route-2d5f6296c7e693c6.js +0 -1
  448. package/.next/static/chunks/app/api/file-index/route-2d5f6296c7e693c6.js +0 -1
  449. package/.next/static/chunks/app/api/files/[...path]/route-2d5f6296c7e693c6.js +0 -1
  450. package/.next/static/chunks/app/api/git/diff/route-2d5f6296c7e693c6.js +0 -1
  451. package/.next/static/chunks/app/api/git/status/route-2d5f6296c7e693c6.js +0 -1
  452. package/.next/static/chunks/app/api/home/route-2d5f6296c7e693c6.js +0 -1
  453. package/.next/static/chunks/app/api/mcp/route-2d5f6296c7e693c6.js +0 -1
  454. package/.next/static/chunks/app/api/models/route-2d5f6296c7e693c6.js +0 -1
  455. package/.next/static/chunks/app/api/models-config/catalog/route-2d5f6296c7e693c6.js +0 -1
  456. package/.next/static/chunks/app/api/models-config/discover/route-2d5f6296c7e693c6.js +0 -1
  457. package/.next/static/chunks/app/api/models-config/route-2d5f6296c7e693c6.js +0 -1
  458. package/.next/static/chunks/app/api/models-config/test/route-2d5f6296c7e693c6.js +0 -1
  459. package/.next/static/chunks/app/api/plugins/route-2d5f6296c7e693c6.js +0 -1
  460. package/.next/static/chunks/app/api/project-trust/route-2d5f6296c7e693c6.js +0 -1
  461. package/.next/static/chunks/app/api/quota/route-2d5f6296c7e693c6.js +0 -1
  462. package/.next/static/chunks/app/api/search/route-2d5f6296c7e693c6.js +0 -1
  463. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-2d5f6296c7e693c6.js +0 -1
  464. package/.next/static/chunks/app/api/sessions/[id]/context/route-2d5f6296c7e693c6.js +0 -1
  465. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-2d5f6296c7e693c6.js +0 -1
  466. package/.next/static/chunks/app/api/sessions/[id]/export/route-2d5f6296c7e693c6.js +0 -1
  467. package/.next/static/chunks/app/api/sessions/[id]/minimap/route-2d5f6296c7e693c6.js +0 -1
  468. package/.next/static/chunks/app/api/sessions/[id]/route-2d5f6296c7e693c6.js +0 -1
  469. package/.next/static/chunks/app/api/sessions/[id]/state/route-2d5f6296c7e693c6.js +0 -1
  470. package/.next/static/chunks/app/api/sessions/[id]/todos/route-2d5f6296c7e693c6.js +0 -1
  471. package/.next/static/chunks/app/api/sessions/route-2d5f6296c7e693c6.js +0 -1
  472. package/.next/static/chunks/app/api/sessions/summary/route-2d5f6296c7e693c6.js +0 -1
  473. package/.next/static/chunks/app/api/skills/check/route-2d5f6296c7e693c6.js +0 -1
  474. package/.next/static/chunks/app/api/skills/install/route-2d5f6296c7e693c6.js +0 -1
  475. package/.next/static/chunks/app/api/skills/route-2d5f6296c7e693c6.js +0 -1
  476. package/.next/static/chunks/app/api/skills/search/route-2d5f6296c7e693c6.js +0 -1
  477. package/.next/static/chunks/app/api/skills/update/route-2d5f6296c7e693c6.js +0 -1
  478. package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-2d5f6296c7e693c6.js +0 -1
  479. package/.next/static/chunks/app/api/task-card-questions/route-2d5f6296c7e693c6.js +0 -1
  480. package/.next/static/chunks/app/api/task-cards/[id]/route-2d5f6296c7e693c6.js +0 -1
  481. package/.next/static/chunks/app/api/task-cards/route-2d5f6296c7e693c6.js +0 -1
  482. package/.next/static/chunks/app/api/task-cards/unbind/route-2d5f6296c7e693c6.js +0 -1
  483. package/.next/static/chunks/app/api/task-scheduler/status/route-2d5f6296c7e693c6.js +0 -1
  484. package/.next/static/chunks/app/api/tasks/[id]/assign-session/route-2d5f6296c7e693c6.js +0 -1
  485. package/.next/static/chunks/app/api/tasks/[id]/board/route-2d5f6296c7e693c6.js +0 -1
  486. package/.next/static/chunks/app/api/tasks/[id]/route-2d5f6296c7e693c6.js +0 -1
  487. package/.next/static/chunks/app/api/tasks/reorder/route-2d5f6296c7e693c6.js +0 -1
  488. package/.next/static/chunks/app/api/tasks/route-2d5f6296c7e693c6.js +0 -1
  489. package/.next/static/chunks/app/api/terminal/[id]/events/route-2d5f6296c7e693c6.js +0 -1
  490. package/.next/static/chunks/app/api/terminal/[id]/route-2d5f6296c7e693c6.js +0 -1
  491. package/.next/static/chunks/app/api/terminal/route-2d5f6296c7e693c6.js +0 -1
  492. package/.next/static/chunks/app/api/worktrees/route-2d5f6296c7e693c6.js +0 -1
  493. package/.next/static/chunks/app/api/yjs-version/route-2d5f6296c7e693c6.js +0 -1
  494. package/.next/static/chunks/app/layout-636e9e756d0734c7.js +0 -1
  495. package/.next/static/chunks/app/manifest.webmanifest/route-2d5f6296c7e693c6.js +0 -1
  496. package/.next/static/chunks/app/page-44daed9dcf9134eb.js +0 -89
  497. package/.next/static/chunks/main-app-b3e8a8d15d83e1f0.js +0 -1
  498. package/.next/static/chunks/next/dist/client/components/builtin/app-error-2d5f6296c7e693c6.js +0 -1
  499. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-2d5f6296c7e693c6.js +0 -1
  500. package/.next/static/chunks/next/dist/client/components/builtin/global-error-00a4badaccb388e6.js +0 -1
  501. package/.next/static/chunks/next/dist/client/components/builtin/not-found-2d5f6296c7e693c6.js +0 -1
  502. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2d5f6296c7e693c6.js +0 -1
  503. package/.next/static/css/4a609fb185e7cff1.css +0 -1
  504. package/.next/static/h-hr7x0pqNUx3TyuarqWJ/_buildManifest.js +0 -1
  505. package/lib/extension-command.test.mjs +0 -63
  506. package/lib/extension-command.ts +0 -81
  507. package/lib/subagent-widget.test.mjs +0 -87
  508. package/lib/subagent-widget.ts +0 -109
  509. /package/.next/static/{h-hr7x0pqNUx3TyuarqWJ → k8ZFqwz7d-bnK0ZiUVgCc}/_ssgManifest.js +0 -0
@@ -0,0 +1,587 @@
1
+ import type { ThinkingLevel } from "@earendil-works/pi-agent-core";
2
+ import {
3
+ createAgentSessionFromServices,
4
+ createAgentSessionServices,
5
+ getAgentDir,
6
+ initTheme,
7
+ SessionManager,
8
+ SettingsManager,
9
+ type ModelRuntime,
10
+ } from "@earendil-works/pi-coding-agent";
11
+ import type { AgentSessionLike } from "./pi-types";
12
+ import {
13
+ subagentFinalText,
14
+ subagentToolDetails,
15
+ type ResumeSubagentRequest,
16
+ type StartSubagentRequest,
17
+ type SubagentExecution,
18
+ type SubagentExtensionRuntime,
19
+ } from "./subagent-extension";
20
+ import {
21
+ readSubagentRun,
22
+ resolveSubagentProfile,
23
+ SUBAGENT_CONTROL_TOOL_NAMES,
24
+ SUBAGENT_META_TYPE,
25
+ SUBAGENT_STATUS_TYPE,
26
+ SUBAGENT_RESULT_TYPE,
27
+ selectSubagentExtensionTools,
28
+ withSubagentExtensionTools,
29
+ type SubagentMetadata,
30
+ type SubagentResultMetadata,
31
+ type SubagentRunInfo,
32
+ } from "./subagents";
33
+ import type { SessionEntry } from "./types";
34
+ import { buildSubagentPromptPlan } from "./subagent-prompt";
35
+ import { appendSubagentInputFiles, loadSubagentInputFiles } from "./subagent-input";
36
+ import { projectTrustReloadOptions } from "./project-trust";
37
+ import { resolveShellTools } from "./powershell-settings";
38
+ import { isBuiltInSubagentsEnabled, readSubagentSettings } from "./subagent-settings";
39
+ import { SubagentQueue } from "./subagent-queue";
40
+ import { addWorktree, removeWorktree } from "./worktree";
41
+ import { randomUUID } from "node:crypto";
42
+
43
+ interface HostSession {
44
+ readonly inner: AgentSessionLike;
45
+ readonly sessionFile: string;
46
+ readonly cwd: string;
47
+ isAlive(): boolean;
48
+ isRunning(): boolean;
49
+ waitUntilReady(): Promise<void>;
50
+ }
51
+
52
+ export interface SubagentRuntimeDependencies {
53
+ getSession(sessionId: string): HostSession | undefined;
54
+ registerSession(
55
+ inner: AgentSessionLike,
56
+ options?: { exactSystemPrompt?: string; chatOnly?: boolean },
57
+ ): void;
58
+ reopenSession(sessionId: string, sessionFile: string): Promise<HostSession>;
59
+ resolveSessionPath(sessionId: string): Promise<string | null>;
60
+ invalidateSessionList(): void;
61
+ isBuiltInSubagentsEnabled?(): boolean;
62
+ }
63
+
64
+ export interface SubagentController {
65
+ readonly extensionRuntime: SubagentExtensionRuntime;
66
+ get(sessionId: string): Promise<SubagentRunInfo | null>;
67
+ steer(sessionId: string, message: string): Promise<void>;
68
+ abort(sessionId: string): Promise<void>;
69
+ }
70
+
71
+ type StoredSubagentExecution = {
72
+ run: SubagentRunInfo;
73
+ completion: Promise<SubagentRunInfo>;
74
+ abortRequested: boolean;
75
+ cancelQueued?: () => boolean;
76
+ };
77
+
78
+ declare global {
79
+ var __piSubagentRuns: Map<string, StoredSubagentExecution> | undefined;
80
+ var __piSubagentQueue: SubagentQueue<SubagentRunInfo> | undefined;
81
+ }
82
+ const SUBAGENT_CONTEXT_LIMIT = 50_000;
83
+ const THINKING_LEVELS = new Set<ThinkingLevel>(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
84
+
85
+ function getSubagentRuns(): Map<string, StoredSubagentExecution> {
86
+ if (!globalThis.__piSubagentRuns) globalThis.__piSubagentRuns = new Map();
87
+ return globalThis.__piSubagentRuns;
88
+ }
89
+
90
+ function getSubagentQueue(): SubagentQueue<SubagentRunInfo> {
91
+ if (!globalThis.__piSubagentQueue) globalThis.__piSubagentQueue = new SubagentQueue();
92
+ return globalThis.__piSubagentQueue;
93
+ }
94
+
95
+ function parseSubagentModel(runtime: ModelRuntime, value: string | undefined) {
96
+ if (!value?.trim()) return undefined;
97
+ const requested = value.trim();
98
+ const slash = requested.indexOf("/");
99
+ if (slash > 0) {
100
+ const provider = requested.slice(0, slash);
101
+ const modelId = requested.slice(slash + 1);
102
+ const model = runtime.getModel(provider, modelId);
103
+ if (!model) throw new Error(`Subagent model not found: ${requested}`);
104
+ return model;
105
+ }
106
+ const matches = runtime.getModels().filter((model) => model.id === requested);
107
+ if (matches.length === 1) return matches[0];
108
+ if (matches.length === 0) throw new Error(`Subagent model not found: ${requested}`);
109
+ throw new Error(`Subagent model is ambiguous; use provider/modelId: ${requested}`);
110
+ }
111
+
112
+ function parentContextText(parent: HostSession): string {
113
+ const messages = parent.inner.sessionManager.buildSessionContext().messages;
114
+ const serialized = JSON.stringify(messages);
115
+ if (serialized.length <= SUBAGENT_CONTEXT_LIMIT) return serialized;
116
+ return `${serialized.slice(0, SUBAGENT_CONTEXT_LIMIT)}\n[Parent context truncated]`;
117
+ }
118
+
119
+ async function cleanupWorktree(
120
+ parentCwd: string,
121
+ worktree: { path: string; branch: string } | undefined,
122
+ ): Promise<string | undefined> {
123
+ if (!worktree) return undefined;
124
+ try {
125
+ await removeWorktree(parentCwd, worktree.path);
126
+ return undefined;
127
+ } catch (error) {
128
+ return `Worktree retained at ${worktree.path}: ${error instanceof Error ? error.message : String(error)}`;
129
+ }
130
+ }
131
+
132
+ export function createSubagentController(
133
+ dependencies: SubagentRuntimeDependencies,
134
+ ): SubagentController {
135
+ async function start(request: StartSubagentRequest): Promise<SubagentExecution> {
136
+ const enabled = dependencies.isBuiltInSubagentsEnabled ?? isBuiltInSubagentsEnabled;
137
+ if (!enabled()) throw new Error("Pi Web built-in sub-agents are disabled");
138
+ const parentSessionId = request.parentContext.sessionManager.getSessionId();
139
+ const parent = dependencies.getSession(parentSessionId);
140
+ if (!parent?.isAlive()) throw new Error("Parent session is no longer available");
141
+ if (!parent.sessionFile) throw new Error("Parent session must be persisted before starting a subagent");
142
+
143
+ let isolatedWorktree: { path: string; branch: string } | undefined;
144
+ try {
145
+ const profile = resolveSubagentProfile(parent.cwd, request.profile);
146
+ if (!profile) throw new Error(`Unknown or disabled subagent profile: ${request.profile}`);
147
+
148
+ const runInBackground = request.runInBackground ?? profile.runInBackground;
149
+ const isolation = profile.isolation === "off" ? undefined : request.isolation ?? profile.isolation;
150
+ if (isolation === "worktree") {
151
+ isolatedWorktree = await addWorktree(parent.cwd, `pi-web-agent-${randomUUID()}`);
152
+ }
153
+ const childCwd = isolatedWorktree?.path ?? parent.cwd;
154
+ const inheritContext = request.inheritContext ?? profile.inheritContext;
155
+ const maxTurns = request.maxTurns ?? profile.maxTurns;
156
+ if (maxTurns !== undefined && (!Number.isFinite(maxTurns) || maxTurns < 0)) {
157
+ throw new Error("max_turns must be a non-negative number");
158
+ }
159
+ const turnLimit = maxTurns && maxTurns > 0 ? Math.floor(maxTurns) : undefined;
160
+ const thinking = request.thinking ?? profile.thinking ?? parent.inner.agent.state?.thinkingLevel;
161
+ if (thinking && !THINKING_LEVELS.has(thinking as ThinkingLevel)) {
162
+ throw new Error(`Invalid subagent thinking level: ${thinking}`);
163
+ }
164
+
165
+ const agentDir = getAgentDir();
166
+ const parentModelRuntime = (parent.inner as unknown as { modelRuntime: ModelRuntime }).modelRuntime;
167
+ const settingsManager = SettingsManager.create(childCwd, agentDir);
168
+ const inheritedParentContext = inheritContext
169
+ ? `The following is the active conversation context from the parent session. Use it only as background for the delegated task:\n${parentContextText(parent)}`
170
+ : undefined;
171
+ const inputFiles = loadSubagentInputFiles(parent.cwd, request.inputFiles ?? []);
172
+ const promptPlan = buildSubagentPromptPlan({
173
+ profileSystemPrompt: profile.systemPrompt,
174
+ tools: profile.tools,
175
+ loadSkills: profile.loadSkills,
176
+ loadExtensions: profile.loadExtensions,
177
+ promptMode: profile.promptMode,
178
+ task: appendSubagentInputFiles(request.task, inputFiles),
179
+ inheritedParentContext,
180
+ });
181
+ const { chatOnly, appendSystemPrompt, delegatedTask } = promptPlan;
182
+ if (!chatOnly) initTheme();
183
+ const services = await createAgentSessionServices({
184
+ cwd: childCwd,
185
+ agentDir,
186
+ modelRuntime: parentModelRuntime,
187
+ settingsManager,
188
+ resourceLoaderOptions: {
189
+ noExtensions: !profile.loadExtensions,
190
+ noSkills: !profile.loadSkills,
191
+ noPromptTemplates: true,
192
+ noThemes: true,
193
+ noContextFiles: true,
194
+ ...(chatOnly || promptPlan.exactSystemPrompt !== undefined
195
+ ? {
196
+ systemPrompt: " ",
197
+ systemPromptOverride: () => undefined,
198
+ }
199
+ : {}),
200
+ appendSystemPrompt,
201
+ },
202
+ ...((profile.loadExtensions || profile.loadSkills)
203
+ ? { resourceLoaderReloadOptions: projectTrustReloadOptions(childCwd, agentDir) }
204
+ : {}),
205
+ });
206
+
207
+ const extensionToolNames = profile.loadExtensions
208
+ ? profile.extensionTools?.length
209
+ ? selectSubagentExtensionTools(services.resourceLoader.getExtensions().extensions, profile.extensionTools)
210
+ : services.resourceLoader.getExtensions().extensions.flatMap((extension) => [...extension.tools.keys()])
211
+ : [];
212
+ const activeTools = resolveShellTools(
213
+ withSubagentExtensionTools(profile.tools, extensionToolNames),
214
+ settingsManager.getDefaultTools(),
215
+ );
216
+
217
+ const sessionManager = isolatedWorktree
218
+ ? SessionManager.create(childCwd, undefined, { parentSession: parent.sessionFile })
219
+ : SessionManager.create(parent.cwd, undefined, { parentSession: parent.sessionFile });
220
+ const createdAt = new Date().toISOString();
221
+ const metadata: SubagentMetadata = {
222
+ version: 1,
223
+ parentSessionId,
224
+ parentSessionPath: parent.sessionFile,
225
+ parentToolCallId: request.parentToolCallId,
226
+ profile: profile.name,
227
+ description: request.description.trim() || profile.displayName,
228
+ task: request.task,
229
+ runInBackground,
230
+ createdAt,
231
+ resourceSnapshot: {
232
+ version: 1,
233
+ appendSystemPrompt: [...appendSystemPrompt],
234
+ tools: [...activeTools],
235
+ loadSkills: profile.loadSkills,
236
+ loadExtensions: profile.loadExtensions,
237
+ ...(promptPlan.exactSystemPrompt !== undefined ? { exactSystemPrompt: promptPlan.exactSystemPrompt } : {}),
238
+ },
239
+ ...(isolatedWorktree ? { worktreePath: isolatedWorktree.path, worktreeBranch: isolatedWorktree.branch } : {}),
240
+ };
241
+ sessionManager.appendCustomEntry(SUBAGENT_META_TYPE, metadata);
242
+ sessionManager.appendSessionInfo(metadata.description);
243
+
244
+ const requestedModel = parseSubagentModel(parentModelRuntime, request.model ?? profile.model);
245
+ const parentModel = parent.inner.model as ReturnType<ModelRuntime["getModel"]>;
246
+ const { session: inner } = await createAgentSessionFromServices({
247
+ services,
248
+ sessionManager,
249
+ model: requestedModel ?? parentModel,
250
+ ...(thinking ? { thinkingLevel: thinking as ThinkingLevel } : {}),
251
+ tools: activeTools,
252
+ excludeTools: [...SUBAGENT_CONTROL_TOOL_NAMES],
253
+ });
254
+ dependencies.registerSession(inner, {
255
+ ...(promptPlan.exactSystemPrompt !== undefined
256
+ ? { exactSystemPrompt: promptPlan.exactSystemPrompt }
257
+ : {}),
258
+ chatOnly,
259
+ });
260
+
261
+ const initialRun: SubagentRunInfo = {
262
+ sessionId: inner.sessionId,
263
+ sessionPath: inner.sessionFile ?? sessionManager.getSessionFile() ?? "",
264
+ parentSessionId,
265
+ parentToolCallId: request.parentToolCallId,
266
+ profile: profile.name,
267
+ description: metadata.description,
268
+ task: request.task,
269
+ runInBackground,
270
+ status: "queued",
271
+ createdAt,
272
+ ...(isolatedWorktree ? { worktreePath: isolatedWorktree.path, worktreeBranch: isolatedWorktree.branch } : {}),
273
+ };
274
+
275
+ let turnCount = 0;
276
+ let maxTurnsReached = false;
277
+ let softLimitReached = false;
278
+ const unsubscribeTurns = turnLimit
279
+ ? inner.subscribe((event) => {
280
+ if (event.type !== "turn_end") return;
281
+ turnCount += 1;
282
+ if (!softLimitReached && turnCount >= turnLimit) {
283
+ softLimitReached = true;
284
+ void inner.steer("You have reached your turn limit. Wrap up immediately and provide your final answer now.");
285
+ } else if (softLimitReached && turnCount >= turnLimit + 1) {
286
+ maxTurnsReached = true;
287
+ void inner.abort();
288
+ }
289
+ })
290
+ : () => {};
291
+ let resolveCompletion!: (run: SubagentRunInfo) => void;
292
+ const completion = new Promise<SubagentRunInfo>((resolve) => { resolveCompletion = resolve; });
293
+ const stored: StoredSubagentExecution = {
294
+ run: initialRun,
295
+ completion,
296
+ abortRequested: false,
297
+ };
298
+ getSubagentRuns().set(initialRun.sessionId, stored);
299
+ request.onUpdate?.(initialRun);
300
+ dependencies.invalidateSessionList();
301
+
302
+ const handleParentAbort = () => {
303
+ stored.abortRequested = true;
304
+ if (stored.run.status === "queued") stored.cancelQueued?.();
305
+ else void inner.abort();
306
+ };
307
+ if (!runInBackground) request.signal?.addEventListener("abort", handleParentAbort, { once: true });
308
+
309
+ const execute = async (): Promise<SubagentRunInfo> => {
310
+ if (stored.abortRequested) {
311
+ const result: SubagentRunInfo = { ...initialRun, status: "aborted", completedAt: new Date().toISOString() };
312
+ sessionManager.appendCustomEntry(SUBAGENT_RESULT_TYPE, { version: 1, status: "aborted", completedAt: result.completedAt });
313
+ await cleanupWorktree(parent.cwd, isolatedWorktree);
314
+ stored.run = result;
315
+ request.onUpdate?.(result);
316
+ getSubagentRuns().delete(initialRun.sessionId);
317
+ dependencies.invalidateSessionList();
318
+ return result;
319
+ }
320
+ stored.run = { ...stored.run, status: "running" };
321
+ sessionManager.appendCustomEntry(SUBAGENT_STATUS_TYPE, { version: 1, status: "running" });
322
+ request.onUpdate?.(stored.run);
323
+ dependencies.invalidateSessionList();
324
+ let result: SubagentRunInfo;
325
+ try {
326
+ await inner.prompt(delegatedTask, {
327
+ source: "rpc",
328
+ ...(chatOnly
329
+ ? {
330
+ preflightResult: (success: boolean) => {
331
+ if (success && inner.agent.state) {
332
+ inner.agent.state.systemPrompt = profile.systemPrompt;
333
+ }
334
+ },
335
+ }
336
+ : {}),
337
+ });
338
+ const text = inner.getLastAssistantText()?.trim();
339
+ const aborted = stored.abortRequested && !maxTurnsReached;
340
+ result = {
341
+ ...initialRun,
342
+ status: aborted ? "aborted" : "completed",
343
+ completedAt: new Date().toISOString(),
344
+ ...(text ? { result: text } : {}),
345
+ };
346
+ } catch (error) {
347
+ const text = inner.getLastAssistantText()?.trim();
348
+ const aborted = stored.abortRequested || request.signal?.aborted;
349
+ result = {
350
+ ...initialRun,
351
+ status: aborted ? "aborted" : maxTurnsReached ? "completed" : "failed",
352
+ completedAt: new Date().toISOString(),
353
+ ...(text ? { result: text } : {}),
354
+ ...(!aborted && !maxTurnsReached
355
+ ? { error: error instanceof Error ? error.message : String(error) }
356
+ : {}),
357
+ };
358
+ } finally {
359
+ unsubscribeTurns();
360
+ request.signal?.removeEventListener("abort", handleParentAbort);
361
+ }
362
+
363
+ const cleanupError = await cleanupWorktree(parent.cwd, isolatedWorktree);
364
+ if (cleanupError) result = { ...result, worktreeCleanupError: cleanupError };
365
+ const persisted: SubagentResultMetadata = {
366
+ version: 1,
367
+ status: result.status as SubagentResultMetadata["status"],
368
+ completedAt: result.completedAt!,
369
+ ...(result.result ? { result: result.result } : {}),
370
+ ...(result.error ? { error: result.error } : {}),
371
+ ...(result.worktreeCleanupError ? { worktreeCleanupError: result.worktreeCleanupError } : {}),
372
+ };
373
+ sessionManager.appendCustomEntry(SUBAGENT_RESULT_TYPE, persisted);
374
+ stored.run = result;
375
+ request.onUpdate?.(result);
376
+ getSubagentRuns().delete(initialRun.sessionId);
377
+ dependencies.invalidateSessionList();
378
+ return result;
379
+ };
380
+
381
+ const finishQueuedAbort = async () => {
382
+ if (stored.run.status !== "queued") return;
383
+ const result: SubagentRunInfo = { ...initialRun, status: "aborted", completedAt: new Date().toISOString() };
384
+ const cleanupError = await cleanupWorktree(parent.cwd, isolatedWorktree);
385
+ const finalResult = cleanupError ? { ...result, worktreeCleanupError: cleanupError } : result;
386
+ sessionManager.appendCustomEntry(SUBAGENT_RESULT_TYPE, { version: 1, status: "aborted", completedAt: finalResult.completedAt, ...(cleanupError ? { worktreeCleanupError: cleanupError } : {}) });
387
+ stored.run = finalResult;
388
+ request.onUpdate?.(finalResult);
389
+ getSubagentRuns().delete(initialRun.sessionId);
390
+ dependencies.invalidateSessionList();
391
+ resolveCompletion(finalResult);
392
+ };
393
+ const queued = getSubagentQueue().enqueue(
394
+ parentSessionId,
395
+ readSubagentSettings().maxConcurrent,
396
+ execute,
397
+ (state) => {
398
+ if (state === "queued") {
399
+ sessionManager.appendCustomEntry(SUBAGENT_STATUS_TYPE, { version: 1, status: "queued" });
400
+ }
401
+ request.onUpdate?.({ ...stored.run, status: state });
402
+ stored.run = { ...stored.run, status: state };
403
+ dependencies.invalidateSessionList();
404
+ },
405
+ finishQueuedAbort,
406
+ );
407
+ stored.cancelQueued = queued.cancel;
408
+ void queued.promise.then(resolveCompletion, (error) => {
409
+ resolveCompletion({ ...initialRun, status: "failed", completedAt: new Date().toISOString(), error: error instanceof Error ? error.message : String(error) });
410
+ });
411
+
412
+ return { run: stored.run, completion: stored.completion };
413
+ } catch (error) {
414
+ if (isolatedWorktree) {
415
+ try { await removeWorktree(parent.cwd, isolatedWorktree.path); } catch { /* preserve setup failure and avoid force deletion */ }
416
+ }
417
+ throw error;
418
+ }
419
+ }
420
+
421
+ async function resume(request: ResumeSubagentRequest): Promise<SubagentExecution> {
422
+ const enabled = dependencies.isBuiltInSubagentsEnabled ?? isBuiltInSubagentsEnabled;
423
+ if (!enabled()) throw new Error("Pi Web built-in sub-agents are disabled");
424
+ const parentSessionId = request.parentContext.sessionManager.getSessionId();
425
+ const existing = await get(request.sessionId);
426
+ if (!existing) throw new Error(`Subagent not found: ${request.sessionId}`);
427
+ if (existing.parentSessionId !== parentSessionId) throw new Error("Subagent does not belong to this parent session");
428
+ if (existing.status === "running" || existing.status === "queued") throw new Error("Subagent is already running");
429
+ const parent = dependencies.getSession(parentSessionId);
430
+ if (!parent?.isAlive()) throw new Error("Parent session is no longer available");
431
+ const sessionPath = existing.sessionPath || await dependencies.resolveSessionPath(request.sessionId);
432
+ if (!sessionPath) throw new Error(`Subagent session file not found: ${request.sessionId}`);
433
+ let wrapper = dependencies.getSession(request.sessionId);
434
+ if (!wrapper?.isAlive()) wrapper = await dependencies.reopenSession(request.sessionId, sessionPath);
435
+ if (!wrapper.isAlive()) throw new Error("Subagent session is no longer available");
436
+ if (wrapper.isRunning()) throw new Error("Subagent is already running");
437
+
438
+ const runInBackground = request.runInBackground ?? existing.runInBackground;
439
+ const initialRun: SubagentRunInfo = {
440
+ ...existing,
441
+ parentToolCallId: request.parentToolCallId,
442
+ task: request.task,
443
+ description: request.description.trim() || existing.description,
444
+ runInBackground,
445
+ status: "queued",
446
+ completedAt: undefined,
447
+ result: undefined,
448
+ error: undefined,
449
+ };
450
+ const manager = wrapper.inner.sessionManager;
451
+ let resolveCompletion!: (run: SubagentRunInfo) => void;
452
+ const completion = new Promise<SubagentRunInfo>((resolve) => { resolveCompletion = resolve; });
453
+ const stored: StoredSubagentExecution = { run: initialRun, completion, abortRequested: false };
454
+ getSubagentRuns().set(request.sessionId, stored);
455
+ request.onUpdate?.(initialRun);
456
+ dependencies.invalidateSessionList();
457
+ const handleParentAbort = () => {
458
+ stored.abortRequested = true;
459
+ if (stored.run.status === "queued") stored.cancelQueued?.();
460
+ else void wrapper!.inner.abort();
461
+ };
462
+ if (!runInBackground) request.signal?.addEventListener("abort", handleParentAbort, { once: true });
463
+
464
+ const execute = async (): Promise<SubagentRunInfo> => {
465
+ if (stored.abortRequested) {
466
+ const result: SubagentRunInfo = { ...initialRun, status: "aborted", completedAt: new Date().toISOString() };
467
+ manager.appendCustomEntry(SUBAGENT_RESULT_TYPE, { version: 1, status: "aborted", completedAt: result.completedAt });
468
+ stored.run = result;
469
+ getSubagentRuns().delete(request.sessionId);
470
+ resolveCompletion(result);
471
+ return result;
472
+ }
473
+ stored.run = { ...stored.run, status: "running" };
474
+ manager.appendCustomEntry(SUBAGENT_STATUS_TYPE, { version: 1, status: "running" });
475
+ request.onUpdate?.(stored.run);
476
+ let result: SubagentRunInfo;
477
+ try {
478
+ await wrapper!.inner.prompt(request.task, { source: "rpc" });
479
+ const text = wrapper!.inner.getLastAssistantText()?.trim();
480
+ result = { ...initialRun, status: stored.abortRequested ? "aborted" : "completed", completedAt: new Date().toISOString(), ...(text ? { result: text } : {}) };
481
+ } catch (error) {
482
+ result = {
483
+ ...initialRun,
484
+ status: stored.abortRequested || request.signal?.aborted ? "aborted" : "failed",
485
+ completedAt: new Date().toISOString(),
486
+ ...(!stored.abortRequested && !request.signal?.aborted ? { error: error instanceof Error ? error.message : String(error) } : {}),
487
+ };
488
+ } finally {
489
+ request.signal?.removeEventListener("abort", handleParentAbort);
490
+ }
491
+ manager.appendCustomEntry(SUBAGENT_RESULT_TYPE, {
492
+ version: 1,
493
+ status: result.status as "completed" | "failed" | "aborted",
494
+ completedAt: result.completedAt!,
495
+ ...(result.result ? { result: result.result } : {}),
496
+ ...(result.error ? { error: result.error } : {}),
497
+ });
498
+ stored.run = result;
499
+ request.onUpdate?.(result);
500
+ getSubagentRuns().delete(request.sessionId);
501
+ dependencies.invalidateSessionList();
502
+ return result;
503
+ };
504
+ const finishQueuedAbort = () => {
505
+ if (stored.run.status !== "queued") return;
506
+ const result: SubagentRunInfo = { ...initialRun, status: "aborted", completedAt: new Date().toISOString() };
507
+ manager.appendCustomEntry(SUBAGENT_RESULT_TYPE, { version: 1, status: "aborted", completedAt: result.completedAt });
508
+ stored.run = result;
509
+ request.onUpdate?.(result);
510
+ getSubagentRuns().delete(request.sessionId);
511
+ dependencies.invalidateSessionList();
512
+ resolveCompletion(result);
513
+ };
514
+ const queued = getSubagentQueue().enqueue(parentSessionId, readSubagentSettings().maxConcurrent, execute, (state) => {
515
+ if (state === "queued") manager.appendCustomEntry(SUBAGENT_STATUS_TYPE, { version: 1, status: "queued" });
516
+ stored.run = { ...stored.run, status: state };
517
+ request.onUpdate?.(stored.run);
518
+ dependencies.invalidateSessionList();
519
+ }, finishQueuedAbort);
520
+ stored.cancelQueued = queued.cancel;
521
+ void queued.promise.then(resolveCompletion, (error) => resolveCompletion({ ...initialRun, status: "failed", completedAt: new Date().toISOString(), error: error instanceof Error ? error.message : String(error) }));
522
+ return { run: stored.run, completion };
523
+ }
524
+
525
+ async function get(sessionId: string): Promise<SubagentRunInfo | null> {
526
+ const stored = getSubagentRuns().get(sessionId);
527
+ if (stored) return stored.run;
528
+ const wrapper = dependencies.getSession(sessionId);
529
+ if (wrapper?.isAlive()) {
530
+ const run = readSubagentRun(
531
+ wrapper.inner.sessionManager.getEntries() as unknown as SessionEntry[],
532
+ sessionId,
533
+ wrapper.sessionFile,
534
+ );
535
+ if (run && wrapper.isRunning()) return { ...run, status: "running" };
536
+ if (run) return run;
537
+ }
538
+ const sessionPath = await dependencies.resolveSessionPath(sessionId);
539
+ if (!sessionPath) return null;
540
+ const manager = SessionManager.open(sessionPath);
541
+ return readSubagentRun(manager.getEntries() as unknown as SessionEntry[], sessionId, sessionPath);
542
+ }
543
+
544
+ async function steer(sessionId: string, message: string): Promise<void> {
545
+ const wrapper = dependencies.getSession(sessionId);
546
+ if (!wrapper?.isAlive() || !wrapper.isRunning()) throw new Error("Subagent is not running");
547
+ if (!message.trim()) throw new Error("Steering message is required");
548
+ await wrapper.inner.steer(message.trim());
549
+ }
550
+
551
+ async function notifyParent(run: SubagentRunInfo): Promise<void> {
552
+ let parent = dependencies.getSession(run.parentSessionId);
553
+ if (!parent?.isAlive()) {
554
+ const sessionFile = await dependencies.resolveSessionPath(run.parentSessionId);
555
+ if (!sessionFile) throw new Error(`Parent session not found: ${run.parentSessionId}`);
556
+ parent = await dependencies.reopenSession(run.parentSessionId, sessionFile);
557
+ }
558
+ await parent.waitUntilReady();
559
+ if (!parent.isAlive()) throw new Error(`Parent session is no longer available: ${run.parentSessionId}`);
560
+ await parent.inner.sendCustomMessage({
561
+ customType: "pi-web:subagent-notification",
562
+ content: subagentFinalText(run),
563
+ display: true,
564
+ details: subagentToolDetails(run),
565
+ }, { deliverAs: "followUp", triggerTurn: true });
566
+ }
567
+
568
+ async function abort(sessionId: string): Promise<void> {
569
+ const wrapper = dependencies.getSession(sessionId);
570
+ const stored = getSubagentRuns().get(sessionId);
571
+ if (stored?.run.status === "queued") {
572
+ stored.abortRequested = true;
573
+ if (!stored.cancelQueued?.()) throw new Error("Subagent is no longer queued");
574
+ return;
575
+ }
576
+ if (!wrapper?.isAlive() || !wrapper.isRunning()) throw new Error("Subagent is not running");
577
+ if (stored) stored.abortRequested = true;
578
+ await wrapper.inner.abort();
579
+ }
580
+
581
+ return {
582
+ extensionRuntime: { start, resume, get, steer, notifyParent },
583
+ get,
584
+ steer,
585
+ abort,
586
+ };
587
+ }
@@ -0,0 +1,50 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import test from "node:test";
6
+ import { createJiti } from "jiti";
7
+
8
+ const {
9
+ isBuiltInSubagentsEnabled,
10
+ readSubagentSettings,
11
+ writeBuiltInSubagentsEnabled,
12
+ } = await createJiti(import.meta.url).import("./subagent-settings.ts");
13
+
14
+ test("subagent settings default the built-in extension to disabled", async (t) => {
15
+ const root = await mkdtemp(join(tmpdir(), "pi-web-subagent-settings-"));
16
+ t.after(() => rm(root, { recursive: true, force: true }));
17
+ const settingsPath = join(root, "agents", "settings.json");
18
+
19
+ assert.deepEqual(readSubagentSettings(settingsPath), { builtInEnabled: false });
20
+ assert.equal(isBuiltInSubagentsEnabled(settingsPath), false);
21
+ });
22
+
23
+ test("subagent settings persist both states and preserve unrelated fields", async (t) => {
24
+ const root = await mkdtemp(join(tmpdir(), "pi-web-subagent-settings-"));
25
+ t.after(() => rm(root, { recursive: true, force: true }));
26
+ const settingsPath = join(root, "agents", "settings.json");
27
+
28
+ writeBuiltInSubagentsEnabled(true, settingsPath);
29
+ assert.deepEqual(readSubagentSettings(settingsPath), { builtInEnabled: true });
30
+ assert.equal(isBuiltInSubagentsEnabled(settingsPath), true);
31
+ const first = JSON.parse(await readFile(settingsPath, "utf8"));
32
+ assert.deepEqual(first, { version: 1, builtInEnabled: true });
33
+
34
+ await writeFile(settingsPath, JSON.stringify({ ...first, futureSetting: 3 }));
35
+ writeBuiltInSubagentsEnabled(false, settingsPath);
36
+ const second = JSON.parse(await readFile(settingsPath, "utf8"));
37
+ assert.deepEqual(second, { version: 1, builtInEnabled: false, futureSetting: 3 });
38
+ });
39
+
40
+ test("damaged settings fail closed and are not overwritten", async (t) => {
41
+ const root = await mkdtemp(join(tmpdir(), "pi-web-subagent-settings-"));
42
+ t.after(() => rm(root, { recursive: true, force: true }));
43
+ const settingsPath = join(root, "settings.json");
44
+ await writeFile(settingsPath, "{");
45
+
46
+ assert.equal(isBuiltInSubagentsEnabled(settingsPath), false);
47
+ assert.throws(() => readSubagentSettings(settingsPath));
48
+ assert.throws(() => writeBuiltInSubagentsEnabled(true, settingsPath));
49
+ assert.equal(await readFile(settingsPath, "utf8"), "{");
50
+ });