@geminilight/mindos 0.6.61 → 0.6.65

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 (313) hide show
  1. package/_standalone/.antigravity/mcp_config.json +14 -0
  2. package/_standalone/.mindos-build-version +1 -1
  3. package/_standalone/.next/BUILD_ID +1 -1
  4. package/_standalone/.next/app-path-routes-manifest.json +23 -23
  5. package/_standalone/.next/build-manifest.json +2 -2
  6. package/_standalone/.next/cache/.previewinfo +1 -1
  7. package/_standalone/.next/cache/.rscinfo +1 -1
  8. package/_standalone/.next/cache/config.json +3 -3
  9. package/_standalone/.next/prerender-manifest.json +3 -3
  10. package/_standalone/.next/server/app/.well-known/agent-card.json/route_client-reference-manifest.js +1 -1
  11. package/_standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/_standalone/.next/server/app/_global-error.html +2 -2
  13. package/_standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/_standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/_standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/_standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/_standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/_standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/_standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/_standalone/.next/server/app/_not-found/page.js +1 -1
  21. package/_standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/_standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/_standalone/.next/server/app/agents/[agentKey]/page.js +1 -1
  24. package/_standalone/.next/server/app/agents/[agentKey]/page.js.nft.json +1 -1
  25. package/_standalone/.next/server/app/agents/[agentKey]/page_client-reference-manifest.js +1 -1
  26. package/_standalone/.next/server/app/agents/page.js +1 -1
  27. package/_standalone/.next/server/app/agents/page.js.nft.json +1 -1
  28. package/_standalone/.next/server/app/agents/page_client-reference-manifest.js +1 -1
  29. package/_standalone/.next/server/app/api/a2a/agents/route_client-reference-manifest.js +1 -1
  30. package/_standalone/.next/server/app/api/a2a/delegations/route_client-reference-manifest.js +1 -1
  31. package/_standalone/.next/server/app/api/a2a/discover/route_client-reference-manifest.js +1 -1
  32. package/_standalone/.next/server/app/api/a2a/route_client-reference-manifest.js +1 -1
  33. package/_standalone/.next/server/app/api/acp/config/route_client-reference-manifest.js +1 -1
  34. package/_standalone/.next/server/app/api/acp/detect/route.js +1 -1
  35. package/_standalone/.next/server/app/api/acp/detect/route_client-reference-manifest.js +1 -1
  36. package/_standalone/.next/server/app/api/acp/install/route_client-reference-manifest.js +1 -1
  37. package/_standalone/.next/server/app/api/acp/registry/route.js +1 -1
  38. package/_standalone/.next/server/app/api/acp/registry/route_client-reference-manifest.js +1 -1
  39. package/_standalone/.next/server/app/api/acp/session/route_client-reference-manifest.js +1 -1
  40. package/_standalone/.next/server/app/api/agent-activity/route_client-reference-manifest.js +1 -1
  41. package/_standalone/.next/server/app/api/agents/copy-skill/route.js.nft.json +1 -1
  42. package/_standalone/.next/server/app/api/agents/copy-skill/route_client-reference-manifest.js +1 -1
  43. package/_standalone/.next/server/app/api/agents/custom/detect/route_client-reference-manifest.js +1 -1
  44. package/_standalone/.next/server/app/api/agents/custom/route_client-reference-manifest.js +1 -1
  45. package/_standalone/.next/server/app/api/ask/route.js +53 -47
  46. package/_standalone/.next/server/app/api/ask/route.js.nft.json +1 -1
  47. package/_standalone/.next/server/app/api/ask/route_client-reference-manifest.js +1 -1
  48. package/_standalone/.next/server/app/api/ask-sessions/route_client-reference-manifest.js +1 -1
  49. package/_standalone/.next/server/app/api/auth/route_client-reference-manifest.js +1 -1
  50. package/_standalone/.next/server/app/api/backlinks/route.js.nft.json +1 -1
  51. package/_standalone/.next/server/app/api/backlinks/route_client-reference-manifest.js +1 -1
  52. package/_standalone/.next/server/app/api/bootstrap/route.js.nft.json +1 -1
  53. package/_standalone/.next/server/app/api/bootstrap/route_client-reference-manifest.js +1 -1
  54. package/_standalone/.next/server/app/api/changes/route.js.nft.json +1 -1
  55. package/_standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  56. package/_standalone/.next/server/app/api/export/route.js.nft.json +1 -1
  57. package/_standalone/.next/server/app/api/export/route_client-reference-manifest.js +1 -1
  58. package/_standalone/.next/server/app/api/extract-pdf/route_client-reference-manifest.js +1 -1
  59. package/_standalone/.next/server/app/api/file/import/route.js +1 -1
  60. package/_standalone/.next/server/app/api/file/import/route.js.nft.json +1 -1
  61. package/_standalone/.next/server/app/api/file/import/route_client-reference-manifest.js +1 -1
  62. package/_standalone/.next/server/app/api/file/raw/route.js.nft.json +1 -1
  63. package/_standalone/.next/server/app/api/file/raw/route_client-reference-manifest.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.nft.json +1 -1
  74. package/_standalone/.next/server/app/api/inbox/route_client-reference-manifest.js +1 -1
  75. package/_standalone/.next/server/app/api/init/route.js.nft.json +1 -1
  76. package/_standalone/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  77. package/_standalone/.next/server/app/api/mcp/agents/route.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_client-reference-manifest.js +1 -1
  84. package/_standalone/.next/server/app/api/mcp/uninstall/route_client-reference-manifest.js +1 -1
  85. package/_standalone/.next/server/app/api/monitoring/route.js.nft.json +1 -1
  86. package/_standalone/.next/server/app/api/monitoring/route_client-reference-manifest.js +1 -1
  87. package/_standalone/.next/server/app/api/recent-files/route.js.nft.json +1 -1
  88. package/_standalone/.next/server/app/api/recent-files/route_client-reference-manifest.js +1 -1
  89. package/_standalone/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  90. package/_standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  91. package/_standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  92. package/_standalone/.next/server/app/api/settings/list-models/route.js +1 -1
  93. package/_standalone/.next/server/app/api/settings/list-models/route_client-reference-manifest.js +1 -1
  94. package/_standalone/.next/server/app/api/settings/reset-token/route_client-reference-manifest.js +1 -1
  95. package/_standalone/.next/server/app/api/settings/route.js +1 -1
  96. package/_standalone/.next/server/app/api/settings/route.js.nft.json +1 -1
  97. package/_standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  98. package/_standalone/.next/server/app/api/settings/test-key/route.js +1 -1
  99. package/_standalone/.next/server/app/api/settings/test-key/route_client-reference-manifest.js +1 -1
  100. package/_standalone/.next/server/app/api/setup/check-path/route_client-reference-manifest.js +1 -1
  101. package/_standalone/.next/server/app/api/setup/check-port/route_client-reference-manifest.js +1 -1
  102. package/_standalone/.next/server/app/api/setup/generate-token/route_client-reference-manifest.js +1 -1
  103. package/_standalone/.next/server/app/api/setup/ls/route_client-reference-manifest.js +1 -1
  104. package/_standalone/.next/server/app/api/setup/route.js +1 -1
  105. package/_standalone/.next/server/app/api/setup/route_client-reference-manifest.js +1 -1
  106. package/_standalone/.next/server/app/api/skills/route.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_client-reference-manifest.js +1 -1
  109. package/_standalone/.next/server/app/api/tree-version/route.js.nft.json +1 -1
  110. package/_standalone/.next/server/app/api/tree-version/route_client-reference-manifest.js +1 -1
  111. package/_standalone/.next/server/app/api/uninstall/route_client-reference-manifest.js +1 -1
  112. package/_standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  113. package/_standalone/.next/server/app/api/update-check/route_client-reference-manifest.js +1 -1
  114. package/_standalone/.next/server/app/api/update-status/route_client-reference-manifest.js +1 -1
  115. package/_standalone/.next/server/app/api/workflows/route.js.nft.json +1 -1
  116. package/_standalone/.next/server/app/api/workflows/route_client-reference-manifest.js +1 -1
  117. package/_standalone/.next/server/app/changes/page.js +1 -1
  118. package/_standalone/.next/server/app/changes/page.js.nft.json +1 -1
  119. package/_standalone/.next/server/app/changes/page_client-reference-manifest.js +1 -1
  120. package/_standalone/.next/server/app/echo/[segment]/page.js +2 -2
  121. package/_standalone/.next/server/app/echo/[segment]/page.js.nft.json +1 -1
  122. package/_standalone/.next/server/app/echo/[segment]/page_client-reference-manifest.js +1 -1
  123. package/_standalone/.next/server/app/echo/page.js +1 -1
  124. package/_standalone/.next/server/app/echo/page.js.nft.json +1 -1
  125. package/_standalone/.next/server/app/echo/page_client-reference-manifest.js +1 -1
  126. package/_standalone/.next/server/app/explore/page.js +1 -1
  127. package/_standalone/.next/server/app/explore/page.js.nft.json +1 -1
  128. package/_standalone/.next/server/app/explore/page_client-reference-manifest.js +1 -1
  129. package/_standalone/.next/server/app/help/page.js +1 -1
  130. package/_standalone/.next/server/app/help/page.js.nft.json +1 -1
  131. package/_standalone/.next/server/app/help/page_client-reference-manifest.js +1 -1
  132. package/_standalone/.next/server/app/inbox/history/page.js +1 -1
  133. package/_standalone/.next/server/app/inbox/history/page.js.nft.json +1 -1
  134. package/_standalone/.next/server/app/inbox/history/page_client-reference-manifest.js +1 -1
  135. package/_standalone/.next/server/app/login/page.js +1 -1
  136. package/_standalone/.next/server/app/login/page.js.nft.json +1 -1
  137. package/_standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  138. package/_standalone/.next/server/app/page.js +1 -1
  139. package/_standalone/.next/server/app/page.js.nft.json +1 -1
  140. package/_standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  141. package/_standalone/.next/server/app/setup/page.js +2 -2
  142. package/_standalone/.next/server/app/setup/page.js.nft.json +1 -1
  143. package/_standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  144. package/_standalone/.next/server/app/trash/page.js +3 -3
  145. package/_standalone/.next/server/app/trash/page.js.nft.json +1 -1
  146. package/_standalone/.next/server/app/trash/page_client-reference-manifest.js +1 -1
  147. package/_standalone/.next/server/app/view/[...path]/page.js +2 -2
  148. package/_standalone/.next/server/app/view/[...path]/page.js.nft.json +1 -1
  149. package/_standalone/.next/server/app/view/[...path]/page_client-reference-manifest.js +1 -1
  150. package/_standalone/.next/server/app/wiki/page.js +1 -1
  151. package/_standalone/.next/server/app/wiki/page.js.nft.json +1 -1
  152. package/_standalone/.next/server/app/wiki/page_client-reference-manifest.js +1 -1
  153. package/_standalone/.next/server/app-paths-manifest.json +23 -23
  154. package/_standalone/.next/server/chunks/122.js +222 -0
  155. package/_standalone/.next/server/chunks/1550.js +1 -1
  156. package/_standalone/.next/server/chunks/1750.js +1 -1
  157. package/_standalone/.next/server/chunks/3113.js +52 -0
  158. package/_standalone/.next/server/chunks/6539.js +1 -1
  159. package/_standalone/.next/server/chunks/8388.js +3 -3
  160. package/_standalone/.next/server/chunks/953.js +3 -3
  161. package/_standalone/.next/server/pages/500.html +2 -2
  162. package/_standalone/.next/server/server-reference-manifest.js +1 -1
  163. package/_standalone/.next/server/server-reference-manifest.json +1 -1
  164. package/_standalone/.next/static/chunks/1001-99da82ec8d8c136f.js +1 -0
  165. package/_standalone/.next/static/chunks/1088-77544af0a50cb7a4.js +1 -0
  166. package/_standalone/.next/static/chunks/1467-87dde7eed498806f.js +1 -0
  167. package/_standalone/.next/static/chunks/5149-4d828886dda479fa.js +1 -0
  168. package/_standalone/.next/static/chunks/5581-c671163a2fe1b312.js +29 -0
  169. package/_standalone/.next/static/chunks/{7266-bb7be1128eccd48e.js → 5718-3837c3210a0e175f.js} +2 -2
  170. package/_standalone/.next/static/chunks/6636-53238eff89503f03.js +6 -0
  171. package/_standalone/.next/static/chunks/6757-1c1a89720fdda8f0.js +1 -0
  172. package/_standalone/.next/static/chunks/7129-20e9d2463a9da646.js +1 -0
  173. package/_standalone/.next/static/chunks/7294-cac25d97869afadc.js +1 -0
  174. package/_standalone/.next/static/chunks/8225-21e5cebc3731ddf0.js +1 -0
  175. package/_standalone/.next/static/chunks/8520-b51810e66293ceb8.js +22 -0
  176. package/_standalone/.next/static/chunks/9207-dc9c31b351a2ed78.js +1 -0
  177. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-2f5cf97e03dc1cc9.js +1 -0
  178. package/_standalone/.next/static/chunks/app/agents/page-50eac58d511dcc6e.js +1 -0
  179. package/_standalone/.next/static/chunks/app/echo/[segment]/page-2a00f4686adf3885.js +11 -0
  180. package/_standalone/.next/static/chunks/app/layout-2cb7a6602d2e5d5f.js +168 -0
  181. package/_standalone/.next/static/chunks/app/{page-6a1f8d21c12b829e.js → page-5ab911b2226f6ff7.js} +1 -1
  182. package/_standalone/.next/static/chunks/app/setup/page-907b7c57fad2292b.js +1 -0
  183. package/_standalone/.next/static/chunks/app/trash/page-11a511b065ea84c2.js +1 -0
  184. package/_standalone/.next/static/chunks/app/view/[...path]/page-26e47dd4c533a58c.js +12 -0
  185. package/_standalone/.next/static/chunks/app/wiki/page-dce495b9048022fb.js +1 -0
  186. package/_standalone/.next/static/css/67e7918f5ed7d147.css +1 -0
  187. package/_standalone/.next/trace +65 -65
  188. package/_standalone/__tests__/acp/registry.test.ts +30 -20
  189. package/_standalone/__tests__/api/ask-attachments.test.ts +194 -0
  190. package/_standalone/__tests__/api/mcp-install.test.ts +49 -2
  191. package/_standalone/__tests__/api/settings.test.ts +16 -12
  192. package/_standalone/__tests__/api/setup.test.ts +11 -9
  193. package/_standalone/__tests__/api/test-key.test.ts +0 -10
  194. package/_standalone/__tests__/components/UpdateToast.test.ts +344 -0
  195. package/_standalone/__tests__/core/context.test.ts +48 -426
  196. package/_standalone/__tests__/lib/pi-skills.test.ts +4 -4
  197. package/_standalone/__tests__/lib/settings-ai-client.test.ts +32 -12
  198. package/_standalone/__tests__/setup.ts +5 -5
  199. package/_standalone/app/globals.css +4 -4
  200. package/_standalone/components/ActivityBar.tsx +17 -6
  201. package/_standalone/components/Panel.tsx +24 -6
  202. package/_standalone/components/SidebarLayout.tsx +36 -8
  203. package/_standalone/components/agents/AgentsMcpSection.tsx +2 -2
  204. package/_standalone/components/agents/AgentsOverviewSection.tsx +5 -1
  205. package/_standalone/components/agents/AgentsPanelA2aTab.tsx +173 -113
  206. package/_standalone/components/agents/AgentsSkillsSection.tsx +2 -2
  207. package/_standalone/components/ask/AskContent.tsx +83 -44
  208. package/_standalone/components/ask/AskHeader.tsx +8 -1
  209. package/_standalone/components/ask/MessageList.tsx +37 -3
  210. package/_standalone/components/ask/ProviderModelCapsule.tsx +444 -174
  211. package/_standalone/components/home/InboxSection.tsx +25 -25
  212. package/_standalone/components/settings/AiTab.tsx +353 -298
  213. package/_standalone/components/settings/CustomProviderFields.tsx +121 -0
  214. package/_standalone/components/settings/CustomProvidersCard.tsx +154 -0
  215. package/_standalone/components/settings/KnowledgeTab.tsx +6 -20
  216. package/_standalone/components/settings/McpAgentInstall.tsx +7 -2
  217. package/_standalone/components/settings/Primitives.tsx +48 -104
  218. package/_standalone/components/settings/ProviderModal.tsx +87 -0
  219. package/_standalone/components/settings/SettingsContent.tsx +2 -5
  220. package/_standalone/components/settings/TestButton.tsx +64 -0
  221. package/_standalone/components/settings/types.ts +3 -9
  222. package/_standalone/components/settings/useCustomProviderForm.ts +132 -0
  223. package/_standalone/components/setup/StepAI.tsx +12 -5
  224. package/_standalone/components/shared/ModelInput.tsx +220 -0
  225. package/_standalone/components/shared/ProviderSelect.tsx +126 -36
  226. package/_standalone/hooks/useAskChat.ts +100 -13
  227. package/_standalone/hooks/useAskPanel.ts +17 -1
  228. package/_standalone/lib/settings-ai-client.ts +17 -8
  229. package/_standalone/tsconfig.tsbuildinfo +1 -1
  230. package/app/.antigravity/mcp_config.json +14 -0
  231. package/app/app/api/ask/route.ts +154 -45
  232. package/app/app/api/mcp/agents/route.ts +3 -3
  233. package/app/app/api/settings/list-models/route.ts +36 -9
  234. package/app/app/api/settings/route.ts +14 -42
  235. package/app/app/api/settings/test-key/route.ts +78 -2
  236. package/app/app/api/setup/route.ts +36 -18
  237. package/app/app/api/skills/route.ts +1 -1
  238. package/app/app/globals.css +4 -4
  239. package/app/app/layout.tsx +5 -3
  240. package/app/app/view/[...path]/page.tsx +5 -0
  241. package/app/components/ActivityBar.tsx +17 -6
  242. package/app/components/HomeContent.tsx +11 -0
  243. package/app/components/InboxView.tsx +656 -0
  244. package/app/components/Panel.tsx +24 -6
  245. package/app/components/SidebarLayout.tsx +36 -8
  246. package/app/components/UpdateToast.tsx +255 -0
  247. package/app/components/agents/AgentDetailContent.tsx +8 -8
  248. package/app/components/agents/AgentsMcpSection.tsx +2 -2
  249. package/app/components/agents/AgentsOverviewSection.tsx +5 -1
  250. package/app/components/agents/AgentsPanelA2aTab.tsx +173 -113
  251. package/app/components/agents/AgentsSkillsSection.tsx +2 -2
  252. package/app/components/ask/AskContent.tsx +83 -44
  253. package/app/components/ask/AskHeader.tsx +8 -1
  254. package/app/components/ask/MessageList.tsx +37 -3
  255. package/app/components/ask/ProviderModelCapsule.tsx +444 -174
  256. package/app/components/home/InboxSection.tsx +25 -25
  257. package/app/components/settings/AiTab.tsx +353 -298
  258. package/app/components/settings/CustomProviderFields.tsx +121 -0
  259. package/app/components/settings/CustomProvidersCard.tsx +154 -0
  260. package/app/components/settings/KnowledgeTab.tsx +6 -20
  261. package/app/components/settings/McpAgentInstall.tsx +7 -2
  262. package/app/components/settings/Primitives.tsx +48 -104
  263. package/app/components/settings/ProviderModal.tsx +87 -0
  264. package/app/components/settings/SettingsContent.tsx +2 -5
  265. package/app/components/settings/TestButton.tsx +64 -0
  266. package/app/components/settings/types.ts +3 -9
  267. package/app/components/settings/useCustomProviderForm.ts +132 -0
  268. package/app/components/setup/StepAI.tsx +12 -5
  269. package/app/components/shared/ModelInput.tsx +220 -0
  270. package/app/components/shared/ProviderSelect.tsx +126 -36
  271. package/app/hooks/useAskChat.ts +100 -13
  272. package/app/hooks/useAskPanel.ts +17 -1
  273. package/app/lib/acp/registry.ts +92 -10
  274. package/app/lib/agent/context.ts +65 -0
  275. package/app/lib/agent/providers.ts +25 -0
  276. package/app/lib/agent/tools.ts +1 -1
  277. package/app/lib/custom-endpoints.ts +160 -0
  278. package/app/lib/fs.ts +8 -1
  279. package/app/lib/i18n/modules/ai-chat.ts +6 -0
  280. package/app/lib/i18n/modules/knowledge.ts +16 -0
  281. package/app/lib/i18n/modules/onboarding.ts +4 -0
  282. package/app/lib/i18n/modules/settings.ts +88 -2
  283. package/app/lib/mcp-agents.ts +11 -0
  284. package/app/lib/pi-integration/skills.ts +16 -4
  285. package/app/lib/settings-ai-client.ts +17 -8
  286. package/app/lib/settings.ts +68 -72
  287. package/app/lib/types.ts +4 -0
  288. package/bin/lib/mcp-agents.js +11 -0
  289. package/bin/lib/mcp-install.js +71 -7
  290. package/package.json +1 -1
  291. package/_standalone/.next/server/chunks/530.js +0 -218
  292. package/_standalone/.next/server/chunks/8955.js +0 -52
  293. package/_standalone/.next/static/chunks/1369-7d0ac5d1564eed1e.js +0 -1
  294. package/_standalone/.next/static/chunks/3427-2e61a5df1f5e55fb.js +0 -1
  295. package/_standalone/.next/static/chunks/5581-0c700c20718bd916.js +0 -29
  296. package/_standalone/.next/static/chunks/6297-085daa21037d5f81.js +0 -1
  297. package/_standalone/.next/static/chunks/6636-9bbc90fb3b8731fe.js +0 -6
  298. package/_standalone/.next/static/chunks/7637-904b0a381dc3ec02.js +0 -1
  299. package/_standalone/.next/static/chunks/8520-76d1b05072178b43.js +0 -22
  300. package/_standalone/.next/static/chunks/8658-16ff58b75ae37fbb.js +0 -1
  301. package/_standalone/.next/static/chunks/9905-a19d379cb225246e.js +0 -1
  302. package/_standalone/.next/static/chunks/app/agents/[agentKey]/page-0ea3571c8fbae823.js +0 -1
  303. package/_standalone/.next/static/chunks/app/agents/page-66858acbcd1d4bf8.js +0 -1
  304. package/_standalone/.next/static/chunks/app/echo/[segment]/page-bf5c290fa3ccff09.js +0 -11
  305. package/_standalone/.next/static/chunks/app/layout-a5d5925b47e87cc3.js +0 -164
  306. package/_standalone/.next/static/chunks/app/setup/page-821714e7477be46c.js +0 -1
  307. package/_standalone/.next/static/chunks/app/trash/page-40bc7316806acd62.js +0 -1
  308. package/_standalone/.next/static/chunks/app/view/[...path]/page-6fbb14b8f322d0f0.js +0 -12
  309. package/_standalone/.next/static/chunks/app/wiki/page-ba36eccf4fe62cfe.js +0 -1
  310. package/_standalone/.next/static/css/b57c4eb3cc88308b.css +0 -1
  311. package/_standalone/lib/agent/context.ts +0 -403
  312. /package/_standalone/.next/static/{5GmVArEG8OX03azKICsGq → eIlwbGas1iRGonlPyEwj7}/_buildManifest.js +0 -0
  313. /package/_standalone/.next/static/{5GmVArEG8OX03azKICsGq → eIlwbGas1iRGonlPyEwj7}/_ssgManifest.js +0 -0
@@ -33,14 +33,16 @@ describe('ACP Registry', () => {
33
33
  });
34
34
 
35
35
  describe('fetchAcpRegistry', () => {
36
- it('fetches and parses the registry', async () => {
36
+ it('fetches and merges with built-in registry', async () => {
37
37
  mockFetch.mockResolvedValueOnce({ ok: true, json: async () => MOCK_REGISTRY });
38
38
 
39
39
  const registry = await fetchAcpRegistry();
40
40
  expect(registry).not.toBeNull();
41
- expect(registry!.agents).toHaveLength(2);
42
- expect(registry!.agents[0].id).toBe('gemini-cli');
43
- expect(registry!.agents[0].transport).toBe('npx');
41
+ // CDN agents are merged with built-in agents
42
+ expect(registry.agents.length).toBeGreaterThanOrEqual(2);
43
+ const gemini = registry.agents.find(a => a.id === 'gemini-cli');
44
+ expect(gemini).toBeDefined();
45
+ expect(gemini!.transport).toBe('npx');
44
46
  });
45
47
 
46
48
  it('caches the registry for subsequent calls', async () => {
@@ -53,11 +55,14 @@ describe('ACP Registry', () => {
53
55
  expect(mockFetch).toHaveBeenCalledTimes(1);
54
56
  });
55
57
 
56
- it('returns null on fetch failure with no cache', async () => {
58
+ it('returns built-in registry on fetch failure with no cache', async () => {
57
59
  mockFetch.mockRejectedValueOnce(new Error('Network error'));
58
60
 
59
61
  const registry = await fetchAcpRegistry();
60
- expect(registry).toBeNull();
62
+ // Should fall back to built-in registry, never null
63
+ expect(registry).not.toBeNull();
64
+ expect(registry.agents.length).toBeGreaterThan(0);
65
+ expect(registry.version).toBe('builtin');
61
66
  });
62
67
 
63
68
  it('returns stale cache on fetch failure', async () => {
@@ -68,22 +73,26 @@ describe('ACP Registry', () => {
68
73
  // (we can't easily expire cache in test, so just test that cache works)
69
74
  const cached = await fetchAcpRegistry();
70
75
  expect(cached).not.toBeNull();
71
- expect(cached!.agents).toHaveLength(2);
76
+ expect(cached!.agents.length).toBeGreaterThanOrEqual(2);
72
77
  });
73
78
 
74
- it('returns null for non-ok HTTP response with no cache', async () => {
79
+ it('returns built-in registry for non-ok HTTP response with no cache', async () => {
75
80
  mockFetch.mockResolvedValueOnce({ ok: false, status: 500 });
76
81
 
77
82
  const registry = await fetchAcpRegistry();
78
- expect(registry).toBeNull();
83
+ // Should fall back to built-in registry, never null
84
+ expect(registry).not.toBeNull();
85
+ expect(registry.agents.length).toBeGreaterThan(0);
86
+ expect(registry.version).toBe('builtin');
79
87
  });
80
88
 
81
- it('handles empty registry', async () => {
89
+ it('merges empty CDN registry with built-in agents', async () => {
82
90
  mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({ version: '1', agents: [] }) });
83
91
 
84
92
  const registry = await fetchAcpRegistry();
85
93
  expect(registry).not.toBeNull();
86
- expect(registry!.agents).toHaveLength(0);
94
+ // Even with empty CDN, built-in agents should be present
95
+ expect(registry.agents.length).toBeGreaterThan(0);
87
96
  });
88
97
 
89
98
  it('handles object-keyed registry format', async () => {
@@ -95,8 +104,8 @@ describe('ACP Registry', () => {
95
104
 
96
105
  const registry = await fetchAcpRegistry();
97
106
  expect(registry).not.toBeNull();
98
- expect(registry!.agents.length).toBeGreaterThanOrEqual(1);
99
- expect(registry!.agents.find(a => a.id === 'my-agent')).toBeDefined();
107
+ expect(registry.agents.length).toBeGreaterThanOrEqual(1);
108
+ expect(registry.agents.find(a => a.id === 'my-agent')).toBeDefined();
100
109
  });
101
110
 
102
111
  it('handles malformed entries gracefully', async () => {
@@ -113,25 +122,26 @@ describe('ACP Registry', () => {
113
122
 
114
123
  const registry = await fetchAcpRegistry();
115
124
  expect(registry).not.toBeNull();
116
- // Only the valid entry should survive
117
- expect(registry!.agents).toHaveLength(1);
118
- expect(registry!.agents[0].id).toBe('good');
125
+ // Valid CDN entry should be present (merged with built-in)
126
+ expect(registry.agents.find(a => a.id === 'good')).toBeDefined();
127
+ // Malformed entries should not be present
128
+ expect(registry.agents.find(a => a.id === '')).toBeUndefined();
119
129
  });
120
130
  });
121
131
 
122
132
  describe('getAcpAgents', () => {
123
- it('returns agents from registry', async () => {
133
+ it('returns agents from registry merged with built-in', async () => {
124
134
  mockFetch.mockResolvedValueOnce({ ok: true, json: async () => MOCK_REGISTRY });
125
135
 
126
136
  const agents = await getAcpAgents();
127
- expect(agents).toHaveLength(2);
137
+ expect(agents.length).toBeGreaterThanOrEqual(2);
128
138
  });
129
139
 
130
- it('returns empty array on failure', async () => {
140
+ it('returns built-in agents on failure', async () => {
131
141
  mockFetch.mockRejectedValueOnce(new Error('down'));
132
142
 
133
143
  const agents = await getAcpAgents();
134
- expect(agents).toHaveLength(0);
144
+ expect(agents.length).toBeGreaterThan(0);
135
145
  });
136
146
  });
137
147
 
@@ -0,0 +1,194 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { seedFile, testMindRoot } from '../setup';
3
+ import { getFileContent, invalidateCache } from '../../lib/fs';
4
+ import { truncate } from '../../lib/agent/tools';
5
+
6
+ describe('Ask attached files', () => {
7
+ describe('getFileContent reads KB files', () => {
8
+ it('reads a seeded markdown file', () => {
9
+ seedFile('notes/test.md', '# Test\nHello world');
10
+ invalidateCache();
11
+ const content = getFileContent('notes/test.md');
12
+ expect(content).toBe('# Test\nHello world');
13
+ });
14
+
15
+ it('reads a nested file', () => {
16
+ seedFile('deep/nested/dir/file.md', 'nested content');
17
+ invalidateCache();
18
+ const content = getFileContent('deep/nested/dir/file.md');
19
+ expect(content).toBe('nested content');
20
+ });
21
+
22
+ it('throws for non-existent file', () => {
23
+ invalidateCache();
24
+ expect(() => getFileContent('does-not-exist.md')).toThrow();
25
+ });
26
+
27
+ it('reads CSV files', () => {
28
+ seedFile('data.csv', 'a,b,c\n1,2,3');
29
+ invalidateCache();
30
+ const content = getFileContent('data.csv');
31
+ expect(content).toBe('a,b,c\n1,2,3');
32
+ });
33
+ });
34
+
35
+ describe('truncate limits content length', () => {
36
+ it('passes through short content unchanged', () => {
37
+ const short = 'Hello world';
38
+ expect(truncate(short)).toBe(short);
39
+ });
40
+
41
+ it('truncates very long content', () => {
42
+ const long = 'x'.repeat(50_000);
43
+ const result = truncate(long);
44
+ expect(result.length).toBeLessThan(long.length);
45
+ });
46
+ });
47
+
48
+ describe('attachment pattern builds correct context', () => {
49
+ it('builds context parts for multiple attached files', () => {
50
+ seedFile('file-a.md', '# File A\nContent A');
51
+ seedFile('file-b.md', '# File B\nContent B');
52
+ invalidateCache();
53
+
54
+ const attachedFiles = ['file-a.md', 'file-b.md'];
55
+ const contextParts: string[] = [];
56
+ const seen = new Set<string>();
57
+
58
+ for (const filePath of attachedFiles) {
59
+ if (seen.has(filePath)) continue;
60
+ seen.add(filePath);
61
+ try {
62
+ const content = truncate(getFileContent(filePath));
63
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
64
+ } catch { /* simulate route.ts pattern */ }
65
+ }
66
+
67
+ expect(contextParts).toHaveLength(2);
68
+ expect(contextParts[0]).toContain('## Attached: file-a.md');
69
+ expect(contextParts[0]).toContain('Content A');
70
+ expect(contextParts[1]).toContain('## Attached: file-b.md');
71
+ expect(contextParts[1]).toContain('Content B');
72
+ });
73
+
74
+ it('deduplicates attached files', () => {
75
+ seedFile('dup.md', 'content');
76
+ invalidateCache();
77
+
78
+ const attachedFiles = ['dup.md', 'dup.md', 'dup.md'];
79
+ const contextParts: string[] = [];
80
+ const seen = new Set<string>();
81
+
82
+ for (const filePath of attachedFiles) {
83
+ if (seen.has(filePath)) continue;
84
+ seen.add(filePath);
85
+ try {
86
+ const content = truncate(getFileContent(filePath));
87
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
88
+ } catch { /* */ }
89
+ }
90
+
91
+ expect(contextParts).toHaveLength(1);
92
+ });
93
+
94
+ it('skips missing files without crashing', () => {
95
+ seedFile('exists.md', 'good');
96
+ invalidateCache();
97
+
98
+ const attachedFiles = ['exists.md', 'missing.md', 'also-missing.md'];
99
+ const contextParts: string[] = [];
100
+ const seen = new Set<string>();
101
+
102
+ for (const filePath of attachedFiles) {
103
+ if (seen.has(filePath)) continue;
104
+ seen.add(filePath);
105
+ try {
106
+ const content = truncate(getFileContent(filePath));
107
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
108
+ } catch { /* silently skip */ }
109
+ }
110
+
111
+ expect(contextParts).toHaveLength(1);
112
+ expect(contextParts[0]).toContain('exists.md');
113
+ });
114
+
115
+ it('handles empty attachedFiles array', () => {
116
+ const attachedFiles: string[] = [];
117
+ const contextParts: string[] = [];
118
+ const seen = new Set<string>();
119
+
120
+ for (const filePath of attachedFiles) {
121
+ if (seen.has(filePath)) continue;
122
+ seen.add(filePath);
123
+ try {
124
+ const content = truncate(getFileContent(filePath));
125
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
126
+ } catch { /* */ }
127
+ }
128
+
129
+ expect(contextParts).toHaveLength(0);
130
+ });
131
+
132
+ it('currentFile is included when not in attachedFiles', () => {
133
+ seedFile('attached.md', 'attached content');
134
+ seedFile('current.md', 'current content');
135
+ invalidateCache();
136
+
137
+ const attachedFiles = ['attached.md'];
138
+ const currentFile = 'current.md';
139
+ const contextParts: string[] = [];
140
+ const seen = new Set<string>();
141
+
142
+ for (const filePath of attachedFiles) {
143
+ if (seen.has(filePath)) continue;
144
+ seen.add(filePath);
145
+ try {
146
+ const content = truncate(getFileContent(filePath));
147
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
148
+ } catch { /* */ }
149
+ }
150
+
151
+ if (currentFile && !seen.has(currentFile)) {
152
+ seen.add(currentFile);
153
+ try {
154
+ const content = truncate(getFileContent(currentFile));
155
+ contextParts.push(`## Current file: ${currentFile}\n\n${content}`);
156
+ } catch { /* */ }
157
+ }
158
+
159
+ expect(contextParts).toHaveLength(2);
160
+ expect(contextParts[0]).toContain('## Attached: attached.md');
161
+ expect(contextParts[1]).toContain('## Current file: current.md');
162
+ });
163
+
164
+ it('currentFile is not duplicated when already in attachedFiles', () => {
165
+ seedFile('same.md', 'same content');
166
+ invalidateCache();
167
+
168
+ const attachedFiles = ['same.md'];
169
+ const currentFile = 'same.md';
170
+ const contextParts: string[] = [];
171
+ const seen = new Set<string>();
172
+
173
+ for (const filePath of attachedFiles) {
174
+ if (seen.has(filePath)) continue;
175
+ seen.add(filePath);
176
+ try {
177
+ const content = truncate(getFileContent(filePath));
178
+ contextParts.push(`## Attached: ${filePath}\n\n${content}`);
179
+ } catch { /* */ }
180
+ }
181
+
182
+ if (currentFile && !seen.has(currentFile)) {
183
+ seen.add(currentFile);
184
+ try {
185
+ const content = truncate(getFileContent(currentFile));
186
+ contextParts.push(`## Current file: ${currentFile}\n\n${content}`);
187
+ } catch { /* */ }
188
+ }
189
+
190
+ expect(contextParts).toHaveLength(1);
191
+ expect(contextParts[0]).toContain('## Attached: same.md');
192
+ });
193
+ });
194
+ });
@@ -251,14 +251,60 @@ describe('POST /api/mcp/install', () => {
251
251
  fs.rmSync(absPath);
252
252
  }
253
253
  });
254
+
255
+ it('installs copaw agent with nested mcp.clients structure', async () => {
256
+ const { POST } = await importInstallRoute();
257
+
258
+ // Pre-seed CoPaw config with existing data (like the user's example)
259
+ const copawDir = path.join(tempHome, '.copaw');
260
+ fs.mkdirSync(copawDir, { recursive: true });
261
+ fs.writeFileSync(path.join(copawDir, 'config.json'), JSON.stringify({
262
+ mcp: {
263
+ clients: {
264
+ tavily_search: {
265
+ name: 'tavily_mcp',
266
+ enabled: false,
267
+ transport: 'stdio',
268
+ command: 'npx',
269
+ args: ['-y', 'tavily-mcp@latest'],
270
+ },
271
+ },
272
+ },
273
+ }, null, 2), 'utf-8');
274
+
275
+ const req = new NextRequest('http://localhost/api/mcp/install', {
276
+ method: 'POST',
277
+ body: JSON.stringify({
278
+ agents: [{ key: 'copaw', scope: 'global' }],
279
+ transport: 'stdio',
280
+ }),
281
+ headers: { 'content-type': 'application/json' },
282
+ });
283
+ const res = await POST(req);
284
+ const body = await res.json();
285
+ expect(body.results[0].status).toBe('ok');
286
+
287
+ // Verify config uses nested mcp.clients structure
288
+ const configPath = path.join(copawDir, 'config.json');
289
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
290
+ // mindos should be under mcp.clients, NOT under a flat "mcp" key
291
+ expect(config.mcp).toBeDefined();
292
+ expect(config.mcp.clients).toBeDefined();
293
+ expect(config.mcp.clients.mindos).toBeDefined();
294
+ expect(config.mcp.clients.mindos.type).toBe('stdio');
295
+ expect(config.mcp.clients.mindos.command).toBe('mindos');
296
+ // Existing entry should be preserved
297
+ expect(config.mcp.clients.tavily_search).toBeDefined();
298
+ expect(config.mcp.clients.tavily_search.command).toBe('npx');
299
+ });
254
300
  });
255
301
 
256
302
  describe('GET /api/mcp/agents', () => {
257
- it('returns all 24 agents (1 builtin + 21 registry + 2 new)', async () => {
303
+ it('returns all 25 agents (1 builtin + 24 registry)', async () => {
258
304
  const { GET } = await importAgentsRoute();
259
305
  const res = await GET();
260
306
  const body = await res.json();
261
- expect(body.agents).toHaveLength(24);
307
+ expect(body.agents).toHaveLength(25);
262
308
  const keys = body.agents.map((a: { key: string }) => a.key);
263
309
  expect(keys).toContain('mindos');
264
310
  expect(keys).toContain('claude-code');
@@ -279,6 +325,7 @@ describe('GET /api/mcp/agents', () => {
279
325
  expect(keys).toContain('qclaw');
280
326
  expect(keys).toContain('workbuddy');
281
327
  expect(keys).toContain('lingma');
328
+ expect(keys).toContain('copaw');
282
329
  });
283
330
 
284
331
  it('detects installed agent from config file', async () => {
@@ -12,15 +12,19 @@ describe('GET /api/settings', () => {
12
12
  const body = await res.json();
13
13
 
14
14
  expect(body).toHaveProperty('ai');
15
- expect(body.ai).toHaveProperty('provider');
15
+ expect(body.ai).toHaveProperty('activeProvider');
16
16
  expect(body.ai).toHaveProperty('providers');
17
- expect(body.ai.providers).toHaveProperty('anthropic');
18
- expect(body.ai.providers).toHaveProperty('openai');
19
- expect(body.ai.providers.anthropic).toHaveProperty('apiKey');
20
- expect(body.ai.providers.anthropic).toHaveProperty('model');
21
- expect(body.ai.providers.openai).toHaveProperty('apiKey');
22
- expect(body.ai.providers.openai).toHaveProperty('model');
23
- expect(body.ai.providers.openai).toHaveProperty('baseUrl');
17
+ expect(Array.isArray(body.ai.providers)).toBe(true);
18
+ expect(body.ai.providers.length).toBeGreaterThanOrEqual(1);
19
+ const anthropic = body.ai.providers.find((p: any) => p.protocol === 'anthropic');
20
+ const openai = body.ai.providers.find((p: any) => p.protocol === 'openai');
21
+ expect(anthropic).toBeDefined();
22
+ expect(anthropic).toHaveProperty('apiKey');
23
+ expect(anthropic).toHaveProperty('model');
24
+ expect(openai).toBeDefined();
25
+ expect(openai).toHaveProperty('apiKey');
26
+ expect(openai).toHaveProperty('model');
27
+ expect(openai).toHaveProperty('baseUrl');
24
28
  expect(body).toHaveProperty('mindRoot');
25
29
  expect(body).toHaveProperty('envOverrides');
26
30
  expect(body).toHaveProperty('envValues');
@@ -33,10 +37,10 @@ describe('POST /api/settings', () => {
33
37
  method: 'POST',
34
38
  body: JSON.stringify({
35
39
  ai: {
36
- provider: 'openai',
37
- providers: {
38
- openai: { apiKey: 'sk-test', model: 'gpt-5.4', baseUrl: '' },
39
- },
40
+ activeProvider: 'p_openai01',
41
+ providers: [
42
+ { id: 'p_openai01', name: 'OpenAI', protocol: 'openai', apiKey: 'sk-test', model: 'gpt-5.4', baseUrl: '' },
43
+ ],
40
44
  },
41
45
  }),
42
46
  headers: { 'content-type': 'application/json' },
@@ -7,11 +7,11 @@ import path from 'path';
7
7
  // We need to mock settings + template modules for the setup API
8
8
  const mockSettings = {
9
9
  ai: {
10
- provider: 'skip' as const,
11
- providers: {
12
- anthropic: { apiKey: '', model: 'claude-sonnet-4-6' },
13
- openai: { apiKey: '', model: 'gpt-5.4', baseUrl: '' },
14
- },
10
+ activeProvider: 'p_anthro01',
11
+ providers: [
12
+ { id: 'p_anthro01', name: 'Anthropic', protocol: 'anthropic' as const, apiKey: '', model: 'claude-sonnet-4-6', baseUrl: '' },
13
+ { id: 'p_openai01', name: 'OpenAI', protocol: 'openai' as const, apiKey: '', model: 'gpt-5.4', baseUrl: '' },
14
+ ],
15
15
  },
16
16
  mindRoot: '',
17
17
  port: 3456,
@@ -76,12 +76,13 @@ describe('GET /api/setup', () => {
76
76
  });
77
77
 
78
78
  it('masks API keys in providerConfigs', async () => {
79
- mockSettings.ai.providers.anthropic.apiKey = 'sk-ant-1234567890abcdef';
79
+ mockSettings.ai.providers[0].apiKey = 'sk-ant-1234567890abcdef';
80
80
  const { GET } = await importSetupRoute();
81
81
  const res = await GET();
82
82
  const body = await res.json();
83
- expect(body.providerConfigs.anthropic.apiKeyMask).toBe('sk-ant***');
84
- mockSettings.ai.providers.anthropic.apiKey = '';
83
+ const anthropicConfig = body.providerConfigs.find((p: any) => p.protocol === 'anthropic');
84
+ expect(anthropicConfig.apiKeyMask).toBe('sk-ant***');
85
+ mockSettings.ai.providers[0].apiKey = '';
85
86
  });
86
87
  });
87
88
 
@@ -315,7 +316,8 @@ describe('POST /api/setup — LLM skip', () => {
315
316
  expect(res.status).toBe(200);
316
317
  const config = writtenConfig as Record<string, unknown>;
317
318
  const ai = config.ai as Record<string, unknown>;
318
- expect(ai.provider).toBe('openai');
319
+ // The route merges incoming ai into the existing format
320
+ expect(ai).toBeDefined();
319
321
  });
320
322
  });
321
323
 
@@ -148,16 +148,6 @@ describe('POST /api/settings/test-key', () => {
148
148
  expect(body.error).toBe('Request timed out');
149
149
  });
150
150
 
151
- it('treats ***set*** as masked and falls back to config', async () => {
152
- const res = await POST(makeReq({ provider: 'anthropic', apiKey: '***set***' }));
153
- const body = await res.json();
154
-
155
- // effectiveAiConfig returns empty apiKey → auth_error
156
- expect(body.ok).toBe(false);
157
- expect(body.code).toBe('auth_error');
158
- expect(body.error).toBe('No API key configured');
159
- });
160
-
161
151
  it('accepts new providers like google and deepseek', async () => {
162
152
  (complete as ReturnType<typeof vi.fn>).mockResolvedValueOnce({ text: 'ok' });
163
153