@geminilight/mindos 0.6.56 → 0.6.57

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 (374) hide show
  1. package/_standalone/.mindos-build-version +1 -1
  2. package/_standalone/.next/BUILD_ID +1 -1
  3. package/_standalone/.next/app-path-routes-manifest.json +23 -21
  4. package/_standalone/.next/build-manifest.json +3 -3
  5. package/_standalone/.next/cache/.previewinfo +1 -1
  6. package/_standalone/.next/cache/.rscinfo +1 -1
  7. package/_standalone/.next/cache/config.json +3 -3
  8. package/_standalone/.next/prerender-manifest.json +3 -3
  9. package/_standalone/.next/react-loadable-manifest.json +8 -8
  10. package/_standalone/.next/routes-manifest.json +12 -0
  11. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  13. package/_standalone/.next/server/app/_global-error.html +2 -2
  14. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  22. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  26. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js +2 -6
  28. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  29. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/agents/custom/detect/route.js +1 -0
  41. package/_standalone/.next/server/app/api/agents/custom/detect/route.js.nft.json +1 -0
  42. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -0
  43. package/_standalone/.next/server/app/api/agents/custom/route.js +1 -0
  44. package/_standalone/.next/server/app/api/agents/custom/route.js.nft.json +1 -0
  45. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -0
  46. package/_standalone/.next/server/app/api/ask/route.js +3 -3
  47. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  48. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  49. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  52. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  54. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  58. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/file/import/route.js +1 -1
  61. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  62. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  63. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
  64. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  66. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  67. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  68. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  69. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  70. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  71. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  72. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  74. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  75. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  77. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
  79. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  80. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  87. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  88. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  89. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  91. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  92. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  93. package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
  94. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  96. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  97. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  99. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  108. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  109. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  111. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  114. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/changes/page.js +1 -1
  116. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  117. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  118. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  119. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  120. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  121. package/_standalone/.next/server/app/echo/page.js +1 -1
  122. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  123. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  124. package/_standalone/.next/server/app/explore/page.js +1 -1
  125. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  126. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  127. package/_standalone/.next/server/app/help/page.js +1 -1
  128. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  129. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  130. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  131. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  132. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  133. package/_standalone/.next/server/app/login/page.js +1 -1
  134. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  135. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  136. package/_standalone/.next/server/app/page.js +1 -1
  137. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  138. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  139. package/_standalone/.next/server/app/setup/page.js +1 -1
  140. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  141. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  142. package/_standalone/.next/server/app/trash/page.js +3 -3
  143. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  144. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  145. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  146. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  147. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  148. package/_standalone/.next/server/app/wiki/page.js +1 -1
  149. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
  150. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
  151. package/_standalone/.next/server/app-paths-manifest.json +23 -21
  152. package/_standalone/.next/server/chunks/2159.js +52 -0
  153. package/_standalone/.next/server/chunks/{2190.js → 3484.js} +1 -1
  154. package/_standalone/.next/server/chunks/530.js +29 -29
  155. package/_standalone/.next/server/chunks/6539.js +1 -1
  156. package/_standalone/.next/server/chunks/8388.js +3 -3
  157. package/_standalone/.next/server/chunks/953.js +2 -2
  158. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  159. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  160. package/_standalone/.next/server/pages/500.html +2 -2
  161. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  162. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  163. package/_standalone/.next/static/chunks/1053-5cb008a24930e271.js +29 -0
  164. package/_standalone/.next/static/chunks/1477.33df3cce509578c2.js +1 -0
  165. package/_standalone/.next/static/chunks/{1814.b08e9fb85dd3b13c.js → 1814.a7c127b2c73d1f70.js} +1 -1
  166. package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +1 -0
  167. package/_standalone/.next/static/chunks/{1007.c11404e50b39d165.js → 2647.e0b67d0c432ad7e7.js} +10 -10
  168. package/_standalone/.next/static/chunks/{2872.c8c8593be1ba4735.js → 2872.045858d00bd8307f.js} +2 -2
  169. package/_standalone/.next/static/chunks/362.3978790a2e636c3c.js +2 -0
  170. package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +1 -0
  171. package/_standalone/.next/static/chunks/54a60aa6.7a74f547ec1bdd5a.js +79 -0
  172. package/_standalone/.next/static/chunks/6087.4b6102dc0bcd07a7.js +1 -0
  173. package/_standalone/.next/static/chunks/6878-e2c5459e1c608f89.js +1 -0
  174. package/_standalone/.next/static/chunks/7249-8cd568ad23656622.js +11 -0
  175. package/_standalone/.next/static/chunks/8252-e5ae7ced3a41e0ed.js +1 -0
  176. package/_standalone/.next/static/chunks/{8753-ea9db680b0f70f25.js → 8658-16ff58b75ae37fbb.js} +1 -1
  177. package/_standalone/.next/static/chunks/{7322-d67d05067544864c.js → 9274-296ab35f9f09e42e.js} +1 -1
  178. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-2f4705aa66819b86.js +1 -0
  179. package/_standalone/.next/static/chunks/app/_global-error/page-2f4705aa66819b86.js +1 -0
  180. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-7bdeab5af8e4f5f2.js +1 -0
  181. package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +1 -0
  182. package/_standalone/.next/static/chunks/app/api/a2a/agents/route-2f4705aa66819b86.js +1 -0
  183. package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-2f4705aa66819b86.js +1 -0
  184. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2f4705aa66819b86.js +1 -0
  185. package/_standalone/.next/static/chunks/app/api/a2a/route-2f4705aa66819b86.js +1 -0
  186. package/_standalone/.next/static/chunks/app/api/acp/config/route-2f4705aa66819b86.js +1 -0
  187. package/_standalone/.next/static/chunks/app/api/acp/detect/route-2f4705aa66819b86.js +1 -0
  188. package/_standalone/.next/static/chunks/app/api/acp/install/route-2f4705aa66819b86.js +1 -0
  189. package/_standalone/.next/static/chunks/app/api/acp/registry/route-2f4705aa66819b86.js +1 -0
  190. package/_standalone/.next/static/chunks/app/api/acp/session/route-2f4705aa66819b86.js +1 -0
  191. package/_standalone/.next/static/chunks/app/api/agent-activity/route-2f4705aa66819b86.js +1 -0
  192. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2f4705aa66819b86.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/agents/custom/route-2f4705aa66819b86.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/ask/route-2f4705aa66819b86.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2f4705aa66819b86.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/auth/route-2f4705aa66819b86.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/backlinks/route-2f4705aa66819b86.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/bootstrap/route-2f4705aa66819b86.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/changes/route-2f4705aa66819b86.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/export/route-2f4705aa66819b86.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2f4705aa66819b86.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/file/import/route-2f4705aa66819b86.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/file/raw/route-2f4705aa66819b86.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/file/route-2f4705aa66819b86.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/files/route-2f4705aa66819b86.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/git/route-2f4705aa66819b86.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/graph/route-2f4705aa66819b86.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/health/route-2f4705aa66819b86.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/inbox/route-2f4705aa66819b86.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/init/route-2f4705aa66819b86.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2f4705aa66819b86.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/mcp/install/route-2f4705aa66819b86.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2f4705aa66819b86.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2f4705aa66819b86.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/mcp/status/route-2f4705aa66819b86.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2f4705aa66819b86.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/monitoring/route-2f4705aa66819b86.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/recent-files/route-2f4705aa66819b86.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/restart/route-2f4705aa66819b86.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/search/route-2f4705aa66819b86.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2f4705aa66819b86.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2f4705aa66819b86.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/settings/route-2f4705aa66819b86.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2f4705aa66819b86.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2f4705aa66819b86.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2f4705aa66819b86.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2f4705aa66819b86.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/setup/ls/route-2f4705aa66819b86.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/setup/route-2f4705aa66819b86.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/skills/route-2f4705aa66819b86.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/sync/route-2f4705aa66819b86.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/tree-version/route-2f4705aa66819b86.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/uninstall/route-2f4705aa66819b86.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/update/route-2f4705aa66819b86.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/update-check/route-2f4705aa66819b86.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/update-status/route-2f4705aa66819b86.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/workflows/route-2f4705aa66819b86.js +1 -0
  238. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-6710da1f581b2854.js → page-b0103509ce34444b.js} +4 -4
  239. package/_standalone/.next/static/chunks/app/echo/page-2f4705aa66819b86.js +1 -0
  240. package/_standalone/.next/static/chunks/app/{layout-d5f28933c5e14d74.js → layout-b3919384ec2eb979.js} +11 -11
  241. package/_standalone/.next/static/chunks/app/loading-2f4705aa66819b86.js +1 -0
  242. package/_standalone/.next/static/chunks/app/{page-45140253e07a135a.js → page-6436a99cda35132b.js} +1 -1
  243. package/_standalone/.next/static/chunks/app/setup/{page-9a81fa4d82c6351b.js → page-99fcfc460fa29733.js} +1 -1
  244. package/_standalone/.next/static/chunks/app/trash/page-8dc388695344fdd4.js +1 -0
  245. package/_standalone/.next/static/chunks/app/view/[...path]/loading-2f4705aa66819b86.js +1 -0
  246. package/_standalone/.next/static/chunks/app/view/[...path]/{page-62cfae628e31d411.js → page-b292b55305ecc021.js} +2 -2
  247. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2f4705aa66819b86.js +1 -0
  248. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2f4705aa66819b86.js +1 -0
  249. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2f4705aa66819b86.js +1 -0
  250. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2f4705aa66819b86.js +1 -0
  251. package/_standalone/.next/static/chunks/webpack-2c19436659aa657b.js +1 -0
  252. package/_standalone/.next/static/css/fd84c8316ead16eb.css +1 -0
  253. package/_standalone/.next/static/zOaEtgJbdRMncnCBucULp/_buildManifest.js +1 -0
  254. package/_standalone/.next/trace +64 -64
  255. package/_standalone/.next/types/routes.d.ts +3 -1
  256. package/_standalone/.next/types/validator.ts +18 -0
  257. package/_standalone/components/Editor.tsx +124 -6
  258. package/_standalone/components/MarkdownView.tsx +3 -1
  259. package/_standalone/components/WysiwygEditor.tsx +90 -0
  260. package/_standalone/components/agents/AgentsOverviewSection.tsx +100 -8
  261. package/_standalone/components/agents/CustomAgentModal.tsx +613 -0
  262. package/_standalone/components/settings/types.ts +4 -0
  263. package/_standalone/hooks/useEditorImageUpload.ts +113 -0
  264. package/_standalone/lib/image.ts +47 -0
  265. package/_standalone/tsconfig.tsbuildinfo +1 -1
  266. package/app/app/api/agents/custom/detect/route.ts +31 -0
  267. package/app/app/api/agents/custom/route.ts +150 -0
  268. package/app/app/api/file/import/route.ts +42 -0
  269. package/app/app/api/mcp/agents/route.ts +59 -7
  270. package/app/app/api/settings/list-models/route.ts +16 -2
  271. package/app/components/Editor.tsx +124 -6
  272. package/app/components/MarkdownView.tsx +3 -1
  273. package/app/components/WysiwygEditor.tsx +90 -0
  274. package/app/components/agents/AgentDetailContent.tsx +74 -1
  275. package/app/components/agents/AgentsContentPage.tsx +76 -1
  276. package/app/components/agents/AgentsOverviewSection.tsx +100 -8
  277. package/app/components/agents/CustomAgentModal.tsx +613 -0
  278. package/app/components/settings/types.ts +4 -0
  279. package/app/hooks/useEditorImageUpload.ts +113 -0
  280. package/app/lib/agent/model.ts +7 -1
  281. package/app/lib/agent/providers.ts +31 -6
  282. package/app/lib/core/organize.ts +1 -1
  283. package/app/lib/core/tree.ts +1 -1
  284. package/app/lib/custom-agents.ts +279 -0
  285. package/app/lib/fs.ts +1 -1
  286. package/app/lib/i18n/modules/panels.ts +96 -0
  287. package/app/lib/image.ts +47 -0
  288. package/app/lib/settings.ts +4 -0
  289. package/bin/commands/start.js +5 -4
  290. package/bin/commands/update.js +6 -2
  291. package/bin/lib/gateway.js +6 -2
  292. package/mcp/dist/index.cjs +1 -1
  293. package/mcp/src/index.ts +6 -1
  294. package/package.json +1 -1
  295. package/_standalone/.next/server/chunks/7543.js +0 -52
  296. package/_standalone/.next/static/3gMJ8EaZfDgHmB0NR0Q4T/_buildManifest.js +0 -1
  297. package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +0 -29
  298. package/_standalone/.next/static/chunks/1880-7abf971bcfd2389b.js +0 -11
  299. package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +0 -1
  300. package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +0 -1
  301. package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +0 -1
  302. package/_standalone/.next/static/chunks/54a60aa6.b97ba5e6900c089b.js +0 -79
  303. package/_standalone/.next/static/chunks/6087.0c32d26d0262c8e7.js +0 -1
  304. package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +0 -1
  305. package/_standalone/.next/static/chunks/8131.5e0bdb36bb91f212.js +0 -1
  306. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-e240db6d5049d336.js +0 -1
  307. package/_standalone/.next/static/chunks/app/_global-error/page-e240db6d5049d336.js +0 -1
  308. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +0 -1
  309. package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +0 -5
  310. package/_standalone/.next/static/chunks/app/api/a2a/agents/route-e240db6d5049d336.js +0 -1
  311. package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-e240db6d5049d336.js +0 -1
  312. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +0 -1
  313. package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +0 -1
  314. package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +0 -1
  315. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +0 -1
  316. package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +0 -1
  317. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +0 -1
  318. package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +0 -1
  319. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +0 -1
  320. package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +0 -1
  321. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +0 -1
  322. package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +0 -1
  323. package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +0 -1
  324. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +0 -1
  325. package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +0 -1
  326. package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +0 -1
  327. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +0 -1
  328. package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +0 -1
  329. package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +0 -1
  330. package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +0 -1
  331. package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +0 -1
  332. package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +0 -1
  333. package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +0 -1
  334. package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +0 -1
  335. package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +0 -1
  336. package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +0 -1
  337. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +0 -1
  338. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +0 -1
  339. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +0 -1
  340. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +0 -1
  341. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +0 -1
  342. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +0 -1
  343. package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +0 -1
  344. package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +0 -1
  345. package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +0 -1
  346. package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +0 -1
  347. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +0 -1
  348. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +0 -1
  349. package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +0 -1
  350. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +0 -1
  351. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +0 -1
  352. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +0 -1
  353. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +0 -1
  354. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +0 -1
  355. package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +0 -1
  356. package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +0 -1
  357. package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +0 -1
  358. package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +0 -1
  359. package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +0 -1
  360. package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +0 -1
  361. package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +0 -1
  362. package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +0 -1
  363. package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +0 -1
  364. package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +0 -1
  365. package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +0 -1
  366. package/_standalone/.next/static/chunks/app/trash/page-c7f14311f040009e.js +0 -1
  367. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +0 -1
  368. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +0 -1
  369. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +0 -1
  370. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +0 -1
  371. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +0 -1
  372. package/_standalone/.next/static/chunks/webpack-521ae5a2ddf0e396.js +0 -1
  373. package/_standalone/.next/static/css/66f8a81e4eda06d4.css +0 -1
  374. /package/_standalone/.next/static/{3gMJ8EaZfDgHmB0NR0Q4T → zOaEtgJbdRMncnCBucULp}/_ssgManifest.js +0 -0
@@ -0,0 +1,31 @@
1
+ export const dynamic = 'force-dynamic';
2
+
3
+ import { NextRequest, NextResponse } from 'next/server';
4
+ import { detectBaseDir } from '@/lib/custom-agents';
5
+
6
+ /** POST — Auto-detect config files in a baseDir. */
7
+ export async function POST(req: NextRequest) {
8
+ try {
9
+ const body = await req.json();
10
+ const { baseDir } = body as { baseDir?: string };
11
+
12
+ if (!baseDir?.trim()) {
13
+ return NextResponse.json({ error: 'baseDir is required' }, { status: 400 });
14
+ }
15
+
16
+ const dir = baseDir.trim();
17
+
18
+ // Security: restrict to home directory only
19
+ if (!dir.startsWith('~/')) {
20
+ return NextResponse.json(
21
+ { error: 'baseDir must start with ~/ (e.g. ~/.qclaw/)' },
22
+ { status: 400 },
23
+ );
24
+ }
25
+
26
+ const result = detectBaseDir(dir);
27
+ return NextResponse.json(result);
28
+ } catch (err) {
29
+ return NextResponse.json({ error: String(err) }, { status: 500 });
30
+ }
31
+ }
@@ -0,0 +1,150 @@
1
+ export const dynamic = 'force-dynamic';
2
+
3
+ import { NextRequest, NextResponse } from 'next/server';
4
+ import { MCP_AGENTS } from '@/lib/mcp-agents';
5
+ import {
6
+ loadCustomAgents,
7
+ saveCustomAgents,
8
+ inferDefaults,
9
+ slugify,
10
+ generateUniqueKey,
11
+ validateCustomAgentInput,
12
+ type CustomAgentDef,
13
+ } from '@/lib/custom-agents';
14
+
15
+ /** POST — Create a new custom agent. */
16
+ export async function POST(req: NextRequest) {
17
+ try {
18
+ const body = await req.json();
19
+ const { name, baseDir, ...overrides } = body as Partial<CustomAgentDef> & { name?: string; baseDir?: string };
20
+
21
+ if (!name?.trim() || !baseDir?.trim()) {
22
+ return NextResponse.json({ error: 'name and baseDir are required' }, { status: 400 });
23
+ }
24
+
25
+ const customs = loadCustomAgents();
26
+ const existingKeys = new Set([
27
+ ...Object.keys(MCP_AGENTS),
28
+ ...customs.map(c => c.key),
29
+ ]);
30
+
31
+ const key = overrides.key && !existingKeys.has(overrides.key)
32
+ ? overrides.key
33
+ : generateUniqueKey(name.trim(), existingKeys);
34
+
35
+ const error = validateCustomAgentInput({ name, baseDir, key }, existingKeys);
36
+ if (error) {
37
+ return NextResponse.json({ error }, { status: 400 });
38
+ }
39
+
40
+ const defaults = inferDefaults(name.trim(), baseDir.trim());
41
+ const agent: CustomAgentDef = {
42
+ ...defaults,
43
+ key,
44
+ ...(overrides.global && { global: overrides.global }),
45
+ ...(overrides.project !== undefined && { project: overrides.project }),
46
+ ...(overrides.configKey && { configKey: overrides.configKey }),
47
+ ...(overrides.format && { format: overrides.format }),
48
+ ...(overrides.preferredTransport && { preferredTransport: overrides.preferredTransport }),
49
+ ...(overrides.presenceDirs && { presenceDirs: overrides.presenceDirs }),
50
+ ...(overrides.presenceCli && { presenceCli: overrides.presenceCli }),
51
+ ...(overrides.globalNestedKey && { globalNestedKey: overrides.globalNestedKey }),
52
+ };
53
+
54
+ customs.push(agent);
55
+ saveCustomAgents(customs);
56
+
57
+ return NextResponse.json({ agent }, { status: 201 });
58
+ } catch (err) {
59
+ return NextResponse.json({ error: String(err) }, { status: 500 });
60
+ }
61
+ }
62
+
63
+ /** PUT — Update an existing custom agent. */
64
+ export async function PUT(req: NextRequest) {
65
+ try {
66
+ const body = await req.json();
67
+ const { key, ...updates } = body as Partial<CustomAgentDef> & { key: string };
68
+
69
+ if (!key) {
70
+ return NextResponse.json({ error: 'key is required' }, { status: 400 });
71
+ }
72
+
73
+ const customs = loadCustomAgents();
74
+ const idx = customs.findIndex(c => c.key === key);
75
+
76
+ if (idx === -1) {
77
+ return NextResponse.json({ error: `Custom agent "${key}" not found` }, { status: 404 });
78
+ }
79
+
80
+ const existing = customs[idx];
81
+
82
+ // Validate enum fields
83
+ if (updates.format && !['json', 'toml'].includes(updates.format)) {
84
+ return NextResponse.json({ error: 'format must be "json" or "toml"' }, { status: 400 });
85
+ }
86
+ if (updates.preferredTransport && !['stdio', 'http'].includes(updates.preferredTransport)) {
87
+ return NextResponse.json({ error: 'preferredTransport must be "stdio" or "http"' }, { status: 400 });
88
+ }
89
+
90
+ // Validate baseDir if changed
91
+ if (updates.baseDir) {
92
+ const dir = updates.baseDir.trim();
93
+ if (!dir.startsWith('~/') && !dir.startsWith('/')) {
94
+ return NextResponse.json({ error: 'baseDir must be an absolute path' }, { status: 400 });
95
+ }
96
+ }
97
+
98
+ const updated: CustomAgentDef = {
99
+ ...existing,
100
+ ...(updates.name && { name: updates.name }),
101
+ ...(updates.baseDir && { baseDir: updates.baseDir }),
102
+ ...(updates.global && { global: updates.global }),
103
+ ...(updates.project !== undefined && { project: updates.project }),
104
+ ...(updates.configKey && { configKey: updates.configKey }),
105
+ ...(updates.format && { format: updates.format }),
106
+ ...(updates.preferredTransport && { preferredTransport: updates.preferredTransport }),
107
+ ...(updates.presenceCli !== undefined && { presenceCli: updates.presenceCli || undefined }),
108
+ ...(updates.globalNestedKey !== undefined && { globalNestedKey: updates.globalNestedKey || undefined }),
109
+ };
110
+
111
+ // Update presenceDirs: explicit override takes priority, then baseDir-derived default
112
+ if (updates.presenceDirs) {
113
+ updated.presenceDirs = updates.presenceDirs;
114
+ } else if (updates.baseDir) {
115
+ updated.presenceDirs = [updates.baseDir.endsWith('/') ? updates.baseDir : updates.baseDir + '/'];
116
+ }
117
+
118
+ customs[idx] = updated;
119
+ saveCustomAgents(customs);
120
+
121
+ return NextResponse.json({ agent: updated });
122
+ } catch (err) {
123
+ return NextResponse.json({ error: String(err) }, { status: 500 });
124
+ }
125
+ }
126
+
127
+ /** DELETE — Remove a custom agent. */
128
+ export async function DELETE(req: NextRequest) {
129
+ try {
130
+ const body = await req.json();
131
+ const { key } = body as { key: string };
132
+
133
+ if (!key) {
134
+ return NextResponse.json({ error: 'key is required' }, { status: 400 });
135
+ }
136
+
137
+ const customs = loadCustomAgents();
138
+ const filtered = customs.filter(c => c.key !== key);
139
+
140
+ if (filtered.length === customs.length) {
141
+ return NextResponse.json({ error: `Custom agent "${key}" not found` }, { status: 404 });
142
+ }
143
+
144
+ saveCustomAgents(filtered);
145
+
146
+ return NextResponse.json({ removed: key });
147
+ } catch (err) {
148
+ return NextResponse.json({ error: String(err) }, { status: 500 });
149
+ }
150
+ }
@@ -15,6 +15,19 @@ import { invalidateCache } from '@/lib/fs';
15
15
  const MAX_FILES = 20;
16
16
  const MAX_CONTENT_LENGTH = 5 * 1024 * 1024;
17
17
 
18
+ /** File extensions that are binary and should be written as raw buffers, not text. */
19
+ const BINARY_EXTENSIONS = new Set([
20
+ '.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico',
21
+ '.mp3', '.wav', '.m4a', '.ogg', '.flac', '.aac',
22
+ '.mp4', '.webm', '.mov', '.mkv',
23
+ '.pdf',
24
+ ]);
25
+
26
+ function isBinaryFile(name: string): boolean {
27
+ const ext = path.extname(name).toLowerCase();
28
+ return BINARY_EXTENSIONS.has(ext);
29
+ }
30
+
18
31
  type ConflictMode = 'skip' | 'rename' | 'overwrite';
19
32
 
20
33
  interface ImportRequest {
@@ -136,6 +149,35 @@ export async function POST(req: NextRequest) {
136
149
 
137
150
  const sanitized = sanitizeFileName(entry.name);
138
151
  const encoding = entry.encoding === 'base64' ? 'base64' : 'text';
152
+
153
+ // Binary files (images, audio, video, PDF): write raw buffer, skip text conversion
154
+ if (encoding === 'base64' && isBinaryFile(sanitized)) {
155
+ const buf = Buffer.from(entry.content, 'base64');
156
+
157
+ let relPath = targetSpaceNorm
158
+ ? path.posix.join(targetSpaceNorm, sanitized)
159
+ : sanitized;
160
+
161
+ const { relPath: finalRel, resolved, skipped: skipReason } = resolveUniquePath(
162
+ mindRoot,
163
+ relPath,
164
+ conflict,
165
+ );
166
+
167
+ if (skipReason) {
168
+ skipped.push({ name: entry.name, reason: skipReason });
169
+ continue;
170
+ }
171
+
172
+ fs.mkdirSync(path.dirname(resolved), { recursive: true });
173
+ fs.writeFileSync(resolved, buf);
174
+
175
+ created.push({ original: entry.name, path: finalRel });
176
+ createdPaths.push(finalRel);
177
+ continue;
178
+ }
179
+
180
+ // Text files: decode and convert to markdown
139
181
  const raw = decodeFileContent(encoding, entry.content, sanitized);
140
182
  const convertResult = convertToMarkdown(sanitized, raw);
141
183
 
@@ -3,8 +3,10 @@ import os from 'os';
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
5
  import { NextResponse } from 'next/server';
6
+ import { execSync } from 'child_process';
6
7
  import {
7
8
  MCP_AGENTS,
9
+ expandHome,
8
10
  detectInstalled,
9
11
  detectAgentPresence,
10
12
  detectAgentRuntimeSignals,
@@ -12,6 +14,7 @@ import {
12
14
  detectAgentInstalledSkills,
13
15
  resolveSkillWorkspaceProfile,
14
16
  } from '@/lib/mcp-agents';
17
+ import { getAllAgents, loadCustomAgents } from '@/lib/custom-agents';
15
18
  import { readSettings } from '@/lib/settings';
16
19
  import { scanSkillDirs } from '@/lib/pi-integration/skills';
17
20
  import { getMindRoot } from '@/lib/fs';
@@ -59,13 +62,60 @@ function enrichMindOsAgent(agent: Record<string, unknown>) {
59
62
 
60
63
  export async function GET() {
61
64
  try {
62
- const agents = Object.entries(MCP_AGENTS).map(([key, agent]) => {
63
- const status = detectInstalled(key);
64
- const present = detectAgentPresence(key);
65
+ const allAgents = getAllAgents();
66
+ const customDefs = loadCustomAgents();
67
+ const customKeySet = new Set(customDefs.map(c => c.key));
68
+ const customByKey = Object.fromEntries(customDefs.map(c => [c.key, c]));
69
+
70
+ const agents = Object.entries(allAgents).map(([key, agent]) => {
71
+ const isCustom = customKeySet.has(key) && !(key in MCP_AGENTS);
72
+
73
+ // Built-in agents: use standard detection. Custom agents: detect using their AgentDef directly.
74
+ let present: boolean;
75
+ let status: { installed: boolean; scope?: string; transport?: string; configPath?: string; url?: string };
76
+
77
+ if (isCustom) {
78
+ present = agent.presenceDirs?.some((d: string) => fs.existsSync(expandHome(d))) ?? false;
79
+ if (agent.presenceCli) {
80
+ try {
81
+ execSync(
82
+ process.platform === 'win32' ? `where ${agent.presenceCli}` : `which ${agent.presenceCli}`,
83
+ { stdio: 'pipe' },
84
+ );
85
+ present = true;
86
+ } catch { /* not in PATH */ }
87
+ }
88
+ status = { installed: false };
89
+ const globalPath = expandHome(agent.global);
90
+ try {
91
+ if (fs.existsSync(globalPath)) {
92
+ const raw = fs.readFileSync(globalPath, 'utf-8');
93
+ const parsed = JSON.parse(raw);
94
+ const configObj = agent.globalNestedKey
95
+ ? agent.globalNestedKey.split('.').reduce((o: Record<string, unknown>, k: string) => (o?.[k] as Record<string, unknown>) ?? {}, parsed)
96
+ : parsed;
97
+ const servers = configObj?.[agent.key] ?? {};
98
+ if (servers && typeof servers === 'object' && 'mindos' in servers) {
99
+ status = { installed: true, scope: 'global', configPath: globalPath };
100
+ }
101
+ }
102
+ } catch { /* config not parseable */ }
103
+ } else {
104
+ present = detectAgentPresence(key);
105
+ status = detectInstalled(key);
106
+ }
107
+
65
108
  const skillProfile = resolveSkillWorkspaceProfile(key);
66
- const runtime = detectAgentRuntimeSignals(key);
67
- const configuredMcp = detectAgentConfiguredMcpServers(key);
68
- const installedSkills = detectAgentInstalledSkills(key);
109
+ const runtime = isCustom
110
+ ? { hiddenRootPath: '', hiddenRootPresent: false, conversationSignal: false, usageSignal: false, lastActivityAt: undefined }
111
+ : detectAgentRuntimeSignals(key);
112
+ const configuredMcp = isCustom
113
+ ? { servers: [] as string[], sources: [] as string[] }
114
+ : detectAgentConfiguredMcpServers(key);
115
+ const installedSkills = isCustom
116
+ ? { skills: [] as string[], sourcePath: '' }
117
+ : detectAgentInstalledSkills(key);
118
+
69
119
  return {
70
120
  key,
71
121
  name: agent.name,
@@ -74,7 +124,7 @@ export async function GET() {
74
124
  scope: status.scope,
75
125
  transport: status.transport,
76
126
  configPath: status.configPath,
77
- url: status.url, // Store URL for verification
127
+ url: status.url,
78
128
  hasProjectScope: !!agent.project,
79
129
  hasGlobalScope: !!agent.global,
80
130
  preferredTransport: agent.preferredTransport,
@@ -97,6 +147,8 @@ export async function GET() {
97
147
  installedSkillNames: installedSkills.skills,
98
148
  installedSkillCount: installedSkills.skills.length,
99
149
  installedSkillSourcePath: installedSkills.sourcePath,
150
+ isCustom,
151
+ customBaseDir: isCustom ? customByKey[key]?.baseDir : undefined,
100
152
  };
101
153
  });
102
154
 
@@ -1,7 +1,8 @@
1
1
  export const dynamic = 'force-dynamic';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
+ import { getModels as piGetModels } from '@mariozechner/pi-ai';
3
4
  import { effectiveAiConfig } from '@/lib/settings';
4
- import { type ProviderId, isProviderId, PROVIDER_PRESETS, getDefaultBaseUrl } from '@/lib/agent/providers';
5
+ import { type ProviderId, isProviderId, PROVIDER_PRESETS, toPiProvider, getDefaultBaseUrl } from '@/lib/agent/providers';
5
6
 
6
7
  const TIMEOUT = 10_000;
7
8
 
@@ -19,8 +20,11 @@ export async function POST(req: NextRequest) {
19
20
  }
20
21
 
21
22
  const preset = PROVIDER_PRESETS[provider as ProviderId];
23
+
24
+ // Providers without remote list-models API: return static list from pi-ai registry
22
25
  if (!preset.supportsListModels) {
23
- return NextResponse.json({ ok: false, error: 'This provider does not support listing models' });
26
+ const models = getRegistryModels(provider as ProviderId);
27
+ return NextResponse.json({ ok: true, models });
24
28
  }
25
29
 
26
30
  const cfg = effectiveAiConfig(provider as ProviderId);
@@ -52,6 +56,16 @@ export async function POST(req: NextRequest) {
52
56
  }
53
57
  }
54
58
 
59
+ /** Return model IDs from pi-ai's static registry for providers without a remote /models API. */
60
+ function getRegistryModels(provider: ProviderId): string[] {
61
+ try {
62
+ const models = piGetModels(toPiProvider(provider) as any);
63
+ return models.map((m: any) => m.id as string).filter(Boolean).sort();
64
+ } catch {
65
+ return [];
66
+ }
67
+ }
68
+
55
69
  async function fetchModels(provider: ProviderId, apiKey: string, baseUrl: string, signal: AbortSignal): Promise<string[]> {
56
70
  if (provider === 'anthropic') {
57
71
  return fetchAnthropicModels(apiKey, signal);
@@ -1,10 +1,13 @@
1
1
  'use client';
2
2
 
3
- import { useEffect, useRef, useCallback } from 'react';
3
+ import { useEffect, useRef, useCallback, useState } from 'react';
4
4
  import { EditorView, basicSetup } from 'codemirror';
5
5
  import { markdown } from '@codemirror/lang-markdown';
6
6
  import { oneDark } from '@codemirror/theme-one-dark';
7
7
  import { EditorState } from '@codemirror/state';
8
+ import { Image as ImageIcon } from 'lucide-react';
9
+ import { useEditorImageUpload } from '@/hooks/useEditorImageUpload';
10
+ import { toast } from '@/lib/toast';
8
11
 
9
12
  interface EditorProps {
10
13
  value: string;
@@ -65,6 +68,54 @@ export default function Editor({ value, onChange, language = 'markdown' }: Edito
65
68
  // Track whether update is from external value change
66
69
  const isExternalUpdate = useRef(false);
67
70
 
71
+ const { uploadToMedia, isUploading } = useEditorImageUpload();
72
+ const uploadRef = useRef(uploadToMedia);
73
+ uploadRef.current = uploadToMedia;
74
+ const [isMarkdown] = useState(language === 'markdown');
75
+
76
+ // Stable image insertion function via ref
77
+ const insertImagesRef = useRef(async (files: File[]) => {});
78
+ insertImagesRef.current = async (files: File[]) => {
79
+ const view = viewRef.current;
80
+ if (!view) return;
81
+
82
+ try {
83
+ const uploadedPaths = await uploadRef.current(files);
84
+
85
+ for (const p of uploadedPaths) {
86
+ const md = `![image](${p})\n`;
87
+ view.dispatch({
88
+ changes: {
89
+ from: view.state.selection.main.head,
90
+ insert: md,
91
+ },
92
+ });
93
+ }
94
+
95
+ toast.success('Images inserted');
96
+ } catch (err) {
97
+ toast.error('Failed to insert images');
98
+ console.error(err);
99
+ }
100
+ };
101
+
102
+ // Handle file picker (image button click)
103
+ const handlePickImages = useCallback(() => {
104
+ if (!isMarkdown) return;
105
+
106
+ const input = document.createElement('input');
107
+ input.type = 'file';
108
+ input.multiple = true;
109
+ input.accept = 'image/*';
110
+ input.onchange = (e) => {
111
+ const files = Array.from((e.target as HTMLInputElement).files ?? []);
112
+ if (files.length > 0) {
113
+ insertImagesRef.current(files);
114
+ }
115
+ };
116
+ input.click();
117
+ }, [isMarkdown]);
118
+
68
119
  useEffect(() => {
69
120
  if (!containerRef.current) return;
70
121
 
@@ -100,6 +151,52 @@ export default function Editor({ value, onChange, language = 'markdown' }: Edito
100
151
  // eslint-disable-next-line react-hooks/exhaustive-deps
101
152
  }, []);
102
153
 
154
+ // Set up paste and drag/drop handlers
155
+ useEffect(() => {
156
+ if (!isMarkdown) return;
157
+
158
+ const container = containerRef.current;
159
+ if (!container) return;
160
+
161
+ const handlePaste = (e: ClipboardEvent) => {
162
+ const items = e.clipboardData?.items;
163
+ if (!items) return;
164
+
165
+ const files: File[] = [];
166
+ for (let i = 0; i < items.length; i++) {
167
+ const item = items[i];
168
+ if (item.kind === 'file' && item.type.startsWith('image/')) {
169
+ const file = item.getAsFile();
170
+ if (file) files.push(file);
171
+ }
172
+ }
173
+
174
+ if (files.length > 0) {
175
+ e.preventDefault();
176
+ insertImagesRef.current(files);
177
+ }
178
+ };
179
+
180
+ const handleDrop = (e: DragEvent) => {
181
+ const files = Array.from(e.dataTransfer?.files ?? []).filter((f) =>
182
+ f.type.startsWith('image/'),
183
+ );
184
+ if (files.length > 0) {
185
+ e.preventDefault();
186
+ e.stopPropagation();
187
+ insertImagesRef.current(files);
188
+ }
189
+ };
190
+
191
+ container.addEventListener('paste', handlePaste as EventListener);
192
+ container.addEventListener('drop', handleDrop as EventListener);
193
+
194
+ return () => {
195
+ container.removeEventListener('paste', handlePaste as EventListener);
196
+ container.removeEventListener('drop', handleDrop as EventListener);
197
+ };
198
+ }, [isMarkdown]);
199
+
103
200
  // Sync external value changes to editor
104
201
  useEffect(() => {
105
202
  const view = viewRef.current;
@@ -115,10 +212,31 @@ export default function Editor({ value, onChange, language = 'markdown' }: Edito
115
212
  }, [value]);
116
213
 
117
214
  return (
118
- <div
119
- ref={containerRef}
120
- className="h-full w-full overflow-hidden rounded-lg border border-zinc-800"
121
- style={{ minHeight: '400px' }}
122
- />
215
+ <div className="relative h-full w-full flex flex-col">
216
+ {/* Image insert button for markdown mode */}
217
+ {isMarkdown && (
218
+ <div className="px-2 py-1.5 border-b border-zinc-800 bg-zinc-900/50 flex items-center gap-1">
219
+ <button
220
+ onClick={handlePickImages}
221
+ disabled={isUploading}
222
+ className="p-1.5 rounded hover:bg-zinc-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
223
+ title="Insert images (Ctrl+V or drag & drop)"
224
+ >
225
+ <ImageIcon size={14} />
226
+ <span>Images</span>
227
+ </button>
228
+ {isUploading && (
229
+ <span className="text-xs text-muted-foreground ml-2">Uploading...</span>
230
+ )}
231
+ </div>
232
+ )}
233
+
234
+ {/* Editor container */}
235
+ <div
236
+ ref={containerRef}
237
+ className="h-full w-full overflow-hidden rounded-lg border border-zinc-800"
238
+ style={{ minHeight: '400px' }}
239
+ />
240
+ </div>
123
241
  );
124
242
  }
@@ -9,6 +9,7 @@ import { useState, useCallback } from 'react';
9
9
  import { Copy, Check, X } from 'lucide-react';
10
10
  import { copyToClipboard } from '@/lib/clipboard';
11
11
  import { toast } from '@/lib/toast';
12
+ import { resolveImagePath } from '@/lib/image';
12
13
  import type { Components } from 'react-markdown';
13
14
 
14
15
  interface MarkdownViewProps {
@@ -118,8 +119,9 @@ const components: Components = {
118
119
  img({ src, alt, node, ...rest }) {
119
120
  void node;
120
121
  if (!src) return null;
122
+ const resolvedSrc = typeof src === 'string' ? resolveImagePath(src) : src;
121
123
  // eslint-disable-next-line @next/next/no-img-element
122
- return <img src={src} alt={alt ?? ''} {...stripNonDom(rest)} />;
124
+ return <img src={resolvedSrc} alt={alt ?? ''} {...stripNonDom(rest)} />;
123
125
  },
124
126
  };
125
127
 
@@ -7,11 +7,27 @@ import Placeholder from '@tiptap/extension-placeholder';
7
7
  import TaskList from '@tiptap/extension-task-list';
8
8
  import TaskItem from '@tiptap/extension-task-item';
9
9
  import Link from '@tiptap/extension-link';
10
+ import Image from '@tiptap/extension-image';
10
11
  import { Table } from '@tiptap/extension-table';
11
12
  import { TableRow } from '@tiptap/extension-table';
12
13
  import { TableCell } from '@tiptap/extension-table';
13
14
  import { TableHeader } from '@tiptap/extension-table';
14
15
  import { Markdown } from 'tiptap-markdown';
16
+ import { useEditorImageUpload } from '@/hooks/useEditorImageUpload';
17
+ import { resolveImagePath } from '@/lib/image';
18
+ import { toast } from '@/lib/toast';
19
+
20
+ /**
21
+ * Custom Image extension that resolves `/.media/` paths to API URLs in the DOM,
22
+ * while keeping the raw path in the markdown serialization.
23
+ */
24
+ const ResolvedImage = Image.extend({
25
+ renderHTML({ HTMLAttributes }) {
26
+ const src = HTMLAttributes.src;
27
+ const resolvedSrc = typeof src === 'string' ? resolveImagePath(src) : src;
28
+ return ['img', { ...HTMLAttributes, src: resolvedSrc }];
29
+ },
30
+ });
15
31
 
16
32
  interface WysiwygEditorProps {
17
33
  value: string;
@@ -22,6 +38,10 @@ export default function WysiwygEditor({ value, onChange }: WysiwygEditorProps) {
22
38
  const onChangeRef = useRef(onChange);
23
39
  onChangeRef.current = onChange;
24
40
 
41
+ const { uploadToMedia, isUploading } = useEditorImageUpload();
42
+ const uploadRef = useRef(uploadToMedia);
43
+ uploadRef.current = uploadToMedia;
44
+
25
45
  const editor = useEditor({
26
46
  extensions: [
27
47
  StarterKit.configure({
@@ -36,6 +56,9 @@ export default function WysiwygEditor({ value, onChange }: WysiwygEditorProps) {
36
56
  TaskList,
37
57
  TaskItem.configure({ nested: true }),
38
58
  Link.configure({ openOnClick: false, autolink: true }),
59
+ ResolvedImage.configure({
60
+ HTMLAttributes: { class: 'rounded-md max-w-full' },
61
+ }),
39
62
  Table.configure({ resizable: false }),
40
63
  TableRow,
41
64
  TableHeader,
@@ -55,6 +78,65 @@ export default function WysiwygEditor({ value, onChange }: WysiwygEditorProps) {
55
78
  immediatelyRender: false,
56
79
  });
57
80
 
81
+ // Set up drag/drop and paste handlers on editor mount
82
+ useEffect(() => {
83
+ if (!editor) return;
84
+
85
+ const editorDom = editor.view.dom;
86
+
87
+ const handleImageInsert = async (files: File[]) => {
88
+ if (!editor) return;
89
+ try {
90
+ const uploadedPaths = await uploadRef.current(files);
91
+ for (const p of uploadedPaths) {
92
+ editor.chain().focus().setImage({ src: p }).run();
93
+ }
94
+ toast.success('Images inserted');
95
+ } catch (err) {
96
+ toast.error('Failed to insert images');
97
+ console.error(err);
98
+ }
99
+ };
100
+
101
+ const handleDrop = (e: DragEvent) => {
102
+ const files = Array.from(e.dataTransfer?.files ?? []).filter((f) =>
103
+ f.type.startsWith('image/'),
104
+ );
105
+ if (files.length > 0) {
106
+ e.preventDefault();
107
+ e.stopPropagation();
108
+ handleImageInsert(files);
109
+ }
110
+ };
111
+
112
+ const handlePaste = (e: ClipboardEvent) => {
113
+ const items = e.clipboardData?.items;
114
+ if (!items) return;
115
+
116
+ const files: File[] = [];
117
+ for (let i = 0; i < items.length; i++) {
118
+ const item = items[i];
119
+ if (item.kind === 'file' && item.type.startsWith('image/')) {
120
+ const file = item.getAsFile();
121
+ if (file) files.push(file);
122
+ }
123
+ }
124
+
125
+ if (files.length > 0) {
126
+ e.preventDefault();
127
+ handleImageInsert(files);
128
+ }
129
+ };
130
+
131
+ editorDom.addEventListener('drop', handleDrop as EventListener);
132
+ editorDom.addEventListener('paste', handlePaste as EventListener);
133
+
134
+ return () => {
135
+ editorDom.removeEventListener('drop', handleDrop as EventListener);
136
+ editorDom.removeEventListener('paste', handlePaste as EventListener);
137
+ };
138
+ }, [editor]);
139
+
58
140
  // Sync external value changes (e.g. cancel → revert) without full re-mount
59
141
  const lastMd = useRef(value);
60
142
  useEffect(() => {
@@ -69,6 +151,14 @@ export default function WysiwygEditor({ value, onChange }: WysiwygEditorProps) {
69
151
 
70
152
  return (
71
153
  <div className="wysiwyg-wrapper h-full overflow-y-auto px-8 py-6">
154
+ {isUploading && (
155
+ <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
156
+ <div className="bg-card border border-border rounded-lg px-6 py-4 text-center shadow-lg">
157
+ <div className="animate-spin inline-block w-5 h-5 border-2 border-primary border-t-transparent rounded-full" />
158
+ <p className="mt-2 text-sm text-muted-foreground">Uploading images...</p>
159
+ </div>
160
+ </div>
161
+ )}
72
162
  <EditorContent editor={editor} />
73
163
  </div>
74
164
  );