@seqyuan/annodex 0.1.10 → 0.1.12

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 (519) hide show
  1. package/app/api/agent/[id]/events/route.ts +94 -0
  2. package/app/api/agent/[id]/route.ts +83 -0
  3. package/app/api/agent/new/route.ts +53 -0
  4. package/app/api/auth/all-providers/route.ts +21 -0
  5. package/app/api/auth/api-key/[provider]/route.ts +7 -0
  6. package/app/api/auth/login/[provider]/route.ts +7 -0
  7. package/app/api/auth/login/route.ts +22 -0
  8. package/app/api/auth/logout/[provider]/route.ts +7 -0
  9. package/app/api/auth/providers/route.ts +15 -0
  10. package/app/api/auth/status/route.ts +6 -0
  11. package/app/api/default-cwd/route.ts +22 -0
  12. package/app/api/files/[...path]/route.ts +621 -0
  13. package/app/api/harness/route.ts +47 -0
  14. package/app/api/home/route.ts +6 -0
  15. package/app/api/internal/runtime/route.ts +26 -0
  16. package/app/api/models/route.ts +67 -0
  17. package/app/api/models-config/discover/route.ts +42 -0
  18. package/app/api/models-config/route.ts +152 -0
  19. package/app/api/models-config/test/route.ts +154 -0
  20. package/app/api/projects/browse/route.ts +51 -0
  21. package/app/api/projects/route.ts +83 -0
  22. package/app/api/reports/[id]/route.ts +108 -0
  23. package/app/api/search/route.ts +122 -0
  24. package/app/api/sessions/[id]/context/route.ts +23 -0
  25. package/app/api/sessions/[id]/route.ts +124 -0
  26. package/app/api/sessions/new/route.ts +5 -0
  27. package/app/api/sessions/route.ts +16 -0
  28. package/app/api/settings/route.ts +51 -0
  29. package/app/api/skills/install/route.ts +249 -0
  30. package/app/api/skills/route.ts +161 -0
  31. package/app/api/skills/search/route.ts +121 -0
  32. package/app/api/soul/route.ts +47 -0
  33. package/app/api/version/route.ts +55 -0
  34. package/app/globals.css +736 -0
  35. package/app/layout.tsx +40 -0
  36. package/app/login/page.tsx +133 -0
  37. package/app/page.tsx +10 -0
  38. package/components/AppShell.tsx +1058 -0
  39. package/components/ChatInput.tsx +1103 -0
  40. package/components/ChatMinimap.tsx +381 -0
  41. package/components/ChatWindow.tsx +576 -0
  42. package/components/CodeMirrorEditor.tsx +137 -0
  43. package/components/ConversationSearch.tsx +369 -0
  44. package/components/DataTableViewer.tsx +248 -0
  45. package/components/FileExplorer.tsx +758 -0
  46. package/components/FileIcons.tsx +241 -0
  47. package/components/FileViewer.tsx +1273 -0
  48. package/components/GlobalFileEditor.tsx +98 -0
  49. package/components/MarkdownRenderer.tsx +331 -0
  50. package/components/MermaidDiagram.tsx +80 -0
  51. package/components/MessageView.tsx +1141 -0
  52. package/components/ModelsConfig.tsx +1991 -0
  53. package/components/ProjectContext.tsx +252 -0
  54. package/components/ProjectFolderPicker.tsx +202 -0
  55. package/components/ProjectsConfig.tsx +288 -0
  56. package/components/ProviderIcons.tsx +91 -0
  57. package/components/ReportPanel.tsx +237 -0
  58. package/components/ResizeHandle.tsx +105 -0
  59. package/components/SessionSidebar.tsx +1464 -0
  60. package/components/SettingsDialog.tsx +287 -0
  61. package/components/SkillsConfig.tsx +1093 -0
  62. package/components/SubagentPanel.tsx +191 -0
  63. package/components/TabBar.tsx +115 -0
  64. package/components/ToolPanel.tsx +131 -0
  65. package/components/WidgetRenderer.tsx +505 -0
  66. package/components/viewers/DocumentToolbar.tsx +78 -0
  67. package/components/viewers/DocxViewer.tsx +97 -0
  68. package/components/viewers/PdfViewer.tsx +206 -0
  69. package/components/viewers/PptxViewer.tsx +240 -0
  70. package/components/viewers/XlsxViewer.tsx +143 -0
  71. package/hooks/useAgentSession.ts +710 -0
  72. package/hooks/useAudio.ts +50 -0
  73. package/hooks/useDragDrop.ts +52 -0
  74. package/hooks/useResizable.ts +60 -0
  75. package/hooks/useTheme.ts +85 -0
  76. package/lib/agent-client.ts +39 -0
  77. package/lib/annodex-config.ts +556 -0
  78. package/lib/auth-token.ts +74 -0
  79. package/lib/auth.ts +90 -0
  80. package/lib/brand.ts +5 -0
  81. package/lib/code-theme.ts +32 -0
  82. package/lib/codex-compat-proxy.ts +1603 -0
  83. package/lib/codex-home.ts +6 -0
  84. package/lib/codex-server.ts +796 -0
  85. package/lib/codex-session.ts +590 -0
  86. package/lib/codex-usage.ts +213 -0
  87. package/lib/file-paths.ts +34 -0
  88. package/lib/model-discovery.ts +379 -0
  89. package/lib/normalize.ts +30 -0
  90. package/lib/npx.ts +87 -0
  91. package/lib/pi-types.ts +49 -0
  92. package/lib/projects.ts +269 -0
  93. package/lib/provider-api.ts +88 -0
  94. package/lib/report-prompt.ts +61 -0
  95. package/lib/report-store.ts +597 -0
  96. package/lib/report-update-parser.ts +66 -0
  97. package/lib/rpc-manager.ts +668 -0
  98. package/lib/runtime-state.ts +117 -0
  99. package/lib/session-reader.ts +903 -0
  100. package/lib/session-runtime.ts +105 -0
  101. package/lib/subagent-progress.ts +279 -0
  102. package/lib/types.ts +241 -0
  103. package/lib/widget-export.ts +318 -0
  104. package/lib/widget-guidelines.ts +288 -0
  105. package/lib/widget-prompt.ts +76 -0
  106. package/lib/widget-utils.ts +523 -0
  107. package/package.json +23 -18
  108. package/postcss.config.mjs +8 -0
  109. package/proxy.ts +64 -0
  110. package/scripts/postinstall.cjs +25 -0
  111. package/tsconfig.json +41 -0
  112. package/.next/BUILD_ID +0 -1
  113. package/.next/app-path-routes-manifest.json +0 -39
  114. package/.next/build-manifest.json +0 -20
  115. package/.next/diagnostics/build-diagnostics.json +0 -6
  116. package/.next/diagnostics/framework.json +0 -1
  117. package/.next/export-marker.json +0 -6
  118. package/.next/images-manifest.json +0 -68
  119. package/.next/next-minimal-server.js.nft.json +0 -1
  120. package/.next/next-server.js.nft.json +0 -1
  121. package/.next/package.json +0 -1
  122. package/.next/prerender-manifest.json +0 -109
  123. package/.next/react-loadable-manifest.json +0 -2320
  124. package/.next/required-server-files.js +0 -343
  125. package/.next/required-server-files.json +0 -343
  126. package/.next/routes-manifest.json +0 -286
  127. package/.next/server/app/_global-error/page.js +0 -32
  128. package/.next/server/app/_global-error/page.js.nft.json +0 -1
  129. package/.next/server/app/_global-error/page_client-reference-manifest.js +0 -1
  130. package/.next/server/app/_global-error.html +0 -1
  131. package/.next/server/app/_global-error.meta +0 -16
  132. package/.next/server/app/_global-error.rsc +0 -14
  133. package/.next/server/app/_global-error.segments/_full.segment.rsc +0 -14
  134. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +0 -5
  135. package/.next/server/app/_global-error.segments/_global-error.segment.rsc +0 -5
  136. package/.next/server/app/_global-error.segments/_head.segment.rsc +0 -5
  137. package/.next/server/app/_global-error.segments/_index.segment.rsc +0 -5
  138. package/.next/server/app/_global-error.segments/_tree.segment.rsc +0 -1
  139. package/.next/server/app/_not-found/page.js +0 -2
  140. package/.next/server/app/_not-found/page.js.nft.json +0 -1
  141. package/.next/server/app/_not-found/page_client-reference-manifest.js +0 -1
  142. package/.next/server/app/_not-found.html +0 -1
  143. package/.next/server/app/_not-found.meta +0 -16
  144. package/.next/server/app/_not-found.rsc +0 -18
  145. package/.next/server/app/_not-found.segments/_full.segment.rsc +0 -18
  146. package/.next/server/app/_not-found.segments/_head.segment.rsc +0 -6
  147. package/.next/server/app/_not-found.segments/_index.segment.rsc +0 -5
  148. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +0 -5
  149. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +0 -5
  150. package/.next/server/app/_not-found.segments/_tree.segment.rsc +0 -4
  151. package/.next/server/app/api/agent/[id]/events/route.js +0 -3
  152. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +0 -1
  153. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +0 -1
  154. package/.next/server/app/api/agent/[id]/route.js +0 -1
  155. package/.next/server/app/api/agent/[id]/route.js.nft.json +0 -1
  156. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +0 -1
  157. package/.next/server/app/api/agent/new/route.js +0 -1
  158. package/.next/server/app/api/agent/new/route.js.nft.json +0 -1
  159. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +0 -1
  160. package/.next/server/app/api/auth/all-providers/route.js +0 -1
  161. package/.next/server/app/api/auth/all-providers/route.js.nft.json +0 -1
  162. package/.next/server/app/api/auth/all-providers/route_client-reference-manifest.js +0 -1
  163. package/.next/server/app/api/auth/api-key/[provider]/route.js +0 -1
  164. package/.next/server/app/api/auth/api-key/[provider]/route.js.nft.json +0 -1
  165. package/.next/server/app/api/auth/api-key/[provider]/route_client-reference-manifest.js +0 -1
  166. package/.next/server/app/api/auth/login/[provider]/route.js +0 -1
  167. package/.next/server/app/api/auth/login/[provider]/route.js.nft.json +0 -1
  168. package/.next/server/app/api/auth/login/[provider]/route_client-reference-manifest.js +0 -1
  169. package/.next/server/app/api/auth/login/route.js +0 -1
  170. package/.next/server/app/api/auth/login/route.js.nft.json +0 -1
  171. package/.next/server/app/api/auth/login/route_client-reference-manifest.js +0 -1
  172. package/.next/server/app/api/auth/logout/[provider]/route.js +0 -1
  173. package/.next/server/app/api/auth/logout/[provider]/route.js.nft.json +0 -1
  174. package/.next/server/app/api/auth/logout/[provider]/route_client-reference-manifest.js +0 -1
  175. package/.next/server/app/api/auth/providers/route.js +0 -1
  176. package/.next/server/app/api/auth/providers/route.js.nft.json +0 -1
  177. package/.next/server/app/api/auth/providers/route_client-reference-manifest.js +0 -1
  178. package/.next/server/app/api/auth/status/route.js +0 -1
  179. package/.next/server/app/api/auth/status/route.js.nft.json +0 -1
  180. package/.next/server/app/api/auth/status/route_client-reference-manifest.js +0 -1
  181. package/.next/server/app/api/default-cwd/route.js +0 -1
  182. package/.next/server/app/api/default-cwd/route.js.nft.json +0 -1
  183. package/.next/server/app/api/default-cwd/route_client-reference-manifest.js +0 -1
  184. package/.next/server/app/api/files/[...path]/route.js +0 -4
  185. package/.next/server/app/api/files/[...path]/route.js.nft.json +0 -1
  186. package/.next/server/app/api/files/[...path]/route_client-reference-manifest.js +0 -1
  187. package/.next/server/app/api/harness/route.js +0 -1
  188. package/.next/server/app/api/harness/route.js.nft.json +0 -1
  189. package/.next/server/app/api/harness/route_client-reference-manifest.js +0 -1
  190. package/.next/server/app/api/home/route.js +0 -1
  191. package/.next/server/app/api/home/route.js.nft.json +0 -1
  192. package/.next/server/app/api/home/route_client-reference-manifest.js +0 -1
  193. package/.next/server/app/api/internal/runtime/route.js +0 -1
  194. package/.next/server/app/api/internal/runtime/route.js.nft.json +0 -1
  195. package/.next/server/app/api/internal/runtime/route_client-reference-manifest.js +0 -1
  196. package/.next/server/app/api/models/route.js +0 -1
  197. package/.next/server/app/api/models/route.js.nft.json +0 -1
  198. package/.next/server/app/api/models/route_client-reference-manifest.js +0 -1
  199. package/.next/server/app/api/models-config/discover/route.js +0 -1
  200. package/.next/server/app/api/models-config/discover/route.js.nft.json +0 -1
  201. package/.next/server/app/api/models-config/discover/route_client-reference-manifest.js +0 -1
  202. package/.next/server/app/api/models-config/route.js +0 -1
  203. package/.next/server/app/api/models-config/route.js.nft.json +0 -1
  204. package/.next/server/app/api/models-config/route_client-reference-manifest.js +0 -1
  205. package/.next/server/app/api/models-config/test/route.js +0 -1
  206. package/.next/server/app/api/models-config/test/route.js.nft.json +0 -1
  207. package/.next/server/app/api/models-config/test/route_client-reference-manifest.js +0 -1
  208. package/.next/server/app/api/projects/browse/route.js +0 -1
  209. package/.next/server/app/api/projects/browse/route.js.nft.json +0 -1
  210. package/.next/server/app/api/projects/browse/route_client-reference-manifest.js +0 -1
  211. package/.next/server/app/api/projects/route.js +0 -1
  212. package/.next/server/app/api/projects/route.js.nft.json +0 -1
  213. package/.next/server/app/api/projects/route_client-reference-manifest.js +0 -1
  214. package/.next/server/app/api/reports/[id]/route.js +0 -10
  215. package/.next/server/app/api/reports/[id]/route.js.nft.json +0 -1
  216. package/.next/server/app/api/reports/[id]/route_client-reference-manifest.js +0 -1
  217. package/.next/server/app/api/search/route.js +0 -1
  218. package/.next/server/app/api/search/route.js.nft.json +0 -1
  219. package/.next/server/app/api/search/route_client-reference-manifest.js +0 -1
  220. package/.next/server/app/api/sessions/[id]/context/route.js +0 -1
  221. package/.next/server/app/api/sessions/[id]/context/route.js.nft.json +0 -1
  222. package/.next/server/app/api/sessions/[id]/context/route_client-reference-manifest.js +0 -1
  223. package/.next/server/app/api/sessions/[id]/route.js +0 -1
  224. package/.next/server/app/api/sessions/[id]/route.js.nft.json +0 -1
  225. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +0 -1
  226. package/.next/server/app/api/sessions/new/route.js +0 -1
  227. package/.next/server/app/api/sessions/new/route.js.nft.json +0 -1
  228. package/.next/server/app/api/sessions/new/route_client-reference-manifest.js +0 -1
  229. package/.next/server/app/api/sessions/route.js +0 -1
  230. package/.next/server/app/api/sessions/route.js.nft.json +0 -1
  231. package/.next/server/app/api/sessions/route_client-reference-manifest.js +0 -1
  232. package/.next/server/app/api/settings/route.js +0 -1
  233. package/.next/server/app/api/settings/route.js.nft.json +0 -1
  234. package/.next/server/app/api/settings/route_client-reference-manifest.js +0 -1
  235. package/.next/server/app/api/skills/install/route.js +0 -5
  236. package/.next/server/app/api/skills/install/route.js.nft.json +0 -1
  237. package/.next/server/app/api/skills/install/route_client-reference-manifest.js +0 -1
  238. package/.next/server/app/api/skills/route.js +0 -6
  239. package/.next/server/app/api/skills/route.js.nft.json +0 -1
  240. package/.next/server/app/api/skills/route_client-reference-manifest.js +0 -1
  241. package/.next/server/app/api/skills/search/route.js +0 -1
  242. package/.next/server/app/api/skills/search/route.js.nft.json +0 -1
  243. package/.next/server/app/api/skills/search/route_client-reference-manifest.js +0 -1
  244. package/.next/server/app/api/soul/route.js +0 -1
  245. package/.next/server/app/api/soul/route.js.nft.json +0 -1
  246. package/.next/server/app/api/soul/route_client-reference-manifest.js +0 -1
  247. package/.next/server/app/api/version/route.js +0 -1
  248. package/.next/server/app/api/version/route.js.nft.json +0 -1
  249. package/.next/server/app/api/version/route_client-reference-manifest.js +0 -1
  250. package/.next/server/app/index.html +0 -1
  251. package/.next/server/app/index.meta +0 -14
  252. package/.next/server/app/index.rsc +0 -17
  253. package/.next/server/app/index.segments/__PAGE__.segment.rsc +0 -6
  254. package/.next/server/app/index.segments/_full.segment.rsc +0 -17
  255. package/.next/server/app/index.segments/_head.segment.rsc +0 -6
  256. package/.next/server/app/index.segments/_index.segment.rsc +0 -5
  257. package/.next/server/app/index.segments/_tree.segment.rsc +0 -4
  258. package/.next/server/app/login/page.js +0 -2
  259. package/.next/server/app/login/page.js.nft.json +0 -1
  260. package/.next/server/app/login/page_client-reference-manifest.js +0 -1
  261. package/.next/server/app/login.html +0 -1
  262. package/.next/server/app/login.meta +0 -15
  263. package/.next/server/app/login.rsc +0 -22
  264. package/.next/server/app/login.segments/_full.segment.rsc +0 -22
  265. package/.next/server/app/login.segments/_head.segment.rsc +0 -6
  266. package/.next/server/app/login.segments/_index.segment.rsc +0 -5
  267. package/.next/server/app/login.segments/_tree.segment.rsc +0 -4
  268. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +0 -9
  269. package/.next/server/app/login.segments/login.segment.rsc +0 -5
  270. package/.next/server/app/page.js +0 -261
  271. package/.next/server/app/page.js.nft.json +0 -1
  272. package/.next/server/app/page_client-reference-manifest.js +0 -1
  273. package/.next/server/app-paths-manifest.json +0 -39
  274. package/.next/server/chunks/1048.js +0 -1
  275. package/.next/server/chunks/1367.js +0 -77
  276. package/.next/server/chunks/1381.js +0 -1
  277. package/.next/server/chunks/165.js +0 -1
  278. package/.next/server/chunks/1681.js +0 -215
  279. package/.next/server/chunks/1688.js +0 -45
  280. package/.next/server/chunks/1703.js +0 -79
  281. package/.next/server/chunks/1712.js +0 -43
  282. package/.next/server/chunks/1813.js +0 -1
  283. package/.next/server/chunks/2325.js +0 -80
  284. package/.next/server/chunks/258.js +0 -1
  285. package/.next/server/chunks/2671.js +0 -287
  286. package/.next/server/chunks/2778.js +0 -1
  287. package/.next/server/chunks/2943.js +0 -1
  288. package/.next/server/chunks/3031.js +0 -226
  289. package/.next/server/chunks/3181.js +0 -1
  290. package/.next/server/chunks/3493.js +0 -1
  291. package/.next/server/chunks/3672.js +0 -1
  292. package/.next/server/chunks/3701.js +0 -104
  293. package/.next/server/chunks/4013.js +0 -1
  294. package/.next/server/chunks/402.js +0 -2
  295. package/.next/server/chunks/4035.js +0 -80
  296. package/.next/server/chunks/4248.js +0 -153
  297. package/.next/server/chunks/4367.js +0 -1
  298. package/.next/server/chunks/4406.js +0 -141
  299. package/.next/server/chunks/4741.js +0 -18
  300. package/.next/server/chunks/4768.js +0 -1
  301. package/.next/server/chunks/4858.js +0 -148
  302. package/.next/server/chunks/4980.js +0 -1
  303. package/.next/server/chunks/5155.js +0 -5
  304. package/.next/server/chunks/5293.js +0 -166
  305. package/.next/server/chunks/5399.js +0 -8
  306. package/.next/server/chunks/5409.js +0 -1
  307. package/.next/server/chunks/5797.js +0 -93
  308. package/.next/server/chunks/5851.js +0 -36
  309. package/.next/server/chunks/6206.js +0 -1
  310. package/.next/server/chunks/6296.js +0 -1
  311. package/.next/server/chunks/63.js +0 -45
  312. package/.next/server/chunks/6346.js +0 -1
  313. package/.next/server/chunks/6406.js +0 -23
  314. package/.next/server/chunks/642.js +0 -1
  315. package/.next/server/chunks/6429.js +0 -50
  316. package/.next/server/chunks/6729.js +0 -64
  317. package/.next/server/chunks/6907.js +0 -115
  318. package/.next/server/chunks/6980.js +0 -1
  319. package/.next/server/chunks/7073.js +0 -24
  320. package/.next/server/chunks/7233.js +0 -24
  321. package/.next/server/chunks/7307.js +0 -1
  322. package/.next/server/chunks/7362.js +0 -9
  323. package/.next/server/chunks/7567.js +0 -29
  324. package/.next/server/chunks/7765.js +0 -1
  325. package/.next/server/chunks/7890.js +0 -1
  326. package/.next/server/chunks/8065.js +0 -1
  327. package/.next/server/chunks/8238.js +0 -34
  328. package/.next/server/chunks/8276.js +0 -1
  329. package/.next/server/chunks/8336.js +0 -1
  330. package/.next/server/chunks/8477.js +0 -3
  331. package/.next/server/chunks/8490.js +0 -1
  332. package/.next/server/chunks/8916.js +0 -1
  333. package/.next/server/chunks/9280.js +0 -252
  334. package/.next/server/chunks/9315.js +0 -1
  335. package/.next/server/chunks/9537.js +0 -90
  336. package/.next/server/chunks/966.js +0 -1
  337. package/.next/server/chunks/9818.js +0 -21
  338. package/.next/server/chunks/static/media/pdf.worker.min.c476e1a0.mjs +0 -6
  339. package/.next/server/functions-config-manifest.json +0 -16
  340. package/.next/server/interception-route-rewrite-manifest.js +0 -1
  341. package/.next/server/middleware-build-manifest.js +0 -1
  342. package/.next/server/middleware-manifest.json +0 -6
  343. package/.next/server/middleware-react-loadable-manifest.js +0 -1
  344. package/.next/server/middleware.js +0 -18
  345. package/.next/server/middleware.js.nft.json +0 -1
  346. package/.next/server/next-font-manifest.js +0 -1
  347. package/.next/server/next-font-manifest.json +0 -1
  348. package/.next/server/pages/404.html +0 -1
  349. package/.next/server/pages/500.html +0 -1
  350. package/.next/server/pages-manifest.json +0 -4
  351. package/.next/server/prefetch-hints.json +0 -1
  352. package/.next/server/server-reference-manifest.js +0 -1
  353. package/.next/server/server-reference-manifest.json +0 -1
  354. package/.next/server/webpack-runtime.js +0 -1
  355. package/.next/static/6cuMSvcr0FVO-GiK5RJZh/_buildManifest.js +0 -1
  356. package/.next/static/6cuMSvcr0FVO-GiK5RJZh/_ssgManifest.js +0 -1
  357. package/.next/static/chunks/0b9a0da7.9075af772487e743.js +0 -62
  358. package/.next/static/chunks/1413.922d232de90c0c41.js +0 -115
  359. package/.next/static/chunks/1643.467a526a1f24f54d.js +0 -24
  360. package/.next/static/chunks/1852.5543122f11aa7fed.js +0 -1
  361. package/.next/static/chunks/1960.b1e26436d7a5f586.js +0 -1
  362. package/.next/static/chunks/2170a4aa.4213bb2183c9cdf9.js +0 -1
  363. package/.next/static/chunks/2274.6cd173f80a1405a2.js +0 -21
  364. package/.next/static/chunks/2419.347fdfe3c170854d.js +0 -166
  365. package/.next/static/chunks/2619.9aac8983f30c7c8a.js +0 -1
  366. package/.next/static/chunks/2623.d20fabd8e18197c6.js +0 -287
  367. package/.next/static/chunks/2729.f5365061a849d659.js +0 -34
  368. package/.next/static/chunks/2821.934bcf60fbdc28c6.js +0 -1
  369. package/.next/static/chunks/2918becc.abff2ece1de37bc1.js +0 -153
  370. package/.next/static/chunks/2947.114e51cb06d1c01a.js +0 -23
  371. package/.next/static/chunks/3079.4c511fa1144e3adf.js +0 -79
  372. package/.next/static/chunks/3274.208ca44844cd7d95.js +0 -148
  373. package/.next/static/chunks/3308.465a94263d04bfea.js +0 -73
  374. package/.next/static/chunks/3325.e4bfe1ca657f3b5b.js +0 -80
  375. package/.next/static/chunks/3506.2a7eaa08b9f55337.js +0 -90
  376. package/.next/static/chunks/363642f4-043c1475ab9af70e.js +0 -1
  377. package/.next/static/chunks/3794-123fdf632563f469.js +0 -32
  378. package/.next/static/chunks/3837.a755ccfe6f9c1c1c.js +0 -5
  379. package/.next/static/chunks/394.91597771688df6d0.js +0 -1
  380. package/.next/static/chunks/3997.1009c06025691712.js +0 -1
  381. package/.next/static/chunks/4453.91a357dc43c21745.js +0 -1
  382. package/.next/static/chunks/4491.44fdf20580ac72bd.js +0 -24
  383. package/.next/static/chunks/4829.cf1d50e43e6d9db5.js +0 -1
  384. package/.next/static/chunks/498.fe1d9da9ecad6c36.js +0 -1
  385. package/.next/static/chunks/4bd1b696-e356ca5ba0218e27.js +0 -1
  386. package/.next/static/chunks/5019.b5a1a2b8daf17525.js +0 -1
  387. package/.next/static/chunks/5034.8f16c3fa3ce75411.js +0 -1
  388. package/.next/static/chunks/5074.d16651da01ec4e02.js +0 -1
  389. package/.next/static/chunks/51fb665c.0950e1b79671348d.js +0 -45
  390. package/.next/static/chunks/532.5956ed631aff722b.js +0 -9
  391. package/.next/static/chunks/5326.69460442bdcd6cd3.js +0 -1
  392. package/.next/static/chunks/5403.ff110bf5bf600758.js +0 -64
  393. package/.next/static/chunks/547.902a733488cfe3f7.js +0 -77
  394. package/.next/static/chunks/5567.540d7fc108ad6ee5.js +0 -215
  395. package/.next/static/chunks/5590.ef62922166d308b4.js +0 -1
  396. package/.next/static/chunks/5690.9d6eb1edb1399995.js +0 -1
  397. package/.next/static/chunks/5749.25faee4a1e55b854.js +0 -226
  398. package/.next/static/chunks/58bb9007.1ccb6bba34b4c635.js +0 -80
  399. package/.next/static/chunks/6121.f3f43f1896ea0cd9.js +0 -1
  400. package/.next/static/chunks/6600.583c88eef37aa524.js +0 -1
  401. package/.next/static/chunks/6696.a41aec266e657d54.js +0 -141
  402. package/.next/static/chunks/6922.42148793782d2fe7.js +0 -1
  403. package/.next/static/chunks/7006.e191611ffc2b9528.js +0 -43
  404. package/.next/static/chunks/7343.9fbb58204d8ac681.js +0 -1
  405. package/.next/static/chunks/73972abe.25a4cffa03b2bcef.js +0 -119
  406. package/.next/static/chunks/7547.58bda8a2aabba0d4.js +0 -93
  407. package/.next/static/chunks/7648.4ae2f183b4db0353.js +0 -1
  408. package/.next/static/chunks/7874.8db6929b94cdf697.js +0 -1
  409. package/.next/static/chunks/7959.1f20a35df316216a.js +0 -104
  410. package/.next/static/chunks/83.85d62d7fc9850b75.js +0 -29
  411. package/.next/static/chunks/8436.cab94b59cca0a8ff.js +0 -1
  412. package/.next/static/chunks/8451.ff6ff72b57dc52e1.js +0 -1
  413. package/.next/static/chunks/8489.45f22859734f514f.js +0 -36
  414. package/.next/static/chunks/8568.f85d8b36fc9a9037.js +0 -1
  415. package/.next/static/chunks/8771-3e14b6810486df1f.js +0 -1
  416. package/.next/static/chunks/8863.be51033a67436277.js +0 -1
  417. package/.next/static/chunks/90542734.dc1a2723e4f6affb.js +0 -1
  418. package/.next/static/chunks/9500.1488aec06ee78127.js +0 -1
  419. package/.next/static/chunks/9633.155548b5fca6e580.js +0 -1
  420. package/.next/static/chunks/9779.673004a62d70e36a.js +0 -1
  421. package/.next/static/chunks/app/_global-error/page-cc518af6b1ffb191.js +0 -1
  422. package/.next/static/chunks/app/_not-found/page-c72daab99269beff.js +0 -1
  423. package/.next/static/chunks/app/api/agent/[id]/events/route-cc518af6b1ffb191.js +0 -1
  424. package/.next/static/chunks/app/api/agent/[id]/route-cc518af6b1ffb191.js +0 -1
  425. package/.next/static/chunks/app/api/agent/new/route-cc518af6b1ffb191.js +0 -1
  426. package/.next/static/chunks/app/api/auth/all-providers/route-cc518af6b1ffb191.js +0 -1
  427. package/.next/static/chunks/app/api/auth/api-key/[provider]/route-cc518af6b1ffb191.js +0 -1
  428. package/.next/static/chunks/app/api/auth/login/[provider]/route-cc518af6b1ffb191.js +0 -1
  429. package/.next/static/chunks/app/api/auth/login/route-cc518af6b1ffb191.js +0 -1
  430. package/.next/static/chunks/app/api/auth/logout/[provider]/route-cc518af6b1ffb191.js +0 -1
  431. package/.next/static/chunks/app/api/auth/providers/route-cc518af6b1ffb191.js +0 -1
  432. package/.next/static/chunks/app/api/auth/status/route-cc518af6b1ffb191.js +0 -1
  433. package/.next/static/chunks/app/api/default-cwd/route-cc518af6b1ffb191.js +0 -1
  434. package/.next/static/chunks/app/api/files/[...path]/route-cc518af6b1ffb191.js +0 -1
  435. package/.next/static/chunks/app/api/harness/route-cc518af6b1ffb191.js +0 -1
  436. package/.next/static/chunks/app/api/home/route-cc518af6b1ffb191.js +0 -1
  437. package/.next/static/chunks/app/api/internal/runtime/route-cc518af6b1ffb191.js +0 -1
  438. package/.next/static/chunks/app/api/models/route-cc518af6b1ffb191.js +0 -1
  439. package/.next/static/chunks/app/api/models-config/discover/route-cc518af6b1ffb191.js +0 -1
  440. package/.next/static/chunks/app/api/models-config/route-cc518af6b1ffb191.js +0 -1
  441. package/.next/static/chunks/app/api/models-config/test/route-cc518af6b1ffb191.js +0 -1
  442. package/.next/static/chunks/app/api/projects/browse/route-cc518af6b1ffb191.js +0 -1
  443. package/.next/static/chunks/app/api/projects/route-cc518af6b1ffb191.js +0 -1
  444. package/.next/static/chunks/app/api/reports/[id]/route-cc518af6b1ffb191.js +0 -1
  445. package/.next/static/chunks/app/api/search/route-cc518af6b1ffb191.js +0 -1
  446. package/.next/static/chunks/app/api/sessions/[id]/context/route-cc518af6b1ffb191.js +0 -1
  447. package/.next/static/chunks/app/api/sessions/[id]/route-cc518af6b1ffb191.js +0 -1
  448. package/.next/static/chunks/app/api/sessions/new/route-cc518af6b1ffb191.js +0 -1
  449. package/.next/static/chunks/app/api/sessions/route-cc518af6b1ffb191.js +0 -1
  450. package/.next/static/chunks/app/api/settings/route-cc518af6b1ffb191.js +0 -1
  451. package/.next/static/chunks/app/api/skills/install/route-cc518af6b1ffb191.js +0 -1
  452. package/.next/static/chunks/app/api/skills/route-cc518af6b1ffb191.js +0 -1
  453. package/.next/static/chunks/app/api/skills/search/route-cc518af6b1ffb191.js +0 -1
  454. package/.next/static/chunks/app/api/soul/route-cc518af6b1ffb191.js +0 -1
  455. package/.next/static/chunks/app/api/version/route-cc518af6b1ffb191.js +0 -1
  456. package/.next/static/chunks/app/layout-be148b7ae915b22a.js +0 -1
  457. package/.next/static/chunks/app/login/page-ebf0e6de99062783.js +0 -1
  458. package/.next/static/chunks/app/page-c45d98ea81c548ca.js +0 -260
  459. package/.next/static/chunks/d3ac728e.7964f816a1ca64e5.js +0 -1
  460. package/.next/static/chunks/framework-711ef29bc66f648c.js +0 -1
  461. package/.next/static/chunks/main-app-45a0f19af99d61b6.js +0 -1
  462. package/.next/static/chunks/main-f74964b7ae52493e.js +0 -5
  463. package/.next/static/chunks/next/dist/client/components/builtin/app-error-cc518af6b1ffb191.js +0 -1
  464. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-cc518af6b1ffb191.js +0 -1
  465. package/.next/static/chunks/next/dist/client/components/builtin/global-error-9bfa08b9491621f2.js +0 -1
  466. package/.next/static/chunks/next/dist/client/components/builtin/not-found-cc518af6b1ffb191.js +0 -1
  467. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-cc518af6b1ffb191.js +0 -1
  468. package/.next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  469. package/.next/static/chunks/webpack-fcf4a889ecbd753c.js +0 -1
  470. package/.next/static/css/45029451a1d7255d.css +0 -3
  471. package/.next/static/media/15605e25b523335c-s.woff2 +0 -0
  472. package/.next/static/media/1a3dce5cfb5f7760-s.woff2 +0 -0
  473. package/.next/static/media/1cdd02902f937a18-s.woff2 +0 -0
  474. package/.next/static/media/4c4b3b30b6bcb2be-s.woff2 +0 -0
  475. package/.next/static/media/641a7b8a5800ee0e-s.woff2 +0 -0
  476. package/.next/static/media/7deddc85b7ffd1dc-s.p.woff2 +0 -0
  477. package/.next/static/media/ec14413c594b3356-s.p.woff2 +0 -0
  478. package/.next/static/media/pdf.worker.min.29aaf158.mjs +0 -6
  479. package/.next/trace +0 -74
  480. package/.next/trace-build +0 -1
  481. package/.next/types/app/api/agent/[id]/events/route.ts +0 -351
  482. package/.next/types/app/api/agent/[id]/route.ts +0 -351
  483. package/.next/types/app/api/agent/new/route.ts +0 -351
  484. package/.next/types/app/api/auth/all-providers/route.ts +0 -351
  485. package/.next/types/app/api/auth/api-key/[provider]/route.ts +0 -351
  486. package/.next/types/app/api/auth/login/[provider]/route.ts +0 -351
  487. package/.next/types/app/api/auth/login/route.ts +0 -351
  488. package/.next/types/app/api/auth/logout/[provider]/route.ts +0 -351
  489. package/.next/types/app/api/auth/providers/route.ts +0 -351
  490. package/.next/types/app/api/auth/status/route.ts +0 -351
  491. package/.next/types/app/api/default-cwd/route.ts +0 -351
  492. package/.next/types/app/api/files/[...path]/route.ts +0 -351
  493. package/.next/types/app/api/harness/route.ts +0 -351
  494. package/.next/types/app/api/home/route.ts +0 -351
  495. package/.next/types/app/api/internal/runtime/route.ts +0 -351
  496. package/.next/types/app/api/models/route.ts +0 -351
  497. package/.next/types/app/api/models-config/discover/route.ts +0 -351
  498. package/.next/types/app/api/models-config/route.ts +0 -351
  499. package/.next/types/app/api/models-config/test/route.ts +0 -351
  500. package/.next/types/app/api/projects/browse/route.ts +0 -351
  501. package/.next/types/app/api/projects/route.ts +0 -351
  502. package/.next/types/app/api/reports/[id]/route.ts +0 -351
  503. package/.next/types/app/api/search/route.ts +0 -351
  504. package/.next/types/app/api/sessions/[id]/context/route.ts +0 -351
  505. package/.next/types/app/api/sessions/[id]/route.ts +0 -351
  506. package/.next/types/app/api/sessions/new/route.ts +0 -351
  507. package/.next/types/app/api/sessions/route.ts +0 -351
  508. package/.next/types/app/api/settings/route.ts +0 -351
  509. package/.next/types/app/api/skills/install/route.ts +0 -351
  510. package/.next/types/app/api/skills/route.ts +0 -351
  511. package/.next/types/app/api/skills/search/route.ts +0 -351
  512. package/.next/types/app/api/soul/route.ts +0 -351
  513. package/.next/types/app/api/version/route.ts +0 -351
  514. package/.next/types/app/layout.ts +0 -87
  515. package/.next/types/app/login/page.ts +0 -87
  516. package/.next/types/app/page.ts +0 -87
  517. package/.next/types/package.json +0 -1
  518. package/.next/types/routes.d.ts +0 -106
  519. package/.next/types/validator.ts +0 -376
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Models API — merged list from annodex providers.json + codex config.toml
3
+ */
4
+
5
+ import { readMergedConfig, listAllModels, getDefaultModel } from "@/lib/annodex-config";
6
+
7
+ export const dynamic = "force-dynamic";
8
+
9
+ const DEFAULT_THINKING_LEVEL_MAP: Record<string, string | null> = {
10
+ auto: null,
11
+ off: "off",
12
+ minimal: "minimal",
13
+ low: "low",
14
+ medium: "medium",
15
+ high: "high",
16
+ xhigh: "xhigh",
17
+ };
18
+
19
+ export async function GET() {
20
+ try {
21
+ const config = readMergedConfig();
22
+ const modelOptions = listAllModels(config);
23
+ const defaultModel = getDefaultModel(config);
24
+
25
+ const models: Record<string, string> = {};
26
+ const modelList: { id: string; name: string; provider: string; contextWindow?: number; maxTokens?: number; input?: string[] }[] = [];
27
+ for (const m of modelOptions) {
28
+ const key = `${m.provider}:${m.modelId}`;
29
+ models[key] = m.name;
30
+ modelList.push({
31
+ id: m.modelId,
32
+ name: m.name,
33
+ provider: m.provider,
34
+ contextWindow: m.contextWindow,
35
+ maxTokens: m.maxTokens,
36
+ input: m.input,
37
+ });
38
+ }
39
+
40
+ const thinkingLevels: Record<string, string[]> = {};
41
+ const thinkingLevelMaps: Record<string, Record<string, string | null>> = {};
42
+ for (const m of modelOptions) {
43
+ const key = `${m.provider}:${m.modelId}`;
44
+ const levelMap = m.thinkingLevelMap ?? DEFAULT_THINKING_LEVEL_MAP;
45
+ thinkingLevels[key] = Object.entries(levelMap)
46
+ .filter(([level, mapped]) => level !== "auto" && mapped !== null)
47
+ .map(([level]) => level);
48
+ thinkingLevelMaps[key] = levelMap;
49
+ }
50
+
51
+ return Response.json({
52
+ models,
53
+ modelList,
54
+ defaultModel,
55
+ thinkingLevels,
56
+ thinkingLevelMaps,
57
+ });
58
+ } catch {
59
+ return Response.json({
60
+ models: {},
61
+ modelList: [],
62
+ defaultModel: null,
63
+ thinkingLevels: {},
64
+ thinkingLevelMaps: {},
65
+ });
66
+ }
67
+ }
@@ -0,0 +1,42 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { convertToPiModels, enrichModelsWithRemoteMetadata, fetchModelsFromBaseUrl, normalizeBaseUrl } from "@/lib/model-discovery";
3
+
4
+ export const dynamic = "force-dynamic";
5
+
6
+ function errorMessage(error: unknown): string {
7
+ return error instanceof Error ? error.message : String(error);
8
+ }
9
+
10
+ export async function POST(req: NextRequest) {
11
+ try {
12
+ const body = await req.json() as {
13
+ baseUrl?: unknown;
14
+ apiKey?: unknown;
15
+ provider?: unknown;
16
+ enrich?: unknown;
17
+ };
18
+
19
+ const baseUrl = typeof body.baseUrl === "string" ? normalizeBaseUrl(body.baseUrl) : "";
20
+ const apiKey = typeof body.apiKey === "string" ? body.apiKey : "";
21
+ const provider = typeof body.provider === "string" ? body.provider.trim() : "";
22
+ if (!baseUrl) {
23
+ return NextResponse.json({ ok: false, error: "Base URL is required" }, { status: 400 });
24
+ }
25
+
26
+ const fetched = await fetchModelsFromBaseUrl(baseUrl, apiKey);
27
+ const enriched = body.enrich === false
28
+ ? fetched.models
29
+ : await enrichModelsWithRemoteMetadata(baseUrl, apiKey, fetched.models);
30
+ const piModels = convertToPiModels(enriched, false, provider || undefined, baseUrl);
31
+
32
+ return NextResponse.json({
33
+ ok: true,
34
+ endpoint: fetched.endpoint,
35
+ baseUrl,
36
+ models: enriched,
37
+ piModels,
38
+ });
39
+ } catch (error) {
40
+ return NextResponse.json({ ok: false, error: errorMessage(error) }, { status: 500 });
41
+ }
42
+ }
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Models Config API — reads/writes ~/.config/annodex/providers.json
3
+ *
4
+ * Annodex maintains its own provider list with API keys.
5
+ * Codex config.toml providers are merged read-only at runtime.
6
+ */
7
+
8
+ import { NextResponse } from "next/server";
9
+ import {
10
+ readMergedConfig,
11
+ readProvidersFile as readProviders,
12
+ writeProvidersFile as writeProviders,
13
+ } from "@/lib/annodex-config";
14
+ import { isProviderApi, normalizeProviderApi } from "@/lib/provider-api";
15
+
16
+ export const dynamic = "force-dynamic";
17
+
18
+ type ModelConfigBody = {
19
+ id: string;
20
+ name?: string;
21
+ api?: string;
22
+ reasoning?: boolean;
23
+ thinkingLevelMap?: Record<string, string | null>;
24
+ input?: string[];
25
+ contextWindow?: number;
26
+ maxTokens?: number;
27
+ compat?: Record<string, unknown>;
28
+ };
29
+
30
+ type ProviderConfigBody = {
31
+ baseUrl?: string;
32
+ api?: string;
33
+ apiKey?: string;
34
+ requiresOpenAiAuth?: boolean;
35
+ source?: string;
36
+ models?: ModelConfigBody[];
37
+ };
38
+
39
+ function normalizeStringArray(value: unknown): string[] | undefined {
40
+ if (!Array.isArray(value)) return undefined;
41
+ const strings = value.filter((item): item is string => typeof item === "string" && item.trim().length > 0);
42
+ return strings.length ? strings : undefined;
43
+ }
44
+
45
+ function isRecord(value: unknown): value is Record<string, unknown> {
46
+ return typeof value === "object" && value !== null && !Array.isArray(value);
47
+ }
48
+
49
+ function normalizeThinkingLevelMap(value: unknown): Record<string, string | null> | undefined {
50
+ if (!isRecord(value)) return undefined;
51
+ const normalized: Record<string, string | null> = {};
52
+ for (const [key, entry] of Object.entries(value)) {
53
+ if (typeof entry === "string" || entry === null) normalized[key] = entry;
54
+ }
55
+ return Object.keys(normalized).length ? normalized : undefined;
56
+ }
57
+
58
+ function normalizeCompat(value: unknown): Record<string, unknown> | undefined {
59
+ if (!isRecord(value)) return undefined;
60
+ return Object.keys(value).length ? value : undefined;
61
+ }
62
+
63
+ export async function GET() {
64
+ try {
65
+ const data = readMergedConfig();
66
+ // Return in format compatible with ModelsConfig UI
67
+ return NextResponse.json({
68
+ providers: Object.fromEntries(
69
+ data.providers.map((p) => [
70
+ p.id,
71
+ {
72
+ baseUrl: p.baseUrl,
73
+ apiKey: p.apiKey,
74
+ api: p.api ?? "openai-responses",
75
+ requiresOpenAiAuth: p.requiresOpenAiAuth,
76
+ source: p.source ?? "annodex",
77
+ sourceProviderId: p.sourceProviderId,
78
+ models: p.models.map((m) => ({
79
+ id: m.id,
80
+ name: m.name,
81
+ api: m.api,
82
+ reasoning: m.reasoning,
83
+ thinkingLevelMap: m.thinkingLevelMap,
84
+ input: m.input,
85
+ contextWindow: m.contextWindow,
86
+ maxTokens: m.maxTokens,
87
+ compat: m.compat,
88
+ })),
89
+ },
90
+ ])
91
+ ),
92
+ defaultProvider: data.defaultProvider,
93
+ defaultModel: data.defaultModel,
94
+ });
95
+ } catch (error) {
96
+ return NextResponse.json({ providers: {}, error: String(error) }, { status: 500 });
97
+ }
98
+ }
99
+
100
+ export async function PUT(req: Request) {
101
+ try {
102
+ const body = await req.json() as {
103
+ providers?: Record<string, ProviderConfigBody>;
104
+ defaultProvider?: string;
105
+ defaultModel?: string;
106
+ };
107
+
108
+ const data = readProviders();
109
+
110
+ if (body.providers) {
111
+ data.providers = Object.entries(body.providers)
112
+ .filter(([, p]) => typeof p.baseUrl === "string" && p.source !== "codex")
113
+ .map(([id, p]) => {
114
+ const baseUrl = (p.baseUrl ?? "").replace(/\/+$/, "");
115
+ return {
116
+ id,
117
+ name: id,
118
+ baseUrl,
119
+ api: normalizeProviderApi(p.api, baseUrl, id),
120
+ apiKey: typeof p.apiKey === "string" ? p.apiKey : "",
121
+ requiresOpenAiAuth: typeof p.requiresOpenAiAuth === "boolean" ? p.requiresOpenAiAuth : undefined,
122
+ models: Array.isArray(p.models)
123
+ ? p.models
124
+ .filter((m): m is ModelConfigBody => typeof m.id === "string")
125
+ .map((m) => {
126
+ const modelId = m.id.trim();
127
+ return {
128
+ id: modelId,
129
+ name: m.name || modelId,
130
+ api: isProviderApi(m.api) ? m.api : undefined,
131
+ reasoning: typeof m.reasoning === "boolean" ? m.reasoning : undefined,
132
+ thinkingLevelMap: normalizeThinkingLevelMap(m.thinkingLevelMap),
133
+ input: normalizeStringArray(m.input),
134
+ contextWindow: typeof m.contextWindow === "number" ? m.contextWindow : undefined,
135
+ maxTokens: typeof m.maxTokens === "number" ? m.maxTokens : undefined,
136
+ compat: normalizeCompat(m.compat),
137
+ };
138
+ })
139
+ .filter((m) => m.id)
140
+ : [],
141
+ };
142
+ });
143
+ }
144
+ delete data.defaultProvider;
145
+ delete data.defaultModel;
146
+
147
+ writeProviders(data);
148
+ return NextResponse.json({ success: true });
149
+ } catch (error) {
150
+ return NextResponse.json({ error: String(error) }, { status: 500 });
151
+ }
152
+ }
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Model test route — validates the saved protocol against the provider endpoint.
3
+ */
4
+
5
+ import { execSync } from "child_process";
6
+ import { NextResponse } from "next/server";
7
+ import { chatCompletionsUrl } from "@/lib/codex-compat-proxy";
8
+ import { normalizeProviderApi } from "@/lib/provider-api";
9
+
10
+ export const dynamic = "force-dynamic";
11
+
12
+ type TestProvider = {
13
+ baseUrl?: string;
14
+ api?: string;
15
+ apiKey?: string;
16
+ };
17
+
18
+ type TestModel = {
19
+ id?: string;
20
+ api?: string;
21
+ };
22
+
23
+ function resolveApiKey(value?: string): string | undefined {
24
+ const trimmed = value?.trim();
25
+ if (!trimmed) return undefined;
26
+ if (trimmed.startsWith("!")) {
27
+ try {
28
+ return execSync(trimmed.slice(1), {
29
+ encoding: "utf8",
30
+ stdio: ["ignore", "pipe", "ignore"],
31
+ timeout: 10_000,
32
+ }).trim() || undefined;
33
+ } catch {
34
+ return undefined;
35
+ }
36
+ }
37
+ if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed) && process.env[trimmed]) {
38
+ return process.env[trimmed];
39
+ }
40
+ return trimmed;
41
+ }
42
+
43
+ function endpointFor(baseUrl: string, api: string): string {
44
+ const normalized = baseUrl.replace(/\/+$/, "");
45
+ if (api === "openai-completions") {
46
+ return chatCompletionsUrl(normalized);
47
+ }
48
+ return normalized.endsWith("/responses") ? normalized : `${normalized}/responses`;
49
+ }
50
+
51
+ function buildBody(api: string, modelId: string): Record<string, unknown> {
52
+ if (api === "openai-completions") {
53
+ return {
54
+ model: modelId,
55
+ messages: [{ role: "user", content: "Reply with pong only." }],
56
+ max_tokens: 8,
57
+ stream: false,
58
+ };
59
+ }
60
+ return {
61
+ model: modelId,
62
+ input: "Reply with pong only.",
63
+ max_output_tokens: 8,
64
+ stream: false,
65
+ };
66
+ }
67
+
68
+ function summarizeResponse(payload: unknown): string {
69
+ if (typeof payload !== "object" || payload === null) return String(payload).slice(0, 200);
70
+ const record = payload as Record<string, unknown>;
71
+ const outputText = record.output_text;
72
+ if (typeof outputText === "string" && outputText) return outputText.slice(0, 200);
73
+
74
+ const choices = record.choices;
75
+ if (Array.isArray(choices) && choices.length > 0) {
76
+ const first = choices[0] as { message?: { content?: unknown }; text?: unknown };
77
+ const content = first.message?.content ?? first.text;
78
+ if (typeof content === "string" && content) return content.slice(0, 200);
79
+ }
80
+
81
+ const error = record.error;
82
+ if (typeof error === "object" && error !== null && "message" in error) {
83
+ const message = (error as { message?: unknown }).message;
84
+ if (typeof message === "string") return message.slice(0, 200);
85
+ }
86
+
87
+ return JSON.stringify(payload).slice(0, 200);
88
+ }
89
+
90
+ export async function POST(req: Request) {
91
+ const started = Date.now();
92
+ try {
93
+ const body = await req.json() as {
94
+ providerName?: string;
95
+ provider?: TestProvider;
96
+ model?: TestModel;
97
+ };
98
+
99
+ const provider = body.provider ?? {};
100
+ const modelId = body.model?.id?.trim();
101
+ const baseUrl = provider.baseUrl?.trim().replace(/\/+$/, "");
102
+ if (!baseUrl) {
103
+ return NextResponse.json({ ok: false, error: "Base URL is required" }, { status: 400 });
104
+ }
105
+ if (!modelId) {
106
+ return NextResponse.json({ ok: false, error: "Model ID is required" }, { status: 400 });
107
+ }
108
+
109
+ const api = normalizeProviderApi(body.model?.api ?? provider.api, baseUrl, body.providerName);
110
+ const apiKey = resolveApiKey(provider.apiKey);
111
+ const headers: Record<string, string> = { "content-type": "application/json" };
112
+ if (apiKey) headers.authorization = `Bearer ${apiKey}`;
113
+
114
+ const upstream = await fetch(endpointFor(baseUrl, api), {
115
+ method: "POST",
116
+ headers,
117
+ body: JSON.stringify(buildBody(api, modelId)),
118
+ signal: AbortSignal.timeout(20_000),
119
+ });
120
+
121
+ const text = await upstream.text();
122
+ let payload: unknown = text;
123
+ try {
124
+ payload = JSON.parse(text);
125
+ } catch {
126
+ // Plain-text provider errors are still useful for diagnostics.
127
+ }
128
+
129
+ const latencyMs = Date.now() - started;
130
+ const responseText = summarizeResponse(payload);
131
+ if (!upstream.ok) {
132
+ return NextResponse.json({
133
+ ok: false,
134
+ error: responseText || `HTTP ${upstream.status}`,
135
+ latencyMs,
136
+ status: upstream.status,
137
+ responseText,
138
+ }, { status: 502 });
139
+ }
140
+
141
+ return NextResponse.json({
142
+ ok: true,
143
+ latencyMs,
144
+ status: upstream.status,
145
+ responseText,
146
+ });
147
+ } catch (error) {
148
+ return NextResponse.json({
149
+ ok: false,
150
+ error: error instanceof Error ? error.message : String(error),
151
+ latencyMs: Date.now() - started,
152
+ }, { status: 500 });
153
+ }
154
+ }
@@ -0,0 +1,51 @@
1
+ import { NextRequest, NextResponse } from "next/server";
2
+ import { readdir, access } from "fs/promises";
3
+ import { constants } from "fs";
4
+ import { homedir } from "os";
5
+ import path from "path";
6
+
7
+ async function getWindowsDrives(): Promise<string[]> {
8
+ if (process.platform !== "win32") return [];
9
+ const drives: string[] = [];
10
+ for (let code = 65; code <= 90; code += 1) {
11
+ const drive = `${String.fromCharCode(code)}:\\`;
12
+ try {
13
+ await access(drive, constants.R_OK);
14
+ drives.push(drive);
15
+ } catch {
16
+ // drive not available
17
+ }
18
+ }
19
+ return drives;
20
+ }
21
+
22
+ export async function GET(request: NextRequest) {
23
+ const dir = request.nextUrl.searchParams.get("dir") || homedir();
24
+ const resolvedDir = path.resolve(dir);
25
+
26
+ try {
27
+ await access(resolvedDir, constants.R_OK);
28
+ } catch {
29
+ return NextResponse.json({ error: "Directory does not exist or cannot be read" }, { status: 404 });
30
+ }
31
+
32
+ try {
33
+ const entries = await readdir(resolvedDir, { withFileTypes: true });
34
+ const directories = entries
35
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
36
+ .map((entry) => ({
37
+ name: entry.name,
38
+ path: path.join(resolvedDir, entry.name),
39
+ }))
40
+ .sort((a, b) => a.name.localeCompare(b.name));
41
+
42
+ return NextResponse.json({
43
+ current: resolvedDir,
44
+ parent: path.dirname(resolvedDir) !== resolvedDir ? path.dirname(resolvedDir) : null,
45
+ directories,
46
+ drives: await getWindowsDrives(),
47
+ });
48
+ } catch {
49
+ return NextResponse.json({ error: "Cannot read directory" }, { status: 500 });
50
+ }
51
+ }
@@ -0,0 +1,83 @@
1
+ import { NextResponse } from "next/server";
2
+ import { mkdirSync, statSync } from "fs";
3
+ import { listProjects, listProjectsFast, removeProject, renameProject, touchProject, upsertProject } from "@/lib/projects";
4
+
5
+ function isDirectory(path: string): boolean {
6
+ try {
7
+ return statSync(path).isDirectory();
8
+ } catch {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ export async function GET(req: Request) {
14
+ try {
15
+ const url = new URL(req.url);
16
+ const includeHidden = url.searchParams.get("includeHidden") === "1";
17
+ const includeSessionStats = url.searchParams.get("sessionStats") === "1";
18
+ const projects = includeSessionStats
19
+ ? await listProjects({ includeHidden })
20
+ : listProjectsFast({ includeHidden });
21
+ return NextResponse.json({ projects });
22
+ } catch (error) {
23
+ return NextResponse.json({ error: String(error) }, { status: 500 });
24
+ }
25
+ }
26
+
27
+ export async function POST(req: Request) {
28
+ try {
29
+ const body = await req.json() as { cwd?: unknown; name?: unknown; create?: unknown };
30
+ if (typeof body.cwd !== "string" || !body.cwd.trim()) {
31
+ return NextResponse.json({ error: "cwd is required" }, { status: 400 });
32
+ }
33
+ const cwd = body.cwd.trim();
34
+ if (body.create === true) {
35
+ mkdirSync(cwd, { recursive: true });
36
+ }
37
+ if (!isDirectory(cwd)) {
38
+ return NextResponse.json({ error: "Project path must be an existing directory" }, { status: 400 });
39
+ }
40
+ const project = upsertProject(cwd, {
41
+ name: typeof body.name === "string" ? body.name : undefined,
42
+ hidden: false,
43
+ });
44
+ return NextResponse.json({ ok: true, project });
45
+ } catch (error) {
46
+ return NextResponse.json({ error: String(error) }, { status: 500 });
47
+ }
48
+ }
49
+
50
+ export async function PATCH(req: Request) {
51
+ try {
52
+ const body = await req.json() as { cwd?: unknown; name?: unknown; touch?: unknown };
53
+ if (typeof body.cwd !== "string" || !body.cwd.trim()) {
54
+ return NextResponse.json({ error: "cwd is required" }, { status: 400 });
55
+ }
56
+ if (body.touch === true) {
57
+ touchProject(body.cwd);
58
+ } else {
59
+ if (typeof body.name !== "string") {
60
+ return NextResponse.json({ error: "name is required" }, { status: 400 });
61
+ }
62
+ renameProject(body.cwd, body.name);
63
+ }
64
+ const projects = await listProjects();
65
+ return NextResponse.json({ ok: true, projects });
66
+ } catch (error) {
67
+ return NextResponse.json({ error: String(error) }, { status: 500 });
68
+ }
69
+ }
70
+
71
+ export async function DELETE(req: Request) {
72
+ try {
73
+ const body = await req.json() as { cwd?: unknown };
74
+ if (typeof body.cwd !== "string" || !body.cwd.trim()) {
75
+ return NextResponse.json({ error: "cwd is required" }, { status: 400 });
76
+ }
77
+ removeProject(body.cwd);
78
+ const projects = await listProjects();
79
+ return NextResponse.json({ ok: true, projects });
80
+ } catch (error) {
81
+ return NextResponse.json({ error: String(error) }, { status: 500 });
82
+ }
83
+ }
@@ -0,0 +1,108 @@
1
+ import { NextResponse } from "next/server";
2
+ import {
3
+ applyReportUpdate,
4
+ generateReportFromSession,
5
+ readReport,
6
+ writeReport,
7
+ type AnalysisReport,
8
+ type AnalysisReportUpdate,
9
+ } from "@/lib/report-store";
10
+ import { loadCodexSessionContext, resolveSessionPath } from "@/lib/session-reader";
11
+
12
+ export const dynamic = "force-dynamic";
13
+
14
+ async function loadSessionForReport(sessionId: string): Promise<{
15
+ cwd: string;
16
+ title: string;
17
+ report: AnalysisReport;
18
+ context?: import("@/lib/types").SessionContext;
19
+ }> {
20
+ const cwd = await resolveSessionPath(sessionId);
21
+ if (!cwd) throw new Error("Session not found");
22
+
23
+ const title = "Analysis Report";
24
+ const report = readReport(sessionId, cwd, title);
25
+
26
+ const context = (await loadCodexSessionContext(sessionId, cwd).catch(() => null))?.context;
27
+
28
+ return { cwd, title, report, context };
29
+ }
30
+
31
+ export async function GET(
32
+ _req: Request,
33
+ { params }: { params: Promise<{ id: string }> }
34
+ ) {
35
+ const { id } = await params;
36
+ try {
37
+ const { report } = await loadSessionForReport(id);
38
+ return NextResponse.json({ report });
39
+ } catch (error) {
40
+ const message = error instanceof Error ? error.message : String(error);
41
+ return NextResponse.json({ error: message }, { status: message === "Session not found" ? 404 : 500 });
42
+ }
43
+ }
44
+
45
+ export async function PUT(
46
+ req: Request,
47
+ { params }: { params: Promise<{ id: string }> }
48
+ ) {
49
+ const { id } = await params;
50
+ try {
51
+ const body = await req.json() as { report?: AnalysisReport };
52
+ if (!body.report || typeof body.report !== "object") {
53
+ return NextResponse.json({ error: "report is required" }, { status: 400 });
54
+ }
55
+ const { cwd, title } = await loadSessionForReport(id);
56
+ const report = writeReport({
57
+ ...body.report,
58
+ schemaVersion: 1,
59
+ sessionId: id,
60
+ cwd,
61
+ title: body.report.title || title,
62
+ });
63
+ return NextResponse.json({ report });
64
+ } catch (error) {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ return NextResponse.json({ error: message }, { status: message === "Session not found" ? 404 : 500 });
67
+ }
68
+ }
69
+
70
+ export async function POST(
71
+ req: Request,
72
+ { params }: { params: Promise<{ id: string }> }
73
+ ) {
74
+ const { id } = await params;
75
+ try {
76
+ const body = await req.json().catch(() => ({})) as {
77
+ action?: string;
78
+ update?: AnalysisReportUpdate;
79
+ updateKey?: string;
80
+ leafId?: string | null;
81
+ topic?: string;
82
+ };
83
+ const { title, report, context } = await loadSessionForReport(id);
84
+ const action = body.action ?? "generate";
85
+ if (action === "apply_update") {
86
+ if (!body.update || typeof body.update !== "object") {
87
+ return NextResponse.json({ error: "update is required" }, { status: 400 });
88
+ }
89
+ const saved = writeReport(applyReportUpdate(report, body.update, typeof body.updateKey === "string" ? body.updateKey : undefined));
90
+ return NextResponse.json({ report: saved });
91
+ }
92
+
93
+ if (action !== "generate") {
94
+ return NextResponse.json({ error: "Unsupported action" }, { status: 400 });
95
+ }
96
+
97
+ if (!context || context.messages.length === 0) {
98
+ return NextResponse.json({ report });
99
+ }
100
+
101
+ const generated = generateReportFromSession({ report, context, sessionTitle: title, topic: body.topic });
102
+ const saved = writeReport(generated);
103
+ return NextResponse.json({ report: saved });
104
+ } catch (error) {
105
+ const message = error instanceof Error ? error.message : String(error);
106
+ return NextResponse.json({ error: message }, { status: message === "Session not found" ? 404 : 500 });
107
+ }
108
+ }