@geminilight/mindos 0.6.52 → 0.6.54

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 (529) hide show
  1. package/README.md +27 -5
  2. package/README_zh.md +27 -5
  3. package/_standalone/.mindos-build-version +1 -1
  4. package/_standalone/.next/BUILD_ID +1 -1
  5. package/_standalone/.next/app-path-routes-manifest.json +17 -14
  6. package/_standalone/.next/build-manifest.json +3 -3
  7. package/_standalone/.next/cache/.previewinfo +1 -1
  8. package/_standalone/.next/cache/.rscinfo +1 -1
  9. package/_standalone/.next/cache/config.json +3 -3
  10. package/_standalone/.next/prerender-manifest.json +3 -3
  11. package/_standalone/.next/react-loadable-manifest.json +18 -2
  12. package/_standalone/.next/routes-manifest.json +18 -0
  13. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  14. package/_standalone/.next/server/app/_global-error/page.js +1 -1
  15. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  16. package/_standalone/.next/server/app/_global-error.html +2 -2
  17. package/_standalone/.next/server/app/_global-error.rsc +2 -2
  18. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  19. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  25. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  26. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  27. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  28. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  29. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/agents/page.js +3 -3
  31. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  32. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  35. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  42. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/ask/route.js +44 -16
  44. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  45. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  46. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  47. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  49. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  51. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  53. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/export/route.js +2 -2
  55. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  56. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  57. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  59. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  60. package/_standalone/.next/server/app/api/file/raw/route.js +1 -0
  61. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -0
  62. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.js +1 -0
  63. package/_standalone/.next/server/app/api/file/route.js +1 -1
  64. package/_standalone/.next/server/app/api/file/route.js.nft.json +1 -1
  65. package/_standalone/.next/server/app/api/file/route_client-reference-manifest.js +1 -1
  66. package/_standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  67. package/_standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  68. package/_standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  69. package/_standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  70. package/_standalone/.next/server/app/api/graph/route.js.nft.json +1 -1
  71. package/_standalone/.next/server/app/api/graph/route_client-reference-manifest.js +1 -1
  72. package/_standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  73. package/_standalone/.next/server/app/api/inbox/route.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.nft.json +1 -1
  79. package/_standalone/.next/server/app/api/mcp/agents/route_client-reference-manifest.js +1 -1
  80. package/_standalone/.next/server/app/api/mcp/install/route_client-reference-manifest.js +1 -1
  81. package/_standalone/.next/server/app/api/mcp/install-skill/route_client-reference-manifest.js +1 -1
  82. package/_standalone/.next/server/app/api/mcp/restart/route_client-reference-manifest.js +1 -1
  83. package/_standalone/.next/server/app/api/mcp/status/route.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.js +1 -1
  91. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  93. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.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 +1 -1
  97. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  98. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  99. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  100. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  105. package/_standalone/.next/server/app/api/setup/route.js +1 -1
  106. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  107. package/_standalone/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  108. package/_standalone/.next/server/app/api/sync/route.js +1 -1
  109. package/_standalone/.next/server/app/api/sync/route_client-reference-manifest.js +1 -1
  110. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  111. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/api/update/route.js +1 -1
  114. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  116. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  117. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  118. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  119. package/_standalone/.next/server/app/changes/page.js +2 -2
  120. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  121. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  122. package/_standalone/.next/server/app/echo/[segment]/page.js +3 -3
  123. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  124. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  125. package/_standalone/.next/server/app/echo/page.js +1 -1
  126. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  127. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  128. package/_standalone/.next/server/app/explore/page.js +2 -2
  129. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  130. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  131. package/_standalone/.next/server/app/help/page.js +2 -2
  132. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  133. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  134. package/_standalone/.next/server/app/inbox/history/page.js +2 -0
  135. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -0
  136. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -0
  137. package/_standalone/.next/server/app/login/page.js +2 -2
  138. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  139. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  140. package/_standalone/.next/server/app/page.js +3 -3
  141. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  142. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  143. package/_standalone/.next/server/app/setup/page.js +2 -2
  144. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  145. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  146. package/_standalone/.next/server/app/trash/page.js +3 -3
  147. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  148. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  149. package/_standalone/.next/server/app/view/[...path]/page.js +3 -3
  150. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  151. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  152. package/_standalone/.next/server/app/wiki/page.js +2 -0
  153. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -0
  154. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -0
  155. package/_standalone/.next/server/app-paths-manifest.json +17 -14
  156. package/_standalone/.next/server/chunks/2190.js +2 -2
  157. package/_standalone/.next/server/chunks/2364.js +2 -0
  158. package/_standalone/.next/server/chunks/357.js +1 -0
  159. package/_standalone/.next/server/chunks/530.js +219 -0
  160. package/_standalone/.next/server/chunks/6054.js +52 -0
  161. package/_standalone/.next/server/chunks/6539.js +1 -1
  162. package/_standalone/.next/server/chunks/8388.js +2 -2
  163. package/_standalone/.next/server/chunks/953.js +4 -4
  164. package/_standalone/.next/server/middleware-build-manifest.js +1 -1
  165. package/_standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  166. package/_standalone/.next/server/next-font-manifest.js +1 -1
  167. package/_standalone/.next/server/next-font-manifest.json +1 -1
  168. package/_standalone/.next/server/pages/500.html +2 -2
  169. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  170. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/_standalone/.next/static/2hrwFOLEOZhHQHfrIt-Dw/_buildManifest.js +1 -0
  172. package/_standalone/.next/static/chunks/1053-2874859f7caefa0f.js +29 -0
  173. package/_standalone/.next/static/chunks/178-105779afb62d36d9.js +1 -0
  174. package/_standalone/.next/static/chunks/1814.b08e9fb85dd3b13c.js +1 -0
  175. package/_standalone/.next/static/chunks/{1880-3ec02adc80531825.js → 1880-7abf971bcfd2389b.js} +2 -2
  176. package/_standalone/.next/static/chunks/{3160-83a7e0b94414b3ac.js → 2218-d54538000574ffef.js} +1 -1
  177. package/_standalone/.next/static/chunks/254-32719a9bea2e74f0.js +1 -0
  178. package/_standalone/.next/static/chunks/362.a77be2f206db7b19.js +1 -0
  179. package/_standalone/.next/static/chunks/4237-ffc6e7c15d4007b6.js +1 -0
  180. package/_standalone/.next/static/chunks/7035-2af69391c7b1ad95.js +1 -0
  181. package/_standalone/.next/static/chunks/7322-d67d05067544864c.js +1 -0
  182. package/_standalone/.next/static/chunks/{6926-4af497b83952fa87.js → 8409-de5726a4a278d28f.js} +1 -1
  183. package/_standalone/.next/static/chunks/8753-ea9db680b0f70f25.js +1 -0
  184. package/_standalone/.next/static/chunks/app/.well-known/agent-card.json/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  185. package/_standalone/.next/static/chunks/app/_global-error/{page-b07a5983e85bc5e3.js → page-e240db6d5049d336.js} +1 -1
  186. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-f006a70f6889eb56.js +1 -0
  187. package/_standalone/.next/static/chunks/app/agents/page-bd522e428e3acb78.js +5 -0
  188. package/_standalone/.next/static/chunks/app/api/a2a/agents/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  189. package/_standalone/.next/static/chunks/app/api/a2a/delegations/{route-b07a5983e85bc5e3.js → route-e240db6d5049d336.js} +1 -1
  190. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-e240db6d5049d336.js +1 -0
  191. package/_standalone/.next/static/chunks/app/api/a2a/route-e240db6d5049d336.js +1 -0
  192. package/_standalone/.next/static/chunks/app/api/acp/config/route-e240db6d5049d336.js +1 -0
  193. package/_standalone/.next/static/chunks/app/api/acp/detect/route-e240db6d5049d336.js +1 -0
  194. package/_standalone/.next/static/chunks/app/api/acp/install/route-e240db6d5049d336.js +1 -0
  195. package/_standalone/.next/static/chunks/app/api/acp/registry/route-e240db6d5049d336.js +1 -0
  196. package/_standalone/.next/static/chunks/app/api/acp/session/route-e240db6d5049d336.js +1 -0
  197. package/_standalone/.next/static/chunks/app/api/agent-activity/route-e240db6d5049d336.js +1 -0
  198. package/_standalone/.next/static/chunks/app/api/ask/route-e240db6d5049d336.js +1 -0
  199. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-e240db6d5049d336.js +1 -0
  200. package/_standalone/.next/static/chunks/app/api/auth/route-e240db6d5049d336.js +1 -0
  201. package/_standalone/.next/static/chunks/app/api/backlinks/route-e240db6d5049d336.js +1 -0
  202. package/_standalone/.next/static/chunks/app/api/bootstrap/route-e240db6d5049d336.js +1 -0
  203. package/_standalone/.next/static/chunks/app/api/changes/route-e240db6d5049d336.js +1 -0
  204. package/_standalone/.next/static/chunks/app/api/export/route-e240db6d5049d336.js +1 -0
  205. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-e240db6d5049d336.js +1 -0
  206. package/_standalone/.next/static/chunks/app/api/file/import/route-e240db6d5049d336.js +1 -0
  207. package/_standalone/.next/static/chunks/app/api/file/raw/route-e240db6d5049d336.js +1 -0
  208. package/_standalone/.next/static/chunks/app/api/file/route-e240db6d5049d336.js +1 -0
  209. package/_standalone/.next/static/chunks/app/api/files/route-e240db6d5049d336.js +1 -0
  210. package/_standalone/.next/static/chunks/app/api/git/route-e240db6d5049d336.js +1 -0
  211. package/_standalone/.next/static/chunks/app/api/graph/route-e240db6d5049d336.js +1 -0
  212. package/_standalone/.next/static/chunks/app/api/health/route-e240db6d5049d336.js +1 -0
  213. package/_standalone/.next/static/chunks/app/api/inbox/route-e240db6d5049d336.js +1 -0
  214. package/_standalone/.next/static/chunks/app/api/init/route-e240db6d5049d336.js +1 -0
  215. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-e240db6d5049d336.js +1 -0
  216. package/_standalone/.next/static/chunks/app/api/mcp/install/route-e240db6d5049d336.js +1 -0
  217. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-e240db6d5049d336.js +1 -0
  218. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-e240db6d5049d336.js +1 -0
  219. package/_standalone/.next/static/chunks/app/api/mcp/status/route-e240db6d5049d336.js +1 -0
  220. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-e240db6d5049d336.js +1 -0
  221. package/_standalone/.next/static/chunks/app/api/monitoring/route-e240db6d5049d336.js +1 -0
  222. package/_standalone/.next/static/chunks/app/api/recent-files/route-e240db6d5049d336.js +1 -0
  223. package/_standalone/.next/static/chunks/app/api/restart/route-e240db6d5049d336.js +1 -0
  224. package/_standalone/.next/static/chunks/app/api/search/route-e240db6d5049d336.js +1 -0
  225. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-e240db6d5049d336.js +1 -0
  226. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-e240db6d5049d336.js +1 -0
  227. package/_standalone/.next/static/chunks/app/api/settings/route-e240db6d5049d336.js +1 -0
  228. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-e240db6d5049d336.js +1 -0
  229. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-e240db6d5049d336.js +1 -0
  230. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-e240db6d5049d336.js +1 -0
  231. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-e240db6d5049d336.js +1 -0
  232. package/_standalone/.next/static/chunks/app/api/setup/ls/route-e240db6d5049d336.js +1 -0
  233. package/_standalone/.next/static/chunks/app/api/setup/route-e240db6d5049d336.js +1 -0
  234. package/_standalone/.next/static/chunks/app/api/skills/route-e240db6d5049d336.js +1 -0
  235. package/_standalone/.next/static/chunks/app/api/sync/route-e240db6d5049d336.js +1 -0
  236. package/_standalone/.next/static/chunks/app/api/tree-version/route-e240db6d5049d336.js +1 -0
  237. package/_standalone/.next/static/chunks/app/api/uninstall/route-e240db6d5049d336.js +1 -0
  238. package/_standalone/.next/static/chunks/app/api/update/route-e240db6d5049d336.js +1 -0
  239. package/_standalone/.next/static/chunks/app/api/update-check/route-e240db6d5049d336.js +1 -0
  240. package/_standalone/.next/static/chunks/app/api/update-status/route-e240db6d5049d336.js +1 -0
  241. package/_standalone/.next/static/chunks/app/api/workflows/route-e240db6d5049d336.js +1 -0
  242. package/_standalone/.next/static/chunks/app/changes/page-5a72144d1080a699.js +1 -0
  243. package/_standalone/.next/static/chunks/app/echo/[segment]/{page-88df174dd64b2c76.js → page-6710da1f581b2854.js} +2 -2
  244. package/_standalone/.next/static/chunks/app/echo/page-e240db6d5049d336.js +1 -0
  245. package/_standalone/.next/static/chunks/app/explore/{page-5eb2835e9e3ab4bb.js → page-d3d99308146c2240.js} +1 -1
  246. package/_standalone/.next/static/chunks/app/global-error-c37d50db6128ec01.js +1 -0
  247. package/_standalone/.next/static/chunks/app/help/page-222df603080b5fab.js +1 -0
  248. package/_standalone/.next/static/chunks/app/inbox/history/page-07819cf95cb0805f.js +1 -0
  249. package/_standalone/.next/static/chunks/app/layout-8eacff5813458190.js +186 -0
  250. package/_standalone/.next/static/chunks/app/loading-e240db6d5049d336.js +1 -0
  251. package/_standalone/.next/static/chunks/app/login/{page-24236460fa7c11d0.js → page-0eeef685052869a6.js} +1 -1
  252. package/_standalone/.next/static/chunks/app/page-5a6c9455efe8a0df.js +7 -0
  253. package/_standalone/.next/static/chunks/app/setup/{page-99f40e9337388cda.js → page-9a81fa4d82c6351b.js} +1 -1
  254. package/_standalone/.next/static/chunks/app/trash/page-72d0ae3649ac4b6c.js +1 -0
  255. package/_standalone/.next/static/chunks/app/view/[...path]/loading-e240db6d5049d336.js +1 -0
  256. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-fc04c2bd4f35bc6f.js +1 -0
  257. package/_standalone/.next/static/chunks/app/view/[...path]/page-e8699f96589c0979.js +12 -0
  258. package/_standalone/.next/static/chunks/app/wiki/page-d492256a93f0b8bc.js +1 -0
  259. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-e240db6d5049d336.js +1 -0
  260. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-e240db6d5049d336.js +1 -0
  261. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-e240db6d5049d336.js +1 -0
  262. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-e240db6d5049d336.js +1 -0
  263. package/_standalone/.next/static/chunks/{webpack-bbd44cbc83dc0aa4.js → webpack-73c9da80c6c1ebfe.js} +1 -1
  264. package/_standalone/.next/static/css/66f8a81e4eda06d4.css +1 -0
  265. package/_standalone/.next/static/css/a4a2b71142b311af.css +31 -0
  266. package/_standalone/.next/trace +64 -64
  267. package/_standalone/.next/types/routes.d.ts +5 -2
  268. package/_standalone/.next/types/validator.ts +27 -0
  269. package/_standalone/__tests__/agents/agents-content-dashboard.test.tsx +1 -0
  270. package/_standalone/__tests__/agents/agents-content-model.test.ts +13 -0
  271. package/_standalone/__tests__/core/inbox.test.ts +168 -0
  272. package/_standalone/__tests__/core/sync.test.ts +37 -0
  273. package/_standalone/__tests__/panels/agents-panel-hub.test.tsx +1 -0
  274. package/_standalone/app/globals.css +29 -3
  275. package/_standalone/components/ActivityBar.tsx +9 -9
  276. package/_standalone/components/AskFab.tsx +1 -1
  277. package/_standalone/components/Backlinks.tsx +1 -1
  278. package/_standalone/components/Breadcrumb.tsx +1 -1
  279. package/_standalone/components/CreateSpaceModal.tsx +1 -1
  280. package/_standalone/components/EchoSpotlight.tsx +14 -10
  281. package/_standalone/components/Editor.tsx +1 -1
  282. package/_standalone/components/ExportModal.tsx +3 -3
  283. package/_standalone/components/FileTree.tsx +6 -11
  284. package/_standalone/components/GuideCard.tsx +1 -1
  285. package/_standalone/components/ImportModal.tsx +1 -2
  286. package/_standalone/components/KeyboardShortcuts.tsx +1 -1
  287. package/_standalone/components/MarkdownEditor.tsx +1 -1
  288. package/_standalone/components/OnboardingView.tsx +2 -2
  289. package/_standalone/components/OrganizeToast.tsx +3 -1
  290. package/_standalone/components/Panel.tsx +27 -6
  291. package/_standalone/components/Sidebar.tsx +1 -1
  292. package/_standalone/components/SidebarLayout.tsx +30 -7
  293. package/_standalone/components/SystemPulse.tsx +16 -16
  294. package/_standalone/components/agents/AgentsOverviewSection.tsx +18 -92
  295. package/_standalone/components/agents/AgentsPanelA2aTab.tsx +67 -66
  296. package/_standalone/components/agents/AgentsPrimitives.tsx +1 -1
  297. package/_standalone/components/agents/RecentActivityFeed.tsx +6 -6
  298. package/_standalone/components/agents/SkillDetailPopover.tsx +1 -1
  299. package/_standalone/components/ask/AskHeader.tsx +1 -1
  300. package/_standalone/components/echo/EchoHero.tsx +1 -1
  301. package/_standalone/components/echo/EchoPageSections.tsx +1 -1
  302. package/_standalone/components/explore/UseCaseCard.tsx +1 -1
  303. package/_standalone/components/home/InboxSection.tsx +262 -54
  304. package/_standalone/components/panels/AgentsPanel.tsx +4 -3
  305. package/_standalone/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  306. package/_standalone/components/panels/AgentsPanelHubNav.tsx +10 -6
  307. package/_standalone/components/panels/PanelHeader.tsx +1 -1
  308. package/_standalone/components/renderers/audio/AudioRenderer.tsx +79 -0
  309. package/_standalone/components/renderers/image/ImageRenderer.tsx +203 -0
  310. package/_standalone/components/renderers/pdf/PdfRenderer.tsx +57 -0
  311. package/_standalone/components/renderers/video/VideoRenderer.tsx +91 -0
  312. package/_standalone/components/settings/McpTab.tsx +154 -28
  313. package/_standalone/components/settings/PluginsTab.tsx +1 -1
  314. package/_standalone/components/settings/SettingsContent.tsx +41 -7
  315. package/_standalone/components/settings/types.ts +7 -1
  316. package/_standalone/components/walkthrough/WalkthroughOverlay.tsx +40 -11
  317. package/_standalone/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  318. package/_standalone/hooks/useAiOrganize.ts +14 -1
  319. package/_standalone/lib/organize-history.ts +6 -0
  320. package/_standalone/lib/stores/walkthrough-store.ts +33 -1
  321. package/_standalone/tsconfig.tsbuildinfo +1 -1
  322. package/app/app/api/ask/route.ts +193 -3
  323. package/app/app/api/file/raw/route.ts +121 -0
  324. package/app/app/api/file/route.ts +21 -0
  325. package/app/app/api/inbox/route.ts +38 -2
  326. package/app/app/api/mcp/status/route.ts +1 -0
  327. package/app/app/api/restart/route.ts +26 -21
  328. package/app/app/api/settings/route.ts +13 -0
  329. package/app/app/api/setup/route.ts +11 -1
  330. package/app/app/api/sync/route.ts +36 -13
  331. package/app/app/api/update/route.ts +24 -10
  332. package/app/app/global-error.tsx +3 -3
  333. package/app/app/globals.css +29 -3
  334. package/app/app/inbox/history/page.tsx +250 -0
  335. package/app/app/layout.tsx +5 -11
  336. package/app/app/login/page.tsx +1 -1
  337. package/app/app/view/[...path]/ViewPageClient.tsx +15 -10
  338. package/app/app/view/[...path]/not-found.tsx +1 -1
  339. package/app/app/view/[...path]/page.tsx +32 -1
  340. package/app/app/wiki/page.tsx +58 -0
  341. package/app/components/ActivityBar.tsx +9 -9
  342. package/app/components/AskFab.tsx +1 -1
  343. package/app/components/Backlinks.tsx +1 -1
  344. package/app/components/Breadcrumb.tsx +1 -1
  345. package/app/components/CreateSpaceModal.tsx +1 -1
  346. package/app/components/DirView.tsx +2 -2
  347. package/app/components/EchoSpotlight.tsx +14 -10
  348. package/app/components/Editor.tsx +1 -1
  349. package/app/components/ExportModal.tsx +3 -3
  350. package/app/components/FileTree.tsx +6 -11
  351. package/app/components/GuideCard.tsx +1 -1
  352. package/app/components/HomeContent.tsx +50 -39
  353. package/app/components/ImportModal.tsx +1 -2
  354. package/app/components/KeyboardShortcuts.tsx +1 -1
  355. package/app/components/MarkdownEditor.tsx +1 -1
  356. package/app/components/OnboardingView.tsx +2 -2
  357. package/app/components/OrganizeToast.tsx +3 -1
  358. package/app/components/Panel.tsx +27 -6
  359. package/app/components/Sidebar.tsx +1 -1
  360. package/app/components/SidebarLayout.tsx +30 -7
  361. package/app/components/SystemPulse.tsx +16 -16
  362. package/app/components/TrashPageClient.tsx +8 -6
  363. package/app/components/UpdateOverlay.tsx +1 -1
  364. package/app/components/WikiHomeContent.tsx +273 -0
  365. package/app/components/agents/AgentDetailContent.tsx +5 -5
  366. package/app/components/agents/AgentsContentPage.tsx +14 -3
  367. package/app/components/agents/AgentsOverviewSection.tsx +18 -92
  368. package/app/components/agents/AgentsPanelA2aTab.tsx +67 -66
  369. package/app/components/agents/AgentsPrimitives.tsx +1 -1
  370. package/app/components/agents/RecentActivityFeed.tsx +6 -6
  371. package/app/components/agents/SkillDetailPopover.tsx +1 -1
  372. package/app/components/agents/agents-content-model.ts +4 -1
  373. package/app/components/ask/AskHeader.tsx +1 -1
  374. package/app/components/changes/ChangesContentPage.tsx +10 -6
  375. package/app/components/echo/EchoHero.tsx +1 -1
  376. package/app/components/echo/EchoPageSections.tsx +1 -1
  377. package/app/components/explore/ExploreContent.tsx +1 -1
  378. package/app/components/explore/UseCaseCard.tsx +1 -1
  379. package/app/components/help/HelpContent.tsx +3 -3
  380. package/app/components/home/InboxSection.tsx +262 -54
  381. package/app/components/panels/AgentsPanel.tsx +4 -3
  382. package/app/components/panels/AgentsPanelAgentDetail.tsx +1 -1
  383. package/app/components/panels/AgentsPanelHubNav.tsx +10 -6
  384. package/app/components/panels/PanelHeader.tsx +1 -1
  385. package/app/components/renderers/audio/AudioRenderer.tsx +79 -0
  386. package/app/components/renderers/audio/manifest.ts +17 -0
  387. package/app/components/renderers/image/ImageRenderer.tsx +203 -0
  388. package/app/components/renderers/image/manifest.ts +17 -0
  389. package/app/components/renderers/pdf/PdfRenderer.tsx +57 -0
  390. package/app/components/renderers/pdf/manifest.ts +15 -0
  391. package/app/components/renderers/video/VideoRenderer.tsx +91 -0
  392. package/app/components/renderers/video/manifest.ts +17 -0
  393. package/app/components/settings/McpTab.tsx +154 -28
  394. package/app/components/settings/PluginsTab.tsx +1 -1
  395. package/app/components/settings/SettingsContent.tsx +41 -7
  396. package/app/components/settings/types.ts +7 -1
  397. package/app/components/setup/index.tsx +4 -3
  398. package/app/components/walkthrough/WalkthroughOverlay.tsx +40 -11
  399. package/app/components/walkthrough/WalkthroughTooltip.tsx +1 -1
  400. package/app/hooks/useAiOrganize.ts +14 -1
  401. package/app/lib/agent/model.ts +2 -1
  402. package/app/lib/core/inbox.ts +131 -2
  403. package/app/lib/core/pdf-text.ts +28 -0
  404. package/app/lib/core/search-index.ts +29 -5
  405. package/app/lib/core/tree.ts +6 -1
  406. package/app/lib/fs.ts +31 -3
  407. package/app/lib/i18n/modules/ai-chat.ts +42 -0
  408. package/app/lib/i18n/modules/knowledge.ts +30 -0
  409. package/app/lib/i18n/modules/navigation.ts +4 -2
  410. package/app/lib/i18n/modules/panels.ts +22 -4
  411. package/app/lib/i18n/modules/settings.ts +26 -0
  412. package/app/lib/organize-history.ts +6 -0
  413. package/app/lib/renderers/index.ts +5 -1
  414. package/app/lib/settings.ts +60 -0
  415. package/app/lib/stores/walkthrough-store.ts +33 -1
  416. package/bin/commands/doctor.js +12 -6
  417. package/bin/commands/file.js +7 -4
  418. package/bin/commands/logs.js +39 -4
  419. package/bin/commands/onboard.js +1 -1
  420. package/bin/commands/open.js +6 -1
  421. package/bin/commands/space.js +7 -4
  422. package/bin/commands/update.js +31 -29
  423. package/bin/lib/build.js +19 -8
  424. package/bin/lib/clean-env.js +38 -0
  425. package/bin/lib/cli-shim.js +67 -2
  426. package/bin/lib/config.js +4 -5
  427. package/bin/lib/gateway.js +51 -27
  428. package/bin/lib/jsonc.js +7 -2
  429. package/bin/lib/mcp-agents.js +26 -5
  430. package/bin/lib/path-expand.js +6 -3
  431. package/bin/lib/port.js +5 -1
  432. package/bin/lib/stop.js +98 -41
  433. package/bin/lib/sync.js +1 -1
  434. package/package.json +1 -1
  435. package/scripts/setup.js +7 -5
  436. package/_standalone/.next/server/chunks/2673.js +0 -52
  437. package/_standalone/.next/server/chunks/5648.js +0 -2
  438. package/_standalone/.next/server/chunks/8408.js +0 -219
  439. package/_standalone/.next/static/IiTZbEzZo8l5MSUxlDwKp/_buildManifest.js +0 -1
  440. package/_standalone/.next/static/chunks/1053-c519cb347faa75e2.js +0 -29
  441. package/_standalone/.next/static/chunks/1814.72f7fe7c61e2b647.js +0 -1
  442. package/_standalone/.next/static/chunks/362.4c226d7887d5f696.js +0 -1
  443. package/_standalone/.next/static/chunks/6357-c645842834c0d4cd.js +0 -1
  444. package/_standalone/.next/static/chunks/6981-3d7dcac2d12a5670.js +0 -1
  445. package/_standalone/.next/static/chunks/7035-032641fb6f4e07b2.js +0 -1
  446. package/_standalone/.next/static/chunks/7144-5febf62f1a79fe64.js +0 -1
  447. package/_standalone/.next/static/chunks/9602-423291fdb36396d1.js +0 -1
  448. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-074d6aafc2606561.js +0 -1
  449. package/_standalone/.next/static/chunks/app/agents/page-710d8c80fa86e93e.js +0 -5
  450. package/_standalone/.next/static/chunks/app/api/a2a/discover/route-b07a5983e85bc5e3.js +0 -1
  451. package/_standalone/.next/static/chunks/app/api/a2a/route-b07a5983e85bc5e3.js +0 -1
  452. package/_standalone/.next/static/chunks/app/api/acp/config/route-b07a5983e85bc5e3.js +0 -1
  453. package/_standalone/.next/static/chunks/app/api/acp/detect/route-b07a5983e85bc5e3.js +0 -1
  454. package/_standalone/.next/static/chunks/app/api/acp/install/route-b07a5983e85bc5e3.js +0 -1
  455. package/_standalone/.next/static/chunks/app/api/acp/registry/route-b07a5983e85bc5e3.js +0 -1
  456. package/_standalone/.next/static/chunks/app/api/acp/session/route-b07a5983e85bc5e3.js +0 -1
  457. package/_standalone/.next/static/chunks/app/api/agent-activity/route-b07a5983e85bc5e3.js +0 -1
  458. package/_standalone/.next/static/chunks/app/api/ask/route-b07a5983e85bc5e3.js +0 -1
  459. package/_standalone/.next/static/chunks/app/api/ask-sessions/route-b07a5983e85bc5e3.js +0 -1
  460. package/_standalone/.next/static/chunks/app/api/auth/route-b07a5983e85bc5e3.js +0 -1
  461. package/_standalone/.next/static/chunks/app/api/backlinks/route-b07a5983e85bc5e3.js +0 -1
  462. package/_standalone/.next/static/chunks/app/api/bootstrap/route-b07a5983e85bc5e3.js +0 -1
  463. package/_standalone/.next/static/chunks/app/api/changes/route-b07a5983e85bc5e3.js +0 -1
  464. package/_standalone/.next/static/chunks/app/api/export/route-b07a5983e85bc5e3.js +0 -1
  465. package/_standalone/.next/static/chunks/app/api/extract-pdf/route-b07a5983e85bc5e3.js +0 -1
  466. package/_standalone/.next/static/chunks/app/api/file/import/route-b07a5983e85bc5e3.js +0 -1
  467. package/_standalone/.next/static/chunks/app/api/file/route-b07a5983e85bc5e3.js +0 -1
  468. package/_standalone/.next/static/chunks/app/api/files/route-b07a5983e85bc5e3.js +0 -1
  469. package/_standalone/.next/static/chunks/app/api/git/route-b07a5983e85bc5e3.js +0 -1
  470. package/_standalone/.next/static/chunks/app/api/graph/route-b07a5983e85bc5e3.js +0 -1
  471. package/_standalone/.next/static/chunks/app/api/health/route-b07a5983e85bc5e3.js +0 -1
  472. package/_standalone/.next/static/chunks/app/api/inbox/route-b07a5983e85bc5e3.js +0 -1
  473. package/_standalone/.next/static/chunks/app/api/init/route-b07a5983e85bc5e3.js +0 -1
  474. package/_standalone/.next/static/chunks/app/api/mcp/agents/route-b07a5983e85bc5e3.js +0 -1
  475. package/_standalone/.next/static/chunks/app/api/mcp/install/route-b07a5983e85bc5e3.js +0 -1
  476. package/_standalone/.next/static/chunks/app/api/mcp/install-skill/route-b07a5983e85bc5e3.js +0 -1
  477. package/_standalone/.next/static/chunks/app/api/mcp/restart/route-b07a5983e85bc5e3.js +0 -1
  478. package/_standalone/.next/static/chunks/app/api/mcp/status/route-b07a5983e85bc5e3.js +0 -1
  479. package/_standalone/.next/static/chunks/app/api/mcp/uninstall/route-b07a5983e85bc5e3.js +0 -1
  480. package/_standalone/.next/static/chunks/app/api/monitoring/route-b07a5983e85bc5e3.js +0 -1
  481. package/_standalone/.next/static/chunks/app/api/recent-files/route-b07a5983e85bc5e3.js +0 -1
  482. package/_standalone/.next/static/chunks/app/api/restart/route-b07a5983e85bc5e3.js +0 -1
  483. package/_standalone/.next/static/chunks/app/api/search/route-b07a5983e85bc5e3.js +0 -1
  484. package/_standalone/.next/static/chunks/app/api/settings/list-models/route-b07a5983e85bc5e3.js +0 -1
  485. package/_standalone/.next/static/chunks/app/api/settings/reset-token/route-b07a5983e85bc5e3.js +0 -1
  486. package/_standalone/.next/static/chunks/app/api/settings/route-b07a5983e85bc5e3.js +0 -1
  487. package/_standalone/.next/static/chunks/app/api/settings/test-key/route-b07a5983e85bc5e3.js +0 -1
  488. package/_standalone/.next/static/chunks/app/api/setup/check-path/route-b07a5983e85bc5e3.js +0 -1
  489. package/_standalone/.next/static/chunks/app/api/setup/check-port/route-b07a5983e85bc5e3.js +0 -1
  490. package/_standalone/.next/static/chunks/app/api/setup/generate-token/route-b07a5983e85bc5e3.js +0 -1
  491. package/_standalone/.next/static/chunks/app/api/setup/ls/route-b07a5983e85bc5e3.js +0 -1
  492. package/_standalone/.next/static/chunks/app/api/setup/route-b07a5983e85bc5e3.js +0 -1
  493. package/_standalone/.next/static/chunks/app/api/skills/route-b07a5983e85bc5e3.js +0 -1
  494. package/_standalone/.next/static/chunks/app/api/sync/route-b07a5983e85bc5e3.js +0 -1
  495. package/_standalone/.next/static/chunks/app/api/tree-version/route-b07a5983e85bc5e3.js +0 -1
  496. package/_standalone/.next/static/chunks/app/api/uninstall/route-b07a5983e85bc5e3.js +0 -1
  497. package/_standalone/.next/static/chunks/app/api/update/route-b07a5983e85bc5e3.js +0 -1
  498. package/_standalone/.next/static/chunks/app/api/update-check/route-b07a5983e85bc5e3.js +0 -1
  499. package/_standalone/.next/static/chunks/app/api/update-status/route-b07a5983e85bc5e3.js +0 -1
  500. package/_standalone/.next/static/chunks/app/api/workflows/route-b07a5983e85bc5e3.js +0 -1
  501. package/_standalone/.next/static/chunks/app/changes/page-350992cf5091bc5b.js +0 -1
  502. package/_standalone/.next/static/chunks/app/echo/page-b07a5983e85bc5e3.js +0 -1
  503. package/_standalone/.next/static/chunks/app/global-error-e1ad0e18236ba26c.js +0 -1
  504. package/_standalone/.next/static/chunks/app/help/page-2325d25b6846ca07.js +0 -1
  505. package/_standalone/.next/static/chunks/app/layout-e706f9a963b177ba.js +0 -186
  506. package/_standalone/.next/static/chunks/app/loading-b07a5983e85bc5e3.js +0 -1
  507. package/_standalone/.next/static/chunks/app/page-2595175820acfd65.js +0 -7
  508. package/_standalone/.next/static/chunks/app/trash/page-61c6210fac1e9710.js +0 -1
  509. package/_standalone/.next/static/chunks/app/view/[...path]/loading-b07a5983e85bc5e3.js +0 -1
  510. package/_standalone/.next/static/chunks/app/view/[...path]/not-found-61474670d6bb6116.js +0 -1
  511. package/_standalone/.next/static/chunks/app/view/[...path]/page-798359c36f10ef8d.js +0 -12
  512. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-b07a5983e85bc5e3.js +0 -1
  513. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-b07a5983e85bc5e3.js +0 -1
  514. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-b07a5983e85bc5e3.js +0 -1
  515. package/_standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-b07a5983e85bc5e3.js +0 -1
  516. package/_standalone/.next/static/css/bbf51803eade6c50.css +0 -31
  517. package/_standalone/.next/static/css/ef1151f74f00d91a.css +0 -1
  518. package/_standalone/lib/i18n/generated/explore-i18n.generated.ts +0 -138
  519. package/_standalone/lib/i18n/index.ts +0 -38
  520. package/_standalone/lib/i18n/modules/ai-chat.ts +0 -237
  521. package/_standalone/lib/i18n/modules/common.ts +0 -71
  522. package/_standalone/lib/i18n/modules/features.ts +0 -153
  523. package/_standalone/lib/i18n/modules/knowledge.ts +0 -727
  524. package/_standalone/lib/i18n/modules/navigation.ts +0 -157
  525. package/_standalone/lib/i18n/modules/onboarding.ts +0 -445
  526. package/_standalone/lib/i18n/modules/panels.ts +0 -1255
  527. package/_standalone/lib/i18n/modules/settings.ts +0 -889
  528. package/_standalone/lib/i18n.ts +0 -3
  529. /package/_standalone/.next/static/{IiTZbEzZo8l5MSUxlDwKp → 2hrwFOLEOZhHQHfrIt-Dw}/_ssgManifest.js +0 -0
@@ -1,7 +1,7 @@
1
1
  export const dynamic = 'force-dynamic';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
3
  import { execSync, execFile } from 'child_process';
4
- import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
4
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, renameSync } from 'fs';
5
5
  import { join, resolve } from 'path';
6
6
  import { homedir } from 'os';
7
7
 
@@ -13,8 +13,23 @@ function loadConfig() {
13
13
  try { return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')); } catch { return {}; }
14
14
  }
15
15
 
16
+ /** Atomic write to prevent data corruption on crash/power loss */
17
+ function atomicWriteJSON(filePath: string, data: unknown) {
18
+ const content = JSON.stringify(data, null, 2) + '\n';
19
+ const tmp = filePath + '.tmp';
20
+ writeFileSync(tmp, content, 'utf-8');
21
+ renameSync(tmp, filePath);
22
+ }
23
+
16
24
  function saveConfig(config: Record<string, unknown>) {
17
- writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf-8');
25
+ atomicWriteJSON(CONFIG_PATH, config);
26
+ }
27
+
28
+ /** Validate that a file path is safely within mindRoot (prevents path traversal) */
29
+ function isPathWithinMindRoot(mindRoot: string, filePath: string): boolean {
30
+ const normalizedPath = resolve(mindRoot, filePath);
31
+ // Must start with mindRoot + separator to prevent escape via symlinks or ../
32
+ return normalizedPath.startsWith(mindRoot + '/') || normalizedPath === mindRoot;
18
33
  }
19
34
 
20
35
  function loadSyncState() {
@@ -175,7 +190,7 @@ export async function POST(req: NextRequest) {
175
190
  delete config.sync;
176
191
  saveConfig(config);
177
192
  // Clear sync state
178
- try { writeFileSync(SYNC_STATE_PATH, '{}', 'utf-8'); } catch {}
193
+ try { atomicWriteJSON(SYNC_STATE_PATH, {}); } catch {}
179
194
  return NextResponse.json({ ok: true, enabled: false });
180
195
  }
181
196
 
@@ -205,8 +220,12 @@ export async function POST(req: NextRequest) {
205
220
  if (!file || typeof file !== 'string') {
206
221
  return NextResponse.json({ error: 'Missing file path' }, { status: 400 });
207
222
  }
208
- const conflictPath = join(mindRoot, file + '.sync-conflict');
209
- const originalPath = join(mindRoot, file);
223
+ // Security: prevent path traversal attacks
224
+ if (!isPathWithinMindRoot(mindRoot, file)) {
225
+ return NextResponse.json({ error: 'Invalid file path' }, { status: 400 });
226
+ }
227
+ const conflictPath = resolve(mindRoot, file + '.sync-conflict');
228
+ const originalPath = resolve(mindRoot, file);
210
229
  try {
211
230
  if (strategy === 'keep-remote' && existsSync(conflictPath)) {
212
231
  // Replace local with remote version
@@ -221,7 +240,7 @@ export async function POST(req: NextRequest) {
221
240
  const state = loadSyncState();
222
241
  if (state.conflicts) {
223
242
  state.conflicts = state.conflicts.filter((c: { file: string }) => c.file !== file);
224
- writeFileSync(SYNC_STATE_PATH, JSON.stringify(state, null, 2) + '\n', 'utf-8');
243
+ atomicWriteJSON(SYNC_STATE_PATH, state);
225
244
  }
226
245
  return NextResponse.json({ ok: true });
227
246
  } catch (e) {
@@ -234,8 +253,12 @@ export async function POST(req: NextRequest) {
234
253
  if (!file || typeof file !== 'string') {
235
254
  return NextResponse.json({ error: 'Missing file path' }, { status: 400 });
236
255
  }
237
- const localPath = join(mindRoot, file);
238
- const remotePath = join(mindRoot, file + '.sync-conflict');
256
+ // Security: prevent path traversal attacks
257
+ if (!isPathWithinMindRoot(mindRoot, file)) {
258
+ return NextResponse.json({ error: 'Invalid file path' }, { status: 400 });
259
+ }
260
+ const localPath = resolve(mindRoot, file);
261
+ const remotePath = resolve(mindRoot, file + '.sync-conflict');
239
262
  const local = existsSync(localPath) ? readFileSync(localPath, 'utf-8') : '';
240
263
  const remote = existsSync(remotePath) ? readFileSync(remotePath, 'utf-8') : '';
241
264
  return NextResponse.json({ local, remote });
@@ -247,17 +270,17 @@ export async function POST(req: NextRequest) {
247
270
  if (commitInterval === undefined && pullInterval === undefined) {
248
271
  return NextResponse.json({ error: 'At least one interval must be provided' }, { status: 400 });
249
272
  }
250
- if (commitInterval !== undefined && (commitInterval < 10 || commitInterval > 300)) {
251
- return NextResponse.json({ error: 'autoCommitInterval must be between 10 and 300 seconds' }, { status: 400 });
273
+ if (commitInterval !== undefined && (!Number.isInteger(commitInterval) || commitInterval < 10 || commitInterval > 300)) {
274
+ return NextResponse.json({ error: 'autoCommitInterval must be an integer between 10 and 300 seconds' }, { status: 400 });
252
275
  }
253
- if (pullInterval !== undefined && (pullInterval < 60 || pullInterval > 3600)) {
254
- return NextResponse.json({ error: 'autoPullInterval must be between 60 and 3600 seconds' }, { status: 400 });
276
+ if (pullInterval !== undefined && (!Number.isInteger(pullInterval) || pullInterval < 60 || pullInterval > 3600)) {
277
+ return NextResponse.json({ error: 'autoPullInterval must be an integer between 60 and 3600 seconds' }, { status: 400 });
255
278
  }
256
279
  const fullConfig = loadConfig();
257
280
  if (!fullConfig.sync) fullConfig.sync = {};
258
281
  if (commitInterval !== undefined) fullConfig.sync.autoCommitInterval = commitInterval;
259
282
  if (pullInterval !== undefined) fullConfig.sync.autoPullInterval = pullInterval;
260
- writeFileSync(CONFIG_PATH, JSON.stringify(fullConfig, null, 2) + '\n', 'utf-8');
283
+ atomicWriteJSON(CONFIG_PATH, fullConfig);
261
284
  return NextResponse.json({
262
285
  autoCommitInterval: fullConfig.sync.autoCommitInterval || 30,
263
286
  autoPullInterval: fullConfig.sync.autoPullInterval || 300,
@@ -3,25 +3,39 @@ import { NextResponse } from 'next/server';
3
3
  import { spawn } from 'node:child_process';
4
4
  import { resolve } from 'node:path';
5
5
 
6
+ /**
7
+ * Strip ALL MINDOS_ and MIND_ prefixed env vars so the update child
8
+ * process re-derives paths from its own installation root after npm install.
9
+ * This prevents the "fake update" bug where the new process inherits
10
+ * stale MINDOS_PROJECT_ROOT / MINDOS_CLI_PATH pointing to old code.
11
+ */
12
+ function cleanEnvForUpdate(): NodeJS.ProcessEnv {
13
+ const cleaned = { ...process.env };
14
+ for (const key of Object.keys(cleaned)) {
15
+ if (key.startsWith('MINDOS_') || key.startsWith('MIND_')) {
16
+ delete cleaned[key];
17
+ }
18
+ }
19
+ delete cleaned.AUTH_TOKEN;
20
+ delete cleaned.WEB_PASSWORD;
21
+ delete cleaned.NODE_OPTIONS;
22
+ return cleaned;
23
+ }
24
+
6
25
  /**
7
26
  * POST /api/update — trigger `mindos update` as a detached child process.
8
27
  *
9
- * Similar to /api/restart: spawns the CLI command and returns immediately.
10
- * The update process will npm install, remove build stamp, and restart
11
- * the server. The current process will be killed during restart.
28
+ * Spawns the CLI command and returns immediately. The update process will
29
+ * npm install, remove build stamp, and restart the server.
30
+ * The current process will be killed during restart.
12
31
  */
13
32
  export async function POST() {
14
33
  try {
34
+ // Resolve CLI path BEFORE cleaning env (we still need current vars)
15
35
  const cliPath = process.env.MINDOS_CLI_PATH || resolve(process.env.MINDOS_PROJECT_ROOT || process.cwd(), '..', 'bin', 'cli.js');
16
36
  const nodeBin = process.env.MINDOS_NODE_BIN || process.execPath;
17
37
 
18
- // Strip MINDOS_* env vars so the child reads fresh config
19
- const childEnv = { ...process.env };
20
- delete childEnv.MINDOS_WEB_PORT;
21
- delete childEnv.MINDOS_MCP_PORT;
22
- delete childEnv.MIND_ROOT;
23
- delete childEnv.AUTH_TOKEN;
24
- delete childEnv.WEB_PASSWORD;
38
+ const childEnv = cleanEnvForUpdate();
25
39
 
26
40
  const child = spawn(nodeBin, [cliPath, 'update'], {
27
41
  detached: true,
@@ -14,13 +14,13 @@ export default function GlobalError({
14
14
  }) {
15
15
  return (
16
16
  <html lang="en">
17
- <body style={{ margin: 0, fontFamily: 'system-ui, sans-serif', background: '#0f0f0f', color: '#e5e5e5' }}>
17
+ <body style={{ margin: 0, fontFamily: "'IBM Plex Sans', system-ui, sans-serif", background: '#131210', color: '#e8e4dc' }}>
18
18
  <div style={{
19
19
  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
20
20
  minHeight: '100vh', gap: '16px', padding: '24px', textAlign: 'center',
21
21
  }}>
22
22
  <h2 style={{ fontSize: '18px', fontWeight: 600, margin: 0 }}>Something went wrong</h2>
23
- <p style={{ fontSize: '14px', color: '#888', maxWidth: '400px', margin: 0 }}>
23
+ <p style={{ fontSize: '14px', color: '#8a8275', maxWidth: '400px', margin: 0 }}>
24
24
  {error.message || 'An unexpected error occurred. Please try again.'}
25
25
  </p>
26
26
  <div style={{ display: 'flex', gap: '12px', marginTop: '8px' }}>
@@ -28,7 +28,7 @@ export default function GlobalError({
28
28
  onClick={reset}
29
29
  style={{
30
30
  padding: '8px 16px', borderRadius: '6px', fontSize: '14px', fontWeight: 500,
31
- background: '#222', color: '#e5e5e5', border: '1px solid #333', cursor: 'pointer',
31
+ background: '#1c1a17', color: '#e8e4dc', border: '1px solid rgba(232,228,220,0.08)', cursor: 'pointer',
32
32
  }}
33
33
  >
34
34
  Try again
@@ -7,8 +7,8 @@
7
7
  @theme inline {
8
8
  --color-background: var(--background);
9
9
  --color-foreground: var(--foreground);
10
- --font-sans: var(--font-sans);
11
- --font-mono: var(--font-geist-mono);
10
+ --font-sans: var(--font-inter);
11
+ --font-mono: var(--font-ibm-plex-mono);
12
12
  --color-sidebar-ring: var(--sidebar-ring);
13
13
  --color-sidebar-border: var(--sidebar-border);
14
14
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -52,7 +52,7 @@
52
52
  }
53
53
 
54
54
  body {
55
- font-family: 'IBM Plex Sans', var(--font-geist-sans), system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji';
55
+ font-family: 'IBM Plex Sans', var(--font-ibm-plex-sans), system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji';
56
56
  }
57
57
 
58
58
  :root {
@@ -138,6 +138,13 @@ body {
138
138
  /* Utility: IBM Plex Mono display heading font */
139
139
  .font-display { font-family: 'IBM Plex Mono', var(--font-ibm-plex-mono), monospace; }
140
140
 
141
+ /* Brand wordmark — premium sans with engineering precision */
142
+ .font-brand {
143
+ font-family: 'IBM Plex Sans', var(--font-ibm-plex-sans), system-ui, sans-serif;
144
+ font-weight: 700;
145
+ letter-spacing: 0.03em;
146
+ }
147
+
141
148
  /* Content width — controlled by Settings > Appearance */
142
149
  :root { --content-width: 780px; --toc-width: 0px; }
143
150
  .content-width { max-width: var(--content-width-override, var(--content-width)); margin-left: auto; margin-right: auto; }
@@ -332,6 +339,25 @@ body {
332
339
  @layer utilities {
333
340
  .text-2xs { font-size: 10px; line-height: 1.4; }
334
341
  .animate-spin-slow { animation: spin 3s linear infinite; }
342
+ /* Checkerboard background for transparent image preview */
343
+ .bg-checkerboard {
344
+ background-color: #f0f0f0;
345
+ background-image:
346
+ linear-gradient(45deg, #e0e0e0 25%, transparent 25%),
347
+ linear-gradient(-45deg, #e0e0e0 25%, transparent 25%),
348
+ linear-gradient(45deg, transparent 75%, #e0e0e0 75%),
349
+ linear-gradient(-45deg, transparent 75%, #e0e0e0 75%);
350
+ background-size: 16px 16px;
351
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0;
352
+ }
353
+ :is(.dark) .bg-checkerboard {
354
+ background-color: #1a1a1a;
355
+ background-image:
356
+ linear-gradient(45deg, #252525 25%, transparent 25%),
357
+ linear-gradient(-45deg, #252525 25%, transparent 25%),
358
+ linear-gradient(45deg, transparent 75%, #252525 75%),
359
+ linear-gradient(-45deg, transparent 75%, #252525 75%);
360
+ }
335
361
  }
336
362
 
337
363
  /* Hide scrollbar but keep scroll functionality */
@@ -0,0 +1,250 @@
1
+ 'use client';
2
+
3
+ import { useState, useMemo, useCallback } from 'react';
4
+ import Link from 'next/link';
5
+ import {
6
+ ArrowLeft,
7
+ Check,
8
+ AlertCircle,
9
+ Trash2,
10
+ ChevronDown,
11
+ FileText,
12
+ Clock,
13
+ Archive,
14
+ } from 'lucide-react';
15
+ import { useLocale } from '@/lib/stores/locale-store';
16
+ import {
17
+ loadHistory,
18
+ clearHistory,
19
+ type OrganizeHistoryEntry,
20
+ type OrganizeSource,
21
+ } from '@/lib/organize-history';
22
+
23
+ export default function InboxHistoryPage() {
24
+ const { t } = useLocale();
25
+ const [entries, setEntries] = useState<OrganizeHistoryEntry[]>(() => loadHistory());
26
+
27
+ const handleClear = useCallback(() => {
28
+ if (!confirm(t.importHistory.clearConfirm)) return;
29
+ clearHistory();
30
+ setEntries([]);
31
+ }, [t]);
32
+
33
+ const grouped = useMemo(() => {
34
+ const now = new Date();
35
+ const todayStr = now.toDateString();
36
+ const yesterday = new Date(now);
37
+ yesterday.setDate(yesterday.getDate() - 1);
38
+ const yesterdayStr = yesterday.toDateString();
39
+
40
+ const groups: { label: string; entries: OrganizeHistoryEntry[] }[] = [];
41
+ let currentLabel = '';
42
+ let currentGroup: OrganizeHistoryEntry[] = [];
43
+
44
+ for (const entry of entries) {
45
+ const d = new Date(entry.timestamp);
46
+ const dateStr = d.toDateString();
47
+ let label: string;
48
+ if (dateStr === todayStr) label = t.importHistory.today;
49
+ else if (dateStr === yesterdayStr) label = t.importHistory.yesterday;
50
+ else label = d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' });
51
+
52
+ if (label !== currentLabel) {
53
+ if (currentGroup.length > 0) groups.push({ label: currentLabel, entries: currentGroup });
54
+ currentLabel = label;
55
+ currentGroup = [entry];
56
+ } else {
57
+ currentGroup.push(entry);
58
+ }
59
+ }
60
+ if (currentGroup.length > 0) groups.push({ label: currentLabel, entries: currentGroup });
61
+ return groups;
62
+ }, [entries, t]);
63
+
64
+ return (
65
+ <div className="max-w-2xl mx-auto px-4 py-8">
66
+ {/* Header */}
67
+ <div className="flex items-center gap-3 mb-6">
68
+ <Link
69
+ href="/wiki"
70
+ className="p-1.5 rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
71
+ >
72
+ <ArrowLeft size={16} />
73
+ </Link>
74
+ <div className="flex-1">
75
+ <h1 className="text-lg font-semibold tracking-tight text-foreground">{t.importHistory.title}</h1>
76
+ <p className="text-xs text-muted-foreground/60 mt-0.5">
77
+ {entries.length > 0
78
+ ? t.importHistory.recordCount(entries.length)
79
+ : t.importHistory.emptyTitle}
80
+ </p>
81
+ </div>
82
+ {entries.length > 0 && (
83
+ <button
84
+ onClick={handleClear}
85
+ className="flex items-center gap-1.5 text-xs text-muted-foreground hover:text-[var(--error)] transition-colors cursor-pointer"
86
+ >
87
+ <Trash2 size={12} />
88
+ {t.importHistory.clearAll}
89
+ </button>
90
+ )}
91
+ </div>
92
+
93
+ {/* Archive notice */}
94
+ {entries.length > 0 && (
95
+ <div className="flex items-start gap-2 px-3 py-2.5 mb-6 rounded-lg bg-muted/30 border border-border/30">
96
+ <Archive size={13} className="text-muted-foreground/50 mt-0.5 shrink-0" />
97
+ <p className="text-2xs text-muted-foreground/60">
98
+ {t.importHistory.processedArchive}
99
+ </p>
100
+ </div>
101
+ )}
102
+
103
+ {/* Empty state */}
104
+ {entries.length === 0 && (
105
+ <div className="flex flex-col items-center gap-3 py-16 text-center">
106
+ <Clock size={32} className="text-muted-foreground/15" />
107
+ <p className="text-sm text-muted-foreground/60">{t.importHistory.emptyTitle}</p>
108
+ <p className="text-xs text-muted-foreground/40">{t.importHistory.emptyDesc}</p>
109
+ </div>
110
+ )}
111
+
112
+ {/* Grouped entries */}
113
+ <div className="space-y-6">
114
+ {grouped.map((group) => (
115
+ <div key={group.label}>
116
+ <h2 className="text-2xs font-medium text-muted-foreground/50 uppercase tracking-wider mb-2">
117
+ {group.label}
118
+ </h2>
119
+ <div className="space-y-2">
120
+ {group.entries.map((entry) => (
121
+ <HistoryCard key={entry.id} entry={entry} />
122
+ ))}
123
+ </div>
124
+ </div>
125
+ ))}
126
+ </div>
127
+ </div>
128
+ );
129
+ }
130
+
131
+ function HistoryCard({ entry }: { entry: OrganizeHistoryEntry }) {
132
+ const { t } = useLocale();
133
+ const [expanded, setExpanded] = useState(false);
134
+ const isUndone = entry.status === 'undone';
135
+ const sourceLabel = getSourceLabel(entry.source);
136
+ const duration = entry.durationMs ? formatDuration(entry.durationMs) : null;
137
+ const time = new Date(entry.timestamp).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });
138
+ const successCount = entry.files.filter(f => f.ok && !f.undone).length;
139
+ const totalCount = entry.files.length;
140
+
141
+ return (
142
+ <div className="rounded-xl border border-border/40 overflow-hidden hover:border-border/60 transition-colors">
143
+ <button
144
+ type="button"
145
+ onClick={() => setExpanded(v => !v)}
146
+ className="w-full flex items-start gap-3 px-4 py-3 text-left hover:bg-muted/20 transition-colors"
147
+ >
148
+ {isUndone ? (
149
+ <AlertCircle size={14} className="text-muted-foreground/40 mt-0.5 shrink-0" />
150
+ ) : (
151
+ <Check size={14} className="text-success/70 mt-0.5 shrink-0" />
152
+ )}
153
+
154
+ <div className="flex-1 min-w-0">
155
+ <div className={`text-sm ${isUndone ? 'text-muted-foreground/50 line-through' : 'text-foreground/90'}`}>
156
+ {entry.sourceFiles.length === 1
157
+ ? entry.sourceFiles[0]
158
+ : `${entry.sourceFiles.length} files`}
159
+ </div>
160
+ <div className="flex items-center gap-2 mt-1 flex-wrap">
161
+ {sourceLabel && (
162
+ <span className="text-2xs px-1.5 py-0.5 rounded bg-muted/60 text-muted-foreground/60">
163
+ {sourceLabel}
164
+ </span>
165
+ )}
166
+ {totalCount > 0 && (
167
+ <span className="text-2xs text-muted-foreground/40">
168
+ {t.importHistory.changesCount(successCount, totalCount)}
169
+ </span>
170
+ )}
171
+ {duration && (
172
+ <span className="text-2xs text-muted-foreground/40">{duration}</span>
173
+ )}
174
+ </div>
175
+ </div>
176
+
177
+ <div className="flex items-center gap-2 shrink-0">
178
+ <span className="text-2xs text-muted-foreground/40 tabular-nums">{time}</span>
179
+ {totalCount > 0 && (
180
+ <ChevronDown
181
+ size={12}
182
+ className={`text-muted-foreground/30 transition-transform duration-150 ${expanded ? 'rotate-180' : ''}`}
183
+ />
184
+ )}
185
+ </div>
186
+ </button>
187
+
188
+ {expanded && totalCount > 0 && (
189
+ <div className="border-t border-border/20 px-4 py-2 space-y-1">
190
+ {/* Source files */}
191
+ {entry.sourceFiles.length > 1 && (
192
+ <div className="mb-2">
193
+ <span className="text-2xs font-medium text-muted-foreground/50 uppercase tracking-wider">
194
+ {t.importHistory.sourceLabel}
195
+ </span>
196
+ <div className="mt-1 space-y-0.5">
197
+ {entry.sourceFiles.map((name, idx) => (
198
+ <div key={idx} className="flex items-center gap-2 text-2xs text-foreground/60">
199
+ <FileText size={10} className="text-muted-foreground/40 shrink-0" />
200
+ <span className="truncate">{name}</span>
201
+ </div>
202
+ ))}
203
+ </div>
204
+ </div>
205
+ )}
206
+
207
+ {/* Changes */}
208
+ {entry.files.map((f, idx) => {
209
+ const fileName = f.path.split('/').pop() ?? f.path;
210
+ return (
211
+ <div
212
+ key={`${f.path}-${idx}`}
213
+ className={`flex items-center gap-2 py-1 text-2xs ${f.undone ? 'opacity-40' : ''}`}
214
+ >
215
+ <span className={`w-1.5 h-1.5 rounded-full shrink-0 ${
216
+ f.ok && !f.undone ? 'bg-success/60' : f.undone ? 'bg-muted-foreground/30' : 'bg-[var(--error)]/50'
217
+ }`} />
218
+ <span className={`truncate flex-1 ${f.undone ? 'line-through text-muted-foreground' : 'text-foreground/70'}`}>
219
+ {f.path}
220
+ </span>
221
+ <span className="text-muted-foreground/40 shrink-0">
222
+ {f.undone ? 'undone' : f.action === 'create' ? 'created' : f.action === 'update' ? 'updated' : f.action}
223
+ </span>
224
+ </div>
225
+ );
226
+ })}
227
+ </div>
228
+ )}
229
+ </div>
230
+ );
231
+ }
232
+
233
+ function getSourceLabel(source?: OrganizeSource): string | null {
234
+ switch (source) {
235
+ case 'drag-drop': return 'Drag & Drop';
236
+ case 'inbox-organize': return 'Inbox';
237
+ case 'import-modal': return 'Import';
238
+ case 'plugin': return 'Plugin';
239
+ case 'upload': return 'Upload';
240
+ default: return null;
241
+ }
242
+ }
243
+
244
+ function formatDuration(ms: number): string {
245
+ const s = Math.round(ms / 1000);
246
+ if (s < 60) return `${s}s`;
247
+ const m = Math.floor(s / 60);
248
+ const rem = s % 60;
249
+ return `${m}m${rem > 0 ? `${rem}s` : ''}`;
250
+ }
@@ -13,14 +13,8 @@ import { cookies } from 'next/headers';
13
13
  import type { Locale } from '@/lib/i18n';
14
14
  import '@/lib/renderers/index'; // globally register built-in renderers once
15
15
 
16
- const geistSans = Inter({
17
- variable: '--font-geist-sans',
18
- subsets: ['latin'],
19
- });
20
-
21
- const geistMono = IBM_Plex_Mono({
22
- variable: '--font-geist-mono',
23
- weight: ['400', '600'],
16
+ const inter = Inter({
17
+ variable: '--font-inter',
24
18
  subsets: ['latin'],
25
19
  });
26
20
 
@@ -32,7 +26,7 @@ const ibmPlexMono = IBM_Plex_Mono({
32
26
 
33
27
  const ibmPlexSans = IBM_Plex_Sans({
34
28
  variable: '--font-ibm-plex-sans',
35
- weight: ['400', '500', '600'],
29
+ weight: ['400', '500', '600', '700'],
36
30
  subsets: ['latin'],
37
31
  });
38
32
 
@@ -98,12 +92,12 @@ export default async function RootLayout({
98
92
  {/* Apply user appearance settings before first paint, preventing flash */}
99
93
  <script
100
94
  dangerouslySetInnerHTML={{
101
- __html: `(function(){try{var s=localStorage.getItem('theme');var dark=s&&s!=='system'?s==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',dark);var cw=localStorage.getItem('content-width');if(cw)document.documentElement.style.setProperty('--content-width-override',cw);var pf=localStorage.getItem('prose-font');var fm={lora:'"Lora", Georgia, serif','ibm-plex-sans':'"IBM Plex Sans", sans-serif',geist:'var(--font-geist-sans), sans-serif','ibm-plex-mono':'"IBM Plex Mono", monospace'};if(pf&&fm[pf])document.documentElement.style.setProperty('--prose-font-override',fm[pf]);var loc=localStorage.getItem('locale')||'system';var rl=loc==='system'?(navigator.language.startsWith('zh')?'zh':'en'):loc;document.documentElement.lang=rl==='zh'?'zh':'en';document.cookie='locale='+rl+';path=/;max-age=31536000;SameSite=Lax'}catch(e){}})();`,
95
+ __html: `(function(){try{var s=localStorage.getItem('theme');var dark=s&&s!=='system'?s==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',dark);var cw=localStorage.getItem('content-width');if(cw)document.documentElement.style.setProperty('--content-width-override',cw);var pf=localStorage.getItem('prose-font');if(pf==='geist'){pf='inter';localStorage.setItem('prose-font','inter')}var fm={lora:'"Lora", Georgia, serif','ibm-plex-sans':'"IBM Plex Sans", sans-serif',inter:'var(--font-inter), sans-serif','ibm-plex-mono':'"IBM Plex Mono", monospace'};if(pf&&fm[pf])document.documentElement.style.setProperty('--prose-font-override',fm[pf]);var loc=localStorage.getItem('locale')||'system';var rl=loc==='system'?(navigator.language.startsWith('zh')?'zh':'en'):loc;document.documentElement.lang=rl==='zh'?'zh':'en';document.cookie='locale='+rl+';path=/;max-age=31536000;SameSite=Lax'}catch(e){}})();`,
102
96
  }}
103
97
  />
104
98
  </head>
105
99
  <body
106
- className={`${geistSans.variable} ${geistMono.variable} ${ibmPlexMono.variable} ${ibmPlexSans.variable} ${lora.variable} antialiased bg-background text-foreground`}
100
+ className={`${inter.variable} ${ibmPlexMono.variable} ${ibmPlexSans.variable} ${lora.variable} antialiased bg-background text-foreground`}
107
101
  suppressHydrationWarning
108
102
  >
109
103
  <LocaleStoreInit ssrLocale={ssrLocale} />
@@ -65,7 +65,7 @@ function LoginForm() {
65
65
  <path d="M35,17.5 Q35,20 37.5,20 Q35,20 35,22.5 Q35,20 32.5,20 Q35,20 35,17.5 Z" fill="#FEF3C7"/>
66
66
  </g>
67
67
  </svg>
68
- <h1 className="text-xl font-semibold text-foreground tracking-tight font-display">
68
+ <h1 className="text-2xl font-brand text-foreground">
69
69
  MindOS
70
70
  </h1>
71
71
  <p className="text-xs text-muted-foreground/70 italic">
@@ -61,7 +61,12 @@ export default function ViewPageClient({
61
61
  // Graph mode — per-view, resets when navigating to a different file
62
62
  const [graphMode, setGraphMode] = useState(false);
63
63
  const router = useRouter();
64
- const [editing, setEditing] = useState(initialEditing || content === '');
64
+ const isBinaryFile = [
65
+ 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'webp', 'svg', 'bmp', 'ico',
66
+ 'mp3', 'wav', 'm4a', 'ogg', 'flac', 'aac',
67
+ 'mp4', 'webm', 'mov', 'mkv',
68
+ ].includes(extension);
69
+ const [editing, setEditing] = useState(!isBinaryFile && (initialEditing || content === ''));
65
70
  const [editContent, setEditContent] = useState(content);
66
71
  const [savedContent, setSavedContent] = useState(content);
67
72
 
@@ -282,7 +287,7 @@ export default function ViewPageClient({
282
287
  e.preventDefault();
283
288
  setFindOpen(true);
284
289
  }
285
- if (e.key === 'e' && !editing && document.activeElement?.tagName === 'BODY') {
290
+ if (e.key === 'e' && !editing && !isBinaryFile && document.activeElement?.tagName === 'BODY') {
286
291
  handleEdit();
287
292
  }
288
293
  if (e.key === 'Escape' && editing) handleCancel();
@@ -374,7 +379,7 @@ export default function ViewPageClient({
374
379
  </span>
375
380
  )}
376
381
  {saveSuccess && (
377
- <span className="text-xs flex items-center gap-1.5 font-display" style={{ color: 'var(--success)' }}>
382
+ <span className="text-xs flex items-center gap-1.5" style={{ color: 'var(--success)' }}>
378
383
  <span className="w-1.5 h-1.5 rounded-full" style={{ background: 'var(--success)' }} />
379
384
  <span className="hidden sm:inline">saved</span>
380
385
  </span>
@@ -383,11 +388,11 @@ export default function ViewPageClient({
383
388
  <span className="text-xs text-error hidden sm:inline">{saveError}</span>
384
389
  )}
385
390
 
386
- {/* Renderer toggle — only shown when a custom renderer exists (excludes graph-mode override) */}
387
- {registryRenderer && !editing && !isDraft && !graphRenderer && (
391
+ {/* Renderer toggle — only shown when a custom renderer exists (excludes graph-mode override and binary files) */}
392
+ {registryRenderer && !editing && !isDraft && !graphRenderer && !isBinaryFile && (
388
393
  <button
389
394
  onClick={handleToggleRaw}
390
- className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors font-display"
395
+ className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors"
391
396
  style={{
392
397
  background: effectiveUseRaw ? `${'var(--amber)'}22` : 'var(--muted)',
393
398
  color: effectiveUseRaw ? 'var(--amber)' : 'var(--muted-foreground)',
@@ -399,10 +404,10 @@ export default function ViewPageClient({
399
404
  </button>
400
405
  )}
401
406
 
402
- {!editing && !showRenderer && !isDraft && (
407
+ {!editing && !showRenderer && !isDraft && !isBinaryFile && (
403
408
  <button
404
409
  onClick={handleEdit}
405
- className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors font-display"
410
+ className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors"
406
411
  style={{ background: 'var(--muted)', color: 'var(--muted-foreground)' }}
407
412
  onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--foreground)'; e.currentTarget.style.background = 'var(--accent)'; }}
408
413
  onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--muted-foreground)'; e.currentTarget.style.background = 'var(--muted)'; }}
@@ -416,7 +421,7 @@ export default function ViewPageClient({
416
421
  <button
417
422
  onClick={handleCancel}
418
423
  disabled={isPending}
419
- className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors disabled:opacity-50 font-display"
424
+ className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors disabled:opacity-50"
420
425
  style={{ background: 'var(--muted)', color: 'var(--muted-foreground)' }}
421
426
  onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--accent)'; }}
422
427
  onMouseLeave={(e) => { e.currentTarget.style.background = 'var(--muted)'; }}
@@ -427,7 +432,7 @@ export default function ViewPageClient({
427
432
  <button
428
433
  onClick={isDraft && showSaveAs ? handleConfirmDraftSave : handleSave}
429
434
  disabled={isPending}
430
- className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium disabled:opacity-50 font-display"
435
+ className="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium disabled:opacity-50"
431
436
  style={{ background: 'var(--amber)', color: 'var(--amber-foreground)' }}
432
437
  >
433
438
  {isPending ? <Loader2 size={13} className="animate-spin" /> : <Save size={13} />}
@@ -52,7 +52,7 @@ export default function ViewNotFound() {
52
52
  <FilePlus size={24} className="text-muted-foreground" />
53
53
  </div>
54
54
 
55
- <h1 className="text-lg font-semibold text-foreground mb-2 font-display">
55
+ <h1 className="text-lg font-semibold tracking-tight text-foreground mb-2">
56
56
  {notFoundT?.title ?? 'File not found'}
57
57
  </h1>
58
58