@geminilight/mindos 0.6.56 → 0.6.58

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 (424) 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 +21 -19
  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 +2 -2
  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.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/detect/route.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/agents/custom/detect/route.js +1 -0
  43. package/_standalone/.next/server/app/api/agents/custom/detect/route.js.nft.json +1 -0
  44. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -0
  45. package/_standalone/.next/server/app/api/agents/custom/route.js +1 -0
  46. package/_standalone/.next/server/app/api/agents/custom/route.js.nft.json +1 -0
  47. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -0
  48. package/_standalone/.next/server/app/api/ask/route.js +5 -5
  49. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  50. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  51. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  53. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  54. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  55. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  58. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  60. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  61. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  62. package/_standalone/.next/server/app/api/file/import/route.js +1 -1
  63. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  64. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  65. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
  66. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -1
  67. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  68. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  69. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  70. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  71. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  72. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  74. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  76. package/_standalone/.next/server/app/api/inbox/route.js.nft.json +1 -1
  77. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  78. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  79. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/mcp/agents/route.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/agents/route.js.nft.json +1 -1
  82. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/mcp/install/route.js +1 -1
  84. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  86. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  87. package/_standalone/.next/server/app/api/mcp/status/route.js +1 -1
  88. package/_standalone/.next/server/app/api/mcp/status/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  91. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  93. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  96. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  97. package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
  98. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/settings/reset-token/route.js +1 -1
  100. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/settings/route.js +1 -1
  102. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  103. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  105. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  108. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  109. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/setup/route.js +1 -1
  111. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/skills/route.js +1 -1
  113. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  114. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  116. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  117. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  118. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  120. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  121. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  122. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  123. package/_standalone/.next/server/app/changes/page.js +2 -2
  124. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  125. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  126. package/_standalone/.next/server/app/echo/[segment]/page.js +1 -1
  127. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  128. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  129. package/_standalone/.next/server/app/echo/page.js +1 -1
  130. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  131. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  132. package/_standalone/.next/server/app/explore/page.js +2 -2
  133. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  134. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  135. package/_standalone/.next/server/app/help/page.js +2 -2
  136. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  137. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  138. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  139. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  140. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  141. package/_standalone/.next/server/app/login/page.js +1 -1
  142. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  143. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  144. package/_standalone/.next/server/app/page.js +1 -1
  145. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  146. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  147. package/_standalone/.next/server/app/setup/page.js +2 -2
  148. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  149. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  150. package/_standalone/.next/server/app/trash/page.js +3 -3
  151. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  152. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  153. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  154. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  155. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  156. package/_standalone/.next/server/app/wiki/page.js +1 -1
  157. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
  158. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
  159. package/_standalone/.next/server/app-paths-manifest.json +21 -19
  160. package/_standalone/.next/server/chunks/1550.js +1 -1
  161. package/_standalone/.next/server/chunks/1750.js +1 -1
  162. package/_standalone/.next/server/chunks/{2190.js → 3484.js} +1 -1
  163. package/_standalone/.next/server/chunks/530.js +30 -30
  164. package/_standalone/.next/server/chunks/6539.js +1 -1
  165. package/_standalone/.next/server/chunks/6793.js +52 -0
  166. package/_standalone/.next/server/chunks/8388.js +3 -3
  167. package/_standalone/.next/server/chunks/953.js +2 -2
  168. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  169. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  170. package/_standalone/.next/server/pages/500.html +2 -2
  171. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  172. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  173. package/_standalone/.next/static/2ksXveDzEcnCMRIElDkLq/_buildManifest.js +1 -0
  174. package/_standalone/.next/static/chunks/1053-fe009233cff06e72.js +29 -0
  175. package/_standalone/.next/static/chunks/1477.33df3cce509578c2.js +1 -0
  176. package/_standalone/.next/static/chunks/{1814.b08e9fb85dd3b13c.js → 1814.a7c127b2c73d1f70.js} +1 -1
  177. package/_standalone/.next/static/chunks/2549-e63cf57fa927a41d.js +1 -0
  178. package/_standalone/.next/static/chunks/{1007.c11404e50b39d165.js → 2647.e0b67d0c432ad7e7.js} +10 -10
  179. package/_standalone/.next/static/chunks/{2872.c8c8593be1ba4735.js → 2872.045858d00bd8307f.js} +2 -2
  180. package/_standalone/.next/static/chunks/362.3978790a2e636c3c.js +2 -0
  181. package/_standalone/.next/static/chunks/3637.38c4f28d8f698e0e.js +1 -0
  182. package/_standalone/.next/static/chunks/54a60aa6.7a74f547ec1bdd5a.js +79 -0
  183. package/_standalone/.next/static/chunks/6087.4b6102dc0bcd07a7.js +1 -0
  184. package/_standalone/.next/static/chunks/6878-e2c5459e1c608f89.js +1 -0
  185. package/_standalone/.next/static/chunks/7249-fa98ca10e9a10f39.js +11 -0
  186. package/_standalone/.next/static/chunks/8252-e5ae7ced3a41e0ed.js +1 -0
  187. package/_standalone/.next/static/chunks/{8753-ea9db680b0f70f25.js → 8658-16ff58b75ae37fbb.js} +1 -1
  188. package/_standalone/.next/static/chunks/{7322-d67d05067544864c.js → 9274-296ab35f9f09e42e.js} +1 -1
  189. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-2f4705aa66819b86.js +1 -0
  190. package/_standalone/.next/static/chunks/app/_global-error/page-2f4705aa66819b86.js +1 -0
  191. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-7bdeab5af8e4f5f2.js +1 -0
  192. package/_standalone/.next/static/chunks/app/agents/page-5d1446665ddb3801.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/a2a/agents/route-2f4705aa66819b86.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-2f4705aa66819b86.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-2f4705aa66819b86.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/a2a/route-2f4705aa66819b86.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/acp/config/route-2f4705aa66819b86.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/acp/detect/route-2f4705aa66819b86.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/acp/install/route-2f4705aa66819b86.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/acp/registry/route-2f4705aa66819b86.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/acp/session/route-2f4705aa66819b86.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/agent-activity/route-2f4705aa66819b86.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/agents/custom/detect/route-2f4705aa66819b86.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/agents/custom/route-2f4705aa66819b86.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/ask/route-2f4705aa66819b86.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-2f4705aa66819b86.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/auth/route-2f4705aa66819b86.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/backlinks/route-2f4705aa66819b86.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/bootstrap/route-2f4705aa66819b86.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/changes/route-2f4705aa66819b86.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/export/route-2f4705aa66819b86.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-2f4705aa66819b86.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/file/import/route-2f4705aa66819b86.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/file/raw/route-2f4705aa66819b86.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/file/route-2f4705aa66819b86.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/files/route-2f4705aa66819b86.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/git/route-2f4705aa66819b86.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/graph/route-2f4705aa66819b86.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/health/route-2f4705aa66819b86.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/inbox/route-2f4705aa66819b86.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/init/route-2f4705aa66819b86.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-2f4705aa66819b86.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/mcp/install/route-2f4705aa66819b86.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-2f4705aa66819b86.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-2f4705aa66819b86.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/mcp/status/route-2f4705aa66819b86.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-2f4705aa66819b86.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/monitoring/route-2f4705aa66819b86.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/recent-files/route-2f4705aa66819b86.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/restart/route-2f4705aa66819b86.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/search/route-2f4705aa66819b86.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-2f4705aa66819b86.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-2f4705aa66819b86.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/settings/route-2f4705aa66819b86.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-2f4705aa66819b86.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-2f4705aa66819b86.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-2f4705aa66819b86.js +1 -0
  238. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-2f4705aa66819b86.js +1 -0
  239. package/_standalone/.next/static/chunks/app/api/setup/ls/route-2f4705aa66819b86.js +1 -0
  240. package/_standalone/.next/static/chunks/app/api/setup/route-2f4705aa66819b86.js +1 -0
  241. package/_standalone/.next/static/chunks/app/api/skills/route-2f4705aa66819b86.js +1 -0
  242. package/_standalone/.next/static/chunks/app/api/sync/route-2f4705aa66819b86.js +1 -0
  243. package/_standalone/.next/static/chunks/app/api/tree-version/route-2f4705aa66819b86.js +1 -0
  244. package/_standalone/.next/static/chunks/app/api/uninstall/route-2f4705aa66819b86.js +1 -0
  245. package/_standalone/.next/static/chunks/app/api/update/route-2f4705aa66819b86.js +1 -0
  246. package/_standalone/.next/static/chunks/app/api/update-check/route-2f4705aa66819b86.js +1 -0
  247. package/_standalone/.next/static/chunks/app/api/update-status/route-2f4705aa66819b86.js +1 -0
  248. package/_standalone/.next/static/chunks/app/api/workflows/route-2f4705aa66819b86.js +1 -0
  249. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-6710da1f581b2854.js → page-b0103509ce34444b.js} +4 -4
  250. package/_standalone/.next/static/chunks/app/echo/page-2f4705aa66819b86.js +1 -0
  251. package/_standalone/.next/static/chunks/app/{layout-d5f28933c5e14d74.js → layout-7e02ddf4144b01f1.js} +11 -11
  252. package/_standalone/.next/static/chunks/app/loading-2f4705aa66819b86.js +1 -0
  253. package/_standalone/.next/static/chunks/app/page-6a6a12bd6d6812d0.js +7 -0
  254. package/_standalone/.next/static/chunks/app/setup/{page-9a81fa4d82c6351b.js → page-99fcfc460fa29733.js} +1 -1
  255. package/_standalone/.next/static/chunks/app/trash/page-54cbd5c98d9de69b.js +1 -0
  256. package/_standalone/.next/static/chunks/app/view/[...path]/loading-2f4705aa66819b86.js +1 -0
  257. package/_standalone/.next/static/chunks/app/view/[...path]/page-ca7bdcbf27f88a46.js +12 -0
  258. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-2f4705aa66819b86.js +1 -0
  259. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-2f4705aa66819b86.js +1 -0
  260. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-2f4705aa66819b86.js +1 -0
  261. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-2f4705aa66819b86.js +1 -0
  262. package/_standalone/.next/static/chunks/webpack-2c19436659aa657b.js +1 -0
  263. package/_standalone/.next/static/css/fd84c8316ead16eb.css +1 -0
  264. package/_standalone/.next/trace +64 -64
  265. package/_standalone/.next/types/routes.d.ts +3 -1
  266. package/_standalone/.next/types/validator.ts +18 -0
  267. package/_standalone/__tests__/api/mcp-install.test.ts +3 -2
  268. package/_standalone/__tests__/ask/non-streaming-api.test.ts +281 -0
  269. package/_standalone/__tests__/core/skill-install-logic.test.ts +1 -0
  270. package/_standalone/components/Editor.tsx +124 -6
  271. package/_standalone/components/MarkdownView.tsx +3 -1
  272. package/_standalone/components/WysiwygEditor.tsx +90 -0
  273. package/_standalone/components/agents/AgentsOverviewSection.tsx +100 -8
  274. package/_standalone/components/agents/CustomAgentModal.tsx +637 -0
  275. package/_standalone/components/settings/types.ts +4 -0
  276. package/_standalone/data/skills/mindos/SKILL.md +14 -9
  277. package/_standalone/data/skills/mindos-zh/SKILL.md +13 -4
  278. package/_standalone/hooks/useEditorImageUpload.ts +113 -0
  279. package/_standalone/lib/image.ts +47 -0
  280. package/_standalone/tsconfig.tsbuildinfo +1 -1
  281. package/app/app/api/agents/custom/detect/route.ts +31 -0
  282. package/app/app/api/agents/custom/route.ts +158 -0
  283. package/app/app/api/ask/route.ts +171 -10
  284. package/app/app/api/file/import/route.ts +42 -0
  285. package/app/app/api/mcp/agents/route.ts +62 -8
  286. package/app/app/api/settings/list-models/route.ts +16 -2
  287. package/app/app/api/settings/route.ts +9 -0
  288. package/app/app/api/settings/test-key/route.ts +13 -1
  289. package/app/components/Editor.tsx +124 -6
  290. package/app/components/MarkdownView.tsx +3 -1
  291. package/app/components/WysiwygEditor.tsx +90 -0
  292. package/app/components/agents/AgentDetailContent.tsx +74 -1
  293. package/app/components/agents/AgentsContentPage.tsx +76 -1
  294. package/app/components/agents/AgentsOverviewSection.tsx +100 -8
  295. package/app/components/agents/CustomAgentModal.tsx +637 -0
  296. package/app/components/settings/types.ts +4 -0
  297. package/app/data/skills/mindos/SKILL.md +14 -9
  298. package/app/data/skills/mindos-zh/SKILL.md +13 -4
  299. package/app/hooks/useEditorImageUpload.ts +113 -0
  300. package/app/lib/agent/model.ts +7 -1
  301. package/app/lib/agent/providers.ts +31 -6
  302. package/app/lib/core/organize.ts +1 -1
  303. package/app/lib/core/tree.ts +1 -1
  304. package/app/lib/custom-agents.ts +322 -0
  305. package/app/lib/fs.ts +1 -1
  306. package/app/lib/i18n/modules/panels.ts +104 -0
  307. package/app/lib/image.ts +47 -0
  308. package/app/lib/mcp-agents.ts +10 -0
  309. package/app/lib/settings.ts +4 -0
  310. package/bin/commands/start.js +5 -4
  311. package/bin/commands/update.js +6 -2
  312. package/bin/lib/gateway.js +6 -2
  313. package/bin/lib/mcp-agents.js +10 -0
  314. package/mcp/dist/index.cjs +1 -1
  315. package/mcp/src/index.ts +6 -1
  316. package/package.json +1 -1
  317. package/skills/mindos/SKILL.md +10 -4
  318. package/skills/mindos-max/SKILL.md +191 -0
  319. package/skills/mindos-max-workspace/evals/evals.json +23 -0
  320. package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/eval_metadata.json +11 -0
  321. package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/old_skill/grading.json +28 -0
  322. package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/old_skill/outputs/transcript.md +203 -0
  323. package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/with_skill/grading.json +28 -0
  324. package/skills/mindos-max-workspace/iteration-1/capture-debugging-experience-en/with_skill/outputs/transcript.md +271 -0
  325. package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/eval_metadata.json +11 -0
  326. package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/old_skill/grading.json +28 -0
  327. package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/old_skill/outputs/transcript.md +121 -0
  328. package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/with_skill/grading.json +28 -0
  329. package/skills/mindos-max-workspace/iteration-1/save-meeting-decision-zh/with_skill/outputs/transcript.md +168 -0
  330. package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/eval_metadata.json +11 -0
  331. package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/old_skill/grading.json +28 -0
  332. package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/old_skill/outputs/transcript.md +143 -0
  333. package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/with_skill/grading.json +28 -0
  334. package/skills/mindos-max-workspace/iteration-1/search-past-decision-zh/with_skill/outputs/transcript.md +233 -0
  335. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/SKILL.md +165 -0
  336. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/README.md +12 -0
  337. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/post-task-hooks.md +27 -0
  338. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/preference-capture.md +41 -0
  339. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/sop-template.md +74 -0
  340. package/skills/mindos-max-workspace/skill-snapshot/mindos-original/references/write-supplement.md +119 -0
  341. package/skills/mindos-max-zh/SKILL.md +192 -0
  342. package/skills/mindos-zh/SKILL.md +11 -3
  343. package/_standalone/.next/server/chunks/7543.js +0 -52
  344. package/_standalone/.next/static/3gMJ8EaZfDgHmB0NR0Q4T/_buildManifest.js +0 -1
  345. package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +0 -29
  346. package/_standalone/.next/static/chunks/1880-7abf971bcfd2389b.js +0 -11
  347. package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +0 -1
  348. package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +0 -1
  349. package/_standalone/.next/static/chunks/3637.0541ac2d0ea7de1f.js +0 -1
  350. package/_standalone/.next/static/chunks/54a60aa6.b97ba5e6900c089b.js +0 -79
  351. package/_standalone/.next/static/chunks/6087.0c32d26d0262c8e7.js +0 -1
  352. package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +0 -1
  353. package/_standalone/.next/static/chunks/8131.5e0bdb36bb91f212.js +0 -1
  354. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/route-e240db6d5049d336.js +0 -1
  355. package/_standalone/.next/static/chunks/app/_global-error/page-e240db6d5049d336.js +0 -1
  356. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +0 -1
  357. package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +0 -5
  358. package/_standalone/.next/static/chunks/app/api/a2a/agents/route-e240db6d5049d336.js +0 -1
  359. package/_standalone/.next/static/chunks/app/api/a2a/delegations/route-e240db6d5049d336.js +0 -1
  360. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +0 -1
  361. package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +0 -1
  362. package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +0 -1
  363. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +0 -1
  364. package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +0 -1
  365. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +0 -1
  366. package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +0 -1
  367. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +0 -1
  368. package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +0 -1
  369. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +0 -1
  370. package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +0 -1
  371. package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +0 -1
  372. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +0 -1
  373. package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +0 -1
  374. package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +0 -1
  375. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +0 -1
  376. package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +0 -1
  377. package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +0 -1
  378. package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +0 -1
  379. package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +0 -1
  380. package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +0 -1
  381. package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +0 -1
  382. package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +0 -1
  383. package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +0 -1
  384. package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +0 -1
  385. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +0 -1
  386. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +0 -1
  387. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +0 -1
  388. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +0 -1
  389. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +0 -1
  390. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +0 -1
  391. package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +0 -1
  392. package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +0 -1
  393. package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +0 -1
  394. package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +0 -1
  395. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +0 -1
  396. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +0 -1
  397. package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +0 -1
  398. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +0 -1
  399. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +0 -1
  400. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +0 -1
  401. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +0 -1
  402. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +0 -1
  403. package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +0 -1
  404. package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +0 -1
  405. package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +0 -1
  406. package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +0 -1
  407. package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +0 -1
  408. package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +0 -1
  409. package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +0 -1
  410. package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +0 -1
  411. package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +0 -1
  412. package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +0 -1
  413. package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +0 -1
  414. package/_standalone/.next/static/chunks/app/page-45140253e07a135a.js +0 -7
  415. package/_standalone/.next/static/chunks/app/trash/page-c7f14311f040009e.js +0 -1
  416. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +0 -1
  417. package/_standalone/.next/static/chunks/app/view/[...path]/page-62cfae628e31d411.js +0 -12
  418. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +0 -1
  419. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +0 -1
  420. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +0 -1
  421. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +0 -1
  422. package/_standalone/.next/static/chunks/webpack-521ae5a2ddf0e396.js +0 -1
  423. package/_standalone/.next/static/css/66f8a81e4eda06d4.css +0 -1
  424. /package/_standalone/.next/static/{3gMJ8EaZfDgHmB0NR0Q4T → 2ksXveDzEcnCMRIElDkLq}/_ssgManifest.js +0 -0
@@ -2,7 +2,7 @@
2
2
  // Do not edit this file manually
3
3
 
4
4
  type AppRoutes = "/" | "/agents" | "/agents/[agentKey]" | "/changes" | "/echo" | "/echo/[segment]" | "/explore" | "/help" | "/inbox/history" | "/login" | "/setup" | "/trash" | "/view/[...path]" | "/wiki"
5
- type AppRouteHandlerRoutes = "/.well-known/agent-card.json" | "/api/a2a" | "/api/a2a/agents" | "/api/a2a/delegations" | "/api/a2a/discover" | "/api/acp/config" | "/api/acp/detect" | "/api/acp/install" | "/api/acp/registry" | "/api/acp/session" | "/api/agent-activity" | "/api/ask" | "/api/ask-sessions" | "/api/auth" | "/api/backlinks" | "/api/bootstrap" | "/api/changes" | "/api/export" | "/api/extract-pdf" | "/api/file" | "/api/file/import" | "/api/file/raw" | "/api/files" | "/api/git" | "/api/graph" | "/api/health" | "/api/inbox" | "/api/init" | "/api/mcp/agents" | "/api/mcp/install" | "/api/mcp/install-skill" | "/api/mcp/restart" | "/api/mcp/status" | "/api/mcp/uninstall" | "/api/monitoring" | "/api/recent-files" | "/api/restart" | "/api/search" | "/api/settings" | "/api/settings/list-models" | "/api/settings/reset-token" | "/api/settings/test-key" | "/api/setup" | "/api/setup/check-path" | "/api/setup/check-port" | "/api/setup/generate-token" | "/api/setup/ls" | "/api/skills" | "/api/sync" | "/api/tree-version" | "/api/uninstall" | "/api/update" | "/api/update-check" | "/api/update-status" | "/api/workflows"
5
+ type AppRouteHandlerRoutes = "/.well-known/agent-card.json" | "/api/a2a" | "/api/a2a/agents" | "/api/a2a/delegations" | "/api/a2a/discover" | "/api/acp/config" | "/api/acp/detect" | "/api/acp/install" | "/api/acp/registry" | "/api/acp/session" | "/api/agent-activity" | "/api/agents/custom" | "/api/agents/custom/detect" | "/api/ask" | "/api/ask-sessions" | "/api/auth" | "/api/backlinks" | "/api/bootstrap" | "/api/changes" | "/api/export" | "/api/extract-pdf" | "/api/file" | "/api/file/import" | "/api/file/raw" | "/api/files" | "/api/git" | "/api/graph" | "/api/health" | "/api/inbox" | "/api/init" | "/api/mcp/agents" | "/api/mcp/install" | "/api/mcp/install-skill" | "/api/mcp/restart" | "/api/mcp/status" | "/api/mcp/uninstall" | "/api/monitoring" | "/api/recent-files" | "/api/restart" | "/api/search" | "/api/settings" | "/api/settings/list-models" | "/api/settings/reset-token" | "/api/settings/test-key" | "/api/setup" | "/api/setup/check-path" | "/api/setup/check-port" | "/api/setup/generate-token" | "/api/setup/ls" | "/api/skills" | "/api/sync" | "/api/tree-version" | "/api/uninstall" | "/api/update" | "/api/update-check" | "/api/update-status" | "/api/workflows"
6
6
  type PageRoutes = never
7
7
  type LayoutRoutes = "/"
8
8
  type RedirectRoutes = never
@@ -25,6 +25,8 @@ interface ParamMap {
25
25
  "/api/acp/registry": {}
26
26
  "/api/acp/session": {}
27
27
  "/api/agent-activity": {}
28
+ "/api/agents/custom": {}
29
+ "/api/agents/custom/detect": {}
28
30
  "/api/ask": {}
29
31
  "/api/ask-sessions": {}
30
32
  "/api/auth": {}
@@ -272,6 +272,24 @@ type RouteHandlerConfig<Route extends AppRouteHandlerRoutes = AppRouteHandlerRou
272
272
  type __Unused = __Check
273
273
  }
274
274
 
275
+ // Validate ../../app/api/agents/custom/detect/route.ts
276
+ {
277
+ type __IsExpected<Specific extends RouteHandlerConfig<"/api/agents/custom/detect">> = Specific
278
+ const handler = {} as typeof import("../../app/api/agents/custom/detect/route.js")
279
+ type __Check = __IsExpected<typeof handler>
280
+ // @ts-ignore
281
+ type __Unused = __Check
282
+ }
283
+
284
+ // Validate ../../app/api/agents/custom/route.ts
285
+ {
286
+ type __IsExpected<Specific extends RouteHandlerConfig<"/api/agents/custom">> = Specific
287
+ const handler = {} as typeof import("../../app/api/agents/custom/route.js")
288
+ type __Check = __IsExpected<typeof handler>
289
+ // @ts-ignore
290
+ type __Unused = __Check
291
+ }
292
+
275
293
  // Validate ../../app/api/ask-sessions/route.ts
276
294
  {
277
295
  type __IsExpected<Specific extends RouteHandlerConfig<"/api/ask-sessions">> = Specific
@@ -254,11 +254,11 @@ describe('POST /api/mcp/install', () => {
254
254
  });
255
255
 
256
256
  describe('GET /api/mcp/agents', () => {
257
- it('returns all 20 agents (1 builtin + 19 registry)', async () => {
257
+ it('returns all 21 agents (1 builtin + 20 registry)', async () => {
258
258
  const { GET } = await importAgentsRoute();
259
259
  const res = await GET();
260
260
  const body = await res.json();
261
- expect(body.agents).toHaveLength(20);
261
+ expect(body.agents).toHaveLength(21);
262
262
  const keys = body.agents.map((a: { key: string }) => a.key);
263
263
  expect(keys).toContain('mindos');
264
264
  expect(keys).toContain('claude-code');
@@ -275,6 +275,7 @@ describe('GET /api/mcp/agents', () => {
275
275
  expect(keys).toContain('roo');
276
276
  expect(keys).toContain('github-copilot');
277
277
  expect(keys).toContain('codex');
278
+ expect(keys).toContain('antigravity');
278
279
  });
279
280
 
280
281
  it('detects installed agent from config file', async () => {
@@ -0,0 +1,281 @@
1
+ import { describe, it, expect } from 'vitest';
2
+
3
+ /**
4
+ * Tests for non-streaming API fallback.
5
+ * Verifies:
6
+ * 1. pi-ai → OpenAI message format conversion
7
+ * 2. SSE response reassembly (for proxies that ignore stream:false)
8
+ */
9
+
10
+ // ─────────────────────────────────────────────────
11
+ // Replicate helper functions from route.ts for unit testing
12
+ // ─────────────────────────────────────────────────
13
+
14
+ function piMessagesToOpenAI(piMessages: any[]): any[] {
15
+ return piMessages.map(msg => {
16
+ const role = msg.role;
17
+ if (role === 'system') return null;
18
+ if (role === 'user') {
19
+ return { role: 'user', content: typeof msg.content === 'string' ? msg.content : msg.content };
20
+ }
21
+ if (role === 'assistant') {
22
+ const content = msg.content;
23
+ let textContent = '';
24
+ const toolCalls: any[] = [];
25
+ if (Array.isArray(content)) {
26
+ for (const part of content) {
27
+ if (part.type === 'text' && part.text) {
28
+ textContent += part.text;
29
+ } else if (part.type === 'toolCall') {
30
+ toolCalls.push({
31
+ id: part.id ?? `call_fallback`,
32
+ type: 'function',
33
+ function: { name: part.name ?? 'unknown', arguments: JSON.stringify(part.arguments ?? {}) },
34
+ });
35
+ }
36
+ }
37
+ }
38
+ const result: any = { role: 'assistant' };
39
+ result.content = textContent || '';
40
+ if (toolCalls.length > 0) result.tool_calls = toolCalls;
41
+ return result;
42
+ }
43
+ if (role === 'toolResult') {
44
+ const contentText = Array.isArray(msg.content)
45
+ ? msg.content.filter((c: any) => c.type === 'text').map((c: any) => c.text ?? '').join('\n')
46
+ : String(msg.content ?? '');
47
+ return { role: 'tool', tool_call_id: msg.toolCallId ?? 'unknown', content: contentText };
48
+ }
49
+ return null;
50
+ }).filter(Boolean);
51
+ }
52
+
53
+ function reassembleSSE(sseText: string): any {
54
+ const lines = sseText.split('\n');
55
+ let content = '';
56
+ let role = 'assistant';
57
+ let finishReason = 'stop';
58
+ const toolCalls: Map<number, { id: string; type: string; function: { name: string; arguments: string } }> = new Map();
59
+
60
+ for (const line of lines) {
61
+ const trimmed = line.trim();
62
+ if (!trimmed.startsWith('data:')) continue;
63
+ const payload = trimmed.slice(5).trim();
64
+ if (payload === '[DONE]') break;
65
+ let chunk: any;
66
+ try { chunk = JSON.parse(payload); } catch { continue; }
67
+ const delta = chunk?.choices?.[0]?.delta;
68
+ if (!delta) continue;
69
+ if (delta.role) role = delta.role;
70
+ if (delta.content) content += delta.content;
71
+ if (chunk.choices[0].finish_reason) finishReason = chunk.choices[0].finish_reason;
72
+ if (delta.tool_calls) {
73
+ for (const tc of delta.tool_calls) {
74
+ const idx = tc.index ?? 0;
75
+ const existing = toolCalls.get(idx);
76
+ if (!existing) {
77
+ toolCalls.set(idx, {
78
+ id: tc.id ?? '',
79
+ type: tc.type ?? 'function',
80
+ function: { name: tc.function?.name ?? '', arguments: tc.function?.arguments ?? '' },
81
+ });
82
+ } else {
83
+ if (tc.id) existing.id = tc.id;
84
+ if (tc.function?.name) existing.function.name += tc.function.name;
85
+ if (tc.function?.arguments) existing.function.arguments += tc.function.arguments;
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ const message: any = { role, content: content || null };
92
+ if (toolCalls.size > 0) {
93
+ message.tool_calls = Array.from(toolCalls.values());
94
+ }
95
+ return { choices: [{ message, finish_reason: finishReason }] };
96
+ }
97
+
98
+ // ─────────────────────────────────────────────────
99
+ // piMessagesToOpenAI tests
100
+ // ─────────────────────────────────────────────────
101
+
102
+ describe('piMessagesToOpenAI', () => {
103
+ it('converts plain user message', () => {
104
+ expect(piMessagesToOpenAI([{ role: 'user', content: 'Hello!' }]))
105
+ .toEqual([{ role: 'user', content: 'Hello!' }]);
106
+ });
107
+
108
+ it('converts assistant text-only message', () => {
109
+ const result = piMessagesToOpenAI([{
110
+ role: 'assistant',
111
+ content: [{ type: 'text', text: 'Response' }],
112
+ }]);
113
+ expect(result).toEqual([{ role: 'assistant', content: 'Response' }]);
114
+ });
115
+
116
+ it('converts assistant message with tool calls', () => {
117
+ const result = piMessagesToOpenAI([{
118
+ role: 'assistant',
119
+ content: [
120
+ { type: 'text', text: 'Calling tool' },
121
+ { type: 'toolCall', id: 'call_1', name: 'read_file', arguments: { path: '/tmp' } },
122
+ ],
123
+ }]);
124
+ expect(result[0].content).toBe('Calling tool');
125
+ expect(result[0].tool_calls[0]).toMatchObject({
126
+ id: 'call_1', type: 'function',
127
+ function: { name: 'read_file', arguments: '{"path":"/tmp"}' },
128
+ });
129
+ });
130
+
131
+ it('converts tool result message', () => {
132
+ expect(piMessagesToOpenAI([{
133
+ role: 'toolResult', toolCallId: 'call_1',
134
+ content: [{ type: 'text', text: 'result data' }],
135
+ }])).toEqual([{ role: 'tool', tool_call_id: 'call_1', content: 'result data' }]);
136
+ });
137
+
138
+ it('skips system messages', () => {
139
+ const result = piMessagesToOpenAI([
140
+ { role: 'system', content: 'sys' },
141
+ { role: 'user', content: 'hi' },
142
+ ]);
143
+ expect(result).toHaveLength(1);
144
+ expect(result[0].role).toBe('user');
145
+ });
146
+
147
+ it('handles empty assistant content', () => {
148
+ const result = piMessagesToOpenAI([{ role: 'assistant', content: [] }]);
149
+ expect(result[0]).toEqual({ role: 'assistant', content: '' });
150
+ });
151
+
152
+ it('handles complex conversation history', () => {
153
+ const result = piMessagesToOpenAI([
154
+ { role: 'user', content: 'list files' },
155
+ { role: 'assistant', content: [
156
+ { type: 'text', text: 'checking' },
157
+ { type: 'toolCall', id: 'c1', name: 'ls', arguments: {} },
158
+ ]},
159
+ { role: 'toolResult', toolCallId: 'c1', content: [{ type: 'text', text: 'a.txt' }] },
160
+ { role: 'assistant', content: [{ type: 'text', text: 'Found a.txt' }] },
161
+ ]);
162
+ expect(result).toHaveLength(4);
163
+ expect(result[0].role).toBe('user');
164
+ expect(result[1].role).toBe('assistant');
165
+ expect(result[1].tool_calls).toHaveLength(1);
166
+ expect(result[2].role).toBe('tool');
167
+ expect(result[3]).toMatchObject({ role: 'assistant', content: 'Found a.txt' });
168
+ });
169
+ });
170
+
171
+ // ─────────────────────────────────────────────────
172
+ // reassembleSSE tests
173
+ // ─────────────────────────────────────────────────
174
+
175
+ describe('reassembleSSE', () => {
176
+ it('reassembles simple text SSE response', () => {
177
+ const sse = [
178
+ 'data: {"choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}',
179
+ 'data: {"choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}',
180
+ 'data: {"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}',
181
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}]}',
182
+ 'data: [DONE]',
183
+ ].join('\n');
184
+
185
+ const result = reassembleSSE(sse);
186
+ expect(result.choices[0].message.content).toBe('Hello!');
187
+ expect(result.choices[0].message.role).toBe('assistant');
188
+ expect(result.choices[0].finish_reason).toBe('stop');
189
+ });
190
+
191
+ it('handles ikuncode-style empty response (proxy returns SSE with no content)', () => {
192
+ // This is the actual response from ikuncode when stream:false is sent
193
+ const sse = [
194
+ 'data: {"id":"","object":"chat.completion.chunk","created":0,"model":"gpt-5.4","choices":[],"usage":{"prompt_tokens":28,"completion_tokens":0,"total_tokens":28}}',
195
+ '',
196
+ 'data: [DONE]',
197
+ ].join('\n');
198
+
199
+ const result = reassembleSSE(sse);
200
+ // Should return empty content (no choices with delta)
201
+ expect(result.choices[0].message.content).toBeNull();
202
+ expect(result.choices[0].message.role).toBe('assistant');
203
+ });
204
+
205
+ it('reassembles SSE with tool calls', () => {
206
+ const sse = [
207
+ 'data: {"choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}',
208
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_abc","type":"function","function":{"name":"read_","arguments":""}}]},"finish_reason":null}]}',
209
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"name":"file","arguments":"{\\"pa"}}]},"finish_reason":null}]}',
210
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"th\\":\\"/tmp\\"}"}}]},"finish_reason":null}]}',
211
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"tool_calls"}]}',
212
+ 'data: [DONE]',
213
+ ].join('\n');
214
+
215
+ const result = reassembleSSE(sse);
216
+ const msg = result.choices[0].message;
217
+ expect(msg.tool_calls).toHaveLength(1);
218
+ expect(msg.tool_calls[0].id).toBe('call_abc');
219
+ expect(msg.tool_calls[0].function.name).toBe('read_file');
220
+ expect(msg.tool_calls[0].function.arguments).toBe('{"path":"/tmp"}');
221
+ expect(result.choices[0].finish_reason).toBe('tool_calls');
222
+ });
223
+
224
+ it('handles SSE with multiple tool calls', () => {
225
+ const sse = [
226
+ 'data: {"choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}',
227
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"c1","type":"function","function":{"name":"tool_a","arguments":"{}"}}]},"finish_reason":null}]}',
228
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"c2","type":"function","function":{"name":"tool_b","arguments":"{}"}}]},"finish_reason":null}]}',
229
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"tool_calls"}]}',
230
+ 'data: [DONE]',
231
+ ].join('\n');
232
+
233
+ const result = reassembleSSE(sse);
234
+ expect(result.choices[0].message.tool_calls).toHaveLength(2);
235
+ expect(result.choices[0].message.tool_calls[0].id).toBe('c1');
236
+ expect(result.choices[0].message.tool_calls[1].id).toBe('c2');
237
+ });
238
+
239
+ it('handles SSE with text + tool calls mixed', () => {
240
+ const sse = [
241
+ 'data: {"choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}',
242
+ 'data: {"choices":[{"index":0,"delta":{"content":"Let me "},"finish_reason":null}]}',
243
+ 'data: {"choices":[{"index":0,"delta":{"content":"check."},"finish_reason":null}]}',
244
+ 'data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"c1","type":"function","function":{"name":"search","arguments":"{\\"q\\":\\"test\\"}"}}]},"finish_reason":null}]}',
245
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"tool_calls"}]}',
246
+ 'data: [DONE]',
247
+ ].join('\n');
248
+
249
+ const result = reassembleSSE(sse);
250
+ expect(result.choices[0].message.content).toBe('Let me check.');
251
+ expect(result.choices[0].message.tool_calls).toHaveLength(1);
252
+ });
253
+
254
+ it('skips invalid SSE lines gracefully', () => {
255
+ const sse = [
256
+ 'data: {"choices":[{"index":0,"delta":{"content":"OK"},"finish_reason":null}]}',
257
+ 'data: INVALID_JSON',
258
+ '',
259
+ ':comment line',
260
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}]}',
261
+ 'data: [DONE]',
262
+ ].join('\n');
263
+
264
+ const result = reassembleSSE(sse);
265
+ expect(result.choices[0].message.content).toBe('OK');
266
+ });
267
+
268
+ it('handles SSE with usage chunk at end (no delta)', () => {
269
+ const sse = [
270
+ 'data: {"choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}',
271
+ 'data: {"choices":[{"index":0,"delta":{"content":"Hi"},"finish_reason":null}]}',
272
+ 'data: {"choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}]}',
273
+ 'data: {"choices":[],"usage":{"prompt_tokens":10,"completion_tokens":5,"total_tokens":15}}',
274
+ 'data: [DONE]',
275
+ ].join('\n');
276
+
277
+ const result = reassembleSSE(sse);
278
+ expect(result.choices[0].message.content).toBe('Hi');
279
+ expect(result.choices[0].finish_reason).toBe('stop');
280
+ });
281
+ });
@@ -35,6 +35,7 @@ const SKILL_AGENT_REGISTRY: Record<string, { mode: 'universal' | 'additional' |
35
35
  'roo': { mode: 'additional', skillAgentName: 'roo' },
36
36
  'github-copilot': { mode: 'universal' },
37
37
  'codex': { mode: 'universal' },
38
+ 'antigravity': { mode: 'additional', skillAgentName: 'antigravity' },
38
39
  };
39
40
 
40
41
  /* ── Replicated logic from scripts/setup.js ──────────────────────── */
@@ -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
  );