@baique/pi-web-sky 0.1.55 → 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 (361) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +8 -4
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +2 -2
  5. package/.next/react-loadable-manifest.json +2 -2
  6. package/.next/required-server-files.js +1 -1
  7. package/.next/required-server-files.json +1 -1
  8. package/.next/routes-manifest.json +28 -0
  9. package/.next/server/app/_global-error/page.js +2 -2
  10. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/_global-error.html +1 -1
  12. package/.next/server/app/_global-error.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page.js +1 -1
  17. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/server/app/_not-found.html +1 -1
  19. package/.next/server/app/_not-found.rsc +4 -3
  20. package/.next/server/app/_not-found.segments/_full.segment.rsc +4 -3
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -3
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -2
  23. package/.next/server/app/api/agent/[id]/bash-output/route.js +2 -2
  24. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  25. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  26. package/.next/server/app/api/agent/[id]/route.js +1 -1
  27. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/new/route.js +1 -1
  29. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  30. package/.next/server/app/api/agent/running/route.js +1 -1
  31. package/.next/server/app/api/agent/running/route.js.nft.json +1 -1
  32. package/.next/server/app/api/app-update/route.js +1 -1
  33. package/.next/server/app/api/auth/all-providers/route.js +1 -1
  34. package/.next/server/app/api/auth/api-key/[provider]/route.js +1 -1
  35. package/.next/server/app/api/auth/login/[provider]/route.js +1 -1
  36. package/.next/server/app/api/auth/logout/[provider]/route.js +1 -1
  37. package/.next/server/app/api/auth/providers/route.js +1 -1
  38. package/.next/server/app/api/board-assets/[...path]/route.js +2 -2
  39. package/.next/server/app/api/board-assets/route.js +2 -2
  40. package/.next/server/app/api/boards/[id]/add-session/route.js +1 -0
  41. package/.next/server/app/api/boards/[id]/add-session/route.js.nft.json +1 -0
  42. package/.next/server/app/api/boards/[id]/add-session/route_client-reference-manifest.js +1 -0
  43. package/.next/server/app/api/boards/[id]/reconcile/route.js +1 -1
  44. package/.next/server/app/api/boards/[id]/route.js +1 -1
  45. package/.next/server/app/api/boards/reorder/route.js +2 -2
  46. package/.next/server/app/api/boards/route.js +1 -1
  47. package/.next/server/app/api/cwd/browse/route.js +1 -1
  48. package/.next/server/app/api/cwd/validate/route.js +2 -2
  49. package/.next/server/app/api/default-cwd/route.js +2 -2
  50. package/.next/server/app/api/file-index/route.js +2 -2
  51. package/.next/server/app/api/files/[...path]/route.js +3 -3
  52. package/.next/server/app/api/git/diff/route.js +1 -1
  53. package/.next/server/app/api/git/status/route.js +1 -1
  54. package/.next/server/app/api/home/route.js +1 -1
  55. package/.next/server/app/api/mcp/route.js +2 -2
  56. package/.next/server/app/api/models/route.js +2 -2
  57. package/.next/server/app/api/models-config/catalog/route.js +1 -1
  58. package/.next/server/app/api/models-config/discover/route.js +1 -1
  59. package/.next/server/app/api/models-config/route.js +1 -1
  60. package/.next/server/app/api/models-config/test/route.js +1 -1
  61. package/.next/server/app/api/plugins/route.js +2 -2
  62. package/.next/server/app/api/project-trust/route.js +1 -1
  63. package/.next/server/app/api/project-trust/route.js.nft.json +1 -1
  64. package/.next/server/app/api/quota/route.js +1 -1
  65. package/.next/server/app/api/search/route.js +2 -2
  66. package/.next/server/app/api/sessions/[id]/auto-name/route.js +2 -2
  67. package/.next/server/app/api/sessions/[id]/auto-name/route.js.nft.json +1 -1
  68. package/.next/server/app/api/sessions/[id]/context/route.js +1 -1
  69. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +1 -1
  70. package/.next/server/app/api/sessions/[id]/entries/[entryId]/thinking/route.js +2 -2
  71. package/.next/server/app/api/sessions/[id]/export/route.js +2 -2
  72. package/.next/server/app/api/sessions/[id]/minimap/route.js +1 -1
  73. package/.next/server/app/api/sessions/[id]/minimap/route.js.nft.json +1 -1
  74. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  75. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  76. package/.next/server/app/api/sessions/[id]/state/route.js +1 -1
  77. package/.next/server/app/api/sessions/[id]/state/route.js.nft.json +1 -1
  78. package/.next/server/app/api/sessions/[id]/todos/route.js +1 -1
  79. package/.next/server/app/api/sessions/[id]/todos/route.js.nft.json +1 -1
  80. package/.next/server/app/api/sessions/route.js +1 -1
  81. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  82. package/.next/server/app/api/sessions/summary/route.js +2 -2
  83. package/.next/server/app/api/skills/check/route.js +1 -1
  84. package/.next/server/app/api/skills/install/route.js +2 -2
  85. package/.next/server/app/api/skills/route.js +1 -1
  86. package/.next/server/app/api/skills/search/route.js +1 -1
  87. package/.next/server/app/api/skills/update/route.js +1 -1
  88. package/.next/server/app/api/subagents/[id]/route.js +1 -0
  89. package/.next/server/app/api/subagents/[id]/route.js.nft.json +1 -0
  90. package/.next/server/app/api/subagents/[id]/route_client-reference-manifest.js +1 -0
  91. package/.next/server/app/api/subagents/profiles/route.js +30 -0
  92. package/.next/server/app/api/subagents/profiles/route.js.nft.json +1 -0
  93. package/.next/server/app/api/subagents/profiles/route_client-reference-manifest.js +1 -0
  94. package/.next/server/app/api/subagents/settings/route.js +1 -0
  95. package/.next/server/app/api/subagents/settings/route.js.nft.json +1 -0
  96. package/.next/server/app/api/subagents/settings/route_client-reference-manifest.js +1 -0
  97. package/.next/server/app/api/task-card-questions/[id]/answer/route.js +2 -2
  98. package/.next/server/app/api/task-card-questions/route.js +2 -2
  99. package/.next/server/app/api/task-cards/[id]/route.js +1 -1
  100. package/.next/server/app/api/task-cards/route.js +1 -1
  101. package/.next/server/app/api/task-cards/unbind/route.js +3 -3
  102. package/.next/server/app/api/task-scheduler/status/route.js +1 -1
  103. package/.next/server/app/api/task-scheduler/status/route.js.nft.json +1 -1
  104. package/.next/server/app/api/tasks/[id]/assign-session/route.js +2 -2
  105. package/.next/server/app/api/tasks/[id]/board/route.js +1 -1
  106. package/.next/server/app/api/tasks/[id]/route.js +1 -1
  107. package/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
  108. package/.next/server/app/api/tasks/reorder/route.js +2 -2
  109. package/.next/server/app/api/tasks/route.js +3 -3
  110. package/.next/server/app/api/terminal/[id]/events/route.js +2 -2
  111. package/.next/server/app/api/terminal/[id]/route.js +2 -2
  112. package/.next/server/app/api/terminal/route.js +2 -2
  113. package/.next/server/app/api/worktrees/route.js +2 -2
  114. package/.next/server/app/api/yjs-version/route.js +1 -1
  115. package/.next/server/app/favicon.ico/route.js +1 -1
  116. package/.next/server/app/index.html +1 -1
  117. package/.next/server/app/index.rsc +6 -5
  118. package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -5
  119. package/.next/server/app/index.segments/_full.segment.rsc +6 -5
  120. package/.next/server/app/index.segments/_tree.segment.rsc +3 -2
  121. package/.next/server/app/manifest.webmanifest/route.js +2 -2
  122. package/.next/server/app/page.js +175 -8
  123. package/.next/server/app/page_client-reference-manifest.js +1 -1
  124. package/.next/server/app-paths-manifest.json +8 -4
  125. package/.next/server/chunks/1937.js +1 -1
  126. package/.next/server/chunks/3379.js +1 -1
  127. package/.next/server/chunks/402.js +12 -2
  128. package/.next/server/chunks/426.js +14 -0
  129. package/.next/server/chunks/4367.js +1 -1
  130. package/.next/server/chunks/4457.js +2 -2
  131. package/.next/server/chunks/4980.js +1 -1
  132. package/.next/server/chunks/542.js +23 -4
  133. package/.next/server/chunks/5794.js +1 -1
  134. package/.next/server/chunks/6337.js +1 -1
  135. package/.next/server/chunks/6429.js +15 -2
  136. package/.next/server/chunks/6525.js +12 -2
  137. package/.next/server/chunks/7048.js +6 -0
  138. package/.next/server/instrumentation.js +1 -1
  139. package/.next/server/middleware-build-manifest.js +1 -1
  140. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  141. package/.next/server/middleware.js +3 -3
  142. package/.next/server/pages/404.html +1 -1
  143. package/.next/server/pages/500.html +1 -1
  144. package/.next/static/chunks/{752.0ad92735d5f38143.js → 752.adce8bc3ebbaf4b6.js} +1 -1
  145. package/.next/static/chunks/8088.0cad1ff2e09fd8ff.js +1 -0
  146. package/.next/static/chunks/app/_global-error/page-ad6e695deb9de65c.js +1 -0
  147. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-ad6e695deb9de65c.js +1 -0
  148. package/.next/static/chunks/app/api/agent/[id]/events/route-ad6e695deb9de65c.js +1 -0
  149. package/.next/static/chunks/app/api/agent/[id]/route-ad6e695deb9de65c.js +1 -0
  150. package/.next/static/chunks/app/api/agent/new/route-ad6e695deb9de65c.js +1 -0
  151. package/.next/static/chunks/app/api/agent/running/route-ad6e695deb9de65c.js +1 -0
  152. package/.next/static/chunks/app/api/app-update/route-ad6e695deb9de65c.js +1 -0
  153. package/.next/static/chunks/app/api/auth/all-providers/route-ad6e695deb9de65c.js +1 -0
  154. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-ad6e695deb9de65c.js +1 -0
  155. package/.next/static/chunks/app/api/auth/login/[provider]/route-ad6e695deb9de65c.js +1 -0
  156. package/.next/static/chunks/app/api/auth/logout/[provider]/route-ad6e695deb9de65c.js +1 -0
  157. package/.next/static/chunks/app/api/auth/providers/route-ad6e695deb9de65c.js +1 -0
  158. package/.next/static/chunks/app/api/board-assets/[...path]/route-ad6e695deb9de65c.js +1 -0
  159. package/.next/static/chunks/app/api/board-assets/route-ad6e695deb9de65c.js +1 -0
  160. package/.next/static/chunks/app/api/boards/[id]/add-session/route-ad6e695deb9de65c.js +1 -0
  161. package/.next/static/chunks/app/api/boards/[id]/reconcile/route-ad6e695deb9de65c.js +1 -0
  162. package/.next/static/chunks/app/api/boards/[id]/route-ad6e695deb9de65c.js +1 -0
  163. package/.next/static/chunks/app/api/boards/reorder/route-ad6e695deb9de65c.js +1 -0
  164. package/.next/static/chunks/app/api/boards/route-ad6e695deb9de65c.js +1 -0
  165. package/.next/static/chunks/app/api/cwd/browse/route-ad6e695deb9de65c.js +1 -0
  166. package/.next/static/chunks/app/api/cwd/validate/route-ad6e695deb9de65c.js +1 -0
  167. package/.next/static/chunks/app/api/default-cwd/route-ad6e695deb9de65c.js +1 -0
  168. package/.next/static/chunks/app/api/file-index/route-ad6e695deb9de65c.js +1 -0
  169. package/.next/static/chunks/app/api/files/[...path]/route-ad6e695deb9de65c.js +1 -0
  170. package/.next/static/chunks/app/api/git/diff/route-ad6e695deb9de65c.js +1 -0
  171. package/.next/static/chunks/app/api/git/status/route-ad6e695deb9de65c.js +1 -0
  172. package/.next/static/chunks/app/api/home/route-ad6e695deb9de65c.js +1 -0
  173. package/.next/static/chunks/app/api/mcp/route-ad6e695deb9de65c.js +1 -0
  174. package/.next/static/chunks/app/api/models/route-ad6e695deb9de65c.js +1 -0
  175. package/.next/static/chunks/app/api/models-config/catalog/route-ad6e695deb9de65c.js +1 -0
  176. package/.next/static/chunks/app/api/models-config/discover/route-ad6e695deb9de65c.js +1 -0
  177. package/.next/static/chunks/app/api/models-config/route-ad6e695deb9de65c.js +1 -0
  178. package/.next/static/chunks/app/api/models-config/test/route-ad6e695deb9de65c.js +1 -0
  179. package/.next/static/chunks/app/api/plugins/route-ad6e695deb9de65c.js +1 -0
  180. package/.next/static/chunks/app/api/project-trust/route-ad6e695deb9de65c.js +1 -0
  181. package/.next/static/chunks/app/api/quota/route-ad6e695deb9de65c.js +1 -0
  182. package/.next/static/chunks/app/api/search/route-ad6e695deb9de65c.js +1 -0
  183. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-ad6e695deb9de65c.js +1 -0
  184. package/.next/static/chunks/app/api/sessions/[id]/context/route-ad6e695deb9de65c.js +1 -0
  185. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-ad6e695deb9de65c.js +1 -0
  186. package/.next/static/chunks/app/api/sessions/[id]/export/route-ad6e695deb9de65c.js +1 -0
  187. package/.next/static/chunks/app/api/sessions/[id]/minimap/route-ad6e695deb9de65c.js +1 -0
  188. package/.next/static/chunks/app/api/sessions/[id]/route-ad6e695deb9de65c.js +1 -0
  189. package/.next/static/chunks/app/api/sessions/[id]/state/route-ad6e695deb9de65c.js +1 -0
  190. package/.next/static/chunks/app/api/sessions/[id]/todos/route-ad6e695deb9de65c.js +1 -0
  191. package/.next/static/chunks/app/api/sessions/route-ad6e695deb9de65c.js +1 -0
  192. package/.next/static/chunks/app/api/sessions/summary/route-ad6e695deb9de65c.js +1 -0
  193. package/.next/static/chunks/app/api/skills/check/route-ad6e695deb9de65c.js +1 -0
  194. package/.next/static/chunks/app/api/skills/install/route-ad6e695deb9de65c.js +1 -0
  195. package/.next/static/chunks/app/api/skills/route-ad6e695deb9de65c.js +1 -0
  196. package/.next/static/chunks/app/api/skills/search/route-ad6e695deb9de65c.js +1 -0
  197. package/.next/static/chunks/app/api/skills/update/route-ad6e695deb9de65c.js +1 -0
  198. package/.next/static/chunks/app/api/subagents/[id]/route-ad6e695deb9de65c.js +1 -0
  199. package/.next/static/chunks/app/api/subagents/profiles/route-ad6e695deb9de65c.js +1 -0
  200. package/.next/static/chunks/app/api/subagents/settings/route-ad6e695deb9de65c.js +1 -0
  201. package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-ad6e695deb9de65c.js +1 -0
  202. package/.next/static/chunks/app/api/task-card-questions/route-ad6e695deb9de65c.js +1 -0
  203. package/.next/static/chunks/app/api/task-cards/[id]/route-ad6e695deb9de65c.js +1 -0
  204. package/.next/static/chunks/app/api/task-cards/route-ad6e695deb9de65c.js +1 -0
  205. package/.next/static/chunks/app/api/task-cards/unbind/route-ad6e695deb9de65c.js +1 -0
  206. package/.next/static/chunks/app/api/task-scheduler/status/route-ad6e695deb9de65c.js +1 -0
  207. package/.next/static/chunks/app/api/tasks/[id]/assign-session/route-ad6e695deb9de65c.js +1 -0
  208. package/.next/static/chunks/app/api/tasks/[id]/board/route-ad6e695deb9de65c.js +1 -0
  209. package/.next/static/chunks/app/api/tasks/[id]/route-ad6e695deb9de65c.js +1 -0
  210. package/.next/static/chunks/app/api/tasks/reorder/route-ad6e695deb9de65c.js +1 -0
  211. package/.next/static/chunks/app/api/tasks/route-ad6e695deb9de65c.js +1 -0
  212. package/.next/static/chunks/app/api/terminal/[id]/events/route-ad6e695deb9de65c.js +1 -0
  213. package/.next/static/chunks/app/api/terminal/[id]/route-ad6e695deb9de65c.js +1 -0
  214. package/.next/static/chunks/app/api/terminal/route-ad6e695deb9de65c.js +1 -0
  215. package/.next/static/chunks/app/api/worktrees/route-ad6e695deb9de65c.js +1 -0
  216. package/.next/static/chunks/app/api/yjs-version/route-ad6e695deb9de65c.js +1 -0
  217. package/.next/static/chunks/app/layout-87087b955e0c9507.js +1 -0
  218. package/.next/static/chunks/app/manifest.webmanifest/route-ad6e695deb9de65c.js +1 -0
  219. package/.next/static/chunks/app/page-efca6bf51a5f8ccb.js +256 -0
  220. package/.next/static/chunks/next/dist/client/components/builtin/app-error-ad6e695deb9de65c.js +1 -0
  221. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-ad6e695deb9de65c.js +1 -0
  222. package/.next/static/chunks/next/dist/client/components/builtin/not-found-ad6e695deb9de65c.js +1 -0
  223. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-ad6e695deb9de65c.js +1 -0
  224. package/.next/static/chunks/{webpack-b0effde51c1651b8.js → webpack-4de8e8dd9f2f3173.js} +1 -1
  225. package/.next/static/css/bb9361c7f832a89d.css +1 -0
  226. package/.next/static/css/c6d32b6031181be7.css +1 -0
  227. package/.next/static/k8ZFqwz7d-bnK0ZiUVgCc/_buildManifest.js +1 -0
  228. package/.next/trace +7 -7
  229. package/.next/trace-build +1 -1
  230. package/.next/types/app/api/boards/[id]/add-session/route.ts +353 -0
  231. package/.next/types/app/api/subagents/[id]/route.ts +353 -0
  232. package/.next/types/app/api/subagents/profiles/route.ts +353 -0
  233. package/.next/types/app/api/subagents/settings/route.ts +353 -0
  234. package/.next/types/routes.d.ts +5 -1
  235. package/.next/types/validator.ts +36 -0
  236. package/lib/api-types.ts +10 -0
  237. package/lib/board-reconcile.test.mjs +20 -0
  238. package/lib/board-reconcile.ts +54 -0
  239. package/lib/chat-lazy-load.test.mjs +0 -62
  240. package/lib/chat-lazy-load.ts +0 -13
  241. package/lib/chat-only.ts +23 -0
  242. package/lib/draft-stash.ts +4 -5
  243. package/lib/file-types.ts +16 -1
  244. package/lib/i18n/messages/en.ts +91 -0
  245. package/lib/i18n/messages/zh-CN.ts +91 -0
  246. package/lib/id.test.mjs +38 -0
  247. package/lib/id.ts +17 -0
  248. package/lib/message-text.ts +24 -0
  249. package/lib/models-cache.ts +1 -1
  250. package/lib/pi-types.ts +19 -1
  251. package/lib/pin-store.ts +85 -0
  252. package/lib/powershell-settings.ts +106 -0
  253. package/lib/quoted-selection.ts +4 -0
  254. package/lib/rpc-manager.ts +208 -22
  255. package/lib/session-family.test.mjs +49 -0
  256. package/lib/session-family.ts +80 -0
  257. package/lib/session-index-scanner.ts +39 -0
  258. package/lib/session-time-group.test.mjs +38 -0
  259. package/lib/session-time-group.ts +55 -0
  260. package/lib/settings-navigation.ts +124 -0
  261. package/lib/subagent-extension.test.mjs +424 -0
  262. package/lib/subagent-extension.ts +309 -0
  263. package/lib/subagent-input.test.mjs +63 -0
  264. package/lib/subagent-input.ts +71 -0
  265. package/lib/subagent-isolation.test.mjs +51 -0
  266. package/lib/subagent-profile-precedence.ts +20 -0
  267. package/lib/subagent-prompt.test.mjs +64 -0
  268. package/lib/subagent-prompt.ts +31 -0
  269. package/lib/subagent-queue.test.mjs +35 -0
  270. package/lib/subagent-queue.ts +74 -0
  271. package/lib/subagent-runtime.test.mjs +150 -0
  272. package/lib/subagent-runtime.ts +587 -0
  273. package/lib/subagent-settings.test.mjs +50 -0
  274. package/lib/subagent-settings.ts +93 -0
  275. package/lib/subagents.test.mjs +601 -0
  276. package/lib/subagents.ts +602 -0
  277. package/lib/tool-presets.ts +4 -0
  278. package/lib/types.ts +19 -0
  279. package/package.json +1 -1
  280. package/.next/static/bsW3fla0-BlBHVMKtAM5I/_buildManifest.js +0 -1
  281. package/.next/static/chunks/8088.53d9cdaf15634d4b.js +0 -1
  282. package/.next/static/chunks/app/_global-error/page-2d5f6296c7e693c6.js +0 -1
  283. package/.next/static/chunks/app/api/agent/[id]/bash-output/route-2d5f6296c7e693c6.js +0 -1
  284. package/.next/static/chunks/app/api/agent/[id]/events/route-2d5f6296c7e693c6.js +0 -1
  285. package/.next/static/chunks/app/api/agent/[id]/route-2d5f6296c7e693c6.js +0 -1
  286. package/.next/static/chunks/app/api/agent/new/route-2d5f6296c7e693c6.js +0 -1
  287. package/.next/static/chunks/app/api/agent/running/route-2d5f6296c7e693c6.js +0 -1
  288. package/.next/static/chunks/app/api/app-update/route-2d5f6296c7e693c6.js +0 -1
  289. package/.next/static/chunks/app/api/auth/all-providers/route-2d5f6296c7e693c6.js +0 -1
  290. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-2d5f6296c7e693c6.js +0 -1
  291. package/.next/static/chunks/app/api/auth/login/[provider]/route-2d5f6296c7e693c6.js +0 -1
  292. package/.next/static/chunks/app/api/auth/logout/[provider]/route-2d5f6296c7e693c6.js +0 -1
  293. package/.next/static/chunks/app/api/auth/providers/route-2d5f6296c7e693c6.js +0 -1
  294. package/.next/static/chunks/app/api/board-assets/[...path]/route-2d5f6296c7e693c6.js +0 -1
  295. package/.next/static/chunks/app/api/board-assets/route-2d5f6296c7e693c6.js +0 -1
  296. package/.next/static/chunks/app/api/boards/[id]/reconcile/route-2d5f6296c7e693c6.js +0 -1
  297. package/.next/static/chunks/app/api/boards/[id]/route-2d5f6296c7e693c6.js +0 -1
  298. package/.next/static/chunks/app/api/boards/reorder/route-2d5f6296c7e693c6.js +0 -1
  299. package/.next/static/chunks/app/api/boards/route-2d5f6296c7e693c6.js +0 -1
  300. package/.next/static/chunks/app/api/cwd/browse/route-2d5f6296c7e693c6.js +0 -1
  301. package/.next/static/chunks/app/api/cwd/validate/route-2d5f6296c7e693c6.js +0 -1
  302. package/.next/static/chunks/app/api/default-cwd/route-2d5f6296c7e693c6.js +0 -1
  303. package/.next/static/chunks/app/api/file-index/route-2d5f6296c7e693c6.js +0 -1
  304. package/.next/static/chunks/app/api/files/[...path]/route-2d5f6296c7e693c6.js +0 -1
  305. package/.next/static/chunks/app/api/git/diff/route-2d5f6296c7e693c6.js +0 -1
  306. package/.next/static/chunks/app/api/git/status/route-2d5f6296c7e693c6.js +0 -1
  307. package/.next/static/chunks/app/api/home/route-2d5f6296c7e693c6.js +0 -1
  308. package/.next/static/chunks/app/api/mcp/route-2d5f6296c7e693c6.js +0 -1
  309. package/.next/static/chunks/app/api/models/route-2d5f6296c7e693c6.js +0 -1
  310. package/.next/static/chunks/app/api/models-config/catalog/route-2d5f6296c7e693c6.js +0 -1
  311. package/.next/static/chunks/app/api/models-config/discover/route-2d5f6296c7e693c6.js +0 -1
  312. package/.next/static/chunks/app/api/models-config/route-2d5f6296c7e693c6.js +0 -1
  313. package/.next/static/chunks/app/api/models-config/test/route-2d5f6296c7e693c6.js +0 -1
  314. package/.next/static/chunks/app/api/plugins/route-2d5f6296c7e693c6.js +0 -1
  315. package/.next/static/chunks/app/api/project-trust/route-2d5f6296c7e693c6.js +0 -1
  316. package/.next/static/chunks/app/api/quota/route-2d5f6296c7e693c6.js +0 -1
  317. package/.next/static/chunks/app/api/search/route-2d5f6296c7e693c6.js +0 -1
  318. package/.next/static/chunks/app/api/sessions/[id]/auto-name/route-2d5f6296c7e693c6.js +0 -1
  319. package/.next/static/chunks/app/api/sessions/[id]/context/route-2d5f6296c7e693c6.js +0 -1
  320. package/.next/static/chunks/app/api/sessions/[id]/entries/[entryId]/thinking/route-2d5f6296c7e693c6.js +0 -1
  321. package/.next/static/chunks/app/api/sessions/[id]/export/route-2d5f6296c7e693c6.js +0 -1
  322. package/.next/static/chunks/app/api/sessions/[id]/minimap/route-2d5f6296c7e693c6.js +0 -1
  323. package/.next/static/chunks/app/api/sessions/[id]/route-2d5f6296c7e693c6.js +0 -1
  324. package/.next/static/chunks/app/api/sessions/[id]/state/route-2d5f6296c7e693c6.js +0 -1
  325. package/.next/static/chunks/app/api/sessions/[id]/todos/route-2d5f6296c7e693c6.js +0 -1
  326. package/.next/static/chunks/app/api/sessions/route-2d5f6296c7e693c6.js +0 -1
  327. package/.next/static/chunks/app/api/sessions/summary/route-2d5f6296c7e693c6.js +0 -1
  328. package/.next/static/chunks/app/api/skills/check/route-2d5f6296c7e693c6.js +0 -1
  329. package/.next/static/chunks/app/api/skills/install/route-2d5f6296c7e693c6.js +0 -1
  330. package/.next/static/chunks/app/api/skills/route-2d5f6296c7e693c6.js +0 -1
  331. package/.next/static/chunks/app/api/skills/search/route-2d5f6296c7e693c6.js +0 -1
  332. package/.next/static/chunks/app/api/skills/update/route-2d5f6296c7e693c6.js +0 -1
  333. package/.next/static/chunks/app/api/task-card-questions/[id]/answer/route-2d5f6296c7e693c6.js +0 -1
  334. package/.next/static/chunks/app/api/task-card-questions/route-2d5f6296c7e693c6.js +0 -1
  335. package/.next/static/chunks/app/api/task-cards/[id]/route-2d5f6296c7e693c6.js +0 -1
  336. package/.next/static/chunks/app/api/task-cards/route-2d5f6296c7e693c6.js +0 -1
  337. package/.next/static/chunks/app/api/task-cards/unbind/route-2d5f6296c7e693c6.js +0 -1
  338. package/.next/static/chunks/app/api/task-scheduler/status/route-2d5f6296c7e693c6.js +0 -1
  339. package/.next/static/chunks/app/api/tasks/[id]/assign-session/route-2d5f6296c7e693c6.js +0 -1
  340. package/.next/static/chunks/app/api/tasks/[id]/board/route-2d5f6296c7e693c6.js +0 -1
  341. package/.next/static/chunks/app/api/tasks/[id]/route-2d5f6296c7e693c6.js +0 -1
  342. package/.next/static/chunks/app/api/tasks/reorder/route-2d5f6296c7e693c6.js +0 -1
  343. package/.next/static/chunks/app/api/tasks/route-2d5f6296c7e693c6.js +0 -1
  344. package/.next/static/chunks/app/api/terminal/[id]/events/route-2d5f6296c7e693c6.js +0 -1
  345. package/.next/static/chunks/app/api/terminal/[id]/route-2d5f6296c7e693c6.js +0 -1
  346. package/.next/static/chunks/app/api/terminal/route-2d5f6296c7e693c6.js +0 -1
  347. package/.next/static/chunks/app/api/worktrees/route-2d5f6296c7e693c6.js +0 -1
  348. package/.next/static/chunks/app/api/yjs-version/route-2d5f6296c7e693c6.js +0 -1
  349. package/.next/static/chunks/app/layout-dace09825b2d3857.js +0 -1
  350. package/.next/static/chunks/app/manifest.webmanifest/route-2d5f6296c7e693c6.js +0 -1
  351. package/.next/static/chunks/app/page-64b9f4b3567a2f73.js +0 -89
  352. package/.next/static/chunks/next/dist/client/components/builtin/app-error-2d5f6296c7e693c6.js +0 -1
  353. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-2d5f6296c7e693c6.js +0 -1
  354. package/.next/static/chunks/next/dist/client/components/builtin/not-found-2d5f6296c7e693c6.js +0 -1
  355. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2d5f6296c7e693c6.js +0 -1
  356. package/.next/static/css/fd25673802257262.css +0 -1
  357. package/lib/extension-command.test.mjs +0 -63
  358. package/lib/extension-command.ts +0 -81
  359. package/lib/subagent-widget.test.mjs +0 -87
  360. package/lib/subagent-widget.ts +0 -109
  361. /package/.next/static/{bsW3fla0-BlBHVMKtAM5I → k8ZFqwz7d-bnK0ZiUVgCc}/_ssgManifest.js +0 -0
@@ -0,0 +1,124 @@
1
+ export const SETTINGS_SECTION_VALUES = [
2
+ "general",
3
+ "models",
4
+ "skills",
5
+ "agents",
6
+ "plugins",
7
+ ] as const;
8
+
9
+ export type SettingsSection = (typeof SETTINGS_SECTION_VALUES)[number];
10
+ export type SettingsDetailSection = Exclude<SettingsSection, "general">;
11
+
12
+ const STORAGE_KEY = "pi-web:settings-navigation";
13
+ const PROJECT_SECTIONS = new Set<SettingsSection>(["skills", "agents", "plugins"]);
14
+
15
+ interface StorageLike {
16
+ getItem(key: string): string | null;
17
+ setItem(key: string, value: string): void;
18
+ }
19
+
20
+ interface SettingsNavigationState {
21
+ section?: string;
22
+ selections?: Record<string, string>;
23
+ }
24
+
25
+ function getBrowserStorage(): StorageLike | null {
26
+ if (typeof window === "undefined") return null;
27
+ try {
28
+ return window.localStorage;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+
34
+ function isSettingsSection(value: unknown): value is SettingsSection {
35
+ return typeof value === "string"
36
+ && SETTINGS_SECTION_VALUES.includes(value as SettingsSection);
37
+ }
38
+
39
+ function readState(storage: StorageLike): SettingsNavigationState {
40
+ const raw = storage.getItem(STORAGE_KEY);
41
+ if (!raw) return {};
42
+ try {
43
+ const parsed: unknown = JSON.parse(raw);
44
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
45
+ const state = parsed as SettingsNavigationState;
46
+ return {
47
+ section: typeof state.section === "string" ? state.section : undefined,
48
+ selections: state.selections !== null
49
+ && typeof state.selections === "object"
50
+ && !Array.isArray(state.selections)
51
+ ? state.selections
52
+ : undefined,
53
+ };
54
+ } catch {
55
+ return {};
56
+ }
57
+ }
58
+
59
+ function selectionKey(section: SettingsDetailSection, cwd?: string | null): string | null {
60
+ if (section === "models") return section;
61
+ return cwd ? JSON.stringify([section, cwd]) : null;
62
+ }
63
+
64
+ export function getLastSettingsSection(
65
+ cwd: string | null,
66
+ storage: StorageLike | null = getBrowserStorage(),
67
+ ): SettingsSection {
68
+ if (!storage) return "general";
69
+ try {
70
+ const section = readState(storage).section;
71
+ if (!isSettingsSection(section)) return "general";
72
+ return PROJECT_SECTIONS.has(section) && !cwd ? "general" : section;
73
+ } catch {
74
+ return "general";
75
+ }
76
+ }
77
+
78
+ export function setLastSettingsSection(
79
+ section: SettingsSection,
80
+ storage: StorageLike | null = getBrowserStorage(),
81
+ ): void {
82
+ if (!storage) return;
83
+ try {
84
+ const state = readState(storage);
85
+ state.section = section;
86
+ storage.setItem(STORAGE_KEY, JSON.stringify(state));
87
+ } catch {
88
+ // Browser storage is best-effort.
89
+ }
90
+ }
91
+
92
+ export function getLastSettingsSelection(
93
+ section: SettingsDetailSection,
94
+ cwd?: string | null,
95
+ storage: StorageLike | null = getBrowserStorage(),
96
+ ): string | null {
97
+ if (!storage) return null;
98
+ const key = selectionKey(section, cwd);
99
+ if (!key) return null;
100
+ try {
101
+ const value = readState(storage).selections?.[key];
102
+ return typeof value === "string" && value.length > 0 ? value : null;
103
+ } catch {
104
+ return null;
105
+ }
106
+ }
107
+
108
+ export function setLastSettingsSelection(
109
+ section: SettingsDetailSection,
110
+ value: string,
111
+ cwd?: string | null,
112
+ storage: StorageLike | null = getBrowserStorage(),
113
+ ): void {
114
+ if (!storage || !value) return;
115
+ const key = selectionKey(section, cwd);
116
+ if (!key) return;
117
+ try {
118
+ const state = readState(storage);
119
+ state.selections = { ...state.selections, [key]: value };
120
+ storage.setItem(STORAGE_KEY, JSON.stringify(state));
121
+ } catch {
122
+ // Browser storage is best-effort.
123
+ }
124
+ }
@@ -0,0 +1,424 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { createJiti } from "jiti";
4
+
5
+ const {
6
+ createSubagentExtension,
7
+ preferPiWebSubagentExtension,
8
+ } = await createJiti(import.meta.url).import("./subagent-extension.ts");
9
+
10
+ async function loadTools(runtime, getProfiles = () => [], isEnabled = () => true) {
11
+ const tools = new Map();
12
+ const sent = [];
13
+ const extension = createSubagentExtension(runtime, getProfiles, isEnabled);
14
+ await extension.factory({
15
+ registerTool(tool) { tools.set(tool.name, tool); },
16
+ sendMessage(message, options) { sent.push({ message, options }); },
17
+ });
18
+ return { tools, sent };
19
+ }
20
+
21
+ function run(overrides = {}) {
22
+ return {
23
+ sessionId: "child-session",
24
+ sessionPath: "/tmp/child.jsonl",
25
+ parentSessionId: "parent-session",
26
+ parentToolCallId: "tool-call",
27
+ profile: "explore",
28
+ description: "Find parser",
29
+ task: "Find the parser",
30
+ runInBackground: false,
31
+ status: "running",
32
+ createdAt: "2026-01-01T00:00:00.000Z",
33
+ ...overrides,
34
+ };
35
+ }
36
+
37
+ test("integrated extension exposes the legacy-compatible tool names", async () => {
38
+ const tools = new Map();
39
+ const extension = createSubagentExtension({
40
+ async start(request) {
41
+ const running = {
42
+ sessionId: "child-session",
43
+ sessionPath: "/tmp/child.jsonl",
44
+ parentSessionId: "parent-session",
45
+ parentToolCallId: request.parentToolCallId,
46
+ profile: request.profile,
47
+ description: request.description,
48
+ task: request.task,
49
+ runInBackground: true,
50
+ status: "running",
51
+ createdAt: "2026-01-01T00:00:00.000Z",
52
+ };
53
+ return {
54
+ run: running,
55
+ completion: Promise.resolve({
56
+ ...running,
57
+ status: "completed",
58
+ completedAt: "2026-01-01T00:01:00.000Z",
59
+ result: "Done",
60
+ }),
61
+ };
62
+ },
63
+ async get() { return null; },
64
+ async steer() {},
65
+ async notifyParent() {},
66
+ }, () => []);
67
+ await extension.factory({
68
+ registerTool(tool) { tools.set(tool.name, tool); },
69
+ sendMessage() {},
70
+ });
71
+
72
+ assert.deepEqual([...tools.keys()], ["Agent", "get_subagent_result", "steer_subagent"]);
73
+ const result = await tools.get("Agent").execute(
74
+ "tool-call",
75
+ {
76
+ subagent_type: "explore",
77
+ prompt: "Find the parser",
78
+ input_files: ["docs/parser.md"],
79
+ description: "Find parser",
80
+ run_in_background: true,
81
+ },
82
+ undefined,
83
+ undefined,
84
+ { sessionManager: { getSessionId: () => "parent-session" } },
85
+ );
86
+ assert.equal(result.details.kind, "pi-web-subagent");
87
+ assert.equal(result.details.sessionId, "child-session");
88
+ });
89
+
90
+ test("integrated extension registers no tools while its feature is disabled", async () => {
91
+ let enabled = false;
92
+ const runtime = {
93
+ async start() { throw new Error("unused"); },
94
+ async get() { return null; },
95
+ async steer() {},
96
+ async notifyParent() {},
97
+ };
98
+ const extension = createSubagentExtension(runtime, () => [], () => enabled);
99
+ const disabledTools = new Map();
100
+ await extension.factory({ registerTool(tool) { disabledTools.set(tool.name, tool); } });
101
+ assert.deepEqual([...disabledTools], []);
102
+
103
+ enabled = true;
104
+ const enabledTools = new Map();
105
+ await extension.factory({ registerTool(tool) { enabledTools.set(tool.name, tool); } });
106
+ assert.deepEqual([...enabledTools.keys()], ["Agent", "get_subagent_result", "steer_subagent"]);
107
+ });
108
+
109
+ test("Agent tool description lists enabled effective profiles and refreshes when its factory reloads", async () => {
110
+ const runtime = {
111
+ async start() { throw new Error("unused"); },
112
+ async get() { return null; },
113
+ async steer() {},
114
+ async notifyParent() {},
115
+ };
116
+ let profiles = [
117
+ {
118
+ name: "explore",
119
+ displayName: "Explore",
120
+ description: "Inspect the codebase",
121
+ systemPrompt: "Explore",
122
+ tools: ["read", "grep"],
123
+ inheritContext: false,
124
+ runInBackground: false,
125
+ enabled: true,
126
+ scope: "builtin",
127
+ },
128
+ {
129
+ name: "disabled-agent",
130
+ displayName: "Disabled agent",
131
+ description: "Must stay hidden",
132
+ systemPrompt: "Disabled",
133
+ tools: [],
134
+ model: "provider/hidden",
135
+ inheritContext: false,
136
+ runInBackground: false,
137
+ enabled: false,
138
+ scope: "project",
139
+ },
140
+ ];
141
+ const extension = createSubagentExtension(runtime, () => profiles);
142
+
143
+ const firstTools = new Map();
144
+ await extension.factory({ registerTool(tool) { firstTools.set(tool.name, tool); }, sendMessage() {} });
145
+ const first = firstTools.get("Agent");
146
+ assert.match(first.description, /- explore: Inspect the codebase \(Tools: read, grep\)/);
147
+ assert.doesNotMatch(first.description, /disabled-agent|Must stay hidden/);
148
+ assert.match(first.parameters.properties.subagent_type.description, /Available types: explore/);
149
+
150
+ profiles = [{
151
+ name: "reviewer",
152
+ displayName: "Reviewer",
153
+ description: "Review a change",
154
+ systemPrompt: "Review",
155
+ tools: [],
156
+ model: "provider/review-model",
157
+ inheritContext: false,
158
+ runInBackground: false,
159
+ enabled: true,
160
+ scope: "project",
161
+ }];
162
+ const reloadedTools = new Map();
163
+ await extension.factory({ registerTool(tool) { reloadedTools.set(tool.name, tool); }, sendMessage() {} });
164
+ const reloaded = reloadedTools.get("Agent");
165
+ assert.match(reloaded.description, /- reviewer: Review a change \(Tools: none; Model: provider\/review-model\)/);
166
+ assert.doesNotMatch(reloaded.description, /explore/);
167
+ assert.match(reloaded.parameters.properties.subagent_type.description, /Available types: reviewer/);
168
+ });
169
+
170
+ test("integrated extension removes a legacy extension that owns the same tools", () => {
171
+ const host = {
172
+ path: "<inline:pi-web-subagents>",
173
+ tools: new Map([["Agent", {}], ["get_subagent_result", {}], ["steer_subagent", {}]]),
174
+ };
175
+ const legacy = {
176
+ path: "/tmp/pi-subagents/index.ts",
177
+ tools: new Map([["Agent", {}], ["get_subagent_result", {}], ["steer_subagent", {}]]),
178
+ };
179
+ const other = { path: "/tmp/other.ts", tools: new Map([["search", {}]]) };
180
+ const lookalike = {
181
+ path: "/tmp/unrelated/index.ts",
182
+ tools: new Map([["Agent", {}], ["get_subagent_result", {}], ["steer_subagent", {}], ["custom", {}]]),
183
+ };
184
+ const result = preferPiWebSubagentExtension({
185
+ extensions: [legacy, lookalike, host, other],
186
+ errors: [{ path: legacy.path, error: "duplicate" }, { path: other.path, error: "other" }],
187
+ });
188
+
189
+ assert.deepEqual(result.extensions.map((extension) => extension.path), [lookalike.path, host.path, other.path]);
190
+ assert.deepEqual(result.errors.map((error) => error.path), [other.path]);
191
+ });
192
+
193
+ test("integrated extension removes recognized legacy extensions with any reserved tool", () => {
194
+ const host = {
195
+ path: "<inline:pi-web-subagents>",
196
+ tools: new Map([["Agent", {}], ["get_subagent_result", {}], ["steer_subagent", {}]]),
197
+ };
198
+ for (const toolName of ["Agent", "get_subagent_result", "steer_subagent"]) {
199
+ const legacy = {
200
+ path: "/tmp/pi-subagents/index.ts",
201
+ tools: new Map([[toolName, {}], ["other", {}]]),
202
+ };
203
+ const result = preferPiWebSubagentExtension({
204
+ extensions: [legacy, host],
205
+ errors: [{
206
+ path: host.path,
207
+ error: `Tool "${toolName}" conflicts with ${legacy.path}`,
208
+ }],
209
+ });
210
+ assert.deepEqual(result.extensions, [host]);
211
+ assert.deepEqual(result.errors, []);
212
+ }
213
+ });
214
+
215
+ test("foreground Agent streams updates and returns the completed result", async () => {
216
+ const updates = [];
217
+ let request;
218
+ const { tools } = await loadTools({
219
+ async start(value) {
220
+ request = value;
221
+ value.onUpdate(run({ status: "running" }));
222
+ return {
223
+ run: run(),
224
+ completion: Promise.resolve(run({
225
+ status: "completed",
226
+ completedAt: "2026-01-01T00:01:00.000Z",
227
+ result: "Parser is in lib/parser.ts",
228
+ })),
229
+ };
230
+ },
231
+ async get() { return null; },
232
+ async steer() {},
233
+ });
234
+ const result = await tools.get("Agent").execute(
235
+ "tool-call",
236
+ {
237
+ subagent_type: "explore",
238
+ prompt: "Find the parser",
239
+ input_files: ["docs/parser.md"],
240
+ description: "Find parser",
241
+ },
242
+ undefined,
243
+ (update) => updates.push(update),
244
+ { sessionManager: { getSessionId: () => "parent-session" } },
245
+ );
246
+
247
+ assert.equal(request.parentToolCallId, "tool-call");
248
+ assert.equal(request.task, "Find the parser");
249
+ assert.deepEqual(request.inputFiles, ["docs/parser.md"]);
250
+ assert.equal(updates[0].details.status, "running");
251
+ assert.equal(result.content[0].text, "Parser is in lib/parser.ts");
252
+ assert.equal(result.details.status, "completed");
253
+ assert.equal(result.isError, undefined);
254
+ });
255
+
256
+ test("foreground Agent reports startup and execution failures as tool errors", async () => {
257
+ const { tools: startFailureTools } = await loadTools({
258
+ async start() { throw new Error("profile missing"); },
259
+ async get() { return null; },
260
+ async steer() {},
261
+ });
262
+ const startup = await startFailureTools.get("Agent").execute(
263
+ "tool-call",
264
+ { prompt: "task", description: "desc" },
265
+ undefined,
266
+ undefined,
267
+ { sessionManager: { getSessionId: () => "parent-session" } },
268
+ );
269
+ assert.equal(startup.isError, true);
270
+ assert.equal(startup.content[0].text, "profile missing");
271
+
272
+ const { tools: runFailureTools } = await loadTools({
273
+ async start() {
274
+ return {
275
+ run: run(),
276
+ completion: Promise.resolve(run({ status: "failed", error: "model failed" })),
277
+ };
278
+ },
279
+ async get() { return null; },
280
+ async steer() {},
281
+ });
282
+ const failure = await runFailureTools.get("Agent").execute(
283
+ "tool-call",
284
+ { prompt: "task", description: "desc" },
285
+ undefined,
286
+ undefined,
287
+ { sessionManager: { getSessionId: () => "parent-session" } },
288
+ );
289
+ assert.equal(failure.isError, true);
290
+ assert.match(failure.content[0].text, /model failed/);
291
+ });
292
+
293
+ test("Agent resume routes the prompt to the existing-session runtime", async () => {
294
+ let resumed;
295
+ const { tools } = await loadTools({
296
+ async start() { throw new Error("must use resume"); },
297
+ async resume(request) {
298
+ resumed = request;
299
+ return { run: run({ sessionId: "existing", runInBackground: false }), completion: Promise.resolve(run({ sessionId: "existing", status: "completed", result: "continued" })) };
300
+ },
301
+ async get() { return null; },
302
+ async steer() {},
303
+ });
304
+ const result = await tools.get("Agent").execute(
305
+ "tool-call",
306
+ { resume: "existing", prompt: "Continue the review", description: "Continue review" },
307
+ undefined,
308
+ undefined,
309
+ { sessionManager: { getSessionId: () => "parent-session" } },
310
+ );
311
+ assert.equal(resumed.sessionId, "existing");
312
+ assert.equal(resumed.task, "Continue the review");
313
+ assert.equal(result.content[0].text, "continued");
314
+ });
315
+
316
+ test("background Agent returns immediately and delegates one completion notification", async () => {
317
+ let finish;
318
+ const notifications = [];
319
+ const completion = new Promise((resolve) => { finish = resolve; });
320
+ const { tools, sent } = await loadTools({
321
+ async start() {
322
+ return { run: run({ runInBackground: true }), completion };
323
+ },
324
+ async get() { return null; },
325
+ async steer() {},
326
+ async notifyParent(completed) { notifications.push(completed); },
327
+ });
328
+ const result = await tools.get("Agent").execute(
329
+ "tool-call",
330
+ { prompt: "task", description: "desc", run_in_background: true },
331
+ undefined,
332
+ undefined,
333
+ { sessionManager: { getSessionId: () => "parent-session" } },
334
+ );
335
+ assert.match(result.content[0].text, /started in background/);
336
+ assert.equal(sent.length, 0);
337
+
338
+ finish(run({ runInBackground: true, status: "completed", result: "done" }));
339
+ await completion;
340
+ await Promise.resolve();
341
+ assert.equal(sent.length, 0);
342
+ assert.equal(notifications.length, 1);
343
+ assert.equal(notifications[0].result, "done");
344
+ });
345
+
346
+ test("get_subagent_result covers missing, running, completed, failed, and aborted runs", async () => {
347
+ let current = null;
348
+ const { tools } = await loadTools({
349
+ async start() { throw new Error("unused"); },
350
+ async get() { return current; },
351
+ async steer() {},
352
+ });
353
+ const tool = tools.get("get_subagent_result");
354
+
355
+ let result = await tool.execute("call", { agent_id: "missing" });
356
+ assert.equal(result.isError, true);
357
+ assert.match(result.content[0].text, /not found/);
358
+
359
+ current = run();
360
+ result = await tool.execute("call", { agent_id: "child-session" });
361
+ assert.equal(result.details.status, "running");
362
+ assert.equal(result.content[0].text, "Subagent child-session is running.");
363
+
364
+ current = run({ status: "completed", result: "done" });
365
+ result = await tool.execute("call", { agent_id: "child-session" });
366
+ assert.equal(result.content[0].text, "done");
367
+
368
+ current = run({ status: "failed", error: "boom" });
369
+ result = await tool.execute("call", { agent_id: "child-session" });
370
+ assert.match(result.content[0].text, /boom/);
371
+ assert.equal(result.isError, true);
372
+
373
+ current = run({ status: "aborted" });
374
+ result = await tool.execute("call", { agent_id: "child-session" });
375
+ assert.match(result.content[0].text, /was stopped/);
376
+
377
+ current = run({ status: "interrupted" });
378
+ result = await tool.execute("call", { agent_id: "child-session" });
379
+ assert.match(result.content[0].text, /interrupted before completion/);
380
+ });
381
+
382
+ test("get_subagent_result wait honors abort signals", async () => {
383
+ const { tools } = await loadTools({
384
+ async start() { throw new Error("unused"); },
385
+ async get() { return run(); },
386
+ async steer() {},
387
+ });
388
+ const controller = new AbortController();
389
+ controller.abort();
390
+ await assert.rejects(
391
+ tools.get("get_subagent_result").execute("call", { agent_id: "child-session", wait: true }, controller.signal),
392
+ /Result wait aborted/,
393
+ );
394
+ });
395
+
396
+ test("steer_subagent returns success and runtime failures", async () => {
397
+ const calls = [];
398
+ const { tools } = await loadTools({
399
+ async start() { throw new Error("unused"); },
400
+ async get() { return null; },
401
+ async steer(id, message) {
402
+ calls.push([id, message]);
403
+ if (message === "fail") throw new Error("not running");
404
+ },
405
+ });
406
+ const tool = tools.get("steer_subagent");
407
+ const success = await tool.execute("call", { agent_id: "child-session", message: "focus" });
408
+ assert.deepEqual(calls[0], ["child-session", "focus"]);
409
+ assert.match(success.content[0].text, /sent/);
410
+
411
+ const failure = await tool.execute("call", { agent_id: "child-session", message: "fail" });
412
+ assert.equal(failure.isError, true);
413
+ assert.equal(failure.content[0].text, "not running");
414
+ });
415
+
416
+ test("legacy preference leaves unrelated and partial-overlap extensions intact", () => {
417
+ const host = { path: "<inline:pi-web-subagents>", tools: new Map() };
418
+ const partial = { path: "/tmp/partial.ts", tools: new Map([["Agent", {}]]) };
419
+ const base = { extensions: [host, partial], errors: [] };
420
+ assert.equal(preferPiWebSubagentExtension(base), base);
421
+
422
+ const noHost = { extensions: [partial], errors: [] };
423
+ assert.equal(preferPiWebSubagentExtension(noHost), noHost);
424
+ });